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

smachine

v0.1.1

Published

Statemachine run simple

Downloads

3

Readme

Statemachine Build Status

The only statemachine where rules and states are fully handled independent. It is also possible to add a statemachine to another statemachine, run in async or sync mode, transit form step to step from machine to machine while link different statemachines together. This helps dividing big problems into smaller ones which can be solved much easier.

Content:

Usage


var StateMachine = require("smachine").StateMachine;

var machine = new StateMachine();

// Adding state transition rules
machine.addTransition({
        from: "start",
        to: {
            "myOutcome": "final"
        }
    });
    // Adding states
    .addState("start", function (next) {
      // First parameter is an error (if there is one), second parameter is the
      // outcome as defined by the stateMachine rules
      next(null, "myOutcome");
    })
    .addState("final", function (next) {
        // Calling next() without any parameter will lead the stateMachine to
        // final state
       next();
     });

// Run the stateMachine
machine.run();

API

setAsync

Signature: .setAsync( true | false )

Defines if the statemachine should run in sync or async mode. Async mode is the default.

Here is an exmaple how the statemachine works in async (default) mode:


// Async mode
var isTested = true;

new StateMachine()
  .setAsync(true) // optional -> async true is default
  .addTransition(...)
  .addState(...)
  on("final", function () {
    isTested = false;
  })
  .run();

console.log(isTested) // outputs true

Here is an exmaple how the statemachine works in sync (default) mode:


// Async mode
var isTested = true;

new StateMachine()
  .setAsync(false) // statemachine should run in sync mode
  .addTransition(...)
  .addState(...)
  on("final", function () {
    isTested = false;
  })
  .run();

console.log(isTested) // outputs false
addTransition

Signature: .addTransition( object | array of objects )

Adds a new transition rule to the statemachine. A transition rule defines the "route" how to transit from one state to another. The expected parameter must be an object defined as follows:

.addTransition({
        from: "start",
        to: {
            "yourOutcome": "state1"
        }
    });

This example expects the outcome of state start to be yourOutcome and will transit to state state1. If the outcome of state start is not available via rules a StateNotFoundError will be the result. See Errorhandling

addState

Signature: .addState( string, function ) | .addState( object )

Adds a state to the statemachine. The name of the state is used in transitions to identify the state in dependency of the outcome of each state.

.addState("myState", function (next) {
    next(null, "yourOutcome")
});
setContext

Signature: .setContext( object | any )

Adds a context object to the statemachine. If a context object is provided, the second parameter of the stats's function is the reference to this context object.

.setContext({
    name: "John"
})
.addState("myState", function (next, context) {
    context.name // "John"
});
addStateMachine

Signature: .addStateMachine( maschine )

Adds a statemachine to another statemachine. Now it is possible to switch from maschineA.step1 to maschineB.step2 and backwards. This is done by a special notation inside addTransition.

var m1 = new StateMachine("m1") // Each statemachine MUST have a name
  .addTransition({
    from: "start",
    to: {
      outcome1: "m2:step1"      // This leads machine m1 transit to m2:step1
    }
  })
  .addState("start", function (next) {
    next(null, "outcome1");
  })
  .addState("final", function (next) {
    next();
  })
  .run();

var m2 = new StateMachine("m2")
  .addTransition({
    from: "step1",
    to: {
      step1Outcome: "m1:final"   // This leads machine m2 to transit to m1:final
    }
  })
  .addState("step1", function (next) {
    next(null, "step1Outcome");
  })
  .run();

m1.addStateMachine(m2);

m1.run();

Events

final

When the stateMachine reaches the final state an event finalis emitted.

statemachine.on("final", function () {
  // statemachine is in final state;
})
error

If any error occurs (async or sync mode) the event erroris emitted;

statemachine.on("error", function (error) {
  // handle the error
})

See also Errorhandling

Errorhandling

Errorhandling is done by emitting an error if any error occurs. Each state error is catched either the error is thrown with throw or by calling next(new Error(...), ...). Because the statemachine is an original node event emitter you can register an error listener to receive all errors:

statemachine.on("error", function (err) {
  // do something with the error
})

The error will be the original error thrown with throw or provided by the state's next(new Error(...)) method.

Test

There are no dependencies. Just run npm test

Issues

If you have any problems please create an issue at https://github.com/DennisAhaus/statemachine/issues

Support

If you want to get support or just discuss an idea please write an email to the author and get in invitation to slack https://hackers-corner.slack.com/#js-smachine

See you soon...