ordinary_app_relation_schedule.bend
bendvy-ecs-core@0.1.0.0 · 84 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.0/system.bend as Sys
3import bendvy-ecs-core@0.1.0.0/schedule.bend as Sch
4import bendvy-ecs-core@0.1.0.0/schedule_provision.bend as SP
5import bendvy-ecs-core@0.1.0.0/world.bend as W
6import bendvy-ecs-core@0.1.0.0/relation_commands.bend as A
7import bendvy-ecs-core@0.1.0.0/ordinary_schema.bend as Schema
8import bendvy-ecs-core@0.1.0.0/ordinary_app_relation.bend as Relation
9import bendvy-ecs-core@0.1.0.0/ordinary_app_recipe.bend as Tree
10import bendvy-ecs-core@0.1.0.0/ordinary_app_composer.bend as Build
11import bendvy-ecs-core@0.1.0.0/ordinary_app_schema.bend as App
12import bendvy-ecs-core@0.1.0.0/ordinary_app_schedule.bend as Scheduled
13import bendvy-ecs-core@0.1.0.0/ordinary_app_observation_data.bend as DTO
14import bendvy-ecs-core@0.1.0.0/ordinary_app_registration_fields.bend as Fields
15import bendvy-ecs-core@0.1.0.0/relation_failure_reader.bend as Ord
16import bendvy-ecs-core@0.1.0.0/ordinary_app_relation_system.bend as Registered
17
18# Advanced schema wrapper adapting storage/event types to the relation graph
19# World without changing entries. Raw schema/projection coherence is trusted setup.
20def graph_schema(~S:Data,~C:Type,~R:Type,schema:Schema.Schema<S,C,R>) -> Schema.Schema<S,A.Store<S,C>,R>:
21 match schema:
22 case Schema.Schema{entries}:Schema.Schema{entries}
23# Single-schedule relation App retaining actual graph World and relation registry.
24# Observation derives from the same operational relation declaration.
25def Application(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>) -> Type:
26 Scheduled.Application<S,A.Store<S,C>,R,A.Notice<S,E>,Registered.Owner(~S,~C,~R,~E,~declaration,~target),Relation.View<S>,Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S)),Registered.empty_fold(~S,~C,~R,~E,~declaration,~target)>
27# Advanced relation-view observation recipe; it owns no second graph or registry.
28def Recipe(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>) -> Type:
29 Tree.Recipe<Relation.World(~S,~C,~R,~E),Relation.View<S>,Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S))>
30def selected_phase(allowed:Bool,current:String,later:Unit -> String) -> String:
31 match allowed:
32 case True{}:current
33 case False{}:later(Unit{})
34def phase_for(steps:List<&2,Sch.Step>,+id:U32,+current:String) -> String:
35 match steps:
36 case []:""
37 case Sch.Phase{name} <> rest:phase_for(rest,id,name)
38 case Sch.Barrier{} <> rest:phase_for(rest,id,current)
39 case Sch.System{candidate,_} <> rest:
40 selected_phase(U32.is_eq(candidate,id),current,unused=>phase_for(rest,id,current))
41def described(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>,plan:SP.Plan<S>,namespace:U32,name:String,steps:List<&2,Sch.Step>,needs:List<&2,SP.Requirement<S>>,schema:Schema.Schema<S,A.Store<S,C>,R>,world:Relation.World(~S,~C,~R,~E),recipe:Recipe(~S,~C,~R,~E,~declaration,~target),debug:Bool,description:Scheduled.Description<S,Relation.View<S>>,result:Registered.Owner(~S,~C,~R,~E,~declaration,~target) & DTO.Binding<S>) -> Application(~S,~C,~R,~E,~declaration,~target) & Maybe<&2,Scheduled.Description<S,Relation.View<S>>>:
42 match description:
43 case Scheduled.Description{App.Description{schemaEntries,DTO.Product{_,observation}},ns,label,planned}:
44 match result:
45 case (owners,binding):(Scheduled.Application{App.Application{schema,Build.Registered{world,owners,recipe,debug}},plan,namespace,name,steps,needs},Some{Scheduled.Description{App.Description{schemaEntries,DTO.Product{[binding],observation}},ns,label,planned}})
46def snapshot_result(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>,result:Application(~S,~C,~R,~E,~declaration,~target) & Maybe<&2,Scheduled.Description<S,Relation.View<S>>>) -> Application(~S,~C,~R,~E,~declaration,~target) & Maybe<&2,Scheduled.Description<S,Relation.View<S>>>:
47 match result:
48 case (app,None{}):(app,None{})
49 case (Scheduled.Application{App.Application{schema,Build.Registered{world,Sys.Registry{+ns,+id,+label,+access,+cursor},recipe,debug}},plan,namespace,name,+steps,needs},Some{description}):described(~S,~C,~R,~E,~declaration,~target,plan,namespace,name,steps,needs,schema,world,recipe,debug,description,Registered.binding(~S,~C,~R,~E,~declaration,~target,Sys.Registry{ns,id,label,access,cursor},phase_for(steps,id,"")))
50# Set debug flag then derive the existing scheduled snapshot and declaration-bound
51# relation binding/phase label. Disabled bypasses observation; missing phase lookup
52# yields an empty label, not invented execution evidence. No graph commands apply.
53def snapshot(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>,app:Application(~S,~C,~R,~E,~declaration,~target),flag:Bool) -> Application(~S,~C,~R,~E,~declaration,~target) & Maybe<&2,Scheduled.Description<S,Relation.View<S>>>:
54 snapshot_result(~S,~C,~R,~E,~declaration,~target,Scheduled.snapshot(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,~Registered.Owner(~S,~C,~R,~E,~declaration,~target),~Relation.View<S>,~Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S)),~Registered.empty_fold(~S,~C,~R,~E,~declaration,~target),Scheduled.enabled(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,~Registered.Owner(~S,~C,~R,~E,~declaration,~target),~Relation.View<S>,~Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S)),~Registered.empty_fold(~S,~C,~R,~E,~declaration,~target),app,flag)))
55# Register the declaration-bound relation system on the supplied graph World.
56# Return its actual registry/World registration result; does not attach/run a plan.
57def install(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>,schema:Schema.Schema<S,C,R>,world:Relation.World(~S,~C,~R,~E),name:String) -> Sys.RegistrationResult<S,A.Store<S,C>,R,A.Notice<S,E>,Unit,Unit,Unit,Registered.reader(~S,~C,~R,~E,~declaration,~target)>:
58 Registered.register(~S,~C,~R,~E,~declaration,~target,world,name)
59def attach_allowed(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>,schema:Schema.Schema<S,C,R>,owner:Registered.Owner(~S,~C,~R,~E,~declaration,~target),name:String,plan:SP.Plan<S>,result:Relation.World(~S,~C,~R,~E) & Bool) -> Scheduled.Attachment<App.Application<S,A.Store<S,C>,R,A.Notice<S,E>,Registered.Owner(~S,~C,~R,~E,~declaration,~target),Relation.View<S>,Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S)),Registered.empty_fold(~S,~C,~R,~E,~declaration,~target)>,Application(~S,~C,~R,~E,~declaration,~target)>:
60 match result:
61 case (world,allowed):
62 match allowed:
63 case False{}:Scheduled.Invalid{App.Application{graph_schema(~S,~C,~R,schema),Build.Registered{world,owner,Tree.Recipe{},False{}}}}
64 case True{}:Scheduled.attach(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,~Registered.Owner(~S,~C,~R,~E,~declaration,~target),~Relation.View<S>,~Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S)),~Registered.empty_fold(~S,~C,~R,~E,~declaration,~target),App.Application{graph_schema(~S,~C,~R,schema),Build.Registered{world,owner,Tree.Recipe{},False{}}},name,plan)
65def attach_namespace_checked(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>,schema:Schema.Schema<S,C,R>,name:String,plan:SP.Plan<S>,allowed:Bool,owner:Registered.Owner(~S,~C,~R,~E,~declaration,~target),world:Relation.World(~S,~C,~R,~E)) -> Scheduled.Attachment<App.Application<S,A.Store<S,C>,R,A.Notice<S,E>,Registered.Owner(~S,~C,~R,~E,~declaration,~target),Relation.View<S>,Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S)),Registered.empty_fold(~S,~C,~R,~E,~declaration,~target)>,Application(~S,~C,~R,~E,~declaration,~target)>:
66 match allowed owner:
67 case False{} owner:Scheduled.Invalid{App.Application{graph_schema(~S,~C,~R,schema),Build.Registered{world,owner,Tree.Recipe{},False{}}}}
68 case True{} Sys.Registry{+namespace,+id,+label,+access,+cursor}:attach_allowed(~S,~C,~R,~E,~declaration,~target,schema,Sys.Registry{namespace,id,label,access,cursor},name,plan,W.registration_matches(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,world,id,label,access))
69def attach_namespace(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>,schema:Schema.Schema<S,C,R>,name:String,plan:SP.Plan<S>,owner:Registered.Owner(~S,~C,~R,~E,~declaration,~target),result:Relation.World(~S,~C,~R,~E) & U32) -> Scheduled.Attachment<App.Application<S,A.Store<S,C>,R,A.Notice<S,E>,Registered.Owner(~S,~C,~R,~E,~declaration,~target),Relation.View<S>,Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S)),Registered.empty_fold(~S,~C,~R,~E,~declaration,~target)>,Application(~S,~C,~R,~E,~declaration,~target)>:
70 match owner:
71 case Sys.Registry{+namespace,id,label,access,cursor}:
72 match result:
73 case (world,actual):attach_namespace_checked(~S,~C,~R,~E,~declaration,~target,schema,name,plan,U32.is_eq(namespace,actual),Sys.Registry{namespace,id,label,access,cursor},world)
74# Validate registry namespace and exact retained registration metadata before
75# attaching the supplied plan. Refusal returns the schema App with actual World
76# and owner; no system is executed. Plan/condition/provision coherence remains
77# ordinary trusted setup rather than authority inferred from a phase name.
78def attach(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>,schema:Schema.Schema<S,C,R>,owner:Registered.Owner(~S,~C,~R,~E,~declaration,~target),world:Relation.World(~S,~C,~R,~E),name:String,plan:SP.Plan<S>) -> Scheduled.Attachment<App.Application<S,A.Store<S,C>,R,A.Notice<S,E>,Registered.Owner(~S,~C,~R,~E,~declaration,~target),Relation.View<S>,Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S)),Registered.empty_fold(~S,~C,~R,~E,~declaration,~target)>,Application(~S,~C,~R,~E,~declaration,~target)>:
79 attach_namespace(~S,~C,~R,~E,~declaration,~target,schema,name,plan,owner,W.namespace(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,world))
80# Run the attached relation schedule through its registered dispatcher and supplied
81# condition/provision adapters, retaining App in every result. Pending graph work
82# applies at explicit barriers; queue admission and structural application differ.
83def run(~S:Data,~C:Type,~R:Type,~E:Data,~declaration:Ord.Declaration<S>,~target:W.Handle<S>,~condition:Relation.World(~S,~C,~R,~E) -> U32 -> Relation.World(~S,~C,~R,~E) & Bool,~provision:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & List<&2,SP.Requirement<S>>,app:Application(~S,~C,~R,~E,~declaration,~target)) -> Scheduled.RunResult<Application(~S,~C,~R,~E,~declaration,~target),S,Maybe<&2,Unit>>:
84 Scheduled.run(~S,~A.Store<S,C>,~R,~A.Notice<S,E>,~Registered.Owner(~S,~C,~R,~E,~declaration,~target),~Relation.View<S>,~Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S)),~Registered.empty_fold(~S,~C,~R,~E,~declaration,~target),~Maybe<&2,Unit>,~Registered.dispatch(~S,~C,~R,~E,~declaration,~target),~condition,~provision,app)