A tiny implementation of a finite state machine written in Javascript.
Current version: 2.0.0
Lead Maintainer: Halim Qarroum
npm install --save fsm.js
Fsm.js
is distributed as an ESM module that you can import in your implementation.
import Fsm from 'fsm.js';
To create an instance of the state machine you simply have to call its constructor :
const fsm = new Fsm();
A state
is an instance of a Fsm.State
object. It takes a reference to the state machine it is associated with as well as optional callbacks associated with the state lifecycle.
As you can see below, creating a state is pretty straightforward :
const state = new Fsm.State({
/**
* An optional name for the state.
*/
name: 'initialization',
/**
* A reference to the used state machine.
*/
fsm: fsm,
/**
* An optional callback invoked when the state is
* entered.
*/
onEntry: () => {},
/**
* An optional callback invoked upon a received
* event.
*/
onEvent: (event) => {
// Do something with the received `event`.
},
/**
* An optional callback invoked when the state is
* exited.
*/
onExit: () => {}
});
When a state machine is created, it is stopped by default. To start a state machine you need to give it a reference to the initial state in which it should be starting :
fsm.start(state);
Usually, you will want states to react to received events by executing actions and transitioning between one another. This can be achieved through the postEvent
and transitionTo
primitives as shown in the example below.
/**
* The `initialization` state of the system.
*/
const initialization = new Fsm.State({
fsm: fsm,
name: 'initialization',
onEntry: () => console.log('Initialization ...'),
onExit: () => console.log('Initialization completed'),
onEvent: (event) => {
if (event === 'init.done') {
this.transitionTo(initialized);
}
}
});
/**
* The `initialized` state.
*/
const initialized = new Fsm.State({
fsm: fsm,
name: 'initialized',
onEntry: () => console.log('System initialized')
});
// Starting the fsm.
fsm.start(initializing);
// Simulating an asynchronous event.
setTimeout(() => fsm.postEvent('init.done'), 1000);
The above code will output :
Initialization ...
Initialization completed
System initialized
In the elevator example, we implemented, as an example of a real life problem, the bare minimum functions provided by an elevator using a finite state machine.
For the sake of simplicity, the implementation is really dummy, meaning that smart behaviours such as ordering of the levels given their location along the elevator path are not implemented.