Please note: this blog has been migrated to a new location at https://jakesgordon.com. All new writing will be published over there, existing content has been left here for reference, but will no longer be updated (as of Nov 2023)

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 (#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

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.

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.