This commit is contained in:
Nathan Bierema 2021-07-16 23:57:57 -04:00
parent a3df1df2eb
commit 82c8f142e6
13 changed files with 182 additions and 93 deletions

View File

@ -37,14 +37,14 @@ export function getLocalFilter(config: Config): LocalFilter | undefined {
return undefined; return undefined;
} }
export const noFiltersApplied = (localFilter) => export const noFiltersApplied = (localFilter: LocalFilter | undefined) =>
// !predicate && // !predicate &&
!localFilter && !localFilter &&
(!window.devToolsOptions || (!window.devToolsOptions ||
!window.devToolsOptions.filter || !window.devToolsOptions.filter ||
window.devToolsOptions.filter === FilterState.DO_NOT_FILTER); window.devToolsOptions.filter === FilterState.DO_NOT_FILTER);
export function isFiltered(action, localFilter) { export function isFiltered(action, localFilter: LocalFilter | undefined) {
if ( if (
noFiltersApplied(localFilter) || noFiltersApplied(localFilter) ||
(typeof action !== 'string' && typeof action.type.match !== 'function') (typeof action !== 'string' && typeof action.type.match !== 'function')
@ -76,23 +76,25 @@ function filterStates(computedStates, stateSanitizer) {
})); }));
} }
export function filterState( export function filterState<S, A extends Action<unknown>>(
state, state: LiftedState<S, A, unknown>,
type, type,
localFilter, localFilter: LocalFilter | undefined,
stateSanitizer, stateSanitizer: ((state: S, index: number) => S) | undefined,
actionSanitizer, actionSanitizer: ((action: A, id: number) => A) | undefined,
nextActionId, nextActionId: number | undefined,
predicate predicate: ((state: S, action: A) => boolean) | undefined
) { ) {
if (type === 'ACTION') { if (type === 'ACTION') {
return !stateSanitizer ? state : stateSanitizer(state, nextActionId - 1); return !stateSanitizer ? state : stateSanitizer(state, nextActionId - 1);
} else if (type !== 'STATE') return state; } else if (type !== 'STATE') return state;
if (predicate || !noFiltersApplied(localFilter)) { if (predicate || !noFiltersApplied(localFilter)) {
const filteredStagedActionIds = []; const filteredStagedActionIds: number[] = [];
const filteredComputedStates = []; const filteredComputedStates: { state: S; error?: string | undefined }[] =
const sanitizedActionsById = actionSanitizer && {}; [];
const sanitizedActionsById: { [p: number]: PerformAction<A> } | undefined =
actionSanitizer && {};
const { actionsById } = state; const { actionsById } = state;
const { computedStates } = state; const { computedStates } = state;
@ -114,7 +116,7 @@ export function filterState(
: liftedState : liftedState
); );
if (actionSanitizer) { if (actionSanitizer) {
sanitizedActionsById[id] = { sanitizedActionsById![id] = {
...liftedAction, ...liftedAction,
action: actionSanitizer(currAction, id), action: actionSanitizer(currAction, id),
}; };
@ -137,6 +139,14 @@ export function filterState(
}; };
} }
export interface PartialLiftedState<S, A extends Action<unknown>> {
readonly actionsById: { [actionId: number]: PerformAction<A> };
readonly computedStates: { state: S; error?: string }[];
readonly stagedActionIds: readonly number[];
readonly currentStateIndex: number;
readonly nextActionId: number;
}
export function startingFrom<S, A extends Action<unknown>>( export function startingFrom<S, A extends Action<unknown>>(
sendingActionId: number, sendingActionId: number,
state: LiftedState<S, A, unknown>, state: LiftedState<S, A, unknown>,
@ -148,7 +158,7 @@ export function startingFrom<S, A extends Action<unknown>>(
predicate: predicate:
| (<S, A extends Action<unknown>>(state: S, action: A) => boolean) | (<S, A extends Action<unknown>>(state: S, action: A) => boolean)
| undefined | undefined
) { ): LiftedState<S, A, unknown> | PartialLiftedState<S, A> | undefined {
const stagedActionIds = state.stagedActionIds; const stagedActionIds = state.stagedActionIds;
if (sendingActionId <= stagedActionIds[1]) return state; if (sendingActionId <= stagedActionIds[1]) return state;
const index = stagedActionIds.indexOf(sendingActionId); const index = stagedActionIds.indexOf(sendingActionId);

View File

@ -2,7 +2,7 @@ import mapValues from 'lodash/mapValues';
import jsan from 'jsan'; import jsan from 'jsan';
import seralizeImmutable from '@redux-devtools/serialize/lib/immutable/serialize'; import seralizeImmutable from '@redux-devtools/serialize/lib/immutable/serialize';
function deprecate(param) { function deprecate(param: string) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.warn( console.warn(
`\`${param}\` parameter for Redux DevTools Extension is deprecated. Use \`serialize\` parameter instead: https://github.com/zalmoxisus/redux-devtools-extension/releases/tag/v2.12.1` `\`${param}\` parameter for Redux DevTools Extension is deprecated. Use \`serialize\` parameter instead: https://github.com/zalmoxisus/redux-devtools-extension/releases/tag/v2.12.1`

View File

@ -2,11 +2,12 @@ import jsan, { Options } from 'jsan';
import throttle from 'lodash/throttle'; import throttle from 'lodash/throttle';
import serializeImmutable from '@redux-devtools/serialize/lib/immutable/serialize'; import serializeImmutable from '@redux-devtools/serialize/lib/immutable/serialize';
import { getActionsArray } from '@redux-devtools/utils'; import { getActionsArray } from '@redux-devtools/utils';
import { getLocalFilter, isFiltered } from './filters'; import { getLocalFilter, isFiltered, PartialLiftedState } from './filters';
import importState from './importState'; import importState from './importState';
import generateId from './generateInstanceId'; import generateId from './generateInstanceId';
import { PageScriptToContentScriptMessage } from '../../browser/extension/inject/contentScript'; import { PageScriptToContentScriptMessage } from '../../browser/extension/inject/contentScript';
import { Config } from '../../browser/extension/inject/pageScript'; import { Config } from '../../browser/extension/inject/pageScript';
import { Action } from 'redux';
const listeners = {}; const listeners = {};
export const source = '@devtools-page'; export const source = '@devtools-page';
@ -109,7 +110,10 @@ function post(message: PageScriptToContentScriptMessage) {
window.postMessage(message, '*'); window.postMessage(message, '*');
} }
function getStackTrace(config, toExcludeFromTrace: Function | undefined) { function getStackTrace(
config: Config,
toExcludeFromTrace: Function | undefined
) {
if (!config.trace) return undefined; if (!config.trace) return undefined;
if (typeof config.trace === 'function') return config.trace(); if (typeof config.trace === 'function') return config.trace();
@ -119,9 +123,9 @@ function getStackTrace(config, toExcludeFromTrace: Function | undefined) {
const traceLimit = config.traceLimit; const traceLimit = config.traceLimit;
const error = Error(); const error = Error();
if (Error.captureStackTrace) { if (Error.captureStackTrace) {
if (Error.stackTraceLimit < traceLimit) { if (Error.stackTraceLimit < traceLimit!) {
prevStackTraceLimit = Error.stackTraceLimit; prevStackTraceLimit = Error.stackTraceLimit;
Error.stackTraceLimit = traceLimit; Error.stackTraceLimit = traceLimit!;
} }
Error.captureStackTrace(error, toExcludeFromTrace); Error.captureStackTrace(error, toExcludeFromTrace);
} else { } else {
@ -132,12 +136,12 @@ function getStackTrace(config, toExcludeFromTrace: Function | undefined) {
if ( if (
extraFrames || extraFrames ||
typeof Error.stackTraceLimit !== 'number' || typeof Error.stackTraceLimit !== 'number' ||
Error.stackTraceLimit > traceLimit Error.stackTraceLimit > traceLimit!
) { ) {
const frames = stack!.split('\n'); const frames = stack!.split('\n');
if (frames.length > traceLimit) { if (frames.length > traceLimit!) {
stack = frames stack = frames
.slice(0, traceLimit + extraFrames + (frames[0] === 'Error' ? 1 : 0)) .slice(0, traceLimit! + extraFrames + (frames[0] === 'Error' ? 1 : 0))
.join('\n'); .join('\n');
} }
} }
@ -159,10 +163,38 @@ function amendActionType(
return { action, timestamp, stack }; return { action, timestamp, stack };
} }
export function toContentScript( interface LiftedMessage {
message, readonly type: 'LIFTED';
serializeState: Serialize | undefined, readonly liftedState: { readonly isPaused: boolean };
serializeAction: Serialize | undefined readonly instanceId: number;
readonly source: typeof source;
}
interface PartialStateMessage<S, A extends Action<unknown>> {
readonly type: 'PARTIAL_STATE';
readonly payload: PartialLiftedState<S, A>;
readonly source: typeof source;
readonly instanceId: number;
readonly maxAge: number;
}
interface ExportMessage<S, A extends Action<unknown>> {
readonly type: 'EXPORT';
readonly payload: readonly A[];
readonly committedState: S;
readonly source: typeof source;
readonly instanceId: number;
}
type ToContentScriptMessage<S, A extends Action<unknown>> =
| LiftedMessage
| PartialStateMessage<S, A>
| ExportMessage<S, A>;
export function toContentScript<S, A extends Action<unknown>>(
message: ToContentScriptMessage<S, A>,
serializeState?: Serialize | undefined,
serializeAction?: Serialize | undefined
) { ) {
if (message.type === 'ACTION') { if (message.type === 'ACTION') {
message.action = stringify(message.action, serializeAction); message.action = stringify(message.action, serializeAction);

View File

@ -31,7 +31,7 @@ interface UpdateStateAction {
readonly type: typeof UPDATE_STATE; readonly type: typeof UPDATE_STATE;
} }
type TabMessage = StartAction | StopAction | OptionsMessage; export type TabMessage = StartAction | StopAction | OptionsMessage;
type PanelMessage = NAAction; type PanelMessage = NAAction;
type MonitorMessage = UpdateStateAction; type MonitorMessage = UpdateStateAction;
@ -80,7 +80,22 @@ function toMonitors(
}); });
} }
function toContentScript({ message, action, id, instanceId, state }) { interface ImportMessage {
readonly message: 'IMPORT';
readonly id: string | number;
readonly instanceId: string;
readonly state: string;
}
type ToContentScriptMessage = ImportMessage;
function toContentScript({
message,
action,
id,
instanceId,
state,
}: ToContentScriptMessage) {
connections.tab[id].postMessage({ connections.tab[id].postMessage({
type: message, type: message,
action, action,
@ -251,7 +266,7 @@ function onConnect(port: chrome.runtime.Port) {
id = getId(port.sender!); id = getId(port.sender!);
if (port.sender!.frameId) id = `${id}-${port.sender!.frameId}`; if (port.sender!.frameId) id = `${id}-${port.sender!.frameId}`;
connections.tab[id] = port; connections.tab[id] = port;
listener = (msg: TabToBackgroundMessage) => { listener = (msg) => {
if (msg.name === 'INIT_INSTANCE') { if (msg.name === 'INIT_INSTANCE') {
if (typeof id === 'number') { if (typeof id === 'number') {
chrome.pageAction.show(id); chrome.pageAction.show(id);

View File

@ -1,4 +1,4 @@
import { Dispatch, Store } from 'redux'; import { Dispatch, MiddlewareAPI } from 'redux';
import { import {
SELECT_INSTANCE, SELECT_INSTANCE,
UPDATE_STATE, UPDATE_STATE,
@ -8,7 +8,7 @@ import { StoreState } from '@redux-devtools/app/lib/reducers';
function selectInstance( function selectInstance(
tabId: number, tabId: number,
store: Store<StoreState, StoreAction>, store: MiddlewareAPI<Dispatch<StoreAction>, StoreState>,
next: Dispatch<StoreAction> next: Dispatch<StoreAction>
) { ) {
const instances = store.getState().instances; const instances = store.getState().instances;
@ -33,7 +33,9 @@ function getCurrentTabId(next: (tabId: number) => void) {
); );
} }
export default function popupSelector(store: Store<StoreState, StoreAction>) { export default function popupSelector(
store: MiddlewareAPI<Dispatch<StoreAction>, StoreState>
) {
return (next: Dispatch<StoreAction>) => (action: StoreAction) => { return (next: Dispatch<StoreAction>) => (action: StoreAction) => {
const result = next(action); const result = next(action);
if (action.type === UPDATE_STATE) { if (action.type === UPDATE_STATE) {

View File

@ -4,7 +4,7 @@ import {
SELECT_INSTANCE, SELECT_INSTANCE,
} from '@redux-devtools/app/lib/constants/actionTypes'; } from '@redux-devtools/app/lib/constants/actionTypes';
import { getActiveInstance } from '@redux-devtools/app/lib/reducers/instances'; import { getActiveInstance } from '@redux-devtools/app/lib/reducers/instances';
import { Dispatch, MiddlewareAPI, Store } from 'redux'; import { Dispatch, MiddlewareAPI } from 'redux';
import { StoreState } from '@redux-devtools/app/lib/reducers'; import { StoreState } from '@redux-devtools/app/lib/reducers';
import { StoreAction } from '@redux-devtools/app/lib/actions'; import { StoreAction } from '@redux-devtools/app/lib/actions';

View File

@ -3,21 +3,28 @@ import {
LIFTED_ACTION, LIFTED_ACTION,
} from '@redux-devtools/app/lib/constants/actionTypes'; } from '@redux-devtools/app/lib/constants/actionTypes';
import { getActiveInstance } from '@redux-devtools/app/lib/reducers/instances'; import { getActiveInstance } from '@redux-devtools/app/lib/reducers/instances';
import { Dispatch, MiddlewareAPI, Store } from 'redux';
import { BackgroundState } from '../reducers/background';
import { StoreAction } from '@redux-devtools/app/lib/actions';
const syncStores = (baseStore) => (store) => (next) => (action) => { const syncStores =
if (action.type === UPDATE_STATE) { (baseStore: Store<BackgroundState, StoreAction>) =>
return next({ (store: MiddlewareAPI<Dispatch<StoreAction>>) =>
...action, (next: Dispatch<StoreAction>) =>
instances: baseStore.getState().instances, (action: StoreAction) => {
}); if (action.type === UPDATE_STATE) {
} return next({
if (action.type === LIFTED_ACTION || action.type === 'TOGGLE_PERSIST') { ...action,
const instances = store.getState().instances; instances: baseStore.getState().instances,
const instanceId = getActiveInstance(instances); });
const id = instances.options[instanceId].connectionId; }
baseStore.dispatch({ ...action, instanceId, id }); if (action.type === LIFTED_ACTION || action.type === 'TOGGLE_PERSIST') {
} const instances = store.getState().instances;
return next(action); const instanceId = getActiveInstance(instances);
}; const id = instances.options[instanceId].connectionId;
baseStore.dispatch({ ...action, instanceId, id });
}
return next(action);
};
export default syncStores; export default syncStores;

View File

@ -1,4 +1,6 @@
export default function persistStates(state = false, action) { import { StoreAction } from '@redux-devtools/app/lib/actions';
export default function persistStates(state = false, action: StoreAction) {
if (action.type === 'TOGGLE_PERSIST') return !state; if (action.type === 'TOGGLE_PERSIST') return !state;
return state; return state;
} }

View File

@ -1,5 +1,6 @@
import { Action } from 'redux'; import { Action } from 'redux';
import { LiftedState } from '@redux-devtools/instrument'; import { LiftedState } from '@redux-devtools/instrument';
import { StoreAction } from '@redux-devtools/app/lib/actions';
declare global { declare global {
interface Window { interface Window {
@ -23,7 +24,7 @@ export default class Monitor<S, A extends Action<unknown>> {
) { ) {
this.update = update; this.update = update;
} }
reducer = (state = {}, action) => { reducer = (state = {}, action: StoreAction) => {
if (!this.active) return state; if (!this.active) return state;
this.lastAction = action.type; this.lastAction = action.type;
if (action.type === 'LOCK_CHANGES') { if (action.type === 'LOCK_CHANGES') {

View File

@ -1,13 +1,7 @@
import { Action, compose, Reducer, StoreEnhancerStoreCreator } from 'redux'; import { Action, compose, Reducer, StoreEnhancerStoreCreator } from 'redux';
import instrument, { import instrument from '@redux-devtools/instrument';
LiftedAction,
LiftedState,
} from '@redux-devtools/instrument';
import persistState from '@redux-devtools/core/lib/persistState'; import persistState from '@redux-devtools/core/lib/persistState';
import { import { ConfigWithExpandedMaxAge } from '../../browser/extension/inject/pageScript';
Config,
ConfigWithExpandedMaxAge,
} from '../../browser/extension/inject/pageScript';
export function getUrlParam(key: string) { export function getUrlParam(key: string) {
const matches = window.location.href.match( const matches = window.location.href.match(
@ -16,9 +10,20 @@ export function getUrlParam(key: string) {
return matches && matches.length > 0 ? matches[1] : null; return matches && matches.length > 0 ? matches[1] : null;
} }
export default function configureStore( declare global {
interface Window {
shouldCatchErrors?: boolean;
}
}
export default function configureStore<
S,
A extends Action<unknown>,
MonitorState,
MonitorAction extends Action<unknown>
>(
next: StoreEnhancerStoreCreator, next: StoreEnhancerStoreCreator,
monitorReducer: Reducer, monitorReducer: Reducer<MonitorState, MonitorAction>,
config: ConfigWithExpandedMaxAge config: ConfigWithExpandedMaxAge
) { ) {
return compose( return compose(

View File

@ -3,6 +3,7 @@ import {
getOptionsFromBg, getOptionsFromBg,
isAllowed, isAllowed,
} from '../options/syncOptions'; } from '../options/syncOptions';
import { TabMessage } from '../../../app/middlewares/api';
const source = '@devtools-extension'; const source = '@devtools-extension';
const pageSource = '@devtools-page'; const pageSource = '@devtools-page';
// Chrome message limit is 64 MB, but we're using 32 MB to include other object's parts // Chrome message limit is 64 MB, but we're using 32 MB to include other object's parts
@ -27,8 +28,8 @@ function connect() {
} }
// Relay background script messages to the page script // Relay background script messages to the page script
bg.onMessage.addListener((message) => { bg.onMessage.addListener((message: TabMessage) => {
if (message.action) { if ('action' in message) {
window.postMessage( window.postMessage(
{ {
type: message.type, type: message.type,
@ -39,7 +40,7 @@ function connect() {
}, },
'*' '*'
); );
} else if (message.options) { } else if ('options' in message) {
injectOptions(message.options); injectOptions(message.options);
} else { } else {
window.postMessage( window.postMessage(

View File

@ -1,7 +1,15 @@
import { getActionsArray, evalAction } from '@redux-devtools/utils'; import { getActionsArray, evalAction } from '@redux-devtools/utils';
import throttle from 'lodash/throttle'; import throttle from 'lodash/throttle';
import { Action, PreloadedState, Reducer, Store, StoreEnhancer } from 'redux'; import {
Action,
PreloadedState,
Reducer,
Store,
StoreEnhancer,
StoreEnhancerStoreCreator,
} from 'redux';
import Immutable from 'immutable'; import Immutable from 'immutable';
import { EnhancedStore } from '@redux-devtools/instrument';
import createStore from '../../../app/stores/createStore'; import createStore from '../../../app/stores/createStore';
import configureStore, { getUrlParam } from '../../../app/stores/enhancerStore'; import configureStore, { getUrlParam } from '../../../app/stores/enhancerStore';
import { isAllowed, Options } from '../options/syncOptions'; import { isAllowed, Options } from '../options/syncOptions';
@ -29,14 +37,15 @@ import {
Serialize, Serialize,
} from '../../../app/api'; } from '../../../app/api';
import { import {
InstrumentExt,
LiftedAction, LiftedAction,
LiftedState, LiftedState,
PerformAction, PerformAction,
} from '@redux-devtools/instrument'; } from '@redux-devtools/instrument';
const source = '@devtools-page'; const source = '@devtools-page';
let stores: { [instanceId: number]: Store<unknown, Action<unknown>> } = {}; let stores: {
[instanceId: number]: EnhancedStore<unknown, Action<unknown>, unknown>;
} = {};
let reportId: string | null | undefined; let reportId: string | null | undefined;
function deprecateParam(oldParam: string, newParam: string) { function deprecateParam(oldParam: string, newParam: string) {
@ -89,9 +98,7 @@ export interface ConfigWithExpandedMaxAge {
currentLiftedAction: LiftedAction<S, A, unknown>, currentLiftedAction: LiftedAction<S, A, unknown>,
previousLiftedState: LiftedState<S, A, unknown> | undefined previousLiftedState: LiftedState<S, A, unknown> | undefined
) => number); ) => number);
readonly trace?: readonly trace?: boolean | (() => string | undefined);
| boolean
| (<A extends Action<unknown>>(action: A) => string | undefined);
readonly traceLimit?: number; readonly traceLimit?: number;
readonly shouldCatchErrors?: boolean; readonly shouldCatchErrors?: boolean;
readonly shouldHotReload?: boolean; readonly shouldHotReload?: boolean;
@ -113,7 +120,7 @@ interface ReduxDevtoolsExtension {
preloadedState?: PreloadedState<S>, preloadedState?: PreloadedState<S>,
config?: Config config?: Config
): Store<S, A>; ): Store<S, A>;
(config: Config): StoreEnhancer; (config?: Config): StoreEnhancer;
open: (position?: Position) => void; open: (position?: Position) => void;
notifyErrors: (onError: () => boolean) => void; notifyErrors: (onError: () => boolean) => void;
disconnect: () => void; disconnect: () => void;
@ -125,15 +132,13 @@ declare global {
} }
} }
const __REDUX_DEVTOOLS_EXTENSION__ = reduxDevtoolsExtension; function __REDUX_DEVTOOLS_EXTENSION__<S, A extends Action<unknown>>(
function reduxDevtoolsExtension<S, A extends Action<unknown>>(
reducer?: Reducer<S, A>, reducer?: Reducer<S, A>,
preloadedState?: PreloadedState<S>, preloadedState?: PreloadedState<S>,
config?: Config config?: Config
): Store<S, A>; ): Store<S, A>;
function reduxDevtoolsExtension(config: Config): StoreEnhancer; function __REDUX_DEVTOOLS_EXTENSION__(config: Config): StoreEnhancer;
function reduxDevtoolsExtension<S, A extends Action<unknown>>( function __REDUX_DEVTOOLS_EXTENSION__<S, A extends Action<unknown>>(
reducer?: Reducer<S, A> | Config | undefined, reducer?: Reducer<S, A> | Config | undefined,
preloadedState?: PreloadedState<S>, preloadedState?: PreloadedState<S>,
config?: Config config?: Config
@ -146,7 +151,7 @@ function reduxDevtoolsExtension<S, A extends Action<unknown>>(
/* eslint-enable no-param-reassign */ /* eslint-enable no-param-reassign */
if (!window.devToolsOptions) window.devToolsOptions = {}; if (!window.devToolsOptions) window.devToolsOptions = {};
let store: Store<S, A> & InstrumentExt<S, A, unknown>; let store: EnhancedStore<S, A, unknown>;
let errorOccurred = false; let errorOccurred = false;
let maxAge: number | undefined; let maxAge: number | undefined;
let actionCreators; let actionCreators;
@ -313,7 +318,7 @@ function reduxDevtoolsExtension<S, A extends Action<unknown>>(
); );
sendingActionId = nextActionId; sendingActionId = nextActionId;
if (typeof payload === 'undefined') return; if (typeof payload === 'undefined') return;
if (typeof payload.skippedActionIds !== 'undefined') { if ('skippedActionIds' in payload) {
relay('STATE', payload); relay('STATE', payload);
return; return;
} }
@ -494,23 +499,30 @@ function reduxDevtoolsExtension<S, A extends Action<unknown>>(
relayState(liftedState); relayState(liftedState);
} }
const enhance = (): StoreEnhancer => (next) => { const enhance =
return (reducer_, initialState_) => { () =>
if (!isAllowed(window.devToolsOptions)) { <NextExt, NextStateExt>(
return next(reducer_, initialState_); next: StoreEnhancerStoreCreator<NextExt, NextStateExt>
} ) => {
return <S2 extends S, A2 extends A>(
reducer_: Reducer<S2, A2>,
initialState_?: PreloadedState<S2>
) => {
if (!isAllowed(window.devToolsOptions)) {
return next(reducer_, initialState_);
}
store = stores[instanceId] = configureStore(next, monitor.reducer, { return configureStore(next, monitor.reducer, {
...config, ...config,
maxAge: getMaxAge, maxAge: getMaxAge,
})(reducer_, initialState_); })(reducer_, initialState_);
if (isInIframe()) setTimeout(init, 3000); if (isInIframe()) setTimeout(init, 3000);
else init(); else init();
return store; return store;
};
}; };
};
if (!reducer) return enhance(); if (!reducer) return enhance();
/* eslint-disable no-console */ /* eslint-disable no-console */
@ -538,8 +550,10 @@ window.__REDUX_DEVTOOLS_EXTENSION__.connect = connect;
window.__REDUX_DEVTOOLS_EXTENSION__.disconnect = disconnect; window.__REDUX_DEVTOOLS_EXTENSION__.disconnect = disconnect;
const preEnhancer = const preEnhancer =
(instanceId) => (next) => (reducer, preloadedState, enhancer) => { (instanceId: number): StoreEnhancer =>
const store = next(reducer, preloadedState, enhancer); (next) =>
(reducer, preloadedState) => {
const store = next(reducer, preloadedState);
if (stores[instanceId]) { if (stores[instanceId]) {
stores[instanceId].initialDispatch = store.dispatch; stores[instanceId].initialDispatch = store.dispatch;

View File

@ -100,7 +100,7 @@ interface ImportStateAction<S, A extends Action<unknown>, MonitorState> {
type: typeof ActionTypes.IMPORT_STATE; type: typeof ActionTypes.IMPORT_STATE;
nextLiftedState: LiftedState<S, A, MonitorState> | readonly A[]; nextLiftedState: LiftedState<S, A, MonitorState> | readonly A[];
preloadedState?: S; preloadedState?: S;
noRecompute: boolean | undefined; noRecompute?: boolean | undefined;
} }
interface LockChangesAction { interface LockChangesAction {