1 import Base 2 import ./ordinary_query_declaration.bend as N 3 import ./ordinary_component_binding.bend as B 4 import ./ordinary_declaration.bend as Identity 5 import ./ordinary_query_selections.bend as F 6 import ./inspector_query_projection.bend as P 7 import ./inspector_query_families.bend as Families 8 import ./inspector_query_world.bend as IW 9 import ./inspector_query.bend as IQ 10 import ./inspector.bend as I 11 import ./compose.bend as Q 12 import ./column.bend as Col 13 import ./component.bend as C 14 import ./capabilities.bend as Cap 15 16 # One ordinary declaration delays both lowerings from the same component binding. 17 # Operational transaction authority never enters the detached read-only query. 18 # One query declaration supplies operational grants and detached inspection 19 # from the same bindings. Declaration uses the ordinary evaluator; the 20 # PreparedDeclaration variant also supplies an enumeration callback. Raw 21 # constructors are trusted adapters. Payload owners never enter detached V. 22 type Declaration<-S:Data,-H:Type,-G:Type,-IH:Type,-V:Data> is Type: 23 Declaration{operational:Unit -> N.Declaration,inspection:Unit -> P.DeclaredSelection} 24 PreparedDeclaration{operational:Unit -> N.Declaration,inspection:Unit -> P.DeclaredSelection,enumerate:IH -> IH & List<&2,IQ.ProjectedRow>} 25 # Consume the observable declaration and obtain its typed operational query. 26 # Does not enumerate rows or run a body; H remains the operational owner type. 27 def operational(~S:Data,~H:Type,~G:Type,~IH:Type,~V:Data,declaration:Declaration) -> N.Declaration: 28 match declaration: 29 case Declaration{operational,_}:operational(Unit{}) 30 case PreparedDeclaration{operational,_,_}:operational(Unit{}) 31 # Consume the declaration and obtain its detached read-only selection recipe. 32 # IH is separate from operational H; no write grant is transferred to inspection. 33 def inspection(~S:Data,~H:Type,~G:Type,~IH:Type,~V:Data,declaration:Declaration) -> P.DeclaredSelection: 34 match declaration: 35 case Declaration{_,inspection}:inspection(Unit{}) 36 case PreparedDeclaration{_,inspection,_}:inspection(Unit{}) 37 # Return declaration-derived query clauses for access/debug descriptions. 38 # Consumes this declaration value, without inspecting or modifying a world. 39 def clauses(~S:Data,~H:Type,~G:Type,~IH:Type,~V:Data,declaration:Declaration) -> List<&2,N.Clause>: 40 N.clauses(~S,~H,~G,operational(~S,~H,~G,~IH,~V,declaration)) 41 42 # Declare required component read access and the matching detached inspection. 43 # The trusted binding fixes schema and storage lenses. view consumes/returns 44 # Payload and exposes Data V; operational results are Found/ComponentAbsent/ 45 # MissingEntity, including stale/foreign rejection. No row is read at setup. 46 def read(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~binding:B.Binding) -> Declaration,Cap.Read,V>,I.Frame,C.Access>: 47 Declaration{_=>(N.read(~S,~Payload,~Store,~R,~E,~Rest,~V,~Token,~B.identity(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,binding),~view,~take,~put)),_=>(F.inspect_slot(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~view,~binding,~Families.Required{}))} 48 49 # Declare required component read/write access with read-only inspection. 50 # Writes consume replacement Payload; failed sets record an error for enclosing 51 # Compose execution/rollback and do not return rejected input through the grant. 52 # Detached inspection exposes only V and never authorizes a write. 53 def write(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~binding:B.Binding) -> Declaration,Cap.Write,Payload,V>,I.Frame,C.Access>: 54 Declaration{_=>(N.write(~S,~Payload,~Store,~R,~E,~Rest,~V,~Token,~B.identity(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,binding),~view,~take,~put)),_=>(F.inspect_slot(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~view,~binding,~Families.Required{}))} 55 56 # Declare read access without requiring component presence on a live row. 57 # Operational and detached selections preserve absence explicitly; stale/foreign 58 # handles remain MissingEntity rather than matching as optional live rows. 59 def optional(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~binding:B.Binding) -> Declaration,Cap.Read,V>,I.Frame,C.Access>: 60 Declaration{_=>(N.optional(~S,~Payload,~Store,~R,~E,~Rest,~V,~Token,~B.identity(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,binding),~view,~take,~put)),_=>(F.inspect_slot(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~view,~binding,~Families.Optional{}))} 61 62 # Require presence without granting payload operations; detached projection 63 # contributes Unit. Combine with pair for additional independently granted data. 64 def with_component(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~binding:B.Binding) -> Declaration,Unit,I.Frame,Unit>: 65 Declaration{_=>(N.with_component(~S,~Payload,~Store,~R,~E,~Rest,~V,~Token,~B.identity(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,binding),~view,~take,~put)),_=>(P.constrain(~I.Frame,~S,~Unit,~P.empty(~I.Frame,~S),~F.inspect_with(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~view,~binding)))} 66 67 # Require absence without granting payload operations; detached projection 68 # contributes Unit. Structural membership changes at explicit barriers. 69 def without_component(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~binding:B.Binding) -> Declaration,Unit,I.Frame,Unit>: 70 Declaration{_=>(N.without_component(~S,~Payload,~Store,~R,~E,~Rest,~V,~Token,~B.identity(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,binding),~view,~take,~put)),_=>(P.constrain(~I.Frame,~S,~Unit,~P.empty(~I.Frame,~S),~F.inspect_without(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~view,~binding)))} 71 72 # Add a lifecycle filter without payload access; inspection uses its supplied 73 # cursor and operational execution uses the registered system cursor. Merely 74 # constructing or inspecting this declaration advances neither system cursor. 75 def added(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~binding:B.Binding) -> Declaration,Unit,I.Frame,Unit>: 76 Declaration{_=>(N.added(~S,~Payload,~Store,~R,~E,~Rest,~V,~Token,~B.identity(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,binding),~view,~take,~put)),_=>(P.constrain(~I.Frame,~S,~Unit,~P.empty(~I.Frame,~S),~F.inspect_filter(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~view,~binding,~Q.Added{})))} 77 78 # Add a changed-since-cursor filter without payload access. The operational 79 # and Inspector owners retain separate cursor authority; declaration construction 80 # and detached inspection do not consume registered system visibility. 81 def changed(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~binding:B.Binding) -> Declaration,Unit,I.Frame,Unit>: 82 Declaration{_=>(N.changed(~S,~Payload,~Store,~R,~E,~Rest,~V,~Token,~B.identity(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,binding),~view,~take,~put)),_=>(P.constrain(~I.Frame,~S,~Unit,~P.empty(~I.Frame,~S),~F.inspect_filter(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~view,~binding,~Q.Changed{})))} 83 84 # Compose conjunctive selections from the same schema and owner types. 85 # Operational grants retain (L & R), detached values Product, and clause 86 # order is left then right. Nest pairs for arbitrary heterogeneous shapes. 87 # Example: examples/scheduled-health/registration.bend, query(). 88 def pair(~S:Data,~H:Type,~L:Type,~R:Type,~IH:Type,~LV:Data,~RV:Data,~left:Declaration,~right:Declaration) -> Declaration>: 89 Declaration{_=>(N.pair(~S,~H,~L,~R,~operational(~S,~H,~L,~IH,~LV,left),~operational(~S,~H,~R,~IH,~RV,right))),_=>(P.pair(~IH,~S,~LV,~RV,~inspection(~S,~H,~L,~IH,~LV,left),~inspection(~S,~H,~R,~IH,~RV,right)))} 90 def prepared_query(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,~selection:P.DeclaredSelection,S,V>,enumerate:I.Frame -> I.Frame & List<&2,IQ.ProjectedRow>) -> IQ.ComposedReadQuery,S,V>: 91 IQ.ComposedReadQuery{enumerate,owner=>target=>IQ.get_composed(~I.Frame,~S,~V,~IQ.grant_composed(~I.Frame,~S,~V,~selection,~IW.inspect_world(~S,~Store,~R,~E)),owner,target)} 92 def inspect_query_value(~S:Data,~Store:Type,~R:Type,~E:Data,~H:Type,~G:Type,~V:Data,~declaration:Declaration,V>,kind:Declaration,V>) -> IQ.ComposedReadQuery,S,V>: 93 match kind: 94 case Declaration{_,_}:IQ.grant_composed(~I.Frame,~S,~V,~inspection(~S,~H,~G,~I.Frame,~V,declaration),~IW.inspect_world(~S,~Store,~R,~E)) 95 case PreparedDeclaration{_,_,enumerate}:prepared_query(~S,~Store,~R,~E,~V,~inspection(~S,~H,~G,~I.Frame,~V,declaration),enumerate) 96 # Lower this observable declaration into an Inspector composed read query. 97 # Preserves prepared enumeration when present; supplies no write operations. 98 # Run it with the public Inspector owner, not a registered system owner, so 99 # detached observations do not consume system cursors or event retention. 100 def inspect_query(~S:Data,~Store:Type,~R:Type,~E:Data,~H:Type,~G:Type,~V:Data,~declaration:Declaration,V>) -> IQ.ComposedReadQuery,S,V>: 101 inspect_query_value(~S,~Store,~R,~E,~H,~G,~V,~declaration,declaration) 102 103 # Declare write access plus a formatter for detached Data V in enabled debug. 104 # Formatter receives no Payload owner; transaction/refusal semantics match write. 105 # Inspection remains read-only even though the operational grant permits writes. 106 def write_displayed(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~display:V -> String,~binding:B.Binding) -> Declaration,Cap.Write,Payload,V>,I.Frame,C.Access>: 107 Declaration{_=>(N.write_displayed(~S,~Payload,~Store,~R,~E,~Rest,~V,~Token,~B.identity(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,binding),~view,~display,~take,~put)),_=>(F.inspect_slot(~S,~Store,~R,~E,~Rest,~Payload,~V,~Token,~take,~put,~view,~binding,~Families.Required{}))}