Module: Statecraft::Introspection
- Defined in:
- lib/statecraft/introspection.rb
Overview
The record-facing questions: "would the guards pass if I fired this transition with these metadata right now". Normalization and freeze are identical to the pipeline's, so a guard that mutates metadata fails the same way in a check as in a transition, and the answer never diverges from what fire! would actually do. Every answer is a snapshot: CAS may still reject the transition later.
Defined Under Namespace
Classes: Availability, Refusal
Instance Method Summary collapse
- #available_events(metadata: {}) ⇒ Object
- #available_transitions(metadata: {}) ⇒ Object
- #can_fire?(event_name, metadata: {}) ⇒ Boolean
-
#offerable_events ⇒ Object
The offering: which events the graph AND this record allow from here — the record layer alone, so an input-reading guard never hides the form its input arrives through.
-
#refusals_for(event_name) ⇒ Object
The structured "why not": every record-layer guard refusing the event right now.
- #transitioned_to?(state_name) ⇒ Boolean
Instance Method Details
#available_events(metadata: {}) ⇒ Object
25 26 27 28 29 30 31 32 33 |
# File 'lib/statecraft/introspection.rb', line 25 def available_events(metadata: {}) normalized = Metadata.normalize() statecraft_graph.events.filter_map do |event_name, branches| edge = branches[statecraft_current_state] next unless edge event_name if statecraft_guards_pass?(edge, event_name, normalized) end end |
#available_transitions(metadata: {}) ⇒ Object
35 36 37 38 39 40 41 42 43 |
# File 'lib/statecraft/introspection.rb', line 35 def available_transitions(metadata: {}) normalized = Metadata.normalize() statecraft_graph.edges.filter_map do |(from, _to), edge| next unless from == statecraft_current_state via = statecraft_passable_via(edge, normalized) Availability.new(to: edge.to, via: via) unless via.empty? end end |
#can_fire?(event_name, metadata: {}) ⇒ Boolean
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/statecraft/introspection.rb', line 14 def can_fire?(event_name, metadata: {}) graph = statecraft_graph branches = graph.events[event_name.to_sym] return false unless branches edge = branches[statecraft_current_state] return false unless edge statecraft_guards_pass?(edge, event_name.to_sym, Metadata.normalize()) end |
#offerable_events ⇒ Object
The offering: which events the graph AND this record allow from here — the record layer alone, so an input-reading guard never hides the form its input arrives through. A snapshot, like every question here.
52 53 54 55 56 57 58 59 |
# File 'lib/statecraft/introspection.rb', line 52 def offerable_events statecraft_graph.events.filter_map do |event_name, branches| edge = branches[statecraft_current_state] next unless edge event_name if statecraft_record_refusals(edge, event_name).empty? end end |
#refusals_for(event_name) ⇒ Object
The structured "why not": every record-layer guard refusing the event right now. Guard handlers by name, no words — the words belong to the presentation. An unknown event or a missing branch answers [].
64 65 66 67 68 69 70 71 72 |
# File 'lib/statecraft/introspection.rb', line 64 def refusals_for(event_name) branches = statecraft_graph.events[event_name.to_sym] return [].freeze unless branches edge = branches[statecraft_current_state] return [].freeze unless edge statecraft_record_refusals(edge, event_name.to_sym) end |
#transitioned_to?(state_name) ⇒ Boolean
45 46 47 |
# File 'lib/statecraft/introspection.rb', line 45 def transitioned_to?(state_name) history.where(to_state: state_name.to_s).exists? end |