1 import Base 2 import ./snapshot_schema.bend as Schema 3 import ./ordinary_schema.bend as Ordinary 4 import ./owner_product.bend as Product 5 import ./decode_data.bend as D 6 7 def resources_join(~User:Type,~Logs:Type,logs:Logs,observed:User & List<&2,D.Field>) -> Product.Owner & List<&2,D.Field>: 8 match observed: 9 case (user,fields):(Product.Owner{user,logs},fields) 10 # Advanced save projection for Product.Owner: project only User and 11 # return both actual owners. Logs are retained unchanged, not serialized as fields. 12 def resources(~User:Type,~Logs:Type,~project:User -> User & List<&2,D.Field>,owner:Product.Owner) -> Product.Owner & List<&2,D.Field>: 13 match owner: 14 case Product.Owner{user,logs}:resources_join(~User,~Logs,logs,project(user)) 15 # Affine event logs are runtime state, never ordinary persisted resource entries. 16 # Lift a save-eligible user-resource schema over its affine event-log owner. 17 # Keep the same declaration inventory/component projection and serialize only user 18 # resources; logs remain runtime state and are returned intact by the projection. 19 # This does not save readers, retained batches or a replayable event checkpoint. 20 # See docs/parity/restore-basic.md for the separate runtime restore boundary. 21 def with_events(~S:Data,~C:Type,~User:Type,~Logs:Type,~components:U32 -> C -> C & List<&2,D.Field>,~user:User -> User & List<&2,D.Field>,schema:Schema.Schema) -> Schema.Schema,True{},components,resources(~User,~Logs,~user)>: 22 match schema: 23 case Schema.Schema{Ordinary.Schema{entries}}:Schema.Schema{Ordinary.Schema{entries}}