Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/qiwi/cyclone
"State machine" for basic purposes
https://github.com/qiwi/cyclone
js-platform
Last synced: 4 days ago
JSON representation
"State machine" for basic purposes
- Host: GitHub
- URL: https://github.com/qiwi/cyclone
- Owner: qiwi
- License: mit
- Created: 2018-09-18T06:41:54.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2024-10-23T06:59:49.000Z (23 days ago)
- Last Synced: 2024-10-30T00:31:56.307Z (17 days ago)
- Topics: js-platform
- Language: TypeScript
- Homepage:
- Size: 1.13 MB
- Stars: 3
- Watchers: 8
- Forks: 1
- Open Issues: 30
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# @qiwi/cyclone
[![CI](https://github.com/qiwi/cyclone/actions/workflows/ci.yaml/badge.svg?branch=master)](https://github.com/qiwi/cyclone/actions/workflows/ci.yaml)
[![Maintainability](https://api.codeclimate.com/v1/badges/86263068bbb0b886ec9d/maintainability)](https://codeclimate.com/github/qiwi/cyclone/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/86263068bbb0b886ec9d/test_coverage)](https://codeclimate.com/github/qiwi/cyclone/test_coverage)"State machine" for basic purposes.
#### Motivation
There're many [redux-state-machine](https://www.google.com/search?q=redux+state+machine) implementations. [krasimir/stent](https://github.com/krasimir/stent) is pretty good among others (just opinion). But:* `Stent` does not allow to "lock" the execution thread. Therefore impossible to verify that `next` step strictly follows (corresponds) by the `prev`.
* Has no standard mechanics for state rollback.If these points are not significant for you, `Stent` might be your best choice.
#### Features
* History-like api
* Lock mechanics
* Multi-step transition declarations#### Typings
* Typescript `typings/index.d.ts`
* Flowtype libdef `flow-typed/index.flow.js` should be found by Flow. If not, add `[lib]` section to [`.flowconfig`](https://flow.org/en/docs/config/libs/)#### API
```javascript
import {Machine} from '@qiwi/cyclone'const handler1 = () => {}
const handler2 = () => {}
const opts = {
initialState: 'foo',
initialData: {a: 'AAA'},
transitions: {
'foo>bar': true, // NOTE applies static DEFAULT_HANDLER
'bar>baz': handler1,
'baz>foo': handler2,
'foo>bar>baz>foo': handler1
},
historySize: 5, // default = 10
}
const machine = new Machine(opts)
```
### Proto
##### `current`
Returns machine state digest:
```javascript
machine.current() // {state: 'foo', data: {a: 'AAA'}, id: '0.2234...', date: 2018-10-07T16:59:23.644Z}
```##### `next`
Transits the machine to a new state:
```javascript
machine.next('bar', {optional: 'args'}, 'for', 'handler')
machine.current() // {state: 'bar', data: {...}, ...}
```##### `prev`
Reverts the last transition:
```javascript
machine.current() // {state: 'bar', data: {...}, ...}
machine.prev() // btw, it returns machine ref
machine.current() // {state: 'foo', data: {...}, ...}
```##### `lock` / `unlock`
Prevents state update.
```javascript
machine.lock('key')
machine.next('qux', {a: 'a'}) // MachineError: Lock violation
machine.unlock('invalidKey') // MachineError: Invalid unlock key
machine.unlock('key')
```### Static
##### DEFAULT_HANDLER
```javascript
DEFAULT_HANDLER('foo', 'bar') // 'bar'
DEFAULT_HANDLER('foo', 'bar', 'baz') // 'baz'
```#### Usage examples
Imagine, [Rematch](https://github.com/rematch/rematch) model:
```javascript
import txn from '../../../../api/txn'
import Machine from '@qiwi/cyclone'
const machine = new Machine({
initialState: 'init',
initialData: {},
transitions: {
'init>loading': true,
'loading>ok': (state, res) => res,
'loading>err': (state, res) => res,
'ok>loading': true,
'err>loading': true
}
})
export default {
state: machine.current(),
reducers: {
next(prev, next, ...payload) {
return machine.next(next, ...payload).current()
}
},
effects: {
async read (opts) {
this.next('loading')
const res = await txn.readList(opts)
this.next('ok', res)
}
}
}
```### Alternatives
* [ericelliott/redux-dsm](https://github.com/ericelliott/redux-dsm)
* [krasimir/stent](https://github.com/krasimir/stent)### License
[MIT](./LICENSE)