maschine
v0.0.1
Published
A finite state machine
Downloads
4
Maintainers
Readme
var maschine = require('maschine');
var dfa = new maschine.Maschine();
Define a state by proving a name only. The state will be neither an initial nor a final state.
dfa.addState('A');
dfa.setInitial('A');
dfa.setFinal('A');
Define a state and make it inital and final. This also defines a transition to the state A on receiving the message 'x'
dfa.addState('B', 'initial', 'final', { 'x': 'A' } );
Define a state with multiple transitions.
dfa.addState('C', 'initial', 'final', { 'x': 'A' }, { 'y' : 'C' });
Set multiple final states
dfa.setFinal('A', 'B');
This state has one transition is a function that computes the target state. This is also useful if the messages that this machine is supposed to handle are not strings.
dfa.addState('D', 'initial', 'final', function (message) {
if (message === 'x') {
return 'A';
}
} );
You can mix regular and computing transitions.
dfa.addState('E',
{ 'x': 'A' },
function (message) { return 'B'; },
{ 'y': 'E' }
);
Define a state in object literal notation. Note that you need to give the transitions in an array.
dfa.addState({
name: 'F',
initial: true,
final: false,
transitions: [
{ 'x': 'A' },
function (message) { return 'B'; },
{ 'y': 'E' }
]
});
Adding states can be chained:
dfa.addState('A', 'initial', { 'm': 'B' })
.addState('B', 'final')
.addState('C', 'final', { 'z' : 'B' });
There is also a full object literal notation for transitions:
dfa.addState('A', {
name: 'alpha',
from: 'A',
message: 'x',
to: 'B'
});
The properties name
and from
are optional. If omitted, the name
will be defined as A>x>B
.
The object literal notation for a computing transition is:
dfa.addState('A', {
name: 'alpha',
from: 'A',
compute: function (message) { }
});
Again, name
and from
are optional.
Define a state with a control function that governs the entry to the state. If the function returns true, the transition is allowed, otherwise the machine will remain in its current state.
dfa.addState({
name: 'G',
transitions: [ { 'x': 'D' } ],
enterGuards: [ function (message, dfa) {
return true;
} ],
exitGuards: [ function (message, dfa) {
return false
} ]
});
Define multiple entry guards.
dfa.addState({
name: 'H',
enterGuards: [
function (message, dfa) {
} ,
function (message, dfa) {
}
]
});
Add listeners: After a new state has been entered.
dfa.on('enter', function (message, from, to) { });
After a state has been exited.
dfa.on('exit', function (message, from, to) { });
After exisiting from a state has been denied by a guard.
dfa.on('exitDenied', function (message, from, to) { });
After entering a new state has been denied.
dfa.on('enterDenied', function (message, from, to) { });
After entering a final state.
dfa.on('final', function (message, from, to) { });
Send the machine a message to trigger a state transition.
dfa.message('hello');
Get the current state name:
console.log( dfa.currentState.name );