1 import Base 2 import ./change_tick.bend as Tick 3 import ./ordinary_app_hierarchy.bend as App 4 import ./ordinary_app_relation.bend as Relation 5 import ./ordinary_app_composer.bend as Build 6 import ./ordinary_app_observation_data.bend as DTO 7 import ./ordinary_app_registration_fields.bend as Fields 8 import ./relation_types.bend as G 9 import ./relation_commands.bend as A 10 import ./hierarchy_traversal_provider.bend as H 11 import ./hierarchy_provider.bend as Path 12 import ./hierarchy_traversal.bend as Traversal 13 import ./ordinary_query_declaration.bend as Query 14 import ./ordinary_system.bend as System 15 import ./compose.bend as Q 16 import ./transaction.bend as Tx 17 import ./world.bend as W 18 19 # Query membership requires a live handle independently of its declaration. 20 # Preserve the raw traversal path; this only chooses the query invocation list. 21 def live_prepend(~S:Data,~C:Type,~R:Type,~E:Data,selected:Bool,handle:W.Handle,observed:Relation.World(~S,~C,~R,~E) & List<&2,W.Handle>) -> Relation.World(~S,~C,~R,~E) & List<&2,W.Handle>: 22 match selected observed: 23 case True{} Tuple{world,handles}:(world,handle <> handles) 24 case False{} Tuple{world,handles}:(world,handles) 25 def live_checked(~S:Data,~C:Type,~R:Type,~E:Data,handle:W.Handle,observed:Relation.World(~S,~C,~R,~E) & Bool,next:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & List<&2,W.Handle>) -> Relation.World(~S,~C,~R,~E) & List<&2,W.Handle>: 26 match observed: 27 case (world,selected):live_prepend(~S,~C,~R,~E,selected,handle,next(world)) 28 def live_handles(~S:Data,~C:Type,~R:Type,~E:Data,handles:List<&2,W.Handle>,world:Relation.World(~S,~C,~R,~E)) -> Relation.World(~S,~C,~R,~E) & List<&2,W.Handle>: 29 match handles: 30 case []:(world,[]) 31 case +handle <> rest:live_checked(~S,~C,~R,~E,handle,W.valid(~S,~A.Store,~R,~A.Notice,world,handle),world => live_handles(~S,~C,~R,~E,rest,world)) 32 33 # Keep the hierarchy diagnostic and existing composition result separately. 34 # The gameplay callback receives only the retained declaration's opaque owner. 35 def executed(~S:Data,~C:Type,~R:Type,~E:Data,~U:Data,~Out:Data,path:Maybe<&2,Path.Path>,result:Q.Executed,Out>) -> Relation.World(~S,~C,~R,~E) & DTO.Product>,Maybe<&2,DTO.Product>,List<&2,Out>>>>: 36 match result: 37 case Q.Executed{world,outcome,values}:(world,DTO.Product{path,Some{DTO.Product{outcome,values}}}) 38 def complete_live(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Arg:Data,~U:Data,~Out:Data,~query:Query.Declaration,R,A.Notice>,Ops(Q.Frame,R,A.Notice>)>,~body:@-H:Type -> @-caps:Ops(H) -> Arg -> H -> H & (Tx.Outcome & Out),path:Maybe<&2,Path.Path>,args:Arg,cursor:Maybe<&2,Tick.Tick>,observed:Relation.World(~S,~C,~R,~E) & List<&2,W.Handle>) -> Relation.World(~S,~C,~R,~E) & DTO.Product>,Maybe<&2,DTO.Product>,List<&2,Out>>>>: 39 executed(~S,~C,~R,~E,~U,~Out,path,Q.reserved(~S,~A.Store,~R,~A.Notice,~Ops,~Arg,~U,~Out,~System.plan(~S,~A.Store,~R,~A.Notice,~Ops,~Arg,~U,~Out,~query,~body),~body,args,cursor,observed)) 40 def selected_path(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Arg:Data,~U:Data,~Out:Data,~query:Query.Declaration,R,A.Notice>,Ops(Q.Frame,R,A.Notice>)>,~body:@-H:Type -> @-caps:Ops(H) -> Arg -> H -> H & (Tx.Outcome & Out),args:Arg,cursor:Maybe<&2,Tick.Tick>,observed:Relation.World(~S,~C,~R,~E) & Maybe<&2,Path.Path>) -> Relation.World(~S,~C,~R,~E) & DTO.Product>,Maybe<&2,DTO.Product>,List<&2,Out>>>>: 41 match observed: 42 case (world,None{}):(world,DTO.Product{None{},None{}}) 43 case (world,Some{Path.Incomplete{handles,pending}}):(world,DTO.Product{Some{Path.Incomplete{handles,pending}},None{}}) 44 case (world,Some{Path.Complete{+handles}}):complete_live(~S,~C,~R,~E,~Ops,~Arg,~U,~Out,~query,~body,Some{Path.Complete{handles}},args,cursor,live_handles(~S,~C,~R,~E,handles,world)) 45 # Run a declared query over a complete descendant traversal and return the App. 46 # Invalid target yields (None, None); incomplete traversal retains its diagnostic 47 # but returns no execution result and invokes no partial gameplay callbacks. 48 # For a complete path, revalidate each handle, retain live members in traversal 49 # order, then apply the declaration's selectors and opaque-owner body. Preserve 50 # the original raw path separately from the execution outcome and output list. 51 # Transaction failure rolls back through ordinary query semantics and clears row 52 # outputs. args and cursor are supplied for this invocation; this does not register 53 # or advance an App reader. Structural commands still require an explicit barrier. 54 # Uses only declared capabilities; it does not widen authority to arbitrary graph 55 # access. See docs/parity/hierarchy.md, ordinary App descendant-query scenarios. 56 def visit_descendants_app(~S:Data,~C:Type,~R:Type,~E:Data,~hierarchy:G.HierarchyDescriptor,~Owners:Type,~Rows:Data,~prior:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~Ops:Type -> Type,~Arg:Data,~U:Data,~Out:Data,~query:Query.Declaration,R,A.Notice>,Ops(Q.Frame,R,A.Notice>)>,~body:@-H:Type -> @-caps:Ops(H) -> Arg -> H -> H & (Tx.Outcome & Out),app:App.Application(~S,~C,~R,~E,~hierarchy,~Owners,~Rows,~prior,~fold),target:W.Handle,order:Traversal.Order,args:Arg,cursor:Maybe<&2,Tick.Tick>) -> App.Application(~S,~C,~R,~E,~hierarchy,~Owners,~Rows,~prior,~fold) & DTO.Product>,Maybe<&2,DTO.Product>,List<&2,Out>>>>: 57 match app: 58 case Build.Registered{world,owners,recipe,debug}:App.returned(~S,~C,~R,~E,~hierarchy,~Owners,~Rows,~prior,~fold,~DTO.Product>,Maybe<&2,DTO.Product>,List<&2,Out>>>>,owners,recipe,debug,selected_path(~S,~C,~R,~E,~Ops,~Arg,~U,~Out,~query,~body,args,cursor,H.lookup_descendants(~S,~C,~R,~E,~hierarchy,world,H.Descendants{target,order})))