Package Exports
- jssm
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (jssm) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
jssm
A Javascript state machine with a simple API. Well tested, and typed with Flowtype. MIT license.
TL;DR
Specify finite state machines with a brief syntax. Run them. Derive charts from them. Save and load states. Make factories. Impress friends and loved ones. Cure corns and callouses.
const traffic_light = sm`
Red 'Proceed' -> Green 'Proceed' -> Yellow 'Proceed' -> Red;
`;
This will produce the following FSM (graphed with jssm-viz):
You could also write that as a piece of data, for when you're generating. That's ... a bit more verbose.
const traffic_light = new jssm.machine({
initial_state : 'Red',
transitions : [
{ action: 'Proceed', from:'Green', to:'Yellow' },
{ action: 'Proceed', from:'Yellow', to:'Red' },
{ action: 'Proceed', from:'Red', to:'Green' }
]
});
In either case, you'll build an executable state machine.
// use with actions
traffic_light.state(); // 'Red'
traffic_light.action('Proceed'); // true
traffic_light.state(); // 'Green'
traffic_light.action('Proceed'); // true
traffic_light.state(); // 'Yellow'
traffic_light.action('Proceed'); // true
traffic_light.state(); // 'Red'
// use with transitions
traffic_light.transition('Yellow'); // false (lights can't go from red to yellow, only to green)
traffic_light.state(); // 'Red'
traffic_light.transition('Red'); // false (lights can't go from red to red, either)
traffic_light.state(); // 'Red'
traffic_light.transition('Green'); // true
traffic_light.state(); // 'Green'
Which you can see being hand-executed in the Chrome console here:
Why
As usual, a valid question.
Why state machines
State machines are a method of making your software better able to prevent illegal states. Similar to type systems, SQL constraints, and linters, state machines are a way to teach the software to catch mistakes in ways you define, to help lead to better software.
The major mechanism of a state machine is to define states
, the transitions
between them, and sometimes associated
data
and other niceties. The minor mechanism of state machines is to attach actions
to the transitions, such that
the state machine can partially run itself.
So, to look at the same traffic light as above, you'll notice some things.
- A sufficiently smart implementation will know that it's okay for
Green
to switch toYellow
, but not toRed
- A sufficiently smart implementation knows there's no such thing as
Blue
- A sufficiently smart implementation knows that when in
Green
, to be told toProceed
means to go toYellow
, but when inYellow
, it means to go toRed
instead
Along with other common sense things, a good state machine implementation can help eliminate large classes of error in software. State machines are often applied when the stakes on having things correct are high.
Why this implementation
Brevity.
High quality testing. JSSM has 100% coverage, and has partial stochastic test coverage.
Feature parity, especially around the DSL and data control.
Data integrity. JSSM allows a much stricter form of state machine than is common, with a relatively low performance and storage overhead. It also offers an extremely terse domain specific language (though it does not require said DSL) to produce state machines in otherwise comparatively tiny and easily read code.
Quick Start
A state machine in JSSM
is defined in one of two ways: through the DSL, or through a datastructure.
In the quick start, we'll use the DSL. It looks like this:
const example = sm` FirstState -> SecondState -> ThirdState; `;
There are two pieces of code there, really. There's the outside javascript, which invokes the library and sets up the state machine's instance variable:
const example = sm` ... `;
And there's the domain-specific language, which creates the actual state machine.
FirstState -> SecondState -> ThirdState;
Terminology
Features
DSL
States
Transitions
Legal, main, and forced
Validators
State history
Automatic visualization
How to think in state machines
Example Machines
Door lock
Traffic lights
Basic three-state
RYG, Off, Flash-red, Flash-yellow
RYG, Off, Flash-red, Flash-yellow, Green-left, Yellow-left
Heirarchal intersection
ATM
HTTP
Better HTTP
TCP
Coin-op vending machine (data)
Video games
Pac-man Ghost (sensors)
Weather (probabilistics)
Roguelike monster (interface satisfaction)
Candy crush clone game flow (practical large use)
React SPA website (practical large use)
BGP
LibGCrypt FIPS mode FSM
How to debug
Notation Comparison
Their notations, one by one
Apples to Apples - Traffic Light
Other state machines
There are a lot of state machine impls for JS, many quite a bit more mature than this one. Here are some options:
- Finity 😮
- Stately.js
- machina.js
- Pastafarian
- Henderson
- fsm-as-promised
- state-machine
- mood
- FSM Workbench
- SimpleStateMachine
- shime/micro-machine
- soveran/micromachine (ruby)
- fabiospampinato/FSM
- HQarroum/FSM
- Finite-State-Automata
- finite-state-machine
- nfm
And some similar stuff: