diff --git a/.changeset/friendly-coats-trade.md b/.changeset/friendly-coats-trade.md new file mode 100644 index 00000000..23f4be01 --- /dev/null +++ b/.changeset/friendly-coats-trade.md @@ -0,0 +1,8 @@ +--- +'d3-state-visualizer': major +--- + +- Remove UMD build. +- Split `style` option into `chartStyles`, `nodeStyleOptions`, `textStyleOptions`, and `linkStyles`. +- The shape of the argument passed to the `onClickText` option has been updated. +- Rename `InputOptions` to `Options`, `Primitive` to `StyleValue`, and `NodeWithId` to `HierarchyPointNode`. diff --git a/.changeset/slimy-elephants-flash.md b/.changeset/slimy-elephants-flash.md new file mode 100644 index 00000000..380595e6 --- /dev/null +++ b/.changeset/slimy-elephants-flash.md @@ -0,0 +1,6 @@ +--- +'@redux-devtools/chart-monitor': major +--- + +- Split `style` option into `chartStyles`, `nodeStyleOptions`, `textStyleOptions`, and `linkStyles`. +- The shape of the argument passed to the `onClickText` option has been updated. diff --git a/.changeset/spicy-olives-compete.md b/.changeset/spicy-olives-compete.md new file mode 100644 index 00000000..222625e8 --- /dev/null +++ b/.changeset/spicy-olives-compete.md @@ -0,0 +1,10 @@ +--- +'d3tooltip': major +--- + +- Remove UMD build. +- Upgrade d3 peer dependency from v3 to v7. +- Remove `attr` configuration method. +- Rename `style` configuration method to `styles` and move to options. +- Move `text` configuration method to options. +- Remove d3 parameter as first parameter for `tooltip`. diff --git a/.changeset/weak-kings-brake.md b/.changeset/weak-kings-brake.md new file mode 100644 index 00000000..3f6b4107 --- /dev/null +++ b/.changeset/weak-kings-brake.md @@ -0,0 +1,5 @@ +--- +'map2tree': major +--- + +- Remove UMD build. diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 38bc5cdb..f2c7b65a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: nrwl/nx-set-shas@v2 + - uses: nrwl/nx-set-shas@v3 - uses: pnpm/action-setup@v2 - uses: actions/setup-node@v3 with: @@ -25,10 +25,10 @@ jobs: - name: Check formatting run: pnpm run format:check - name: Build - run: pnpm exec nx affected --target=build --parallel=3 + run: pnpm exec nx affected --target=build --parallel=1 - name: Lint - run: pnpm exec nx affected --target=lint --parallel=3 + run: pnpm exec nx affected --target=lint --parallel=1 - name: Test uses: GabrielBB/xvfb-action@v1 with: - run: pnpm exec nx affected --target=test --parallel=3 + run: pnpm exec nx affected --target=test --parallel=1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b3a4ea15..70ae909c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,8 @@ on: branches: - main +permissions: write-all + jobs: release: name: Release @@ -36,3 +38,21 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Archive Chrome Extension + uses: actions/upload-artifact@v3 + with: + name: chrome + path: extension/chrome/dist + + - name: Archive Edge Extension + uses: actions/upload-artifact@v3 + with: + name: edge + path: extension/edge/dist + + - name: Archive Firefox Extension + uses: actions/upload-artifact@v3 + with: + name: firefox + path: extension/firefox/dist diff --git a/extension/.eslintignore b/extension/.eslintignore index 85ffff06..d8c3bcd8 100644 --- a/extension/.eslintignore +++ b/extension/.eslintignore @@ -1,7 +1,3 @@ -node_modules -build -dev -webpack/replace -examples -npm-package -_book +node_modules +dist +examples diff --git a/extension/.gitignore b/extension/.gitignore index bbe0a464..f06235c4 100644 --- a/extension/.gitignore +++ b/extension/.gitignore @@ -1,9 +1,2 @@ node_modules -npm-debug.log -.DS_Store -.idea/ -dist/ -build/ -dev/ -tmp/ -_book +dist diff --git a/extension/CHANGELOG.md b/extension/CHANGELOG.md index 9474ce0d..e7ba695d 100644 --- a/extension/CHANGELOG.md +++ b/extension/CHANGELOG.md @@ -1,5 +1,23 @@ # remotedev-redux-devtools-extension +## 3.0.17 + +### Patch Changes + +- 1aa6c4f7: Fix remounting root for devpanel + +## 3.0.16 + +### Patch Changes + +- 20ebf725: Remove source map from page wrap bundle + +## 3.0.14 + +### Patch Changes + +- 24f60a7a: bump min popup window width to 760px #1126 #1129 + ## 3.0.13 ### Patch Changes diff --git a/extension/README.md b/extension/README.md index 5c8dc144..2e3cd99c 100644 --- a/extension/README.md +++ b/extension/README.md @@ -57,7 +57,7 @@ const composeEnhancers = compose; ``` -> For TypeScript use [`redux-devtools-extension` npm package](#13-use-redux-devtools-extension-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 const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; diff --git a/extension/src/browser/extension/manifest.json b/extension/chrome/manifest.json similarity index 97% rename from extension/src/browser/extension/manifest.json rename to extension/chrome/manifest.json index 449267a6..da162077 100644 --- a/extension/src/browser/extension/manifest.json +++ b/extension/chrome/manifest.json @@ -1,7 +1,6 @@ { - "version": "3.0.11", + "version": "3.0.17", "name": "Redux DevTools", - "short_name": "Redux DevTools", "description": "Redux DevTools for debugging application's state changes.", "homepage_url": "https://github.com/reduxjs/redux-devtools", "manifest_version": 2, diff --git a/extension/docs/Troubleshooting.md b/extension/docs/Troubleshooting.md index e3cf226f..d4b8591e 100644 --- a/extension/docs/Troubleshooting.md +++ b/extension/docs/Troubleshooting.md @@ -16,6 +16,8 @@ If you develop on your local filesystem, make sure to allow Redux DevTools acces Most likely you mutate the state. Check it by [adding `redux-immutable-state-invariant` middleware](https://github.com/zalmoxisus/redux-devtools-extension/blob/master/examples/counter/store/configureStore.js#L3). +Another cause could be that you are creating multiple stores, which means that the devtools get attached to one but the application uses another. See [https://github.com/reduxjs/redux-toolkit/issues/2753](this issue). + ### @@INIT or REPLACE action resets the state of the app or last actions RE-APPLIED `@@redux/REPLACE` (or `@@INIT`) is used internally when the application is hot reloaded. When you use `store.replaceReducer` the effect will be the same as for hot-reloading, where the extension is recomputing all the history again. To avoid that set [`shouldHotReload`](/docs/API/Arguments.md#shouldhotreload) parameter to `false`. diff --git a/extension/edge/manifest.json b/extension/edge/manifest.json new file mode 100644 index 00000000..e6dae08a --- /dev/null +++ b/extension/edge/manifest.json @@ -0,0 +1,67 @@ +{ + "version": "3.0.17", + "name": "Redux DevTools", + "description": "Redux DevTools for debugging application's state changes.", + "homepage_url": "https://github.com/reduxjs/redux-devtools", + "manifest_version": 2, + "page_action": { + "default_icon": "img/logo/gray.png", + "default_title": "Redux DevTools", + "default_popup": "window.html#popup" + }, + "commands": { + "devtools-left": { + "description": "DevTools window to left" + }, + "devtools-right": { + "description": "DevTools window to right" + }, + "devtools-bottom": { + "description": "DevTools window to bottom" + }, + "devtools-remote": { + "description": "Remote DevTools" + }, + "_execute_page_action": { + "suggested_key": { + "default": "Ctrl+Shift+E" + } + } + }, + "icons": { + "16": "img/logo/16x16.png", + "48": "img/logo/48x48.png", + "128": "img/logo/128x128.png" + }, + "options_ui": { + "page": "options.html", + "chrome_style": true + }, + "background": { + "scripts": ["background.bundle.js"], + "persistent": false + }, + "content_scripts": [ + { + "matches": [""], + "exclude_globs": ["https://www.google*"], + "js": ["content.bundle.js", "pagewrap.bundle.js"], + "run_at": "document_start", + "all_frames": true + } + ], + "devtools_page": "devtools.html", + "web_accessible_resources": ["page.bundle.js"], + "externally_connectable": { + "ids": ["*"] + }, + "permissions": [ + "notifications", + "contextMenus", + "storage", + "file:///*", + "http://*/*", + "https://*/*" + ], + "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'; style-src * 'unsafe-inline'; img-src 'self' data:;" +} diff --git a/extension/src/browser/firefox/manifest.json b/extension/firefox/manifest.json similarity index 98% rename from extension/src/browser/firefox/manifest.json rename to extension/firefox/manifest.json index 8ff36ba4..a036827e 100644 --- a/extension/src/browser/firefox/manifest.json +++ b/extension/firefox/manifest.json @@ -1,5 +1,5 @@ { - "version": "3.0.11", + "version": "3.0.17", "name": "Redux DevTools", "manifest_version": 2, "description": "Redux Developer Tools for debugging application state changes.", diff --git a/extension/jest.config.js b/extension/jest.config.js index b70a7b3e..26d1c602 100644 --- a/extension/jest.config.js +++ b/extension/jest.config.js @@ -5,4 +5,7 @@ module.exports = { moduleNameMapper: { '\\.css$': '/test/__mocks__/styleMock.ts', }, + transformIgnorePatterns: [ + 'node_modules/(?!.pnpm|d3|dateformat|delaunator|nanoid|robust-predicates|uuid)', + ], }; diff --git a/extension/package.json b/extension/package.json index 0fd349d5..6ff2d2d3 100644 --- a/extension/package.json +++ b/extension/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "remotedev-redux-devtools-extension", - "version": "3.0.13", + "version": "3.0.17", "description": "Redux Developer Tools for debugging application state changes.", "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/extension", "license": "MIT", @@ -11,20 +11,18 @@ "url": "https://github.com/reduxjs/redux-devtools.git" }, "scripts": { - "start": "webpack --config webpack/dev.config.babel.js", - "build": "pnpm run build:extension && pnpm run build:firefox", - "build:extension": "rimraf build/extension && webpack --config webpack/wrap.config.babel.js && webpack --config webpack/prod.config.babel.js", - "build:firefox": "webpack --config webpack/prod.firefox.config.babel.js", + "start": "webpack --env development --watch", + "build": "pnpm run build:extension && pnpm run build:chrome && pnpm run build:edge && pnpm run build:firefox", + "build:extension": "webpack --env production && webpack --config wrap.webpack.config.js", + "build:chrome": "cpy . ../chrome/dist --cwd dist && cpy manifest.json dist --cwd chrome", + "build:edge": "cpy . ../edge/dist --cwd dist && cpy manifest.json dist --cwd edge", + "build:firefox": "cpy . ../firefox/dist --cwd dist && cpy manifest.json dist --cwd firefox", "build:examples": "babel-node examples/buildAll.js", - "precompress:extension": "pnpm run lint && pnpm run test:app && pnpm run build:extension && pnpm run test:chrome && pnpm run test:electron", - "precompress:firefox": "pnpm run lint && pnpm run build:firefox && pnpm run test:app", - "compress:extension": "bestzip build/extension.zip build/extension", - "compress:firefox": "bestzip build/extension.zip build/extension", - "clean": "rimraf build && rimraf dev", + "clean": "rimraf dist && rimraf chrome/dist && rimraf edge/dist && rimraf firefox/dist", "test:app": "cross-env BABEL_ENV=test jest test/app", "test:chrome": "jest test/chrome", "test:electron": "pnpm run build:test:electron:fixture && jest test/electron", - "test": "pnpm run test:app && pnpm run build:extension && pnpm run test:chrome && pnpm run test:electron", + "test": "pnpm run test:app && pnpm run test:chrome && pnpm run test:electron", "build:test:electron:fixture": "webpack --config test/electron/fixture/webpack.config.js", "type-check": "tsc --noEmit" }, @@ -43,56 +41,56 @@ "lodash": "^4.17.21", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-icons": "^4.4.0", + "react-icons": "^4.7.1", "react-is": "^18.2.0", "react-json-tree": "^0.17.0", - "react-redux": "^8.0.2", + "react-redux": "^8.0.5", "redux": "^4.2.0", "redux-persist": "^6.0.0", - "styled-components": "^5.3.5" + "styled-components": "^5.3.6" }, "devDependencies": { - "@babel/core": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", - "@babel/register": "^7.17.7", - "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.3.0", - "@types/chrome": "^0.0.190", - "@types/lodash": "^4.14.182", - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", - "@types/styled-components": "^5.1.25", - "babel-loader": "^8.2.5", - "bestzip": "^2.2.1", - "chromedriver": "^102.0.0", + "@babel/core": "^7.20.5", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@babel/register": "^7.18.9", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@types/chrome": "^0.0.206", + "@types/lodash": "^4.14.191", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", + "@types/styled-components": "^5.1.26", + "babel-loader": "^9.1.0", + "chromedriver": "^108.0.0", "copy-webpack-plugin": "^11.0.0", + "cpy-cli": "^4.2.0", "cross-env": "^7.0.3", - "css-loader": "^6.7.1", - "electron": "^19.0.4", - "eslint": "^8.18.0", + "css-loader": "^6.7.3", + "electron": "^22.0.0", + "eslint": "^8.30.0", "eslint-config-airbnb": "^19.0.4", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-jsx-a11y": "^6.6.1", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", "file-loader": "^6.2.0", - "fork-ts-checker-webpack-plugin": "^7.2.11", + "fork-ts-checker-webpack-plugin": "^7.2.14", "immutable": "^4.1.0", - "jest": "^27.5.1", - "path-browserify": "^1.0.1", + "jest": "^29.3.1", + "jest-environment-jsdom": "^29.3.1", "pug-html-loader": "^1.1.5", "raw-loader": "^4.0.2", "react-transform-catch-errors": "^1.0.2", "react-transform-hmr": "^1.0.4", "rimraf": "^3.0.2", - "selenium-webdriver": "^4.2.0", + "selenium-webdriver": "^4.7.1", "sinon-chrome": "^3.0.1", "style-loader": "^3.3.1", - "ts-jest": "^27.1.5", - "typescript": "~4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0" + "ts-jest": "^29.0.3", + "typescript": "~4.9.4", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1" } } diff --git a/extension/src/app/containers/Actions.tsx b/extension/src/app/Actions.tsx similarity index 96% rename from extension/src/app/containers/Actions.tsx rename to extension/src/app/Actions.tsx index c821afe4..bf1c6f39 100644 --- a/extension/src/app/containers/Actions.tsx +++ b/extension/src/app/Actions.tsx @@ -19,8 +19,8 @@ import { } from '@redux-devtools/app'; import { GoRadioTower } from 'react-icons/go'; import { MdBorderBottom, MdBorderLeft, MdBorderRight } from 'react-icons/md'; -import { Position } from '../api/openWindow'; -import { SingleMessage } from '../middlewares/api'; +import type { Position } from '../pageScript/api/openWindow'; +import type { SingleMessage } from '../background/store/apiMiddleware'; type StateProps = ReturnType; type DispatchProps = ResolveThunks; diff --git a/extension/src/app/containers/App.tsx b/extension/src/app/App.tsx similarity index 100% rename from extension/src/app/containers/App.tsx rename to extension/src/app/App.tsx diff --git a/extension/src/app/stores/createStore.ts b/extension/src/app/stores/createStore.ts deleted file mode 100644 index f91dd548..00000000 --- a/extension/src/app/stores/createStore.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { - Action, - createStore, - PreloadedState, - Reducer, - StoreEnhancer, -} from 'redux'; - -export default function configureStore>( - reducer: Reducer, - initialState: PreloadedState | undefined, - enhance: () => StoreEnhancer -) { - return createStore(reducer, initialState, enhance()); -} diff --git a/extension/src/browser/extension/background/contextMenus.ts b/extension/src/background/contextMenus.ts similarity index 100% rename from extension/src/browser/extension/background/contextMenus.ts rename to extension/src/background/contextMenus.ts diff --git a/extension/src/browser/extension/background/index.ts b/extension/src/background/index.ts similarity index 86% rename from extension/src/browser/extension/background/index.ts rename to extension/src/background/index.ts index 165b1af0..c7236e2e 100644 --- a/extension/src/browser/extension/background/index.ts +++ b/extension/src/background/index.ts @@ -1,11 +1,9 @@ import { Store } from 'redux'; -import configureStore, { - BackgroundAction, -} from '../../../app/stores/backgroundStore'; +import configureStore, { BackgroundAction } from './store/backgroundStore'; import openDevToolsWindow, { DevToolsPosition } from './openWindow'; import { createMenu, removeMenu } from './contextMenus'; import syncOptions from '../options/syncOptions'; -import { BackgroundState } from '../../../app/reducers/background'; +import { BackgroundState } from './store/backgroundReducer'; declare global { interface Window { diff --git a/extension/src/browser/extension/background/logging.ts b/extension/src/background/logging.ts similarity index 100% rename from extension/src/browser/extension/background/logging.ts rename to extension/src/background/logging.ts diff --git a/extension/src/browser/extension/background/openWindow.ts b/extension/src/background/openWindow.ts similarity index 100% rename from extension/src/browser/extension/background/openWindow.ts rename to extension/src/background/openWindow.ts diff --git a/extension/src/app/middlewares/api.ts b/extension/src/background/store/apiMiddleware.ts similarity index 96% rename from extension/src/app/middlewares/api.ts rename to extension/src/background/store/apiMiddleware.ts index c8cb8937..fb132e1d 100644 --- a/extension/src/app/middlewares/api.ts +++ b/extension/src/background/store/apiMiddleware.ts @@ -15,28 +15,23 @@ import syncOptions, { Options, OptionsMessage, SyncOptions, -} from '../../browser/extension/options/syncOptions'; -import openDevToolsWindow, { - DevToolsPosition, -} from '../../browser/extension/background/openWindow'; -import { getReport } from '../../browser/extension/background/logging'; +} from '../../options/syncOptions'; +import openDevToolsWindow, { DevToolsPosition } from '../openWindow'; +import { getReport } from '../logging'; import { Action, Dispatch, MiddlewareAPI } from 'redux'; -import { +import type { ContentScriptToBackgroundMessage, SplitMessage, -} from '../../browser/extension/inject/contentScript'; -import { +} from '../../contentScript'; +import type { ErrorMessage, PageScriptToContentScriptMessageForwardedToMonitors, PageScriptToContentScriptMessageWithoutDisconnectOrInitInstance, -} from '../api'; +} from '../../pageScript/api'; import { LiftedState } from '@redux-devtools/instrument'; -import { - BackgroundAction, - LiftedActionAction, -} from '../stores/backgroundStore'; -import { Position } from '../api/openWindow'; -import { BackgroundState } from '../reducers/background'; +import type { BackgroundAction, LiftedActionAction } from './backgroundStore'; +import type { Position } from '../../pageScript/api/openWindow'; +import type { BackgroundState } from './backgroundReducer'; interface TabMessageBase { readonly type: string; diff --git a/extension/src/app/reducers/background/index.ts b/extension/src/background/store/backgroundReducer.ts similarity index 84% rename from extension/src/app/reducers/background/index.ts rename to extension/src/background/store/backgroundReducer.ts index bea610c0..01ca5a02 100644 --- a/extension/src/app/reducers/background/index.ts +++ b/extension/src/background/store/backgroundReducer.ts @@ -1,6 +1,6 @@ import { combineReducers, Reducer } from 'redux'; import { instances, InstancesState } from '@redux-devtools/app'; -import { BackgroundAction } from '../../stores/backgroundStore'; +import type { BackgroundAction } from './backgroundStore'; export interface BackgroundState { readonly instances: InstancesState; diff --git a/extension/src/app/stores/backgroundStore.ts b/extension/src/background/store/backgroundStore.ts similarity index 93% rename from extension/src/app/stores/backgroundStore.ts rename to extension/src/background/store/backgroundStore.ts index 55eed9e4..da72bdd4 100644 --- a/extension/src/app/stores/backgroundStore.ts +++ b/extension/src/background/store/backgroundStore.ts @@ -5,8 +5,8 @@ import { LIFTED_ACTION, StoreActionWithoutLiftedAction, } from '@redux-devtools/app'; -import rootReducer, { BackgroundState } from '../reducers/background'; -import api, { CONNECTED, DISCONNECTED } from '../middlewares/api'; +import rootReducer, { BackgroundState } from './backgroundReducer'; +import api, { CONNECTED, DISCONNECTED } from './apiMiddleware'; interface LiftedActionActionBase { action?: DispatchAction | string | CustomAction; diff --git a/extension/src/browser/extension/chromeAPIMock.ts b/extension/src/chromeApiMock.ts similarity index 100% rename from extension/src/browser/extension/chromeAPIMock.ts rename to extension/src/chromeApiMock.ts diff --git a/extension/src/browser/extension/inject/contentScript.ts b/extension/src/contentScript/index.ts similarity index 98% rename from extension/src/browser/extension/inject/contentScript.ts rename to extension/src/contentScript/index.ts index 61c49e85..2c65ee14 100644 --- a/extension/src/browser/extension/inject/contentScript.ts +++ b/extension/src/contentScript/index.ts @@ -3,12 +3,12 @@ import { getOptionsFromBg, isAllowed, } from '../options/syncOptions'; -import { TabMessage } from '../../../app/middlewares/api'; -import { +import type { TabMessage } from '../background/store/apiMiddleware'; +import type { PageScriptToContentScriptMessage, PageScriptToContentScriptMessageWithoutDisconnect, PageScriptToContentScriptMessageWithoutDisconnectOrInitInstance, -} from '../../../app/api'; +} from '../pageScript/api'; import { Action } from 'redux'; import { CustomAction, diff --git a/extension/src/browser/views/devpanel.pug b/extension/src/devpanel/devpanel.pug similarity index 82% rename from extension/src/browser/views/devpanel.pug rename to extension/src/devpanel/devpanel.pug index ee41747c..4aa1268d 100644 --- a/extension/src/browser/views/devpanel.pug +++ b/extension/src/devpanel/devpanel.pug @@ -1,15 +1,15 @@ -doctype html - -html - head - meta(charset='UTF-8') - title Redux DevTools - include ./includes/style.pug - style. - body { - min-height: 100px; - } - - body - #root - script(src='/devpanel.bundle.js') +doctype html + +html + head + meta(charset='UTF-8') + title Redux DevTools + include ../style.pug + style. + body { + min-height: 100px; + } + + body + #root + script(src='/devpanel.bundle.js') diff --git a/extension/src/browser/extension/devpanel/index.tsx b/extension/src/devpanel/index.tsx similarity index 77% rename from extension/src/browser/extension/devpanel/index.tsx rename to extension/src/devpanel/index.tsx index af4fbfc3..a3879998 100644 --- a/extension/src/browser/extension/devpanel/index.tsx +++ b/extension/src/devpanel/index.tsx @@ -1,15 +1,15 @@ -import React, { CSSProperties } from 'react'; +import React, { CSSProperties, ReactNode } from 'react'; import { createRoot, Root } from 'react-dom/client'; import { Provider } from 'react-redux'; import { Persistor } from 'redux-persist'; import { REMOVE_INSTANCE, StoreAction } from '@redux-devtools/app'; -import App from '../../../app/containers/App'; -import configureStore from '../../../app/stores/panelStore'; +import App from '../app/App'; +import configureStore from './store/panelStore'; -import '../../views/devpanel.pug'; +import './devpanel.pug'; import { Action, Store } from 'redux'; -import { PanelMessage } from '../../../app/middlewares/api'; -import { StoreStateWithoutSocket } from '../../../app/reducers/panel'; +import type { PanelMessage } from '../background/store/apiMiddleware'; +import type { StoreStateWithoutSocket } from './store/panelReducer'; import { PersistGate } from 'redux-persist/integration/react'; const position = location.hash; @@ -20,6 +20,7 @@ const messageStyle: CSSProperties = { }; let rendered: boolean | undefined; +let currentRoot: Root | undefined; let store: Store | undefined; let persistor: Persistor | undefined; let bgConnection: chrome.runtime.Port; @@ -27,11 +28,16 @@ let naTimeout: NodeJS.Timeout; const isChrome = navigator.userAgent.indexOf('Firefox') === -1; -function renderDevTools(root: Root) { - root.unmount(); +function renderNodeAtRoot(node: ReactNode) { + if (currentRoot) currentRoot.unmount(); + currentRoot = createRoot(document.getElementById('root')!); + currentRoot.render(node); +} + +function renderDevTools() { clearTimeout(naTimeout); ({ store, persistor } = configureStore(position, bgConnection)); - root.render( + renderNodeAtRoot( @@ -41,7 +47,7 @@ function renderDevTools(root: Root) { rendered = true; } -function renderNA(root: Root) { +function renderNA() { if (rendered === false) return; rendered = false; naTimeout = setTimeout(() => { @@ -74,31 +80,28 @@ function renderNA(root: Root) { ); } - root.unmount(); - root.render(message); + renderNodeAtRoot(message); store = undefined; }); } else { - root.unmount(); - root.render(message); + renderNodeAtRoot(message); store = undefined; } }, 3500); } function init(id: number) { - const root = createRoot(document.getElementById('root')!); - renderNA(root); + renderNA(); bgConnection = chrome.runtime.connect({ name: id ? id.toString() : undefined, }); bgConnection.onMessage.addListener( >(message: PanelMessage) => { if (message.type === 'NA') { - if (message.id === id) renderNA(root); + if (message.id === id) renderNA(); else store!.dispatch({ type: REMOVE_INSTANCE, id: message.id }); } else { - if (!rendered) renderDevTools(root); + if (!rendered) renderDevTools(); store!.dispatch(message); } } diff --git a/extension/src/app/reducers/panel/index.ts b/extension/src/devpanel/store/panelReducer.ts similarity index 100% rename from extension/src/app/reducers/panel/index.ts rename to extension/src/devpanel/store/panelReducer.ts diff --git a/extension/src/app/stores/panelStore.ts b/extension/src/devpanel/store/panelStore.ts similarity index 86% rename from extension/src/app/stores/panelStore.ts rename to extension/src/devpanel/store/panelStore.ts index 873e7284..f8b8e622 100644 --- a/extension/src/app/stores/panelStore.ts +++ b/extension/src/devpanel/store/panelStore.ts @@ -2,8 +2,8 @@ import { createStore, applyMiddleware, Reducer } from 'redux'; import localForage from 'localforage'; import { persistReducer, persistStore } from 'redux-persist'; import { exportStateMiddleware, StoreAction } from '@redux-devtools/app'; -import panelDispatcher from '../middlewares/panelSync'; -import rootReducer, { StoreStateWithoutSocket } from '../reducers/panel'; +import panelDispatcher from './panelSyncMiddleware'; +import rootReducer, { StoreStateWithoutSocket } from './panelReducer'; const persistConfig = { key: 'redux-devtools', diff --git a/extension/src/app/middlewares/panelSync.ts b/extension/src/devpanel/store/panelSyncMiddleware.ts similarity index 100% rename from extension/src/app/middlewares/panelSync.ts rename to extension/src/devpanel/store/panelSyncMiddleware.ts diff --git a/extension/src/browser/views/devtools.pug b/extension/src/devtools/devtools.pug similarity index 93% rename from extension/src/browser/views/devtools.pug rename to extension/src/devtools/devtools.pug index 7a361b53..c9f56539 100644 --- a/extension/src/browser/views/devtools.pug +++ b/extension/src/devtools/devtools.pug @@ -1,10 +1,10 @@ -doctype html - -html - head - meta(charset='UTF-8') - title Redux DevTools - - body - #root - script(src='/devtools.bundle.js') +doctype html + +html + head + meta(charset='UTF-8') + title Redux DevTools + + body + #root + script(src='/devtools.bundle.js') diff --git a/extension/src/browser/extension/devtools/index.ts b/extension/src/devtools/index.ts similarity index 92% rename from extension/src/browser/extension/devtools/index.ts rename to extension/src/devtools/index.ts index de6abaaa..cdd376b6 100644 --- a/extension/src/browser/extension/devtools/index.ts +++ b/extension/src/devtools/index.ts @@ -1,4 +1,4 @@ -import '../../views/devtools.pug'; +import './devtools.pug'; function createPanel(url: string) { chrome.devtools.panels.create( diff --git a/extension/src/browser/extension/options/AllowToRunGroup.tsx b/extension/src/options/AllowToRunGroup.tsx similarity index 100% rename from extension/src/browser/extension/options/AllowToRunGroup.tsx rename to extension/src/options/AllowToRunGroup.tsx diff --git a/extension/src/browser/extension/options/ContextMenuGroup.tsx b/extension/src/options/ContextMenuGroup.tsx similarity index 100% rename from extension/src/browser/extension/options/ContextMenuGroup.tsx rename to extension/src/options/ContextMenuGroup.tsx diff --git a/extension/src/browser/extension/options/EditorGroup.tsx b/extension/src/options/EditorGroup.tsx similarity index 97% rename from extension/src/browser/extension/options/EditorGroup.tsx rename to extension/src/options/EditorGroup.tsx index 130ef824..9b21097e 100644 --- a/extension/src/browser/extension/options/EditorGroup.tsx +++ b/extension/src/options/EditorGroup.tsx @@ -23,7 +23,7 @@ export default ({ options, saveOption }: OptionsProps) => { diff --git a/extension/src/browser/extension/options/FilterGroup.tsx b/extension/src/options/FilterGroup.tsx similarity index 97% rename from extension/src/browser/extension/options/FilterGroup.tsx rename to extension/src/options/FilterGroup.tsx index 56c050f1..792ca9f4 100644 --- a/extension/src/browser/extension/options/FilterGroup.tsx +++ b/extension/src/options/FilterGroup.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { FilterState } from '../../../app/api/filters'; +import { FilterState } from '../pageScript/api/filters'; import { OptionsProps } from './Options'; export default ({ options, saveOption }: OptionsProps) => { diff --git a/extension/src/browser/extension/options/MiscellaneousGroup.tsx b/extension/src/options/MiscellaneousGroup.tsx similarity index 90% rename from extension/src/browser/extension/options/MiscellaneousGroup.tsx rename to extension/src/options/MiscellaneousGroup.tsx index 1c3c9a05..f1301d40 100644 --- a/extension/src/browser/extension/options/MiscellaneousGroup.tsx +++ b/extension/src/options/MiscellaneousGroup.tsx @@ -2,10 +2,6 @@ import React from 'react'; import { OptionsProps } from './Options'; export default ({ options, saveOption }: OptionsProps) => { - const browserName = navigator.userAgent.includes('Firefox') - ? 'Firefox' - : 'Chrome'; - return (
Miscellaneous @@ -46,7 +42,7 @@ export default ({ options, saveOption }: OptionsProps) => { Show errors
- Show the {browserName} notifications when errors occur in the app + Show the browser notifications when errors occur in the app
diff --git a/extension/src/browser/extension/options/Options.tsx b/extension/src/options/Options.tsx similarity index 100% rename from extension/src/browser/extension/options/Options.tsx rename to extension/src/options/Options.tsx diff --git a/extension/src/browser/extension/options/index.tsx b/extension/src/options/index.tsx similarity index 95% rename from extension/src/browser/extension/options/index.tsx rename to extension/src/options/index.tsx index b344b86b..181fa1b1 100644 --- a/extension/src/browser/extension/options/index.tsx +++ b/extension/src/options/index.tsx @@ -3,7 +3,7 @@ import { createRoot } from 'react-dom/client'; import OptionsComponent from './Options'; import { Options } from './syncOptions'; -import '../../views/options.pug'; +import './options.pug'; chrome.runtime.getBackgroundPage((background) => { const syncOptions = background!.syncOptions; diff --git a/extension/src/browser/views/options.pug b/extension/src/options/options.pug similarity index 95% rename from extension/src/browser/views/options.pug rename to extension/src/options/options.pug index 6e2dda01..48192b6a 100644 --- a/extension/src/browser/views/options.pug +++ b/extension/src/options/options.pug @@ -1,93 +1,93 @@ -doctype html - -html - head - meta(charset='UTF-8') - title Redux DevTools Options - style. - body { - padding: 2px; - min-width: 380px; - } - - .option-group { - /* Reset the default fieldset styles */ - margin: initial; - border: initial; - padding: initial; - } - - .option-group + .option-group { - margin-top: 30px; - } - - .option-group__title { - /* Reset the default legend styles */ - margin: initial; - padding: initial; - - margin-bottom: 8px; - font-weight: bold; - font-size: 30px; - } - - .option + .option { - margin-top: 5px; - } - - .option__textarea { - margin-top: 2px; - width: 300px; - min-height: 50px; - } - - .option__hint { - margin-top: 2px; - font-size: 10px; - } - - .option__textarea + .option__hint { - margin-top: -2px; - } - - /* Checkbox and radio styling */ - .option_type_checkbox .option__element, - .option_type_radio .option__element { - vertical-align: bottom; - } - - .option_type_checkbox .option__label, - .option_type_radio .option__label { - margin-left: 4px; - } - - .option_type_checkbox .option__textarea, - .option_type_checkbox .option__hint, - .option_type_radio .option__textarea, - .option_type_radio .option__hint { - margin-left: 20px; - } - - - /* Checkbox styling */ - .option_type_checkbox .option__element { - /* Checkboxes in Chrome are 2px narrower than radio buttons. - These margins align them. */ - margin-left: 1px; - /* ...margin-right is 2px instead of 1px - because both radios and checkboxes have initial margin-right of 1px */ - margin-right: 2px; - } - - /* Value-based styling */ - .option_value_max-age { - margin-left: 20px; - } - - .option_value_max-age .option__element { - width: 50px; - } - - body - #root - script(src='/options.bundle.js') +doctype html + +html + head + meta(charset='UTF-8') + title Redux DevTools Options + style. + body { + padding: 2px; + min-width: 380px; + } + + .option-group { + /* Reset the default fieldset styles */ + margin: initial; + border: initial; + padding: initial; + } + + .option-group + .option-group { + margin-top: 30px; + } + + .option-group__title { + /* Reset the default legend styles */ + margin: initial; + padding: initial; + + margin-bottom: 8px; + font-weight: bold; + font-size: 30px; + } + + .option + .option { + margin-top: 5px; + } + + .option__textarea { + margin-top: 2px; + width: 300px; + min-height: 50px; + } + + .option__hint { + margin-top: 2px; + font-size: 10px; + } + + .option__textarea + .option__hint { + margin-top: -2px; + } + + /* Checkbox and radio styling */ + .option_type_checkbox .option__element, + .option_type_radio .option__element { + vertical-align: bottom; + } + + .option_type_checkbox .option__label, + .option_type_radio .option__label { + margin-left: 4px; + } + + .option_type_checkbox .option__textarea, + .option_type_checkbox .option__hint, + .option_type_radio .option__textarea, + .option_type_radio .option__hint { + margin-left: 20px; + } + + + /* Checkbox styling */ + .option_type_checkbox .option__element { + /* Checkboxes in Chrome are 2px narrower than radio buttons. + These margins align them. */ + margin-left: 1px; + /* ...margin-right is 2px instead of 1px + because both radios and checkboxes have initial margin-right of 1px */ + margin-right: 2px; + } + + /* Value-based styling */ + .option_value_max-age { + margin-left: 20px; + } + + .option_value_max-age .option__element { + width: 50px; + } + + body + #root + script(src='/options.bundle.js') diff --git a/extension/src/browser/extension/options/syncOptions.ts b/extension/src/options/syncOptions.ts similarity index 98% rename from extension/src/browser/extension/options/syncOptions.ts rename to extension/src/options/syncOptions.ts index ede4b150..e523c598 100644 --- a/extension/src/browser/extension/options/syncOptions.ts +++ b/extension/src/options/syncOptions.ts @@ -1,4 +1,4 @@ -import { FilterState, FilterStateValue } from '../../../app/api/filters'; +import { FilterState, FilterStateValue } from '../pageScript/api/filters'; export interface Options { readonly useEditor: number; diff --git a/extension/src/app/service/Monitor.ts b/extension/src/pageScript/Monitor.ts similarity index 100% rename from extension/src/app/service/Monitor.ts rename to extension/src/pageScript/Monitor.ts diff --git a/extension/src/app/api/filters.ts b/extension/src/pageScript/api/filters.ts similarity index 100% rename from extension/src/app/api/filters.ts rename to extension/src/pageScript/api/filters.ts diff --git a/extension/src/app/api/generateInstanceId.ts b/extension/src/pageScript/api/generateInstanceId.ts similarity index 100% rename from extension/src/app/api/generateInstanceId.ts rename to extension/src/pageScript/api/generateInstanceId.ts diff --git a/extension/src/app/api/importState.ts b/extension/src/pageScript/api/importState.ts similarity index 95% rename from extension/src/app/api/importState.ts rename to extension/src/pageScript/api/importState.ts index 70bda05e..ae818149 100644 --- a/extension/src/app/api/importState.ts +++ b/extension/src/pageScript/api/importState.ts @@ -1,9 +1,6 @@ import jsan from 'jsan'; import { immutableSerialize } from '@redux-devtools/serialize'; -import { - Config, - SerializeWithImmutable, -} from '../../browser/extension/inject/pageScript'; +import type { Config, SerializeWithImmutable } from '../index'; import Immutable from 'immutable'; import { LiftedState } from '@redux-devtools/instrument'; import { Action } from 'redux'; diff --git a/extension/src/app/api/index.ts b/extension/src/pageScript/api/index.ts similarity index 99% rename from extension/src/app/api/index.ts rename to extension/src/pageScript/api/index.ts index e0e6c3a9..ed062fe9 100644 --- a/extension/src/app/api/index.ts +++ b/extension/src/pageScript/api/index.ts @@ -5,15 +5,15 @@ import { getActionsArray, getLocalFilter } from '@redux-devtools/utils'; import { isFiltered, PartialLiftedState } from './filters'; import importState from './importState'; import generateId from './generateInstanceId'; -import { Config } from '../../browser/extension/inject/pageScript'; +import type { Config } from '../index'; import { Action } from 'redux'; import { LiftedState, PerformAction } from '@redux-devtools/instrument'; import { LibConfig } from '@redux-devtools/app'; -import { +import type { ContentScriptToPageScriptMessage, ListenerMessage, -} from '../../browser/extension/inject/contentScript'; -import { Position } from './openWindow'; +} from '../../contentScript'; +import type { Position } from './openWindow'; const listeners: { [instanceId: string]: diff --git a/extension/src/app/api/notifyErrors.ts b/extension/src/pageScript/api/notifyErrors.ts similarity index 100% rename from extension/src/app/api/notifyErrors.ts rename to extension/src/pageScript/api/notifyErrors.ts diff --git a/extension/src/app/api/openWindow.ts b/extension/src/pageScript/api/openWindow.ts similarity index 86% rename from extension/src/app/api/openWindow.ts rename to extension/src/pageScript/api/openWindow.ts index 51f9d145..53704b58 100644 --- a/extension/src/app/api/openWindow.ts +++ b/extension/src/pageScript/api/openWindow.ts @@ -1,5 +1,5 @@ import { Action } from 'redux'; -import { PageScriptToContentScriptMessage } from './index'; +import type { PageScriptToContentScriptMessage } from './index'; export type Position = 'left' | 'right' | 'bottom' | 'panel' | 'remote'; diff --git a/extension/src/app/stores/enhancerStore.ts b/extension/src/pageScript/enhancerStore.ts similarity index 93% rename from extension/src/app/stores/enhancerStore.ts rename to extension/src/pageScript/enhancerStore.ts index 532cfccb..5961292f 100644 --- a/extension/src/app/stores/enhancerStore.ts +++ b/extension/src/pageScript/enhancerStore.ts @@ -1,7 +1,7 @@ import { Action, compose, Reducer, StoreEnhancerStoreCreator } from 'redux'; import { instrument } from '@redux-devtools/instrument'; import { persistState } from '@redux-devtools/core'; -import { ConfigWithExpandedMaxAge } from '../../browser/extension/inject/pageScript'; +import type { ConfigWithExpandedMaxAge } from './index'; export function getUrlParam(key: string) { const matches = window.location.href.match( diff --git a/extension/src/browser/extension/inject/pageScript.ts b/extension/src/pageScript/index.ts similarity index 96% rename from extension/src/browser/extension/inject/pageScript.ts rename to extension/src/pageScript/index.ts index a0d48399..4b6bfb35 100644 --- a/extension/src/browser/extension/inject/pageScript.ts +++ b/extension/src/pageScript/index.ts @@ -27,19 +27,19 @@ import { LibConfig, Features, } from '@redux-devtools/app'; -import configureStore, { getUrlParam } from '../../../app/stores/enhancerStore'; +import configureStore, { getUrlParam } from './enhancerStore'; import { isAllowed, Options } from '../options/syncOptions'; -import Monitor from '../../../app/service/Monitor'; +import Monitor from './Monitor'; import { noFiltersApplied, isFiltered, filterState, startingFrom, -} from '../../../app/api/filters'; -import notifyErrors from '../../../app/api/notifyErrors'; -import importState from '../../../app/api/importState'; -import openWindow, { Position } from '../../../app/api/openWindow'; -import generateId from '../../../app/api/generateInstanceId'; +} from './api/filters'; +import notifyErrors from './api/notifyErrors'; +import importState from './api/importState'; +import openWindow, { Position } from './api/openWindow'; +import generateId from './api/generateInstanceId'; import { toContentScript, sendMessage, @@ -51,8 +51,8 @@ import { Serialize, StructuralPerformAction, ConnectResponse, -} from '../../../app/api'; -import { ContentScriptToPageScriptMessage } from './contentScript'; +} from './api'; +import type { ContentScriptToPageScriptMessage } from '../contentScript'; type EnhancedStoreWithInitialDispatch< S, @@ -539,10 +539,14 @@ function __REDUX_DEVTOOLS_EXTENSION__>( return next(reducer_, initialState_); } - store = stores[instanceId] = configureStore(next, monitor.reducer, { - ...config, - maxAge: getMaxAge as any, - })(reducer_, initialState_) as any; + store = stores[instanceId] = configureStore( + next as StoreEnhancerStoreCreator, + monitor.reducer, + { + ...config, + maxAge: getMaxAge as any, + } + )(reducer_, initialState_) as any; if (isInIframe()) setTimeout(init, 3000); else init(); diff --git a/extension/src/browser/extension/inject/pageScriptWrap.ts b/extension/src/pageScriptWrap.ts similarity index 87% rename from extension/src/browser/extension/inject/pageScriptWrap.ts rename to extension/src/pageScriptWrap.ts index 3c7f5147..ae1da249 100644 --- a/extension/src/browser/extension/inject/pageScriptWrap.ts +++ b/extension/src/pageScriptWrap.ts @@ -2,7 +2,7 @@ let s = document.createElement('script'); s.type = 'text/javascript'; if (process.env.NODE_ENV === 'production') { - const { default: script } = require('raw-loader!tmp/page.bundle.js'); + const { default: script } = require('raw-loader!../dist/page.bundle.js'); s.appendChild(document.createTextNode(script)); (document.head || document.documentElement).appendChild(s); s.parentNode!.removeChild(s); diff --git a/extension/src/browser/extension/window/remote.tsx b/extension/src/remote/index.tsx similarity index 96% rename from extension/src/browser/extension/window/remote.tsx rename to extension/src/remote/index.tsx index f91c372a..af100aca 100644 --- a/extension/src/browser/extension/window/remote.tsx +++ b/extension/src/remote/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; import { Root } from '@redux-devtools/app'; -import '../../views/remote.pug'; +import './remote.pug'; chrome.storage.local.get( { diff --git a/extension/src/browser/views/remote.pug b/extension/src/remote/remote.pug similarity index 78% rename from extension/src/browser/views/remote.pug rename to extension/src/remote/remote.pug index c70bc7f5..259bd8f4 100644 --- a/extension/src/browser/views/remote.pug +++ b/extension/src/remote/remote.pug @@ -1,11 +1,11 @@ -doctype html - -html - head - meta(charset='UTF-8') - title RemoteDev - include ./includes/style.pug - - body - #root - script(src='/remote.bundle.js') +doctype html + +html + head + meta(charset='UTF-8') + title RemoteDev + include ../style.pug + + body + #root + script(src='/remote.bundle.js') diff --git a/extension/src/browser/views/includes/style.pug b/extension/src/style.pug similarity index 95% rename from extension/src/browser/views/includes/style.pug rename to extension/src/style.pug index a98b4769..ad4498a7 100644 --- a/extension/src/browser/views/includes/style.pug +++ b/extension/src/style.pug @@ -7,7 +7,7 @@ style. overflow: hidden; height: 100%; width: 100%; - min-width: 350px; + min-width: 760px; min-height: 400px; margin: 0; padding: 0; @@ -17,6 +17,7 @@ style. color: #fff; } #root { + min-width: 760px; height: 100%; } #root > div { diff --git a/extension/src/browser/extension/window/index.tsx b/extension/src/window/index.tsx similarity index 84% rename from extension/src/browser/extension/window/index.tsx rename to extension/src/window/index.tsx index 41b72b08..c74e33a1 100644 --- a/extension/src/browser/extension/window/index.tsx +++ b/extension/src/window/index.tsx @@ -3,11 +3,11 @@ import { createRoot } from 'react-dom/client'; import { Provider } from 'react-redux'; import { PersistGate } from 'redux-persist/integration/react'; import { UPDATE_STATE } from '@redux-devtools/app'; -import App from '../../../app/containers/App'; -import configureStore from '../../../app/stores/windowStore'; -import { MonitorMessage } from '../../../app/middlewares/api'; +import App from '../app/App'; +import configureStore from './store/windowStore'; +import type { MonitorMessage } from '../background/store/apiMiddleware'; -import '../../views/window.pug'; +import './window.pug'; const position = location.hash; diff --git a/extension/src/app/middlewares/instanceSelector.ts b/extension/src/window/store/instanceSelectorMiddleware.ts similarity index 100% rename from extension/src/app/middlewares/instanceSelector.ts rename to extension/src/window/store/instanceSelectorMiddleware.ts diff --git a/extension/src/app/reducers/window/instances.ts b/extension/src/window/store/instancesReducer.ts similarity index 94% rename from extension/src/app/reducers/window/instances.ts rename to extension/src/window/store/instancesReducer.ts index 6ef0cad3..cc39478b 100644 --- a/extension/src/app/reducers/window/instances.ts +++ b/extension/src/window/store/instancesReducer.ts @@ -6,10 +6,10 @@ import { LIFTED_ACTION, SET_PERSIST, } from '@redux-devtools/app'; -import { +import type { ExpandedUpdateStateAction, WindowStoreAction, -} from '../../stores/windowStore'; +} from './windowStore'; export default function instances( state = instancesInitialState, diff --git a/extension/src/app/reducers/window/index.ts b/extension/src/window/store/windowReducer.ts similarity index 80% rename from extension/src/app/reducers/window/index.ts rename to extension/src/window/store/windowReducer.ts index 3ec4ddf3..9a14cd3b 100644 --- a/extension/src/app/reducers/window/index.ts +++ b/extension/src/window/store/windowReducer.ts @@ -9,8 +9,8 @@ import { theme, StoreState, } from '@redux-devtools/app'; -import instances from './instances'; -import { WindowStoreAction } from '../../stores/windowStore'; +import instances from './instancesReducer'; +import type { WindowStoreAction } from './windowStore'; const rootReducer: Reducer = combineReducers({ diff --git a/extension/src/app/stores/windowStore.ts b/extension/src/window/store/windowStore.ts similarity index 81% rename from extension/src/app/stores/windowStore.ts rename to extension/src/window/store/windowStore.ts index 186203ab..f63002ae 100644 --- a/extension/src/app/stores/windowStore.ts +++ b/extension/src/window/store/windowStore.ts @@ -17,12 +17,15 @@ import { StoreState, UpdateStateAction, } from '@redux-devtools/app'; -import syncStores from '../middlewares/windowSync'; -import instanceSelector from '../middlewares/instanceSelector'; -import rootReducer from '../reducers/window'; -import { BackgroundState } from '../reducers/background'; -import { BackgroundAction } from './backgroundStore'; -import { EmptyUpdateStateAction, NAAction } from '../middlewares/api'; +import syncStores from './windowSyncMiddleware'; +import instanceSelector from './instanceSelectorMiddleware'; +import rootReducer from './windowReducer'; +import type { BackgroundState } from '../../background/store/backgroundReducer'; +import type { BackgroundAction } from '../../background/store/backgroundStore'; +import type { + EmptyUpdateStateAction, + NAAction, +} from '../../background/store/apiMiddleware'; export interface ExpandedUpdateStateAction extends UpdateStateAction { readonly instances: InstancesState; diff --git a/extension/src/app/middlewares/windowSync.ts b/extension/src/window/store/windowSyncMiddleware.ts similarity index 80% rename from extension/src/app/middlewares/windowSync.ts rename to extension/src/window/store/windowSyncMiddleware.ts index e6c2c599..6f9f9cf7 100644 --- a/extension/src/app/middlewares/windowSync.ts +++ b/extension/src/window/store/windowSyncMiddleware.ts @@ -7,9 +7,9 @@ import { UPDATE_STATE, } from '@redux-devtools/app'; import { Dispatch, MiddlewareAPI, Store } from 'redux'; -import { BackgroundState } from '../reducers/background'; -import { WindowStoreAction } from '../stores/windowStore'; -import { BackgroundAction } from '../stores/backgroundStore'; +import type { BackgroundState } from '../../background/store/backgroundReducer'; +import type { WindowStoreAction } from './windowStore'; +import type { BackgroundAction } from '../../background/store/backgroundStore'; const syncStores = (baseStore: Store) => diff --git a/extension/src/browser/views/window.pug b/extension/src/window/window.pug similarity index 89% rename from extension/src/browser/views/window.pug rename to extension/src/window/window.pug index 4ea83033..630a3edf 100644 --- a/extension/src/browser/views/window.pug +++ b/extension/src/window/window.pug @@ -1,17 +1,17 @@ -doctype html - -html - head - meta(charset='UTF-8') - title Redux DevTools - include ./includes/style.pug - - body - #root - div(style='position: relative') - img( - src='/img/loading.svg', - height=300, width=350, - style='position: absolute; top: 50%; left: 50%; margin-top: -175px; margin-left: -175px;' - ) - script(src='/window.bundle.js') +doctype html + +html + head + meta(charset='UTF-8') + title Redux DevTools + include ../style.pug + + body + #root + div(style='position: relative') + img( + src='/img/loading.svg', + height=300, width=350, + style='position: absolute; top: 50%; left: 50%; margin-top: -175px; margin-left: -175px;' + ) + script(src='/window.bundle.js') diff --git a/extension/test/app/containers/App.spec.js b/extension/test/app/containers/App.spec.js index 971789d7..26725311 100644 --- a/extension/test/app/containers/App.spec.js +++ b/extension/test/app/containers/App.spec.js @@ -1,8 +1,8 @@ import React from 'react'; import { render, screen, within } from '@testing-library/react'; import { Provider } from 'react-redux'; -import configureStore from '../../../src/app/stores/windowStore'; -import App from '../../../src/app/containers/App'; +import configureStore from '../../../src/window/store/windowStore'; +import App from '../../../src/app/App'; Object.defineProperty(window, 'matchMedia', { writable: true, @@ -18,7 +18,7 @@ Object.defineProperty(window, 'matchMedia', { })), }); -const { store } = configureStore(store); +const { store } = configureStore(); describe('App container', () => { it("should render inspector monitor's component", () => { diff --git a/extension/test/app/inject/api.spec.js b/extension/test/app/inject/api.spec.js index 0b30f33e..0a06d321 100644 --- a/extension/test/app/inject/api.spec.js +++ b/extension/test/app/inject/api.spec.js @@ -1,5 +1,5 @@ import { insertScript, listenMessage } from '../../utils/inject'; -import '../../../src/browser/extension/inject/pageScript'; +import '../../../src/pageScript'; describe('API', () => { it('should get window.__REDUX_DEVTOOLS_EXTENSION__ function', () => { diff --git a/extension/test/app/inject/enhancer.spec.js b/extension/test/app/inject/enhancer.spec.js index 49229474..c4ce2b88 100644 --- a/extension/test/app/inject/enhancer.spec.js +++ b/extension/test/app/inject/enhancer.spec.js @@ -1,7 +1,7 @@ import '@babel/polyfill'; import { createStore, compose } from 'redux'; import { insertScript, listenMessage } from '../../utils/inject'; -import '../../../src/browser/extension/inject/pageScript'; +import '../../../src/pageScript'; function counter(state = 0, action) { switch (action.type) { diff --git a/extension/test/chrome/extension.spec.js b/extension/test/chrome/extension.spec.js index d3082167..94e2ac60 100644 --- a/extension/test/chrome/extension.spec.js +++ b/extension/test/chrome/extension.spec.js @@ -5,7 +5,7 @@ import chromedriver from 'chromedriver'; import { switchMonitorTests, delay } from '../utils/e2e'; const port = 9515; -const path = resolve(__dirname, '..', '..', 'build', 'extension'); +const path = resolve(__dirname, '..', '..', 'dist'); const extensionId = 'lmhkpmbekcpmknklioeibfkpmmfibljd'; const actionsPattern = /^@@INIT(.|\n)+@@reduxReactRouter\/routerDidChange(.|\n)+@@reduxReactRouter\/initRoutes(.|\n)+$/; diff --git a/extension/test/electron/fixture/main.js b/extension/test/electron/fixture/main.js index 9d56953c..6bf7c2ef 100644 --- a/extension/test/electron/fixture/main.js +++ b/extension/test/electron/fixture/main.js @@ -4,7 +4,7 @@ const { app, BrowserWindow, session } = require('electron'); app.on('window-all-closed', app.quit); app.whenReady().then(async () => { await session.defaultSession.loadExtension( - path.join(__dirname, '../../../build/extension'), + path.join(__dirname, '../../../dist'), { allowFileAccess: true } ); diff --git a/extension/webpack.config.js b/extension/webpack.config.js new file mode 100644 index 00000000..9e31302e --- /dev/null +++ b/extension/webpack.config.js @@ -0,0 +1,81 @@ +const path = require('path'); +const webpack = require('webpack'); +const CopyPlugin = require('copy-webpack-plugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = function (env) { + return { + mode: env.production ? 'production' : 'development', + devtool: env.production ? undefined : 'eval-source-map', + entry: { + background: [ + path.resolve(__dirname, 'src/chromeApiMock'), + path.resolve(__dirname, 'src/background/index'), + ], + options: [ + path.resolve(__dirname, 'src/chromeApiMock'), + path.resolve(__dirname, 'src/options/index'), + ], + window: [path.resolve(__dirname, 'src/window/index')], + remote: [path.resolve(__dirname, 'src/remote/index')], + devpanel: [ + path.resolve(__dirname, 'src/chromeApiMock'), + path.resolve(__dirname, 'src/devpanel/index'), + ], + devtools: path.resolve(__dirname, 'src/devtools/index'), + content: [ + path.resolve(__dirname, 'src/chromeApiMock'), + path.resolve(__dirname, 'src/contentScript/index'), + ], + page: path.join(__dirname, 'src/pageScript'), + ...(env.production + ? {} + : { pagewrap: path.resolve(__dirname, 'src/pageScriptWrap') }), + }, + output: { + filename: '[name].bundle.js', + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env.BABEL_ENV': JSON.stringify(process.env.NODE_ENV), + }), + new ForkTsCheckerWebpackPlugin({ + typescript: { + configFile: 'tsconfig.json', + }, + }), + new CopyPlugin({ + patterns: [ + { + from: path.join(__dirname, 'chrome/manifest.json'), + to: path.join(__dirname, 'dist/manifest.json'), + }, + { + from: path.join(__dirname, 'src/assets'), + to: path.join(__dirname, 'dist'), + }, + ], + }), + ], + resolve: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + module: { + rules: [ + { + test: /\.(js|ts)x?$/, + use: 'babel-loader', + exclude: /node_modules/, + }, + { + test: /\.css?$/, + use: ['style-loader', 'css-loader'], + }, + { + test: /\.pug$/, + use: ['file-loader?name=[name].html', 'pug-html-loader'], + }, + ], + }, + }; +}; diff --git a/extension/webpack/base.config.js b/extension/webpack/base.config.js deleted file mode 100644 index b320b890..00000000 --- a/extension/webpack/base.config.js +++ /dev/null @@ -1,91 +0,0 @@ -import path from 'path'; -import webpack from 'webpack'; -import CopyPlugin from 'copy-webpack-plugin'; -import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; - -const extpath = path.join(__dirname, '../src/browser/extension/'); -const mock = `${extpath}chromeAPIMock`; - -const baseConfig = (params) => ({ - // devtool: 'source-map', - mode: params.mode, - entry: params.input || { - background: [mock, `${extpath}background/index`], - options: [mock, `${extpath}options/index`], - window: [`${extpath}window/index`], - remote: [`${extpath}window/remote`], - devpanel: [mock, `${extpath}devpanel/index`], - devtools: [`${extpath}devtools/index`], - content: [mock, `${extpath}inject/contentScript`], - pagewrap: [`${extpath}inject/pageScriptWrap`], - ...params.inputExtra, - }, - output: { - filename: '[name].bundle.js', - chunkFilename: '[id].chunk.js', - ...params.output, - }, - plugins: [ - new webpack.DefinePlugin(params.globals), - ...(params.plugins - ? params.plugins - : [ - new ForkTsCheckerWebpackPlugin({ - typescript: { - configFile: 'tsconfig.json', - }, - }), - ]), - ].concat( - params.copy - ? new CopyPlugin({ - patterns: [ - { - from: params.manifestJsonPath, - to: path.join(params.output.path, 'manifest.json'), - }, - { - from: path.join(__dirname, '../src/assets/'), - to: params.output.path, - }, - ], - }) - : [] - ), - performance: { - hints: false, - }, - resolve: { - alias: { - app: path.join(__dirname, '../src/app'), - tmp: path.join(__dirname, '../build/tmp'), - }, - extensions: ['.js', '.jsx', '.ts', '.tsx'], - fallback: { - path: require.resolve('path-browserify'), - }, - }, - module: { - rules: [ - ...(params.loaders - ? params.loaders - : [ - { - test: /\.(js|ts)x?$/, - use: 'babel-loader', - exclude: /(node_modules|tmp\/page\.bundle)/, - }, - ]), - { - test: /\.css?$/, - use: ['style-loader', 'css-loader'], - }, - { - test: /\.pug$/, - use: ['file-loader?name=[name].html', 'pug-html-loader'], - }, - ], - }, -}); - -export default baseConfig; diff --git a/extension/webpack/dev.config.babel.js b/extension/webpack/dev.config.babel.js deleted file mode 100644 index cca1fa78..00000000 --- a/extension/webpack/dev.config.babel.js +++ /dev/null @@ -1,26 +0,0 @@ -import path from 'path'; -import webpack from 'webpack'; -import baseConfig from './base.config'; - -let config = baseConfig({ - mode: 'development', - inputExtra: { - page: [path.join(__dirname, '../src/browser/extension/inject/pageScript')], - }, - output: { path: path.join(__dirname, '../dev') }, - globals: { - 'process.env': { - NODE_ENV: '"development"', - }, - }, - plugins: [new webpack.NoEmitOnErrorsPlugin()], - copy: true, - manifestJsonPath: path.join( - __dirname, - '../src/browser/extension/manifest.json' - ), -}); - -config.watch = true; - -export default config; diff --git a/extension/webpack/prod.config.babel.js b/extension/webpack/prod.config.babel.js deleted file mode 100644 index ff04e735..00000000 --- a/extension/webpack/prod.config.babel.js +++ /dev/null @@ -1,20 +0,0 @@ -import path from 'path'; -import baseConfig from './base.config'; - -export default baseConfig({ - mode: 'production', - inputExtra: { - page: [path.join(__dirname, '../src/browser/extension/inject/pageScript')], - }, - output: { path: path.join(__dirname, '../build/extension') }, - globals: { - 'process.env': { - NODE_ENV: '"production"', - }, - }, - copy: true, - manifestJsonPath: path.join( - __dirname, - '../src/browser/extension/manifest.json' - ), -}); diff --git a/extension/webpack/prod.firefox.config.babel.js b/extension/webpack/prod.firefox.config.babel.js deleted file mode 100644 index 54fdf8b9..00000000 --- a/extension/webpack/prod.firefox.config.babel.js +++ /dev/null @@ -1,17 +0,0 @@ -import path from 'path'; -import baseConfig from './base.config'; - -export default baseConfig({ - mode: 'production', - output: { path: path.join(__dirname, '../build/extension') }, - globals: { - 'process.env': { - NODE_ENV: '"production"', - }, - }, - copy: true, - manifestJsonPath: path.join( - __dirname, - '../src/browser/firefox/manifest.json' - ), -}); diff --git a/extension/webpack/wrap.config.babel.js b/extension/webpack/wrap.config.babel.js deleted file mode 100644 index 25b57d11..00000000 --- a/extension/webpack/wrap.config.babel.js +++ /dev/null @@ -1,15 +0,0 @@ -import path from 'path'; -import baseConfig from './base.config'; - -export default baseConfig({ - mode: 'production', - input: { - page: [path.join(__dirname, '../src/browser/extension/inject/pageScript')], - }, - output: { path: path.join(__dirname, '../build/tmp') }, - globals: { - 'process.env': { - NODE_ENV: '"production"', - }, - }, -}); diff --git a/extension/wrap.webpack.config.js b/extension/wrap.webpack.config.js new file mode 100644 index 00000000..1eb38ca1 --- /dev/null +++ b/extension/wrap.webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + mode: 'production', + entry: { + pagewrap: path.resolve(__dirname, 'src/pageScriptWrap'), + }, + output: { + filename: '[name].bundle.js', + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + typescript: { + configFile: 'tsconfig.json', + }, + }), + ], + resolve: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + module: { + rules: [ + { + test: /\.(js|ts)x?$/, + use: 'babel-loader', + exclude: /(node_modules|dist\/page\.bundle)/, + }, + ], + }, +}; diff --git a/package.json b/package.json index 53df58cf..12d3fbdd 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,29 @@ { "private": true, "devDependencies": { - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@changesets/cli": "^2.23.0", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@changesets/cli": "^2.26.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "jest": "^27.5.1", - "prettier": "2.7.1", - "typescript": "~4.7.4", - "nx": "^14.3.6", - "@nrwl/nx-cloud": "^14.1.2" + "jest": "^29.3.1", + "prettier": "2.8.1", + "typescript": "~4.9.4", + "nx": "^15.3.3", + "@nrwl/nx-cloud": "^15.0.2" }, "scripts": { "format": "prettier --write .", "format:check": "prettier --check .", - "build:all": "nx run-many --target=build --all", - "lint:all": "nx run-many --target=lint --all", - "test:all": "nx run-many --target=test --all", + "build:all": "nx run-many --target=build --all --parallel=1", + "lint:all": "nx run-many --target=lint --all --parallel=1", + "test:all": "nx run-many --target=test --all --parallel=1", + "clean:all": "nx run-many --target=clean --all --parallel=1", "release": "pnpm build:all && changeset publish" }, "workspaces": [ @@ -38,7 +39,7 @@ "packages/redux-devtools-rtk-query-monitor/demo", "packages/redux-devtools-slider-monitor/examples/todomvc" ], - "packageManager": "pnpm@7.3.0", + "packageManager": "pnpm@7.19.0", "pnpm": { "overrides": { "@babel/highlight>chalk": "Methuselah96/chalk#v2-without-process" diff --git a/packages/d3-state-visualizer/README.md b/packages/d3-state-visualizer/README.md index b74dc149..bb7cc2ca 100644 --- a/packages/d3-state-visualizer/README.md +++ b/packages/d3-state-visualizer/README.md @@ -35,7 +35,7 @@ const render = tree(document.getElementById('root'), { isSorted: false, widthBetweenNodesCoeff: 1.5, heightBetweenNodesCoeff: 2, - style: { border: '1px solid black' }, + chartStyles: { border: '1px solid black' }, tooltipOptions: { offset: { left: 30, top: 10 }, indentationSize: 2 }, }); @@ -61,7 +61,7 @@ Other options are listed below and have reasonable default values if you want to | Option | Type | Default | Description | | ------------------------- | ------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `id` | String | `'d3svg'` | Sets the identifier of the SVG element —i.e your chart— that will be added to the DOM element you passed as first argument | -| `style` | Object | `{}` | Sets the CSS style of the chart | +| `chartStyles` | Object | `{}` | Sets the CSS style of the chart | | `size` | Number | `500` | Sets size of the chart in pixels | | `aspectRatio` | Float | `1.0` | Sets the chart height to `size * aspectRatio` and [viewBox](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox) in order to preserve the aspect ratio of the chart. [Great video](https://www.youtube.com/watch?v=FCOeMy7HrBc) if you want to learn more about how SVG works | | `widthBetweenNodesCoeff` | Float | `1.0` | Alters the horizontal space between each node | @@ -74,12 +74,6 @@ Other options are listed below and have reasonable default values if you want to More to come... -## Bindings - -### React - -[example](https://github.com/reduxjs/redux-devtools/tree/master/packages/d3-state-visualizer/examples/react-tree) implementation. - ## Roadmap - Threshold for large arrays so only a single node is displayed instead of all the children. That single node would be exclude from searching until selected. diff --git a/packages/d3-state-visualizer/examples/tree/package.json b/packages/d3-state-visualizer/examples/tree/package.json index 0b08a7dc..5d2680a3 100644 --- a/packages/d3-state-visualizer/examples/tree/package.json +++ b/packages/d3-state-visualizer/examples/tree/package.json @@ -29,22 +29,22 @@ "map2tree": "^2.1.0" }, "devDependencies": { - "@babel/core": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-typescript": "^7.17.12", - "@types/node": "^16.11.41", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "babel-loader": "^8.2.5", + "@babel/core": "^7.20.5", + "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", + "@types/node": "^18.11.17", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "babel-loader": "^9.1.0", "cross-env": "^7.0.3", - "eslint": "^8.18.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "fork-ts-checker-webpack-plugin": "^7.2.11", + "fork-ts-checker-webpack-plugin": "^7.2.14", "html-webpack-plugin": "^5.5.0", - "ts-node": "^10.8.1", - "typescript": "~4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.2" + "ts-node": "^10.9.1", + "typescript": "~4.9.4", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" } } diff --git a/packages/d3-state-visualizer/examples/tree/src/index.ts b/packages/d3-state-visualizer/examples/tree/src/index.ts index 5e8cf5e6..8c06c327 100644 --- a/packages/d3-state-visualizer/examples/tree/src/index.ts +++ b/packages/d3-state-visualizer/examples/tree/src/index.ts @@ -28,7 +28,7 @@ const render = tree(document.getElementById('root')!, { isSorted: false, widthBetweenNodesCoeff: 1.5, heightBetweenNodesCoeff: 2, - style: { border: '1px solid black' }, + chartStyles: { border: '1px solid black' }, tooltipOptions: { offset: { left: 30, top: 10 }, indentationSize: 2 }, }); diff --git a/packages/d3-state-visualizer/package.json b/packages/d3-state-visualizer/package.json index db97f526..83d2d071 100644 --- a/packages/d3-state-visualizer/package.json +++ b/packages/d3-state-visualizer/package.json @@ -23,18 +23,16 @@ "main": "lib/cjs/index.js", "module": "lib/esm/index.js", "types": "lib/types/index.d.ts", - "unpkg": "dist/d3-state-visualizer.umd.js", "sideEffects": false, "repository": { "type": "git", "url": "https://github.com/reduxjs/redux-devtools.git" }, "scripts": { - "build": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:types && pnpm run build:umd", + "build": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:types", "build:cjs": "babel src --extensions \".ts\" --out-dir lib/cjs", "build:esm": "babel src --config-file ./babel.config.esm.json --extensions \".ts\" --out-dir lib/esm", "build:types": "tsc --emitDeclarationOnly", - "build:umd": "rollup -c", "clean": "rimraf lib", "lint": "eslint . --ext .ts", "type-check": "tsc --noEmit", @@ -42,35 +40,26 @@ "prepublish": "pnpm run type-check && pnpm run lint" }, "dependencies": { - "@babel/runtime": "^7.18.3", - "@types/d3": "^3.5.47", - "d3": "^3.5.17", + "@babel/runtime": "^7.20.6", + "@types/d3": "^7.4.0", + "d3": "^7.8.0", "d3tooltip": "^2.1.0", "deepmerge": "^4.2.2", "map2tree": "^2.1.0", "ramda": "^0.28.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-typescript": "^7.17.12", - "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-commonjs": "^22.0.0", - "@rollup/plugin-node-resolve": "^13.3.0", - "@types/node": "^16.11.41", - "@types/ramda": "^0.28.14", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", + "@types/ramda": "^0.28.20", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", "rimraf": "^3.0.2", - "rollup": "^2.75.6", - "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-typescript2": "^0.32.1", - "tslib": "^2.4.0", - "typescript": "~4.7.4" + "typescript": "~4.9.4" } } diff --git a/packages/d3-state-visualizer/rollup.config.js b/packages/d3-state-visualizer/rollup.config.js deleted file mode 100644 index 70ce4df1..00000000 --- a/packages/d3-state-visualizer/rollup.config.js +++ /dev/null @@ -1,51 +0,0 @@ -import typescript from 'rollup-plugin-typescript2'; -import resolve from '@rollup/plugin-node-resolve'; -import commonjs from '@rollup/plugin-commonjs'; -import babel from '@rollup/plugin-babel'; -import { terser } from 'rollup-plugin-terser'; - -const config = [ - { - input: 'src/index.ts', - output: { - name: 'd3-state-visualizer', - file: 'lib/umd/d3-state-visualizer.js', - format: 'umd', - }, - plugins: [ - typescript({ - tsconfigOverride: { compilerOptions: { declaration: false } }, - }), - resolve(), - commonjs(), - babel({ - babelHelpers: 'runtime', - extensions: ['.ts'], - plugins: ['@babel/plugin-transform-runtime'], - }), - ], - }, - { - input: 'src/index.ts', - output: { - name: 'd3-state-visualizer', - file: 'lib/umd/d3-state-visualizer.min.js', - format: 'umd', - }, - plugins: [ - typescript({ - tsconfigOverride: { compilerOptions: { declaration: false } }, - }), - resolve(), - commonjs(), - babel({ - babelHelpers: 'runtime', - extensions: ['.ts'], - plugins: ['@babel/plugin-transform-runtime'], - }), - terser(), - ], - }, -]; - -export default config; diff --git a/packages/d3-state-visualizer/src/charts/index.ts b/packages/d3-state-visualizer/src/charts/index.ts index fe78e795..90e07fa8 100644 --- a/packages/d3-state-visualizer/src/charts/index.ts +++ b/packages/d3-state-visualizer/src/charts/index.ts @@ -1,2 +1,4 @@ +export type { HierarchyPointNode } from 'd3'; +export type { StyleValue } from 'd3tooltip'; export { default as tree } from './tree/tree'; -export type { InputOptions, NodeWithId, Primitive } from './tree/tree'; +export type { Node, Options } from './tree/tree'; diff --git a/packages/d3-state-visualizer/src/charts/tree/tree.ts b/packages/d3-state-visualizer/src/charts/tree/tree.ts index e4b778d1..f3c38143 100644 --- a/packages/d3-state-visualizer/src/charts/tree/tree.ts +++ b/packages/d3-state-visualizer/src/charts/tree/tree.ts @@ -1,6 +1,8 @@ -import d3, { ZoomEvent, Primitive } from 'd3'; +import * as d3 from 'd3'; +import type { D3ZoomEvent, HierarchyPointLink, HierarchyPointNode } from 'd3'; import { isEmpty } from 'ramda'; import { map2tree } from 'map2tree'; +import type { Node } from 'map2tree'; import deepmerge from 'deepmerge'; import { getTooltipString, @@ -9,17 +11,33 @@ import { getNodeGroupByDepthCount, } from './utils'; import { tooltip } from 'd3tooltip'; +import type { StyleValue } from 'd3tooltip'; -export interface InputOptions { +export interface Options { // eslint-disable-next-line @typescript-eslint/ban-types state?: {} | null; // eslint-disable-next-line @typescript-eslint/ban-types - tree?: NodeWithId | {}; + tree?: Node | {}; rootKeyName: string; pushMethod: 'push' | 'unshift'; id: string; - style: { [key: string]: Primitive }; + chartStyles: { [key: string]: StyleValue }; + nodeStyleOptions: { + colors: { + default: string; + collapsed: string; + parent: string; + }; + radius: number; + }; + textStyleOptions: { + colors: { + default: string; + hover: string; + }; + }; + linkStyles: { [key: string]: StyleValue }; size: number; aspectRatio: number; initialZoom: number; @@ -34,7 +52,7 @@ export interface InputOptions { widthBetweenNodesCoeff: number; transitionDuration: number; blinkDuration: number; - onClickText: (datum: NodeWithId) => void; + onClickText: (datum: HierarchyPointNode) => void; tooltipOptions: { disabled?: boolean; left?: number | undefined; @@ -43,64 +61,7 @@ export interface InputOptions { left: number; top: number; }; - style?: { [key: string]: Primitive } | undefined; - indentationSize?: number; - }; -} - -interface Options { - // eslint-disable-next-line @typescript-eslint/ban-types - state?: {} | null; - // eslint-disable-next-line @typescript-eslint/ban-types - tree?: NodeWithId | {}; - - rootKeyName: string; - pushMethod: 'push' | 'unshift'; - id: string; - style: { - node: { - colors: { - default: string; - collapsed: string; - parent: string; - }; - radius: number; - }; - text: { - colors: { - default: string; - hover: string; - }; - }; - link: { - stroke: string; - fill: string; - }; - }; - size: number; - aspectRatio: number; - initialZoom: number; - margin: { - top: number; - right: number; - bottom: number; - left: number; - }; - isSorted: boolean; - heightBetweenNodesCoeff: number; - widthBetweenNodesCoeff: number; - transitionDuration: number; - blinkDuration: number; - onClickText: () => void; - tooltipOptions: { - disabled: boolean; - left: number | undefined; - top: number | undefined; - offset: { - left: number; - top: number; - }; - style: { [key: string]: Primitive } | undefined; + styles?: { [key: string]: StyleValue } | undefined; indentationSize?: number; }; } @@ -111,26 +72,25 @@ const defaultOptions: Options = { pushMethod: 'push', tree: undefined, id: 'd3svg', - style: { - node: { - colors: { - default: '#ccc', - collapsed: 'lightsteelblue', - parent: 'white', - }, - radius: 7, + chartStyles: {}, + nodeStyleOptions: { + colors: { + default: '#ccc', + collapsed: 'lightsteelblue', + parent: 'white', }, - text: { - colors: { - default: 'black', - hover: 'skyblue', - }, - }, - link: { - stroke: '#000', - fill: 'none', + radius: 7, + }, + textStyleOptions: { + colors: { + default: 'black', + hover: 'skyblue', }, }, + linkStyles: { + stroke: '#000', + fill: 'none', + }, size: 500, aspectRatio: 1.0, initialZoom: 1, @@ -156,37 +116,29 @@ const defaultOptions: Options = { left: 0, top: 0, }, - style: undefined, + styles: undefined, }, -}; +} satisfies Options; -export interface NodeWithId { - name: string; - children?: NodeWithId[] | null; - _children?: NodeWithId[] | null; - value?: unknown; - id: string; - - parent?: NodeWithId; - depth?: number; - x?: number; - y?: number; +export interface InternalNode extends Node { + _children?: this[] | undefined; + id: string | number; } interface NodePosition { - parentId: string | null | undefined; - id: string; - x: number | undefined; - y: number | undefined; + parentId: string | number | null; + id: string | number; + x: number; + y: number; } -export default function ( - DOMNode: HTMLElement, - options: Partial = {} -) { +export default function (DOMNode: HTMLElement, options: Partial = {}) { const { id, - style, + chartStyles, + nodeStyleOptions, + textStyleOptions, + linkStyles, size, aspectRatio, initialZoom, @@ -202,64 +154,50 @@ export default function ( tree, tooltipOptions, onClickText, - } = deepmerge(defaultOptions, options) as Options; + } = deepmerge(defaultOptions, options); const width = size - margin.left - margin.right; const height = size * aspectRatio - margin.top - margin.bottom; const fullWidth = size; const fullHeight = size * aspectRatio; - const attr: { [key: string]: Primitive } = { - id, - preserveAspectRatio: 'xMinYMin slice', - }; - - if (!(style as unknown as { [key: string]: Primitive }).width) { - attr.width = fullWidth; - } - - if ( - !(style as unknown as { [key: string]: Primitive }).width || - !(style as unknown as { [key: string]: Primitive }).height - ) { - attr.viewBox = `0 0 ${fullWidth} ${fullHeight}`; - } - const root = d3.select(DOMNode); - const zoom = d3.behavior.zoom().scaleExtent([0.1, 3]).scale(initialZoom); - const vis = root + const zoom = d3.zoom().scaleExtent([0.1, 3]); + + const svgElement = root .append('svg') - .attr(attr) - .style({ cursor: '-webkit-grab', ...style } as unknown as { - [key: string]: Primitive; - }) + .attr('id', id) + .attr('preserveAspectRatio', 'xMinYMin slice') + .style('cursor', '-webkit-grab'); + + if (!chartStyles.width) { + svgElement.attr('width', fullWidth); + } + + if (!chartStyles.width || !chartStyles.height) { + svgElement.attr('viewBox', `0 0 ${fullWidth} ${fullHeight}`); + } + + for (const [key, value] of Object.entries(chartStyles)) { + svgElement.style(key, value); + } + + const vis = svgElement + // eslint-disable-next-line @typescript-eslint/unbound-method + .call(zoom.scaleTo, initialZoom) .call( - zoom.on('zoom', () => { - const { translate, scale } = d3.event as ZoomEvent; - vis.attr( - 'transform', - `translate(${translate.toString()})scale(${scale})` - ); + zoom.on('zoom', (event) => { + const { transform } = event as D3ZoomEvent; + vis.attr('transform', transform.toString()); }) ) .append('g') - .attr({ - transform: `translate(${margin.left + style.node.radius}, ${ + .attr( + 'transform', + `translate(${margin.left + nodeStyleOptions.radius}, ${ margin.top - }) scale(${initialZoom})`, - }); - - let layout = d3.layout.tree().size([width, height]); - let data: NodeWithId; - - if (isSorted) { - layout.sort((a, b) => - (b as NodeWithId).name.toLowerCase() < - (a as NodeWithId).name.toLowerCase() - ? 1 - : -1 + }) scale(${initialZoom})` ); - } // previousNodePositionsById stores node x and y // as well as hierarchy (id / parentId); @@ -277,8 +215,8 @@ export default function ( // of parent ids; once a parent that matches the given filter is found, // the parent position gets returned function findParentNodePosition( - nodePositionsById: { [nodeId: string]: NodePosition }, - nodeId: string, + nodePositionsById: { [nodeId: string | number]: NodePosition }, + nodeId: string | number, filter: (nodePosition: NodePosition) => boolean ) { let currentPosition = nodePositionsById[nodeId]; @@ -294,19 +232,18 @@ export default function ( } return function renderChart(nextState = tree || state) { - data = !tree - ? // eslint-disable-next-line @typescript-eslint/ban-types - (map2tree(nextState as {}, { + let data = !tree + ? (map2tree(nextState, { key: rootKeyName, pushMethod, - }) as NodeWithId) - : (nextState as NodeWithId); + }) as InternalNode) + : (nextState as InternalNode); if (isEmpty(data) || !data.name) { data = { name: 'error', message: 'Please provide a state map or a tree structure', - } as unknown as NodeWithId; + } as unknown as InternalNode; } let nodeIndex = 0; @@ -334,76 +271,94 @@ export default function ( function update() { // path generator for links - const diagonal = d3.svg - .diagonal() - .projection((d) => [d.y!, d.x!]); + const linkHorizontal = d3 + .linkHorizontal< + { + source: { x: number; y: number }; + target: { x: number; y: number }; + }, + { x: number; y: number } + >() + .x((d) => d.y) + .y((d) => d.x); // set tree dimensions and spacing between branches and nodes const maxNodeCountByLevel = Math.max(...getNodeGroupByDepthCount(data)); - layout = layout.size([ - maxNodeCountByLevel * 25 * heightBetweenNodesCoeff, - width, - ]); + const layout = d3 + .tree() + .size([maxNodeCountByLevel * 25 * heightBetweenNodesCoeff, width]); - const nodes = layout.nodes(data as d3.layout.tree.Node) as NodeWithId[]; - const links = layout.links(nodes as d3.layout.tree.Node[]); + const rootNode = d3.hierarchy(data); + if (isSorted) { + rootNode.sort((a, b) => + b.data.name.toLowerCase() < a.data.name.toLowerCase() ? 1 : -1 + ); + } - nodes.forEach( + const rootPointNode = layout(rootNode); + const links = rootPointNode.links(); + + rootPointNode.each( (node) => - (node.y = node.depth! * (maxLabelLength * 7 * widthBetweenNodesCoeff)) + (node.y = node.depth * (maxLabelLength * 7 * widthBetweenNodesCoeff)) ); + const nodes = rootPointNode.descendants(); + const nodePositions = nodes.map((n) => ({ - parentId: n.parent && n.parent.id, - id: n.id, + parentId: n.parent && n.parent.data.id, + id: n.data.id, x: n.x, y: n.y, })); - const nodePositionsById: { [nodeId: string]: NodePosition } = {}; + const nodePositionsById: { [nodeId: string | number]: NodePosition } = {}; nodePositions.forEach((node) => (nodePositionsById[node.id] = node)); // process the node selection const node = vis - .selectAll('g.node') - .property('__oldData__', (d: NodeWithId) => d) - .data(nodes, (d) => d.id || (d.id = ++nodeIndex as unknown as string)); + .selectAll>('g.node') + .property('__oldData__', (d) => d) + .data(nodes, (d) => d.data.id || (d.data.id = ++nodeIndex)); const nodeEnter = node .enter() .append('g') - .attr({ - class: 'node', - transform: (d) => { - const position = findParentNodePosition( - nodePositionsById, - d.id, - (n) => !!previousNodePositionsById[n.id] - ); - const previousPosition = - (position && previousNodePositionsById[position.id]) || - previousNodePositionsById.root; - return `translate(${previousPosition.y!},${previousPosition.x!})`; - }, + .attr('class', 'node') + .attr('transform', (d) => { + const position = findParentNodePosition( + nodePositionsById, + d.data.id, + (n) => !!previousNodePositionsById[n.id] + ); + const previousPosition = + (position && previousNodePositionsById[position.id]) || + previousNodePositionsById.root; + return `translate(${previousPosition.y},${previousPosition.x})`; }) - .style({ - fill: style.text.colors.default, - cursor: 'pointer', + .style('fill', textStyleOptions.colors.default) + .style('cursor', 'pointer') + .on('mouseover', function mouseover() { + d3.select(this).style('fill', textStyleOptions.colors.hover); }) - .on('mouseover', function mouseover(this: EventTarget) { - d3.select(this).style({ - fill: style.text.colors.hover, - }); - }) - .on('mouseout', function mouseout(this: EventTarget) { - d3.select(this).style({ - fill: style.text.colors.default, - }); + .on('mouseout', function mouseout() { + d3.select(this).style('fill', textStyleOptions.colors.default); }); if (!tooltipOptions.disabled) { nodeEnter.call( - tooltip(d3, 'tooltip', { ...tooltipOptions, root }) - .text((d, i) => getTooltipString(d, i, tooltipOptions)) - .style(tooltipOptions.style) + tooltip< + SVGGElement, + HierarchyPointNode, + SVGGElement, + unknown, + HTMLElement, + unknown, + null, + undefined + >('tooltip', { + ...tooltipOptions, + root, + text: (d) => getTooltipString(d.data, tooltipOptions), + }) ); } @@ -412,77 +367,81 @@ export default function ( const nodeEnterInnerGroup = nodeEnter.append('g'); nodeEnterInnerGroup .append('circle') - .attr({ - class: 'nodeCircle', - r: 0, - }) - .on('click', (clickedNode) => { - if ((d3.event as Event).defaultPrevented) return; - toggleChildren(clickedNode); + .attr('class', 'nodeCircle') + .attr('r', 0) + .on('click', (event, clickedNode) => { + if ((event as Event).defaultPrevented) return; + toggleChildren(clickedNode.data); update(); }); nodeEnterInnerGroup .append('text') - .attr({ - class: 'nodeText', - 'text-anchor': 'middle', - transform: 'translate(0,0)', - dy: '.35em', - }) - .style({ - 'fill-opacity': 0, - }) - .text((d) => d.name) - .on('click', onClickText); - - // update the text to reflect whether node has children or not - node.select('text').text((d) => d.name); - - // change the circle fill depending on whether it has children and is collapsed - node.select('circle').style({ - stroke: 'black', - 'stroke-width': '1.5px', - fill: (d) => - d._children - ? style.node.colors.collapsed - : d.children - ? style.node.colors.parent - : style.node.colors.default, - }); - - // transition nodes to their new position - const nodeUpdate = node - .transition() - .duration(transitionDuration) - .attr({ - transform: (d) => `translate(${d.y!},${d.x!})`, + .attr('class', 'nodeText') + .attr('text-anchor', 'middle') + .attr('transform', 'translate(0,0)') + .attr('dy', '.35em') + .style('fill-opacity', 0) + .text((d) => d.data.name) + .on('click', (_, datum) => { + onClickText(datum); }); + const nodeEnterAndUpdate = nodeEnter.merge(node); + + // update the text to reflect whether node has children or not + nodeEnterAndUpdate.select('text').text((d) => d.data.name); + + // change the circle fill depending on whether it has children and is collapsed + nodeEnterAndUpdate + .select('circle') + .style('stroke', 'black') + .style('stroke-width', '1.5px') + .style('fill', (d) => + d.data._children && d.data._children.length > 0 + ? nodeStyleOptions.colors.collapsed + : d.data.children && d.data.children.length > 0 + ? nodeStyleOptions.colors.parent + : nodeStyleOptions.colors.default + ); + + // transition nodes to their new position + const nodeUpdate = nodeEnterAndUpdate + .transition() + .duration(transitionDuration) + .attr('transform', (d) => `translate(${d.y},${d.x})`); + // ensure circle radius is correct - nodeUpdate.select('circle').attr('r', style.node.radius); + nodeUpdate.select('circle').attr('r', nodeStyleOptions.radius); // fade the text in and align it nodeUpdate - .select('text') + .select('text') .style('fill-opacity', 1) - .attr({ - transform: function transform(this: SVGGraphicsElement, d) { - const x = - (d.children || d._children ? -1 : 1) * - (this.getBBox().width / 2 + style.node.radius + 5); - return `translate(${x},0)`; - }, + .attr('transform', function transform(d) { + const x = + (((d.data.children ?? d.data._children)?.length ?? 0) > 0 + ? -1 + : 1) * + (this.getBBox().width / 2 + nodeStyleOptions.radius + 5); + return `translate(${x},0)`; }); // blink updated nodes - node - .filter(function flick(this: any, d) { + nodeEnterAndUpdate + .filter(function flick( + this: SVGGElement & { + __oldData__?: HierarchyPointNode; + }, + d + ) { // test whether the relevant properties of d match // the equivalent property of the oldData // also test whether the old data exists, // to catch the entering elements! - return this.__oldData__ && d.value !== this.__oldData__.value; + return ( + !!this.__oldData__ && d.data.value !== this.__oldData__.data.value + ); }) .select('g') .style('opacity', '0.3') @@ -492,21 +451,19 @@ export default function ( // transition exiting nodes to the parent's new position const nodeExit = node - .exit() + .exit>() .transition() .duration(transitionDuration) - .attr({ - transform: (d) => { - const position = findParentNodePosition( - previousNodePositionsById, - d.id, - (n) => !!nodePositionsById[n.id] - ); - const futurePosition = - (position && nodePositionsById[position.id]) || - nodePositionsById.root; - return `translate(${futurePosition.y!},${futurePosition.x!})`; - }, + .attr('transform', (d) => { + const position = findParentNodePosition( + previousNodePositionsById, + d.data.id, + (n) => !!nodePositionsById[n.id] + ); + const futurePosition = + (position && nodePositionsById[position.id]) || + nodePositionsById.root; + return `translate(${futurePosition.y},${futurePosition.x})`; }) .remove(); @@ -516,65 +473,66 @@ export default function ( // update the links const link = vis - .selectAll('path.link') - .data(links, (d) => (d.target as NodeWithId).id); + .selectAll>( + 'path.link' + ) + .data(links, (d) => d.target.data.id); // enter any new links at the parent's previous position - link + const linkEnter = link .enter() .insert('path', 'g') - .attr({ - class: 'link', - d: (d) => { - const position = findParentNodePosition( - nodePositionsById, - (d.target as NodeWithId).id, - (n) => !!previousNodePositionsById[n.id] - ); - const previousPosition = - (position && previousNodePositionsById[position.id]) || - previousNodePositionsById.root; - return diagonal({ - source: previousPosition, - target: previousPosition, - } as d3.svg.diagonal.Link); - }, - }) - .style(style.link); + .attr('class', 'link') + .attr('d', (d) => { + const position = findParentNodePosition( + nodePositionsById, + d.target.data.id, + (n) => !!previousNodePositionsById[n.id] + ); + const previousPosition = + (position && previousNodePositionsById[position.id]) || + previousNodePositionsById.root; + return linkHorizontal({ + source: previousPosition, + target: previousPosition, + }); + }); + + for (const [key, value] of Object.entries(linkStyles)) { + linkEnter.style(key, value); + } + + const linkEnterAndUpdate = linkEnter.merge(link); // transition links to their new position - link + linkEnterAndUpdate .transition() .duration(transitionDuration) - .attr({ - d: diagonal as unknown as Primitive, - }); + .attr('d', linkHorizontal); // transition exiting nodes to the parent's new position link - .exit() + .exit>() .transition() .duration(transitionDuration) - .attr({ - d: (d) => { - const position = findParentNodePosition( - previousNodePositionsById, - (d.target as NodeWithId).id, - (n) => !!nodePositionsById[n.id] - ); - const futurePosition = - (position && nodePositionsById[position.id]) || - nodePositionsById.root; - return diagonal({ - source: futurePosition, - target: futurePosition, - }); - }, + .attr('d', (d) => { + const position = findParentNodePosition( + previousNodePositionsById, + d.target.data.id, + (n) => !!nodePositionsById[n.id] + ); + const futurePosition = + (position && nodePositionsById[position.id]) || + nodePositionsById.root; + return linkHorizontal({ + source: futurePosition, + target: futurePosition, + }); }) .remove(); // delete the old data once it's no longer needed - node.property('__oldData__', null); + nodeEnterAndUpdate.property('__oldData__', null); // stash the old positions for transition previousNodePositionsById = nodePositionsById; @@ -582,4 +540,4 @@ export default function ( }; } -export { Primitive }; +export type { Node }; diff --git a/packages/d3-state-visualizer/src/charts/tree/utils.ts b/packages/d3-state-visualizer/src/charts/tree/utils.ts index 10a87a3c..a20873ca 100644 --- a/packages/d3-state-visualizer/src/charts/tree/utils.ts +++ b/packages/d3-state-visualizer/src/charts/tree/utils.ts @@ -1,38 +1,38 @@ import { is, join, pipe, replace } from 'ramda'; import sortAndSerialize from './sortAndSerialize'; -import { NodeWithId } from './tree'; +import type { InternalNode } from './tree'; -export function collapseChildren(node: NodeWithId) { +export function collapseChildren(node: InternalNode) { if (node.children) { node._children = node.children; node._children.forEach(collapseChildren); - node.children = null; + node.children = undefined; } } -export function expandChildren(node: NodeWithId) { +export function expandChildren(node: InternalNode) { if (node._children) { node.children = node._children; node.children.forEach(expandChildren); - node._children = null; + node._children = undefined; } } -export function toggleChildren(node: NodeWithId) { +export function toggleChildren(node: InternalNode) { if (node.children) { node._children = node.children; - node.children = null; + node.children = undefined; } else if (node._children) { node.children = node._children; - node._children = null; + node._children = undefined; } return node; } export function visit( - parent: NodeWithId, - visitFn: (parent: NodeWithId) => void, - childrenFn: (parent: NodeWithId) => NodeWithId[] | null | undefined + parent: InternalNode, + visitFn: (parent: InternalNode) => void, + childrenFn: (parent: InternalNode) => InternalNode[] | null | undefined ) { if (!parent) { return; @@ -50,10 +50,10 @@ export function visit( } } -export function getNodeGroupByDepthCount(rootNode: NodeWithId) { +export function getNodeGroupByDepthCount(rootNode: InternalNode) { const nodeGroupByDepthCount = [1]; - const traverseFrom = function traverseFrom(node: NodeWithId, depth = 0) { + const traverseFrom = function traverseFrom(node: InternalNode, depth = 0) { if (!node.children || node.children.length === 0) { return 0; } @@ -73,11 +73,7 @@ export function getNodeGroupByDepthCount(rootNode: NodeWithId) { return nodeGroupByDepthCount; } -export function getTooltipString( - node: unknown, - i: number | undefined, - { indentationSize = 4 } -) { +export function getTooltipString(node: InternalNode, { indentationSize = 4 }) { if (!is(Object, node)) return ''; const spacer = join('  '); @@ -89,7 +85,6 @@ export function getTooltipString( if (typeof node.value !== 'undefined') return json2html(node.value); if (typeof node.object !== 'undefined') return json2html(node.object); - if (children && children.length) - return `childrenCount: ${(children as unknown[]).length}`; + if (children && children.length) return `childrenCount: ${children.length}`; return 'empty'; } diff --git a/packages/d3-state-visualizer/src/index.ts b/packages/d3-state-visualizer/src/index.ts index 6239d3ce..a2ce88d8 100644 --- a/packages/d3-state-visualizer/src/index.ts +++ b/packages/d3-state-visualizer/src/index.ts @@ -1,2 +1,2 @@ export { tree } from './charts'; -export type { InputOptions, NodeWithId, Primitive } from './charts'; +export type { HierarchyPointNode, Node, Options, StyleValue } from './charts'; diff --git a/packages/d3tooltip/README.md b/packages/d3tooltip/README.md index 7a22d1c5..9671dada 100644 --- a/packages/d3tooltip/README.md +++ b/packages/d3tooltip/README.md @@ -10,45 +10,45 @@ It was created by [@romseguy](https://github.com/romseguy) and merged from [`rom ## Quick usage ```javascript -import d3 from 'd3'; +import * as d3 from 'd3'; import { tooltip } from 'd3tooltip'; const DOMNode = document.getElementById('chart'); const root = d3.select(DOMNode); const vis = root.append('svg'); -let options = { - offset: {left: 30, top: 10} +const options = { + offset: { left: 30, top: 10 }, + styles: { 'min-width': '50px', 'border-radius': '5px' }, }; -vis.selectAll('circle').data(someData).enter() +vis + .selectAll('circle') + .data(someData) + .enter() .append('circle') .attr('r', 10) .call( - d3tooltip(d3, 'tooltipClassName', options) - .text((d, i) => toStringOrHtml(d)) - .attr({ 'class': 'anotherClassName' }) - .style({ 'min-width': '50px', 'border-radius: 5px' }) + d3tooltip('tooltipClassName', { + ...options, + text: (d) => toStringOrHtml(d), + }) ) - .on({ - mouseover(d, i) { - d3.select(this).style({ - fill: 'skyblue' - }); - }, - mouseout(d, i) { - d3.select(this).style({ - fill: 'black' - }); - } + .on('mouseover', function () { + d3.select(this).style('fill', 'skyblue'); + }) + .on('mouseout', function () { + d3.select(this).style('fill', 'black'); }); ``` ## API -| Option | Type | Default | Description | -| -------- | ----------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `root` | DOM.Element | `body` | The tooltip will be added as a child of that element. You can also use a D3 [selection](https://github.com/mbostock/d3/wiki/Selections#d3_select) | -| `left` | Number | `undefined` | Sets the tooltip `x` absolute position instead of the mouse `x` position, relative to the `root` element | -| `top` | Number | `undefined` | Sets the tooltip `y` absolute position instead of the mouse `y` position, relative to the `root` element | -| `offset` | Object | `{left: 0, top: 0}` | Sets the distance, starting from the cursor position, until the tooltip is rendered. **Warning**: only applicable if you don't provide a `left` or `top` option | +| Option | Type | Default | Description | +| -------- | ------------------ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `root` | DOM.Element | `body` | The tooltip will be added as a child of that element. You can also use a D3 [selection](https://github.com/mbostock/d3/wiki/Selections#d3_select). | +| `left` | Number | `undefined` | Sets the tooltip `x` absolute position instead of the mouse `x` position, relative to the `root` element. | +| `top` | Number | `undefined` | Sets the tooltip `y` absolute position instead of the mouse `y` position, relative to the `root` element. | +| `offset` | Object | `{left: 0, top: 0}` | Sets the distance, starting from the cursor position, until the tooltip is rendered. **Warning**: only applicable if you don't provide a `left` or `top` option. | +| `styles` | Object | `{}` | Sets the styles of the tooltip element. | +| `text` | String or Function | `''` | Sets the text of the tooltip. Can be a constant `string` or a function that takes the datum and returns a `string`. | diff --git a/packages/d3tooltip/package.json b/packages/d3tooltip/package.json index 2ac9055a..04844c08 100644 --- a/packages/d3tooltip/package.json +++ b/packages/d3tooltip/package.json @@ -19,18 +19,16 @@ "main": "lib/cjs/index.js", "module": "lib/esm/index.js", "types": "lib/types/index.d.ts", - "unpkg": "lib/umd/d3tooltip.umd.js", "sideEffects": false, "repository": { "type": "git", "url": "https://github.com/reduxjs/redux-devtools.git" }, "scripts": { - "build": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:types && pnpm run build:umd", + "build": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:types", "build:cjs": "babel src --extensions \".ts\" --out-dir lib/cjs", "build:esm": "babel src --config-file ./babel.config.esm.json --extensions \".ts\" --out-dir lib/esm", "build:types": "tsc --emitDeclarationOnly", - "build:umd": "rollup -c", "clean": "rimraf lib", "lint": "eslint . --ext .ts", "type-check": "tsc --noEmit", @@ -38,36 +36,25 @@ "prepublish": "pnpm run type-check && pnpm run lint" }, "dependencies": { - "@babel/runtime": "^7.18.3", - "ramda": "^0.28.0" + "@babel/runtime": "^7.20.6" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-typescript": "^7.17.12", - "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-commonjs": "^22.0.0", - "@rollup/plugin-node-resolve": "^13.3.0", - "@types/d3": "^3.5.47", - "@types/node": "^16.11.41", - "@types/ramda": "^0.28.14", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "d3": "^3.5.17", - "eslint": "^8.18.0", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", + "@types/d3": "^7.4.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "d3": "^7.8.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", "rimraf": "^3.0.2", - "rollup": "^2.75.6", - "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-typescript2": "^0.32.1", - "tslib": "^2.4.0", - "typescript": "~4.7.4" + "typescript": "~4.9.4" }, "peerDependencies": { - "@types/d3": "^3.5.47", - "d3": "^3.5.17" + "@types/d3": "^7.4.0", + "d3": "^7.8.0" } } diff --git a/packages/d3tooltip/rollup.config.js b/packages/d3tooltip/rollup.config.js deleted file mode 100644 index 6a442f22..00000000 --- a/packages/d3tooltip/rollup.config.js +++ /dev/null @@ -1,51 +0,0 @@ -import typescript from 'rollup-plugin-typescript2'; -import resolve from '@rollup/plugin-node-resolve'; -import commonjs from '@rollup/plugin-commonjs'; -import babel from '@rollup/plugin-babel'; -import { terser } from 'rollup-plugin-terser'; - -const config = [ - { - input: 'src/index.ts', - output: { - name: 'd3tooltip', - file: 'lib/umd/d3tooltip.js', - format: 'umd', - }, - plugins: [ - typescript({ - tsconfigOverride: { compilerOptions: { declaration: false } }, - }), - resolve(), - commonjs(), - babel({ - babelHelpers: 'runtime', - extensions: ['.ts'], - plugins: ['@babel/plugin-transform-runtime'], - }), - ], - }, - { - input: 'src/index.ts', - output: { - name: 'd3tooltip', - file: 'lib/umd/d3tooltip.min.js', - format: 'umd', - }, - plugins: [ - typescript({ - tsconfigOverride: { compilerOptions: { declaration: false } }, - }), - resolve(), - commonjs(), - babel({ - babelHelpers: 'runtime', - extensions: ['.ts'], - plugins: ['@babel/plugin-transform-runtime'], - }), - terser(), - ], - }, -]; - -export default config; diff --git a/packages/d3tooltip/src/index.ts b/packages/d3tooltip/src/index.ts index bf8e2795..7d295b60 100644 --- a/packages/d3tooltip/src/index.ts +++ b/packages/d3tooltip/src/index.ts @@ -1,161 +1,102 @@ -import d3Package, { Primitive, Selection } from 'd3'; -import { is } from 'ramda'; -import utils from './utils'; -const { prependClass, functor } = utils; +import * as d3 from 'd3'; +import type { BaseType, Selection } from 'd3'; -interface Options { +export type StyleValue = string | number | boolean; + +interface Options< + Datum, + RootGElement extends BaseType, + RootDatum, + RootPElement extends BaseType, + RootPDatum +> { left: number | undefined; top: number | undefined; offset: { left: number; top: number; }; - root: Selection | undefined; + root: + | Selection + | undefined; + styles: { [key: string]: StyleValue }; + text: string | ((datum: Datum) => string); } -const defaultOptions: Options = { +const defaultOptions: Options = { left: undefined, // mouseX top: undefined, // mouseY offset: { left: 0, top: 0 }, root: undefined, + styles: {}, + text: '', }; -interface Tip { - (selection: Selection): void; - attr: ( - this: this, - d: - | string - | { - [key: string]: - | Primitive - | ((datum: Datum, index: number, outerIndex: number) => Primitive); - } - ) => this; - style: ( - this: this, - d: - | string - | { - [key: string]: - | Primitive - | ((datum: Datum, index: number, outerIndex: number) => Primitive); - } - | undefined - ) => this; - text: ( - this: this, - d: string | ((datum: Datum, index?: number, outerIndex?: number) => string) - ) => this; -} - -export function tooltip( - d3: typeof d3Package, +export function tooltip< + GElement extends BaseType, + Datum, + PElement extends BaseType, + PDatum, + RootGElement extends BaseType, + RootDatum, + RootPElement extends BaseType, + RootPDatum +>( className = 'tooltip', - options: Partial> = {} -): Tip { - const { left, top, offset, root } = { + options: Partial< + Options + > = {} +) { + const { left, top, offset, root, styles, text } = { ...defaultOptions, ...options, - } as Options; + } as Options; - let attrs = { class: className }; - let text: (datum: Datum, index?: number, outerIndex?: number) => string = ( - node: Datum - ) => ''; - let styles = {}; + let el: Selection; + const anchor: Selection< + RootGElement, + RootDatum, + RootPElement | HTMLElement, + RootPDatum + > = root || d3.select('body'); + const rootNode = anchor.node()!; - let el: Selection; - const anchor = root || d3.select('body'); - const rootNode = anchor.node(); - - function tip(selection: Selection) { - selection.on('mouseover.tip', (node) => { - const [mouseX, mouseY] = d3.mouse(rootNode); - const [x, y] = [left || mouseX + offset.left, top || mouseY - offset.top]; + return function tip(selection: Selection) { + selection.on('mouseover.tip', (event, datum) => { + const [pointerX, pointerY] = d3.pointer(event, rootNode); + const [x, y] = [ + left || pointerX + offset.left, + top || pointerY - offset.top, + ]; anchor.selectAll(`div.${className}`).remove(); el = anchor .append('div') - .attr(prependClass(className)(attrs)) - .style({ - position: 'absolute', - 'z-index': 1001, - left: `${x}px`, - top: `${y}px`, - ...styles, - }) - .html(() => text(node)) as Selection; + .attr('class', className) + .style('position', 'absolute') + .style('z-index', 1001) + .style('left', `${x}px`) + .style('top', `${y}px`) + .html(typeof text === 'function' ? () => text(datum) : () => text); + + for (const [key, value] of Object.entries(styles)) { + el.style(key, value); + } }); - selection.on('mousemove.tip', (node) => { - const [mouseX, mouseY] = d3.mouse(rootNode); - const [x, y] = [left || mouseX + offset.left, top || mouseY - offset.top]; + selection.on('mousemove.tip', (event, datum) => { + const [pointerX, pointerY] = d3.pointer(event, rootNode); + const [x, y] = [ + left || pointerX + offset.left, + top || pointerY - offset.top, + ]; - el.style({ - left: `${x}px`, - top: `${y}px`, - }).html(() => text(node)); + el.style('left', `${x}px`) + .style('top', `${y}px`) + .html(typeof text === 'function' ? () => text(datum) : () => text); }); selection.on('mouseout.tip', () => el.remove()); - } - - tip.attr = function setAttr( - this: typeof tip, - d: - | string - | { - [key: string]: - | Primitive - | ((datum: Datum, index: number, outerIndex: number) => Primitive); - } - ) { - if (is(Object, d)) { - attrs = { - ...attrs, - ...(d as { - [key: string]: - | Primitive - | ((datum: Datum, index: number, outerIndex: number) => Primitive); - }), - }; - } - return this; }; - - tip.style = function setStyle( - this: typeof tip, - d: - | string - | { - [key: string]: - | Primitive - | ((datum: Datum, index: number, outerIndex: number) => Primitive); - } - | undefined - ) { - if (is(Object, d)) { - styles = { - ...styles, - ...(d as { - [key: string]: - | Primitive - | ((datum: Datum, index: number, outerIndex: number) => Primitive); - }), - }; - } - return this; - }; - - tip.text = function setText( - this: typeof tip, - d: string | ((datum: Datum, index?: number, outerIndex?: number) => string) - ) { - text = functor(d); - return this; - }; - - return tip; } diff --git a/packages/d3tooltip/src/utils/functor.ts b/packages/d3tooltip/src/utils/functor.ts deleted file mode 100644 index 9ed7427b..00000000 --- a/packages/d3tooltip/src/utils/functor.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { is } from 'ramda'; -import { Primitive } from 'd3'; - -export default function functor( - v: string | ((datum: Datum, index?: number, outerIndex?: number) => string) -): (datum: Datum, index?: number, outerIndex?: number) => string; -export default function functor( - v: - | Primitive - | ((datum: Datum, index: number, outerIndex?: number) => Primitive) -): (datum: Datum, index?: number, outerIndex?: number) => Primitive; -export default function functor( - v: - | Primitive - | ((datum: Datum, index: number, outerIndex?: number) => Primitive) -): (datum: Datum, index: number, outerIndex?: number) => Primitive { - return is(Function, v) - ? (v as (datum: Datum, index: number, outerIndex?: number) => Primitive) - : () => v; -} diff --git a/packages/d3tooltip/src/utils/index.ts b/packages/d3tooltip/src/utils/index.ts deleted file mode 100644 index ef868239..00000000 --- a/packages/d3tooltip/src/utils/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import prependClass from './prependClass'; -import functor from './functor'; - -export default { - prependClass, - functor, -}; diff --git a/packages/d3tooltip/src/utils/prependClass.ts b/packages/d3tooltip/src/utils/prependClass.ts deleted file mode 100644 index cc9bf058..00000000 --- a/packages/d3tooltip/src/utils/prependClass.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { mapObjIndexed, join } from 'ramda'; -import functor from './functor'; -import { Primitive } from 'd3'; - -export default function prependClass(className: string) { - return mapObjIndexed( - ( - value: - | Primitive - | ((datum: Datum, index: number, outerIndex?: number) => Primitive), - key - ) => { - if (key === 'class') { - const fn = functor(value); - - return (d: Datum, i: number) => { - const classNames = fn(d, i); - if (classNames !== className) { - return join(' ', [className, classNames]); - } - return classNames; - }; - } - - return value; - } - ); -} diff --git a/packages/map2tree/jest.config.js b/packages/map2tree/jest.config.js index 05d33807..f68efd05 100644 --- a/packages/map2tree/jest.config.js +++ b/packages/map2tree/jest.config.js @@ -1,8 +1,6 @@ module.exports = { preset: 'ts-jest', - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, }; diff --git a/packages/map2tree/package.json b/packages/map2tree/package.json index 5359a1e6..baeb9169 100755 --- a/packages/map2tree/package.json +++ b/packages/map2tree/package.json @@ -22,18 +22,16 @@ "main": "lib/cjs/index.js", "module": "lib/esm/index.js", "types": "lib/types/index.d.ts", - "unpkg": "lib/umd/map2tree.umd.js", "sideEffects": false, "repository": { "type": "git", "url": "https://github.com/reduxjs/redux-devtools.git" }, "scripts": { - "build": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:types && pnpm run build:umd", + "build": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:types", "build:cjs": "babel src --extensions \".ts\" --out-dir lib/cjs", "build:esm": "babel src --config-file ./babel.config.esm.json --extensions \".ts\" --out-dir lib/esm", "build:types": "tsc --emitDeclarationOnly", - "build:umd": "rollup -c", "clean": "rimraf lib", "test": "jest", "lint": "eslint . --ext .ts", @@ -42,35 +40,26 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "lodash": "^4.17.21" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-typescript": "^7.17.12", - "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-commonjs": "^22.0.0", - "@rollup/plugin-node-resolve": "^13.3.0", - "@types/jest": "^27.5.2", - "@types/lodash": "^4.14.182", - "@types/node": "^16.11.41", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", + "@types/jest": "^29.2.4", + "@types/lodash": "^4.14.191", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", + "eslint-plugin-jest": "^27.1.7", "immutable": "^4.1.0", - "jest": "^27.5.1", + "jest": "^29.3.1", "rimraf": "^3.0.2", - "rollup": "^2.75.6", - "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-typescript2": "^0.32.1", - "ts-jest": "^27.1.5", - "tslib": "^2.4.0", - "typescript": "~4.7.4" + "ts-jest": "^29.0.3", + "typescript": "~4.9.4" } } diff --git a/packages/map2tree/rollup.config.js b/packages/map2tree/rollup.config.js deleted file mode 100644 index f977bb7c..00000000 --- a/packages/map2tree/rollup.config.js +++ /dev/null @@ -1,51 +0,0 @@ -import typescript from 'rollup-plugin-typescript2'; -import resolve from '@rollup/plugin-node-resolve'; -import commonjs from '@rollup/plugin-commonjs'; -import babel from '@rollup/plugin-babel'; -import { terser } from 'rollup-plugin-terser'; - -const config = [ - { - input: 'src/index.ts', - output: { - name: 'map2tree', - file: 'lib/umd/map2tree.js', - format: 'umd', - }, - plugins: [ - typescript({ - tsconfigOverride: { compilerOptions: { declaration: false } }, - }), - resolve(), - commonjs(), - babel({ - babelHelpers: 'runtime', - extensions: ['.ts'], - plugins: ['@babel/plugin-transform-runtime'], - }), - ], - }, - { - input: 'src/index.ts', - output: { - name: 'map2tree', - file: 'lib/umd/map2tree.min.js', - format: 'umd', - }, - plugins: [ - typescript({ - tsconfigOverride: { compilerOptions: { declaration: false } }, - }), - resolve(), - commonjs(), - babel({ - babelHelpers: 'runtime', - extensions: ['.ts'], - plugins: ['@babel/plugin-transform-runtime'], - }), - terser(), - ], - }, -]; - -export default config; diff --git a/packages/map2tree/src/index.ts b/packages/map2tree/src/index.ts index 00aac7c5..a07163b6 100644 --- a/packages/map2tree/src/index.ts +++ b/packages/map2tree/src/index.ts @@ -4,7 +4,8 @@ import mapValues from 'lodash/mapValues'; export interface Node { name: string; - children?: Node[] | null; + children?: this[]; + object?: unknown; value?: unknown; } @@ -43,7 +44,6 @@ function getNode(tree: Node, key: string): Node | null { } export function map2tree( - // eslint-disable-next-line @typescript-eslint/ban-types root: unknown, options: { key?: string; pushMethod?: 'push' | 'unshift' } = {}, tree: Node = { name: options.key || 'state', children: [] } diff --git a/packages/react-base16-styling/jest.config.js b/packages/react-base16-styling/jest.config.js index f0ecd734..dcef0803 100644 --- a/packages/react-base16-styling/jest.config.js +++ b/packages/react-base16-styling/jest.config.js @@ -1,9 +1,7 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'jsdom', - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, }; diff --git a/packages/react-base16-styling/package.json b/packages/react-base16-styling/package.json index e33e64f1..4012ee43 100644 --- a/packages/react-base16-styling/package.json +++ b/packages/react-base16-styling/package.json @@ -39,32 +39,33 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "@types/base16": "^1.0.2", - "@types/lodash": "^4.14.182", + "@types/lodash": "^4.14.191", "base16": "^1.0.0", "color": "^4.2.3", - "csstype": "^3.1.0", + "csstype": "^3.1.1", "lodash.curry": "^4.1.1" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", "@types/color": "^3.0.3", - "@types/jest": "^27.5.2", + "@types/jest": "^29.2.4", "@types/lodash.curry": "^4.1.7", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "jest": "^27.5.1", + "eslint-plugin-jest": "^27.1.7", + "jest": "^29.3.1", + "jest-environment-jsdom": "^29.3.1", "rimraf": "^3.0.2", - "ts-jest": "^27.1.5", - "typescript": "~4.7.4" + "ts-jest": "^29.0.3", + "typescript": "~4.9.4" } } diff --git a/packages/react-dock/demo/package.json b/packages/react-dock/demo/package.json index 957c8b5d..2947351e 100644 --- a/packages/react-dock/demo/package.json +++ b/packages/react-dock/demo/package.json @@ -11,36 +11,36 @@ }, "dependencies": { "react": "^18.2.0", - "react-bootstrap": "^2.4.0", + "react-bootstrap": "^2.7.0", "react-dock": "^0.6.0", "react-dom": "^18.2.0", - "react-icons": "^4.4.0", + "react-icons": "^4.7.1", "react-is": "^18.2.0", - "styled-components": "^5.3.5" + "styled-components": "^5.3.6" }, "devDependencies": { - "@babel/core": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", - "@types/node": "^16.11.41", - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", - "@types/styled-components": "^5.1.25", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "babel-loader": "^8.2.5", + "@babel/core": "^7.20.5", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@types/node": "^18.11.17", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", + "@types/styled-components": "^5.1.26", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "babel-loader": "^9.1.0", "cross-env": "^7.0.3", - "eslint": "^8.18.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "fork-ts-checker-webpack-plugin": "^7.2.11", + "fork-ts-checker-webpack-plugin": "^7.2.14", "html-webpack-plugin": "^5.5.0", - "ts-node": "^10.8.1", - "typescript": "~4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.2" + "ts-node": "^10.9.1", + "typescript": "~4.9.4", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" } } diff --git a/packages/react-dock/jest.config.js b/packages/react-dock/jest.config.js index f0ecd734..dcef0803 100644 --- a/packages/react-dock/jest.config.js +++ b/packages/react-dock/jest.config.js @@ -1,9 +1,7 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'jsdom', - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, }; diff --git a/packages/react-dock/package.json b/packages/react-dock/package.json index 4417f088..7ede3afc 100644 --- a/packages/react-dock/package.json +++ b/packages/react-dock/package.json @@ -39,37 +39,38 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", - "@types/lodash": "^4.14.182", + "@babel/runtime": "^7.20.6", + "@types/lodash": "^4.14.191", "@types/prop-types": "^15.7.5", "lodash.debounce": "^4.0.8", "prop-types": "^15.8.1" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", - "@types/jest": "^27.5.2", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@types/jest": "^29.2.4", "@types/lodash.debounce": "^4.0.7", - "@types/react": "^18.0.14", + "@types/react": "^18.0.26", "@types/react-test-renderer": "^18.0.0", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "jest": "^27.5.1", + "jest": "^29.3.1", + "jest-environment-jsdom": "^29.3.1", "react": "^18.2.0", "react-test-renderer": "^18.2.0", "rimraf": "^3.0.2", - "ts-jest": "^27.1.5", - "typescript": "~4.7.4" + "ts-jest": "^29.0.3", + "typescript": "~4.9.4" }, "peerDependencies": { "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", diff --git a/packages/react-json-tree/README.md b/packages/react-json-tree/README.md index f1e96518..6e802e5f 100644 --- a/packages/react-json-tree/README.md +++ b/packages/react-json-tree/README.md @@ -34,7 +34,7 @@ Check out [examples](examples) directory for more details. This component now uses [react-base16-styling](https://github.com/reduxjs/redux-devtools/tree/main/packages/react-base16-styling) module, which allows to customize component via `theme` property, which can be the following: -- [base16](http://chriskempson.com/projects/base16/) theme data. [The example theme data can be found here](https://github.com/gaearon/redux-devtools/tree/75322b15ee7ba03fddf10ac3399881e302848874/src/react/themes). +- [base16](https://github.com/chriskempson/base16) theme data. [The example theme data can be found here](https://github.com/gaearon/redux-devtools/tree/75322b15ee7ba03fddf10ac3399881e302848874/src/react/themes). - object that contains style objects, strings (that treated as classnames) or functions. A function is used to extend its first argument `{ style, className }` and should return an object with the same structure. Other arguments depend on particular context (and should be described here). See [createStylingFromTheme.js](https://github.com/reduxjs/redux-devtools/blob/main/packages/react-json-tree/src/createStylingFromTheme.ts) for the list of styling object keys. Also, this object can extend `base16` theme via `extend` property. Every theme has a light version, which is enabled with `invertTheme` prop. diff --git a/packages/react-json-tree/examples/package.json b/packages/react-json-tree/examples/package.json index 9d39ad8f..c0a203f3 100644 --- a/packages/react-json-tree/examples/package.json +++ b/packages/react-json-tree/examples/package.json @@ -26,27 +26,27 @@ "react-json-tree": "^0.17.0" }, "devDependencies": { - "@babel/core": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", - "@types/node": "^16.11.41", - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "babel-loader": "^8.2.5", + "@babel/core": "^7.20.5", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@types/node": "^18.11.17", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "babel-loader": "^9.1.0", "cross-env": "^7.0.3", - "eslint": "^8.18.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "fork-ts-checker-webpack-plugin": "^7.2.11", + "fork-ts-checker-webpack-plugin": "^7.2.14", "html-webpack-plugin": "^5.5.0", - "ts-node": "^10.8.1", - "typescript": "~4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.2" + "ts-node": "^10.9.1", + "typescript": "~4.9.4", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" } } diff --git a/packages/react-json-tree/jest.config.js b/packages/react-json-tree/jest.config.js index 05d33807..f68efd05 100644 --- a/packages/react-json-tree/jest.config.js +++ b/packages/react-json-tree/jest.config.js @@ -1,8 +1,6 @@ module.exports = { preset: 'ts-jest', - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, }; diff --git a/packages/react-json-tree/package.json b/packages/react-json-tree/package.json index 772f5750..07ed2b13 100644 --- a/packages/react-json-tree/package.json +++ b/packages/react-json-tree/package.json @@ -45,44 +45,44 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", - "@types/lodash": "^4.14.182", + "@babel/runtime": "^7.20.6", + "@types/lodash": "^4.14.191", "@types/prop-types": "^15.7.5", "prop-types": "^15.8.1", "react-base16-styling": "^0.9.1" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", - "@rollup/plugin-babel": "^5.3.1", - "@rollup/plugin-commonjs": "^22.0.0", - "@rollup/plugin-node-resolve": "^13.3.0", - "@types/jest": "^27.5.2", - "@types/node": "^16.11.41", - "@types/react": "^18.0.14", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@rollup/plugin-babel": "^6.0.3", + "@rollup/plugin-commonjs": "^24.0.0", + "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-terser": "^0.2.1", + "@types/jest": "^29.2.4", + "@types/node": "^18.11.17", + "@types/react": "^18.0.26", "@types/react-test-renderer": "^18.0.0", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "jest": "^27.5.1", + "jest": "^29.3.1", "react": "^18.2.0", "react-test-renderer": "^18.2.0", "rimraf": "^3.0.2", - "rollup": "^2.75.6", - "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-typescript2": "^0.32.1", - "ts-jest": "^27.1.5", - "tslib": "^2.4.0", - "typescript": "~4.7.4" + "rollup": "^3.7.5", + "rollup-plugin-typescript2": "^0.34.1", + "ts-jest": "^29.0.3", + "tslib": "^2.4.1", + "typescript": "~4.9.4" }, "peerDependencies": { "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", diff --git a/packages/react-json-tree/rollup.config.js b/packages/react-json-tree/rollup.config.mjs similarity index 96% rename from packages/react-json-tree/rollup.config.js rename to packages/react-json-tree/rollup.config.mjs index 8d2e2555..de6c3688 100644 --- a/packages/react-json-tree/rollup.config.js +++ b/packages/react-json-tree/rollup.config.mjs @@ -2,7 +2,7 @@ import typescript from 'rollup-plugin-typescript2'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import babel from '@rollup/plugin-babel'; -import { terser } from 'rollup-plugin-terser'; +import terser from '@rollup/plugin-terser'; const config = [ { diff --git a/packages/redux-devtools-app/jest.config.js b/packages/redux-devtools-app/jest.config.js index 2aaa8218..e15f90f8 100644 --- a/packages/redux-devtools-app/jest.config.js +++ b/packages/redux-devtools-app/jest.config.js @@ -5,9 +5,11 @@ module.exports = { moduleNameMapper: { '\\.css$': '/test/__mocks__/styleMock.ts', }, - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.jsx?$': 'babel-jest', + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, + transformIgnorePatterns: [ + 'node_modules/(?!.pnpm|d3|dateformat|delaunator|nanoid|robust-predicates|uuid)', + ], }; diff --git a/packages/redux-devtools-app/package.json b/packages/redux-devtools-app/package.json index 4ca989a4..9cd52756 100644 --- a/packages/redux-devtools-app/package.json +++ b/packages/redux-devtools-app/package.json @@ -29,9 +29,9 @@ "build:cjs": "babel src --extensions \".ts,.tsx\" --out-dir lib/cjs", "build:esm": "babel src --config-file ./babel.config.esm.json --extensions \".ts,.tsx\" --out-dir lib/esm", "build:types": "tsc --emitDeclarationOnly", - "build:web": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack --env platform=web --progress", - "build:umd": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack --progress --config webpack.config.umd.ts", - "build:umd:min": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack --env production --progress --config webpack.config.umd.ts", + "build:web": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack --env platform=web", + "build:umd": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack --config webpack.config.umd.ts", + "build:umd:min": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack --env production --config webpack.config.umd.ts", "clean": "rimraf build lib umd", "test": "jest", "lint": "eslint . --ext .ts,.tsx", @@ -40,7 +40,7 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "@redux-devtools/chart-monitor": "^3.0.0", "@redux-devtools/core": "^3.13.0", "@redux-devtools/inspector-monitor": "^3.0.0", @@ -50,7 +50,7 @@ "@redux-devtools/rtk-query-monitor": "^3.0.0", "@redux-devtools/slider-monitor": "^4.0.0", "@redux-devtools/ui": "^1.3.0", - "@reduxjs/toolkit": "^1.8.2", + "@reduxjs/toolkit": "^1.9.1", "@types/prop-types": "^15.7.5", "d3-state-visualizer": "^1.6.0", "javascript-stringify": "^2.1.0", @@ -59,66 +59,66 @@ "localforage": "^1.10.0", "lodash": "^4.17.21", "prop-types": "^15.8.1", - "react-icons": "^4.4.0", + "react-icons": "^4.7.1", "react-is": "^18.2.0", - "react-redux": "^8.0.2", + "react-redux": "^8.0.5", "redux": "^4.2.0", "redux-persist": "^6.0.0", - "socketcluster-client": "^16.1.1" + "socketcluster-client": "^17.1.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", - "@rjsf/core": "^4.2.0", - "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.3.0", - "@types/jest": "^27.5.2", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@rjsf/core": "^4.2.3", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@types/jest": "^29.2.4", "@types/jsan": "^3.1.2", "@types/json-schema": "^7.0.11", - "@types/lodash": "^4.14.182", - "@types/node": "^16.11.41", - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", + "@types/lodash": "^4.14.191", + "@types/node": "^18.11.17", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", "@types/socketcluster-client": "^16.0.0", - "@types/styled-components": "^5.1.25", - "@types/testing-library__jest-dom": "^5.14.4", - "@types/webpack-env": "^1.17.0", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "babel-loader": "^8.2.5", + "@types/styled-components": "^5.1.26", + "@types/testing-library__jest-dom": "^5.14.5", + "@types/webpack-env": "^1.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "babel-loader": "^9.1.0", "cross-env": "^7.0.3", - "css-loader": "^6.7.1", - "eslint": "^8.18.0", + "css-loader": "^6.7.3", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "fork-ts-checker-webpack-plugin": "^7.2.11", - "html-loader": "^3.1.2", + "fork-ts-checker-webpack-plugin": "^7.2.14", + "html-loader": "^4.2.0", "html-webpack-plugin": "^5.5.0", - "jest": "^27.5.1", - "path-browserify": "^1.0.1", + "jest": "^29.3.1", + "jest-environment-jsdom": "^29.3.1", "react": "^18.2.0", "react-dom": "^18.2.0", "rimraf": "^3.0.2", "style-loader": "^3.3.1", - "styled-components": "^5.3.5", - "ts-jest": "^27.1.5", - "ts-node": "^10.8.1", - "typescript": "~4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.2" + "styled-components": "^5.3.6", + "ts-jest": "^29.0.3", + "ts-node": "^10.9.1", + "typescript": "~4.9.4", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "peerDependencies": { "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "@types/styled-components": "^5.1.25", + "@types/styled-components": "^5.1.26", "react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "styled-components": "^5.3.5" + "styled-components": "^5.3.6" } } diff --git a/packages/redux-devtools-app/src/containers/monitors/ChartMonitorWrapper.tsx b/packages/redux-devtools-app/src/containers/monitors/ChartMonitorWrapper.tsx index b8a5a829..7639c32b 100644 --- a/packages/redux-devtools-app/src/containers/monitors/ChartMonitorWrapper.tsx +++ b/packages/redux-devtools-app/src/containers/monitors/ChartMonitorWrapper.tsx @@ -1,14 +1,17 @@ import React, { Component } from 'react'; import { connect, ResolveThunks } from 'react-redux'; import { ChartMonitor } from '@redux-devtools/chart-monitor'; -import { NodeWithId } from 'd3-state-visualizer'; +import type { HierarchyPointNode, Node } from 'd3-state-visualizer'; import { selectMonitorWithState } from '../../actions'; -export function getPath(obj: NodeWithId, inspectedStatePath: string[]) { +export function getPath( + obj: HierarchyPointNode, + inspectedStatePath: string[] +) { const parent = obj.parent; if (!parent) return; getPath(parent, inspectedStatePath); - let name = obj.name; + let name = obj.data.name; const item = /.+\[(\d+)]/.exec(name); if (item) name = item[1]; inspectedStatePath.push(name); @@ -20,7 +23,7 @@ type Props = DispatchProps; class ChartMonitorWrapper extends Component { static update = ChartMonitor.update; - onClickText = (data: NodeWithId) => { + onClickText = (data: HierarchyPointNode) => { const inspectedStatePath: string[] = []; getPath(data, inspectedStatePath); this.props.selectMonitorWithState('InspectorMonitor', { diff --git a/packages/redux-devtools-app/src/containers/monitors/InspectorWrapper/ChartTab.tsx b/packages/redux-devtools-app/src/containers/monitors/InspectorWrapper/ChartTab.tsx index c9b91f38..7009069b 100644 --- a/packages/redux-devtools-app/src/containers/monitors/InspectorWrapper/ChartTab.tsx +++ b/packages/redux-devtools-app/src/containers/monitors/InspectorWrapper/ChartTab.tsx @@ -1,7 +1,8 @@ import React, { Component, RefCallback } from 'react'; import { connect, ResolveThunks } from 'react-redux'; import { withTheme } from 'styled-components'; -import { InputOptions, NodeWithId, tree } from 'd3-state-visualizer'; +import { tree } from 'd3-state-visualizer'; +import type { HierarchyPointNode, Node, Options } from 'd3-state-visualizer'; import { getPath } from '../ChartMonitorWrapper'; import { updateMonitorState } from '../../../actions'; import { ThemeFromProvider } from '@redux-devtools/ui'; @@ -54,12 +55,12 @@ class ChartTab extends Component { this.renderChart(props.data as {} | null | undefined); } - getChartTheme(theme: ThemeFromProvider): Partial { + getChartTheme(theme: ThemeFromProvider): Partial { return { heightBetweenNodesCoeff: 1, widthBetweenNodesCoeff: 1.3, tooltipOptions: { - style: { + styles: { color: theme.base06, 'background-color': theme.base01, opacity: '0.9', @@ -69,29 +70,29 @@ class ChartTab extends Component { offset: { left: 30, top: 10 }, indentationSize: 2, }, - style: { + chartStyles: { width: '100%', height: '100%', - node: { - colors: { - default: theme.base0B, - collapsed: theme.base0B, - parent: theme.base0E, - }, - radius: 7, - } as unknown as string, - text: { - colors: { - default: theme.base0D, - hover: theme.base06, - }, - } as unknown as string, + }, + nodeStyleOptions: { + colors: { + default: theme.base0B, + collapsed: theme.base0B, + parent: theme.base0E, + }, + radius: 7, + }, + textStyleOptions: { + colors: { + default: theme.base0D, + hover: theme.base06, + }, }, onClickText: this.onClickText, }; } - onClickText = (data: NodeWithId) => { + onClickText = (data: HierarchyPointNode) => { const inspectedStatePath: string[] = []; getPath(data, inspectedStatePath); this.props.updateMonitorState({ diff --git a/packages/redux-devtools-app/webpack.config.ts b/packages/redux-devtools-app/webpack.config.ts index c20747b6..d48dc365 100644 --- a/packages/redux-devtools-app/webpack.config.ts +++ b/packages/redux-devtools-app/webpack.config.ts @@ -39,9 +39,6 @@ export default ( }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], - fallback: { - path: require.resolve('path-browserify'), - }, }, plugins: [ new webpack.DefinePlugin({ diff --git a/packages/redux-devtools-app/webpack.config.umd.ts b/packages/redux-devtools-app/webpack.config.umd.ts index 58ae1c22..d3f4e829 100644 --- a/packages/redux-devtools-app/webpack.config.umd.ts +++ b/packages/redux-devtools-app/webpack.config.umd.ts @@ -39,9 +39,6 @@ export default (env: { production?: boolean } = {}): webpack.Configuration => ({ }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], - fallback: { - path: require.resolve('path-browserify'), - }, }, plugins: [ new webpack.DefinePlugin({ diff --git a/packages/redux-devtools-chart-monitor/README.md b/packages/redux-devtools-chart-monitor/README.md index 6c6006db..37ff6bff 100644 --- a/packages/redux-devtools-chart-monitor/README.md +++ b/packages/redux-devtools-chart-monitor/README.md @@ -47,16 +47,18 @@ Consult the [`DockMonitor` README](https://github.com/reduxjs/redux-devtools/tre You can read the React component [propTypes](https://github.com/reduxjs/redux-devtools/blob/master/packages/redux-devtools-chart-monitor/src/Chart.js#L11) in addition to the details below: -| Name | Description | -| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `defaultIsVisible` | By default, set to `true`. | -| `transitionDuration` | By default, set to `750`, in milliseconds. | -| `heightBetweenNodesCoeff` | By default, set to `1`. | -| `widthBetweenNodesCoeff` | By default, set to `1.3`. | -| `isSorted` | By default, set to `false`. | -| `style` | {
  width: '100%', height: '100%', // i.e fullscreen for [`DockMonitor`](https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-dock-monitor)
  text: {
    colors: {
      'default': `theme.base0D`,
      hover: `theme.base06`
    }
  },
  node: {
    colors: {
      'default': `theme.base0B`,
      collapsed: `theme.base0B`,
      parent: `theme.base0E`
    },
    radius: 7
  }
} | -| `onClickText` | Function called with a reference to the clicked node as first argument when clicking on the text next to a node. | -| `tooltipOptions` | {
  disabled: false,
  indentationSize: 2,
  style: {
    'background-color': `theme.base06`,
    'opacity': '0.7',
    'border-radius': '5px',
    'padding': '5px'
  }
}
[More info](https://github.com/reduxjs/redux-devtools/tree/master/packages/d3tooltip#api). | +| Name | Description | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `defaultIsVisible` | By default, set to `true`. | +| `transitionDuration` | By default, set to `750`, in milliseconds. | +| `heightBetweenNodesCoeff` | By default, set to `1`. | +| `widthBetweenNodesCoeff` | By default, set to `1.3`. | +| `isSorted` | By default, set to `false`. | +| `chartStyles` | {
  width: '100%', height: '100%', // i.e fullscreen for [`DockMonitor`](https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-dock-monitor)
} | +| `textStyleOptions` | {
  colors: {
    default: `theme.base0D`,
    hover: `theme.base06`,
  },
} | +| `nodeStyleOptions` | {
  colors: {
    default: `theme.base0B`,
    collapsed: `theme.base0B`,
    parent: `theme.base0E`,
  },
  radius: 7,
} | +| `onClickText` | Function called with a reference to the clicked node as first argument when clicking on the text next to a node. | +| `tooltipOptions` | {
  disabled: false,
  indentationSize: 2,
  styles: {
    'background-color': `theme.base06`,
    'opacity': '0.7',
    'border-radius': '5px',
    'padding': '5px',
  },
}
[More info](https://github.com/reduxjs/redux-devtools/tree/master/packages/d3tooltip#api). | #### Redux DevTools props diff --git a/packages/redux-devtools-chart-monitor/package.json b/packages/redux-devtools-chart-monitor/package.json index 03993b63..4768dc82 100644 --- a/packages/redux-devtools-chart-monitor/package.json +++ b/packages/redux-devtools-chart-monitor/package.json @@ -39,34 +39,32 @@ "prepublish": "pnpm run type-check && pnpm run lint" }, "dependencies": { - "@babel/runtime": "^7.18.3", - "@types/prop-types": "^15.7.5", + "@babel/runtime": "^7.20.6", "@types/redux-devtools-themes": "^1.0.0", "d3-state-visualizer": "^1.6.0", "deepmerge": "^4.2.2", - "prop-types": "^15.8.1", "redux-devtools-themes": "^1.0.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@redux-devtools/core": "^3.13.1", - "@types/react": "^18.0.14", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@types/react": "^18.0.26", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", "react": "^18.2.0", "redux": "^4.2.0", "rimraf": "^3.0.2", - "typescript": "~4.7.4" + "typescript": "~4.9.4" }, "peerDependencies": { "@redux-devtools/core": "^3.13.1", diff --git a/packages/redux-devtools-chart-monitor/src/Chart.tsx b/packages/redux-devtools-chart-monitor/src/Chart.tsx index aa75a733..3ea4ada8 100644 --- a/packages/redux-devtools-chart-monitor/src/Chart.tsx +++ b/packages/redux-devtools-chart-monitor/src/Chart.tsx @@ -1,6 +1,6 @@ import React, { Component, createRef } from 'react'; -import PropTypes from 'prop-types'; -import { tree, NodeWithId, Primitive } from 'd3-state-visualizer'; +import { tree } from 'd3-state-visualizer'; +import type { Options } from 'd3-state-visualizer'; import { Action, Dispatch } from 'redux'; import { LiftedAction, LiftedState } from '@redux-devtools/core'; import * as themes from 'redux-devtools-themes'; @@ -12,7 +12,8 @@ const wrapperStyle = { }; export interface Props> - extends LiftedState { + extends LiftedState, + Options { dispatch: Dispatch>; preserveScrollTop: boolean; select: (state: S) => unknown; @@ -20,76 +21,10 @@ export interface Props> invertTheme: boolean; state: S | null; - isSorted: boolean; - heightBetweenNodesCoeff: number; - widthBetweenNodesCoeff: number; - onClickText: (datum: NodeWithId) => void; - tooltipOptions: { - disabled: boolean; - offset: { - left: number; - top: number; - }; - indentationSize: number; - style: { [key: string]: Primitive } | undefined; - }; - style: { [key: string]: Primitive } | undefined; defaultIsVisible?: boolean; } class Chart> extends Component> { - static propTypes = { - state: PropTypes.object, - rootKeyName: PropTypes.string, - pushMethod: PropTypes.oneOf(['push', 'unshift']), - tree: PropTypes.shape({ - name: PropTypes.string, - children: PropTypes.array, - }), - id: PropTypes.string, - style: PropTypes.shape({ - node: PropTypes.shape({ - colors: PropTypes.shape({ - default: PropTypes.string, - parent: PropTypes.string, - collapsed: PropTypes.string, - }), - radius: PropTypes.number, - }), - text: PropTypes.shape({ - colors: PropTypes.shape({ - default: PropTypes.string, - hover: PropTypes.string, - }), - }), - link: PropTypes.object, - }), - size: PropTypes.number, - aspectRatio: PropTypes.number, - margin: PropTypes.shape({ - top: PropTypes.number, - right: PropTypes.number, - bottom: PropTypes.number, - left: PropTypes.number, - }), - isSorted: PropTypes.bool, - heightBetweenNodesCoeff: PropTypes.number, - widthBetweenNodesCoeff: PropTypes.number, - transitionDuration: PropTypes.number, - onClickText: PropTypes.func, - tooltipOptions: PropTypes.shape({ - disabled: PropTypes.bool, - left: PropTypes.number, - top: PropTypes.number, - offset: PropTypes.shape({ - left: PropTypes.number, - top: PropTypes.number, - }), - indentationSize: PropTypes.number, - style: PropTypes.object, - }), - }; - divRef = createRef(); // eslint-disable-next-line @typescript-eslint/ban-types renderChart?: (state?: {} | null | undefined) => void; diff --git a/packages/redux-devtools-chart-monitor/src/ChartMonitor.tsx b/packages/redux-devtools-chart-monitor/src/ChartMonitor.tsx index 18eb4feb..660c29a5 100644 --- a/packages/redux-devtools-chart-monitor/src/ChartMonitor.tsx +++ b/packages/redux-devtools-chart-monitor/src/ChartMonitor.tsx @@ -1,5 +1,4 @@ import React, { CSSProperties, PureComponent } from 'react'; -import PropTypes from 'prop-types'; import * as themes from 'redux-devtools-themes'; import { ActionCreators, @@ -8,7 +7,7 @@ import { } from '@redux-devtools/core'; import deepmerge from 'deepmerge'; import { Action, Dispatch } from 'redux'; -import { NodeWithId, Primitive } from 'd3-state-visualizer'; +import type { Options } from 'd3-state-visualizer'; import reducer, { ChartMonitorState } from './reducers'; import Chart, { Props } from './Chart'; @@ -41,37 +40,14 @@ function invertColors(theme: themes.Base16Theme) { } export interface ChartMonitorProps> - extends LiftedState { + extends LiftedState, + Options { dispatch: Dispatch>; preserveScrollTop: boolean; select: (state: S) => unknown; theme: keyof typeof themes | themes.Base16Theme; invertTheme: boolean; - state: S | null; - isSorted: boolean; - heightBetweenNodesCoeff: number; - widthBetweenNodesCoeff: number; - onClickText: (datum: NodeWithId) => void; - tooltipOptions: unknown; - style: { - width: number; - height: number; - node: { - colors: { - default: string; - collapsed: string; - parent: string; - }; - radius: number; - }; - text: { - colors: { - default: string; - hover: string; - }; - }; - }; defaultIsVisible?: boolean; } @@ -80,23 +56,6 @@ class ChartMonitor> extends PureComponent< > { static update = reducer; - static propTypes = { - dispatch: PropTypes.func, - computedStates: PropTypes.array, - currentStateIndex: PropTypes.number, - actionsById: PropTypes.object, - stagedActionIds: PropTypes.array, - skippedActionIds: PropTypes.array, - monitorState: PropTypes.shape({ - initialScrollTop: PropTypes.number, - }), - - preserveScrollTop: PropTypes.bool, - select: PropTypes.func.isRequired, - theme: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - invertTheme: PropTypes.bool, - }; - static defaultProps = { select: (state: unknown) => state, theme: 'nicinabox', @@ -140,45 +99,10 @@ class ChartMonitor> extends PureComponent< return invertTheme ? invertColors(themes.nicinabox) : themes.nicinabox; } - getChartStyle() { - const theme = this.getTheme(); - - return { - width: '100%', - height: '100%', - node: { - colors: { - default: theme.base0B, - collapsed: theme.base0B, - parent: theme.base0E, - }, - radius: 7, - }, - text: { - colors: { - default: theme.base0D, - hover: theme.base06, - }, - }, - }; - } - getChartOptions(props = this.props): Props { const { computedStates } = props; const theme = this.getTheme(); - const tooltipOptions = { - disabled: false, - offset: { left: 30, top: 10 }, - indentationSize: 2, - style: { - 'background-color': theme.base06, - opacity: '0.7', - 'border-radius': '5px', - padding: '5px', - }, - }; - const defaultOptions = { state: computedStates.length ? computedStates[props.currentStateIndex].state @@ -186,10 +110,35 @@ class ChartMonitor> extends PureComponent< isSorted: false, heightBetweenNodesCoeff: 1, widthBetweenNodesCoeff: 1.3, - tooltipOptions, - style: this.getChartStyle() as unknown as - | { [key: string]: Primitive } - | undefined, + tooltipOptions: { + disabled: false, + offset: { left: 30, top: 10 }, + indentationSize: 2, + styles: { + 'background-color': theme.base06, + opacity: '0.7', + 'border-radius': '5px', + padding: '5px', + }, + }, + chartStyles: { + width: '100%', + height: '100%', + }, + nodeStyleOptions: { + colors: { + default: theme.base0B, + collapsed: theme.base0B, + parent: theme.base0E, + }, + radius: 7, + }, + textStyleOptions: { + colors: { + default: theme.base0D, + hover: theme.base06, + }, + }, }; return deepmerge(defaultOptions, props); @@ -198,10 +147,9 @@ class ChartMonitor> extends PureComponent< render() { const theme = this.getTheme(); - const ChartAsAny = Chart as any; return (
- +
); } diff --git a/packages/redux-devtools-cli/jest.config.js b/packages/redux-devtools-cli/jest.config.js index 05d33807..f68efd05 100644 --- a/packages/redux-devtools-cli/jest.config.js +++ b/packages/redux-devtools-cli/jest.config.js @@ -1,8 +1,6 @@ module.exports = { preset: 'ts-jest', - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, }; diff --git a/packages/redux-devtools-cli/package.json b/packages/redux-devtools-cli/package.json index 4cc982ab..6d054c7d 100644 --- a/packages/redux-devtools-cli/package.json +++ b/packages/redux-devtools-cli/package.json @@ -41,57 +41,57 @@ }, "dependencies": { "@redux-devtools/app": "^2.1.3", - "@types/react": "^18.0.14", - "apollo-server-express": "^3.9.0", - "body-parser": "^1.20.0", + "@types/react": "^18.0.26", + "apollo-server-express": "^3.11.1", + "body-parser": "^1.20.1", "chalk": "^4.1.2", "cors": "^2.8.5", "cross-spawn": "^7.0.3", - "electron": "^19.0.4", - "express": "^4.18.1", + "electron": "^22.0.0", + "express": "^4.18.2", "getport": "^0.1.0", - "graphql": "^16.5.0", - "knex": "^2.1.0", + "graphql": "^16.6.0", + "knex": "^2.3.0", "lodash": "^4.17.21", - "minimist": "^1.2.6", + "minimist": "^1.2.7", "morgan": "^1.10.0", "open": "^8.4.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-is": "^18.2.0", - "semver": "^7.3.7", - "socketcluster-server": "^16.2.1", - "sqlite3": "^5.0.8", - "styled-components": "^5.3.5", - "uuid": "^8.3.2" + "semver": "^7.3.8", + "socketcluster-server": "^17.2.0", + "sqlite3": "^5.1.4", + "styled-components": "^5.3.6", + "uuid": "^9.0.0" }, "devDependencies": { "@types/body-parser": "^1.19.2", - "@types/cors": "^2.8.12", + "@types/cors": "^2.8.13", "@types/cross-spawn": "^6.0.2", - "@types/express": "^4.17.13", - "@types/jest": "^27.5.2", - "@types/lodash": "^4.14.182", + "@types/express": "^4.17.15", + "@types/jest": "^29.2.4", + "@types/lodash": "^4.14.191", "@types/minimist": "^1.2.2", "@types/morgan": "^1.9.3", - "@types/node": "^16.11.41", - "@types/semver": "^7.3.10", + "@types/node": "^18.11.17", + "@types/semver": "^7.3.13", "@types/socketcluster-client": "^16.0.0", "@types/socketcluster-server": "^16.1.0", - "@types/styled-components": "^5.1.25", + "@types/styled-components": "^5.1.26", "@types/supertest": "^2.0.12", - "@types/uuid": "^8.3.4", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@types/uuid": "^9.0.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "jest": "^27.5.1", + "eslint-plugin-jest": "^27.1.7", + "jest": "^29.3.1", "ncp": "^2.0.0", "rimraf": "^3.0.2", - "socketcluster-client": "^16.1.1", - "supertest": "^6.2.3", - "ts-jest": "^27.1.5", - "typescript": "~4.7.4" + "socketcluster-client": "^17.1.0", + "supertest": "^6.3.3", + "ts-jest": "^29.0.3", + "typescript": "~4.9.4" } } diff --git a/packages/redux-devtools-dock-monitor/package.json b/packages/redux-devtools-dock-monitor/package.json index 90ad87f3..22589df8 100644 --- a/packages/redux-devtools-dock-monitor/package.json +++ b/packages/redux-devtools-dock-monitor/package.json @@ -41,33 +41,33 @@ "prepublish": "pnpm run type-check && pnpm run lint" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "@types/prop-types": "^15.7.5", "parse-key": "^0.2.1", "prop-types": "^15.8.1", "react-dock": "^0.6.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@redux-devtools/core": "^3.13.1", "@types/parse-key": "^0.2.0", - "@types/react": "^18.0.14", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@types/react": "^18.0.26", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", "react": "^18.2.0", "redux": "^4.2.0", "rimraf": "^3.0.2", - "typescript": "~4.7.4" + "typescript": "~4.9.4" }, "peerDependencies": { "@redux-devtools/core": "^3.13.1", diff --git a/packages/redux-devtools-extension/CHANGELOG.md b/packages/redux-devtools-extension/CHANGELOG.md index 80596c1e..d49676a4 100644 --- a/packages/redux-devtools-extension/CHANGELOG.md +++ b/packages/redux-devtools-extension/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.2.3 + +### Patch Changes + +- 6cf1865f: Fix type for serialize option + ## 3.2.2 ### Patch Changes diff --git a/packages/redux-devtools-extension/package.json b/packages/redux-devtools-extension/package.json index c28f77c3..eacc2352 100644 --- a/packages/redux-devtools-extension/package.json +++ b/packages/redux-devtools-extension/package.json @@ -1,6 +1,6 @@ { "name": "@redux-devtools/extension", - "version": "3.2.2", + "version": "3.2.3", "description": "Wrappers for Redux DevTools Extension.", "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-extension", "license": "MIT", @@ -29,22 +29,23 @@ "prepublish": "pnpm run type-check && pnpm run lint" }, "dependencies": { - "@babel/runtime": "^7.18.3" + "@babel/runtime": "^7.20.6", + "immutable": "^4.1.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-typescript": "^7.17.12", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", "redux": "^4.2.0", "rimraf": "^3.0.2", - "typescript": "~4.7.4" + "typescript": "~4.9.4" }, "peerDependencies": { "redux": "^3.1.0 || ^4.0.0" diff --git a/packages/redux-devtools-extension/src/index.ts b/packages/redux-devtools-extension/src/index.ts index 140909cf..54ba0545 100644 --- a/packages/redux-devtools-extension/src/index.ts +++ b/packages/redux-devtools-extension/src/index.ts @@ -1,3 +1,4 @@ +import Immutable from 'immutable'; import { Action, ActionCreator, compose, StoreEnhancer } from 'redux'; export interface EnhancerOptions { @@ -25,26 +26,58 @@ export interface EnhancerOptions { */ maxAge?: number; /** - * - `undefined` - will use regular `JSON.stringify` to send data (it's the fast mode). - * - `false` - will handle also circular references. - * - `true` - will handle also date, regex, undefined, error objects, symbols, maps, sets and functions. - * - object, which contains `date`, `regex`, `undefined`, `error`, `symbol`, `map`, `set` and `function` keys. - * For each of them you can indicate if to include (by setting as `true`). - * For `function` key you can also specify a custom function which handles serialization. - * See [`jsan`](https://github.com/kolodny/jsan) for more details. + * Customizes how actions and state are serialized and deserialized. Can be a boolean or object. If given a boolean, the behavior is the same as if you + * were to pass an object and specify `options` as a boolean. Giving an object allows fine-grained customization using the `replacer` and `reviver` + * functions. */ serialize?: | boolean | { - date?: boolean; - regex?: boolean; - undefined?: boolean; - error?: boolean; - symbol?: boolean; - map?: boolean; - set?: boolean; - // eslint-disable-next-line @typescript-eslint/ban-types - function?: boolean | Function; + /** + * - `undefined` - will use regular `JSON.stringify` to send data (it's the fast mode). + * - `false` - will handle also circular references. + * - `true` - will handle also date, regex, undefined, error objects, symbols, maps, sets and functions. + * - object, which contains `date`, `regex`, `undefined`, `error`, `symbol`, `map`, `set` and `function` keys. + * For each of them you can indicate if to include (by setting as `true`). + * For `function` key you can also specify a custom function which handles serialization. + * See [`jsan`](https://github.com/kolodny/jsan) for more details. + */ + options?: + | undefined + | boolean + | { + date?: true; + regex?: true; + undefined?: true; + error?: true; + symbol?: true; + map?: true; + set?: true; + function?: true | ((fn: (...args: any[]) => any) => string); + }; + /** + * [JSON replacer function](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter) used for both actions and states stringify. + * In addition, you can specify a data type by adding a [`__serializedType__`](https://github.com/zalmoxisus/remotedev-serialize/blob/master/helpers/index.js#L4) + * key. So you can deserialize it back while importing or persisting data. + * Moreover, it will also [show a nice preview showing the provided custom type](https://cloud.githubusercontent.com/assets/7957859/21814330/a17d556a-d761-11e6-85ef-159dd12f36c5.png): + */ + replacer?: (key: string, value: unknown) => any; + /** + * [JSON `reviver` function](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_the_reviver_parameter) + * used for parsing the imported actions and states. See [`remotedev-serialize`](https://github.com/zalmoxisus/remotedev-serialize/blob/master/immutable/serialize.js#L8-L41) + * as an example on how to serialize special data types and get them back. + */ + reviver?: (key: string, value: unknown) => any; + /** + * Automatically serialize/deserialize immutablejs via [remotedev-serialize](https://github.com/zalmoxisus/remotedev-serialize). + * Just pass the Immutable library. It will support all ImmutableJS structures. You can even export them into a file and get them back. + * The only exception is `Record` class, for which you should pass this in addition the references to your classes in `refs`. + */ + immutable?: typeof Immutable; + /** + * ImmutableJS `Record` classes used to make possible restore its instances back when importing, persisting... + */ + refs?: Immutable.Record.Factory[]; }; /** * function which takes `action` object and id number as arguments, and should return `action` object back. diff --git a/packages/redux-devtools-extension/src/utils/assign.ts b/packages/redux-devtools-extension/src/utils/assign.ts index b9588369..c0a193ef 100644 --- a/packages/redux-devtools-extension/src/utils/assign.ts +++ b/packages/redux-devtools-extension/src/utils/assign.ts @@ -8,7 +8,7 @@ const objectKeys = return keys; }; -export default function assign( +export default function assign( obj: T, newKey: K, newValue: T[K] diff --git a/packages/redux-devtools-inspector-monitor-test-tab/demo/package.json b/packages/redux-devtools-inspector-monitor-test-tab/demo/package.json index 6c6ea102..96b2d9d0 100644 --- a/packages/redux-devtools-inspector-monitor-test-tab/demo/package.json +++ b/packages/redux-devtools-inspector-monitor-test-tab/demo/package.json @@ -20,40 +20,40 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-is": "^18.2.0", - "react-redux": "^8.0.2", - "react-router-dom": "^6.3.0", + "react-redux": "^8.0.5", + "react-router-dom": "^6.6.0", "redux": "^4.2.0", "redux-logger": "^3.0.6", - "styled-components": "^5.3.5" + "styled-components": "^5.3.6" }, "devDependencies": { - "@babel/core": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/core": "^7.20.5", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@types/lodash.shuffle": "^4.2.7", - "@types/node": "^16.11.41", - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", + "@types/node": "^18.11.17", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", "@types/redux-logger": "^3.0.9", - "@types/styled-components": "^5.1.25", - "@types/webpack-env": "^1.17.0", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "babel-loader": "^8.2.5", + "@types/styled-components": "^5.1.26", + "@types/webpack-env": "^1.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "babel-loader": "^9.1.0", "cross-env": "^7.0.3", - "css-loader": "^6.7.1", - "eslint": "^8.18.0", + "css-loader": "^6.7.3", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "fork-ts-checker-webpack-plugin": "^7.2.11", + "fork-ts-checker-webpack-plugin": "^7.2.14", "html-webpack-plugin": "^5.5.0", "style-loader": "^3.3.1", - "ts-node": "^10.8.1", - "typescript": "~4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.2" + "ts-node": "^10.9.1", + "typescript": "~4.9.4", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" } } diff --git a/packages/redux-devtools-inspector-monitor-test-tab/jest.config.js b/packages/redux-devtools-inspector-monitor-test-tab/jest.config.js index bf9761dc..b5063992 100644 --- a/packages/redux-devtools-inspector-monitor-test-tab/jest.config.js +++ b/packages/redux-devtools-inspector-monitor-test-tab/jest.config.js @@ -4,9 +4,9 @@ module.exports = { moduleNameMapper: { '\\.css$': '/test/__mocks__/styleMock.ts', }, - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.jsx?$': 'babel-jest', + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, + transformIgnorePatterns: ['node_modules/(?!.pnpm|nanoid)'], }; diff --git a/packages/redux-devtools-inspector-monitor-test-tab/package.json b/packages/redux-devtools-inspector-monitor-test-tab/package.json index 97cad327..f0d259ba 100644 --- a/packages/redux-devtools-inspector-monitor-test-tab/package.json +++ b/packages/redux-devtools-inspector-monitor-test-tab/package.json @@ -43,7 +43,7 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "@redux-devtools/ui": "^1.3.0", "@types/prop-types": "^15.7.5", "es6template": "^1.0.5", @@ -51,47 +51,48 @@ "jsan": "^3.1.14", "object-path": "^0.11.8", "prop-types": "^15.8.1", - "react-icons": "^4.4.0", + "react-icons": "^4.7.1", "simple-diff": "^1.6.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@redux-devtools/core": "^3.13.0", "@redux-devtools/inspector-monitor": "^3.0.0", - "@testing-library/react": "^13.3.0", + "@testing-library/react": "^13.4.0", "@types/es6template": "^1.0.0", - "@types/jest": "^27.5.2", + "@types/jest": "^29.2.4", "@types/jsan": "^3.1.2", "@types/object-path": "^0.11.1", - "@types/react": "^18.0.14", + "@types/react": "^18.0.26", "@types/simple-diff": "^1.6.1", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "jest": "^27.5.1", + "jest": "^29.3.1", + "jest-environment-jsdom": "^29.3.1", "react": "^18.2.0", "react-dom": "^18.2.0", "redux": "^4.2.0", "rimraf": "^3.0.2", - "ts-jest": "^27.1.5", - "typescript": "~4.7.4" + "ts-jest": "^29.0.3", + "typescript": "~4.9.4" }, "peerDependencies": { "@redux-devtools/inspector-monitor": "^3.0.0", "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "@types/styled-components": "^5.1.25", + "@types/styled-components": "^5.1.26", "react": "^16.3.0 || ^17.0.0 || ^18.0.0", "redux": "^3.4.0 || ^4.0.0", - "styled-components": "^5.3.5" + "styled-components": "^5.3.6" } } diff --git a/packages/redux-devtools-inspector-monitor-test-tab/src/index.tsx b/packages/redux-devtools-inspector-monitor-test-tab/src/index.tsx index 1dd54784..91d23019 100644 --- a/packages/redux-devtools-inspector-monitor-test-tab/src/index.tsx +++ b/packages/redux-devtools-inspector-monitor-test-tab/src/index.tsx @@ -155,11 +155,13 @@ export class TestTab> extends Component< {...rest} /> )} - {!persistedState.hideTip && assertion && rest.startActionId === null && ( - - Hold SHIFT key to select more actions. - - )} + {!persistedState.hideTip && + assertion && + rest.startActionId === null && ( + + Hold SHIFT key to select more actions. + + )} {dialogStatus && ( open diff --git a/packages/redux-devtools-inspector-monitor-trace-tab/package.json b/packages/redux-devtools-inspector-monitor-trace-tab/package.json index 1cebe74d..99c827bf 100644 --- a/packages/redux-devtools-inspector-monitor-trace-tab/package.json +++ b/packages/redux-devtools-inspector-monitor-trace-tab/package.json @@ -30,9 +30,9 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@types/chrome": "^0.0.190", + "@babel/code-frame": "^7.18.6", + "@babel/runtime": "^7.20.6", + "@types/chrome": "^0.0.206", "anser": "^2.1.1", "html-entities": "^2.3.3", "path-browserify": "^1.0.1", @@ -40,39 +40,40 @@ "source-map": "^0.5.7" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@redux-devtools/core": "^3.13.0", "@redux-devtools/inspector-monitor": "^3.0.0", - "@testing-library/react": "^13.3.0", + "@testing-library/react": "^13.4.0", "@types/babel__code-frame": "^7.0.3", "@types/html-entities": "^1.3.4", - "@types/jest": "^27.5.2", - "@types/node": "^16.11.41", + "@types/jest": "^29.2.4", + "@types/node": "^18.11.17", "@types/path-browserify": "^1.0.0", - "@types/react": "^18.0.14", + "@types/react": "^18.0.26", "@types/redux-devtools-themes": "^1.0.0", "@types/source-map": "0.5.2", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "jest": "^27.5.1", + "jest": "^29.3.1", + "jest-environment-jsdom": "^29.3.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-test-renderer": "^18.2.0", "redux": "^4.2.0", "rimraf": "^3.0.2", - "ts-jest": "^27.1.5", - "typescript": "~4.7.4" + "ts-jest": "^29.0.3", + "typescript": "~4.9.4" }, "peerDependencies": { "@redux-devtools/inspector-monitor": "^3.0.0", diff --git a/packages/redux-devtools-inspector-monitor-trace-tab/rollup.config.js b/packages/redux-devtools-inspector-monitor-trace-tab/rollup.config.js deleted file mode 100644 index 93ef2d27..00000000 --- a/packages/redux-devtools-inspector-monitor-trace-tab/rollup.config.js +++ /dev/null @@ -1,39 +0,0 @@ -import typescript from 'rollup-plugin-typescript2'; -import babel from '@rollup/plugin-babel'; -import nodePolyfills from 'rollup-plugin-node-polyfills'; - -const config = [ - { - input: 'src/StackTraceTab.tsx', - output: [ - { - file: 'dist/redux-devtools-inspector-monitor-trace-tab.cjs.js', - format: 'cjs', - }, - { - file: 'dist/redux-devtools-inspector-monitor-trace-tab.esm.js', - format: 'esm', - }, - ], - plugins: [ - typescript(), - babel({ - babelHelpers: 'runtime', - extensions: ['.ts', '.tsx'], - plugins: ['@babel/plugin-transform-runtime'], - }), - nodePolyfills(), - ], - external: [ - /@babel\/runtime/, - 'react', - 'redux-devtools-themes', - 'source-map', - '@babel/code-frame', - 'anser', - 'html-entities', - ], - }, -]; - -export default config; diff --git a/packages/redux-devtools-inspector-monitor/demo/package.json b/packages/redux-devtools-inspector-monitor/demo/package.json index b0e255e5..e858c15b 100644 --- a/packages/redux-devtools-inspector-monitor/demo/package.json +++ b/packages/redux-devtools-inspector-monitor/demo/package.json @@ -17,39 +17,39 @@ "immutable": "^4.1.0", "lodash.shuffle": "^4.2.0", "react": "^18.2.0", - "react-bootstrap": "^2.4.0", + "react-bootstrap": "^2.7.0", "react-dom": "^18.2.0", - "react-redux": "^8.0.2", - "react-router-dom": "^6.3.0", + "react-redux": "^8.0.5", + "react-router-dom": "^6.6.0", "redux": "^4.2.0", "redux-logger": "^3.0.6" }, "devDependencies": { - "@babel/core": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/core": "^7.20.5", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@types/base16": "^1.0.2", "@types/lodash.shuffle": "^4.2.7", - "@types/node": "^16.11.41", - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", + "@types/node": "^18.11.17", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", "@types/redux-logger": "^3.0.9", - "@types/webpack-env": "^1.17.0", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "babel-loader": "^8.2.5", + "@types/webpack-env": "^1.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "babel-loader": "^9.1.0", "cross-env": "^7.0.3", - "eslint": "^8.18.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "fork-ts-checker-webpack-plugin": "^7.2.11", + "fork-ts-checker-webpack-plugin": "^7.2.14", "html-webpack-plugin": "^5.5.0", - "ts-node": "^10.8.1", - "typescript": "~4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.2" + "ts-node": "^10.9.1", + "typescript": "~4.9.4", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" } } diff --git a/packages/redux-devtools-inspector-monitor/package.json b/packages/redux-devtools-inspector-monitor/package.json index 7a446058..c32ec949 100644 --- a/packages/redux-devtools-inspector-monitor/package.json +++ b/packages/redux-devtools-inspector-monitor/package.json @@ -35,17 +35,17 @@ "prepublish": "pnpm run type-check && pnpm run lint" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "@types/dragula": "^3.7.1", - "@types/lodash": "^4.14.182", + "@types/lodash": "^4.14.191", "@types/prop-types": "^15.7.5", - "dateformat": "^4.6.3", + "dateformat": "^5.0.3", "hex-rgba": "^1.0.2", "immutable": "^4.1.0", "javascript-stringify": "^2.1.0", "jsondiffpatch": "^0.4.1", - "jss": "^10.9.0", - "jss-preset-default": "^10.9.0", + "jss": "^10.9.2", + "jss-preset-default": "^10.9.2", "lodash.debounce": "^4.0.8", "prop-types": "^15.8.1", "react-base16-styling": "^0.9.1", @@ -54,31 +54,31 @@ "redux-devtools-themes": "^1.0.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@redux-devtools/core": "^3.13.1", - "@types/dateformat": "^3.0.1", + "@types/dateformat": "^5.0.0", "@types/hex-rgba": "^1.0.1", "@types/history": "^4.7.11", "@types/lodash.debounce": "^4.0.7", - "@types/react": "^18.0.14", + "@types/react": "^18.0.26", "@types/react-dragula": "^1.1.0", "@types/redux-devtools-themes": "^1.0.0", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", "react": "^18.2.0", "redux": "^4.2.0", "rimraf": "^3.0.2", - "typescript": "~4.7.4" + "typescript": "~4.9.4" }, "peerDependencies": { "@redux-devtools/core": "^3.13.1", diff --git a/packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx b/packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx index 5fbf4f3c..0d28d107 100644 --- a/packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx +++ b/packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { Base16Theme } from 'redux-devtools-themes'; import { Action } from 'redux'; -import { StylingFunction } from 'react-base16-styling'; +import type { StylingFunction } from 'react-base16-styling'; import { PerformAction } from '@redux-devtools/core'; import { Delta } from 'jsondiffpatch'; import { DEFAULT_STATE, DevtoolsInspectorState } from './redux'; diff --git a/packages/redux-devtools-inspector-monitor/src/index.ts b/packages/redux-devtools-inspector-monitor/src/index.ts index 0b0cd949..2861d4e5 100644 --- a/packages/redux-devtools-inspector-monitor/src/index.ts +++ b/packages/redux-devtools-inspector-monitor/src/index.ts @@ -1,3 +1,4 @@ +export type { StylingFunction } from 'react-base16-styling'; export { default as InspectorMonitor } from './DevtoolsInspector'; export type { Tab, TabComponentProps } from './ActionPreview'; export type { DevtoolsInspectorState } from './redux'; diff --git a/packages/redux-devtools-instrument/jest.config.js b/packages/redux-devtools-instrument/jest.config.js index 05d33807..f68efd05 100644 --- a/packages/redux-devtools-instrument/jest.config.js +++ b/packages/redux-devtools-instrument/jest.config.js @@ -1,8 +1,6 @@ module.exports = { preset: 'ts-jest', - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, }; diff --git a/packages/redux-devtools-instrument/package.json b/packages/redux-devtools-instrument/package.json index 5070ebe6..c682904c 100644 --- a/packages/redux-devtools-instrument/package.json +++ b/packages/redux-devtools-instrument/package.json @@ -41,30 +41,30 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "lodash": "^4.17.21" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-typescript": "^7.17.12", - "@types/jest": "^27.5.2", - "@types/lodash": "^4.14.182", - "@types/node": "^16.11.41", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", + "@types/jest": "^29.2.4", + "@types/lodash": "^4.14.191", + "@types/node": "^18.11.17", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "jest": "^27.5.1", + "eslint-plugin-jest": "^27.1.7", + "jest": "^29.3.1", "redux": "^4.2.0", "rimraf": "^3.0.2", - "rxjs": "^7.5.5", - "ts-jest": "^27.1.5", - "typescript": "~4.7.4" + "rxjs": "^7.8.0", + "ts-jest": "^29.0.3", + "typescript": "~4.9.4" }, "peerDependencies": { "redux": "^3.4.0 || ^4.0.0" diff --git a/packages/redux-devtools-log-monitor/package.json b/packages/redux-devtools-log-monitor/package.json index 6b820d25..c7bb39af 100644 --- a/packages/redux-devtools-log-monitor/package.json +++ b/packages/redux-devtools-log-monitor/package.json @@ -41,7 +41,7 @@ "prepublish": "pnpm run type-check && pnpm run lint" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "@types/lodash.debounce": "^4.0.7", "@types/prop-types": "^15.7.5", "@types/redux-devtools-themes": "^1.0.0", @@ -51,25 +51,25 @@ "redux-devtools-themes": "^1.0.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@redux-devtools/core": "^3.13.1", - "@types/react": "^18.0.14", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@types/react": "^18.0.26", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", "react": "^18.2.0", "redux": "^4.2.0", "rimraf": "^3.0.2", - "typescript": "~4.7.4" + "typescript": "~4.9.4" }, "peerDependencies": { "@redux-devtools/core": "^3.13.1", diff --git a/packages/redux-devtools-remote/package.json b/packages/redux-devtools-remote/package.json index c03c1140..0066cdf7 100644 --- a/packages/redux-devtools-remote/package.json +++ b/packages/redux-devtools-remote/package.json @@ -41,32 +41,32 @@ "prepublish": "pnpm run type-check && pnpm run lint" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "@redux-devtools/instrument": "^2.1.0", "@redux-devtools/utils": "^2.0.0", "jsan": "^3.1.14", "querystring": "^0.2.1", "rn-host-detect": "^1.2.0", - "socketcluster-client": "^16.1.1" + "socketcluster-client": "^17.1.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", "@types/jsan": "^3.1.2", - "@types/node": "^16.11.41", + "@types/node": "^18.11.17", "@types/rn-host-detect": "^1.2.0", "@types/socketcluster-client": "^16.0.0", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", "redux": "^4.2.0", "rimraf": "^3.0.2", - "typescript": "~4.7.4" + "typescript": "~4.9.4" }, "peerDependencies": { "redux": "^3.5.2 || ^4.0.0" diff --git a/packages/redux-devtools-rtk-query-monitor/.eslintignore b/packages/redux-devtools-rtk-query-monitor/.eslintignore index d3c23dcb..de820eed 100644 --- a/packages/redux-devtools-rtk-query-monitor/.eslintignore +++ b/packages/redux-devtools-rtk-query-monitor/.eslintignore @@ -1,2 +1,3 @@ demo lib +dist diff --git a/packages/redux-devtools-rtk-query-monitor/.eslintrc.js b/packages/redux-devtools-rtk-query-monitor/.eslintrc.js index 87abc2e1..e62f5871 100644 --- a/packages/redux-devtools-rtk-query-monitor/.eslintrc.js +++ b/packages/redux-devtools-rtk-query-monitor/.eslintrc.js @@ -9,5 +9,13 @@ module.exports = { project: ['./tsconfig.json'], }, }, + { + files: ['test/**/*.ts', 'test/**/*.tsx'], + extends: '../../eslintrc.ts.react.jest.base.json', + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./tsconfig.test.json'], + }, + }, ], }; diff --git a/packages/redux-devtools-rtk-query-monitor/CHANGELOG.md b/packages/redux-devtools-rtk-query-monitor/CHANGELOG.md index 54c86762..f065600f 100644 --- a/packages/redux-devtools-rtk-query-monitor/CHANGELOG.md +++ b/packages/redux-devtools-rtk-query-monitor/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.1.0 + +### Minor Changes + +- 24f60a7a: feat(rtk-query): add Data tab to rtk-query-monitor #1126 #1129 + ## 3.0.1 ### Patch Changes diff --git a/packages/redux-devtools-rtk-query-monitor/demo/CHANGELOG.md b/packages/redux-devtools-rtk-query-monitor/demo/CHANGELOG.md index 04906628..f729253a 100644 --- a/packages/redux-devtools-rtk-query-monitor/demo/CHANGELOG.md +++ b/packages/redux-devtools-rtk-query-monitor/demo/CHANGELOG.md @@ -1,5 +1,13 @@ # rtk-query-demo +## 0.1.10 + +### Patch Changes + +- 24f60a7a: fix: rtk-query-monitor demo not working #1126 #1129 +- Updated dependencies [24f60a7a] + - @redux-devtools/rtk-query-monitor@3.1.0 + ## 0.1.9 ### Patch Changes diff --git a/packages/redux-devtools-rtk-query-monitor/demo/package.json b/packages/redux-devtools-rtk-query-monitor/demo/package.json index 3ec78bee..6e8c8229 100644 --- a/packages/redux-devtools-rtk-query-monitor/demo/package.json +++ b/packages/redux-devtools-rtk-query-monitor/demo/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "rtk-query-demo", - "version": "0.1.9", + "version": "0.1.10", "license": "MIT", "scripts": { "start": "cross-env TS_NODE_PROJECT=\"tsconfig.webpack.json\" webpack serve --open", @@ -10,54 +10,54 @@ "type-check": "tsc --noEmit" }, "dependencies": { - "@babel/runtime": "^7.18.3", - "@chakra-ui/react": "^2.2.1", - "@emotion/react": "^11.9.3", - "@emotion/styled": "^11.9.3", - "@mswjs/data": "^0.10.1", + "@babel/runtime": "^7.20.6", + "@chakra-ui/react": "^2.4.4", + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", + "@mswjs/data": "^0.11.0", "@redux-devtools/core": "^3.13.0", "@redux-devtools/dock-monitor": "^3.0.0", - "@redux-devtools/rtk-query-monitor": "^3.0.0", - "@reduxjs/toolkit": "^1.8.2", - "framer-motion": "^6.3.11", - "msw": "^0.42.1", + "@redux-devtools/rtk-query-monitor": "^3.1.0", + "@reduxjs/toolkit": "^1.9.1", + "framer-motion": "^8.0.1", + "msw": "^0.49.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-icons": "^4.4.0", + "react-icons": "^4.7.1", "react-is": "^18.2.0", - "react-redux": "^8.0.2", - "react-router-dom": "^6.3.0", - "styled-components": "^5.3.5" + "react-redux": "^8.0.5", + "react-router-dom": "^6.6.0", + "styled-components": "^5.3.6" }, "devDependencies": { - "@babel/core": "^7.18.5", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/core": "^7.20.5", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@types/copy-webpack-plugin": "^8.0.1", - "@types/node": "^16.11.41", - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", - "@types/styled-components": "^5.1.25", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "babel-loader": "^8.2.5", + "@types/node": "^18.11.17", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", + "@types/styled-components": "^5.1.26", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "babel-loader": "^9.1.0", "copy-webpack-plugin": "^11.0.0", "cross-env": "^7.0.3", - "css-loader": "^6.7.1", - "eslint": "^8.18.0", + "css-loader": "^6.7.3", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "fork-ts-checker-webpack-plugin": "^7.2.11", + "fork-ts-checker-webpack-plugin": "^7.2.14", "html-webpack-plugin": "^5.5.0", "style-loader": "^3.3.1", - "ts-node": "^10.8.1", - "typescript": "~4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.2" + "ts-node": "^10.9.1", + "typescript": "~4.9.4", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" }, "msw": { "workerDirectory": "public" diff --git a/packages/redux-devtools-rtk-query-monitor/jest.config.js b/packages/redux-devtools-rtk-query-monitor/jest.config.js new file mode 100644 index 00000000..b5063992 --- /dev/null +++ b/packages/redux-devtools-rtk-query-monitor/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'jsdom', + moduleNameMapper: { + '\\.css$': '/test/__mocks__/styleMock.ts', + }, + transform: { + '^.+\\.jsx?$': 'babel-jest', + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], + }, + transformIgnorePatterns: ['node_modules/(?!.pnpm|nanoid)'], +}; diff --git a/packages/redux-devtools-rtk-query-monitor/package.json b/packages/redux-devtools-rtk-query-monitor/package.json index 27e39614..fc2d24c0 100644 --- a/packages/redux-devtools-rtk-query-monitor/package.json +++ b/packages/redux-devtools-rtk-query-monitor/package.json @@ -1,6 +1,6 @@ { "name": "@redux-devtools/rtk-query-monitor", - "version": "3.0.1", + "version": "3.1.0", "description": "rtk-query monitor for Redux DevTools", "keywords": [ "redux", @@ -37,21 +37,22 @@ "build:esm": "babel src --config-file ./babel.config.esm.json --extensions \".ts,.tsx\" --out-dir lib/esm", "build:types": "tsc --emitDeclarationOnly", "clean": "rimraf lib", + "test": "jest", "lint": "eslint . --ext .ts,.tsx", "type-check": "tsc --noEmit", "prepack": "pnpm run clean && pnpm run build", - "prepublish": "pnpm run type-check && pnpm run lint" + "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "@redux-devtools/ui": "^1.3.0", - "@types/lodash": "^4.14.182", + "@types/lodash": "^4.14.191", "@types/prop-types": "^15.7.5", "@types/redux-devtools-themes": "^1.0.0", "hex-rgba": "^1.0.2", "immutable": "^4.1.0", - "jss": "^10.9.0", - "jss-preset-default": "^10.9.0", + "jss": "^10.9.2", + "jss-preset-default": "^10.9.2", "lodash.debounce": "^4.0.8", "prop-types": "^15.8.1", "react-base16-styling": "^0.9.1", @@ -59,36 +60,45 @@ "redux-devtools-themes": "^1.0.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@redux-devtools/core": "^3.13.1", - "@reduxjs/toolkit": "^1.8.2", + "@reduxjs/toolkit": "^1.9.1", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@types/jest": "^29.2.4", "@types/hex-rgba": "^1.0.1", "@types/lodash.debounce": "^4.0.7", - "@types/react": "^18.0.14", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@types/react": "^18.0.26", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", + "jest": "^29.3.1", + "jest-environment-jsdom": "^29.3.1", "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-redux": "^8.0.5", "redux": "^4.2.0", "rimraf": "^3.0.2", - "typescript": "~4.7.4" + "ts-jest": "^29.0.3", + "typescript": "~4.9.4" }, "peerDependencies": { "@redux-devtools/core": "^3.13.1", - "@reduxjs/toolkit": "^1.8.2", + "@reduxjs/toolkit": "^1.9.1", "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "@types/styled-components": "^5.1.25", + "@types/styled-components": "^5.1.26", "react": "^16.3.0 || ^17.0.0 || ^18.0.0", "redux": "^3.4.0 || ^4.0.0", - "styled-components": "^5.3.5" + "styled-components": "^5.3.6" } } diff --git a/packages/redux-devtools-rtk-query-monitor/src/components/QueryForm.tsx b/packages/redux-devtools-rtk-query-monitor/src/components/QueryForm.tsx index c7431e70..155c08cc 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/components/QueryForm.tsx +++ b/packages/redux-devtools-rtk-query-monitor/src/components/QueryForm.tsx @@ -128,6 +128,7 @@ export class QueryForm extends React.PureComponent< {({ styling, base16Theme }) => { return (
{ selectFormattedActions: Selector< AnyAction[], @@ -74,6 +82,7 @@ export class QueryPreviewActions extends PureComponent return ( { shouldExpandApiStateNode = ( keyPath: (string | number)[], @@ -33,7 +40,7 @@ export class QueryPreviewApi extends PureComponent { return ( {({ styling }) => ( -
+

{apiState.config.reducerPath}

State} diff --git a/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewData.tsx b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewData.tsx new file mode 100644 index 00000000..cab37563 --- /dev/null +++ b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewData.tsx @@ -0,0 +1,38 @@ +import React, { ReactNode, PureComponent } from 'react'; +import { QueryPreviewTabs, RtkResourceInfo } from '../types'; +import { renderTabPanelButtonId, renderTabPanelId } from '../utils/a11y'; +import { TreeView, TreeViewProps } from './TreeView'; + +export interface QueryPreviewDataProps { + data: RtkResourceInfo['state']['data']; + isWideLayout: boolean; +} + +const rootProps: TreeViewProps['rootProps'] = { + 'aria-labelledby': renderTabPanelButtonId(QueryPreviewTabs.data), + id: renderTabPanelId(QueryPreviewTabs.data), + role: 'tabpanel', +}; + +export class QueryPreviewData extends PureComponent { + shouldExpandNode = ( + keyPath: (string | number)[], + value: unknown, + layer: number + ): boolean => { + return layer <= 1; + }; + + render(): ReactNode { + const { data, isWideLayout } = this.props; + + return ( + + ); + } +} diff --git a/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewHeader.tsx b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewHeader.tsx index ef9ddc1d..b4fcbde9 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewHeader.tsx +++ b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewHeader.tsx @@ -1,6 +1,7 @@ import React, { ReactNode } from 'react'; import { StyleUtilsContext } from '../styles/createStylingFromTheme'; import { QueryPreviewTabs, TabOption } from '../types'; +import { renderTabPanelButtonId } from '../utils/a11y'; import { emptyArray } from '../utils/object'; export interface QueryPreviewHeaderProps { @@ -28,7 +29,11 @@ export class QueryPreviewHeader extends React.Component
{tabs.map((tab) => ( -
this.handleTabClick(tab)} key={tab.value} {...styling( @@ -42,7 +47,7 @@ export class QueryPreviewHeader extends React.Component {renderTabLabel ? renderTabLabel(tab) : tab.label} -
+ ))}
diff --git a/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewInfo.tsx b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewInfo.tsx index f2bfff3a..cbd15a7b 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewInfo.tsx +++ b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewInfo.tsx @@ -1,11 +1,12 @@ import { createSelector, Selector } from '@reduxjs/toolkit'; import { QueryStatus } from '@reduxjs/toolkit/dist/query'; import React, { ReactNode, PureComponent } from 'react'; -import { RtkResourceInfo, RTKStatusFlags } from '../types'; +import { QueryPreviewTabs, RtkResourceInfo, RTKStatusFlags } from '../types'; +import { renderTabPanelButtonId, renderTabPanelId } from '../utils/a11y'; import { formatMs } from '../utils/formatters'; import { identity } from '../utils/object'; import { getQueryStatusFlags } from '../utils/rtk-query'; -import { TreeView } from './TreeView'; +import { TreeView, TreeViewProps } from './TreeView'; type QueryTimings = { startedAt: string; @@ -23,6 +24,12 @@ type FormattedQuery = { | { query: RtkResourceInfo['state'] } ); +const rootProps: TreeViewProps['rootProps'] = { + 'aria-labelledby': renderTabPanelButtonId(QueryPreviewTabs.queryinfo), + id: renderTabPanelId(QueryPreviewTabs.queryinfo), + role: 'tabpanel', +}; + export interface QueryPreviewInfoProps { resInfo: RtkResourceInfo; isWideLayout: boolean; @@ -97,6 +104,7 @@ export class QueryPreviewInfo extends PureComponent { return ( + ); } } diff --git a/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewTags.tsx b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewTags.tsx index ba576d78..3b19729a 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewTags.tsx +++ b/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewTags.tsx @@ -1,11 +1,18 @@ import React, { ReactNode, PureComponent } from 'react'; -import { RtkQueryTag } from '../types'; -import { TreeView } from './TreeView'; +import { QueryPreviewTabs, RtkQueryTag } from '../types'; +import { renderTabPanelButtonId, renderTabPanelId } from '../utils/a11y'; +import { TreeView, TreeViewProps } from './TreeView'; interface QueryPreviewTagsState { data: { tags: RtkQueryTag[] }; } +const rootProps: TreeViewProps['rootProps'] = { + 'aria-labelledby': renderTabPanelButtonId(QueryPreviewTabs.queryTags), + id: renderTabPanelId(QueryPreviewTabs.queryTags), + role: 'tabpanel', +}; + export interface QueryPreviewTagsProps { tags: RtkQueryTag[]; isWideLayout: boolean; @@ -26,6 +33,8 @@ export class QueryPreviewTags extends PureComponent< render(): ReactNode { const { isWideLayout, tags } = this.props; - return ; + return ( + + ); } } diff --git a/packages/redux-devtools-rtk-query-monitor/src/components/TreeView.tsx b/packages/redux-devtools-rtk-query-monitor/src/components/TreeView.tsx index d02c0349..091f18f2 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/components/TreeView.tsx +++ b/packages/redux-devtools-rtk-query-monitor/src/components/TreeView.tsx @@ -22,6 +22,9 @@ export interface TreeViewProps before?: ReactNode; after?: ReactNode; children?: ReactNode; + rootProps?: Partial< + Omit, 'className' | 'style'> + >; } export class TreeView extends React.PureComponent { @@ -80,13 +83,14 @@ export class TreeView extends React.PureComponent { keyPath, shouldExpandNode, hideRoot, + rootProps, } = this.props; return ( {({ styling, invertTheme, base16Theme }) => { return ( -
+
{before} { readonly selectedTab: QueryPreviewTabs; @@ -66,6 +70,14 @@ const MappedQueryPreviewInfo = mapProps< QueryPreviewInfoProps >(({ resInfo, isWideLayout }) => ({ resInfo, isWideLayout }))(QueryPreviewInfo); +const MappedQueryPreviewData = mapProps< + QueryPreviewTabProps, + QueryPreviewDataProps +>(({ resInfo, isWideLayout }) => ({ + data: resInfo?.state?.data, + isWideLayout, +}))(QueryPreviewData); + const MappedQuerySubscriptipns = mapProps< QueryPreviewTabProps, QueryPreviewSubscriptionsProps @@ -93,6 +105,16 @@ const MappedQueryPreviewActions = mapProps< const tabs: ReadonlyArray< TabOption > = [ + { + label: 'Data', + value: QueryPreviewTabs.data, + component: MappedQueryPreviewData, + visible: { + query: true, + mutation: true, + default: true, + }, + }, { label: 'Query', value: QueryPreviewTabs.queryinfo, diff --git a/packages/redux-devtools-rtk-query-monitor/src/containers/mapProps.tsx b/packages/redux-devtools-rtk-query-monitor/src/containers/mapProps.tsx index 2dc00182..79271e9f 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/containers/mapProps.tsx +++ b/packages/redux-devtools-rtk-query-monitor/src/containers/mapProps.tsx @@ -16,7 +16,8 @@ export function mapProps( render(): ReactNode { const mappedProps = mapper(this.props); - return ; + // TODO Not really sure why this is needed, but it is + return ; } static displayName = `mapProps(${ diff --git a/packages/redux-devtools-rtk-query-monitor/src/selectors.ts b/packages/redux-devtools-rtk-query-monitor/src/selectors.ts index 5a964aba..305542ca 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/selectors.ts +++ b/packages/redux-devtools-rtk-query-monitor/src/selectors.ts @@ -258,6 +258,7 @@ export function createInspectorSelectors(): InspectorSelectors { ], (subscriptions, actions, tags) => { return { + [QueryPreviewTabs.data]: 0, [QueryPreviewTabs.queryTags]: tags.length, [QueryPreviewTabs.querySubscriptions]: Object.keys(subscriptions ?? {}) .length, diff --git a/packages/redux-devtools-rtk-query-monitor/src/styles/createStylingFromTheme.ts b/packages/redux-devtools-rtk-query-monitor/src/styles/createStylingFromTheme.ts index e7868144..139aa807 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/styles/createStylingFromTheme.ts +++ b/packages/redux-devtools-rtk-query-monitor/src/styles/createStylingFromTheme.ts @@ -220,6 +220,8 @@ const getSheetFromColorMap = (map: ColorMap) => { padding: '0 8px', display: 'inline-flex', alignItems: 'center', + boxShadow: 'none', + outline: 'none', color: map.TEXT_COLOR, 'border-style': 'solid', 'border-width': '1px', diff --git a/packages/redux-devtools-rtk-query-monitor/src/types.ts b/packages/redux-devtools-rtk-query-monitor/src/types.ts index e81fbb9c..aeb35bb5 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/types.ts +++ b/packages/redux-devtools-rtk-query-monitor/src/types.ts @@ -8,6 +8,7 @@ import type { QueryComparators } from './utils/comparators'; import type { QueryFilters } from './utils/filters'; export enum QueryPreviewTabs { + data, queryinfo, apiConfig, querySubscriptions, diff --git a/packages/redux-devtools-rtk-query-monitor/src/utils/a11y.ts b/packages/redux-devtools-rtk-query-monitor/src/utils/a11y.ts new file mode 100644 index 00000000..e92a799a --- /dev/null +++ b/packages/redux-devtools-rtk-query-monitor/src/utils/a11y.ts @@ -0,0 +1,9 @@ +import { QueryPreviewTabs } from '../types'; + +export function renderTabPanelId(value: QueryPreviewTabs): string { + return `rtk-query-monitor-tab-panel-${value}`; +} + +export function renderTabPanelButtonId(value: QueryPreviewTabs): string { + return renderTabPanelId(value) + '-button'; +} diff --git a/packages/redux-devtools-rtk-query-monitor/src/utils/comparators.ts b/packages/redux-devtools-rtk-query-monitor/src/utils/comparators.ts index ff923a21..8714a864 100644 --- a/packages/redux-devtools-rtk-query-monitor/src/utils/comparators.ts +++ b/packages/redux-devtools-rtk-query-monitor/src/utils/comparators.ts @@ -55,6 +55,9 @@ export function compareJSONPrimitive< return 0; } + if (a == null) return -1; + if (b == null) return 1; + return a > b ? 1 : -1; } diff --git a/packages/redux-devtools-rtk-query-monitor/test/__mocks__/styleMock.ts b/packages/redux-devtools-rtk-query-monitor/test/__mocks__/styleMock.ts new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/packages/redux-devtools-rtk-query-monitor/test/__mocks__/styleMock.ts @@ -0,0 +1 @@ +export default {}; diff --git a/packages/redux-devtools-rtk-query-monitor/test/devtools.mocks.tsx b/packages/redux-devtools-rtk-query-monitor/test/devtools.mocks.tsx new file mode 100644 index 00000000..906203a2 --- /dev/null +++ b/packages/redux-devtools-rtk-query-monitor/test/devtools.mocks.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; +import { createDevTools } from '@redux-devtools/core'; +import { RtkQueryMonitor } from '../src'; + +const MonitorAsAny = RtkQueryMonitor as any; + +export const ReduxDevTools = createDevTools(); diff --git a/packages/redux-devtools-rtk-query-monitor/test/integration.spec.tsx b/packages/redux-devtools-rtk-query-monitor/test/integration.spec.tsx new file mode 100644 index 00000000..56bf85aa --- /dev/null +++ b/packages/redux-devtools-rtk-query-monitor/test/integration.spec.tsx @@ -0,0 +1,121 @@ +import * as React from 'react'; +import { Provider } from 'react-redux'; +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import { ReduxDevTools } from './devtools.mocks'; +import { BaseQueryJestMockFunction, setupStore } from './rtk-query.mocks'; + +function Providers({ + store, + children, +}: { + store: ReturnType['store']; + children?: React.ComponentProps['children']; +}) { + const AnyProvider = Provider as any; + + return ( +
+ + {children} + + +
+ ); +} + +describe('rtk-query-monitor standalone integration', () => { + // Hushes symbol.observable warning + // @see https://github.com/reduxjs/redux-devtools/issues/1002 + jest.spyOn(console, 'warn'); + // eslint-disable-next-line @typescript-eslint/no-empty-function + (console.warn as jest.Mock).mockImplementation(() => {}); + + const dataPanelDomId = '#rtk-query-monitor-tab-panel-0'; + + const childrenTextContent = 'Renders children'; + const fetchBaseQueryMock: BaseQueryJestMockFunction> = + jest.fn((...fetchArgs) => + Promise.resolve({ + data: { + name: fetchArgs[0], + }, + }) + ); + const { store, pokemonApi } = setupStore(fetchBaseQueryMock, ReduxDevTools); + + beforeAll(() => { + // let's populate api + (store.dispatch as any)( + pokemonApi.endpoints.getPokemonByName.initiate('bulbasaur') + ); + }); + + beforeEach(() => { + fetchBaseQueryMock.mockClear(); + }); + + afterAll(() => { + (console.warn as jest.Mock).mockRestore(); + }); + + it('renders on a standalone app without crashing', () => { + const { container } = render( + +
{childrenTextContent}
+
+ ); + + expect(screen.getByTestId('children').textContent).toBe( + childrenTextContent + ); + + expect( + screen + .getByRole('tab', { name: /actions/i }) + ?.textContent?.toLowerCase() + .trim() + ).toBe('actions'); + expect( + screen + .getByRole('tab', { name: /data/i }) + ?.textContent?.toLowerCase() + .trim() + ).toBe('data'); + expect( + screen + .getByRole('tab', { name: /api/i }) + ?.textContent?.toLowerCase() + .trim() + ).toBe('api'); + expect( + container.querySelector( + 'form[id="rtk-query-monitor-query-selection-form"]' + ) + ).toBeDefined(); + }); + + it('displays query data tab content', async () => { + // `Promise.resolve()` hushes `@typescript-eslint/await-thenable` + await Promise.resolve( + store.dispatch(pokemonApi.util.getRunningQueriesThunk() as any) + ); + + const { container } = render( + +
{childrenTextContent}
+
+ ); + + // We need to select the query & the correct tab + fireEvent.click(screen.getByRole('tab', { name: /data/i })); + fireEvent.click(screen.getByText(/bulbasaur/i)); + + await waitFor(() => + expect(container.querySelector(dataPanelDomId)).not.toBeNull() + ); + + expect(container.querySelector(dataPanelDomId)?.textContent).toMatch( + /name\W+pokemon\/bulbasaur/i + ); + }); +}); diff --git a/packages/redux-devtools-rtk-query-monitor/test/rtk-query.mocks.ts b/packages/redux-devtools-rtk-query-monitor/test/rtk-query.mocks.ts new file mode 100644 index 00000000..d1d8c167 --- /dev/null +++ b/packages/redux-devtools-rtk-query-monitor/test/rtk-query.mocks.ts @@ -0,0 +1,84 @@ +import { + combineReducers, + configureStore, + EnhancedStore, + Middleware, +} from '@reduxjs/toolkit'; +import { createApi } from '@reduxjs/toolkit/query/react'; +import type { BaseQueryFn, FetchArgs } from '@reduxjs/toolkit/query'; +import type { ReduxDevTools } from './devtools.mocks'; + +export type MockBaseQuery< + Result, + Args = string | FetchArgs, + Meta = { status?: number } +> = BaseQueryFn; + +export type BaseQueryJestMockFunction = jest.Mock< + ReturnType>, + Parameters> +>; + +export function createMockBaseQuery( + jestMockFn: BaseQueryJestMockFunction +): MockBaseQuery { + return async function mockBaseQuery(param, api, extra) { + try { + const output = await jestMockFn(param, api, extra); + + return output; + } catch (error) { + return { + error, + }; + } + }; +} + +export function createPokemonApi( + jestMockFn: BaseQueryJestMockFunction> +) { + return createApi({ + reducerPath: 'pokemonApi', + keepUnusedDataFor: 9999, + baseQuery: createMockBaseQuery(jestMockFn), + tagTypes: ['pokemon'], + endpoints: (builder) => ({ + getPokemonByName: builder.query, string>({ + query: (name: string) => `pokemon/${name}`, + providesTags: (result, error, name: string) => [ + { type: 'pokemon' }, + { type: 'pokemon', id: name }, + ], + }), + }), + }); +} + +export function setupStore( + jestMockFn: BaseQueryJestMockFunction>, + devTools: typeof ReduxDevTools +) { + const pokemonApi = createPokemonApi(jestMockFn); + + const reducer = combineReducers({ + [pokemonApi.reducerPath]: pokemonApi.reducer, + }); + + const store: EnhancedStore> = configureStore({ + reducer, + devTools: false, + // adding the api middleware enables caching, invalidation, polling and other features of `rtk-query` + middleware: (getDefaultMiddleware) => + getDefaultMiddleware().concat([pokemonApi.middleware]) as Middleware[], + enhancers: [devTools.instrument()], + }); + + return { + jestMockFn, + devTools, + store, + reducer, + pokemonApi, + }; +} diff --git a/packages/redux-devtools-rtk-query-monitor/tsconfig.test.json b/packages/redux-devtools-rtk-query-monitor/tsconfig.test.json new file mode 100644 index 00000000..9d56eb9d --- /dev/null +++ b/packages/redux-devtools-rtk-query-monitor/tsconfig.test.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.react.base.json", + "compilerOptions": { + "types": ["jest"] + }, + "include": ["src", "test"], + "exclude": ["dist"] +} diff --git a/packages/redux-devtools-serialize/jest.config.js b/packages/redux-devtools-serialize/jest.config.js index 05d33807..f68efd05 100644 --- a/packages/redux-devtools-serialize/jest.config.js +++ b/packages/redux-devtools-serialize/jest.config.js @@ -1,8 +1,6 @@ module.exports = { preset: 'ts-jest', - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, }; diff --git a/packages/redux-devtools-serialize/package.json b/packages/redux-devtools-serialize/package.json index 66686e75..d0aed428 100644 --- a/packages/redux-devtools-serialize/package.json +++ b/packages/redux-devtools-serialize/package.json @@ -37,28 +37,28 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "jsan": "^3.1.14" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-typescript": "^7.17.12", - "@types/jest": "^27.5.2", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-typescript": "^7.18.6", + "@types/jest": "^29.2.4", "@types/jsan": "^3.1.2", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", + "eslint-plugin-jest": "^27.1.7", "immutable": "^4.1.0", - "jest": "^27.5.1", + "jest": "^29.3.1", "rimraf": "^3.0.2", - "ts-jest": "^27.1.5", - "typescript": "~4.7.4" + "ts-jest": "^29.0.3", + "typescript": "~4.9.4" }, "peerDependencies": { "immutable": "^4.1.0" diff --git a/packages/redux-devtools-serialize/test/__snapshots__/helpers.spec.ts.snap b/packages/redux-devtools-serialize/test/__snapshots__/helpers.spec.ts.snap index 00056f49..14984dc6 100644 --- a/packages/redux-devtools-serialize/test/__snapshots__/helpers.spec.ts.snap +++ b/packages/redux-devtools-serialize/test/__snapshots__/helpers.spec.ts.snap @@ -1,34 +1,34 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Helpers extract 1`] = ` -Object { +{ "__serializedType__": "testType", - "data": Object { + "data": { "testData": "test", }, } `; exports[`Helpers mark 1`] = ` -Object { +{ "__serializedType__": "testType", - "data": Object { + "data": { "testData": "test", }, } `; exports[`Helpers mark 2`] = ` -Object { +{ "__serializedType__": "testType", "data": "[object Object]", } `; exports[`Helpers refer 1`] = ` -Object { +{ "__serializedType__": "testType", - "data": Object { + "data": { "testData": "test", }, } diff --git a/packages/redux-devtools-serialize/test/__snapshots__/immutable.spec.ts.snap b/packages/redux-devtools-serialize/test/__snapshots__/immutable.spec.ts.snap index 4c460e04..2fe2a9f9 100644 --- a/packages/redux-devtools-serialize/test/__snapshots__/immutable.spec.ts.snap +++ b/packages/redux-devtools-serialize/test/__snapshots__/immutable.spec.ts.snap @@ -1,23 +1,23 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Immutable Nested stringify 1`] = `"{\\"data\\":[{\\"data\\":{\\"map\\":{\\"data\\":{\\"seq\\":{\\"data\\":[1,2,3,4,5,6,7,8],\\"__serializedType__\\":\\"ImmutableSeq\\"},\\"stack\\":{\\"data\\":[\\"a\\",\\"b\\",\\"c\\"],\\"__serializedType__\\":\\"ImmutableStack\\"}},\\"__serializedType__\\":\\"ImmutableOrderedMap\\"},\\"repeat\\":{\\"data\\":{\\"_value\\":\\"hi\\",\\"size\\":100},\\"__serializedType__\\":\\"ImmutableRepeat\\"}},\\"__serializedType__\\":\\"ImmutableRecord\\",\\"__serializedRef__\\":0},{\\"data\\":[10,9,8,7,6,5,4,3,2,1],\\"__serializedType__\\":\\"ImmutableOrderedSet\\"},{\\"data\\":{\\"_start\\":0,\\"_end\\":7,\\"_step\\":1,\\"size\\":7},\\"__serializedType__\\":\\"ImmutableRange\\"}],\\"__serializedType__\\":\\"ImmutableSet\\"}"`; +exports[`Immutable Nested stringify 1`] = `"{"data":[{"data":{"map":{"data":{"seq":{"data":[1,2,3,4,5,6,7,8],"__serializedType__":"ImmutableSeq"},"stack":{"data":["a","b","c"],"__serializedType__":"ImmutableStack"}},"__serializedType__":"ImmutableOrderedMap"},"repeat":{"data":{"_value":"hi","size":100},"__serializedType__":"ImmutableRepeat"}},"__serializedType__":"ImmutableRecord","__serializedRef__":0},{"data":[10,9,8,7,6,5,4,3,2,1],"__serializedType__":"ImmutableOrderedSet"},{"data":{"_start":0,"_end":7,"_step":1,"size":7},"__serializedType__":"ImmutableRange"}],"__serializedType__":"ImmutableSet"}"`; -exports[`Immutable Record stringify 1`] = `"{\\"data\\":{\\"a\\":1,\\"b\\":3},\\"__serializedType__\\":\\"ImmutableRecord\\",\\"__serializedRef__\\":0}"`; +exports[`Immutable Record stringify 1`] = `"{"data":{"a":1,"b":3},"__serializedType__":"ImmutableRecord","__serializedRef__":0}"`; -exports[`Immutable Stringify list 1`] = `"{\\"data\\":[1,2,3,4,5,6,7,8,9,10],\\"__serializedType__\\":\\"ImmutableList\\"}"`; +exports[`Immutable Stringify list 1`] = `"{"data":[1,2,3,4,5,6,7,8,9,10],"__serializedType__":"ImmutableList"}"`; -exports[`Immutable Stringify map 1`] = `"{\\"data\\":{\\"a\\":1,\\"b\\":2,\\"c\\":3,\\"d\\":4},\\"__serializedType__\\":\\"ImmutableMap\\"}"`; +exports[`Immutable Stringify map 1`] = `"{"data":{"a":1,"b":2,"c":3,"d":4},"__serializedType__":"ImmutableMap"}"`; -exports[`Immutable Stringify orderedMap 1`] = `"{\\"data\\":{\\"b\\":2,\\"a\\":1,\\"c\\":3,\\"d\\":4},\\"__serializedType__\\":\\"ImmutableOrderedMap\\"}"`; +exports[`Immutable Stringify orderedMap 1`] = `"{"data":{"b":2,"a":1,"c":3,"d":4},"__serializedType__":"ImmutableOrderedMap"}"`; -exports[`Immutable Stringify orderedSet 1`] = `"{\\"data\\":[10,9,8,7,6,5,4,3,2,1],\\"__serializedType__\\":\\"ImmutableOrderedSet\\"}"`; +exports[`Immutable Stringify orderedSet 1`] = `"{"data":[10,9,8,7,6,5,4,3,2,1],"__serializedType__":"ImmutableOrderedSet"}"`; -exports[`Immutable Stringify range 1`] = `"{\\"data\\":{\\"_start\\":0,\\"_end\\":7,\\"_step\\":1,\\"size\\":7},\\"__serializedType__\\":\\"ImmutableRange\\"}"`; +exports[`Immutable Stringify range 1`] = `"{"data":{"_start":0,"_end":7,"_step":1,"size":7},"__serializedType__":"ImmutableRange"}"`; -exports[`Immutable Stringify repeat 1`] = `"{\\"data\\":{\\"_value\\":\\"hi\\",\\"size\\":100},\\"__serializedType__\\":\\"ImmutableRepeat\\"}"`; +exports[`Immutable Stringify repeat 1`] = `"{"data":{"_value":"hi","size":100},"__serializedType__":"ImmutableRepeat"}"`; -exports[`Immutable Stringify seq 1`] = `"{\\"data\\":[1,2,3,4,5,6,7,8],\\"__serializedType__\\":\\"ImmutableSeq\\"}"`; +exports[`Immutable Stringify seq 1`] = `"{"data":[1,2,3,4,5,6,7,8],"__serializedType__":"ImmutableSeq"}"`; -exports[`Immutable Stringify set 1`] = `"{\\"data\\":[1,2,3,4,5,6,7,8,9,10],\\"__serializedType__\\":\\"ImmutableSet\\"}"`; +exports[`Immutable Stringify set 1`] = `"{"data":[1,2,3,4,5,6,7,8,9,10],"__serializedType__":"ImmutableSet"}"`; -exports[`Immutable Stringify stack 1`] = `"{\\"data\\":[\\"a\\",\\"b\\",\\"c\\"],\\"__serializedType__\\":\\"ImmutableStack\\"}"`; +exports[`Immutable Stringify stack 1`] = `"{"data":["a","b","c"],"__serializedType__":"ImmutableStack"}"`; diff --git a/packages/redux-devtools-slider-monitor/examples/todomvc/package.json b/packages/redux-devtools-slider-monitor/examples/todomvc/package.json index d48743a6..c4668a76 100644 --- a/packages/redux-devtools-slider-monitor/examples/todomvc/package.json +++ b/packages/redux-devtools-slider-monitor/examples/todomvc/package.json @@ -19,44 +19,44 @@ "@redux-devtools/dock-monitor": "^3.0.0", "@redux-devtools/log-monitor": "^4.0.0", "@redux-devtools/slider-monitor": "^4.0.0", - "classnames": "^2.3.1", + "classnames": "^2.3.2", "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-is": "^18.2.0", - "react-redux": "^8.0.2", + "react-redux": "^8.0.5", "redux": "^4.2.0", - "styled-components": "^5.3.5", + "styled-components": "^5.3.6", "todomvc-app-css": "^2.4.2" }, "devDependencies": { - "@babel/core": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/core": "^7.20.5", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@types/classnames": "^2.3.1", - "@types/node": "^16.11.41", + "@types/node": "^18.11.17", "@types/prop-types": "^15.7.5", - "@types/react": "^18.0.14", - "@types/react-dom": "^18.0.5", - "@types/styled-components": "^5.1.25", - "@types/webpack-env": "^1.17.0", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "babel-loader": "^8.2.5", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", + "@types/styled-components": "^5.1.26", + "@types/webpack-env": "^1.18.0", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "babel-loader": "^9.1.0", "cross-env": "^7.0.3", - "css-loader": "^6.7.1", - "eslint": "^8.18.0", + "css-loader": "^6.7.3", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "fork-ts-checker-webpack-plugin": "^7.2.11", + "fork-ts-checker-webpack-plugin": "^7.2.14", "html-webpack-plugin": "^5.5.0", "style-loader": "^3.3.1", - "ts-node": "^10.8.1", - "typescript": "~4.7.4", - "webpack": "^5.73.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.9.2" + "ts-node": "^10.9.1", + "typescript": "~4.9.4", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.1", + "webpack-dev-server": "^4.11.1" } } diff --git a/packages/redux-devtools-slider-monitor/package.json b/packages/redux-devtools-slider-monitor/package.json index e7630269..89eb72a5 100644 --- a/packages/redux-devtools-slider-monitor/package.json +++ b/packages/redux-devtools-slider-monitor/package.json @@ -32,7 +32,7 @@ "prepublish": "pnpm run type-check && pnpm run lint" }, "dependencies": { - "@babel/runtime": "^7.18.3", + "@babel/runtime": "^7.20.6", "@redux-devtools/ui": "^1.3.0", "@types/prop-types": "^15.7.5", "@types/redux-devtools-themes": "^1.0.0", @@ -40,37 +40,32 @@ "redux-devtools-themes": "^1.0.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", "@redux-devtools/core": "^3.13.1", - "@rollup/plugin-babel": "^5.3.1", - "@types/node": "^16.11.41", - "@types/react": "^18.0.14", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "eslint": "^8.18.0", + "@types/node": "^18.11.17", + "@types/react": "^18.0.26", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", "react": "^18.2.0", "redux": "^4.2.0", "rimraf": "^3.0.2", - "rollup": "^2.75.6", - "rollup-plugin-typescript2": "^0.32.1", - "tslib": "^2.4.0", - "typescript": "~4.7.4" + "typescript": "~4.9.4" }, "peerDependencies": { "@redux-devtools/core": "^3.13.1", "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "@types/styled-components": "^5.1.25", + "@types/styled-components": "^5.1.26", "react": "^16.3.0 || ^17.0.0 || ^18.0.0", "redux": "^3.4.0 || ^4.0.0", - "styled-components": "^5.3.5" + "styled-components": "^5.3.6" } } diff --git a/packages/redux-devtools-ui/.storybook/main.js b/packages/redux-devtools-ui/.storybook/main.js index 0b048608..b2931238 100644 --- a/packages/redux-devtools-ui/.storybook/main.js +++ b/packages/redux-devtools-ui/.storybook/main.js @@ -1,4 +1,7 @@ module.exports = { + core: { + builder: 'webpack5', + }, stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], addons: [ { diff --git a/packages/redux-devtools-ui/.babelrc.json b/packages/redux-devtools-ui/babel.config.json similarity index 100% rename from packages/redux-devtools-ui/.babelrc.json rename to packages/redux-devtools-ui/babel.config.json diff --git a/packages/redux-devtools-ui/jest.config.js b/packages/redux-devtools-ui/jest.config.js index bf9761dc..b5063992 100644 --- a/packages/redux-devtools-ui/jest.config.js +++ b/packages/redux-devtools-ui/jest.config.js @@ -4,9 +4,9 @@ module.exports = { moduleNameMapper: { '\\.css$': '/test/__mocks__/styleMock.ts', }, - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, + transform: { + '^.+\\.jsx?$': 'babel-jest', + '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }], }, + transformIgnorePatterns: ['node_modules/(?!.pnpm|nanoid)'], }; diff --git a/packages/redux-devtools-ui/package.json b/packages/redux-devtools-ui/package.json index 24577490..52a073ed 100644 --- a/packages/redux-devtools-ui/package.json +++ b/packages/redux-devtools-ui/package.json @@ -25,12 +25,12 @@ }, "scripts": { "start": "pnpm run storybook", - "storybook": "start-storybook -p 6006 -s ./fonts", - "build:storybook": "build-storybook -s ./fonts", + "storybook": "start-storybook --port 6006 --static-dir ./fonts", + "build:storybook": "build-storybook --static-dir ./fonts --quiet", "build": "pnpm run build:lib && pnpm run build:storybook", "build:lib": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:types && pnpm run build:css", "build:cjs": "babel src --extensions \".ts,.tsx\" --out-dir lib/cjs", - "build:esm": "babel src --config-file ./babel.config.esm.json --no-babelrc --extensions \".ts,.tsx\" --out-dir lib/esm", + "build:esm": "babel src --config-file ./babel.config.esm.json --extensions \".ts,.tsx\" --out-dir lib/esm", "build:types": "tsc --emitDeclarationOnly", "build:css": "ncp fonts lib/fonts", "clean": "rimraf lib storybook-static", @@ -42,8 +42,8 @@ "prepublish": "pnpm run type-check && pnpm run lint && pnpm run test" }, "dependencies": { - "@babel/runtime": "^7.18.3", - "@rjsf/core": "^4.2.0", + "@babel/runtime": "^7.20.6", + "@rjsf/core": "^4.2.3", "@types/base16": "^1.0.2", "@types/codemirror": "^5.60.5", "@types/json-schema": "^7.0.11", @@ -51,61 +51,64 @@ "@types/redux-devtools-themes": "^1.0.0", "@types/simple-element-resize-detector": "^1.3.0", "base16": "^1.0.0", - "codemirror": "^5.65.5", + "codemirror": "^5.65.11", "color": "^4.2.3", "prop-types": "^15.8.1", - "react-icons": "^4.4.0", - "react-select": "^5.3.2", + "react-icons": "^4.7.1", + "react-select": "^5.7.0", "redux-devtools-themes": "^1.0.0", "simple-element-resize-detector": "^1.3.0" }, "devDependencies": { - "@babel/cli": "^7.17.10", - "@babel/core": "^7.18.5", - "@babel/eslint-parser": "^7.18.2", - "@babel/plugin-transform-runtime": "^7.18.5", - "@babel/preset-env": "^7.18.2", - "@babel/preset-react": "^7.17.12", - "@babel/preset-typescript": "^7.17.12", - "@storybook/addon-essentials": "^6.5.9", - "@storybook/react": "^6.5.9", - "@testing-library/dom": "^8.13.0", - "@testing-library/react": "^13.3.0", - "@testing-library/user-event": "^14.2.1", + "@babel/cli": "^7.19.3", + "@babel/core": "^7.20.5", + "@babel/eslint-parser": "^7.19.1", + "@babel/plugin-transform-runtime": "^7.19.6", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@storybook/addon-essentials": "^6.5.15", + "@storybook/builder-webpack5": "^6.5.15", + "@storybook/manager-webpack5": "^6.5.15", + "@storybook/react": "^6.5.15", + "@testing-library/dom": "^8.19.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^14.4.3", "@types/color": "^3.0.3", - "@types/jest": "^27.5.2", - "@types/react": "^18.0.14", - "@types/styled-components": "^5.1.25", - "@typescript-eslint/eslint-plugin": "^5.28.0", - "@typescript-eslint/parser": "^5.28.0", - "babel-loader": "^8.2.5", - "csstype": "^3.1.0", - "eslint": "^8.18.0", + "@types/jest": "^29.2.4", + "@types/react": "^18.0.26", + "@types/styled-components": "^5.1.26", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "babel-loader": "^9.1.0", + "csstype": "^3.1.1", + "eslint": "^8.30.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^26.5.3", - "eslint-plugin-react": "^7.30.0", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "jest": "^27.5.1", + "jest": "^29.3.1", + "jest-environment-jsdom": "^29.3.1", "ncp": "^2.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-is": "^18.2.0", "require-from-string": "^2.0.2", "rimraf": "^3.0.2", - "styled-components": "^5.3.5", - "stylelint": "^14.9.1", - "stylelint-config-prettier": "^9.0.3", - "stylelint-config-standard": "^25.0.0", + "styled-components": "^5.3.6", + "stylelint": "^14.16.0", + "stylelint-config-prettier": "^9.0.4", + "stylelint-config-standard": "^29.0.0", "stylelint-config-styled-components": "^0.1.1", "stylelint-processor-styled-components": "^1.10.0", - "ts-jest": "^27.1.5", - "typescript": "~4.7.4", - "webpack": "^5.73.0" + "ts-jest": "^29.0.3", + "typescript": "~4.9.4", + "webpack": "^5.75.0" }, "peerDependencies": { "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "@types/styled-components": "^5.1.25", + "@types/styled-components": "^5.1.26", "react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "styled-components": "^5.3.5" + "styled-components": "^5.3.6" } } diff --git a/packages/redux-devtools-ui/src/Tabs/Tabs.stories.tsx b/packages/redux-devtools-ui/src/Tabs/Tabs.stories.tsx index 7598992a..2ef8e78c 100644 --- a/packages/redux-devtools-ui/src/Tabs/Tabs.stories.tsx +++ b/packages/redux-devtools-ui/src/Tabs/Tabs.stories.tsx @@ -18,7 +18,7 @@ export default { component: Tabs, }; -const Template: Story> = (args) => ( +const Template: Story> = (args) => ( diff --git a/packages/redux-devtools-ui/src/Tabs/Tabs.tsx b/packages/redux-devtools-ui/src/Tabs/Tabs.tsx index c47351d5..2aaae2df 100644 --- a/packages/redux-devtools-ui/src/Tabs/Tabs.tsx +++ b/packages/redux-devtools-ui/src/Tabs/Tabs.tsx @@ -14,7 +14,7 @@ export interface TabsProps

{ position: Position; } -export default class Tabs

extends Component> { +export default class Tabs

extends Component> { SelectedComponent?: React.ComponentType

; selector?: () => P; diff --git a/packages/redux-devtools-ui/src/index.ts b/packages/redux-devtools-ui/src/index.ts index fdfad8bd..58b36732 100644 --- a/packages/redux-devtools-ui/src/index.ts +++ b/packages/redux-devtools-ui/src/index.ts @@ -1,3 +1,5 @@ +export type { Base16Theme } from 'base16'; + export { default as Container } from './Container'; export { default as Button } from './Button'; export { default as ContextMenu } from './ContextMenu'; diff --git a/packages/redux-devtools-ui/test/__snapshots__/Button.test.tsx.snap b/packages/redux-devtools-ui/test/__snapshots__/Button.test.tsx.snap index 1bcb5caf..9d6c2198 100644 --- a/packages/redux-devtools-ui/test/__snapshots__/Button.test.tsx.snap +++ b/packages/redux-devtools-ui/test/__snapshots__/Button.test.tsx.snap @@ -2,10 +2,10 @@ exports[`Button renders correctly 1`] = `

diff --git a/packages/redux-devtools-ui/test/__snapshots__/Container.test.tsx.snap b/packages/redux-devtools-ui/test/__snapshots__/Container.test.tsx.snap index bd15d5d5..7e498f65 100644 --- a/packages/redux-devtools-ui/test/__snapshots__/Container.test.tsx.snap +++ b/packages/redux-devtools-ui/test/__snapshots__/Container.test.tsx.snap @@ -2,7 +2,7 @@ exports[`Container renders correctly 1`] = `
Text
diff --git a/packages/redux-devtools-ui/test/__snapshots__/ContextMenu.test.tsx.snap b/packages/redux-devtools-ui/test/__snapshots__/ContextMenu.test.tsx.snap index ea4037d8..6a21114e 100644 --- a/packages/redux-devtools-ui/test/__snapshots__/ContextMenu.test.tsx.snap +++ b/packages/redux-devtools-ui/test/__snapshots__/ContextMenu.test.tsx.snap @@ -2,7 +2,7 @@ exports[`ContextMenu renders correctly 1`] = `
@@ -45,7 +45,7 @@ exports[`Dialog renders correctly 1`] = ` exports[`Dialog renders modal 1`] = `
@@ -61,19 +61,19 @@ exports[`Dialog renders modal 1`] = ` class="mc-dialog--footer" >
@@ -85,7 +85,7 @@ exports[`Dialog renders modal 1`] = ` exports[`Dialog renders with props 1`] = `
@@ -109,19 +109,19 @@ exports[`Dialog renders with props 1`] = ` class="mc-dialog--footer" >
diff --git a/packages/redux-devtools-ui/test/__snapshots__/Editor.test.tsx.snap b/packages/redux-devtools-ui/test/__snapshots__/Editor.test.tsx.snap index a47f3afd..0eb7381d 100644 --- a/packages/redux-devtools-ui/test/__snapshots__/Editor.test.tsx.snap +++ b/packages/redux-devtools-ui/test/__snapshots__/Editor.test.tsx.snap @@ -2,7 +2,7 @@ exports[`Editor renders correctly 1`] = `