Architecture
Pick a stage to learn more about its moosbett architecture.
Stage
Every edit is automatically “staged” in memory by
the editor, as a minimal overlay of just the edited features. The edited
features can be joined to the immutable base data by
fid, and rendered in
whatever way best suits your project. Our demo map renders what would be
committed as the “current” state, with changed features
highlighted while editing.
fid is a feature's permanent identity in moosbett: a
stable integer assigned once and never reused. It is the join key between
base and overlay, and the unit of merge and deletion — to be
editable, every feature must carry one.
Data does not need to arrive with it: an import assigns
fresh fids in row order and keeps any source id (a UUID, an
OBJECTID, a name) as an ordinary attribute. A file moosbett
itself wrote already carries a fid column — the first
column of CURRENT — which is adopted
unchanged, so re-importing an export is a no-op.
Commit
A commit writes the staged overlay to a layer's store. This store is a flat key-value space that can be hosted in either the browser's IndexedDB (our demo's default) or in cloud blob storage. Hosting in cloud blob storage enables concurrent editing. Teammates will see recently committed edits the moment they commit and re-read the branch ref. The branch ref only advances by compare-and-swap, so stale writers are always rebased.
Below are the key-value objects a new commit writes to the store.
fid.
Why the whole row?
A delta keeps the whole feature row even when only one cell changed.
That way, every delta is a small, valid GeoParquet in its own right, and
reading stays one cheap pass: the newest row per fid wins.
If a delta held only the changed cell, a feature's current state would be
scattered across many commits, and every read would stitch rows back
together column by column — whole rows spend a little storage to
save that compute on every read.
There is an open opportunity here: in geospatial data the geometry column is often larger than all other columns combined, so a delta that could skip an unchanged geometry would shrink attribute-only edits dramatically.
fids this
commit removed
Bundle
Bundling turns a branch into one portable file — a
<branch>.moos.parquet, the
moosbett bundle — at your choice of
fidelity. Each tier takes a different approach to history, appropriate for
different use-cases — click a row for exactly what is kept, the tradeoff,
and the call that produces it.
Lossless. The full commit log rides along in SHADOW — every commit, time-travel anywhere. Tradeoff: file size grows with history.
pack()→pack() folds
them into CURRENT — the current layer, written as ordinary row
groups — and carries the history objects along in SHADOW.Call: repo.pack("main", Fidelity::Full)
· demo Export → Full history.
Lossy. CURRENT is the head; SHADOW keeps exactly one reverse delta back to a commit you choose, so a moosbett reader can rewind or diff between those two states — one exportable comparison. Everything between and before is shed. Tradeoff: one extra table over a bare export.
Call: repo.prune("main", PruneMode::Reversible { steps })
· CLI moosbett prune out.moos.parquet --mode reversible --steps N
· demo Export → Reversible.
Lossy. The commit history is gone; who created and last edited each
feature, and when, survive as four regular columns added to the parquet
— created_user, created_date,
last_edited_user, last_edited_date — the
editor-tracking convention ArcGIS users know.
Tradeoff: four extra columns, and blame is computed at
export time.
Call: repo.prune("main", PruneMode::Provenance)
· CLI moosbett prune out.provenance.parquet --mode provenance
· demo Export → Provenance.
Lossy. Current features only; nothing is recoverable — the smallest export, exactly what a vanilla re-save would produce, made explicit. Tradeoff: none in the file itself.
Call: repo.prune("main", PruneMode::Bare)
· CLI moosbett prune out.parquet
· demo Export → Bare.