Sync / foldkit-durable
Reading history
const { snapshot, cursor } = yield* journal.load(key) // the state, and where it is
const later = yield* journal.read(key, cursor, { limit: 500 }) // what came afterread returns at most limit operations, so a server answers a far-behind
replica in pages; Sync's exchange carries more for this. cursor(key) reads
the last sequence without decoding a snapshot, for checking a client's cursor
before anything is appended.
Sequence and Cursor are different brands on purpose: a committed
operation's position cannot be passed where a read position is expected.
Compaction and checkpoints. compact(key, through) drops committed
payloads up to through; floor(key) is the highest dropped sequence. A read
from below the floor fails with CompactedCursorError, which tells the server to
send a checkpoint, load's snapshot and cursor, instead of a misleading
partial tail. Identity rows stay, so an old retry is still recognized.
Reset and epoch. A cursor only means something within one history.
epoch(key) names it: the same while the operations are kept, new after
reset(key) or on a new database file. Hand it to clients with every answer; a
client that comes back with another epoch holds a cursor into history this
journal does not have, and has to be answered from 0. reset drops a
document's snapshot and operations but keeps replica bindings and effect
records.
Change notification. journal.subscribe is a Stream of document keys a
commit changed. It is a wake-up, not a history transport: it slides, a slow
subscriber may miss wake-ups, and a subscriber never slows or fails a commit.
Catch up with read.