Skip to content
/ state Public
forked from steelbreeze/state

Finite state machine for TypeScript and JavaScript

License

Notifications You must be signed in to change notification settings

iumlomki/state

 
 

Repository files navigation

state

Executable finite state machine for TypeScript and JavaScript.

If you like @steelbreeze/state, please star it...

NPM Version NPM Downloads Build Status Maintainability Test Coverage

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.

Install

npm i @steelbreeze/state

Usage

The API is broken up into two distinct parts:

  1. A set of classes that represent a state machine model (State, PseudoState, Region, etc.);
  2. 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.

TypeScript

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));

JavaScript (ECMAScript 2015)

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));

JavaScript (ECMAScript 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));

Output

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 of initial, stateA and stateB; the name of default regions copy their parent state hence seeing model.model in the output above.

License

MIT License

Copyright (c) 2014-9 David Mesquita-Morris

About

Finite state machine for TypeScript and JavaScript

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 58.2%
  • TypeScript 41.8%