ordinary_app_relation_failure_reader.bend
bendvy-ecs-core@0.1.0.1 · 77 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.1/ordinary_app_composer.bend as Build
3import bendvy-ecs-core@0.1.0.1/ordinary_app_observation_data.bend as DTO
4import bendvy-ecs-core@0.1.0.1/ordinary_app_records.bend as Records
5import bendvy-ecs-core@0.1.0.1/ordinary_app_recipe.bend as Tree
6import bendvy-ecs-core@0.1.0.1/internal/relation_failures/domains.bend as D
7import bendvy-ecs-core@0.1.0.1/world.bend as W
8import bendvy-ecs-core@0.1.0.1/system.bend as Sys
9import bendvy-ecs-core@0.1.0.1/relation_commands.bend as Notice
10import bendvy-ecs-core@0.1.0.1/relation_types.bend as G
11import bendvy-ecs-core@0.1.0.1/relation_failure_runtime.bend as K
12import bendvy-ecs-core@0.1.0.1/relation_failure_reader.bend as Decl
13import bendvy-ecs-core@0.1.0.1/event_notice_runtime.bend as Mixed
14import bendvy-ecs-core@0.1.0.1/event_family_runtime.bend as Family
15import bendvy-ecs-core@0.1.0.1/event_family_routing.bend as Route
16import bendvy-ecs-core@0.1.0.1/ordinary_app_registration_fields.bend as Fields
17import bendvy-ecs-core@0.1.0.1/ordinary_query_declaration.bend as Query
18
19# Retains the same operative declaration and the actual descriptor Reader/Registry.
20type Owner<S:Data,Reader:Type> is Type:Owner{declaration:Decl.Declaration<S>,reader:Reader}
21# Specialize the affine reader owner to its world, argument and runner types.
22def OwnerType(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>) -> Type:Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,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.
25def fields(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>,owner:Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>>) -> Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>> & List<&2,Fields.Fields<S>>:
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.
30type Registration<S:Data,C:Type,R:Type,P:Data,F:Type,H:Type,Owner:Type> is Type:
31 Registered{runtime:Route.Runtime<S,C,R,Notice.Notice<S,P>,Mixed.State<S,P,F,H>>,owner:Owner}
32 RegistrationFailed{runtime:Route.Runtime<S,C,R,Notice.Notice<S,P>,Mixed.State<S,P,F,H>>}
33def registered(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>,~F:Type,~H:Type,held:Family.State<P,F,H> & Nat,declaration:Decl.Declaration<S>,result:K.Registered<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>) -> Registration<S,C,R,P,F,H,Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,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.
39def register_detached(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>,~F:Type,~H:Type,+declaration:Decl.Declaration<S>,name:String,detached:K.Runtime<S,C,R,Notice.Notice<S,P>> & Family.State<P,F,H> & Nat) -> Registration<S,C,R,P,F,H,Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,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<S,P>,~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.
44def register(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>,~F:Type,~H:Type,runtime:Route.Runtime<S,C,R,Notice.Notice<S,P>,Mixed.State<S,P,F,H>>,declaration:Decl.Declaration<S>,name:String) -> Registration<S,C,R,P,F,H,Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,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.
47type RunResult<S:Data,C:Type,R:Type,P:Data,F:Type,H:Type,Owner:Type,Error:Data,Out:Type,A:Type> is Type:
48 Ran{runtime:Route.Runtime<S,C,R,Notice.Notice<S,P>,Mixed.State<S,P,F,H>>,owner:Owner,completion:K.Completion<Error,Out,A>}
49def ran(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>,~F:Type,~H:Type,declaration:Decl.Declaration<S>,held:Family.State<P,F,H> & Nat,result:K.RunResult<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>) -> RunResult<S,C,R,P,F,H,Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,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}
52def completed_owner(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>,~F:Type,~H:Type,~classify:Notice.Notice<S,P> -> Maybe<D.DescriptorKey<S>>,held:Family.State<P,F,H> & Nat,runtime:K.Runtime<S,C,R,Notice.Notice<S,P>>,args:A,owner:Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>>) -> RunResult<S,C,R,P,F,H,Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,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<S,P>,~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.
57def run_detached(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>,~F:Type,~H:Type,~classify:Notice.Notice<S,P> -> Maybe<D.DescriptorKey<S>>,owner:Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>>,args:A,detached:K.Runtime<S,C,R,Notice.Notice<S,P>> & Family.State<P,F,H> & Nat) -> RunResult<S,C,R,P,F,H,Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,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.
68def run(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>,~F:Type,~H:Type,~classify:Notice.Notice<S,P> -> Maybe<D.DescriptorKey<S>>,runtime:Route.Runtime<S,C,R,Notice.Notice<S,P>,Mixed.State<S,P,F,H>>,owner:Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>>,args:A) -> RunResult<S,C,R,P,F,H,Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,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.
71def observe(~S:Data,~C:Type,~R:Type,~P:Data,world:W.World<S,C,R,Notice.Notice<S,P>>) -> W.World<S,C,R,Notice.Notice<S,P>> & DTO.Observation<Unit>:(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.
75def append(~S:Data,~C:Type,~R:Type,~P:Data,~A:Type,~Error:Data,~Out:Type,~runner:W.World<S,C,R,Notice.Notice<S,P>> -> K.Input<S,Notice.Notice<S,P>,A> -> Sys.Outcome<W.World<S,C,R,Notice.Notice<S,P>>,Error,Out>,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,Notice.Notice<S,P>> -> W.World<S,C,R,Notice.Notice<S,P>> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,owner:Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>>,value:Build.Registered<S,W.World<S,C,R,Notice.Notice<S,P>>,Owners,Rows,prior,fold>) -> Build.Registered<S,W.World<S,C,R,Notice.Notice<S,P>>,Owners & Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>>,DTO.Product<Rows,Unit>,Tree.observe_pair(~W.World<S,C,R,Notice.Notice<S,P>>,~Rows,~Unit,~prior,~observe(~S,~C,~R,~P)),Records.fold_pair(~S,~Owners,~Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,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<S,C,R,Notice.Notice<S,P>>,~Owners,~Rows,~prior,~fold,~Owner<S,K.Reader<S,C,R,Notice.Notice<S,P>,A,Error,Out,runner>>,~Unit,~observe(~S,~C,~R,~P),~fields(~S,~C,~R,~P,~A,~Error,~Out,~runner),world,owners,owner,debug)