events.bend

bendvy-ecs-core@0.1.0.0 · 48 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.0/world.bend as W
3
4# Legacy independent affine readers for the append-only event log.
5# Registered bounded retention/lag/skip/disposal use event-runtime.bend.
6# Affine payload streams use the separate owned-event APIs.
7# Legacy independent reader for one World's append-only Data event log.
8# Owns a namespace and list offset, not a registered retention lease. Use
9# event-runtime or typed family readers for bounded retention/lag/skip/disposal.
10type Reader<S: Data> is Type:
11  Reader{namespace: U32,offset: Nat}
12# Read returns World, advanced reader and detached unread Data events;
13# ForeignReader returns World and the original reader without reading the log.
14# Neither result carries affine event payload ownership.
15type Observed<S: Data,C: Type,R: Type,E: Data> is Type:
16  Read{world: W.World<S,C,R,E>,reader: Reader<S>,events: List<&2,E>}
17  ForeignReader{world: W.World<S,C,R,E>,reader: Reader<S>}
18
19def create_join(~S: Data,~C: Type,~R: Type,~E: Data,named: W.World<S,C,R,E> & U32) -> W.World<S,C,R,E> & Reader<S>:
20  (world,namespace) = named
21  (world,Reader{namespace,0n})
22
23# Create an independent append-only reader at offset zero, returning World.
24# Existing events are initially unread. This creates no system registration or
25# bounded-retention lease; raw Reader construction remains trusted setup.
26def create(~S: Data,~C: Type,~R: Type,~E: Data,world: W.World<S,C,R,E>) -> W.World<S,C,R,E> & Reader<S>:
27  create_join(~S,~C,~R,~E,W.namespace(~S,~C,~R,~E,world))
28
29def read_events(~S: Data,~C: Type,~R: Type,~E: Data,+namespace: U32,+offset: Nat,observed: W.World<S,C,R,E> & List<&2,E>) -> Observed<S,C,R,E>:
30  (world,+events) = observed
31  Read{world,Reader{namespace,List.length(&2,E,events)},List.drop(&2,E,events,offset)}
32
33def read_checked(~S: Data,~C: Type,~R: Type,~E: Data,allowed: Bool,world: W.World<S,C,R,E>,reader: Reader<S>) -> Observed<S,C,R,E>:
34  match allowed reader:
35    case False{} reader: ForeignReader{world,reader}
36    case True{} Reader{+namespace,+offset}: read_events(~S,~C,~R,~E,namespace,offset,W.events_view(~S,~C,~R,~E,world))
37
38def read_named(~S: Data,~C: Type,~R: Type,~E: Data,named: W.World<S,C,R,E> & U32,reader: Reader<S>) -> Observed<S,C,R,E>:
39  match named reader:
40    case (world,actual) Reader{+namespace,+offset}: read_checked(~S,~C,~R,~E,U32.is_eq(actual,namespace),world,Reader{namespace,offset})
41
42# Read the unread append-only suffix and return the reader at current log
43# length, preserving event order. Namespace mismatch returns ForeignReader
44# without accessing events. No registered lifecycle cursor or stream retention
45# state is advanced. This legacy path has no lag/refusal protocol for log reset.
46# Example: examples/user-simulation/driver.bend; bounded readers: event-runtime.
47def read(~S: Data,~C: Type,~R: Type,~E: Data,world: W.World<S,C,R,E>,reader: Reader<S>) -> Observed<S,C,R,E>:
48  read_named(~S,~C,~R,~E,W.namespace(~S,~C,~R,~E,world),reader)