-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(#285): add composeWithStateSync to resolve issues with enhancer o…
…rder (#296) * fix(#285): add composeWithStateSync to resolve issues with enhancer order * fix: resolve PR comments * chore: add type tests * docs: update README getting started and add changes to FAQ Co-authored-by: Maciej Małkowski <[email protected]>
- Loading branch information
1 parent
134d290
commit cce8018
Showing
15 changed files
with
260 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* eslint-disable @typescript-eslint/ban-types */ | ||
|
||
import { StoreEnhancer } from 'redux' | ||
import { forwardAction } from './forwardAction' | ||
import { StateSyncOptions } from './options/StateSyncOptions' | ||
import { stateSyncEnhancer } from './stateSyncEnhancer' | ||
|
||
const forwardActionEnhancer = (options?: StateSyncOptions): StoreEnhancer => (createStore) => ( | ||
reducer, | ||
preloadedState | ||
) => { | ||
const store = createStore(reducer, preloadedState) | ||
|
||
return forwardAction(store, options) | ||
} | ||
|
||
const extensionCompose = (options: StateSyncOptions) => ( | ||
...funcs: StoreEnhancer[] | ||
): StoreEnhancer => { | ||
return (createStore) => { | ||
return [ | ||
stateSyncEnhancer({ ...options, preventActionReplay: true }), | ||
...funcs, | ||
forwardActionEnhancer(options), | ||
].reduceRight((composed, f) => f(composed), createStore) | ||
} | ||
} | ||
|
||
export function composeWithStateSync( | ||
options: StateSyncOptions | ||
): (...funcs: Function[]) => StoreEnhancer | ||
export function composeWithStateSync(...funcs: StoreEnhancer[]): StoreEnhancer | ||
export function composeWithStateSync( | ||
firstFuncOrOpts: StoreEnhancer | StateSyncOptions, | ||
...funcs: StoreEnhancer[] | ||
): StoreEnhancer | ((...funcs: StoreEnhancer[]) => StoreEnhancer) { | ||
if (arguments.length === 0) { | ||
return stateSyncEnhancer() | ||
} | ||
if (arguments.length === 1 && typeof firstFuncOrOpts === 'object') { | ||
return extensionCompose(firstFuncOrOpts) | ||
} | ||
return extensionCompose({})(firstFuncOrOpts as StoreEnhancer, ...funcs) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { ipcRenderer, webContents } from 'electron' | ||
import { Store } from 'redux' | ||
import { IPCEvents } from './constants' | ||
import { MainStateSyncEnhancerOptions } from './options/MainStateSyncEnhancerOptions' | ||
import { RendererStateSyncEnhancerOptions } from './options/RendererStateSyncEnhancerOptions' | ||
import { StateSyncOptions } from './options/StateSyncOptions' | ||
import { isMain, isRenderer, validateAction } from './utils' | ||
|
||
export const processActionMain = <A>( | ||
action: A, | ||
options: MainStateSyncEnhancerOptions = {} | ||
): void => { | ||
if (validateAction(action, options.denyList)) { | ||
webContents.getAllWebContents().forEach((contents) => { | ||
// Ignore chromium devtools | ||
if (contents.getURL().startsWith('devtools://')) return | ||
contents.send(IPCEvents.ACTION, action) | ||
}) | ||
} | ||
} | ||
|
||
export const processActionRenderer = <A>( | ||
action: A, | ||
options: RendererStateSyncEnhancerOptions = {} | ||
): void => { | ||
if (validateAction(action, options.denyList)) { | ||
ipcRenderer.send(IPCEvents.ACTION, action) | ||
} | ||
} | ||
|
||
export const forwardAction = <S extends Store<any, any>>( | ||
store: S, | ||
options?: StateSyncOptions | ||
): S => { | ||
return { | ||
...store, | ||
dispatch: (action) => { | ||
const value = store.dispatch(action) | ||
|
||
if (!options?.preventActionReplay) { | ||
if (isMain) { | ||
processActionMain(action, options) | ||
} else if (isRenderer) { | ||
processActionRenderer(action, options) | ||
} | ||
} | ||
|
||
return value | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,13 @@ | ||
import { mainStateSyncEnhancer } from './mainStateSyncEnhancer' | ||
import { stopForwarding } from './utils' | ||
import { rendererStateSyncEnhancer } from './rendererStateSyncEnhancer' | ||
import { stateSyncEnhancer } from './stateSyncEnhancer' | ||
import { composeWithStateSync } from './composeWithStateSync' | ||
|
||
export { mainStateSyncEnhancer, rendererStateSyncEnhancer, stopForwarding } | ||
export { | ||
mainStateSyncEnhancer, | ||
rendererStateSyncEnhancer, | ||
stopForwarding, | ||
stateSyncEnhancer, | ||
composeWithStateSync, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,10 @@ | ||
export type MainStateSyncEnhancerOptions = { | ||
import { StateSyncOptions } from './StateSyncOptions' | ||
|
||
export interface MainStateSyncEnhancerOptions extends StateSyncOptions { | ||
/** | ||
* Custom store serialization function. | ||
* This function is called for each member of the object. If a member contains nested objects, | ||
* the nested objects are transformed before the parent object is. | ||
*/ | ||
serializer?: (this: unknown, key: string, value: unknown) => unknown | ||
|
||
/** | ||
* Custom list for actions that should never replay across stores | ||
*/ | ||
denyList?: RegExp[] | ||
} | ||
|
||
export const defaultMainOptions: MainStateSyncEnhancerOptions = {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export interface StateSyncOptions { | ||
/** | ||
* Custom list for actions that should never replay across stores | ||
*/ | ||
denyList?: RegExp[] | ||
|
||
/** | ||
* Prevent replaying actions in the current process | ||
*/ | ||
preventActionReplay?: boolean | ||
} |
Oops, something went wrong.