# immutable-state-machine

> Immutable state machine for Javascript with ability to associate extra data with each state. Useful for React.

Latest version **1.2.0** (published 2016-09-30) · MIT license · 0 weekly downloads

## Install

```sh
npm install immutable-state-machine
pnpm add immutable-state-machine
yarn add immutable-state-machine
bun add immutable-state-machine
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.2.0 |
| Published | 2016-09-30 |
| First published | 2016-02-09 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 6 |
| Author | Ramesh Nair |
| Maintainers | hiddentao |
| Keywords | statemachine, state, immutable, react, es6 |

## Links

- npm: https://www.npmjs.com/package/immutable-state-machine
- Repository: https://github.com/hiddentao/immutable-state-machine
- Issues: https://github.com/hiddentao/immutable-state-machine/issues
- npm.io page: https://npm.io/package/immutable-state-machine

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 1.2.0 (latest) — 2016-09-30
- 1.1.0 — 2016-09-30
- 1.0.1 — 2016-02-09
- 1.0.0 — 2016-02-09

## README

# Immutable state machine

[![Build Status](https://secure.travis-ci.org/hiddentao/immutable-state-machine.png)](http://travis-ci.org/hiddentao/immutable-state-machine)

A simple yet flexible _immutable_ [finite-state machine](https://en.wikipedia.org/wiki/Finite-state_machine) for Javascript. Great for when building with frameworks like 
[React](https://facebook.github.io/react/).

Features:

* Works in Node.js and the browser.
* Immutability - use simple object equality to check if state changed.
* Restrict state transitions using from/to rules.
* Store additional data alongside each state.
* Very small (<2 KB).


## Installation

### CommonJS

Install using [npm](http://npmjs.org/):

  $ npm install immutable-state-machine

### Browser

Include the `build/immutableStateMachine.js` script.

In the browser the library is exposed via the `ImmutableStateMachine` class function.

## How to use

### The basics - states and data

Let's create a machine with two states - `start` and `stop`:

```javascript
var Machine = require('immutable-state-machine');

/*
We'll have two states - "start" and "stop"
*/
var m = new Machine([
  'start',
  'stop'
]);

console.log( m.getState() );      // "start"
console.log( m.getData() );       // null
```

By default the first state passed-in (`start`) is the initially active state. 
The data associated with a state is initially always `null`. 

If needed we can explicitly set the initial state:

```javascript
var m = new Machine([
  'start',
  {
    id: 'stop',
    initial: true,
  }
]);

console.log( m.getState() );      // "stop"
```

Now let's goto a new state and see what happens:

```javascript
var m = new Machine([
  'start',
  'start'
]);

var m2 = m.goto('stop');

console.log( m2 === m );      // false
console.log( m2.getState() ); // "stop"
console.log( m.getState() );  // "start"
```

As expected according to _immutability_, it returned a new instance of the 
machine, leaving the original unchanged. 

Instead, what if we went to the same state?

```javascript
var m = new Machine([
  'start',
  'start'
]);

var m2 = m.goto('start');

console.log( m2 === m );      // true

console.log( m2.getState() ); // "start"
console.log( m2.getData() ); // null
```

The same instance gets returned back as expected. But if we goto the same state 
with different data a new instance will be returned:

```javascript
var m = new Machine([
  'start',
  'start'
]);

var m2 = m.goto('start', {
  some: 'data'
});

console.log( m2 === m );      // false

console.log( m2.getState() ); // "start"
console.log( m2.getData() ); // { some: 'data' }

console.log( m.getState() ); // "start"
console.log( m.getData() ); // null
```


### Restricting transitions

By default we can transition from any state to any other state.

But sometimes we want to restrict state-to-state transitions according to 
pre-configured rules. We can specify such rules using `from` and `to` arrays:

```javascript
var Machine = require('immutable-state-machine');

var m = new Machine([
  {
    id: 'step1',
    from: [],
    to: ['step2'],
  },
  {
    id: 'step2',
    from: ['step1'],
    to: ['step3'],
  },
  {
    id: 'step3',
    from: ['step2'],
    to: ['step4'],
  },
  {
    id: 'step4',
    from: ['step3'],
    to: ['step1'],
  },
])

console.log( m.getState() );    // "step1"

// m.goto('step3');  -> Error
// m.goto('step4');  -> Error

m.goto('step2');

// m.goto('step1');  -> Error
// m.goto('step4');  -> Error

m.goto('step3');

// m.goto('step1');  -> Error
// m.goto('step2');  -> Error

m.goto('step4');

// m.goto('step1');  -> Error, because step1 "from" is empty array
// m.goto('step2');  -> Error
// m.goto('step3');  -> Error
```

The above machine allows us transition from `step1` through to `step4` and 
then nothing else. Note that although we have specified that `step4` may 
transition _to_ `step1`, we specified an empty _from_ array for `step1` thus 
specifying that it is not possible to transition to `step1` from another step.


### Seamless sub-classing

If you inherit from `Machine` then all methods will return new instances of 
your subclass rather than the base class.

```js
class MyMachine extends Dummy {}
  
var m = new MyMachine(['start', 'stop']);

var m2 = m.goto('stop');

console.log( m2 instanceof MyMachine ); /* true */
```

## Building

To build the code and run the tests:

    $ npm install -g gulp
    $ npm install
    $ npm run build


## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](https://github.com/hiddentao/immutable-state-machine/blob/master/CONTRIBUTING.md).

## License

MIT - see [LICENSE.md](https://github.com/hiddentao/immutable-state-machine/blob/master/LICENSE.md)

---
_Source: https://npm.io/package/immutable-state-machine · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
