mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-11 00:32:19 +03:00
Enable linting for extension
This commit is contained in:
parent
b934e80d23
commit
42ba91917a
43
eslint.js.react.jest.config.base.mjs
Normal file
43
eslint.js.react.jest.config.base.mjs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import eslint from '@eslint/js';
|
||||||
|
import react from 'eslint-plugin-react';
|
||||||
|
import { fixupPluginRules } from '@eslint/compat';
|
||||||
|
import eslintPluginReactHooks from 'eslint-plugin-react-hooks';
|
||||||
|
import jest from 'eslint-plugin-jest';
|
||||||
|
import eslintConfigPrettier from 'eslint-config-prettier';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
files: ['test/**/*.js', 'test/**/*.jsx'],
|
||||||
|
...eslint.configs.recommended,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['test/**/*.js', 'test/**/*.jsx'],
|
||||||
|
...react.configs.flat.recommended,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['test/**/*.js', 'test/**/*.jsx'],
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['test/**/*.js', 'test/**/*.jsx'],
|
||||||
|
plugins: {
|
||||||
|
'react-hooks': fixupPluginRules(eslintPluginReactHooks),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['test/**/*.js', 'test/**/*.jsx'],
|
||||||
|
...jest.configs['flat/recommended'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['test/**/*.js', 'test/**/*.jsx'],
|
||||||
|
...jest.configs['jest/style'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['test/**/*.js', 'test/**/*.jsx'],
|
||||||
|
...eslintConfigPrettier,
|
||||||
|
},
|
||||||
|
];
|
|
@ -1,3 +0,0 @@
|
||||||
node_modules
|
|
||||||
dist
|
|
||||||
examples
|
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"root": true,
|
|
||||||
"extends": "eslint-config-airbnb",
|
|
||||||
"globals": {
|
|
||||||
"chrome": true,
|
|
||||||
"__DEVELOPMENT__": true
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"browser": true,
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"react/jsx-uses-react": 2,
|
|
||||||
"react/jsx-uses-vars": 2,
|
|
||||||
"react/react-in-jsx-scope": 2,
|
|
||||||
"react/jsx-quotes": 0,
|
|
||||||
"block-scoped-var": 0,
|
|
||||||
"padded-blocks": 0,
|
|
||||||
"quotes": [1, "single"],
|
|
||||||
"comma-style": [2, "last"],
|
|
||||||
"no-use-before-define": [0, "nofunc"],
|
|
||||||
"func-names": 0,
|
|
||||||
"prefer-const": 0,
|
|
||||||
"comma-dangle": 0,
|
|
||||||
"id-length": 0,
|
|
||||||
"indent": [2, 2, { "SwitchCase": 1 }],
|
|
||||||
"new-cap": [2, { "capIsNewExceptions": ["Test"] }],
|
|
||||||
"default-case": 0
|
|
||||||
},
|
|
||||||
"plugins": ["react"]
|
|
||||||
}
|
|
38
extension/eslint.config.mjs
Normal file
38
extension/eslint.config.mjs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import globals from 'globals';
|
||||||
|
import eslintJs from '../eslint.js.config.base.mjs';
|
||||||
|
import eslintTsReact from '../eslint.ts.react.config.base.mjs';
|
||||||
|
import eslintJsReactJest from '../eslint.js.react.jest.config.base.mjs';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
...eslintJs,
|
||||||
|
...eslintTsReact(import.meta.dirname),
|
||||||
|
...eslintJsReactJest,
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
'chrome',
|
||||||
|
'dist',
|
||||||
|
'edge',
|
||||||
|
'examples',
|
||||||
|
'firefox',
|
||||||
|
'test/electron/fixture/dist',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['build.mjs'],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.nodeBuiltin,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['test/**/*.js', 'test/**/*.jsx'],
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
...globals.node,
|
||||||
|
EUI: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
|
@ -3,7 +3,7 @@ module.exports = {
|
||||||
testPathIgnorePatterns: ['<rootDir>/examples'],
|
testPathIgnorePatterns: ['<rootDir>/examples'],
|
||||||
testEnvironment: 'jsdom',
|
testEnvironment: 'jsdom',
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'\\.css$': '<rootDir>/test/__mocks__/styleMock.ts',
|
'\\.css$': '<rootDir>/test/__mocks__/styleMock.js',
|
||||||
},
|
},
|
||||||
transformIgnorePatterns: [
|
transformIgnorePatterns: [
|
||||||
'node_modules/(?!.pnpm|@babel/code-frame|@babel/highlight|@babel/helper-validator-identifier|chalk|d3|dateformat|delaunator|internmap|jsondiffpatch|lodash-es|nanoid|robust-predicates|uuid)',
|
'node_modules/(?!.pnpm|@babel/code-frame|@babel/highlight|@babel/helper-validator-identifier|chalk|d3|dateformat|delaunator|internmap|jsondiffpatch|lodash-es|nanoid|robust-predicates|uuid)',
|
|
@ -17,9 +17,10 @@
|
||||||
"clean": "rimraf dist && rimraf chrome/dist && rimraf edge/dist && rimraf firefox/dist",
|
"clean": "rimraf dist && rimraf chrome/dist && rimraf edge/dist && rimraf firefox/dist",
|
||||||
"test:app": "cross-env BABEL_ENV=test jest test/app",
|
"test:app": "cross-env BABEL_ENV=test jest test/app",
|
||||||
"test:chrome": "jest test/chrome",
|
"test:chrome": "jest test/chrome",
|
||||||
|
"build:test:electron:fixture": "webpack --config test/electron/fixture/webpack.config.js",
|
||||||
"test:electron": "pnpm run build:test:electron:fixture && jest test/electron",
|
"test:electron": "pnpm run build:test:electron:fixture && jest test/electron",
|
||||||
"test": "pnpm run test:app && pnpm run test:chrome && pnpm run test:electron",
|
"test": "pnpm run test:app && pnpm run test:chrome && pnpm run test:electron",
|
||||||
"build:test:electron:fixture": "webpack --config test/electron/fixture/webpack.config.js",
|
"lint": "eslint .",
|
||||||
"type-check": "tsc --noEmit"
|
"type-check": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -64,12 +65,7 @@
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"electron": "^31.6.0",
|
"electron": "^31.6.0",
|
||||||
"esbuild": "^0.23.1",
|
"esbuild": "^0.23.1",
|
||||||
"eslint": "^8.57.1",
|
"globals": "^15.9.0",
|
||||||
"eslint-config-airbnb": "^19.0.4",
|
|
||||||
"eslint-plugin-import": "^2.30.0",
|
|
||||||
"eslint-plugin-jsx-a11y": "^6.10.0",
|
|
||||||
"eslint-plugin-react": "^7.36.1",
|
|
||||||
"eslint-plugin-react-hooks": "^4.6.2",
|
|
||||||
"immutable": "^4.3.7",
|
"immutable": "^4.3.7",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-environment-jsdom": "^29.7.0",
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
|
|
|
@ -31,19 +31,19 @@ type Props = StateProps & DispatchProps & OwnProps;
|
||||||
|
|
||||||
const isElectron = navigator.userAgent.includes('Electron');
|
const isElectron = navigator.userAgent.includes('Electron');
|
||||||
|
|
||||||
function sendMessage(message: SingleMessage) {
|
async function sendMessage(message: SingleMessage) {
|
||||||
chrome.runtime.sendMessage(message);
|
await chrome.runtime.sendMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Actions extends Component<Props> {
|
class Actions extends Component<Props> {
|
||||||
openWindow = (position: Position) => {
|
openWindow = async (position: Position) => {
|
||||||
sendMessage({ type: 'OPEN', position });
|
await sendMessage({ type: 'OPEN', position });
|
||||||
};
|
};
|
||||||
openOptionsPage = () => {
|
openOptionsPage = async () => {
|
||||||
if (navigator.userAgent.indexOf('Firefox') !== -1) {
|
if (navigator.userAgent.includes('Firefox')) {
|
||||||
sendMessage({ type: 'OPEN_OPTIONS' });
|
await sendMessage({ type: 'OPEN_OPTIONS' });
|
||||||
} else {
|
} else {
|
||||||
chrome.runtime.openOptionsPage();
|
await chrome.runtime.openOptionsPage();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ class Actions extends Component<Props> {
|
||||||
{features.import && <ImportButton />}
|
{features.import && <ImportButton />}
|
||||||
{position &&
|
{position &&
|
||||||
(position !== '#popup' ||
|
(position !== '#popup' ||
|
||||||
navigator.userAgent.indexOf('Firefox') !== -1) && <PrintButton />}
|
navigator.userAgent.includes('Firefox')) && <PrintButton />}
|
||||||
<Divider />
|
<Divider />
|
||||||
<MonitorSelector />
|
<MonitorSelector />
|
||||||
<Divider />
|
<Divider />
|
||||||
|
@ -96,8 +96,8 @@ class Actions extends Component<Props> {
|
||||||
<Divider />
|
<Divider />
|
||||||
{!isElectron && (
|
{!isElectron && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
this.openWindow('window');
|
await this.openWindow('window');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MdOutlineWindow />
|
<MdOutlineWindow />
|
||||||
|
@ -105,8 +105,8 @@ class Actions extends Component<Props> {
|
||||||
)}
|
)}
|
||||||
{!isElectron && (
|
{!isElectron && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
this.openWindow('remote');
|
await this.openWindow('remote');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<GoBroadcast />
|
<GoBroadcast />
|
||||||
|
|
|
@ -27,6 +27,7 @@ class App extends Component<Props> {
|
||||||
<a
|
<a
|
||||||
href="https://github.com/zalmoxisus/redux-devtools-extension#usage"
|
href="https://github.com/zalmoxisus/redux-devtools-extension#usage"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
the instructions
|
the instructions
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -6,7 +6,7 @@ export function createMenu() {
|
||||||
{ id: 'devtools-remote', title: 'Open Remote DevTools' },
|
{ id: 'devtools-remote', title: 'Open Remote DevTools' },
|
||||||
];
|
];
|
||||||
|
|
||||||
let shortcuts: { [commandName: string]: string | undefined } = {};
|
const shortcuts: { [commandName: string]: string | undefined } = {};
|
||||||
chrome.commands.getAll((commands) => {
|
chrome.commands.getAll((commands) => {
|
||||||
for (const { name, shortcut } of commands) {
|
for (const { name, shortcut } of commands) {
|
||||||
shortcuts[name!] = shortcut;
|
shortcuts[name!] = shortcut;
|
||||||
|
|
|
@ -15,7 +15,7 @@ chrome.commands.onCommand.addListener((shortcut) => {
|
||||||
|
|
||||||
// Disable the action by default and create the context menu when installed
|
// Disable the action by default and create the context menu when installed
|
||||||
chrome.runtime.onInstalled.addListener(() => {
|
chrome.runtime.onInstalled.addListener(() => {
|
||||||
chrome.action.disable();
|
void chrome.action.disable();
|
||||||
|
|
||||||
getOptions((option) => {
|
getOptions((option) => {
|
||||||
if (option.showContextMenus) createMenu();
|
if (option.showContextMenus) createMenu();
|
||||||
|
@ -32,6 +32,7 @@ chrome.storage.onChanged.addListener((changes) => {
|
||||||
|
|
||||||
// https://developer.chrome.com/docs/extensions/develop/migrate/to-service-workers#keep_a_service_worker_alive_continuously
|
// https://developer.chrome.com/docs/extensions/develop/migrate/to-service-workers#keep_a_service_worker_alive_continuously
|
||||||
setInterval(
|
setInterval(
|
||||||
() => chrome.storage.local.set({ 'last-heartbeat': new Date().getTime() }),
|
() =>
|
||||||
|
void chrome.storage.local.set({ 'last-heartbeat': new Date().getTime() }),
|
||||||
20000,
|
20000,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
export type DevToolsPosition = 'devtools-window' | 'devtools-remote';
|
export type DevToolsPosition = 'devtools-window' | 'devtools-remote';
|
||||||
|
|
||||||
let windows: { [K in DevToolsPosition]?: number } = {};
|
const windows: { [K in DevToolsPosition]?: number } = {};
|
||||||
|
|
||||||
export default function openDevToolsWindow(position: DevToolsPosition) {
|
export default function openDevToolsWindow(position: DevToolsPosition) {
|
||||||
if (!windows[position]) {
|
if (!windows[position]) {
|
||||||
createWindow(position);
|
createWindow(position);
|
||||||
} else {
|
} else {
|
||||||
chrome.windows.update(windows[position]!, { focused: true }, () => {
|
chrome.windows.update(windows[position], { focused: true }, () => {
|
||||||
if (chrome.runtime.lastError) createWindow(position);
|
if (chrome.runtime.lastError) createWindow(position);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ function createWindow(position: DevToolsPosition) {
|
||||||
const url = chrome.runtime.getURL(getPath(position));
|
const url = chrome.runtime.getURL(getPath(position));
|
||||||
chrome.windows.create({ type: 'popup', url }, (win) => {
|
chrome.windows.create({ type: 'popup', url }, (win) => {
|
||||||
windows[position] = win!.id;
|
windows[position] = win!.id;
|
||||||
if (navigator.userAgent.indexOf('Firefox') !== -1) {
|
if (navigator.userAgent.includes('Firefox')) {
|
||||||
chrome.windows.update(win!.id!, { focused: true });
|
void chrome.windows.update(win!.id!, { focused: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,6 @@ function getPath(position: DevToolsPosition) {
|
||||||
case 'devtools-remote':
|
case 'devtools-remote':
|
||||||
return 'remote.html';
|
return 'remote.html';
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unrecognized position: ${position}`);
|
throw new Error('Unrecognized position');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,14 +324,8 @@ function toContentScript(messageBody: ToContentScriptMessage) {
|
||||||
connections.tab[id!].postMessage({
|
connections.tab[id!].postMessage({
|
||||||
type: message,
|
type: message,
|
||||||
action,
|
action,
|
||||||
state: nonReduxDispatch(
|
state: nonReduxDispatch(store, message, instanceId, action, state),
|
||||||
store,
|
id: instanceId.toString().replace(/^[^/]+\//, ''),
|
||||||
message,
|
|
||||||
instanceId,
|
|
||||||
action as AppDispatchAction,
|
|
||||||
state,
|
|
||||||
),
|
|
||||||
id: instanceId.toString().replace(/^[^\/]+\//, ''),
|
|
||||||
});
|
});
|
||||||
} else if (messageBody.message === 'IMPORT') {
|
} else if (messageBody.message === 'IMPORT') {
|
||||||
const { message, action, id, instanceId, state } = messageBody;
|
const { message, action, id, instanceId, state } = messageBody;
|
||||||
|
@ -345,7 +339,7 @@ function toContentScript(messageBody: ToContentScriptMessage) {
|
||||||
action as unknown as AppDispatchAction,
|
action as unknown as AppDispatchAction,
|
||||||
state,
|
state,
|
||||||
),
|
),
|
||||||
id: instanceId.toString().replace(/^[^\/]+\//, ''),
|
id: instanceId.toString().replace(/^[^/]+\//, ''),
|
||||||
});
|
});
|
||||||
} else if (messageBody.message === 'ACTION') {
|
} else if (messageBody.message === 'ACTION') {
|
||||||
const { message, action, id, instanceId, state } = messageBody;
|
const { message, action, id, instanceId, state } = messageBody;
|
||||||
|
@ -359,7 +353,7 @@ function toContentScript(messageBody: ToContentScriptMessage) {
|
||||||
action as unknown as AppDispatchAction,
|
action as unknown as AppDispatchAction,
|
||||||
state,
|
state,
|
||||||
),
|
),
|
||||||
id: instanceId.toString().replace(/^[^\/]+\//, ''),
|
id: instanceId.toString().replace(/^[^/]+\//, ''),
|
||||||
});
|
});
|
||||||
} else if (messageBody.message === 'EXPORT') {
|
} else if (messageBody.message === 'EXPORT') {
|
||||||
const { message, action, id, instanceId, state } = messageBody;
|
const { message, action, id, instanceId, state } = messageBody;
|
||||||
|
@ -373,11 +367,11 @@ function toContentScript(messageBody: ToContentScriptMessage) {
|
||||||
action as unknown as AppDispatchAction,
|
action as unknown as AppDispatchAction,
|
||||||
state,
|
state,
|
||||||
),
|
),
|
||||||
id: instanceId.toString().replace(/^[^\/]+\//, ''),
|
id: instanceId.toString().replace(/^[^/]+\//, ''),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const { message, action, id, instanceId, state } = messageBody;
|
const { message, action, id, instanceId, state } = messageBody;
|
||||||
connections.tab[id!].postMessage({
|
connections.tab[id].postMessage({
|
||||||
type: message,
|
type: message,
|
||||||
action,
|
action,
|
||||||
state: nonReduxDispatch(
|
state: nonReduxDispatch(
|
||||||
|
@ -387,7 +381,7 @@ function toContentScript(messageBody: ToContentScriptMessage) {
|
||||||
action as AppDispatchAction,
|
action as AppDispatchAction,
|
||||||
state,
|
state,
|
||||||
),
|
),
|
||||||
id: (instanceId as number).toString().replace(/^[^\/]+\//, ''),
|
id: (instanceId as number).toString().replace(/^[^/]+\//, ''),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,7 +446,7 @@ function messaging<S, A extends Action<string>>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (request.type === 'OPEN_OPTIONS') {
|
if (request.type === 'OPEN_OPTIONS') {
|
||||||
chrome.runtime.openOptionsPage();
|
void chrome.runtime.openOptionsPage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (request.type === 'OPTIONS') {
|
if (request.type === 'OPTIONS') {
|
||||||
|
@ -557,8 +551,8 @@ function onConnect<S, A extends Action<string>>(port: chrome.runtime.Port) {
|
||||||
console.log(`Message from tab ${id}: ${msg.name}`);
|
console.log(`Message from tab ${id}: ${msg.name}`);
|
||||||
if (msg.name === 'INIT_INSTANCE') {
|
if (msg.name === 'INIT_INSTANCE') {
|
||||||
if (typeof id === 'number') {
|
if (typeof id === 'number') {
|
||||||
chrome.action.enable(id);
|
void chrome.action.enable(id);
|
||||||
chrome.action.setIcon({ tabId: id, path: 'img/logo/38x38.png' });
|
void chrome.action.setIcon({ tabId: id, path: 'img/logo/38x38.png' });
|
||||||
}
|
}
|
||||||
if (monitors > 0) port.postMessage({ type: 'START' });
|
if (monitors > 0) port.postMessage({ type: 'START' });
|
||||||
|
|
||||||
|
@ -611,6 +605,7 @@ chrome.notifications.onClicked.addListener((id) => {
|
||||||
openDevToolsWindow('devtools-window');
|
openDevToolsWindow('devtools-window');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||||
const api: Middleware<{}, BackgroundState, Dispatch<BackgroundAction>> =
|
const api: Middleware<{}, BackgroundState, Dispatch<BackgroundAction>> =
|
||||||
(store) => (next) => (untypedAction) => {
|
(store) => (next) => (untypedAction) => {
|
||||||
const action = untypedAction as BackgroundAction;
|
const action = untypedAction as BackgroundAction;
|
||||||
|
|
|
@ -9,28 +9,42 @@ if (
|
||||||
isFirefox
|
isFirefox
|
||||||
) {
|
) {
|
||||||
(chrome.runtime as any).onConnectExternal = {
|
(chrome.runtime as any).onConnectExternal = {
|
||||||
addListener() {},
|
addListener() {
|
||||||
|
// do nothing.
|
||||||
|
},
|
||||||
};
|
};
|
||||||
(chrome.runtime as any).onMessageExternal = {
|
(chrome.runtime as any).onMessageExternal = {
|
||||||
addListener() {},
|
addListener() {
|
||||||
|
// do nothing.
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isElectron) {
|
if (isElectron) {
|
||||||
(chrome.notifications as any) = {
|
(chrome.notifications as any) = {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
addListener() {},
|
addListener() {
|
||||||
|
// do nothing.
|
||||||
|
},
|
||||||
|
},
|
||||||
|
create() {
|
||||||
|
// do nothing.
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
// do nothing.
|
||||||
},
|
},
|
||||||
create() {},
|
|
||||||
clear() {},
|
|
||||||
};
|
};
|
||||||
(chrome.contextMenus as any) = {
|
(chrome.contextMenus as any) = {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
addListener() {},
|
addListener() {
|
||||||
|
// do nothing.
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
(chrome.commands as any) = {
|
(chrome.commands as any) = {
|
||||||
onCommand: {
|
onCommand: {
|
||||||
addListener() {},
|
addListener() {
|
||||||
|
// do nothing.
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
@ -44,31 +58,36 @@ if (
|
||||||
if (isElectron) {
|
if (isElectron) {
|
||||||
if (!chrome.storage.local || !chrome.storage.local.remove) {
|
if (!chrome.storage.local || !chrome.storage.local.remove) {
|
||||||
(chrome.storage as any).local = {
|
(chrome.storage as any).local = {
|
||||||
set(obj: any, callback: any) {
|
set(items: { [key: string]: string }, callback: () => void) {
|
||||||
Object.keys(obj).forEach((key) => {
|
for (const [key, value] of Object.entries(items)) {
|
||||||
localStorage.setItem(key, obj[key]);
|
localStorage.setItem(key, value);
|
||||||
});
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
get(obj: any, callback: any) {
|
get(
|
||||||
const result: any = {};
|
keys: { [key: string]: any },
|
||||||
Object.keys(obj).forEach((key) => {
|
callback: (items: { [key: string]: any }) => void,
|
||||||
result[key] = localStorage.getItem(key) || obj[key];
|
) {
|
||||||
});
|
const result = Object.fromEntries(
|
||||||
|
Object.entries(keys).map(([key, value]) => [
|
||||||
|
key,
|
||||||
|
localStorage.getItem(key) ?? value,
|
||||||
|
]),
|
||||||
|
);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(result);
|
callback(result);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Electron ~ 1.4.6
|
// Electron ~ 1.4.6
|
||||||
remove(items: any, callback: any) {
|
remove(keys: string | string[], callback: () => void) {
|
||||||
if (Array.isArray(items)) {
|
if (Array.isArray(keys)) {
|
||||||
items.forEach((name) => {
|
for (const key of keys) {
|
||||||
localStorage.removeItem(name);
|
localStorage.removeItem(key);
|
||||||
});
|
}
|
||||||
} else {
|
} else {
|
||||||
localStorage.removeItem(items);
|
localStorage.removeItem(keys);
|
||||||
}
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
|
@ -78,14 +97,14 @@ if (isElectron) {
|
||||||
}
|
}
|
||||||
// Avoid error: chrome.runtime.sendMessage is not supported responseCallback
|
// Avoid error: chrome.runtime.sendMessage is not supported responseCallback
|
||||||
const originSendMessage = (chrome.runtime as any).sendMessage;
|
const originSendMessage = (chrome.runtime as any).sendMessage;
|
||||||
chrome.runtime.sendMessage = function () {
|
(chrome.runtime as any).sendMessage = function (...args: unknown[]) {
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
return originSendMessage(...arguments);
|
return originSendMessage(...args);
|
||||||
}
|
}
|
||||||
if (typeof arguments[arguments.length - 1] === 'function') {
|
if (typeof args[arguments.length - 1] === 'function') {
|
||||||
Array.prototype.pop.call(arguments);
|
Array.prototype.pop.call(args);
|
||||||
}
|
}
|
||||||
return originSendMessage(...arguments);
|
return originSendMessage(...args);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ function tryCatch<S, A extends Action<string>>(
|
||||||
}
|
}
|
||||||
newArgs[key as keyof typeof newArgs] = arg;
|
newArgs[key as keyof typeof newArgs] = arg;
|
||||||
});
|
});
|
||||||
fn(newArgs as any);
|
fn(newArgs as SplitMessage);
|
||||||
for (let i = 0; i < toSplit.length; i++) {
|
for (let i = 0; i < toSplit.length; i++) {
|
||||||
for (let j = 0; j < toSplit[i][1].length; j += maxChromeMsgSize) {
|
for (let j = 0; j < toSplit[i][1].length; j += maxChromeMsgSize) {
|
||||||
fn({
|
fn({
|
||||||
|
|
|
@ -36,7 +36,7 @@ let persistor: Persistor | undefined;
|
||||||
let bgConnection: chrome.runtime.Port;
|
let bgConnection: chrome.runtime.Port;
|
||||||
let naTimeout: NodeJS.Timeout;
|
let naTimeout: NodeJS.Timeout;
|
||||||
|
|
||||||
const isChrome = navigator.userAgent.indexOf('Firefox') === -1;
|
const isChrome = !navigator.userAgent.includes('Firefox');
|
||||||
|
|
||||||
function renderNodeAtRoot(node: ReactNode) {
|
function renderNodeAtRoot(node: ReactNode) {
|
||||||
if (currentRoot) currentRoot.unmount();
|
if (currentRoot) currentRoot.unmount();
|
||||||
|
@ -67,6 +67,7 @@ function renderNA() {
|
||||||
<a
|
<a
|
||||||
href="https://github.com/zalmoxisus/redux-devtools-extension#usage"
|
href="https://github.com/zalmoxisus/redux-devtools-extension#usage"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
the instructions
|
the instructions
|
||||||
</a>
|
</a>
|
||||||
|
@ -87,6 +88,7 @@ function renderNA() {
|
||||||
<a
|
<a
|
||||||
href="https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/Troubleshooting.md#access-file-url-file"
|
href="https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/Troubleshooting.md#access-file-url-file"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
>
|
>
|
||||||
See details
|
See details
|
||||||
</a>
|
</a>
|
||||||
|
@ -139,12 +141,18 @@ function init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.split === 'chunk') {
|
if (request.split === 'chunk') {
|
||||||
if ((splitMessage as Record<string, unknown>)[request.chunk[0]]) {
|
if (
|
||||||
(splitMessage as Record<string, unknown>)[request.chunk[0]] +=
|
(splitMessage as unknown as Record<string, string>)[
|
||||||
request.chunk[1];
|
request.chunk[0]
|
||||||
|
]
|
||||||
|
) {
|
||||||
|
(splitMessage as unknown as Record<string, string>)[
|
||||||
|
request.chunk[0]
|
||||||
|
] += request.chunk[1];
|
||||||
} else {
|
} else {
|
||||||
(splitMessage as Record<string, unknown>)[request.chunk[0]] =
|
(splitMessage as unknown as Record<string, string>)[
|
||||||
request.chunk[1];
|
request.chunk[0]
|
||||||
|
] = request.chunk[1];
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ function getCurrentTabId(next: (tabId: number) => void) {
|
||||||
|
|
||||||
function panelDispatcher(
|
function panelDispatcher(
|
||||||
bgConnection: chrome.runtime.Port,
|
bgConnection: chrome.runtime.Port,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||||
): Middleware<{}, StoreState, Dispatch<StoreAction>> {
|
): Middleware<{}, StoreState, Dispatch<StoreAction>> {
|
||||||
let autoselected = false;
|
let autoselected = false;
|
||||||
|
|
||||||
|
|
|
@ -2,5 +2,7 @@ chrome.devtools.panels.create(
|
||||||
'Redux',
|
'Redux',
|
||||||
'img/logo/scalable.png',
|
'img/logo/scalable.png',
|
||||||
'devpanel.html',
|
'devpanel.html',
|
||||||
() => {},
|
() => {
|
||||||
|
// do nothing.
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { OptionsProps } from './Options';
|
import { OptionsProps } from './Options';
|
||||||
|
|
||||||
export default ({ options, saveOption }: OptionsProps) => {
|
export default function AllowToRunGroup({ options, saveOption }: OptionsProps) {
|
||||||
const AllowToRunState = {
|
const AllowToRunState = {
|
||||||
EVERYWHERE: true,
|
EVERYWHERE: true,
|
||||||
ON_SPECIFIC_URLS: false,
|
ON_SPECIFIC_URLS: false,
|
||||||
|
@ -50,4 +50,4 @@ export default ({ options, saveOption }: OptionsProps) => {
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { OptionsProps } from './Options';
|
import { OptionsProps } from './Options';
|
||||||
|
|
||||||
export default ({ options, saveOption }: OptionsProps) => {
|
export default function ContextMenuGroup({
|
||||||
|
options,
|
||||||
|
saveOption,
|
||||||
|
}: OptionsProps) {
|
||||||
return (
|
return (
|
||||||
<fieldset className="option-group">
|
<fieldset className="option-group">
|
||||||
<legend className="option-group__title">Context Menu</legend>
|
<legend className="option-group__title">Context Menu</legend>
|
||||||
|
@ -23,4 +26,4 @@ export default ({ options, saveOption }: OptionsProps) => {
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { OptionsProps } from './Options';
|
import { OptionsProps } from './Options';
|
||||||
|
|
||||||
export default ({ options, saveOption }: OptionsProps) => {
|
export default function EditorGroup({ options, saveOption }: OptionsProps) {
|
||||||
const EditorState = {
|
const EditorState = {
|
||||||
BROWSER: 0,
|
BROWSER: 0,
|
||||||
EXTERNAL: 1,
|
EXTERNAL: 1,
|
||||||
|
@ -21,7 +21,7 @@ export default ({ options, saveOption }: OptionsProps) => {
|
||||||
onChange={() => saveOption('useEditor', EditorState.BROWSER)}
|
onChange={() => saveOption('useEditor', EditorState.BROWSER)}
|
||||||
/>
|
/>
|
||||||
<label className="option__label" htmlFor="editor-browser">
|
<label className="option__label" htmlFor="editor-browser">
|
||||||
{navigator.userAgent.indexOf('Firefox') !== -1
|
{navigator.userAgent.includes('Firefox')
|
||||||
? "Don't open in external editor"
|
? "Don't open in external editor"
|
||||||
: "Use browser's debugger (from browser devpanel only)"}
|
: "Use browser's debugger (from browser devpanel only)"}
|
||||||
</label>
|
</label>
|
||||||
|
@ -80,4 +80,4 @@ export default ({ options, saveOption }: OptionsProps) => {
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import { FilterState } from '../pageScript/api/filters';
|
import { FilterState } from '../pageScript/api/filters';
|
||||||
import { OptionsProps } from './Options';
|
import { OptionsProps } from './Options';
|
||||||
|
|
||||||
export default ({ options, saveOption }: OptionsProps) => {
|
export default function FilterGroup({ options, saveOption }: OptionsProps) {
|
||||||
return (
|
return (
|
||||||
<fieldset className="option-group">
|
<fieldset className="option-group">
|
||||||
<legend className="option-group__title">
|
<legend className="option-group__title">
|
||||||
|
@ -68,4 +68,4 @@ export default ({ options, saveOption }: OptionsProps) => {
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { OptionsProps } from './Options';
|
import { OptionsProps } from './Options';
|
||||||
|
|
||||||
export default ({ options, saveOption }: OptionsProps) => {
|
export default function MiscellaneousGroup({
|
||||||
|
options,
|
||||||
|
saveOption,
|
||||||
|
}: OptionsProps) {
|
||||||
return (
|
return (
|
||||||
<fieldset className="option-group">
|
<fieldset className="option-group">
|
||||||
<legend className="option-group__title">Miscellaneous</legend>
|
<legend className="option-group__title">Miscellaneous</legend>
|
||||||
|
@ -47,4 +50,4 @@ export default ({ options, saveOption }: OptionsProps) => {
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
|
@ -14,34 +14,38 @@ export interface OptionsProps {
|
||||||
) => void;
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (props: OptionsProps) => (
|
export default function OptionsComponent(props: OptionsProps) {
|
||||||
<div>
|
return (
|
||||||
<EditorGroup {...props} />
|
<div>
|
||||||
<FilterGroup {...props} />
|
<EditorGroup {...props} />
|
||||||
<AllowToRunGroup {...props} />
|
<FilterGroup {...props} />
|
||||||
<MiscellaneousGroup {...props} />
|
<AllowToRunGroup {...props} />
|
||||||
<ContextMenuGroup {...props} />
|
<MiscellaneousGroup {...props} />
|
||||||
<div style={{ color: 'red' }}>
|
<ContextMenuGroup {...props} />
|
||||||
<br />
|
<div style={{ color: 'red' }}>
|
||||||
<hr />
|
<br />
|
||||||
Setting options here is discouraged, and will not be possible in the next
|
<hr />
|
||||||
major release. Please{' '}
|
Setting options here is discouraged, and will not be possible in the
|
||||||
<a
|
next major release. Please{' '}
|
||||||
href="https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md"
|
<a
|
||||||
target="_blank"
|
href="https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md"
|
||||||
style={{ color: 'red' }}
|
target="_blank"
|
||||||
>
|
rel="noreferrer"
|
||||||
specify them as parameters
|
style={{ color: 'red' }}
|
||||||
</a>
|
>
|
||||||
. See{' '}
|
specify them as parameters
|
||||||
<a
|
</a>
|
||||||
href="https://github.com/zalmoxisus/redux-devtools-extension/issues/296"
|
. See{' '}
|
||||||
target="_blank"
|
<a
|
||||||
style={{ color: 'red' }}
|
href="https://github.com/zalmoxisus/redux-devtools-extension/issues/296"
|
||||||
>
|
target="_blank"
|
||||||
the issue
|
rel="noreferrer"
|
||||||
</a>{' '}
|
style={{ color: 'red' }}
|
||||||
for more details.
|
>
|
||||||
|
the issue
|
||||||
|
</a>{' '}
|
||||||
|
for more details.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
|
|
||||||
subscribeToOptions((options) => {
|
subscribeToOptions((options) => {
|
||||||
const message: OptionsMessage = { type: 'OPTIONS', options };
|
const message: OptionsMessage = { type: 'OPTIONS', options };
|
||||||
chrome.runtime.sendMessage(message);
|
void chrome.runtime.sendMessage(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
const renderOptions = (options: Options) => {
|
const renderOptions = (options: Options) => {
|
||||||
|
|
|
@ -46,9 +46,9 @@ export const saveOption = <K extends keyof Options>(
|
||||||
key: K,
|
key: K,
|
||||||
value: Options[K],
|
value: Options[K],
|
||||||
) => {
|
) => {
|
||||||
let obj: { [K1 in keyof Options]?: Options[K1] } = {};
|
const obj: { [K1 in keyof Options]?: Options[K1] } = {};
|
||||||
obj[key] = value;
|
obj[key] = value;
|
||||||
chrome.storage.sync.set(obj);
|
void chrome.storage.sync.set(obj);
|
||||||
options![key] = value;
|
options![key] = value;
|
||||||
for (const subscriber of subscribers) {
|
for (const subscriber of subscribers) {
|
||||||
subscriber(options!);
|
subscriber(options!);
|
||||||
|
@ -99,7 +99,10 @@ export const getOptions = (callback: (options: Options) => void) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const prefetchOptions = () => getOptions(() => {});
|
export const prefetchOptions = () =>
|
||||||
|
getOptions(() => {
|
||||||
|
// do nothing.
|
||||||
|
});
|
||||||
|
|
||||||
export const subscribeToOptions = (callback: (options: Options) => void) => {
|
export const subscribeToOptions = (callback: (options: Options) => void) => {
|
||||||
subscribers = subscribers.concat(callback);
|
subscribers = subscribers.concat(callback);
|
||||||
|
|
|
@ -26,8 +26,7 @@ export function isFiltered<A extends Action<string>>(
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
noFiltersApplied(localFilter) ||
|
noFiltersApplied(localFilter) ||
|
||||||
(typeof action !== 'string' &&
|
(typeof action !== 'string' && typeof action.type.match !== 'function')
|
||||||
typeof (action.type as string).match !== 'function')
|
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ export default function importState<S, A extends Action<string>>(
|
||||||
| LiftedState<S, A, unknown> = parse(state) as
|
| LiftedState<S, A, unknown> = parse(state) as
|
||||||
| ParsedSerializedLiftedState
|
| ParsedSerializedLiftedState
|
||||||
| LiftedState<S, A, unknown>;
|
| LiftedState<S, A, unknown>;
|
||||||
let preloadedState =
|
const preloadedState =
|
||||||
'payload' in parsedSerializedLiftedState &&
|
'payload' in parsedSerializedLiftedState &&
|
||||||
parsedSerializedLiftedState.preloadedState
|
parsedSerializedLiftedState.preloadedState
|
||||||
? (parse(parsedSerializedLiftedState.preloadedState) as S)
|
? (parse(parsedSerializedLiftedState.preloadedState) as S)
|
||||||
|
|
|
@ -222,6 +222,7 @@ function post<S, A extends Action<string>>(
|
||||||
|
|
||||||
function getStackTrace(
|
function getStackTrace(
|
||||||
config: Config,
|
config: Config,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||||
toExcludeFromTrace: Function | undefined,
|
toExcludeFromTrace: Function | undefined,
|
||||||
) {
|
) {
|
||||||
if (!config.trace) return undefined;
|
if (!config.trace) return undefined;
|
||||||
|
@ -248,6 +249,7 @@ function getStackTrace(
|
||||||
typeof Error.stackTraceLimit !== 'number' ||
|
typeof Error.stackTraceLimit !== 'number' ||
|
||||||
Error.stackTraceLimit > traceLimit!
|
Error.stackTraceLimit > traceLimit!
|
||||||
) {
|
) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
const frames = stack!.split('\n');
|
const frames = stack!.split('\n');
|
||||||
if (frames.length > traceLimit!) {
|
if (frames.length > traceLimit!) {
|
||||||
stack = frames
|
stack = frames
|
||||||
|
@ -265,10 +267,11 @@ function amendActionType<A extends Action<string>>(
|
||||||
| StructuralPerformAction<A>[]
|
| StructuralPerformAction<A>[]
|
||||||
| string,
|
| string,
|
||||||
config: Config,
|
config: Config,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||||
toExcludeFromTrace: Function | undefined,
|
toExcludeFromTrace: Function | undefined,
|
||||||
): StructuralPerformAction<A> {
|
): StructuralPerformAction<A> {
|
||||||
let timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
let stack = getStackTrace(config, toExcludeFromTrace);
|
const stack = getStackTrace(config, toExcludeFromTrace);
|
||||||
if (typeof action === 'string') {
|
if (typeof action === 'string') {
|
||||||
return { action: { type: action } as A, timestamp, stack };
|
return { action: { type: action } as A, timestamp, stack };
|
||||||
}
|
}
|
||||||
|
@ -595,7 +598,11 @@ export function connect(preConfig: Config): ConnectResponse {
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendDelayed = throttle(() => {
|
const sendDelayed = throttle(() => {
|
||||||
sendMessage(delayedActions, delayedStates as any, config);
|
sendMessage(
|
||||||
|
delayedActions,
|
||||||
|
delayedStates as unknown as LiftedState<unknown, Action<string>, unknown>,
|
||||||
|
config,
|
||||||
|
);
|
||||||
delayedActions = [];
|
delayedActions = [];
|
||||||
delayedStates = [];
|
delayedStates = [];
|
||||||
}, latency);
|
}, latency);
|
||||||
|
|
|
@ -10,7 +10,7 @@ function createExpBackoffTimer(step: number) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Calculate next timeout
|
// Calculate next timeout
|
||||||
let timeout = Math.pow(2, count - 1);
|
const timeout = Math.pow(2, count - 1);
|
||||||
if (count < 5) count += 1;
|
if (count < 5) count += 1;
|
||||||
return timeout * step;
|
return timeout * step;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,8 +4,8 @@ import { persistState } from '@redux-devtools/core';
|
||||||
import type { ConfigWithExpandedMaxAge } from './index';
|
import type { ConfigWithExpandedMaxAge } from './index';
|
||||||
|
|
||||||
export function getUrlParam(key: string) {
|
export function getUrlParam(key: string) {
|
||||||
const matches = window.location.href.match(
|
const matches = new RegExp(`[?&]${key}=([^&#]+)\\b`).exec(
|
||||||
new RegExp(`[?&]${key}=([^&#]+)\\b`),
|
window.location.href,
|
||||||
);
|
);
|
||||||
return matches && matches.length > 0 ? matches[1] : null;
|
return matches && matches.length > 0 ? matches[1] : null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ type EnhancedStoreWithInitialDispatch<
|
||||||
> = EnhancedStore<S, A, MonitorState> & { initialDispatch: Dispatch<A> };
|
> = EnhancedStore<S, A, MonitorState> & { initialDispatch: Dispatch<A> };
|
||||||
|
|
||||||
const source = '@devtools-page';
|
const source = '@devtools-page';
|
||||||
let stores: {
|
const stores: {
|
||||||
[K in string | number]: EnhancedStoreWithInitialDispatch<
|
[K in string | number]: EnhancedStoreWithInitialDispatch<
|
||||||
unknown,
|
unknown,
|
||||||
Action<string>,
|
Action<string>,
|
||||||
|
@ -167,7 +167,7 @@ function __REDUX_DEVTOOLS_EXTENSION__<S, A extends Action<string>>(
|
||||||
const localFilter = getLocalFilter(config);
|
const localFilter = getLocalFilter(config);
|
||||||
const serializeState = getSerializeParameter(config);
|
const serializeState = getSerializeParameter(config);
|
||||||
const serializeAction = getSerializeParameter(config);
|
const serializeAction = getSerializeParameter(config);
|
||||||
let { stateSanitizer, actionSanitizer, predicate, latency = 500 } = config;
|
const { stateSanitizer, actionSanitizer, predicate, latency = 500 } = config;
|
||||||
|
|
||||||
// Deprecate actionsWhitelist and actionsBlacklist
|
// Deprecate actionsWhitelist and actionsBlacklist
|
||||||
if (config.actionsWhitelist) {
|
if (config.actionsWhitelist) {
|
||||||
|
@ -447,7 +447,7 @@ function __REDUX_DEVTOOLS_EXTENSION__<S, A extends Action<string>>(
|
||||||
liftedAction?: LiftedAction<S, A, unknown>,
|
liftedAction?: LiftedAction<S, A, unknown>,
|
||||||
liftedState?: LiftedState<S, A, unknown> | undefined,
|
liftedState?: LiftedState<S, A, unknown> | undefined,
|
||||||
) => {
|
) => {
|
||||||
let m = (config && config.maxAge) || window.devToolsOptions.maxAge || 50;
|
const m = (config && config.maxAge) || window.devToolsOptions.maxAge || 50;
|
||||||
if (
|
if (
|
||||||
!liftedAction ||
|
!liftedAction ||
|
||||||
noFiltersApplied(localFilter) ||
|
noFiltersApplied(localFilter) ||
|
||||||
|
@ -464,10 +464,7 @@ function __REDUX_DEVTOOLS_EXTENSION__<S, A extends Action<string>>(
|
||||||
if (filteredActionIds.length >= m) {
|
if (filteredActionIds.length >= m) {
|
||||||
const stagedActionIds = liftedState!.stagedActionIds;
|
const stagedActionIds = liftedState!.stagedActionIds;
|
||||||
let i = 1;
|
let i = 1;
|
||||||
while (
|
while (maxAge > m && !filteredActionIds.includes(stagedActionIds[i])) {
|
||||||
maxAge > m &&
|
|
||||||
filteredActionIds.indexOf(stagedActionIds[i]) === -1
|
|
||||||
) {
|
|
||||||
maxAge--;
|
maxAge--;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -539,7 +536,7 @@ function __REDUX_DEVTOOLS_EXTENSION__<S, A extends Action<string>>(
|
||||||
...config,
|
...config,
|
||||||
maxAge: getMaxAge as any,
|
maxAge: getMaxAge as any,
|
||||||
}) as any
|
}) as any
|
||||||
)(reducer_, initialState_) as any;
|
)(reducer_, initialState_);
|
||||||
|
|
||||||
if (isInIframe()) setTimeout(init, 3000);
|
if (isInIframe()) setTimeout(init, 3000);
|
||||||
else init();
|
else init();
|
||||||
|
@ -591,18 +588,19 @@ export type InferComposedStoreExt<StoreEnhancers> = StoreEnhancers extends [
|
||||||
? HeadStoreEnhancer extends StoreEnhancer<infer StoreExt>
|
? HeadStoreEnhancer extends StoreEnhancer<infer StoreExt>
|
||||||
? StoreExt & InferComposedStoreExt<RestStoreEnhancers>
|
? StoreExt & InferComposedStoreExt<RestStoreEnhancers>
|
||||||
: never
|
: never
|
||||||
: {};
|
: // eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||||
|
{};
|
||||||
|
|
||||||
const extensionCompose =
|
const extensionCompose =
|
||||||
(config: Config) =>
|
(config: Config) =>
|
||||||
<StoreEnhancers extends readonly StoreEnhancer[]>(
|
<StoreEnhancers extends readonly StoreEnhancer[]>(
|
||||||
...funcs: StoreEnhancers
|
...funcs: StoreEnhancers
|
||||||
): StoreEnhancer<InferComposedStoreExt<StoreEnhancers>> => {
|
): StoreEnhancer<InferComposedStoreExt<StoreEnhancers>> => {
|
||||||
// @ts-ignore FIXME
|
// @ts-expect-error FIXME
|
||||||
return (...args) => {
|
return (...args) => {
|
||||||
const instanceId = generateId(config.instanceId);
|
const instanceId = generateId(config.instanceId);
|
||||||
return [preEnhancer(instanceId), ...funcs].reduceRight(
|
return [preEnhancer(instanceId), ...funcs].reduceRight(
|
||||||
// @ts-ignore FIXME
|
// @ts-expect-error FIXME
|
||||||
(composed, f) => f(composed),
|
(composed, f) => f(composed),
|
||||||
__REDUX_DEVTOOLS_EXTENSION__({ ...config, instanceId })(...args),
|
__REDUX_DEVTOOLS_EXTENSION__({ ...config, instanceId })(...args),
|
||||||
);
|
);
|
||||||
|
|
1
extension/test/__mocks__/styleMock.js
Normal file
1
extension/test/__mocks__/styleMock.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module.exports = {};
|
|
@ -1 +0,0 @@
|
||||||
export default {};
|
|
|
@ -71,6 +71,7 @@ describe('Chrome extension', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(switchMonitorTests).forEach((description) =>
|
Object.keys(switchMonitorTests).forEach((description) =>
|
||||||
|
// eslint-disable-next-line jest/expect-expect,jest/valid-title
|
||||||
it(description, () => switchMonitorTests[description](driver)),
|
it(description, () => switchMonitorTests[description](driver)),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -76,6 +76,7 @@ describe('DevTools panel for Electron', function () {
|
||||||
expect(className).not.toMatch(/hidden/); // not hidden
|
expect(className).not.toMatch(/hidden/); // not hidden
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/expect-expect
|
||||||
it('should have Redux DevTools UI on current tab', async () => {
|
it('should have Redux DevTools UI on current tab', async () => {
|
||||||
await driver
|
await driver
|
||||||
.switchTo()
|
.switchTo()
|
||||||
|
@ -107,9 +108,11 @@ describe('DevTools panel for Electron', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(switchMonitorTests).forEach((description) =>
|
Object.keys(switchMonitorTests).forEach((description) =>
|
||||||
|
// eslint-disable-next-line jest/expect-expect,jest/valid-title
|
||||||
it(description, () => switchMonitorTests[description](driver)),
|
it(description, () => switchMonitorTests[description](driver)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/no-commented-out-tests
|
||||||
/* it('should be no logs in console of main window', async () => {
|
/* it('should be no logs in console of main window', async () => {
|
||||||
const handles = await driver.getAllWindowHandles();
|
const handles = await driver.getAllWindowHandles();
|
||||||
await driver.switchTo().window(handles[1]); // Change to main window
|
await driver.switchTo().window(handles[1]); // Change to main window
|
||||||
|
|
|
@ -31,7 +31,7 @@ importers:
|
||||||
version: 9.1.0(eslint@8.57.1)
|
version: 9.1.0(eslint@8.57.1)
|
||||||
eslint-plugin-jest:
|
eslint-plugin-jest:
|
||||||
specifier: ^28.8.3
|
specifier: ^28.8.3
|
||||||
version: 28.8.3(@typescript-eslint/eslint-plugin@8.6.0(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(jest@29.7.0(@types/node@22.5.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@22.5.5)(typescript@5.5.4)))(typescript@5.5.4)
|
version: 28.8.3(@typescript-eslint/eslint-plugin@8.6.0(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(jest@29.7.0(@types/node@20.16.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.16.5)(typescript@5.5.4)))(typescript@5.5.4)
|
||||||
eslint-plugin-react:
|
eslint-plugin-react:
|
||||||
specifier: ^7.36.1
|
specifier: ^7.36.1
|
||||||
version: 7.36.1(eslint@8.57.1)
|
version: 7.36.1(eslint@8.57.1)
|
||||||
|
@ -40,7 +40,7 @@ importers:
|
||||||
version: 4.6.2(eslint@8.57.1)
|
version: 4.6.2(eslint@8.57.1)
|
||||||
jest:
|
jest:
|
||||||
specifier: ^29.7.0
|
specifier: ^29.7.0
|
||||||
version: 29.7.0(@types/node@22.5.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@22.5.5)(typescript@5.5.4))
|
version: 29.7.0(@types/node@20.16.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.16.5)(typescript@5.5.4))
|
||||||
nx:
|
nx:
|
||||||
specifier: ^19.7.3
|
specifier: ^19.7.3
|
||||||
version: 19.7.3(@swc/core@1.7.26(@swc/helpers@0.5.13))
|
version: 19.7.3(@swc/core@1.7.26(@swc/helpers@0.5.13))
|
||||||
|
@ -192,12 +192,15 @@ importers:
|
||||||
eslint-plugin-react-hooks:
|
eslint-plugin-react-hooks:
|
||||||
specifier: ^4.6.2
|
specifier: ^4.6.2
|
||||||
version: 4.6.2(eslint@8.57.1)
|
version: 4.6.2(eslint@8.57.1)
|
||||||
|
globals:
|
||||||
|
specifier: ^15.9.0
|
||||||
|
version: 15.9.0
|
||||||
immutable:
|
immutable:
|
||||||
specifier: ^4.3.7
|
specifier: ^4.3.7
|
||||||
version: 4.3.7
|
version: 4.3.7
|
||||||
jest:
|
jest:
|
||||||
specifier: ^29.7.0
|
specifier: ^29.7.0
|
||||||
version: 29.7.0(@types/node@20.16.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.16.5)(typescript@5.5.4))
|
version: 29.7.0(@types/node@22.5.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@22.5.5)(typescript@5.5.4))
|
||||||
jest-environment-jsdom:
|
jest-environment-jsdom:
|
||||||
specifier: ^29.7.0
|
specifier: ^29.7.0
|
||||||
version: 29.7.0
|
version: 29.7.0
|
||||||
|
@ -215,7 +218,7 @@ importers:
|
||||||
version: 3.0.1
|
version: 3.0.1
|
||||||
ts-jest:
|
ts-jest:
|
||||||
specifier: ^29.2.5
|
specifier: ^29.2.5
|
||||||
version: 29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(esbuild@0.23.1)(jest@29.7.0(@types/node@20.16.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.16.5)(typescript@5.5.4)))(typescript@5.5.4)
|
version: 29.2.5(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(esbuild@0.23.1)(jest@29.7.0(@types/node@22.5.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@22.5.5)(typescript@5.5.4)))(typescript@5.5.4)
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ~5.5.4
|
specifier: ~5.5.4
|
||||||
version: 5.5.4
|
version: 5.5.4
|
||||||
|
@ -17007,13 +17010,13 @@ snapshots:
|
||||||
- eslint-import-resolver-webpack
|
- eslint-import-resolver-webpack
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-plugin-jest@28.8.3(@typescript-eslint/eslint-plugin@8.6.0(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(jest@29.7.0(@types/node@22.5.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@22.5.5)(typescript@5.5.4)))(typescript@5.5.4):
|
eslint-plugin-jest@28.8.3(@typescript-eslint/eslint-plugin@8.6.0(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(jest@29.7.0(@types/node@20.16.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.16.5)(typescript@5.5.4)))(typescript@5.5.4):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/utils': 8.6.0(eslint@8.57.1)(typescript@5.5.4)
|
'@typescript-eslint/utils': 8.6.0(eslint@8.57.1)(typescript@5.5.4)
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@typescript-eslint/eslint-plugin': 8.6.0(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)
|
'@typescript-eslint/eslint-plugin': 8.6.0(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.5.4))(eslint@8.57.1)(typescript@5.5.4)
|
||||||
jest: 29.7.0(@types/node@22.5.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@22.5.5)(typescript@5.5.4))
|
jest: 29.7.0(@types/node@20.16.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.16.5)(typescript@5.5.4))
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
- typescript
|
- typescript
|
||||||
|
|
Loading…
Reference in New Issue
Block a user