1 import Base 2 import ./world.bend as W 3 import ./world_resource_owner.bend as WR 4 import ./owner_product.bend as Product 5 import ./event_runtime.bend as Ev 6 import ./event_family_runtime.bend as FR 7 import ./event_family_routing.bend as Route 8 import ./owned_event_family_catalog.bend as Catalog 9 # The complete typed catalog is derived by leaf/both, not a list of user cleanup 10 # callbacks. All payload owners are returned before shared publication state clears. 11 def resource_returned(~S:Data,~C:Type,~User:Type,~Logs:Type,~E:Data,~Receipt:Type,rest:WR.Rest,E>,user:User,result:Logs & Receipt) -> W.World,E> & Receipt: 12 match result: 13 case (logs,receipt):(WR.put(~S,~C,~Product.Owner,~E,rest,Product.Owner{user,logs}),receipt) 14 def resource_taken(~S:Data,~C:Type,~User:Type,~Logs:Type,~E:Data,~Receipt:Type,~retain:Logs -> List<&2,E> -> Logs & Receipt,~drain:Logs -> Logs & Receipt,shutdown:Bool,records:List<&2,E>,result:WR.Rest,E> & Product.Owner) -> W.World,E> & Receipt: 15 match shutdown result: 16 case False{}, (rest,Product.Owner{user,logs}):resource_returned(~S,~C,~User,~Logs,~E,~Receipt,rest,user,retain(logs,records)) 17 case True{}, (rest,Product.Owner{user,logs}):resource_returned(~S,~C,~User,~Logs,~E,~Receipt,rest,user,drain(logs)) 18 def completed(~S:Data,~C:Type,~User:Type,~Logs:Type,~E:Data,~F:Type,~Owners:Type,~Receipt:Type,~clear:F -> F,shutdown:Bool,family:F,owners:Owners,journal:List<&2,Ev.Batch>,frameStart:Nat,tick:Nat,result:W.World,E> & Receipt) -> Route.Runtime,E,FR.State> & Receipt: 19 match shutdown result: 20 case False{}, (world,receipt):(Route.Runtime{world,FR.State{family,owners,journal,frameStart},tick},receipt) 21 case True{}, (world,receipt):(Route.Runtime{W.events_replace(~S,~C,~Product.Owner,~E,world,[]),FR.State{clear(family),owners,[],frameStart},tick},receipt) 22 def observed(~S:Data,~C:Type,~User:Type,~Logs:Type,~E:Data,~F:Type,~Owners:Type,~Receipt:Type,~retain:Logs -> List<&2,E> -> Logs & Receipt,~drain:Logs -> Logs & Receipt,~clear:F -> F,+shutdown:Bool,family:F,owners:Owners,journal:List<&2,Ev.Batch>,frameStart:Nat,tick:Nat,result:W.World,E> & List<&2,E>) -> Route.Runtime,E,FR.State> & Receipt: 23 match result: 24 case (world,records):completed(~S,~C,~User,~Logs,~E,~F,~Owners,~Receipt,~clear,shutdown,family,owners,journal,frameStart,tick,resource_taken(~S,~C,~User,~Logs,~E,~Receipt,~retain,~drain,shutdown,records,WR.take(~S,~C,~Product.Owner,~E,world))) 25 def collect(~S:Data,~C:Type,~User:Type,~Logs:Type,~E:Data,~F:Type,~Owners:Type,~Receipt:Type,~retain:Logs -> List<&2,E> -> Logs & Receipt,~drain:Logs -> Logs & Receipt,~clear:F -> F,shutdown:Bool,runtime:Route.Runtime,E,FR.State>) -> Route.Runtime,E,FR.State> & Receipt: 26 match runtime: 27 case Route.Runtime{world,FR.State{family,owners,journal,frameStart},tick}:observed(~S,~C,~User,~Logs,~E,~F,~Owners,~Receipt,~retain,~drain,~clear,shutdown,family,owners,journal,frameStart,tick,W.events_view(~S,~C,~Product.Owner,~E,world)) 28 def frame(~S:Data,~C:Type,~User:Type,~Logs:Type,~E:Data,~F:Type,~Owners:Type,~Receipt:Type,~retain:Logs -> List<&2,E> -> Logs & Receipt,~drain:Logs -> Logs & Receipt,~clear:F -> F,~catalog:Catalog.Catalog,~frame:F -> Nat -> F,~retainRecords:F -> Nat -> List<&2,E> -> F & List<&2,E>,runtime:Route.Runtime,E,FR.State>) -> Route.Runtime,E,FR.State> & Receipt: 29 collect(~S,~C,~User,~Logs,~E,~F,~Owners,~Receipt,~retain,~drain,~clear,False{},FR.frame(~S,~C,~Product.Owner,~E,~F,~Owners,~frame,~retainRecords,runtime)) 30 def shutdown(~S:Data,~C:Type,~User:Type,~Logs:Type,~E:Data,~F:Type,~Owners:Type,~Receipt:Type,~retain:Logs -> List<&2,E> -> Logs & Receipt,~drain:Logs -> Logs & Receipt,~clear:F -> F,~catalog:Catalog.Catalog,runtime:Route.Runtime,E,FR.State>) -> Route.Runtime,E,FR.State> & Receipt: 31 collect(~S,~C,~User,~Logs,~E,~F,~Owners,~Receipt,~retain,~drain,~clear,True{},runtime)