Some checks are pending
Test, Build, and Deploy / test-build-deploy (push) Waiting to run
snapshot.sx: snapshot is a projection state {:value :seq} stored in kv under
snapshot/<name>. persist/checkpoint replays and saves; persist/replay folds
only the tail after the snapshot. Tests assert snapshot+tail == full replay
both ways + determinism. 65/65.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
41 lines
1.4 KiB
Plaintext
41 lines
1.4 KiB
Plaintext
; 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))))
|