mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-27 00:19:55 +03:00
More improvements to types
This commit is contained in:
parent
0915714127
commit
9af6e54649
|
@ -44,31 +44,41 @@ export const noFiltersApplied = (localFilter: LocalFilter | undefined) =>
|
|||
!window.devToolsOptions.filter ||
|
||||
window.devToolsOptions.filter === FilterState.DO_NOT_FILTER);
|
||||
|
||||
export function isFiltered(action, localFilter: LocalFilter | undefined) {
|
||||
export function isFiltered<A extends Action<unknown>>(
|
||||
action: A | string,
|
||||
localFilter: LocalFilter | undefined
|
||||
) {
|
||||
if (
|
||||
noFiltersApplied(localFilter) ||
|
||||
(typeof action !== 'string' && typeof action.type.match !== 'function')
|
||||
(typeof action !== 'string' &&
|
||||
typeof (action.type as string).match !== 'function')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { whitelist, blacklist } = localFilter || window.devToolsOptions || {};
|
||||
const actionType = action.type || action;
|
||||
const actionType = ((action as A).type || action) as string;
|
||||
return (
|
||||
(whitelist && !actionType.match(whitelist)) ||
|
||||
(blacklist && actionType.match(blacklist))
|
||||
);
|
||||
}
|
||||
|
||||
function filterActions(actionsById, actionSanitizer) {
|
||||
function filterActions<A extends Action<unknown>>(
|
||||
actionsById: { [p: number]: PerformAction<A> },
|
||||
actionSanitizer: ((action: A, id: number) => A) | undefined
|
||||
) {
|
||||
if (!actionSanitizer) return actionsById;
|
||||
return mapValues(actionsById, (action, id) => ({
|
||||
return mapValues(actionsById, (action, id: number) => ({
|
||||
...action,
|
||||
action: actionSanitizer(action.action, id),
|
||||
}));
|
||||
}
|
||||
|
||||
function filterStates(computedStates, stateSanitizer) {
|
||||
function filterStates<S>(
|
||||
computedStates: { state: S; error?: string | undefined }[],
|
||||
stateSanitizer: ((state: S, index: number) => S) | undefined
|
||||
) {
|
||||
if (!stateSanitizer) return computedStates;
|
||||
return computedStates.map((state, idx) => ({
|
||||
...state,
|
||||
|
|
|
@ -7,9 +7,16 @@ import importState from './importState';
|
|||
import generateId from './generateInstanceId';
|
||||
import { Config } from '../../browser/extension/inject/pageScript';
|
||||
import { Action } from 'redux';
|
||||
import { LiftedState, PerformAction } from '@redux-devtools/instrument';
|
||||
import {
|
||||
EnhancedStore,
|
||||
LiftedState,
|
||||
PerformAction,
|
||||
} from '@redux-devtools/instrument';
|
||||
import { LibConfig } from '@redux-devtools/app/lib/actions';
|
||||
import { ContentScriptToPageScriptMessage } from '../../browser/extension/inject/contentScript';
|
||||
import {
|
||||
ContentScriptToPageScriptMessage,
|
||||
ListenerMessage,
|
||||
} from '../../browser/extension/inject/contentScript';
|
||||
import { Position } from './openWindow';
|
||||
|
||||
const listeners: {
|
||||
|
@ -267,19 +274,23 @@ function getStackTrace(
|
|||
return stack;
|
||||
}
|
||||
|
||||
function amendActionType(
|
||||
action,
|
||||
config,
|
||||
function amendActionType<A extends Action<unknown>>(
|
||||
action: A | StructuralPerformAction<A> | string,
|
||||
config: Config,
|
||||
toExcludeFromTrace: Function | undefined
|
||||
) {
|
||||
): StructuralPerformAction<A> {
|
||||
let timestamp = Date.now();
|
||||
let stack = getStackTrace(config, toExcludeFromTrace);
|
||||
if (typeof action === 'string') {
|
||||
return { action: { type: action }, timestamp, stack };
|
||||
return { action: { type: action } as A, timestamp, stack };
|
||||
}
|
||||
if (!action.type) return { action: { type: 'update' }, timestamp, stack };
|
||||
if (action.action) return stack ? { stack, ...action } : action;
|
||||
return { action, timestamp, stack };
|
||||
if (!(action as A).type)
|
||||
return { action: { type: 'update' } as A, timestamp, stack };
|
||||
if ((action as StructuralPerformAction<A>).action)
|
||||
return (
|
||||
stack ? { stack, ...action } : action
|
||||
) as StructuralPerformAction<A>;
|
||||
return { action, timestamp, stack } as StructuralPerformAction<A>;
|
||||
}
|
||||
|
||||
interface LiftedMessage {
|
||||
|
@ -305,12 +316,26 @@ interface ExportMessage<S, A extends Action<unknown>> {
|
|||
readonly instanceId: number;
|
||||
}
|
||||
|
||||
interface StructuralPerformAction<A extends Action<unknown>> {
|
||||
readonly action: A;
|
||||
readonly timestamp?: number;
|
||||
readonly stack?: string;
|
||||
}
|
||||
|
||||
type SingleUserAction<A extends Action<unknown>> =
|
||||
| PerformAction<A>
|
||||
| StructuralPerformAction<A>
|
||||
| A;
|
||||
type UserAction<A extends Action<unknown>> =
|
||||
| SingleUserAction<A>
|
||||
| readonly SingleUserAction<A>[];
|
||||
|
||||
interface ActionMessage<S, A extends Action<unknown>> {
|
||||
readonly type: 'ACTION';
|
||||
readonly payload: S;
|
||||
readonly source: typeof source;
|
||||
readonly instanceId: number;
|
||||
readonly action: PerformAction<A> | A;
|
||||
readonly action: UserAction<A>;
|
||||
readonly maxAge: number;
|
||||
readonly nextActionId: number;
|
||||
}
|
||||
|
@ -407,9 +432,9 @@ export function toContentScript<S, A extends Action<unknown>>(
|
|||
}
|
||||
}
|
||||
|
||||
export function sendMessage(
|
||||
action,
|
||||
state,
|
||||
export function sendMessage<S, A extends Action<unknown>>(
|
||||
action: StructuralPerformAction<A> | StructuralPerformAction<A>[],
|
||||
state: S,
|
||||
config: Config,
|
||||
instanceId?: number,
|
||||
name?: string
|
||||
|
@ -459,18 +484,22 @@ export function setListener(
|
|||
}
|
||||
|
||||
const liftListener =
|
||||
(listener, config: Config) => (message: ContentScriptToPageScriptMessage) => {
|
||||
let data = {};
|
||||
<S, A extends Action<unknown>>(
|
||||
listener: (message: ListenerMessage<S, A>) => void,
|
||||
config: Config
|
||||
) =>
|
||||
(message: ContentScriptToPageScriptMessage) => {
|
||||
if (message.type === 'IMPORT') {
|
||||
data.type = 'DISPATCH';
|
||||
data.payload = {
|
||||
type: 'IMPORT_STATE',
|
||||
...importState(message.state, config),
|
||||
};
|
||||
listener({
|
||||
type: 'DISPATCH',
|
||||
payload: {
|
||||
type: 'IMPORT_STATE',
|
||||
...importState(message.state, config),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
data = message;
|
||||
listener(message);
|
||||
}
|
||||
listener(data);
|
||||
};
|
||||
|
||||
export function disconnect() {
|
||||
|
@ -493,8 +522,8 @@ export function connect(preConfig: Config) {
|
|||
const localFilter = getLocalFilter(config);
|
||||
const autoPause = config.autoPause;
|
||||
let isPaused = autoPause;
|
||||
let delayedActions = [];
|
||||
let delayedStates = [];
|
||||
let delayedActions: StructuralPerformAction<Action<unknown>>[] = [];
|
||||
let delayedStates: unknown[] = [];
|
||||
|
||||
const rootListener = (action: ContentScriptToPageScriptMessage) => {
|
||||
if (autoPause) {
|
||||
|
@ -517,7 +546,9 @@ export function connect(preConfig: Config) {
|
|||
|
||||
listeners[id] = [rootListener];
|
||||
|
||||
const subscribe = (listener) => {
|
||||
const subscribe = <S, A extends Action<unknown>>(
|
||||
listener: (message: ListenerMessage<S, A>) => void
|
||||
) => {
|
||||
if (!listener) return undefined;
|
||||
const liftedListener = liftListener(listener, config);
|
||||
const listenersForId = listeners[id] as ((
|
||||
|
@ -541,7 +572,7 @@ export function connect(preConfig: Config) {
|
|||
delayedStates = [];
|
||||
}, latency);
|
||||
|
||||
const send = (action, state) => {
|
||||
const send = <S, A extends Action<unknown>>(action: A, state: S) => {
|
||||
if (
|
||||
isPaused ||
|
||||
isFiltered(action, localFilter) ||
|
||||
|
@ -550,7 +581,7 @@ export function connect(preConfig: Config) {
|
|||
return;
|
||||
}
|
||||
|
||||
let amendedAction = action;
|
||||
let amendedAction: A | StructuralPerformAction<A> = action;
|
||||
const amendedState = config.stateSanitizer
|
||||
? config.stateSanitizer(state)
|
||||
: state;
|
||||
|
@ -561,7 +592,7 @@ export function connect(preConfig: Config) {
|
|||
amendedAction = {
|
||||
action: { type: amendedAction },
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
} as unknown as A;
|
||||
}
|
||||
} else if (config.actionSanitizer) {
|
||||
amendedAction = config.actionSanitizer(action);
|
||||
|
@ -624,8 +655,15 @@ export function connect(preConfig: Config) {
|
|||
};
|
||||
}
|
||||
|
||||
export function updateStore(stores) {
|
||||
return function (newStore, instanceId) {
|
||||
export function updateStore<S, A extends Action<unknown>>(
|
||||
stores: {
|
||||
[K in string | number]: EnhancedStore<S, Action<A>, unknown>;
|
||||
}
|
||||
) {
|
||||
return function (
|
||||
newStore: EnhancedStore<S, Action<A>, unknown>,
|
||||
instanceId: number
|
||||
) {
|
||||
/* eslint-disable no-console */
|
||||
console.warn(
|
||||
'`__REDUX_DEVTOOLS_EXTENSION__.updateStore` is deprecated, remove it and just use ' +
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
CustomAction,
|
||||
DispatchAction as AppDispatchAction,
|
||||
} from '@redux-devtools/app/lib/actions';
|
||||
import { LiftedState } from '@redux-devtools/instrument';
|
||||
const source = '@devtools-extension';
|
||||
const pageSource = '@devtools-page';
|
||||
// Chrome message limit is 64 MB, but we're using 32 MB to include other object's parts
|
||||
|
@ -90,6 +91,27 @@ export type ContentScriptToPageScriptMessage =
|
|||
| ExportAction
|
||||
| UpdateAction;
|
||||
|
||||
interface ImportStatePayload<S, A extends Action<unknown>> {
|
||||
readonly type: 'IMPORT_STATE';
|
||||
readonly nextLiftedState: LiftedState<S, A, unknown> | readonly A[];
|
||||
readonly preloadedState?: S;
|
||||
}
|
||||
|
||||
interface ImportStateDispatchAction<S, A extends Action<unknown>> {
|
||||
readonly type: 'DISPATCH';
|
||||
readonly payload: ImportStatePayload<S, A>;
|
||||
}
|
||||
|
||||
export type ListenerMessage<S, A extends Action<unknown>> =
|
||||
| StartAction
|
||||
| StopAction
|
||||
| DispatchAction
|
||||
| ImportAction
|
||||
| ActionAction
|
||||
| ExportAction
|
||||
| UpdateAction
|
||||
| ImportStateDispatchAction<S, A>;
|
||||
|
||||
function postToPageScript(message: ContentScriptToPageScriptMessage) {
|
||||
window.postMessage(message, '*');
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ import { Features } from '@redux-devtools/app/lib/reducers/instances';
|
|||
|
||||
const source = '@devtools-page';
|
||||
let stores: {
|
||||
[instanceId: number]: EnhancedStore<unknown, Action<unknown>, unknown>;
|
||||
[K in string | number]: EnhancedStore<unknown, Action<unknown>, unknown>;
|
||||
} = {};
|
||||
let reportId: string | null | undefined;
|
||||
|
||||
|
@ -80,12 +80,12 @@ export interface ConfigWithExpandedMaxAge {
|
|||
readonly statesFilter?: <S>(state: S, index?: number) => S;
|
||||
readonly actionsFilter?: <A extends Action<unknown>>(
|
||||
action: A,
|
||||
id: number
|
||||
id?: number
|
||||
) => A;
|
||||
readonly stateSanitizer?: <S>(state: S, index?: number) => S;
|
||||
readonly actionSanitizer?: <A extends Action<unknown>>(
|
||||
action: A,
|
||||
id: number
|
||||
id?: number
|
||||
) => A;
|
||||
readonly predicate?: <S, A extends Action<unknown>>(
|
||||
state: S,
|
||||
|
@ -114,6 +114,7 @@ export interface ConfigWithExpandedMaxAge {
|
|||
readonly autoPause?: boolean;
|
||||
readonly features?: Features;
|
||||
readonly type?: string;
|
||||
readonly getActionType?: <A extends Action<unknown>>(action: A) => A;
|
||||
}
|
||||
|
||||
export interface Config extends ConfigWithExpandedMaxAge {
|
||||
|
|
Loading…
Reference in New Issue
Block a user