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 ||
|
||||||
window.devToolsOptions.filter === FilterState.DO_NOT_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 (
|
if (
|
||||||
noFiltersApplied(localFilter) ||
|
noFiltersApplied(localFilter) ||
|
||||||
(typeof action !== 'string' && typeof action.type.match !== 'function')
|
(typeof action !== 'string' &&
|
||||||
|
typeof (action.type as string).match !== 'function')
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { whitelist, blacklist } = localFilter || window.devToolsOptions || {};
|
const { whitelist, blacklist } = localFilter || window.devToolsOptions || {};
|
||||||
const actionType = action.type || action;
|
const actionType = ((action as A).type || action) as string;
|
||||||
return (
|
return (
|
||||||
(whitelist && !actionType.match(whitelist)) ||
|
(whitelist && !actionType.match(whitelist)) ||
|
||||||
(blacklist && actionType.match(blacklist))
|
(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;
|
if (!actionSanitizer) return actionsById;
|
||||||
return mapValues(actionsById, (action, id) => ({
|
return mapValues(actionsById, (action, id: number) => ({
|
||||||
...action,
|
...action,
|
||||||
action: actionSanitizer(action.action, id),
|
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;
|
if (!stateSanitizer) return computedStates;
|
||||||
return computedStates.map((state, idx) => ({
|
return computedStates.map((state, idx) => ({
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -7,9 +7,16 @@ import importState from './importState';
|
||||||
import generateId from './generateInstanceId';
|
import generateId from './generateInstanceId';
|
||||||
import { Config } from '../../browser/extension/inject/pageScript';
|
import { Config } from '../../browser/extension/inject/pageScript';
|
||||||
import { Action } from 'redux';
|
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 { 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';
|
import { Position } from './openWindow';
|
||||||
|
|
||||||
const listeners: {
|
const listeners: {
|
||||||
|
@ -267,19 +274,23 @@ function getStackTrace(
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
function amendActionType(
|
function amendActionType<A extends Action<unknown>>(
|
||||||
action,
|
action: A | StructuralPerformAction<A> | string,
|
||||||
config,
|
config: Config,
|
||||||
toExcludeFromTrace: Function | undefined
|
toExcludeFromTrace: Function | undefined
|
||||||
) {
|
): StructuralPerformAction<A> {
|
||||||
let timestamp = Date.now();
|
let timestamp = Date.now();
|
||||||
let stack = getStackTrace(config, toExcludeFromTrace);
|
let stack = getStackTrace(config, toExcludeFromTrace);
|
||||||
if (typeof action === 'string') {
|
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 as A).type)
|
||||||
if (action.action) return stack ? { stack, ...action } : action;
|
return { action: { type: 'update' } as A, timestamp, stack };
|
||||||
return { action, 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 {
|
interface LiftedMessage {
|
||||||
|
@ -305,12 +316,26 @@ interface ExportMessage<S, A extends Action<unknown>> {
|
||||||
readonly instanceId: number;
|
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>> {
|
interface ActionMessage<S, A extends Action<unknown>> {
|
||||||
readonly type: 'ACTION';
|
readonly type: 'ACTION';
|
||||||
readonly payload: S;
|
readonly payload: S;
|
||||||
readonly source: typeof source;
|
readonly source: typeof source;
|
||||||
readonly instanceId: number;
|
readonly instanceId: number;
|
||||||
readonly action: PerformAction<A> | A;
|
readonly action: UserAction<A>;
|
||||||
readonly maxAge: number;
|
readonly maxAge: number;
|
||||||
readonly nextActionId: number;
|
readonly nextActionId: number;
|
||||||
}
|
}
|
||||||
|
@ -407,9 +432,9 @@ export function toContentScript<S, A extends Action<unknown>>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sendMessage(
|
export function sendMessage<S, A extends Action<unknown>>(
|
||||||
action,
|
action: StructuralPerformAction<A> | StructuralPerformAction<A>[],
|
||||||
state,
|
state: S,
|
||||||
config: Config,
|
config: Config,
|
||||||
instanceId?: number,
|
instanceId?: number,
|
||||||
name?: string
|
name?: string
|
||||||
|
@ -459,18 +484,22 @@ export function setListener(
|
||||||
}
|
}
|
||||||
|
|
||||||
const liftListener =
|
const liftListener =
|
||||||
(listener, config: Config) => (message: ContentScriptToPageScriptMessage) => {
|
<S, A extends Action<unknown>>(
|
||||||
let data = {};
|
listener: (message: ListenerMessage<S, A>) => void,
|
||||||
|
config: Config
|
||||||
|
) =>
|
||||||
|
(message: ContentScriptToPageScriptMessage) => {
|
||||||
if (message.type === 'IMPORT') {
|
if (message.type === 'IMPORT') {
|
||||||
data.type = 'DISPATCH';
|
listener({
|
||||||
data.payload = {
|
type: 'DISPATCH',
|
||||||
type: 'IMPORT_STATE',
|
payload: {
|
||||||
...importState(message.state, config),
|
type: 'IMPORT_STATE',
|
||||||
};
|
...importState(message.state, config),
|
||||||
|
},
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
data = message;
|
listener(message);
|
||||||
}
|
}
|
||||||
listener(data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function disconnect() {
|
export function disconnect() {
|
||||||
|
@ -493,8 +522,8 @@ export function connect(preConfig: Config) {
|
||||||
const localFilter = getLocalFilter(config);
|
const localFilter = getLocalFilter(config);
|
||||||
const autoPause = config.autoPause;
|
const autoPause = config.autoPause;
|
||||||
let isPaused = autoPause;
|
let isPaused = autoPause;
|
||||||
let delayedActions = [];
|
let delayedActions: StructuralPerformAction<Action<unknown>>[] = [];
|
||||||
let delayedStates = [];
|
let delayedStates: unknown[] = [];
|
||||||
|
|
||||||
const rootListener = (action: ContentScriptToPageScriptMessage) => {
|
const rootListener = (action: ContentScriptToPageScriptMessage) => {
|
||||||
if (autoPause) {
|
if (autoPause) {
|
||||||
|
@ -517,7 +546,9 @@ export function connect(preConfig: Config) {
|
||||||
|
|
||||||
listeners[id] = [rootListener];
|
listeners[id] = [rootListener];
|
||||||
|
|
||||||
const subscribe = (listener) => {
|
const subscribe = <S, A extends Action<unknown>>(
|
||||||
|
listener: (message: ListenerMessage<S, A>) => void
|
||||||
|
) => {
|
||||||
if (!listener) return undefined;
|
if (!listener) return undefined;
|
||||||
const liftedListener = liftListener(listener, config);
|
const liftedListener = liftListener(listener, config);
|
||||||
const listenersForId = listeners[id] as ((
|
const listenersForId = listeners[id] as ((
|
||||||
|
@ -541,7 +572,7 @@ export function connect(preConfig: Config) {
|
||||||
delayedStates = [];
|
delayedStates = [];
|
||||||
}, latency);
|
}, latency);
|
||||||
|
|
||||||
const send = (action, state) => {
|
const send = <S, A extends Action<unknown>>(action: A, state: S) => {
|
||||||
if (
|
if (
|
||||||
isPaused ||
|
isPaused ||
|
||||||
isFiltered(action, localFilter) ||
|
isFiltered(action, localFilter) ||
|
||||||
|
@ -550,7 +581,7 @@ export function connect(preConfig: Config) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let amendedAction = action;
|
let amendedAction: A | StructuralPerformAction<A> = action;
|
||||||
const amendedState = config.stateSanitizer
|
const amendedState = config.stateSanitizer
|
||||||
? config.stateSanitizer(state)
|
? config.stateSanitizer(state)
|
||||||
: state;
|
: state;
|
||||||
|
@ -561,7 +592,7 @@ export function connect(preConfig: Config) {
|
||||||
amendedAction = {
|
amendedAction = {
|
||||||
action: { type: amendedAction },
|
action: { type: amendedAction },
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
};
|
} as unknown as A;
|
||||||
}
|
}
|
||||||
} else if (config.actionSanitizer) {
|
} else if (config.actionSanitizer) {
|
||||||
amendedAction = config.actionSanitizer(action);
|
amendedAction = config.actionSanitizer(action);
|
||||||
|
@ -624,8 +655,15 @@ export function connect(preConfig: Config) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateStore(stores) {
|
export function updateStore<S, A extends Action<unknown>>(
|
||||||
return function (newStore, instanceId) {
|
stores: {
|
||||||
|
[K in string | number]: EnhancedStore<S, Action<A>, unknown>;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
return function (
|
||||||
|
newStore: EnhancedStore<S, Action<A>, unknown>,
|
||||||
|
instanceId: number
|
||||||
|
) {
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
console.warn(
|
console.warn(
|
||||||
'`__REDUX_DEVTOOLS_EXTENSION__.updateStore` is deprecated, remove it and just use ' +
|
'`__REDUX_DEVTOOLS_EXTENSION__.updateStore` is deprecated, remove it and just use ' +
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
CustomAction,
|
CustomAction,
|
||||||
DispatchAction as AppDispatchAction,
|
DispatchAction as AppDispatchAction,
|
||||||
} from '@redux-devtools/app/lib/actions';
|
} from '@redux-devtools/app/lib/actions';
|
||||||
|
import { LiftedState } from '@redux-devtools/instrument';
|
||||||
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
|
||||||
|
@ -90,6 +91,27 @@ export type ContentScriptToPageScriptMessage =
|
||||||
| ExportAction
|
| ExportAction
|
||||||
| UpdateAction;
|
| 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) {
|
function postToPageScript(message: ContentScriptToPageScriptMessage) {
|
||||||
window.postMessage(message, '*');
|
window.postMessage(message, '*');
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ import { Features } from '@redux-devtools/app/lib/reducers/instances';
|
||||||
|
|
||||||
const source = '@devtools-page';
|
const source = '@devtools-page';
|
||||||
let stores: {
|
let stores: {
|
||||||
[instanceId: number]: EnhancedStore<unknown, Action<unknown>, unknown>;
|
[K in string | number]: EnhancedStore<unknown, Action<unknown>, unknown>;
|
||||||
} = {};
|
} = {};
|
||||||
let reportId: string | null | undefined;
|
let reportId: string | null | undefined;
|
||||||
|
|
||||||
|
@ -80,12 +80,12 @@ export interface ConfigWithExpandedMaxAge {
|
||||||
readonly statesFilter?: <S>(state: S, index?: number) => S;
|
readonly statesFilter?: <S>(state: S, index?: number) => S;
|
||||||
readonly actionsFilter?: <A extends Action<unknown>>(
|
readonly actionsFilter?: <A extends Action<unknown>>(
|
||||||
action: A,
|
action: A,
|
||||||
id: number
|
id?: number
|
||||||
) => A;
|
) => A;
|
||||||
readonly stateSanitizer?: <S>(state: S, index?: number) => S;
|
readonly stateSanitizer?: <S>(state: S, index?: number) => S;
|
||||||
readonly actionSanitizer?: <A extends Action<unknown>>(
|
readonly actionSanitizer?: <A extends Action<unknown>>(
|
||||||
action: A,
|
action: A,
|
||||||
id: number
|
id?: number
|
||||||
) => A;
|
) => A;
|
||||||
readonly predicate?: <S, A extends Action<unknown>>(
|
readonly predicate?: <S, A extends Action<unknown>>(
|
||||||
state: S,
|
state: S,
|
||||||
|
@ -114,6 +114,7 @@ export interface ConfigWithExpandedMaxAge {
|
||||||
readonly autoPause?: boolean;
|
readonly autoPause?: boolean;
|
||||||
readonly features?: Features;
|
readonly features?: Features;
|
||||||
readonly type?: string;
|
readonly type?: string;
|
||||||
|
readonly getActionType?: <A extends Action<unknown>>(action: A) => A;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Config extends ConfigWithExpandedMaxAge {
|
export interface Config extends ConfigWithExpandedMaxAge {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user