ordinary_owned_event_family_publisher.bend
bendvy-ecs-core@0.1.0.0 · 55 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.0/trace_facts.bend as Facts
3import bendvy-ecs-core@0.1.0.0/world.bend as W
4import bendvy-ecs-core@0.1.0.0/system.bend as Sys
5import bendvy-ecs-core@0.1.0.0/transaction.bend as T
6import bendvy-ecs-core@0.1.0.0/owned_event_journal.bend as Journal
7import bendvy-ecs-core@0.1.0.0/ordinary_owned_event_declaration.bend as D
8# Standalone publisher runs once, including worlds without entities. Actual log
9# owners enter the world only after success; failure returns the typed receipt.
10# Publication decision with retained body Out and typed recovery owners.
11# Body Failure is inside Reply, not an outer System.Failed that would discard
12# Out/recovery. Commit/abort follows the canonical staged journal contract.
13type Reply<Error:Data,Out:Type,Recovery:Type> is Type:
14 Reply{outcome:T.Outcome<Error>,output:Out,recovered:Recovery}
15def finished(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Error:Data,~Out:Type,outcome:T.Outcome<Error>,output:Out,result:W.World<S,C,R,E> & Recovery) -> Sys.Outcome<W.World<S,C,R,E>,Unit,Reply<Error,Out,Recovery>>:
16 match result:
17 case (world,recovered):Sys.Succeeded{world,Reply{outcome,output,recovered}}
18def returned(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Error:Data,~Out:Type,world:W.World<S,C,R,E>,recovery:Recovery,result:Journal.Stage<W.World<S,C,R,E>,Recovery> & (T.Outcome<Error> & Out)) -> Sys.Outcome<W.World<S,C,R,E>,Unit,Reply<Error,Out,Recovery>>:
19 match result:
20 case (stage,(T.Success{},output)):finished(~S,~C,~R,~E,~Recovery,~Error,~Out,T.Success{},output,Journal.finish(~W.World<S,C,R,E>,~Recovery,stage,True{},world,recovery))
21 case (stage,(T.Failure{error},output)):finished(~S,~C,~R,~E,~Recovery,~Error,~Out,T.Failure{error},output,Journal.finish(~W.World<S,C,R,E>,~Recovery,stage,False{},world,recovery))
22# Advanced standalone staged publisher: invokes the opaque body once even
23# with no entities. Success commits staged log owners; failure returns typed
24# recovery for staged publication. No payload copying or arbitrary host-effect
25# rollback is provided. Use define/run for registration validation.
26def runner(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World<S,C,R,E>,~Recovery,~Ops),~declaration:D.Declaration<S,W.World<S,C,R,E>,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome<Error> & Out),world:W.World<S,C,R,E>,args:Args) -> Sys.Outcome<W.World<S,C,R,E>,Unit,Reply<Error,Out,Recovery>>:
27 returned(~S,~C,~R,~E,~Recovery,~Error,~Out,world,D.empty(~S,~W.World<S,C,R,E>,~Recovery,~Ops,~builder,declaration)(Unit{}),body(Journal.Stage<W.World<S,C,R,E>,Recovery>,D.root_grant(~S,~W.World<S,C,R,E>,~Recovery,~Ops,~builder),args,Journal.empty(~W.World<S,C,R,E>,~Recovery)))
28# Advanced type alias for the publisher's actual closed runner registration.
29# Keep it with its matching World; raw construction is trusted administration.
30def Registry(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World<S,C,R,E>,~Recovery,~Ops),~declaration:D.Declaration<S,W.World<S,C,R,E>,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome<Error> & Out)) -> Type:Sys.Registry<S,C,R,E,Args,Unit,Reply<Error,Out,Recovery>,runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body)>
31# Register a staged publisher with access from its owned-event declaration.
32# Returns System registration result retaining World on refusal. Does not
33# execute body or publish events while registering.
34def define(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World<S,C,R,E>,~Recovery,~Ops),~declaration:D.Declaration<S,W.World<S,C,R,E>,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome<Error> & Out),world:W.World<S,C,R,E>,name:String) -> Sys.RegistrationResult<S,C,R,E,Args,Unit,Reply<Error,Out,Recovery>,runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body)>:
35 Sys.register(~S,~C,~R,~E,~Args,~Unit,~Reply<Error,Out,Recovery>,~runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body),world,name,D.access(~S,~W.World<S,C,R,E>,~Recovery,~Ops,~builder,declaration))
36# Validate the publisher registration, then execute its staged body.
37# Admission refusal returns original Args/Registry/World. Completion is outer
38# Succeeded with Reply containing actual publication outcome, Out and typed
39# recovery; inspect Reply.outcome rather than assuming publication succeeded.
40# Publication contract: docs/parity/affine-events.md.
41def run(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World<S,C,R,E>,~Recovery,~Ops),~declaration:D.Declaration<S,W.World<S,C,R,E>,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome<Error> & Out),registry:Sys.Registry<S,C,R,E,Args,Unit,Reply<Error,Out,Recovery>,runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body)>,world:W.World<S,C,R,E>,args:Args) -> Sys.RunResult<S,C,R,E,Args,Unit,Reply<Error,Out,Recovery>,runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body)>:
42 Sys.run(~S,~C,~R,~E,~Args,~Unit,~Reply<Error,Out,Recovery>,~runner(~S,~C,~R,~E,~Recovery,~Ops,~builder,~declaration,~Args,~Error,~Out,~body),registry,world,args)
43
44def finished_observed(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Error:Data,~Out:Type,outcome:T.Outcome<Error>,output:Out,result:(W.World<S,C,R,E> & Recovery) & Facts.State) -> Sys.Outcome<W.World<S,C,R,E>,Unit,Reply<Error,Out,Recovery>> & Facts.State:
45 match result:
46 case ((world,recovered),trace):(Sys.Succeeded{world,Reply{outcome,output,recovered}},trace)
47def returned_observed(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Error:Data,~Out:Type,world:W.World<S,C,R,E>,recovery:Recovery,result:Journal.Stage<W.World<S,C,R,E>,Recovery> & (T.Outcome<Error> & Out)) -> Sys.Outcome<W.World<S,C,R,E>,Unit,Reply<Error,Out,Recovery>> & Facts.State:
48 match result:
49 case (stage,(T.Success{},output)):finished_observed(~S,~C,~R,~E,~Recovery,~Error,~Out,T.Success{},output,Journal.finish_observed(~W.World<S,C,R,E>,~Recovery,stage,True{},world,recovery))
50 case (stage,(T.Failure{error},output)):finished_observed(~S,~C,~R,~E,~Recovery,~Error,~Out,T.Failure{error},output,Journal.finish_observed(~W.World<S,C,R,E>,~Recovery,stage,False{},world,recovery))
51# Advanced traced adapter for the same publisher body and typed recovery.
52# Returns the actual outcome with settled journal facts; observation does not
53# commit additional payloads or change failure recovery semantics.
54def runner_observed(~S:Data,~C:Type,~R:Type,~E:Data,~Recovery:Type,~Ops:Type -> Type,~builder:D.Builder(~W.World<S,C,R,E>,~Recovery,~Ops),~declaration:D.Declaration<S,W.World<S,C,R,E>,Recovery,Ops,builder>,~Args:Type,~Error:Data,~Out:Type,~body:@-J:Type -> @-caps:Ops(J) -> Args -> J -> J & (T.Outcome<Error> & Out),trace:Facts.State,world:W.World<S,C,R,E>,args:Args) -> Sys.Outcome<W.World<S,C,R,E>,Unit,Reply<Error,Out,Recovery>> & Facts.State:
55 returned_observed(~S,~C,~R,~E,~Recovery,~Error,~Out,world,D.empty(~S,~W.World<S,C,R,E>,~Recovery,~Ops,~builder,declaration)(Unit{}),body(Journal.Stage<W.World<S,C,R,E>,Recovery>,D.root_grant(~S,~W.World<S,C,R,E>,~Recovery,~Ops,~builder),args,Journal.with_trace(~W.World<S,C,R,E>,~Recovery,trace)))