owned_event_runtime.bend

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

1import Base
2import bendvy-ecs-core@0.1.0.0/world.bend as W
3import bendvy-ecs-core@0.1.0.0/system.bend as Sys
4import bendvy-ecs-core@0.1.0.0/event_runtime.bend as Ev
5import bendvy-ecs-core@0.1.0.0/transaction.bend as T
6import bendvy-ecs-core@0.1.0.0/capabilities.bend as Cap
7import bendvy-ecs-core@0.1.0.0/owned_event_log.bend as Log
8import bendvy-ecs-core@0.1.0.0/owned_event_storage.bend as Storage
9import bendvy-ecs-core@0.1.0.0/ordinary_owned_event.bend as Ord
10
11# One declared reader folds its unread payloads through a confined request cap.
12# Providers are trusted schema provisioning; payload ownership stays in the log.
13type Failure<Error:Data> is Data:
14  BodyFailed{error:Error}
15  MissingPayload{}
16type Reply<Error:Data,Args:Type> is Type:
17  Reply{outcome:T.Outcome<Failure<Error>>,args:Args,lagged:Bool}
18def stopped(~S:Data,~C:Type,~R:Type,~P:Type,~Args:Type,~Error:Data,world:W.World<S,C,Storage.Resources<R,P>,Nat>,args:Args,outcome:T.Outcome<Failure<Error>>,lagged:Bool) -> W.World<S,C,Storage.Resources<R,P>,Nat> & Reply<Error,Args>:
19  (world,Reply{outcome,args,lagged})
20def visited(~S:Data,~C:Type,~R:Type,~P:Type,~Args:Type,~Error:Data,lagged:Bool,next:W.World<S,C,Storage.Resources<R,P>,Nat> -> Args -> W.World<S,C,Storage.Resources<R,P>,Nat> & Reply<Error,Args>,result:W.World<S,C,Storage.Resources<R,P>,Nat> & Log.ReadResult<Args,T.Outcome<Error> & Args>) -> W.World<S,C,Storage.Resources<R,P>,Nat> & Reply<Error,Args>:
21  match result:
22    case (world,Log.Missing{args}):stopped(~S,~C,~R,~P,~Args,~Error,world,args,T.Failure{MissingPayload{}},lagged)
23    case (world,Log.Found{(T.Failure{error},args)}):stopped(~S,~C,~R,~P,~Args,~Error,world,args,T.Failure{BodyFailed{error}},lagged)
24    case (world,Log.Found{(T.Success{},args)}):next(world,args)
25def fold_rows(~S:Data,~C:Type,~R:Type,~P:Type,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~identity:Ord.Domain<S,P>,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request<H,Request,Projection> -> H -> Args -> H & (T.Outcome<Error> & Args),keys:List<&2,Nat>,world:W.World<S,C,Storage.Resources<R,P>,Nat>,args:Args,+lagged:Bool) -> W.World<S,C,Storage.Resources<R,P>,Nat> & Reply<Error,Args>:
26  match keys:
27    case []:stopped(~S,~C,~R,~P,~Args,~Error,world,args,T.Success{},lagged)
28    case key <> remaining:visited(~S,~C,~R,~P,~Args,~Error,lagged,nextWorld => nextArgs => fold_rows(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body,remaining,nextWorld,nextArgs,lagged),Storage.read(~S,~C,~R,~P,~Request,~Projection,~Args,~(T.Outcome<Error> & Args),~at,~body,world,key,args))
29def transported(~S:Data,~C:Type,~R:Type,~P:Type,~Args:Type,~Error:Data,result:W.World<S,C,Storage.Resources<R,P>,Nat> & Reply<Error,Args>) -> Sys.Outcome<W.World<S,C,Storage.Resources<R,P>,Nat>,Unit,Reply<Error,Args>>:
30  match result:
31    case (world,reply):Sys.Succeeded{world,reply}
32def runner(~S:Data,~C:Type,~R:Type,~P:Type,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~identity:Ord.Domain<S,P>,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request<H,Request,Projection> -> H -> Args -> H & (T.Outcome<Error> & Args),world:W.World<S,C,Storage.Resources<R,P>,Nat>,input:Ev.Input<Nat,Args>) -> Sys.Outcome<W.World<S,C,Storage.Resources<R,P>,Nat>,Unit,Reply<Error,Args>>:
33  match input:
34    case Ev.Input{keys,lagged,args}:transported(~S,~C,~R,~P,~Args,~Error,fold_rows(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body,keys,world,args,lagged))
35def Registry(~S:Data,~C:Type,~R:Type,~P:Type,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~identity:Ord.Domain<S,P>,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request<H,Request,Projection> -> H -> Args -> H & (T.Outcome<Error> & Args)) -> Type:Sys.Registry<S,C,Storage.Resources<R,P>,Nat,Ev.Input<Nat,Args>,Unit,Reply<Error,Args>,runner(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body)>
36def define(~S:Data,~C:Type,~R:Type,~P:Type,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~identity:Ord.Domain<S,P>,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request<H,Request,Projection> -> H -> Args -> H & (T.Outcome<Error> & Args),runtime:Ev.Runtime<S,C,Storage.Resources<R,P>,Nat>,name:String) -> Ev.Registered<S,C,Storage.Resources<R,P>,Nat,Args,Unit,Reply<Error,Args>,runner(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body)>:
37  Ev.register(~S,~C,~Storage.Resources<R,P>,~Nat,~Args,~Unit,~Reply<Error,Args>,~runner(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body),runtime,name,[Ord.access(~S,~P,identity,":read")])
38# Ev.run performs the existing namespace + registration checks and lazy activation.
39# The closed runner transports semantic failure separately so affine output is
40# returned. Restore exactly Ev.run_outcome's failed-reader position afterward.
41def failed_positions(~S:Data,~C:Type,~R:Type,~P:Type,old:List<&2,Ev.Position>,id:U32,runtime:Ev.Runtime<S,C,Storage.Resources<R,P>,Nat>) -> Ev.Runtime<S,C,Storage.Resources<R,P>,Nat>:
42  match runtime:
43    case Ev.Runtime{world,namespace,batches,_,nextReader,+tick,frameStart,boundary,capacity,dropped}:
44      Ev.Runtime{world,namespace,batches,Ev.activate(old,id,Nat.sub(tick,1n)),nextReader,tick,frameStart,boundary,capacity,dropped}
45def reconciled(~S:Data,~C:Type,~R:Type,~P:Type,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~identity:Ord.Domain<S,P>,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request<H,Request,Projection> -> H -> Args -> H & (T.Outcome<Error> & Args),old:List<&2,Ev.Position>,id:U32,result:Ev.RunResult<S,C,Storage.Resources<R,P>,Nat,Args,Unit,Reply<Error,Args>,runner(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body)>) -> Ev.RunResult<S,C,Storage.Resources<R,P>,Nat,Args,Unit,Reply<Error,Args>,runner(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body)>:
46  match result:
47    case Ev.Ran{runtime,reader,registry,Ev.Succeeded{Reply{T.Failure{error},args,lagged}}}:
48      Ev.Ran{failed_positions(~S,~C,~R,~P,old,id,runtime),reader,registry,Ev.Succeeded{Reply{T.Failure{error},args,lagged}}}
49    case result:result
50
51def run(~S:Data,~C:Type,~R:Type,~P:Type,~Request:Type,~Projection:Data,~Args:Type,~Error:Data,~identity:Ord.Domain<S,P>,~at:P -> Request -> P & Projection,~body:@-H:Type -> @-read:Cap.Request<H,Request,Projection> -> H -> Args -> H & (T.Outcome<Error> & Args),runtime:Ev.Runtime<S,C,Storage.Resources<R,P>,Nat>,reader:Ev.Reader<S>,registry:Sys.Registry<S,C,Storage.Resources<R,P>,Nat,Ev.Input<Nat,Args>,Unit,Reply<Error,Args>,runner(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body)>,args:Args) -> Ev.RunResult<S,C,Storage.Resources<R,P>,Nat,Args,Unit,Reply<Error,Args>,runner(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body)>:
52  match runtime reader:
53    case Ev.Runtime{world,namespace,batches,+positions,nextReader,tick,frameStart,boundary,capacity,dropped} Ev.Reader{readerNamespace,+id,registryId}:
54      reconciled(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body,positions,id,Ev.run(~S,~C,~Storage.Resources<R,P>,~Nat,~Args,~Unit,~Reply<Error,Args>,~runner(~S,~C,~R,~P,~Request,~Projection,~Args,~Error,~identity,~at,~body),Ev.Runtime{world,namespace,batches,positions,nextReader,tick,frameStart,boundary,capacity,dropped},Ev.Reader{readerNamespace,id,registryId},registry,args))