I've published a simple JavaScript library the other day. Its goal is to help dealing with states and it provides a simple API for managing a minimalistic implementation of a state machine.
It's really miniature - it has only 50 lines of code. Its source code should be easy to read, even to a beginner. I've used Jasmine and Grunt to TDD it from scratch, so hopefully - the tests should also be really expressive.
It has no dependencies and supports everything a state machine should have, nothing more.
Give it a go by installing its node package:
npm install micro-machine
or use it in the browser with:
<script src="//rawgithub.com/shime/micro-machine-js/master/dist/micro-machine.min.js"></script>
Here's a walkthrough of its features.
// create a new instance and set its initial state to "pending"
var machine = new MicroMachine("pending");
console.log(machine.state); // outputs 'pending'
// define transitions
machine.transitionsFor.confirm = {pending: 'confirmed'};
machine.transitionsFor.ignore = {pending: 'ignored'};
machine.transitionsFor.reset = {confirmed: 'pending', ignored: 'pending'};
machine.trigger('confirm');
console.log(machine.state); // outputs 'confirmed'
// define callbacks
machine.on('reset', function(){
console.log("resetting...");
});
machine.trigger('reset'); // resets state and outputs 'resetting...'
// define special callback that will be called after any transition
machine.on('any', function(machine){
console.log("transitioned to '" + machine.state + "'");
});
machine.trigger('ignore'); // outputs "transitioned to 'ignored'"
Adding MicroMachine to your objects is piece of cake - just use composition!
var User = function User(){
var machine = new MicroMachine("pending");
machine.transitionsFor.confirm = {pending: 'confirmed'};
machine.transitionsFor.reset = {confirmed: 'pending'};
self = this;
machine.on("any", function(machine){
self.state = machine.state;
});
this.confirm = function(){
machine.trigger('confirm');
};
this.state = undefined;
return this;
};
var user = new User();
user.confirm();
console.log(user.state); // outputs 'confirmed'
That's all there is to it. Go give it a spin!