A simple JavaScript state machine with observers, for browsers and Node.js.

Skinny Coffee Machine

Skinny Coffee Machine is a simple JavaScript state machine written in CoffeeScript. It is being developed for the 2.0 rewrite of jQuery Endless Scroll.

If you use npm, you can grab the source code by:

npm install skinny-coffee-machine
@coffeeMachine.power = new SkinnyCoffeeMachine
  default: 'off'
      off: 'on'
      on: 'off'
    turnOn:  (from, to) -> "#{from.toUpperCase()} to #{to.toUpperCase()}"
    turnOff: (from, to) -> "#{from.toUpperCase()} to #{to.toUpperCase()}"
    turnOff: (from, to) -> "Before switching to #{to.toUpperCase()}"
    turnOn:  (from, to) -> "After switching to #{to.toUpperCase()}"
    turnOff: (from, to) -> "After switching to #{to.toUpperCase()}"
@coffeeMachine.mode = new SkinnyCoffeeMachine
  default: 'latte'
      latte: 'cappuccino'
      cappuccino: 'espresso'
      espresso: 'lungo'
      lungo: 'latte'
      latte: 'lungo'
      lungo: 'espresso'
      espresso: 'cappuccino'
      cappuccino: 'latte'

You may use either switch or change for switching states:

@coffeeMachine.power.currentState() #=> "off" 
@coffeeMachine.power.currentState() #=> "on" 

To change states multiple times:

@coffeeMachine.mode.currentState() #=> "latte" 
@coffeeMachine.mode.currentState() #=> "cappuccino" 

In order to provide more flexibility on state transition callbacks, you may use observers to dynamically add and remove events.

To start observing:

@coffeeMachine.power.observeBefore('turnOn').start 'labelA'(from, to) => "Observer A before switching to #{to.toUpperCase()}"
@coffeeMachine.power.observeOn(    'turnOn').start 'labelB'(from, to) => "Observer B on switching to #{to.toUpperCase()}"
@coffeeMachine.power.observeAfter( 'turnOn').start 'labelC'(from, to) => "Observer C after switching to #{to.toUpperCase()}"

To stop observing:


Skinny Coffee Machine uses Grunt, PhantomJS and Mocha.

After you have Grunt and PhantomJS set up, you may run tests by:


To automatically compile CoffeeScript as well as run tests during development, you may use:

grunt watch

Copyright (c) 2012 Fred Wu

Licensed under the MIT license.