Compare commits

..

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

185 changed files with 8350 additions and 8821 deletions

View File

@ -1,5 +0,0 @@
---
'@redux-devtools/cli': major
---
Require Node.js 20

View File

@ -11,9 +11,9 @@ jobs:
runs-on: 'ubuntu-22.04' runs-on: 'ubuntu-22.04'
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6 - uses: actions/setup-node@v4
with: with:
node-version: 'lts/*' node-version: 'lts/*'
cache: 'pnpm' cache: 'pnpm'

View File

@ -13,7 +13,7 @@ jobs:
runs-on: 'ubuntu-22.04' runs-on: 'ubuntu-22.04'
steps: steps:
- name: Checkout Repo - name: Checkout Repo
uses: actions/checkout@v6 uses: actions/checkout@v4
with: with:
# 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
@ -21,7 +21,7 @@ jobs:
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v6 uses: actions/setup-node@v4
with: with:
node-version: 'lts/*' node-version: 'lts/*'
cache: 'pnpm' cache: 'pnpm'
@ -40,19 +40,19 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Archive Chrome Extension - name: Archive Chrome Extension
uses: actions/upload-artifact@v6 uses: actions/upload-artifact@v4
with: with:
name: chrome name: chrome
path: extension/chrome/dist path: extension/chrome/dist
- name: Archive Edge Extension - name: Archive Edge Extension
uses: actions/upload-artifact@v6 uses: actions/upload-artifact@v4
with: with:
name: edge name: edge
path: extension/edge/dist path: extension/edge/dist
- name: Archive Firefox Extension - name: Archive Firefox Extension
uses: actions/upload-artifact@v6 uses: actions/upload-artifact@v4
with: with:
name: firefox name: firefox
path: extension/firefox/dist path: extension/firefox/dist

View File

@ -1,5 +1,4 @@
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js'; import eslint from '@eslint/js';
import eslintConfigPrettier from 'eslint-config-prettier'; import eslintConfigPrettier from 'eslint-config-prettier';
export default defineConfig([eslint.configs.recommended, eslintConfigPrettier]); export default [eslint.configs.recommended, eslintConfigPrettier];

View File

@ -1,11 +1,11 @@
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js'; import eslint from '@eslint/js';
import react from 'eslint-plugin-react'; import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks'; import { fixupPluginRules } from '@eslint/compat';
import eslintPluginReactHooks from 'eslint-plugin-react-hooks';
import jest from 'eslint-plugin-jest'; import jest from 'eslint-plugin-jest';
import eslintConfigPrettier from 'eslint-config-prettier'; import eslintConfigPrettier from 'eslint-config-prettier';
export default defineConfig([ export default [
{ {
files: ['test/**/*.js', 'test/**/*.jsx'], files: ['test/**/*.js', 'test/**/*.jsx'],
...eslint.configs.recommended, ...eslint.configs.recommended,
@ -24,7 +24,9 @@ export default defineConfig([
}, },
{ {
files: ['test/**/*.js', 'test/**/*.jsx'], files: ['test/**/*.js', 'test/**/*.jsx'],
...reactHooks.configs.flat.recommended, plugins: {
'react-hooks': fixupPluginRules(eslintPluginReactHooks),
},
}, },
{ {
files: ['test/**/*.js', 'test/**/*.jsx'], files: ['test/**/*.js', 'test/**/*.jsx'],
@ -38,4 +40,4 @@ export default defineConfig([
files: ['test/**/*.js', 'test/**/*.jsx'], files: ['test/**/*.js', 'test/**/*.jsx'],
...eslintConfigPrettier, ...eslintConfigPrettier,
}, },
]); ];

View File

@ -1,57 +1,55 @@
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js'; import eslint from '@eslint/js';
import tseslint from 'typescript-eslint'; import tseslint from 'typescript-eslint';
import eslintConfigPrettier from 'eslint-config-prettier'; import eslintConfigPrettier from 'eslint-config-prettier';
export default (tsconfigRootDir, files = ['**/*.ts'], project = true) => export default (tsconfigRootDir, files = ['**/*.ts'], project = true) => [
defineConfig([ {
{ files,
files, ...eslint.configs.recommended,
...eslint.configs.recommended, },
}, ...tseslint.configs.recommendedTypeChecked.map((config) => ({
...tseslint.configs.recommendedTypeChecked.map((config) => ({ files,
files, ...config,
...config, })),
})), ...tseslint.configs.stylisticTypeChecked.map((config) => ({
...tseslint.configs.stylisticTypeChecked.map((config) => ({ files,
files, ...config,
...config, })),
})), {
{ files,
files, languageOptions: {
languageOptions: { parserOptions: {
parserOptions: { project,
project, tsconfigRootDir,
tsconfigRootDir,
},
}, },
}, },
{ },
files, {
...eslintConfigPrettier, files,
...eslintConfigPrettier,
},
{
files,
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
}, },
{ },
files, ];
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
},
},
]);

View File

@ -1,66 +1,64 @@
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js'; import eslint from '@eslint/js';
import tseslint from 'typescript-eslint'; import tseslint from 'typescript-eslint';
import jest from 'eslint-plugin-jest'; import jest from 'eslint-plugin-jest';
import eslintConfigPrettier from 'eslint-config-prettier'; import eslintConfigPrettier from 'eslint-config-prettier';
export default (tsconfigRootDir) => export default (tsconfigRootDir) => [
defineConfig([ {
{ files: ['test/**/*.ts'],
files: ['test/**/*.ts'], ...eslint.configs.recommended,
...eslint.configs.recommended, },
}, ...tseslint.configs.recommendedTypeChecked.map((config) => ({
...tseslint.configs.recommendedTypeChecked.map((config) => ({ files: ['test/**/*.ts'],
files: ['test/**/*.ts'], ...config,
...config, })),
})), ...tseslint.configs.stylisticTypeChecked.map((config) => ({
...tseslint.configs.stylisticTypeChecked.map((config) => ({ files: ['test/**/*.ts'],
files: ['test/**/*.ts'], ...config,
...config, })),
})), {
{ files: ['test/**/*.ts'],
files: ['test/**/*.ts'], languageOptions: {
languageOptions: { parserOptions: {
parserOptions: { project: ['./tsconfig.test.json'],
project: ['./tsconfig.test.json'], tsconfigRootDir,
tsconfigRootDir,
},
}, },
}, },
{ },
files: ['test/**/*.ts'], {
...jest.configs['flat/recommended'], files: ['test/**/*.ts'],
...jest.configs['flat/recommended'],
},
{
files: ['test/**/*.ts'],
...jest.configs['jest/style'],
},
{
files: ['test/**/*.ts'],
...eslintConfigPrettier,
},
{
files: ['test/**/*.ts'],
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
}, },
{ },
files: ['test/**/*.ts'], ];
...jest.configs['jest/style'],
},
{
files: ['test/**/*.ts'],
...eslintConfigPrettier,
},
{
files: ['test/**/*.ts'],
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
},
},
]);

View File

@ -1,88 +1,89 @@
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js'; import eslint from '@eslint/js';
import tseslint from 'typescript-eslint'; import tseslint from 'typescript-eslint';
import react from 'eslint-plugin-react'; import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks'; import { fixupPluginRules } from '@eslint/compat';
import eslintPluginReactHooks from 'eslint-plugin-react-hooks';
import eslintConfigPrettier from 'eslint-config-prettier'; import eslintConfigPrettier from 'eslint-config-prettier';
export default ( export default (
tsconfigRootDir, tsconfigRootDir,
files = ['**/*.ts', '**/*.tsx'], files = ['**/*.ts', '**/*.tsx'],
project = true, project = true,
) => ) => [
defineConfig([ {
{ files,
files, ...eslint.configs.recommended,
...eslint.configs.recommended, },
}, ...tseslint.configs.recommendedTypeChecked.map((config) => ({
...tseslint.configs.recommendedTypeChecked.map((config) => ({ files,
files, ...config,
...config, })),
})), ...tseslint.configs.stylisticTypeChecked.map((config) => ({
...tseslint.configs.stylisticTypeChecked.map((config) => ({ files,
files, ...config,
...config, })),
})), {
{ files,
files, languageOptions: {
languageOptions: { parserOptions: {
parserOptions: { project,
project, tsconfigRootDir,
tsconfigRootDir,
},
}, },
}, },
{ },
files, {
...react.configs.flat.recommended, files,
}, ...react.configs.flat.recommended,
{ },
files, {
settings: { files,
react: { settings: {
version: 'detect', react: {
}, version: 'detect',
}, },
}, },
{ },
files, {
...reactHooks.configs.flat.recommended, files,
plugins: {
'react-hooks': fixupPluginRules(eslintPluginReactHooks),
}, },
{ },
files, {
...eslintConfigPrettier, files,
}, ...eslintConfigPrettier,
{ },
files, {
rules: { files,
'@typescript-eslint/no-unsafe-return': 'off', rules: {
'@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off', '@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-misused-promises': [ '@typescript-eslint/no-unsafe-member-access': 'off',
'error', '@typescript-eslint/no-misused-promises': [
{ 'error',
checksVoidReturn: { {
attributes: false, checksVoidReturn: {
}, attributes: false,
}, },
], },
'@typescript-eslint/prefer-optional-chain': 'off', ],
'@typescript-eslint/no-base-to-string': 'off', '@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off', '@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off', '@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/consistent-type-definitions': 'off', '@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/no-unused-vars': 'off', '@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/prefer-for-of': 'off', '@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off', '@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/class-literal-property-style': 'off', '@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off', '@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off', '@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off', '@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/array-type': 'off', '@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/prefer-function-type': 'off', '@typescript-eslint/array-type': 'off',
'react/prop-types': 'off', '@typescript-eslint/prefer-function-type': 'off',
}, 'react/prop-types': 'off',
}, },
]); },
];

View File

@ -1,84 +1,85 @@
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js'; import eslint from '@eslint/js';
import tseslint from 'typescript-eslint'; import tseslint from 'typescript-eslint';
import react from 'eslint-plugin-react'; import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks'; import { fixupPluginRules } from '@eslint/compat';
import eslintPluginReactHooks from 'eslint-plugin-react-hooks';
import jest from 'eslint-plugin-jest'; import jest from 'eslint-plugin-jest';
import eslintConfigPrettier from 'eslint-config-prettier'; import eslintConfigPrettier from 'eslint-config-prettier';
export default (tsconfigRootDir) => export default (tsconfigRootDir) => [
defineConfig([ {
{ files: ['test/**/*.ts', 'test/**/*.tsx'],
files: ['test/**/*.ts', 'test/**/*.tsx'], ...eslint.configs.recommended,
...eslint.configs.recommended, },
}, ...tseslint.configs.recommendedTypeChecked.map((config) => ({
...tseslint.configs.recommendedTypeChecked.map((config) => ({ files: ['test/**/*.ts', 'test/**/*.tsx'],
files: ['test/**/*.ts', 'test/**/*.tsx'], ...config,
...config, })),
})), ...tseslint.configs.stylisticTypeChecked.map((config) => ({
...tseslint.configs.stylisticTypeChecked.map((config) => ({ files: ['test/**/*.ts', 'test/**/*.tsx'],
files: ['test/**/*.ts', 'test/**/*.tsx'], ...config,
...config, })),
})), {
{ files: ['test/**/*.ts', 'test/**/*.tsx'],
files: ['test/**/*.ts', 'test/**/*.tsx'], languageOptions: {
languageOptions: { parserOptions: {
parserOptions: { project: ['./tsconfig.test.json'],
project: ['./tsconfig.test.json'], tsconfigRootDir,
tsconfigRootDir,
},
}, },
}, },
{ },
files: ['test/**/*.ts', 'test/**/*.tsx'], {
...react.configs.flat.recommended, files: ['test/**/*.ts', 'test/**/*.tsx'],
}, ...react.configs.flat.recommended,
{ },
files: ['test/**/*.ts', 'test/**/*.tsx'], {
settings: { files: ['test/**/*.ts', 'test/**/*.tsx'],
react: { settings: {
version: 'detect', react: {
}, version: 'detect',
}, },
}, },
{ },
files: ['test/**/*.ts', 'test/**/*.tsx'], {
...reactHooks.configs.flat.recommended, files: ['test/**/*.ts', 'test/**/*.tsx'],
plugins: {
'react-hooks': fixupPluginRules(eslintPluginReactHooks),
}, },
{ },
files: ['test/**/*.ts', 'test/**/*.tsx'], {
...jest.configs['flat/recommended'], files: ['test/**/*.ts', 'test/**/*.tsx'],
...jest.configs['flat/recommended'],
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
...jest.configs['jest/style'],
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
...eslintConfigPrettier,
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
}, },
{ },
files: ['test/**/*.ts', 'test/**/*.tsx'], ];
...jest.configs['jest/style'],
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
...eslintConfigPrettier,
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
},
},
]);

View File

@ -1,14 +1,5 @@
# remotedev-redux-devtools-extension # remotedev-redux-devtools-extension
## 3.2.11
### Patch Changes
- Updated dependencies [6163276]
- @redux-devtools/app@7.0.0
- @redux-devtools/slider-monitor@6.0.0
- @redux-devtools/ui@2.0.0
## 3.2.10 ## 3.2.10
### Patch Changes ### Patch Changes

View File

@ -57,7 +57,7 @@ const composeEnhancers =
compose; compose;
``` ```
> For TypeScript use [`redux-devtools-extension` npm package](#13-use-redux-devtoolsextension-package-from-npm), which contains all the definitions, or just use `(window as any)` (see [Recipes](docs/Recipes.md#using-in-a-typescript-project) for an example). > For TypeScript use [`redux-devtools-extension` npm package](#13-use-redux-devtoolsextension-package-from-npm), which contains all the definitions, or just use `(window as any)` (see [Recipes](/docs/Recipes.md#using-in-a-typescript-project) for an example).
```js ```js
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
@ -228,7 +228,7 @@ See [integrations](docs/Integrations.md) and [the blog post](https://medium.com/
- [Methods (advanced API)](docs/API/Methods.md) - [Methods (advanced API)](docs/API/Methods.md)
- [FAQ](docs/FAQ.md) - [FAQ](docs/FAQ.md)
- Features - Features
- [Trace actions calls](docs/Features/Trace.md) - [Trace actions calls](/docs/Features/Trace.md)
- [Troubleshooting](docs/Troubleshooting.md) - [Troubleshooting](docs/Troubleshooting.md)
- [Articles](docs/Articles.md) - [Articles](docs/Articles.md)
- [Videos](docs/Videos.md) - [Videos](docs/Videos.md)

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

@ -6,6 +6,6 @@ module.exports = {
'\\.css$': '<rootDir>/test/__mocks__/styleMock.js', '\\.css$': '<rootDir>/test/__mocks__/styleMock.js',
}, },
transformIgnorePatterns: [ transformIgnorePatterns: [
'node_modules/(?!.pnpm|@babel/code-frame|@babel/highlight|@babel/helper-validator-identifier|@x0k/json-schema-merge|chalk|color|d3|dateformat|delaunator|internmap|jsondiffpatch|js-tokens|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.11", "version": "3.2.10",
"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,7 +16,7 @@
"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", "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",
@ -25,7 +25,6 @@
}, },
"dependencies": { "dependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@redux-devtools/app": "workspace:^", "@redux-devtools/app": "workspace:^",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@redux-devtools/instrument": "workspace:^", "@redux-devtools/instrument": "workspace:^",
@ -33,48 +32,50 @@
"@redux-devtools/slider-monitor": "workspace:^", "@redux-devtools/slider-monitor": "workspace:^",
"@redux-devtools/ui": "workspace:^", "@redux-devtools/ui": "workspace:^",
"@redux-devtools/utils": "workspace:^", "@redux-devtools/utils": "workspace:^",
"@reduxjs/toolkit": "^2.11.2", "@reduxjs/toolkit": "^2.6.0",
"@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.22", "lodash-es": "^4.17.21",
"react": "^19.2.3", "react": "^18.3.1",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-is": "^19.2.3", "react-is": "^18.3.1",
"react-json-tree": "workspace:^", "react-json-tree": "workspace:^",
"react-redux": "^9.2.0", "react-redux": "^9.2.0",
"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.28.6", "@babel/core": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@babel/register": "^7.28.6", "@babel/register": "^7.25.9",
"@testing-library/dom": "^10.4.1", "@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.9.1", "@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.1", "@testing-library/react": "^16.2.0",
"@types/chrome": "^0.1.33", "@types/chrome": "^0.0.308",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^18.3.5",
"@types/styled-components": "^5.1.34",
"chromedriver": "^126.0.5", "chromedriver": "^126.0.5",
"cross-env": "^10.1.0", "cross-env": "^7.0.3",
"electron": "^31.7.7", "electron": "^31.7.7",
"esbuild": "^0.27.2", "esbuild": "^0.25.0",
"globals": "^17.0.0", "globals": "^15.15.0",
"immutable": "^5.1.4", "immutable": "^5.0.3",
"jest": "^30.2.0", "jest": "^29.7.0",
"jest-environment-jsdom": "^30.2.0", "jest-environment-jsdom": "^29.7.0",
"pug": "^3.0.3", "pug": "^3.0.3",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"selenium-webdriver": "^4.39.0", "selenium-webdriver": "^4.29.0",
"sinon-chrome": "^3.0.1", "sinon-chrome": "^3.0.1",
"ts-jest": "^29.4.6", "ts-jest": "^29.2.6",
"typescript": "~5.9.3", "typescript": "~5.8.2",
"webpack": "^5.104.1", "webpack": "^5.98.0",
"webpack-cli": "^6.0.1" "webpack-cli": "^6.0.1"
} }
} }

View File

@ -6,11 +6,7 @@ export function getReport(
tabId: string | number, tabId: string | number,
instanceId: number, instanceId: number,
) { ) {
chrome.storage.local.get<{ chrome.storage.local.get(['s:hostname', 's:port', 's:secure'], (options) => {
's:hostname': string | undefined;
's:port': string | undefined;
's:secure': string | undefined;
}>(['s:hostname', 's:port', 's:secure'], (options) => {
if (!options['s:hostname'] || !options['s:port']) return; if (!options['s:hostname'] || !options['s:port']) return;
const url = `${options['s:secure'] ? 'https' : 'http'}://${ const url = `${options['s:secure'] ? 'https' : 'http'}://${
options['s:hostname'] options['s:hostname']

View File

@ -472,7 +472,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'
@ -628,7 +628,7 @@ 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');
}); });

View File

@ -75,7 +75,7 @@ const migrateOldOptions = (oldOptions: OldOrNewOptions): Options => ({
export const getOptions = (callback: (options: Options) => void) => { export const getOptions = (callback: (options: Options) => void) => {
if (options) callback(options); if (options) callback(options);
else { else {
chrome.storage.sync.get<OldOrNewOptions>( chrome.storage.sync.get(
{ {
useEditor: 0, useEditor: 0,
editor: '', editor: '',
@ -92,7 +92,7 @@ export const getOptions = (callback: (options: Options) => void) => {
showContextMenus: true, showContextMenus: true,
}, },
function (items) { function (items) {
options = migrateOldOptions(items); options = migrateOldOptions(items as OldOrNewOptions);
callback(options); callback(options);
}, },
); );

View File

@ -1,18 +1,19 @@
{ {
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@changesets/cli": "^2.29.8", "@changesets/cli": "^2.28.1",
"@eslint/js": "^9.39.2", "@eslint/compat": "^1.2.7",
"eslint": "^9.39.2", "@eslint/js": "^9.21.0",
"eslint-config-prettier": "^10.1.8", "eslint": "^9.21.0",
"eslint-plugin-jest": "^29.12.1", "eslint-config-prettier": "^10.0.2",
"eslint-plugin-react": "^7.37.5", "eslint-plugin-jest": "^28.11.0",
"eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-react": "^7.37.4",
"jest": "^30.2.0", "eslint-plugin-react-hooks": "^4.6.2",
"prettier": "3.8.0", "jest": "^29.7.0",
"typescript": "~5.9.3", "prettier": "3.5.3",
"typescript-eslint": "^8.53.0" "typescript": "~5.8.2",
"typescript-eslint": "^8.26.0"
}, },
"scripts": { "scripts": {
"format": "prettier --write .", "format": "prettier --write .",
@ -23,5 +24,5 @@
"clean:all": "pnpm --recursive run clean", "clean:all": "pnpm --recursive run clean",
"release": "pnpm build:all && pnpm publish -r" "release": "pnpm build:all && pnpm publish -r"
}, },
"packageManager": "pnpm@10.28.0" "packageManager": "pnpm@9.15.6"
} }

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

@ -29,18 +29,18 @@
"map2tree": "workspace:^" "map2tree": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"cross-env": "^10.1.0", "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.5", "html-webpack-plugin": "^5.6.3",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.9.3", "typescript": "~5.8.2",
"webpack": "^5.104.1", "webpack": "^5.98.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.3" "webpack-dev-server": "^5.2.0"
} }
} }

View File

@ -42,11 +42,11 @@
"d3tooltip": "workspace:^", "d3tooltip": "workspace:^",
"deepmerge": "^4.3.1", "deepmerge": "^4.3.1",
"map2tree": "workspace:^", "map2tree": "workspace:^",
"ramda": "^0.32.0" "ramda": "^0.30.1"
}, },
"devDependencies": { "devDependencies": {
"@types/ramda": "^0.31.1", "@types/ramda": "^0.30.2",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"typescript": "~5.9.3" "typescript": "~5.8.2"
} }
} }

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

@ -35,8 +35,8 @@
"devDependencies": { "devDependencies": {
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",
"d3": "^7.9.0", "d3": "^7.9.0",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"@types/d3": "^7.4.3", "@types/d3": "^7.4.3",

View File

@ -37,15 +37,15 @@
"prepublish": "pnpm run lint && pnpm run test" "prepublish": "pnpm run lint && pnpm run test"
}, },
"dependencies": { "dependencies": {
"lodash-es": "^4.17.22" "lodash-es": "^4.17.21"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^30.0.0", "@types/jest": "^29.5.14",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"immutable": "^5.1.4", "immutable": "^5.0.3",
"jest": "^30.2.0", "jest": "^29.7.0",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"ts-jest": "^29.4.6", "ts-jest": "^29.2.6",
"typescript": "~5.9.3" "typescript": "~5.8.2"
} }
} }

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.23", "@types/lodash": "^4.17.16",
"color": "^5.0.3", "color": "^4.2.3",
"csstype": "^3.2.3", "csstype": "^3.1.3",
"lodash-es": "^4.17.22" "lodash-es": "^4.17.21"
}, },
"devDependencies": { "devDependencies": {
"@types/color": "^4.2.0", "@types/color": "^4.2.0",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.14",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"jest": "^30.2.0", "jest": "^29.7.0",
"jest-environment-jsdom": "^30.2.0", "jest-environment-jsdom": "^29.7.0",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"ts-jest": "^29.4.6", "ts-jest": "^29.2.6",
"typescript": "~5.9.3" "typescript": "~5.8.2"
} }
} }

View File

@ -10,30 +10,31 @@
"type-check": "tsc --noEmit" "type-check": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"@emotion/styled": "^11.14.1", "react": "^18.3.1",
"react": "^19.2.3", "react-bootstrap": "^2.10.9",
"react-bootstrap": "^2.10.10",
"react-dock": "workspace:^", "react-dock": "workspace:^",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-is": "^19.2.3" "react-is": "^18.3.1",
"styled-components": "^5.3.11"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^18.3.5",
"@types/styled-components": "^5.1.34",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"cross-env": "^10.1.0", "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.5", "html-webpack-plugin": "^5.6.3",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.9.3", "typescript": "~5.8.2",
"webpack": "^5.104.1", "webpack": "^5.98.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.3" "webpack-dev-server": "^5.2.0"
} }
} }

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

@ -29,20 +29,27 @@
"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.22" "lodash-es": "^4.17.21"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^19.2.8", "@types/jest": "^29.5.14",
"react": "^19.2.3", "@types/react": "^18.3.18",
"rimraf": "^6.1.2", "@types/react-test-renderer": "^18.3.1",
"typescript": "~5.9.3" "jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"react": "^18.3.1",
"react-test-renderer": "^18.3.1",
"rimraf": "^6.0.1",
"ts-jest": "^29.2.6",
"typescript": "~5.8.2"
}, },
"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 || ^19.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

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

@ -19,28 +19,28 @@
"type-check": "tsc --noEmit" "type-check": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"immutable": "^5.1.4", "immutable": "^5.0.3",
"react": "^19.2.3", "react": "^18.3.1",
"react-base16-styling": "workspace:^", "react-base16-styling": "workspace:^",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"react-json-tree": "workspace:^" "react-json-tree": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^18.3.5",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"cross-env": "^10.1.0", "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.5", "html-webpack-plugin": "^5.6.3",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.9.3", "typescript": "~5.8.2",
"webpack": "^5.104.1", "webpack": "^5.98.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.3" "webpack-dev-server": "^5.2.0"
} }
} }

View File

@ -40,17 +40,19 @@
"prepublish": "pnpm run lint && pnpm run test" "prepublish": "pnpm run lint && pnpm run test"
}, },
"dependencies": { "dependencies": {
"@types/lodash": "^4.17.23", "@types/lodash": "^4.17.16",
"react-base16-styling": "workspace:^" "react-base16-styling": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^30.0.0", "@types/jest": "^29.5.14",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"jest": "^30.2.0", "@types/react-test-renderer": "^18.3.1",
"react": "^19.2.3", "jest": "^29.7.0",
"rimraf": "^6.1.2", "react": "^18.3.1",
"ts-jest": "^29.4.6", "react-test-renderer": "^18.3.1",
"typescript": "~5.9.3" "rimraf": "^6.0.1",
"ts-jest": "^29.2.6",
"typescript": "~5.8.2"
}, },
"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 || ^19.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,21 +1,5 @@
# @redux-devtools/app-core # @redux-devtools/app-core
## 2.0.0
### Major Changes
- 6163276: Replace styled-components with Emotion
### Patch Changes
- Updated dependencies [6163276]
- Updated dependencies [20883e5]
- @redux-devtools/inspector-monitor-test-tab@5.0.0
- @redux-devtools/rtk-query-monitor@6.0.0
- @redux-devtools/slider-monitor@6.0.0
- @redux-devtools/ui@2.0.0
- @redux-devtools/inspector-monitor@6.1.2
## 1.1.2 ## 1.1.2
### Patch Changes ### Patch 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|@x0k/json-schema-merge|chalk|color|d3|dateformat|delaunator|internmap|jsondiffpatch|js-tokens|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": "2.0.0", "version": "1.1.2",
"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,7 +35,7 @@
"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.28.6", "@babel/runtime": "^7.26.9",
"@redux-devtools/chart-monitor": "workspace:^", "@redux-devtools/chart-monitor": "workspace:^",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "workspace:^",
@ -48,54 +48,56 @@
"d3-state-visualizer": "workspace:^", "d3-state-visualizer": "workspace:^",
"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.5.0",
"react-is": "^19.2.3" "react-is": "^18.3.1"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1", "@reduxjs/toolkit": "^2.6.0",
"@reduxjs/toolkit": "^2.11.2", "@rjsf/core": "^5.24.3",
"@rjsf/core": "^6.2.4", "@testing-library/dom": "^10.4.0",
"@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.6.3",
"@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.2.0",
"@testing-library/react": "^16.3.1", "@types/jest": "^29.5.14",
"@types/jest": "^30.0.0",
"@types/jsan": "^3.1.5", "@types/jsan": "^3.1.5",
"@types/json-schema": "^7.0.15", "@types/json-schema": "^7.0.15",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^18.3.5",
"cross-env": "^10.1.0", "@types/styled-components": "^5.1.34",
"esbuild": "^0.27.2", "cross-env": "^7.0.3",
"jest": "^30.2.0", "esbuild": "^0.25.0",
"jest-environment-jsdom": "^30.2.0", "jest": "^29.7.0",
"react": "^19.2.3", "jest-environment-jsdom": "^29.7.0",
"react-dom": "^19.2.3", "react": "^18.3.1",
"react-dom": "^18.3.1",
"react-redux": "^9.2.0", "react-redux": "^9.2.0",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"ts-jest": "^29.4.6", "styled-components": "^5.3.11",
"ts-jest": "^29.2.6",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@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 || ^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 || ^19.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 || ^19.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,17 +1,5 @@
# Change Log # Change Log
## 7.0.0
### Major Changes
- 6163276: Replace styled-components with Emotion
### Patch Changes
- Updated dependencies [6163276]
- @redux-devtools/app-core@2.0.0
- @redux-devtools/ui@2.0.0
## 6.2.2 ## 6.2.2
### Patch Changes ### Patch Changes

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/app", "name": "@redux-devtools/app",
"version": "7.0.0", "version": "6.2.2",
"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": {
@ -46,52 +46,54 @@
"react-redux": "^9.2.0", "react-redux": "^9.2.0",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"socketcluster-client": "^20.0.1" "socketcluster-client": "^19.2.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1", "@reduxjs/toolkit": "^2.6.0",
"@reduxjs/toolkit": "^2.11.2", "@rjsf/core": "^5.24.3",
"@rjsf/core": "^6.2.4",
"@types/jsan": "^3.1.5", "@types/jsan": "^3.1.5",
"@types/json-schema": "^7.0.15", "@types/json-schema": "^7.0.15",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^18.3.5",
"@types/socketcluster-client": "^20.0.0", "@types/socketcluster-client": "^19.1.0",
"@types/styled-components": "^5.1.34",
"@types/webpack-env": "^1.18.8", "@types/webpack-env": "^1.18.8",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"cross-env": "^10.1.0", "cross-env": "^7.0.3",
"css-loader": "^7.1.2", "css-loader": "^7.1.2",
"esbuild": "^0.27.2", "esbuild": "^0.25.0",
"fork-ts-checker-webpack-plugin": "^9.1.0", "fork-ts-checker-webpack-plugin": "^9.0.2",
"globals": "^17.0.0", "globals": "^15.15.0",
"html-loader": "^5.1.0", "html-loader": "^5.1.0",
"html-webpack-plugin": "^5.6.5", "html-webpack-plugin": "^5.6.3",
"react": "^19.2.3", "react": "^18.3.1",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"ts-jest": "^29.4.6", "styled-components": "^5.3.11",
"ts-jest": "^29.2.6",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.9.3", "typescript": "~5.8.2",
"webpack": "^5.104.1", "webpack": "^5.98.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.3" "webpack-dev-server": "^5.2.0"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@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 || ^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 || ^19.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 || ^19.0.0",
"styled-components": "^5.3.11"
} }
} }

View File

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

@ -39,25 +39,25 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.26.9",
"d3-state-visualizer": "workspace:^", "d3-state-visualizer": "workspace:^",
"deepmerge": "^4.3.1", "deepmerge": "^4.3.1",
"react-base16-styling": "workspace:^" "react-base16-styling": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"react": "^19.2.3", "react": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",

View File

@ -13,7 +13,8 @@ const wrapperStyle = {
}; };
export interface Props<S, A extends Action<string>> export interface Props<S, A extends Action<string>>
extends LiftedState<S, A, ChartMonitorState>, Options { extends LiftedState<S, A, ChartMonitorState>,
Options {
dispatch: Dispatch<LiftedAction<S, A, ChartMonitorState>>; dispatch: Dispatch<LiftedAction<S, A, ChartMonitorState>>;
preserveScrollTop: boolean; preserveScrollTop: boolean;
select: (state: S) => unknown; select: (state: S) => unknown;

View File

@ -41,7 +41,8 @@ function invertColors(theme: Base16Theme) {
} }
export interface ChartMonitorProps<S, A extends Action<string>> export interface ChartMonitorProps<S, A extends Action<string>>
extends LiftedState<S, A, ChartMonitorState>, Options { extends LiftedState<S, A, ChartMonitorState>,
Options {
dispatch: Dispatch<LiftedAction<S, A, ChartMonitorState>>; dispatch: Dispatch<LiftedAction<S, A, ChartMonitorState>>;
preserveScrollTop: boolean; preserveScrollTop: boolean;
select: (state: S) => unknown; select: (state: S) => unknown;

View File

@ -1,12 +1,5 @@
# Change Log # Change Log
## 4.0.4
### Patch Changes
- Updated dependencies [6163276]
- @redux-devtools/app@7.0.0
## 4.0.3 ## 4.0.3
### Patch Changes ### Patch Changes

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/cli", "name": "@redux-devtools/cli",
"version": "4.0.4", "version": "4.0.3",
"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": {
@ -38,59 +38,59 @@
"prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test"
}, },
"engines": { "engines": {
"node": ">=20" "node": ">= 18.12.0"
}, },
"dependencies": { "dependencies": {
"@apollo/server": "^5.2.0", "@apollo/server": "^4.11.3",
"@as-integrations/express5": "^1.1.2",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@redux-devtools/app": "workspace:^", "@redux-devtools/app": "workspace:^",
"@reduxjs/toolkit": "^2.11.2", "@reduxjs/toolkit": "^2.6.0",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"body-parser": "^2.2.2", "body-parser": "^1.20.3",
"chalk": "^5.6.2", "chalk": "^5.4.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"cross-spawn": "^7.0.6", "cross-spawn": "^7.0.6",
"electron": "^31.7.7", "electron": "^31.7.7",
"express": "^5.2.1", "express": "^4.21.2",
"get-port": "^7.1.0", "get-port": "^7.1.0",
"graphql": "^16.12.0", "graphql": "^16.10.0",
"knex": "^3.1.0", "knex": "^3.1.0",
"lodash-es": "^4.17.22", "lodash-es": "^4.17.21",
"minimist": "^1.2.8", "minimist": "^1.2.8",
"morgan": "^1.10.1", "morgan": "^1.10.0",
"open": "^11.0.0", "open": "^10.1.0",
"react": "^19.2.3", "react": "^18.3.1",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"react-is": "^19.2.3", "react-is": "^18.3.1",
"semver": "^7.7.3", "semver": "^7.7.1",
"socketcluster-server": "^20.0.0", "socketcluster-server": "^19.1.1",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"uuid": "^13.0.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.6", "@types/express": "^4.17.21",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.14",
"@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": "^24.10.9", "@types/node": "^22.13.9",
"@types/semver": "^7.7.1", "@types/semver": "^7.5.8",
"@types/socketcluster-client": "^20.0.0", "@types/socketcluster-client": "^19.1.0",
"@types/socketcluster-server": "^20.0.0", "@types/socketcluster-server": "^19.0.1",
"@types/supertest": "^6.0.3", "@types/styled-components": "^5.1.34",
"@types/uuid": "^11.0.0", "@types/supertest": "^6.0.2",
"globals": "^17.0.0", "@types/uuid": "^10.0.0",
"jest": "^30.2.0", "globals": "^15.15.0",
"jest": "^29.7.0",
"ncp": "^2.0.0", "ncp": "^2.0.0",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"socketcluster-client": "^20.0.1", "socketcluster-client": "^19.2.3",
"supertest": "^7.2.2", "supertest": "^7.0.0",
"ts-jest": "^29.4.6", "ts-jest": "^29.2.6",
"typescript": "~5.9.3" "typescript": "~5.8.2"
} }
} }

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

@ -9,7 +9,7 @@ import bodyParser from 'body-parser';
import cors from 'cors'; import cors from 'cors';
import { AGServer } from 'socketcluster-server'; import { AGServer } from 'socketcluster-server';
import { ApolloServer } from '@apollo/server'; import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@as-integrations/express5'; import { expressMiddleware } from '@apollo/server/express4';
import type { AddData, ReportBaseFields, Store } from './store.js'; import type { AddData, ReportBaseFields, Store } from './store.js';
import { resolvers, schema } from './api/schema.js'; import { resolvers, schema } from './api/schema.js';
@ -68,7 +68,7 @@ function routes(
); );
}) })
.catch((error) => { .catch((error) => {
console.error(error); console.error(error); // eslint-disable-line no-console
}); });
serveUmdModule('react'); serveUmdModule('react');
@ -76,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)),
@ -92,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
@ -104,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;
@ -115,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;
@ -133,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

@ -41,25 +41,25 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.26.9",
"parse-key": "^0.2.1", "parse-key": "^0.2.1",
"react-dock": "workspace:^" "react-dock": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@types/parse-key": "^0.2.2", "@types/parse-key": "^0.2.2",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"react": "^19.2.3", "react": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",

View File

@ -44,10 +44,8 @@ interface DefaultProps {
fluid: boolean; fluid: boolean;
} }
export interface DockMonitorProps< export interface DockMonitorProps<S, A extends Action<string>>
S, extends LiftedState<S, A, DockMonitorState> {
A extends Action<string>,
> extends LiftedState<S, A, DockMonitorState> {
defaultPosition: 'left' | 'top' | 'right' | 'bottom'; defaultPosition: 'left' | 'top' | 'right' | 'bottom';
defaultIsVisible: boolean; defaultIsVisible: boolean;
defaultSize: number; defaultSize: number;

View File

@ -29,18 +29,18 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6" "@babel/runtime": "^7.26.9"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"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,18 +1,5 @@
# Change Log # Change Log
## 5.0.0
### Major Changes
- 6163276: Replace styled-components with Emotion
### Patch Changes
- Updated dependencies [6163276]
- Updated dependencies [20883e5]
- @redux-devtools/ui@2.0.0
- @redux-devtools/inspector-monitor@6.1.2
## 4.1.1 ## 4.1.1
### Patch Changes ### Patch Changes

View File

@ -1,15 +1,5 @@
# test-demo # test-demo
## 0.1.18
### Patch Changes
- Updated dependencies [6163276]
- Updated dependencies [20883e5]
- @redux-devtools/inspector-monitor-test-tab@5.0.0
- @redux-devtools/ui@2.0.0
- @redux-devtools/inspector-monitor@6.1.2
## 0.1.17 ## 0.1.17
### Patch Changes ### Patch Changes

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"name": "test-demo", "name": "test-demo",
"version": "0.1.18", "version": "0.1.17",
"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",
@ -11,43 +11,44 @@
}, },
"dependencies": { "dependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@redux-devtools/dock-monitor": "workspace:^", "@redux-devtools/dock-monitor": "workspace:^",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "workspace:^",
"@redux-devtools/inspector-monitor-test-tab": "workspace:^", "@redux-devtools/inspector-monitor-test-tab": "workspace:^",
"@redux-devtools/ui": "workspace:^", "@redux-devtools/ui": "workspace:^",
"immutable": "^5.1.4", "immutable": "^5.0.3",
"lodash.shuffle": "^4.2.0", "lodash.shuffle": "^4.2.0",
"react": "^19.2.3", "react": "^18.3.1",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"react-is": "^19.2.3", "react-is": "^18.3.1",
"react-redux": "^9.2.0", "react-redux": "^9.2.0",
"react-router-dom": "^7.12.0", "react-router-dom": "^6.30.0",
"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.28.6", "@babel/core": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@types/lodash.shuffle": "^4.2.9", "@types/lodash.shuffle": "^4.2.9",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^18.3.5",
"@types/redux-logger": "^3.0.13", "@types/redux-logger": "^3.0.13",
"@types/styled-components": "^5.1.34",
"@types/webpack-env": "^1.18.8", "@types/webpack-env": "^1.18.8",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"cross-env": "^10.1.0", "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.5", "html-webpack-plugin": "^5.6.3",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.9.3", "typescript": "~5.8.2",
"webpack": "^5.104.1", "webpack": "^5.98.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.3" "webpack-dev-server": "^5.2.0"
} }
} }

View File

@ -48,10 +48,8 @@ const styles: {
const ROOT = '/'; // process.env.NODE_ENV === 'production' ? '/' : '/'; const ROOT = '/'; // process.env.NODE_ENV === 'production' ? '/' : '/';
interface Props extends Omit< interface Props
DemoAppState, extends Omit<DemoAppState, 'addFunction' | 'addSymbol' | 'shuffleArray'> {
'addFunction' | 'addSymbol' | 'shuffleArray'
> {
toggleTimeoutUpdate: (timeoutUpdateEnabled: boolean) => void; toggleTimeoutUpdate: (timeoutUpdateEnabled: boolean) => void;
timeoutUpdate: () => void; timeoutUpdate: () => void;
increment: () => void; increment: () => void;
@ -72,7 +70,7 @@ interface Props extends Omit<
} }
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

@ -36,6 +36,5 @@ export const getDevTools = (location: { search: string }) =>
export function ConnectedDevTools() { export function ConnectedDevTools() {
const location = useLocation(); const location = useLocation();
const DevTools = getDevTools(location); const DevTools = getDevTools(location);
// eslint-disable-next-line react-hooks/static-components
return <DevTools />; return <DevTools />;
} }

View File

@ -41,8 +41,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,7 +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: [ transformIgnorePatterns: ['node_modules/(?!.pnpm|lodash-es|nanoid)'],
'node_modules/(?!.pnpm|@x0k/json-schema-merge|color|lodash-es|nanoid)',
],
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/inspector-monitor-test-tab", "name": "@redux-devtools/inspector-monitor-test-tab",
"version": "5.0.0", "version": "4.1.1",
"description": "Generate tests for redux devtools.", "description": "Generate tests for redux devtools.",
"keywords": [ "keywords": [
"redux", "redux",
@ -43,7 +43,7 @@
"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.28.6", "@babel/runtime": "^7.26.9",
"@redux-devtools/ui": "workspace:^", "@redux-devtools/ui": "workspace:^",
"es6template": "^1.0.5", "es6template": "^1.0.5",
"javascript-stringify": "^2.1.0", "javascript-stringify": "^2.1.0",
@ -53,40 +53,40 @@
"simple-diff": "^1.7.2" "simple-diff": "^1.7.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "workspace:^",
"@testing-library/dom": "^10.4.1", "@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.3.1", "@testing-library/react": "^16.2.0",
"@types/es6template": "^1.0.5", "@types/es6template": "^1.0.5",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.14",
"@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.2.8", "@types/react": "^18.3.18",
"jest": "^30.2.0", "jest": "^29.7.0",
"jest-environment-jsdom": "^30.2.0", "jest-environment-jsdom": "^29.7.0",
"react": "^19.2.3", "react": "^18.3.1",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"ts-jest": "^29.4.6", "ts-jest": "^29.2.6",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "workspace:^",
"@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 || ^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 || ^19.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 || ^19.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

@ -59,10 +59,8 @@ export function compare<S>(
).forEach(generate); ).forEach(generate);
} }
interface Props<S, A extends Action<string>> extends Omit< interface Props<S, A extends Action<string>>
TabComponentProps<S, A>, extends Omit<TabComponentProps<S, A>, 'monitorState' | 'updateMonitorState'> {
'monitorState' | 'updateMonitorState'
> {
name?: string; name?: string;
isVanilla?: boolean; isVanilla?: boolean;
wrap?: string | ((locals: WrapLocals) => string); wrap?: string | ((locals: WrapLocals) => string);

View File

@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TestGenerator component should be empty when no actions provided 1`] = ` exports[`TestGenerator component should be empty when no actions provided 1`] = `
<textarea <textarea

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|js-tokens|lodash-es)', 'node_modules/(?!.pnpm|@babel/code-frame|@babel/highlight|@babel/helper-validator-identifier|chalk|lodash-es)',
], ],
}; };

View File

@ -30,42 +30,43 @@
"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.4", "@babel/code-frame": "^8.0.0-alpha.16",
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.26.9",
"@types/chrome": "^0.1.33", "@types/chrome": "^0.0.308",
"anser": "^2.3.5", "anser": "^2.3.2",
"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": "workspace:^",
"source-map": "^0.5.7" "source-map": "^0.5.7"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "workspace:^",
"@testing-library/dom": "^10.4.1", "@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.3.1", "@testing-library/react": "^16.2.0",
"@types/babel__code-frame": "^7.27.0", "@types/babel__code-frame": "^7.0.6",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.14",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"@types/path-browserify": "^1.0.3", "@types/path-browserify": "^1.0.3",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"@types/source-map": "0.5.2", "@types/source-map": "0.5.2",
"jest": "^30.2.0", "jest": "^29.7.0",
"jest-environment-jsdom": "^30.2.0", "jest-environment-jsdom": "^29.7.0",
"react": "^19.2.3", "react": "^18.3.1",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"react-test-renderer": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"ts-jest": "^29.4.6", "ts-jest": "^29.2.6",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",

View File

@ -32,10 +32,11 @@ function openAndCloseTab(url: string) {
const removeTab = () => { const removeTab = () => {
chrome.windows.onFocusChanged.removeListener(removeTab); chrome.windows.onFocusChanged.removeListener(removeTab);
if (tab && tab.id) { if (tab && tab.id) {
chrome.tabs.remove(tab.id, () => { chrome.tabs.remove(tab.id, async () => {
// eslint-disable-next-line no-console
if (chrome.runtime.lastError) console.log(chrome.runtime.lastError); if (chrome.runtime.lastError) console.log(chrome.runtime.lastError);
else if (chrome.devtools && chrome.devtools.inspectedWindow) { else if (chrome.devtools && chrome.devtools.inspectedWindow) {
void chrome.tabs.update(chrome.devtools.inspectedWindow.tabId, { await chrome.tabs.update(chrome.devtools.inspectedWindow.tabId, {
active: true, active: true,
}); });
} }

View File

@ -1,4 +1,4 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`StackTraceTab component should render the link to docs 1`] = ` exports[`StackTraceTab component should render the link to docs 1`] = `
<div <div

View File

@ -1,11 +1,5 @@
# Change Log # Change Log
## 6.1.2
### Patch Changes
- 20883e5: fix(deps): update all non-major dependencies
## 6.1.1 ## 6.1.1
### Patch Changes ### Patch Changes

View File

@ -14,36 +14,36 @@
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@redux-devtools/dock-monitor": "workspace:^", "@redux-devtools/dock-monitor": "workspace:^",
"@redux-devtools/inspector-monitor": "workspace:^", "@redux-devtools/inspector-monitor": "workspace:^",
"immutable": "^5.1.4", "immutable": "^5.0.3",
"lodash.shuffle": "^4.2.0", "lodash.shuffle": "^4.2.0",
"react": "^19.2.3", "react": "^18.3.1",
"react-base16-styling": "workspace:^", "react-base16-styling": "workspace:^",
"react-bootstrap": "^2.10.10", "react-bootstrap": "^2.10.9",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"react-redux": "^9.2.0", "react-redux": "^9.2.0",
"react-router-dom": "^7.12.0", "react-router-dom": "^6.30.0",
"redux": "^5.0.1", "redux": "^5.0.1",
"redux-logger": "^3.0.6" "redux-logger": "^3.0.6"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@types/lodash.shuffle": "^4.2.9", "@types/lodash.shuffle": "^4.2.9",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^18.3.5",
"@types/redux-logger": "^3.0.13", "@types/redux-logger": "^3.0.13",
"@types/webpack-env": "^1.18.8", "@types/webpack-env": "^1.18.8",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"cross-env": "^10.1.0", "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.5", "html-webpack-plugin": "^5.6.3",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.9.3", "typescript": "~5.8.2",
"webpack": "^5.104.1", "webpack": "^5.98.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.3" "webpack-dev-server": "^5.2.0"
} }
} }

View File

@ -119,10 +119,8 @@ function buildUrl(options: Options) {
); );
} }
interface Props extends Omit< interface Props
DemoAppState, extends Omit<DemoAppState, 'addFunction' | 'addSymbol' | 'shuffleArray'> {
'addFunction' | 'addSymbol' | 'shuffleArray'
> {
toggleTimeoutUpdate: (timeoutUpdateEnabled: boolean) => void; toggleTimeoutUpdate: (timeoutUpdateEnabled: boolean) => void;
timeoutUpdate: () => void; timeoutUpdate: () => void;
increment: () => void; increment: () => void;
@ -144,7 +142,7 @@ interface Props extends Omit<
} }
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 navigate = useNavigate(); const navigate = useNavigate();
@ -157,22 +155,22 @@ function DemoApp(props: Props) {
}); });
}; };
const toggleImmutableSupport = async () => { const toggleImmutableSupport = () => {
const options = getOptions(location); const options = getOptions(location);
await navigate( navigate(
buildUrl({ ...options, supportImmutable: !options.supportImmutable }), buildUrl({ ...options, supportImmutable: !options.supportImmutable }),
); );
}; };
const toggleTheme = async () => { const toggleTheme = () => {
const options = getOptions(location); const options = getOptions(location);
await navigate(buildUrl({ ...options, dark: !options.dark })); navigate(buildUrl({ ...options, dark: !options.dark }));
}; };
const setTheme = async (options: Options, theme: string) => { const setTheme = (options: Options, theme: string) => {
await navigate(buildUrl({ ...options, theme })); navigate(buildUrl({ ...options, theme }));
}; };
const toggleTimeoutUpdate = () => { const toggleTimeoutUpdate = () => {

View File

@ -47,6 +47,5 @@ export const getDevTools = (location: { search: string }) =>
export function ConnectedDevTools() { export function ConnectedDevTools() {
const location = useLocation(); const location = useLocation();
const DevTools = getDevTools(location); const DevTools = getDevTools(location);
// eslint-disable-next-line react-hooks/static-components
return <DevTools />; return <DevTools />;
} }

View File

@ -66,8 +66,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

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/inspector-monitor", "name": "@redux-devtools/inspector-monitor",
"version": "6.1.2", "version": "6.1.1",
"description": "Redux DevTools Diff Monitor", "description": "Redux DevTools Diff Monitor",
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-inspector-monitor", "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-inspector-monitor",
"bugs": { "bugs": {
@ -35,40 +35,40 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.26.9",
"@dnd-kit/core": "^6.3.1", "@dnd-kit/core": "^6.3.1",
"@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/modifiers": "^7.0.0",
"@dnd-kit/sortable": "^10.0.0", "@dnd-kit/sortable": "^8.0.0",
"@dnd-kit/utilities": "^3.2.2", "@dnd-kit/utilities": "^3.2.2",
"@types/lodash": "^4.17.23", "@types/lodash": "^4.17.16",
"dateformat": "^5.0.3", "dateformat": "^5.0.3",
"hex-rgba": "^1.0.2", "hex-rgba": "^1.0.2",
"immutable": "^5.1.4", "immutable": "^5.0.3",
"javascript-stringify": "^2.1.0", "javascript-stringify": "^2.1.0",
"jsondiffpatch": "^0.7.3", "jsondiffpatch": "^0.6.0",
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"react-base16-styling": "workspace:^", "react-base16-styling": "workspace:^",
"react-json-tree": "workspace:^" "react-json-tree": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@emotion/babel-preset-css-prop": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.12.0",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@types/dateformat": "^5.0.3", "@types/dateformat": "^5.0.3",
"@types/hex-rgba": "^1.0.3", "@types/hex-rgba": "^1.0.3",
"@types/lodash.debounce": "^4.0.9", "@types/lodash.debounce": "^4.0.9",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"react": "^19.2.3", "react": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",

View File

@ -83,7 +83,7 @@ export default function ActionList<A extends Action<string>>({
onReorderAction, onReorderAction,
}: Props<A>): JSX.Element { }: Props<A>): JSX.Element {
const nodeRef = useRef<HTMLDivElement | null>(null); const nodeRef = useRef<HTMLDivElement | null>(null);
const prevLastActionId = useRef<number | undefined>(undefined); const prevLastActionId = useRef<number | undefined>();
useLayoutEffect(() => { useLayoutEffect(() => {
if (nodeRef.current && prevLastActionId.current !== lastActionId) { if (nodeRef.current && prevLastActionId.current !== lastActionId) {

View File

@ -144,10 +144,8 @@ interface DefaultProps {
invertTheme: boolean; invertTheme: boolean;
} }
export interface DevtoolsInspectorProps< export interface DevtoolsInspectorProps<S, A extends Action<string>>
S, extends LiftedState<S, A, DevtoolsInspectorState> {
A extends Action<string>,
> extends LiftedState<S, A, DevtoolsInspectorState> {
dispatch: Dispatch< dispatch: Dispatch<
DevtoolsInspectorAction | LiftedAction<S, A, DevtoolsInspectorState> DevtoolsInspectorAction | LiftedAction<S, A, DevtoolsInspectorState>
>; >;

View File

@ -41,20 +41,20 @@
"prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.14",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"jest": "^30.2.0", "jest": "^29.7.0",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"rxjs": "^7.8.2", "rxjs": "^7.8.2",
"ts-jest": "^29.4.6", "ts-jest": "^29.2.6",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"redux": "^3.4.0 || ^4.0.0 || ^5.0.0" "redux": "^3.4.0 || ^4.0.0 || ^5.0.0"

View File

@ -41,26 +41,26 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.26.9",
"@types/lodash.debounce": "^4.0.9", "@types/lodash.debounce": "^4.0.9",
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"react-base16-styling": "workspace:^", "react-base16-styling": "workspace:^",
"react-json-tree": "workspace:^" "react-json-tree": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"react": "^19.2.3", "react": "^18.3.1",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",

View File

@ -64,10 +64,8 @@ interface DefaultProps<S> {
markStateDiff: boolean; markStateDiff: boolean;
} }
export interface LogMonitorProps< export interface LogMonitorProps<S, A extends Action<string>>
S, extends LiftedState<S, A, LogMonitorState> {
A extends Action<string>,
> extends LiftedState<S, A, LogMonitorState> {
dispatch: Dispatch<LogMonitorAction | LiftedAction<S, A, LogMonitorState>>; dispatch: Dispatch<LogMonitorAction | LiftedAction<S, A, LogMonitorState>>;
preserveScrollTop: boolean; preserveScrollTop: boolean;

View File

@ -41,31 +41,31 @@
"prepublish": "pnpm run type-check && pnpm run lint" "prepublish": "pnpm run type-check && pnpm run lint"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.26.9",
"@redux-devtools/instrument": "workspace:^", "@redux-devtools/instrument": "workspace:^",
"@redux-devtools/utils": "workspace:^", "@redux-devtools/utils": "workspace:^",
"jsan": "^3.1.14", "jsan": "^3.1.14",
"rn-host-detect": "^1.2.0", "rn-host-detect": "^1.2.0",
"socketcluster-client": "^20.0.1" "socketcluster-client": "^19.2.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@types/jsan": "^3.1.5", "@types/jsan": "^3.1.5",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"@types/rn-host-detect": "^1.2.2", "@types/rn-host-detect": "^1.2.2",
"@types/socketcluster-client": "^20.0.0", "@types/socketcluster-client": "^19.1.0",
"@typescript-eslint/eslint-plugin": "^8.53.0", "@typescript-eslint/eslint-plugin": "^8.26.0",
"@typescript-eslint/parser": "^8.53.0", "@typescript-eslint/parser": "^8.26.0",
"eslint": "^9.39.2", "eslint": "^9.21.0",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.0.2",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"redux": "^3.5.2 || ^4.0.0 || ^5.0.0" "redux": "^3.5.2 || ^4.0.0 || ^5.0.0"

View File

@ -1,16 +1,5 @@
# Change Log # Change Log
## 6.0.0
### Major Changes
- 6163276: Replace styled-components with Emotion
### Patch Changes
- Updated dependencies [6163276]
- @redux-devtools/ui@2.0.0
## 5.2.0 ## 5.2.0
### Minor Changes ### Minor Changes

View File

@ -1,12 +1,5 @@
# rtk-query-demo # rtk-query-demo
## 0.1.16
### Patch Changes
- Updated dependencies [6163276]
- @redux-devtools/rtk-query-monitor@6.0.0
## 0.1.15 ## 0.1.15
### Patch Changes ### Patch Changes

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"name": "rtk-query-demo", "name": "rtk-query-demo",
"version": "0.1.16", "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,48 +10,49 @@
"type-check": "tsc --noEmit" "type-check": "tsc --noEmit"
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.28.6", "@babel/runtime": "^7.26.9",
"@chakra-ui/react": "^3.31.0", "@chakra-ui/react": "^2.10.6",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1", "@emotion/styled": "^11.14.0",
"@mswjs/data": "^0.16.2", "@mswjs/data": "^0.16.2",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@redux-devtools/dock-monitor": "workspace:^", "@redux-devtools/dock-monitor": "workspace:^",
"@redux-devtools/rtk-query-monitor": "workspace:^", "@redux-devtools/rtk-query-monitor": "workspace:^",
"@reduxjs/toolkit": "^2.11.2", "@reduxjs/toolkit": "^2.6.0",
"msw": "^2.12.4", "framer-motion": "^11.18.2",
"react": "^19.2.3", "msw": "^2.7.3",
"react-dom": "^19.2.3", "react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-is": "^19.2.3", "react-is": "^18.3.1",
"react-redux": "^9.2.0", "react-redux": "^9.2.0",
"react-router-dom": "^7.12.0" "react-router-dom": "^6.30.0",
"styled-components": "^5.3.11"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@types/node": "^24.10.9", "@types/node": "^22.13.9",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^18.3.5",
"@types/styled-components": "^5.1.34",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"copy-webpack-plugin": "^13.0.1", "copy-webpack-plugin": "^12.0.2",
"cross-env": "^10.1.0", "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.5", "html-webpack-plugin": "^5.6.3",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "~5.9.3", "typescript": "~5.8.2",
"webpack": "^5.104.1", "webpack": "^5.98.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.3" "webpack-dev-server": "^5.2.0"
}, },
"msw": { "msw": {
"workerDirectory": [ "workerDirectory": "public"
"public"
]
} }
} }

View File

@ -5,23 +5,24 @@
* Mock Service Worker. * Mock Service Worker.
* @see https://github.com/mswjs/msw * @see https://github.com/mswjs/msw
* - Please do NOT modify this file. * - Please do NOT modify this file.
* - Please do NOT serve this file on production.
*/ */
const PACKAGE_VERSION = '2.12.4' const PACKAGE_VERSION = '2.7.3'
const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82' const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse') const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
const activeClientIds = new Set() const activeClientIds = new Set()
addEventListener('install', function () { self.addEventListener('install', function () {
self.skipWaiting() self.skipWaiting()
}) })
addEventListener('activate', function (event) { self.addEventListener('activate', function (event) {
event.waitUntil(self.clients.claim()) event.waitUntil(self.clients.claim())
}) })
addEventListener('message', async function (event) { self.addEventListener('message', async function (event) {
const clientId = Reflect.get(event.source || {}, 'id') const clientId = event.source.id
if (!clientId || !self.clients) { if (!clientId || !self.clients) {
return return
@ -71,6 +72,11 @@ addEventListener('message', async function (event) {
break break
} }
case 'MOCK_DEACTIVATE': {
activeClientIds.delete(clientId)
break
}
case 'CLIENT_CLOSED': { case 'CLIENT_CLOSED': {
activeClientIds.delete(clientId) activeClientIds.delete(clientId)
@ -88,92 +94,69 @@ addEventListener('message', async function (event) {
} }
}) })
addEventListener('fetch', function (event) { self.addEventListener('fetch', function (event) {
const requestInterceptedAt = Date.now() const { request } = event
// Bypass navigation requests. // Bypass navigation requests.
if (event.request.mode === 'navigate') { if (request.mode === 'navigate') {
return return
} }
// Opening the DevTools triggers the "only-if-cached" request // Opening the DevTools triggers the "only-if-cached" request
// that cannot be handled by the worker. Bypass such requests. // that cannot be handled by the worker. Bypass such requests.
if ( if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
event.request.cache === 'only-if-cached' &&
event.request.mode !== 'same-origin'
) {
return return
} }
// Bypass all requests when there are no active clients. // Bypass all requests when there are no active clients.
// Prevents the self-unregistered worked from handling requests // Prevents the self-unregistered worked from handling requests
// after it's been terminated (still remains active until the next reload). // after it's been deleted (still remains active until the next reload).
if (activeClientIds.size === 0) { if (activeClientIds.size === 0) {
return return
} }
// Generate unique request ID.
const requestId = crypto.randomUUID() const requestId = crypto.randomUUID()
event.respondWith(handleRequest(event, requestId, requestInterceptedAt)) event.respondWith(handleRequest(event, requestId))
}) })
/** async function handleRequest(event, requestId) {
* @param {FetchEvent} event
* @param {string} requestId
* @param {number} requestInterceptedAt
*/
async function handleRequest(event, requestId, requestInterceptedAt) {
const client = await resolveMainClient(event) const client = await resolveMainClient(event)
const requestCloneForEvents = event.request.clone() const response = await getResponse(event, client, requestId)
const response = await getResponse(
event,
client,
requestId,
requestInterceptedAt,
)
// Send back the response clone for the "response:*" life-cycle events. // Send back the response clone for the "response:*" life-cycle events.
// Ensure MSW is active and ready to handle the message, otherwise // Ensure MSW is active and ready to handle the message, otherwise
// this message will pend indefinitely. // this message will pend indefinitely.
if (client && activeClientIds.has(client.id)) { if (client && activeClientIds.has(client.id)) {
const serializedRequest = await serializeRequest(requestCloneForEvents) ;(async function () {
const responseClone = response.clone()
// Clone the response so both the client and the library could consume it. sendToClient(
const responseClone = response.clone() client,
{
sendToClient( type: 'RESPONSE',
client, payload: {
{ requestId,
type: 'RESPONSE', isMockedResponse: IS_MOCKED_RESPONSE in response,
payload: {
isMockedResponse: IS_MOCKED_RESPONSE in response,
request: {
id: requestId,
...serializedRequest,
},
response: {
type: responseClone.type, type: responseClone.type,
status: responseClone.status, status: responseClone.status,
statusText: responseClone.statusText, statusText: responseClone.statusText,
headers: Object.fromEntries(responseClone.headers.entries()),
body: responseClone.body, body: responseClone.body,
headers: Object.fromEntries(responseClone.headers.entries()),
}, },
}, },
}, [responseClone.body],
responseClone.body ? [serializedRequest.body, responseClone.body] : [], )
) })()
} }
return response return response
} }
/** // Resolve the main client for the given event.
* Resolve the main client for the given event. // Client that issues a request doesn't necessarily equal the client
* Client that issues a request doesn't necessarily equal the client // that registered the worker. It's with the latter the worker should
* that registered the worker. It's with the latter the worker should // communicate with during the response resolving phase.
* communicate with during the response resolving phase.
* @param {FetchEvent} event
* @returns {Promise<Client | undefined>}
*/
async function resolveMainClient(event) { async function resolveMainClient(event) {
const client = await self.clients.get(event.clientId) const client = await self.clients.get(event.clientId)
@ -201,17 +184,12 @@ async function resolveMainClient(event) {
}) })
} }
/** async function getResponse(event, client, requestId) {
* @param {FetchEvent} event const { request } = event
* @param {Client | undefined} client
* @param {string} requestId
* @param {number} requestInterceptedAt
* @returns {Promise<Response>}
*/
async function getResponse(event, client, requestId, requestInterceptedAt) {
// Clone the request because it might've been already used // Clone the request because it might've been already used
// (i.e. its body has been read and sent to the client). // (i.e. its body has been read and sent to the client).
const requestClone = event.request.clone() const requestClone = request.clone()
function passthrough() { function passthrough() {
// Cast the request headers to a new Headers instance // Cast the request headers to a new Headers instance
@ -252,18 +230,29 @@ async function getResponse(event, client, requestId, requestInterceptedAt) {
} }
// Notify the client that a request has been intercepted. // Notify the client that a request has been intercepted.
const serializedRequest = await serializeRequest(event.request) const requestBuffer = await request.arrayBuffer()
const clientMessage = await sendToClient( const clientMessage = await sendToClient(
client, client,
{ {
type: 'REQUEST', type: 'REQUEST',
payload: { payload: {
id: requestId, id: requestId,
interceptedAt: requestInterceptedAt, url: request.url,
...serializedRequest, mode: request.mode,
method: request.method,
headers: Object.fromEntries(request.headers.entries()),
cache: request.cache,
credentials: request.credentials,
destination: request.destination,
integrity: request.integrity,
redirect: request.redirect,
referrer: request.referrer,
referrerPolicy: request.referrerPolicy,
body: requestBuffer,
keepalive: request.keepalive,
}, },
}, },
[serializedRequest.body], [requestBuffer],
) )
switch (clientMessage.type) { switch (clientMessage.type) {
@ -279,12 +268,6 @@ async function getResponse(event, client, requestId, requestInterceptedAt) {
return passthrough() return passthrough()
} }
/**
* @param {Client} client
* @param {any} message
* @param {Array<Transferable>} transferrables
* @returns {Promise<any>}
*/
function sendToClient(client, message, transferrables = []) { function sendToClient(client, message, transferrables = []) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const channel = new MessageChannel() const channel = new MessageChannel()
@ -297,18 +280,14 @@ function sendToClient(client, message, transferrables = []) {
resolve(event.data) resolve(event.data)
} }
client.postMessage(message, [ client.postMessage(
channel.port2, message,
...transferrables.filter(Boolean), [channel.port2].concat(transferrables.filter(Boolean)),
]) )
}) })
} }
/** async function respondWithMock(response) {
* @param {Response} response
* @returns {Response}
*/
function respondWithMock(response) {
// Setting response status code to 0 is a no-op. // Setting response status code to 0 is a no-op.
// However, when responding with a "Response.error()", the produced Response // However, when responding with a "Response.error()", the produced Response
// instance will have status code set to 0. Since it's not possible to create // instance will have status code set to 0. Since it's not possible to create
@ -326,24 +305,3 @@ function respondWithMock(response) {
return mockedResponse return mockedResponse
} }
/**
* @param {Request} request
*/
async function serializeRequest(request) {
return {
url: request.url,
mode: request.mode,
method: request.method,
headers: Object.fromEntries(request.headers.entries()),
cache: request.cache,
credentials: request.credentials,
destination: request.destination,
integrity: request.integrity,
redirect: request.redirect,
referrer: request.referrer,
referrerPolicy: request.referrerPolicy,
body: await request.arrayBuffer(),
keepalive: request.keepalive,
}
}

View File

@ -1,7 +1,7 @@
import PokemonView from './features/pokemon/PokemonView'; import PokemonView from './features/pokemon/PokemonView';
import PostsView from './features/posts/PostsView'; import PostsView from './features/posts/PostsView';
import { Box, Flex, Heading, List } from '@chakra-ui/react'; import { Box, Flex, Heading } from '@chakra-ui/react';
import { Link } from '@chakra-ui/react'; import { Link, UnorderedList, ListItem } from '@chakra-ui/react';
import { Code } from '@chakra-ui/react'; import { Code } from '@chakra-ui/react';
import * as React from 'react'; import * as React from 'react';
import { DevToolsSelector } from './features/DevTools/DevToolsSelector'; import { DevToolsSelector } from './features/DevTools/DevToolsSelector';
@ -27,48 +27,44 @@ export function App() {
</Box> </Box>
</Flex> </Flex>
<Flex p="2" as="footer"> <Flex p="2" as="footer">
<List.Root p="2"> <UnorderedList p="2">
<List.Item> <ListItem>
<Link <Link
className="link" className="link"
target="_blank" isExternal
rel="noopener noreferrer"
href="https://github.com/FaberVitale/redux-devtools/tree/feat/rtk-query-monitor/packages/redux-devtools-rtk-query-monitor/demo" href="https://github.com/FaberVitale/redux-devtools/tree/feat/rtk-query-monitor/packages/redux-devtools-rtk-query-monitor/demo"
> >
demo source demo source
</Link> </Link>
</List.Item> </ListItem>
<List.Item> <ListItem>
<Link <Link
className="link" className="link"
target="_blank" isExternal
rel="noopener noreferrer"
href="https://github.com/FaberVitale/redux-devtools/tree/feat/rtk-query-monitor/packages/redux-devtools-rtk-query-monitor" href="https://github.com/FaberVitale/redux-devtools/tree/feat/rtk-query-monitor/packages/redux-devtools-rtk-query-monitor"
> >
@redux-devtools/rtk-query-monitor source @redux-devtools/rtk-query-monitor source
</Link> </Link>
</List.Item> </ListItem>
<List.Item> <ListItem>
<Link <Link
className="link" className="link"
target="_blank" isExternal
rel="noopener noreferrer"
href="https://github.com/reduxjs/redux-toolkit/tree/master/examples/query/react/polling" href="https://github.com/reduxjs/redux-toolkit/tree/master/examples/query/react/polling"
> >
polling example polling example
</Link> </Link>
</List.Item> </ListItem>
<List.Item> <ListItem>
<Link <Link
className="link" className="link"
target="_blank" isExternal
rel="noopener noreferrer"
href="https://github.com/reduxjs/redux-toolkit/tree/master/examples/query/react/mutations" href="https://github.com/reduxjs/redux-toolkit/tree/master/examples/query/react/mutations"
> >
mutations example mutations example
</Link> </Link>
</List.Item> </ListItem>
</List.Root> </UnorderedList>
</Flex> </Flex>
</main> </main>
); );

View File

@ -1,8 +0,0 @@
'use client';
import React from 'react';
import { ChakraProvider, defaultSystem } from '@chakra-ui/react';
export function Provider({ children }: { children: React.ReactNode }) {
return <ChakraProvider value={defaultSystem}>{children}</ChakraProvider>;
}

View File

@ -1,44 +0,0 @@
'use client';
import React from 'react';
import {
Toaster as ChakraToaster,
Portal,
Spinner,
Stack,
Toast,
createToaster,
} from '@chakra-ui/react';
export const toaster = createToaster({
placement: 'bottom-end',
pauseOnPageIdle: true,
});
export const Toaster = () => {
return (
<Portal>
<ChakraToaster toaster={toaster} insetInline={{ mdDown: '4' }}>
{(toast) => (
<Toast.Root width={{ md: 'sm' }}>
{toast.type === 'loading' ? (
<Spinner size="sm" color="blue.solid" />
) : (
<Toast.Indicator />
)}
<Stack gap="1" flex="1" maxWidth="100%">
{toast.title && <Toast.Title>{toast.title}</Toast.Title>}
{toast.description && (
<Toast.Description>{toast.description}</Toast.Description>
)}
</Stack>
{toast.action && (
<Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>
)}
{toast.closable && <Toast.CloseTrigger />}
</Toast.Root>
)}
</ChakraToaster>
</Portal>
);
};

View File

@ -14,7 +14,7 @@ export function DevToolsSelector() {
return ( return (
<Box as="section" p="2"> <Box as="section" p="2">
<Heading as="h2">Set active devTools</Heading> <Heading as="h2">Set active devTools</Heading>
<ButtonGroup variant="outline" gap="4" p="4"> <ButtonGroup variant="outline" spacing="4" p="4">
<Button <Button
aria-selected={!extensionEnabled} aria-selected={!extensionEnabled}
colorScheme="blue" colorScheme="blue"

View File

@ -1,17 +1,15 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Button, createListCollection, Portal, Select } from '@chakra-ui/react'; import { Button, Select } from '@chakra-ui/react';
import { useGetPokemonByNameQuery } from '../../services/pokemon'; import { useGetPokemonByNameQuery } from '../../services/pokemon';
import type { PokemonName } from '../../pokemon.data'; import type { PokemonName } from '../../pokemon.data';
const intervalOptions = createListCollection({ const intervalOptions = [
items: [ { label: 'Off', value: 0 },
{ label: 'Off', value: '0' }, { label: '3s', value: 3000 },
{ label: '3s', value: '3000' }, { label: '5s', value: 5000 },
{ label: '5s', value: '5000' }, { label: '10s', value: 10000 },
{ label: '10s', value: '10000' }, { label: '1m', value: 60000 },
{ label: '1m', value: '60000' }, ];
],
});
export function Pokemon({ name }: { name: PokemonName }) { export function Pokemon({ name }: { name: PokemonName }) {
const [pollingInterval, setPollingInterval] = useState(60000); const [pollingInterval, setPollingInterval] = useState(60000);
@ -43,39 +41,19 @@ export function Pokemon({ name }: { name: PokemonName }) {
/> />
</div> </div>
<div> <div>
<Select.Root <label style={{ display: 'block' }}>Polling interval</label>
collection={intervalOptions} <Select
value={[pollingInterval.toString()]} value={pollingInterval}
onValueChange={({ value }) => onChange={({ target: { value } }) =>
setPollingInterval(Number(value[0])) setPollingInterval(Number(value))
} }
> >
<Select.HiddenSelect /> {intervalOptions.map(({ label, value }) => (
<Select.Label>Polling interval</Select.Label> <option key={value} value={value}>
<Select.Control> {label}
<Select.Trigger> </option>
<Select.ValueText placeholder="Polling interval" /> ))}
</Select.Trigger> </Select>
<Select.IndicatorGroup>
<Select.Indicator />
</Select.IndicatorGroup>
</Select.Control>
<Portal>
<Select.Positioner>
<Select.Content>
{intervalOptions.items.map((intervalOption) => (
<Select.Item
item={intervalOption}
key={intervalOption.value}
>
{intervalOption.label}
<Select.ItemIndicator />
</Select.Item>
))}
</Select.Content>
</Select.Positioner>
</Portal>
</Select.Root>
</div> </div>
<div> <div>
<Button <Button

View File

@ -15,8 +15,8 @@ import {
Input, Input,
Spacer, Spacer,
Stack, Stack,
useToast,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { toaster } from '../../components/ui/toaster';
const EditablePostName = ({ const EditablePostName = ({
name: initialName, name: initialName,
@ -50,8 +50,8 @@ const EditablePostName = ({
</Box> </Box>
<Spacer /> <Spacer />
<Box> <Box>
<Stack gap={4} direction="row" align="center"> <Stack spacing={4} direction="row" align="center">
<Button onClick={handleUpdate} loading={isLoading}> <Button onClick={handleUpdate} isLoading={isLoading}>
Update Update
</Button> </Button>
<CloseButton bg="red" onClick={handleCancel} disabled={isLoading} /> <CloseButton bg="red" onClick={handleCancel} disabled={isLoading} />
@ -75,6 +75,8 @@ export const PostDetail = () => {
const { id } = useParams<{ id: string }>(); const { id } = useParams<{ id: string }>();
const navigate = useNavigate(); const navigate = useNavigate();
const toast = useToast();
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const { data: post, isLoading } = useGetPostQuery(id!); const { data: post, isLoading } = useGetPostQuery(id!);
@ -106,12 +108,12 @@ export const PostDetail = () => {
try { try {
await updatePost({ id: id!, name }).unwrap(); await updatePost({ id: id!, name }).unwrap();
} catch { } catch {
toaster.create({ toast({
title: 'An error occurred', title: 'An error occurred',
description: "We couldn't save your changes, try again!", description: "We couldn't save your changes, try again!",
type: 'error', status: 'error',
duration: 2000, duration: 2000,
closable: true, isClosable: true,
}); });
} finally { } finally {
setIsEditing(false); setIsEditing(false);
@ -127,7 +129,7 @@ export const PostDetail = () => {
</Box> </Box>
<Spacer /> <Spacer />
<Box> <Box>
<Stack gap={4} direction="row" align="center"> <Stack spacing={4} direction="row" align="center">
<Button <Button
onClick={() => setIsEditing(true)} onClick={() => setIsEditing(true)}
disabled={isDeleting || isUpdating} disabled={isDeleting || isUpdating}

View File

@ -2,15 +2,20 @@ import {
Box, Box,
Button, Button,
Center, Center,
Field, Divider,
Flex, Flex,
FormatNumber, FormControl,
FormLabel,
Heading, Heading,
Input, Input,
List, List,
Separator, ListIcon,
ListItem,
Spacer, Spacer,
Stat, Stat,
StatLabel,
StatNumber,
useToast,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { Route, Routes, useNavigate } from 'react-router-dom'; import { Route, Routes, useNavigate } from 'react-router-dom';
import { MdBook } from 'react-icons/md'; import { MdBook } from 'react-icons/md';
@ -21,12 +26,12 @@ import {
useGetPostsQuery, useGetPostsQuery,
} from '../../services/posts'; } from '../../services/posts';
import { PostDetail } from './PostDetail'; import { PostDetail } from './PostDetail';
import { toaster } from '../../components/ui/toaster';
const AddPost = () => { const AddPost = () => {
const initialValue = { name: '' }; const initialValue = { name: '' };
const [post, setPost] = useState<Pick<Post, 'name'>>(initialValue); const [post, setPost] = useState<Pick<Post, 'name'>>(initialValue);
const [addPost, { isLoading }] = useAddPostMutation(); const [addPost, { isLoading }] = useAddPostMutation();
const toast = useToast();
const handleChange = ({ target }: React.ChangeEvent<HTMLInputElement>) => { const handleChange = ({ target }: React.ChangeEvent<HTMLInputElement>) => {
setPost((prev) => ({ setPost((prev) => ({
@ -40,12 +45,12 @@ const AddPost = () => {
await addPost(post).unwrap(); await addPost(post).unwrap();
setPost(initialValue); setPost(initialValue);
} catch { } catch {
toaster.create({ toast({
title: 'An error occurred', title: 'An error occurred',
description: "We couldn't save your post, try again!", description: "We couldn't save your post, try again!",
type: 'error', status: 'error',
duration: 2000, duration: 2000,
closable: true, isClosable: true,
}); });
} }
}; };
@ -53,11 +58,11 @@ const AddPost = () => {
return ( return (
<Flex p={'5px 0'} flexDirection="row" flexWrap="wrap" maxWidth={'85%'}> <Flex p={'5px 0'} flexDirection="row" flexWrap="wrap" maxWidth={'85%'}>
<Box flex={'5 0 auto'} padding="0 5px 0 0"> <Box flex={'5 0 auto'} padding="0 5px 0 0">
<Field.Root <FormControl
flexDirection="column" flexDirection="column"
invalid={Boolean(post.name.length < 3 && post.name)} isInvalid={Boolean(post.name.length < 3 && post.name)}
> >
<Field.Label htmlFor="name">Post name</Field.Label> <FormLabel htmlFor="name">Post name</FormLabel>
<Input <Input
id="name" id="name"
name="name" name="name"
@ -65,13 +70,13 @@ const AddPost = () => {
value={post.name} value={post.name}
onChange={handleChange} onChange={handleChange}
/> />
</Field.Root> </FormControl>
</Box> </Box>
<Box> <Box>
<Button <Button
mt={8} mt={8}
colorScheme="purple" colorScheme="purple"
loading={isLoading} isLoading={isLoading}
onClick={handleAddPost} onClick={handleAddPost}
> >
Add Post Add Post
@ -94,16 +99,13 @@ const PostList = () => {
} }
return ( return (
<List.Root gap={3}> <List spacing={3}>
{posts.map(({ id, name }) => ( {posts.map(({ id, name }) => (
<List.Item key={id} onClick={() => navigate(`/posts/${id}`)}> <ListItem key={id} onClick={() => navigate(`/posts/${id}`)}>
<List.Indicator asChild color="green.500"> <ListIcon as={MdBook} color="green.500" /> {name}
<MdBook /> </ListItem>
</List.Indicator>
{name}
</List.Item>
))} ))}
</List.Root> </List>
); );
}; };
@ -113,12 +115,10 @@ export const PostsCountStat = () => {
if (!posts) return null; if (!posts) return null;
return ( return (
<Stat.Root> <Stat>
<Stat.Label>Active Posts</Stat.Label> <StatLabel>Active Posts</StatLabel>
<Stat.ValueText> <StatNumber>{posts?.length}</StatNumber>
<FormatNumber value={posts?.length} /> </Stat>
</Stat.ValueText>
</Stat.Root>
); );
}; };
@ -134,9 +134,9 @@ export const PostsManager = () => {
<PostsCountStat /> <PostsCountStat />
</Box> </Box>
</Flex> </Flex>
<Separator /> <Divider />
<AddPost /> <AddPost />
<Separator /> <Divider />
<Flex wrap="wrap"> <Flex wrap="wrap">
<Box flex={1} borderRight="1px solid #eee"> <Box flex={1} borderRight="1px solid #eee">
<Box p={4} borderBottom="1px solid #eee"> <Box p={4} borderBottom="1px solid #eee">

View File

@ -1,14 +1,13 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { Provider as ChakraProvider } from './components/ui/provider'; import { ChakraProvider } from '@chakra-ui/react';
import './index.css'; import './index.css';
import { store } from './store'; import { store } from './store';
import DevTools from './features/DevTools/DevTools'; import DevTools from './features/DevTools/DevTools';
import { BrowserRouter } from 'react-router-dom'; import { BrowserRouter } from 'react-router-dom';
import { App } from './App'; import { App } from './App';
import { worker } from './mocks/browser'; import { worker } from './mocks/browser';
import { Toaster } from './components/ui/toaster';
function renderApp() { function renderApp() {
const rootElement = document.getElementById('root'); const rootElement = document.getElementById('root');
@ -18,7 +17,6 @@ function renderApp() {
<ChakraProvider> <ChakraProvider>
<BrowserRouter> <BrowserRouter>
<App /> <App />
<Toaster />
<DevTools /> <DevTools />
</BrowserRouter> </BrowserRouter>
</ChakraProvider> </ChakraProvider>

View File

@ -1,3 +1,5 @@
/// <reference types="react-scripts" />
declare module '@redux-devtools/app'; declare module '@redux-devtools/app';
declare module 'remote-redux-devtools'; declare module 'remote-redux-devtools';

View File

@ -21,8 +21,5 @@ export const store: EnhancedStore<ReturnType<typeof reducer>> = configureStore({
// adding the api middleware enables caching, invalidation, polling and other features of `rtk-query` // adding the api middleware enables caching, invalidation, polling and other features of `rtk-query`
middleware: (getDefaultMiddleware) => middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat([pokemonApi.middleware, postsApi.middleware]), getDefaultMiddleware().concat([pokemonApi.middleware, postsApi.middleware]),
enhancers: devTools enhancers: (devTools ? [] : [DevTools.instrument()]) as any,
? undefined
: (getDefaultEnhancers) =>
getDefaultEnhancers().concat(DevTools.instrument()),
}); });

View File

@ -8,7 +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: [ transformIgnorePatterns: ['node_modules/(?!.pnpm|lodash-es|nanoid)'],
'node_modules/(?!.pnpm|@x0k/json-schema-merge|color|lodash-es|nanoid)',
],
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "@redux-devtools/rtk-query-monitor", "name": "@redux-devtools/rtk-query-monitor",
"version": "6.0.0", "version": "5.2.0",
"description": "rtk-query monitor for Redux DevTools", "description": "rtk-query monitor for Redux DevTools",
"keywords": [ "keywords": [
"redux", "redux",
@ -44,52 +44,52 @@
"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.28.6", "@babel/runtime": "^7.26.9",
"@redux-devtools/ui": "workspace:^", "@redux-devtools/ui": "workspace:^",
"@types/lodash": "^4.17.23", "@types/lodash": "^4.17.16",
"hex-rgba": "^1.0.2", "hex-rgba": "^1.0.2",
"immutable": "^5.1.4", "immutable": "^5.0.3",
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"react-base16-styling": "workspace:^", "react-base16-styling": "workspace:^",
"react-json-tree": "workspace:^" "react-json-tree": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.28.6", "@babel/cli": "^7.26.4",
"@babel/core": "^7.28.6", "@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.28.6", "@babel/eslint-parser": "^7.26.8",
"@babel/plugin-transform-runtime": "^7.28.5", "@babel/plugin-transform-runtime": "^7.26.9",
"@babel/preset-env": "^7.28.6", "@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.28.5", "@babel/preset-react": "^7.26.3",
"@babel/preset-typescript": "^7.28.5", "@babel/preset-typescript": "^7.26.0",
"@emotion/babel-preset-css-prop": "^11.12.0", "@emotion/babel-preset-css-prop": "^11.12.0",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@reduxjs/toolkit": "^2.11.2", "@reduxjs/toolkit": "^2.6.0",
"@testing-library/dom": "^10.4.1", "@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.9.1", "@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.1", "@testing-library/react": "^16.2.0",
"@types/jest": "^30.0.0", "@types/jest": "^29.5.14",
"@types/hex-rgba": "^1.0.3", "@types/hex-rgba": "^1.0.3",
"@types/lodash.debounce": "^4.0.9", "@types/lodash.debounce": "^4.0.9",
"@types/react": "^19.2.8", "@types/react": "^18.3.18",
"jest": "^30.2.0", "jest": "^29.7.0",
"jest-environment-jsdom": "^30.2.0", "jest-environment-jsdom": "^29.7.0",
"react": "^19.2.3", "react": "^18.3.1",
"react-dom": "^19.2.3", "react-dom": "^18.3.1",
"react-redux": "^9.2.0", "react-redux": "^9.2.0",
"redux": "^5.0.1", "redux": "^5.0.1",
"rimraf": "^6.1.2", "rimraf": "^6.0.1",
"ts-jest": "^29.4.6", "ts-jest": "^29.2.6",
"typescript": "~5.9.3" "typescript": "~5.8.2"
}, },
"peerDependencies": { "peerDependencies": {
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@redux-devtools/core": "workspace:^", "@redux-devtools/core": "workspace:^",
"@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 || ^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 || ^19.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"
} }
} }

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