npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

backbone.statemachine

v0.2.7

Published

Simple finite-state machine for Backbone. View states made easy. Synchronizing your application's parts with events made easy.

Downloads

7

Readme

Backbone.StateMachine

Is a small javascript library to add state machine capacities to any Backbone or non-Backbone object.

Index

  • Backbone.StateMachine. A module that can be mixed into any object, giving this object the super-powers of a state machine.
  • Backbone.StatefulView. A Backbone view, augmented with state machine capabilities.

StateMachine

Backbone.StateMachine is used as a mixin, somewhat like Backbone.Events.

Declaring a state machine

Let's declare a very simple state machine representing an HTML element that can be either hidden or visible.

This machine will have 3 states, init, hidden and visible, and 3 transitions :

init --['initialized']--> visible
hidden  --['show']--> visible
visible --['hide']--> hidden

Also, in order to actually show or hide the element, everytime the state machine enters in state visible a method doShow will be called, and everytime it leaves the state visible, a method doHide will be called.


var element = {el: $('#myElement')}

// !!! note that `StateMachine` requires the `Events` mixin
_.extend(element, Backbone.StateMachine, Backbone.Events, {
  states: {
    visible: {enter: ['doShow'], leave: ['doHide']}, // All options see: 'state options'
    hidden: {}                                       // Declaring an emtpy state is optional
  },
  transitions: {
    init: {
      initialized: 'visible'            // You can declare a transition like that
    },
    visible: {
      hide: {
        enterState: 'hidden',           // Or like this if you want to specify options
        triggers: 'nowVisible'
      }
    },
    hidden: {
      show: {
        enterState: 'visible',
        triggers: 'nowHidden'
      }
    }
  },
  doShow: function() { this.el.show() },
  doHide: function() { this.el.hide() }
})

state options

  • enter - array containing names of methods to call when entering the state (Optional).
  • leave - array containing names of methods to call when leaving the state (Optional).

transition options

  • enterState - arrival state of the transition.
  • callbacks - array containing names of methods to call when transition is crossed (Optional).
  • triggers - Backbone event to trigger when transition is crossed (Optional).

Note : This is not demonstrated here, but you can also define a transition from one state to itself.

Triggering transitions

The state machines are always created in init state, even if it isn't declared. Therefore, you should always declare at least one transition from state init to another state.


// !!! this method needs to be called before the state machine can be used
element.startStateMachine()

// First, let's get the machine out from 'init' state
element.trigger('initialized')

element.currentState                // 'visible'
element.trigger('hide')             // a transition is triggered, the element should disappear
element.currentState                // 'hidden'
element.trigger('hide')             // event 'hide' while in state 'hidden' -> no transition
element.trigger('show', 'quick')    // extra arguments will be passed to the callbacks

Transition events

Every time a transition is crossed, the state machine triggers a bunch of Backbone events. This way, you can setup an efficient event-based communication between the different parts of your application. Cool thing with using this method is that those different parts don't need to know each other.


element.bind('transition', function(leaveState, enterState) {
  alert('Transition from state "'+leaveState+'" to state "'+enterState+'"')
})
element.bind('leaveState:hidden', function() {
  // synchronize other objects in your application
  bla.trigger('activate')
  aView.render()
})
element.bind('enterState:hidden', function() {
  // synchronize other objects in your application
  bla.trigger('deactivate')
})

Also, if your transition defines the triggers option, for example {triggers: 'showItAll'}, an extra event 'showItAll' will be triggered when that transition is crossed :


element.bind('showItAll', function() {
  // do stuff
})

If you want to hush-up the state machine, and prevent any of those events to be triggered, just set silent to true :


element.silent = true      // next transitions will happen in silence
element.trigger('show')
element.trigger('hide')
element.silent = false     // next transitions will trigger events as described above

Matching any state with '*'

When declaring the transitions of your state machine, you can use the wildcard character '*' to match any state.


var obj = {}
_.extend(obj, Backbone.StateMachine, Backbone.Events, {
  transitions: {
    visible: { hide: 'hidden' },
    hidden: { show: 'visible' },
    // No matter the machine's state, 'panic' will always trigger a transition :
    '*': { panic: 'panicking' }
  }
})

Forcing the machine to a given state

You can use the method toState to force the machine to a particular state. In that case, no transition will occur, but the enter callbacks will be executed.

element.currentState       // 'hidden'
element.toState('visible') // the callback 'doShow' is executed.
element.currentState       // 'visible'

StatefulView

Backbone.StatefulView is a backbone view that has state machine capabilities, plus a few goodies.

A css class for each state

To each state of the machine corresponds a css class on the view's el. By default the css class name is the state.

This makes styling very easy, for example :


#myStatefulView.visible {
  display: block;
}
#myStatefulView.hidden {
  display: none;
}

Transition events as view events

It is possible to declare transition events exactly the same way as in the Backbone.View.events hash. For example :

Note : You don't need to call startStateMachine when using a StatefulView.


var MyView = Backbone.StatefulView.extend({
  transitions: {
    'init': {'loaded': 'idle'}
    // transition will occur when clicking on '.activate'
    'idle': {'click .activate': 'active'}
  }
})

state options

  • className - a css class added to view's el when the view is in this state.

Requirements

backbone.statemachine requires backbone (and therefore all its dependencies).

It is tested against backbone 0.9.2.

Questions, contributions ?

Any suggestion, comment, question - are welcome - contact me directly or open a ticket.

Any bug report, feature request, ... open a ticket ! To run tests, either open tests/tests.html in a browser, or run them from NodeJS (requires PhantomJS):

npm install -g grunt
grunt

More infos about state machines

http://en.wikipedia.org/wiki/Finite-state_machine

http://upload.wikimedia.org/wikipedia/commons/c/cf/Finite_state_machine_example_with_comments.svg

Release History

0.2.6

  • Repackaged for browserify and AMD, and available through npm

0.2.5

  • Callbacks can also be anonymous functions
  • Switched to 2-spaces indentation and removed semicolons
  • Now throws an error if startStateMachine is called twice

0.2.4

  • Added StatefulModel
  • Added simplified syntax for transition declaration if only the enterState if specified

0.2.3

  • 'enterCb' and 'leaveCb' renamed to 'enter' and 'leave'
  • now machine always created in 'init' state.

0.2.2

  • added the wilcard characted '*' to match any state.

0.2.1

  • the states of the machine don't need to be declared anymore, the state machine can deduce it from the transitions.

0.2.0

  • Backbone.StateMachine now fully uses backbone's events system. Events now triggered with trigger, instead of receive previously.
  • in Backbone.StatefulView, transitions can now contain DOM events, using the same syntax as Backbone.View.events.

0.1.0

  • Initial release

License

Copyright (c) 2012 Sébastien Piquemal
Licensed under the MIT license.