spacedb-crdt
SpaceDB Layer 1 — convergent collections.
The default data tier, and the reason SpaceDB survives a partition-prone mesh:
data is modeled as Y-CRDT (via yrs), so
every write is locally available and merges conflict-free with no coordination.
Writing offline on a Starlink-partitioned home is a non-event, not an error.
Part of SpaceDB. Dual-licensed MIT OR Apache-2.0.
[]
= "0.5"
The model
A CrdtDoc is a document with a typed field → CRDT-type mapping. Pick the CRDT
per field; the merge rule follows from the type.
use CrdtDoc;
let laptop = new; // actor id
let phone = new;
laptop.set_register.unwrap; // LWW-Register
laptop.increment; // PN-Counter
laptop.text_push; // Y.Text
laptop.set_add; // OR-Set
// Sync: exchange state vectors, ship only the delta they imply.
let delta = laptop.encode_update_since.unwrap;
phone.apply_update.unwrap;
assert_eq!;
assert_eq!;
| CRDT type | Field API | Merge rule |
|---|---|---|
| LWW-Register | set_register / get_register / remove_register |
last writer wins |
| PN-Counter | increment / counter |
sum of per-actor increments |
| Y.Text | text_push / text_insert / text_remove / text |
character-level intent preservation |
| OR-Set | set_add / set_remove / set_contains / set_members |
add wins over concurrent remove |
Reactive queries
use CrdtDoc;
let doc = new;
let watcher = doc.watch;
// ... after any local or merged write:
if watcher.drain_changed
ReactiveQuery::poll gives the same thing with a derived value: it recomputes
only when the document revision moves.
Encrypted persistence
CrdtStore writes documents into a spacedb-store engine
behind the KeyProvider AEAD boundary — save, load, apply_remote,
contains. compact_updates folds an update log into one minimal update so a
long-lived document doesn't grow without bound.
The convergence property
The same updates, applied in any order, produce the same state. That is the
guarantee everything above this layer depends on, and it is proven — not
asserted — by the fuzzed suite in tests/convergence.rs,
which shuffles update orderings across replicas and requires byte-identical
final state.
ops_behind and estimated_state_size expose honest lag / size, which
spacedb-replica turns into a Freshness verdict.
Open-core boundary
Depends on yrs and spacedb-store — never on a MATA crate.
Testing
The workspace defaults to wasm32; this crate is native. Test on your host
triple:
Suites: convergence.rs (fuzzed), fields.rs, reactive.rs, persistence.rs,
compact.rs, lag.rs.
License
MIT OR Apache-2.0, at your option. See LICENSE-MIT and LICENSE-APACHE.