seneca-sm

1.0.1 • Public • Published

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.

Package Sidebar

Install

npm i seneca-sm

Weekly Downloads

0

Version

1.0.1

License

MIT

Last publish

Collaborators

  • malex