- Notifications
You must be signed in to change notification settings - Fork1
Run a Redux store and middleware in a Web Worker.
License
patrimart/workeredux
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This library makes it trivial to process expensive calculations in a Web Workerwhile using theRedux pattern you know and love.
If you knowRedux, you already know how to useworkeredux.
This library is built withTypeScript.
Usingnpm:
$ npm i workeredux$ npm i -D worker-loaderUsingYarn:
$ yarn add workeredux$ yarn add -D worker-loaderActions pass through the Redux reducers and middlewares on the main thread as expected.
ThereduxWorkerMiddleware will send Actions marked asWorkerActions to the Worker. If possible,actions will be sent in batches every 33ms.
- Create aWorkerAction with
workerActionCreator. - Mark an Action as aWorkerAction with
markWorkerAction.
TheWorkerAction will pass through the Redux reducers and middlewares in the Worker.
If an Effect in the Worker dispatches aReturnAction it will be dispatched to the main thread.
- Create aReturnAction with
returnActionCreator. - Mark an Action as aReturnAction with
markReturnAction.
Here's a fun little chart of the Action path.
+----------+ +----------+ +----------+ACTION1 -> | Reducers | -> | Store | -> | Effects | -> ACTION2 ↑ +----------+ +----------+ | +----------+ | | +----------+ | ACTION w/ Worker Flag +->| Worker | -> ACTION3 | +----------+ | | | +---------------------------------------------------+ ACTION w/ Return FlagTIP: Take extra care to watch for infinite loops. Especially ifsetting
postAll: trueincreateReduxWorkerMiddleware.
TIP: Only run expensive calculations in the Worker. Attempting to runeverything in the worker will surely lead to madness.
TIP: UseReturnActions to pass Worker state to the main thread.
Example of code that will run in the Web Worker.
import{applyMiddleware}from'redux';import{createLogger}from'redux-logger';importcreateSagaMiddlewarefrom'redux-saga';import{put,select,takeEvery}from'redux-saga/effects';import{createWorkerStore,returnActionCreator}from'workeredux';constdefaultState={counter:0};constreducer=(state=defaultState,action:any)=>{switch(action.type){case'counter/increment':return{counter:state.counter+action.payload||0,};}returnstate;};constcounterAction=returnActionCreator('reduxWorker/counter');function*saga(){yieldtakeEvery('counter/increment',function*(){const{ counter}=yieldselect();yieldput(counterAction(counter));});}constsagaMiddleware=createSagaMiddleware();createWorkerStore(reducer,applyMiddleware(createLogger({collapsed:false,}),sagaMiddleware,),);sagaMiddleware.run(saga);
Example of Redux store setup.
import{createReduxWorkerMiddleware}from'workeredux';importsagasfrom'./sagas';importreducersfrom'./reducers';// Use Webpack's worker-loader to import the Worker.importReduxWorkerfrom'worker-loader!./counter.worker';// Create the middleware for the Worker.const{ reduxWorkerMiddleware}=createReduxWorkerMiddleware(newReduxWorker());constsagaMiddleware=createSagaMiddleware();constcomposeMiddlewares=applyMiddleware(reduxWorkerMiddleware,sagaMiddleware,createLogger({collapsed:true,}),);exportfunctioninitStore(){store=createStore(reducers,composeMiddlewares);sagaMiddleware.run(sagas);returnstore;}
/** * Error Action type. */constREDUX_WORKER_ERROR="@@redux-worker/error-action";`
/** * Type guard checks if the Action has a Worker Action flag. */constisWorkerAction:<Textendsstring>(action:AnyAction)=>action isAction<T>;
/** * Type guard checks for Worker Error Action. */constisErrorAction:(action:AnyAction)=>action isAction<'@@redux-worker/error-action'>;
/** * Mark any Action as a WorkerAction. */constmarkWorkerAction:<Textendsstring>(action:Action<T>)=>Action<T>;
/** * Worker Actions are sent to the web worker. */constworkerActionCreator:<Textendsstring>(type:T,)=><P,M=undefined>(payload:P,meta?:M)=>AnyAction;
/** * Function to create Redux Worker middleware. */functioncreateReduxWorkerMiddleware(worker:Worker,postAll?:boolean,):{reduxWorkerMiddleware:(api:MiddlewareAPI<Dispatch<AnyAction>,any>,)=>(next:(value:Action<any>)=>void)=>(action:Action<any>)=>void;terminate:()=>void;};
/** * Type guard checks if the action has a ReturnAction flag. */exportdeclareconstisReturnAction:<Textendsstring>(action:any)=>action isAction<T>;
/** * Mark any Action as a ReturnAction. */exportdeclareconstmarkReturnAction:<Textendsstring>(action:Action<T>)=>Action<T>;
/** * Return Actions are sent to the client. */exportdeclareconstreturnActionCreator:<Textendsstring>(type:T,)=><P,M=undefined>(payload:P,meta?:M)=>AnyAction;
/** * The createWorkerStore function is identical to the Redux createStore functon. * Except that it automatically includes the middleware to post ReturnActions to the main thread. */constcreateWorkerStore:StoreCreator;
Most likely, you are using Webpack to build your application. You will need to addworker-loader to your config script.
https://github.com/webpack-contrib/worker-loader
While using Workers, you may encounter the errorwindow is not defined, especially ifusingnew webpack.HotModuleReplacementPlugin(). To fix it, addoutput.globalObject: "this"to the Webpack config.
Copyright (c) 2018 Patrick Martin
Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THESOFTWARE.
About
Run a Redux store and middleware in a Web Worker.
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.