Class: Phronomy::Workflow::Builder
- Inherits:
-
Object
- Object
- Phronomy::Workflow::Builder
- Defined in:
- lib/phronomy/workflow.rb
Overview
DSL builder for Phronomy::Workflow.define. Collects state/event/transition declarations and produces a WorkflowRunner.
Constant Summary collapse
- FINISH =
Phronomy::WorkflowRunner::FINISH
Instance Method Summary collapse
-
#build ⇒ Object
Builds and returns a Phronomy::Workflow backed by a WorkflowRunner.
-
#entry(name, callable) ⇒ Object
Declares an entry action for a state.
-
#exit(name, callable) ⇒ Object
Declares an exit action for a state.
-
#initial(state_name) ⇒ Object
Declares the initial (entry) state.
-
#initialize(context_class, state_store: nil) ⇒ Builder
constructor
A new instance of Builder.
-
#state(name, action: nil) ⇒ Object
Declares an action state.
-
#transition(from:, to:, guard: nil, on: nil) ⇒ Object
Declares a transition between states.
-
#wait_state(name) ⇒ Object
Declares a wait state that automatically halts execution when reached.
Constructor Details
#initialize(context_class, state_store: nil) ⇒ Builder
Returns a new instance of Builder.
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/phronomy/workflow.rb', line 128 def initialize(context_class, state_store: nil) @context_class = context_class @state_store = state_store @initial = nil # Ordered list of declared state names (action states only, not wait states). @declared_states = [] # { state_name => [callable, ...] } — entry actions registered via entry() @entry_actions = {} # { state_name => [callable, ...] } — exit actions registered via exit() @exit_actions = {} # Array of { from:, to:, guard:, on: } — all transitions in declaration order @transitions = [] # Set of wait state names @wait_state_names = [] end |
Instance Method Details
#build ⇒ Object
Builds and returns a Phronomy::Workflow backed by a WorkflowRunner. Performs build-time validation of the graph structure:
- raises ArgumentError when no initial state is declared and no states have been defined
- raises ArgumentError when a transition references an undeclared target state
- warns when declared states are unreachable from the initial state
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/phronomy/workflow.rb', line 283 def build entry_actions = @entry_actions.dup exit_actions = @exit_actions.dup validate_graph! # Auto-fire transitions (no :on): fire automatically when action completes. # External events (with :on): triggered manually via send_event. auto_transitions = [] external_events = {} @transitions.each do |t| if t[:on] external_events[t[:on]] ||= [] external_events[t[:on]] << {from: t[:from], to: t[:to], guard: t[:guard]} else auto_transitions << {from: t[:from], to: t[:to], guard: t[:guard]} end end runner = Phronomy::WorkflowRunner.new( state_class: @context_class, entry_actions: entry_actions, exit_actions: exit_actions, declared_states: @declared_states.dup, auto_transitions: auto_transitions, external_events: external_events, entry_point: @initial || @declared_states.first, wait_state_names: @wait_state_names, state_store: @state_store ) Workflow.new(runner) end |
#entry(name, callable) ⇒ Object
Declares an entry action for a state. The callable is invoked when the workflow enters +name+. It receives the current context. Two styles are supported:
- Mutation-in-place: mutate context fields directly (+s.field = value+); the return value is ignored.
- Immutable update: return a new context via +s.merge(field: value)+; the returned context replaces the current one. Multiple calls for the same state are allowed; callables fire in declaration order.
175 176 177 |
# File 'lib/phronomy/workflow.rb', line 175 def entry(name, callable) (@entry_actions[name] ||= []) << callable end |
#exit(name, callable) ⇒ Object
Declares an exit action for a state. The callable is invoked when the workflow leaves +name+. It receives the current context and should mutate it in place. Return value is ignored. Multiple calls for the same state are allowed; callables fire in declaration order.
187 188 189 |
# File 'lib/phronomy/workflow.rb', line 187 def exit(name, callable) (@exit_actions[name] ||= []) << callable end |
#initial(state_name) ⇒ Object
Declares the initial (entry) state. rubocop:disable Style/TrivialAccessors
148 149 150 |
# File 'lib/phronomy/workflow.rb', line 148 def initial(state_name) @initial = state_name end |
#state(name, action: nil) ⇒ Object
Declares an action state.
159 160 161 162 |
# File 'lib/phronomy/workflow.rb', line 159 def state(name, action: nil) @declared_states << name entry(name, action) if action end |
#transition(from:, to:, guard: nil, on: nil) ⇒ Object
Declares a transition between states. Auto-fire transitions (no +on:+) fire automatically when an action state's action completes. External transitions (+on: :event_name+) are triggered manually via +send_event+. When +guard:+ is provided the transition is taken only if the guard returns truthy for the current context. Multiple transitions from the same source are evaluated in declaration order; the first passing guard wins.
211 212 213 214 |
# File 'lib/phronomy/workflow.rb', line 211 def transition(from:, to:, guard: nil, on: nil) dest = (to == :__finish__) ? FINISH : to @transitions << {from: from, to: dest, guard: guard, on: on} end |
#wait_state(name) ⇒ Object
Declares a wait state that automatically halts execution when reached. No entry action is registered; the workflow pauses here until an event resumes it.
195 196 197 |
# File 'lib/phronomy/workflow.rb', line 195 def wait_state(name) @wait_state_names << name end |