ordinary_app_schedules.bend
bendvy-ecs-core@0.1.0.4 · 160 lines · 31 definitions
1import Base
2import bendvy-ecs-core@0.1.0.4/ordinary_app_access.bend as Access
3import bendvy-ecs-core@0.1.0.4/ordinary_app_schedule_access.bend as SelectedAccess
4import bendvy-ecs-core@0.1.0.4/ordinary_schema.bend as Schema
5import bendvy-ecs-core@0.1.0.4/ordinary_app_recipe.bend as Tree
6import bendvy-ecs-core@0.1.0.4/ordinary_app_schema.bend as App
7import bendvy-ecs-core@0.1.0.4/ordinary_app_composer.bend as Build
8import bendvy-ecs-core@0.1.0.4/ordinary_app_registration_fields.bend as Records
9import bendvy-ecs-core@0.1.0.4/ordinary_app_observation_data.bend as DTO
10import bendvy-ecs-core@0.1.0.4/ordinary_app_schedule.bend as Single
11import bendvy-ecs-core@0.1.0.4/ordinary_app_schedule_description.bend as Detail
12import bendvy-ecs-core@0.1.0.4/world.bend as W
13import bendvy-ecs-core@0.1.0.4/system.bend as Sys
14import bendvy-ecs-core@0.1.0.4/schedule.bend as Sch
15import bendvy-ecs-core@0.1.0.4/schedule_provision.bend as SP
16import bendvy-ecs-core@0.1.0.4/string_equality.bend as Text
17
18
19
20type Named<S:Data> is Data:
21 Named{label:String,plan:SP.Plan<S>}
22
23
24
25type Application<S:Data,C:Type,R:Type,E:Data,H:Type,Rows:Data,-observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,-fold:H -> H & List<&2,Records.Fields<S>>> is Type:
26 Application{app:App.Application<S,C,R,E,H,Rows,observe,fold>,plans:List<&2,Named<S>>}
27
28
29type Insertion<-A:Type,-S:Data> is Type:
30 Inserted{app:A,previous:Maybe<&2,SP.Plan<S>>}
31 Invalid{app:A}
32
33
34type RunResult<-A:Type,-S:Data,-Error:Data> is Type:
35 Executed{result:Single.RunResult<A,S,Error>}
36 Unknown{app:A}
37
38
39type Description<S:Data,Rows:Data> is Data:
40 Description{application:App.Description<S,Rows>,plans:List<&2,Detail.Description<S,Rows>>}
41def lookup_next(~S:Data,found:Bool,plan:SP.Plan<S>,next:Maybe<&2,SP.Plan<S>>) -> Maybe<&2,SP.Plan<S>>:
42 match found:
43 case True{}:Some{plan}
44 case False{}:next
45def lookup(~S:Data,+label:String,plans:List<&2,Named<S>>) -> Maybe<&2,SP.Plan<S>>:
46 match plans:
47 case []:None{}
48 case Named{name,plan} <> rest:lookup_next(~S,Text.equal(label,name),plan,lookup(~S,label,rest))
49def replace_next(~S:Data,same:Bool,label:String,plan:SP.Plan<S>,old:Named<S>,rest:List<&2,Named<S>>,next:List<&2,Named<S>>) -> List<&2,Named<S>>:
50 match same:
51 case True{}:Named{label,plan} <> rest
52 case False{}:old <> next
53def replace(~S:Data,+label:String,+plan:SP.Plan<S>,plans:List<&2,Named<S>>) -> List<&2,Named<S>>:
54 match plans:
55 case []:[Named{label,plan}]
56 case Named{+name,+old} <> +rest:replace_next(~S,Text.equal(label,name),label,plan,Named{name,old},rest,replace(~S,label,plan,rest))
57def remove_next(~S:Data,same:Bool,old:Named<S>,rest:List<&2,Named<S>>,next:List<&2,Named<S>>) -> List<&2,Named<S>>:
58 match same:
59 case True{}:rest
60 case False{}:old <> next
61def without(~S:Data,+label:String,plans:List<&2,Named<S>>) -> List<&2,Named<S>>:
62 match plans:
63 case []:[]
64 case Named{+name,+plan} <> +rest:remove_next(~S,Text.equal(label,name),Named{name,plan},rest,without(~S,label,rest))
65
66
67def create(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,app:App.Application<S,C,R,E,H,Rows,observe,fold>) -> Application<S,C,R,E,H,Rows,observe,fold>:
68 Application{app,[]}
69
70def get(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,value:Application<S,C,R,E,H,Rows,observe,fold>,+label:String) -> Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,SP.Plan<S>>:
71 match value:
72 case Application{app,+plans}:(Application{app,plans},lookup(~S,label,plans))
73
74
75def remove(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,value:Application<S,C,R,E,H,Rows,observe,fold>,+label:String) -> Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,SP.Plan<S>>:
76 match value:
77 case Application{app,+plans}:(Application{app,without(~S,label,plans)},lookup(~S,label,plans))
78def inserted(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,+plans:List<&2,Named<S>>,+label:String,+plan:SP.Plan<S>,result:Single.Attachment<App.Application<S,C,R,E,H,Rows,observe,fold>,Single.Application<S,C,R,E,H,Rows,observe,fold>>) -> Insertion<Application<S,C,R,E,H,Rows,observe,fold>,S>:
79 match result:
80 case Single.Invalid{app}:Invalid{Application{app,plans}}
81 case Single.Attached{Single.Application{app,_,_,_,_,_}}:Inserted{Application{app,replace(~S,label,plan,plans)},lookup(~S,label,plans)}
82
83
84
85
86
87def insert(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,value:Application<S,C,R,E,H,Rows,observe,fold>,+label:String,+plan:SP.Plan<S>) -> Insertion<Application<S,C,R,E,H,Rows,observe,fold>,S>:
88 match value:
89 case Application{app,plans}:inserted(~S,~C,~R,~E,~H,~Rows,~observe,~fold,plans,label,plan,Single.attach(~S,~C,~R,~E,~H,~Rows,~observe,~fold,app,label,plan))
90def restored(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,plans:List<&2,Named<S>>,result:Single.RunResult<Single.Application<S,C,R,E,H,Rows,observe,fold>,S,Error>) -> RunResult<Application<S,C,R,E,H,Rows,observe,fold>,S,Error>:
91 match result:
92 case Single.Finished{Single.Application{app,_,_,_,_,_},observations}:Executed{Single.Finished{Application{app,plans},observations}}
93 case Single.Failed{Single.Application{app,_,_,_,_,_},error,observations}:Executed{Single.Failed{Application{app,plans},error,observations}}
94 case Single.Rejected{Single.Application{app,_,_,_,_,_}}:Executed{Single.Rejected{Application{app,plans}}}
95 case Single.Missing{Single.Application{app,_,_,_,_,_},requirements}:Executed{Single.Missing{Application{app,plans},requirements}}
96def attached(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>,~condition:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,~provision:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,plans:List<&2,Named<S>>,result:Single.Attachment<App.Application<S,C,R,E,H,Rows,observe,fold>,Single.Application<S,C,R,E,H,Rows,observe,fold>>) -> RunResult<Application<S,C,R,E,H,Rows,observe,fold>,S,Error>:
97 match result:
98 case Single.Invalid{app}:Executed{Single.Rejected{Application{app,plans}}}
99 case Single.Attached{app}:restored(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,plans,Single.run(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,~dispatch,~condition,~provision,app))
100def selected(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>,~condition:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,~provision:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,app:App.Application<S,C,R,E,H,Rows,observe,fold>,plans:List<&2,Named<S>>,label:String,found:Maybe<&2,SP.Plan<S>>) -> RunResult<Application<S,C,R,E,H,Rows,observe,fold>,S,Error>:
101 match found:
102 case None{}:Unknown{Application{app,plans}}
103 case Some{plan}:attached(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,~dispatch,~condition,~provision,plans,Single.attach(~S,~C,~R,~E,~H,~Rows,~observe,~fold,app,label,plan))
104
105
106
107
108
109
110def run(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~Error:Data,~dispatch:H -> W.World<S,C,R,E> -> U32 -> H & Sys.Outcome<W.World<S,C,R,E>,Error,Unit>,~condition:W.World<S,C,R,E> -> U32 -> W.World<S,C,R,E> & Bool,~provision:W.World<S,C,R,E> -> W.World<S,C,R,E> & List<&2,SP.Requirement<S>>,value:Application<S,C,R,E,H,Rows,observe,fold>,+label:String) -> RunResult<Application<S,C,R,E,H,Rows,observe,fold>,S,Error>:
111 match value:
112 case Application{app,+plans}:selected(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~Error,~dispatch,~condition,~provision,app,plans,label,lookup(~S,label,plans))
113
114def enabled(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,value:Application<S,C,R,E,H,Rows,observe,fold>,flag:Bool) -> Application<S,C,R,E,H,Rows,observe,fold>:
115 match value:
116 case Application{app,plans}:Application{App.enabled(~S,~C,~R,~E,~H,~Rows,~observe,~fold,app,flag),plans}
117
118
119def descriptions(~S:Data,~Rows:Data,+view:App.Description<S,Rows>,+namespace:U32,plans:List<&2,Named<S>>) -> List<&2,Detail.Description<S,Rows>>:
120 match plans:
121 case []:[]
122 case Named{label,+plan} <> rest:Detail.described(~S,~Rows,Single.Description{view,namespace,label,Single.planned(~S,plan)}) <> descriptions(~S,~Rows,view,namespace,rest)
123def observed(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,+plans:List<&2,Named<S>>,namespace:U32,result:App.Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,App.Description<S,Rows>>) -> Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Description<S,Rows>>:
124 match result:
125 case (app,None{}):(Application{app,plans},None{})
126 case (app,Some{+view}):(Application{app,plans},Some{Description{view,descriptions(~S,~Rows,view,namespace,plans)}})
127def cataloged_snapshot(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,schema:Schema.Schema<S,C,R>,owners:H,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,debug:Bool,plans:List<&2,Named<S>>,result:W.World<S,C,R,E> & U32) -> Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Description<S,Rows>>:
128 match result:
129 case (world,namespace):observed(~S,~C,~R,~E,~H,~Rows,~observe,~fold,plans,namespace,App.snapshot(~S,~C,~R,~E,~H,~Rows,~observe,~fold,App.Application{schema,Build.Registered{world,owners,recipe,debug}}))
130
131
132
133def snapshot(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,value:Application<S,C,R,E,H,Rows,observe,fold>) -> Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Description<S,Rows>>:
134 match value:
135 case Application{App.Application{schema,Build.Registered{world,owners,recipe,False{}}},plans}:(Application{App.Application{schema,Build.Registered{world,owners,recipe,False{}}},plans},None{})
136 case Application{App.Application{schema,Build.Registered{world,owners,recipe,True{}}},plans}:cataloged_snapshot(~S,~C,~R,~E,~H,~Rows,~observe,~fold,schema,owners,recipe,True{},plans,W.namespace(~S,~C,~R,~E,world))
137
138type PlanIndex is Data:
139 PlanIndex{label:String,entries:List<&2,Access.Entry>}
140
141
142type Index is Data:
143 Index{namespace:U32,inventory:List<&2,Access.Entry>,plans:List<&2,PlanIndex>}
144def plan_indexes(~S:Data,+namespace:U32,+records:List<&2,Records.Fields<S>>,plans:List<&2,Named<S>>) -> List<&2,PlanIndex>:
145 match plans:
146 case []:[]
147 case Named{label,plan} <> rest:PlanIndex{label,Access.grouped(Access.fields(~S,SelectedAccess.placed(~S,Single.planned(~S,plan),namespace,records)),[])} <> plan_indexes(~S,namespace,records,rest)
148def indexed(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,schema:Schema.Schema<S,C,R>,world:W.World<S,C,R,E>,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,+plans:List<&2,Named<S>>,+namespace:U32,result:H & List<&2,Records.Fields<S>>) -> Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Index>:
149 match result:
150 case (owners,+records):(Application{App.Application{schema,Build.Registered{world,owners,recipe,True{}}},plans},Some{Index{namespace,Access.grouped(Access.fields(~S,records),[]),plan_indexes(~S,namespace,records,plans)}})
151def index_named(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,schema:Schema.Schema<S,C,R>,owners:H,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,plans:List<&2,Named<S>>,result:W.World<S,C,R,E> & U32) -> Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Index>:
152 match result:
153 case (world,namespace):indexed(~S,~C,~R,~E,~H,~Rows,~observe,~fold,schema,world,recipe,plans,namespace,fold(owners))
154
155
156
157def index(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,value:Application<S,C,R,E,H,Rows,observe,fold>) -> Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Index>:
158 match value:
159 case Application{App.Application{schema,Build.Registered{world,owners,recipe,False{}}},plans}:(Application{App.Application{schema,Build.Registered{world,owners,recipe,False{}}},plans},None{})
160 case Application{App.Application{schema,Build.Registered{world,owners,recipe,True{}}},plans}:index_named(~S,~C,~R,~E,~H,~Rows,~observe,~fold,schema,owners,recipe,plans,W.namespace(~S,~C,~R,~E,world))