Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/mutebg/workerstore

Small React state container running inside WebWorker
https://github.com/mutebg/workerstore

preact react reactjs redux webworker

Last synced: 28 days ago
JSON representation

Small React state container running inside WebWorker

Awesome Lists containing this project

README

        

- [Worker-Store](#worker-store)
- [Examples](#examples)
- [Installation](#installation)
- [Documentaion](#documentaion)
- [Usage](#usage)
- [Debug](#debug)
- [Inspiration](#inspiration)
- [LICENSE](#license)

# Worker-Store

1kb state container running inside WebWorker.
A similar idea to Redux, besides the action-reducers run inside WebWorker.
To do that, dispatch sends only the name of the actions and payload.

Offload expensive work to a WebWorker might improve significant performance.
While Main ( UI ) thread can be blocked from expensive operations, the WebWorker solves that like messaging results ( state ) of the operations to UI thread.

## Examples

[React example](./examples/react)

[Live demo](https://workerstore.surge.sh/)

## Installation

```sh
npm install --save worker-store
```

## Documentaion

[API documentation](./docs)

## Usage

You need worker loader, something like https://github.com/webpack-contrib/worker-loader

In your app.js

```js
import { createStore } from 'worker-store';
import { Provider, connect } from 'worker-store/react';
import Worker from './store.worker.js';

// initial store state
const initState = {count: 0, news: []};

// create store
const store = createStore( initState , new Worker() );

// Select state from the store
const mapStateToProps = ( state, ownProps) => ({
count: state.count,
news: state.news,
});

//Connects React/Preact component to the store.
const App = connect(mapStateToProps)(({count, news, dispatch}) => {
return (


{count}


dispatch('inc')}>+1
dispatch('dec')}>-1
dispatch('fetch', 5)}>fetch news
dispatch('generator')}>generator

)
});

// Makes the store available to the connect() calls in the component hierarchy below.
export default () => (


,
)
```

Inside your web worker: store.worker.js

```js
import { runStore, put } from "worker-store/worker";

// runStore receive objet of actions
// every action receive current state as first parameter
// and rest as parameters from dispatch function
// action must return the next state or part of it
runStore({
inc: state => ({ count: state.count + 1 }),
dec: state => ({ count: state.count - 1 }),

// can return Promise which resolves into next state
fetch: (state, payload) =>
fetch("https://jsonplaceholder.typicode.com/posts/" + payload)
.then(res => res.json())
.then(json => ({ news: json })),

// or generator function which yield next state
generator: function*(state) {
try {
// using yield and put to update the state
yield put({ status: "loading" });
const response = yield fetch(
"https://jsonplaceholder.typicode.com/posts/1"
);
const news = yield response.json();
yield put({ news: news, status: "done" });
} catch (err) {
yield put({ status: "loaded", error: true });
}
}
});
```

## Debug

You can use [kuker](https://github.com/krasimir/kuker) to debug state and actions,
very similar way redux-dev-tools does

```js
store.subscribe(({ state, action }) => {
window.postMessage(
{
kuker: true,
type: "change state",
origin: "none",
label: action,
time: new Date().getTime(),
state: state
},
"*"
);
});
```

## Inspiration

Inspired by
https://github.com/developit/unistore
https://github.com/developit/stockroom

## LICENSE

MIT