ordinary_owned_event.bend

bendvy-ecs-core@0.1.0.1 · 78 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/transaction.bend as T
5import bendvy-ecs-core@0.1.0.1/commands.bend as Cmd
6import bendvy-ecs-core@0.1.0.1/owned_event_storage.bend as Storage
7
8# Ordinary identity derives publication metadata and the confined grant.
9# Raw Frame and runner constructors are trusted engine administration.
10# Schema/payload-indexed owned event name. Contains no live log or payload;
11# raw names alone do not confer runtime publication or read authority.
12type Domain<-S:Data,-P:Type> is Data:
13  Domain{key:String}
14# Declare a domain for arbitrary affine Type payload P without creating
15# log storage, publishing a payload or allocating a reader.
16def domain(~S:Data,~P:Type,key:String) -> Domain<S,P>:Domain{key}
17# Return the authored event domain key without accessing a log or payload.
18def name(~S:Data,~P:Type,domain:Domain<S,P>) -> String:
19  match domain:
20    case Domain{key}:key
21# Return authored domain name plus suffix for registration metadata.
22# This string does not replace the typed grant or runtime World checks.
23def access(~S:Data,~P:Type,domain:Domain<S,P>,suffix:String) -> String:
24  match domain:
25    case Domain{key}:String.concat([key,suffix])
26# Trusted single-domain engine stage owning transaction and unpublished
27# payloads. Gameplay receives abstract H through Write, not this raw constructor.
28type Frame<World:Type,P:Type> is Type:
29  Frame{tx:T.Tx<World,Nat>,newest:List<P>}
30# Nominal publication grant consuming P and returning opaque H. It exposes
31# no live payload alias; bound operation defines staging/commit/abort behavior.
32type Write<-S:Data,-P:Type,-identity:Domain<S,P>,-H:Type> is Type:
33  Write{emit:H -> P -> H}
34# Advanced projection extracting the closed emission operation. Does not
35# publish, validate a World or transfer any payload by itself.
36def emit_field(~S:Data,~P:Type,~identity:Domain<S,P>,~H:Type,grant:Write<S,P,identity,H>) -> H -> P -> H:
37  match grant:
38    case Write{emit}:emit
39# Consume an affine payload through its typed domain grant and return H.
40# Canonical staged grants retain payload until commit or abort recovery; this
41# helper itself adds no admission result or arbitrary mutation recovery.
42def emit(~S:Data,~P:Type,~identity:Domain<S,P>,~H:Type,~grant:Write<S,P,identity,H>,owner:H,payload:P) -> H:
43  emit_field(~S,~P,~identity,~H,grant)(owner,payload)
44def staged(~World:Type,~P:Type,owner:Frame<World,P>,payload:P) -> Frame<World,P>:
45  match owner:
46    case Frame{tx,newest}:Frame{tx,payload <> newest}
47# Single-domain publication reply retaining body output and staged payload
48# recovery. Failure returns available staged owners in emission order; success
49# commits them and returns an empty recovery list. Inspect the inner outcome.
50type Reply<Error:Data,Out:Type,P:Type> is Type:
51  Reply{outcome:T.Outcome<Error>,output:Out,recovered:List<P>}
52# Only available independently staged owners are recovered, after ECS rollback.
53def finished(~S:Data,~C:Type,~R:Type,~P:Type,~Error:Data,~Out:Type,newest:List<P>,output:Out,result:T.Returned<W.World<S,C,Storage.Resources<R,P>,Nat>,Error>) -> Sys.Outcome<W.World<S,C,Storage.Resources<R,P>,Nat>,Unit,Reply<Error,Out,P>>:
54  match result:
55    case T.Returned{world,T.Success{}}:Sys.Succeeded{Storage.commit_owned(~S,~C,~R,~P,world,List.reverse(&1,P,newest)),Reply{T.Success{},output,[]}}
56    case T.Returned{world,T.Failure{error}}:Sys.Succeeded{world,Reply{T.Failure{error},output,List.reverse(&1,P,newest)}}
57def returned(~S:Data,~C:Type,~R:Type,~P:Type,~Error:Data,~Out:Type,result:Frame<W.World<S,C,Storage.Resources<R,P>,Nat>,P> & (T.Outcome<Error> & Out)) -> Sys.Outcome<W.World<S,C,Storage.Resources<R,P>,Nat>,Unit,Reply<Error,Out,P>>:
58  match result:
59    case (Frame{tx,newest},(outcome,output)):finished(~S,~C,~R,~P,~Error,~Out,newest,output,T.finish(~W.World<S,C,Storage.Resources<R,P>,Nat>,~Nat,~Error,~Cmd.enqueue(~S,~C,~Storage.Resources<R,P>,~Nat),~Cmd.publish(~S,~C,~Storage.Resources<R,P>,~Nat),tx,outcome))
60# Advanced single-domain publisher body with opaque staged-owner grant.
61# Runs once, including an empty World. Body failure rolls back recorded ECS
62# changes and recovers separately staged payloads, not arbitrary consumed data.
63def runner(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Domain<S,P>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-grant:Write<S,P,identity,H> -> Args -> H -> H & (T.Outcome<Error> & Out),world:W.World<S,C,Storage.Resources<R,P>,Nat>,args:Args) -> Sys.Outcome<W.World<S,C,Storage.Resources<R,P>,Nat>,Unit,Reply<Error,Out,P>>:
64  returned(~S,~C,~R,~P,~Error,~Out,body(Frame<W.World<S,C,Storage.Resources<R,P>,Nat>,P>,Write{staged(~W.World<S,C,Storage.Resources<R,P>,Nat>,~P)},args,Frame{T.begin(~W.World<S,C,Storage.Resources<R,P>,Nat>,~Nat,world),[]}))
65# Advanced closed publisher registration type. Runtime namespace/live
66# metadata checks still occur through run; this alias owns no registration.
67def Registry(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Domain<S,P>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-grant:Write<S,P,identity,H> -> Args -> H -> H & (T.Outcome<Error> & Out)) -> Type:
68  Sys.Registry<S,C,Storage.Resources<R,P>,Nat,Args,Unit,Reply<Error,Out,P>,runner(~S,~C,~R,~P,~identity,~Args,~Error,~Out,~body)>
69# Register the single-domain publisher with declaration-derived write
70# metadata. Retains World on registration failure and invokes no body here.
71def define(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Domain<S,P>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-grant:Write<S,P,identity,H> -> Args -> H -> H & (T.Outcome<Error> & Out),world:W.World<S,C,Storage.Resources<R,P>,Nat>,name:String) -> Sys.RegistrationResult<S,C,Storage.Resources<R,P>,Nat,Args,Unit,Reply<Error,Out,P>,runner(~S,~C,~R,~P,~identity,~Args,~Error,~Out,~body)>:
72  Sys.register(~S,~C,~Storage.Resources<R,P>,~Nat,~Args,~Unit,~Reply<Error,Out,P>,~runner(~S,~C,~R,~P,~identity,~Args,~Error,~Out,~body),world,name,[access(~S,~P,identity,":write")])
73# Run the checked single-domain publisher. Admission refusal returns original
74# Args/Registry/World; completed execution returns outer Succeeded with Reply
75# carrying the actual body outcome and available staged payload recovery.
76# This distinguishes safe recovery from an outer failure that discards Out.
77def run(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Domain<S,P>,~Args:Type,~Error:Data,~Out:Type,~body:@-H:Type -> @-grant:Write<S,P,identity,H> -> Args -> H -> H & (T.Outcome<Error> & Out),registry:Sys.Registry<S,C,Storage.Resources<R,P>,Nat,Args,Unit,Reply<Error,Out,P>,runner(~S,~C,~R,~P,~identity,~Args,~Error,~Out,~body)>,world:W.World<S,C,Storage.Resources<R,P>,Nat>,args:Args) -> Sys.RunResult<S,C,Storage.Resources<R,P>,Nat,Args,Unit,Reply<Error,Out,P>,runner(~S,~C,~R,~P,~identity,~Args,~Error,~Out,~body)>:
78  Sys.run(~S,~C,~Storage.Resources<R,P>,~Nat,~Args,~Unit,~Reply<Error,Out,P>,~runner(~S,~C,~R,~P,~identity,~Args,~Error,~Out,~body),registry,world,args)