1 import Base 2 import ./ordinary_app_composer.bend as Build 3 import ./ordinary_app_observation_data.bend as DTO 4 import ./ordinary_app_records.bend as Records 5 import ./ordinary_app_recipe.bend as Tree 6 import ./internal/relation_failures/domains.bend as D 7 import ./world.bend as W 8 import ./system.bend as Sys 9 import ./relation_commands.bend as Notice 10 import ./relation_types.bend as G 11 import ./relation_failure_runtime.bend as K 12 import ./relation_failure_reader.bend as Decl 13 import ./event_notice_runtime.bend as Mixed 14 import ./event_family_runtime.bend as Family 15 import ./event_family_routing.bend as Route 16 import ./ordinary_app_registration_fields.bend as Fields 17 import ./ordinary_query_declaration.bend as Query 18 19 # Retains the same operative declaration and the actual descriptor Reader/Registry. 20 type Owner is Type:Owner{declaration:Decl.Declaration,reader:Reader} 21 # Specialize the affine reader owner to its world, argument and runner types. 22 def OwnerType(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>) -> Type:Owner,A,Error,Out,runner>> 23 # Return the same reader owner with detached registration/debug fields, including 24 # its current registry cursor and the declared relation read clause. 25 def fields(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>,owner:Owner,A,Error,Out,runner>>) -> Owner,A,Error,Out,runner>> & List<&2,Fields.Fields>: 26 match owner: 27 case Owner{Decl.Declaration{G.Descriptor{+key,+name,+inverse,+kind}},K.Reader{Sys.Registry{+namespace,+id,+systemName,+access,+cursor},+keys,readerId}}:(Owner{Decl.Declaration{G.Descriptor{key,name,inverse,kind}},K.Reader{Sys.Registry{namespace,id,systemName,access,cursor},keys,readerId}},[Fields.Fields{namespace,id,systemName,access,cursor,name,[Query.Clause{name,Query.Read{}}],Fields.EventKind{}}]) 28 # Registration returns the mixed runtime on both branches; only Registered 29 # supplies a reader owner. Other event-family state is reattached on refusal. 30 type Registration is Type: 31 Registered{runtime:Route.Runtime,Mixed.State>,owner:Owner} 32 RegistrationFailed{runtime:Route.Runtime,Mixed.State>} 33 def registered(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>,~F:Type,~H:Type,held:Family.State & Nat,declaration:Decl.Declaration,result:K.Registered,A,Error,Out,runner>) -> Registration,A,Error,Out,runner>>>: 34 match result: 35 case K.RegistrationFailed{runtime}:RegistrationFailed{Mixed.failure_returned(~S,~C,~R,~P,~F,~H,held,runtime)} 36 case K.Registered{runtime,reader}:Registered{Mixed.failure_returned(~S,~C,~R,~P,~F,~H,held,runtime),Owner{declaration,reader}} 37 # Advanced registration from a detached failure runtime and held family state. 38 # Reattach that state on success or refusal; select the single declared relation. 39 def register_detached(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>,~F:Type,~H:Type,+declaration:Decl.Declaration,name:String,detached:K.Runtime> & Family.State & Nat) -> Registration,A,Error,Out,runner>>>: 40 match detached: 41 case (runtime,held):registered(~S,~C,~R,~P,~A,~Error,~Out,~runner,~F,~H,held,declaration,Decl.register(~S,~C,~R,~Notice.Notice,~A,~Error,~Out,~runner,runtime,[declaration],name)) 42 # Register an independent reader for this relation declaration in the mixed 43 # runtime. Return its owner on success, or RegistrationFailed with the runtime. 44 def register(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>,~F:Type,~H:Type,runtime:Route.Runtime,Mixed.State>,declaration:Decl.Declaration,name:String) -> Registration,A,Error,Out,runner>>>:register_detached(~S,~C,~R,~P,~A,~Error,~Out,~runner,~F,~H,declaration,name,Mixed.failure_runtime(~S,~C,~R,~P,~F,~H,runtime)) 45 # Every completion returns the runtime and reader owner. Inspect completion 46 # for output, system failure or refusal rather than interpreting Ran as success. 47 type RunResult is Type: 48 Ran{runtime:Route.Runtime,Mixed.State>,owner:Owner,completion:K.Completion} 49 def ran(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>,~F:Type,~H:Type,declaration:Decl.Declaration,held:Family.State & Nat,result:K.RunResult,A,Error,Out,runner>) -> RunResult,A,Error,Out,runner>>,Error,Out,A>: 50 match result: 51 case K.Ran{runtime,reader,completion}:Ran{Mixed.failure_returned(~S,~C,~R,~P,~F,~H,held,runtime),Owner{declaration,reader},completion} 52 def completed_owner(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>,~F:Type,~H:Type,~classify:Notice.Notice -> Maybe>,held:Family.State & Nat,runtime:K.Runtime>,args:A,owner:Owner,A,Error,Out,runner>>) -> RunResult,A,Error,Out,runner>>,Error,Out,A>: 53 match owner: 54 case Owner{declaration,reader}:ran(~S,~C,~R,~P,~A,~Error,~Out,~runner,~F,~H,declaration,held,K.run(~S,~C,~R,~Notice.Notice,~A,~Error,~Out,~runner,~classify,runtime,reader,args)) 55 # Advanced execution with already detached failure/family state. Reattach the 56 # family state and return the reader owner for every underlying completion. 57 def run_detached(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>,~F:Type,~H:Type,~classify:Notice.Notice -> Maybe>,owner:Owner,A,Error,Out,runner>>,args:A,detached:K.Runtime> & Family.State & Nat) -> RunResult,A,Error,Out,runner>>,Error,Out,A>: 58 match detached: 59 case (runtime,held):completed_owner(~S,~C,~R,~P,~A,~Error,~Out,~runner,~F,~H,~classify,held,runtime,args,owner) 60 # Run this registered relation reader through the failure runtime, returning 61 # its updated owner and completion. The trusted classify callback identifies 62 # relation failures; use the same schema and notice classification as registration. 63 # Readings use this reader's independent position and report retained-history lag. 64 # Success acknowledges through the returned clock; failure does not acknowledge 65 # new notices, but may activate a missing position. Rejection returns args without 66 # advancing reader positions. World recovery follows the supplied runner contract. 67 # See relation-failure-runtime.bend for completion and retention details. 68 def run(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>,~F:Type,~H:Type,~classify:Notice.Notice -> Maybe>,runtime:Route.Runtime,Mixed.State>,owner:Owner,A,Error,Out,runner>>,args:A) -> RunResult,A,Error,Out,runner>>,Error,Out,A>:run_detached(~S,~C,~R,~P,~A,~Error,~Out,~runner,~F,~H,~classify,owner,args,Mixed.failure_runtime(~S,~C,~R,~P,~F,~H,runtime)) 69 # Composer observation for a reader registration: preserve the world and emit 70 # Unit with no rows. This does not execute or acknowledge the reader. 71 def observe(~S:Data,~C:Type,~R:Type,~P:Data,world:W.World>) -> W.World> & DTO.Observation:(world,DTO.Observation{Unit{},[]}) 72 # Append an existing reader owner to an App registration product. Preserve 73 # previous observations, add Unit rows and fold this reader's debug fields; 74 # appending alone does not run the reader. 75 def append(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World> -> K.Input,A> -> Sys.Outcome>,Error,Out>,~Owners:Type,~Rows:Data,~prior:W.World> -> W.World> & DTO.Observation,~fold:Owners -> Owners & List<&2,Fields.Fields>,owner:Owner,A,Error,Out,runner>>,value:Build.Registered>,Owners,Rows,prior,fold>) -> Build.Registered>,Owners & Owner,A,Error,Out,runner>>,DTO.Product,Tree.observe_pair(~W.World>,~Rows,~Unit,~prior,~observe(~S,~C,~R,~P)),Records.fold_pair(~S,~Owners,~Owner,A,Error,Out,runner>>,~fold,~fields(~S,~C,~R,~P,~A,~Error,~Out,~runner))>: 76 match value: 77 case Build.Registered{world,owners,_,debug}:Build.appended(~S,~W.World>,~Owners,~Rows,~prior,~fold,~Owner,A,Error,Out,runner>>,~Unit,~observe(~S,~C,~R,~P),~fields(~S,~C,~R,~P,~A,~Error,~Out,~runner),world,owners,owner,debug)