ordinary_resource_field_system.bend

bendvy-ecs-core@0.1.0.0 · 111 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.0/trace_facts.bend as TraceFacts
3import bendvy-ecs-core@0.1.0.0/resource_field_binding.bend as B
4import bendvy-ecs-core@0.1.0.0/resource_field.bend as Field
5import bendvy-ecs-core@0.1.0.0/ordinary_schema.bend as Schema
6import bendvy-ecs-core@0.1.0.0/ordinary_query_declaration.bend as Q
7import bendvy-ecs-core@0.1.0.0/ordinary_resource_system.bend as Whole
8import bendvy-ecs-core@0.1.0.0/owner_product.bend as Product
9import bendvy-ecs-core@0.1.0.0/world.bend as W
10import bendvy-ecs-core@0.1.0.0/system.bend as Sys
11import bendvy-ecs-core@0.1.0.0/transaction.bend as T
12import bendvy-ecs-core@0.1.0.0/capabilities.bend as Cap
13# Descriptor identity is retained in each operation type, including equal payloads.
14# Identity-indexed selected-resource read grant for detached V and opaque H.
15# Equal payload types do not erase the retained resource identity.
16type Read<-S:Data,-P:Type,-identity:Schema.Resource<S,P>,-H:Type,-V:Data> is Type:
17  Read{operation:Cap.ValueRead<H,V>}
18# Identity-indexed selected-resource read/replacement grant. Consumes actual P
19# while siblings remain behind the canonical lens; no incoming recovery receipt.
20type Write<-S:Data,-P:Type,-identity:Schema.Resource<S,P>,-H:Type,-V:Data> is Type:
21  Write{operation:Cap.ValueWrite<H,P,V>}
22# Advanced projection of the closed read operation, without invoking it.
23def read_field(~S:Data,~P:Type,~identity:Schema.Resource<S,P>,~H:Type,~V:Data,cap:Read<S,P,identity,H,V>) -> H -> H & V:
24  match cap:
25    case Read{operation}:Cap.value_read_field(~H,~V,operation)
26# Read detached V through the declared selected-field grant and return actual H.
27def read_value(~S:Data,~P:Type,~identity:Schema.Resource<S,P>,~H:Type,~V:Data,~cap:Read<S,P,identity,H,V>,owner:H) -> H & V:
28  read_field(~S,~P,~identity,~H,~V,cap)(owner)
29# Advanced projection of the read operation from a selected-field write grant.
30def get_field(~S:Data,~P:Type,~identity:Schema.Resource<S,P>,~H:Type,~V:Data,cap:Write<S,P,identity,H,V>) -> H -> H & V:
31  match cap:
32    case Write{operation}:Cap.value_write_read_field(~H,~P,~V,operation)
33# Read detached V through a write-capable field grant without replacing P.
34def get(~S:Data,~P:Type,~identity:Schema.Resource<S,P>,~H:Type,~V:Data,~cap:Write<S,P,identity,H,V>,owner:H) -> H & V:
35  get_field(~S,~P,~identity,~H,~V,cap)(owner)
36# Advanced projection of the consuming selected-field setter.
37def set_field(~S:Data,~P:Type,~identity:Schema.Resource<S,P>,~H:Type,~V:Data,cap:Write<S,P,identity,H,V>) -> H -> P -> H:
38  match cap:
39    case Write{operation}:Cap.value_write_field(~H,~P,~V,operation)
40# Consume replacement P and return H through the bound setter. Adds no extra
41# validation, transaction finish or owned refusal result beyond that operation.
42def set(~S:Data,~P:Type,~identity:Schema.Resource<S,P>,~H:Type,~V:Data,~cap:Write<S,P,identity,H,V>,owner:H,replacement:P) -> H:
43  set_field(~S,~P,~identity,~H,~V,cap)(owner,replacement)
44# Operational grants and ordered resource clauses retained together. Canonical
45# builders bind identity to the selected lens; forged raw values are trusted setup.
46type Declaration<-S:Data,-H:Type,-Ops:Type> is Type:
47  Declaration{grant:Ops,clauses:List<&2,Q.Clause<S>>}
48# Build a selected-field read declaration from its canonical binding and view.
49# view must return actual P with detached V; canonical lenses preserve siblings.
50def read(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Rest:Type,~V:Data,~lens:Product.Lens<R,P,Rest>,~identity:Schema.Resource<S,P>,~binding:B.Binding<S,R,P,Rest,lens,identity>,~view:P -> P & V) -> Declaration<S,T.Tx<W.World<S,C,R,E>,E>,Read<S,P,identity,T.Tx<W.World<S,C,R,E>,E>,V>>:
51  Declaration{Read{Field.read(~S,~C,~R,~E,~P,~Rest,~V,~lens,~view)},[Q.Clause{Schema.resource_key(~S,~P,identity),Q.Read{}}]}
52# Build a selected-P replacement declaration with canonical binding identity.
53# Ordinary inverse journaling restores old P on failure; successful setters consume
54# replacement P without returning displaced payloads as a recovery receipt.
55def write(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Rest:Type,~V:Data,~lens:Product.Lens<R,P,Rest>,~identity:Schema.Resource<S,P>,~binding:B.Binding<S,R,P,Rest,lens,identity>,~view:P -> P & V) -> Declaration<S,T.Tx<W.World<S,C,R,E>,E>,Write<S,P,identity,T.Tx<W.World<S,C,R,E>,E>,V>>:
56  Declaration{Write{Field.write(~S,~C,~R,~E,~P,~Rest,~V,~lens,~view)},[Q.Clause{Schema.resource_key(~S,~P,identity),Q.Write{}}]}
57# Compose grants and clauses left before right, retaining both operations. This
58# does not deduplicate clauses or add a new alias/overlap policy.
59def pair(~S:Data,~H:Type,~L:Type,~R:Type,left:Declaration<S,H,L>,right:Declaration<S,H,R>) -> Declaration<S,H,Cap.Bundle<L,R>>:
60  match left right:
61    case Declaration{l,lc} Declaration{r,rc}:Declaration{Cap.Bundle{l,r},List.append(&2,Q.Clause<S>,lc,rc)}
62# Advanced projection of stored operational caps, without invocation.
63def grant(~S:Data,~H:Type,~Ops:Type,value:Declaration<S,H,Ops>) -> Ops:
64  match value:
65    case Declaration{grant,_}:grant
66# Advanced projection of detached clauses derived alongside the operational caps.
67def clauses(~S:Data,~H:Type,~Ops:Type,value:Declaration<S,H,Ops>) -> List<&2,Q.Clause<S>>:
68  match value:
69    case Declaration{_,clauses}:clauses
70# Ordered clause-name projection for registration, preserving duplicates/order.
71# No string normalization grants additional field authority.
72def access(~S:Data,clauses:List<&2,Q.Clause<S>>) -> List<&2,String>:
73  match clauses:
74    case []:[]
75    case Q.Clause{name,_} <> rest:name <> access(~S,rest)
76# Execute body once with opaque Tx caps from this field declaration and finish
77# the ECS transaction. Failure restores recorded fields, discards Out and suppresses
78# staged work; canonical lenses preserve siblings. No implicit structural barrier.
79def runner(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Args:Type,~Error:Data,~Out:Type,~declaration:Declaration<S,T.Tx<W.World<S,C,R,E>,E>,Ops(T.Tx<W.World<S,C,R,E>,E>)>,~body:@-H:Type -> @-caps:Ops(H) -> Args -> H -> H & (T.Outcome<Error> & Out),world:W.World<S,C,R,E>,args:Args) -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>:
80  Whole.finished(~S,~C,~R,~E,~Error,~Out,Cap.invoke_owned(~Ops,~Args,~(T.Outcome<Error> & Out),~body,~T.Tx<W.World<S,C,R,E>,E>,~grant(~S,~T.Tx<W.World<S,C,R,E>,E>,~Ops(T.Tx<W.World<S,C,R,E>,E>),declaration),args,T.begin(~W.World<S,C,R,E>,~E,world)))
81# Only actual Registry is runtime-owned; clauses are an erased generated index.
82# Actual registry owner indexed by erased generated field clauses; no copied
83# resource payload or independent runtime clause registry is stored.
84type Owner<-S:Data,-Registry:Type,-clauses:List<&2,Q.Clause<S>>> is Type:
85  Owner{registry:Registry}
86# Registration result returning World on success/refusal, with Owner only after
87# successful registry creation. This does not execute the resource body.
88type Defined<-S:Data,-World:Type,-Registry:Type,-clauses:List<&2,Q.Clause<S>>> is Type:
89  Defined{world:World,owner:Owner<S,Registry,clauses>}
90  Rejected{world:World}
91def registered(~S:Data,~C:Type,~R:Type,~E:Data,~Args:Type,~Error:Data,~Out:Type,~run:W.World<S,C,R,E> -> Args -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,~clauses:List<&2,Q.Clause<S>>,result:Sys.RegistrationResult<S,C,R,E,Args,Error,Out,run>) -> Defined<S,W.World<S,C,R,E>,Sys.Registry<S,C,R,E,Args,Error,Out,run>,clauses>:
92  match result:
93    case Sys.RegistrationFailed{world}:Rejected{world}
94    case Sys.Registered{world,registry}:Defined{world,Owner{registry}}
95# Register the field declaration/body using ordered derived access clauses.
96# Bindings, lenses and view functions are trusted setup, not arbitrary metadata
97# validation. Higher-level ordinary App resource-field declarations expose this.
98def define(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Args:Type,~Error:Data,~Out:Type,~declaration:Declaration<S,T.Tx<W.World<S,C,R,E>,E>,Ops(T.Tx<W.World<S,C,R,E>,E>)>,~body:@-H:Type -> @-caps:Ops(H) -> Args -> H -> H & (T.Outcome<Error> & Out),world:W.World<S,C,R,E>,name:String) -> Defined<S,W.World<S,C,R,E>,Sys.Registry<S,C,R,E,Args,Error,Out,runner(~S,~C,~R,~E,~Ops,~Args,~Error,~Out,~declaration,~body)>,clauses(~S,~T.Tx<W.World<S,C,R,E>,E>,~Ops(T.Tx<W.World<S,C,R,E>,E>),declaration)>:
99  registered(~S,~C,~R,~E,~Args,~Error,~Out,~runner(~S,~C,~R,~E,~Ops,~Args,~Error,~Out,~declaration,~body),~clauses(~S,~T.Tx<W.World<S,C,R,E>,E>,~Ops(T.Tx<W.World<S,C,R,E>,E>),declaration),Sys.register(~S,~C,~R,~E,~Args,~Error,~Out,~runner(~S,~C,~R,~E,~Ops,~Args,~Error,~Out,~declaration,~body),world,name,access(~S,clauses(~S,~T.Tx<W.World<S,C,R,E>,E>,~Ops(T.Tx<W.World<S,C,R,E>,E>),declaration))))
100# Run the actual registry through Sys.run. Full refusal returns registry,
101# World and unconsumed Args; normal completion retains the returned registry and
102# World. This wrapper does not execute the deferred command barrier.
103def run(~S:Data,~C:Type,~R:Type,~E:Data,~Args:Type,~Error:Data,~Out:Type,~run:W.World<S,C,R,E> -> Args -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,~clauses:List<&2,Q.Clause<S>>,owner:Owner<S,Sys.Registry<S,C,R,E,Args,Error,Out,run>,clauses>,world:W.World<S,C,R,E>,args:Args) -> Sys.RunResult<S,C,R,E,Args,Error,Out,run>:
104  match owner:
105    case Owner{registry}:Sys.run(~S,~C,~R,~E,~Args,~Error,~Out,~run,registry,world,args)
106
107# Trace-aware counterpart of runner with supplied/returned fact state. Same caps,
108# transaction decision and output disposal; observation adds no resource authority
109# and does not make attempted writes committed.
110def runner_observed(~S:Data,~C:Type,~R:Type,~E:Data,~Ops:Type -> Type,~Args:Type,~Error:Data,~Out:Type,~declaration:Declaration<S,T.Tx<W.World<S,C,R,E>,E>,Ops(T.Tx<W.World<S,C,R,E>,E>)>,~body:@-H:Type -> @-caps:Ops(H) -> Args -> H -> H & (T.Outcome<Error> & Out),trace:TraceFacts.State,world:W.World<S,C,R,E>,args:Args) -> Sys.Outcome<W.World<S,C,R,E>,Error,Out> & TraceFacts.State:
111  Whole.finished_observed(~S,~C,~R,~E,~Error,~Out,Cap.invoke_owned(~Ops,~Args,~(T.Outcome<Error> & Out),~body,~T.Tx<W.World<S,C,R,E>,E>,~grant(~S,~T.Tx<W.World<S,C,R,E>,E>,~Ops(T.Tx<W.World<S,C,R,E>,E>),declaration),args,T.begin_with_trace(~W.World<S,C,R,E>,~E,world,trace)))