jakmar v0.0.4
Jakmar.js
Jakmar is a finite state machine for Javascript.
Usage
For Node.js, just include the library:
var jakmar = require('jakmar')Stateful objects creation
First, build a MachineDefinition:
var definition = jakmar.create('foo-def') // foo-def is an identifierOnce it's created, start by adding states:
definition
.state('opened')
.state('closed')And some transitions:
definition
.transition('open', 'opened', 'closed')
.transition('close', 'closed', 'opened')Then just build the definition to get your stateful instance:
var stateful = definition.build('opened')Changing state
Your stateful instance has been enriched with methods defined by transitions. You can also very the current state using the state property:
console.log(stateful.state) // opened
stateful.close()
console.log(stateful.state) // closed
stateful.open()
console.log(stateful.state) // openedAPI
jakmar.create(id, options)
The create method creates and returns a new instance of a MachineDefinition with id as an identifier. The following options are valid (and all are optional):
errorOnInvalidTransition: will throw an Error if a transition tries to be applied but the stateful object is not in an expected state. Default istrue.
machineDefinition = jakmar.create('fooDef', {errorOnInvalidTransition: false})machineDefinition.state(stateId)
Register a new state with stateId as an identifier to the machineDefinition. Returns this for chained calls.
machineDefinition.state('opened')machineDefinition.states(stateIds)
Register an array of new states with stateIds being an Array of identifier for the machineDefinition. Returns this for chained calls.
machineDefinition.states(['opened', 'closed'])machineDefinition.states(...args)
Alternate way of registering new states, using any number of string, each a stateIdfor the machineDefinition. Returns this for chained calls.
machineDefinition.states('opened', 'closed')machineDefinition.transition(transitionId, fromStateId, toStateId)
Register a new transition with transitionId as an identifier to the machineDefinition. The transition will change the move the stateful object from the state defined by fromStateId to the state defined by toStateId. Returns this for chained calls.
machineDefinition.transition('open', 'opened', 'closed')machineDefinition.build(initialState, target)
Transform the target into a statefulObject with the current machineDefinition states and transitions applied to it. target is optional ; a new object is created if missing. The stateful object initial state is mandatory and defined by the initialState. Returns a statefulObject.
machineDefinition.transition('open', 'opened', 'closed')machineDefinition.getStates()
Expose the registered states of the machineDefinition. Returns an object with key / value pairs, key being the state ids and the value being the State objects. A State object only has an id at the moment.
var states = machineDefinition.getStates()
console.log(states)
// {
// opened: { id: 'opened' },
// closed: { id: 'closed' }
// }machineDefinition.getTransitions()
Expose the registered transitions of the machineDefinition. Returns an Arrat of Transition objects. A Transition object has two properties: the transition id and an applicableStates object of key / value pairs, where the key is the applicable fromState and the value is the corresponding toState for that transition.
machineDefinition.transition('toggle', 'opened', 'closed')
machineDefinition.transition('toggle', 'closed', 'opened')
var transitions = machineDefinition.getTransitions()
console.log(transitions)
// [
// { id: 'toggle', applicableStates : { opened: 'closed', closed: 'opened' } }
// ]machineDefinition.onEnter(onEnterFn)
Register a function that will be called every time the statefulObject enter a new state. It is called after the onExitFn, once the new state has been applied. The onEnterFn should be a function accepting one argument, being the id of state that has just been entered. Returns this for chained calls.
var onEnter = function(stateId) {
console.log('Entering', stateId)
}
machineDefinition.onEnterFn(onEnter)
var statefulObject = machineDefinition.build('opened')
statefulObject.close()
// Entering closedmachineDefinition.onExit(onExitFn)
Register a function that will be called every time the statefulObject exits a state. It is called before the onEnterFn, once the new state has been applied. The onExitFn should be a function accepting one argument, being the id of state that will be exited. Returns this for chained calls.
var onExit = function(stateId) {
console.log('Exiting', stateId)
}
machineDefinition.onExitFn(onExit)
var statefulObject = machineDefinition.build('opened')
statefulObject.close()
// Exiting openedstatefulObject.state
Return the current state id of the statefulObject.
var statefulObject = machineDefinition.build('opened')
statefulObject.state // 'opened'statefulObject.stateChange
Function that gets called every time the statefulObject changes state. It gets called with three arguments: the transition id that trigerred the change of state, the fromState id and the toState id. It gets called `after the state has changed.
var statefulObject = machineDefinition.build('opened')
statefulObject.stateChange = function(transitionId, fromStateId, toStateId) {
console.log('Going from', fromStateId, 'to', toStateId, 'because of transition', transitionId)
}
statefulObject.open()
// Going from opened to closed because of transition openstatefulObject.\
Apply a registered transition to the statefulObject. Returns true id the transitions was applied, throws an Error if the transition can't be applied (because the statefulObject is not in a state where the transition can be applied) or returns false if the errorOnInvalidTransition option is set to false.
statefulOject.state // closed
statefulObject.open() // returns true
statefulOject.state // opened
statefulObject.open() // throws an ErrorTODO
- Retrieve machine definition by id
- Provide a simple example with React
- Provide a simple example with Vue

