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 2.0.0 to 2.0.1

CONTRIBUTING.md

96

lib/fsm.js

@@ -1,3 +0,11 @@

// Copyright 2015 Joyent, Inc.
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Copyright (c) 2016, Joyent, Inc.
*/
module.exports = FSM;

@@ -23,2 +31,4 @@

FSMStateHandle.prototype.validTransitions = function (states) {
if (this.fsh_validTransitions !== undefined)
throw (new Error('FSM validTransitions already set'));
assert.arrayOfString(states, 'states');

@@ -46,2 +56,8 @@ this.fsh_validTransitions = states;

FSMStateHandle.prototype.reset = function () {
this.fsh_valid = true;
this.fsh_nextState = undefined;
};
/* Disconnect just this handle, returning our parent handle (if any). */
FSMStateHandle.prototype.disconnect = function () {

@@ -68,7 +84,21 @@ var ls = this.fsh_listeners;

this.fsh_immediates = [];
if (this.fsh_link !== undefined)
this.fsh_link.disconnect();
this.fsh_valid = false;
var link = this.fsh_link;
this.fsh_link = undefined;
return (link);
};
/* Disconnect this handle and all parents. */
FSMStateHandle.prototype.disconnectAll = function () {
var l = this.disconnect();
if (l !== undefined)
l.disconnectAll();
};
FSMStateHandle.prototype.on = function (obj, evt, cb) {
if (!this.fsh_valid) {
throw (new Error('FSM attempted to set up handler in state ' +
this.fsh_state + ' but already called gotoState() to ' +
'enter state ' + this.fsh_nextState));
}
obj.on(evt, cb);

@@ -79,2 +109,7 @@ this.fsh_listeners.push([obj, evt, cb]);

FSMStateHandle.prototype.interval = function (interval, cb) {
if (!this.fsh_valid) {
throw (new Error('FSM attempted to set up interval in state ' +
this.fsh_state + ' but already called gotoState() to ' +
'enter state ' + this.fsh_nextState));
}
var timer = setInterval(cb, interval);

@@ -86,2 +121,7 @@ this.fsh_intervals.push(timer);

FSMStateHandle.prototype.timeout = function (timeout, cb) {
if (!this.fsh_valid) {
throw (new Error('FSM attempted to set up timeout in state ' +
this.fsh_state + ' but already called gotoState() to ' +
'enter state ' + this.fsh_nextState));
}
var timer = setTimeout(cb, timeout);

@@ -93,2 +133,7 @@ this.fsh_timeouts.push(timer);

FSMStateHandle.prototype.immediate = function (cb) {
if (!this.fsh_valid) {
throw (new Error('FSM attempted to set up immediate in state ' +
this.fsh_state + ' but already called gotoState() to ' +
'enter state ' + this.fsh_nextState));
}
var timer = setImmediate(cb);

@@ -100,2 +145,7 @@ this.fsh_immediates.push(timer);

FSMStateHandle.prototype.callback = function (cb) {
if (!this.fsh_valid) {
throw (new Error('FSM attempted to set up callback in state ' +
this.fsh_state + ' but already called gotoState() to ' +
'enter state ' + this.fsh_nextState));
}
var s = this;

@@ -173,10 +223,40 @@ return (function () {

/*
* If we're changing to a state that is not a sub-state of this one,
* then kill of all timers and listeners we created in this state.
* First, kill event handlers and timers from our previous state, as
* needed.
*/
var parts = (this.fsm_state ? this.fsm_state.split('.') : ['']);
var newParts = state.split('.');
if (parts[0] !== newParts[0] && this.fsm_handle !== undefined) {
this.fsm_handle.disconnect();
this.fsm_handle = undefined;
if (newParts.length > 2)
throw (new Error('Invalid FSM destination state: ' + state));
if (this.fsm_handle !== undefined) {
if (parts[0] === newParts[0] && parts[1] === undefined &&
newParts[1] !== undefined) {
/*
* e.g. 'connected' => 'connected.idle'. Don't
* disconnect anything.
*/
this.fsm_handle.reset();
} else if (parts[0] === newParts[0] && parts[1] !== undefined &&
newParts[1] !== undefined) {
/*
* e.g. 'connected.idle' => 'connected.busy'. Just
* disconnect the things we set up in 'connected.idle'
* while leaving things from 'connected' alone. Also
* reset the parent handle in case it was the cause of
* the transition.
*
* Note we end up here if we're re-entering the same
* exact state, too.
*/
this.fsm_handle = this.fsm_handle.disconnect();
if (this.fsm_handle !== undefined)
this.fsm_handle.reset();
} else {
/*
* e.g. 'connected' => 'closing'. Disconnect all
* handlers (including from any parent states).
*/
this.fsm_handle.disconnectAll();
this.fsm_handle = undefined;
}
}

@@ -183,0 +263,0 @@

@@ -1,3 +0,11 @@

// Copyright 2015 Joyent, Inc.
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Copyright (c) 2016, Joyent, Inc.
*/
var FSM = require('./fsm');

@@ -4,0 +12,0 @@

4

package.json
{
"name": "mooremachine",
"version": "2.0.0",
"version": "2.0.1",
"description": "Moore finite state machines",

@@ -20,3 +20,3 @@ "main": "lib/index.js",

],
"license": "MIT",
"license": "MPL-v2.0",
"bugs": {

@@ -23,0 +23,0 @@ "url": "https://github.com/arekinath/node-mooremachine/issues"

mooremachine
============
Short version
-------------
This is a framework for organising your async node.js code as Moore
Finite State Machines. FSMs can be easier to reason about and debug than
implicit state kept in callbacks and objects, leading to more correct code.
License and contributing
------------------------
MPL v2.0
Contributions should be made through Gerrit -- see
[CONTRIBUTING.md](./CONTRIBUTING.md).
Introduction

@@ -112,3 +127,3 @@ -----------

ThingFSM.prototype.state_connected = function (on) {
ThingFSM.prototype.state_connected = function (S) {
/* ... */

@@ -204,2 +219,7 @@ };

### `FSMStateHandle#callback(cb)`
Wraps an arbitrary callback function in such a way that calling it once the FSM
has left the current state is a no-op.
### `FSMStateHandle#interval(intervalMs, cb)`

@@ -226,1 +246,46 @@

- `state`: String, state to enter
## Sub-states
It is possible to create a "sub-state" with mooremachine FSMs, which "inherits
from" its parent state. For example:
```js
ThingFSM.prototype.state_connected = function (S) {
S.on(this.tf_sock, 'close', function () {
S.gotoState('closed');
});
if (workAvailable)
S.gotoState('connected.busy');
else
S.gotoState('connected.idle');
};
ThingFSM.prototype.state_connected.busy = function (S) {
this.tf_sock.ref();
/* ... */
S.on(this.tf_work, 'finished', function () {
S.gotoState('connected');
});
};
ThingFSM.prototype.state_connected.idle = function (S) {
this.tf_sock.unref();
S.on(this, 'workAvailable', function () {
S.gotoState('connected.busy');
});
};
```
All event handlers that are set up in the `'connected'` state entry function are
kept when entering `'connected.busy'` or `'connected.idle'`. When changing from
`'connected.busy'` to `'connected.idle'`, the handlers set up in that sub-state
are torn down, but those originating from `'connected'` are kept.
While in a sub-state of `'connected'`, `fsm.isInState('connected')` will
continue to evaluate to `true`. Separate `'stateChanged'` events will be emitted
for each sub-state entered.
Once a handle is used to transition to an unrelated state (e.g. `'closed'` in
the example), all handlers are torn down (from both the parent state and
sub-state) as usual before entering the new state.
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