Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m9s
project.sx: projection state {:value :seq}; persist/project folds the whole
stream, persist/project-resume folds only the tail so read models update
incrementally. Pure step (value event)->value. 37/37.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
31 lines
1.2 KiB
Plaintext
31 lines
1.2 KiB
Plaintext
; persist/project — a projection folds a stream's events into a read model.
|
|
; A projection state is {:value v :seq s} where s is the last seq folded in,
|
|
; so a projection can resume incrementally from where it left off (replay only
|
|
; the tail). step : (value event) -> value. Determinism: step must be pure —
|
|
; time lives on the event (event-at), never a clock here.
|
|
; Requires: lib/persist/event.sx, lib/persist/log.sx.
|
|
|
|
; fold the tail (events with seq > prior's seq) onto a prior projection state
|
|
(define
|
|
persist/project-resume
|
|
(fn
|
|
(b stream step prior)
|
|
(let
|
|
((tail (persist/read-from b stream (+ 1 (get prior :seq)))))
|
|
(reduce (fn (acc e) {:value (step (get acc :value) e) :seq (persist/event-seq e)}) prior tail))))
|
|
|
|
; project the whole stream from seed
|
|
(define
|
|
persist/project
|
|
(fn (b stream step seed) (persist/project-resume b stream step {:value seed :seq 0})))
|
|
|
|
(define persist/project-value (fn (p) (get p :value)))
|
|
(define persist/project-seq (fn (p) (get p :seq)))
|
|
|
|
; convenience: project and return just the value
|
|
(define
|
|
persist/project-fold
|
|
(fn
|
|
(b stream step seed)
|
|
(persist/project-value (persist/project b stream step seed))))
|