A Finite State Machine which
- is declarative
- supports programmatic state transitions
- makes states stateful by allowing events to pass data and states to store data
- provides hooks to get notified about state transitions
The above state machine could be modeled as follows (thresholds are omitted for the sake of simplicity).
var fsm = FSM4JS.fsm()
.events(["success", "fail", "timeout"])
.states(["closed", "open", "halfopen"])
.init("closed")
.transitions([
{from: "closed", event: "success", to: "closed" },
{from: "closed", event: "fail", to: "open" },
{from: "open", event: "timeout", to: "halfopen"},
{from: "halfopen", event: "success", to: "closed" },
{from: "halfopen", event: "fail", to: "open" }
])
.on("open", {
enter: function () {
// timeout logic
}
})
.start();
You can find a demo of the same here.
FSM4JS is available for both node and browser.
- Browser
bower install fsm4js
- Node
npm install fsm4js
Use the fsm()
factory method to create a new Finite State Machine.
var fsm = FSM4JS.fsm();
FSM4JS exposes fluent APIs so that the entire Finite State Machine can be built in a single statement.
The events declared under .events(["success", "fail", "timeout"])
could be programmatically fired as follows.
fsm.success( data );
fsm.fail( data );
fsm.timeout( data );
fsm.transitionTo( new_state, data );
The current
method returns the current state in the form of { state: 'state name', data: { ... } }
fsm.current();
fsm.on("open", {
enter: function (options) {
// options.from -> entering 'open' state from which state?
// options.event -> what event caused to enter into this state
// options.to.data -> data being passed to this - i.e. open - state
},
exit: function (options) {
// options.from -> exiting from what state i.e. open
// options.event -> what event caused to exit from this state
}
)
Get some code executed before entering or after exiting any state
fsm.beforeEnter(function(options) {
// options.from -> going to enter some state from 'from' state
// options.event -> what event caused the state transition
})
fsm.afterExit(function(options) {
// options.from -> going to exit from 'from' state
// options.event -> what event caused the state transition
// options.to.data -> data being passed during state transition
})