Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mooremachine

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mooremachine - npm Package Compare versions

Comparing version 1.3.0 to 1.4.0

35

lib/fsm.js

@@ -36,2 +36,6 @@ // Copyright 2015 Joyent, Inc.

this.fsm_history = [];
this.fsm_validTransitions = undefined;
if (this.fsm_allStateEvents === undefined)
this.fsm_allStateEvents = [];
this.fsm_state = undefined;
EventEmitter.call(this);

@@ -51,2 +55,14 @@ this.gotoState(defState);

FSM.prototype.validTransitions = function (states) {
assert.arrayOfString(states, 'states');
this.fsm_validTransitions = states;
};
FSM.prototype.allStateEvent = function (evt) {
assert.string(evt, 'event');
if (this.fsm_allStateEvents === undefined)
this.fsm_allStateEvents = [];
this.fsm_allStateEvents.push(evt);
}
/*

@@ -81,2 +97,9 @@ * Calls a callback when this FSM reaches a given state. This is for use by

if (this.fsm_validTransitions !== undefined) {
if (this.fsm_validTransitions.indexOf(state) === -1) {
throw (new Error('Invalid FSM transition: ' +
this.fsm_state + ' => ' + state));
}
}
/*

@@ -115,5 +138,17 @@ * If we're changing to a state that is not a sub-state of this one,

this.fsm_validTransitions = undefined;
f.call(this, this.sOn.bind(this), this.sOnce.bind(this),
this.sTimeout.bind(this), this.sOnState.bind(this));
var self = this;
this.fsm_allStateEvents.forEach(function (evt) {
if (self.listeners(evt).length < 1) {
throw (new Error('FSM consistency error: ' +
'state entry function for "' + state + '" did ' +
'not add a handler for all-state event "' +
evt + '"'));
}
});
this.emit('stateChanged', state);

@@ -120,0 +155,0 @@ };

2

package.json
{
"name": "mooremachine",
"version": "1.3.0",
"version": "1.4.0",
"description": "Moore finite state machines",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -18,5 +18,6 @@ mooremachine

This lets you define sequential actions with asynchronous functions. However,
if you need more complex logic within this structure, this becomes rapidly
limiting -- it is difficult, for example, to create a loop. You have to improvise one by nesting some form of loop within a `series` call and a second
This lets you define sequential actions with asynchronous functions. However, if
you need more complex logic within this structure, this becomes rapidly
limiting -- it is difficult, for example, to create a loop. You have to
improvise one by nesting some form of loop within a `series` call and a second
layer of callbacks.

@@ -65,3 +66,152 @@

todo
In this example we'll create an FSM called `ThingFSM`. It's a typical network
client, which wants to make a TCP connection to something and talk to it. It
also wants to delay/backoff and retry on failure.
```js
var mod_mooremachine = require('mooremachine');
var mod_util = require('util');
var mod_net = require('net');
function ThingFSM() {
this.tf_sock = undefined;
this.tf_lastError = undefined;
mod_mooremachine.FSM.call(this, 'stopped');
}
mod_util.inherits(ThingFSM, mod_mooremachine.FSM);
ThingFSM.prototype.state_stopped = function (on) {
var self = this;
on(this, 'startAsserted', function () {
self.gotoState('connecting');
});
};
ThingFSM.prototype.state_connecting = function (on) {
var self = this;
this.tf_sock = mod_net.connect(...);
on(this.tf_sock, 'connect', function () {
self.gotoState('connected');
});
on(this.tf_sock, 'error', function (err) {
self.tf_lastError = err;
self.gotoState('error');
});
};
ThingFSM.prototype.state_error = function (on, once, timeout) {
var self = this;
if (this.tf_sock !== undefined)
this.tf_sock.destroy();
this.tf_sock = undefined;
/* Print an error, do something, check # of retries... */
/* Retry the connection in 5 seconds */
timeout(5000, function () {
self.gotoState('connecting');
});
};
ThingFSM.prototype.state_connected = function (on) {
/* ... */
};
```
API
---
### Inheriting from FSM
Implementations of a state machine should inherit from `mod_mooremachine.FSM`,
using `mod_util.inherits`. The only compulsory methods that the subprototype
must implement are the state callbacks.
### `mod_mooremachine.FSM(initialState)`
Constructor. Must be called by the constructor of the subprototype.
Parameters:
- `initialState`: String, name of the initial state the FSM will enter at
startup
### `mod_mooremachine#state_name(on, once, timeout, onState)`
State entry functions. These run exactly once, at entry to the new state. They
should take any actions associated with the state and set up any callbacks that
can cause transition out of it.
The `on`, `once`, `timeout` and `onState` arguments are functions that should be
used to set up events that can lead to a state transition. The `on` function is
like `EventEmitter#on`, but any handlers set up with it will be automatically
torn down as soon as the FSM leaves its current state. Similar for `once` and
`timeout`. The `onState` function is used in place of calling
`mod_mooremachine#onState` on another FSM.
Parameters:
- `on`: Function `(emitter, event, cb)`, sets up an event callback like
`EventEmitter#on`. Parameters:
- `emitter`: an EventEmitter
- `event`: a String, name of the event
- `cb`: a Function, callback to run when the event happens
- `once`: Function `(emitter, event, cb)`, like `on` but only runs once
- `timeout`: Function `(timeout, cb)`, like `setTimeout()`. Parameters:
- `timeout`: Number, milliseconds until the callback runs
- `cb`: a Function, callback to run
- `onState`: Function `(fsm, state, cb)`
### `mod_mooremachine#validTransitions(possibleStates)`
Should be called from a state entry function. Sets the list of valid transitions
that are possible out of the current state. Any attempt to transition the FSM
out of the current state to a state not on this list (using `gotoState()`) will
throw an error.
Parameters:
- `possibleStates`: Array of String, names of valid states
### `mod_mooremachine#allStateEvent(name)`
Adds an "all-state event". Should be called in the constructor for an FSM
subclass. Any registered all-state event must have a handler registered on it
after any state transition. This allows you to enforce that particular events
must be handled in every state of the FSM.
Parameters:
- `name`: String, name of the event
### `mod_mooremachine#getState()`
Returns a String, full current state of the FSM (including sub-state).
### `mod_mooremachine#isInState(state)`
Tests whether the FSM is in the given state, or any sub-state of it.
Parameters:
- `state`: String, state to test for
Returns a Boolean.
### `mod_mooremachine#onState(state, cb)`
Runs a callback on the next time that the FSM enters a given state or any
sub-state of it.
Parameters:
- `state`: String, state to test for
- `cb`: Function `(newState)`
### `mod_mooremachine#gotoState(state)`
Causes the FSM to enter the given new state.
Parameters:
- `state`: String, state to enter
### `mod_mooremachine.FSM.wrap(fun)`
Wraps a conventional node callback function up into an EventEmitter, to make
life a little easier with `on()`.
Parameters:
- `fun`: Function `(cb)`
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc