; persist/snapshot — checkpoint a projection so a read model rebuilds as ; snapshot + tail instead of a full replay. A snapshot is just a projection ; state {:value :seq} stored in the kv facet under a namespaced key. The ; headline property (tested both ways): snapshot + tail == full replay. Replay ; is pure — it depends only on the stored snapshot and the log tail, never a ; clock. Requires: lib/persist/project.sx, lib/persist/kv.sx. (define persist/snapshot-key (fn (name) (str "snapshot/" name))) ; load the stored snapshot for name, or a fresh {:value seed :seq 0} if none (define persist/snapshot-load (fn (b name seed) (persist/kv-get-or b (persist/snapshot-key name) {:value seed :seq 0}))) ; store a projection state as the snapshot for name; returns the state (define persist/snapshot-save (fn (b name state) (persist/kv-put b (persist/snapshot-key name) state))) (define persist/snapshot-exists? (fn (b name) (persist/kv-has? b (persist/snapshot-key name)))) ; replay = snapshot + tail: load the snapshot then fold events after it (define persist/replay (fn (b stream name step seed) (persist/project-resume b stream step (persist/snapshot-load b name seed)))) ; replay then persist the new snapshot; returns the updated state (define persist/checkpoint (fn (b stream name step seed) (let ((state (persist/replay b stream name step seed))) (begin (persist/snapshot-save b name state) state))))