Executable finite state machine for TypeScript and JavaScript.
If you like @steelbreeze/state, please star it...
Notes:
v7 is now live and contains breaking changes but offers a much simplified code base and considerable performance improvements. See the release notes for more information.
@steelbreeze/state the new home for state.js and the versioning starts here from v6.0.0.
npm i @steelbreeze/state
The API is broken up into two distinct parts:
- A set of classes that represent a state machine model (State, PseudoState, Region, etc.);
- An interface (IInstance), and default implementation of that interface (Instance), to represent an instance of a state machine model. This embodies the active state configuration of a state machine instance, and enables multiple instances of the same state machine model.
The full API reference can be found here.
import * as state from "@steelbreeze/state";
// create event class that a transition will respond to
class MyEvent {
public constructor(public fieldA: string, public fieldB: number) { }
public toString(): string {
return JSON.stringify(this);
}
}
// log state entry, exit and trigger event evaluation
log.add(message => console.info(message), log.Entry | log.Exit | log.Evaluate);
// create the state machine model elements
const model = new State("model");
const initial = new PseudoState("initial", model, PseudoStateKind.Initial);
const stateA = new State("stateA", model);
const stateB = new State("stateB", model);
// create the transition from initial pseudo state to stateA
initial.to(stateA);
// create a transtion from stateA to stateB a for events of type MyEvent with a guard condition
stateA.on(MyEvent).when(myEvent => myEvent.fieldB > 2).to(stateB);
// create an instance of the state machine model
let instance = new Instance("instance", model);
// send the machine events for evaluation
instance.evaluate(new MyEvent("test", 1));
instance.evaluate(new MyEvent("test", 3));
var state = require("@steelbreeze/state");
// create event class that a transition will respond to
class MyEvent {
constructor(fieldA, fieldB) { this.fieldA = fieldA; this.fieldB = fieldB; }
toString() { return JSON.stringify(this); }
}
// log state entry, exit and trigger event evaluation
state.log.add(message => console.info(message), state.log.Entry | state.log.Exit | state.log.Evaluate);
// create the state machine model elements
const model = new state.State("model");
const initial = new state.PseudoState("initial", model, state.PseudoStateKind.Initial);
const stateA = new state.State("stateA", model);
const stateB = new state.State("stateB", model);
// create the transition from initial pseudo state to stateA
initial.to(stateA);
// create a transtion from stateA to stateB a for events of type MyEvent with a guard condition
stateA.on(MyEvent).when(myEvent => myEvent.fieldB > 2).to(stateB);
// create an instance of the state machine model
let instance = new state.Instance("instance", model);
// send the machine events for evaluation
instance.evaluate(new MyEvent("test", 1));
instance.evaluate(new MyEvent("test", 3));
var state = require("@steelbreeze/state");
// create event class that a transition will respond to
var MyEvent = (function () {
function MyEvent(fieldA, fieldB) { this.fieldA = fieldA; this.fieldB = fieldB; }
MyEvent.prototype.toString = function () { return JSON.stringify(this); };
return MyEvent;
}());
// log state entry, exit and trigger event evaluation
state.log.add(function (message) { console.info(message); }, state.log.Entry | state.log.Exit | state.log.Evaluate);
// create the state machine model elements
var model = new state.State("model");
var initial = new state.PseudoState("initial", model, state.PseudoStateKind.Initial);
var stateA = new state.State("stateA", model);
var stateB = new state.State("stateB", model);
// create the transition from initial pseudo state to stateA
initial.to(stateA);
// create a transtion from stateA to stateB a for events of type MyEvent with a guard condition
stateA.on(MyEvent).when(function (myEvent) { return myEvent.fieldB > 2; }).to(stateB);
// create an instance of the state machine model
var instance = new state.Instance("instance", model);
// send the machine events for evaluation
instance.evaluate(new MyEvent("test", 1));
instance.evaluate(new MyEvent("test", 3));
The output of the above code will be:
instance enter model
instance enter model.model
instance enter model.model.initial
instance leave model.model.initial
instance enter model.model.stateA
instance evaluate {"fieldA":"test","fieldB":1}
instance evaluate {"fieldA":"test","fieldB":3}
instance leave model.model.stateA
instance enter model.model.stateB
Note that in the example above, a default region is inserted as a child of
model
and parent ofinitial
,stateA
andstateB
; the name of default regions copy their parent state hence seeingmodel.model
in the output above.
MIT License
Copyright (c) 2014-9 David Mesquita-Morris