ordinary_event_declaration.bend

bendvy-ecs-core@0.1.0.1 · 76 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.1/world.bend as W
3import bendvy-ecs-core@0.1.0.1/system.bend as Sys
4import bendvy-ecs-core@0.1.0.1/event_runtime.bend as Ev
5
6# The ordinary typed event domain is supplied once to grants and registration.
7# Schema-scoped name for one Data event stream. Owns no stream, payload
8# or cursor; use the same declaration for typed grants and registration.
9# For affine Type events use the owned-event APIs, not this Data-only domain.
10# Full typed-family contract: docs/parity/typed-data-events.md.
11type Domain<S:Data,E:Data> is Data:
12  Domain{key:String}
13# Requested event access: Read observes a stream; Write publishes to it.
14# A write declaration does not implicitly confer read access.
15type Mode is Data:
16  Read{}
17  Write{}
18# Event domain and requested read/write mode used for registration metadata.
19# This Data declaration owns no reader and does not itself publish or retain events.
20type Declaration<S:Data,E:Data> is Data:
21  Declaration{domain:Domain<S,E>,mode:Mode}
22# Name a Data event domain in schema S. Does not create storage, register a
23# reader or validate collisions; typed family setup supplies stream routing.
24# Example: Event.write(~S,~E,Event.domain(~S,~E,"hit")); see
25# test-fixtures/connected-performance/failedtxn-health64/consumer/health-access.bend.
26def domain(~S:Data,~E:Data,key:String) -> Domain<S,E>:Domain{key}
27# Declare read access to this Data stream without allocating a cursor.
28# Register a reader to obtain independent visibility and retention ownership.
29def read(~S:Data,~E:Data,domain:Domain<S,E>) -> Declaration<S,E>:Declaration{domain,Read{}}
30# Declare publication access to this Data stream without publishing an event.
31# Visibility and rollback follow the enclosing publication/transaction path.
32def write(~S:Data,~E:Data,domain:Domain<S,E>) -> Declaration<S,E>:Declaration{domain,Write{}}
33# Return the domain key suffixed with :read or :write for registration metadata.
34# This string does not grant access or identify an actual runtime world.
35def access(~S:Data,~E:Data,declaration:Declaration<S,E>) -> String:
36  match declaration:
37    case Declaration{Domain{key},Read{}}:String.concat([key,":read"])
38    case Declaration{Domain{key},Write{}}:String.concat([key,":write"])
39# Select a typed read grant: Some only for Read, None for Write.
40# observe is trusted owner-threading setup; constructing a grant invokes no
41# reader and does not advance a cursor or inspect a stream.
42def reading(~S:Data,~E:Data,~H:Type,~observe:H -> H & Ev.Reading<E>,declaration:Declaration<S,E>) -> Maybe<&2,Ev.ReadAccess<H,E,observe>>:
43  match declaration:
44    case Declaration{_,Read{}}:Some{Ev.ReadAccess{}}
45    case Declaration{_,Write{}}:None{}
46# Select a typed publication grant: Some only for Write, None for Read.
47# publish is a trusted owner-threading operation; the declaration does not
48# make arbitrary callback effects transactional or execute publication here.
49def publishing(~S:Data,~E:Data,~H:Type,~publish:H -> E -> H,declaration:Declaration<S,E>) -> Maybe<&2,Ev.WriteAccess<H,E,publish>>:
50  match declaration:
51    case Declaration{_,Write{}}:Some{Ev.WriteAccess{}}
52    case Declaration{_,Read{}}:None{}
53# Register a reader with declaration-derived access metadata and an independent
54# stream cursor. A Write declaration returns RegisterFailed with runtime retained;
55# ordinary registration refusal also retains runtime. Success returns runtime,
56# reader and registry owners; no body executes while registering.
57def register_reader(~S:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~O:Type,~runner:W.World<S,C,R,E> -> Ev.Input<E,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,O>,runtime:Ev.Runtime<S,C,R,E>,+declaration:Declaration<S,E>,name:String) -> Ev.Registered<S,C,R,E,A,Error,O,runner>:
58  match declaration:
59    case Declaration{_,Write{}}:Ev.RegisterFailed{runtime}
60    case Declaration{+domain,Read{}}:Ev.register(~S,~C,~R,~E,~A,~Error,~O,~runner,runtime,name,[access(~S,~E,Declaration{domain,Read{}})])
61# Register a publishing system using declaration-derived access metadata.
62# A Read declaration returns RegistrationFailed with world retained; successful
63# registration returns the world and registry. No event is sent by registration.
64def register_writer(~S:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~O:Type,~runner:W.World<S,C,R,E> -> A -> Sys.Outcome<W.World<S,C,R,E>,Error,O>,world:W.World<S,C,R,E>,+declaration:Declaration<S,E>,name:String) -> Sys.RegistrationResult<S,C,R,E,A,Error,O,runner>:
65  match declaration:
66    case Declaration{_,Read{}}:Sys.RegistrationFailed{world}
67    case Declaration{+domain,Write{}}:Sys.register(~S,~C,~R,~E,~A,~Error,~O,~runner,world,name,[access(~S,~E,Declaration{domain,Write{}})])
68
69# Trusted setup constructor for a closed read operation indexed by observe.
70# Accepts a domain without mode validation; prefer reading when checking a
71# Declaration. Runtime world/reader checks belong to the supplied operation.
72def read_grant(~S:Data,~E:Data,~H:Type,~observe:H -> H & Ev.Reading<E>,_:Domain<S,E>) -> Ev.ReadAccess<H,E,observe>:Ev.ReadAccess{}
73# Trusted setup constructor for a closed publication operation indexed by
74# publish. Accepts a domain without checking a Declaration mode. Runtime
75# authority and rollback are properties of the supplied operation, not this token.
76def write_grant(~S:Data,~E:Data,~H:Type,~publish:H -> E -> H,_:Domain<S,E>) -> Ev.WriteAccess<H,E,publish>:Ev.WriteAccess{}