Showing preview only (1,931K chars total). Download the full file or copy to clipboard to get everything.
Repository: reduxjs/redux-devtools
Branch: main
Commit: 48798a7a698e
Files: 874
Total size: 1.7 MB
Directory structure:
gitextract_iubpoav9/
├── .changeset/
│ └── config.json
├── .eslintignore
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ ├── CI.yml
│ └── release.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── CODE_OF_CONDUCT.md
├── LICENSE.md
├── README.md
├── docs/
│ ├── Integrations/
│ │ └── Remote.md
│ └── Walkthrough.md
├── eslint.js.config.base.mjs
├── eslint.js.react.jest.config.base.mjs
├── eslint.ts.config.base.mjs
├── eslint.ts.jest.config.base.mjs
├── eslint.ts.react.config.base.mjs
├── eslint.ts.react.jest.config.base.mjs
├── extension/
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── CODE_OF_CONDUCT.md
│ ├── LICENSE
│ ├── README.md
│ ├── babel.config.json
│ ├── build.mjs
│ ├── chrome/
│ │ └── manifest.json
│ ├── docs/
│ │ ├── API/
│ │ │ ├── Arguments.md
│ │ │ ├── Methods.md
│ │ │ └── README.md
│ │ ├── Architecture.md
│ │ ├── Articles.md
│ │ ├── Credits.md
│ │ ├── FAQ.md
│ │ ├── Features/
│ │ │ └── Trace.md
│ │ ├── Feedback.md
│ │ ├── Integrations.md
│ │ ├── README.md
│ │ ├── Recipes.md
│ │ ├── Troubleshooting.md
│ │ └── Videos.md
│ ├── edge/
│ │ └── manifest.json
│ ├── eslint.config.mjs
│ ├── firefox/
│ │ └── manifest.json
│ ├── jest.config.ts
│ ├── package.json
│ ├── src/
│ │ ├── app/
│ │ │ ├── Actions.tsx
│ │ │ └── App.tsx
│ │ ├── background/
│ │ │ ├── contextMenus.ts
│ │ │ ├── index.ts
│ │ │ ├── logging.ts
│ │ │ ├── openWindow.ts
│ │ │ └── store/
│ │ │ ├── apiMiddleware.ts
│ │ │ ├── backgroundReducer.ts
│ │ │ └── backgroundStore.ts
│ │ ├── chromeApiMock.ts
│ │ ├── contentScript/
│ │ │ └── index.ts
│ │ ├── devpanel/
│ │ │ ├── devpanel.pug
│ │ │ ├── index.tsx
│ │ │ └── store/
│ │ │ ├── panelReducer.ts
│ │ │ ├── panelStore.ts
│ │ │ └── panelSyncMiddleware.ts
│ │ ├── devtools/
│ │ │ ├── devtools.pug
│ │ │ └── index.ts
│ │ ├── options/
│ │ │ ├── AllowToRunGroup.tsx
│ │ │ ├── ContextMenuGroup.tsx
│ │ │ ├── EditorGroup.tsx
│ │ │ ├── FilterGroup.tsx
│ │ │ ├── MiscellaneousGroup.tsx
│ │ │ ├── Options.tsx
│ │ │ ├── index.tsx
│ │ │ ├── options.pug
│ │ │ └── syncOptions.ts
│ │ ├── pageScript/
│ │ │ ├── Monitor.ts
│ │ │ ├── api/
│ │ │ │ ├── filters.ts
│ │ │ │ ├── generateInstanceId.ts
│ │ │ │ ├── importState.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── notifyErrors.ts
│ │ │ │ └── openWindow.ts
│ │ │ ├── enhancerStore.ts
│ │ │ └── index.ts
│ │ ├── remote/
│ │ │ ├── index.tsx
│ │ │ └── remote.pug
│ │ └── style.pug
│ ├── test/
│ │ ├── .eslintrc
│ │ ├── __mocks__/
│ │ │ └── styleMock.js
│ │ ├── app/
│ │ │ ├── containers/
│ │ │ │ └── App.spec.jsx
│ │ │ └── inject/
│ │ │ ├── api.spec.js
│ │ │ └── enhancer.spec.js
│ │ ├── chrome/
│ │ │ └── extension.spec.js
│ │ ├── electron/
│ │ │ ├── devpanel.spec.js
│ │ │ └── fixture/
│ │ │ ├── index.html
│ │ │ ├── main.js
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ └── renderer.js
│ │ │ └── webpack.config.js
│ │ ├── perf/
│ │ │ ├── data.js
│ │ │ └── send.spec.js
│ │ ├── setup.js
│ │ └── utils/
│ │ ├── e2e.js
│ │ └── inject.js
│ └── tsconfig.json
├── jest.config.js
├── package.json
├── packages/
│ ├── d3-state-visualizer/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── examples/
│ │ │ └── tree/
│ │ │ ├── CHANGELOG.md
│ │ │ ├── eslint.config.mjs
│ │ │ ├── index.html
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ └── index.ts
│ │ │ └── tsconfig.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── charts/
│ │ │ │ ├── index.ts
│ │ │ │ └── tree/
│ │ │ │ ├── sortAndSerialize.ts
│ │ │ │ ├── tree.ts
│ │ │ │ └── utils.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── d3tooltip/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── map2tree/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── test/
│ │ │ └── map2tree.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── react-base16-styling/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── colorConverters.ts
│ │ │ ├── index.ts
│ │ │ ├── themes/
│ │ │ │ ├── apathy.ts
│ │ │ │ ├── ashes.ts
│ │ │ │ ├── atelier-dune.ts
│ │ │ │ ├── atelier-forest.ts
│ │ │ │ ├── atelier-heath.ts
│ │ │ │ ├── atelier-lakeside.ts
│ │ │ │ ├── atelier-seaside.ts
│ │ │ │ ├── bespin.ts
│ │ │ │ ├── brewer.ts
│ │ │ │ ├── bright.ts
│ │ │ │ ├── chalk.ts
│ │ │ │ ├── codeschool.ts
│ │ │ │ ├── colors.ts
│ │ │ │ ├── default.ts
│ │ │ │ ├── eighties.ts
│ │ │ │ ├── embers.ts
│ │ │ │ ├── flat.ts
│ │ │ │ ├── google.ts
│ │ │ │ ├── grayscale.ts
│ │ │ │ ├── greenscreen.ts
│ │ │ │ ├── harmonic.ts
│ │ │ │ ├── hopscotch.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── isotope.ts
│ │ │ │ ├── marrakesh.ts
│ │ │ │ ├── mocha.ts
│ │ │ │ ├── monokai.ts
│ │ │ │ ├── nicinabox.ts
│ │ │ │ ├── ocean.ts
│ │ │ │ ├── paraiso.ts
│ │ │ │ ├── pop.ts
│ │ │ │ ├── railscasts.ts
│ │ │ │ ├── shapeshifter.ts
│ │ │ │ ├── solarized.ts
│ │ │ │ ├── summerfruit.ts
│ │ │ │ ├── threezerotwofour.ts
│ │ │ │ ├── tomorrow.ts
│ │ │ │ ├── tube.ts
│ │ │ │ └── twilight.ts
│ │ │ └── types.ts
│ │ ├── test/
│ │ │ └── index.test.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── react-dock/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── demo/
│ │ │ ├── CHANGELOG.md
│ │ │ ├── eslint.config.mjs
│ │ │ ├── index.html
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ ├── App.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── tsconfig.app.json
│ │ │ ├── tsconfig.json
│ │ │ ├── tsconfig.node.json
│ │ │ └── vite.config.ts
│ │ ├── eslint.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── Dock.tsx
│ │ │ ├── autoprefix.ts
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── react-json-tree/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.js
│ │ ├── examples/
│ │ │ ├── CHANGELOG.md
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── eslint.config.mjs
│ │ │ ├── index.html
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ ├── App.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── tsconfig.app.json
│ │ │ ├── tsconfig.json
│ │ │ ├── tsconfig.node.json
│ │ │ └── vite.config.ts
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── ItemRange.tsx
│ │ │ ├── JSONArrayNode.tsx
│ │ │ ├── JSONArrow.tsx
│ │ │ ├── JSONIterableNode.tsx
│ │ │ ├── JSONNestedNode.tsx
│ │ │ ├── JSONNode.tsx
│ │ │ ├── JSONObjectNode.tsx
│ │ │ ├── JSONValueNode.tsx
│ │ │ ├── createStylingFromTheme.ts
│ │ │ ├── getCollectionEntries.ts
│ │ │ ├── index.tsx
│ │ │ ├── objType.ts
│ │ │ ├── themes/
│ │ │ │ └── solarized.ts
│ │ │ └── types.ts
│ │ ├── test/
│ │ │ └── objType.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── redux-devtools/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── examples/
│ │ │ ├── counter/
│ │ │ │ ├── CHANGELOG.md
│ │ │ │ ├── README.md
│ │ │ │ ├── eslint.config.mjs
│ │ │ │ ├── index.html
│ │ │ │ ├── package.json
│ │ │ │ ├── src/
│ │ │ │ │ ├── actions/
│ │ │ │ │ │ └── CounterActions.ts
│ │ │ │ │ ├── components/
│ │ │ │ │ │ └── Counter.tsx
│ │ │ │ │ ├── constants/
│ │ │ │ │ │ └── ActionTypes.ts
│ │ │ │ │ ├── containers/
│ │ │ │ │ │ ├── CounterApp.tsx
│ │ │ │ │ │ ├── DevTools.tsx
│ │ │ │ │ │ ├── Root.dev.tsx
│ │ │ │ │ │ ├── Root.prod.tsx
│ │ │ │ │ │ └── Root.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── reducers/
│ │ │ │ │ │ ├── counter.ts
│ │ │ │ │ │ └── index.ts
│ │ │ │ │ └── store/
│ │ │ │ │ ├── configureStore.dev.ts
│ │ │ │ │ ├── configureStore.prod.ts
│ │ │ │ │ └── configureStore.ts
│ │ │ │ ├── tsconfig.json
│ │ │ │ ├── tsconfig.webpack.json
│ │ │ │ └── webpack.config.ts
│ │ │ └── todomvc/
│ │ │ ├── CHANGELOG.md
│ │ │ ├── README.md
│ │ │ ├── eslint.config.mjs
│ │ │ ├── index.html
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ ├── actions/
│ │ │ │ │ └── TodoActions.ts
│ │ │ │ ├── components/
│ │ │ │ │ ├── Footer.tsx
│ │ │ │ │ ├── Header.tsx
│ │ │ │ │ ├── MainSection.tsx
│ │ │ │ │ ├── TodoItem.tsx
│ │ │ │ │ └── TodoTextInput.tsx
│ │ │ │ ├── constants/
│ │ │ │ │ ├── ActionTypes.ts
│ │ │ │ │ └── TodoFilters.ts
│ │ │ │ ├── containers/
│ │ │ │ │ ├── DevTools.tsx
│ │ │ │ │ ├── Root.dev.tsx
│ │ │ │ │ ├── Root.prod.tsx
│ │ │ │ │ ├── Root.ts
│ │ │ │ │ └── TodoApp.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── reducers/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── todos.ts
│ │ │ │ └── store/
│ │ │ │ ├── configureStore.dev.ts
│ │ │ │ ├── configureStore.prod.ts
│ │ │ │ └── configureStore.ts
│ │ │ ├── tsconfig.json
│ │ │ ├── tsconfig.webpack.json
│ │ │ └── webpack.config.ts
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── createDevTools.tsx
│ │ │ ├── index.ts
│ │ │ └── persistState.ts
│ │ ├── test/
│ │ │ ├── globalLocalStorage.d.ts
│ │ │ └── persistState.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── redux-devtools-app/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── assets/
│ │ │ └── index.html
│ │ ├── babel.config.json
│ │ ├── buildUmd.mjs
│ │ ├── demo/
│ │ │ └── index.tsx
│ │ ├── eslint.config.mjs
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── actions/
│ │ │ │ └── index.ts
│ │ │ ├── components/
│ │ │ │ └── Settings/
│ │ │ │ └── Connection.tsx
│ │ │ ├── constants/
│ │ │ │ └── socketActionTypes.ts
│ │ │ ├── index.tsx
│ │ │ ├── middlewares/
│ │ │ │ └── api.ts
│ │ │ ├── reducers/
│ │ │ │ ├── connection.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── socket.ts
│ │ │ ├── store/
│ │ │ │ └── configureStore.ts
│ │ │ └── utils/
│ │ │ └── monitorActions.ts
│ │ ├── tsconfig.demo.json
│ │ ├── tsconfig.json
│ │ ├── tsconfig.webpack.json
│ │ └── webpack.config.ts
│ ├── redux-devtools-app-core/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── actions/
│ │ │ │ └── index.ts
│ │ │ ├── components/
│ │ │ │ ├── BottomButtons.tsx
│ │ │ │ ├── Header.tsx
│ │ │ │ ├── InstanceSelector.tsx
│ │ │ │ ├── MonitorSelector.tsx
│ │ │ │ ├── Settings/
│ │ │ │ │ ├── StateTree.tsx
│ │ │ │ │ ├── Themes.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── TopButtons.tsx
│ │ │ │ └── buttons/
│ │ │ │ ├── DispatcherButton.tsx
│ │ │ │ ├── ExportButton.tsx
│ │ │ │ ├── ImportButton.tsx
│ │ │ │ ├── LockButton.tsx
│ │ │ │ ├── PersistButton.tsx
│ │ │ │ ├── PrintButton.tsx
│ │ │ │ ├── RecordButton.tsx
│ │ │ │ ├── SliderButton.tsx
│ │ │ │ └── SyncButton.tsx
│ │ │ ├── constants/
│ │ │ │ ├── actionTypes.ts
│ │ │ │ └── dataTypes.ts
│ │ │ ├── containers/
│ │ │ │ ├── Actions.tsx
│ │ │ │ ├── App.tsx
│ │ │ │ ├── DevTools.tsx
│ │ │ │ └── monitors/
│ │ │ │ ├── ChartMonitorWrapper.tsx
│ │ │ │ ├── Dispatcher.tsx
│ │ │ │ ├── InspectorWrapper/
│ │ │ │ │ ├── ChartTab.tsx
│ │ │ │ │ ├── RawTab.tsx
│ │ │ │ │ ├── SubTabs.tsx
│ │ │ │ │ ├── VisualDiffTab.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ └── Slider.tsx
│ │ │ ├── index.tsx
│ │ │ ├── middlewares/
│ │ │ │ ├── exportState.ts
│ │ │ │ └── index.ts
│ │ │ ├── reducers/
│ │ │ │ ├── index.ts
│ │ │ │ ├── instances.ts
│ │ │ │ ├── monitor.ts
│ │ │ │ ├── notification.ts
│ │ │ │ ├── reports.ts
│ │ │ │ ├── section.ts
│ │ │ │ ├── stateTreeSettings.ts
│ │ │ │ └── theme.ts
│ │ │ └── utils/
│ │ │ ├── commitExcessActions.ts
│ │ │ ├── getMonitor.tsx
│ │ │ ├── parseJSON.ts
│ │ │ ├── stringifyJSON.ts
│ │ │ └── updateState.ts
│ │ ├── test/
│ │ │ ├── __mocks__/
│ │ │ │ └── styleMock.ts
│ │ │ ├── app.spec.tsx
│ │ │ └── setup.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── redux-devtools-chart-monitor/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── Chart.tsx
│ │ │ ├── ChartMonitor.tsx
│ │ │ ├── actions.ts
│ │ │ ├── index.ts
│ │ │ └── reducers.ts
│ │ └── tsconfig.json
│ ├── redux-devtools-cli/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── app/
│ │ │ ├── electron.cjs
│ │ │ ├── index.html
│ │ │ └── package.json
│ │ ├── bin/
│ │ │ └── redux-devtools.js
│ │ ├── defaultDbOptions.json
│ │ ├── eslint.config.mjs
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── api/
│ │ │ │ ├── schema.ts
│ │ │ │ └── schema_def.graphql
│ │ │ ├── bin/
│ │ │ │ ├── injectServer.ts
│ │ │ │ ├── openApp.ts
│ │ │ │ └── redux-devtools.ts
│ │ │ ├── db/
│ │ │ │ ├── connector.ts
│ │ │ │ ├── migrations/
│ │ │ │ │ └── index.ts
│ │ │ │ └── seeds/
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── options.ts
│ │ │ ├── routes.ts
│ │ │ └── store.ts
│ │ ├── test/
│ │ │ └── integration.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── redux-devtools-dock-monitor/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── DockMonitor.tsx
│ │ │ ├── actions.ts
│ │ │ ├── constants.ts
│ │ │ ├── index.ts
│ │ │ └── reducers.ts
│ │ └── tsconfig.json
│ ├── redux-devtools-extension/
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── developmentOnly.ts
│ │ │ ├── index.ts
│ │ │ ├── logOnly.ts
│ │ │ └── logOnlyInProduction.ts
│ │ └── tsconfig.json
│ ├── redux-devtools-inspector-monitor/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── demo/
│ │ │ ├── CHANGELOG.md
│ │ │ ├── eslint.config.mjs
│ │ │ ├── index.html
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ ├── DemoApp.tsx
│ │ │ │ ├── DevTools.tsx
│ │ │ │ ├── getOptions.ts
│ │ │ │ ├── index.tsx
│ │ │ │ └── reducers.ts
│ │ │ ├── tsconfig.json
│ │ │ ├── tsconfig.webpack.json
│ │ │ └── webpack.config.ts
│ │ ├── eslint.config.mjs
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── ActionList.tsx
│ │ │ ├── ActionListHeader.tsx
│ │ │ ├── ActionListRow.tsx
│ │ │ ├── ActionPreview.tsx
│ │ │ ├── ActionPreviewHeader.tsx
│ │ │ ├── DevtoolsInspector.tsx
│ │ │ ├── RightSlider.tsx
│ │ │ ├── createDiffPatcher.ts
│ │ │ ├── index.ts
│ │ │ ├── redux.ts
│ │ │ ├── tabs/
│ │ │ │ ├── ActionTab.tsx
│ │ │ │ ├── DiffTab.tsx
│ │ │ │ ├── JSONDiff.tsx
│ │ │ │ ├── StateTab.tsx
│ │ │ │ ├── getItemString.tsx
│ │ │ │ └── getJsonTreeTheme.ts
│ │ │ ├── themes/
│ │ │ │ ├── index.ts
│ │ │ │ └── inspector.ts
│ │ │ └── utils/
│ │ │ ├── getInspectedState.ts
│ │ │ ├── isIterable.ts
│ │ │ ├── selectorButtonStyles.ts
│ │ │ └── themes.ts
│ │ └── tsconfig.json
│ ├── redux-devtools-inspector-monitor-test-tab/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── demo/
│ │ │ ├── CHANGELOG.md
│ │ │ ├── eslint.config.mjs
│ │ │ ├── index.html
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ ├── DemoApp.tsx
│ │ │ │ ├── DevTools.tsx
│ │ │ │ ├── getOptions.ts
│ │ │ │ ├── index.tsx
│ │ │ │ └── reducers.ts
│ │ │ ├── tsconfig.json
│ │ │ ├── tsconfig.webpack.json
│ │ │ └── webpack.config.ts
│ │ ├── eslint.config.mjs
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── TestGenerator.tsx
│ │ │ ├── index.tsx
│ │ │ ├── redux/
│ │ │ │ ├── ava/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── template.ts
│ │ │ │ ├── jest/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── template.ts
│ │ │ │ ├── mocha/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── template.ts
│ │ │ │ └── tape/
│ │ │ │ ├── index.ts
│ │ │ │ └── template.ts
│ │ │ ├── templateForm.ts
│ │ │ ├── types.ts
│ │ │ └── vanilla/
│ │ │ ├── ava/
│ │ │ │ ├── index.ts
│ │ │ │ └── template.ts
│ │ │ ├── jest/
│ │ │ │ ├── index.ts
│ │ │ │ └── template.ts
│ │ │ ├── mocha/
│ │ │ │ ├── index.ts
│ │ │ │ └── template.ts
│ │ │ └── tape/
│ │ │ ├── index.ts
│ │ │ └── template.ts
│ │ ├── test/
│ │ │ ├── TestGenerator.spec.tsx
│ │ │ ├── __mocks__/
│ │ │ │ └── styleMock.ts
│ │ │ ├── __snapshots__/
│ │ │ │ └── TestGenerator.spec.tsx.snap
│ │ │ └── assertions.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── redux-devtools-inspector-monitor-trace-tab/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── StackTraceTab.tsx
│ │ │ ├── openFile.ts
│ │ │ ├── presets.ts
│ │ │ └── react-error-overlay/
│ │ │ ├── components/
│ │ │ │ ├── CodeBlock.tsx
│ │ │ │ └── Collapsible.tsx
│ │ │ ├── containers/
│ │ │ │ ├── StackFrame.tsx
│ │ │ │ ├── StackFrameCodeBlock.tsx
│ │ │ │ └── StackTrace.tsx
│ │ │ └── utils/
│ │ │ ├── dom/
│ │ │ │ ├── absolutifyCaret.ts
│ │ │ │ └── css.ts
│ │ │ ├── generateAnsiHTML.ts
│ │ │ ├── getLinesAround.ts
│ │ │ ├── getPrettyURL.ts
│ │ │ ├── getSourceMap.ts
│ │ │ ├── getStackFrames.ts
│ │ │ ├── isBultinErrorName.ts
│ │ │ ├── isInternalFile.ts
│ │ │ ├── mapper.ts
│ │ │ ├── parseCompileError.ts
│ │ │ ├── parser.ts
│ │ │ ├── stack-frame.ts
│ │ │ └── unmapper.ts
│ │ ├── test/
│ │ │ ├── StackTraceTab.spec.tsx
│ │ │ └── __snapshots__/
│ │ │ └── StackTraceTab.spec.tsx.snap
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── redux-devtools-instrument/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── getSymbolObservable.ts
│ │ │ └── instrument.ts
│ │ ├── test/
│ │ │ └── instrument.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── redux-devtools-log-monitor/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── LogMonitor.tsx
│ │ │ ├── LogMonitorButton.tsx
│ │ │ ├── LogMonitorButtonBar.tsx
│ │ │ ├── LogMonitorEntry.tsx
│ │ │ ├── LogMonitorEntryAction.tsx
│ │ │ ├── LogMonitorEntryList.tsx
│ │ │ ├── actions.ts
│ │ │ ├── brighten.ts
│ │ │ ├── index.ts
│ │ │ └── reducers.ts
│ │ └── tsconfig.json
│ ├── redux-devtools-remote/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── configureStore.ts
│ │ │ ├── constants.ts
│ │ │ ├── devTools.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── redux-devtools-rtk-query-monitor/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── demo/
│ │ │ ├── CHANGELOG.md
│ │ │ ├── eslint.config.mjs
│ │ │ ├── index.html
│ │ │ ├── package.json
│ │ │ ├── public/
│ │ │ │ └── mockServiceWorker.js
│ │ │ ├── src/
│ │ │ │ ├── App.tsx
│ │ │ │ ├── components/
│ │ │ │ │ └── ui/
│ │ │ │ │ ├── provider.tsx
│ │ │ │ │ └── toaster.tsx
│ │ │ │ ├── features/
│ │ │ │ │ ├── DevTools/
│ │ │ │ │ │ ├── DevTools.tsx
│ │ │ │ │ │ ├── DevToolsSelector.tsx
│ │ │ │ │ │ ├── config.ts
│ │ │ │ │ │ └── helpers.ts
│ │ │ │ │ ├── pokemon/
│ │ │ │ │ │ ├── Pokemon.tsx
│ │ │ │ │ │ └── PokemonView.tsx
│ │ │ │ │ └── posts/
│ │ │ │ │ ├── PostDetail.tsx
│ │ │ │ │ ├── PostsManager.tsx
│ │ │ │ │ └── PostsView.tsx
│ │ │ │ ├── index.css
│ │ │ │ ├── index.tsx
│ │ │ │ ├── mocks/
│ │ │ │ │ ├── browser.ts
│ │ │ │ │ └── db.ts
│ │ │ │ ├── pokemon.data.ts
│ │ │ │ ├── react-app-env.d.ts
│ │ │ │ ├── services/
│ │ │ │ │ ├── pokemon.ts
│ │ │ │ │ └── posts.ts
│ │ │ │ └── store.ts
│ │ │ ├── tsconfig.json
│ │ │ ├── tsconfig.webpack.json
│ │ │ └── webpack.config.ts
│ │ ├── eslint.config.mjs
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── components/
│ │ │ │ ├── ArrowUpIcon.tsx
│ │ │ │ ├── NoRtkQueryApi.tsx
│ │ │ │ ├── QueryForm.tsx
│ │ │ │ ├── QueryList.tsx
│ │ │ │ ├── QueryPreviewActions.tsx
│ │ │ │ ├── QueryPreviewApi.tsx
│ │ │ │ ├── QueryPreviewData.tsx
│ │ │ │ ├── QueryPreviewHeader.tsx
│ │ │ │ ├── QueryPreviewInfo.tsx
│ │ │ │ ├── QueryPreviewSubscriptions.tsx
│ │ │ │ ├── QueryPreviewTags.tsx
│ │ │ │ ├── RegexIcon.tsx
│ │ │ │ ├── SortOrderButton.tsx
│ │ │ │ ├── TreeView.tsx
│ │ │ │ └── UList.tsx
│ │ │ ├── containers/
│ │ │ │ ├── QueryPreview.tsx
│ │ │ │ ├── RtkQueryInspector.tsx
│ │ │ │ ├── RtkQueryMonitor.tsx
│ │ │ │ └── mapProps.tsx
│ │ │ ├── index.ts
│ │ │ ├── monitor-config.ts
│ │ │ ├── reducers.ts
│ │ │ ├── selectors.ts
│ │ │ ├── styles/
│ │ │ │ ├── themes.ts
│ │ │ │ └── tree.tsx
│ │ │ ├── types.ts
│ │ │ └── utils/
│ │ │ ├── a11y.ts
│ │ │ ├── comparators.ts
│ │ │ ├── filters.ts
│ │ │ ├── formatters.ts
│ │ │ ├── isIterable.ts
│ │ │ ├── object.ts
│ │ │ ├── regexp.ts
│ │ │ ├── rtk-query.ts
│ │ │ ├── statistics.ts
│ │ │ └── tabs.ts
│ │ ├── test/
│ │ │ ├── __mocks__/
│ │ │ │ └── styleMock.ts
│ │ │ ├── devtools.mocks.tsx
│ │ │ ├── integration.spec.tsx
│ │ │ └── rtk-query.mocks.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── redux-devtools-serialize/
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── constants/
│ │ │ │ └── options.ts
│ │ │ ├── helpers/
│ │ │ │ └── index.ts
│ │ │ ├── immutable/
│ │ │ │ ├── index.ts
│ │ │ │ └── serialize.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── test/
│ │ │ ├── __snapshots__/
│ │ │ │ ├── helpers.spec.ts.snap
│ │ │ │ └── immutable.spec.ts.snap
│ │ │ ├── helpers.spec.ts
│ │ │ └── immutable.spec.ts
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ ├── redux-devtools-slider-monitor/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── examples/
│ │ │ └── todomvc/
│ │ │ ├── CHANGELOG.md
│ │ │ ├── README.md
│ │ │ ├── eslint.config.mjs
│ │ │ ├── index.html
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ ├── actions/
│ │ │ │ │ └── TodoActions.ts
│ │ │ │ ├── components/
│ │ │ │ │ ├── Footer.tsx
│ │ │ │ │ ├── Header.tsx
│ │ │ │ │ ├── MainSection.tsx
│ │ │ │ │ ├── TodoItem.tsx
│ │ │ │ │ └── TodoTextInput.tsx
│ │ │ │ ├── constants/
│ │ │ │ │ ├── ActionTypes.ts
│ │ │ │ │ └── TodoFilters.ts
│ │ │ │ ├── containers/
│ │ │ │ │ ├── DevTools.tsx
│ │ │ │ │ ├── Root.dev.tsx
│ │ │ │ │ ├── Root.prod.tsx
│ │ │ │ │ ├── Root.ts
│ │ │ │ │ └── TodoApp.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── reducers/
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── todos.ts
│ │ │ │ └── store/
│ │ │ │ ├── configureStore.dev.ts
│ │ │ │ ├── configureStore.prod.ts
│ │ │ │ └── configureStore.ts
│ │ │ ├── tsconfig.json
│ │ │ ├── tsconfig.webpack.json
│ │ │ └── webpack.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── SliderButton.tsx
│ │ │ ├── SliderMonitor.tsx
│ │ │ ├── index.ts
│ │ │ └── reducers.ts
│ │ └── tsconfig.json
│ ├── redux-devtools-ui/
│ │ ├── .gitignore
│ │ ├── .storybook/
│ │ │ ├── main.ts
│ │ │ └── preview.tsx
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── eslint.config.mjs
│ │ ├── fonts/
│ │ │ └── index.css
│ │ ├── jest.config.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── Button/
│ │ │ │ ├── Button.stories.tsx
│ │ │ │ ├── Button.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ ├── common.ts
│ │ │ │ ├── default.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── material.ts
│ │ │ ├── Container/
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles/
│ │ │ │ └── index.ts
│ │ │ ├── ContextMenu/
│ │ │ │ ├── ContextMenu.stories.tsx
│ │ │ │ ├── ContextMenu.tsx
│ │ │ │ ├── data.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ └── index.ts
│ │ │ ├── Dialog/
│ │ │ │ ├── Dialog.stories.tsx
│ │ │ │ ├── Dialog.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ ├── default.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── material.ts
│ │ │ ├── Editor/
│ │ │ │ ├── Editor.stories.tsx
│ │ │ │ ├── Editor.tsx
│ │ │ │ ├── WithTabs.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ └── index.ts
│ │ │ ├── Form/
│ │ │ │ ├── Form.stories.tsx
│ │ │ │ ├── Form.tsx
│ │ │ │ ├── index.ts
│ │ │ │ ├── schema.ts
│ │ │ │ ├── styles/
│ │ │ │ │ └── index.ts
│ │ │ │ └── widgets.tsx
│ │ │ ├── Notification/
│ │ │ │ ├── Notification.stories.tsx
│ │ │ │ ├── Notification.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ └── index.ts
│ │ │ ├── SegmentedControl/
│ │ │ │ ├── SegmentedControl.stories.tsx
│ │ │ │ ├── SegmentedControl.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles/
│ │ │ │ └── index.ts
│ │ │ ├── Select/
│ │ │ │ ├── Select.stories.tsx
│ │ │ │ ├── Select.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── options.ts
│ │ │ ├── Slider/
│ │ │ │ ├── Slider.stories.tsx
│ │ │ │ ├── Slider.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ ├── common.ts
│ │ │ │ ├── default.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── material.ts
│ │ │ ├── Tabs/
│ │ │ │ ├── Tabs.stories.tsx
│ │ │ │ ├── Tabs.tsx
│ │ │ │ ├── TabsHeader.tsx
│ │ │ │ ├── data.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ ├── common.ts
│ │ │ │ ├── default.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── material.ts
│ │ │ ├── Toolbar/
│ │ │ │ ├── Toolbar.stories.tsx
│ │ │ │ ├── index.ts
│ │ │ │ └── styles/
│ │ │ │ ├── Divider.ts
│ │ │ │ ├── Spacer.ts
│ │ │ │ └── Toolbar.ts
│ │ │ ├── colorSchemes/
│ │ │ │ ├── atom-one-dark.ts
│ │ │ │ ├── default.ts
│ │ │ │ ├── dracula.ts
│ │ │ │ ├── github.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── ir-black.ts
│ │ │ │ ├── macintosh.ts
│ │ │ │ ├── materia.ts
│ │ │ │ ├── oceanic-next.ts
│ │ │ │ ├── phd.ts
│ │ │ │ ├── pico.ts
│ │ │ │ ├── solar-flare.ts
│ │ │ │ ├── spacemacs.ts
│ │ │ │ ├── unikitty.ts
│ │ │ │ └── woodland.ts
│ │ │ ├── index.ts
│ │ │ ├── themes/
│ │ │ │ ├── default.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── material.ts
│ │ │ └── utils/
│ │ │ ├── animations.ts
│ │ │ ├── autoPrefix.ts
│ │ │ ├── color.ts
│ │ │ ├── createStyledComponent.ts
│ │ │ ├── createThemedComponent.tsx
│ │ │ ├── invertColors.ts
│ │ │ └── theme.ts
│ │ ├── test/
│ │ │ ├── Button.test.tsx
│ │ │ ├── Container.test.tsx
│ │ │ ├── ContextMenu.test.tsx
│ │ │ ├── Dialog.test.tsx
│ │ │ ├── Editor.test.tsx
│ │ │ ├── Form.test.tsx
│ │ │ ├── Notification.test.tsx
│ │ │ ├── SegmentedControl.test.tsx
│ │ │ ├── Select.test.tsx
│ │ │ ├── Slider.test.tsx
│ │ │ ├── Tabs.test.tsx
│ │ │ ├── Toolbar.test.tsx
│ │ │ ├── __mocks__/
│ │ │ │ └── styleMock.ts
│ │ │ └── __snapshots__/
│ │ │ ├── Button.test.tsx.snap
│ │ │ ├── Container.test.tsx.snap
│ │ │ ├── ContextMenu.test.tsx.snap
│ │ │ ├── Dialog.test.tsx.snap
│ │ │ ├── Editor.test.tsx.snap
│ │ │ ├── Form.test.tsx.snap
│ │ │ ├── Notification.test.tsx.snap
│ │ │ ├── SegmentedControl.test.tsx.snap
│ │ │ ├── Select.test.tsx.snap
│ │ │ ├── Slider.test.tsx.snap
│ │ │ ├── Tabs.test.tsx.snap
│ │ │ └── Toolbar.test.tsx.snap
│ │ ├── tsconfig.json
│ │ └── tsconfig.test.json
│ └── redux-devtools-utils/
│ ├── CHANGELOG.md
│ ├── LICENSE.md
│ ├── eslint.config.mjs
│ ├── package.json
│ ├── src/
│ │ ├── catchErrors.ts
│ │ ├── filters.ts
│ │ ├── importState.ts
│ │ └── index.ts
│ └── tsconfig.json
├── patches/
│ ├── @dnd-kit__core.patch
│ ├── @dnd-kit__sortable.patch
│ └── redux-persist.patch
├── pnpm-workspace.yaml
├── renovate.json
├── tsconfig.base.json
├── tsconfig.esm.base.json
├── tsconfig.esm.react.base.json
└── tsconfig.react.base.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .changeset/config.json
================================================
{
"$schema": "https://unpkg.com/@changesets/config@1.6.4/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"onlyUpdatePeerDependentsWhenOutOfRange": true
}
}
================================================
FILE: .eslintignore
================================================
*.log
.idea
lib
dist
umd
build
coverage
node_modules
__snapshots__
storybook-static
.vscode/*
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
================================================
FILE: .github/FUNDING.yml
================================================
github: Methuselah96
open_collective: redux-devtools-extension
================================================
FILE: .github/workflows/CI.yml
================================================
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: 'ubuntu-24.04'
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v6
with:
node-version: 'lts/*'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Check formatting
run: pnpm run format:check
- name: Build
run: pnpm run build:all
- name: Lint
run: pnpm run lint:all
- run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- name: Test
uses: coactions/setup-xvfb@v1
with:
run: pnpm run test:all
================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
push:
branches:
- main
permissions: write-all
jobs:
release:
name: Release
runs-on: 'ubuntu-24.04'
steps:
- name: Checkout Repo
uses: actions/checkout@v6
with:
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0
- uses: pnpm/action-setup@v5
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 'lts/*'
cache: 'pnpm'
- name: Install Dependencies
run: pnpm install
- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
with:
version: pnpm changeset version
publish: pnpm run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Archive Chrome Extension
uses: actions/upload-artifact@v7
with:
name: chrome
path: extension/chrome/dist
- name: Archive Edge Extension
uses: actions/upload-artifact@v7
with:
name: edge
path: extension/edge/dist
- name: Archive Firefox Extension
uses: actions/upload-artifact@v7
with:
name: firefox
path: extension/firefox/dist
================================================
FILE: .gitignore
================================================
node_modules
*.log
.DS_Store
lib
dist
umd
build
coverage
.idea
.eslintcache
!packages/redux-devtools-slider-monitor/examples/todomvc/dist/index.html
.nx
*.tsbuildinfo
================================================
FILE: .prettierignore
================================================
*.log
.idea
lib
dist
umd
build
coverage
node_modules
__snapshots__
dev
**/demo/public/**
storybook-static
.vscode/*
pnpm-lock.yaml
================================================
FILE: .prettierrc
================================================
{
"singleQuote": true
}
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Code of Conduct
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)
Copyright (c) 2015-present Dan Abramov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================

[](https://github.com/reduxjs/redux-devtools/pulls)
[](#backers)
[](#sponsors)
# Redux DevTools
Developer Tools to power-up [Redux](https://redux.js.org/) development workflow or any other architecture which handles the state change (see [integrations](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/Integrations.md)).
It can be used as a browser extension (for [Chrome](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd), [Edge](https://microsoftedge.microsoft.com/addons/detail/redux-devtools/nnkgneoiohoecpdiaponcejilbhhikei) and [Firefox](https://addons.mozilla.org/en-US/firefox/addon/reduxdevtools/)), as [a standalone app](https://github.com/reduxjs/redux-devtools/tree/main/packages/redux-devtools-app) or as [a React component](https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools) integrated in the client app.

## Documentation
- [Browser Extension Installation and Configuration](https://github.com/reduxjs/redux-devtools/tree/main/extension#installation)
- [Manual Integration as a React Component](./docs/Walkthrough.md#manual-integration)
- [Extension Options (Arguments)](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/API/Arguments.md)
- [Extension Methods (Advanced API)](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/API/Methods.md)
- [Remote monitoring](./docs/Integrations/Remote.md)
- [Troubleshooting](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/Troubleshooting.md)
- [Recipes](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/Recipes.md)
- [FAQ](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/FAQ.md)
## Development
This is a monorepo powered by [pnpm](https://pnpm.io/). [Install pnpm](https://pnpm.io/installation) and run `pnpm install` to get started. Each package's dependencies need to be built before the package itself can be built. You can either build all the packages (i.e., `pnpm run build:all`) or use pnpm workspace commands to build only the packages necessary for the packages you're working on (i.e., `pnpm --filter "remotedev-redux-devtools-extension" build`).
## Backers
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/redux-devtools-extension#backer)]
<a href="https://opencollective.com/redux-devtools-extension/backer/0/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/1/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/2/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/3/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/4/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/5/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/6/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/7/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/8/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/9/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/10/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/11/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/12/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/13/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/14/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/15/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/16/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/17/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/18/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/19/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/20/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/21/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/22/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/23/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/24/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/25/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/26/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/27/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/28/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/29/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/29/avatar.svg"></a>
## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/redux-devtools-extension#sponsor)]
<a href="https://opencollective.com/redux-devtools-extension/sponsor/0/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/1/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/2/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/3/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/4/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/5/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/6/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/7/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/8/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/9/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/10/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/11/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/12/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/13/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/14/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/15/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/16/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/17/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/18/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/19/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/20/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/21/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/22/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/23/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/24/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/25/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/26/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/27/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/27/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/28/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/29/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/29/avatar.svg"></a>
### License
MIT
================================================
FILE: docs/Integrations/Remote.md
================================================
## Remote monitoring
By installing [`@redux-devtools/cli`](https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-cli#usage), starting the server server and launching the Redux DevTools app (`redux-devtools --open`), you can connect any remote application, even not javascript. There are some integrations for javascript like [remote-redux-devtools](https://github.com/zalmoxisus/remote-redux-devtools) and [remotedev](https://github.com/zalmoxisus/remotedev), but the plan is to deprecate them and support it out of the box from the extension without a websocket server. It is more useful for non-js apps.
### WebSocket Clients
We're using [SocketCluster](http://socketcluster.io/) for realtime communication, which provides a fast and scalable webSocket layer and a minimal pub/sub system. You need to include one of [its clients](https://github.com/SocketCluster/client-drivers) in your app to communicate with RemotedevServer. Currently there are clients for [JavaScript (NodeJS)](https://github.com/SocketCluster/socketcluster-client), [Java](https://github.com/sacOO7/socketcluster-client-java), [Python](https://github.com/sacOO7/socketcluster-client-python), [C](https://github.com/sacOO7/socketcluster-client-C), [Objective-C](https://github.com/abpopov/SocketCluster-ios-client) and [.NET/C#](https://github.com/sacOO7/SocketclusterClientDotNet).
By default, the websocket server is running on `ws://localhost:8000/socketcluster/`.
### Messaging lifecycle
#### 1. Connecting to the WebSocket server
The client driver provides a way to connect to the server via websockets (see the docs for the selected client).
##### JavaScript
```js
var socket = socketCluster.connect({
hostname: 'localhost',
port: 8000,
});
```
##### Python
```py
socket = Socketcluster.socket("ws://localhost:8000/socketcluster/")
socket.connect()
```
> Note that JavaScript client composes the url from `hostname` and `port`, adding `/socketcluster/` path automatically. For other clients, you should specify that path. For example, for `ObjectiveC` it would be `self.client.initWithHost("localhost/socketcluster/", onPort: 8000, securely: false)`.
#### 2. Disconnecting and reconnecting
SocketCluster client handles reconnecting for you, but you still might want to know when the connection is established, or when it failed to connect.
##### JavaScript
```js
socket.on('connect', (status) => {
// Here will come the next step
});
socket.on('disconnect', (code) => {
console.warn('Socket disconnected with code', code);
});
socket.on('error', (error) => {
console.warn('Socket error', error);
});
```
##### Python
```py
def onconnect(socket):
// Here will call the next step
def ondisconnect(socket):
logging.info("on disconnect got called")
def onConnectError(socket, error):
logging.info("On connect error got called")
socket.setBasicListener(onconnect, ondisconnect, onConnectError)
```
#### 3. Authorizing and subscribing to the channel of events
We're not providing an authorizing mechanism yet. All you have to do is to emit a `login` event, and you'll get a `channelName` you should subscribe for, and watch for messages and events. Make sure to pass the `master` event, otherwise it should be a monitor, not a client app.
##### JavaScript
```js
socket.emit('login', 'master', (error, channelName) => {
if (error) {
console.log(error);
return;
}
channel = socket.subscribe(channelName);
channel.watch(handleMessages);
socket.on(channelName, handleMessages);
});
function handleMessages(message) {
// 5. Listening for monitor events
}
```
##### Python
```py
socket.emitack("login", "master", login)
def login(key, error, channelName):
socket.subscribe(channelName)
socket.onchannel(channelName, handleMessages)
socket.on(channelName, handleMessages)
def handleMessages(key, message):
// 5. Listening for monitor events
```
You could just emit the `login` event, and omit subscribing (and point `5` bellow) if you want only to log data, not to interact with te app.
#### 4. Sending the action and state to the monitor
To send your data to the monitor use `log` or `log-noid` channel. The latter will add the socket id to the message from the server side (useful when the message was sent before the connection was established).
The message object includes the following:
- `type` - usually should be `ACTION`. If you want to indicate that we're starting a new log (clear all actions emitted before and add `@@INIT`), use `INIT`. In case you have a lifted state similar to one provided by [`redux-devtools-instrument`](https://github.com/zalmoxisus/redux-devtools-instrument), use `STATE`.
- `action` - the action object. It is recommended to lift it in another object, and add `timestamp` to show when the action was fired off: `{ timestamp: Date.now(), action: { type: 'SOME_ACTION' } }`.
- `payload` - usually the state or lifted state object.
- `name` - name of the instance to be shown in the instances selector. If not provided, it will be equal to `instanceId`.
- `instanceId` - an id to identify the instance. If not provided, it will be the same as `id`. However, it is useful when having several instances (or stores) in the same connection. Also if the user will specify a constant value, it would allow to persist the state on app reload.
- `id` - socket connection id, which should be either `socket.id` or should not provided and use `log-noid` channel.
##### JavaScript
```js
const message = {
type: 'ACTION',
action: { action, timestamp: Date.now() },
payload: state,
id: socket.id,
instanceId: window.btoa(location.href),
name: document.title,
};
socket.emit(socket.id ? 'log' : 'log-noid', message);
```
##### Python
```py
class Message:
def __init__(self, action, state):
self.type = "ACTION"
self.action = action
self.payload = state
id: socket.id
socket.emit(socket.id if "log" else "log-noid", Message(action, state));
```
#### 5. Listening for monitor events
When a monitor action is emitted, you'll get an event on the subscribed function. The argument object includes a `type` key, which can be:
- `DISPATCH` - a monitor action dispatched on Redux DevTools monitor, like `{ type: 'DISPATCH', payload: { type: 'JUMP_TO_STATE', 'index': 2 }`. See [`redux-devtools-instrument`](https://github.com/zalmoxisus/redux-devtools-instrument/blob/master/src/instrument.js) for details. Additionally to that API, you'll get also a stringified `state` object when needed. So, for example, for time travelling (`JUMP_TO_STATE`) you can just parse and set the state (see the example). Usually implementing this type of actions would be enough.
- `ACTION` - the user requested to dispatch an action remotely like `{ type: 'ACTION', action: '{ type: \'INCREMENT_COUNTER\' }' }`. The `action` can be either a stringified javascript object which should be evalled or a function which arguments should be evalled like [here](https://github.com/zalmoxisus/remotedev-utils/blob/master/src/index.js#L62-L70).
- `START` - a monitor was opened. You could handle this event in order not to do extra tasks when the app is not monitored.
- `STOP` - a monitor was closed. You can take this as no need to send data to the monitor. I there are several monitors and one was closed, all others will send `START` event to acknowledge that we still have to send data.
See [`mobx-remotedev`](https://github.com/zalmoxisus/mobx-remotedev/blob/master/src/monitorActions.js) for an example of implementation without [`redux-devtools-instrument`](https://github.com/zalmoxisus/redux-devtools-instrument/blob/master/src/instrument.js).
##### JavaScript
```js
function handleMessages(message) {
if (message.type === 'DISPATCH' && message.payload.type === 'JUMP_TO_STATE') {
store.setState(JSON.parse(message.state));
}
}
```
##### Python
```py
def handleMessages(key, message):
if message.type === "DISPATCH" and message.payload.type === "JUMP_TO_STATE":
store.setState(json.loads(message.state));
```
================================================
FILE: docs/Walkthrough.md
================================================
# Walkthrough
## Browser Extension
If you don’t want to bother with installing Redux DevTools and integrating it into your project, consider using [Redux DevTools Extension](https://github.com/reduxjs/redux-devtools/tree/master/extension) for Chrome and Firefox. It provides access to the most popular monitors, is easy to configure to filter actions, and doesn’t require installing any packages.
## Manual Integration
If you want to have full control over where DevTools are displayed, or are developing a custom monitor, you will probably want to integrate them manually.
It’s more steps, but you will have full control over monitors and their configuration.
### Installation
```
npm install --save-dev @redux-devtools/core
```
You’ll also likely want to install some monitors:
```
npm install --save-dev @redux-devtools/log-monitor
npm install --save-dev @redux-devtools/dock-monitor
```
### Usage
#### Create a `DevTools` Component
Somewhere in your project, create a `DevTools` component by passing a `monitor` element to `createDevTools`. In the following example our `monitor` consists of [`LogMonitor`](https://github.com/gaearon/redux-devtools-log-monitor) docked within [`DockMonitor`](https://github.com/gaearon/redux-devtools-dock-monitor):
##### `containers/DevTools.js`
```js
import React from 'react';
// Exported from redux-devtools
import { createDevTools } from '@redux-devtools/core';
// Monitors are separate packages, and you can make a custom one
import LogMonitor from '@redux-devtools/log-monitor';
import DockMonitor from '@redux-devtools/dock-monitor';
// createDevTools takes a monitor and produces a DevTools component
const DevTools = createDevTools(
// Monitors are individually adjustable with props.
// Consult their repositories to learn about those props.
// Here, we put LogMonitor inside a DockMonitor.
// Note: DockMonitor is visible by default.
<DockMonitor
toggleVisibilityKey="ctrl-h"
changePositionKey="ctrl-q"
defaultIsVisible={true}
>
<LogMonitor theme="tomorrow" />
</DockMonitor>,
);
export default DevTools;
```
Note that you can use `LogMonitor` directly without wrapping it in `DockMonitor` if you’d like to display the DevTools UI somewhere right inside your application:
```js
// If you'd rather not use docking UI, use <LogMonitor> directly
const DevTools = createDevTools(<LogMonitor theme="solarized" />);
```
#### Use `DevTools.instrument()` Store Enhancer
The `DevTools` component you created with `createDevTools()` has a special static method called `instrument()`. It returns a [store enhancer](http://redux.js.org/docs/Glossary.html#store-enhancer) that you need to use in development.
A store enhancer is a function that enhances the behavior of `createStore()`. You can pass store enhancer as the last optional argument to `createStore()`. You probably already used another store enhancer—[`applyMiddleware()`](http://redux.js.org/docs/api/applyMiddleware.html). Unlike `applyMiddleware()`, you will need to be careful to only use `DevTools.instrument()` in development environment, and never in production.
The easiest way to apply several store enhancers in a row is to use the [`compose()`](http://redux.js.org/docs/api/compose.html) utility function that ships with Redux. It is the same `compose()` that you can find in Underscore and Lodash. In our case, we would use it to compose several store enhancers into one: `compose(applyMiddleware(m1, m2, m3), DevTools.instrument())`.
You can add additional options to it: `DevTools.instrument({ maxAge: 50, shouldCatchErrors: true })`. See [`redux-devtools-instrument`'s API](https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-instrument#api) for more details.
It’s important that you should add `DevTools.instrument()` _after_ `applyMiddleware` in your `compose()` function arguments. This is because `applyMiddleware` is potentially asynchronous, but `DevTools.instrument()` expects all actions to be plain objects rather than actions interpreted by asynchronous middleware such as [redux-promise](https://github.com/acdlite/redux-promise) or [redux-thunk](https://github.com/gaearon/redux-thunk). So make sure `applyMiddleware()` goes first in the `compose()` call, and `DevTools.instrument()` goes after it.
##### `store/configureStore.js`
```js
import { createStore, applyMiddleware, compose } from 'redux';
import rootReducer from '../reducers';
import DevTools from '../containers/DevTools';
const enhancer = compose(
// Middleware you want to use in development:
applyMiddleware(d1, d2, d3),
// Required! Enable Redux DevTools with the monitors you chose
DevTools.instrument(),
);
export default function configureStore(initialState) {
// Note: only Redux >= 3.1.0 supports passing enhancer as third argument.
// See https://github.com/reactjs/redux/releases/tag/v3.1.0
const store = createStore(rootReducer, initialState, enhancer);
// Hot reload reducers (requires Webpack or Browserify HMR to be enabled)
if (module.hot) {
module.hot.accept('../reducers', () =>
store.replaceReducer(
require('../reducers') /*.default if you use Babel 6+ */,
),
);
}
return store;
}
```
If you’d like, you may add another store enhancer called `persistState()`. It ships with this package, and it lets you serialize whole sessions (including all dispatched actions and the state of the monitors) by a URL key. So if you visit `http://localhost:3000/?debug_session=reproducing_weird_bug`, do something in the app, then open `http://localhost:3000/?debug_session=some_other_feature`, and then go back to `http://localhost:3000/?debug_session=reproducing_weird_bug`, the state will be restored. The implementation of `persistState()` is fairly naïve but you can take it as an inspiration and build a proper UI for it if you feel like it!
```js
// ...
import { persistState } from '@redux-devtools/core';
const enhancer = compose(
// Middleware you want to use in development:
applyMiddleware(d1, d2, d3),
// Required! Enable Redux DevTools with the monitors you chose
DevTools.instrument(),
// Optional. Lets you write ?debug_session=<key> in address bar to persist debug sessions
persistState(getDebugSessionKey()),
);
function getDebugSessionKey() {
// You can write custom logic here!
// By default we try to read the key from ?debug_session=<key> in the address bar
const matches = window.location.href.match(/[?&]debug_session=([^&#]+)\b/);
return matches && matches.length > 0 ? matches[1] : null;
}
export default function configureStore(initialState) {
// ...
}
```
#### Exclude DevTools from Production Builds
Finally, to make sure we’re not pulling any DevTools-related code in the production builds, we will envify our code. You can use [`DefinePlugin`](https://github.com/webpack/docs/wiki/list-of-plugins#defineplugin) with Webpack, or [`envify`](https://github.com/zertosh/loose-envify) for Browserify.
The trick is to replace all occurrences of a constant like `process.env.NODE_ENV` into a string depending on the environment, and import and render `redux-devtools` only when `process.env.NODE_ENV` is not `'production'`. Then, if you have an Uglify step before production, Uglify will eliminate dead `if (false)` branches with `redux-devtools` imports.
With Webpack, you'll need two config files, one for development and one for production. Here's a snippet from an example production config:
##### `webpack.config.prod.js`
```js
// ...
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
],
// ...
```
If you are using ES6 modules with Webpack 1.x and Babel, you might try putting your `import` statement inside an `if (process.env.NODE_ENV !== 'production)` to exclude the DevTools package from your production bundle. However this ES6 specification forbids it, so this won’t compile. Instead, you can use a conditional CommonJS `require`. Babel will let it compile, and Uglify will eliminate the dead branches before Webpack creates a bundle. This is why we recommend creating a `configureStore.js` file that either directs you to `configureStore.dev.js` or `configureStore.prod.js` depending on the configuration. While it is a little bit more maintenance, the upside is that you can be sure you won’t pull any development dependencies into the production builds, and that you can easily enable different middleware (e.g. crash reporting, logging) in the production environment.
##### `store/configureStore.js`
```js
// Use DefinePlugin (Webpack) or loose-envify (Browserify)
// together with Uglify to strip the dev branch in prod build.
if (process.env.NODE_ENV === 'production') {
module.exports = require('./configureStore.prod');
} else {
module.exports = require('./configureStore.dev');
}
```
##### `store/configureStore.prod.js`
```js
import { createStore, applyMiddleware, compose } from 'redux';
import rootReducer from '../reducers';
// Middleware you want to use in production:
const enhancer = applyMiddleware(p1, p2, p3);
export default function configureStore(initialState) {
// Note: only Redux >= 3.1.0 supports passing enhancer as third argument.
// See https://github.com/rackt/redux/releases/tag/v3.1.0
return createStore(rootReducer, initialState, enhancer);
}
```
##### `store/configureStore.dev.js`
```js
import { createStore, applyMiddleware, compose } from 'redux';
import { persistState } from '@redux-devtools/core';
import rootReducer from '../reducers';
import DevTools from '../containers/DevTools';
const enhancer = compose(
// Middleware you want to use in development:
applyMiddleware(d1, d2, d3),
// Required! Enable Redux DevTools with the monitors you chose
DevTools.instrument(),
// Optional. Lets you write ?debug_session=<key> in address bar to persist debug sessions
persistState(getDebugSessionKey()),
);
function getDebugSessionKey() {
// You can write custom logic here!
// By default we try to read the key from ?debug_session=<key> in the address bar
const matches = window.location.href.match(/[?&]debug_session=([^&]+)\b/);
return matches && matches.length > 0 ? matches[1] : null;
}
export default function configureStore(initialState) {
// Note: only Redux >= 3.1.0 supports passing enhancer as third argument.
// See https://github.com/rackt/redux/releases/tag/v3.1.0
const store = createStore(rootReducer, initialState, enhancer);
// Hot reload reducers (requires Webpack or Browserify HMR to be enabled)
if (module.hot) {
module.hot.accept('../reducers', () =>
store.replaceReducer(
require('../reducers') /*.default if you use Babel 6+ */,
),
);
}
return store;
}
```
#### Render `<DevTools>` in Your App...
Finally, include the `DevTools` component in your page.
A naïve way to do this would be to render it right in your `index.js`:
##### `index.js`
```js
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import configureStore from './store/configureStore';
import TodoApp from './containers/TodoApp';
// Don't do this! You’re bringing DevTools into the production bundle.
import DevTools from './containers/DevTools';
const store = configureStore();
render(
<Provider store={store}>
<div>
<TodoApp />
<DevTools />
</div>
</Provider>
document.getElementById('app')
);
```
We recommend a different approach. Create a `Root.js` component that renders the root of your application (usually some component surrounded by a `<Provider>`). Then use the same trick with conditional `require` statements to have two versions of it, one for development, and one for production:
##### `containers/Root.js`
```js
if (process.env.NODE_ENV === 'production') {
module.exports = require('./Root.prod');
} else {
module.exports = require('./Root.dev');
}
```
##### `containers/Root.dev.js`
```js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import TodoApp from './TodoApp';
import DevTools from './DevTools';
export default class Root extends Component {
render() {
const { store } = this.props;
return (
<Provider store={store}>
<div>
<TodoApp />
<DevTools />
</div>
</Provider>
);
}
}
```
##### `containers/Root.prod.js`
```js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import TodoApp from './TodoApp';
export default class Root extends Component {
render() {
const { store } = this.props;
return (
<Provider store={store}>
<TodoApp />
</Provider>
);
}
}
```
#### ...Or Open Them in a New Window
When you use [`DockMonitor`](https://github.com/gaearon/redux-devtools-dock-monitor), you usually want to render `<DevTools>` at the root of your app. It will appear in a docked container above it. However, you can also render it anywhere else in your React component tree. To do this, you can remove `DockMonitor` and instead render `<DevTools>` inside some component of your app. Don’t forget to create two versions of this component to exclude `DevTools` in production!
However you don’t even have to render `<DevTools>` in the same window. For example, you may prefer to display it in a popup. In this case, you can remove `DockMonitor` from `DevTools.js` and just use the `LogMonitor`, and have some code like this:
##### `index.js`
```js
import React from 'react';
import { Provider } from 'react-redux';
import { render } from 'react-dom';
import configureStore from './store/configureStore';
import App from './containers/App';
const store = configureStore();
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root'),
);
if (process.env.NODE_ENV !== 'production') {
const showDevTools = require('./showDevTools');
showDevTools(store);
}
```
##### `showDevTools.js`
```js
import React from 'react';
import { render } from 'react-dom';
import DevTools from './containers/DevTools';
export default function showDevTools(store) {
const popup = window.open(
null,
'Redux DevTools',
'menubar=no,location=no,resizable=yes,scrollbars=no,status=no',
);
// Reload in case it already exists
popup.location.reload();
setTimeout(() => {
popup.document.write('<div id="react-devtools-root"></div>');
render(
<DevTools store={store} />,
popup.document.getElementById('react-devtools-root'),
);
}, 10);
}
```
Personal preferences vary, and whether to put the DevTools in a separate window, in a dock, or right inside you app’s user interface, is up to you. Make sure to check the documentation for the monitors you use and learn about the different props they support for customizing the appearance and the behavior.
Note that there are no useful props you can pass to the `DevTools` component other than the `store`. The `store` prop is needed if you don’t wrap `<DevTools>` in a `<Provider>`—just like with any connected component. To adjust the monitors, you need to pass props to them inside `DevTools.js` itself inside the `createDevTools()` call when they are used.
### Gotchas
- **Your reducers have to be pure and free of side effects to work correctly with DevTools.** For example, even generating a random ID in reducer makes it impure and non-deterministic. Instead, do this in action creators.
- **Make sure to only apply `DevTools.instrument()` and render `<DevTools>` in development!** In production, this will be terribly slow because actions just accumulate forever. As described above, you need to use conditional `require`s and use `DefinePlugin` (Webpack) or `loose-envify` (Browserify) together with Uglify to remove the dead code. Here is [an example](https://github.com/erikras/react-redux-universal-hot-example/) that adds Redux DevTools handling the production case correctly.
- **It is important that `DevTools.instrument()` store enhancer should be added to your middleware stack _after_ `applyMiddleware` in the `compose`d functions, as `applyMiddleware` is potentially asynchronous.** Otherwise, DevTools won’t see the raw actions emitted by asynchronous middleware such as [redux-promise](https://github.com/acdlite/redux-promise) or [redux-thunk](https://github.com/gaearon/redux-thunk).
### What Next?
Now that you see the DevTools, you might want to learn what those buttons mean and how to use them. This usually depends on the monitor. You can begin by exploring the [LogMonitor](https://github.com/gaearon/redux-devtools-log-monitor) and [DockMonitor](https://github.com/gaearon/redux-devtools-dock-monitor) documentation, as they are the default monitors we suggest to use together. When you’re comfortable using them, you may want to create your own monitor for more exotic purposes, such as a [chart](https://github.com/romseguy/redux-devtools-chart-monitor) or a [diff](https://github.com/whetstone/redux-devtools-diff-monitor) monitor. Don’t forget to send a PR to feature your monitor at the front page!
================================================
FILE: eslint.js.config.base.mjs
================================================
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import eslintConfigPrettier from 'eslint-config-prettier';
export default defineConfig([eslint.configs.recommended, eslintConfigPrettier]);
================================================
FILE: eslint.js.react.jest.config.base.mjs
================================================
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import jest from 'eslint-plugin-jest';
import eslintConfigPrettier from 'eslint-config-prettier';
export default defineConfig([
{
files: ['test/**/*.js', 'test/**/*.jsx'],
...eslint.configs.recommended,
},
{
files: ['test/**/*.js', 'test/**/*.jsx'],
...react.configs.flat.recommended,
},
{
files: ['test/**/*.js', 'test/**/*.jsx'],
settings: {
react: {
version: 'detect',
},
},
},
{
files: ['test/**/*.js', 'test/**/*.jsx'],
...reactHooks.configs.flat.recommended,
},
{
files: ['test/**/*.js', 'test/**/*.jsx'],
...jest.configs['flat/recommended'],
},
{
files: ['test/**/*.js', 'test/**/*.jsx'],
...jest.configs['jest/style'],
},
{
files: ['test/**/*.js', 'test/**/*.jsx'],
...eslintConfigPrettier,
},
]);
================================================
FILE: eslint.ts.config.base.mjs
================================================
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import eslintConfigPrettier from 'eslint-config-prettier';
export default (tsconfigRootDir, files = ['**/*.ts'], project = true) =>
defineConfig([
{
files,
...eslint.configs.recommended,
},
...tseslint.configs.recommendedTypeChecked.map((config) => ({
files,
...config,
})),
...tseslint.configs.stylisticTypeChecked.map((config) => ({
files,
...config,
})),
{
files,
languageOptions: {
parserOptions: {
project,
tsconfigRootDir,
},
},
},
{
files,
...eslintConfigPrettier,
},
{
files,
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
},
},
]);
================================================
FILE: eslint.ts.jest.config.base.mjs
================================================
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import jest from 'eslint-plugin-jest';
import eslintConfigPrettier from 'eslint-config-prettier';
export default (tsconfigRootDir) =>
defineConfig([
{
files: ['test/**/*.ts'],
...eslint.configs.recommended,
},
...tseslint.configs.recommendedTypeChecked.map((config) => ({
files: ['test/**/*.ts'],
...config,
})),
...tseslint.configs.stylisticTypeChecked.map((config) => ({
files: ['test/**/*.ts'],
...config,
})),
{
files: ['test/**/*.ts'],
languageOptions: {
parserOptions: {
project: ['./tsconfig.test.json'],
tsconfigRootDir,
},
},
},
{
files: ['test/**/*.ts'],
...jest.configs['flat/recommended'],
},
{
files: ['test/**/*.ts'],
...jest.configs['jest/style'],
},
{
files: ['test/**/*.ts'],
...eslintConfigPrettier,
},
{
files: ['test/**/*.ts'],
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
},
},
]);
================================================
FILE: eslint.ts.react.config.base.mjs
================================================
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import eslintConfigPrettier from 'eslint-config-prettier';
export default (
tsconfigRootDir,
files = ['**/*.ts', '**/*.tsx'],
project = true,
) =>
defineConfig([
{
files,
...eslint.configs.recommended,
},
...tseslint.configs.recommendedTypeChecked.map((config) => ({
files,
...config,
})),
...tseslint.configs.stylisticTypeChecked.map((config) => ({
files,
...config,
})),
{
files,
languageOptions: {
parserOptions: {
project,
tsconfigRootDir,
},
},
},
{
files,
...react.configs.flat.recommended,
},
{
files,
settings: {
react: {
version: 'detect',
},
},
},
{
files,
...reactHooks.configs.flat.recommended,
},
{
files,
...eslintConfigPrettier,
},
{
files,
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-misused-promises': [
'error',
{
checksVoidReturn: {
attributes: false,
},
},
],
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
'react/prop-types': 'off',
},
},
]);
================================================
FILE: eslint.ts.react.jest.config.base.mjs
================================================
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import jest from 'eslint-plugin-jest';
import eslintConfigPrettier from 'eslint-config-prettier';
export default (tsconfigRootDir) =>
defineConfig([
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
...eslint.configs.recommended,
},
...tseslint.configs.recommendedTypeChecked.map((config) => ({
files: ['test/**/*.ts', 'test/**/*.tsx'],
...config,
})),
...tseslint.configs.stylisticTypeChecked.map((config) => ({
files: ['test/**/*.ts', 'test/**/*.tsx'],
...config,
})),
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
languageOptions: {
parserOptions: {
project: ['./tsconfig.test.json'],
tsconfigRootDir,
},
},
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
...react.configs.flat.recommended,
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
settings: {
react: {
version: 'detect',
},
},
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
...reactHooks.configs.flat.recommended,
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
...jest.configs['flat/recommended'],
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
...jest.configs['jest/style'],
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
...eslintConfigPrettier,
},
{
files: ['test/**/*.ts', 'test/**/*.tsx'],
rules: {
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/prefer-optional-chain': 'off',
'@typescript-eslint/no-base-to-string': 'off',
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
'@typescript-eslint/prefer-string-starts-ends-with': 'off',
'@typescript-eslint/no-duplicate-type-constituents': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/prefer-function-type': 'off',
},
},
]);
================================================
FILE: extension/.gitignore
================================================
node_modules
dist
================================================
FILE: extension/CHANGELOG.md
================================================
# remotedev-redux-devtools-extension
## 3.2.12
### Patch Changes
- Updated dependencies [3f90241]
- Updated dependencies [d61d31a]
- Updated dependencies [804e729]
- Updated dependencies [12849a4]
- Updated dependencies [804d6bd]
- Updated dependencies [6481386]
- @redux-devtools/instrument@3.0.0
- @redux-devtools/ui@3.0.0
- @redux-devtools/slider-monitor@7.0.0
- @redux-devtools/core@5.0.0
- @redux-devtools/app@8.0.0
- @redux-devtools/serialize@1.0.0
- @redux-devtools/utils@4.0.0
## 3.2.11
### Patch Changes
- Updated dependencies [6163276]
- @redux-devtools/app@7.0.0
- @redux-devtools/slider-monitor@6.0.0
- @redux-devtools/ui@2.0.0
## 3.2.10
### Patch Changes
- @redux-devtools/app@6.2.2
## 3.2.9
### Patch Changes
- Updated dependencies [91f21b2]
- @redux-devtools/core@4.1.1
- @redux-devtools/slider-monitor@5.1.1
- @redux-devtools/utils@3.1.1
- @redux-devtools/app@6.2.1
## 3.2.8
### Patch Changes
- Updated dependencies [6830118]
- react-json-tree@0.20.0
- @redux-devtools/app@6.2.0
- @redux-devtools/slider-monitor@6.0.0
- @redux-devtools/ui@1.4.0
- @redux-devtools/core@4.1.0
- @redux-devtools/utils@4.0.0
## 3.2.7
### Patch Changes
- b25bf13: Send state from background when monitor connects
## 3.2.6
### Patch Changes
- 50d7682: Fix DevTools from losing connection
## 3.2.5
### Patch Changes
- eb3ac09: Add logging to background service worker
## 3.2.4
### Patch Changes
- f1d6158: Fix mocking Chrome API for Electron
## 3.2.3
### Patch Changes
- fd9f950: Fix monitoring on opening panel
- e49708d: Fix manifest.json for Edge
## 3.2.1
### Patch Changes
- abd03a7: Fix: only send data to extension if DevTools are open
## 3.2.0
### Minor Changes
- 83b2c19: Upgrade to Manifest V3
## 3.1.11
### Patch Changes
- 73688e1: Fix releasing Firefox extension
## 3.1.10
### Patch Changes
- 2163bc3: Split large messages sent from background page to devpanel
## 3.1.9
### Patch Changes
- Updated dependencies [bbb1a40]
- react-json-tree@0.19.0
- @redux-devtools/slider-monitor@5.0.1
- @redux-devtools/ui@1.3.2
## 3.1.8
### Patch Changes
- 191d419: Convert d3 packages to ESM
- Updated dependencies [191d419]
- @redux-devtools/app@6.0.1
## 3.1.7
### Patch Changes
- Updated dependencies [5cfe3e5]
- Updated dependencies [decc035]
- @redux-devtools/app@6.0.0
- @redux-devtools/slider-monitor@5.0.0
- @redux-devtools/core@4.0.0
- @redux-devtools/utils@3.0.0
## 3.1.6
### Patch Changes
- Updated dependencies [158ba2c]
- @redux-devtools/app@5.0.0
## 3.1.5
### Patch Changes
- 65205f90: Replace Action<unknown> with Action<string>
- Updated dependencies [65205f90]
- @redux-devtools/app@4.0.1
- @redux-devtools/core@3.13.2
## 3.1.4
### Patch Changes
- Updated dependencies [e57bcb39]
- @redux-devtools/app@4.0.0
## 3.1.3
### Patch Changes
- bca76009: Fix missing CSS for code editor
## 3.1.2
### Patch Changes
- 64ed81b0: Fix extension in Firefox and Chrome Incognito
## 3.1.1
### Patch Changes
- d18525b5: Increase min-width of popup
- Updated dependencies [57751ff9]
- @redux-devtools/app@3.0.0
## 3.1.0
### Minor Changes
- d54adb76: Option to sort State Tree keys alphabetically
Option to disable collapsing of object keys
### Patch Changes
- @redux-devtools/app@2.2.2
## 3.0.19
### Patch Changes
- 450cde6e: Fix responsive layout
## 3.0.18
### Patch Changes
- Updated dependencies [81926f32]
- react-json-tree@0.18.0
- @redux-devtools/app@2.2.1
## 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
- Updated dependencies [8a7eae4]
- react-json-tree@0.17.0
- @redux-devtools/app@2.2.0
- @redux-devtools/slider-monitor@4.0.0
- @redux-devtools/ui@1.3.0
- @redux-devtools/core@3.13.0
- @redux-devtools/utils@2.0.0
## 3.0.12
### Patch Changes
- Updated dependencies [4891bf6]
- @redux-devtools/core@3.12.0
- @redux-devtools/slider-monitor@3.1.2
- @redux-devtools/utils@1.2.1
- @redux-devtools/app@2.1.4
## 3.0.11
### Patch Changes
- ab3c0e2: Avoid persisting the selected action index between sessions
- Updated dependencies [ab3c0e2]
- Updated dependencies [4c9a890]
- @redux-devtools/app@2.1.3
- react-json-tree@0.16.2
## 3.0.10
### Patch Changes
- 55cc37e: Fix filter to show state-controlled search value
- Updated dependencies [55cc37e]
- @redux-devtools/app@2.1.2
================================================
FILE: extension/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: extension/LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015-present Mihail Diordiev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: extension/README.md
================================================
# Redux DevTools Extension
[](https://gitter.im/zalmoxisus/redux-devtools-extension?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](http://makeapullrequest.com)
[](#backers)
[](#sponsors)

## Installation
### 1. For Chrome
- from [Chrome Web Store](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd);
- or download `extension.zip` from [last releases](https://github.com/zalmoxisus/redux-devtools-extension/releases), unzip, open `chrome://extensions` url and turn on developer mode from top left and then click; on `Load Unpacked` and select the extracted folder for use
- or build it with `npm i && npm run build:extension` and [load the extension's folder](https://developer.chrome.com/docs/extensions/get-started/tutorial/hello-world#load-unpacked) `./build/extension`;
- or run it in dev mode with `npm i && npm start` and [load the extension's folder](https://developer.chrome.com/docs/extensions/get-started/tutorial/hello-world#load-unpacked) `./dev`.
### 2. For Firefox
- from [Mozilla Add-ons](https://addons.mozilla.org/en-US/firefox/addon/reduxdevtools/);
- or build it with `npm i && npm run build:firefox` and [load the extension's folder](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox) `./build/firefox` (just select a file from inside the dir).
### 3. For Electron
- just specify `REDUX_DEVTOOLS` in [`electron-devtools-installer`](https://github.com/GPMDP/electron-devtools-installer).
### 4. For other browsers and non-browser environment
- use [`remote-redux-devtools`](https://github.com/zalmoxisus/remote-redux-devtools).
## Usage
> Note that starting from v2.7, `window.devToolsExtension` was renamed to `window.__REDUX_DEVTOOLS_EXTENSION__` / `window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__`.
## 1. With Redux
### 1.1 Basic store
For a basic [Redux store](https://redux.js.org/api/createstore#createstorereducer-preloadedstate-enhancer) simply add:
```diff
const store = createStore(
reducer, /* preloadedState, */
+ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
```
Note that [`preloadedState`](https://redux.js.org/api/createstore#createstorereducer-preloadedstate-enhancer) argument is optional in Redux's [`createStore`](https://redux.js.org/api/createstore#createstorereducer-preloadedstate-enhancer).
> For universal ("isomorphic") apps, prefix it with `typeof window !== 'undefined' &&`.
```js
const composeEnhancers =
(typeof window !== 'undefined' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
compose;
```
> For TypeScript use [`redux-devtools-extension` npm package](#13-use-redux-devtoolsextension-package-from-npm), which contains all the definitions, or just use `(window as any)` (see [Recipes](docs/Recipes.md#using-in-a-typescript-project) for an example).
```js
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
```
In case ESLint is configured to not allow using the underscore dangle, wrap it like so:
```diff
+ /* eslint-disable no-underscore-dangle */
const store = createStore(
reducer, /* preloadedState, */
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
+ /* eslint-enable */
```
> **Note**: Passing enhancer as last argument requires **redux@>=3.1.0**. For older versions apply it like [here](https://github.com/zalmoxisus/redux-devtools-extension/blob/v0.4.2/examples/todomvc/store/configureStore.js) or [here](https://github.com/zalmoxisus/redux-devtools-extension/blob/v0.4.2/examples/counter/store/configureStore.js#L7-L12). Don't mix the old Redux API with the new one.
> You don't need to npm install [`redux-devtools`](https://github.com/gaearon/redux-devtools) when using the extension (that's a different lib).
### 1.2 Advanced store setup
If you setup your store with [middleware and enhancers](http://redux.js.org/docs/api/applyMiddleware.html), change:
```diff
import { createStore, applyMiddleware, compose } from 'redux';
+ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
+ const store = createStore(reducer, /* preloadedState, */ composeEnhancers(
- const store = createStore(reducer, /* preloadedState, */ compose(
applyMiddleware(...middleware)
));
```
> Note that when the extension is not installed, we’re using Redux compose here.
To specify [extension’s options](https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md), use it like so:
```js
const composeEnhancers =
typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// Specify extension’s options like name, actionsDenylist, actionsCreators, serialize...
})
: compose;
const enhancer = composeEnhancers(
applyMiddleware(...middleware),
// other store enhancers if any
);
const store = createStore(reducer, enhancer);
```
> [See the post for more details](https://medium.com/@zalmoxis/improve-your-development-workflow-with-redux-devtools-extension-f0379227ff83).
### 1.3 Use `@redux-devtools/extension` package from npm
To make things easier, there's an npm package to install:
```
npm install --save @redux-devtools/extension
```
and to use like so:
```js
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from '@redux-devtools/extension';
const store = createStore(
reducer,
composeWithDevTools(
applyMiddleware(...middleware),
// other store enhancers if any
),
);
```
To specify [extension’s options](https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md#windowdevtoolsextensionconfig):
```js
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from '@redux-devtools/extension';
const composeEnhancers = composeWithDevTools({
// Specify name here, actionsDenylist, actionsCreators and other options if needed
});
const store = createStore(
reducer,
/* preloadedState, */ composeEnhancers(
applyMiddleware(...middleware),
// other store enhancers if any
),
);
```
> There are just a [few lines of code](https://github.com/zalmoxisus/redux-devtools-extension/blob/master/npm-package/index.js) added to your bundle.
In case you don't include other enhancers and middlewares, just use `devToolsEnhancer`:
```js
import { createStore } from 'redux';
import { devToolsEnhancer } from '@redux-devtools/extension';
const store = createStore(
reducer,
/* preloadedState, */ devToolsEnhancer(),
// Specify name here, actionsDenylist, actionsCreators and other options if needed
);
```
### 1.4 Using in production
It's useful to include the extension in production as well. Usually you [can use it for development](https://medium.com/@zalmoxis/using-redux-devtools-in-production-4c5b56c5600f).
If you want to restrict it there, use `composeWithDevToolsLogOnlyInProduction` or `devToolsEnhancerLogOnlyInProduction`:
```js
import { createStore } from 'redux';
import { devToolsEnhancerLogOnlyInProduction } from '@redux-devtools/extension';
const store = createStore(
reducer,
/* preloadedState, */ devToolsEnhancerLogOnlyInProduction(),
// options like actionSanitizer, stateSanitizer
);
```
or with middlewares and enhancers:
```js
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevToolsLogOnlyInProduction } from '@redux-devtools/extension';
const composeEnhancers = composeWithDevToolsLogOnlyInProduction({
// options like actionSanitizer, stateSanitizer
});
const store = createStore(
reducer,
/* preloadedState, */ composeEnhancers(
applyMiddleware(...middleware),
// other store enhancers if any
),
);
```
> You'll have to add `'process.env.NODE_ENV': JSON.stringify('production')` in your Webpack config for the production bundle ([to envify](https://github.com/gaearon/redux-devtools/blob/master/docs/Walkthrough.md#exclude-devtools-from-production-builds)). If you use `create-react-app`, [it already does it for you.](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/config/webpack.config.prod.js#L253-L257)
If you're already checking `process.env.NODE_ENV` when creating the store, import `composeWithDevToolsLogOnly` or `devToolsEnhancerLogOnly` for production environment.
If you don’t want to allow the extension in production, just use `composeWithDevToolsDevelopmentOnly` or `devToolsEnhancerDevelopmentOnly`.
> See [the article](https://medium.com/@zalmoxis/using-redux-devtools-in-production-4c5b56c5600f) for more details.
### 1.5 For React Native, hybrid, desktop and server side Redux apps
For React Native we can use [`react-native-debugger`](https://github.com/jhen0409/react-native-debugger), which already included [the same API](https://github.com/jhen0409/react-native-debugger/blob/master/docs/redux-devtools-integration.md) with Redux DevTools Extension.
For most platforms, include [`Remote Redux DevTools`](https://github.com/zalmoxisus/remote-redux-devtools)'s store enhancer, and from the extension's context menu choose 'Open Remote DevTools' for remote monitoring.
## 2. Without Redux
See [integrations](docs/Integrations.md) and [the blog post](https://medium.com/@zalmoxis/redux-devtools-without-redux-or-how-to-have-a-predictable-state-with-any-architecture-61c5f5a7716f) for more details on how to use the extension with any architecture.
## Docs
- [Options (arguments)](docs/API/Arguments.md)
- [Methods (advanced API)](docs/API/Methods.md)
- [FAQ](docs/FAQ.md)
- Features
- [Trace actions calls](docs/Features/Trace.md)
- [Troubleshooting](docs/Troubleshooting.md)
- [Articles](docs/Articles.md)
- [Videos](docs/Videos.md)
- [Feedback](docs/Feedback.md)
## Demo
Live demos to use the extension with:
- [Counter](http://zalmoxisus.github.io/examples/counter/)
- [TodoMVC](http://zalmoxisus.github.io/examples/todomvc/)
- [Redux Form](http://redux-form.com/6.5.0/examples/simple/)
- [React Tetris](https://chvin.github.io/react-tetris/?lan=en)
- [Book Collection (Angular ngrx store)](https://ngrx.github.io/platform/example-app/)
Also see [`./examples` folder](https://github.com/zalmoxisus/redux-devtools-extension/tree/master/examples).
## Backers
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/redux-devtools-extension#backer)]
<a href="https://opencollective.com/redux-devtools-extension/backer/0/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/1/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/2/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/3/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/4/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/5/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/6/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/7/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/8/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/9/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/10/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/11/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/12/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/13/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/14/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/15/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/16/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/17/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/18/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/19/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/20/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/21/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/22/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/23/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/24/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/25/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/26/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/27/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/28/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/backer/29/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/backer/29/avatar.svg"></a>
## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/redux-devtools-extension#sponsor)]
<a href="https://opencollective.com/redux-devtools-extension/sponsor/0/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/1/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/2/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/3/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/4/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/5/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/6/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/7/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/8/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/9/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/10/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/11/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/12/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/13/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/14/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/15/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/16/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/17/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/18/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/19/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/20/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/21/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/22/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/23/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/24/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/25/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/26/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/27/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/27/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/28/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/redux-devtools-extension/sponsor/29/website" target="_blank"><img src="https://opencollective.com/redux-devtools-extension/sponsor/29/avatar.svg"></a>
## License
MIT
## Created By
If you like this, follow [@mdiordiev](https://twitter.com/mdiordiev) on twitter.
================================================
FILE: extension/babel.config.json
================================================
{
"presets": [
["@babel/preset-env", { "targets": "defaults" }],
"@babel/preset-react",
"@babel/preset-typescript"
]
}
================================================
FILE: extension/build.mjs
================================================
import * as fs from 'node:fs';
import * as esbuild from 'esbuild';
import pug from 'pug';
const args = process.argv.slice(2);
const prod = !args.includes('--dev');
await esbuild.build({
bundle: true,
logLevel: 'info',
outdir: 'dist',
minify: prod,
sourcemap: !prod,
define: {
'process.env.NODE_ENV': prod ? '"production"' : '"development"',
'process.env.BABEL_ENV': prod ? '"production"' : '"development"',
},
entryPoints: [
{ out: 'background.bundle', in: 'src/background/index.ts' },
{ out: 'options.bundle', in: 'src/options/index.tsx' },
{ out: 'remote.bundle', in: 'src/remote/index.tsx' },
{ out: 'devpanel.bundle', in: 'src/devpanel/index.tsx' },
{ out: 'devtools.bundle', in: 'src/devtools/index.ts' },
{ out: 'content.bundle', in: 'src/contentScript/index.ts' },
{ out: 'page.bundle', in: 'src/pageScript/index.ts' },
],
loader: {
'.woff2': 'file',
},
});
console.log();
console.log('Creating HTML files...');
const htmlFiles = ['devpanel', 'devtools', 'options', 'remote'];
for (const htmlFile of htmlFiles) {
fs.writeFileSync(
`dist/${htmlFile}.html`,
pug.renderFile(`src/${htmlFile}/${htmlFile}.pug`),
);
}
console.log('Copying manifest.json...');
fs.copyFileSync('chrome/manifest.json', 'dist/manifest.json');
console.log('Copying assets...');
fs.cpSync('src/assets', 'dist', { recursive: true });
console.log('Copying dist for each browser...');
fs.cpSync('dist', 'chrome/dist', { recursive: true });
fs.copyFileSync('chrome/manifest.json', 'chrome/dist/manifest.json');
fs.cpSync('dist', 'edge/dist', { recursive: true });
fs.copyFileSync('edge/manifest.json', 'edge/dist/manifest.json');
fs.cpSync('dist', 'firefox/dist', { recursive: true });
fs.copyFileSync('firefox/manifest.json', 'firefox/dist/manifest.json');
================================================
FILE: extension/chrome/manifest.json
================================================
{
"version": "3.2.10",
"name": "Redux DevTools",
"description": "Redux DevTools for debugging application's state changes.",
"homepage_url": "https://github.com/reduxjs/redux-devtools",
"manifest_version": 3,
"action": {
"default_icon": "img/logo/gray.png",
"default_title": "Redux DevTools",
"default_popup": "devpanel.html#popup"
},
"commands": {
"devtools-window": {
"description": "DevTools window"
},
"devtools-remote": {
"description": "Remote DevTools"
},
"_execute_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"
},
"background": {
"service_worker": "background.bundle.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"exclude_globs": ["https://www.google*"],
"js": ["content.bundle.js"],
"run_at": "document_start",
"all_frames": true
},
{
"matches": ["<all_urls>"],
"exclude_globs": ["https://www.google*"],
"js": ["page.bundle.js"],
"run_at": "document_start",
"all_frames": true,
"world": "MAIN"
}
],
"devtools_page": "devtools.html",
"externally_connectable": {
"ids": ["*"]
},
"permissions": ["notifications", "contextMenus", "storage"],
"host_permissions": ["file:///*", "http://*/*", "https://*/*"],
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'; style-src * 'unsafe-inline'; img-src 'self' data:;"
},
"update_url": "https://clients2.google.com/service/update2/crx",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsdJEPwY92xUACA9CcDBDBmbdbp8Ap3cKQ0DJTUuVQvqb4FQAv8RtKY3iUjGvdwuAcSJQIZwHXcP2aNDH3TiFik/NhRK2GRW8X3OZyTdkuDueABGP2KEX8q1WQDgjX/rPIinGYztUrvoICw/UerMPwNW62jwGoVU3YhAGf+15CgX2Y6a4tppnf/+1mPedKPidh0RsM+aJY98rX+r1SPAHPcGzMjocLkqcT75DZBXer8VQN14tOOzRCd6T6oy7qm7eWru8lJwcY66qMQvhk0osqEod2G3nA7aTWpmqPFS66VEiecP9PgZlp8gQdgZ3dFhA62exydlD55JuRhiMIR63yQIDAQAB"
}
================================================
FILE: extension/docs/API/Arguments.md
================================================
# Options
Use with
- `window.__REDUX_DEVTOOLS_EXTENSION__([options])`
- `window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__([options])()`
- `window.__REDUX_DEVTOOLS_EXTENSION__.connect([options])`
- `@redux-devtools/extension` npm package:
```js
import { composeWithDevTools } from '@redux-devtools/extension';
const composeEnhancers = composeWithDevTools(options);
const store = createStore(
reducer,
/* preloadedState, */ composeEnhancers(
applyMiddleware(...middleware),
// other store enhancers if any
),
);
```
The `options` object is optional, and can include any of the following.
### `name`
_string_ - the instance name to be shown on the monitor page. Default value is `document.title`. If not specified and there's no document title, it will consist of `tabId` and `instanceId`.
### `actionCreators`
_array_ or _object_ - action creators functions to be available in the Dispatcher. See [the example](https://github.com/zalmoxisus/redux-devtools-extension/commit/477e69d8649dfcdc9bf84dd45605dab7d9775c03).
### `latency`
_number (in ms)_ - if more than one action is dispatched in the indicated interval, all new actions will be collected and sent at once. It is the joint between performance and speed. When set to `0`, all actions will be sent instantly. Set it to a higher value when experiencing perf issues (also `maxAge` to a lower value). Default is `500 ms`.
### `maxAge`
_number_ (>1) - maximum allowed actions to be stored in the history tree. The oldest actions are removed once maxAge is reached. It's critical for performance. Default is `50`.
### `trace`
_boolean_ or _function_ - if set to `true`, will include stack trace for every dispatched action, so you can see it in trace tab jumping directly to that part of code ([more details](../Features/Trace.md)). You can use a function (with action object as argument) which should return `new Error().stack` string, getting the stack outside of reducers. Default to `false`.
### `traceLimit`
_number_ - maximum stack trace frames to be stored (in case `trace` option was provided as `true`). By default it's `10`. Note that, because extension's calls are excluded, the resulted frames could be 1 less. If `trace` option is a function, `traceLimit` will have no effect, as it's supposed to be handled there.
### `serialize`
_boolean_ or _object_ which contains:
- **options** `object or boolean`:
- `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, primitives, error objects, symbols, maps, sets and functions.
- object, which contains `date`, `regex`, `undefined`, `nan`, `infinity`, `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. Example:
```js
const store = Redux.createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({
serialize: {
options: {
undefined: true,
function: function (fn) {
return fn.toString();
},
},
},
}),
);
```
- **replacer** `function(key, value)` - [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.
Example of usage with [mori data structures](https://github.com/swannodette/mori):
```js
const store = Redux.createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({
serialize: {
replacer: (key, value) =>
value && mori.isMap(value) ? mori.toJs(value) : value,
},
}),
);
```
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):
```js
const store = Redux.createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({
serialize: {
replacer: (key, value) => {
if (Immutable.List.isList(value)) {
// use your custom data type checker
return {
data: value.toArray(), // ImmutableJS custom method to get JS data as array
__serializedType__: 'ImmutableList', // mark you custom data type to show and retrieve back
};
}
},
},
}),
);
```
- **reviver** `function(key, value)` - [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:
```js
const store = Redux.createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({
serialize: {
reviver: (key, value) => {
if (
typeof value === 'object' &&
value !== null &&
'__serializedType__' in value
) {
switch (value.__serializedType__) {
case 'ImmutableList':
return Immutable.List(value.data);
}
}
},
},
}),
);
```
- **immutable** `object` - automatically serialize/deserialize immutablejs via [remotedev-serialize](https://github.com/zalmoxisus/remotedev-serialize). Just pass the Immutable library like so:
```js
import Immutable from 'immutable'; // https://facebook.github.io/immutable-js/
// ...
// Like above, only showing off compose this time. Reminder you might not want this in prod.
const composeEnhancers =
typeof window === 'object' &&
typeof window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ !== 'undefined'
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
serialize: {
immutable: Immutable,
},
})
: compose;
```
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 in addition the references to your classes in `refs`.
- **refs** `array` - ImmutableJS `Record` classes used to make possible restore its instances back when importing, persisting... Example of usage:
```js
import Immutable from 'immutable';
// ...
const ABRecord = Immutable.Record({ a: 1, b: 2 });
const myRecord = new ABRecord({ b: 3 }); // used in the reducers
const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({
serialize: {
immutable: Immutable,
refs: [ABRecord],
},
}),
);
```
Also you can specify alternative values right in the state object (in the initial state of the reducer) by adding `toJSON` function:
In the example bellow it will always send `{ component: '[React]' }`, regardless of the state's `component` value (useful when you don't want to send lots of unnecessary data):
```js
function component(
state = { component: null, toJSON: () => ({ component: '[React]' }) },
action,
) {
switch (action.type) {
case 'ADD_COMPONENT':
return { component: action.component };
default:
return state;
}
}
```
You could also alter the value. For example when state is `{ count: 1 }`, we'll send `{ counter: 10 }` (notice we don't have an arrow function this time to use the object's `this`):
```js
function counter(
state = {
count: 0,
toJSON: function () {
return { conter: this.count * 10 };
},
},
action,
) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
default:
return state;
}
}
```
### `actionSanitizer` / `stateSanitizer`
- **actionSanitizer** (_function_) - function which takes `action` object and id number as arguments, and should return `action` object back. See the example bellow.
- **stateSanitizer** (_function_) - function which takes `state` object and index as arguments, and should return `state` object back.
Example of usage:
```js
const actionSanitizer = (action) =>
action.type === 'FILE_DOWNLOAD_SUCCESS' && action.data
? { ...action, data: '<<LONG_BLOB>>' }
: action;
const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({
actionSanitizer,
stateSanitizer: (state) =>
state.data ? { ...state, data: '<<LONG_BLOB>>' } : state,
}),
);
```
### `actionsDenylist` / `actionsAllowlist`
_string or array of strings as regex_ - actions types to be hidden / shown in the monitors (while passed to the reducers). If `actionsAllowlist` specified, `actionsDenylist` is ignored.
Example:
```js
createStore(
reducer,
remotedev({
sendTo: 'http://localhost:8000',
actionsDenylist: 'SOME_ACTION',
// or actionsDenylist: ['SOME_ACTION', 'SOME_OTHER_ACTION']
// or just actionsDenylist: 'SOME_' to omit both
}),
);
```
### `predicate`
_function_ - called for every action before sending, takes `state` and `action` object, and returns `true` in case it allows sending the current data to the monitor. Use it as a more advanced version of `actionsDenylist`/`actionsAllowlist` parameters.
Example of usage:
```js
const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({
predicate: (state, action) =>
state.dev.logLevel === VERBOSE && !action.forwarded,
}),
);
```
### `shouldRecordChanges`
_boolean_ - if specified as `false`, it will not record the changes till clicking on `Start recording` button. Default is `true`. Available only for Redux enhancer, for others use `autoPause`.
### `pauseActionType`
_string_ - if specified, whenever clicking on `Pause recording` button and there are actions in the history log, will add this action type. If not specified, will commit when paused. Available only for Redux enhancer. Default is `@@PAUSED`.
### `autoPause`
_boolean_ - auto pauses when the extension’s window is not opened, and so has zero impact on your app when not in use. Not available for Redux enhancer (as it already does it but storing the data to be sent). Default is `false`.
### `shouldStartLocked`
_boolean_ - if specified as `true`, it will not allow any non-monitor actions to be dispatched till clicking on `Unlock changes` button. Available only for Redux enhancer. Default is `false`.
### `shouldHotReload`
_boolean_ - if set to `false`, will not recompute the states on hot reloading (or on replacing the reducers). Available only for Redux enhancer. Default to `true`.
### `shouldCatchErrors`
_boolean_ - if specified as `true`, whenever there's an exception in reducers, the monitors will show the error message, and next actions will not be dispatched.
### `features`
If you want to restrict the extension, just specify the features you allow:
```js
const composeEnhancers = composeWithDevTools({
features: {
pause: true, // start/pause recording of dispatched actions
lock: true, // lock/unlock dispatching actions and side effects
persist: true, // persist states on page reloading
export: true, // export history of actions in a file
import: 'custom', // import history of actions from a file
jump: true, // jump back and forth (time travelling)
skip: true, // skip (cancel) actions
reorder: true, // drag and drop actions in the history list
dispatch: true, // dispatch custom actions or action creators
test: true, // generate tests for the selected actions
},
// other options like actionSanitizer, stateSanitizer
});
```
If not specified, all of the features are enabled. When set as an object, only those included as `true` will be allowed.
Note that except `true`/`false`, `import` and `export` can be set as `custom` (which is by default for Redux enhancer), meaning that the importing/exporting occurs on the client side. Otherwise, you'll get/set the data right from the monitor part.
================================================
FILE: extension/docs/API/Methods.md
================================================
## Communicate with the extension directly
> Note this is advanced API, which you usually don't need to use with Redux enhancer.
Use the following methods of `window.__REDUX_DEVTOOLS_EXTENSION__`:
- [connect](#connect)
- [disconnect](#disconnect)
- [send](#send)
- [listen](#listen)
- [open](#open)
- [notifyErrors](#notifyerrors)
<a id="connect"></a>
### connect([options])
##### Arguments
- [`options`] _Object_ - [see the available options](Arguments.md).
##### Returns
_Object_ containing the following methods:
- `subscribe(listener)` - adds a change listener. It will be called any time an action is dispatched from the monitor. Returns a function to unsubscribe the current listener.
- `unsubscribe()` - unsubscribes all listeners.
- `send(action, state)` - sends a new action and state manually to be shown on the monitor. If action is `null` then we suppose we send `liftedState`.
- `init(state)` - sends the initial state to the monitor.
- `error(message)` - sends the error message to be shown in the extension's monitor.
Example of usage:
```js
const devTools = window.__REDUX_DEVTOOLS_EXTENSION__.connect(config);
devTools.subscribe((message) => {
if (message.type === 'DISPATCH' && message.state) {
console.log('DevTools requested to change the state to', message.state);
}
});
devTools.init({ value: 'initial state' });
devTools.send('change state', { value: 'state changed' });
```
See [redux enhancer's example](https://github.com/reduxjs/redux-devtools/blob/main/packages/redux-devtools-extension/src/logOnly.ts), [react example](https://github.com/zalmoxisus/redux-devtools-extension/blob/master/examples/react-counter-messaging/components/Counter.js) and [blog post](https://medium.com/@zalmoxis/redux-devtools-without-redux-or-how-to-have-a-predictable-state-with-any-architecture-61c5f5a7716f) for more details.
### disconnect()
Remove extensions listener and disconnect extensions background script connection. Usually just unsubscribing the listener inside the `connect` is enough.
<a id="send"></a>
### send(action, state, [options, instanceId])
Send a new action and state manually to be shown on the monitor. It's recommended to use [`connect`](connect), unless you want to hook into an already created instance.
##### Arguments
- `action` _String_ (action type) or _Object_ with required `type` key.
- `state` _any_ - usually object to expand.
- [`options`] _Object_ - [see the available options](Arguments.md).
- [`instanceId`] _String_ - instance id for which to include the log. If not specified and not present in the `options` object, will be the first available instance.
<a id="listen"></a>
### listen(onMessage, instanceId)
Listen for messages dispatched for specific `instanceId`. For most cases it's better to use `subcribe` inside the [`connect`](connect).
##### Arguments
- `onMessage` _Function_ to call when there's an action from the monitor.
- `instanceId` _String_ - instance id for which to handle actions.
<a id="open"></a>
### open([position])
Open the extension's window. This should be conditional (usually you don't need to open extension's window automatically).
##### Arguments
- [`position`] _String_ - window position: `left`, `right`, `bottom`. Also can be `panel` to [open it in a Chrome panel](../FAQ.md#how-to-keep-devtools-window-focused-all-the-time-in-a-chrome-panel). Or `remote` to [open remote monitor](../FAQ.md#how-to-get-it-work-with-webworkers-react-native-hybrid-desktop-and-server-side-apps). By default is `left`.
<a id="notifyErrors"></a>
### notifyErrors([onError])
When called, the extension will listen for uncaught exceptions on the page, and, if any, will show native notifications. Optionally, you can provide a function to be called when an exception occurs.
##### Arguments
- [`onError`] _Function_ to call when there's an exceptions.
================================================
FILE: extension/docs/API/README.md
================================================
# API Reference
- [Parameters](Arguments.md)
- [Methods](Methods.md)
================================================
FILE: extension/docs/Architecture.md
================================================
# Architecture Notes
This document exists to keep track of how the different parts of the Redux DevTools interact, since it's easy to forget how it all works together. This is intended for internal purposes and is just a collection of notes to myself.
## Entry Points
### Window
This is the default view that is shown in the Redux DevTools popup, the Chrome DevTools tab (if direct access to the background page is available), and new popup windows that are created. It has direct access to the background page via `chrome.runtime.getBackgroundPage`.
### DevPanel
This is the view that is shown in the Chrome DevTools tab if direct access to the background page is not available.
Initially this was the view that was always used for the Chrome DevTools tab, but when support to directly access the background page from the DevTools tab was added, [the Window View became the preferred view](https://github.com/zalmoxisus/redux-devtools-extension/pull/580).
### Remote
This does not interact with the other parts of the extension at all, it just renders the `App` component from `@redux-devtools/app`.
It can be triggered by hitting the "Remote" button in any of the other views, which calls `chrome.windows.create` and creates a new window.
### DevTools
This is the script that adds the Redux panel in the Chrome DevTools using `chrome.devtools.panels.create`.
It creates a Window View if it has direct access to the background page, otherwise it creates a DevPanel View.
Note that this used to always show the DevPanel View, but [started using the Window View by default](https://github.com/zalmoxisus/redux-devtools-extension/pull/580) once direct access to the background page was added to Chrome DevTools tabs.
### Content Script
Passes messages between the injected page script and the background page.
It listens for messages from the injected page script using `window.addEventListener('message', ...)`. It knows the message is from the injected page script if `message.source` is `'@devtools-page'`. See the Chrome DevTools docs where this approach [is documented](https://developer.chrome.com/docs/extensions/how-to/devtools/extend-devtools#evaluated-scripts-to-devtools).
It creates a connection to the background page using `chrome.runtime.connect` with the name `'tab'` when it receives the first message from the injected page script.
================================================
FILE: extension/docs/Articles.md
================================================
# Articles
- [Improve your development workflow with Redux DevTools Extension](https://medium.com/@zalmoxis/improve-your-development-workflow-with-redux-devtools-extension-f0379227ff83)
- [Using Redux DevTools in production](https://medium.com/@zalmoxis/using-redux-devtools-in-production-4c5b56c5600f)
- [Redux DevTools without Redux](https://medium.com/@zalmoxis/redux-devtools-without-redux-or-how-to-have-a-predictable-state-with-any-architecture-61c5f5a7716f)
================================================
FILE: extension/docs/Credits.md
================================================
# Credits
- Built using [Crossbuilder](https://github.com/zalmoxisus/crossbuilder) boilerplate.
- Includes [Dan Abramov](https://github.com/gaearon)'s [redux-devtools](https://github.com/gaearon/redux-devtools) and the following monitors:
- [Log Monitor](https://github.com/gaearon/redux-devtools-log-monitor)
- [Inspector](https://github.com/alexkuz/redux-devtools-inspector)
- [Dispatch](https://github.com/YoruNoHikage/redux-devtools-dispatch)
- [Slider](https://github.com/calesce/redux-slider-monitor)
- [Chart](https://github.com/romseguy/redux-devtools-chart-monitor)
- [The logo icon](https://github.com/reactjs/redux/issues/151) made by [Keith Yong](https://github.com/keithyong) .
- Examples from [Redux](https://github.com/rackt/redux/tree/master/examples).
================================================
FILE: extension/docs/FAQ.md
================================================
# Redux DevTools Extension FAQ
## Table of Contents
- [How to get it work](#how-to-get-it-work)
- [How to disable/enable it in production](#how-to-disable-it-in-production)
- [How to persist debug sessions across page reloads](#how-to-persist-debug-sessions-across-page-reloads)
- [How to open DevTools programmatically](#how-to-open-devtools-programmatically)
- [How to enable/disable errors notifying](#how-to-enabledisable-errors-notifying)
- [How to get it work with WebWorkers, React Native, hybrid, desktop and server side apps](#how-to-get-it-work-with-webworkers-react-native-hybrid-desktop-and-server-side-apps)
- [Keyboard shortcuts](#keyboard-shortcuts)
#### How to get it work
- Check the extension with [Counter](http://zalmoxisus.github.io/examples/counter/) or [TodoMVC](http://zalmoxisus.github.io/examples/todomvc/) demo.
- Reload the extension on the extensions page (`chrome://extensions/`).
- If something goes wrong, [open an issue](https://github.com/zalmoxisus/redux-devtools-extension/issues) or tweet me: [@mdiordiev](https://twitter.com/mdiordiev).
#### How to disable it in production
Usually you don't have to. See [the article for details on how to include it in production](https://medium.com/@zalmoxis/using-redux-devtools-in-production-4c5b56c5600f).
#### How to persist debug sessions across page reloads
Just click the `Persist` button or add `?debug_session=<session_name>` to the url.
#### How to open DevTools programmatically
```js
window.__REDUX_DEVTOOLS_EXTENSION__.open();
```
Make sure to have it conditionally. Auto opening windows is a bad DX. See the [API](https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Methods.md#open) for details.
#### How to enable/disable errors notifying
Just find `Redux DevTools` on the extensions page (`chrome://extensions/`) and click the `Options` link to customize everything. The errors notifying is disabled by default. If enabled, it works only when the store enhancer is called (in order not to show notifications for any sites you visit). In case you want notifications for a non-redux app, init it explicitly by calling `window.__REDUX_DEVTOOLS_EXTENSION__.notifyErrors()` (probably you'll check if `window.__REDUX_DEVTOOLS_EXTENSION__` exists before calling it).
#### How to get it work with WebWorkers, React Native, hybrid, desktop and server side apps
It is not possible to inject extension's script there and to communicate directly. To solve this, use [Remote Redux DevTools](https://github.com/zalmoxisus/remote-redux-devtools). After including it inside the app, click `Remote` button for remote monitoring.
#### Keyboard shortcuts
To set/change the keyboard shortcuts, click "Keyboard shortcuts" button on the bottom of the extensions page (`chrome://extensions/`). By default only `Cmd` (`Ctrl`) + `Shift` + `E` is available, which will open the extension popup (only when the Redux store is available in the current page).
================================================
FILE: extension/docs/Features/Trace.md
================================================
## Trace actions calls

One of the features of Redux DevTools is to select an action in the history and see the callstack that triggered it. It aims to solve the problem of finding the source of events in the event list.
By default it's disabled as, depending of the use case, generating and serializing stack traces for every action can impact the performance. To enable it, set `trace` option to `true` as in [examples](https://github.com/zalmoxisus/redux-devtools-extension/commit/64717bb9b3534ff616d9db56c2be680627c7b09d). See [the API](../API/Arguments.md#trace) for more details.
For some edge cases where stack trace cannot be obtained with just `Error().stack`, you can pass a function as `trace` with your implementation. It's useful for cases where the stack is broken, like, for example, [when calling `setTimeout`](https://github.com/zalmoxisus/redux-devtools-instrument/blob/e7c05c98e7e9654cb7db92a2f56c6b5f3ff2452b/test/instrument.spec.js#L735-L737). It takes `action` object as argument and should return `stack` string. This way it can be also used to provide stack conditionally only for certain actions.
There's also an optional `traceLimit` parameter, which is `10` by default, to prevent consuming too much memory and serializing large stacks and also allows you to get larger stacks than limited by the browser (it will overpass default limit of `10` imposed by Chrome in `Error.stackTraceLimit`). If `trace` option is a function, `traceLimit` will have no effect, that should be handled there like so: `trace: () => new Error().stack.split('\n').slice(0, limit+1).join('\n')` (`+1` is needed for Chrome where's an extra 1st frame for `Error\n`).
Apart from opening resources in Chrome DevTools, as seen in the demo above, it can open the file (and jump to the line-column) right in your editor. Pretty useful for debugging, and also as an alternative when it's not possible to use openResource (for Firefox or when using the extension from window or for remote debugging). You can click Settings button and enable that, also adding the path to your project root directory to use. It works out of the box for VSCode, Atom, Webstorm/Phpstorm/IntelliJ, Sublime, Emacs, MacVim, Textmate on Mac and Windows. For Linux you can use [`atom-url-handler`](https://github.com/eclemens/atom-url-handler).
================================================
FILE: extension/docs/Feedback.md
================================================
# Feedback wanted
[File an issue](https://github.com/zalmoxisus/redux-devtools-extension/issues) or [submit a PR](https://github.com/zalmoxisus/redux-devtools-extension/pulls) if you have suggestions, rate us and leave a review on [Chrome Store](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd/reviews), post feature requests and bug reports on [Product Pains](https://productpains.com/product/redux-devtools-extension), or ping me on Twitter as [@mdiordiev](https://twitter.com/mdiordiev).
<iframe width="100%" height="400px" scrolling="no" style="border:0" src="https://productpains.com/widget.html?token=fc7887ce-f3f9-105a-e5cb-43b9eeb668d5"></iframe><script type="text/javascript" src="https://productpains.com/js/lib/iframeResizer.min.js"></script>
================================================
FILE: extension/docs/Integrations.md
================================================
# Integrations for js and non-js frameworks
Mostly functional:
- [React](#react)
- [Angular](#angular)
- [Cycle](#cycle)
- [Ember](#ember)
- [Fable](#fable)
- [Freezer](#freezer)
- [Mobx](#mobx)
- [PureScript](#purescript)
- [Reductive](#reductive)
- [Aurelia](#aurelia)
In progress:
- [ClojureScript](#clojurescript)
- [Horizon](#horizon)
- [Python](#python)
- [Swift](#swift)
### [React](https://github.com/facebook/react)
#### Inspect React props
##### [`react-inspect-props`](https://github.com/lucasconstantino/react-inspect-props)
```js
import { compose, withState } from 'recompose';
import { inspectProps } from 'react-inspect-props';
compose(
withState('count', 'setCount', 0),
inspectProps('Counter inspector'),
)(Counter);
```
#### Inspect React states
##### [`remotedev-react-state`](https://github.com/jhen0409/remotedev-react-state)
```js
import connectToDevTools from 'remotedev-react-state'
componentWillMount() {
// Connect to devtools after setup initial state
connectToDevTools(this/*, options */)
}
```
#### Inspect React hooks (useState and useReducer)
##### [`reinspect`](https://github.com/troch/reinspect)
```js
import { useState } from 'reinspect';
export function CounterWithUseState({ id }) {
const [count, setCount] = useState(0, id);
// ...
}
```
### [Mobx](https://github.com/mobxjs/mobx)
#### [`mobx-remotedev`](https://github.com/zalmoxisus/mobx-remotedev)
```js
import remotedev from 'mobx-remotedev';
// or import remotedev from 'mobx-remotedev/lib/dev'
// in case you want to use it in production or don't have process.env.NODE_ENV === 'development'
const appStore = observable({
// ...
});
// Or
class appStore {
// ...
}
export default remotedev(appStore);
```
### [Angular](https://github.com/angular/angular)
#### [ng2-redux](https://github.com/angular-redux/ng2-redux)
```js
import { NgReduxModule, NgRedux, DevToolsExtension } from 'ng2-redux';
@NgModule({
/* ... */
imports: [ /* ... */, NgReduxModule ]
})export class AppModule {
constructor(
private ngRedux: NgRedux,
private devTools: DevToolsExtension) {
let enhancers = [];
// ... add whatever other enhancers you want.
// You probably only want to expose this tool in devMode.
if (__DEVMODE__ && devTools.isEnabled()) {
enhancers = [ ...enhancers, devTools.enhancer() ];
}
this.ngRedux.configureStore(
rootReducer,
initialState,
[],
enhancers);
}
}
```
For Angular 1 see [ng-redux](https://github.com/angular-redux/ng-redux).
#### [Angular @ngrx/store](https://ngrx.io/) + [`@ngrx/store-devtools`](https://ngrx.io/guide/store-devtools)
```js
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
@NgModule({
imports: [
StoreModule.forRoot(rootReducer),
// Instrumentation must be imported after importing StoreModule (config is optional)
StoreDevtoolsModule.instrument({
maxAge: 5,
}),
],
})
export class AppModule {}
```
[`Example of integration`](https://github.com/ngrx/platform/tree/master/projects/example-app/) ([live demo](https://ngrx.github.io/platform/example-app/)).
### [Ember](http://emberjs.com/)
#### [`ember-redux`](https://github.com/ember-redux/ember-redux)
```js
//app/enhancers/index.js
import { compose } from 'redux';
var devtools = window.__REDUX_DEVTOOLS_EXTENSION__
? window.__REDUX_DEVTOOLS_EXTENSION__()
: (f) => f;
export default compose(devtools);
```
### [Cycle](https://github.com/cyclejs/cyclejs)
#### [`@culli/store`](https://github.com/milankinen/culli/tree/master/packages/store)
```js
import { run } from '@cycle/most-run';
import { makeDOMDriver as DOM } from '@cycle/dom';
import Store, { ReduxDevtools } from '@culli/store';
import App, { newId } from './App';
run(App, {
DOM: DOM('#app'),
Store: Store(
ReduxDevtools({
items: [
{ id: newId(), num: 0 },
{ id: newId(), num: 0 },
],
}),
),
});
```
### [Freezer](https://github.com/arqex/freezer)
#### [`freezer-redux-devtools`](https://github.com/arqex/freezer-redux-devtools)
```js
import React, { Component } from 'react';
import { supportChromeExtension } from 'freezer-redux-devtools/freezer-redux-middleware';
import Freezer from 'freezer-js';
// Our state is a freezer object
var State = new Freezer({ hello: 'world' });
// Enable the extension
supportChromeExtension(State);
```
### [Horizon](https://github.com/rethinkdb/horizon)
#### [`horizon-remotedev`](https://github.com/zalmoxisus/horizon-remotedev)
```js
// import hzRemotedev from 'horizon-remotedev';
// or import hzRemotedev from 'horizon-remotedev/lib/dev'
// in case you want to use it in production or don't have process.env.NODE_ENV === 'development'
//Setup Horizon connection
const horizon = Horizon();
// ...
// Specify the horizon instance to monitor
hzRemotedev(horizon('react_messages'));
```
### [Fable](https://github.com/fable-compiler/Fable)
#### [`fable-elmish/debugger`](https://github.com/fable-elmish/debugger)
```fsharp
open Elmish.Debug
Program.mkProgram init update view
|> Program.withDebugger // connect to a devtools monitor via Chrome extension if available
|> Program.run
```
or
```fsharp
open Elmish.Debug
Program.mkProgram init update view
|> Program.withDebuggerAt (Remote("localhost",8000)) // connect to a server running on localhost:8000
|> Program.run
```
### [PureScript](https://github.com/purescript/purescript)
#### [`purescript-react-redux`](https://github.com/ethul/purescript-react-redux)
[`Example of integration`](https://github.com/ethul/purescript-react-redux-example).
### [ClojureScript](https://github.com/clojure/clojurescript)
[`Example of integration`](http://gitlab.xet.ru:9999/publicpr/clojurescript-redux/tree/master#dev-setup)
### [Python](https://www.python.org/)
#### [`pyredux`](https://github.com/peterpeter5/pyredux)
[WIP](https://github.com/zalmoxisus/remotedev-server/issues/34)
### [Swift](https://github.com/apple/swift)
#### [`katanaMonitor`](https://github.com/bolismauro/katanaMonitor-lib-swift) for [`katana-swift`](https://github.com/BendingSpoons/katana-swift)
```swift
import KatanaMonitor
var middleware: [StoreMiddleware] = [
// other middleware
]
#if DEBUG
middleware.append(MonitorMiddleware.create(using: .defaultConfiguration))
#endif
```
### [Reductive](https://github.com/reasonml-community/reductive)
#### [`reductive-dev-tools`](https://github.com/ambientlight/reductive-dev-tools)
```reason
let storeEnhancer =
ReductiveDevTools.(
Connectors.reductiveEnhancer(
Extension.enhancerOptions(~name="MyApp", ()),
)
);
let storeCreator = storeEnhancer @@ Reductive.Store.create;
```
### [Aurelia](http://aurelia.io)
#### [`aurelia-store`](https://aurelia.io/docs/plugins/store)
```ts
import {Aurelia} from 'aurelia-framework';
import {initialState} from './state';
export function configure(aurelia: Aurelia) {
aurelia.use
.standardConfiguration()
.feature('resources');
...
aurelia.use.plugin('aurelia-store', {
initialState,
devToolsOptions: { // optional
... // see https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md
},
});
aurelia.start().then(() => aurelia.setRoot());
}
```
================================================
FILE: extension/docs/README.md
================================================
# Documentation
- [Extension](/README.md)
- [Installation](/README.md#installation)
- [Usage](/README.md#usage)
- [Demo](/README.md#demo)
- [API Reference](/docs/API/README.md)
- [Options (arguments)](/docs/API/Arguments.md)
- [Methods (advanced API)](/docs/API/Methods.md)
- Features
- [Trace actions calls](/docs/Features/Trace.md)
- [Integrations](/docs/Integrations.md)
- [FAQ](/docs/FAQ.md)
- [Troubleshooting](/docs/Troubleshooting.md)
- [Recipes](/docs/Recipes.md)
- [Articles](/docs/Articles.md)
- [Videos](/docs/Videos.md)
- [Credits](/docs/Credits.md)
- [Support us](/README.md#backers)
- [Feedback](/docs/Feedback.md)
- [Change Log](https://github.com/zalmoxisus/redux-devtools-extension/releases)
================================================
FILE: extension/docs/Recipes.md
================================================
# Recipes
### Using in a typescript project
The recommended way is to use [`@redux-devtools/extension` npm package](/README.md#13-use-redux-devtools-extension-package-from-npm), which contains all typescript definitions. Or you can just use `window as any`:
```js
const store = createStore(
rootReducer,
initialState,
(window as any).__REDUX_DEVTOOLS_EXTENSION__ &&
(window as any).__REDUX_DEVTOOLS_EXTENSION__()
);
```
Note that you many need to set `no-any` to false in your `tslint.json` file.
Alternatively you can use type-guard in order to avoid
casting to any.
```typescript
import { createStore, StoreEnhancer } from 'redux';
// ...
type WindowWithDevTools = Window & {
__REDUX_DEVTOOLS_EXTENSION__: () => StoreEnhancer<unknown, {}>;
};
const isReduxDevtoolsExtenstionExist = (
arg: Window | WindowWithDevTools,
): arg is WindowWithDevTools => {
return '__REDUX_DEVTOOLS_EXTENSION__' in arg;
};
// ...
const store = createStore(
rootReducer,
initialState,
isReduxDevtoolsExtenstionExist(window)
? window.__REDUX_DEVTOOLS_EXTENSION__()
: undefined,
);
```
### Export from browser console or from application
```js
store.liftedStore.getState();
```
The extension is not sharing `store` object, so you should take care of that.
### Applying multiple times with different sets of options
We're [not allowing that from instrumentation part](https://github.com/reduxjs/redux-devtools/blob/main/packages/redux-devtools-extension/src/logOnly.ts), which can be used it like so:
```js
import { createStore, compose } from 'redux';
import { devToolsEnhancerLogOnly } from '@redux-devtools/extension';
const store = createStore(
reducer,
/* preloadedState, */ compose(
devToolsEnhancerLogOnly({
instaceID: 1,
name: 'Denylisted',
actionsDenylist: '...',
}),
devToolsEnhancerLogOnly({
instaceID: 2,
name: 'Allowlisted',
actionsAllowlist: '...',
}),
),
);
```
================================================
FILE: extension/docs/Troubleshooting.md
================================================
# Troubleshooting
### I just see empty log or "No store found"
Make sure you [applied the enhancer](https://github.com/zalmoxisus/redux-devtools-extension#2-use-with-redux). Note that passing enhancer as last argument requires redux@>=3.1.0. For older versions apply it like [here](https://github.com/zalmoxisus/redux-devtools-extension/blob/v0.4.2/examples/todomvc/store/configureStore.js) or [here](https://github.com/zalmoxisus/redux-devtools-extension/blob/v0.4.2/examples/counter/store/configureStore.js#L7-L12).
Don't mix the old Redux API with the new one. Pass enhancers and applyMiddleware as last createStore argument.
### Access file url (`file:///`)
If you develop on your local filesystem, make sure to allow Redux DevTools access to `file:///` URLs in the settings of this extension:
<img width="746" alt="extensions" src="https://cloud.githubusercontent.com/assets/7957859/19075220/a0fad99e-8a4c-11e6-8b87-757f2dc179cb.png">
### It shows only the `@@INIT` action or moving back and forth doesn't update the state
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`.
### It doesn't work with other store enhancers
Usually the extension's store enhancer should be last in the compose. When you're using [`window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__`](/README.md#12-advanced-store-setup) or [`composeWithDevTools`](/README.md#13-use-redux-devtools-extension-package-from-npm) helper you don't have to worry about the enhancers order. However some enhancers ([like `redux-batched-subscribe`](https://github.com/zalmoxisus/redux-devtools-extension/issues/261)) also have this requirement to be the last in the compose. In this case you can use it like so:
```js
const store = createStore(
reducer,
preloadedState,
compose(
// applyMiddleware(thunk),
window.__REDUX_DEVTOOLS_EXTENSION__
? window.__REDUX_DEVTOOLS_EXTENSION__()
: (noop) => noop,
batchedSubscribe(/* ... */),
),
);
```
Where `batchedSubscribe` is `redux-batched-subscribe` store enhancer.
### Excessive use of memory and CPU
That is happening due to serialization of some huge objects included in the state or action. The solution is to [sanitize them](/docs/API/Arguments.md#actionsanitizer--statesanitizer).
You can do that by including/omitting data containing specific values, having specific types... In the example below we're omitting parts of action and state objects with the key `data` (in case of action only when was dispatched action `FILE_DOWNLOAD_SUCCESS`):
```js
const actionSanitizer = (action) =>
action.type === 'FILE_DOWNLOAD_SUCCESS' && action.data
? { ...action, data: '<<LONG_BLOB>>' }
: action;
const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({
actionSanitizer,
stateSanitizer: (state) =>
state.data ? { ...state, data: '<<LONG_BLOB>>' } : state,
}),
);
```
There's a more advanced [example on how to implement that for `ui-router`](https://github.com/zalmoxisus/redux-devtools-extension/issues/455#issuecomment-404538385).
The extension is in different process and cannot access the store object directly, unlike vanilla [`redux-devtools`](https://github.com/reduxjs/redux-devtools) which doesn't have this issue. In case sanitizing doesn't fit your use case, you might consider including it directly as a react component, so there will be no need to serialize the data, but it would add some complexity.
### It fails to serialize data when [passing synthetic events](https://github.com/zalmoxisus/redux-devtools-extension/issues/275) or [calling an action directly with `redux-actions`](https://github.com/zalmoxisus/redux-devtools-extension/issues/287)
React synthetic event cannot be reused for performance reason. So, it's not possible to serialize event objects you pass to action payloads.
1. The best solution is **not to pass the whole event object to reducers, but the data you need**:
```diff
function click(event) {
return {
type: ELEMENT_CLICKED,
- event: event
+ value: event.target.value
};
}
```
2. If you cannot pick data from the event object or, for some reason, you need the whole object, use `event.persist()` as suggested in [React Docs](https://facebook.github.io/react/docs/events.html#event-pooling), but it will consume RAM while not needed.
```diff
function increment(event) {
+ event.persist();
return {
type: ELEMENT_CLICKED,
event: event,
};
}
```
3. A workaround, to pass the whole object and at the same time not to persist it, is to override this key of the stringified payload in your action creator. Add a custom `toJSON` function right in the action object (which will be called by the extension before accessing the object):
```diff
function increment(event) {
return {
type: ELEMENT_CLICKED,
event: event,
+ toJSON: function (){
+ return { ...this, event: '[Event]' };
+ }
};
}
```
Note that it shouldn't be arrow function as we want to have access to the function's `this`.
As we don't have access to the original object, skipping and recomputing actions during hot reloading will not work in this case. We recommend to use the first solution whenever possible.
### Symbols or other unserializable data not shown
To get data which cannot be serialized by `JSON.stringify`, set [`serialize` parameter](/docs/API/Arguments.md#serialize):
```js
const store = Redux.createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__({
serialize: true,
}),
);
```
It will handle also date, regex, undefined, error objects, symbols, maps, sets and functions.
================================================
FILE: extension/docs/Videos.md
================================================
# Videos
- [Debugging flux applications in production at React Europe 2016](https://youtu.be/YU8jQ2HtqH4)
- [Hot Reloading with Time Travel at React Europe 2015](https://youtu.be/xsSnOQynTHs)
- [Getting Started with Redux DevTools Extension](https://egghead.io/lessons/javascript-getting-started-with-redux-dev-tools)
- [React & Redux With ExpressJS](https://www.youtube.com/watch?v=6ygcbRpZFR4)
================================================
FILE: extension/edge/manifest.json
================================================
{
"version": "3.2.10",
"name": "Redux DevTools",
"description": "Redux DevTools for debugging application's state changes.",
"homepage_url": "https://github.com/reduxjs/redux-devtools",
"manifest_version": 3,
"action": {
"default_icon": "img/logo/gray.png",
"default_title": "Redux DevTools",
"default_popup": "devpanel.html#popup"
},
"commands": {
"devtools-window": {
"description": "DevTools window"
},
"devtools-remote": {
"description": "Remote DevTools"
},
"_execute_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"
},
"background": {
"service_worker": "background.bundle.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"exclude_globs": ["https://www.google*"],
"js": ["content.bundle.js"],
"run_at": "document_start",
"all_frames": true
},
{
"matches": ["<all_urls>"],
"exclude_globs": ["https://www.google*"],
"js": ["page.bundle.js"],
"run_at": "document_start",
"all_frames": true,
"world": "MAIN"
}
],
"devtools_page": "devtools.html",
"externally_connectable": {
"ids": ["*"]
},
"permissions": ["notifications", "contextMenus", "storage"],
"host_permissions": ["file:///*", "http://*/*", "https://*/*"],
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'; style-src * 'unsafe-inline'; img-src 'self' data:;"
}
}
================================================
FILE: extension/eslint.config.mjs
================================================
import globals from 'globals';
import eslintJs from '../eslint.js.config.base.mjs';
import eslintTsReact from '../eslint.ts.react.config.base.mjs';
import eslintJsReactJest from '../eslint.js.react.jest.config.base.mjs';
export default [
...eslintJs,
...eslintTsReact(import.meta.dirname),
...eslintJsReactJest,
{
ignores: [
'chrome',
'dist',
'edge',
'examples',
'firefox',
'jest.config.ts',
'test/electron/fixture/dist',
],
},
{
files: ['build.mjs'],
languageOptions: {
globals: {
...globals.nodeBuiltin,
},
},
},
{
files: ['test/**/*.js', 'test/**/*.jsx'],
languageOptions: {
globals: {
...globals.browser,
...globals.node,
EUI: true,
},
},
},
];
================================================
FILE: extension/firefox/manifest.json
================================================
{
"version": "3.2.10",
"name": "Redux DevTools",
"manifest_version": 3,
"description": "Redux Developer Tools for debugging application state changes.",
"homepage_url": "https://github.com/reduxjs/redux-devtools",
"browser_specific_settings": {
"gecko": {
"id": "extension@redux.devtools"
}
},
"action": {
"default_icon": "img/logo/38x38.png",
"default_title": "Redux DevTools",
"default_popup": "devpanel.html#popup"
},
"commands": {
"devtools-window": {
"description": "DevTools window"
},
"devtools-remote": {
"description": "Remote DevTools"
}
},
"icons": {
"16": "img/logo/16x16.png",
"48": "img/logo/48x48.png",
"128": "img/logo/128x128.png"
},
"options_ui": {
"page": "options.html"
},
"background": {
"scripts": ["background.bundle.js"]
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.bundle.js"],
"run_at": "document_start",
"all_frames": true
},
{
"matches": ["<all_urls>"],
"js": ["page.bundle.js"],
"run_at": "document_start",
"all_frames": true,
"world": "MAIN"
}
],
"devtools_page": "devtools.html",
"permissions": ["notifications", "contextMenus", "tabs", "storage"],
"host_permissions": ["file:///*", "http://*/*", "https://*/*"],
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'; img-src 'self' data:;"
}
}
================================================
FILE: extension/jest.config.ts
================================================
import { createJsWithTsEsmPreset, type JestConfigWithTsJest } from 'ts-jest';
const presetConfig = createJsWithTsEsmPreset({
tsconfig: 'tsconfig.json',
});
const jestConfig: JestConfigWithTsJest = {
...presetConfig,
setupFilesAfterEnv: ['<rootDir>/test/setup.js'],
testPathIgnorePatterns: ['<rootDir>/examples'],
testEnvironment: 'jsdom',
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
'\\.css$': '<rootDir>/test/__mocks__/styleMock.js',
},
};
export default jestConfig;
================================================
FILE: extension/package.json
================================================
{
"private": true,
"name": "remotedev-redux-devtools-extension",
"version": "3.2.12",
"description": "Redux Developer Tools for debugging application state changes.",
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/extension",
"license": "MIT",
"author": "Mihail Diordiev <zalmoxisus@gmail.com> (https://github.com/zalmoxisus)",
"type": "module",
"repository": {
"type": "git",
"url": "https://github.com/reduxjs/redux-devtools.git"
},
"scripts": {
"build": "pnpm run build:extension && pnpm run type-check",
"build:extension": "node build.mjs",
"clean": "rimraf dist && rimraf chrome/dist && rimraf edge/dist && rimraf firefox/dist",
"test:app": "cross-env BABEL_ENV=test node --experimental-vm-modules node_modules/jest/bin/jest.js test/app",
"test:chrome": "cross-env SE_FORCE_BROWSER_DOWNLOAD=true node --experimental-vm-modules node_modules/jest/bin/jest.js test/chrome",
"build:test:electron:fixture": "webpack --config test/electron/fixture/webpack.config.js",
"test:electron": "pnpm run build:test:electron:fixture && node --experimental-vm-modules node_modules/jest/bin/jest.js test/electron",
"test": "pnpm run test:app && pnpm run test:chrome && pnpm run test:electron",
"lint": "eslint .",
"type-check": "tsc --noEmit"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@redux-devtools/app": "workspace:^",
"@redux-devtools/core": "workspace:^",
"@redux-devtools/instrument": "workspace:^",
"@redux-devtools/serialize": "workspace:^",
"@redux-devtools/slider-monitor": "workspace:^",
"@redux-devtools/ui": "workspace:^",
"@redux-devtools/utils": "workspace:^",
"@reduxjs/toolkit": "^2.11.2",
"@types/jsan": "^3.1.5",
"jsan": "^3.1.14",
"localforage": "^1.10.0",
"lodash-es": "^4.17.23",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-icons": "^5.6.0",
"react-is": "^19.2.4",
"react-json-tree": "workspace:^",
"react-redux": "^9.2.0",
"redux": "^5.0.1",
"redux-persist": "^6.0.0"
},
"devDependencies": {
"@babel/core": "^7.29.0",
"@babel/preset-env": "^7.29.0",
"@babel/preset-react": "^7.28.5",
"@babel/preset-typescript": "^7.28.5",
"@babel/register": "^7.28.6",
"@jest/globals": "^30.3.0",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@types/chrome": "^0.1.37",
"@types/lodash-es": "^4.17.12",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"chromedriver": "^146.0.3",
"cross-env": "^10.1.0",
"electron": "^41.0.2",
"esbuild": "^0.27.4",
"globals": "^17.4.0",
"immutable": "^5.1.5",
"jest": "^30.3.0",
"jest-environment-jsdom": "^30.3.0",
"pug": "^3.0.4",
"rimraf": "^6.1.3",
"selenium-webdriver": "^4.41.0",
"sinon-chrome": "^3.0.1",
"ts-jest": "^29.4.6",
"typescript": "~5.9.3",
"webpack": "^5.105.4",
"webpack-cli": "^7.0.0"
}
}
================================================
FILE: extension/src/app/Actions.tsx
================================================
import React, { Component } from 'react';
import { connect, ResolveThunks } from 'react-redux';
import { Button, Container, Divider, Toolbar } from '@redux-devtools/ui';
import {
DevTools,
Dispatcher,
DispatcherButton,
ExportButton,
getActiveInstance,
getReport,
ImportButton,
liftedDispatch,
MonitorSelector,
PrintButton,
SliderButton,
SliderMonitor,
StoreState,
TopButtons,
} from '@redux-devtools/app';
import { GoBroadcast } from 'react-icons/go';
import { MdOutlineWindow } from 'react-icons/md';
import type { Position } from '../pageScript/api/openWindow.js';
import type { SingleMessage } from '../background/store/apiMiddleware.js';
type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>;
interface OwnProps {
readonly position: string;
}
type Props = StateProps & DispatchProps & OwnProps;
const isElectron = navigator.userAgent.includes('Electron');
async function sendMessage(message: SingleMessage) {
await chrome.runtime.sendMessage(message);
}
class Actions extends Component<Props> {
openWindow = async (position: Position) => {
await sendMessage({ type: 'OPEN', position });
};
openOptionsPage = async () => {
if (navigator.userAgent.includes('Firefox')) {
await sendMessage({ type: 'OPEN_OPTIONS' });
} else {
await chrome.runtime.openOptionsPage();
}
};
render() {
const {
monitor,
dispatcherIsOpen,
sliderIsOpen,
options,
liftedState,
liftedDispatch,
position,
stateTreeSettings,
} = this.props;
const { features } = options;
return (
<Container>
<TopButtons
dispatch={liftedDispatch}
liftedState={liftedState}
options={options}
/>
<DevTools
monitor={monitor}
liftedState={liftedState}
monitorState={this.props.monitorState}
dispatch={liftedDispatch}
features={options.features}
stateTreeSettings={stateTreeSettings}
/>
{sliderIsOpen && options.connectionId && options.features.jump && (
<SliderMonitor liftedState={liftedState} dispatch={liftedDispatch} />
)}
{dispatcherIsOpen &&
options.connectionId &&
options.features.dispatch && <Dispatcher options={options} />}
<Toolbar borderPosition="top">
{features.export && <ExportButton />}
{features.import && <ImportButton />}
{position &&
(position !== '#popup' ||
navigator.userAgent.includes('Firefox')) && <PrintButton />}
<Divider />
<MonitorSelector />
<Divider />
{features.jump && <SliderButton isOpen={this.props.sliderIsOpen} />}
{features.dispatch && (
<DispatcherButton dispatcherIsOpen={this.props.dispatcherIsOpen} />
)}
<Divider />
{!isElectron && (
<Button
onClick={async () => {
await this.openWindow('window');
}}
>
<MdOutlineWindow />
</Button>
)}
{!isElectron && (
<Button
onClick={async () => {
await this.openWindow('remote');
}}
>
<GoBroadcast />
</Button>
)}
</Toolbar>
</Container>
);
}
}
const mapStateToProps = (state: StoreState) => {
const instances = state.instances;
const id = getActiveInstance(instances);
return {
liftedState: instances.states[id],
monitorState: state.monitor.monitorState,
options: instances.options[id],
monitor: state.monitor.selected,
dispatcherIsOpen: state.monitor.dispatcherIsOpen,
sliderIsOpen: state.monitor.sliderIsOpen,
reports: state.reports.data,
stateTreeSettings: state.stateTreeSettings,
};
};
const actionCreators = {
liftedDispatch,
getReport,
};
export default connect(mapStateToProps, actionCreators)(Actions);
================================================
FILE: extension/src/app/App.tsx
================================================
import React, { Component } from 'react';
import { connect, ResolveThunks } from 'react-redux';
import { Container, Notification } from '@redux-devtools/ui';
import {
clearNotification,
getActiveInstance,
Header,
Settings,
StoreState,
} from '@redux-devtools/app';
import Actions from './Actions.js';
type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>;
interface OwnProps {
readonly position: string;
}
type Props = StateProps & DispatchProps & OwnProps;
class App extends Component<Props> {
render() {
const { position, options, section, theme, notification } = this.props;
if (!position && (!options || !options.features)) {
return (
<div style={{ padding: '20px', width: '100%', textAlign: 'center' }}>
No store found. Make sure to follow{' '}
<a
href="https://github.com/zalmoxisus/redux-devtools-extension#usage"
target="_blank"
rel="noreferrer"
>
the instructions
</a>
.
</div>
);
}
let body;
switch (section) {
case 'Settings':
body = <Settings />;
break;
default:
body = <Actions position={position} />;
}
return (
<Container themeData={theme}>
<Header section={section} />
{body}
{notification && (
<Notification
type={notification.type}
onClose={this.props.clearNotification}
>
{notification.message}
</Notification>
)}
</Container>
);
}
}
function mapStateToProps(state: StoreState) {
const instances = state.instances;
const id = getActiveInstance(instances);
return {
options: instances.options[id],
section: state.section,
theme: state.theme,
notification: state.notification,
};
}
const actionCreators = {
clearNotification,
};
export default connect(mapStateToProps, actionCreators)(App);
================================================
FILE: extension/src/background/contextMenus.ts
================================================
import openDevToolsWindow, { DevToolsPosition } from './openWindow.js';
export function createMenu() {
const menus = [
{ id: 'devtools-window', title: 'Open in a window' },
{ id: 'devtools-remote', title: 'Open Remote DevTools' },
];
const shortcuts: { [commandName: string]: string | undefined } = {};
chrome.commands.getAll((commands) => {
for (const { name, shortcut } of commands) {
shortcuts[name!] = shortcut;
}
for (const { id, title } of menus) {
chrome.contextMenus.create({
id: id,
title: title + (shortcuts[id] ? ' (' + shortcuts[id] + ')' : ''),
contexts: ['all'],
});
}
});
}
export async function removeMenu() {
await chrome.contextMenus.removeAll();
}
chrome.contextMenus.onClicked.addListener(({ menuItemId }) => {
openDevToolsWindow(menuItemId as DevToolsPosition);
});
================================================
FILE: extension/src/background/index.ts
================================================
import '../chromeApiMock.js';
import configureStore from './store/backgroundStore.js';
import openDevToolsWindow, { DevToolsPosition } from './openWindow.js';
import { createMenu, removeMenu } from './contextMenus.js';
import { getOptions } from '../options/syncOptions.js';
// Expose the extension's store globally to access it from the windows
// via chrome.runtime.getBackgroundPage
export const store = configureStore();
// Listen for keyboard shortcuts
chrome.commands.onCommand.addListener((shortcut) => {
openDevToolsWindow(shortcut as DevToolsPosition);
});
// Disable the action by default and create the context menu when installed
chrome.runtime.onInstalled.addListener(() => {
void chrome.action.disable();
getOptions((option) => {
if (option.showContextMenus) createMenu();
});
});
// Create or Remove context menu when config changed
chrome.storage.onChanged.addListener((changes) => {
if (changes.showContextMenus) {
if (changes.showContextMenus.newValue) createMenu();
else void removeMenu();
}
});
// https://developer.chrome.com/docs/extensions/develop/migrate/to-service-workers#keep_a_service_worker_alive_continuously
setInterval(
() =>
void chrome.storage.local.set({ 'last-heartbeat': new Date().getTime() }),
20000,
);
================================================
FILE: extension/src/background/logging.ts
================================================
import { LIFTED_ACTION } from '@redux-devtools/app';
import { store } from './index.js';
export function getReport(
reportId: string,
tabId: string | number,
instanceId: number,
) {
chrome.storage.local.get<{
's:hostname': string | undefined;
's:port': string | undefined;
's:secure': string | undefined;
}>(['s:hostname', 's:port', 's:secure'], (options) => {
if (!options['s:hostname'] || !options['s:port']) return;
const url = `${options['s:secure'] ? 'https' : 'http'}://${
options['s:hostname']
}:${options['s:port']}`;
fetch(url, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({ op: 'get', id: reportId }),
})
.then((response) => {
return response.json();
})
.then((json) => {
const { payload, preloadedState } = json;
if (!payload) return;
store.dispatch({
type: LIFTED_ACTION,
message: 'IMPORT',
state: JSON.stringify({ payload, preloadedState }),
id: tabId,
instanceId: `${tabId}/${instanceId}`,
});
})
.catch(function (err) {
/* eslint-disable no-console */
console.warn(err);
/* eslint-enable no-console */
});
});
}
================================================
FILE: extension/src/background/openWindow.ts
================================================
export type DevToolsPosition = 'devtools-window' | 'devtools-remote';
const windows: { [K in DevToolsPosition]?: number } = {};
export default function openDevToolsWindow(position: DevToolsPosition) {
if (!windows[position]) {
createWindow(position);
} else {
chrome.windows.update(windows[position], { focused: true }, () => {
if (chrome.runtime.lastError) createWindow(position);
});
}
}
function createWindow(position: DevToolsPosition) {
const url = chrome.runtime.getURL(getPath(position));
chrome.windows.create({ type: 'popup', url }, (win) => {
windows[position] = win!.id;
if (navigator.userAgent.includes('Firefox')) {
void chrome.windows.update(win!.id!, { focused: true });
}
});
}
function getPath(position: DevToolsPosition) {
switch (position) {
case 'devtools-window':
return 'devpanel.html';
case 'devtools-remote':
return 'remote.html';
default:
throw new Error('Unrecognized position');
}
}
================================================
FILE: extension/src/background/store/apiMiddleware.ts
================================================
import {
CustomAction,
DispatchAction as AppDispatchAction,
LibConfig,
LIFTED_ACTION,
nonReduxDispatch,
REMOVE_INSTANCE,
SET_PERSIST,
SetPersistAction,
stringifyJSON,
TOGGLE_PERSIST,
UPDATE_STATE,
} from '@redux-devtools/app';
import type { Options, OptionsMessage } from '../../options/syncOptions.js';
import openDevToolsWindow, { DevToolsPosition } from '../openWindow.js';
import { getReport } from '../logging.js';
import { Action, Dispatch, Middleware } from 'redux';
import type {
ContentScriptToBackgroundMessage,
SplitMessage,
} from '../../contentScript/index.js';
import type {
ErrorMessage,
PageScriptToContentScriptMessageForwardedToMonitors,
PageScriptToContentScriptMessageWithoutDisconnectOrInitInstance,
} from '../../pageScript/api/index.js';
import { LiftedState } from '@redux-devtools/instrument';
import type {
BackgroundAction,
LiftedActionAction,
} from './backgroundStore.js';
import type { Position } from '../../pageScript/api/openWindow.js';
import type { BackgroundState } from './backgroundReducer.js';
import { store } from '../index.js';
interface TabMessageBase {
readonly type: string;
readonly state?: string | undefined;
readonly id?: string;
}
interface StartAction extends TabMessageBase {
readonly type: 'START';
readonly state?: never;
readonly id?: never;
}
interface StopAction extends TabMessageBase {
readonly type: 'STOP';
readonly state?: never;
readonly id?: never;
}
interface OptionsAction {
readonly type: 'OPTIONS';
readonly options: Options;
}
interface DispatchAction extends TabMessageBase {
readonly type: 'DISPATCH';
readonly action: AppDispatchAction;
readonly state: string | undefined;
readonly id: string;
}
interface ImportAction extends TabMessageBase {
readonly type: 'IMPORT';
readonly action: undefined;
readonly state: string | undefined;
readonly id: string;
}
interface ActionAction extends TabMessageBase {
readonly type: 'ACTION';
readonly action: string | CustomAction;
readonly state: string | undefined;
readonly id: string;
}
interface ExportAction extends TabMessageBase {
readonly type: 'EXPORT';
readonly action: undefined;
readonly state: string | undefined;
readonly id: string;
}
export interface NAAction {
readonly type: 'NA';
readonly id: string | number;
}
interface InitMessage<S, A extends Action<string>> {
readonly type: 'INIT';
readonly payload: string;
instanceId: string;
readonly source: '@devtools-page';
action?: string;
name?: string | undefined;
liftedState?: LiftedState<S, A, unknown>;
libConfig?: LibConfig;
}
interface LiftedMessage {
type: 'LIFTED';
liftedState: { isPaused: boolean | undefined };
instanceId: number;
source: '@devtools-page';
}
interface SerializedPartialLiftedState {
readonly stagedActionIds: readonly number[];
readonly currentStateIndex: number;
readonly nextActionId: number;
}
interface SerializedPartialStateMessage {
readonly type: 'PARTIAL_STATE';
readonly payload: SerializedPartialLiftedState;
readonly source: '@devtools-page';
instanceId: number;
readonly maxAge: number;
readonly actionsById: string;
readonly computedStates: string;
readonly committedState: boolean;
}
interface SerializedExportMessage {
readonly type: 'EXPORT';
readonly payload: string;
readonly committedState: string | undefined;
readonly source: '@devtools-page';
instanceId: number;
}
interface SerializedActionMessage {
readonly type: 'ACTION';
readonly payload: string;
readonly source: '@devtools-page';
instanceId: number;
readonly action: string;
readonly maxAge: number;
readonly nextActionId: number;
}
interface SerializedStateMessage<S, A extends Action<string>> {
readonly type: 'STATE';
readonly payload: Omit<
LiftedState<S, A, unknown>,
'actionsById' | 'computedStates' | 'committedState'
>;
readonly source: '@devtools-page';
instanceId: string;
readonly libConfig?: LibConfig;
readonly actionsById: string;
readonly computedStates: string;
readonly committedState: boolean;
}
export type UpdateStateRequest<S, A extends Action<string>> =
| InitMessage<S, A>
| LiftedMessage
| SerializedPartialStateMessage
| SerializedExportMessage
| SerializedActionMessage
| SerializedStateMessage<S, A>;
interface UpdateStateAction<S, A extends Action<string>> {
readonly type: typeof UPDATE_STATE;
request: UpdateStateRequest<S, A>;
readonly id: string | number;
}
type SplitUpdateStateRequestStart<S, A extends Action<string>> = {
split: 'start';
} & Partial<UpdateStateRequest<S, A>>;
interface SplitUpdateStateRequestChunk {
readonly split: 'chunk';
readonly chunk: [string, string];
}
interface SplitUpdateStateRequestEnd {
readonly split: 'end';
}
export type SplitUpdateStateRequest<S, A extends Action<string>> =
| SplitUpdateStateRequestStart<S, A>
| SplitUpdateStateRequestChunk
| SplitUpdateStateRequestEnd;
interface SplitUpdateStateAction<S, A extends Action<string>> {
readonly type: typeof UPDATE_STATE;
request: SplitUpdateStateRequest<S, A>;
readonly id: string | number;
}
export type TabMessage =
| StartAction
| StopAction
| OptionsAction
| DispatchAction
| ImportAction
| ActionAction
| ExportAction;
export type PanelMessageWithoutNA<S, A extends Action<string>> =
| ErrorMessage
| UpdateStateAction<S, A>
| SetPersistAction;
export type PanelMessage<S, A extends Action<string>> =
| PanelMessageWithoutNA<S, A>
| NAAction;
export type PanelMessageWithSplitAction<S, A extends Action<string>> =
| PanelMessage<S, A>
| SplitUpdateStateAction<S, A>;
type TabPort = Omit<chrome.runtime.Port, 'postMessage'> & {
postMessage: (message: TabMessage) => void;
};
type PanelPort = Omit<chrome.runtime.Port, 'postMessage'> & {
postMessage: <S, A extends Action<string>>(
message: PanelMessageWithSplitAction<S, A>,
) => void;
};
export const CONNECTED = 'socket/CONNECTED';
export const DISCONNECTED = 'socket/DISCONNECTED';
const connections: {
readonly tab: { [K in number | string]: TabPort };
readonly panel: { [K in number | string]: PanelPort };
} = {
tab: {},
panel: {},
};
const chunks: {
[instanceId: string]: PageScriptToContentScriptMessageForwardedToMonitors<
unknown,
Action<string>
>;
} = {};
let monitors = 0;
const getId = (sender: chrome.runtime.MessageSender, name?: string) =>
sender.tab ? sender.tab.id! : name || sender.id!;
type MonitorAction<S, A extends Action<string>> =
| NAAction
| ErrorMessage
| UpdateStateAction<S, A>
| SetPersistAction;
// Chrome message limit is 64 MB, but we're using 32 MB to include other object's parts
const maxChromeMsgSize = 32 * 1024 * 1024;
function toMonitors<S, A extends Action<string>>(action: MonitorAction<S, A>) {
console.log(`Message to monitors: ${action.type}`);
for (const port of Object.values(connections.panel)) {
try {
port.postMessage(action);
} catch (err) {
if (
action.type !== UPDATE_STATE ||
err == null ||
(err as Error).message !==
'Message length exceeded maximum allowed length.'
) {
throw err;
}
const splitMessageStart: SplitUpdateStateRequestStart<S, A> = {
split: 'start',
};
const toSplit: [string, string][] = [];
let size = 0;
for (const [key, value] of Object.entries(
action.request as unknown as Record<string, unknown>,
)) {
if (typeof value === 'string') {
size += value.length;
if (size > maxChromeMsgSize) {
toSplit.push([key, value]);
continue;
}
}
(splitMessageStart as any)[key as keyof typeof splitMessageStart] =
value;
}
port.postMessage({ ...action, request: splitMessageStart });
for (let i = 0; i < toSplit.length; i++) {
for (let j = 0; j < toSplit[i][1].length; j += maxChromeMsgSize) {
port.postMessage({
...action,
request: {
split: 'chunk',
chunk: [
toSplit[i][0],
toSplit[i][1].substring(j, j + maxChromeMsgSize),
],
},
});
}
}
port.postMessage({ ...action, request: { split: 'end' } });
}
}
}
interface ImportMessage {
readonly message: 'IMPORT';
readonly id: string | number;
readonly instanceId: string;
readonly state: string;
readonly action?: never;
}
type ToContentScriptMessage = ImportMessage | LiftedActionAction;
function toContentScript(messageBody: ToContentScriptMessage) {
console.log(`Message to tab ${messageBody.id}: ${messageBody.message}`);
if (messageBody.message === 'DISPATCH') {
const { message, action, id, instanceId, state } = messageBody;
connections.tab[id!].postMessage({
type: message,
action,
state: nonReduxDispatch(store, message, instanceId, action, state),
id: instanceId.toString().replace(/^[^/]+\//, ''),
});
} else if (messageBody.message === 'IMPORT') {
const { message, action, id, instanceId, state } = messageBody;
connections.tab[id!].postMessage({
type: message,
action,
state: nonReduxDispatch(
store,
message,
instanceId,
action as unknown as AppDispatchAction,
state,
),
id: instanceId.toString().replace(/^[^/]+\//, ''),
});
} else if (messageBody.message === 'ACTION') {
const { message, action, id, instanceId, state } = messageBody;
connections.tab[id!].postMessage({
type: message,
action,
state: nonReduxDispatch(
store,
message,
instanceId,
action as unknown as AppDispatchAction,
state,
),
id: instanceId.toString().replace(/^[^/]+\//, ''),
});
} else if (messageBody.message === 'EXPORT') {
const { message, action, id, instanceId, state } = messageBody;
connections.tab[id!].postMessage({
type: message,
action,
state: nonReduxDispatch(
store,
message,
instanceId,
action as unknown as AppDispatchAction,
state,
),
id: instanceId.toString().replace(/^[^/]+\//, ''),
});
} else {
const { message, action, id, instanceId, state } = messageBody;
connections.tab[id].postMessage({
type: message,
action,
state: nonReduxDispatch(
store,
message,
instanceId,
action as AppDispatchAction,
state,
),
id: (instanceId as number).toString().replace(/^[^/]+\//, ''),
});
}
}
function toAllTabs(msg: TabMessage) {
console.log(`Message to all tabs: ${msg.type}`);
for (const tabPort of Object.values(connections.tab)) {
tabPort.postMessage(msg);
}
}
function getReducerError() {
const instancesState = store.getState().instances;
const payload = instancesState.states[instancesState.current];
const computedState = payload.computedStates[payload.currentStateIndex];
if (!computedState) return false;
return computedState.error;
}
function togglePersist() {
const state = store.getState();
if (state.instances.persisted) {
for (const id of Object.keys(state.instances.connections)) {
if (connections.tab[id]) return;
store.dispatch({ type: REMOVE_INSTANCE, id });
toMonitors({ type: 'NA', id });
}
}
}
interface OpenMessage {
readonly type: 'OPEN';
readonly position: Position;
}
interface OpenOptionsMessage {
readonly type: 'OPEN_OPTIONS';
}
export type SingleMessage = OpenMessage | OpenOptionsMessage | OptionsMessage;
type BackgroundStoreMessage<S, A extends Action<string>> =
| PageScriptToContentScriptMessageWithoutDisconnectOrInitInstance<S, A>
| SplitMessage
| SingleMessage;
// Receive messages from content scripts
function messaging<S, A extends Action<string>>(
request: BackgroundStoreMessage<S, A>,
sender: chrome.runtime.MessageSender,
) {
let tabId = getId(sender);
console.log(`Message from tab ${tabId}: ${request.type ?? request.split}`);
if (!tabId) return;
if (sender.frameId) tabId = `${tabId}-${sender.frameId}`;
if (request.type === 'STOP') {
if (!Object.keys(store.getState().instances.connections).length) {
store.dispatch({ type: DISCONNECTED });
}
return;
}
if (request.type === 'OPEN_OPTIONS') {
void chrome.runtime.openOptionsPage();
return;
}
if (request.type === 'OPTIONS') {
toAllTabs({ type: 'OPTIONS', options: request.options });
return;
}
if (request.type === 'GET_REPORT') {
getReport(request.payload, tabId, request.instanceId);
return;
}
if (request.type === 'OPEN') {
let position: DevToolsPosition = 'devtools-window';
if (['remote', 'window'].includes(request.position)) {
position = ('devtools-' + request.position) as DevToolsPosition;
}
openDevToolsWindow(position);
return;
}
if (request.type === 'ERROR') {
if (request.payload) {
toMonitors(request);
return;
}
if (!request.message) return;
const reducerError = getReducerError();
void chrome.notifications.create('app-error', {
type: 'basic',
title: reducerError
? 'An error occurred in the reducer'
: 'An error occurred in the app',
message: reducerError || request.message,
iconUrl: 'img/logo/48x48.png',
isClickable: !!reducerError,
});
return;
}
const action: UpdateStateAction<S, A> = {
type: UPDATE_STATE,
request,
id: tabId,
} as UpdateStateAction<S, A>;
const instanceId = `${tabId}/${request.instanceId}`;
if ('split' in request) {
if (request.split === 'start') {
chunks[instanceId] = request as any;
return;
}
if (request.split === 'chunk') {
(chunks[instanceId] as any)[request.chunk[0]] =
((chunks[instanceId] as any)[request.chunk[0]] || '') +
request.chunk[1];
return;
}
action.request = chunks[instanceId] as any;
delete chunks[instanceId];
}
if (request.instanceId) {
action.request.instanceId = instanceId;
}
store.dispatch(action);
toMonitors(action);
}
function disconnect(
type: 'tab' | 'panel',
id: number | string,
listener: (message: any, port: chrome.runtime.Port) => void,
) {
return function disconnectListener() {
console.log(`Disconnected from ${type} ${id}`);
const p = connections[type][id];
if (listener && p) p.onMessage.removeListener(listener);
if (p) p.onDisconnect.removeListener(disconnectListener);
delete connections[type][id];
if (type === 'tab') {
if (!store.getState().instances.persisted) {
store.dispatch({ type: REMOVE_INSTANCE, id });
toMonitors({ type: 'NA', id });
}
} else {
monitors--;
if (monitors === 0) toAllTabs({ type: 'STOP' });
}
};
}
function onConnect<S, A extends Action<string>>(port: chrome.runtime.Port) {
let id: number | string;
let listener;
store.dispatch({ type: CONNECTED, port });
if (port.name === 'tab') {
id = getId(port.sender!);
console.log(`Connected to tab ${id}`);
if (port.sender!.frameId) id = `${id}-${port.sender!.frameId}`;
connections.tab[id] = port;
listener = (msg: ContentScriptToBackgroundMessage<S, A>) => {
console.log(`Message from tab ${id}: ${msg.name}`);
if (msg.name === 'INIT_INSTANCE') {
if (typeof id === 'number') {
void chrome.action.enable(id);
void chrome.action.setIcon({ tabId: id, path: 'img/logo/38x38.png' });
}
if (monitors > 0) port.postMessage({ type: 'START' });
const state = store.getState();
if (state.instances.persisted) {
const instanceId = `${id}/${msg.instanceId}`;
const persistedState = state.instances.states[instanceId];
if (!persistedState) return;
toContentScript({
message: 'IMPORT',
id,
instanceId,
state: stringifyJSON(
persistedState,
state.instances.options[instanceId].serialize,
),
});
}
return;
}
if (msg.name === 'RELAY') {
messaging(msg.message, port.sender!);
}
};
port.onMessage.addListener(listener);
port.onDisconnect.addListener(disconnect('tab', id, listener));
} else if (port.name && port.name.indexOf('monitor') === 0) {
// devpanel
id = getId(port.sender!, port.name);
console.log(`Connected to monitor ${id}`);
connections.panel[id] = port;
monitors++;
toAllTabs({ type: 'START' });
listener = (msg: BackgroundAction) => {
console.log(`Message from monitor ${id}: ${msg.type}`);
store.dispatch(msg);
};
port.onMessage.addListener(listener);
port.onDisconnect.addListener(disconnect('panel', id, listener));
const { current } = store.getState().instances;
if (current !== 'default') {
const connectionId = Object.entries(
store.getState().instances.connections,
).find(([, instanceIds]) => instanceIds.includes(current))?.[0];
const options = store.getState().instances.options[current];
const state = store.getState().instances.states[current];
const { actionsById, computedStates, committedState, ...rest } = state;
toMonitors({
type: UPDATE_STATE,
request: {
type: 'STATE',
payload: rest as Omit<
LiftedState<S, A, unknown>,
'actionsById' | 'computedStates' | 'committedState'
>,
source: '@devtools-page',
instanceId:
typeof current === 'number' ? current.toString() : current,
actionsById: stringifyJSON(actionsById, options.serialize),
computedStates: stringifyJSON(computedStates, options.serialize),
committedState: typeof committedState !== 'undefined',
},
id: connectionId ?? current,
});
}
}
}
chrome.runtime.onConnect.addListener(onConnect);
chrome.runtime.onConnectExternal.addListener(onConnect);
chrome.runtime.onMessage.addListener(messaging);
chrome.runtime.onMessageExternal.addListener(messaging);
chrome.notifications.onClicked.addListener((id) => {
void chrome.notifications.clear(id);
openDevToolsWindow('devtools-window');
});
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
const api: Middleware<{}, BackgroundState, Dispatch<BackgroundAction>> =
(store) => (next) => (untypedAction) => {
const action = untypedAction as BackgroundAction;
if (action.type === LIFTED_ACTION) toContentScript(action);
else if (action.type === TOGGLE_PERSIST) {
togglePersist();
toMonitors({
type: SET_PERSIST,
payload: !store.getState().instances.persisted,
});
}
return next(action);
};
export default api;
================================================
FILE: extension/src/background/store/backgroundReducer.ts
================================================
import { combineReducers, Reducer } from 'redux';
import { instances, InstancesState } from '@redux-devtools/app';
import { BackgroundAction } from './backgroundStore.js';
export interface BackgroundState {
readonly instances: InstancesState;
}
const rootReducer: Reducer<
BackgroundState,
BackgroundAction,
Partial<BackgroundState>
> = combineReducers({
instances,
}) as any;
export default rootReducer;
================================================
FILE: extension/src/background/store/backgroundStore.ts
================================================
import { createStore, applyMiddleware } from 'redux';
import {
CustomAction,
DispatchAction,
LIFTED_ACTION,
StoreActionWithoutLiftedAction,
} from '@redux-devtools/app';
import rootReducer, { BackgroundState } from './backgroundReducer.js';
import api, { CONNECTED, DISCONNECTED } from './apiMiddleware.js';
interface LiftedActionActionBase {
action?: DispatchAction | string | CustomAction;
state?: string;
toAll?: boolean;
readonly instanceId: string | number;
readonly id: string | number | undefined;
}
interface LiftedActionDispatchAction extends LiftedActionActionBase {
type: typeof LIFTED_ACTION;
message: 'DISPATCH';
action: DispatchAction;
toAll?: boolean;
}
interface LiftedActionImportAction extends LiftedActionActionBase {
type: typeof LIFTED_ACTION;
message: 'IMPORT';
state: string;
preloadedState?: unknown | undefined;
action?: never;
}
interface LiftedActionActionAction extends LiftedActionActionBase {
type: typeof LIFTED_ACTION;
message: 'ACTION';
action: string | CustomAction;
}
interface LiftedActionExportAction extends LiftedActionActionBase {
type: typeof LIFTED_ACTION;
message: 'EXPORT';
toExport: boolean;
action?: never;
}
export type LiftedActionAction =
| LiftedActionDispatchAction
| LiftedActionImportAction
| LiftedActionActionAction
| LiftedActionExportAction;
interface ConnectedAction {
readonly type: typeof CONNECTED;
}
interface DisconnectedAction {
readonly type: typeof DISCONNECTED;
}
export type BackgroundAction =
| StoreActionWithoutLiftedAction
| LiftedActionAction
| ConnectedAction
| DisconnectedAction;
export default function configureStore(
preloadedState?: Partial<BackgroundState>,
) {
return createStore(rootReducer, preloadedState, applyMiddleware(api));
/*
let enhancer;
if (process.env.NODE_ENV === 'production') {
enhancer = applyMiddleware(api);
} else {
const logger = require('redux-logger');
enhancer = applyMiddleware(api, logger());
}
return createStore(rootReducer, preloadedState, enhancer);
*/
}
================================================
FILE: extension/src/chromeApiMock.ts
================================================
// Mock not supported chrome.* API for Firefox and Electron
const isElectron = navigator.userAgent.includes('Electron');
const isFirefox = navigator.userAgent.includes('Firefox');
// Background page only
if (
(isElectron && location.pathname === '/background.bundle.js') ||
isFirefox
) {
(chrome.runtime as any).onConnectExternal = {
addListener() {
// do nothing.
},
};
(chrome.runtime as any).onMessageExternal = {
addListener() {
// do nothing.
},
};
if (isElectron) {
(chrome.notifications as any) = {
onClicked: {
addListener() {
// do nothing.
},
},
create() {
// do nothing.
},
clear() {
// do nothing.
},
};
(chrome.contextMenus as any) = {
onClicked: {
addListener() {
// do nothing.
},
},
};
(chrome.commands as any) = {
onCommand: {
addListener() {
// do nothing.
},
},
};
} else {
(chrome.storage as any).sync = chrome.storage.local;
(chrome.runtime as any).onInstalled = {
addListener: (cb: any) => cb(),
};
}
}
if (isElectron) {
if (!chrome.storage.local || !chrome.storage.local.remove) {
(chrome.storage as any).local = {
set(items: { [key: string]: string }, callback: () => void) {
for (const [key, value] of Object.entries(items)) {
localStorage.setItem(key, value);
}
if (callback) {
callback();
}
},
get(
keys: { [key: string]: any },
callback: (items: { [key: string]: any }) => void,
) {
const result = Object.fromEntries(
Object.entries(keys).map(([key, value]) => [
key,
localStorage.getItem(key) ?? value,
]),
);
if (callback) {
callback(result);
}
},
// Electron ~ 1.4.6
remove(keys: string | string[], callback: () => void) {
if (Array.isArray(keys)) {
for (const key of keys) {
localStorage.removeItem(key);
}
} else {
localStorage.removeItem(keys);
}
if (callback) {
callback();
}
},
};
}
// Avoid error: chrome.runtime.sendMessage is not supported responseCallback
const originSendMessage = (chrome.runtime as any).sendMessage;
(chrome.runtime as any).sendMessage = function (...args: unknown[]) {
if (process.env.NODE_ENV === 'development') {
return originSendMessage(...args);
}
if (typeof args[arguments.length - 1] === 'function') {
Array.prototype.pop.call(args);
}
return originSendMessage(...args);
};
}
if (isFirefox || isElectron) {
(chrome.storage as any).sync = chrome.storage.local;
}
================================================
FILE: extension/src/contentScript/index.ts
================================================
import '../chromeApiMock.js';
import {
getOptions,
isAllowed,
Options,
prefetchOptions,
prepareOptionsForPage,
} from '../options/syncOptions.js';
import type { TabMessage } from '../background/store/apiMiddleware.js';
import type {
PageScriptToContentScriptMessage,
PageScriptToContentScriptMessageWithoutDisconnect,
PageScriptToContentScriptMessageWithoutDisconnectOrInitInstance,
} from '../pageScript/api/index.js';
import { Action } from 'redux';
import {
CustomAction,
DispatchAction as AppDispatchAction,
} from '@redux-devtools/app';
import { LiftedState } from '@redux-devtools/instrument';
const source = '@devtools-extension';
const pageSource = '@devtools-page';
// Chrome message limit is 64 MB, but we're using 32 MB to include other object's parts
const maxChromeMsgSize = 32 * 1024 * 1024;
let connected = false;
let bg: chrome.runtime.Port | undefined;
declare global {
interface Window {
devToolsExtensionID?: string;
}
}
interface StartAction {
readonly type: 'START';
readonly state: undefined;
readonly id: undefined;
readonly source: typeof source;
}
interface StopAction {
readonly type: 'STOP';
readonly state: undefined;
readonly id: undefined;
readonly source: typeof source;
readonly failed?: boolean;
}
interface DispatchAction {
readonly type: 'DISPATCH';
readonly payload: AppDispatchAction;
readonly state: string | undefined;
readonly id: string;
readonly source: typeof source;
}
interface ImportAction {
readonly type: 'IMPORT';
readonly payload: undefined;
readonly state: string | undefined;
readonly id: string;
readonly source: typeof source;
}
interface ActionAction {
readonly type: 'ACTION';
readonly payload: string | CustomAction;
readonly state: string | undefined;
readonly id: string;
readonly source: typeof source;
}
interface ExportAction {
readonly type: 'EXPORT';
readonly payload: undefined;
readonly state: string | undefined;
readonly id: string;
readonly source: typeof source;
}
interface UpdateAction {
readonly type: 'UPDATE';
readonly state: string | undefined;
readonly id: string;
readonly source: typeof source;
}
interface OptionsAction {
readonly type: 'OPTIONS';
readonly options: Options;
readonly id: undefined;
readonly source: typeof source;
}
export type ContentScriptToPageScriptMessage =
| StartAction
| StopAction
| DispatchAction
| ImportAction
| ActionAction
| ExportAction
| UpdateAction
| OptionsAction;
interface ImportStatePayload<S, A extends Action<string>> {
readonly type: 'IMPORT_STATE';
readonly nextLiftedState: LiftedState<S, A, unknown> | readonly A[];
readonly preloadedState?: S;
}
interface ImportStateDispatchAction<S, A extends Action<string>> {
readonly type: 'DISPATCH';
readonly payload: ImportStatePayload<S, A>;
}
export type ListenerMessage<S, A extends Action<string>> =
| StartAction
| StopAction
| DispatchAction
| ImportAction
| ActionAction
| ExportAction
| UpdateAction
| OptionsAction
| ImportStateDispatchAction<S, A>;
function postToPageScript(message: ContentScriptToPageScriptMessage) {
window.postMessage(message, '*');
}
function connect() {
// Connect to the background script
connected = true;
const name = 'tab';
if (window.devToolsExtensionID) {
bg = chrome.runtime.connect(window.devToolsExtensionID, { name });
} else {
bg = chrome.runtime.connect({ name });
}
// Relay background script messages to the page script
bg.onMessage.addListener((message: TabMessage) => {
if ('action' in message) {
if (message.type === 'DISPATCH') {
postToPageScript({
type: message.type,
payload: message.action,
state: message.state,
id: message.id,
source,
});
} else if (message.type === 'ACTION') {
postToPageScript({
type: message.type,
payload: message.action,
state: message.state,
id: message.id,
source,
});
} else {
postToPageScript({
type: message.type,
payload: message.action,
state: message.state,
id: message.id,
source,
});
}
} else if (message.type === 'OPTIONS') {
postToPageScript({
type: message.type,
options: prepareOptionsForPage(message.options),
id: undefined,
source,
});
} else {
postToPageScript({
type: message.type,
state: message.state,
id: message.id,
source,
});
}
});
bg.onDisconnect.addListener(handleDisconnect);
}
function handleDisconnect() {
window.removeEventListener('message', handleMessages);
window.postMessage({ type: 'STOP', failed: true, source }, '*');
bg = undefined;
}
interface SplitMessageBase {
readonly type?: never;
}
interface SplitMessageStart extends SplitMessageBase {
readonly instanceId: number;
readonly source: typeof pageSource;
readonly split: 'start';
}
interface SplitMessageChunk extends SplitMessageBase {
readonly instanceId: number;
readonly source: typeof pageSource;
readonly split: 'chunk';
readonly chunk: [string, string];
}
interface SplitMessageEnd extends SplitMessageBase {
readonly instanceId: number;
readonly source: typeof pageSource;
readonly split: 'end';
}
export type SplitMessage =
| SplitMessageStart
| SplitMessageChunk
| SplitMessageEnd;
function tryCatch<S, A extends Action<string>>(
fn: (
args:
| PageScriptToContentScriptMessageWithoutDisconnect<S, A>
| SplitMessage,
) => void,
args: PageScriptToContentScriptMessageWithoutDisconnect<S, A>,
) {
try {
return fn(args);
} catch (err) {
if (
(err as Error).message ===
'Message length exceeded maximum allowed length.'
) {
const instanceId = (args as any).instanceId;
const newArgs = {
split: 'start',
};
const toSplit: [string, string][] = [];
let size = 0;
let arg;
Object.keys(args).map((key) => {
arg = args[key as keyof typeof args];
if (typeof arg === 'string') {
size += arg.length;
if (size > maxChromeMsgSize) {
toSplit.push([key, arg]);
return;
}
}
newArgs[key as keyof typeof newArgs] = arg;
});
fn(newArgs as SplitMessage);
for (let i = 0; i < toSplit.length; i++) {
for (let j = 0; j < toSplit[i][1].length; j += maxChromeMsgSize) {
fn({
instanceId,
source: pageSource,
split: 'chunk',
chunk: [toSplit[i][0], toSplit[i][1].substr(j, maxChromeMsgSize)],
});
}
}
return fn({ instanceId, source: pageSource, split: 'end' });
}
handleDisconnect();
/* eslint-disable no-console */
if (process.env.NODE_ENV !== 'production') {
console.error('Failed to send message', err);
}
/* eslint-enable no-console */
}
}
interface InitInstanceContentScriptToBackgroundMessage {
readonly name: 'INIT_INSTANCE';
readonly instanceId: number;
}
interface RelayMessage<S, A extends Action<string>> {
readonly name: 'RELAY';
readonly message:
| PageScriptToContentScriptMessageWithoutDisconnectOrInitInstance<S, A>
| SplitMessage;
}
export type ContentScriptToBackgroundMessage<S, A extends Action<string>> =
| InitInstanceContentScriptToBackgroundMessage
| RelayMessage<S, A>;
function postToBackground<S, A extends Action<string>>(
message: ContentScriptToBackgroundMessage<S, A>,
) {
bg!.postMessage(message);
}
function send<S, A extends Action<string>>(
message:
| PageScriptToContentScriptMessageWithoutDisconnect<S, A>
| SplitMessage,
) {
if (!connected) connect();
if (message.type === 'INIT_INSTANCE') {
getOptions((options) => {
postToPageScript({
type: 'OPTIONS',
options: prepareOptionsForPage(options),
id: undefined,
source,
});
});
postToBackground({ name: 'INIT_INSTANCE', instanceId: message.instanceId });
} else {
postToBackground({ name: 'RELAY', message });
}
}
// Resend messages from the page to the background script
function handleMessages<S, A extends Action<string>>(
event: MessageEvent<PageScriptToContentScriptMessage<S, A>>,
) {
if (!isAllowed()) return;
if (!event || event.source !== window || typeof event.data !== 'object') {
return;
}
const message = event.data;
if (message.source !== pageSource) return;
if (message.type === 'DISCONNECT') {
if (bg) {
bg.disconnect();
connected = false;
}
return;
}
tryCatch(send, message);
}
prefetchOptions();
window.addEventListener('message', handleMessages, false);
================================================
FILE: extension/src/devpanel/devpanel.pug
================================================
doctype html
html
head
meta(charset='UTF-8')
title Redux DevTools
include ../style.pug
body
#root
div(style='display: flex; justify-content: center; align-items: center')
img(
src='/img/loading.svg',
height=300, width=350,
)
link(href='/devpanel.bundle.css', rel='stylesheet')
script(src='/devpanel.bundle.js')
================================================
FILE: extension/src/devpanel/index.tsx
================================================
import '../chromeApiMock.js';
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,
StoreState,
UPDATE_STATE,
} from '@redux-devtools/app';
import App from '../app/App.js';
import configureStore from './store/panelStore.js';
import { Action, Store } from 'redux';
import {
PanelMessageWithoutNA,
PanelMessageWithSplitAction,
SplitUpdateStateRequest,
UpdateStateRequest,
} from '../background/store/apiMiddleware.js';
import { PersistGate } from 'redux-persist/integration/react';
const position = location.hash;
const messageStyle: CSSProperties = {
paddingTop: '20px',
width: '100%',
textAlign: 'center',
boxSizing: 'border-box',
};
let rendered: boolean | undefined;
let currentRoot: Root | undefined;
let store: Store<StoreState, StoreAction> | undefined;
let persistor: Persistor | undefined;
let bgConnection: chrome.runtime.Port;
let naTimeout: NodeJS.Timeout;
const isChrome = !navigator.userAgent.includes('Firefox');
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));
renderNodeAtRoot(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App position={position} />
</PersistGate>
</Provider>,
);
rendered = true;
}
function renderNA() {
if (rendered === false) return;
rendered = false;
naTimeout = setTimeout(() => {
let message = (
<div style={messageStyle}>
No store found. Make sure to follow{' '}
<a
href="https://github.com/zalmoxisus/redux-devtools-extension#usage"
target="_blank"
rel="noreferrer"
>
the instructions
</a>
.
</div>
);
if (
isChrome &&
chrome &&
chrome.devtools &&
chrome.devtools.inspectedWindow
) {
chrome.devtools.inspectedWindow.getResources((resources) => {
if (resources[0].url.substr(0, 4) === 'file') {
message = (
<div style={messageStyle}>
No store found. Most likely you did not allow access to file URLs.{' '}
<a
href="https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/Troubleshooting.md#access-file-url-file"
target="_blank"
rel="noreferrer"
>
See details
</a>
.
</div>
);
}
renderNodeAtRoot(message);
store = undefined;
});
} else {
renderNodeAtRoot(message);
store = undefined;
}
}, 3500);
}
let splitMessage: SplitUpdateStateRequest<unknown, Action<string>>;
function init() {
renderNA();
let name = 'monitor';
if (chrome && chrome.devtools && chrome.devtools.inspectedWindow) {
name += chrome.devtools.inspectedWindow.tabId;
}
bgConnection = chrome.runtime.connect({ name });
bgConnection.onMessage.addListener(
<S, A extends Action<string>>(
message: PanelMessageWithSplitAction<S, A>,
) => {
if (message.type === 'NA') {
// TODO Double-check this now that the name is different
if (message.id === name) renderNA();
else store!.dispatch({ type: REMOVE_INSTANCE, id: message.id });
} else {
if (!rendered) renderDevTools();
if (
message.type === UPDATE_STATE &&
(message.request as SplitUpdateStateRequest<S, A>).split
) {
const request = message.request as SplitUpdateStateRequest<S, A>;
if (request.split === 'start') {
splitMessage = request;
return;
}
if (request.split === 'chunk') {
if (
(splitMessage as unknown as Record<string, string>)[
request.chunk[0]
]
) {
(splitMessage as unknown as Record<string, string>)[
request.chunk[0]
] += request.chunk[1];
} else {
(splitMessage as unknown as Record<string, string>)[
request.chunk[0]
] = request.chunk[1];
}
return;
}
if (request.split === 'end') {
store!.dispatch({
...message,
request: splitMessage as UpdateStateRequest<S, A>,
});
return;
}
throw new Error(
`Unable to process split message with type: ${(request as any).split}`,
);
} else {
store!.dispatch(message as PanelMessageWithoutNA<S, A>);
}
}
},
);
}
if (position === '#popup') document.body.style.minWidth = '760px';
if (position !== '#popup') document.body.style.minHeight = '100%';
init();
================================================
FILE: extension/src/devpanel/store/panelReducer.ts
================================================
import { combineReducers, Reducer } from 'redux';
import {
connection,
instances,
monitor,
notification,
reports,
section,
socket,
stateTreeSettings,
StoreAction,
StoreState,
theme,
} from '@redux-devtools/app';
const rootReducer: Reducer<
StoreState,
StoreAction,
Partial<StoreState>
> = combineReducers({
instances,
monitor,
reports,
notification,
section,
socket,
theme,
connection,
stateTreeSettings,
}) as any;
export default rootReducer;
================================================
FILE: extension/src/devpanel/store/panelStore.ts
================================================
import { createStore, applyMiddleware, Reducer, Store } from 'redux';
import localForage from 'localforage';
import { persistReducer, persistStore } from 'redux-persist';
import {
exportStateMiddleware,
StoreAction,
StoreState,
} from '@redux-devtools/app';
import panelDispatcher from './panelSyncMiddleware.js';
import rootReducer from './panelReducer.js';
const persistConfig = {
key: 'redux-devtools',
blacklist: ['instances', 'socket'],
storage: localForage,
};
const persistedReducer: Reducer<StoreState, StoreAction> = persistReducer(
persistConfig,
rootReducer,
) as any;
export default function configureStore(
position: string,
bgConnection: chrome.runtime.Port,
) {
const enhancer = applyMiddleware(
exportSt
gitextract_iubpoav9/ ├── .changeset/ │ └── config.json ├── .eslintignore ├── .gitattributes ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ ├── CI.yml │ └── release.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── LICENSE.md ├── README.md ├── docs/ │ ├── Integrations/ │ │ └── Remote.md │ └── Walkthrough.md ├── eslint.js.config.base.mjs ├── eslint.js.react.jest.config.base.mjs ├── eslint.ts.config.base.mjs ├── eslint.ts.jest.config.base.mjs ├── eslint.ts.react.config.base.mjs ├── eslint.ts.react.jest.config.base.mjs ├── extension/ │ ├── .gitignore │ ├── CHANGELOG.md │ ├── CODE_OF_CONDUCT.md │ ├── LICENSE │ ├── README.md │ ├── babel.config.json │ ├── build.mjs │ ├── chrome/ │ │ └── manifest.json │ ├── docs/ │ │ ├── API/ │ │ │ ├── Arguments.md │ │ │ ├── Methods.md │ │ │ └── README.md │ │ ├── Architecture.md │ │ ├── Articles.md │ │ ├── Credits.md │ │ ├── FAQ.md │ │ ├── Features/ │ │ │ └── Trace.md │ │ ├── Feedback.md │ │ ├── Integrations.md │ │ ├── README.md │ │ ├── Recipes.md │ │ ├── Troubleshooting.md │ │ └── Videos.md │ ├── edge/ │ │ └── manifest.json │ ├── eslint.config.mjs │ ├── firefox/ │ │ └── manifest.json │ ├── jest.config.ts │ ├── package.json │ ├── src/ │ │ ├── app/ │ │ │ ├── Actions.tsx │ │ │ └── App.tsx │ │ ├── background/ │ │ │ ├── contextMenus.ts │ │ │ ├── index.ts │ │ │ ├── logging.ts │ │ │ ├── openWindow.ts │ │ │ └── store/ │ │ │ ├── apiMiddleware.ts │ │ │ ├── backgroundReducer.ts │ │ │ └── backgroundStore.ts │ │ ├── chromeApiMock.ts │ │ ├── contentScript/ │ │ │ └── index.ts │ │ ├── devpanel/ │ │ │ ├── devpanel.pug │ │ │ ├── index.tsx │ │ │ └── store/ │ │ │ ├── panelReducer.ts │ │ │ ├── panelStore.ts │ │ │ └── panelSyncMiddleware.ts │ │ ├── devtools/ │ │ │ ├── devtools.pug │ │ │ └── index.ts │ │ ├── options/ │ │ │ ├── AllowToRunGroup.tsx │ │ │ ├── ContextMenuGroup.tsx │ │ │ ├── EditorGroup.tsx │ │ │ ├── FilterGroup.tsx │ │ │ ├── MiscellaneousGroup.tsx │ │ │ ├── Options.tsx │ │ │ ├── index.tsx │ │ │ ├── options.pug │ │ │ └── syncOptions.ts │ │ ├── pageScript/ │ │ │ ├── Monitor.ts │ │ │ ├── api/ │ │ │ │ ├── filters.ts │ │ │ │ ├── generateInstanceId.ts │ │ │ │ ├── importState.ts │ │ │ │ ├── index.ts │ │ │ │ ├── notifyErrors.ts │ │ │ │ └── openWindow.ts │ │ │ ├── enhancerStore.ts │ │ │ └── index.ts │ │ ├── remote/ │ │ │ ├── index.tsx │ │ │ └── remote.pug │ │ └── style.pug │ ├── test/ │ │ ├── .eslintrc │ │ ├── __mocks__/ │ │ │ └── styleMock.js │ │ ├── app/ │ │ │ ├── containers/ │ │ │ │ └── App.spec.jsx │ │ │ └── inject/ │ │ │ ├── api.spec.js │ │ │ └── enhancer.spec.js │ │ ├── chrome/ │ │ │ └── extension.spec.js │ │ ├── electron/ │ │ │ ├── devpanel.spec.js │ │ │ └── fixture/ │ │ │ ├── index.html │ │ │ ├── main.js │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ └── renderer.js │ │ │ └── webpack.config.js │ │ ├── perf/ │ │ │ ├── data.js │ │ │ └── send.spec.js │ │ ├── setup.js │ │ └── utils/ │ │ ├── e2e.js │ │ └── inject.js │ └── tsconfig.json ├── jest.config.js ├── package.json ├── packages/ │ ├── d3-state-visualizer/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.js │ │ ├── examples/ │ │ │ └── tree/ │ │ │ ├── CHANGELOG.md │ │ │ ├── eslint.config.mjs │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ └── index.ts │ │ │ └── tsconfig.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── charts/ │ │ │ │ ├── index.ts │ │ │ │ └── tree/ │ │ │ │ ├── sortAndSerialize.ts │ │ │ │ ├── tree.ts │ │ │ │ └── utils.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── d3tooltip/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── map2tree/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.js │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── test/ │ │ │ └── map2tree.spec.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── react-base16-styling/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.js │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── colorConverters.ts │ │ │ ├── index.ts │ │ │ ├── themes/ │ │ │ │ ├── apathy.ts │ │ │ │ ├── ashes.ts │ │ │ │ ├── atelier-dune.ts │ │ │ │ ├── atelier-forest.ts │ │ │ │ ├── atelier-heath.ts │ │ │ │ ├── atelier-lakeside.ts │ │ │ │ ├── atelier-seaside.ts │ │ │ │ ├── bespin.ts │ │ │ │ ├── brewer.ts │ │ │ │ ├── bright.ts │ │ │ │ ├── chalk.ts │ │ │ │ ├── codeschool.ts │ │ │ │ ├── colors.ts │ │ │ │ ├── default.ts │ │ │ │ ├── eighties.ts │ │ │ │ ├── embers.ts │ │ │ │ ├── flat.ts │ │ │ │ ├── google.ts │ │ │ │ ├── grayscale.ts │ │ │ │ ├── greenscreen.ts │ │ │ │ ├── harmonic.ts │ │ │ │ ├── hopscotch.ts │ │ │ │ ├── index.ts │ │ │ │ ├── isotope.ts │ │ │ │ ├── marrakesh.ts │ │ │ │ ├── mocha.ts │ │ │ │ ├── monokai.ts │ │ │ │ ├── nicinabox.ts │ │ │ │ ├── ocean.ts │ │ │ │ ├── paraiso.ts │ │ │ │ ├── pop.ts │ │ │ │ ├── railscasts.ts │ │ │ │ ├── shapeshifter.ts │ │ │ │ ├── solarized.ts │ │ │ │ ├── summerfruit.ts │ │ │ │ ├── threezerotwofour.ts │ │ │ │ ├── tomorrow.ts │ │ │ │ ├── tube.ts │ │ │ │ └── twilight.ts │ │ │ └── types.ts │ │ ├── test/ │ │ │ └── index.test.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── react-dock/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── demo/ │ │ │ ├── CHANGELOG.md │ │ │ ├── eslint.config.mjs │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ └── index.tsx │ │ │ ├── tsconfig.app.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.node.json │ │ │ └── vite.config.ts │ │ ├── eslint.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── Dock.tsx │ │ │ ├── autoprefix.ts │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── react-json-tree/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.js │ │ ├── examples/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── eslint.config.mjs │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ └── index.tsx │ │ │ ├── tsconfig.app.json │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.node.json │ │ │ └── vite.config.ts │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── ItemRange.tsx │ │ │ ├── JSONArrayNode.tsx │ │ │ ├── JSONArrow.tsx │ │ │ ├── JSONIterableNode.tsx │ │ │ ├── JSONNestedNode.tsx │ │ │ ├── JSONNode.tsx │ │ │ ├── JSONObjectNode.tsx │ │ │ ├── JSONValueNode.tsx │ │ │ ├── createStylingFromTheme.ts │ │ │ ├── getCollectionEntries.ts │ │ │ ├── index.tsx │ │ │ ├── objType.ts │ │ │ ├── themes/ │ │ │ │ └── solarized.ts │ │ │ └── types.ts │ │ ├── test/ │ │ │ └── objType.spec.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── redux-devtools/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── examples/ │ │ │ ├── counter/ │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── README.md │ │ │ │ ├── eslint.config.mjs │ │ │ │ ├── index.html │ │ │ │ ├── package.json │ │ │ │ ├── src/ │ │ │ │ │ ├── actions/ │ │ │ │ │ │ └── CounterActions.ts │ │ │ │ │ ├── components/ │ │ │ │ │ │ └── Counter.tsx │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── ActionTypes.ts │ │ │ │ │ ├── containers/ │ │ │ │ │ │ ├── CounterApp.tsx │ │ │ │ │ │ ├── DevTools.tsx │ │ │ │ │ │ ├── Root.dev.tsx │ │ │ │ │ │ ├── Root.prod.tsx │ │ │ │ │ │ └── Root.ts │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── reducers/ │ │ │ │ │ │ ├── counter.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── store/ │ │ │ │ │ ├── configureStore.dev.ts │ │ │ │ │ ├── configureStore.prod.ts │ │ │ │ │ └── configureStore.ts │ │ │ │ ├── tsconfig.json │ │ │ │ ├── tsconfig.webpack.json │ │ │ │ └── webpack.config.ts │ │ │ └── todomvc/ │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── eslint.config.mjs │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── actions/ │ │ │ │ │ └── TodoActions.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── Footer.tsx │ │ │ │ │ ├── Header.tsx │ │ │ │ │ ├── MainSection.tsx │ │ │ │ │ ├── TodoItem.tsx │ │ │ │ │ └── TodoTextInput.tsx │ │ │ │ ├── constants/ │ │ │ │ │ ├── ActionTypes.ts │ │ │ │ │ └── TodoFilters.ts │ │ │ │ ├── containers/ │ │ │ │ │ ├── DevTools.tsx │ │ │ │ │ ├── Root.dev.tsx │ │ │ │ │ ├── Root.prod.tsx │ │ │ │ │ ├── Root.ts │ │ │ │ │ └── TodoApp.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── reducers/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── todos.ts │ │ │ │ └── store/ │ │ │ │ ├── configureStore.dev.ts │ │ │ │ ├── configureStore.prod.ts │ │ │ │ └── configureStore.ts │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.webpack.json │ │ │ └── webpack.config.ts │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── createDevTools.tsx │ │ │ ├── index.ts │ │ │ └── persistState.ts │ │ ├── test/ │ │ │ ├── globalLocalStorage.d.ts │ │ │ └── persistState.spec.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── redux-devtools-app/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── assets/ │ │ │ └── index.html │ │ ├── babel.config.json │ │ ├── buildUmd.mjs │ │ ├── demo/ │ │ │ └── index.tsx │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── src/ │ │ │ ├── actions/ │ │ │ │ └── index.ts │ │ │ ├── components/ │ │ │ │ └── Settings/ │ │ │ │ └── Connection.tsx │ │ │ ├── constants/ │ │ │ │ └── socketActionTypes.ts │ │ │ ├── index.tsx │ │ │ ├── middlewares/ │ │ │ │ └── api.ts │ │ │ ├── reducers/ │ │ │ │ ├── connection.ts │ │ │ │ ├── index.ts │ │ │ │ └── socket.ts │ │ │ ├── store/ │ │ │ │ └── configureStore.ts │ │ │ └── utils/ │ │ │ └── monitorActions.ts │ │ ├── tsconfig.demo.json │ │ ├── tsconfig.json │ │ ├── tsconfig.webpack.json │ │ └── webpack.config.ts │ ├── redux-devtools-app-core/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── actions/ │ │ │ │ └── index.ts │ │ │ ├── components/ │ │ │ │ ├── BottomButtons.tsx │ │ │ │ ├── Header.tsx │ │ │ │ ├── InstanceSelector.tsx │ │ │ │ ├── MonitorSelector.tsx │ │ │ │ ├── Settings/ │ │ │ │ │ ├── StateTree.tsx │ │ │ │ │ ├── Themes.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── TopButtons.tsx │ │ │ │ └── buttons/ │ │ │ │ ├── DispatcherButton.tsx │ │ │ │ ├── ExportButton.tsx │ │ │ │ ├── ImportButton.tsx │ │ │ │ ├── LockButton.tsx │ │ │ │ ├── PersistButton.tsx │ │ │ │ ├── PrintButton.tsx │ │ │ │ ├── RecordButton.tsx │ │ │ │ ├── SliderButton.tsx │ │ │ │ └── SyncButton.tsx │ │ │ ├── constants/ │ │ │ │ ├── actionTypes.ts │ │ │ │ └── dataTypes.ts │ │ │ ├── containers/ │ │ │ │ ├── Actions.tsx │ │ │ │ ├── App.tsx │ │ │ │ ├── DevTools.tsx │ │ │ │ └── monitors/ │ │ │ │ ├── ChartMonitorWrapper.tsx │ │ │ │ ├── Dispatcher.tsx │ │ │ │ ├── InspectorWrapper/ │ │ │ │ │ ├── ChartTab.tsx │ │ │ │ │ ├── RawTab.tsx │ │ │ │ │ ├── SubTabs.tsx │ │ │ │ │ ├── VisualDiffTab.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── Slider.tsx │ │ │ ├── index.tsx │ │ │ ├── middlewares/ │ │ │ │ ├── exportState.ts │ │ │ │ └── index.ts │ │ │ ├── reducers/ │ │ │ │ ├── index.ts │ │ │ │ ├── instances.ts │ │ │ │ ├── monitor.ts │ │ │ │ ├── notification.ts │ │ │ │ ├── reports.ts │ │ │ │ ├── section.ts │ │ │ │ ├── stateTreeSettings.ts │ │ │ │ └── theme.ts │ │ │ └── utils/ │ │ │ ├── commitExcessActions.ts │ │ │ ├── getMonitor.tsx │ │ │ ├── parseJSON.ts │ │ │ ├── stringifyJSON.ts │ │ │ └── updateState.ts │ │ ├── test/ │ │ │ ├── __mocks__/ │ │ │ │ └── styleMock.ts │ │ │ ├── app.spec.tsx │ │ │ └── setup.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── redux-devtools-chart-monitor/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── src/ │ │ │ ├── Chart.tsx │ │ │ ├── ChartMonitor.tsx │ │ │ ├── actions.ts │ │ │ ├── index.ts │ │ │ └── reducers.ts │ │ └── tsconfig.json │ ├── redux-devtools-cli/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── app/ │ │ │ ├── electron.cjs │ │ │ ├── index.html │ │ │ └── package.json │ │ ├── bin/ │ │ │ └── redux-devtools.js │ │ ├── defaultDbOptions.json │ │ ├── eslint.config.mjs │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── api/ │ │ │ │ ├── schema.ts │ │ │ │ └── schema_def.graphql │ │ │ ├── bin/ │ │ │ │ ├── injectServer.ts │ │ │ │ ├── openApp.ts │ │ │ │ └── redux-devtools.ts │ │ │ ├── db/ │ │ │ │ ├── connector.ts │ │ │ │ ├── migrations/ │ │ │ │ │ └── index.ts │ │ │ │ └── seeds/ │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── options.ts │ │ │ ├── routes.ts │ │ │ └── store.ts │ │ ├── test/ │ │ │ └── integration.spec.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── redux-devtools-dock-monitor/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── src/ │ │ │ ├── DockMonitor.tsx │ │ │ ├── actions.ts │ │ │ ├── constants.ts │ │ │ ├── index.ts │ │ │ └── reducers.ts │ │ └── tsconfig.json │ ├── redux-devtools-extension/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── src/ │ │ │ ├── developmentOnly.ts │ │ │ ├── index.ts │ │ │ ├── logOnly.ts │ │ │ └── logOnlyInProduction.ts │ │ └── tsconfig.json │ ├── redux-devtools-inspector-monitor/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── demo/ │ │ │ ├── CHANGELOG.md │ │ │ ├── eslint.config.mjs │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── DemoApp.tsx │ │ │ │ ├── DevTools.tsx │ │ │ │ ├── getOptions.ts │ │ │ │ ├── index.tsx │ │ │ │ └── reducers.ts │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.webpack.json │ │ │ └── webpack.config.ts │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── src/ │ │ │ ├── ActionList.tsx │ │ │ ├── ActionListHeader.tsx │ │ │ ├── ActionListRow.tsx │ │ │ ├── ActionPreview.tsx │ │ │ ├── ActionPreviewHeader.tsx │ │ │ ├── DevtoolsInspector.tsx │ │ │ ├── RightSlider.tsx │ │ │ ├── createDiffPatcher.ts │ │ │ ├── index.ts │ │ │ ├── redux.ts │ │ │ ├── tabs/ │ │ │ │ ├── ActionTab.tsx │ │ │ │ ├── DiffTab.tsx │ │ │ │ ├── JSONDiff.tsx │ │ │ │ ├── StateTab.tsx │ │ │ │ ├── getItemString.tsx │ │ │ │ └── getJsonTreeTheme.ts │ │ │ ├── themes/ │ │ │ │ ├── index.ts │ │ │ │ └── inspector.ts │ │ │ └── utils/ │ │ │ ├── getInspectedState.ts │ │ │ ├── isIterable.ts │ │ │ ├── selectorButtonStyles.ts │ │ │ └── themes.ts │ │ └── tsconfig.json │ ├── redux-devtools-inspector-monitor-test-tab/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── demo/ │ │ │ ├── CHANGELOG.md │ │ │ ├── eslint.config.mjs │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── DemoApp.tsx │ │ │ │ ├── DevTools.tsx │ │ │ │ ├── getOptions.ts │ │ │ │ ├── index.tsx │ │ │ │ └── reducers.ts │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.webpack.json │ │ │ └── webpack.config.ts │ │ ├── eslint.config.mjs │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── TestGenerator.tsx │ │ │ ├── index.tsx │ │ │ ├── redux/ │ │ │ │ ├── ava/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── template.ts │ │ │ │ ├── jest/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── template.ts │ │ │ │ ├── mocha/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── template.ts │ │ │ │ └── tape/ │ │ │ │ ├── index.ts │ │ │ │ └── template.ts │ │ │ ├── templateForm.ts │ │ │ ├── types.ts │ │ │ └── vanilla/ │ │ │ ├── ava/ │ │ │ │ ├── index.ts │ │ │ │ └── template.ts │ │ │ ├── jest/ │ │ │ │ ├── index.ts │ │ │ │ └── template.ts │ │ │ ├── mocha/ │ │ │ │ ├── index.ts │ │ │ │ └── template.ts │ │ │ └── tape/ │ │ │ ├── index.ts │ │ │ └── template.ts │ │ ├── test/ │ │ │ ├── TestGenerator.spec.tsx │ │ │ ├── __mocks__/ │ │ │ │ └── styleMock.ts │ │ │ ├── __snapshots__/ │ │ │ │ └── TestGenerator.spec.tsx.snap │ │ │ └── assertions.spec.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── redux-devtools-inspector-monitor-trace-tab/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── StackTraceTab.tsx │ │ │ ├── openFile.ts │ │ │ ├── presets.ts │ │ │ └── react-error-overlay/ │ │ │ ├── components/ │ │ │ │ ├── CodeBlock.tsx │ │ │ │ └── Collapsible.tsx │ │ │ ├── containers/ │ │ │ │ ├── StackFrame.tsx │ │ │ │ ├── StackFrameCodeBlock.tsx │ │ │ │ └── StackTrace.tsx │ │ │ └── utils/ │ │ │ ├── dom/ │ │ │ │ ├── absolutifyCaret.ts │ │ │ │ └── css.ts │ │ │ ├── generateAnsiHTML.ts │ │ │ ├── getLinesAround.ts │ │ │ ├── getPrettyURL.ts │ │ │ ├── getSourceMap.ts │ │ │ ├── getStackFrames.ts │ │ │ ├── isBultinErrorName.ts │ │ │ ├── isInternalFile.ts │ │ │ ├── mapper.ts │ │ │ ├── parseCompileError.ts │ │ │ ├── parser.ts │ │ │ ├── stack-frame.ts │ │ │ └── unmapper.ts │ │ ├── test/ │ │ │ ├── StackTraceTab.spec.tsx │ │ │ └── __snapshots__/ │ │ │ └── StackTraceTab.spec.tsx.snap │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── redux-devtools-instrument/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── getSymbolObservable.ts │ │ │ └── instrument.ts │ │ ├── test/ │ │ │ └── instrument.spec.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── redux-devtools-log-monitor/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── src/ │ │ │ ├── LogMonitor.tsx │ │ │ ├── LogMonitorButton.tsx │ │ │ ├── LogMonitorButtonBar.tsx │ │ │ ├── LogMonitorEntry.tsx │ │ │ ├── LogMonitorEntryAction.tsx │ │ │ ├── LogMonitorEntryList.tsx │ │ │ ├── actions.ts │ │ │ ├── brighten.ts │ │ │ ├── index.ts │ │ │ └── reducers.ts │ │ └── tsconfig.json │ ├── redux-devtools-remote/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── package.json │ │ ├── src/ │ │ │ ├── configureStore.ts │ │ │ ├── constants.ts │ │ │ ├── devTools.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── redux-devtools-rtk-query-monitor/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── demo/ │ │ │ ├── CHANGELOG.md │ │ │ ├── eslint.config.mjs │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── public/ │ │ │ │ └── mockServiceWorker.js │ │ │ ├── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── components/ │ │ │ │ │ └── ui/ │ │ │ │ │ ├── provider.tsx │ │ │ │ │ └── toaster.tsx │ │ │ │ ├── features/ │ │ │ │ │ ├── DevTools/ │ │ │ │ │ │ ├── DevTools.tsx │ │ │ │ │ │ ├── DevToolsSelector.tsx │ │ │ │ │ │ ├── config.ts │ │ │ │ │ │ └── helpers.ts │ │ │ │ │ ├── pokemon/ │ │ │ │ │ │ ├── Pokemon.tsx │ │ │ │ │ │ └── PokemonView.tsx │ │ │ │ │ └── posts/ │ │ │ │ │ ├── PostDetail.tsx │ │ │ │ │ ├── PostsManager.tsx │ │ │ │ │ └── PostsView.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.tsx │ │ │ │ ├── mocks/ │ │ │ │ │ ├── browser.ts │ │ │ │ │ └── db.ts │ │ │ │ ├── pokemon.data.ts │ │ │ │ ├── react-app-env.d.ts │ │ │ │ ├── services/ │ │ │ │ │ ├── pokemon.ts │ │ │ │ │ └── posts.ts │ │ │ │ └── store.ts │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.webpack.json │ │ │ └── webpack.config.ts │ │ ├── eslint.config.mjs │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── components/ │ │ │ │ ├── ArrowUpIcon.tsx │ │ │ │ ├── NoRtkQueryApi.tsx │ │ │ │ ├── QueryForm.tsx │ │ │ │ ├── QueryList.tsx │ │ │ │ ├── QueryPreviewActions.tsx │ │ │ │ ├── QueryPreviewApi.tsx │ │ │ │ ├── QueryPreviewData.tsx │ │ │ │ ├── QueryPreviewHeader.tsx │ │ │ │ ├── QueryPreviewInfo.tsx │ │ │ │ ├── QueryPreviewSubscriptions.tsx │ │ │ │ ├── QueryPreviewTags.tsx │ │ │ │ ├── RegexIcon.tsx │ │ │ │ ├── SortOrderButton.tsx │ │ │ │ ├── TreeView.tsx │ │ │ │ └── UList.tsx │ │ │ ├── containers/ │ │ │ │ ├── QueryPreview.tsx │ │ │ │ ├── RtkQueryInspector.tsx │ │ │ │ ├── RtkQueryMonitor.tsx │ │ │ │ └── mapProps.tsx │ │ │ ├── index.ts │ │ │ ├── monitor-config.ts │ │ │ ├── reducers.ts │ │ │ ├── selectors.ts │ │ │ ├── styles/ │ │ │ │ ├── themes.ts │ │ │ │ └── tree.tsx │ │ │ ├── types.ts │ │ │ └── utils/ │ │ │ ├── a11y.ts │ │ │ ├── comparators.ts │ │ │ ├── filters.ts │ │ │ ├── formatters.ts │ │ │ ├── isIterable.ts │ │ │ ├── object.ts │ │ │ ├── regexp.ts │ │ │ ├── rtk-query.ts │ │ │ ├── statistics.ts │ │ │ └── tabs.ts │ │ ├── test/ │ │ │ ├── __mocks__/ │ │ │ │ └── styleMock.ts │ │ │ ├── devtools.mocks.tsx │ │ │ ├── integration.spec.tsx │ │ │ └── rtk-query.mocks.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── redux-devtools-serialize/ │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── constants/ │ │ │ │ └── options.ts │ │ │ ├── helpers/ │ │ │ │ └── index.ts │ │ │ ├── immutable/ │ │ │ │ ├── index.ts │ │ │ │ └── serialize.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── test/ │ │ │ ├── __snapshots__/ │ │ │ │ ├── helpers.spec.ts.snap │ │ │ │ └── immutable.spec.ts.snap │ │ │ ├── helpers.spec.ts │ │ │ └── immutable.spec.ts │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ ├── redux-devtools-slider-monitor/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── examples/ │ │ │ └── todomvc/ │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── eslint.config.mjs │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src/ │ │ │ │ ├── actions/ │ │ │ │ │ └── TodoActions.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── Footer.tsx │ │ │ │ │ ├── Header.tsx │ │ │ │ │ ├── MainSection.tsx │ │ │ │ │ ├── TodoItem.tsx │ │ │ │ │ └── TodoTextInput.tsx │ │ │ │ ├── constants/ │ │ │ │ │ ├── ActionTypes.ts │ │ │ │ │ └── TodoFilters.ts │ │ │ │ ├── containers/ │ │ │ │ │ ├── DevTools.tsx │ │ │ │ │ ├── Root.dev.tsx │ │ │ │ │ ├── Root.prod.tsx │ │ │ │ │ ├── Root.ts │ │ │ │ │ └── TodoApp.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── reducers/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── todos.ts │ │ │ │ └── store/ │ │ │ │ ├── configureStore.dev.ts │ │ │ │ ├── configureStore.prod.ts │ │ │ │ └── configureStore.ts │ │ │ ├── tsconfig.json │ │ │ ├── tsconfig.webpack.json │ │ │ └── webpack.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── SliderButton.tsx │ │ │ ├── SliderMonitor.tsx │ │ │ ├── index.ts │ │ │ └── reducers.ts │ │ └── tsconfig.json │ ├── redux-devtools-ui/ │ │ ├── .gitignore │ │ ├── .storybook/ │ │ │ ├── main.ts │ │ │ └── preview.tsx │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── eslint.config.mjs │ │ ├── fonts/ │ │ │ └── index.css │ │ ├── jest.config.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── Button/ │ │ │ │ ├── Button.stories.tsx │ │ │ │ ├── Button.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles/ │ │ │ │ ├── common.ts │ │ │ │ ├── default.ts │ │ │ │ ├── index.ts │ │ │ │ └── material.ts │ │ │ ├── Container/ │ │ │ │ ├── index.tsx │ │ │ │ └── styles/ │ │ │ │ └── index.ts │ │ │ ├── ContextMenu/ │ │ │ │ ├── ContextMenu.stories.tsx │ │ │ │ ├── ContextMenu.tsx │ │ │ │ ├── data.ts │ │ │ │ ├── index.ts │ │ │ │ └── styles/ │ │ │ │ └── index.ts │ │ │ ├── Dialog/ │ │ │ │ ├── Dialog.stories.tsx │ │ │ │ ├── Dialog.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles/ │ │ │ │ ├── default.ts │ │ │ │ ├── index.ts │ │ │ │ └── material.ts │ │ │ ├── Editor/ │ │ │ │ ├── Editor.stories.tsx │ │ │ │ ├── Editor.tsx │ │ │ │ ├── WithTabs.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles/ │ │ │ │ └── index.ts │ │ │ ├── Form/ │ │ │ │ ├── Form.stories.tsx │ │ │ │ ├── Form.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── schema.ts │ │ │ │ ├── styles/ │ │ │ │ │ └── index.ts │ │ │ │ └── widgets.tsx │ │ │ ├── Notification/ │ │ │ │ ├── Notification.stories.tsx │ │ │ │ ├── Notification.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles/ │ │ │ │ └── index.ts │ │ │ ├── SegmentedControl/ │ │ │ │ ├── SegmentedControl.stories.tsx │ │ │ │ ├── SegmentedControl.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── styles/ │ │ │ │ └── index.ts │ │ │ ├── Select/ │ │ │ │ ├── Select.stories.tsx │ │ │ │ ├── Select.tsx │ │ │ │ ├── index.ts │ │ │ │ └── options.ts │ │ │ ├── Slider/ │ │ │ │ ├── Slider.stories.tsx │ │ │ │ ├── Slider.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles/ │ │ │ │ ├── common.ts │ │ │ │ ├── default.ts │ │ │ │ ├── index.ts │ │ │ │ └── material.ts │ │ │ ├── Tabs/ │ │ │ │ ├── Tabs.stories.tsx │ │ │ │ ├── Tabs.tsx │ │ │ │ ├── TabsHeader.tsx │ │ │ │ ├── data.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles/ │ │ │ │ ├── common.ts │ │ │ │ ├── default.ts │ │ │ │ ├── index.ts │ │ │ │ └── material.ts │ │ │ ├── Toolbar/ │ │ │ │ ├── Toolbar.stories.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles/ │ │ │ │ ├── Divider.ts │ │ │ │ ├── Spacer.ts │ │ │ │ └── Toolbar.ts │ │ │ ├── colorSchemes/ │ │ │ │ ├── atom-one-dark.ts │ │ │ │ ├── default.ts │ │ │ │ ├── dracula.ts │ │ │ │ ├── github.ts │ │ │ │ ├── index.ts │ │ │ │ ├── ir-black.ts │ │ │ │ ├── macintosh.ts │ │ │ │ ├── materia.ts │ │ │ │ ├── oceanic-next.ts │ │ │ │ ├── phd.ts │ │ │ │ ├── pico.ts │ │ │ │ ├── solar-flare.ts │ │ │ │ ├── spacemacs.ts │ │ │ │ ├── unikitty.ts │ │ │ │ └── woodland.ts │ │ │ ├── index.ts │ │ │ ├── themes/ │ │ │ │ ├── default.ts │ │ │ │ ├── index.ts │ │ │ │ └── material.ts │ │ │ └── utils/ │ │ │ ├── animations.ts │ │ │ ├── autoPrefix.ts │ │ │ ├── color.ts │ │ │ ├── createStyledComponent.ts │ │ │ ├── createThemedComponent.tsx │ │ │ ├── invertColors.ts │ │ │ └── theme.ts │ │ ├── test/ │ │ │ ├── Button.test.tsx │ │ │ ├── Container.test.tsx │ │ │ ├── ContextMenu.test.tsx │ │ │ ├── Dialog.test.tsx │ │ │ ├── Editor.test.tsx │ │ │ ├── Form.test.tsx │ │ │ ├── Notification.test.tsx │ │ │ ├── SegmentedControl.test.tsx │ │ │ ├── Select.test.tsx │ │ │ ├── Slider.test.tsx │ │ │ ├── Tabs.test.tsx │ │ │ ├── Toolbar.test.tsx │ │ │ ├── __mocks__/ │ │ │ │ └── styleMock.ts │ │ │ └── __snapshots__/ │ │ │ ├── Button.test.tsx.snap │ │ │ ├── Container.test.tsx.snap │ │ │ ├── ContextMenu.test.tsx.snap │ │ │ ├── Dialog.test.tsx.snap │ │ │ ├── Editor.test.tsx.snap │ │ │ ├── Form.test.tsx.snap │ │ │ ├── Notification.test.tsx.snap │ │ │ ├── SegmentedControl.test.tsx.snap │ │ │ ├── Select.test.tsx.snap │ │ │ ├── Slider.test.tsx.snap │ │ │ ├── Tabs.test.tsx.snap │ │ │ └── Toolbar.test.tsx.snap │ │ ├── tsconfig.json │ │ └── tsconfig.test.json │ └── redux-devtools-utils/ │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── eslint.config.mjs │ ├── package.json │ ├── src/ │ │ ├── catchErrors.ts │ │ ├── filters.ts │ │ ├── importState.ts │ │ └── index.ts │ └── tsconfig.json ├── patches/ │ ├── @dnd-kit__core.patch │ ├── @dnd-kit__sortable.patch │ └── redux-persist.patch ├── pnpm-workspace.yaml ├── renovate.json ├── tsconfig.base.json ├── tsconfig.esm.base.json ├── tsconfig.esm.react.base.json └── tsconfig.react.base.json
SYMBOL INDEX (1714 symbols across 346 files)
FILE: extension/src/app/Actions.tsx
type StateProps (line 25) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 26) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type OwnProps (line 27) | interface OwnProps {
type Props (line 30) | type Props = StateProps & DispatchProps & OwnProps;
function sendMessage (line 34) | async function sendMessage(message: SingleMessage) {
class Actions (line 38) | class Actions extends Component<Props> {
method render (line 50) | render() {
FILE: extension/src/app/App.tsx
type StateProps (line 13) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 14) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type OwnProps (line 15) | interface OwnProps {
type Props (line 18) | type Props = StateProps & DispatchProps & OwnProps;
class App (line 20) | class App extends Component<Props> {
method render (line 21) | render() {
function mapStateToProps (line 65) | function mapStateToProps(state: StoreState) {
FILE: extension/src/background/contextMenus.ts
function createMenu (line 3) | function createMenu() {
function removeMenu (line 25) | async function removeMenu() {
FILE: extension/src/background/logging.ts
function getReport (line 4) | function getReport(
FILE: extension/src/background/openWindow.ts
type DevToolsPosition (line 1) | type DevToolsPosition = 'devtools-window' | 'devtools-remote';
function openDevToolsWindow (line 5) | function openDevToolsWindow(position: DevToolsPosition) {
function createWindow (line 15) | function createWindow(position: DevToolsPosition) {
function getPath (line 25) | function getPath(position: DevToolsPosition) {
FILE: extension/src/background/store/apiMiddleware.ts
type TabMessageBase (line 36) | interface TabMessageBase {
type StartAction (line 42) | interface StartAction extends TabMessageBase {
type StopAction (line 48) | interface StopAction extends TabMessageBase {
type OptionsAction (line 54) | interface OptionsAction {
type DispatchAction (line 59) | interface DispatchAction extends TabMessageBase {
type ImportAction (line 66) | interface ImportAction extends TabMessageBase {
type ActionAction (line 73) | interface ActionAction extends TabMessageBase {
type ExportAction (line 80) | interface ExportAction extends TabMessageBase {
type NAAction (line 87) | interface NAAction {
type InitMessage (line 92) | interface InitMessage<S, A extends Action<string>> {
type LiftedMessage (line 103) | interface LiftedMessage {
type SerializedPartialLiftedState (line 110) | interface SerializedPartialLiftedState {
type SerializedPartialStateMessage (line 116) | interface SerializedPartialStateMessage {
type SerializedExportMessage (line 127) | interface SerializedExportMessage {
type SerializedActionMessage (line 135) | interface SerializedActionMessage {
type SerializedStateMessage (line 145) | interface SerializedStateMessage<S, A extends Action<string>> {
type UpdateStateRequest (line 159) | type UpdateStateRequest<S, A extends Action<string>> =
type UpdateStateAction (line 167) | interface UpdateStateAction<S, A extends Action<string>> {
type SplitUpdateStateRequestStart (line 173) | type SplitUpdateStateRequestStart<S, A extends Action<string>> = {
type SplitUpdateStateRequestChunk (line 177) | interface SplitUpdateStateRequestChunk {
type SplitUpdateStateRequestEnd (line 182) | interface SplitUpdateStateRequestEnd {
type SplitUpdateStateRequest (line 186) | type SplitUpdateStateRequest<S, A extends Action<string>> =
type SplitUpdateStateAction (line 191) | interface SplitUpdateStateAction<S, A extends Action<string>> {
type TabMessage (line 197) | type TabMessage =
type PanelMessageWithoutNA (line 205) | type PanelMessageWithoutNA<S, A extends Action<string>> =
type PanelMessage (line 209) | type PanelMessage<S, A extends Action<string>> =
type PanelMessageWithSplitAction (line 212) | type PanelMessageWithSplitAction<S, A extends Action<string>> =
type TabPort (line 216) | type TabPort = Omit<chrome.runtime.Port, 'postMessage'> & {
type PanelPort (line 219) | type PanelPort = Omit<chrome.runtime.Port, 'postMessage'> & {
constant CONNECTED (line 225) | const CONNECTED = 'socket/CONNECTED';
constant DISCONNECTED (line 226) | const DISCONNECTED = 'socket/DISCONNECTED';
type MonitorAction (line 245) | type MonitorAction<S, A extends Action<string>> =
function toMonitors (line 254) | function toMonitors<S, A extends Action<string>>(action: MonitorAction<S...
type ImportMessage (line 312) | interface ImportMessage {
type ToContentScriptMessage (line 320) | type ToContentScriptMessage = ImportMessage | LiftedActionAction;
function toContentScript (line 322) | function toContentScript(messageBody: ToContentScriptMessage) {
function toAllTabs (line 392) | function toAllTabs(msg: TabMessage) {
function getReducerError (line 400) | function getReducerError() {
function togglePersist (line 408) | function togglePersist() {
type OpenMessage (line 419) | interface OpenMessage {
type OpenOptionsMessage (line 424) | interface OpenOptionsMessage {
type SingleMessage (line 428) | type SingleMessage = OpenMessage | OpenOptionsMessage | OptionsMessage;
type BackgroundStoreMessage (line 430) | type BackgroundStoreMessage<S, A extends Action<string>> =
function messaging (line 436) | function messaging<S, A extends Action<string>>(
function disconnect (line 518) | function disconnect(
function onConnect (line 542) | function onConnect<S, A extends Action<string>>(port: chrome.runtime.Por...
FILE: extension/src/background/store/backgroundReducer.ts
type BackgroundState (line 5) | interface BackgroundState {
FILE: extension/src/background/store/backgroundStore.ts
type LiftedActionActionBase (line 11) | interface LiftedActionActionBase {
type LiftedActionDispatchAction (line 18) | interface LiftedActionDispatchAction extends LiftedActionActionBase {
type LiftedActionImportAction (line 24) | interface LiftedActionImportAction extends LiftedActionActionBase {
type LiftedActionActionAction (line 31) | interface LiftedActionActionAction extends LiftedActionActionBase {
type LiftedActionExportAction (line 36) | interface LiftedActionExportAction extends LiftedActionActionBase {
type LiftedActionAction (line 42) | type LiftedActionAction =
type ConnectedAction (line 48) | interface ConnectedAction {
type DisconnectedAction (line 52) | interface DisconnectedAction {
type BackgroundAction (line 56) | type BackgroundAction =
function configureStore (line 62) | function configureStore(
FILE: extension/src/chromeApiMock.ts
method addListener (line 12) | addListener() {
method addListener (line 17) | addListener() {
method addListener (line 25) | addListener() {
method create (line 29) | create() {
method clear (line 32) | clear() {
method addListener (line 38) | addListener() {
method addListener (line 45) | addListener() {
method set (line 61) | set(items: { [key: string]: string }, callback: () => void) {
method get (line 69) | get(
method remove (line 84) | remove(keys: string | string[], callback: () => void) {
FILE: extension/src/contentScript/index.ts
type Window (line 30) | interface Window {
type StartAction (line 35) | interface StartAction {
type StopAction (line 42) | interface StopAction {
type DispatchAction (line 50) | interface DispatchAction {
type ImportAction (line 58) | interface ImportAction {
type ActionAction (line 66) | interface ActionAction {
type ExportAction (line 74) | interface ExportAction {
type UpdateAction (line 82) | interface UpdateAction {
type OptionsAction (line 89) | interface OptionsAction {
type ContentScriptToPageScriptMessage (line 96) | type ContentScriptToPageScriptMessage =
type ImportStatePayload (line 106) | interface ImportStatePayload<S, A extends Action<string>> {
type ImportStateDispatchAction (line 112) | interface ImportStateDispatchAction<S, A extends Action<string>> {
type ListenerMessage (line 117) | type ListenerMessage<S, A extends Action<string>> =
function postToPageScript (line 128) | function postToPageScript(message: ContentScriptToPageScriptMessage) {
function connect (line 132) | function connect() {
function handleDisconnect (line 190) | function handleDisconnect() {
type SplitMessageBase (line 196) | interface SplitMessageBase {
type SplitMessageStart (line 200) | interface SplitMessageStart extends SplitMessageBase {
type SplitMessageChunk (line 206) | interface SplitMessageChunk extends SplitMessageBase {
type SplitMessageEnd (line 213) | interface SplitMessageEnd extends SplitMessageBase {
type SplitMessage (line 219) | type SplitMessage =
function tryCatch (line 224) | function tryCatch<S, A extends Action<string>>(
type InitInstanceContentScriptToBackgroundMessage (line 279) | interface InitInstanceContentScriptToBackgroundMessage {
type RelayMessage (line 284) | interface RelayMessage<S, A extends Action<string>> {
type ContentScriptToBackgroundMessage (line 291) | type ContentScriptToBackgroundMessage<S, A extends Action<string>> =
function postToBackground (line 295) | function postToBackground<S, A extends Action<string>>(
function send (line 301) | function send<S, A extends Action<string>>(
function handleMessages (line 323) | function handleMessages<S, A extends Action<string>>(
FILE: extension/src/devpanel/index.tsx
function renderNodeAtRoot (line 41) | function renderNodeAtRoot(node: ReactNode) {
function renderDevTools (line 47) | function renderDevTools() {
function renderNA (line 60) | function renderNA() {
function init (line 112) | function init() {
FILE: extension/src/devpanel/store/panelStore.ts
function configureStore (line 23) | function configureStore(
FILE: extension/src/devpanel/store/panelSyncMiddleware.ts
function selectInstance (line 12) | function selectInstance(
function getCurrentTabId (line 25) | function getCurrentTabId(next: (tabId: number) => void) {
function panelDispatcher (line 39) | function panelDispatcher(
FILE: extension/src/options/AllowToRunGroup.tsx
function AllowToRunGroup (line 4) | function AllowToRunGroup({ options, saveOption }: OptionsProps) {
FILE: extension/src/options/ContextMenuGroup.tsx
function ContextMenuGroup (line 4) | function ContextMenuGroup({
FILE: extension/src/options/EditorGroup.tsx
function EditorGroup (line 4) | function EditorGroup({ options, saveOption }: OptionsProps) {
FILE: extension/src/options/FilterGroup.tsx
function FilterGroup (line 5) | function FilterGroup({ options, saveOption }: OptionsProps) {
FILE: extension/src/options/MiscellaneousGroup.tsx
function MiscellaneousGroup (line 4) | function MiscellaneousGroup({
FILE: extension/src/options/Options.tsx
type OptionsProps (line 9) | interface OptionsProps {
function OptionsComponent (line 17) | function OptionsComponent(props: OptionsProps) {
FILE: extension/src/options/syncOptions.ts
type Options (line 3) | interface Options {
type OldOrNewOptions (line 17) | interface OldOrNewOptions {
type OptionsMessage (line 40) | interface OptionsMessage {
FILE: extension/src/pageScript/Monitor.ts
type Window (line 6) | interface Window {
class Monitor (line 11) | class Monitor<S, A extends Action<string>> {
method constructor (line 21) | constructor(
FILE: extension/src/pageScript/api/filters.ts
type FilterStateValue (line 5) | type FilterStateValue =
function isFiltered (line 23) | function isFiltered<A extends Action<string>>(
function filterActions (line 42) | function filterActions<A extends Action<string>>(
function filterStates (line 58) | function filterStates<S>(
function filterState (line 69) | function filterState<S, A extends Action<string>>(
type PartialLiftedState (line 126) | interface PartialLiftedState<S, A extends Action<string>> {
function startingFrom (line 135) | function startingFrom<S, A extends Action<string>>(
FILE: extension/src/pageScript/api/generateInstanceId.ts
function generateId (line 3) | function generateId(instanceId: number | undefined) {
FILE: extension/src/pageScript/api/importState.ts
type SerializeWithRequiredImmutable (line 8) | interface SerializeWithRequiredImmutable extends SerializeWithImmutable {
function isSerializeWithImmutable (line 12) | function isSerializeWithImmutable(
type SerializeWithRequiredReviver (line 18) | interface SerializeWithRequiredReviver extends SerializeWithImmutable {
function isSerializeWithReviver (line 22) | function isSerializeWithReviver(
type ParsedSerializedLiftedState (line 28) | interface ParsedSerializedLiftedState {
function importState (line 33) | function importState<S, A extends Action<string>>(
FILE: extension/src/pageScript/api/index.ts
function windowReplacer (line 25) | function windowReplacer(key: string, value: unknown) {
function tryCatchStringify (line 32) | function tryCatchStringify(obj: unknown) {
function stringify (line 49) | function stringify(obj: unknown, serialize?: Serialize | undefined) {
type Serialize (line 68) | interface Serialize {
function getSerializeParameter (line 74) | function getSerializeParameter(config: Config) {
type InitInstancePageScriptToContentScriptMessage (line 107) | interface InitInstancePageScriptToContentScriptMessage {
type DisconnectMessage (line 113) | interface DisconnectMessage {
type InitMessage (line 118) | interface InitMessage<S, A extends Action<string>> {
type SerializedPartialLiftedState (line 129) | interface SerializedPartialLiftedState {
type SerializedPartialStateMessage (line 135) | interface SerializedPartialStateMessage {
type SerializedExportMessage (line 146) | interface SerializedExportMessage {
type SerializedActionMessage (line 154) | interface SerializedActionMessage {
type SerializedStateMessage (line 164) | interface SerializedStateMessage<S, A extends Action<string>> {
type OpenMessage (line 178) | interface OpenMessage {
type PageScriptToContentScriptMessageForwardedToMonitors (line 184) | type PageScriptToContentScriptMessageForwardedToMonitors<
type PageScriptToContentScriptMessageWithoutDisconnectOrInitInstance (line 195) | type PageScriptToContentScriptMessageWithoutDisconnectOrInitInstance<
type PageScriptToContentScriptMessageWithoutDisconnect (line 205) | type PageScriptToContentScriptMessageWithoutDisconnect<
type PageScriptToContentScriptMessage (line 213) | type PageScriptToContentScriptMessage<S, A extends Action<string>> =
function post (line 217) | function post<S, A extends Action<string>>(
function getStackTrace (line 223) | function getStackTrace(
function amendActionType (line 263) | function amendActionType<A extends Action<string>>(
type LiftedMessage (line 287) | interface LiftedMessage {
type PartialStateMessage (line 294) | interface PartialStateMessage<S, A extends Action<string>> {
type ExportMessage (line 302) | interface ExportMessage<S, A extends Action<string>> {
type StructuralPerformAction (line 310) | interface StructuralPerformAction<A extends Action<string>> {
type SingleUserAction (line 316) | type SingleUserAction<A extends Action<string>> =
type UserAction (line 320) | type UserAction<A extends Action<string>> =
type ActionMessage (line 324) | interface ActionMessage<S, A extends Action<string>> {
type StateMessage (line 335) | interface StateMessage<S, A extends Action<string>> {
type ErrorMessage (line 346) | interface ErrorMessage {
type InitInstanceMessage (line 354) | interface InitInstanceMessage {
type GetReportMessage (line 361) | interface GetReportMessage {
type StopMessage (line 368) | interface StopMessage {
type ToContentScriptMessage (line 375) | type ToContentScriptMessage<S, A extends Action<string>> =
function toContentScript (line 386) | function toContentScript<S, A extends Action<string>>(
function sendMessage (line 431) | function sendMessage<S, A extends Action<string>>(
function handleMessages (line 475) | function handleMessages(event: MessageEvent<ContentScriptToPageScriptMes...
function setListener (line 493) | function setListener(
function disconnect (line 520) | function disconnect() {
type ConnectResponse (line 525) | interface ConnectResponse {
function connect (line 541) | function connect(preConfig: Config): ConnectResponse {
function isInIframe (line 700) | function isInIframe() {
FILE: extension/src/pageScript/api/notifyErrors.ts
function createExpBackoffTimer (line 4) | function createExpBackoffTimer(step: number) {
function postError (line 21) | function postError(message: string) {
function catchErrors (line 33) | function catchErrors(e: ErrorEvent) {
function notifyErrors (line 45) | function notifyErrors(onError?: () => boolean) {
FILE: extension/src/pageScript/api/openWindow.ts
type Position (line 4) | type Position = 'window' | 'remote';
function post (line 6) | function post<S, A extends Action<string>>(
function openWindow (line 12) | function openWindow(position?: Position) {
FILE: extension/src/pageScript/enhancerStore.ts
function getUrlParam (line 6) | function getUrlParam(key: string) {
type Window (line 14) | interface Window {
function configureStore (line 19) | function configureStore<
FILE: extension/src/pageScript/index.ts
type EnhancedStoreWithInitialDispatch (line 49) | type EnhancedStoreWithInitialDispatch<
function deprecateParam (line 65) | function deprecateParam(oldParam: string, newParam: string) {
type SerializeWithImmutable (line 73) | interface SerializeWithImmutable extends Serialize {
type ConfigWithExpandedMaxAge (line 78) | interface ConfigWithExpandedMaxAge {
type Config (line 124) | interface Config extends ConfigWithExpandedMaxAge {
type ReduxDevtoolsExtension (line 128) | interface ReduxDevtoolsExtension {
type Window (line 148) | interface Window {
function __REDUX_DEVTOOLS_EXTENSION__ (line 153) | function __REDUX_DEVTOOLS_EXTENSION__<S, A extends Action<string>>(
type Window (line 552) | interface Window {
type InferComposedStoreExt (line 584) | type InferComposedStoreExt<StoreEnhancers> = StoreEnhancers extends [
type ReduxDevtoolsExtensionCompose (line 609) | interface ReduxDevtoolsExtensionCompose {
type Window (line 621) | interface Window {
function reduxDevtoolsExtensionCompose (line 636) | function reduxDevtoolsExtensionCompose(...funcs: [Config] | StoreEnhance...
FILE: extension/test/app/inject/enhancer.spec.js
function counter (line 5) | function counter(state = 0, action) {
FILE: extension/test/electron/devpanel.spec.js
function showReduxPanel (line 51) | function showReduxPanel() {
FILE: extension/test/electron/fixture/src/renderer.js
constant INCREMENT_COUNTER (line 3) | const INCREMENT_COUNTER = 'INCREMENT_COUNTER';
constant DECREMENT_COUNTER (line 4) | const DECREMENT_COUNTER = 'DECREMENT_COUNTER';
FILE: extension/test/perf/send.spec.js
function test (line 4) | function test(title, data, maxTime = 100) {
FILE: extension/test/utils/inject.js
function insertScript (line 1) | function insertScript(str) {
function listenMessage (line 7) | function listenMessage(f) {
FILE: packages/d3-state-visualizer/src/charts/tree/sortAndSerialize.ts
function sortObject (line 1) | function sortObject(obj: unknown, strict?: boolean) {
function sortAndSerialize (line 23) | function sortAndSerialize(obj: unknown) {
FILE: packages/d3-state-visualizer/src/charts/tree/tree.ts
type Options (line 16) | interface Options {
type InternalNode (line 123) | interface InternalNode extends Node {
type NodePosition (line 128) | interface NodePosition {
function findParentNodePosition (line 217) | function findParentNodePosition(
function update (line 272) | function update() {
FILE: packages/d3-state-visualizer/src/charts/tree/utils.ts
function collapseChildren (line 5) | function collapseChildren(node: InternalNode) {
function expandChildren (line 13) | function expandChildren(node: InternalNode) {
function toggleChildren (line 21) | function toggleChildren(node: InternalNode) {
function visit (line 32) | function visit(
function getNodeGroupByDepthCount (line 53) | function getNodeGroupByDepthCount(rootNode: InternalNode) {
function getTooltipString (line 76) | function getTooltipString(node: InternalNode, { indentationSize = 4 }) {
FILE: packages/d3tooltip/src/index.ts
type StyleValue (line 4) | type StyleValue = string | number | boolean;
type Options (line 6) | interface Options<
function tooltip (line 35) | function tooltip<
FILE: packages/map2tree/src/index.ts
type Node (line 3) | interface Node {
function visit (line 10) | function visit(
function getNode (line 28) | function getNode(tree: Node, key: string): Node | null {
function map2tree (line 44) | function map2tree(
FILE: packages/react-base16-styling/src/colorConverters.ts
type Color (line 1) | type Color = [number, number, number];
function yuv2rgb (line 3) | function yuv2rgb(yuv: Color): Color {
function rgb2yuv (line 20) | function rgb2yuv(rgb: Color): Color {
FILE: packages/react-base16-styling/src/index.ts
constant DEFAULT_BASE16 (line 17) | const DEFAULT_BASE16 = base16.default;
constant BASE16_KEYS (line 19) | const BASE16_KEYS = Object.keys(DEFAULT_BASE16);
type Options (line 200) | interface Options {
FILE: packages/react-base16-styling/src/themes/index.ts
type Base16Theme (line 40) | interface Base16Theme {
FILE: packages/react-base16-styling/src/types.ts
type Styling (line 4) | interface Styling {
type StylingValueFunction (line 9) | type StylingValueFunction = (
type StylingValue (line 14) | type StylingValue =
type StylingConfig (line 19) | type StylingConfig = {
type Theme (line 27) | type Theme = string | Base16Theme | StylingConfig;
type StylingFunction (line 29) | type StylingFunction = (
FILE: packages/react-dock/demo/src/App.tsx
type State (line 43) | interface State {
class App (line 54) | class App extends Component<{}, State> {
method render (line 65) | render() {
FILE: packages/react-dock/src/Dock.tsx
type Styles (line 6) | interface Styles {
function autoprefixes (line 10) | function autoprefixes(styles: Styles) {
function getTransitions (line 81) | function getTransitions(duration: number) {
function getDockStyles (line 87) | function getDockStyles(
function getDimStyles (line 145) | function getDimStyles(
function getResizerStyles (line 162) | function getResizerStyles(position: 'left' | 'right' | 'top' | 'bottom') {
function getFullSize (line 208) | function getFullSize(
type Props (line 216) | interface Props {
type State (line 240) | interface State {
class Dock (line 251) | class Dock extends Component<Props, State> {
method componentDidMount (line 271) | componentDidMount() {
method componentWillUnmount (line 281) | componentWillUnmount() {
method UNSAFE_componentWillReceiveProps (line 289) | UNSAFE_componentWillReceiveProps(nextProps: Props) {
method updateSize (line 307) | updateSize(props: Props) {
method componentDidUpdate (line 317) | componentDidUpdate(prevProps: Props) {
method render (line 339) | render() {
FILE: packages/react-dock/src/autoprefix.ts
function prefixProp (line 39) | function prefixProp<Value>(key: string, value: Value) {
function autoprefix (line 49) | function autoprefix(style: CSSProperties) {
FILE: packages/react-json-tree/examples/src/App.tsx
class Custom (line 41) | class Custom {
method constructor (line 44) | constructor(value: unknown) {
method [Symbol.toStringTag] (line 48) | get [Symbol.toStringTag]() {
FILE: packages/react-json-tree/src/ItemRange.tsx
type Props (line 5) | interface Props extends CommonInternalProps {
function ItemRange (line 15) | function ItemRange(props: Props) {
FILE: packages/react-json-tree/src/JSONArrayNode.tsx
function createItemString (line 7) | function createItemString(data: unknown) {
type Props (line 13) | interface Props extends CommonInternalProps {
function JSONArrayNode (line 19) | function JSONArrayNode({ data, ...props }: Props) {
FILE: packages/react-json-tree/src/JSONArrow.tsx
type Props (line 4) | interface Props {
function JSONArrow (line 12) | function JSONArrow({
FILE: packages/react-json-tree/src/JSONIterableNode.tsx
function createItemString (line 7) | function createItemString(data: any, limit: number) {
type Props (line 25) | interface Props extends CommonInternalProps {
function JSONIterableNode (line 31) | function JSONIterableNode(props: Props) {
FILE: packages/react-json-tree/src/JSONNestedNode.tsx
type RenderChildNodesProps (line 12) | interface RenderChildNodesProps extends CommonInternalProps {
type Range (line 19) | interface Range {
type Entry (line 24) | interface Entry {
function isRange (line 29) | function isRange(rangeOrEntry: Range | Entry): rangeOrEntry is Range {
function renderChildNodes (line 33) | function renderChildNodes(
type Props (line 89) | interface Props extends CommonInternalProps {
function JSONNestedNode (line 97) | function JSONNestedNode(props: Props) {
FILE: packages/react-json-tree/src/JSONNode.tsx
type Props (line 9) | interface Props extends CommonInternalProps {
function JSONNode (line 13) | function JSONNode({
FILE: packages/react-json-tree/src/JSONObjectNode.tsx
function createItemString (line 7) | function createItemString(data: unknown) {
type Props (line 12) | interface Props extends CommonInternalProps {
function JSONObjectNode (line 18) | function JSONObjectNode({ data, ...props }: Props) {
FILE: packages/react-json-tree/src/JSONValueNode.tsx
type Props (line 15) | interface Props {
function JSONValueNode (line 27) | function JSONValueNode({
FILE: packages/react-json-tree/src/createStylingFromTheme.ts
type Color (line 28) | type Color = keyof ReturnType<typeof colorMap>;
type Colors (line 29) | type Colors = {
FILE: packages/react-json-tree/src/getCollectionEntries.ts
function getLength (line 3) | function getLength(type: string, collection: unknown) {
function isIterableMap (line 13) | function isIterableMap(collection: unknown) {
function getEntries (line 17) | function getEntries(
function getRanges (line 85) | function getRanges(from: number, to: number, limit: number) {
function getCollectionEntries (line 97) | function getCollectionEntries(
FILE: packages/react-json-tree/src/index.tsx
type Props (line 19) | interface Props extends Partial<CommonExternalProps> {
function JSONTree (line 36) | function JSONTree({
FILE: packages/react-json-tree/src/objType.ts
function objType (line 1) | function objType(obj: any) {
FILE: packages/react-json-tree/src/types.ts
type Key (line 4) | type Key = string | number;
type KeyPath (line 6) | type KeyPath = readonly (string | number)[];
type GetItemString (line 8) | type GetItemString = (
type LabelRenderer (line 16) | type LabelRenderer = (
type ValueRenderer (line 23) | type ValueRenderer = (
type ShouldExpandNodeInitially (line 29) | type ShouldExpandNodeInitially = (
type PostprocessValue (line 35) | type PostprocessValue = (value: unknown) => unknown;
type IsCustomNode (line 37) | type IsCustomNode = (value: unknown) => boolean;
type SortObjectKeys (line 39) | type SortObjectKeys = ((a: unknown, b: unknown) => number) | boolean;
type Styling (line 41) | type Styling = StylingFunction;
type CircularCache (line 43) | type CircularCache = unknown[];
type CommonExternalProps (line 45) | interface CommonExternalProps {
type CommonInternalProps (line 58) | interface CommonInternalProps extends CommonExternalProps {
FILE: packages/redux-devtools-app-core/src/actions/index.ts
type ChangeSectionAction (line 44) | interface ChangeSectionAction {
function changeSection (line 48) | function changeSection(section: string): ChangeSectionAction {
type ChangeThemeFormData (line 52) | interface ChangeThemeFormData {
type ChangeThemeData (line 57) | interface ChangeThemeData {
type ChangeThemeAction (line 60) | interface ChangeThemeAction {
function changeTheme (line 66) | function changeTheme(data: ChangeThemeData): ChangeThemeAction {
type ChangeStateTreeSettingsFormData (line 70) | interface ChangeStateTreeSettingsFormData {
type ChangeStateTreeSettingsData (line 75) | interface ChangeStateTreeSettingsData {
type ChangeStateTreeSettingsAction (line 79) | interface ChangeStateTreeSettingsAction {
function changeStateTreeSettings (line 85) | function changeStateTreeSettings(
type InitMonitorAction (line 91) | interface InitMonitorAction {
type MonitorActionAction (line 101) | interface MonitorActionAction {
type JumpToStateAction (line 111) | interface JumpToStateAction {
type JumpToActionAction (line 115) | interface JumpToActionAction {
type PauseRecordingAction (line 119) | interface PauseRecordingAction {
type LockChangesAction (line 123) | interface LockChangesAction {
type ToggleActionAction (line 127) | interface ToggleActionAction {
type RollbackAction (line 131) | interface RollbackAction {
type SweepAction (line 135) | interface SweepAction {
type ReorderActionAction (line 138) | interface ReorderActionAction {
type ImportStateAction (line 143) | interface ImportStateAction {
type DispatchAction (line 151) | type DispatchAction =
type LiftedActionActionBase (line 161) | interface LiftedActionActionBase {
type LiftedActionDispatchAction (line 166) | interface LiftedActionDispatchAction extends LiftedActionActionBase {
type LiftedActionImportAction (line 172) | interface LiftedActionImportAction extends LiftedActionActionBase {
type LiftedActionActionAction (line 178) | interface LiftedActionActionAction extends LiftedActionActionBase {
type LiftedActionExportAction (line 183) | interface LiftedActionExportAction extends LiftedActionActionBase {
type LiftedActionAction (line 188) | type LiftedActionAction =
function liftedDispatch (line 193) | function liftedDispatch(
type SelectInstanceAction (line 219) | interface SelectInstanceAction {
function selectInstance (line 223) | function selectInstance(selected: string): SelectInstanceAction {
type SelectMonitorAction (line 227) | interface SelectMonitorAction {
function selectMonitor (line 232) | function selectMonitor(monitor: string): SelectMonitorAction {
function selectMonitorWithState (line 235) | function selectMonitorWithState(
type NextState (line 242) | interface NextState {
type UpdateMonitorStateAction (line 246) | interface UpdateMonitorStateAction {
function selectMonitorTab (line 250) | function selectMonitorTab(subTabName: string): UpdateMonitorStateAction {
function updateMonitorState (line 254) | function updateMonitorState(
function importState (line 260) | function importState(
type ExportAction (line 267) | interface ExportAction {
function exportState (line 270) | function exportState(): ExportAction {
function lockChanges (line 274) | function lockChanges(status: boolean): LiftedActionDispatchAction {
function pauseRecording (line 283) | function pauseRecording(status: boolean): LiftedActionDispatchAction {
type CustomAction (line 292) | interface CustomAction {
function dispatchRemotely (line 298) | function dispatchRemotely(
type TogglePersistAction (line 304) | interface TogglePersistAction {
function togglePersist (line 307) | function togglePersist(): TogglePersistAction {
type SetPersistAction (line 311) | interface SetPersistAction {
function setPersist (line 315) | function setPersist(persist: boolean): SetPersistAction {
type ToggleSyncAction (line 319) | interface ToggleSyncAction {
function toggleSync (line 322) | function toggleSync(): ToggleSyncAction {
type ToggleSliderAction (line 326) | interface ToggleSliderAction {
function toggleSlider (line 329) | function toggleSlider(): ToggleSliderAction {
type ToggleDispatcherAction (line 333) | interface ToggleDispatcherAction {
function toggleDispatcher (line 336) | function toggleDispatcher(): ToggleDispatcherAction {
type Notification (line 340) | interface Notification {
type ShowNotificationAction (line 344) | interface ShowNotificationAction {
function showNotification (line 348) | function showNotification(message: string): ShowNotificationAction {
type ClearNotificationAction (line 352) | interface ClearNotificationAction {
function clearNotification (line 355) | function clearNotification(): ClearNotificationAction {
type GetReportRequest (line 359) | interface GetReportRequest {
function getReport (line 363) | function getReport(report: unknown): GetReportRequest {
type ActionCreator (line 367) | interface ActionCreator {
type LibConfig (line 372) | interface LibConfig {
type RequestBase (line 380) | interface RequestBase {
type InitRequest (line 392) | interface InitRequest extends RequestBase {
type ActionRequest (line 397) | interface ActionRequest extends RequestBase {
type StateRequest (line 404) | interface StateRequest extends RequestBase {
type PartialStateRequest (line 408) | interface PartialStateRequest extends RequestBase {
type LiftedRequest (line 413) | interface LiftedRequest extends RequestBase {
type ExportRequest (line 416) | interface ExportRequest extends RequestBase {
type Request (line 420) | type Request =
type UpdateStateAction (line 428) | interface UpdateStateAction {
type SetStateAction (line 434) | interface SetStateAction {
type RemoveInstanceAction (line 439) | interface RemoveInstanceAction {
type ClearInstancesAction (line 444) | interface ClearInstancesAction {
type ListRequest (line 448) | interface ListRequest {
type AddRequest (line 452) | interface AddRequest {
type RemoveRequest (line 456) | interface RemoveRequest {
type UpdateReportsRequest (line 461) | type UpdateReportsRequest = ListRequest | AddRequest | RemoveRequest;
type UpdateReportsAction (line 462) | interface UpdateReportsAction {
type GetReportError (line 467) | interface GetReportError {
type GetReportSuccess (line 472) | interface GetReportSuccess {
type ErrorAction (line 477) | interface ErrorAction {
type ReduxPersistRehydrateAction (line 482) | interface ReduxPersistRehydrateAction {
type CoreStoreActionWithoutUpdateStateOrLiftedAction (line 487) | type CoreStoreActionWithoutUpdateStateOrLiftedAction =
type CoreStoreActionWithoutUpdateState (line 513) | type CoreStoreActionWithoutUpdateState =
type CoreStoreActionWithoutLiftedAction (line 517) | type CoreStoreActionWithoutLiftedAction =
type CoreStoreAction (line 521) | type CoreStoreAction =
FILE: packages/redux-devtools-app-core/src/components/BottomButtons.tsx
type Props (line 11) | interface Props {
class BottomButtons (line 17) | class BottomButtons extends Component<Props> {
method shouldComponentUpdate (line 18) | shouldComponentUpdate(nextProps: Props) {
method render (line 26) | render() {
FILE: packages/redux-devtools-app-core/src/components/Header.tsx
type DispatchProps (line 12) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type OwnProps (line 13) | interface OwnProps {
type Props (line 16) | type Props = DispatchProps & OwnProps;
class Header (line 18) | class Header extends Component<Props> {
method render (line 23) | render() {
FILE: packages/redux-devtools-app-core/src/components/InstanceSelector.tsx
type StateProps (line 7) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 8) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 9) | type Props = StateProps & DispatchProps;
class InstanceSelector (line 11) | class InstanceSelector extends Component<Props> {
method render (line 14) | render() {
FILE: packages/redux-devtools-app-core/src/components/MonitorSelector.tsx
type StateProps (line 8) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 9) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 10) | type Props = StateProps & DispatchProps;
class MonitorSelector (line 12) | class MonitorSelector extends Component<Props> {
method shouldComponentUpdate (line 13) | shouldComponentUpdate(nextProps: Props) {
method render (line 17) | render() {
FILE: packages/redux-devtools-app-core/src/components/Settings/StateTree.tsx
type StateProps (line 7) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 8) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 9) | type Props = StateProps & DispatchProps;
class StateTree (line 11) | class StateTree extends Component<Props> {
method render (line 12) | render() {
FILE: packages/redux-devtools-app-core/src/components/Settings/Themes.tsx
type StateProps (line 8) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 9) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 10) | type Props = StateProps & DispatchProps;
class Themes (line 12) | class Themes extends Component<Props> {
method render (line 13) | render() {
FILE: packages/redux-devtools-app-core/src/components/Settings/index.tsx
type Props (line 6) | interface Props {
type State (line 10) | interface State {
class Settings (line 14) | class Settings extends Component<Props, State> {
method render (line 21) | render() {
FILE: packages/redux-devtools-app-core/src/components/TopButtons.tsx
type Props (line 14) | interface Props {
class TopButtons (line 20) | class TopButtons extends Component<Props> {
method shouldComponentUpdate (line 21) | shouldComponentUpdate(nextProps: Props) {
method render (line 44) | render() {
FILE: packages/redux-devtools-app-core/src/components/buttons/DispatcherButton.tsx
type DispatchProps (line 7) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type OwnProps (line 8) | interface OwnProps {
type Props (line 11) | type Props = DispatchProps & OwnProps;
class DispatcherButton (line 13) | class DispatcherButton extends Component<Props> {
method shouldComponentUpdate (line 14) | shouldComponentUpdate(nextProps: Props) {
method render (line 18) | render() {
FILE: packages/redux-devtools-app-core/src/components/buttons/ExportButton.tsx
type DispatchProps (line 7) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 8) | type Props = DispatchProps;
class ExportButton (line 10) | class ExportButton extends Component<Props> {
method shouldComponentUpdate (line 11) | shouldComponentUpdate() {
method render (line 15) | render() {
FILE: packages/redux-devtools-app-core/src/components/buttons/ImportButton.tsx
type DispatchProps (line 7) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 8) | type Props = DispatchProps;
class ImportButton (line 10) | class ImportButton extends Component<Props> {
method shouldComponentUpdate (line 13) | shouldComponentUpdate() {
method render (line 35) | render() {
FILE: packages/redux-devtools-app-core/src/components/buttons/LockButton.tsx
type DispatchProps (line 8) | type DispatchProps = ReturnType<typeof mapDispatchToProps>;
type OwnProps (line 9) | interface OwnProps {
type Props (line 13) | type Props = DispatchProps & OwnProps;
class LockButton (line 15) | class LockButton extends Component<Props> {
method shouldComponentUpdate (line 16) | shouldComponentUpdate(nextProps: Props) {
method render (line 20) | render() {
function mapDispatchToProps (line 35) | function mapDispatchToProps(
FILE: packages/redux-devtools-app-core/src/components/buttons/PersistButton.tsx
type StateProps (line 8) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 9) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type OwnProps (line 10) | interface OwnProps {
type Props (line 13) | type Props = StateProps & DispatchProps & OwnProps;
class LockButton (line 15) | class LockButton extends Component<Props> {
method shouldComponentUpdate (line 16) | shouldComponentUpdate(nextProps: Props) {
method render (line 20) | render() {
FILE: packages/redux-devtools-app-core/src/components/buttons/PrintButton.tsx
class PrintButton (line 5) | class PrintButton extends Component {
method shouldComponentUpdate (line 6) | shouldComponentUpdate() {
method render (line 37) | render() {
FILE: packages/redux-devtools-app-core/src/components/buttons/RecordButton.tsx
type DispatchProps (line 8) | type DispatchProps = ReturnType<typeof mapDispatchToProps>;
type OwnProps (line 9) | interface OwnProps {
type Props (line 12) | type Props = DispatchProps & OwnProps;
class RecordButton (line 14) | class RecordButton extends Component<Props> {
method shouldComponentUpdate (line 15) | shouldComponentUpdate(nextProps: Props) {
method render (line 19) | render() {
function mapDispatchToProps (line 33) | function mapDispatchToProps(
FILE: packages/redux-devtools-app-core/src/components/buttons/SliderButton.tsx
type DispatchProps (line 7) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type OwnProps (line 8) | interface OwnProps {
type Props (line 11) | type Props = DispatchProps & OwnProps;
class SliderButton (line 13) | class SliderButton extends Component<Props> {
method shouldComponentUpdate (line 14) | shouldComponentUpdate(nextProps: Props) {
method render (line 18) | render() {
FILE: packages/redux-devtools-app-core/src/components/buttons/SyncButton.tsx
type StateProps (line 8) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 9) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 10) | type Props = StateProps & DispatchProps;
class SyncButton (line 12) | class SyncButton extends Component<Props> {
method shouldComponentUpdate (line 13) | shouldComponentUpdate(nextProps: Props) {
method render (line 17) | render() {
FILE: packages/redux-devtools-app-core/src/constants/actionTypes.ts
constant CHANGE_SECTION (line 1) | const CHANGE_SECTION = 'main/CHANGE_SECTION';
constant CHANGE_THEME (line 2) | const CHANGE_THEME = 'main/CHANGE_THEME';
constant CHANGE_STATE_TREE_SETTINGS (line 3) | const CHANGE_STATE_TREE_SETTINGS = 'main/CHANGE_STATE_TREE_SETTINGS';
constant UPDATE_STATE (line 5) | const UPDATE_STATE = 'devTools/UPDATE_STATE';
constant SET_STATE (line 6) | const SET_STATE = 'devTools/SET_STATE';
constant SELECT_INSTANCE (line 7) | const SELECT_INSTANCE = 'devTools/SELECT_INSTANCE';
constant REMOVE_INSTANCE (line 8) | const REMOVE_INSTANCE = 'devTools/REMOVE_INSTANCE';
constant CLEAR_INSTANCES (line 9) | const CLEAR_INSTANCES = 'devTools/CLEAR_INSTANCES';
constant LIFTED_ACTION (line 10) | const LIFTED_ACTION = 'devTools/LIFTED_ACTION';
constant MONITOR_ACTION (line 11) | const MONITOR_ACTION = 'devTools/MONITOR_ACTION';
constant TOGGLE_SYNC (line 12) | const TOGGLE_SYNC = 'devTools/TOGGLE_SYNC';
constant TOGGLE_PERSIST (line 13) | const TOGGLE_PERSIST = 'devTools/TOGGLE_PERSIST';
constant SET_PERSIST (line 14) | const SET_PERSIST = 'devTools/SET_PERSIST';
constant SELECT_MONITOR (line 15) | const SELECT_MONITOR = 'devTools/SELECT_MONITOR';
constant UPDATE_MONITOR_STATE (line 16) | const UPDATE_MONITOR_STATE = 'devTools/UPDATE_MONITOR_STATE';
constant TOGGLE_SLIDER (line 17) | const TOGGLE_SLIDER = 'devTools/TOGGLE_SLIDER';
constant TOGGLE_DISPATCHER (line 18) | const TOGGLE_DISPATCHER = 'devTools/TOGGLE_DISPATCHER';
constant EXPORT (line 19) | const EXPORT = 'devTools/EXPORT';
constant SHOW_NOTIFICATION (line 20) | const SHOW_NOTIFICATION = 'devTools/SHOW_NOTIFICATION';
constant CLEAR_NOTIFICATION (line 21) | const CLEAR_NOTIFICATION = 'devTools/CLEAR_NOTIFICATION';
constant UPDATE_REPORTS (line 23) | const UPDATE_REPORTS = 'reports/UPDATE';
constant GET_REPORT_REQUEST (line 24) | const GET_REPORT_REQUEST = 'reports/GET_REPORT_REQUEST';
constant GET_REPORT_ERROR (line 25) | const GET_REPORT_ERROR = 'reports/GET_REPORT_ERROR';
constant GET_REPORT_SUCCESS (line 26) | const GET_REPORT_SUCCESS = 'reports/GET_REPORT_SUCCESS';
constant ERROR (line 27) | const ERROR = 'ERROR';
FILE: packages/redux-devtools-app-core/src/constants/dataTypes.ts
constant DATA_TYPE_KEY (line 1) | const DATA_TYPE_KEY = Symbol.for('__serializedType__');
constant DATA_REF_KEY (line 2) | const DATA_REF_KEY = Symbol.for('__serializedRef__');
FILE: packages/redux-devtools-app-core/src/containers/Actions.tsx
type StateProps (line 13) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 14) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 15) | type Props = StateProps & DispatchProps;
class Actions (line 17) | class Actions extends Component<Props> {
method render (line 18) | render() {
FILE: packages/redux-devtools-app-core/src/containers/App.tsx
type StateProps (line 10) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 11) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type OwnProps (line 12) | type OwnProps = {
type Props (line 15) | type Props = StateProps & DispatchProps & OwnProps;
class App (line 17) | class App extends Component<Props> {
method render (line 18) | render() {
FILE: packages/redux-devtools-app-core/src/containers/DevTools.tsx
type Props (line 12) | interface Props {
class DevTools (line 24) | class DevTools extends Component<Props> {
method constructor (line 38) | constructor(props: Props) {
method getMonitor (line 43) | getMonitor(props: Props, skipUpdate?: unknown) {
method UNSAFE_componentWillUpdate (line 76) | UNSAFE_componentWillUpdate(nextProps: Props) {
method shouldComponentUpdate (line 80) | shouldComponentUpdate(nextProps: Props) {
method render (line 96) | render() {
FILE: packages/redux-devtools-app-core/src/containers/monitors/ChartMonitorWrapper.tsx
function getPath (line 13) | function getPath(
type DispatchProps (line 26) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 27) | type Props = DispatchProps;
class ChartMonitorWrapper (line 29) | class ChartMonitorWrapper extends Component<Props> {
method render (line 49) | render() {
FILE: packages/redux-devtools-app-core/src/containers/monitors/Dispatcher.tsx
type DispatchProps (line 55) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type OwnProps (line 56) | interface OwnProps {
type Props (line 59) | type Props = DispatchProps & OwnProps;
type State (line 61) | interface State {
class Dispatcher (line 69) | class Dispatcher extends Component<Props, State> {
method UNSAFE_componentWillReceiveProps (line 79) | UNSAFE_componentWillReceiveProps(nextProps: Props) {
method shouldComponentUpdate (line 91) | shouldComponentUpdate(nextProps: Props, nextState: State) {
method render (line 153) | render() {
FILE: packages/redux-devtools-app-core/src/containers/monitors/InspectorWrapper/ChartTab.tsx
type DispatchProps (line 15) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type OwnProps (line 16) | interface OwnProps {
type Props (line 20) | type Props = DispatchProps & OwnProps;
class ChartTab (line 22) | class ChartTab extends Component<Props> {
method shouldComponentUpdate (line 27) | shouldComponentUpdate() {
method componentDidMount (line 31) | componentDidMount() {
method UNSAFE_componentWillReceiveProps (line 35) | UNSAFE_componentWillReceiveProps(nextProps: Props) {
method createChart (line 52) | createChart(props: Props) {
method getChartTheme (line 58) | getChartTheme(theme: ThemeFromProvider): Partial<Options> {
method render (line 104) | render() {
FILE: packages/redux-devtools-app-core/src/containers/monitors/InspectorWrapper/RawTab.tsx
type Props (line 5) | interface Props {
class RawTab (line 9) | class RawTab extends Component<Props> {
method constructor (line 12) | constructor(props: Props) {
method shouldComponentUpdate (line 17) | shouldComponentUpdate(nextProps: Props) {
method UNSAFE_componentWillUpdate (line 21) | UNSAFE_componentWillUpdate(nextProps: Props) {
method stringifyData (line 25) | stringifyData(props: Props) {
method render (line 29) | render() {
FILE: packages/redux-devtools-app-core/src/containers/monitors/InspectorWrapper/SubTabs.tsx
type StateProps (line 18) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 19) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 20) | type Props = StateProps &
class SubTabs (line 24) | class SubTabs extends Component<Props> {
method constructor (line 27) | constructor(props: Props) {
method UNSAFE_componentWillReceiveProps (line 32) | UNSAFE_componentWillReceiveProps(nextProps: Props) {
method updateTabs (line 49) | updateTabs(props: Props) {
method render (line 87) | render() {
FILE: packages/redux-devtools-app-core/src/containers/monitors/InspectorWrapper/VisualDiffTab.tsx
type Props (line 223) | interface Props {
class VisualDiffTab (line 227) | class VisualDiffTab extends Component<Props> {
method shouldComponentUpdate (line 228) | shouldComponentUpdate(nextProps: Props) {
method render (line 232) | render() {
FILE: packages/redux-devtools-app-core/src/containers/monitors/InspectorWrapper/index.tsx
constant DEFAULT_TABS (line 15) | const DEFAULT_TABS = [
type Features (line 34) | interface Features {
type Props (line 38) | interface Props {
class InspectorWrapper (line 42) | class InspectorWrapper extends Component<Props> {
method render (line 50) | render() {
FILE: packages/redux-devtools-app-core/src/containers/monitors/Slider.tsx
type Props (line 16) | interface Props {
class Slider (line 22) | class Slider extends Component<Props> {
method shouldComponentUpdate (line 23) | shouldComponentUpdate(nextProps: Props) {
method render (line 29) | render() {
FILE: packages/redux-devtools-app-core/src/middlewares/exportState.ts
function download (line 14) | function download(state: string) {
FILE: packages/redux-devtools-app-core/src/reducers/index.ts
type CoreStoreState (line 9) | interface CoreStoreState {
FILE: packages/redux-devtools-app-core/src/reducers/instances.ts
type Features (line 23) | interface Features {
type Options (line 37) | interface Options {
type State (line 47) | interface State {
type InstancesState (line 59) | interface InstancesState {
function updateState (line 87) | function updateState(
function dispatchAction (line 212) | function dispatchAction(
function removeState (line 234) | function removeState(state: InstancesState, connectionId: string | numbe...
function init (line 269) | function init(
function instances (line 305) | function instances(
FILE: packages/redux-devtools-app-core/src/reducers/monitor.ts
type MonitorStateMonitorState (line 11) | interface MonitorStateMonitorState {
type MonitorState (line 20) | interface MonitorState {
function dispatchMonitorAction (line 34) | function dispatchMonitorAction(
function monitor (line 49) | function monitor(
FILE: packages/redux-devtools-app-core/src/reducers/notification.ts
type Notification (line 9) | interface Notification {
type NotificationState (line 13) | type NotificationState = Notification | null;
function notification (line 15) | function notification(
FILE: packages/redux-devtools-app-core/src/reducers/reports.ts
type Data (line 6) | interface Data {
type ReportsState (line 10) | interface ReportsState {
function reports (line 18) | function reports(
FILE: packages/redux-devtools-app-core/src/reducers/section.ts
type SectionState (line 4) | type SectionState = string;
function section (line 6) | function section(state = 'Actions', action: CoreStoreAction) {
FILE: packages/redux-devtools-app-core/src/reducers/stateTreeSettings.ts
type StateTreeSettings (line 4) | interface StateTreeSettings {
function stateTreeSettings (line 9) | function stateTreeSettings(
FILE: packages/redux-devtools-app-core/src/reducers/theme.ts
type ThemeState (line 5) | interface ThemeState {
function theme (line 11) | function theme(
FILE: packages/redux-devtools-app-core/src/utils/commitExcessActions.ts
function commitExcessActions (line 6) | function commitExcessActions(liftedState: State, n = 1) {
FILE: packages/redux-devtools-app-core/src/utils/getMonitor.tsx
function getMonitor (line 14) | function getMonitor({ monitor }: { monitor: string }) {
FILE: packages/redux-devtools-app-core/src/utils/parseJSON.ts
function reviver (line 4) | function reviver(key: string, value: unknown) {
function parseJSON (line 29) | function parseJSON(
FILE: packages/redux-devtools-app-core/src/utils/stringifyJSON.ts
function replacer (line 4) | function replacer(key: string, value: unknown) {
function stringifyJSON (line 17) | function stringifyJSON(data: unknown, serialize: boolean | undefined) {
FILE: packages/redux-devtools-app-core/src/utils/updateState.ts
function recompute (line 6) | function recompute(
FILE: packages/redux-devtools-app/buildUmd.mjs
function importAsGlobals (line 30) | function importAsGlobals(mapping) {
FILE: packages/redux-devtools-app/src/actions/index.ts
type ConnectionType (line 26) | type ConnectionType = 'disabled' | 'custom';
type ConnectionOptions (line 27) | interface ConnectionOptions {
type ReconnectAction (line 33) | interface ReconnectAction {
function saveSocketSettings (line 37) | function saveSocketSettings(
type ConnectRequestAction (line 43) | interface ConnectRequestAction {
type ConnectSuccessPayload (line 47) | interface ConnectSuccessPayload {
type ConnectSuccessAction (line 52) | interface ConnectSuccessAction {
type ConnectErrorAction (line 58) | interface ConnectErrorAction {
type AuthRequestAction (line 63) | interface AuthRequestAction {
type AuthSuccessAction (line 67) | interface AuthSuccessAction {
type AuthErrorAction (line 72) | interface AuthErrorAction {
type DisconnectedAction (line 77) | interface DisconnectedAction {
type DeauthenticateAction (line 82) | interface DeauthenticateAction {
type SubscribeRequestAction (line 86) | interface SubscribeRequestAction {
type SubscribeSuccessAction (line 92) | interface SubscribeSuccessAction {
type SubscribeErrorAction (line 97) | interface SubscribeErrorAction {
type UnsubscribeAction (line 103) | interface UnsubscribeAction {
type EmitAction (line 108) | interface EmitAction {
type StoreActionWithoutUpdateStateOrLiftedAction (line 117) | type StoreActionWithoutUpdateStateOrLiftedAction =
type StoreActionWithoutUpdateState (line 134) | type StoreActionWithoutUpdateState =
type StoreActionWithoutLiftedAction (line 138) | type StoreActionWithoutLiftedAction =
type StoreAction (line 142) | type StoreAction = StoreActionWithoutUpdateState | UpdateStateAction;
FILE: packages/redux-devtools-app/src/components/Settings/Connection.tsx
type JSONSchema7 (line 11) | interface JSONSchema7 {
type Schema (line 16) | interface Schema {
type StateProps (line 52) | type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps (line 53) | type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props (line 54) | type Props = StateProps & DispatchProps;
type FormData (line 56) | interface FormData extends ConnectionStateOptions {
type State (line 60) | interface State {
class Connection (line 67) | class Connection extends Component<Props, State> {
method shouldComponentUpdate (line 91) | shouldComponentUpdate(nextProps: Props, nextState: State) {
method UNSAFE_componentWillReceiveProps (line 95) | UNSAFE_componentWillReceiveProps(nextProps: Props) {
method render (line 118) | render() {
FILE: packages/redux-devtools-app/src/constants/socketActionTypes.ts
type States (line 3) | interface States {
constant CONNECT_REQUEST (line 20) | const CONNECT_REQUEST = 'socket/CONNECT_REQUEST';
constant CONNECT_SUCCESS (line 21) | const CONNECT_SUCCESS = 'socket/CONNECT_SUCCESS';
constant CONNECT_ERROR (line 22) | const CONNECT_ERROR = 'socket/CONNECT_ERROR';
constant RECONNECT (line 23) | const RECONNECT = 'socket/RECONNECT';
constant AUTH_REQUEST (line 24) | const AUTH_REQUEST = 'socket/AUTH_REQUEST';
constant AUTH_SUCCESS (line 25) | const AUTH_SUCCESS = 'socket/AUTH_SUCCESS';
constant AUTH_ERROR (line 26) | const AUTH_ERROR = 'socket/AUTH_ERROR';
constant DISCONNECTED (line 27) | const DISCONNECTED = 'socket/DISCONNECTED';
constant DEAUTHENTICATE (line 28) | const DEAUTHENTICATE = 'socket/DEAUTHENTICATE';
constant SUBSCRIBE_REQUEST (line 29) | const SUBSCRIBE_REQUEST = 'socket/SUBSCRIBE_REQUEST';
constant SUBSCRIBE_SUCCESS (line 30) | const SUBSCRIBE_SUCCESS = 'socket/SUBSCRIBE_SUCCESS';
constant SUBSCRIBE_ERROR (line 31) | const SUBSCRIBE_ERROR = 'socket/SUBSCRIBE_ERROR';
constant UNSUBSCRIBE (line 32) | const UNSUBSCRIBE = 'socket/UNSUBSCRIBE';
constant EMIT (line 33) | const EMIT = 'socket/EMIT';
FILE: packages/redux-devtools-app/src/index.tsx
class Root (line 13) | class Root extends Component {
method UNSAFE_componentWillMount (line 17) | UNSAFE_componentWillMount() {
method render (line 31) | render() {
FILE: packages/redux-devtools-app/src/middlewares/api.ts
function emit (line 29) | function emit({ message: type, id, instanceId, action, state }: EmitActi...
function startMonitoring (line 38) | function startMonitoring(channel: string) {
function dispatchRemoteAction (line 43) | function dispatchRemoteAction({
type RequestBase (line 69) | interface RequestBase {
type DisconnectedAction (line 73) | interface DisconnectedAction extends RequestBase {
type StartAction (line 77) | interface StartAction extends RequestBase {
type ErrorAction (line 81) | interface ErrorAction extends RequestBase {
type RequestWithData (line 85) | interface RequestWithData extends RequestBase {
type MonitoringRequest (line 88) | type MonitoringRequest =
function monitoring (line 94) | function monitoring(request: MonitoringRequest) {
function subscribe (line 135) | function subscribe(
function handleConnection (line 158) | function handleConnection() {
function connect (line 214) | function connect() {
function disconnect (line 228) | function disconnect() {
function login (line 234) | function login() {
function getReport (line 255) | function getReport(reportId: unknown) {
FILE: packages/redux-devtools-app/src/reducers/connection.ts
type ConnectionStateOptions (line 4) | interface ConnectionStateOptions {
type ConnectionState (line 9) | interface ConnectionState {
function connection (line 14) | function connection(
FILE: packages/redux-devtools-app/src/reducers/index.ts
type StoreState (line 6) | interface StoreState extends CoreStoreState {
FILE: packages/redux-devtools-app/src/reducers/socket.ts
type SocketState (line 5) | interface SocketState {
function socket (line 23) | function socket(state = initialState, action: StoreAction): SocketState {
FILE: packages/redux-devtools-app/src/store/configureStore.ts
function configureStore (line 20) | function configureStore(
FILE: packages/redux-devtools-app/src/utils/monitorActions.ts
function sweep (line 11) | function sweep(state: State): State {
function nonReduxDispatch (line 32) | function nonReduxDispatch(
FILE: packages/redux-devtools-chart-monitor/src/Chart.tsx
type Props (line 15) | interface Props<S, A extends Action<string>>
class Chart (line 27) | class Chart<S, A extends Action<string>> extends Component<Props<S, A>> {
method componentDidMount (line 32) | componentDidMount() {
method UNSAFE_componentWillReceiveProps (line 41) | UNSAFE_componentWillReceiveProps(nextProps: Props<S, A>) {
method render (line 50) | render() {
FILE: packages/redux-devtools-chart-monitor/src/ChartMonitor.tsx
function invertColors (line 29) | function invertColors(theme: Base16Theme) {
type ChartMonitorProps (line 43) | interface ChartMonitorProps<S, A extends Action<string>>
class ChartMonitor (line 54) | class ChartMonitor<S, A extends Action<string>> extends PureComponent<
method getTheme (line 86) | getTheme() {
method getChartOptions (line 106) | getChartOptions(props = this.props): Props<S, A> {
method render (line 151) | render() {
FILE: packages/redux-devtools-chart-monitor/src/actions.ts
constant TOGGLE_VISIBILITY (line 1) | const TOGGLE_VISIBILITY =
type ToggleVisibilityAction (line 3) | interface ToggleVisibilityAction {
type ChartMonitorAction (line 6) | type ChartMonitorAction = ToggleVisibilityAction;
FILE: packages/redux-devtools-chart-monitor/src/reducers.ts
function toggleVisibility (line 5) | function toggleVisibility<S, A extends Action<string>>(
type ChartMonitorState (line 21) | interface ChartMonitorState {
function reducer (line 25) | function reducer<S, A extends Action<string>>(
FILE: packages/redux-devtools-cli/app/electron.cjs
function createWindow (line 6) | function createWindow() {
FILE: packages/redux-devtools-cli/src/bin/injectServer.ts
function getModuleVersion (line 24) | function getModuleVersion(modulePath: string): string {
function getServerFlag (line 30) | function getServerFlag(moduleName: string, version: string): string {
function inject (line 46) | function inject(
function revert (line 83) | function revert(
FILE: packages/redux-devtools-cli/src/bin/openApp.ts
function openApp (line 10) | async function openApp(app: true | string, options: Options) {
FILE: packages/redux-devtools-cli/src/bin/redux-devtools.ts
function readFile (line 15) | function readFile(filePath: string) {
function log (line 24) | function log(pass: boolean, msg: string) {
function getModuleName (line 30) | function getModuleName(type: string) {
function getModulePath (line 43) | function getModulePath(moduleName: string) {
function getModule (line 47) | function getModule(type: string) {
function injectRN (line 60) | function injectRN(type: string, msg: string) {
FILE: packages/redux-devtools-cli/src/db/connector.ts
type KnexFunction (line 8) | type KnexFunction = <TRecord extends {} = any, TResult = unknown[]>(
function connector (line 12) | function connector(options: AGServer.AGServerOptions) {
FILE: packages/redux-devtools-cli/src/db/migrations/index.ts
function up (line 3) | function up(knex: Knex) {
function down (line 82) | function down(knex: Knex) {
FILE: packages/redux-devtools-cli/src/db/seeds/index.ts
function seed (line 3) | function seed(knex: Knex) {
FILE: packages/redux-devtools-cli/src/index.ts
constant LOG_LEVEL_WARN (line 11) | const LOG_LEVEL_WARN = 2;
constant LOG_LEVEL_INFO (line 12) | const LOG_LEVEL_INFO = 3;
FILE: packages/redux-devtools-cli/src/options.ts
type ProtocolOptions (line 3) | interface ProtocolOptions {
type DbOptions (line 9) | interface DbOptions {
type Options (line 19) | interface Options {
function getOptions (line 31) | function getOptions(argv: { [arg: string]: any }): Options {
FILE: packages/redux-devtools-cli/src/routes.ts
function serveUmdModule (line 20) | function serveUmdModule(name: string) {
type Context (line 28) | interface Context {
function routes (line 32) | function routes(
FILE: packages/redux-devtools-cli/src/store.ts
function error (line 13) | function error(msg: string): Promise<{ error: string }> {
type ReportType (line 19) | type ReportType = 'STATE' | 'ACTION' | 'STATES' | 'ACTIONS';
type Report (line 21) | interface Report {
type ReportBaseFields (line 41) | interface ReportBaseFields {
function list (line 47) | function list(query?: string, fields?: string[]): Promise<ReportBaseFiel...
function listAll (line 53) | function listAll(query?: string): Promise<Report[]> {
function get (line 59) | function get(id: string): Promise<Report | { error: string }> {
type AddData (line 65) | interface AddData {
function add (line 83) | function add(data: AddData): Promise<ReportBaseFields | { error: string ...
function byBaseFields (line 131) | function byBaseFields(data: Report): ReportBaseFields {
type Store (line 135) | interface Store {
function createStore (line 142) | function createStore(options: AGServer.AGServerOptions): Store {
function composeException (line 153) | function composeException(exception: Error | undefined) {
FILE: packages/redux-devtools-dock-monitor/src/DockMonitor.tsx
type KeyObject (line 15) | interface KeyObject {
type ExternalProps (line 24) | interface ExternalProps<S, A extends Action<string>> {
type DefaultProps (line 40) | interface DefaultProps {
type DockMonitorProps (line 47) | interface DockMonitorProps<
class DockMonitor (line 66) | class DockMonitor<S, A extends Action<string>> extends Component<
method constructor (line 78) | constructor(props: DockMonitorProps<S, A>) {
method componentDidMount (line 100) | componentDidMount() {
method componentWillUnmount (line 104) | componentWillUnmount() {
method matchesKey (line 108) | matchesKey(key: KeyObject | undefined, event: KeyboardEvent) {
method renderChild (line 163) | renderChild(
method render (line 184) | render() {
FILE: packages/redux-devtools-dock-monitor/src/actions.ts
constant TOGGLE_VISIBILITY (line 1) | const TOGGLE_VISIBILITY =
type ToggleVisibilityAction (line 3) | interface ToggleVisibilityAction {
function toggleVisibility (line 6) | function toggleVisibility(): ToggleVisibilityAction {
constant CHANGE_POSITION (line 10) | const CHANGE_POSITION = '@@redux-devtools-log-monitor/CHANGE_POSITION';
type ChangePositionAction (line 11) | interface ChangePositionAction {
function changePosition (line 14) | function changePosition(): ChangePositionAction {
constant CHANGE_SIZE (line 18) | const CHANGE_SIZE = '@@redux-devtools-log-monitor/CHANGE_SIZE';
type ChangeSizeAction (line 19) | interface ChangeSizeAction {
function changeSize (line 23) | function changeSize(size: number): ChangeSizeAction {
constant CHANGE_MONITOR (line 27) | const CHANGE_MONITOR = '@@redux-devtools-log-monitor/CHANGE_MONITOR';
type ChangeMonitorAction (line 28) | interface ChangeMonitorAction {
function changeMonitor (line 31) | function changeMonitor(): ChangeMonitorAction {
type DockMonitorAction (line 35) | type DockMonitorAction =
FILE: packages/redux-devtools-dock-monitor/src/constants.ts
constant POSITIONS (line 1) | const POSITIONS = ['left', 'top', 'right', 'bottom'] as const;
FILE: packages/redux-devtools-dock-monitor/src/reducers.ts
type DockMonitorState (line 13) | interface DockMonitorState {
function position (line 21) | function position<S, A extends Action<string>>(
function size (line 31) | function size<S, A extends Action<string>>(
function isVisible (line 39) | function isVisible<S, A extends Action<string>>(
function childMonitorStates (line 47) | function childMonitorStates<S, A extends Action<string>>(
function childMonitorIndex (line 57) | function childMonitorIndex<S, A extends Action<string>>(
function reducer (line 70) | function reducer<S, A extends Action<string>>(
FILE: packages/redux-devtools-extension/src/developmentOnly.ts
function extensionComposeStub (line 24) | function extensionComposeStub(...funcs: [Config] | StoreEnhancer[]) {
FILE: packages/redux-devtools-extension/src/index.ts
type EnhancerOptions (line 4) | interface EnhancerOptions {
type Config (line 216) | interface Config extends EnhancerOptions {
type ConnectResponse (line 220) | interface ConnectResponse {
type ReduxDevtoolsExtension (line 225) | interface ReduxDevtoolsExtension {
type InferComposedStoreExt (line 230) | type InferComposedStoreExt<StoreEnhancers> = StoreEnhancers extends [
type ReduxDevtoolsExtensionCompose (line 240) | interface ReduxDevtoolsExtensionCompose {
type Window (line 252) | interface Window {
function extensionComposeStub (line 266) | function extensionComposeStub(...funcs: [Config] | StoreEnhancer[]) {
FILE: packages/redux-devtools-extension/src/logOnly.ts
function enhancer (line 9) | function enhancer(options?: EnhancerOptions): StoreEnhancer {
function composeWithEnhancer (line 38) | function composeWithEnhancer(config?: EnhancerOptions) {
function composeWithDevTools (line 54) | function composeWithDevTools(...funcs: [Config] | StoreEnhancer[]) {
FILE: packages/redux-devtools-extension/src/logOnlyInProduction.ts
function extensionComposeStub (line 25) | function extensionComposeStub(...funcs: [Config] | StoreEnhancer[]) {
FILE: packages/redux-devtools-inspector-monitor-test-tab/demo/src/DemoApp.tsx
constant ROOT (line 49) | const ROOT = '/';
type Props (line 51) | interface Props extends Omit<
function DemoApp (line 74) | function DemoApp(props: Props) {
FILE: packages/redux-devtools-inspector-monitor-test-tab/demo/src/DevTools.tsx
function ConnectedDevTools (line 36) | function ConnectedDevTools() {
FILE: packages/redux-devtools-inspector-monitor-test-tab/demo/src/getOptions.ts
type Options (line 1) | interface Options {
function getOptions (line 8) | function getOptions(location: { search: string }) {
function getTheme (line 17) | function getTheme(location: { search: string }) {
FILE: packages/redux-devtools-inspector-monitor-test-tab/demo/src/index.tsx
function getDebugSessionKey (line 20) | function getDebugSessionKey() {
constant ROOT (line 25) | const ROOT =
FILE: packages/redux-devtools-inspector-monitor-test-tab/demo/src/reducers.ts
type Nested (line 12) | type Nested = { long: { nested: { path: { to: { a: string } } }[] } };
constant NESTED (line 14) | const NESTED = {
constant IMMUTABLE_NESTED (line 28) | const IMMUTABLE_NESTED = fromJS(NESTED) as ImmutableMap<unknown, unknown>;
constant IMMUTABLE_MAP (line 30) | const IMMUTABLE_MAP = ImmutableMap({
constant HUGE_ARRAY (line 38) | const HUGE_ARRAY = Array.from({ length: 5000 }).map((_, key) => ({
constant HUGE_OBJECT (line 42) | const HUGE_OBJECT = Array.from({ length: 5000 }).reduce(
constant RECURSIVE (line 54) | const RECURSIVE: { obj?: unknown } = {};
function createIterator (line 57) | function createIterator() {
constant DEFAULT_SHUFFLE_ARRAY (line 69) | const DEFAULT_SHUFFLE_ARRAY = [0, 1, null, { id: 1 }, { id: 2 }, 'string'];
type ToggleTimeoutUpdateAction (line 71) | interface ToggleTimeoutUpdateAction {
type TimeoutUpdateAction (line 75) | interface TimeoutUpdateAction {
type IncrementAction (line 78) | interface IncrementAction {
type PushAction (line 81) | interface PushAction {
type PopAction (line 84) | interface PopAction {
type ReplaceAction (line 87) | interface ReplaceAction {
type ChangeNestedAction (line 90) | interface ChangeNestedAction {
type PushHugeArrayAction (line 93) | interface PushHugeArrayAction {
type AddIteratorAction (line 96) | interface AddIteratorAction {
type AddHugeObjectAction (line 99) | interface AddHugeObjectAction {
type AddRecursiveAction (line 102) | interface AddRecursiveAction {
type AddImmutableMapAction (line 105) | interface AddImmutableMapAction {
type ChangeImmutableNestedAction (line 108) | interface ChangeImmutableNestedAction {
type HugePayloadAction (line 111) | interface HugePayloadAction {
type AddFunctionAction (line 115) | interface AddFunctionAction {
type AddSymbolAction (line 118) | interface AddSymbolAction {
type ShuffleArrayAction (line 121) | interface ShuffleArrayAction {
type DemoAppAction (line 124) | type DemoAppAction =
type DemoAppState (line 143) | interface DemoAppState {
FILE: packages/redux-devtools-inspector-monitor-test-tab/src/TestGenerator.tsx
function getState (line 15) | function getState<S>(
function compare (line 24) | function compare<S>(
type Props (line 62) | interface Props<S, A extends Action<string>> extends Omit<
class TestGenerator (line 76) | class TestGenerator<
method getMethod (line 80) | getMethod(action: A) {
method getAction (line 91) | getAction(action: A) {
method generateTest (line 96) | generateTest() {
method render (line 198) | render() {
FILE: packages/redux-devtools-inspector-monitor-test-tab/src/index.tsx
type TestGeneratorMonitorState (line 34) | interface TestGeneratorMonitorState {
type State (line 40) | interface State {
class TestTab (line 44) | class TestTab<S, A extends Action<string>> extends Component<
method render (line 119) | render() {
FILE: packages/redux-devtools-inspector-monitor-test-tab/src/types.ts
type DispatcherLocals (line 1) | interface DispatcherLocals {
type AssertionLocals (line 6) | interface AssertionLocals {
type WrapLocals (line 11) | interface WrapLocals {
type Template (line 18) | interface Template {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/StackTraceTab.tsx
type Props (line 13) | interface Props<S, A extends Action<string>> extends TabComponentProps<S...
type State (line 21) | interface State {
class TraceTab (line 27) | class TraceTab<S, A extends Action<string>> extends Component<
method componentDidMount (line 39) | componentDidMount() {
method componentDidUpdate (line 44) | componentDidUpdate(prevProps: Props<S, A>) {
method checkForStackTrace (line 52) | checkForStackTrace() {
method render (line 125) | render() {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/openFile.ts
function openResource (line 5) | function openResource(
function openAndCloseTab (line 30) | function openAndCloseTab(url: string) {
function openInIframe (line 49) | function openInIframe(url: string) {
function openInEditor (line 57) | function openInEditor(editor: string, path: string, stackFrame: StackFra...
function openFile (line 98) | function openFile(
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/components/CodeBlock.tsx
type CodeBlockPropsType (line 26) | interface CodeBlockPropsType {
function CodeBlock (line 31) | function CodeBlock(props: CodeBlockPropsType) {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/components/Collapsible.tsx
type Props (line 36) | interface Props {
type State (line 41) | interface State {
class Collapsible (line 45) | class Collapsible extends Component<Props, State> {
method render (line 61) | render() {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/containers/StackFrame.tsx
type Props (line 48) | interface Props {
type State (line 56) | interface State {
class StackFrame (line 60) | class StackFrame extends Component<Props, State> {
method getErrorLocation (line 71) | getErrorLocation(): ErrorLocation | null {
method render (line 103) | render() {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/containers/StackFrameCodeBlock.tsx
type StackFrameCodeBlockPropsType (line 20) | interface StackFrameCodeBlockPropsType {
function StackFrameCodeBlock (line 28) | function StackFrameCodeBlock(props: StackFrameCodeBlockPropsType) {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/containers/StackTrace.tsx
type Props (line 24) | interface Props {
class StackTrace (line 31) | class StackTrace extends Component<Props> {
method renderFrames (line 32) | renderFrames() {
method render (line 96) | render() {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/dom/absolutifyCaret.ts
function removeNextBr (line 8) | function removeNextBr(parent: Node, component: Element | null | undefine...
function absolutifyCaret (line 17) | function absolutifyCaret(component: Node) {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/dom/css.ts
function getHead (line 11) | function getHead(document: Document) {
function injectCss (line 15) | function injectCss(document: Document, css: string): number {
function removeCss (line 26) | function removeCss(document: Document, ref: number) {
function applyStyles (line 35) | function applyStyles(
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/generateAnsiHTML.ts
function generateAnsiHTML (line 29) | function generateAnsiHTML(txt: string): string {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/getLinesAround.ts
function getLinesAround (line 16) | function getLinesAround(
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/getPrettyURL.ts
function getPrettyURL (line 8) | function getPrettyURL(
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/getSourceMap.ts
class SourceMap (line 15) | class SourceMap {
method constructor (line 18) | constructor(sourceMap: SourceMapConsumer) {
method getOriginalPosition (line 27) | getOriginalPosition(
method getGeneratedPosition (line 48) | getGeneratedPosition(
method getSource (line 68) | getSource(sourceName: string): string | null {
method getSources (line 72) | getSources(): string[] {
function extractSourceMapUrl (line 77) | function extractSourceMapUrl(
function getSourceMap (line 103) | async function getSourceMap(
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/getStackFrames.ts
function getStackFrames (line 14) | function getStackFrames(
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/isBultinErrorName.ts
function isBultinErrorName (line 8) | function isBultinErrorName(errorName: string | null | undefined) {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/isInternalFile.ts
function isInternalFile (line 8) | function isInternalFile(
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/mapper.ts
function map (line 17) | async function map(
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/parseCompileError.ts
type ErrorLocation (line 3) | interface ErrorLocation {
function parseCompileError (line 24) | function parseCompileError(message: string): ErrorLocation | null | unde...
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/parser.ts
function extractLocation (line 12) | function extractLocation(token: string): [string, number, number] {
function parseStack (line 29) | function parseStack(stack: string[]): StackFrame[] {
function parseError (line 74) | function parseError(error: Error | string | string[]): StackFrame[] {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/stack-frame.ts
class ScriptLine (line 9) | class ScriptLine {
method constructor (line 17) | constructor(lineNumber: number, content: string, highlight = false) {
class StackFrame (line 27) | class StackFrame {
method constructor (line 41) | constructor(
method getFunctionName (line 85) | getFunctionName(): string {
method getSource (line 93) | getSource(): string {
method toString (line 110) | toString(): string {
FILE: packages/redux-devtools-inspector-monitor-trace-tab/src/react-error-overlay/utils/unmapper.ts
function count (line 13) | function count(search: string, string: string): number {
function unmap (line 33) | async function unmap(
FILE: packages/redux-devtools-inspector-monitor/demo/src/DemoApp.tsx
constant ROOT (line 103) | const ROOT =
function buildUrl (line 108) | function buildUrl(options: Options) {
type Props (line 122) | interface Props extends Omit<
function DemoApp (line 146) | function DemoApp(props: Props) {
FILE: packages/redux-devtools-inspector-monitor/demo/src/DevTools.tsx
function ConnectedDevTools (line 47) | function ConnectedDevTools() {
FILE: packages/redux-devtools-inspector-monitor/demo/src/getOptions.ts
type Options (line 1) | interface Options {
function getOptions (line 8) | function getOptions(location: { search: string }) {
function getTheme (line 17) | function getTheme(location: { search: string }) {
FILE: packages/redux-devtools-inspector-monitor/demo/src/index.tsx
function getDebugSessionKey (line 19) | function getDebugSessionKey() {
constant ROOT (line 24) | const ROOT =
FILE: packages/redux-devtools-inspector-monitor/demo/src/reducers.ts
type Nested (line 12) | type Nested = { long: { nested: { path: { to: { a: string } } }[] } };
constant NESTED (line 14) | const NESTED = {
constant IMMUTABLE_NESTED (line 28) | const IMMUTABLE_NESTED = fromJS(NESTED) as ImmutableMap<unknown, unknown>;
constant IMMUTABLE_MAP (line 30) | const IMMUTABLE_MAP = ImmutableMap({
type MapValue (line 38) | type MapValue =
constant NATIVE_MAP (line 44) | const NATIVE_MAP = new window.Map<string, MapValue>([
constant HUGE_ARRAY (line 63) | const HUGE_ARRAY = Array.from({ length: 5000 }).map((_, key) => ({
constant HUGE_OBJECT (line 67) | const HUGE_OBJECT = Array.from({ length: 5000 }).reduce(
constant RECURSIVE (line 79) | const RECURSIVE: { obj?: unknown } = {};
function createIterator (line 82) | function createIterator() {
constant DEFAULT_SHUFFLE_ARRAY (line 94) | const DEFAULT_SHUFFLE_ARRAY = [0, 1, null, { id: 1 }, { id: 2 }, 'string'];
type ToggleTimeoutUpdateAction (line 96) | interface ToggleTimeoutUpdateAction {
type TimeoutUpdateAction (line 100) | interface TimeoutUpdateAction {
type IncrementAction (line 103) | interface IncrementAction {
type PushAction (line 106) | interface PushAction {
type PopAction (line 109) | interface PopAction {
type ReplaceAction (line 112) | interface ReplaceAction {
type ChangeNestedAction (line 115) | interface ChangeNestedAction {
type PushHugeArrayAction (line 118) | interface PushHugeArrayAction {
type AddIteratorAction (line 121) | interface AddIteratorAction {
type AddHugeObjectAction (line 124) | interface AddHugeObjectAction {
type AddRecursiveAction (line 127) | interface AddRecursiveAction {
type AddNativeMapAction (line 130) | interface AddNativeMapAction {
type AddImmutableMapAction (line 133) | interface AddImmutableMapAction {
type ChangeImmutableNestedAction (line 136) | interface ChangeImmutableNestedAction {
type HugePayloadAction (line 139) | interface HugePayloadAction {
type AddFunctionAction (line 143) | interface AddFunctionAction {
type AddSymbolAction (line 146) | interface AddSymbolAction {
type ShuffleArrayAction (line 149) | interface ShuffleArrayAction {
type DemoAppAction (line 152) | type DemoAppAction =
type DemoAppState (line 172) | interface DemoAppState {
FILE: packages/redux-devtools-inspector-monitor/src/ActionList.tsx
function getTimestamps (line 25) | function getTimestamps<A extends Action<string>>(
function scrollToBottom (line 39) | function scrollToBottom(node: HTMLDivElement) {
type Props (line 43) | interface Props<A extends Action<string>> {
function ActionList (line 65) | function ActionList<A extends Action<string>>({
type SortableItemProps (line 231) | interface SortableItemProps {
function SortableItem (line 236) | function SortableItem({ children, actionId }: SortableItemProps) {
FILE: packages/redux-devtools-inspector-monitor/src/ActionListHeader.tsx
type Props (line 13) | interface Props {
FILE: packages/redux-devtools-inspector-monitor/src/ActionListRow.tsx
constant BUTTON_SKIP (line 15) | const BUTTON_SKIP = 'Skip';
constant BUTTON_JUMP (line 16) | const BUTTON_JUMP = 'Jump';
type Button (line 18) | type Button = typeof BUTTON_SKIP | typeof BUTTON_JUMP;
type Props (line 32) | interface Props<A extends Action<string>> {
type State (line 47) | interface State {
class ActionListRow (line 51) | class ActionListRow<
method render (line 56) | render(): JSX.Element {
method handleButtonClick (line 178) | handleButtonClick(btn: Button, e: MouseEvent<HTMLDivElement>) {
FILE: packages/redux-devtools-inspector-monitor/src/ActionPreview.tsx
type TabComponentProps (line 14) | interface TabComponentProps<S, A extends Action<string>> {
type Tab (line 33) | interface Tab<S, A extends Action<string>> {
constant DEFAULT_TABS (line 38) | const DEFAULT_TABS = [
type Props (line 53) | interface Props<S, A extends Action<string>> {
class ActionPreview (line 77) | class ActionPreview<S, A extends Action<string>> extends Component<
method render (line 84) | render(): JSX.Element {
FILE: packages/redux-devtools-inspector-monitor/src/ActionPreviewHeader.tsx
type Props (line 26) | interface Props<S, A extends Action<string>> {
FILE: packages/redux-devtools-inspector-monitor/src/DevtoolsInspector.tsx
function getLastActionId (line 36) | function getLastActionId<S, A extends Action<string>>(
function getCurrentActionId (line 42) | function getCurrentActionId<S, A extends Action<string>>(
function getFromState (line 51) | function getFromState<S>(
function createIntermediateState (line 66) | function createIntermediateState<S, A extends Action<string>>(
type ExternalProps (line 119) | interface ExternalProps<S, A extends Action<string>> {
type DefaultProps (line 139) | interface DefaultProps {
type DevtoolsInspectorProps (line 147) | interface DevtoolsInspectorProps<
type State (line 170) | interface State<S, A extends Action<string>> {
class DevtoolsInspector (line 178) | class DevtoolsInspector<S, A extends Action<string>> extends PureComponent<
method componentDidMount (line 200) | componentDidMount() {
method componentWillUnmount (line 208) | componentWillUnmount() {
method updateSizeMode (line 216) | updateSizeMode() {
method UNSAFE_componentWillReceiveProps (line 224) | UNSAFE_componentWillReceiveProps(nextProps: DevtoolsInspectorProps<S, ...
method render (line 246) | render() {
FILE: packages/redux-devtools-inspector-monitor/src/RightSlider.tsx
type Props (line 3) | interface Props {
FILE: packages/redux-devtools-inspector-monitor/src/createDiffPatcher.ts
function createDiffPatcher (line 27) | function createDiffPatcher(
FILE: packages/redux-devtools-inspector-monitor/src/redux.ts
constant UPDATE_MONITOR_STATE (line 4) | const UPDATE_MONITOR_STATE =
type UpdateMonitorStateAction (line 7) | interface UpdateMonitorStateAction {
function updateMonitorState (line 11) | function updateMonitorState(
type DevtoolsInspectorAction (line 17) | type DevtoolsInspectorAction = UpdateMonitorStateAction;
type DevtoolsInspectorState (line 19) | interface DevtoolsInspectorState {
constant DEFAULT_STATE (line 28) | const DEFAULT_STATE: DevtoolsInspectorState = {
function reduceUpdateState (line 36) | function reduceUpdateState(
function reducer (line 48) | function reducer<S, A extends Action<string>>(
FILE: packages/redux-devtools-inspector-monitor/src/tabs/JSONDiff.tsx
function stringifyAndShrink (line 13) | function stringifyAndShrink(val: any, isWideLayout?: boolean) {
function prepareDelta (line 31) | function prepareDelta(value: any) {
type Props (line 61) | interface Props {
type State (line 70) | interface State {
class JSONDiff (line 74) | class JSONDiff extends Component<Props, State> {
method componentDidMount (line 77) | componentDidMount() {
method componentDidUpdate (line 81) | componentDidUpdate(prevProps: Props) {
method updateData (line 87) | updateData() {
method render (line 95) | render(): JSX.Element {
FILE: packages/redux-devtools-inspector-monitor/src/tabs/getItemString.tsx
constant IS_IMMUTABLE_KEY (line 6) | const IS_IMMUTABLE_KEY = '@@__IS_IMMUTABLE__@@';
function isImmutable (line 8) | function isImmutable(value: any) {
function getShortTypeString (line 12) | function getShortTypeString(val: any, diff: boolean | undefined) {
function getText (line 38) | function getText(
FILE: packages/redux-devtools-inspector-monitor/src/tabs/getJsonTreeTheme.ts
function getJsonTreeTheme (line 3) | function getJsonTreeTheme(
FILE: packages/redux-devtools-inspector-monitor/src/utils/getInspectedState.ts
function iterateToKey (line 4) | function iterateToKey(obj: any, key: string | number) {
function getInspectedState (line 18) | function getInspectedState<S>(
FILE: packages/redux-devtools-inspector-monitor/src/utils/isIterable.ts
function isIterable (line 1) | function isIterable(obj: any) {
FILE: packages/redux-devtools-inspector-monitor/src/utils/themes.ts
type Base16ThemeName (line 8) | type Base16ThemeName = keyof typeof base16Themes;
function resolveBase16Theme (line 10) | function resolveBase16Theme(theme: Base16ThemeName | Base16Theme) {
type Theme (line 18) | interface Theme {
function createInspectorMonitorThemeFromBase16Theme (line 71) | function createInspectorMonitorThemeFromBase16Theme(
FILE: packages/redux-devtools-instrument/src/getSymbolObservable.ts
function getSymbolObservable (line 1) | function getSymbolObservable() {
FILE: packages/redux-devtools-instrument/src/instrument.ts
type PerformAction (line 42) | interface PerformAction<A extends Action<string>> {
type ResetAction (line 49) | interface ResetAction {
type RollbackAction (line 54) | interface RollbackAction {
type CommitAction (line 59) | interface CommitAction {
type SweepAction (line 64) | interface SweepAction {
type ToggleAction (line 68) | interface ToggleAction {
type SetActionsActiveAction (line 73) | interface SetActionsActiveAction {
type ReorderAction (line 80) | interface ReorderAction {
type JumpToStateAction (line 86) | interface JumpToStateAction {
type JumpToActionAction (line 91) | interface JumpToActionAction {
type ImportStateAction (line 96) | interface ImportStateAction<S, A extends Action<string>, MonitorState> {
type LockChangesAction (line 103) | interface LockChangesAction {
type PauseRecordingAction (line 108) | interface PauseRecordingAction {
type LiftedAction (line 113) | type LiftedAction<S, A extends Action<string>, MonitorState> =
method performAction (line 132) | performAction<A extends Action<string>>(
method reset (line 204) | reset(this: void): ResetAction {
method rollback (line 208) | rollback(this: void): RollbackAction {
method commit (line 212) | commit(this: void): CommitAction {
method sweep (line 216) | sweep(this: void): SweepAction {
method toggleAction (line 220) | toggleAction(this: void, id: number): ToggleAction {
method setActionsActive (line 224) | setActionsActive(
method reorderAction (line 233) | reorderAction(
method jumpToState (line 241) | jumpToState(this: void, index: number): JumpToStateAction {
method jumpToAction (line 245) | jumpToAction(this: void, actionId: number): JumpToActionAction {
method importState (line 249) | importState<S, A extends Action<string>, MonitorState = null>(
method lockChanges (line 257) | lockChanges(this: void, status: boolean): LockChangesAction {
method pauseRecording (line 261) | pauseRecording(this: void, status: boolean): PauseRecordingAction {
constant INIT_ACTION (line 266) | const INIT_ACTION = { type: '@@INIT' };
function computeWithTryCatch (line 271) | function computeWithTryCatch<S, A extends Action<string>, PreloadedState>(
function computeNextEntry (line 301) | function computeNextEntry<S, A extends Action<string>, PreloadedState>(
function recomputeStates (line 316) | function recomputeStates<S, A extends Action<string>, PreloadedState>(
function liftAction (line 373) | function liftAction<A extends Action<string>>(
function isArray (line 388) | function isArray<S, A extends Action<string>, MonitorState>(
type LiftedState (line 394) | interface LiftedState<S, A extends Action<string>, MonitorState> {
function liftReducerWith (line 410) | function liftReducerWith<
function unliftState (line 851) | function unliftState<S, A extends Action<string>, MonitorState, NextStat...
type LiftedReducer (line 859) | type LiftedReducer<S, A extends Action<string>, MonitorState> = Reducer<
type LiftedStore (line 864) | type LiftedStore<S, A extends Action<string>, MonitorState> = Store<
type InstrumentExt (line 869) | type InstrumentExt<S, A extends Action<string>, MonitorState> = {
type EnhancedStore (line 873) | type EnhancedStore<S, A extends Action<string>, MonitorState> = Store<
function unliftStore (line 882) | function unliftStore<
type Options (line 980) | interface Options<
function instrument (line 1005) | function instrument<
FILE: packages/redux-devtools-instrument/test/instrument.spec.ts
type CounterAction (line 20) | type CounterAction = { type: 'INCREMENT' } | { type: 'DECREMENT' };
function counter (line 21) | function counter(state = 0, action: CounterAction) {
type CounterWithBugAction (line 32) | type CounterWithBugAction =
function counterWithBug (line 36) | function counterWithBug(state = 0, action: CounterWithBugAction) {
type CounterWithAnotherBugAction (line 51) | type CounterWithAnotherBugAction =
function counterWithAnotherBug (line 55) | function counterWithAnotherBug(state = 0, action: CounterWithBugAction) {
type DoubleCounterAction (line 70) | type DoubleCounterAction = { type: 'INCREMENT' } | { type: 'DECREMENT' };
function doubleCounter (line 71) | function doubleCounter(state = 0, action: DoubleCounterAction) {
type CounterWithMultiplyAction (line 82) | type CounterWithMultiplyAction =
function counterWithMultiply (line 86) | function counterWithMultiply(state = 0, action: CounterWithMultiplyActio...
function ActionClass (line 383) | function ActionClass(this: any) {
function fn1 (line 825) | function fn1() {
function fn2 (line 850) | function fn2() {
function fn3 (line 854) | function fn3() {
function fn4 (line 858) | function fn4() {
function fn1 (line 866) | function fn1() {
function fn2 (line 889) | function fn2() {
function fn3 (line 893) | function fn3() {
function fn4 (line 897) | function fn4() {
function fn1 (line 908) | function fn1() {
function fn2 (line 931) | function fn2() {
function fn3 (line 935) | function fn3() {
function fn4 (line 939) | function fn4() {
function fn1 (line 974) | function fn1() {
function fn2 (line 998) | function fn2() {
function fn3 (line 1002) | function fn3() {
function fn4 (line 1006) | function fn4() {
function filterStackAndTimestamps (line 1171) | function filterStackAndTimestamps<S, A extends Action<string>>(
FILE: packages/redux-devtools-log-monitor/src/LogMonitor.tsx
type ExternalProps (line 46) | interface ExternalProps<S, A extends Action<string>> {
type DefaultProps (line 58) | interface DefaultProps<S> {
type LogMonitorProps (line 67) | interface LogMonitorProps<
class LogMonitor (line 82) | class LogMonitor<S, A extends Action<string>> extends PureComponent<
method scroll (line 104) | scroll() {
method componentDidMount (line 116) | componentDidMount() {
method componentWillUnmount (line 131) | componentWillUnmount() {
method UNSAFE_componentWillReceiveProps (line 138) | UNSAFE_componentWillReceiveProps(nextProps: LogMonitorProps<S, A>) {
method componentDidUpdate (line 154) | componentDidUpdate() {
method getTheme (line 177) | getTheme() {
method render (line 198) | render() {
FILE: packages/redux-devtools-log-monitor/src/LogMonitorButton.tsx
type State (line 23) | interface State {
type Props (line 28) | interface Props {
class LogMonitorButton (line 35) | class LogMonitorButton extends React.PureComponent<
method render (line 69) | render() {
FILE: packages/redux-devtools-log-monitor/src/LogMonitorButtonBar.tsx
type Props (line 21) | interface Props<S, A extends Action<string>> {
class LogMonitorButtonBar (line 28) | class LogMonitorButtonBar<
method render (line 48) | render() {
FILE: packages/redux-devtools-log-monitor/src/LogMonitorEntry.tsx
type Props (line 31) | interface Props<S, A extends Action<string>> {
class LogMonitorEntry (line 49) | class LogMonitorEntry<
method printState (line 53) | printState(state: S, error: string | undefined) {
method render (line 144) | render() {
FILE: packages/redux-devtools-log-monitor/src/LogMonitorEntryAction.tsx
type Props (line 20) | interface Props<A extends Action<string>> {
class LogMonitorAction (line 29) | class LogMonitorAction<
method renderPayload (line 32) | renderPayload(payload: Record<string, unknown>) {
method render (line 63) | render() {
FILE: packages/redux-devtools-log-monitor/src/LogMonitorEntryList.tsx
type Props (line 7) | interface Props<S, A extends Action<string>> {
class LogMonitorEntryList (line 24) | class LogMonitorEntryList<
method render (line 28) | render() {
FILE: packages/redux-devtools-log-monitor/src/actions.ts
constant UPDATE_SCROLL_TOP (line 1) | const UPDATE_SCROLL_TOP =
type UpdateScrollTopAction (line 3) | interface UpdateScrollTopAction {
function updateScrollTop (line 7) | function updateScrollTop(scrollTop: number): UpdateScrollTopAction {
constant START_CONSECUTIVE_TOGGLE (line 11) | const START_CONSECUTIVE_TOGGLE =
type StartConsecutiveToggleAction (line 13) | interface StartConsecutiveToggleAction {
function startConsecutiveToggle (line 17) | function startConsecutiveToggle(
type LogMonitorAction (line 23) | type LogMonitorAction =
FILE: packages/redux-devtools-log-monitor/src/reducers.ts
function initialScrollTop (line 9) | function initialScrollTop<S, A extends Action<string>>(
function startConsecutiveToggle (line 21) | function startConsecutiveToggle<S, A extends Action<string>>(
type LogMonitorState (line 29) | interface LogMonitorState {
function reducer (line 34) | function reducer<S, A extends Action<string>>(
FILE: packages/redux-devtools-remote/src/configureStore.ts
function configureStore (line 4) | function configureStore<
FILE: packages/redux-devtools-remote/src/devTools.ts
function async (line 33) | function async(fn: () => unknown) {
function str2array (line 37) | function str2array(
function getRandomId (line 47) | function getRandomId() {
type AutoReconnectOptions (line 51) | interface AutoReconnectOptions {
type SocketOptions (line 55) | interface SocketOptions {
type Filters (line 63) | interface Filters {
type Options (line 76) | interface Options<S, A extends Action<string>> {
type MessageToRelay (line 116) | interface MessageToRelay {
type ImportMessage (line 127) | interface ImportMessage {
type SyncMessage (line 132) | interface SyncMessage {
type UpdateMessage (line 139) | interface UpdateMessage {
type StartMessage (line 143) | interface StartMessage {
type StopMessage (line 147) | interface StopMessage {
type DisconnectedMessage (line 151) | interface DisconnectedMessage {
type ActionMessage (line 155) | interface ActionMessage {
type DispatchMessage (line 160) | interface DispatchMessage<S, A extends Action<string>> {
type Message (line 166) | type Message<S, A extends Action<string>> =
class DevToolsEnhancer (line 176) | class DevToolsEnhancer<S, A extends Action<string>, PreloadedState> {
method getLiftedStateRaw (line 204) | getLiftedStateRaw() {
method getLiftedState (line 208) | getLiftedState() {
method relay (line 235) | relay(
method dispatchRemotely (line 286) | dispatchRemotely(
method init (line 343) | init(options: Options<S, A>) {
method login (line 392) | login() {
method handleChange (line 514) | handleChange(state: S, liftedState: LiftedState<S, A, {}>, maxAge: num...
function preEnhancer (line 593) | function preEnhancer(createStore: StoreEnhancerStoreCreator) {
function composeWithDevTools (line 617) | function composeWithDevTools(
FILE: packages/redux-devtools-rtk-query-monitor/demo/public/mockServiceWorker.js
constant PACKAGE_VERSION (line 10) | const PACKAGE_VERSION = '2.12.10'
constant INTEGRITY_CHECKSUM (line 11) | const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
constant IS_MOCKED_RESPONSE (line 12) | const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
function handleRequest (line 124) | async function handleRequest(event, requestId, requestInterceptedAt) {
function resolveMainClient (line 177) | async function resolveMainClient(event) {
function getResponse (line 211) | async function getResponse(event, client, requestId, requestInterceptedA...
function sendToClient (line 288) | function sendToClient(client, message, transferrables = []) {
function respondWithMock (line 311) | function respondWithMock(response) {
function serializeRequest (line 333) | async function serializeRequest(request) {
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/App.tsx
function App (line 9) | function App() {
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/components/ui/provider.tsx
function Provider (line 6) | function Provider({ children }: { children: React.ReactNode }) {
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/features/DevTools/DevToolsSelector.tsx
function DevToolsSelector (line 6) | function DevToolsSelector() {
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/features/DevTools/helpers.ts
function isExtensionEnabled (line 3) | function isExtensionEnabled(): boolean {
function setIsExtensionEnabled (line 16) | function setIsExtensionEnabled(active: boolean): void {
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/features/pokemon/Pokemon.tsx
function Pokemon (line 16) | function Pokemon({ name }: { name: PokemonName }) {
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/features/pokemon/PokemonView.tsx
function PokemonView (line 9) | function PokemonView() {
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/features/posts/PostsView.tsx
function PostsView (line 6) | function PostsView() {
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/index.tsx
function renderApp (line 13) | function renderApp() {
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/pokemon.data.ts
constant POKEMON_NAMES (line 1) | const POKEMON_NAMES = [
type PokemonName (line 155) | type PokemonName = (typeof POKEMON_NAMES)[number];
FILE: packages/redux-devtools-rtk-query-monitor/demo/src/services/posts.ts
type Post (line 3) | interface Post {
type PostsResponse (line 8) | type PostsResponse = Post[];
method query (line 46) | query(id) {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/ArrowUpIcon.tsx
type ArrowUpIconProps (line 3) | type ArrowUpIconProps = Omit<
function ArrowUpIcon (line 12) | function ArrowUpIcon(props: ArrowUpIconProps): React.JSX.Element {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/NoRtkQueryApi.tsx
function NoRtkQueryApi (line 3) | function NoRtkQueryApi(): React.JSX.Element {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/QueryForm.tsx
type QueryFormProps (line 25) | interface QueryFormProps {
type QueryFormState (line 31) | interface QueryFormState {
class QueryForm (line 47) | class QueryForm extends React.PureComponent<
method constructor (line 51) | constructor(props: QueryFormProps) {
method render (line 121) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/QueryList.tsx
type QueryListProps (line 21) | interface QueryListProps {
class QueryList (line 27) | class QueryList extends PureComponent<QueryListProps> {
method isItemSelected (line 28) | static isItemSelected(
method formatQuery (line 39) | static formatQuery(resInfo: RtkResourceInfo): string {
method render (line 48) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewActions.tsx
type QueryPreviewActionsProps (line 10) | interface QueryPreviewActionsProps {
class QueryPreviewActions (line 23) | class QueryPreviewActions extends PureComponent<QueryPreviewActionsProps> {
method render (line 81) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewApi.tsx
type QueryPreviewApiProps (line 7) | interface QueryPreviewApiProps {
class QueryPreviewApi (line 19) | class QueryPreviewApi extends PureComponent<QueryPreviewApiProps> {
method render (line 30) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewData.tsx
type QueryPreviewDataProps (line 7) | interface QueryPreviewDataProps {
class QueryPreviewData (line 18) | class QueryPreviewData extends PureComponent<QueryPreviewDataProps> {
method render (line 27) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewHeader.tsx
type QueryPreviewHeaderProps (line 6) | interface QueryPreviewHeaderProps {
class QueryPreviewHeader (line 15) | class QueryPreviewHeader extends React.Component<QueryPreviewHeaderProps> {
method render (line 22) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewInfo.tsx
type QueryTimings (line 12) | type QueryTimings = {
type FormattedQuery (line 18) | type FormattedQuery = {
type QueryPreviewInfoProps (line 34) | interface QueryPreviewInfoProps {
class QueryPreviewInfo (line 38) | class QueryPreviewInfo extends PureComponent<QueryPreviewInfoProps> {
method render (line 102) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewSubscriptions.tsx
type QueryPreviewSubscriptionsProps (line 14) | interface QueryPreviewSubscriptionsProps {
class QueryPreviewSubscriptions (line 19) | class QueryPreviewSubscriptions extends PureComponent<QueryPreviewSubscr...
method render (line 20) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewTags.tsx
type QueryPreviewTagsState (line 6) | interface QueryPreviewTagsState {
type QueryPreviewTagsProps (line 16) | interface QueryPreviewTagsProps {
class QueryPreviewTags (line 21) | class QueryPreviewTags extends PureComponent<
method constructor (line 25) | constructor(props: QueryPreviewTagsProps) {
method render (line 33) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/RegexIcon.tsx
type RegexIconProps (line 3) | type RegexIconProps = Omit<
function RegexIcon (line 10) | function RegexIcon(
FILE: packages/redux-devtools-rtk-query-monitor/src/components/SortOrderButton.tsx
type SortOrderButtonProps (line 4) | interface SortOrderButtonProps {
function SortOrderButton (line 10) | function SortOrderButton({
FILE: packages/redux-devtools-rtk-query-monitor/src/components/TreeView.tsx
type TreeViewProps (line 9) | interface TreeViewProps extends Partial<
class TreeView (line 25) | class TreeView extends React.PureComponent<TreeViewProps> {
method constructor (line 46) | constructor(props: TreeViewProps) {
method render (line 50) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/components/UList.tsx
type UListProps (line 3) | type UListProps = React.HTMLAttributes<HTMLUListElement>;
function UList (line 5) | function UList(props: UListProps): React.JSX.Element {
FILE: packages/redux-devtools-rtk-query-monitor/src/containers/QueryPreview.tsx
type QueryPreviewProps (line 56) | interface QueryPreviewProps<S = unknown> {
type QueryPreviewTabProps (line 69) | type QueryPreviewTabProps = Omit<QueryPreviewProps<unknown>, 'resInfo'> & {
class QueryPreview (line 179) | class QueryPreview<S> extends React.PureComponent<QueryPreviewProps<S>> {
method render (line 209) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/containers/RtkQueryInspector.tsx
type ForwardedMonitorProps (line 24) | type ForwardedMonitorProps<S, A extends Action<string>> = Pick<
type RtkQueryInspectorProps (line 29) | interface RtkQueryInspectorProps<
type RtkQueryInspectorState (line 36) | type RtkQueryInspectorState<S> = {
class RtkQueryInspector (line 41) | class RtkQueryInspector<S, A extends Action<string>> extends PureComponent<
method constructor (line 49) | constructor(props: RtkQueryInspectorProps<S, A>) {
method getDerivedStateFromProps (line 60) | static getDerivedStateFromProps(
method componentDidMount (line 91) | componentDidMount(): void {
method componentWillUnmount (line 97) | componentWillUnmount(): void {
method render (line 133) | render(): ReactNode {
FILE: packages/redux-devtools-rtk-query-monitor/src/containers/RtkQueryMonitor.tsx
type DefaultProps (line 17) | interface DefaultProps {
class RtkQueryMonitor (line 22) | class RtkQueryMonitor<S, A extends Action<string>> extends Component<
method render (line 32) | render() {
FILE: packages/redux-devtools-rtk-query-monitor/src/containers/mapProps.tsx
type Mapper (line 3) | interface Mapper<In, Out> {
type MapPropsOutput (line 7) | interface MapPropsOutput<In, Out> {
function mapProps (line 11) | function mapProps<In, Out>(
FILE: packages/redux-devtools-rtk-query-monitor/src/monitor-config.ts
constant DATA_TYPE_KEY (line 1) | const DATA_TYPE_KEY = Symbol.for('__serializedType__');
FILE: packages/redux-devtools-rtk-query-monitor/src/reducers.ts
method changeQueryFormValues (line 35) | changeQueryFormValues(
method selectQueryKey (line 41) | selectQueryKey(
method selectedPreviewTab (line 50) | selectedPreviewTab(state, action: PayloadAction<QueryPreviewTabs>) {
function reducer (line 56) | function reducer<S, A extends Action<string>>(
FILE: packages/redux-devtools-rtk-query-monitor/src/selectors.ts
type InspectorSelector (line 28) | type InspectorSelector<S, Output> = Selector<SelectorsSource<S>, Output>;
function computeSelectorSource (line 30) | function computeSelectorSource<S, A extends Action<string>>(
type InspectorSelectors (line 57) | interface InspectorSelectors<S> {
function createInspectorSelectors (line 90) | function createInspectorSelectors<S>(): InspectorSelectors<S> {
FILE: packages/redux-devtools-rtk-query-monitor/src/styles/themes.ts
function resolveBase16Theme (line 11) | function resolveBase16Theme(
type Theme (line 21) | interface Theme {
function createRtkQueryMonitorThemeFromBase16Theme (line 89) | function createRtkQueryMonitorThemeFromBase16Theme(
function getJsonTreeTheme (line 104) | function getJsonTreeTheme(base16Theme: Base16Theme): StylingConfig {
FILE: packages/redux-devtools-rtk-query-monitor/src/styles/tree.tsx
constant IS_IMMUTABLE_KEY (line 7) | const IS_IMMUTABLE_KEY = '@@__IS_IMMUTABLE__@@';
function isImmutable (line 9) | function isImmutable(value: unknown) {
function getShortTypeString (line 13) | function getShortTypeString(val: unknown, diff: boolean | undefined) {
function getText (line 41) | function getText(
FILE: packages/redux-devtools-rtk-query-monitor/src/types.ts
type QueryPreviewTabs (line 14) | enum QueryPreviewTabs {
type QueryFormValues (line 23) | interface QueryFormValues {
type RtkQueryMonitorState (line 30) | interface RtkQueryMonitorState {
type RtkQueryMonitorProps (line 38) | interface RtkQueryMonitorProps<
type RtkQueryApiState (line 47) | type RtkQueryApiState = ReturnType<
type RtkQueryState (line 51) | type RtkQueryState = NonNullable<
type RtkMutationState (line 55) | type RtkMutationState = NonNullable<
type RtkQueryApiConfig (line 59) | type RtkQueryApiConfig = RtkQueryApiState['config'];
type FullTagDescription (line 61) | type FullTagDescription<TagType> = {
type RtkQueryProvidedTagsState (line 68) | type RtkQueryProvidedTagsState = {
type RtkQuery262ProvidedState (line 77) | type RtkQuery262ProvidedState = {
function isRtkQuery262Provided (line 82) | function isRtkQuery262Provided(
type ExternalProps (line 93) | interface ExternalProps<S, A extends Action<string>> {
type QueryInfo (line 100) | interface QueryInfo {
type MutationInfo (line 107) | interface MutationInfo {
type RtkResourceInfo (line 114) | type RtkResourceInfo = QueryInfo | MutationInfo;
type ApiInfo (line 116) | interface ApiInfo {
type SelectOption (line 121) | interface SelectOption<
type SelectorsSource (line 130) | interface SelectorsSource<S> {
type StyleUtils (line 137) | interface StyleUtils {
type RTKQuerySubscribers (line 142) | type RTKQuerySubscribers = NonNullable<
type RtkQueryTag (line 146) | interface RtkQueryTag {
type Tally (line 151) | interface Tally {
type QueryTally (line 155) | type QueryTally = {
type RtkRequestTiming (line 159) | interface RtkRequestTiming {
type QueryTimings (line 168) | interface QueryTimings {
type ApiTimings (line 177) | interface ApiTimings {
type ApiStats (line 182) | interface ApiStats {
type TabOption (line 192) | interface TabOption<
type RTKStatusFlags (line 203) | interface RTKStatusFlags {
type RtkRequest (line 210) | type RtkRequest = {
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/a11y.ts
function renderTabPanelId (line 3) | function renderTabPanelId(value: QueryPreviewTabs): string {
function renderTabPanelButtonId (line 7) | function renderTabPanelButtonId(value: QueryPreviewTabs): string {
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/comparators.ts
type Comparator (line 4) | interface Comparator<T> {
type QueryComparators (line 8) | enum QueryComparators {
function sortQueryByFulfilled (line 24) | function sortQueryByFulfilled(
function sortQueryByStatus (line 41) | function sortQueryByStatus(
function compareJSONPrimitive (line 51) | function compareJSONPrimitive<
function sortByQueryKey (line 64) | function sortByQueryKey(
function sortQueryByEndpointName (line 71) | function sortQueryByEndpointName(
function sortByApiReducerPath (line 81) | function sortByApiReducerPath(
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/filters.ts
type FilterList (line 3) | interface FilterList<T> {
type QueryFilters (line 7) | enum QueryFilters {
function filterByQueryKey (line 14) | function filterByQueryKey(
function filterByReducerPath (line 25) | function filterByReducerPath(
function filterByEndpointName (line 38) | function filterByEndpointName(
function filterByStatus (line 51) | function filterByStatus(
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/formatters.ts
function formatMs (line 1) | function formatMs(milliseconds: number): string {
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/isIterable.ts
function isIterable (line 1) | function isIterable(obj: unknown): boolean {
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/object.ts
function identity (line 7) | function identity<T>(val: T): T {
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/regexp.ts
function escapeRegExpSpecialCharacter (line 2) | function escapeRegExpSpecialCharacter(text: string): string {
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/rtk-query.ts
function isApiSlice (line 44) | function isApiSlice(val: unknown): val is RtkQueryApiState {
function getApiStatesOf (line 69) | function getApiStatesOf(
function extractAllApiQueries (line 95) | function extractAllApiQueries(
function extractAllApiMutations (line 129) | function extractAllApiMutations(
function computeQueryTallyOf (line 162) | function computeQueryTallyOf(
function tallySubscriptions (line 188) | function tallySubscriptions(
function computeRtkQueryRequests (line 206) | function computeRtkQueryRequests(
function formatRtkRequest (line 326) | function formatRtkRequest(
function computeQueryApiTimings (line 357) | function computeQueryApiTimings(
function computeApiTimings (line 428) | function computeApiTimings(
function generateApiStatsOfCurrentQuery (line 459) | function generateApiStatsOfCurrentQuery(
function flipComparator (line 479) | function flipComparator<T>(comparator: Comparator<T>): Comparator<T> {
function isQuerySelected (line 485) | function isQuerySelected(
function getApiStateOf (line 496) | function getApiStateOf(
function getQuerySubscriptionsOf (line 507) | function getQuerySubscriptionsOf(
function getProvidedOf (line 521) | function getProvidedOf(
function getQueryTagsOf (line 532) | function getQueryTagsOf(
function getQueryStatusFlags (line 585) | function getQueryStatusFlags({
function matchesEndpoint (line 602) | function matchesEndpoint(endpointName: unknown) {
function matchesQueryKey (line 607) | function matchesQueryKey(queryKey: string) {
function macthesRequestId (line 612) | function macthesRequestId(requestId: string) {
function matchesReducerPath (line 617) | function matchesReducerPath(reducerPath: string) {
function matchesExecuteQuery (line 622) | function matchesExecuteQuery(reducerPath: string) {
function matchesExecuteMutation (line 637) | function matchesExecuteMutation(reducerPath: string) {
function getActionsOfCurrentQuery (line 649) | function getActionsOfCurrentQuery(
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/statistics.ts
function sum (line 8) | function sum(nums: number[]): number {
function mean (line 37) | function mean(nums: number[]): number {
function median (line 50) | function median(nums: number[]): number {
FILE: packages/redux-devtools-rtk-query-monitor/src/utils/tabs.ts
function isTabVisible (line 3) | function isTabVisible<St, Props, Vis extends string>(
FILE: packages/redux-devtools-rtk-query-monitor/test/integration.spec.tsx
function Providers (line 8) | function Providers({
FILE: packages/redux-devtools-rtk-query-monitor/test/rtk-query.mocks.ts
type MockBaseQuery (line 10) | type MockBaseQuery<
type BaseQueryJestMockFunction (line 16) | type BaseQueryJestMockFunction<Result> = jest.Mock<
function createMockBaseQuery (line 21) | function createMockBaseQuery<Result>(
function createPokemonApi (line 37) | function createPokemonApi(
function setupStore (line 57) | function setupStore(
FILE: packages/redux-devtools-serialize/src/helpers/index.ts
type SerializedData (line 1) | interface SerializedData {
function mark (line 18) | function mark<K extends string>(
function extract (line 31) | function extract(data: unknown, type: string): SerializedData {
function refer (line 51) | function refer<K extends string>(
FILE: packages/redux-devtools-serialize/src/immutable/serialize.ts
function serialize (line 7) | function serialize(
FILE: packages/redux-devtools-serialize/src/types.ts
type SerializedImmutableMap (line 1) | interface SerializedImmutableMap {
type SerializedImmutableOrderedMap (line 6) | interface SerializedImmutableOrderedMap {
type SerializedImmutableList (line 11) | interface SerializedImmutableList {
type SerializedImmutableRangeData (line 16) | interface SerializedImmutableRangeData {
type SerializedImmutableRange (line 21) | interface SerializedImmutableRange {
type SerializedImmutableRepeatData (line 26) | interface SerializedImmutableRepeatData {
type SerializedImmutableRepeat (line 30) | interface SerializedImmutableRepeat {
type SerializedImmutableSet (line 35) | interface SerializedImmutableSet {
type SerializedImmutableOrderedSet (line 40) | interface SerializedImmutableOrderedSet {
type SerializedImmutableSeq (line 45) | interface SerializedImmutableSeq {
type SerializedImmutableStack (line 50) | interface SerializedImmutableStack {
type SerializedImmutableRecord (line 55) | interface SerializedImmutableRecord {
type SerializedImmutableData (line 61) | type SerializedImmutableData =
FILE: packages/redux-devtools-serialize/test/immutable.spec.ts
function customReplacer (line 112) | function customReplacer(
function customReviver (line 123) | function customReviver(
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/actions/TodoActions.ts
type AddTodoAction (line 3) | interface AddTodoAction {
function addTodo (line 7) | function addTodo(text: string): AddTodoAction {
type DeleteTodoAction (line 14) | interface DeleteTodoAction {
function deleteTodo (line 18) | function deleteTodo(id: number): DeleteTodoAction {
type EditTodoAction (line 25) | interface EditTodoAction {
function editTodo (line 30) | function editTodo(id: number, text: string): EditTodoAction {
type MarkTodoAction (line 38) | interface MarkTodoAction {
function markTodo (line 42) | function markTodo(id: number): MarkTodoAction {
type MarkAllAction (line 49) | interface MarkAllAction {
function markAll (line 52) | function markAll(): MarkAllAction {
type ClearMarkedAction (line 58) | interface ClearMarkedAction {
function clearMarked (line 61) | function clearMarked(): ClearMarkedAction {
type TodoAction (line 67) | type TodoAction =
type TodoActions (line 75) | interface TodoActions {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/components/Footer.tsx
constant FILTER_TITLES (line 10) | const FILTER_TITLES = {
type Props (line 16) | interface Props {
class Footer (line 24) | class Footer extends Component<Props> {
method render (line 25) | render() {
method renderTodoCount (line 39) | renderTodoCount() {
method renderFilterLink (line 50) | renderFilterLink(filter: TodoFilter) {
method renderClearButton (line 65) | renderClearButton() {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/components/Header.tsx
type Props (line 4) | interface Props {
class Header (line 8) | class Header extends Component<Props> {
method render (line 15) | render() {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/components/MainSection.tsx
constant TODO_FILTERS (line 13) | const TODO_FILTERS = {
type State (line 19) | interface State {
type Props (line 23) | interface Props {
class MainSection (line 28) | class MainSection extends Component<Props, State> {
method render (line 42) | render() {
method renderToggleAll (line 65) | renderToggleAll(markedCount: number) {
method renderFooter (line 80) | renderFooter(markedCount: number) {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/components/TodoItem.tsx
type State (line 6) | interface State {
type Props (line 10) | interface Props {
class TodoItem (line 20) | class TodoItem extends Component<Props, State> {
method render (line 38) | render() {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/components/TodoTextInput.tsx
type State (line 9) | interface State {
type Props (line 13) | interface Props {
class TodoTextInput (line 21) | class TodoTextInput extends Component<Props, State> {
method render (line 53) | render() {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/constants/ActionTypes.ts
constant ADD_TODO (line 1) | const ADD_TODO = 'ADD_TODO';
constant DELETE_TODO (line 2) | const DELETE_TODO = 'DELETE_TODO';
constant EDIT_TODO (line 3) | const EDIT_TODO = 'EDIT_TODO';
constant MARK_TODO (line 4) | const MARK_TODO = 'MARK_TODO';
constant MARK_ALL (line 5) | const MARK_ALL = 'MARK_ALL';
constant CLEAR_MARKED (line 6) | const CLEAR_MARKED = 'CLEAR_MARKED';
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/constants/TodoFilters.ts
constant SHOW_ALL (line 1) | const SHOW_ALL = 'show_all';
constant SHOW_MARKED (line 2) | const SHOW_MARKED = 'show_marked';
constant SHOW_UNMARKED (line 3) | const SHOW_UNMARKED = 'show_unmarked';
type TodoFilter (line 5) | type TodoFilter =
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/containers/Root.dev.tsx
type Props (line 9) | interface Props {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/containers/Root.prod.tsx
type Props (line 8) | interface Props {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/containers/Root.ts
type Props (line 6) | interface Props {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/containers/TodoApp.tsx
type Props (line 14) | interface Props {
function mapState (line 26) | function mapState(state: TodoState) {
function mapDispatch (line 32) | function mapDispatch(dispatch: Dispatch<TodoAction>) {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/reducers/index.ts
type TodoState (line 5) | interface TodoState {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/reducers/todos.ts
type Todo (line 11) | interface Todo {
function todos (line 25) | function todos(state = initialState, action: TodoAction) {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/store/configureStore.dev.ts
function getDebugSessionKey (line 6) | function getDebugSessionKey() {
function configureStore (line 16) | function configureStore(initialState?: Partial<TodoState>) {
FILE: packages/redux-devtools-slider-monitor/examples/todomvc/src/store/configureStore.prod.ts
function configureStore (line 4) | function configureStore(initialState?: Partial<TodoState>) {
FILE: packages/redux-devtools-slider-monitor/src/SliderButton.tsx
type Props (line 5) | interface Props {
class SliderButton (line 12) | class SliderButton extends (PureComponent || Component)<Props> {
method iconStyle (line 13) | iconStyle() {
method renderPlayButton (line 22) | renderPlayButton() {
method render (line 91) | render() {
FILE: packages/redux-devtools-slider-monitor/src/SliderMonitor.tsx
type ExternalProps (line 23) | interface ExternalProps<S, A extends Action<string>> {
type DefaultProps (line 33) | interface DefaultProps {
type SliderMonitorProps (line 40) | interface SliderMonitorProps<S, A extends Action<string>> // eslint-disa...
type State (line 51) | interface State {
class SliderMonitor (line 56) | class SliderMonitor<S, A extends Action<string>> extends (PureComponent ||
method componentDidMount (line 72) | componentDidMount() {
method componentWillUnmount (line 78) | componentWillUnmount() {
method render (line 301) | render() {
FILE: packages/redux-devtools-slider-monitor/src/reducers.ts
function reducer (line 1) | function reducer() {
FILE: packages/redux-devtools-ui/.storybook/main.ts
function getAbsolutePath (line 10) | function getAbsolutePath(packageName: string) {
FILE: packages/redux-devtools-ui/src/Button/Button.stories.tsx
type Story (line 22) | type Story = StoryObj<typeof Button>;
FILE: packages/redux-devtools-ui/src/Button/Button.tsx
type TooltipPosition (line 11) | type TooltipPosition =
type Size (line 21) | type Size = 'big' | 'normal' | 'small';
type Mark (line 23) | type Mark =
type ButtonProps (line 33) | interface ButtonProps {
class Button (line 46) | class Button extends Component<ButtonProps> {
method shouldComponentUpdate (line 47) | shouldComponentUpdate(nextProps: ButtonProps) {
method render (line 63) | render() {
FILE: packages/redux-devtools-ui/src/Button/styles/common.ts
type CommonStyleProps (line 132) | interface CommonStyleProps {
type TooltipStyleProps (line 178) | interface TooltipStyleProps {
FILE: packages/redux-devtools-ui/src/Button/styles/default.ts
type StyleProps (line 4) | interface StyleProps {
FILE: packages/redux-devtools-ui/src/Container/index.tsx
type ContainerFromThemeDataProps (line 7) | interface ContainerFromThemeDataProps {
type Props (line 26) | interface Props {
FILE: packages/redux-devtools-ui/src/ContextMenu/ContextMenu.stories.tsx
type Story (line 22) | type Story = StoryObj<typeof ContextMenu>;
FILE: packages/redux-devtools-ui/src/ContextMenu/ContextMenu.tsx
type ReactButtonElement (line 7) | type ReactButtonElement = React.ReactElement<
type Item (line 11) | type Item = { name: string; value?: string } | ReactButtonElement;
function isReactButtonElement (line 13) | function isReactButtonElement(item: Item): item is ReactButtonElement {
type ContextMenuProps (line 17) | interface ContextMenuProps {
class ContextMenu (line 25) | class ContextMenu extends Component<ContextMenuProps> {
method componentDidMount (line 28) | componentDidMount() {
method componentDidUpdate (line 32) | componentDidUpdate(prevProps: ContextMenuProps) {
method amendPosition (line 46) | amendPosition() {
method renderItems (line 71) | renderItems() {
method render (line 92) | render() {
FILE: packages/redux-devtools-ui/src/ContextMenu/styles/index.ts
type StyleProps (line 4) | interface StyleProps {
FILE: packages/redux-devtools-ui/src/Dialog/Dialog.stories.tsx
type Story (line 13) | type Story = StoryObj<typeof Dialog>;
FILE: packages/redux-devtools-ui/src/Dialog/Dialog.tsx
type DialogProps (line 11) | interface DialogProps {
type Rest (line 28) | type Rest<P> = Omit<
function isForm (line 41) | function isForm<P>(rest?: FormProps<P>): rest is FormProps<P> {
class Dialog (line 45) | class Dialog<P> extends PureComponent<
method render (line 66) | render() {
FILE: packages/redux-devtools-ui/src/Dialog/styles/default.ts
type StyleProps (line 4) | interface StyleProps {
FILE: packages/redux-devtools-ui/src/Editor/Editor.stories.tsx
type Story (line 21) | type Story = StoryObj<typeof Editor>;
FILE: packages/redux-devtools-ui/src/Editor/Editor.tsx
type EditorProps (line 19) | interface EditorProps {
function Editor (line 28) | function Editor({
FILE: packages/redux-devtools-ui/src/Editor/WithTabs.tsx
type WithTabsProps (line 13) | interface WithTabsProps {
type TabProps (line 18) | interface TabProps {
class WithTabs (line 23) | class WithTabs extends Component<WithTabsProps> {
method render (line 28) | render() {
FILE: packages/redux-devtools-ui/src/Form/Form.stories.tsx
type Story (line 12) | type Story = StoryObj<typeof Form>;
FILE: packages/redux-devtools-ui/src/Form/Form.tsx
type Props (line 12) | interface Props<T> extends Omit<FormProps<T>, 'validator'> {
class Form (line 23) | class Form<T> extends (PureComponent || Component)<Props<T>> {
method render (line 24) | render() {
FILE: packages/redux-devtools-ui/src/Notification/Notification.stories.tsx
type Story (line 21) | type Story = StoryObj<typeof Notification>;
FILE: packages/redux-devtools-ui/src/Notification/Notification.tsx
type Type (line 12) | type Type = 'info' | 'success' | 'warning' | 'error';
type NotificationProps (line 14) | interface NotificationProps {
class Notification (line 21) | class Notification extends Component<NotificationProps> {
method shouldComponentUpdate (line 22) | shouldComponentUpdate(nextProps: NotificationProps) {
method render (line 42) | render() {
FILE: packages/redux-devtools-ui/src/Notification/styles/index.ts
type StyleProps (line 18) | interface StyleProps {
FILE: packages/redux-devtools-ui/src/SegmentedControl/SegmentedControl.stories.tsx
type Story (line 21) | type Story = StoryObj<typeof SegmentedControl>;
FILE: packages/redux-devtools-ui/src/SegmentedControl/SegmentedControl.tsx
type SegmentedControlProps (line 8) | interface SegmentedControlProps {
class SegmentedControl (line 16) | class SegmentedControl extends Component<SegmentedControlProps> {
method shouldComponentUpdate (line 17) | shouldComponentUpdate(nextProps: SegmentedControlProps) {
method render (line 32) | render() {
FILE: packages/redux-devtools-ui/src/SegmentedControl/styles/index.ts
type StyleProps (line 5) | interface StyleProps {
FILE: packages/redux-devtools-ui/src/Select/Select.stories.tsx
type Story (line 26) | type Story = StoryObj<typeof Select>;
FILE: packages/redux-devtools-ui/src/Select/Select.tsx
type SelectProps (line 9) | interface SelectProps<
class Select (line 20) | class Select<
method render (line 25) | render() {
type ExternalSelectProps (line 84) | interface ExternalSelectProps<
type SelectComponent (line 92) | type SelectComponent = <
FILE: packages/redux-devtools-ui/src/Slider/Slider.stories.tsx
type Story (line 21) | type Story = StoryObj<typeof Slider>;
FILE: packages/redux-devtools-ui/src/Slider/Slider.tsx
type SliderProps (line 10) | interface SliderProps {
class Slider (line 22) | class Slider extends Component<SliderProps> {
method shouldComponentUpdate (line 23) | shouldComponentUpdate(nextProps: SliderProps) {
method render (line 38) | render() {
FILE: packages/redux-devtools-ui/src/Slider/styles/default.ts
type StyleProps (line 13) | interface StyleProps {
FILE: packages/redux-devtools-ui/src/Tabs/Tabs.stories.tsx
type Story (line 23) | type Story = StoryObj<typeof Tabs>;
FILE: packages/redux-devtools-ui/src/Tabs/Tabs.tsx
type Position (line 5) | type Position = 'left' | 'right' | 'center';
type TabsProps (line 7) | interface TabsProps<P> {
class Tabs (line 16) | class Tabs<P extends object> extends Component<TabsProps<P>> {
method renderTabs (line 28) | renderTabs() {
method render (line 56) | render() {
FILE: packages/redux-devtools-ui/src/Tabs/TabsHeader.tsx
type ReactButtonElement (line 10) | type ReactButtonElement = React.ReactElement<
type Tab (line 15) | interface Tab<P> {
type Props (line 22) | interface Props<P> {
type State (line 32) | interface State {
class TabsHeader (line 39) | class TabsHeader<P> extends Component<Props<P>, State> {
method UNSAFE_componentWillReceiveProps (line 53) | UNSAFE_componentWillReceiveProps(nextProps: Props<P>) {
method componentDidMount (line 63) | componentDidMount() {
method componentDidUpdate (line 70) | componentDidUpdate(prevProps: Props<P>) {
method componentWillUnmount (line 102) | componentWillUnmount() {
method enableResizeEvents (line 108) | enableResizeEvents() {
method disableResizeEvents (line 113) | disableResizeEvents() {
method render (line 207) | render() {
FILE: packages/redux-devtools-ui/src/Tabs/styles/common.ts
type StyleProps (line 4) | interface StyleProps {
FILE: packages/redux-devtools-ui/src/Tabs/styles/default.ts
type StyleProps (line 4) | interface StyleProps {
FILE: packages/redux-devtools-ui/src/Toolbar/Toolbar.stories.tsx
type TemplateArgs (line 44) | interface TemplateArgs {
type TabsTemplateArgs (line 128) | interface TabsTemplateArgs {
type WithSliderTemplateArgs (line 235) | interface WithSliderTemplateArgs {
FILE: packages/redux-devtools-ui/src/Toolbar/styles/Toolbar.ts
type BorderPosition (line 5) | type BorderPosition = 'top' | 'bottom';
type Props (line 7) | interface Props {
FILE: packages/redux-devtools-ui/src/themes/default.ts
type Theme (line 5) | interface Theme extends Base16Theme {
FILE: packages/redux-devtools-ui/src/utils/createStyledComponent.ts
type StyleFunction (line 11) | type StyleFunction<Props> = FunctionInterpolation<Props>;
type StylesObject (line 13) | interface StylesObject<Props> {
type Styles (line 17) | type Styles<Props> = StylesObject<Props> | StyleFunction<Props>;
function isStylesObject (line 19) | function isStylesObject<Props>(
function isThemeFromProvider (line 28) | function isThemeFromProvider(
function createStyledComponent (line 34) | function createStyledComponent<
FILE: packages/redux-devtools-ui/src/utils/invertColors.ts
function invertColors (line 3) | function invertColors(theme: Base16Theme) {
FILE: packages/redux-devtools-ui/src/utils/theme.ts
type ThemeName (line 14) | type ThemeName = keyof typeof themes;
type SchemeName (line 15) | type SchemeName = keyof typeof schemes;
type ThemeData (line 17) | interface ThemeData {
type ThemeFromProvider (line 23) | interface ThemeFromProvider extends ThemeBase {
FILE: packages/redux-devtools-utils/src/catchErrors.ts
constant ERROR (line 1) | const ERROR = '@@redux-devtools/ERROR';
type ErrorAction (line 3) | interface ErrorAction {
function catchErrors (line 17) | function catchErrors(sendError: (errorAction: ErrorAction) => void) {
FILE: packages/redux-devtools-utils/src/filters.ts
type State (line 4) | interface State {
function arrToRegex (line 16) | function arrToRegex(v: string | string[]) {
function filterActions (line 20) | function filterActions(
function filterStates (line 36) | function filterStates(
function isArray (line 47) | function isArray(arg: unknown): arg is readonly unknown[] {
type Config (line 51) | interface Config {
type LocalFilter (line 64) | interface LocalFilter {
function getLocalFilter (line 69) | function getLocalFilter(config: Config): LocalFilter | undefined {
type DevToolsOptions (line 81) | interface DevToolsOptions {
function getDevToolsOptions (line 89) | function getDevToolsOptions() {
function isFiltered (line 97) | function isFiltered(
function filterStagedActions (line 120) | function filterStagedActions(
function filterState (line 146) | function filterState(
FILE: packages/redux-devtools-utils/src/importState.ts
type State (line 7) | interface State {
function importState (line 13) | function importState(
FILE: packages/redux-devtools-utils/src/index.ts
function generateId (line 8) | function generateId(id: string | undefined) {
type ActionCreatorObject (line 12) | interface ActionCreatorObject {
function flatTree (line 18) | function flatTree(
function getMethods (line 38) | function getMethods(obj: unknown) {
function getActionsArray (line 66) | function getActionsArray(actionCreators: {
function evalArgs (line 77) | function evalArgs(inArgs: string[], restArgs: string): unknown[] {
function evalAction (line 85) | function evalAction(
function evalMethod (line 99) | function evalMethod(
function tryCatchStringify (line 117) | function tryCatchStringify(obj: unknown) {
function stringify (line 136) | function stringify(
function getSeralizeParameter (line 168) | function getSeralizeParameter(
function getStackTrace (line 218) | function getStackTrace(
FILE: packages/redux-devtools/examples/counter/src/actions/CounterActions.ts
type IncrementCounterAction (line 5) | interface IncrementCounterAction {
function increment (line 8) | function increment(): IncrementCounterAction {
type DecrementCounterAction (line 14) | interface DecrementCounterAction {
function decrement (line 17) | function decrement(): DecrementCounterAction {
type CounterAction (line 23) | type CounterAction = IncrementCounterAction | DecrementCounterAction;
function incrementIfOdd (line 25) | function incrementIfOdd(): ThunkAction<
function incrementAsync (line 42) | function incrementAsync(): ThunkAction<
FILE: packages/redux-devtools/examples/counter/src/components/Counter.tsx
type Props (line 3) | interface Props {
class Counter (line 10) | class Counter extends Component<Props> {
method render (line 11) | render() {
FILE: packages/redux-devtools/examples/counter/src/constants/ActionTypes.ts
constant INCREMENT_COUNTER (line 1) | const INCREMENT_COUNTER = 'INCREMENT_COUNTER';
constant DECREMENT_COUNTER (line 2) | const DECREMENT_COUNTER = 'DECREMENT_COUNTER';
FILE: packages/redux-devtools/examples/counter/src/containers/CounterApp.tsx
type Props (line 9) | interface Props {
class CounterApp (line 14) | class CounterApp extends Component<Props> {
method render (line 15) | render() {
function select (line 26) | function select(state: CounterState) {
FILE: packages/redux-devtools/examples/counter/src/containers/Root.dev.tsx
type Props (line 9) | interface Props {
class Root (line 13) | class Root extends Component<Props> {
method render (line 14) | render() {
FILE: packages/redux-devtools/examples/counter/src/containers/Root.prod.tsx
type Props (line 8) | interface Props {
class Root (line 12) | class Root extends Component<Props> {
method render (line 13) | render() {
FILE: packages/redux-devtools/examples/counter/src/containers/Root.ts
type Props (line 6) | interface Props {
FILE: packages/redux-devtools/examples/counter/src/reducers/counter.ts
function counter (line 4) | function counter(state = 0, action: CounterAction) {
FILE: packages/redux-devtools/examples/counter/src/reducers/index.ts
type CounterState (line 13) | interface CounterState {
FILE: packages/redux-devtools/examples/counter/src/store/configureStore.dev.ts
function getDebugSessionKey (line 15) | function getDebugSessionKey() {
function configureStore (line 26) | function configureStore(initialState?: Partial<CounterState>) {
FILE: packages/redux-devtools/examples/counter/src/store/configureStore.prod.ts
function configureStore (line 7) | function configureStore(initialState?: Partial<CounterState>) {
FILE: packages/redux-devtools/examples/todomvc/src/actions/TodoActions.ts
type AddTodoAction (line 3) | interface AddTodoAction {
function addTodo (line 7) | function addTodo(text: string): AddTodoAction {
type DeleteTodoAction (line 14) | interface DeleteTodoAction {
function deleteTodo (line 18) | function deleteTodo(id: number): DeleteTodoAction {
type EditTodoAction (line 25) | interface EditTodoAction {
function editTodo (line 30) | function editTodo(id: number, text: string): EditTodoAction {
type MarkTodoAction (line 38) | interface MarkTodoAction {
function markTodo (line 42) | function markTodo(id: number): MarkTodoAction {
type MarkAllAction (line 49) | interface MarkAllAction {
function markAll (line 52) | function markAll(): MarkAllAction {
type ClearMarkedAction (line 58) | interface ClearMarkedAction {
function clearMarked (line 61) | function clearMarked(): ClearMarkedAction {
type TodoAction (line 67) | type TodoAction =
type TodoActions (line 75) | interface TodoActions {
FILE: packages/redux-devtools/examples/todomvc/src/components/Footer.tsx
constant FILTER_TITLES (line 10) | const FILTER_TITLES = {
type Props (line 16) | interface Props {
class Footer (line 24) | class Footer extends Component<Props> {
method render (line 25) | render() {
method renderTodoCount (line 39) | renderTodoCount() {
method renderFilterLink (line 50) | renderFilterLink(filter: TodoFilter) {
method renderClearButton (line 65) | renderClearButton() {
FILE: packages/redux-devtools/examples/todomvc/src/components/Header.tsx
type Props (line 4) | interface Props {
class Header (line 8) | class Header extends Component<Props> {
method render (line 15) | render() {
FILE: packages/redux-devtools/examples/todomvc/src/components/MainSection.tsx
constant TODO_FILTERS (line 13) | const TODO_FILTERS = {
type State (line 19) | interface State {
type Props (line 23) | interface Props {
class MainSection (line 28) | class MainSection extends Component<Props, State> {
method render (line 46) | render() {
method renderToggleAll (line 69) | renderToggleAll(markedCount: number) {
method renderFooter (line 88) | renderFooter(markedCount: number) {
FILE: packages/redux-devtools/examples/todomvc/src/components/TodoItem.tsx
type State (line 6) | interface State {
type Props (line 10) | interface Props {
class TodoItem (line 20) | class TodoItem extends Component<Props, State> {
method handleSave (line 29) | handleSave(id: number, text: string) {
method render (line 38) | render() {
FILE: packages/redux-devtools/examples/todomvc/src/components/TodoTextInput.tsx
type State (line 9) | interface State {
type Props (line 13) | interface Props {
class TodoTextInput (line 21) | class TodoTextInput extends Component<Props, State> {
method render (line 46) | render() {
FILE: packages/redux-devtools/examples/todomvc/src/constants/ActionTypes.ts
constant ADD_TODO (line 1) | const ADD_TODO = 'ADD_TODO';
constant DELETE_TODO (line 2) | const DELETE_TODO = 'DELETE_TODO';
constant EDIT_TODO (line 3) | const EDIT_TODO = 'EDIT_TODO';
constant MARK_TODO (line 4) | const MARK_TODO = 'MARK_TODO';
constant MARK_ALL (line 5) | const MARK_ALL = 'MARK_ALL';
constant CLEAR_MARKED (line 6) | const CLEAR_MARKED = 'CLEAR_MARKED';
FILE: packages/redux-devtools/examples/todomvc/src/constants/TodoFilters.ts
constant SHOW_ALL (line 1) | const SHOW_ALL = 'show_all';
constant SHOW_MARKED (line 2) | const SHOW_MARKED = 'show_marked';
constant SHOW_UNMARKED (line 3) | const SHOW_UNMARKED = 'show_unmarked';
type TodoFilter (line 5) | type TodoFilter =
FILE: packages/redux-devtools/examples/todomvc/src/containers/Root.dev.tsx
type Props (line 9) | interface Props {
class Root (line 13) | class Root extends Component<Props> {
method render (line 14) | render() {
FILE: packages/redux-devtools/examples/todomvc/src/containers/Root.prod.tsx
type Props (line 8) | interface Props {
class Root (line 12) | class Root extends Component<Props> {
method render (line 13) | render() {
FILE: packages/redux-devtools/examples/todomvc/src/containers/Root.ts
type Props (line 6) | interface Props {
FILE: packages/redux-devtools/examples/todomvc/src/containers/TodoApp.tsx
type Props (line 14) | interface Props {
class TodoApp (line 19) | class TodoApp extends Component<Props> {
method render (line 20) | render() {
function mapState (line 32) | function mapState(state: TodoState) {
function mapDispatch (line 38) | function mapDispatch(dispatch: Dispatch<TodoAction>) {
FILE: packages/redux-devtools/examples/todomvc/src/reducers/index.ts
type TodoState (line 5) | interface TodoState {
FILE: packages/redux-devtools/examples/todomvc/src/reducers/todos.ts
type Todo (line 11) | interface Todo {
function todos (line 25) | function todos(state = initialState, action: TodoAction) {
FILE: packages/redux-devtools/examples/todomvc/src/store/configureStore.dev.ts
function getDebugSessionKey (line 6) | function getDebugSessionKey() {
function configureStore (line 16) | function configureStore(initialState?: Partial<TodoState>) {
FILE: packages/redux-devtools/examples/todomvc/src/store/configureStore.prod.ts
function configureStore (line 4) | function configureStore(initialState?: Partial<TodoState>) {
FILE: packages/redux-devtools/src/createDevTools.tsx
function logError (line 13) | function logError(type: string) {
type Props (line 29) | interface Props<S, A extends Action<string>, MonitorState> {
type Monitor (line 33) | type Monitor<
type DevToolsInstance (line 50) | interface DevToolsInstance<
type DevToolsClass (line 58) | interface DevToolsClass<
function createDevTools (line 70) | function createDevTools<
FILE: packages/redux-devtools/src/persistState.ts
function persistState (line 4) | function persistState<S, A extends Action<string>, MonitorState>(
FILE: packages/redux-devtools/test/globalLocalStorage.d.ts
type Global (line 2) | interface Global {
FILE: packages/redux-devtools/test/persistState.spec.ts
method getItem (line 14) | getItem(key) {
method setItem (line 17) | setItem(key, value) {
method removeItem (line 20) | removeItem(key) {
method clear (line 23) | clear() {
method length (line 26) | get length() {
method key (line 29) | key(index) {
type Action (line 39) | type Action = { type: 'INCREMENT' } | { type: 'DECREMENT' };
Condensed preview — 874 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,902K chars).
[
{
"path": ".changeset/config.json",
"chars": 369,
"preview": "{\n \"$schema\": \"https://unpkg.com/@changesets/config@1.6.4/schema.json\",\n \"changelog\": \"@changesets/cli/changelog\",\n \""
},
{
"path": ".eslintignore",
"chars": 94,
"preview": "*.log\n.idea\nlib\ndist\numd\nbuild\ncoverage\nnode_modules\n__snapshots__\nstorybook-static\n.vscode/*\n"
},
{
"path": ".gitattributes",
"chars": 19,
"preview": "* text=auto eol=lf\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 63,
"preview": "github: Methuselah96\nopen_collective: redux-devtools-extension\n"
},
{
"path": ".github/workflows/CI.yml",
"chars": 719,
"preview": "name: CI\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\njobs:\n build:\n runs-on: 'ubuntu-24."
},
{
"path": ".github/workflows/release.yml",
"chars": 1395,
"preview": "name: Release\n\non:\n push:\n branches:\n - main\n\npermissions: write-all\n\njobs:\n release:\n name: Release\n ru"
},
{
"path": ".gitignore",
"chars": 167,
"preview": "node_modules\n*.log\n.DS_Store\nlib\ndist\numd\nbuild\ncoverage\n.idea\n.eslintcache\n!packages/redux-devtools-slider-monitor/exam"
},
{
"path": ".prettierignore",
"chars": 131,
"preview": "*.log\n.idea\nlib\ndist\numd\nbuild\ncoverage\nnode_modules\n__snapshots__\ndev\n**/demo/public/**\nstorybook-static\n.vscode/*\npnpm"
},
{
"path": ".prettierrc",
"chars": 26,
"preview": "{\n \"singleQuote\": true\n}\n"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 1423,
"preview": "# Contributor Code of Conduct\n\nAs contributors and maintainers of this project, we pledge to respect all people who cont"
},
{
"path": "LICENSE.md",
"chars": 1086,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015-present Dan Abramov\n\nPermission is hereby granted, free of charge, to any pers"
},
{
"path": "README.md",
"chars": 14160,
"preview": "\n[\n\nCopyright (c) 2015-present Mihail Diordiev\n\nPermission is hereby granted, free of charge, to any "
},
{
"path": "extension/README.md",
"chars": 22414,
"preview": "# Redux DevTools Extension\n\n[`\n- `window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__(["
},
{
"path": "extension/docs/API/Methods.md",
"chars": 3859,
"preview": "## Communicate with the extension directly\n\n> Note this is advanced API, which you usually don't need to use with Redux "
},
{
"path": "extension/docs/API/README.md",
"chars": 70,
"preview": "# API Reference\n\n- [Parameters](Arguments.md)\n- [Methods](Methods.md)\n"
},
{
"path": "extension/docs/Architecture.md",
"chars": 2366,
"preview": "# Architecture Notes\n\nThis document exists to keep track of how the different parts of the Redux DevTools interact, sinc"
},
{
"path": "extension/docs/Articles.md",
"chars": 466,
"preview": "# Articles\n\n- [Improve your development workflow with Redux DevTools Extension](https://medium.com/@zalmoxis/improve-you"
},
{
"path": "extension/docs/Credits.md",
"chars": 780,
"preview": "# Credits\n\n- Built using [Crossbuilder](https://github.com/zalmoxisus/crossbuilder) boilerplate.\n- Includes [Dan Abramov"
},
{
"path": "extension/docs/FAQ.md",
"chars": 2961,
"preview": "# Redux DevTools Extension FAQ\n\n## Table of Contents\n\n- [How to get it work](#how-to-get-it-work)\n- [How to disable/enab"
},
{
"path": "extension/docs/Features/Trace.md",
"chars": 2435,
"preview": "## Trace actions calls\n\n or [submit a PR](https"
},
{
"path": "extension/docs/Integrations.md",
"chars": 7256,
"preview": "# Integrations for js and non-js frameworks\n\nMostly functional:\n\n- [React](#react)\n- [Angular](#angular)\n- [Cycle](#cycl"
},
{
"path": "extension/docs/README.md",
"chars": 722,
"preview": "# Documentation\n\n- [Extension](/README.md)\n - [Installation](/README.md#installation)\n - [Usage](/README.md#usage)\n -"
},
{
"path": "extension/docs/Recipes.md",
"chars": 1959,
"preview": "# Recipes\n\n### Using in a typescript project\n\nThe recommended way is to use [`@redux-devtools/extension` npm package](/R"
},
{
"path": "extension/docs/Troubleshooting.md",
"chars": 6521,
"preview": "# Troubleshooting\n\n### I just see empty log or \"No store found\"\n\nMake sure you [applied the enhancer](https://github.com"
},
{
"path": "extension/docs/Videos.md",
"chars": 397,
"preview": "# Videos\n\n- [Debugging flux applications in production at React Europe 2016](https://youtu.be/YU8jQ2HtqH4)\n- [Hot Reload"
},
{
"path": "extension/edge/manifest.json",
"chars": 1647,
"preview": "{\n \"version\": \"3.2.10\",\n \"name\": \"Redux DevTools\",\n \"description\": \"Redux DevTools for debugging application's state "
},
{
"path": "extension/eslint.config.mjs",
"chars": 798,
"preview": "import globals from 'globals';\nimport eslintJs from '../eslint.js.config.base.mjs';\nimport eslintTsReact from '../eslint"
},
{
"path": "extension/firefox/manifest.json",
"chars": 1478,
"preview": "{\n \"version\": \"3.2.10\",\n \"name\": \"Redux DevTools\",\n \"manifest_version\": 3,\n \"description\": \"Redux Developer Tools fo"
},
{
"path": "extension/jest.config.ts",
"chars": 499,
"preview": "import { createJsWithTsEsmPreset, type JestConfigWithTsJest } from 'ts-jest';\n\nconst presetConfig = createJsWithTsEsmPre"
},
{
"path": "extension/package.json",
"chars": 3064,
"preview": "{\n \"private\": true,\n \"name\": \"remotedev-redux-devtools-extension\",\n \"version\": \"3.2.12\",\n \"description\": \"Redux Deve"
},
{
"path": "extension/src/app/Actions.tsx",
"chars": 4070,
"preview": "import React, { Component } from 'react';\nimport { connect, ResolveThunks } from 'react-redux';\nimport { Button, Contain"
},
{
"path": "extension/src/app/App.tsx",
"chars": 2019,
"preview": "import React, { Component } from 'react';\nimport { connect, ResolveThunks } from 'react-redux';\nimport { Container, Noti"
},
{
"path": "extension/src/background/contextMenus.ts",
"chars": 872,
"preview": "import openDevToolsWindow, { DevToolsPosition } from './openWindow.js';\n\nexport function createMenu() {\n const menus = "
},
{
"path": "extension/src/background/index.ts",
"chars": 1281,
"preview": "import '../chromeApiMock.js';\nimport configureStore from './store/backgroundStore.js';\nimport openDevToolsWindow, { DevT"
},
{
"path": "extension/src/background/logging.ts",
"chars": 1305,
"preview": "import { LIFTED_ACTION } from '@redux-devtools/app';\nimport { store } from './index.js';\n\nexport function getReport(\n r"
},
{
"path": "extension/src/background/openWindow.ts",
"chars": 996,
"preview": "export type DevToolsPosition = 'devtools-window' | 'devtools-remote';\n\nconst windows: { [K in DevToolsPosition]?: number"
},
{
"path": "extension/src/background/store/apiMiddleware.ts",
"chars": 18957,
"preview": "import {\n CustomAction,\n DispatchAction as AppDispatchAction,\n LibConfig,\n LIFTED_ACTION,\n nonReduxDispatch,\n REMO"
},
{
"path": "extension/src/background/store/backgroundReducer.ts",
"chars": 418,
"preview": "import { combineReducers, Reducer } from 'redux';\nimport { instances, InstancesState } from '@redux-devtools/app';\nimpor"
},
{
"path": "extension/src/background/store/backgroundStore.ts",
"chars": 2071,
"preview": "import { createStore, applyMiddleware } from 'redux';\nimport {\n CustomAction,\n DispatchAction,\n LIFTED_ACTION,\n Stor"
},
{
"path": "extension/src/chromeApiMock.ts",
"chars": 2823,
"preview": "// Mock not supported chrome.* API for Firefox and Electron\n\nconst isElectron = navigator.userAgent.includes('Electron')"
},
{
"path": "extension/src/contentScript/index.ts",
"chars": 8825,
"preview": "import '../chromeApiMock.js';\nimport {\n getOptions,\n isAllowed,\n Options,\n prefetchOptions,\n prepareOptionsForPage,"
},
{
"path": "extension/src/devpanel/devpanel.pug",
"chars": 396,
"preview": "doctype html\r\n\r\nhtml\r\n head\r\n meta(charset='UTF-8')\r\n title Redux DevTools\r\n include ../style.pug\r\n\r\n body\r\n #"
},
{
"path": "extension/src/devpanel/index.tsx",
"chars": 5127,
"preview": "import '../chromeApiMock.js';\nimport React, { CSSProperties, ReactNode } from 'react';\nimport { createRoot, Root } from "
},
{
"path": "extension/src/devpanel/store/panelReducer.ts",
"chars": 492,
"preview": "import { combineReducers, Reducer } from 'redux';\nimport {\n connection,\n instances,\n monitor,\n notification,\n repor"
},
{
"path": "extension/src/devpanel/store/panelStore.ts",
"chars": 943,
"preview": "import { createStore, applyMiddleware, Reducer, Store } from 'redux';\nimport localForage from 'localforage';\nimport { pe"
},
{
"path": "extension/src/devpanel/store/panelSyncMiddleware.ts",
"chars": 1924,
"preview": "import {\n getActiveInstance,\n LIFTED_ACTION,\n SELECT_INSTANCE,\n StoreAction,\n StoreState,\n TOGGLE_PERSIST,\n UPDAT"
},
{
"path": "extension/src/devtools/devtools.pug",
"chars": 159,
"preview": "doctype html\r\n\r\nhtml\r\n head\r\n meta(charset='UTF-8')\r\n title Redux DevTools\r\n\r\n body\r\n #root\r\n "
},
{
"path": "extension/src/devtools/index.ts",
"chars": 125,
"preview": "chrome.devtools.panels.create(\n 'Redux',\n 'img/logo/scalable.png',\n 'devpanel.html',\n () => {\n // do nothing.\n }"
},
{
"path": "extension/src/options/AllowToRunGroup.tsx",
"chars": 1659,
"preview": "import React from 'react';\nimport { OptionsProps } from './Options.js';\n\nexport default function AllowToRunGroup({ optio"
},
{
"path": "extension/src/options/ContextMenuGroup.tsx",
"chars": 837,
"preview": "import React from 'react';\nimport { OptionsProps } from './Options.js';\n\nexport default function ContextMenuGroup({\n op"
},
{
"path": "extension/src/options/EditorGroup.tsx",
"chars": 2644,
"preview": "import React from 'react';\nimport { OptionsProps } from './Options.js';\n\nexport default function EditorGroup({ options, "
},
{
"path": "extension/src/options/FilterGroup.tsx",
"chars": 2414,
"preview": "import React from 'react';\nimport { FilterState } from '../pageScript/api/filters.js';\nimport { OptionsProps } from './O"
},
{
"path": "extension/src/options/MiscellaneousGroup.tsx",
"chars": 1687,
"preview": "import React from 'react';\nimport { OptionsProps } from './Options.js';\n\nexport default function MiscellaneousGroup({\n "
},
{
"path": "extension/src/options/Options.tsx",
"chars": 1508,
"preview": "import React from 'react';\nimport EditorGroup from './EditorGroup.js';\nimport FilterGroup from './FilterGroup.js';\nimpor"
},
{
"path": "extension/src/options/index.tsx",
"chars": 693,
"preview": "import '../chromeApiMock.js';\nimport React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport OptionsCo"
},
{
"path": "extension/src/options/options.pug",
"chars": 2001,
"preview": "doctype html\r\n\r\nhtml\r\n head\r\n meta(charset='UTF-8')\r\n title Redux DevTools Options\r\n style.\r\n body {\r\n pad"
},
{
"path": "extension/src/options/syncOptions.ts",
"chars": 3575,
"preview": "import { FilterState, FilterStateValue } from '../pageScript/api/filters.js';\n\nexport interface Options {\n readonly use"
},
{
"path": "extension/src/pageScript/Monitor.ts",
"chars": 2139,
"preview": "import { Action } from 'redux';\nimport { LiftedState } from '@redux-devtools/instrument';\nimport { DispatchAction, LibCo"
},
{
"path": "extension/src/pageScript/api/filters.ts",
"chars": 6413,
"preview": "import { Action } from 'redux';\nimport { LiftedState, PerformAction } from '@redux-devtools/instrument';\nimport { LocalF"
},
{
"path": "extension/src/pageScript/api/generateInstanceId.ts",
"chars": 113,
"preview": "let id = 0;\n\nexport default function generateId(instanceId: number | undefined) {\n return instanceId || ++id;\n}\n"
},
{
"path": "extension/src/pageScript/api/importState.ts",
"chars": 2307,
"preview": "import jsan from 'jsan';\nimport { immutableSerialize } from '@redux-devtools/serialize';\nimport type { Config, Serialize"
},
{
"path": "extension/src/pageScript/api/index.ts",
"chars": 20231,
"preview": "import jsan, { Options } from 'jsan';\nimport { throttle } from 'lodash-es';\nimport { immutableSerialize } from '@redux-d"
},
{
"path": "extension/src/pageScript/api/notifyErrors.ts",
"chars": 1066,
"preview": "let handleError: (() => boolean) | undefined;\nlet lastTime = 0;\n\nfunction createExpBackoffTimer(step: number) {\n let co"
},
{
"path": "extension/src/pageScript/api/openWindow.ts",
"chars": 443,
"preview": "import { Action } from 'redux';\nimport type { PageScriptToContentScriptMessage } from './index.js';\n\nexport type Positio"
},
{
"path": "extension/src/pageScript/enhancerStore.ts",
"chars": 1293,
"preview": "import { Action, compose, Reducer, StoreEnhancerStoreCreator } from 'redux';\nimport { instrument } from '@redux-devtools"
},
{
"path": "extension/src/pageScript/index.ts",
"chars": 18467,
"preview": "import {\n ActionCreatorObject,\n evalAction,\n getActionsArray,\n getLocalFilter,\n} from '@redux-devtools/utils';\nimpor"
},
{
"path": "extension/src/remote/index.tsx",
"chars": 951,
"preview": "import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { Root } from '@redux-devtools/app';\n\nc"
},
{
"path": "extension/src/remote/remote.pug",
"chars": 213,
"preview": "doctype html\r\n\r\nhtml\r\n head\r\n meta(charset='UTF-8')\r\n title RemoteDev\r\n include ../style.pug\r\n\r\n body\r\n #root\r"
},
{
"path": "extension/src/style.pug",
"chars": 1063,
"preview": "style.\n html {\n height: 100%;\n width: 100%;\n }\n body {\n overflow: hidden;\n height: 100%;\n width: 100%;"
},
{
"path": "extension/test/.eslintrc",
"chars": 121,
"preview": "{\n \"env\": {\n \"mocha\": true\n },\n \"globals\": {\n \"UI\": true\n },\n \"rules\": {\n \"no-unused-expressions\": 0\n }\n}"
},
{
"path": "extension/test/__mocks__/styleMock.js",
"chars": 19,
"preview": "export default {};\n"
},
{
"path": "extension/test/app/containers/App.spec.jsx",
"chars": 1272,
"preview": "import { jest } from '@jest/globals';\nimport React from 'react';\nimport { render, screen, within } from '@testing-librar"
},
{
"path": "extension/test/app/inject/api.spec.js",
"chars": 2515,
"preview": "import { jest } from '@jest/globals';\nimport { insertScript, listenMessage } from '../../utils/inject.js';\nimport '../.."
},
{
"path": "extension/test/app/inject/enhancer.spec.js",
"chars": 6387,
"preview": "import { createStore, compose } from 'redux';\nimport { insertScript, listenMessage } from '../../utils/inject.js';\nimpor"
},
{
"path": "extension/test/chrome/extension.spec.js",
"chars": 2383,
"preview": "import { resolve } from 'path';\nimport webdriver from 'selenium-webdriver';\nimport chrome from 'selenium-webdriver/chrom"
},
{
"path": "extension/test/electron/devpanel.spec.js",
"chars": 4070,
"preview": "import { join } from 'path';\nimport webdriver from 'selenium-webdriver';\nimport chrome from 'selenium-webdriver/chrome';"
},
{
"path": "extension/test/electron/fixture/index.html",
"chars": 286,
"preview": "<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\" />\n <title>Electron Test</title>\n </head>\n <body>\n <sp"
},
{
"path": "extension/test/electron/fixture/main.js",
"chars": 561,
"preview": "const path = require('path');\nconst { app, BrowserWindow, session } = require('electron');\n\napp.on('window-all-closed', "
},
{
"path": "extension/test/electron/fixture/package.json",
"chars": 107,
"preview": "{\n \"name\": \"electron-test\",\n \"productName\": \"Electron Test\",\n \"main\": \"main.js\",\n \"version\": \"0.1.0\"\n}\n"
},
{
"path": "extension/test/electron/fixture/src/renderer.js",
"chars": 941,
"preview": "const { createStore } = require('redux');\n\nconst INCREMENT_COUNTER = 'INCREMENT_COUNTER';\nconst DECREMENT_COUNTER = 'DEC"
},
{
"path": "extension/test/electron/fixture/webpack.config.js",
"chars": 217,
"preview": "const path = require('path');\n\nmodule.exports = {\n mode: 'development',\n entry: './test/electron/fixture/src/renderer."
},
{
"path": "extension/test/perf/data.js",
"chars": 119224,
"preview": "// Source: http://beta.json-generator.com/V1omRaUJG\n/* eslint-disable */\n\nexport const bigString = Array(10000000).join("
},
{
"path": "extension/test/perf/send.spec.js",
"chars": 648,
"preview": "import { bigArray, bigString, circularData } from './data.js';\nimport { listenMessage } from '../utils/inject.js';\n\nfunc"
},
{
"path": "extension/test/setup.js",
"chars": 164,
"preview": "import { jest } from '@jest/globals';\nimport * as chrome from 'sinon-chrome';\n\nglobal.chrome = chrome;\nimport '@testing-"
},
{
"path": "extension/test/utils/e2e.js",
"chars": 1599,
"preview": "import webdriver from 'selenium-webdriver';\n\nexport const delay = (time) =>\n new Promise((resolve) => setTimeout(resolv"
},
{
"path": "extension/test/utils/inject.js",
"chars": 500,
"preview": "export function insertScript(str) {\n const s = window.document.createElement('script');\n s.appendChild(document.create"
},
{
"path": "extension/tsconfig.json",
"chars": 125,
"preview": "{\n \"extends\": \"../tsconfig.esm.react.base.json\",\n \"compilerOptions\": {\n \"types\": [\"chrome\"]\n },\n \"include\": [\"src"
},
{
"path": "jest.config.js",
"chars": 83,
"preview": "module.exports = {\n projects: ['<rootDir>/extension', '<rootDir>/packages/*'],\n};\n"
},
{
"path": "package.json",
"chars": 808,
"preview": "{\n \"private\": true,\n \"devDependencies\": {\n \"@babel/core\": \"^7.29.0\",\n \"@changesets/cli\": \"^2.30.0\",\n \"@eslint"
},
{
"path": "packages/d3-state-visualizer/CHANGELOG.md",
"chars": 1760,
"preview": "# Change Log\n\n## 3.0.0\n\n### Major Changes\n\n- 191d419: Convert d3 packages to ESM\n\n### Patch Changes\n\n- Updated dependenc"
},
{
"path": "packages/d3-state-visualizer/LICENSE.md",
"chars": 1079,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Romain Séguy\n\nPermission is hereby granted, free of charge, to any person obta"
},
{
"path": "packages/d3-state-visualizer/README.md",
"chars": 7251,
"preview": "# d3-state-visualizer\n\nEnables real-time visualization of your application state.\n\nCreated by [@romseguy](https://github"
},
{
"path": "packages/d3-state-visualizer/eslint.config.js",
"chars": 227,
"preview": "import eslintJs from '../../eslint.js.config.base.mjs';\nimport eslintTs from '../../eslint.ts.config.base.mjs';\n\nexport "
},
{
"path": "packages/d3-state-visualizer/examples/tree/CHANGELOG.md",
"chars": 294,
"preview": "# d3-state-visualizer-tree-example\n\n## 0.1.6\n\n### Patch Changes\n\n- Updated dependencies [191d419]\n - d3-state-visualize"
},
{
"path": "packages/d3-state-visualizer/examples/tree/eslint.config.mjs",
"chars": 333,
"preview": "import eslintJs from '../../../../eslint.js.config.base.mjs';\nimport eslintTs from '../../../../eslint.ts.config.base.mj"
},
{
"path": "packages/d3-state-visualizer/examples/tree/index.html",
"chars": 892,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-w"
},
{
"path": "packages/d3-state-visualizer/examples/tree/package.json",
"chars": 882,
"preview": "{\n \"private\": true,\n \"name\": \"d3-state-visualizer-tree-example\",\n \"version\": \"0.1.6\",\n \"description\": \"Visualize you"
},
{
"path": "packages/d3-state-visualizer/examples/tree/src/index.ts",
"chars": 735,
"preview": "import { tree } from 'd3-state-visualizer';\n\nconst appState = {\n todoStore: {\n todos: [\n { title: 'd3' },\n "
},
{
"path": "packages/d3-state-visualizer/examples/tree/tsconfig.json",
"chars": 123,
"preview": "{\n \"extends\": \"../../../../tsconfig.esm.base.json\",\n \"compilerOptions\": {\n \"noEmit\": true\n },\n \"include\": [\"src\"]"
},
{
"path": "packages/d3-state-visualizer/package.json",
"chars": 1179,
"preview": "{\n \"name\": \"d3-state-visualizer\",\n \"version\": \"3.0.0\",\n \"description\": \"Visualize your app state with a range of reus"
},
{
"path": "packages/d3-state-visualizer/src/charts/index.ts",
"chars": 194,
"preview": "export type { HierarchyPointNode } from 'd3';\nexport type { StyleValue } from 'd3tooltip';\nexport { default as tree } fr"
},
{
"path": "packages/d3-state-visualizer/src/charts/tree/sortAndSerialize.ts",
"chars": 561,
"preview": "function sortObject(obj: unknown, strict?: boolean) {\n if (obj instanceof Array) {\n let ary;\n if (strict) {\n "
},
{
"path": "packages/d3-state-visualizer/src/charts/tree/tree.ts",
"chars": 15410,
"preview": "import * as d3 from 'd3';\nimport type { D3ZoomEvent, HierarchyPointLink, HierarchyPointNode } from 'd3';\nimport { isEmpt"
},
{
"path": "packages/d3-state-visualizer/src/charts/tree/utils.ts",
"chars": 2439,
"preview": "import { is, join, pipe, replace } from 'ramda';\nimport sortAndSerialize from './sortAndSerialize.js';\nimport type { Int"
},
{
"path": "packages/d3-state-visualizer/src/index.ts",
"chars": 139,
"preview": "export { tree } from './charts/index.js';\nexport type {\n HierarchyPointNode,\n Node,\n Options,\n StyleValue,\n} from '."
},
{
"path": "packages/d3-state-visualizer/tsconfig.json",
"chars": 118,
"preview": "{\n \"extends\": \"../../tsconfig.esm.base.json\",\n \"compilerOptions\": {\n \"outDir\": \"lib\"\n },\n \"include\": [\"src\"]\n}\n"
},
{
"path": "packages/d3tooltip/CHANGELOG.md",
"chars": 1459,
"preview": "# Change Log\n\n## 4.0.0\n\n### Major Changes\n\n- 191d419: Convert d3 packages to ESM\n\n## 3.0.1\n\n### Patch Changes\n\n- 7f5bddb"
},
{
"path": "packages/d3tooltip/LICENSE.md",
"chars": 1075,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 romseguy\n\nPermission is hereby granted, free of charge, to any person obtainin"
},
{
"path": "packages/d3tooltip/README.md",
"chars": 2781,
"preview": "# d3tooltip\n\nThis tooltip aims for a minimal yet highly configurable API. It has a long way to go, but the essentials ar"
},
{
"path": "packages/d3tooltip/eslint.config.js",
"chars": 215,
"preview": "import eslintJs from '../../eslint.js.config.base.mjs';\nimport eslintTs from '../../eslint.ts.config.base.mjs';\n\nexport "
},
{
"path": "packages/d3tooltip/package.json",
"chars": 989,
"preview": "{\n \"name\": \"d3tooltip\",\n \"version\": \"4.0.0\",\n \"description\": \"A highly configurable tooltip for d3\",\n \"keywords\": [\n"
},
{
"path": "packages/d3tooltip/src/index.ts",
"chars": 2718,
"preview": "import * as d3 from 'd3';\nimport type { BaseType, Selection } from 'd3';\n\nexport type StyleValue = string | number | boo"
},
{
"path": "packages/d3tooltip/tsconfig.json",
"chars": 118,
"preview": "{\n \"extends\": \"../../tsconfig.esm.base.json\",\n \"compilerOptions\": {\n \"outDir\": \"lib\"\n },\n \"include\": [\"src\"]\n}\n"
},
{
"path": "packages/map2tree/CHANGELOG.md",
"chars": 1489,
"preview": "# Change Log\n\n## 4.0.0\n\n### Major Changes\n\n- 191d419: Convert d3 packages to ESM\n\n## 3.0.0\n\n### Major Changes\n\n- b323f77"
},
{
"path": "packages/map2tree/LICENSE.md",
"chars": 1079,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Romain Séguy\n\nPermission is hereby granted, free of charge, to any person obta"
},
{
"path": "packages/map2tree/README.md",
"chars": 2263,
"preview": "A pure function to convert a map into a tree structure. Created by [@romseguy](https://github.com/romseguy) and merged f"
},
{
"path": "packages/map2tree/eslint.config.js",
"chars": 338,
"preview": "import eslintJs from '../../eslint.js.config.base.mjs';\nimport eslintTs from '../../eslint.ts.config.base.mjs';\nimport e"
},
{
"path": "packages/map2tree/jest.config.ts",
"chars": 317,
"preview": "import { createDefaultEsmPreset, type JestConfigWithTsJest } from 'ts-jest';\n\nconst presetConfig = createDefaultEsmPrese"
},
{
"path": "packages/map2tree/package.json",
"chars": 1200,
"preview": "{\n \"name\": \"map2tree\",\n \"version\": \"4.0.0\",\n \"description\": \"Utility for mapping maps to trees\",\n \"keywords\": [\n "
},
{
"path": "packages/map2tree/src/index.ts",
"chars": 2525,
"preview": "import { isArray, isPlainObject, mapValues } from 'lodash-es';\n\nexport interface Node {\n name: string;\n children?: thi"
},
{
"path": "packages/map2tree/test/map2tree.spec.ts",
"chars": 4724,
"preview": "import { map2tree, Node } from '../src/index.js';\nimport * as immutable from 'immutable';\n\ntest('# rootNodeKey', () => {"
},
{
"path": "packages/map2tree/tsconfig.json",
"chars": 118,
"preview": "{\n \"extends\": \"../../tsconfig.esm.base.json\",\n \"compilerOptions\": {\n \"outDir\": \"lib\"\n },\n \"include\": [\"src\"]\n}\n"
},
{
"path": "packages/map2tree/tsconfig.test.json",
"chars": 128,
"preview": "{\n \"extends\": \"../../tsconfig.esm.base.json\",\n \"compilerOptions\": {\n \"types\": [\"jest\"]\n },\n \"include\": [\"src\", \"t"
},
{
"path": "packages/react-base16-styling/CHANGELOG.md",
"chars": 1312,
"preview": "# Change Log\n\n## 0.10.0\n\n### Minor Changes\n\n- bbb1a40: Convert React packages to ESM\n\n## 0.9.0\n\n- Adds ESM build (https:"
},
{
"path": "packages/react-base16-styling/LICENSE.md",
"chars": 1086,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2016 Alexander Kuznetsov\n\nPermission is hereby granted, free of charge, to any pers"
},
{
"path": "packages/react-base16-styling/README.md",
"chars": 3524,
"preview": "# react-base16-styling [](https://www.npm"
},
{
"path": "packages/react-base16-styling/eslint.config.js",
"chars": 338,
"preview": "import eslintJs from '../../eslint.js.config.base.mjs';\nimport eslintTs from '../../eslint.ts.config.base.mjs';\nimport e"
},
{
"path": "packages/react-base16-styling/jest.config.ts",
"chars": 317,
"preview": "import { createDefaultEsmPreset, type JestConfigWithTsJest } from 'ts-jest';\n\nconst presetConfig = createDefaultEsmPrese"
},
{
"path": "packages/react-base16-styling/package.json",
"chars": 1388,
"preview": "{\n \"name\": \"react-base16-styling\",\n \"version\": \"0.10.0\",\n \"description\": \"React styling with base16 color scheme supp"
},
{
"path": "packages/react-base16-styling/src/colorConverters.ts",
"chars": 712,
"preview": "export type Color = [number, number, number];\n\nexport function yuv2rgb(yuv: Color): Color {\n const y = yuv[0],\n u = "
},
{
"path": "packages/react-base16-styling/src/index.ts",
"chars": 8701,
"preview": "import Color from 'color';\nimport * as CSS from 'csstype';\nimport { curry } from 'lodash-es';\nimport type { CurriedFunct"
},
{
"path": "packages/react-base16-styling/src/themes/apathy.ts",
"chars": 433,
"preview": "export default {\n scheme: 'apathy',\n author: 'jannik siebert (https://github.com/janniks)',\n base00: '#031A16',\n bas"
},
{
"path": "packages/react-base16-styling/src/themes/ashes.ts",
"chars": 432,
"preview": "export default {\n scheme: 'ashes',\n author: 'jannik siebert (https://github.com/janniks)',\n base00: '#1C2023',\n base"
},
{
"path": "packages/react-base16-styling/src/themes/atelier-dune.ts",
"chars": 484,
"preview": "export default {\n scheme: 'atelier dune',\n author:\n 'bram de haan (http://atelierbram.github.io/syntax-highlighting"
},
{
"path": "packages/react-base16-styling/src/themes/atelier-forest.ts",
"chars": 488,
"preview": "export default {\n scheme: 'atelier forest',\n author:\n 'bram de haan (http://atelierbram.github.io/syntax-highlighti"
},
{
"path": "packages/react-base16-styling/src/themes/atelier-heath.ts",
"chars": 486,
"preview": "export default {\n scheme: 'atelier heath',\n author:\n 'bram de haan (http://atelierbram.github.io/syntax-highlightin"
},
{
"path": "packages/react-base16-styling/src/themes/atelier-lakeside.ts",
"chars": 493,
"preview": "export default {\n scheme: 'atelier lakeside',\n author:\n 'bram de haan (http://atelierbram.github.io/syntax-highligh"
},
{
"path": "packages/react-base16-styling/src/themes/atelier-seaside.ts",
"chars": 491,
"preview": "export default {\n scheme: 'atelier seaside',\n author:\n 'bram de haan (http://atelierbram.github.io/syntax-highlight"
},
{
"path": "packages/react-base16-styling/src/themes/bespin.ts",
"chars": 401,
"preview": "export default {\n scheme: 'bespin',\n author: 'jan t. sott',\n base00: '#28211c',\n base01: '#36312e',\n base02: '#5e5d"
},
{
"path": "packages/react-base16-styling/src/themes/brewer.ts",
"chars": 433,
"preview": "export default {\n scheme: 'brewer',\n author: 'timothée poisot (http://github.com/tpoisot)',\n base00: '#0c0d0e',\n bas"
},
{
"path": "packages/react-base16-styling/src/themes/bright.ts",
"chars": 429,
"preview": "export default {\n scheme: 'bright',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#000000',\n base01:"
},
{
"path": "packages/react-base16-styling/src/themes/chalk.ts",
"chars": 428,
"preview": "export default {\n scheme: 'chalk',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#151515',\n base01: "
},
{
"path": "packages/react-base16-styling/src/themes/codeschool.ts",
"chars": 403,
"preview": "export default {\n scheme: 'codeschool',\n author: 'brettof86',\n base00: '#232c31',\n base01: '#1c3657',\n base02: '#2a"
},
{
"path": "packages/react-base16-styling/src/themes/colors.ts",
"chars": 412,
"preview": "export default {\n scheme: 'colors',\n author: 'mrmrs (http://clrs.cc)',\n base00: '#111111',\n base01: '#333333',\n bas"
},
{
"path": "packages/react-base16-styling/src/themes/default.ts",
"chars": 430,
"preview": "export default {\n scheme: 'default',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#181818',\n base01"
},
{
"path": "packages/react-base16-styling/src/themes/eighties.ts",
"chars": 431,
"preview": "export default {\n scheme: 'eighties',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#2d2d2d',\n base0"
},
{
"path": "packages/react-base16-styling/src/themes/embers.ts",
"chars": 433,
"preview": "export default {\n scheme: 'embers',\n author: 'jannik siebert (https://github.com/janniks)',\n base00: '#16130F',\n bas"
},
{
"path": "packages/react-base16-styling/src/themes/flat.ts",
"chars": 427,
"preview": "export default {\n scheme: 'flat',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#2C3E50',\n base01: '"
},
{
"path": "packages/react-base16-styling/src/themes/google.ts",
"chars": 426,
"preview": "export default {\n scheme: 'google',\n author: 'seth wright (http://sethawright.com)',\n base00: '#1d1f21',\n base01: '#"
},
{
"path": "packages/react-base16-styling/src/themes/grayscale.ts",
"chars": 439,
"preview": "export default {\n scheme: 'grayscale',\n author: 'alexandre gavioli (https://github.com/alexx2/)',\n base00: '#101010',"
},
{
"path": "packages/react-base16-styling/src/themes/greenscreen.ts",
"chars": 435,
"preview": "export default {\n scheme: 'green screen',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#001100',\n b"
},
{
"path": "packages/react-base16-styling/src/themes/harmonic.ts",
"chars": 437,
"preview": "export default {\n scheme: 'harmonic16',\n author: 'jannik siebert (https://github.com/janniks)',\n base00: '#0b1c2c',\n "
},
{
"path": "packages/react-base16-styling/src/themes/hopscotch.ts",
"chars": 404,
"preview": "export default {\n scheme: 'hopscotch',\n author: 'jan t. sott',\n base00: '#322931',\n base01: '#433b42',\n base02: '#5"
},
{
"path": "packages/react-base16-styling/src/themes/index.ts",
"chars": 2913,
"preview": "import { default as threezerotwofour } from './threezerotwofour.js';\nimport { default as apathy } from './apathy.js';\nim"
},
{
"path": "packages/react-base16-styling/src/themes/isotope.ts",
"chars": 402,
"preview": "export default {\n scheme: 'isotope',\n author: 'jan t. sott',\n base00: '#000000',\n base01: '#404040',\n base02: '#606"
},
{
"path": "packages/react-base16-styling/src/themes/marrakesh.ts",
"chars": 438,
"preview": "export default {\n scheme: 'marrakesh',\n author: 'alexandre gavioli (http://github.com/alexx2/)',\n base00: '#201602',\n"
},
{
"path": "packages/react-base16-styling/src/themes/mocha.ts",
"chars": 428,
"preview": "export default {\n scheme: 'mocha',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#3B3228',\n base01: "
},
{
"path": "packages/react-base16-styling/src/themes/monokai.ts",
"chars": 430,
"preview": "export default {\n scheme: 'monokai',\n author: 'wimer hazenberg (http://www.monokai.nl)',\n base00: '#272822',\n base01"
},
{
"path": "packages/react-base16-styling/src/themes/nicinabox.ts",
"chars": 600,
"preview": "export default {\n scheme: 'nicinabox',\n author: 'nicinabox (http://github.com/nicinabox)',\n base00: '#2A2F3A',\n base"
},
{
"path": "packages/react-base16-styling/src/themes/ocean.ts",
"chars": 428,
"preview": "export default {\n scheme: 'ocean',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#2b303b',\n base01: "
},
{
"path": "packages/react-base16-styling/src/themes/paraiso.ts",
"chars": 402,
"preview": "export default {\n scheme: 'paraiso',\n author: 'jan t. sott',\n base00: '#2f1e2e',\n base01: '#41323f',\n base02: '#4f4"
},
{
"path": "packages/react-base16-styling/src/themes/pop.ts",
"chars": 426,
"preview": "export default {\n scheme: 'pop',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#000000',\n base01: '#"
},
{
"path": "packages/react-base16-styling/src/themes/railscasts.ts",
"chars": 428,
"preview": "export default {\n scheme: 'railscasts',\n author: 'ryan bates (http://railscasts.com)',\n base00: '#2b2b2b',\n base01: "
},
{
"path": "packages/react-base16-styling/src/themes/shapeshifter.ts",
"chars": 430,
"preview": "export default {\n scheme: 'shapeshifter',\n author: 'tyler benziger (http://tybenz.com)',\n base00: '#000000',\n base01"
},
{
"path": "packages/react-base16-styling/src/themes/solarized.ts",
"chars": 448,
"preview": "export default {\n scheme: 'solarized',\n author: 'ethan schoonover (http://ethanschoonover.com/solarized)',\n base00: '"
},
{
"path": "packages/react-base16-styling/src/themes/summerfruit.ts",
"chars": 442,
"preview": "export default {\n scheme: 'summerfruit',\n author: 'christopher corley (http://cscorley.github.io/)',\n base00: '#15151"
},
{
"path": "packages/react-base16-styling/src/themes/threezerotwofour.ts",
"chars": 440,
"preview": "export default {\n scheme: 'threezerotwofour',\n author: 'jan t. sott (http://github.com/idleberg)',\n base00: '#090300'"
},
{
"path": "packages/react-base16-styling/src/themes/tomorrow.ts",
"chars": 431,
"preview": "export default {\n scheme: 'tomorrow',\n author: 'chris kempson (http://chriskempson.com)',\n base00: '#1d1f21',\n base0"
},
{
"path": "packages/react-base16-styling/src/themes/tube.ts",
"chars": 406,
"preview": "export default {\n scheme: 'london tube',\n author: 'jan t. sott',\n base00: '#231f20',\n base01: '#1c3f95',\n base02: '"
},
{
"path": "packages/react-base16-styling/src/themes/twilight.ts",
"chars": 424,
"preview": "export default {\n scheme: 'twilight',\n author: 'david hart (http://hart-dev.com)',\n base00: '#1e1e1e',\n base01: '#32"
},
{
"path": "packages/react-base16-styling/src/types.ts",
"chars": 817,
"preview": "import * as CSS from 'csstype';\nimport type { Base16Theme } from './themes/index.js';\n\nexport interface Styling {\n clas"
},
{
"path": "packages/react-base16-styling/test/index.test.ts",
"chars": 5061,
"preview": "import {\n createStyling,\n invertBase16Theme,\n getBase16Theme,\n} from '../src/index.js';\nimport { base16Themes, Base16"
},
{
"path": "packages/react-base16-styling/tsconfig.json",
"chars": 118,
"preview": "{\n \"extends\": \"../../tsconfig.esm.base.json\",\n \"compilerOptions\": {\n \"outDir\": \"lib\"\n },\n \"include\": [\"src\"]\n}\n"
},
{
"path": "packages/react-base16-styling/tsconfig.test.json",
"chars": 128,
"preview": "{\n \"extends\": \"../../tsconfig.esm.base.json\",\n \"compilerOptions\": {\n \"types\": [\"jest\"]\n },\n \"include\": [\"src\", \"t"
},
{
"path": "packages/react-dock/CHANGELOG.md",
"chars": 1598,
"preview": "# Change Log\n\n## 0.8.0\n\n### Minor Changes\n\n- 6830118: Add React 19 to peer deps\n\n## 0.7.0\n\n### Minor Changes\n\n- bbb1a40:"
},
{
"path": "packages/react-dock/LICENSE",
"chars": 1087,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Alexander Kuznetsov\n\nPermission is hereby granted, free of charge, to any pers"
},
{
"path": "packages/react-dock/README.md",
"chars": 4921,
"preview": "# react-dock\n\nResizable dockable react component.\n\n#### Demo\n\n[http://alexkuz.github.io/react-dock/demo/](http://alexkuz"
},
{
"path": "packages/react-dock/demo/CHANGELOG.md",
"chars": 270,
"preview": "# react-dock-demo\n\n## 0.1.7\n\n### Patch Changes\n\n- Updated dependencies [6830118]\n - react-dock@0.8.0\n\n## 0.1.6\n\n### Pat"
},
{
"path": "packages/react-dock/demo/eslint.config.mjs",
"chars": 406,
"preview": "import eslintJs from '../../../eslint.js.config.base.mjs';\nimport eslintTs from '../../../eslint.ts.react.config.base.mj"
},
{
"path": "packages/react-dock/demo/index.html",
"chars": 1113,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-w"
},
{
"path": "packages/react-dock/demo/package.json",
"chars": 716,
"preview": "{\n \"private\": true,\n \"name\": \"react-dock-demo\",\n \"version\": \"0.1.7\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"scrip"
},
{
"path": "packages/react-dock/demo/src/App.tsx",
"chars": 4837,
"preview": "import React, { Component } from 'react';\nimport { Button, Form } from 'react-bootstrap';\nimport { BsX } from 'react-ico"
},
{
"path": "packages/react-dock/demo/src/index.tsx",
"chars": 187,
"preview": "import React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport App from './App.js';\n\nconst root = ReactDOM.c"
}
]
// ... and 674 more files (download for full content)
About this extraction
This page contains the full source code of the reduxjs/redux-devtools GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 874 files (1.7 MB), approximately 487.3k tokens, and a symbol index with 1714 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.