restore_schema.bend
bendvy-ecs-core@0.1.0.0 · 90 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.0/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.0/restore_clear.bend as Clear
4import bendvy-ecs-core@0.1.0.0/restore_transient.bend as Transient
5import bendvy-ecs-core@0.1.0.0/restore_data.bend as R
6import bendvy-ecs-core@0.1.0.0/restore_leaf.bend as Stage
7import bendvy-ecs-core@0.1.0.0/restore_storage.bend as Storage
8import bendvy-ecs-core@0.1.0.0/restore_product.bend as Product
9import bendvy-ecs-core@0.1.0.0/snapshot_schema.bend as Save
10import bendvy-ecs-core@0.1.0.0/snapshot_leaf.bend as Leaf
11import bendvy-ecs-core@0.1.0.0/ordinary_schema.bend as Ordinary
12import bendvy-ecs-core@0.1.0.0/ordinary_declaration.bend as Identity
13import bendvy-ecs-core@0.1.0.0/owner_product.bend as Owner
14import bendvy-ecs-core@0.1.0.0/decode_data.bend as D
15import bendvy-ecs-core@0.1.0.0/decode_construction.bend as Constructor
16import bendvy-ecs-core@0.1.0.0/bundle_construction.bend as Build
17import bendvy-ecs-core@0.1.0.0/world.bend as W
18
19# Restore schema retaining the ordinary declaration inventory with closed staged
20# construction/cleanup/insertion/recovery adapters in its type. Compose canonical
21# builders rather than a second name registry. Raw schema/lens/supply callbacks
22# remain trusted provisioning, not arbitrary descriptor validation by this wrapper.
23type Schema<-S:Data,-C:Type,-Resources:Type,-State:Type,-Custom:Data,-stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,-release:State -> State,-clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,-insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,-Recovery:Type,-commit:State -> State,-takeRecovery:State -> State & Recovery> is Data:
24 Schema{ordinary:Ordinary.Schema<S,C,Resources>}
25def component_kind() -> Stage.FamilyKind:Stage.Component{}
26def resource_kind() -> Stage.FamilyKind:Stage.Resource{}
27def component_stage(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction<I,P,Custom>,~factory:Constructor.FallibleFactory<S,I,P,Custom,identity,project,incoming,build>,~supply:Context -> D.Raw -> Context & I,state:Stage.State<Context,I,P>,position:R.Position,field:D.Field) -> Stage.State<Context,I,P> & R.Dispatch<Custom>:
28 Stage.stage(~S,~Context,~I,~P,~Custom,~identity,~project,~incoming,~build,~factory,~supply,~component_kind(),state,position,field)
29def resource_stage(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction<I,P,Custom>,~factory:Constructor.FallibleFactory<S,I,P,Custom,identity,project,incoming,build>,~supply:Context -> D.Raw -> Context & I,state:Stage.State<Context,I,P>,position:R.Position,field:D.Field) -> Stage.State<Context,I,P> & R.Dispatch<Custom>:
30 Stage.stage(~S,~Context,~I,~P,~Custom,~identity,~project,~incoming,~build,~factory,~supply,~resource_kind(),state,position,field)
31def component_clear(~S:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,owner:Leaf.Component<S,P,identity,project>,handle:W.Handle<S>) -> Leaf.Component<S,P,identity,project> & List<&2,R.Change<S>>:
32 Clear.component(~S,~P,~identity,~project,owner,handle)
33def resource_clear(~S:Data,owner:Unit,handle:W.Handle<S>) -> Unit & List<&2,R.Change<S>>:
34 Clear.unit(~S,owner,handle)
35def product_clear(~S:Data,~LC:Type,~RC:Type,~left:LC -> W.Handle<S> -> LC & List<&2,R.Change<S>>,~right:RC -> W.Handle<S> -> RC & List<&2,R.Change<S>>,owner:Owner.Owner<LC,RC>,handle:W.Handle<S>) -> Owner.Owner<LC,RC> & List<&2,R.Change<S>>:
36 Clear.product(~S,~LC,~RC,~left,~right,owner,handle)
37def component_insert_join(~S:Data,~Context:Type,~I:Type,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,observed:Leaf.Component<S,P,identity,project> & Stage.State<Context,I,P>) -> (Leaf.Component<S,P,identity,project> & Unit) & Stage.State<Context,I,P>:
38 match observed:
39 case (owner,state):((owner,Unit{}),state)
40def component_insert(~S:Data,~Context:Type,~I:Type,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,owner:Leaf.Component<S,P,identity,project>,unit:Unit,state:Stage.State<Context,I,P>,bindings:List<&2,R.Binding<S>>,tick:Tick.Tick) -> (Leaf.Component<S,P,identity,project> & Unit) & Stage.State<Context,I,P>:
41 component_insert_join(~S,~Context,~I,~P,~identity,~project,Storage.components(~S,~Context,~I,~P,~identity,~project,owner,state,bindings,tick))
42def resource_insert_join(~S:Data,~Context:Type,~I:Type,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,observed:Leaf.Resource<S,P,identity,project> & Stage.State<Context,I,P>) -> (Unit & Leaf.Resource<S,P,identity,project>) & Stage.State<Context,I,P>:
43 match observed:
44 case (owner,state):((Unit{},owner),state)
45def resource_insert(~S:Data,~Context:Type,~I:Type,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,unit:Unit,owner:Leaf.Resource<S,P,identity,project>,state:Stage.State<Context,I,P>,bindings:List<&2,R.Binding<S>>,tick:Tick.Tick) -> (Unit & Leaf.Resource<S,P,identity,project>) & Stage.State<Context,I,P>:
46 resource_insert_join(~S,~Context,~I,~P,~identity,~project,Storage.resources(~S,~Context,~I,~P,~identity,~project,owner,state))
47# Build a persisted component restore leaf from its nominal identity, canonical
48# codec/fallible factory and owned input supply. Stage incoming construction and
49# validate the resulting stored P before World insertion; refusal returns actual
50# inputs through schema release/recovery. No generic Raw-to-arbitrary-Type cast.
51def component(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction<I,P,Custom>,~factory:Constructor.FallibleFactory<S,I,P,Custom,identity,project,incoming,build>,~supply:Context -> D.Raw -> Context & I) -> Schema<S,Leaf.Component<S,P,identity,project>,Unit,Stage.State<Context,I,P>,Custom,component_stage(~S,~Context,~I,~P,~Custom,~identity,~project,~incoming,~build,~factory,~supply),Stage.release(~Context,~I,~P),component_clear(~S,~P,~identity,~project),component_insert(~S,~Context,~I,~P,~identity,~project),List<I>,Stage.commit(~Context,~I,~P),Stage.take_recovery(~Context,~I,~P)>:
52 Schema{Save.inventory(~S,~Leaf.Component<S,P,identity,project>,~Unit,~True{},~Leaf.component_fields(~S,~P,~identity,~project),~Save.unit_resource,Save.component(~S,~P,~identity,~project))}
53# Build a persisted resource restore leaf using the same constructed declaration
54# and factory contract. Omitted resources remain owned by World; a staged value
55# replaces through schema insertion only after complete preparation/admission.
56def resource(~S:Data,~Context:Type,~I:Type,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~incoming:I -> I & D.Raw,~build:I -> D.Raw -> Build.Construction<I,P,Custom>,~factory:Constructor.FallibleFactory<S,I,P,Custom,identity,project,incoming,build>,~supply:Context -> D.Raw -> Context & I) -> Schema<S,Unit,Leaf.Resource<S,P,identity,project>,Stage.State<Context,I,P>,Custom,resource_stage(~S,~Context,~I,~P,~Custom,~identity,~project,~incoming,~build,~factory,~supply),Stage.release(~Context,~I,~P),resource_clear(~S),resource_insert(~S,~Context,~I,~P,~identity,~project),List<I>,Stage.commit(~Context,~I,~P),Stage.take_recovery(~Context,~I,~P)>:
57 Schema{Save.inventory(~S,~Unit,~Leaf.Resource<S,P,identity,project>,~True{},~Save.unit_component,~Leaf.resource_fields(~S,~P,~identity,~project),Save.resource(~S,~P,~identity,~project))}
58def product_stage(~S:Data,~LC:Type,~LR:Type,~RC:Type,~RR:Type,~L:Type,~Right:Type,~Custom:Data,~stageLeft:L -> R.Position -> D.Field -> L & R.Dispatch<Custom>,~releaseLeft:L -> L,~clearLeft:LC -> W.Handle<S> -> LC & List<&2,R.Change<S>>,~insertLeft:LC -> LR -> L -> List<&2,R.Binding<S>> -> Tick.Tick -> (LC & LR) & L,~stageRight:Right -> R.Position -> D.Field -> Right & R.Dispatch<Custom>,~releaseRight:Right -> Right,~clearRight:RC -> W.Handle<S> -> RC & List<&2,R.Change<S>>,~insertRight:RC -> RR -> Right -> List<&2,R.Binding<S>> -> Tick.Tick -> (RC & RR) & Right,state:Owner.Owner<L,Right>,position:R.Position,field:D.Field) -> Owner.Owner<L,Right> & R.Dispatch<Custom>:
59 Product.stage(~L,~Right,~Custom,~stageLeft,~stageRight,state,position,field)
60def product_insert(~S:Data,~LC:Type,~LR:Type,~RC:Type,~RR:Type,~L:Type,~Right:Type,~Custom:Data,~stageLeft:L -> R.Position -> D.Field -> L & R.Dispatch<Custom>,~releaseLeft:L -> L,~clearLeft:LC -> W.Handle<S> -> LC & List<&2,R.Change<S>>,~insertLeft:LC -> LR -> L -> List<&2,R.Binding<S>> -> Tick.Tick -> (LC & LR) & L,~stageRight:Right -> R.Position -> D.Field -> Right & R.Dispatch<Custom>,~releaseRight:Right -> Right,~clearRight:RC -> W.Handle<S> -> RC & List<&2,R.Change<S>>,~insertRight:RC -> RR -> Right -> List<&2,R.Binding<S>> -> Tick.Tick -> (RC & RR) & Right,owner:Owner.Owner<LC,RC>,resource:Owner.Owner<LR,RR>,state:Owner.Owner<L,Right>,bindings:List<&2,R.Binding<S>>,tick:Tick.Tick) -> (Owner.Owner<LC,RC> & Owner.Owner<LR,RR>) & Owner.Owner<L,Right>:
61 Product.insert(~S,~LC,~LR,~RC,~RR,~L,~Right,~insertLeft,~insertRight,owner,resource,state,bindings,tick)
62def product_join(~S:Data,~LC:Type,~LR:Type,~RC:Type,~RR:Type,~L:Type,~Right:Type,~Custom:Data,~stageLeft:L -> R.Position -> D.Field -> L & R.Dispatch<Custom>,~releaseLeft:L -> L,~clearLeft:LC -> W.Handle<S> -> LC & List<&2,R.Change<S>>,~insertLeft:LC -> LR -> L -> List<&2,R.Binding<S>> -> Tick.Tick -> (LC & LR) & L,~stageRight:Right -> R.Position -> D.Field -> Right & R.Dispatch<Custom>,~releaseRight:Right -> Right,~clearRight:RC -> W.Handle<S> -> RC & List<&2,R.Change<S>>,~insertRight:RC -> RR -> Right -> List<&2,R.Binding<S>> -> Tick.Tick -> (RC & RR) & Right,~LRecovery:Type,~RRecovery:Type,~commitLeft:L -> L,~commitRight:Right -> Right,~takeLeft:L -> L & LRecovery,~takeRight:Right -> Right & RRecovery,left:Ordinary.Schema<S,LC,LR>,right:Ordinary.Schema<S,RC,RR>) -> Schema<S,Owner.Owner<LC,RC>,Owner.Owner<LR,RR>,Owner.Owner<L,Right>,Custom,product_stage(~S,~LC,~LR,~RC,~RR,~L,~Right,~Custom,~stageLeft,~releaseLeft,~clearLeft,~insertLeft,~stageRight,~releaseRight,~clearRight,~insertRight),Product.release(~L,~Right,~releaseLeft,~releaseRight),product_clear(~S,~LC,~RC,~clearLeft,~clearRight),product_insert(~S,~LC,~LR,~RC,~RR,~L,~Right,~Custom,~stageLeft,~releaseLeft,~clearLeft,~insertLeft,~stageRight,~releaseRight,~clearRight,~insertRight),Owner.Owner<LRecovery,RRecovery>,Product.release(~L,~Right,~commitLeft,~commitRight),Product.take_recovery(~L,~Right,~LRecovery,~RRecovery,~takeLeft,~takeRight)>:
63 Schema{Ordinary.product(~S,~LC,~LR,~RC,~RR,left,right)}
64# Compose schema inventories, staged field dispatch, owner cleanup/insertion and
65# actual recovery products in left-before-right order. Canonical dispatch tries
66# right only when left is Unhandled; this adds no new duplicate-field policy.
67def product(~S:Data,~LC:Type,~LR:Type,~RC:Type,~RR:Type,~L:Type,~Right:Type,~Custom:Data,~stageLeft:L -> R.Position -> D.Field -> L & R.Dispatch<Custom>,~releaseLeft:L -> L,~clearLeft:LC -> W.Handle<S> -> LC & List<&2,R.Change<S>>,~insertLeft:LC -> LR -> L -> List<&2,R.Binding<S>> -> Tick.Tick -> (LC & LR) & L,~stageRight:Right -> R.Position -> D.Field -> Right & R.Dispatch<Custom>,~releaseRight:Right -> Right,~clearRight:RC -> W.Handle<S> -> RC & List<&2,R.Change<S>>,~insertRight:RC -> RR -> Right -> List<&2,R.Binding<S>> -> Tick.Tick -> (RC & RR) & Right,~LRecovery:Type,~RRecovery:Type,~commitLeft:L -> L,~commitRight:Right -> Right,~takeLeft:L -> L & LRecovery,~takeRight:Right -> Right & RRecovery,left:Schema<S,LC,LR,L,Custom,stageLeft,releaseLeft,clearLeft,insertLeft,LRecovery,commitLeft,takeLeft>,right:Schema<S,RC,RR,Right,Custom,stageRight,releaseRight,clearRight,insertRight,RRecovery,commitRight,takeRight>) -> Schema<S,Owner.Owner<LC,RC>,Owner.Owner<LR,RR>,Owner.Owner<L,Right>,Custom,product_stage(~S,~LC,~LR,~RC,~RR,~L,~Right,~Custom,~stageLeft,~releaseLeft,~clearLeft,~insertLeft,~stageRight,~releaseRight,~clearRight,~insertRight),Product.release(~L,~Right,~releaseLeft,~releaseRight),product_clear(~S,~LC,~RC,~clearLeft,~clearRight),product_insert(~S,~LC,~LR,~RC,~RR,~L,~Right,~Custom,~stageLeft,~releaseLeft,~clearLeft,~insertLeft,~stageRight,~releaseRight,~clearRight,~insertRight),Owner.Owner<LRecovery,RRecovery>,Product.release(~L,~Right,~commitLeft,~commitRight),Product.take_recovery(~L,~Right,~LRecovery,~RRecovery,~takeLeft,~takeRight)>:
68 match left right:
69 case Schema{left} Schema{right}:product_join(~S,~LC,~LR,~RC,~RR,~L,~Right,~Custom,~stageLeft,~releaseLeft,~clearLeft,~insertLeft,~stageRight,~releaseRight,~clearRight,~insertRight,~LRecovery,~RRecovery,~commitLeft,~commitRight,~takeLeft,~takeRight,left,right)
70# Build an explicitly omitted transient component leaf. Snapshot input does not
71# construct this payload; old entity cleanup still handles its existing storage
72# when restoring the live entity set. No new arbitrary-Type factory is invented.
73def transient_component(~S:Data,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>) -> Schema<S,Leaf.TransientComponent<S,P,identity>,Unit,Transient.State<P>,Custom,Transient.stage(~Transient.State<P>,~Custom),Transient.release(~Transient.State<P>),Clear.transient_component(~S,~P,~identity),Transient.insert(~S,~P,~identity),Unit,Transient.commit(~P),Transient.take_recovery(~Transient.State<P>)>:
74 Schema{Save.inventory(~S,~Leaf.TransientComponent<S,P,identity>,~Unit,~True{},~Leaf.transient_component_fields(~S,~P,~identity),~Save.unit_resource,Save.transient_component(~S,~P,~identity))}
75# Build an omitted transient resource leaf, preserving its existing actual owner
76# on insertion. Incoming named fields are not admitted through transient staging.
77def transient_resource(~S:Data,~P:Type,~Custom:Data,~identity:Identity.Declaration<S,P>) -> Schema<S,Unit,Leaf.TransientResource<S,P,identity>,Unit,Custom,Transient.stage(~Unit,~Custom),Transient.release(~Unit),resource_clear(~S),Transient.resource_insert(~S,~P,~identity),Unit,Transient.release(~Unit),Transient.take_recovery(~Unit)>:
78 Schema{Save.inventory(~S,~Unit,~Leaf.TransientResource<S,P,identity>,~True{},~Save.unit_component,~Leaf.transient_resource_fields(~S,~P,~identity),Save.transient_resource(~S,~P,~identity))}
79def events_insert_join(~S:Data,~C:Type,~Resources:Type,~Logs:Type,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,logs:Logs,observed:(C & Resources) & State) -> (C & Owner.Owner<Resources,Logs>) & State:
80 match observed:
81 case ((owner,resource),state):((owner,Owner.Owner{resource,logs}),state)
82def events_insert(~S:Data,~C:Type,~Resources:Type,~Logs:Type,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,owner:C,resource:Owner.Owner<Resources,Logs>,state:State,bindings:List<&2,R.Binding<S>>,tick:Tick.Tick) -> (C & Owner.Owner<Resources,Logs>) & State:
83 match resource:
84 case Owner.Owner{resource,logs}:events_insert_join(~S,~C,~Resources,~Logs,~State,~Custom,~stage,~release,~clear,~insert,logs,insert(owner,resource,state,bindings,tick))
85# Lift user-resource restore over Product.Owner<Resources,Logs>, retaining actual
86# logs during basic schema insertion. Logs are not persisted fields; restore-runtime
87# performs the separate typed drain/stream-clearing boundary.
88def with_events(~S:Data,~C:Type,~Resources:Type,~Logs:Type,~State:Type,~Custom:Data,~stage:State -> R.Position -> D.Field -> State & R.Dispatch<Custom>,~release:State -> State,~clear:C -> W.Handle<S> -> C & List<&2,R.Change<S>>,~insert:C -> Resources -> State -> List<&2,R.Binding<S>> -> Tick.Tick -> (C & Resources) & State,~Recovery:Type,~commit:State -> State,~takeRecovery:State -> State & Recovery,schema:Schema<S,C,Resources,State,Custom,stage,release,clear,insert,Recovery,commit,takeRecovery>) -> Schema<S,C,Owner.Owner<Resources,Logs>,State,Custom,stage,release,clear,events_insert(~S,~C,~Resources,~Logs,~State,~Custom,~stage,~release,~clear,~insert),Recovery,commit,takeRecovery>:
89 match schema:
90 case Schema{Ordinary.Schema{entries}}:Schema{Ordinary.Schema{entries}}