Core Concepts of StateWalker FSM

StateWalker is a TypeScript library for creating and executing finite state machines (FSMs), supporting hierarchical states and transitions.

This documentation covers the core concepts used in StateWalker, providing a foundation for defining workflows and processes effectively.


State Machines

A state machine is a model of computation that defines a set of states and transitions between them, triggered by events. Each state can represent an action, condition, or phase within a process.

Key Components:


States

States represent the possible phases within a process or lifecycle stages. In StateWalker, states are hierarchical – transitions between sub-states are defined in the parent state.

Note: it is important to highlight that transitions are possible only between direct sub-states of the parent state.

All states have exactly the same structure as their parents and children with the following three fields:

Example:

- key: Telephone
  transitions:
  - ["", "*", "Off"]
  - ["Off", "switch", "On"]
  - ["On", "switch", "Off"]
  - ["*", "unplug", ""]
  states:
  - key: On
    transitions:
    - ["", "*", "Waiting"]
    - ["Waiting", "signal", "Ringing"]
    - ["Ringing", "hangUp", "Talking"]
    - ["Talking", "hangOut", "Waiting"]
    - ["Ringing", "timeout", "FaxRecieving"]
    - ["FaxRecieving", "done", "Waiting"]

Transitions

Transitions define the conditions under which the FSM moves from one state to another. Each transition specifies:

Configuration for transitions contains triples of string keys:
SourceStateKey -eventKey-> TargetStateKey

Syntax:

transitions:
  - ["Start", "begin", "Processing"]
  - ["Processing", "complete", "Completed"]

Special cases:


Transitions: Events

Events are the triggers that cause transitions between states. These can be external inputs or internal signals. Events can be global or specific to certain states.

Example:

transitions:
  - ["Start", "initialize", "Processing"]
  - ["Processing", "error", "ErrorState"]

Transitions: Initial State

The initial state is where the FSM begins its execution. It is specified using an empty source state ("") in a transition.

Example:

transitions:
  - ["", "", "InitialState"]

Transitions: Termination State

A transition to an empty state ("") explicitly defines exit condition for the current state:

Examples:

Exit from the EditingReview substates on done event:

transitions: 
  - ["EditingReview", "done", ""]

Exit from all substates on exit event:

transitions: 
  - ["*", "exit", ""]

Here we are using a wildcard mask ("*") to match all substate.


Wildcards

Wildcards ("*") for states and events simplify transitions definitions.

transitions:
  - ["*", "error", "HandleError"]
  - ["*", "reset", "Start"]

Example for a transition to occur on any event:

transitions:
  - ["ErrorState", "*", "Completed"]

Execution

StateWalker enables the execution of FSMs by dispatching events to trigger transitions. Execution includes tracking the current state and responding to events accordingly.

Example Code:

const process = new FsmProcess(config);

process.onStateCreate((state) => {
  // Add state-specific handlers
  if (state.key === "Download") {
    const controller = new AbortController();
    state.onEnter(async () => {
      // Start a long-running task
      const response = await fetch(url, { signal });
      ...
    })
    state.onExit(async () => {
      // Cleanup resources here...
      controller.abort();
    })
  } else if (...) { 
    ...
  }
})

// Start the process
process.dispatch("start");