GithubHelp home page GithubHelp logo

javascript-state-machine's People

Contributors

cbaatz avatar cboone avatar conorgil avatar ifdattic avatar imeditron avatar jakesgordon avatar offirmo avatar quentinroy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

javascript-state-machine's Issues

Get Valid Events for current state

Is there a way to get the valid events the current state can take?

Looking at the declaration of fsm.can it looks like it would just be finding all the events that include the current state in from?

My use case is getting all the valid events and creating a button for each valid event.

TypeError: Object #<object> has no method 'apply'

Any thoughts on debugging TypeError: Object # has no method 'apply'?

I'm building the FSM inside a class as follows:

this.fsm = StateMachine.create({
    initial: constants.S_CSM_COLD,
    events: [
        { from: constants.S_CSM_COLD,        name: constants.E_SCK_GUI_STARTUP,             to: constants.S_CSM_REGISTER},
        { from: constants.S_CSM_REGISTER,    name: constants.E_CSM_REGISTER_SUCCESS,        to: constants.S_CSM_WAITING},
        ....
    ],
    callbacks: {
        onS_CSM_REGISTER:       this.register,
        ...
    }
});

Inside a callback from a socket.io connect, I call:

self.fsm.E_SCK_GUI_STARTUP();

and it transitions into my register state.

However, from within my register state, I'm trying to fire the next transition by calling:

self.fsm.E_CSM_REGISTER_SUCCESS();

However, it is generating the TypeError: Object # has no method 'apply' error.

Not sure how the first transitions fine, but the second doesn't.

Any help greatly appreciated.

Error when executing previously-cancelled transition

Hi,

First of all, let me say thanks for this state machine project. It's rocking my world!

Unfortunately, I'm dealing with what I think is a bug.

I am using async transitions, and doing some basic validation during each state's 'onleave' callback. If the validation fails, I return false.

For example

onleaveState1 = function (event, from,  to, args) {

    // Check for required param
    args = args || {};

    // if the required param isn't there, return false to
    // cancel the transition
    if (!args.requiredParam) {
        return false;
    }

    // If the required param is there, run
    // an async function to do awesome stuff
    awesomeAsyncFunction(args);

    return StateMachine.ASYNC;

I am getting strange behaviour where a previously-cancelled transition, cancelled by 'return false', throws an error when it is called a second time. The error message I get is:

uncaught exception: event myTransition inappropriate because previous transition did not complete

I can reproduce the bug every time by doing these steps:

  1. execute a transition that fails validation, and cancels the event with 'return false'
  2. execute a successful transition that passes validation.

The error doesn't crash the script, and everything works as normal, but the error is still being thrown and I can't solve it.

EDIT: This bug is now sporadically crashing my script. I have also tried to fix it by explicitly cancelling the transition, with transition.cancel(), instead of returning false. This doesn't seem to work either.

[enhancement] Add missing bower.json.

Hey, maintainer(s) of jakesgordon/javascript-state-machine!

We at VersionEye are working hard to keep up the quality of the bower's registry.

We just finished our initial analysis of the quality of the Bower.io registry:

7530 - registered packages, 224 of them doesnt exists anymore;

We analysed 7306 existing packages and 1070 of them don't have bower.json on the master branch ( that's where a Bower client pulls a data ).

Sadly, your library jakesgordon/javascript-state-machine is one of them.

Can you spare 15 minutes to help us to make Bower better?

Just add a new file bower.json and change attributes.

{
  "name": "jakesgordon/javascript-state-machine",
  "version": "1.0.0",
  "main": "path/to/main.css",
  "description": "please add it",
  "license": "Eclipse",
  "ignore": [
    ".jshintrc",
    "**/*.txt"
  ],
  "dependencies": {
    "<dependency_name>": "<semantic_version>",
    "<dependency_name>": "<Local_folder>",
    "<dependency_name>": "<package>"
  },
  "devDependencies": {
    "<test-framework-name>": "<version>"
  }
}

Read more about bower.json on the official spefication and nodejs semver library has great examples of proper versioning.

NB! Please validate your bower.json with jsonlint before commiting your updates.

Thank you!

Timo,
twitter: @versioneye
email: [email protected]
VersionEye - no more legacy software!

Bower support

Any chance to register the library to Bower?

It is quite trivial to work directly with the git repository but having it listed there saves one browser visit here. Thanks! :)

Supporting nondeterministic and empty (epsilon) transitions

Any thoughts on supporting nondeterministic and epsilon transitions? I.e. nondeterministic transitions would enable that a machine transitions from one state to multiple states for a single event, while epsilon transitions would enable transitions between states without reading an event (which is usually modeled using a special 'epsilon' event).

Not sure what your goals for the library are, but having these two features would make it a full FSM library for a wide specter of use-cases.

Events shouldn't trigger transitioning from one state to another?

Thanks for a such great framework.

It has been my goal to use a statechart on the frontend together with ExtJS and I finally found a good one.

However I have some questions about the design choice of this framework.

Having used Sproutore's statechart I wonder why each event by default is triggering a transitioning from one state to another? If I am in a let's say "loggedin" state I should be able to "createpost", "deletepost", "searchposts" etc without having to enter a new state. Maybe I only want a transition to the "loggedout" state on "logout" event.

Or am I missing something?

Success or failure of an event

It's helpful if the event methods return true or false based on whether the event was successful or was cancelled.
In my use case, I want to keep statistics on event firings. This could also be used for situations where an event can unpredictably fail and multiple retires is necessary until it succeeds.

New `transitions()` method is broken

The new transitions() method does not work for events that have multiple from states. e.g

var fsm = StateMachine.create({
    events: [
        { name: 'start', from: 'none', to: 'green' },
        { name: 'warn', from: ['green','red'], to: 'yellow' },
        { name: 'panic', from: ['green','yellow'], to: 'red' },        
        { name: 'clear', from: ['red','yellow'], to: 'green' },
    ]});

onafterenter

onenter is triggered before onchangestate, we need something that is called after everything is done/all callbacks are triggered,
because we want to change state after entering a state (state is entered via n transitions -> we want to take care of callbacks in this state)

ie8 issue

I'm trying this in IE8 and get an error

'from' is null or not an object
state-machine.js Line 38 Char 9
Code: 0

It's possible to use this to get a ready setup IE8 to test in ..
https://github.com/xdissent/ievms

Don't swallow errors in SM callbacks

Line 77 in the callback has a try/catch which swallows errors in SM transition callbacks. This is quite annoying in development for debugging as it hides exactly what is going wrong. It would be great if you could either remove it or bubble the error message up.

THOUGHTS FOR VERSION 3.0

I have some (preliminary) plans on building a new 3.0 version, almost certainly NOT backward compatible, but including some of the common requests for:

  • nested/composable states
  • conditional transitions
  • observers (pub/sub) for state changes (instead of singular on*** callbacks)
  • stacked states (undo/redo)

A way to reliably intercept exceptions

Currently certain things will aways trigger an exception, and there is nothing that can be done about it short of wrapping calls to the state machine in a try/catch block.

I think it would be desirable to allow a special callback to be triggered instead of throwing an exception, in some circumstances.

perhaps generic events should come before and after specific events

they are good for logging and debugging and so bracketing specific events would be useful

  • onbeforeevent - generic handler for all events
    • onbeforego - specific handler for the go event only
      • onleavestate - generic handler for all states
        • onleavered - specific handler for the red state only
        • 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

Observers for state changes

I'm not sure how this fits in with the state machine programming paradigm but external observers attached to states on the state machine I think would be a really good feature.

sm = new StateMachine() ...

observer = sm.observe('stateName', function() { alert('in the state'); });

sm.doStateChange() would fire the observer.

observer would contain a UID which could be used to unbind the observer again:

sm.removeObserver(observer);

Thoughts? Would this be a good fit for the project or is it straying from the core functionality too far? Maybe I'm missing something with what's there already :)

Allow defining final states

Hello,

It would be nice if we could define final state(s) for the machine, so we could query it like fsm.isFinished() or something.

This could be declared by adding a new property to the constructing object called 'final', similar to the 'initial' one.

Missing license-required attribution in statemachine.js and statemachine.min.js

Greetings!

It seems that your license requires attribution, but your source code does not contain any attribution comment. I think you need to add an attribution or else the files cannot be used according to your license. Or do you expect each person to manually create a new version of the file to add the license attribution themselves?

onleavestate should also be able to cancel an event

In fact, I can think of more use cases where the departing state doesn't let the event to complete because of some unfinished business, as opposed to the actual event itself. Right now, onbeforeevent is the only callback from which returning false would result in cancellation of the event. I propose the same functionality in onleavestate.

Currently, returning false from onleavestate triggers an async transition. This could be changed to a different value (e.g. "async" string). It's only after we have left the old state that it no longer makes sense to cancel the event. Up until then, both callbacks should have this ability.

Here's a use case:

  • SM is in "modified" state and a "close" event is fired (or any other event). The onleave callback for "modified" state will only let the transition go through if it manages to save the changes.

Non-transitional, intra-state events

I would love to be able to define events which are only allowed to fire from within a state, but which don't trigger a state transition. I believe this is an integral part of the statechart pattern: for example, if there are things that should only happen when my app is in "account management" state or something... this would be an ideal way to manage that. That code could run secure in the knowledge that it's running from the correct state.

events: [
   { name: 'intrastate-event', from: 'myState' }
]
callbacks: {
   'onintrastate-event': function() { console.log('run some code that can assume it's being run from myState. :D'); }
}

Events with the same 'from' and 'to' are ignored

My understanding is that entering and leaving a state triggers the onenter[state] and onleave[state] callbacks, which is true.

I would have also expected that events always fire their onbefore[event] and onafter[event] callbacks, even if the event is taking the state machine from its current state to that same state. After all, the event is occurring, is it not?

If the code in the event-related callback is not supposed to run if the state isn't changing, there are three ways to solve this problem:

  1. Triggering no event in the first place.
  2. Placing the code in the relevant state-related callback(s).
  3. Checking the 'from' and/or 'to' parameters within the callback.

But if the event-related callback's code should be running on transitions from one state to the same state… then you have only one solution, and it sucks:

  1. Create additional events and states. Have the additional states always just go to the state that we really intend to be in. Try to avoid doing anything in on[enter/leave][state] that is completely redundant if you are going right back to that state, or check from/to within the callback to this end.

There are obvious implied downsides, not the least of which is code bloat and the forced constraints on the on[enter/leave][state] callbacks for states which have faux transition-to-self support.

Because I would expect events to operate differently than they do, I consider the results here a bug:

http://jsfiddle.net/alanhogan/5Z6Hd/1/

I would expect the output to read:

Entering Y
State machine is: y
(We will now call sm.dox().)
Event: dox
Leaving Y
Entering X
(We will now call sm.dox().)
Event: dox

But instead it reads:

Entering Y
State machine is: y
(We will now call sm.dox().)
Event: dox
Leaving Y
Entering X
(We will now call sm.dox().)

State machine hides callback exceptions. (SOLVED)

When I get an error like "an exception occurred in a caller-provided callback function" is there a way of finding out what that exception might be? If not, this is a huge problem for debugging.

can() with unexpected event

I could be nice to support error when using can with unexpected even:

var fsm = StateMachine.create({
  initial: 'hungry',
  events: [
    { name: 'eat',  from: 'hungry',                                to: 'satisfied' },
    { name: 'eat',  from: 'satisfied',                             to: 'full'      },
    { name: 'eat',  from: 'full',                                  to: 'sick'      },
    { name: 'rest', from: ['hungry', 'satisfied', 'full', 'sick'], to: 'hungry'    },
]})

fsm.can('sleep');

produces the following error:

.can     = function(event) { return !this.transition && (map[event].hasOwnProp
                                                                    ^
TypeError: Cannot call method 'hasOwnProperty' of undefined

It may be possible to return false instead of getting an error?

I'm writting a parser using state machine mechanism, so all my transitions depend on the input source that I cannot control that why I can stay in this use case :)

How to Create Workflow?

I will want to create a work flow something like this

                             Root
                                |
                             Start
                           /        \
                     Node0      Node1
                      \                     /
                     Node2       Node3
                        \             /
                           Node4

Is this possible with this API. If yes how can thanks

Namespace events using "namespace.EventName" or some other means

Would be convenient. For example I have events that are coming from two different sources, user touch events and a backend so I'd love to pass those namespaces to those two sources to use without exposing the other interface.

For example:

var fsm = new StateMachine({
  events: [
    { name: "backend.foo", from: "s1", to: "s2 },
    { name: "backend.bar", from: "s1", to: "s2 },
    { name: "frontend.babe", from: "s2", to: "s3 },
    { name: "frontend.pig", from: "s3", to: "s4" }
  ]
});
var backend = new Backend({ interface: fsm.backend });
var frontend = new FrontEnd({ interface: fsm.frontend });

And in Backend, for example:

interface.foo()

Child states

In Sproutcore you can have a state with child states and so on.

Eg. I can have "loggedin" state with child states like "adminpanel", "buypanel" etc.

Any thoughts about including this in the future?

Conditional branching logic for transitions

Depending on the system, it might be desirable to have conditional branching logic for the transitions. I've implemented this feature via an optional function parameter for each event definition. If you are interested let me know and I'll clean it up a bit and send the pull request.

Improve ASYNC behavior with a transition.pause/continue/cancel model

It's possible to pause the statemachine by returning StateMachine.ASYNC from the onleave event. The point I'm trying to make, is that method 1 shouldn't know anything about method 2.

So, if method 2 is running some async code and the statemachine has to wait while it's running, than method 2 should be responsible for pausing the statemachine instead of (an event of) method 1

Idea's to solve the problem:

  • Make it possible to return StateMachine.ASYNC from the onbefore event.
  • Add a function that does the opposite of fsm.transition().

The first can be used like:

callbacks: {
     onbeforeFetch: function(event, from, to) {
         return StateMachine.ASYNC;
     },
     onFetch: function(event, from, to) {
         $.getJSON(url, function(data) {
             this.transition();
         });   
     }
 }

and the second like: (my personal favorite)

callbacks: {
     onFetch: function(event, from, to) {
         this.transition.await()
         $.getJSON(url, function(data) {
             this.transition();
         }).error(function() { 
             this.transition.cancel();
         });   
     }
 }

Composable state machines

It would be nice if a state could be represented with a state machine itself. So all events get delegated to it.
Having composable state machines would be great to use in plugin-based architectures, where the plug-in can just fit into the general state machine to represent its "sub-state-machine".
Right now i look into the conditional transition from #27 to solve my particular issue but i thought having composition would be nice, if others also think so.

Gracefully ignore no-op transitions ?

(from twitter) @rentzsch says: @jakesgordon I'm loving jsm, thanks! One thing: I'm having to if(!fsm.is('foo')) fsm.foo() a bunch. Consider making it not an error?

Absolutely, will do, but with some caveats...

The issue sounds like, in 140 chars :-), you are triggering an event from a state that is not allowed, and in this case you are already in that state ? The state-machine is defensive by default, in most cases triggering an event from an innapropriate state would be a logic error.

If you want the event to be allowed and just a NO-OP (instead of an error), you can add the appropriate from state to the declaration. Example, a traffic light that has

 { name: 'red', from: 'yellow', to: 'red' },

would become

 { name: 'red', from: ['yellow', 'red'], to: 'red' },

or, an alternate, but identical declaration is

 { name: 'red', from: 'yellow', to: 'red' },
 { name: 'red', from: 'red',    to: 'red' }, // NO-OP: gracefully ignore red => red transitions

Both formats, would allow the red() event to be called from either the yellow or the red state and end up in the red state.

I could probably add something like an ignore_noop_transition: true setting to enable this behavior for the entire instance, so that if you find yourself needing this for every event you can just set this one setting.

Thoughts ?

As a sidenote from this issue, I highly recommend keeping event names separate from state names, even though it is often tempting to use the same name it becomes confusing. So for example the eat event might transition to the eating state... or the traffic light event turnRed might transition from the yellow state to the red state.

State machine prototypes

Great library!

What do you think about the create method being able to add methods to a constructor function and then expose a much simpler/faster instance creation method from that? It would be useful in the cases where an application has to manage many state machines.

A Function to cancel a transition after StateMachine.ASYNC

Hi there,

When you return a StateMachine.ASYNC value from an event callback, the expectation is that you are later going to call my-state-machine.transition() to go to the new state. However, I can't see a way to cancel that transition if there was an error somewhere in my asynchronous callback.

Looking at the code, what I did was take my-state-machine.transition member, which is a function, and set it to false. I did this just by looking at the algorithm in the source code. But there should definitely be a function call to cancel the transition, after an StateMachine.ASYNC call. This is, unless, I've missed it in the documentation.

Thanks

transition from a state to itself should call event callbacks

Currently, it is possible to define an event from and to the same state. However, firing that event will not call any callbacks.
Logically, we are not leaving the current state nor entering another one, so calling state callbacks (onleavestate, onenterstate) is meaningless. However, we are firing an event and expect something to happen as result of it. I think it makes sense to fire onbeforeevent and onafterevent (or just the latter) in this situation.

My use case:
I have a SM with couple of states, each of which maintain an internal SM. Events on the top level SM can trigger events internal to each state. Hence, there could be events firing on a single state of the top level SM which only affects SM internal to that state. If the original event doesn't call and callbacks, there would be no way to trigger anything else.

DOT (graphviz) export

I saw you mentioned this as a future feature but I'm bringing it up again so it is listed as a feature request in issues and you know people are interested.

Thanks for this great little project.

Typo in README

Code example under "Asynchronous State Transitions" reads:

    onleavegame: function() {
      $('#game').slideDown('slow', function() {

Surely it should be:

    onleavegame: function() {
      $('#game').slideUp('slow', function() {

since slideDown shows the element instead of hiding it.

Missing tag for v2.2.0?

I was just wondering if you intend to tag version 2.2.0 if it is considered officially released? If not, is version 2.1.0 considered the last stable version?

Thanks!

RequireJS and Target

Hi,

More of a query than an issue as I'm really loving the work you've done so far. It's really cool to have a version of the FSM that's ready to be brought in by requireJS. What's stumping me is how you might add the FSM to an existing module after you've brought it in as a dependency? From what I've tried you can't simply target the prototype in this instance. Any ideas? I'm happy to fork off and try some of my own stuff ... just wondered if I was missing something or if it's something you're currently looking at.

Thanks,

J

Can one event transition in multiple ways?

Is it possible to define an event foo that takes machine from state a to state b, if we are in state a, or from state x to state y, if we are in state x?

This would be useful for constructing state machines that track to variables, say i and j, and we want to move variable j from j1 to j2 regardless of what state i is in.

Does that make sense?

Example

Saving a document. We want to track whether the document is dirty since last save, and whether a save is in progress. Marking the document as dirty should change state, but we don't want to forget whether a save is in progress.

Event dirty should:

  • move from state clean to dirty, or
  • move from state cleanAndSaving to dirtyAndSaving

Is this possible?

Missing `transitions` method?

According to the documentation, a new instance should have the following member:

fsm.transitions() - return list of events that are allowed from the current state

This doesn't appear to be implemented?

Initial State in State Machine Class missing constructor properties

I like to have my state machine objects encapsulated as classes so that I can say

var myFSM = new MyFSM();
and I can immediately go on and use it.

This works fine as long as I do not specify the 'initial' option in the 'StateMachine.create' command as in this example:

var Foo = function()
{
    this.counter = 0;
    this.createStateMachine();
};
Foo.prototype.getCount = function()
{
    return this.counter;
};
Foo.prototype.onchangestate = function(event, from, to)
{
    console.log("Foo:[" + from + "]---" + event + "-->[" + to + "]");
};
Foo.prototype.onenterready = function()
{
    console.log('onenterready:' + this.counter);
    this.counter++;
};
Foo.prototype.onenterrunning = function()
{
    console.log('onenterrunning:' + this.counter);
    this.counter++;
};
Foo.prototype.createStateMachine = function()
{
    StateMachine.create({
        target : Foo.prototype,
        events : [{name: 'execute', from: 'ready', to: 'running'},
                {name: 'abort', from: 'running', to: 'ready'}],
        initial : 'ready'});
};

var foo = new Foo();

assertTrue(foo.is('ready'));
foo.execute();
assertEquals(2, foo.getCount());

The output I get is

[LOG] onenterready:undefined
[LOG] Foo:[none]---startup-->[ready]
[LOG] onenterrunning:0
[LOG] Foo:[ready]---execute-->[running]
AssertError: expected 2 but was 1

I.e. the enter state handler of the initial state is called but it has no access to the this properties of the constructor.
Maybe this is perfectly intended by the library, however I was unable to find another class concept to integrate the 'StateMachine.create' factory method. And I would really like to do it this way.

I this behaviour intended or is it a bug?

Best regards
Semmel

This Workflow possible?

I will want to create a work flow something like this

                             Root
                                |
                             Start
                           /        \
                     Node0      Node1
                      \                     /
                     Node2       Node3
                        \             /
                           Node4

Is this possible with this API. If yes how can thanks

Error handling

Hi,

I've got a problem with the way the state machine is handling the errors happening in "caller-provided".

I spent an hour finding out a bug as the error displayed was: "an exception occurred in a caller-provided callback function", displayed from a try-catch that is part of the library:

return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function", e);

I understand the attempt in trying to give more information about the states when something wrong is happening but the problem is that it is really masking completely the real error.

I tried to log the error from the try catch in the state machine but all I got was a useless: TypeError {} with no information at all. Not sure why I couldn't propagate the real error on my side. I don't have a try-catch at that level in my code but we are using a large tv application framework that might have some. Anyway, that's out of my reach.

I found the issue in my code by removing the try-catch from the state-machine and calling the callback directly, all finally got the error description, in which javascript file, at what line.

Conceptually, I do not think that the state machine should have a try-catch there for several reasons:

  • it is not the matter of the library to care about what is happening outside of its scope
  • it is masking the real problem really well
  • solving bugs inside those callback is REALLY HARD, I can't remember the last time I had a problem like this
  • providing state information when an error occurs is of little interest compared to get information about the real problem
  • the user can still add a try-catch on a higher level, which is better

The only things the state machine should do is have a a condition that checks that the function is actually a function, and that's it:

if (typeof func === 'function') {
   return func.apply(fsm, [name, from, to].concat(args));
}

Would you consider a pull request to remove the try-catch? We are re-building a large TV application and I need it rock solid. I'd prefer to contribute to the original library rather than using my own fork.

Cheers.

Romu

Enable state machine events to be called directly from methods that use a global scope (i.e. setTimeout)

When trying to call an event directly from setTimeout was getting an exception that the method cannot was not defined on an object. Traced it down to the fact that buildEvent uses 'this', which when used in a method called by setTimeout will be the root object (window in case of a browser).

Some example code:

var fsm = StateMachine.create({
  initial: 'green',
    events: [
      { name: 'warn',  from: 'green',  to: 'yellow' },
      { name: 'panic', from: 'yellow', to: 'red'    },
      { name: 'calm',  from: 'red',    to: 'yellow' },
      { name: 'clear', from: 'yellow', to: 'green'  }
   ],
   callbacks: {
     onwarn: function () {
       alert("Made it!");
     }
   }
});

setTimeout(fsm.warn, 0);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.