Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mjstahl/use-state-machine
Use Finite State Machines with React Hooks
https://github.com/mjstahl/use-state-machine
finite-state-machine fsm javascript react react-hooks state-machine state-management
Last synced: 3 months ago
JSON representation
Use Finite State Machines with React Hooks
- Host: GitHub
- URL: https://github.com/mjstahl/use-state-machine
- Owner: mjstahl
- License: mit
- Created: 2019-02-13T17:34:27.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2019-09-10T13:36:47.000Z (over 5 years ago)
- Last Synced: 2024-10-12T18:16:03.426Z (4 months ago)
- Topics: finite-state-machine, fsm, javascript, react, react-hooks, state-machine, state-management
- Language: JavaScript
- Homepage: https://npm.im/use-state-machine
- Size: 104 KB
- Stars: 28
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![npm bundle size](https://img.shields.io/bundlephobia/minzip/use-state-machine.svg?color=success&label=size) [![Build Status](https://travis-ci.com/mjstahl/use-state-machine.svg?branch=master)](https://travis-ci.com/mjstahl/use-state-machine) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-blue.svg)](https://standardjs.com)
# use-state-machine
Use Finite State Machines with React Hooks* [Installation](#installation)
* [Example](#example)
* [API](#api)
* [Maintainers](#maintainers)
* [License](#license)## Installation
```console
$ npm install --save use-state-machine
```## Example
```js
// H2O.js
import React from 'react'
import { useStateMachine } from 'use-state-machine'
import H2OState from './H2O.state'function H2O () {
const [current, transition] = useStateMachine(H2OState)
return (
Your H2O is in a {current.state} state.
The temperature of your H2O is {current.value}.
transition.toLiquid()}>
To Liquid
transition.freeze()}>
To Solid
transition.boil()}>
To Gas
)
}
``````js
// H2O.state.js
import { StateMachine } from 'use-state-machine'export default new StateMachine({
initial: 'liquid',
liquid: {
freeze: 'solid',
boil: 'gas',
value: '60F'
},
solid: {
melt: 'liquid',
value: '32F'
},
gas: {
chill: 'liquid'
value: '212F'
}
})
```## API
### useStateMachine
```js
import { useStateMachine } from 'use-state-machine'
```**`useStateMachine(machine: Object | StateMachine) -> [Object, Object]`**
`useStateMachine` takes a JavaScript object or `StateMachine` Object as an argument and returns an array consisting of a `current` object and a `transition` object.
**`current -> Object`**
The `current` state consists of two properties: `state` and `value`.
`state` returns the string representing the current state. `value` returns the value (object or primitive) of the current state if one exists and returns `undefined` if not.```js
const [ current ] = useStateMachine(H2OState)current.state //-> 'liquid'
current.value //-> '60F'
```**`transition -> Object`**
`transition` is an object with a collection of functions allowing the developer to avoid
transitioning using the string names. In the example above, when in the `liquid` state, two passive and two active functions exist on `transition`. The passive functions are `transition.toSolid`, `transition.toGas`. The two active functions are `transition.freeze` and `transition.boil`. All state specific functions on `transition` accept a single `value` argument.If the value argument is an Object, the state's `value` and value argument will be merged. If the the state's `value` is not an Object, the state's `value` will be replaced with the value argument. If the state's `value` is a primitive and the value argument is an object, the state's `value` will be set to the value argument including a property named `value` set to the state's previous primitive value.
```js
const [ current, transition ] = useStateMachine(H2OState)
transition.freeze()current.state //-> 'solid'
current.value //-> '32F'transition.melt()
current.state //-> 'liquid'
transition.toGas()
```### StateMachine
```js
import { StateMachine } from 'use-state-machine'
```**`new StateMachine(states: Object) -> StateMachine`**
To create an instance of a StateMachine pass a 'states' object. A valid 'states' object must have, at a minimum, a single state. And an `initial` property which is set to a valid state property.
There are two types of `StateMachine` definitions: "active" and passive. If the definition includes names for each valid transition it is an "active" definition and the `transition` property will include "active" functions (like `freeze()` and `boild()`). An example of an "active" definition is:
```js
new StateMachine({
initial: 'liquid',
liquid: {
freeze: 'solid',
boil: 'gas',
value: '60F'
},
solid: {
melt: 'liquid',
value: '32F'
},
gas: {
chill: 'liquid'
value: '212F'
}
})
```A "passive" definition uses the `to` property on each state indicating one or more valid states the current state can transition to. For a "passive" definition, the `transition` property will only include "passive" functions (like `toSolid` and `toGas`). An example of an "passive" definition is:
```js
new StateMachine({
initial: 'liquid',
liquid: {
to: ['solid', 'gas']
value: '60F'
},
solid: {
to: 'liquid'
value: '32F'
},
gas: {
to: 'liquid'
value: '212F'
}
})
```**`.state -> String`**
Return the string name of the `StateMachine` state.
**`.value -> Any`**
`value` returns the value (object or primitive) of the current state if one exists and returns `undefined` if not.
**`.transition -> Object`**
`transition` is an object with a collection of functions allowing the developer to avoid
transitioning using the string names. In the example above, when in the `liquid` state, two passive and two active functions exist on `transition`. The passive functions are `transition.toSolid`, `transition.toGas`. The two active functions are `transition.freeze` and `transition.boil`. All state specific functions on `transition` accept a single `value` argument.If the value argument is an Object, the state's `value` and value argument will be merged. If the the state's `value` is not an Object, the state's `value` will be replaced with the value argument. If the state's `value` is a primitive and the value argument is an object, the state's `value` will be set to the value argument including a property named `value` set to the state's previous primitive value.
**`.onTransition(callback: Function) -> unsubscribe: Function`**
When a `StateMachine` object transitions from one state to another all callbacks passed to the `onTransition` function are evaluated with the `StateMachine` object passed as the only argument to the callback. `onTransition` returns a function that unsubscribes the callback when executed.
## Maintainers
* Mark Stahl
## License
MIT