smachine
v0.1.1
Published
Statemachine run simple
Downloads
3
Maintainers
Readme
Statemachine
The only statemachine where rules and states are fully handled independent. It is also possible to add a statemachine to another statemachine, run in async or sync mode, transit form step to step from machine to machine while link different statemachines together. This helps dividing big problems into smaller ones which can be solved much easier.
Content:
- Usage
- API
- setAsync
- addTransition
- addState
- setContext
- addStateMachine
- Events
- final
- error
- Errorhandling
- Test
- Issues
- Support
Usage
var StateMachine = require("smachine").StateMachine;
var machine = new StateMachine();
// Adding state transition rules
machine.addTransition({
from: "start",
to: {
"myOutcome": "final"
}
});
// Adding states
.addState("start", function (next) {
// First parameter is an error (if there is one), second parameter is the
// outcome as defined by the stateMachine rules
next(null, "myOutcome");
})
.addState("final", function (next) {
// Calling next() without any parameter will lead the stateMachine to
// final state
next();
});
// Run the stateMachine
machine.run();
API
setAsync
Signature: .setAsync( true | false )
Defines if the statemachine should run in sync or async mode. Async mode is the default.
Here is an exmaple how the statemachine works in async (default) mode:
// Async mode
var isTested = true;
new StateMachine()
.setAsync(true) // optional -> async true is default
.addTransition(...)
.addState(...)
on("final", function () {
isTested = false;
})
.run();
console.log(isTested) // outputs true
Here is an exmaple how the statemachine works in sync (default) mode:
// Async mode
var isTested = true;
new StateMachine()
.setAsync(false) // statemachine should run in sync mode
.addTransition(...)
.addState(...)
on("final", function () {
isTested = false;
})
.run();
console.log(isTested) // outputs false
addTransition
Signature: .addTransition( object | array of objects )
Adds a new transition rule to the statemachine. A transition rule defines the "route" how to transit from one state to another. The expected parameter must be an object defined as follows:
.addTransition({
from: "start",
to: {
"yourOutcome": "state1"
}
});
This example expects the outcome of state start
to be yourOutcome
and will transit to state
state1
. If the outcome of state start
is not available via rules a
StateNotFoundError
will be the result. See Errorhandling
addState
Signature: .addState( string, function ) | .addState( object )
Adds a state to the statemachine. The name of the state is used in transitions to identify the state in dependency of the outcome of each state.
.addState("myState", function (next) {
next(null, "yourOutcome")
});
setContext
Signature: .setContext( object | any )
Adds a context object to the statemachine. If a context object is provided, the second parameter of the stats's function is the reference to this context object.
.setContext({
name: "John"
})
.addState("myState", function (next, context) {
context.name // "John"
});
addStateMachine
Signature: .addStateMachine( maschine )
Adds a statemachine to another statemachine. Now it is possible to switch from maschineA.step1 to maschineB.step2 and backwards. This is done by a special notation inside addTransition.
var m1 = new StateMachine("m1") // Each statemachine MUST have a name
.addTransition({
from: "start",
to: {
outcome1: "m2:step1" // This leads machine m1 transit to m2:step1
}
})
.addState("start", function (next) {
next(null, "outcome1");
})
.addState("final", function (next) {
next();
})
.run();
var m2 = new StateMachine("m2")
.addTransition({
from: "step1",
to: {
step1Outcome: "m1:final" // This leads machine m2 to transit to m1:final
}
})
.addState("step1", function (next) {
next(null, "step1Outcome");
})
.run();
m1.addStateMachine(m2);
m1.run();
Events
final
When the stateMachine reaches the final state an event final
is emitted.
statemachine.on("final", function () {
// statemachine is in final state;
})
error
If any error occurs (async or sync mode) the event error
is emitted;
statemachine.on("error", function (error) {
// handle the error
})
See also Errorhandling
Errorhandling
Errorhandling is done by emitting an error if any error occurs.
Each state error is catched either the error is thrown with throw
or by
calling next(new Error(...), ...)
.
Because the statemachine is an original node event emitter you can register
an error listener to receive all errors:
statemachine.on("error", function (err) {
// do something with the error
})
The error will be the original error thrown with
throw
or provided by the state'snext(new Error(...))
method.
Test
There are no dependencies. Just run npm test
Issues
If you have any problems please create an issue at https://github.com/DennisAhaus/statemachine/issues
Support
If you want to get support or just discuss an idea please write an email to the author and get in invitation to slack https://hackers-corner.slack.com/#js-smachine
See you soon...