1 import Base 2 import ./change_tick.bend as Tick 3 import ./event_runtime.bend as Ev 4 import ./relation_commands.bend as A 5 import ./capabilities.bend as Cap 6 import ./inspector_stream_frame.bend as F 7 import ./inspector_transition_projection.bend as T 8 import ./inspector_failure_projection.bend as Fail 9 import ./machine_stream.bend as St 10 11 # Detached machine transition log and declaration-scoped relation failure view. 12 # Does not contain mutable World ownership or a new reader acknowledgement. 13 type Values is Data: 14 Values{transitions:T.TransitionLog,failures:Fail.FailureView} 15 # Detached transition name plus projected stream values, not a restorable save. 16 type Description is Data: 17 Description{name:String,values:Values} 18 # Project the authored transition declaration name without reading runtime state. 19 def transition_name(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & St.Stream,declaration:T.Declaration) -> String: 20 match declaration: 21 case T.Declaration{name}:name 22 # Actual event Runtime and heterogeneous owners with a separate U32 observation 23 # cursor/debug flag. Transition/failure declarations index the available views; 24 # raw projection adapters remain trusted. This is not a second stream registry. 25 type Application R & St.Stream,-transition:T.Declaration,-failure:Fail.Declaration> is Type: 26 Application{runtime:Ev.Runtime>,owners:H,cursor:Maybe<&2,Tick.Tick>,debug:Bool} 27 def failure_done(~S:Data,~K:Data,~V:Data,~E:Data,~H:Type,transitions:T.TransitionLog,returned:H & Fail.FailureView) -> H & Values: 28 (owner,failures)=returned 29 (owner,Values{transitions,failures}) 30 def transition_done(~S:Data,~K:Data,~V:Data,~E:Data,~H:Type,~grant:Cap.ValueRead>,returned:H & T.TransitionLog) -> H & Values: 31 (owner,transitions)=returned 32 failure_done(~S,~K,~V,~E,~H,transitions,Cap.value_read(~H,~Fail.FailureView,~grant,owner)) 33 def transition_grant(~S:Data,~K:Data,~V:Data,~E:Data,~H:Type,grants:Cap.ValueRead> & Cap.ValueRead>) -> Cap.ValueRead>: 34 (transition,_)=grants 35 transition 36 def failure_grant(~S:Data,~K:Data,~V:Data,~E:Data,~H:Type,grants:Cap.ValueRead> & Cap.ValueRead>) -> Cap.ValueRead>: 37 (_,failure)=grants 38 failure 39 def selected(~S:Data,~K:Data,~V:Data,~E:Data,~H:Type,~grants:Cap.ValueRead> & Cap.ValueRead>,args:Unit,owner:H) -> H & Values: 40 transition_done(~S,~K,~V,~E,~H,~failure_grant(~S,~K,~V,~E,~H,grants),Cap.value_read(~H,~T.TransitionLog,~transition_grant(~S,~K,~V,~E,~H,grants),owner)) 41 # Retain the actual runtime/owners and supplied observation cursor with debug off. 42 # Does not register a reader, synchronize publications or advance the cursor. 43 def bind(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~H:Type,~take:R -> R & St.Stream,~transition:T.Declaration,~failure:Fail.Declaration,runtime:Ev.Runtime>,owners:H,cursor:Maybe<&2,Tick.Tick>) -> Application: 44 Application{runtime,owners,cursor,False{}} 45 def read_finished(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~H:Type,~take:R -> R & St.Stream,~transition:T.Declaration,~failure:Fail.Declaration,owners:H,debug:Bool,returned:F.Frame & Values) -> Application & Values: 46 match returned: 47 case (F.Frame{runtime,cursor},values):(Application{runtime,owners,cursor,debug},values) 48 # Read transition projection then selected relation failures through confined 49 # inspector grants, returning actual runtime/owners and detached Values. This entry 50 # is explicit reading regardless of debug flag; it preserves the supplied cursor 51 # and does not advance/acknowledge event readers or change retention boundaries. 52 # The transition resource projector must return its actual resource owner. 53 def read_app(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~H:Type,~take:R -> R & St.Stream,~transition:T.Declaration,~failure:Fail.Declaration,app:Application) -> Application & Values: 54 match app: 55 case Application{runtime,owners,cursor,debug}:read_finished(~S,~K,~V,~C,~R,~E,~H,~take,~transition,~failure,owners,debug,Cap.invoke(~(Owner => Cap.ValueRead> & Cap.ValueRead>),~Unit,~Values,~selected(~S,~K,~V,~E),~F.Frame,~(T.inspect(~S,~K,~V,~C,~R,~E,~take,~transition),Fail.inspect(~S,~C,~R,~E,~failure)),Unit{},F.Frame{runtime,cursor})) 56 # Set observation enablement, retaining runtime, owners and cursor unchanged. 57 def enabled(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~H:Type,~take:R -> R & St.Stream,~transition:T.Declaration,~failure:Fail.Declaration,app:Application,flag:Bool) -> Application: 58 match app: 59 case Application{runtime,owners,cursor,_}:Application{runtime,owners,cursor,flag} 60 def snapshot_read(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~H:Type,~take:R -> R & St.Stream,~transition:T.Declaration,~failure:Fail.Declaration,returned:Application & Values) -> Application & Maybe<&2,Description>: 61 (app,values)=returned 62 (app,Some{Description{transition_name(~S,~K,~V,~R,~take,transition),values}}) 63 # Return App and optional stream Description. Disabled returns None before either 64 # projection. Enabled uses read_app without advancing cursor, running gameplay or 65 # flushing commands. Failure view filters its declaration relation, not all shared 66 # Notice payloads. See inspector-transition/failure-projection.bend. 67 def snapshot(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~H:Type,~take:R -> R & St.Stream,~transition:T.Declaration,~failure:Fail.Declaration,app:Application) -> Application & Maybe<&2,Description>: 68 match app: 69 case Application{runtime,owners,cursor,False{}}:(Application{runtime,owners,cursor,False{}},None{}) 70 case Application{runtime,owners,cursor,True{}}:snapshot_read(~S,~K,~V,~C,~R,~E,~H,~take,~transition,~failure,read_app(~S,~K,~V,~C,~R,~E,~H,~take,~transition,~failure,Application{runtime,owners,cursor,True{}})) 71 def with_runtime_finished(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~H:Type,~take:R -> R & St.Stream,~transition:T.Declaration,~failure:Fail.Declaration,~O:Type,owners:H,cursor:Maybe<&2,Tick.Tick>,debug:Bool,returned:Ev.Runtime> & O) -> Application & O: 72 (runtime,out)=returned 73 (Application{runtime,owners,cursor,debug},out) 74 # Advanced effect adapter threading actual Runtime and returning Out while retaining 75 # App owners/cursor/debug. The effect chooses any synchronization/frame changes; 76 # this wrapper supplies no transaction, implicit acknowledgement or cleanup. 77 def with_runtime(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~H:Type,~take:R -> R & St.Stream,~transition:T.Declaration,~failure:Fail.Declaration,~O:Type,effect:Ev.Runtime> -> Ev.Runtime> & O,app:Application) -> Application & O: 78 match app: 79 case Application{runtime,owners,cursor,debug}:with_runtime_finished(~S,~K,~V,~C,~R,~E,~H,~take,~transition,~failure,~O,owners,cursor,debug,effect(runtime))