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

seneca-sm

v1.0.1

Published

A state machine implementation plugin for Seneca

Downloads

6

Readme

State-machine plugin for Seneca

Seneca

seneca-sm

npm version Build Status Coverage Status

Seneca State-Machine Plugin

This plugin stores and execute a state-machine context. The state machine have two main concepts: States and Commands. At each moment the state machine can be in one single state. In each state there can be defined one or more commands, result of these commands changing the state of the state machine.

Seneca State-Machine Plugin

Install

npm install seneca-sm

Usage

Initialisation

seneca.act( 'role: sm, create: instance', config, function( err, context ) {
})

Executing commands

seneca.act( 'role: sm, cmd: command-name', {sm_name: sm_name, ....}, function( err, data ) {
})

where:

  • sm-name is the name of the state-machine as it was set in the configuration
  • command-name the command to be executed for current state. Should be defined in the configuration.
  • some_data optional JSON containing additional-data for command

Retrieving state machine context

seneca.act( 'role: sm, get: context', {sm_name: sm_name} function( err, context ) {
})

Set data in state-machine context

This command will set some data in the state machine context. This data will be sent to all commands executed on the state machine.

seneca.act( 'role: sm, set: data', {sm_name: sm_name, ....}, function( err, context ) {
})

Load a specific state-machine context

This command can be called after a sm is initialized to change its internal state from the default state to a specific one

seneca.act( 'role: sm, load: state', { sm_name: sm_name, state: state_to_load}, function( err, context ) {
})

Remove state-machine context

This command will close the state machine. This state machine cannot be used anymore. A new state machine with same name can be started.

seneca.act( 'role: sm, drop: instance', {sm_name: sm_name}, function( err, context ) {
})

Configuration

Configuration structure for state machine is:

  • validate if configuration will be strict validated when instance is created.
  • name name of the state machine - it will be used as role configuration when state machine actions will be called
  • states object defining the states and commands. Key is the state and value an object with
    • defaults default behavior for this state - TBD
    • initState default state for state machine. One single state should have this parameter true
    • events allows adding event hooks trigered when the state changes
      • before called before the state execution - can be the child of the root states object or child of a state
        • pattern seneca pattern defining the action to be called before the state execution
      • after called after a state is executed - can be the child of the root states object or child of a state
        • pattern seneca pattern defining the action to be called after the state execution
    • commands array with all commands for current state
      • key command to be executed for this state
      • pattern seneca pattern defining the action to be called to execute the state
      • next define transitions based on seneca action result
        • err define next status in case of error - this is a String
        • success value can be:
          • String in this case defines next status in case that Seneca action defined by pattern returns success data
          • Array of objects with following structure:
            • schema Parambulator schema to be applied on callback data
            • state next state in case Parambulator schema matches data

Example

The following simple state machine will be used as example.

Diagram

The configuration to be used for this state machine is:

{
  validate: true,
  name:     'sm1',
  states: {
    events: {
      before: {
        pattern: "role: 'transport', execute: 'before_any_state_change'"
      },
      after: {
        pattern: "role: 'transport', execute: 'after_any_state_change'"
      }
    },
    "INIT": {
      initState: true,
      defaults: {
        next: {
          error:   "INIT"
        }
      },
      commands: {
        execute: {
          pattern: "role: 'transport', execute: 'connect'",
          next:  {
            success: "NOT_CONFIGURED"
          }
        },
        disconnect: {
          pattern: "role: 'transport', execute: 'disconnect'",
          next:  {
            success: "INIT"
          }
        }
      }
    },
    "NOT_CONFIGURED": {
      commands: {
        execute: {
          pattern: "role: 'transport', send: 'config'",
          next:  {
            error:   "DISCONNECTED",
            success: "CONNECTED"
          }
        },
        disconnect: {
          pattern: "role: 'transport', execute: 'disconnect'",
          next:  {
            error:   "INIT",
            success: "DISCONNECTED"
          }
        }
      },
      events: {
        before: {
          pattern: "role: 'transport', execute: 'before_notconfigured_state_change'"
        },
        after: {
          pattern: "role: 'transport', execute: 'after_notconfigured_state_change'"
        }
      }
    },
    "CONNECTED": {
      commands: {
        execute: {
          pattern: "role: 'transport', send: 'some_command'",
          next:  {
            error:   "DISCONNECTED",
            success: "CONNECTED"
          }
        },
        disconnect: {
          pattern: "role: 'transport', execute: 'disconnect'",
          next:  {
            error:   "INIT",
            success: "DISCONNECTED"
          }
        }
      }
    },
    "DISCONNECTED": {
      commands: {
        execute: {
          cmd:   '',
          pattern: "role: 'transport', execute: 'cleanup'",
          next:  {
            error:   "INIT",
            success: "INIT"
          }
        },
        disconnect: {
          pattern: "role: 'transport', execute: 'disconnect'",
          next:  {
            error:   "INIT",
            success: "DISCONNECTED"
          }
        }
      }
    }
  }
}

Test

npm test

Example

For an example of state machine implementation please check this repository State Machine Example

Contributing

We encourage participation. If you feel you can help in any way, be it with examples, extra testing, or new features please get in touch.