1 import Base 2 import ./change_tick.bend as Tick 3 import ./decode_frame.bend as F 4 import ./decode_requests.bend as Request 5 import ./compose.bend as Query 6 import ./world.bend as World 7 import ./transaction.bend as T 8 import ./capabilities.bend as Cap 9 import ./decode_data.bend as D 10 import ./ordinary_declaration.bend as Identity 11 12 # Trusted traversal kernel. A is an explicit application-owned state threaded 13 # once across selected rows; the Local adapter retains it on system failure. 14 # Data row observations stay commit-only. This is not a new captures policy. 15 def completed(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Q:Type,~A:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~identity:Identity.Declaration,~project:P -> P & D.Raw,next:F.Frame -> A -> List<&2,Out> -> F.Frame & (A & (T.Outcome> & List<&2,Out>)),frame:F.Frame,state:A,values:List<&2,Out>,result:T.Outcome>) -> F.Frame & (A & (T.Outcome> & List<&2,Out>)): 16 match result: 17 case T.Failure{error}:(frame,(state,(T.Failure{error},[]))) 18 case T.Success{}:next(frame,state,values) 19 20 def returned(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Q:Type,~A:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~identity:Identity.Declaration,~project:P -> P & D.Raw,next:F.Frame -> A -> List<&2,Out> -> F.Frame & (A & (T.Outcome> & List<&2,Out>)),values:List<&2,Out>,observed:F.Frame & (A & (T.Outcome & Out))) -> F.Frame & (A & (T.Outcome> & List<&2,Out>)): 21 match observed: 22 case (F.Frame{owner,handle,+error,cursor,receipts,pending},(state,(outcome,value))):completed(~S,~C,~R,~E,~P,~Q,~A,~U,~Out,~Ops,~identity,~project,next,F.Frame{owner,handle,error,cursor,receipts,pending},state,value <> values,Query.outcome(~U,error,outcome)) 23 24 def selected(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Q:Type,~A:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~identity:Identity.Declaration,~project:P -> P & D.Raw,~grants:Ops(F.Frame),~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (A & (T.Outcome & Out)),next:F.Frame -> A -> List<&2,Out> -> F.Frame & (A & (T.Outcome> & List<&2,Out>)),state:A,values:List<&2,Out>,observed:F.Frame & Bool) -> F.Frame & (A & (T.Outcome> & List<&2,Out>)): 25 match observed: 26 case (frame,False{}):next(frame,state,values) 27 case (frame,True{}):returned(~S,~C,~R,~E,~P,~Q,~A,~U,~Out,~Ops,~identity,~project,next,values,Cap.invoke_owned(~Ops,~A,~(A & (T.Outcome & Out)),~body,~F.Frame,~grants,state,frame)) 28 29 def at_handle(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Q:Type,~identity:Identity.Declaration,~project:P -> P & D.Raw,frame:F.Frame,handle:World.Handle,cursor:Maybe<&2,Tick.Tick>) -> F.Frame: 30 match frame: 31 case F.Frame{owner,_,_,_,receipts,pending}:F.Frame{owner,handle,None{},cursor,receipts,pending} 32 33 def run_rows(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Q:Type,~A:Type,~U:Data,~Out:Data,~Ops:Type -> Type,~identity:Identity.Declaration,~project:P -> P & D.Raw,~selector:F.Frame -> F.Frame & Bool,~grants:Ops(F.Frame),~body:@-H:Type -> @-caps:Ops(H) -> A -> H -> H & (A & (T.Outcome & Out)),handles:List<&2,World.Handle>,+cursor:Maybe<&2,Tick.Tick>,frame:F.Frame,state:A,values:List<&2,Out>) -> F.Frame & (A & (T.Outcome> & List<&2,Out>)): 34 match handles: 35 case []:(frame,(state,(T.Success{},List.reverse(&2,Out,values)))) 36 case handle <> rest:selected(~S,~C,~R,~E,~P,~Q,~A,~U,~Out,~Ops,~identity,~project,~grants,~body,(frame => state => values => run_rows(~S,~C,~R,~E,~P,~Q,~A,~U,~Out,~Ops,~identity,~project,~selector,~grants,~body,rest,cursor,frame,state,values)),state,values,selector(at_handle(~S,~C,~R,~E,~P,~Q,~identity,~project,frame,handle,cursor)))