1 import Base 2 import ./deferred_command.bend as Deferred 3 import ./trace_facts.bend as TraceFacts 4 import ./ordinary_app_composer.bend as Build 5 import ./ordinary_app_recipe.bend as Tree 6 import ./ordinary_app_observation_data.bend as DTO 7 import ./ordinary_app_registration_fields.bend as Fields 8 import ./ordinary_app_relation.bend as Relation 9 import ./relation_failure_reader.bend as Ord 10 import ./relation_types.bend as G 11 import ./relation_commands.bend as A 12 import ./relation_cleanup.bend as Cleanup 13 import ./world.bend as W 14 import ./transaction.bend as T 15 import ./commands.bend as Cmd 16 17 # Trusted setup captures component-binding-derived clear and declaration installs. 18 # This wrapper cannot infer declarations from an arbitrary existing App recipe. 19 type Installed Relation.World(~S,~C,~R,~E) & DTO.Observation,-fold:Owners -> Owners & List<&2,Fields.Fields>,-declarations:List<&2,Ord.Declaration>,-clear:C -> W.Handle -> C & List<&2,A.Notice>,-record:W.Handle -> A.Notice> is Type: 20 Installed{app:Build.Registered} 21 def descriptors(~S:Data,declarations:List<&2,Ord.Declaration>) -> List<&2,G.Descriptor>: 22 match declarations: 23 case []:[] 24 case Ord.Declaration{descriptor} <> rest:descriptor <> descriptors(~S,rest) 25 def empty(~S:Data,~C:Type,~R:Type,~E:Data,~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,app:Build.Registered) -> Installed: 26 Installed{app} 27 def install_relation(~S:Data,~C:Type,~R:Type,~E:Data,~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~declaration:Ord.Declaration,installed:Installed) -> Installed,~observe,~Relation.observe(~S,~C,~R,~E,~declaration,~Relation.builtin_row(~S))),fold,List.append(&2,Ord.Declaration,declarations,[declaration]),clear,record>: 28 match installed: 29 case Installed{app}:Installed{Relation.install(~S,~C,~R,~E,~declaration,~Owners,~Rows,~observe,~fold,app)} 30 def result(~S:Data,~C:Type,~R:Type,~E:Data,result:Cleanup.CleanupResult) -> Relation.World(~S,~C,~R,~E): 31 match result: 32 case Cleanup.Complete{world}:world 33 case Cleanup.Incomplete{world,frames}:W.event_publish(~S,~A.Store,~R,~A.Notice,world,[A.CleanupPaused{frames}]) 34 def apply(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,world:Relation.World(~S,~C,~R,~E),handle:W.Handle) -> Relation.World(~S,~C,~R,~E): 35 result(~S,~C,~R,~E,Cleanup.automatic(~S,~C,~R,~E,~clear,~record,world,handle,descriptors(~S,declarations))) 36 def checked(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,allowed:Bool,world:Relation.World(~S,~C,~R,~E),undo:List<(Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E))>,commands:List>,events:List<&2,A.Notice>,trace:TraceFacts.State,handle:W.Handle) -> T.Tx> & A.QueueStatus: 37 match allowed: 38 case False{}:(T.Tx{world,undo,commands,events,trace},A.MissingEntity{}) 39 case True{}:(T.Tx{world,undo,Deferred.Raw{(world => apply(~S,~C,~R,~E,~declarations,~clear,~record,world,handle))} <> commands,events,trace},A.Queued{}) 40 def validated(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,handle:W.Handle,undo:List<(Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E))>,commands:List>,events:List<&2,A.Notice>,trace:TraceFacts.State,seen:Relation.World(~S,~C,~R,~E) & Bool) -> T.Tx> & A.QueueStatus: 41 match seen: 42 case (world,allowed):checked(~S,~C,~R,~E,~declarations,~clear,~record,allowed,world,undo,commands,events,trace,handle) 43 def queue(~S:Data,~C:Type,~R:Type,~E:Data,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,tx:T.Tx>,+handle:W.Handle) -> T.Tx> & A.QueueStatus: 44 match tx: 45 case T.Tx{world,undo,commands,events,trace}:validated(~S,~C,~R,~E,~declarations,~clear,~record,handle,undo,commands,events,trace,W.valid(~S,~A.Store,~R,~A.Notice,world,handle)) 46 def returned(~S:Data,~C:Type,~R:Type,~E:Data,~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Error:Data,owners:Owners,recipe:Tree.Recipe,debug:Bool,status:A.QueueStatus,seen:T.Returned) -> Installed & DTO.Product>: 47 match seen: 48 case T.Returned{world,outcome}:(Installed{Build.Registered{world,owners,recipe,debug}},DTO.Product{status,outcome}) 49 def queued(~S:Data,~C:Type,~R:Type,~E:Data,~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Error:Data,owners:Owners,recipe:Tree.Recipe,debug:Bool,outcome:T.Outcome,seen:T.Tx> & A.QueueStatus) -> Installed & DTO.Product>: 50 match seen: 51 case (tx,status):returned(~S,~C,~R,~E,~Owners,~Rows,~observe,~fold,~declarations,~clear,~record,~Error,owners,recipe,debug,status,Cmd.tx_finish(~S,~A.Store,~R,~A.Notice,~Error,tx,outcome)) 52 def cleanup_app(~S:Data,~C:Type,~R:Type,~E:Data,~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,~Error:Data,installed:Installed,handle:W.Handle,outcome:T.Outcome) -> Installed & DTO.Product>: 53 match installed: 54 case Installed{Build.Registered{world,owners,recipe,debug}}:queued(~S,~C,~R,~E,~Owners,~Rows,~observe,~fold,~declarations,~clear,~record,~Error,owners,recipe,debug,outcome,queue(~S,~C,~R,~E,~declarations,~clear,~record,T.begin(~Relation.World(~S,~C,~R,~E),~A.Notice,world),handle)) 55 def barrier_app(~S:Data,~C:Type,~R:Type,~E:Data,~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,installed:Installed) -> Installed: 56 match installed: 57 case Installed{Build.Registered{world,owners,recipe,debug}}:Installed{Build.Registered{W.barrier(~S,~A.Store,~R,~A.Notice,world),owners,recipe,debug}} 58 def snapshot_returned(~S:Data,~C:Type,~R:Type,~E:Data,~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,seen:Build.Registered & Maybe<&2,DTO.Product>,DTO.Observation>>) -> Installed & Maybe<&2,DTO.Product>,DTO.Observation>>: 59 match seen: 60 case (app,view):(Installed{app},view) 61 def snapshot_app(~S:Data,~C:Type,~R:Type,~E:Data,~Owners:Type,~Rows:Data,~observe:Relation.World(~S,~C,~R,~E) -> Relation.World(~S,~C,~R,~E) & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,~declarations:List<&2,Ord.Declaration>,~clear:C -> W.Handle -> C & List<&2,A.Notice>,~record:W.Handle -> A.Notice,installed:Installed,flag:Bool) -> Installed & Maybe<&2,DTO.Product>,DTO.Observation>>: 62 match installed: 63 case Installed{app}:snapshot_returned(~S,~C,~R,~E,~Owners,~Rows,~observe,~fold,~declarations,~clear,~record,Build.snapshot(~S,~Relation.World(~S,~C,~R,~E),~Owners,~Rows,~observe,~fold,Build.enabled(~S,~Relation.World(~S,~C,~R,~E),~Owners,~Rows,~observe,~fold,app,flag)))