Sync / foldkit-durable
Limits
- SQLite is the only database: through
@effect/sql-sqlite-node(Node 22) forJournal.make, or anyeffect/sqlSQLite client for the coreJournal.layer(foldkit-durable/core), such as@effect/sql-sqlite-wasmin a browser or@effect/sql-d1on Cloudflare (withd1: true).vacuumreclaims a file's space and checkpoints its write-ahead log, which an in-memory database has nothing of; on D1 it is a no-op (see above). reduce,validate, andauthorizehold the write lock. Keep them pure, fast, and service-free.- One Journal handle per file. Uniqueness of
[key, op_id]and[key, sequence]is enforced by the database, but the intended deployment is one authoritative writer. - Payloads compacted before schema 3 have no canonical hash, so only those rows cannot reject a key-reordered retry.
recoveris application-driven; there is no background worker and no atomic append-and-enqueue.
Older spellings
makeJournal, makeJournalLayer, and journalMetrics are Journal.make,
Journal.layer, and Journal.metrics; documentId, opId, actorId,
sequence, and cursor are the branded .make constructors. JournalService(key)
still works, but its generic arguments are supplied again at each use site with
nothing tying them to the layer; Journal.define fixes both together. A codec
given as a function pair is accepted wherever a Schema.Codec is.
See also
- Replicated state: both halves end to end, including the exchange handler over this journal.
- Editing server data through a journal: a table as this journal's read model, edits laid over Remote's rows.
foldkit-sync: the client half;journalContract()supplies the codecs, reducer, initial state, replica binding, and compiled authorization.examples/sync: a SQLite journal, several replicas, server policy, compaction, and the effect ledger, with a test per failure.