; persist/query — read-side helpers over a stream: slice by seq range, filter by ; timestamp / type / predicate. Pure reads composed from persist/read, no ; backend changes. The log is bad at ad-hoc relational queries (project into a ; kv read model for those) but these cover the common log scans: an audit window ; by time, a type filter, a since-cursor for incremental consumers. ; Requires: lib/persist/log.sx. ; events with seq in [from, to] inclusive (define persist/read-between (fn (b stream from to) (filter (fn (e) (and (>= (persist/event-seq e) from) (<= (persist/event-seq e) to))) (persist/read b stream)))) ; events at or after a timestamp (events carry :at; never a clock here) (define persist/read-since (fn (b stream at) (filter (fn (e) (>= (persist/event-at e) at)) (persist/read b stream)))) ; events whose :at is in [from, to] inclusive — an audit window (define persist/read-window (fn (b stream from to) (filter (fn (e) (and (>= (persist/event-at e) from) (<= (persist/event-at e) to))) (persist/read b stream)))) ; events matching a predicate (e -> truthy) (define persist/read-where (fn (b stream pred) (filter pred (persist/read b stream)))) ; events of a given type (define persist/read-by-type (fn (b stream type) (filter (fn (e) (equal? (persist/event-type e) type)) (persist/read b stream)))) ; count events matching a predicate (define persist/count-where (fn (b stream pred) (len (persist/read-where b stream pred))))