node-state-machine
Version:
State machine for NodeJS.
90 lines (77 loc) • 2.94 kB
JavaScript
// @flow
import { Transition } from './Transition';
/**
* Class representing a list of possible transitions that can be triggered
* by starting at some state. It holds a list of transitions with each its own
* trigger, but also a default transition in case no other transition is fired.
* @author Jensen Bernard
*/
class Transitions {
_transitions: Array<Transition>;
_default: ?Transition;
/**
* Creates a new instance of transitions with an empty transitions list and
* no default transition.
*/
constructor() {
this._transitions = [];
this._default = undefined;
}
/**
* Returns the total amount of transitions in this instance. If there is a
* default transition, it will also be counted as one.
* @return {number} Amount of transitions.
*/
totalTransitions(): number {
let extra: number = this._default != undefined ? 1 : 0;
return this._transitions.length + extra;
}
/**
* Adds the given transition to the list of possible transitions.
* @param transition {transition} A transition that should be added.
*/
add(transition: Transition) {
this._transitions.push(transition);
}
/**
* Sets the default transition to the given state with the given middlewares.
* Note that if a default transition already exists, it will be overwritten.
* @param state {string} The destination state of the default transition.
* @param middlewares {array} The middlewares of the default transition.
*/
default(state: string, middlewares: Array<(v: string) => void> = []) {
this._default = new Transition((v: string) => true, state, middlewares);
}
/**
* Finds the transition that gets fired by the given value. Note that there
* should always be only one possible transition for every value in order to
* have a deterministic machine (with the exception of the default
* transition).
* @param v {string} The value that should fire a transition.
* @throws Error {error} Throws if there are multiple transitions found.
* @throws Error {error} Throws if no possible transitions found.
*/
find(v: string): Transition {
let matches = [];
for(var transition of this._transitions)
if (transition.fires(v))
matches.push(transition);
if (matches.length > 1) throw new Error(`Multiple transitions found!`);
if (matches.length == 1) return matches[0];
if (this._default != undefined) return this._default;
throw new Error(`No transitions found!`);
}
/**
* Returns a string representation of this instance.
* @return {string} A string representation of this instance.
*/
toString(): string {
let str = ``;
for(var transition of this._transitions)
str += `${transition.toString()}\n`;
if (this._default != undefined)
str += `${this._default.toString()}\n`;
return str;
}
}
module.exports.Transitions = Transitions;