# quex

> State Transition Processor

Latest version **0.0.8** (published 2017-03-05) · MIT license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install quex
pnpm add quex
yarn add quex
bun add quex
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 0.0.8 |
| Published | 2017-03-05 |
| First published | 2017-02-07 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 1 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | cotto |
| Maintainers | cotto |
| Keywords | flux, queue, typescript |

## Links

- npm: https://www.npmjs.com/package/quex
- Repository: https://github.com/cotto89/quex
- Homepage: https://github.com/cotto89/quex#readme
- Issues: https://github.com/cotto89/quex/issues
- npm.io page: https://npm.io/package/quex

## Dependencies (1)

- [@types/node](https://npm.io/package/@types/node.md) ^7.0.5

## Alternatives

- [cron](https://npm.io/package/cron.md) — 4.9M weekly downloads
- [@vercel/queue](https://npm.io/package/@vercel/queue.md) — 731.6K weekly downloads
- [create-sonicjs](https://npm.io/package/create-sonicjs.md) — 1.6K weekly downloads
- [@exellix/jobs-api](https://npm.io/package/@exellix/jobs-api.md) — 941 weekly downloads
- [@forwardimpact/libskill](https://npm.io/package/@forwardimpact/libskill.md) — 575 weekly downloads

## Recent versions

- 0.0.8 (latest) — 2017-03-05
- 0.0.7 — 2017-03-04
- 0.0.6 — 2017-02-17
- 0.0.5 — 2017-02-16
- 0.0.4 — 2017-02-15
- 0.0.3 — 2017-02-14
- 0.0.2 — 2017-02-09
- 0.0.1 — 2017-02-07

## README

# Quex

State Transition Processor.

Quex is not a Flux that process with Command Pattern but just processor use to state transition with `Queue` and `Task`.

## Install

```
npm i -S quex
```

https://www.npmjs.com/package/quex

## Example

```js
import createStore from 'quex';

const store = createStore({ count: 0 });

// Subscribing changing of state.
const unsubscribe = store.subscribe((state, error) => {
	// ...
})

const task = {
    increment: (state count) => ({
        count: s.count + count
    }),

    /*
     * AsyncTask
     *
     * AsyncTask should return TaskFunction, not state,
     * whenever want to update state.
     */
    incrementAsync: async (_, count) => {
        const n = await Promise.resolve(count);
        return (state) => ({
            count: s.count + n
        });
    },

    incrementMulti: (state, count) => ({
        count: s.count * count
    })
};

store.usecase('INCREMENT').use([
	task.increment,
	task.incrementAsync,

	// incrementMult will waiting for the completion of incrementAsync
	task.incrementMulti,

	// currentState will be this
	(state, params) => {
		assert.deepEqual(state, { count: 8 });
		assert.equal(params, 2)
	}
])(2)
```


## API

### `createStore<S>(initialState: S, option?: Option<S>): store`

**return**: `store`.

##### `Option`

```js
interface Option<S> {
    updater?: (currentState: S, nextState: Partial<S>) => S;
    enhancer?: <T>(name: string | undefined, task: T) => T;
}
```

#### `option.updater`

`updater` can customize how to assign currentState and nextState.

**default**: `(s1: S, s2: Partial<S>) => Object.assign({}, s1, s2)`

#### `option.enhancer`

`enhancer` can enhance all task in all queue.

Example: For logging.

```js
const enhancer = (name, task) => (state, params) => {
    const result = task(state, params);
    console.log(`${name}::${task.name}`, result);
    return result
}
```


### `store.getState(): S`

### `store.setState(state: Partial<S>): S`

### `store.subscribe(Listener): () => void`

Subscribing changing of state and transition error.

**return**: Function that remove listener.

```js
interface Listener {
	(state: S, error: Error) => void;
}
```

### `store.usecase(name?: string): { use }`

`store.usecaes` copmose a queue by `use`.

**alias**: `store.dispatch()`

**return**: `use()`

```js
/* Type of Task */
interface T1<S> {
    (state: S): Partial<S> | void;
}
interface T2<S> {
    (state: S): Promise<T1<S>> | void;
}
interface T3<S, P> {
    (state: S, param: P): Partial<S> | void;
}
interface T4<S, P> {
    (state: S, param: P): Promise<T3<S, P>> | void;
}

/* Type of Queue */
type Q1<S> = (T1<S> | T2<S>)[];
type Q2<S, P> = (T3<S, P> | T4<S, P>)[];
```

`use` can chain.

```js
store.usecase()
    .use(task.increment)
    .use(task.incrementAsync)
    .use(task.incrementMulti)
```


### `store.listenerCount`

```js
 readonly listenerCount: number;
```

## Advanced

### About Task

Basicaly, `Task` is a Function that recieve `currentState` and `parameter` then return `nextState`.

State will be change when Task return `nextState`.

#### AsyncTask

**AsyncTask should return `Promise<Function>`, not `Promise<State>`**, whenever want to update state.

```js
type Task = (state: S, params: P) => S
type AsyncTask = (state: S, params: P) => Promise<Task>
```

### How to process task in the queue

All task in the queue are waiting for completition of previous task even if it is AsyncTask.

 If task throw Error, Queue processing is aborted.


### Transition aborting

To abort state transition, Throw Error in the Task.


### Timing of publishing new state to listener

#### 1. When last task in the queue is compoleted.

Notification is reduced when state is updated by the sequence of SyncTask in order to reduce rendering of view.

#### 2. When task return Promise.

Otherwise, view will not updated until async process is completed.

#### 3. When Task throw Error

In this case, State transition is aborted and Listener is called with state and error.


### With React.js

If you are using Quex with React.js, you can use [react-redux](https://github.com/reactjs/react-redux) without special settings.

Example:

```js
const store = createStore({count: 0})

<Provider store={store}>
	<Counter>
</Provider>
```

```js
/* mapUseCaseToProps */
const mapUseCaseToProps = (usecase) => ({
	increment: usecase('INCREMENT').use([
 		task.increment
 	])
})

/* connect */
export default connect(mapStateToProps, mapUseCaseToProps)(Counter)
```

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