1 import Base 2 import ./change_tick.bend as Tick 3 import ./world.bend as W 4 import ./system.bend as Sys 5 import ./transaction.bend as T 6 import ./compose.bend as Q 7 import ./capture_query.bend as Fold 8 import ./ordinary_query_declaration.bend as Decl 9 import ./ordinary_system.bend as Ordinary 10 import ./ordinary_owned_event.bend as Pub 11 import ./owned_event_storage.bend as Storage 12 # Engine-private staged owner, outside the query transaction and its inverses. 13 # Ordinary gameplay sees independent abstract H (query) and J (publication). 14 type Stage is Type:Stage{newest:List

} 15 def emit(~P:Type,stage:Stage

,payload:P) -> Stage

: 16 match stage: 17 case Stage{newest}:Stage{payload <> newest} 18 def plan(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Pub.Domain,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Decl.Declaration,Nat>,Ops(Q.Frame,Nat>)>,~body:@-H:Type -> @-caps:Ops(H) -> @-J:Type -> @-emit:Pub.Write -> A -> H -> J -> H & (J & (T.Outcome & Out))) -> Q.Plan,Nat,Ops>: 19 Q.Plan{Decl.grant(~S,~Q.Frame,Nat>,~Ops(Q.Frame,Nat>),query),Decl.selector(~S,~Q.Frame,Nat>,~Ops(Q.Frame,Nat>),query)} 20 def row(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Pub.Domain,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Decl.Declaration,Nat>,Ops(Q.Frame,Nat>)>,~body:@-H:Type -> @-caps:Ops(H) -> @-J:Type -> @-emit:Pub.Write -> A -> H -> J -> H & (J & (T.Outcome & Out)),~H:Type,~caps:Ops(H),stage:Stage

,args:A,owner:H) -> H & (Stage

& (T.Outcome & Out)): 21 body(H,caps,Stage

,Pub.Write{emit(~P)},args,owner,stage) 22 def finished(~S:Data,~C:Type,~R:Type,~P:Type,~U:Data,~Out:Data,result:Fold.Executed,Nat>,Stage

,Q.Error,Out>) -> Sys.Outcome,Nat>,Unit,Pub.Reply,List<&2,Out>,P>>: 23 match result: 24 case Fold.Executed{world,Stage{newest},T.Success{},values}:Sys.Succeeded{Storage.commit_owned(~S,~C,~R,~P,world,List.reverse(&1,P,newest)),Pub.Reply{T.Success{},values,[]}} 25 case Fold.Executed{world,Stage{newest},T.Failure{error},_}:Sys.Succeeded{world,Pub.Reply{T.Failure{error},[],List.reverse(&1,P,newest)}} 26 def runner(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Pub.Domain,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Decl.Declaration,Nat>,Ops(Q.Frame,Nat>)>,~body:@-H:Type -> @-caps:Ops(H) -> @-J:Type -> @-emit:Pub.Write -> A -> H -> J -> H & (J & (T.Outcome & Out)),world:W.World,Nat>,input:A & Maybe<&2,Tick.Tick>) -> Sys.Outcome,Nat>,Unit,Pub.Reply,List<&2,Out>,P>>: 27 match input: 28 case (args,cursor):finished(~S,~C,~R,~P,~U,~Out,Fold.each_since(~S,~C,~Storage.Resources,~Nat,~Stage

,~U,~Out,~Ops,~A,~plan(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body),~row(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body),args,cursor,Stage{[]},world)) 29 def Registry(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Pub.Domain,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Decl.Declaration,Nat>,Ops(Q.Frame,Nat>)>,~body:@-H:Type -> @-caps:Ops(H) -> @-J:Type -> @-emit:Pub.Write -> A -> H -> J -> H & (J & (T.Outcome & Out))) -> Type:Sys.Registry,Nat,A & Maybe<&2,Tick.Tick>,Unit,Pub.Reply,List<&2,Out>,P>,runner(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body)> 30 def define(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Pub.Domain,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Decl.Declaration,Nat>,Ops(Q.Frame,Nat>)>,~body:@-H:Type -> @-caps:Ops(H) -> @-J:Type -> @-emit:Pub.Write -> A -> H -> J -> H & (J & (T.Outcome & Out)),world:W.World,Nat>,name:String) -> Sys.RegistrationResult,Nat,A & Maybe<&2,Tick.Tick>,Unit,Pub.Reply,List<&2,Out>,P>,runner(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body)>: 31 Sys.register(~S,~C,~Storage.Resources,~Nat,~(A & Maybe<&2,Tick.Tick>),~Unit,~Pub.Reply,List<&2,Out>,P>,~runner(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body),world,name,List.append(&2,String,Ordinary.access(~S,Decl.clauses(~S,~Q.Frame,Nat>,~Ops(Q.Frame,Nat>),query)),[Pub.access(~S,~P,identity,":write")])) 32 # Transport is closed and always succeeds. Semantic failure must not advance the 33 # ordinary query cursor; the returned receipt remains outside Sys.Failed erasure. 34 def run_observed(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Pub.Domain,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Decl.Declaration,Nat>,Ops(Q.Frame,Nat>)>,~body:@-H:Type -> @-caps:Ops(H) -> @-J:Type -> @-emit:Pub.Write -> A -> H -> J -> H & (J & (T.Outcome & Out)),world:W.World,Nat>,args:A,observed:Sys.Registry,Nat,A & Maybe<&2,Tick.Tick>,Unit,Pub.Reply,List<&2,Out>,P>,runner(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body)> & Maybe<&2,Tick.Tick>) -> Sys.RunResult,Nat,A & Maybe<&2,Tick.Tick>,Unit,Pub.Reply,List<&2,Out>,P>,runner(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body)>: 35 match observed: 36 case (registry,cursor):Sys.run(~S,~C,~Storage.Resources,~Nat,~(A & Maybe<&2,Tick.Tick>),~Unit,~Pub.Reply,List<&2,Out>,P>,~runner(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body),registry,world,(args,cursor)) 37 def run(~S:Data,~C:Type,~R:Type,~P:Type,~identity:Pub.Domain,~Ops:Type -> Type,~A:Data,~U:Data,~Out:Data,~query:Decl.Declaration,Nat>,Ops(Q.Frame,Nat>)>,~body:@-H:Type -> @-caps:Ops(H) -> @-J:Type -> @-emit:Pub.Write -> A -> H -> J -> H & (J & (T.Outcome & Out)),registry:Sys.Registry,Nat,A & Maybe<&2,Tick.Tick>,Unit,Pub.Reply,List<&2,Out>,P>,runner(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body)>,world:W.World,Nat>,args:A) -> Sys.RunResult,Nat,A & Maybe<&2,Tick.Tick>,Unit,Pub.Reply,List<&2,Out>,P>,runner(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body)>: 38 run_observed(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body,world,args,Sys.cursor(~S,~C,~Storage.Resources,~Nat,~(A & Maybe<&2,Tick.Tick>),~Unit,~Pub.Reply,List<&2,Out>,P>,~runner(~S,~C,~R,~P,~identity,~Ops,~A,~U,~Out,~query,~body),registry))