shared-redux
Motivations
- Using redux with electron poses a couple of problems. Processes (main and renderer) are isolated.
- At Station, we have the core the app that runs inside a Worker process (invisible renderer). This implies the following:
- The worker process acts as the redux server
- We need a way to have the main process and any other renderer to directly talk to the worker
- Those 2 points make it tricky to use electron own IPC methods because they force the main process to act as the server
Differences with electron-redux
- This fork doesn't enforce FSA
- Supports only ImmutableJS (for now)
- Change dispatch execution order: the process from where the action is dispatched reduces action immediately instead of waiting for the the main to dispatch action in other processes.
- Can be used by electron or node in the same way. This also means that, if used in Electron, any renderer process can act as the "server" instead of the main process.
The solution
shared-redux
offers a plug and play solution:
- Choose a process: it acts as the single source of truth for your redux store
- Choose how your processes communicate: We leverage stream-json-rpc to have a transport agnostic lib. You can plug any stream-compatible layer or write your own.
stream-json-rpc
already implements a Stream layer for electron own IPC and node-ipc
Install
# npm npm install --save shared-redux# yarn yarn add shared-redux
shared-redux
comes as redux middleware:
// in the server store;;// Or if you want to use node-ipc// import { firstConnectionHandler } from 'stream-node-ipc'; // firstConnectionHandler have the following signature:// (callback: (socket: Duplex) => void) => void;// This method should use own Duplex implementation on top of the protocol you have chosen,// and call the given callback with the Duplex as a parameter once a new client is connected.// See https://github.com/getstation/stream-json-rpc/blob/master/packages/stream-electron-ipc/src/index.ts for details.const forwardToClients replayActionServer = ; // reducers are shared amongst processes, so keep them pure!const todoApp = ; const store = ; ;
// in the client store;;// Or any other protocol wrapped in a Duplex const duplex = ; const forwardToServer getInitialStateClient replayActionClient = ; // reducers are shared amongst processes, so keep them pure!const todoApp = ;const initialState = await ; const store = ; ;
And that's it! You are now ready to fire actions without having to worry about synchronising your state between processes.