Compare commits

..

No commits in common. "main" and "remotedev-redux-devtools-extensions@3.2.1" have entirely different histories.

224 changed files with 15986 additions and 16274 deletions

View File

@ -1,10 +0,0 @@
---
'@redux-devtools/app-core': major
'@redux-devtools/app': major
'@redux-devtools/inspector-monitor-test-tab': major
'@redux-devtools/rtk-query-monitor': major
'@redux-devtools/slider-monitor': major
'@redux-devtools/ui': major
---
Replace styled-components with Emotion

View File

@ -8,11 +8,14 @@ on:
jobs: jobs:
build: build:
runs-on: 'ubuntu-22.04' runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v4 with:
fetch-depth: 0
- uses: nrwl/nx-set-shas@v4
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 'lts/*' node-version: 'lts/*'

View File

@ -10,7 +10,7 @@ permissions: write-all
jobs: jobs:
release: release:
name: Release name: Release
runs-on: 'ubuntu-22.04' runs-on: ubuntu-latest
steps: steps:
- name: Checkout Repo - name: Checkout Repo
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -18,7 +18,7 @@ jobs:
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0 fetch-depth: 0
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v2
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4

View File

@ -24,7 +24,7 @@ It can be used as a browser extension (for [Chrome](https://chrome.google.com/we
## Development ## Development
This is a monorepo powered by [pnpm](https://pnpm.io/). [Install pnpm](https://pnpm.io/installation) and run `pnpm install` to get started. Each package's dependencies need to be built before the package itself can be built. You can either build all the packages (i.e., `pnpm run build:all`) or use pnpm workspace commands to build only the packages necessary for the packages you're working on (i.e., `pnpm --filter "remotedev-redux-devtools-extension" build`). This is a monorepo powered by [pnpm](https://pnpm.io/) and [Nx](https://nx.dev/). [Install pnpm](https://pnpm.io/installation) and run `pnpm install` to get started. Each package's dependencies need to be built before the package itself can be built. You can either build all the packages (i.e., `pnpm run build:all`) or use Nx commands to build only the packages necessary for the packages you're working on (i.e., `pnpm nx build remotedev-redux-devtools-extension`).
## Backers ## Backers

View File

@ -1,43 +0,0 @@
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,
},
];

3
extension/.eslintignore Normal file
View File

@ -0,0 +1,3 @@
node_modules
dist
examples

31
extension/.eslintrc Normal file
View File

@ -0,0 +1,31 @@
{
"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"]
}

View File

@ -1,64 +1,5 @@
# remotedev-redux-devtools-extension # remotedev-redux-devtools-extension
## 3.2.10
### Patch Changes
- @redux-devtools/app@6.2.2
## 3.2.9
### Patch Changes
- Updated dependencies [91f21b2]
- @redux-devtools/core@4.1.1
- @redux-devtools/slider-monitor@5.1.1
- @redux-devtools/utils@3.1.1
- @redux-devtools/app@6.2.1
## 3.2.8
### Patch Changes
- Updated dependencies [6830118]
- react-json-tree@0.20.0
- @redux-devtools/app@6.2.0
- @redux-devtools/slider-monitor@6.0.0
- @redux-devtools/ui@1.4.0
- @redux-devtools/core@4.1.0
- @redux-devtools/utils@4.0.0
## 3.2.7
### Patch Changes
- b25bf13: Send state from background when monitor connects
## 3.2.6
### Patch Changes
- 50d7682: Fix DevTools from losing connection
## 3.2.5
### Patch Changes
- eb3ac09: Add logging to background service worker
## 3.2.4
### Patch Changes
- f1d6158: Fix mocking Chrome API for Electron
## 3.2.3
### Patch Changes
- fd9f950: Fix monitoring on opening panel
- e49708d: Fix manifest.json for Edge
## 3.2.1 ## 3.2.1
### Patch Changes ### Patch Changes

View File

@ -1,5 +1,5 @@
{ {
"version": "3.2.10", "version": "3.2.1",
"name": "Redux DevTools", "name": "Redux DevTools",
"description": "Redux DevTools for debugging application's state changes.", "description": "Redux DevTools for debugging application's state changes.",
"homepage_url": "https://github.com/reduxjs/redux-devtools", "homepage_url": "https://github.com/reduxjs/redux-devtools",

View File

@ -51,6 +51,7 @@ _number_ - maximum stack trace frames to be stored (in case `trace` option was p
_boolean_ or _object_ which contains: _boolean_ or _object_ which contains:
- **options** `object or boolean`: - **options** `object or boolean`:
- `undefined` - will use regular `JSON.stringify` to send data (it's the fast mode). - `undefined` - will use regular `JSON.stringify` to send data (it's the fast mode).
- `false` - will handle also circular references. - `false` - will handle also circular references.
- `true` - will handle also date, regex, undefined, primitives, error objects, symbols, maps, sets and functions. - `true` - will handle also date, regex, undefined, primitives, error objects, symbols, maps, sets and functions.

View File

@ -1,5 +1,5 @@
{ {
"version": "3.2.10", "version": "3.2.1",
"name": "Redux DevTools", "name": "Redux DevTools",
"description": "Redux DevTools for debugging application's state changes.", "description": "Redux DevTools for debugging application's state changes.",
"homepage_url": "https://github.com/reduxjs/redux-devtools", "homepage_url": "https://github.com/reduxjs/redux-devtools",
@ -28,7 +28,8 @@
"128": "img/logo/128x128.png" "128": "img/logo/128x128.png"
}, },
"options_ui": { "options_ui": {
"page": "options.html" "page": "options.html",
"chrome_style": true
}, },
"background": { "background": {
"service_worker": "background.bundle.js" "service_worker": "background.bundle.js"

View File

@ -1,38 +0,0 @@
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,
},
},
},
];

View File

@ -1,5 +1,5 @@
{ {
"version": "3.2.10", "version": "3.2.1",
"name": "Redux DevTools", "name": "Redux DevTools",
"manifest_version": 3, "manifest_version": 3,
"description": "Redux Developer Tools for debugging application state changes.", "description": "Redux Developer Tools for debugging application state changes.",

View File

@ -3,9 +3,9 @@ module.exports = {
testPathIgnorePatterns: ['<rootDir>/examples'], testPathIgnorePatterns: ['<rootDir>/examples'],
testEnvironment: 'jsdom', testEnvironment: 'jsdom',
moduleNameMapper: { moduleNameMapper: {
'\\.css$': '<rootDir>/test/__mocks__/styleMock.js', '\\.css$': '<rootDir>/test/__mocks__/styleMock.ts',
}, },
transformIgnorePatterns: [ transformIgnorePatterns: [
'node_modules/(?!.pnpm|@babel/code-frame|@babel/highlight|@babel/helper-validator-identifier|chalk|color|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)',
], ],
}; };

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"name": "remotedev-redux-devtools-extension", "name": "remotedev-redux-devtools-extension",
"version": "3.2.10", "version": "3.2.1",
"description": "Redux Developer Tools for debugging application state changes.", "description": "Redux Developer Tools for debugging application state changes.",
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/extension", "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/extension",
"license": "MIT", "license": "MIT",
@ -16,65 +16,70 @@
"build:examples": "babel-node examples/buildAll.js", "build:examples": "babel-node examples/buildAll.js",
"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": "cross-env SE_FORCE_BROWSER_DOWNLOAD=true 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",
"lint": "eslint .", "build:test:electron:fixture": "webpack --config test/electron/fixture/webpack.config.js",
"type-check": "tsc --noEmit" "type-check": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.14.0", "@redux-devtools/app": "^6.1.0",
"@redux-devtools/app": "workspace:^", "@redux-devtools/core": "^4.0.0",
"@redux-devtools/core": "workspace:^", "@redux-devtools/instrument": "^2.1.0",
"@redux-devtools/instrument": "workspace:^", "@redux-devtools/serialize": "^0.4.1",
"@redux-devtools/serialize": "workspace:^", "@redux-devtools/slider-monitor": "^5.0.1",
"@redux-devtools/slider-monitor": "workspace:^", "@redux-devtools/ui": "^1.3.2",
"@redux-devtools/ui": "workspace:^", "@redux-devtools/utils": "^3.0.0",
"@redux-devtools/utils": "workspace:^", "@reduxjs/toolkit": "^2.2.7",
"@reduxjs/toolkit": "^2.8.2",
"@types/jsan": "^3.1.5", "@types/jsan": "^3.1.5",
"jsan": "^3.1.14", "jsan": "^3.1.14",
"localforage": "^1.10.0", "localforage": "^1.10.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"react": "^19.1.0", "react": "^18.3.1",
"react-dom": "^19.1.0", "react-dom": "^18.3.1",
"react-icons": "^5.5.0", "react-icons": "^5.3.0",
"react-is": "^19.1.0", "react-is": "^18.3.1",
"react-json-tree": "workspace:^", "react-json-tree": "^0.19.0",
"react-redux": "^9.2.0", "react-redux": "^9.1.2",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-persist": "^6.0.0" "redux-persist": "^6.0.0",
"styled-components": "^5.3.11"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@babel/register": "^7.27.1", "@babel/register": "^7.24.6",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3", "@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.3.0", "@testing-library/react": "^16.0.0",
"@types/chrome": "^0.0.326", "@types/chrome": "^0.0.270",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^18.3.0",
"@types/styled-components": "^5.1.34",
"chromedriver": "^126.0.5", "chromedriver": "^126.0.5",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"electron": "^31.7.7", "electron": "^31.4.0",
"esbuild": "^0.25.5", "esbuild": "^0.23.1",
"globals": "^16.2.0", "eslint": "^8.57.0",
"immutable": "^5.1.3", "eslint-config-airbnb": "^19.0.4",
"jest": "^30.0.2", "eslint-plugin-import": "^2.29.1",
"jest-environment-jsdom": "^30.0.2", "eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-react": "^7.35.0",
"eslint-plugin-react-hooks": "^4.6.2",
"immutable": "^4.3.7",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"pug": "^3.0.3", "pug": "^3.0.3",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"selenium-webdriver": "^4.33.0", "selenium-webdriver": "^4.23.0",
"sinon-chrome": "^3.0.1", "sinon-chrome": "^3.0.1",
"ts-jest": "^29.4.0", "ts-jest": "^29.2.5",
"typescript": "~5.8.3", "typescript": "~5.5.4",
"webpack": "^5.99.9", "webpack": "^5.94.0",
"webpack-cli": "^6.0.1" "webpack-cli": "^5.1.4"
} }
} }

View File

@ -29,21 +29,25 @@ interface OwnProps {
} }
type Props = StateProps & DispatchProps & OwnProps; type Props = StateProps & DispatchProps & OwnProps;
const isElectron = navigator.userAgent.includes('Electron'); declare global {
interface Window {
isElectron?: boolean;
}
}
async function sendMessage(message: SingleMessage) { function sendMessage(message: SingleMessage) {
await chrome.runtime.sendMessage(message); chrome.runtime.sendMessage(message);
} }
class Actions extends Component<Props> { class Actions extends Component<Props> {
openWindow = async (position: Position) => { openWindow = (position: Position) => {
await sendMessage({ type: 'OPEN', position }); sendMessage({ type: 'OPEN', position });
}; };
openOptionsPage = async () => { openOptionsPage = () => {
if (navigator.userAgent.includes('Firefox')) { if (navigator.userAgent.indexOf('Firefox') !== -1) {
await sendMessage({ type: 'OPEN_OPTIONS' }); sendMessage({ type: 'OPEN_OPTIONS' });
} else { } else {
await chrome.runtime.openOptionsPage(); chrome.runtime.openOptionsPage();
} }
}; };
@ -85,7 +89,7 @@ class Actions extends Component<Props> {
{features.import && <ImportButton />} {features.import && <ImportButton />}
{position && {position &&
(position !== '#popup' || (position !== '#popup' ||
navigator.userAgent.includes('Firefox')) && <PrintButton />} navigator.userAgent.indexOf('Firefox') !== -1) && <PrintButton />}
<Divider /> <Divider />
<MonitorSelector /> <MonitorSelector />
<Divider /> <Divider />
@ -94,19 +98,19 @@ class Actions extends Component<Props> {
<DispatcherButton dispatcherIsOpen={this.props.dispatcherIsOpen} /> <DispatcherButton dispatcherIsOpen={this.props.dispatcherIsOpen} />
)} )}
<Divider /> <Divider />
{!isElectron && ( {!window.isElectron && (
<Button <Button
onClick={async () => { onClick={() => {
await this.openWindow('window'); this.openWindow('window');
}} }}
> >
<MdOutlineWindow /> <MdOutlineWindow />
</Button> </Button>
)} )}
{!isElectron && ( {!window.isElectron && (
<Button <Button
onClick={async () => { onClick={() => {
await this.openWindow('remote'); this.openWindow('remote');
}} }}
> >
<GoBroadcast /> <GoBroadcast />

View File

@ -27,7 +27,6 @@ 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>

View File

@ -6,7 +6,7 @@ export function createMenu() {
{ id: 'devtools-remote', title: 'Open Remote DevTools' }, { id: 'devtools-remote', title: 'Open Remote DevTools' },
]; ];
const shortcuts: { [commandName: string]: string | undefined } = {}; let 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;
@ -22,8 +22,8 @@ export function createMenu() {
}); });
} }
export async function removeMenu() { export function removeMenu() {
await chrome.contextMenus.removeAll(); chrome.contextMenus.removeAll();
} }
chrome.contextMenus.onClicked.addListener(({ menuItemId }) => { chrome.contextMenus.onClicked.addListener(({ menuItemId }) => {

View File

@ -1,4 +1,3 @@
import '../chromeApiMock';
import configureStore from './store/backgroundStore'; import configureStore from './store/backgroundStore';
import openDevToolsWindow, { DevToolsPosition } from './openWindow'; import openDevToolsWindow, { DevToolsPosition } from './openWindow';
import { createMenu, removeMenu } from './contextMenus'; import { createMenu, removeMenu } from './contextMenus';
@ -15,7 +14,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(() => {
void chrome.action.disable(); chrome.action.disable();
getOptions((option) => { getOptions((option) => {
if (option.showContextMenus) createMenu(); if (option.showContextMenus) createMenu();
@ -26,13 +25,6 @@ chrome.runtime.onInstalled.addListener(() => {
chrome.storage.onChanged.addListener((changes) => { chrome.storage.onChanged.addListener((changes) => {
if (changes.showContextMenus) { if (changes.showContextMenus) {
if (changes.showContextMenus.newValue) createMenu(); if (changes.showContextMenus.newValue) createMenu();
else void removeMenu(); else removeMenu();
} }
}); });
// https://developer.chrome.com/docs/extensions/develop/migrate/to-service-workers#keep_a_service_worker_alive_continuously
setInterval(
() =>
void chrome.storage.local.set({ 'last-heartbeat': new Date().getTime() }),
20000,
);

View File

@ -1,12 +1,12 @@
export type DevToolsPosition = 'devtools-window' | 'devtools-remote'; export type DevToolsPosition = 'devtools-window' | 'devtools-remote';
const windows: { [K in DevToolsPosition]?: number } = {}; let 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.includes('Firefox')) { if (navigator.userAgent.indexOf('Firefox') !== -1) {
void chrome.windows.update(win!.id!, { focused: true }); 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'); throw new Error(`Unrecognized position: ${position}`);
} }
} }

View File

@ -161,6 +161,10 @@ export type UpdateStateRequest<S, A extends Action<string>> =
| SerializedActionMessage | SerializedActionMessage
| SerializedStateMessage<S, A>; | SerializedStateMessage<S, A>;
export interface EmptyUpdateStateAction {
readonly type: typeof UPDATE_STATE;
}
interface UpdateStateAction<S, A extends Action<string>> { interface UpdateStateAction<S, A extends Action<string>> {
readonly type: typeof UPDATE_STATE; readonly type: typeof UPDATE_STATE;
request: UpdateStateRequest<S, A>; request: UpdateStateRequest<S, A>;
@ -209,6 +213,11 @@ export type PanelMessage<S, A extends Action<string>> =
export type PanelMessageWithSplitAction<S, A extends Action<string>> = export type PanelMessageWithSplitAction<S, A extends Action<string>> =
| PanelMessage<S, A> | PanelMessage<S, A>
| SplitUpdateStateAction<S, A>; | SplitUpdateStateAction<S, A>;
export type MonitorMessage =
| NAAction
| ErrorMessage
| EmptyUpdateStateAction
| SetPersistAction;
type TabPort = Omit<chrome.runtime.Port, 'postMessage'> & { type TabPort = Omit<chrome.runtime.Port, 'postMessage'> & {
postMessage: (message: TabMessage) => void; postMessage: (message: TabMessage) => void;
@ -218,15 +227,20 @@ type PanelPort = Omit<chrome.runtime.Port, 'postMessage'> & {
message: PanelMessageWithSplitAction<S, A>, message: PanelMessageWithSplitAction<S, A>,
) => void; ) => void;
}; };
type MonitorPort = Omit<chrome.runtime.Port, 'postMessage'> & {
postMessage: (message: MonitorMessage) => void;
};
export const CONNECTED = 'socket/CONNECTED'; export const CONNECTED = 'socket/CONNECTED';
export const DISCONNECTED = 'socket/DISCONNECTED'; export const DISCONNECTED = 'socket/DISCONNECTED';
const connections: { const connections: {
readonly tab: { [K in number | string]: TabPort }; readonly tab: { [K in number | string]: TabPort };
readonly panel: { [K in number | string]: PanelPort }; readonly panel: { [K in number | string]: PanelPort };
readonly monitor: { [K in number | string]: MonitorPort };
} = { } = {
tab: {}, tab: {},
panel: {}, panel: {},
monitor: {},
}; };
const chunks: { const chunks: {
[instanceId: string]: PageScriptToContentScriptMessageForwardedToMonitors< [instanceId: string]: PageScriptToContentScriptMessageForwardedToMonitors<
@ -235,6 +249,7 @@ const chunks: {
>; >;
} = {}; } = {};
let monitors = 0; let monitors = 0;
let isMonitored = false;
const getId = (sender: chrome.runtime.MessageSender, name?: string) => const getId = (sender: chrome.runtime.MessageSender, name?: string) =>
sender.tab ? sender.tab.id! : name || sender.id!; sender.tab ? sender.tab.id! : name || sender.id!;
@ -249,9 +264,10 @@ type MonitorAction<S, A extends Action<string>> =
const maxChromeMsgSize = 32 * 1024 * 1024; const maxChromeMsgSize = 32 * 1024 * 1024;
function toMonitors<S, A extends Action<string>>(action: MonitorAction<S, A>) { function toMonitors<S, A extends Action<string>>(action: MonitorAction<S, A>) {
console.log(`Message to monitors: ${action.type}`); for (const port of [
...Object.values(connections.monitor),
for (const port of Object.values(connections.panel)) { ...Object.values(connections.panel),
]) {
try { try {
port.postMessage(action); port.postMessage(action);
} catch (err) { } catch (err) {
@ -317,15 +333,19 @@ interface ImportMessage {
type ToContentScriptMessage = ImportMessage | LiftedActionAction; type ToContentScriptMessage = ImportMessage | LiftedActionAction;
function toContentScript(messageBody: ToContentScriptMessage) { function toContentScript(messageBody: ToContentScriptMessage) {
console.log(`Message to tab ${messageBody.id}: ${messageBody.message}`);
if (messageBody.message === 'DISPATCH') { if (messageBody.message === 'DISPATCH') {
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(store, message, instanceId, action, state), state: nonReduxDispatch(
id: instanceId.toString().replace(/^[^/]+\//, ''), store,
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;
@ -339,7 +359,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;
@ -353,7 +373,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;
@ -367,11 +387,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(
@ -381,19 +401,30 @@ function toContentScript(messageBody: ToContentScriptMessage) {
action as AppDispatchAction, action as AppDispatchAction,
state, state,
), ),
id: (instanceId as number).toString().replace(/^[^/]+\//, ''), id: (instanceId as number).toString().replace(/^[^\/]+\//, ''),
}); });
} }
} }
function toAllTabs(msg: TabMessage) { function toAllTabs(msg: TabMessage) {
console.log(`Message to all tabs: ${msg.type}`);
for (const tabPort of Object.values(connections.tab)) { for (const tabPort of Object.values(connections.tab)) {
tabPort.postMessage(msg); tabPort.postMessage(msg);
} }
} }
function monitorInstances(shouldMonitor: boolean, id?: string) {
if (!id && isMonitored === shouldMonitor) return;
const action = {
type: shouldMonitor ? ('START' as const) : ('STOP' as const),
};
if (id) {
if (connections.tab[id]) connections.tab[id].postMessage(action);
} else {
toAllTabs(action);
}
isMonitored = shouldMonitor;
}
function getReducerError() { function getReducerError() {
const instancesState = store.getState().instances; const instancesState = store.getState().instances;
const payload = instancesState.states[instancesState.current]; const payload = instancesState.states[instancesState.current];
@ -405,11 +436,11 @@ function getReducerError() {
function togglePersist() { function togglePersist() {
const state = store.getState(); const state = store.getState();
if (state.instances.persisted) { if (state.instances.persisted) {
for (const id of Object.keys(state.instances.connections)) { Object.keys(state.instances.connections).forEach((id) => {
if (connections.tab[id]) return; if (connections.tab[id]) return;
store.dispatch({ type: REMOVE_INSTANCE, id }); store.dispatch({ type: REMOVE_INSTANCE, id });
toMonitors({ type: 'NA', id }); toMonitors({ type: 'NA', id });
} });
} }
} }
@ -435,7 +466,6 @@ function messaging<S, A extends Action<string>>(
sender: chrome.runtime.MessageSender, sender: chrome.runtime.MessageSender,
) { ) {
let tabId = getId(sender); let tabId = getId(sender);
console.log(`Message from tab ${tabId}: ${request.type ?? request.split}`);
if (!tabId) return; if (!tabId) return;
if (sender.frameId) tabId = `${tabId}-${sender.frameId}`; if (sender.frameId) tabId = `${tabId}-${sender.frameId}`;
@ -446,7 +476,7 @@ function messaging<S, A extends Action<string>>(
return; return;
} }
if (request.type === 'OPEN_OPTIONS') { if (request.type === 'OPEN_OPTIONS') {
void chrome.runtime.openOptionsPage(); chrome.runtime.openOptionsPage();
return; return;
} }
if (request.type === 'OPTIONS') { if (request.type === 'OPTIONS') {
@ -472,7 +502,7 @@ function messaging<S, A extends Action<string>>(
} }
if (!request.message) return; if (!request.message) return;
const reducerError = getReducerError(); const reducerError = getReducerError();
void chrome.notifications.create('app-error', { chrome.notifications.create('app-error', {
type: 'basic', type: 'basic',
title: reducerError title: reducerError
? 'An error occurred in the reducer' ? 'An error occurred in the reducer'
@ -513,13 +543,11 @@ function messaging<S, A extends Action<string>>(
} }
function disconnect( function disconnect(
type: 'tab' | 'panel', type: 'tab' | 'monitor' | 'panel',
id: number | string, id: number | string,
listener: (message: any, port: chrome.runtime.Port) => void, listener?: (message: any, port: chrome.runtime.Port) => void,
) { ) {
return function disconnectListener() { return function disconnectListener() {
console.log(`Disconnected from ${type} ${id}`);
const p = connections[type][id]; const p = connections[type][id];
if (listener && p) p.onMessage.removeListener(listener); if (listener && p) p.onMessage.removeListener(listener);
if (p) p.onDisconnect.removeListener(disconnectListener); if (p) p.onDisconnect.removeListener(disconnectListener);
@ -531,7 +559,7 @@ function disconnect(
} }
} else { } else {
monitors--; monitors--;
if (monitors === 0) toAllTabs({ type: 'STOP' }); if (!monitors) monitorInstances(false);
} }
}; };
} }
@ -544,17 +572,16 @@ function onConnect<S, A extends Action<string>>(port: chrome.runtime.Port) {
if (port.name === 'tab') { if (port.name === 'tab') {
id = getId(port.sender!); id = getId(port.sender!);
console.log(`Connected to tab ${id}`);
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: ContentScriptToBackgroundMessage<S, A>) => { listener = (msg: ContentScriptToBackgroundMessage<S, A> | 'heartbeat') => {
console.log(`Message from tab ${id}: ${msg.name}`); if (msg === 'heartbeat') return;
if (msg.name === 'INIT_INSTANCE') { if (msg.name === 'INIT_INSTANCE') {
if (typeof id === 'number') { if (typeof id === 'number') {
void chrome.action.enable(id); chrome.action.enable(id);
void chrome.action.setIcon({ tabId: id, path: 'img/logo/38x38.png' }); chrome.action.setIcon({ tabId: id, path: 'img/logo/38x38.png' });
} }
if (monitors > 0) port.postMessage({ type: 'START' }); if (isMonitored) port.postMessage({ type: 'START' });
const state = store.getState(); const state = store.getState();
if (state.instances.persisted) { if (state.instances.persisted) {
@ -580,45 +607,28 @@ function onConnect<S, A extends Action<string>>(port: chrome.runtime.Port) {
port.onMessage.addListener(listener); port.onMessage.addListener(listener);
port.onDisconnect.addListener(disconnect('tab', id, listener)); port.onDisconnect.addListener(disconnect('tab', id, listener));
} else if (port.name && port.name.indexOf('monitor') === 0) { } else if (port.name && port.name.indexOf('monitor') === 0) {
// devpanel
id = getId(port.sender!, port.name); id = getId(port.sender!, port.name);
console.log(`Connected to monitor ${id}`); connections.monitor[id] = port;
connections.panel[id] = port; monitorInstances(true);
listener = (msg: BackgroundAction | 'heartbeat') => {
if (msg === 'heartbeat') return;
store.dispatch(msg);
};
port.onMessage.addListener(listener);
monitors++; monitors++;
toAllTabs({ type: 'START' }); port.onDisconnect.addListener(disconnect('monitor', id));
listener = (msg: BackgroundAction) => { } else {
console.log(`Message from monitor ${id}: ${msg.type}`); // devpanel
id = port.name || port.sender!.frameId!;
connections.panel[id] = port;
monitorInstances(true, port.name);
monitors++;
listener = (msg: BackgroundAction | 'heartbeat') => {
if (msg === 'heartbeat') return;
store.dispatch(msg); store.dispatch(msg);
}; };
port.onMessage.addListener(listener); port.onMessage.addListener(listener);
port.onDisconnect.addListener(disconnect('panel', id, listener)); port.onDisconnect.addListener(disconnect('panel', id, listener));
const { current } = store.getState().instances;
if (current !== 'default') {
const connectionId = Object.entries(
store.getState().instances.connections,
).find(([, instanceIds]) => instanceIds.includes(current))?.[0];
const options = store.getState().instances.options[current];
const state = store.getState().instances.states[current];
const { actionsById, computedStates, committedState, ...rest } = state;
toMonitors({
type: UPDATE_STATE,
request: {
type: 'STATE',
payload: rest as Omit<
LiftedState<S, A, unknown>,
'actionsById' | 'computedStates' | 'committedState'
>,
source: '@devtools-page',
instanceId:
typeof current === 'number' ? current.toString() : current,
actionsById: stringifyJSON(actionsById, options.serialize),
computedStates: stringifyJSON(computedStates, options.serialize),
committedState: typeof committedState !== 'undefined',
},
id: connectionId ?? current,
});
}
} }
} }
@ -628,11 +638,10 @@ chrome.runtime.onMessage.addListener(messaging);
chrome.runtime.onMessageExternal.addListener(messaging); chrome.runtime.onMessageExternal.addListener(messaging);
chrome.notifications.onClicked.addListener((id) => { chrome.notifications.onClicked.addListener((id) => {
void chrome.notifications.clear(id); chrome.notifications.clear(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;

View File

@ -1,50 +1,34 @@
// Mock not supported chrome.* API for Firefox and Electron // Mock not supported chrome.* API for Firefox and Electron
const isElectron = navigator.userAgent.includes('Electron'); window.isElectron =
const isFirefox = navigator.userAgent.includes('Firefox'); window.navigator && window.navigator.userAgent.indexOf('Electron') !== -1;
const isFirefox = navigator.userAgent.indexOf('Firefox') !== -1;
// Background page only // Background page only
if ( if (
(isElectron && location.pathname === '/background.bundle.js') || (window.isElectron &&
location.pathname === '/_generated_background_page.html') ||
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 (window.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) = {
onCommand: {
addListener() {
// do nothing.
},
}, },
}; };
} else { } else {
@ -55,39 +39,34 @@ if (
} }
} }
if (isElectron) { if (window.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(items: { [key: string]: string }, callback: () => void) { set(obj: any, callback: any) {
for (const [key, value] of Object.entries(items)) { Object.keys(obj).forEach((key) => {
localStorage.setItem(key, value); localStorage.setItem(key, obj[key]);
} });
if (callback) { if (callback) {
callback(); callback();
} }
}, },
get( get(obj: any, callback: any) {
keys: { [key: string]: any }, const result: any = {};
callback: (items: { [key: string]: any }) => void, Object.keys(obj).forEach((key) => {
) { 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(keys: string | string[], callback: () => void) { remove(items: any, callback: any) {
if (Array.isArray(keys)) { if (Array.isArray(items)) {
for (const key of keys) { items.forEach((name) => {
localStorage.removeItem(key); localStorage.removeItem(name);
} });
} else { } else {
localStorage.removeItem(keys); localStorage.removeItem(items);
} }
if (callback) { if (callback) {
callback(); callback();
@ -97,17 +76,17 @@ 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 as any).sendMessage = function (...args: unknown[]) { chrome.runtime.sendMessage = function () {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
return originSendMessage(...args); return originSendMessage(...arguments);
} }
if (typeof args[arguments.length - 1] === 'function') { if (typeof arguments[arguments.length - 1] === 'function') {
Array.prototype.pop.call(args); Array.prototype.pop.call(arguments);
} }
return originSendMessage(...args); return originSendMessage(...arguments);
}; };
} }
if (isFirefox || isElectron) { if (isFirefox || window.isElectron) {
(chrome.storage as any).sync = chrome.storage.local; (chrome.storage as any).sync = chrome.storage.local;
} }

View File

@ -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 SplitMessage); fn(newArgs as any);
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({
@ -343,3 +343,7 @@ function handleMessages<S, A extends Action<string>>(
prefetchOptions(); prefetchOptions();
window.addEventListener('message', handleMessages, false); window.addEventListener('message', handleMessages, false);
setInterval(() => {
bg?.postMessage('heartbeat');
}, 15000);

View File

@ -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.includes('Firefox'); const isChrome = navigator.userAgent.indexOf('Firefox') === -1;
function renderNodeAtRoot(node: ReactNode) { function renderNodeAtRoot(node: ReactNode) {
if (currentRoot) currentRoot.unmount(); if (currentRoot) currentRoot.unmount();
@ -67,7 +67,6 @@ 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>
@ -88,7 +87,6 @@ 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>
@ -118,6 +116,10 @@ function init() {
} }
bgConnection = chrome.runtime.connect({ name }); bgConnection = chrome.runtime.connect({ name });
setInterval(() => {
bgConnection.postMessage('heartbeat');
}, 15000);
bgConnection.onMessage.addListener( bgConnection.onMessage.addListener(
<S, A extends Action<string>>( <S, A extends Action<string>>(
message: PanelMessageWithSplitAction<S, A>, message: PanelMessageWithSplitAction<S, A>,
@ -141,18 +143,12 @@ function init() {
} }
if (request.split === 'chunk') { if (request.split === 'chunk') {
if ( if ((splitMessage as Record<string, unknown>)[request.chunk[0]]) {
(splitMessage as unknown as Record<string, string>)[ (splitMessage as Record<string, unknown>)[request.chunk[0]] +=
request.chunk[0] request.chunk[1];
]
) {
(splitMessage as unknown as Record<string, string>)[
request.chunk[0]
] += request.chunk[1];
} else { } else {
(splitMessage as unknown as Record<string, string>)[ (splitMessage as Record<string, unknown>)[request.chunk[0]] =
request.chunk[0] request.chunk[1];
] = request.chunk[1];
} }
return; return;
} }

View File

@ -38,7 +38,6 @@ 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;

View File

@ -2,7 +2,5 @@ chrome.devtools.panels.create(
'Redux', 'Redux',
'img/logo/scalable.png', 'img/logo/scalable.png',
'devpanel.html', 'devpanel.html',
() => { () => {},
// do nothing.
},
); );

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { OptionsProps } from './Options'; import { OptionsProps } from './Options';
export default function AllowToRunGroup({ options, saveOption }: OptionsProps) { export default ({ 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 function AllowToRunGroup({ options, saveOption }: OptionsProps) {
</div> </div>
</fieldset> </fieldset>
); );
} };

View File

@ -1,10 +1,7 @@
import React from 'react'; import React from 'react';
import { OptionsProps } from './Options'; import { OptionsProps } from './Options';
export default function ContextMenuGroup({ export default ({ options, saveOption }: OptionsProps) => {
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>
@ -26,4 +23,4 @@ export default function ContextMenuGroup({
</div> </div>
</fieldset> </fieldset>
); );
} };

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { OptionsProps } from './Options'; import { OptionsProps } from './Options';
export default function EditorGroup({ options, saveOption }: OptionsProps) { export default ({ options, saveOption }: OptionsProps) => {
const EditorState = { const EditorState = {
BROWSER: 0, BROWSER: 0,
EXTERNAL: 1, EXTERNAL: 1,
@ -21,7 +21,7 @@ export default function EditorGroup({ 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.includes('Firefox') {navigator.userAgent.indexOf('Firefox') !== -1
? "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 function EditorGroup({ options, saveOption }: OptionsProps) {
</div> </div>
</fieldset> </fieldset>
); );
} };

View File

@ -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 function FilterGroup({ options, saveOption }: OptionsProps) { export default ({ 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 function FilterGroup({ options, saveOption }: OptionsProps) {
</div> </div>
</fieldset> </fieldset>
); );
} };

View File

@ -1,10 +1,7 @@
import React from 'react'; import React from 'react';
import { OptionsProps } from './Options'; import { OptionsProps } from './Options';
export default function MiscellaneousGroup({ export default ({ options, saveOption }: OptionsProps) => {
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>
@ -50,4 +47,4 @@ export default function MiscellaneousGroup({
</div> </div>
</fieldset> </fieldset>
); );
} };

View File

@ -14,8 +14,7 @@ export interface OptionsProps {
) => void; ) => void;
} }
export default function OptionsComponent(props: OptionsProps) { export default (props: OptionsProps) => (
return (
<div> <div>
<EditorGroup {...props} /> <EditorGroup {...props} />
<FilterGroup {...props} /> <FilterGroup {...props} />
@ -25,12 +24,11 @@ export default function OptionsComponent(props: OptionsProps) {
<div style={{ color: 'red' }}> <div style={{ color: 'red' }}>
<br /> <br />
<hr /> <hr />
Setting options here is discouraged, and will not be possible in the Setting options here is discouraged, and will not be possible in the next
next major release. Please{' '} major release. Please{' '}
<a <a
href="https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md" href="https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md"
target="_blank" target="_blank"
rel="noreferrer"
style={{ color: 'red' }} style={{ color: 'red' }}
> >
specify them as parameters specify them as parameters
@ -39,7 +37,6 @@ export default function OptionsComponent(props: OptionsProps) {
<a <a
href="https://github.com/zalmoxisus/redux-devtools-extension/issues/296" href="https://github.com/zalmoxisus/redux-devtools-extension/issues/296"
target="_blank" target="_blank"
rel="noreferrer"
style={{ color: 'red' }} style={{ color: 'red' }}
> >
the issue the issue
@ -47,5 +44,4 @@ export default function OptionsComponent(props: OptionsProps) {
for more details. for more details.
</div> </div>
</div> </div>
); );
}

View File

@ -12,7 +12,7 @@ import {
subscribeToOptions((options) => { subscribeToOptions((options) => {
const message: OptionsMessage = { type: 'OPTIONS', options }; const message: OptionsMessage = { type: 'OPTIONS', options };
void chrome.runtime.sendMessage(message); chrome.runtime.sendMessage(message);
}); });
const renderOptions = (options: Options) => { const renderOptions = (options: Options) => {

View File

@ -46,9 +46,9 @@ export const saveOption = <K extends keyof Options>(
key: K, key: K,
value: Options[K], value: Options[K],
) => { ) => {
const obj: { [K1 in keyof Options]?: Options[K1] } = {}; let obj: { [K1 in keyof Options]?: Options[K1] } = {};
obj[key] = value; obj[key] = value;
void chrome.storage.sync.set(obj); 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,10 +99,7 @@ export const getOptions = (callback: (options: Options) => void) => {
} }
}; };
export const prefetchOptions = () => export const prefetchOptions = () => getOptions(() => {});
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);

View File

@ -26,7 +26,8 @@ export function isFiltered<A extends Action<string>>(
) { ) {
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;
} }

View File

@ -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>;
const preloadedState = let preloadedState =
'payload' in parsedSerializedLiftedState && 'payload' in parsedSerializedLiftedState &&
parsedSerializedLiftedState.preloadedState parsedSerializedLiftedState.preloadedState
? (parse(parsedSerializedLiftedState.preloadedState) as S) ? (parse(parsedSerializedLiftedState.preloadedState) as S)

View File

@ -222,7 +222,6 @@ 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;
@ -249,7 +248,6 @@ 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
@ -267,11 +265,10 @@ 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> {
const timestamp = Date.now(); let timestamp = Date.now();
const stack = getStackTrace(config, toExcludeFromTrace); let 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 };
} }
@ -598,11 +595,7 @@ export function connect(preConfig: Config): ConnectResponse {
}; };
const sendDelayed = throttle(() => { const sendDelayed = throttle(() => {
sendMessage( sendMessage(delayedActions, delayedStates as any, config);
delayedActions,
delayedStates as unknown as LiftedState<unknown, Action<string>, unknown>,
config,
);
delayedActions = []; delayedActions = [];
delayedStates = []; delayedStates = [];
}, latency); }, latency);

View File

@ -10,7 +10,7 @@ function createExpBackoffTimer(step: number) {
return 0; return 0;
} }
// Calculate next timeout // Calculate next timeout
const timeout = Math.pow(2, count - 1); let timeout = Math.pow(2, count - 1);
if (count < 5) count += 1; if (count < 5) count += 1;
return timeout * step; return timeout * step;
}; };

View File

@ -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 = new RegExp(`[?&]${key}=([^&#]+)\\b`).exec( const matches = window.location.href.match(
window.location.href, new RegExp(`[?&]${key}=([^&#]+)\\b`),
); );
return matches && matches.length > 0 ? matches[1] : null; return matches && matches.length > 0 ? matches[1] : null;
} }

View File

@ -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';
const stores: { let 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);
const { stateSanitizer, actionSanitizer, predicate, latency = 500 } = config; let { 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,
) => { ) => {
const m = (config && config.maxAge) || window.devToolsOptions.maxAge || 50; let m = (config && config.maxAge) || window.devToolsOptions.maxAge || 50;
if ( if (
!liftedAction || !liftedAction ||
noFiltersApplied(localFilter) || noFiltersApplied(localFilter) ||
@ -464,7 +464,10 @@ 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 (maxAge > m && !filteredActionIds.includes(stagedActionIds[i])) { while (
maxAge > m &&
filteredActionIds.indexOf(stagedActionIds[i]) === -1
) {
maxAge--; maxAge--;
i++; i++;
} }
@ -536,7 +539,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_); )(reducer_, initialState_) as any;
if (isInIframe()) setTimeout(init, 3000); if (isInIframe()) setTimeout(init, 3000);
else init(); else init();
@ -588,18 +591,18 @@ 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-expect-error FIXME // @ts-ignore 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
(composed, f) => f(composed), (composed, f) => f(composed),
__REDUX_DEVTOOLS_EXTENSION__({ ...config, instanceId })(...args), __REDUX_DEVTOOLS_EXTENSION__({ ...config, instanceId })(...args),
); );

View File

@ -1 +0,0 @@
module.exports = {};

View File

@ -0,0 +1 @@
export default {};

View File

@ -71,7 +71,6 @@ 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)),
); );
}); });

View File

@ -6,7 +6,7 @@ import chromedriver from 'chromedriver';
import { switchMonitorTests, delay } from '../utils/e2e'; import { switchMonitorTests, delay } from '../utils/e2e';
const devPanelPath = const devPanelPath =
'chrome-extension://lmhkpmbekcpmknklioeibfkpmmfibljd/devpanel.html'; 'chrome-extension://lmhkpmbekcpmknklioeibfkpmmfibljd/window.html';
describe('DevTools panel for Electron', function () { describe('DevTools panel for Electron', function () {
let driver; let driver;
@ -76,8 +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.skip('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()
.frame( .frame(
@ -88,7 +87,7 @@ describe('DevTools panel for Electron', function () {
await delay(1000); await delay(1000);
}); });
it('should contain INIT action', async () => { it.skip('should contain INIT action', async () => {
const element = await driver.wait( const element = await driver.wait(
webdriver.until.elementLocated( webdriver.until.elementLocated(
webdriver.By.xpath('//div[@data-testid="actionListRows"]'), webdriver.By.xpath('//div[@data-testid="actionListRows"]'),
@ -100,7 +99,7 @@ describe('DevTools panel for Electron', function () {
expect(val).toMatch(/@@INIT/); expect(val).toMatch(/@@INIT/);
}); });
it("should contain Inspector monitor's component", async () => { it.skip("should contain Inspector monitor's component", async () => {
const val = await driver const val = await driver
.findElement(webdriver.By.xpath('//div[@data-testid="inspector"]')) .findElement(webdriver.By.xpath('//div[@data-testid="inspector"]'))
.getText(); .getText();
@ -108,11 +107,9 @@ 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.skip(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

40
nx.json Normal file
View File

@ -0,0 +1,40 @@
{
"extends": "nx/presets/npm.json",
"npmScope": "undetermined",
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": ["build", "test", "lint", "package", "prepare"]
}
}
},
"targetDependencies": {
"build": [
{
"target": "build",
"projects": "dependencies"
}
],
"prepare": [
{
"target": "prepare",
"projects": "dependencies"
}
],
"package": [
{
"target": "package",
"projects": "dependencies"
}
]
},
"affected": {
"defaultBase": "main"
},
"pluginsConfig": {
"@nrwl/js": {
"analyzeSourceFiles": false
}
}
}

View File

@ -1,28 +1,43 @@
{ {
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@changesets/cli": "^2.29.5", "@changesets/cli": "^2.27.7",
"@eslint/compat": "^1.3.0", "@eslint/compat": "^1.1.1",
"@eslint/js": "^9.29.0", "@eslint/js": "^8.57.0",
"eslint": "^9.29.0", "@nrwl/nx-cloud": "^19.0.0",
"eslint-config-prettier": "^10.1.5", "eslint": "^8.57.0",
"eslint-plugin-jest": "^29.0.1", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-react": "^7.37.5", "eslint-plugin-jest": "^28.8.0",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react": "^7.35.0",
"jest": "^30.0.2", "eslint-plugin-react-hooks": "^4.6.2",
"prettier": "3.6.0", "jest": "^29.7.0",
"typescript": "~5.8.3", "nx": "^19.6.2",
"typescript-eslint": "^8.35.0" "prettier": "3.3.3",
"typescript": "~5.5.4",
"typescript-eslint": "^8.2.0"
}, },
"scripts": { "scripts": {
"format": "prettier --write .", "format": "prettier --write .",
"format:check": "prettier --check .", "format:check": "prettier --check .",
"build:all": "pnpm --recursive run build", "build:all": "nx run-many --target=build --all --parallel=1",
"lint:all": "pnpm --recursive run lint", "lint:all": "nx run-many --target=lint --all --parallel=1",
"test:all": "pnpm --recursive run test", "test:all": "nx run-many --target=test --all --parallel=1",
"clean:all": "pnpm --recursive run clean", "clean:all": "nx run-many --target=clean --all --parallel=1",
"release": "pnpm build:all && pnpm publish -r" "release": "pnpm build:all && changeset publish"
}, },
"packageManager": "pnpm@10.12.3" "workspaces": [
"extension",
"packages/*",
"packages/d3-state-visualizer/examples/tree",
"packages/react-dock/demo",
"packages/react-json-tree/examples",
"packages/redux-devtools/examples/counter",
"packages/redux-devtools/examples/todomvc",
"packages/redux-devtools-inspector-monitor/demo",
"packages/redux-devtools-inspector-monitor-test-tab/demo",
"packages/redux-devtools-rtk-query-monitor/demo",
"packages/redux-devtools-slider-monitor/examples/todomvc"
],
"packageManager": "pnpm@8.15.9"
} }

View File

@ -17,6 +17,7 @@
### Major Changes ### Major Changes
- b323f77d: Upgrade D3 - b323f77d: Upgrade D3
- Remove UMD build. - Remove UMD build.
- Split `style` option into `chartStyles`, `nodeStyleOptions`, `textStyleOptions`, and `linkStyles`. - Split `style` option into `chartStyles`, `nodeStyleOptions`, `textStyleOptions`, and `linkStyles`.
- The shape of the argument passed to the `onClickText` option has been updated. - The shape of the argument passed to the `onClickText` option has been updated.

View File

@ -25,22 +25,22 @@
"type-check": "tsc --noEmit" "type-check": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"d3-state-visualizer": "workspace:^", "d3-state-visualizer": "^3.0.0",
"map2tree": "workspace:^" "map2tree": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@types/node": "^22.15.32", "@types/node": "^20.16.1",
"babel-loader": "^10.0.0", "babel-loader": "^9.1.3",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"fork-ts-checker-webpack-plugin": "^9.1.0", "fork-ts-checker-webpack-plugin": "^9.0.2",
"html-webpack-plugin": "^5.6.3", "html-webpack-plugin": "^5.6.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.8.3", "typescript": "~5.5.4",
"webpack": "^5.99.9", "webpack": "^5.94.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.2.2" "webpack-dev-server": "^5.0.4"
} }
} }

View File

@ -39,14 +39,14 @@
"dependencies": { "dependencies": {
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",
"d3": "^7.9.0", "d3": "^7.9.0",
"d3tooltip": "workspace:^", "d3tooltip": "^4.0.0",
"deepmerge": "^4.3.1", "deepmerge": "^4.3.1",
"map2tree": "workspace:^", "map2tree": "^4.0.0",
"ramda": "^0.31.3" "ramda": "^0.30.1"
}, },
"devDependencies": { "devDependencies": {
"@types/ramda": "^0.30.2", "@types/ramda": "^0.30.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"typescript": "~5.8.3" "typescript": "~5.5.4"
} }
} }

View File

@ -17,6 +17,7 @@
### Major Changes ### Major Changes
- b323f77d: Upgrade D3 - b323f77d: Upgrade D3
- Remove UMD build. - Remove UMD build.
- Upgrade d3 peer dependency from v3 to v7. - Upgrade d3 peer dependency from v3 to v7.
- Remove `attr` configuration method. - Remove `attr` configuration method.

View File

@ -36,7 +36,7 @@
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",
"d3": "^7.9.0", "d3": "^7.9.0",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"typescript": "~5.8.3" "typescript": "~5.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",

View File

@ -40,12 +40,12 @@
"lodash-es": "^4.17.21" "lodash-es": "^4.17.21"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^30.0.0", "@types/jest": "^29.5.12",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"immutable": "^5.1.3", "immutable": "^4.3.7",
"jest": "^30.0.2", "jest": "^29.7.0",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"ts-jest": "^29.4.0", "ts-jest": "^29.2.5",
"typescript": "~5.8.3" "typescript": "~5.5.4"
} }
} }

View File

@ -36,19 +36,19 @@
"prepublish": "pnpm run lint && pnpm run test" "prepublish": "pnpm run lint && pnpm run test"
}, },
"dependencies": { "dependencies": {
"@types/lodash": "^4.17.18", "@types/lodash": "^4.17.7",
"color": "^5.0.0", "color": "^4.2.3",
"csstype": "^3.1.3", "csstype": "^3.1.3",
"lodash-es": "^4.17.21" "lodash-es": "^4.17.21"
}, },
"devDependencies": { "devDependencies": {
"@types/color": "^4.2.0", "@types/color": "^3.0.6",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.12",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"jest": "^30.0.2", "jest": "^29.7.0",
"jest-environment-jsdom": "^30.0.2", "jest-environment-jsdom": "^29.7.0",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"ts-jest": "^29.4.0", "ts-jest": "^29.2.5",
"typescript": "~5.8.3" "typescript": "~5.5.4"
} }
} }

View File

@ -1,11 +1,5 @@
# Change Log # Change Log
## 0.8.0
### Minor Changes
- 6830118: Add React 19 to peer deps
## 0.7.0 ## 0.7.0
### Minor Changes ### Minor Changes

View File

@ -1,12 +1,5 @@
# react-dock-demo # react-dock-demo
## 0.1.7
### Patch Changes
- Updated dependencies [6830118]
- react-dock@0.8.0
## 0.1.6 ## 0.1.6
### Patch Changes ### Patch Changes

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"name": "react-dock-demo", "name": "react-dock-demo",
"version": "0.1.7", "version": "0.1.6",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"start": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack serve --open", "start": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack serve --open",
@ -10,30 +10,31 @@
"type-check": "tsc --noEmit" "type-check": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"@emotion/styled": "^11.14.0", "react": "^18.3.1",
"react": "^19.1.0", "react-bootstrap": "^2.10.4",
"react-bootstrap": "^2.10.10", "react-dock": "^0.7.0",
"react-dock": "workspace:^", "react-dom": "^18.3.1",
"react-dom": "^19.1.0", "react-icons": "^5.3.0",
"react-icons": "^5.5.0", "react-is": "^18.3.1",
"react-is": "^19.1.0" "styled-components": "^5.3.11"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@types/node": "^22.15.32", "@types/node": "^20.16.1",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^18.3.0",
"babel-loader": "^10.0.0", "@types/styled-components": "^5.1.34",
"babel-loader": "^9.1.3",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"fork-ts-checker-webpack-plugin": "^9.1.0", "fork-ts-checker-webpack-plugin": "^9.0.2",
"html-webpack-plugin": "^5.6.3", "html-webpack-plugin": "^5.6.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.8.3", "typescript": "~5.5.4",
"webpack": "^5.99.9", "webpack": "^5.94.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.2.2" "webpack-dev-server": "^5.0.4"
} }
} }

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import Button from 'react-bootstrap/Button'; import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form'; import Form from 'react-bootstrap/Form';
import { BsX } from 'react-icons/bs'; import { BsX } from 'react-icons/bs';
import styled from '@emotion/styled'; import styled from 'styled-components';
import { Dock } from 'react-dock'; import { Dock } from 'react-dock';

View File

@ -1,9 +1,11 @@
import eslintJs from '../../eslint.js.config.base.mjs'; import eslintJs from '../../eslint.js.config.base.mjs';
import eslintTsReact from '../../eslint.ts.react.config.base.mjs'; import eslintTsReact from '../../eslint.ts.react.config.base.mjs';
import eslintTsReactJest from '../../eslint.ts.react.jest.config.base.mjs';
export default [ export default [
...eslintJs, ...eslintJs,
...eslintTsReact(import.meta.dirname), ...eslintTsReact(import.meta.dirname),
...eslintTsReactJest(import.meta.dirname),
{ {
ignores: ['demo', 'lib'], ignores: ['demo', 'lib'],
}, },

View File

@ -0,0 +1,13 @@
module.exports = {
testEnvironment: 'jsdom',
extensionsToTreatAsEsm: ['.ts', '.tsx'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
transform: {
'^.+\\.tsx?$': [
'ts-jest',
{ tsconfig: 'tsconfig.test.json', useESM: true },
],
},
};

View File

@ -1,6 +1,6 @@
{ {
"name": "react-dock", "name": "react-dock",
"version": "0.8.0", "version": "0.7.0",
"description": "Resizable dockable react component", "description": "Resizable dockable react component",
"keywords": [ "keywords": [
"react", "react",
@ -29,23 +29,30 @@
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"clean": "rimraf lib", "clean": "rimraf lib",
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
"lint": "eslint .", "lint": "eslint .",
"type-check": "tsc --noEmit", "type-check": "tsc --noEmit",
"prepack": "pnpm run clean && pnpm run build", "prepack": "pnpm run clean && pnpm run build",
"prepublish": "pnpm run lint" "prepublish": "pnpm run lint && pnpm run test"
}, },
"dependencies": { "dependencies": {
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"lodash-es": "^4.17.21" "lodash-es": "^4.17.21"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^19.1.8", "@types/jest": "^29.5.12",
"react": "^19.1.0", "@types/react": "^18.3.4",
"@types/react-test-renderer": "^18.3.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"react": "^18.3.1",
"react-test-renderer": "^18.3.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"typescript": "~5.8.3" "ts-jest": "^29.2.5",
"typescript": "~5.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0",
"react": "^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" "react": "^16.3.0 || ^17.0.0 || ^18.0.0"
} }
} }

View File

@ -228,12 +228,12 @@ interface Props {
dockHiddenStyle?: React.CSSProperties | null; dockHiddenStyle?: React.CSSProperties | null;
duration: number; duration: number;
children?: children?:
| ((params: { | React.FunctionComponent<{
position: 'left' | 'right' | 'top' | 'bottom'; position: 'left' | 'right' | 'top' | 'bottom';
isResizing: boolean | undefined; isResizing: boolean | undefined;
size: number; size: number;
isVisible: boolean | undefined; isVisible: boolean | undefined;
}) => ReactNode) }>
| ReactNode; | ReactNode;
} }
@ -363,7 +363,14 @@ export default class Dock extends Component<Props, State> {
/> />
<div style={styles.dockContent}> <div style={styles.dockContent}>
{typeof children === 'function' {typeof children === 'function'
? children({ ? (
children as React.FunctionComponent<{
position: 'left' | 'right' | 'top' | 'bottom';
isResizing: boolean | undefined;
size: number;
isVisible: boolean | undefined;
}>
)({
position, position,
isResizing, isResizing,
size, size,

View File

@ -39,8 +39,7 @@ const prefixes = ['Moz', 'Webkit', 'ms', 'O'];
function prefixProp<Value>(key: string, value: Value) { function prefixProp<Value>(key: string, value: Value) {
return prefixes.reduce<{ [key: string]: Value }>( return prefixes.reduce<{ [key: string]: Value }>(
(obj, pre) => ( (obj, pre) => (
(obj[pre + key[0].toUpperCase() + key.substr(1)] = value), (obj[pre + key[0].toUpperCase() + key.substr(1)] = value), obj
obj
), ),
{}, {},
); );

View File

@ -0,0 +1,23 @@
import React from 'react';
import TestRenderer from 'react-test-renderer/shallow';
import Dock from '../src/Dock.js';
describe('Dock component', function () {
it('should have shallow rendering', function () {
const renderer = TestRenderer.createRenderer();
const DockEl = <Dock />;
renderer.render(DockEl);
const result = renderer.getRenderOutput();
expect(DockEl.props).toEqual({
position: 'left',
zIndex: 99999999,
fluid: true,
defaultSize: 0.3,
dimMode: 'opaque',
duration: 200,
});
expect(result.type).toBe('div');
});
});

View File

@ -1,11 +1,5 @@
# Change Log # Change Log
## 0.20.0
### Minor Changes
- 6830118: Add React 19 to peer deps
## 0.19.0 ## 0.19.0
### Minor Changes ### Minor Changes
@ -22,6 +16,7 @@
### Major Changes ### Major Changes
- 81926f32: Remove UNSAFE method from react-json-tree - 81926f32: Remove UNSAFE method from react-json-tree
- Replace `shouldExpandNode` with `shouldExpandNodeInitially`. This function is now only called when a node in the tree is first rendered, when before it would update the expanded state of the node if the results of calling `shouldExpandNode` changed between renders. There is no way to replicate the old behavior exactly, but the new behavior is the intended behavior for the use cases within Redux DevTools. Please open an issue if you need a way to programatically control the expanded state of nodes. - Replace `shouldExpandNode` with `shouldExpandNodeInitially`. This function is now only called when a node in the tree is first rendered, when before it would update the expanded state of the node if the results of calling `shouldExpandNode` changed between renders. There is no way to replicate the old behavior exactly, but the new behavior is the intended behavior for the use cases within Redux DevTools. Please open an issue if you need a way to programatically control the expanded state of nodes.
- Bump the minimum React version from `16.3.0` to `16.8.0` so that `react-json-tree` can use hooks. - Bump the minimum React version from `16.3.0` to `16.8.0` so that `react-json-tree` can use hooks.
- Tightened TypeScript prop types to use `unknown` instead of `any` where possible and make the key path array `readonly`. - Tightened TypeScript prop types to use `unknown` instead of `any` where possible and make the key path array `readonly`.

View File

@ -1,12 +1,5 @@
# react-json-tree-example # react-json-tree-example
## 1.1.10
### Patch Changes
- Updated dependencies [6830118]
- react-json-tree@0.20.0
## 1.1.9 ## 1.1.9
### Patch Changes ### Patch Changes

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"name": "react-json-tree-example", "name": "react-json-tree-example",
"version": "1.1.10", "version": "1.1.9",
"description": "React-Json-Tree example", "description": "React-Json-Tree example",
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/react-json-tree/examples", "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/react-json-tree/examples",
"bugs": { "bugs": {
@ -19,28 +19,28 @@
"type-check": "tsc --noEmit" "type-check": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"immutable": "^5.1.3", "immutable": "^4.3.7",
"react": "^19.1.0", "react": "^18.3.1",
"react-base16-styling": "workspace:^", "react-base16-styling": "^0.10.0",
"react-dom": "^19.1.0", "react-dom": "^18.3.1",
"react-json-tree": "workspace:^" "react-json-tree": "^0.19.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@types/node": "^22.15.32", "@types/node": "^20.16.1",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^18.3.0",
"babel-loader": "^10.0.0", "babel-loader": "^9.1.3",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"fork-ts-checker-webpack-plugin": "^9.1.0", "fork-ts-checker-webpack-plugin": "^9.0.2",
"html-webpack-plugin": "^5.6.3", "html-webpack-plugin": "^5.6.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.8.3", "typescript": "~5.5.4",
"webpack": "^5.99.9", "webpack": "^5.94.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.2.2" "webpack-dev-server": "^5.0.4"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "react-json-tree", "name": "react-json-tree",
"version": "0.20.0", "version": "0.19.0",
"description": "React JSON Viewer Component, Extracted from redux-devtools", "description": "React JSON Viewer Component, Extracted from redux-devtools",
"keywords": [ "keywords": [
"react", "react",
@ -40,20 +40,22 @@
"prepublish": "pnpm run lint && pnpm run test" "prepublish": "pnpm run lint && pnpm run test"
}, },
"dependencies": { "dependencies": {
"@types/lodash": "^4.17.18", "@types/lodash": "^4.17.7",
"react-base16-styling": "workspace:^" "react-base16-styling": "^0.10.0"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^30.0.0", "@types/jest": "^29.5.12",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"jest": "^30.0.2", "@types/react-test-renderer": "^18.3.0",
"react": "^19.1.0", "jest": "^29.7.0",
"react": "^18.3.1",
"react-test-renderer": "^18.3.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"ts-jest": "^29.4.0", "ts-jest": "^29.2.5",
"typescript": "~5.8.3" "typescript": "~5.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
} }
} }

View File

@ -0,0 +1,22 @@
import React from 'react';
import TestRenderer from 'react-test-renderer/shallow';
import { JSONTree } from '../src/index.js';
import JSONNode from '../src/JSONNode.js';
const BASIC_DATA = { a: 1, b: 'c' };
function render(component: React.ReactElement) {
const renderer = TestRenderer.createRenderer();
renderer.render(component);
return renderer.getRenderOutput();
}
describe('JSONTree', () => {
it('should render basic tree', () => {
const result = render(<JSONTree data={BASIC_DATA} />);
expect(result.type).toBe('ul');
expect(result.props.children.type.name).toBe(JSONNode.name);
});
});

View File

@ -1,45 +1,5 @@
# @redux-devtools/app-core # @redux-devtools/app-core
## 1.1.2
### Patch Changes
- Updated dependencies [17b55ef]
- @redux-devtools/rtk-query-monitor@5.2.0
## 1.1.1
### Patch Changes
- Updated dependencies [91f21b2]
- @redux-devtools/core@4.1.1
- @redux-devtools/chart-monitor@5.1.1
- @redux-devtools/inspector-monitor@6.1.1
- @redux-devtools/inspector-monitor-test-tab@4.1.1
- @redux-devtools/inspector-monitor-trace-tab@4.1.1
- @redux-devtools/log-monitor@5.1.1
- @redux-devtools/rtk-query-monitor@5.1.1
- @redux-devtools/slider-monitor@5.1.1
## 1.1.0
### Minor Changes
- 6830118: Add React 19 to peer deps
### Patch Changes
- Updated dependencies [6830118]
- @redux-devtools/chart-monitor@6.0.0
- @redux-devtools/inspector-monitor-test-tab@5.0.0
- @redux-devtools/inspector-monitor-trace-tab@5.0.0
- @redux-devtools/inspector-monitor@7.0.0
- @redux-devtools/log-monitor@6.0.0
- @redux-devtools/rtk-query-monitor@6.0.0
- @redux-devtools/slider-monitor@6.0.0
- @redux-devtools/ui@1.4.0
- @redux-devtools/core@4.1.0
## 1.0.0 ## 1.0.0
### Major Changes ### Major Changes

View File

@ -10,6 +10,6 @@ module.exports = {
'^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }],
}, },
transformIgnorePatterns: [ transformIgnorePatterns: [
'node_modules/(?!.pnpm|@babel/code-frame|@babel/highlight|@babel/helper-validator-identifier|chalk|color|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)',
], ],
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/app-core", "name": "@redux-devtools/app-core",
"version": "1.1.2", "version": "1.0.0",
"description": "Redux DevTools app core", "description": "Redux DevTools app core",
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-app-core", "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-app-core",
"bugs": { "bugs": {
@ -35,67 +35,69 @@
"prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.27.6", "@babel/runtime": "^7.25.4",
"@redux-devtools/chart-monitor": "workspace:^", "@redux-devtools/chart-monitor": "^5.0.1",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "^4.0.0",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "^6.0.0",
"@redux-devtools/inspector-monitor-test-tab": "workspace:^", "@redux-devtools/inspector-monitor-test-tab": "^4.0.0",
"@redux-devtools/inspector-monitor-trace-tab": "workspace:^", "@redux-devtools/inspector-monitor-trace-tab": "^4.0.0",
"@redux-devtools/log-monitor": "workspace:^", "@redux-devtools/log-monitor": "^5.0.0",
"@redux-devtools/rtk-query-monitor": "workspace:^", "@redux-devtools/rtk-query-monitor": "^5.0.0",
"@redux-devtools/slider-monitor": "workspace:^", "@redux-devtools/slider-monitor": "^5.0.0",
"@redux-devtools/ui": "workspace:^", "@redux-devtools/ui": "^1.3.1",
"d3-state-visualizer": "workspace:^", "d3-state-visualizer": "^3.0.0",
"javascript-stringify": "^2.1.0", "javascript-stringify": "^2.1.0",
"jsan": "^3.1.14", "jsan": "^3.1.14",
"jsondiffpatch": "^0.7.3", "jsondiffpatch": "^0.6.0",
"react-icons": "^5.5.0", "react-icons": "^5.3.0",
"react-is": "^19.1.0" "react-is": "^18.3.1"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.27.2", "@babel/cli": "^7.24.8",
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.27.5", "@babel/eslint-parser": "^7.25.1",
"@babel/plugin-transform-runtime": "^7.27.4", "@babel/plugin-transform-runtime": "^7.25.4",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.14.0", "@reduxjs/toolkit": "^2.2.7",
"@reduxjs/toolkit": "^2.8.2", "@rjsf/core": "^5.20.0",
"@rjsf/core": "^5.24.12",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3", "@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.3.0", "@testing-library/react": "^16.0.0",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.12",
"@types/jsan": "^3.1.5", "@types/jsan": "^3.1.5",
"@types/json-schema": "^7.0.15", "@types/json-schema": "^7.0.15",
"@types/node": "^22.15.32", "@types/node": "^20.16.1",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^18.3.0",
"@types/styled-components": "^5.1.34",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"esbuild": "^0.25.5", "esbuild": "^0.23.1",
"jest": "^30.0.2", "jest": "^29.7.0",
"jest-environment-jsdom": "^30.0.2", "jest-environment-jsdom": "^29.7.0",
"react": "^19.1.0", "react": "^18.3.1",
"react-dom": "^19.1.0", "react-dom": "^18.3.1",
"react-redux": "^9.2.0", "react-redux": "^9.1.2",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"ts-jest": "^29.4.0", "styled-components": "^5.3.11",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.8.3" "typescript": "~5.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.14.0",
"@reduxjs/toolkit": "^1.0.0 || ^2.0.0", "@reduxjs/toolkit": "^1.0.0 || ^2.0.0",
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/styled-components": "^5.1.34",
"react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.4 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0",
"react-redux": "^8.0.0 || ^9.0.0", "react-redux": "^8.0.0 || ^9.0.0",
"redux": "^4.0.0 || ^5.0.0", "redux": "^4.0.0 || ^5.0.0",
"redux-persist": "^6.0.0" "redux-persist": "^6.0.0",
"styled-components": "^5.3.11"
} }
} }

View File

@ -1,5 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { withTheme } from '@emotion/react'; import { withTheme } from 'styled-components';
import { LiftedAction, LiftedState } from '@redux-devtools/core'; import { LiftedAction, LiftedState } from '@redux-devtools/core';
import { Action } from 'redux'; import { Action } from 'redux';
import getMonitor from '../utils/getMonitor'; import getMonitor from '../utils/getMonitor';

View File

@ -1,14 +1,8 @@
// Based on https://github.com/YoruNoHikage/redux-devtools-dispatch // Based on https://github.com/YoruNoHikage/redux-devtools-dispatch
import React, { Component } from 'react'; import React, { Component } from 'react';
import styled from '@emotion/styled'; import styled from 'styled-components';
import { import { Button, Select, Editor, Toolbar } from '@redux-devtools/ui';
Button,
Select,
Editor,
Toolbar,
Base16Theme,
} from '@redux-devtools/ui';
import { connect, ResolveThunks } from 'react-redux'; import { connect, ResolveThunks } from 'react-redux';
import { dispatchRemotely } from '../../actions'; import { dispatchRemotely } from '../../actions';
import { Options } from '../../reducers/instances'; import { Options } from '../../reducers/instances';
@ -18,7 +12,7 @@ export const DispatcherContainer = styled.div`
flex-direction: column; flex-direction: column;
flex-shrink: 0; flex-shrink: 0;
padding-top: 2px; padding-top: 2px;
background: ${(props: { theme?: Base16Theme }) => props.theme!.base01}; background: ${(props) => props.theme.base01};
`; `;
export const CodeContainer = styled.div` export const CodeContainer = styled.div`
@ -30,7 +24,7 @@ export const CodeContainer = styled.div`
export const ActionContainer = styled.div` export const ActionContainer = styled.div`
display: table; display: table;
width: 100%; width: 100%;
color: ${(props: { theme?: Base16Theme }) => props.theme!.base06}; color: ${(props) => props.theme.base06};
> div { > div {
display: table-row; display: table-row;

View File

@ -1,6 +1,6 @@
import React, { Component, RefCallback } from 'react'; import React, { Component, RefCallback } from 'react';
import { connect, ResolveThunks } from 'react-redux'; import { connect, ResolveThunks } from 'react-redux';
import { withTheme } from '@emotion/react'; import { withTheme } from 'styled-components';
import { tree } from 'd3-state-visualizer'; import { tree } from 'd3-state-visualizer';
import type { HierarchyPointNode, Node, Options } from 'd3-state-visualizer'; import type { HierarchyPointNode, Node, Options } from 'd3-state-visualizer';
import { getPath } from '../ChartMonitorWrapper'; import { getPath } from '../ChartMonitorWrapper';

View File

@ -1,8 +1,8 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import type { Delta } from 'jsondiffpatch'; import type { Delta } from 'jsondiffpatch';
import * as htmlFormatter from 'jsondiffpatch/formatters/html'; import * as htmlFormatter from 'jsondiffpatch/formatters/html';
import styled from '@emotion/styled'; import styled, { ThemedStyledProps } from 'styled-components';
import { Base16Theme, effects } from '@redux-devtools/ui'; import { effects, Theme } from '@redux-devtools/ui';
export const StyledContainer = styled.div` export const StyledContainer = styled.div`
.jsondiffpatch-delta { .jsondiffpatch-delta {
@ -19,7 +19,8 @@ export const StyledContainer = styled.div`
padding: 2px 3px; padding: 2px 3px;
border-radius: 3px; border-radius: 3px;
position: relative; position: relative;
color: ${(props: { theme?: Base16Theme }) => props.theme!.base07}; ${/* eslint-disable-next-line @typescript-eslint/no-empty-object-type */ ''}
color: ${(props: ThemedStyledProps<{}, Theme>) => props.theme.base07};
display: inline-block; display: inline-block;
} }
@ -43,22 +44,25 @@ export const StyledContainer = styled.div`
.jsondiffpatch-modified .jsondiffpatch-right-value:before { .jsondiffpatch-modified .jsondiffpatch-right-value:before {
vertical-align: top; vertical-align: top;
padding: 2px; padding: 2px;
color: ${(props) => props.theme.base0E}; ${/* eslint-disable-next-line @typescript-eslint/no-empty-object-type */ ''}
color: ${(props: ThemedStyledProps<{}, Theme>) => props.theme.base0E};
content: ' => '; content: ' => ';
} }
.jsondiffpatch-added .jsondiffpatch-value pre, .jsondiffpatch-added .jsondiffpatch-value pre,
.jsondiffpatch-modified .jsondiffpatch-right-value pre, .jsondiffpatch-modified .jsondiffpatch-right-value pre,
.jsondiffpatch-textdiff-added { .jsondiffpatch-textdiff-added {
background: ${(props: { theme?: Base16Theme }) => ${/* eslint-disable-next-line @typescript-eslint/no-empty-object-type */ ''}
effects.color(props.theme!.base0B, 'alpha', 0.2)}; background: ${(props: ThemedStyledProps<{}, Theme>) =>
effects.color(props.theme.base0B, 'alpha', 0.2)};
} }
.jsondiffpatch-deleted pre, .jsondiffpatch-deleted pre,
.jsondiffpatch-modified .jsondiffpatch-left-value pre, .jsondiffpatch-modified .jsondiffpatch-left-value pre,
.jsondiffpatch-textdiff-deleted { .jsondiffpatch-textdiff-deleted {
background: ${(props: { theme?: Base16Theme }) => ${/* eslint-disable-next-line @typescript-eslint/no-empty-object-type */ ''}
effects.color(props.theme!.base08, 'alpha', 0.2)}; background: ${(props: ThemedStyledProps<{}, Theme>) =>
effects.color(props.theme.base08, 'alpha', 0.2)};
text-decoration: line-through; text-decoration: line-through;
} }
@ -125,12 +129,14 @@ export const StyledContainer = styled.div`
padding: 2px 0; padding: 2px 0;
padding-right: 5px; padding-right: 5px;
vertical-align: top; vertical-align: top;
color: ${(props) => props.theme.base0D}; ${/* eslint-disable-next-line @typescript-eslint/no-empty-object-type */ ''}
color: ${(props: ThemedStyledProps<{}, Theme>) => props.theme.base0D};
} }
.jsondiffpatch-property-name:after { .jsondiffpatch-property-name:after {
content: ': '; content: ': ';
color: ${(props) => props.theme.base07}; ${/* eslint-disable-next-line @typescript-eslint/no-empty-object-type */ ''}
color: ${(props: ThemedStyledProps<{}, Theme>) => props.theme.base07};
} }
.jsondiffpatch-child-node-type-array > .jsondiffpatch-property-name:after { .jsondiffpatch-child-node-type-array > .jsondiffpatch-property-name:after {
@ -166,7 +172,8 @@ export const StyledContainer = styled.div`
} }
.jsondiffpatch-value pre:after { .jsondiffpatch-value pre:after {
color: ${(props) => props.theme.base07}; ${/* eslint-disable-next-line @typescript-eslint/no-empty-object-type */ ''}
color: ${(props: ThemedStyledProps<{}, Theme>) => props.theme.base07};
content: ','; content: ',';
} }
@ -189,7 +196,8 @@ export const StyledContainer = styled.div`
.jsondiffpatch-moved .jsondiffpatch-moved-destination { .jsondiffpatch-moved .jsondiffpatch-moved-destination {
display: inline-block; display: inline-block;
background: ${(props) => props.theme.base0A}; ${/* eslint-disable-next-line @typescript-eslint/no-empty-object-type */ ''}
background: ${(props: ThemedStyledProps<{}, Theme>) => props.theme.base0A};
} }
.jsondiffpatch-moved .jsondiffpatch-moved-destination:before { .jsondiffpatch-moved .jsondiffpatch-moved-destination:before {

View File

@ -1,14 +1,13 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import styled from '@emotion/styled'; import styled, { withTheme } from 'styled-components';
import { withTheme } from '@emotion/react';
import { SliderMonitor } from '@redux-devtools/slider-monitor'; import { SliderMonitor } from '@redux-devtools/slider-monitor';
import { LiftedAction } from '@redux-devtools/core'; import { LiftedAction } from '@redux-devtools/core';
import { Action } from 'redux'; import { Action } from 'redux';
import { Base16Theme, ThemeFromProvider } from '@redux-devtools/ui'; import { ThemeFromProvider } from '@redux-devtools/ui';
import { State } from '../../reducers/instances'; import { State } from '../../reducers/instances';
const SliderWrapper = styled.div` const SliderWrapper = styled.div`
border-color: ${(props: { theme?: Base16Theme }) => props.theme!.base02}; border-color: ${(props) => props.theme.base02};
border-style: solid; border-style: solid;
border-width: 1px 0; border-width: 1px 0;
`; `;

View File

@ -1,29 +1,5 @@
# Change Log # Change Log
## 6.2.2
### Patch Changes
- @redux-devtools/app-core@1.1.2
## 6.2.1
### Patch Changes
- @redux-devtools/app-core@1.1.1
## 6.2.0
### Minor Changes
- 6830118: Add React 19 to peer deps
### Patch Changes
- Updated dependencies [6830118]
- @redux-devtools/app-core@1.1.0
- @redux-devtools/ui@1.4.0
## 6.1.0 ## 6.1.0
### Minor Changes ### Minor Changes

View File

@ -11,7 +11,6 @@ Also it's a react component you can use to build amazing monitor applications li
- [remote-redux-devtools-on-debugger](https://github.com/jhen0409/remote-redux-devtools-on-debugger) - Used in React Native debugger as a dock monitor. - [remote-redux-devtools-on-debugger](https://github.com/jhen0409/remote-redux-devtools-on-debugger) - Used in React Native debugger as a dock monitor.
- [atom-redux-devtools](https://github.com/zalmoxisus/atom-redux-devtools) - Used in Atom editor. - [atom-redux-devtools](https://github.com/zalmoxisus/atom-redux-devtools) - Used in Atom editor.
- [vscode-redux-devtools](https://github.com/jkzing/vscode-redux-devtools) - Used in Visual Studio Code. - [vscode-redux-devtools](https://github.com/jkzing/vscode-redux-devtools) - Used in Visual Studio Code.
- [intellij-redux-devtools](https://github.com/takanuva15/intellij-redux-devtools) - Used in IntelliJ IDEA.
### Usage ### Usage

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/app", "name": "@redux-devtools/app",
"version": "6.2.2", "version": "6.1.0",
"description": "Redux DevTools app", "description": "Redux DevTools app",
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-app", "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-app",
"bugs": { "bugs": {
@ -39,59 +39,61 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@redux-devtools/app-core": "workspace:^", "@redux-devtools/app-core": "^1.0.0",
"@redux-devtools/ui": "workspace:^", "@redux-devtools/ui": "^1.3.2",
"localforage": "^1.10.0", "localforage": "^1.10.0",
"jsan": "^3.1.14", "jsan": "^3.1.14",
"react-redux": "^9.2.0", "react-redux": "^9.1.2",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"socketcluster-client": "^19.2.7" "socketcluster-client": "^19.2.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.27.2", "@babel/cli": "^7.24.8",
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.27.5", "@babel/eslint-parser": "^7.25.1",
"@babel/plugin-transform-runtime": "^7.27.4", "@babel/plugin-transform-runtime": "^7.25.4",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.14.0", "@reduxjs/toolkit": "^2.2.7",
"@reduxjs/toolkit": "^2.8.2", "@rjsf/core": "^5.20.0",
"@rjsf/core": "^5.24.12",
"@types/jsan": "^3.1.5", "@types/jsan": "^3.1.5",
"@types/json-schema": "^7.0.15", "@types/json-schema": "^7.0.15",
"@types/node": "^22.15.32", "@types/node": "^20.16.1",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^18.3.0",
"@types/socketcluster-client": "^19.1.0", "@types/socketcluster-client": "^19.1.0",
"@types/webpack-env": "^1.18.8", "@types/styled-components": "^5.1.34",
"babel-loader": "^10.0.0", "@types/webpack-env": "^1.18.5",
"babel-loader": "^9.1.3",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"css-loader": "^7.1.2", "css-loader": "^7.1.2",
"esbuild": "^0.25.5", "esbuild": "^0.23.1",
"fork-ts-checker-webpack-plugin": "^9.1.0", "fork-ts-checker-webpack-plugin": "^9.0.2",
"globals": "^16.2.0", "globals": "^15.9.0",
"html-loader": "^5.1.0", "html-loader": "^5.1.0",
"html-webpack-plugin": "^5.6.3", "html-webpack-plugin": "^5.6.0",
"react": "^19.1.0", "react": "^18.3.1",
"react-dom": "^19.1.0", "react-dom": "^18.3.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"ts-jest": "^29.4.0", "styled-components": "^5.3.11",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.8.3", "typescript": "~5.5.4",
"webpack": "^5.99.9", "webpack": "^5.94.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.2.2" "webpack-dev-server": "^5.0.4"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.14.0",
"@reduxjs/toolkit": "^1.0.0 || ^2.0.0", "@reduxjs/toolkit": "^1.0.0 || ^2.0.0",
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/styled-components": "^5.1.34",
"react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0" "react": "^16.8.4 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0",
"styled-components": "^5.3.11"
} }
} }

View File

@ -1,23 +1,5 @@
# Change Log # Change Log
## 5.1.1
### Patch Changes
- Updated dependencies [91f21b2]
- @redux-devtools/core@4.1.1
## 5.1.0
### Minor Changes
- 6830118: Add React 19 to peer deps
### Patch Changes
- Updated dependencies [6830118]
- @redux-devtools/core@4.1.0
## 5.0.2 ## 5.0.2
### Patch Changes ### Patch Changes
@ -66,6 +48,7 @@
### Major Changes ### Major Changes
- b323f77d: Upgrade D3 - b323f77d: Upgrade D3
- Split `style` option into `chartStyles`, `nodeStyleOptions`, `textStyleOptions`, and `linkStyles`. - Split `style` option into `chartStyles`, `nodeStyleOptions`, `textStyleOptions`, and `linkStyles`.
- The shape of the argument passed to the `onClickText` option has been updated. - The shape of the argument passed to the `onClickText` option has been updated.

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/chart-monitor", "name": "@redux-devtools/chart-monitor",
"version": "5.1.1", "version": "5.0.2",
"description": "Chart monitor for Redux DevTools", "description": "Chart monitor for Redux DevTools",
"keywords": [ "keywords": [
"redux", "redux",
@ -39,30 +39,30 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.27.6", "@babel/runtime": "^7.25.4",
"d3-state-visualizer": "workspace:^", "d3-state-visualizer": "^3.0.0",
"deepmerge": "^4.3.1", "deepmerge": "^4.3.1",
"react-base16-styling": "workspace:^" "react-base16-styling": "^0.10.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.27.2", "@babel/cli": "^7.24.8",
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.27.5", "@babel/eslint-parser": "^7.25.1",
"@babel/plugin-transform-runtime": "^7.27.4", "@babel/plugin-transform-runtime": "^7.25.4",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "^4.0.0",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"react": "^19.1.0", "react": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"typescript": "~5.8.3" "typescript": "~5.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "^4.0.0",
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.4 || ^17.0.0 || ^18.0.0",
"redux": "^3.4.0 || ^4.0.0 || ^5.0.0" "redux": "^3.4.0 || ^4.0.0 || ^5.0.0"
} }
} }

View File

@ -1,24 +1,5 @@
# Change Log # Change Log
## 4.0.3
### Patch Changes
- @redux-devtools/app@6.2.2
## 4.0.2
### Patch Changes
- @redux-devtools/app@6.2.1
## 4.0.1
### Patch Changes
- Updated dependencies [6830118]
- @redux-devtools/app@6.2.0
## 4.0.0 ## 4.0.0
### Major Changes ### Major Changes

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/cli", "name": "@redux-devtools/cli",
"version": "4.0.3", "version": "4.0.0",
"description": "CLI for remote debugging with Redux DevTools.", "description": "CLI for remote debugging with Redux DevTools.",
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-cli", "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-cli",
"bugs": { "bugs": {
@ -41,56 +41,56 @@
"node": ">= 18.12.0" "node": ">= 18.12.0"
}, },
"dependencies": { "dependencies": {
"@apollo/server": "^4.12.2", "@apollo/server": "^4.11.0",
"@as-integrations/express5": "^1.1.0", "@emotion/react": "^11.13.3",
"@emotion/react": "^11.14.0", "@redux-devtools/app": "^6.0.0",
"@emotion/styled": "^11.14.0", "@reduxjs/toolkit": "^2.2.7",
"@redux-devtools/app": "workspace:^", "@types/react": "^18.3.4",
"@reduxjs/toolkit": "^2.8.2", "body-parser": "^1.20.2",
"@types/react": "^19.1.8", "chalk": "^5.3.0",
"body-parser": "^2.2.0",
"chalk": "^5.4.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"cross-spawn": "^7.0.6", "cross-spawn": "^7.0.3",
"electron": "^31.7.7", "electron": "^31.4.0",
"express": "^5.1.0", "express": "^4.19.2",
"get-port": "^7.1.0", "get-port": "^7.1.0",
"graphql": "^16.11.0", "graphql": "^16.9.0",
"knex": "^3.1.0", "knex": "^3.1.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"minimist": "^1.2.8", "minimist": "^1.2.8",
"morgan": "^1.10.0", "morgan": "^1.10.0",
"open": "^10.1.2", "open": "^10.1.0",
"react": "^19.1.0", "react": "^18.3.1",
"react-dom": "^19.1.0", "react-dom": "^18.3.1",
"react-is": "^19.1.0", "react-is": "^18.3.1",
"semver": "^7.7.2", "semver": "^7.6.3",
"socketcluster-server": "^19.2.0", "socketcluster-server": "^19.1.0",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"uuid": "^11.1.0" "styled-components": "^5.3.11",
"uuid": "^10.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/body-parser": "^1.19.6", "@types/body-parser": "^1.19.5",
"@types/cors": "^2.8.19", "@types/cors": "^2.8.17",
"@types/cross-spawn": "^6.0.6", "@types/cross-spawn": "^6.0.6",
"@types/express": "^5.0.3", "@types/express": "^4.17.21",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.12",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/minimist": "^1.2.5", "@types/minimist": "^1.2.5",
"@types/morgan": "^1.9.10", "@types/morgan": "^1.9.9",
"@types/node": "^22.15.32", "@types/node": "^20.16.1",
"@types/semver": "^7.7.0", "@types/semver": "^7.5.8",
"@types/socketcluster-client": "^19.1.0", "@types/socketcluster-client": "^19.1.0",
"@types/socketcluster-server": "^19.0.1", "@types/socketcluster-server": "^19.0.1",
"@types/supertest": "^6.0.3", "@types/styled-components": "^5.1.34",
"@types/supertest": "^6.0.2",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"globals": "^16.2.0", "globals": "^15.9.0",
"jest": "^30.0.2", "jest": "^29.7.0",
"ncp": "^2.0.0", "ncp": "^2.0.0",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"socketcluster-client": "^19.2.7", "socketcluster-client": "^19.2.2",
"supertest": "^7.1.1", "supertest": "^7.0.0",
"ts-jest": "^29.4.0", "ts-jest": "^29.2.5",
"typescript": "~5.8.3" "typescript": "~5.5.4"
} }
} }

View File

@ -41,7 +41,6 @@ export default async function (argv: { [arg: string]: any }): Promise<{
const agServer = socketClusterServer.attach(httpServer, options); const agServer = socketClusterServer.attach(httpServer, options);
const app = express(); const app = express();
// eslint-disable-next-line @typescript-eslint/no-misused-promises
httpServer.on('request', app); httpServer.on('request', app);
const store = createStore(options); const store = createStore(options);
app.use(routes(options, store, agServer)); app.use(routes(options, store, agServer));
@ -77,7 +76,7 @@ export default async function (argv: { [arg: string]: any }): Promise<{
}); });
}) })
.catch(function (error) { .catch(function (error) {
console.error(error); console.error(error); // eslint-disable-line no-console
}); });
} }
} }
@ -111,7 +110,7 @@ export default async function (argv: { [arg: string]: any }): Promise<{
request.end(data); request.end(data);
}) })
.catch(function (error) { .catch(function (error) {
console.error(error); console.error(error); // eslint-disable-line no-console
}); });
} }
})(); })();
@ -119,6 +118,7 @@ export default async function (argv: { [arg: string]: any }): Promise<{
for await (const data of socket.listener('disconnect')) { for await (const data of socket.listener('disconnect')) {
const channel = agServer.exchange.channel('sc-' + socket.id); const channel = agServer.exchange.channel('sc-' + socket.id);
channel.unsubscribe(); channel.unsubscribe();
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
void agServer.exchange.transmitPublish(channelToEmit!, { void agServer.exchange.transmitPublish(channelToEmit!, {
id: socket.id, id: socket.id,
type: 'DISCONNECTED', type: 'DISCONNECTED',

View File

@ -62,14 +62,13 @@ function routes(
'/graphql', '/graphql',
cors<cors.CorsRequest>(), cors<cors.CorsRequest>(),
bodyParser.json(), bodyParser.json(),
// @ts-expect-error https://github.com/apollo-server-integrations/apollo-server-integration-express5/issues/9
expressMiddleware(server, { expressMiddleware(server, {
context: () => Promise.resolve({ store }), context: () => Promise.resolve({ store }),
}), }),
); );
}) })
.catch((error) => { .catch((error) => {
console.error(error); console.error(error); // eslint-disable-line no-console
}); });
serveUmdModule('react'); serveUmdModule('react');
@ -77,9 +76,10 @@ function routes(
serveUmdModule('@redux-devtools/app'); serveUmdModule('@redux-devtools/app');
app.get('/port.js', function (req, res) { app.get('/port.js', function (req, res) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
res.send(`reduxDevToolsPort = ${options.port}`); res.send(`reduxDevToolsPort = ${options.port}`);
}); });
app.get('/{*splat}', function (req, res) { app.get('*', function (req, res) {
res.sendFile( res.sendFile(
path.join( path.join(
path.dirname(fileURLToPath(import.meta.url)), path.dirname(fileURLToPath(import.meta.url)),
@ -93,10 +93,7 @@ function routes(
app.use(bodyParser.urlencoded({ limit: limit, extended: false })); app.use(bodyParser.urlencoded({ limit: limit, extended: false }));
app.post('/', function (req, res) { app.post('/', function (req, res) {
if (!req.body) { if (!req.body) return res.status(404).end();
res.status(404).end();
return;
}
switch (req.body.op) { switch (req.body.op) {
case 'get': case 'get':
store store
@ -105,7 +102,7 @@ function routes(
res.send(r || {}); res.send(r || {});
}) })
.catch(function (error) { .catch(function (error) {
console.error(error); console.error(error); // eslint-disable-line no-console
res.sendStatus(500); res.sendStatus(500);
}); });
break; break;
@ -116,7 +113,7 @@ function routes(
res.send(r); res.send(r);
}) })
.catch(function (error) { .catch(function (error) {
console.error(error); console.error(error); // eslint-disable-line no-console
res.sendStatus(500); res.sendStatus(500);
}); });
break; break;
@ -134,7 +131,7 @@ function routes(
}); });
}) })
.catch(function (error) { .catch(function (error) {
console.error(error); console.error(error); // eslint-disable-line no-console
res.status(500).send({}); res.status(500).send({});
}); });
} }

View File

@ -1,24 +1,5 @@
# Change Log # Change Log
## 4.1.1
### Patch Changes
- Updated dependencies [91f21b2]
- @redux-devtools/core@4.1.1
## 4.1.0
### Minor Changes
- 6830118: Add React 19 to peer deps
### Patch Changes
- Updated dependencies [6830118]
- react-dock@0.8.0
- @redux-devtools/core@4.1.0
## 4.0.1 ## 4.0.1
### Patch Changes ### Patch Changes

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/dock-monitor", "name": "@redux-devtools/dock-monitor",
"version": "4.1.1", "version": "4.0.1",
"description": "A resizable and movable dock for Redux DevTools monitors", "description": "A resizable and movable dock for Redux DevTools monitors",
"keywords": [ "keywords": [
"redux", "redux",
@ -41,30 +41,30 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.27.6", "@babel/runtime": "^7.25.4",
"parse-key": "^0.2.1", "parse-key": "^0.2.1",
"react-dock": "workspace:^" "react-dock": "^0.7.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.27.2", "@babel/cli": "^7.24.8",
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.27.5", "@babel/eslint-parser": "^7.25.1",
"@babel/plugin-transform-runtime": "^7.27.4", "@babel/plugin-transform-runtime": "^7.25.4",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "^4.0.0",
"@types/parse-key": "^0.2.2", "@types/parse-key": "^0.2.2",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"react": "^19.1.0", "react": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"typescript": "~5.8.3" "typescript": "~5.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "^4.0.0",
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.4 || ^17.0.0 || ^18.0.0",
"redux": "^3.4.0 || ^4.0.0 || ^5.0.0" "redux": "^3.4.0 || ^4.0.0 || ^5.0.0"
} }
} }

View File

@ -29,18 +29,19 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.27.6" "@babel/runtime": "^7.25.4",
"immutable": "^4.3.7"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.27.2", "@babel/cli": "^7.24.8",
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.27.5", "@babel/eslint-parser": "^7.25.1",
"@babel/plugin-transform-runtime": "^7.27.4", "@babel/plugin-transform-runtime": "^7.25.4",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"typescript": "~5.8.3" "typescript": "~5.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"redux": "^3.1.0 || ^4.0.0 || ^5.0.0" "redux": "^3.1.0 || ^4.0.0 || ^5.0.0"

View File

@ -1,3 +1,4 @@
import type Immutable from 'immutable';
import { compose } from 'redux'; import { compose } from 'redux';
import type { Action, ActionCreator, StoreEnhancer } from 'redux'; import type { Action, ActionCreator, StoreEnhancer } from 'redux';
@ -73,11 +74,11 @@ export interface EnhancerOptions {
* Just pass the Immutable library. It will support all ImmutableJS structures. You can even export them into a file and get them back. * Just pass the Immutable library. It will support all ImmutableJS structures. You can even export them into a file and get them back.
* The only exception is `Record` class, for which you should pass this in addition the references to your classes in `refs`. * The only exception is `Record` class, for which you should pass this in addition the references to your classes in `refs`.
*/ */
immutable?: unknown; immutable?: typeof Immutable;
/** /**
* ImmutableJS `Record` classes used to make possible restore its instances back when importing, persisting... * ImmutableJS `Record` classes used to make possible restore its instances back when importing, persisting...
*/ */
refs?: (new (data: any) => unknown)[]; refs?: Immutable.Record.Factory<any>[];
}; };
/** /**
* function which takes `action` object and id number as arguments, and should return `action` object back. * function which takes `action` object and id number as arguments, and should return `action` object back.

View File

@ -1,23 +1,5 @@
# Change Log # Change Log
## 4.1.1
### Patch Changes
- @redux-devtools/inspector-monitor@6.1.1
## 4.1.0
### Minor Changes
- 6830118: Add React 19 to peer deps
### Patch Changes
- Updated dependencies [6830118]
- @redux-devtools/inspector-monitor@7.0.0
- @redux-devtools/ui@1.4.0
## 4.0.0 ## 4.0.0
### Major Changes ### Major Changes

View File

@ -1,26 +1,5 @@
# test-demo # test-demo
## 0.1.17
### Patch Changes
- Updated dependencies [91f21b2]
- @redux-devtools/core@4.1.1
- @redux-devtools/dock-monitor@4.1.1
- @redux-devtools/inspector-monitor@6.1.1
- @redux-devtools/inspector-monitor-test-tab@4.1.1
## 0.1.16
### Patch Changes
- Updated dependencies [6830118]
- @redux-devtools/dock-monitor@5.0.0
- @redux-devtools/inspector-monitor-test-tab@5.0.0
- @redux-devtools/inspector-monitor@7.0.0
- @redux-devtools/ui@1.4.0
- @redux-devtools/core@4.1.0
## 0.1.15 ## 0.1.15
### Patch Changes ### Patch Changes

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"name": "test-demo", "name": "test-demo",
"version": "0.1.17", "version": "0.1.15",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"start": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack serve --open", "start": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack serve --open",
@ -10,44 +10,45 @@
"type-check": "tsc --noEmit" "type-check": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.14.0", "@redux-devtools/core": "^4.0.0",
"@redux-devtools/core": "workspace:^", "@redux-devtools/dock-monitor": "^4.0.0",
"@redux-devtools/dock-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "^6.0.0",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor-test-tab": "^4.0.0",
"@redux-devtools/inspector-monitor-test-tab": "workspace:^", "@redux-devtools/ui": "^1.3.0",
"@redux-devtools/ui": "workspace:^", "immutable": "^4.3.7",
"immutable": "^5.1.3",
"lodash.shuffle": "^4.2.0", "lodash.shuffle": "^4.2.0",
"react": "^19.1.0", "react": "^18.3.1",
"react-dom": "^19.1.0", "react-dom": "^18.3.1",
"react-is": "^19.1.0", "react-is": "^18.3.1",
"react-redux": "^9.2.0", "react-redux": "^9.1.2",
"react-router-dom": "^7.6.2", "react-router-dom": "^6.26.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-logger": "^3.0.6" "redux-logger": "^3.0.6",
"styled-components": "^5.3.11"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@types/lodash.shuffle": "^4.2.9", "@types/lodash.shuffle": "^4.2.9",
"@types/node": "^22.15.32", "@types/node": "^20.16.1",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^18.3.0",
"@types/redux-logger": "^3.0.13", "@types/redux-logger": "^3.0.13",
"@types/webpack-env": "^1.18.8", "@types/styled-components": "^5.1.34",
"babel-loader": "^10.0.0", "@types/webpack-env": "^1.18.5",
"babel-loader": "^9.1.3",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"css-loader": "^7.1.2", "css-loader": "^7.1.2",
"fork-ts-checker-webpack-plugin": "^9.1.0", "fork-ts-checker-webpack-plugin": "^9.0.2",
"html-webpack-plugin": "^5.6.3", "html-webpack-plugin": "^5.6.0",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.8.3", "typescript": "~5.5.4",
"webpack": "^5.99.9", "webpack": "^5.94.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.2.2" "webpack-dev-server": "^5.0.4"
} }
} }

View File

@ -70,7 +70,7 @@ interface Props
} }
function DemoApp(props: Props) { function DemoApp(props: Props) {
const timeout = useRef<number | undefined>(undefined); const timeout = useRef<number | undefined>();
const location = useLocation(); const location = useLocation();
const options = getOptions(location); const options = getOptions(location);

View File

@ -1,11 +1,4 @@
import { import Immutable from 'immutable';
fromJS,
Map as ImmutableMap,
List,
Set as ImmutableSet,
Stack,
Seq,
} from 'immutable';
import shuffle from 'lodash.shuffle'; import shuffle from 'lodash.shuffle';
import { combineReducers, Reducer } from 'redux'; import { combineReducers, Reducer } from 'redux';
@ -25,14 +18,17 @@ const NESTED = {
}, },
}; };
const IMMUTABLE_NESTED = fromJS(NESTED) as ImmutableMap<unknown, unknown>; const IMMUTABLE_NESTED = Immutable.fromJS(NESTED) as Immutable.Map<
unknown,
unknown
>;
const IMMUTABLE_MAP = ImmutableMap({ const IMMUTABLE_MAP = Immutable.Map({
map: ImmutableMap({ a: 1, b: 2, c: 3 }), map: Immutable.Map({ a: 1, b: 2, c: 3 }),
list: List(['a', 'b', 'c']), list: Immutable.List(['a', 'b', 'c']),
set: ImmutableSet(['a', 'b', 'c']), set: Immutable.Set(['a', 'b', 'c']),
stack: Stack(['a', 'b', 'c']), stack: Immutable.Stack(['a', 'b', 'c']),
seq: Seq([1, 2, 3, 4, 5, 6, 7, 8]), seq: Immutable.Seq([1, 2, 3, 4, 5, 6, 7, 8]),
}); });
const HUGE_ARRAY = Array.from({ length: 5000 }).map((_, key) => ({ const HUGE_ARRAY = Array.from({ length: 5000 }).map((_, key) => ({
@ -41,8 +37,7 @@ const HUGE_ARRAY = Array.from({ length: 5000 }).map((_, key) => ({
const HUGE_OBJECT = Array.from({ length: 5000 }).reduce( const HUGE_OBJECT = Array.from({ length: 5000 }).reduce(
(o: { [key: string]: string }, _, key) => ( (o: { [key: string]: string }, _, key) => (
(o[`key ${key}`] = `item ${key}`), (o[`key ${key}`] = `item ${key}`), o
o
), ),
{}, {},
); );

View File

@ -8,5 +8,5 @@ module.exports = {
'^.+\\.jsx?$': 'babel-jest', '^.+\\.jsx?$': 'babel-jest',
'^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }],
}, },
transformIgnorePatterns: ['node_modules/(?!.pnpm|color|lodash-es|nanoid)'], transformIgnorePatterns: ['node_modules/(?!.pnpm|lodash-es|nanoid)'],
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/inspector-monitor-test-tab", "name": "@redux-devtools/inspector-monitor-test-tab",
"version": "4.1.1", "version": "4.0.0",
"description": "Generate tests for redux devtools.", "description": "Generate tests for redux devtools.",
"keywords": [ "keywords": [
"redux", "redux",
@ -43,50 +43,50 @@
"prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.27.6", "@babel/runtime": "^7.25.4",
"@redux-devtools/ui": "workspace:^", "@redux-devtools/ui": "^1.3.1",
"es6template": "^1.0.5", "es6template": "^1.0.5",
"javascript-stringify": "^2.1.0", "javascript-stringify": "^2.1.0",
"jsan": "^3.1.14", "jsan": "^3.1.14",
"object-path": "^0.11.8", "object-path": "^0.11.8",
"react-icons": "^5.5.0", "react-icons": "^5.3.0",
"simple-diff": "^1.7.2" "simple-diff": "^1.7.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.27.2", "@babel/cli": "^7.24.8",
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.27.5", "@babel/eslint-parser": "^7.25.1",
"@babel/plugin-transform-runtime": "^7.27.4", "@babel/plugin-transform-runtime": "^7.25.4",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.14.0", "@redux-devtools/core": "^4.0.0",
"@redux-devtools/core": "workspace:^", "@redux-devtools/inspector-monitor": "^6.0.0",
"@redux-devtools/inspector-monitor": "workspace:^",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.3.0", "@testing-library/react": "^16.0.0",
"@types/es6template": "^1.0.5", "@types/es6template": "^1.0.5",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.12",
"@types/jsan": "^3.1.5", "@types/jsan": "^3.1.5",
"@types/object-path": "^0.11.4", "@types/object-path": "^0.11.4",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"jest": "^30.0.2", "jest": "^29.7.0",
"jest-environment-jsdom": "^30.0.2", "jest-environment-jsdom": "^29.7.0",
"react": "^19.1.0", "react": "^18.3.1",
"react-dom": "^19.1.0", "react-dom": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"ts-jest": "^29.4.0", "ts-jest": "^29.2.5",
"typescript": "~5.8.3" "typescript": "~5.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@emotion/styled": "^11.14.0", "@redux-devtools/inspector-monitor": "^6.0.0",
"@redux-devtools/inspector-monitor": "workspace:^", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/styled-components": "^5.1.34",
"react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.4 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0",
"redux": "^3.4.0 || ^4.0.0 || ^5.0.0" "redux": "^3.4.0 || ^4.0.0 || ^5.0.0",
"styled-components": "^5.3.11"
} }
} }

View File

@ -1,22 +1,5 @@
# Change Log # Change Log
## 4.1.1
### Patch Changes
- @redux-devtools/inspector-monitor@6.1.1
## 4.1.0
### Minor Changes
- 6830118: Add React 19 to peer deps
### Patch Changes
- Updated dependencies [6830118]
- @redux-devtools/inspector-monitor@7.0.0
## 4.0.1 ## 4.0.1
### Patch Changes ### Patch Changes

View File

@ -6,6 +6,6 @@ module.exports = {
'^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }],
}, },
transformIgnorePatterns: [ transformIgnorePatterns: [
'node_modules/(?!.pnpm|@babel/code-frame|@babel/highlight|@babel/helper-validator-identifier|chalk|color|lodash-es)', 'node_modules/(?!.pnpm|@babel/code-frame|@babel/highlight|@babel/helper-validator-identifier|chalk|lodash-es)',
], ],
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/inspector-monitor-trace-tab", "name": "@redux-devtools/inspector-monitor-trace-tab",
"version": "4.1.1", "version": "4.0.1",
"description": "Submonitor for Redux DevTools inspector to show stack traces.", "description": "Submonitor for Redux DevTools inspector to show stack traces.",
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-inspector-monitor-trace-tab", "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-inspector-monitor-trace-tab",
"license": "MIT", "license": "MIT",
@ -30,49 +30,50 @@
"prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test"
}, },
"dependencies": { "dependencies": {
"@babel/code-frame": "^8.0.0-beta.0", "@babel/code-frame": "^8.0.0-alpha.12",
"@babel/runtime": "^7.27.6", "@babel/runtime": "^7.25.4",
"@types/chrome": "^0.0.326", "@types/chrome": "^0.0.270",
"anser": "^2.3.2", "anser": "^2.1.1",
"html-entities": "^2.6.0", "html-entities": "^2.5.2",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"react-base16-styling": "workspace:^", "react-base16-styling": "^0.10.0",
"source-map": "^0.5.7" "source-map": "^0.5.7"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.27.2", "@babel/cli": "^7.24.8",
"@babel/core": "^7.27.4", "@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.27.5", "@babel/eslint-parser": "^7.25.1",
"@babel/plugin-transform-runtime": "^7.27.4", "@babel/plugin-transform-runtime": "^7.25.4",
"@babel/preset-env": "^7.27.2", "@babel/preset-env": "^7.25.4",
"@babel/preset-react": "^7.27.1", "@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.27.1", "@babel/preset-typescript": "^7.24.7",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "^4.0.0",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "^6.0.1",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.3.0", "@testing-library/react": "^16.0.0",
"@types/babel__code-frame": "^7.0.6", "@types/babel__code-frame": "^7.0.6",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.12",
"@types/node": "^22.15.32", "@types/node": "^20.16.1",
"@types/path-browserify": "^1.0.3", "@types/path-browserify": "^1.0.3",
"@types/react": "^19.1.8", "@types/react": "^18.3.4",
"@types/source-map": "0.5.2", "@types/source-map": "0.5.2",
"jest": "^30.0.2", "jest": "^29.7.0",
"jest-environment-jsdom": "^30.0.2", "jest-environment-jsdom": "^29.7.0",
"react": "^19.1.0", "react": "^18.3.1",
"react-dom": "^19.1.0", "react-dom": "^18.3.1",
"react-test-renderer": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"ts-jest": "^29.4.0", "ts-jest": "^29.2.5",
"typescript": "~5.8.3" "typescript": "~5.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.13.3",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "^6.0.0",
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^16.8.4 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0",
"redux": "^3.4.0 || ^4.0.0 || ^5.0.0" "redux": "^3.4.0 || ^4.0.0 || ^5.0.0"
} }
} }

Some files were not shown because too many files have changed in this diff Show More