Javascript State Machine v2.2

Sat, Jan 26, 2013

Time for another minor update to my javascript state machine library. The code, along with updated usage instructions are available on github.

New features include:

  • Generic callbacks
  • Optional final state(s)
  • Cancellable ASYNC events
  • Fix undefined return codes

Generic callbacks (#28)

In previous versions, callbacks were attached to individual events or state transitions using a naming convention:

  onbeforeEVENT   // fired before the event
  onleaveSTATE    // fired when leaving the old state
  onenterSTATE    // fired when entering the new state
  onafterEVENT    // fired after the event

(using your specific EVENT and STATE names)

But sometimes you want to handle all events the same way in a single function. The only way to do that in previous versions was to use the generic onchangestate callback.

In this release, the onchangestate callback has been deprecated, and replaced with general purpose versions of all the existing callback types.

  onbeforeevent   // fired before any event
  onleavestate    // fired when leaving any state
  onenterstate    // fired when entering any state
  onafterevent    // fired after any event

The order in which callbacks occur is as follows:

(assume the go event transitions from red to green)

  onbeforego      // specific handler for the go    event only
  onbeforeevent   // generic  handler for all       events
  onleavered      // specific handler for the red   state only
  onleavestate    // generic  handler for all       states
  onentergreen    // specific handler for the green state only
  onenterstate    // generic  handler for all       states
  onaftergo       // specific handler for the go    event only
  onafterevent    // generic  handler for all       events

This gives the calling code the choice of attaching callbacks to either

  • individual events
  • individual state transitions
  • all events
  • all state transitions

Optional final states(s) (#23)

For state machines that will eventually transition into a final state, you can now specify that state during construction and a new isFinished() method will be provided to return true/false to indicate when that state has been reached.

  var fsm = StateMachine.create({
    initial: 'first', final: 'fourth',
    events: [
      { name: 'hop',  from: 'first',  to: 'second' },
      { name: 'skip', from: 'second', to: 'third'  },
      { name: 'jump', from: 'third',  to: 'fourth' },
    ]
  }); 
  
  fsm.isFinished(); // false

  fsm.hop();
  fsm.isFinished(); // false

  fsm.skip();
  fsm.isFinished(); // false

  fsm.jump();
  fsm.isFinished(); // true

This is a cosmetic helper wrapper around the existing fsm.is(state) method. The state machine does not enforce the finished state, you can still call other events to transition into and out of the finished state.

  • You can specify final as either a single state or an array of states
  • final is a javascript keyword, if this is a problem in your environment use terminal instead

Cancellable ASYNC events (#22)

If you need to cancel an ASYNC event without performing the state transition, you can now call

  fsm.transition.cancel()`

Fix undefined return codes (#34)

In the previous version I namespaced the return code constants.

StateMachine.Result.CANCELLED
StateMachine.Result.PENDING
// etc

However, I didn’t actually update the code that used the constants (DUH!) resulting in undefined values.

This has now been fixed.