mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-06-15 18:43:13 +03:00
feat(redux-devtools-inspector): convert to TypeScript (#623)
* stash * stash * stash * stash * preset * @types/dragula
This commit is contained in:
parent
3cd1ae1754
commit
c7b0c7aa6e
|
@ -4,6 +4,7 @@
|
||||||
"@babel/cli": "^7.10.5",
|
"@babel/cli": "^7.10.5",
|
||||||
"@babel/core": "^7.11.1",
|
"@babel/core": "^7.11.1",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
||||||
|
"@babel/plugin-transform-runtime": "^7.11.0",
|
||||||
"@babel/preset-env": "^7.11.0",
|
"@babel/preset-env": "^7.11.0",
|
||||||
"@babel/preset-typescript": "^7.10.4",
|
"@babel/preset-typescript": "^7.10.4",
|
||||||
"@types/jest": "^26.0.9",
|
"@types/jest": "^26.0.9",
|
||||||
|
@ -14,12 +15,16 @@
|
||||||
"@typescript-eslint/parser": "^3.9.0",
|
"@typescript-eslint/parser": "^3.9.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"babel-loader": "^8.1.0",
|
"babel-loader": "^8.1.0",
|
||||||
|
"clean-webpack-plugin": "^3.0.0",
|
||||||
|
"cross-env": "^7.0.2",
|
||||||
"eslint": "^7.6.0",
|
"eslint": "^7.6.0",
|
||||||
"eslint-config-prettier": "^6.11.0",
|
"eslint-config-prettier": "^6.11.0",
|
||||||
"eslint-plugin-babel": "^5.3.1",
|
"eslint-plugin-babel": "^5.3.1",
|
||||||
"eslint-plugin-jest": "^23.20.0",
|
"eslint-plugin-jest": "^23.20.0",
|
||||||
"eslint-plugin-prettier": "^3.1.4",
|
"eslint-plugin-prettier": "^3.1.4",
|
||||||
"eslint-plugin-react": "^7.20.5",
|
"eslint-plugin-react": "^7.20.5",
|
||||||
|
"fork-ts-checker-webpack-plugin": "^5.1.0",
|
||||||
|
"html-webpack-plugin": "^4.3.0",
|
||||||
"jest": "^26.2.2",
|
"jest": "^26.2.2",
|
||||||
"lerna": "^3.22.1",
|
"lerna": "^3.22.1",
|
||||||
"prettier": "^2.0.5",
|
"prettier": "^2.0.5",
|
||||||
|
|
|
@ -142,7 +142,7 @@ const mergeStylings = (
|
||||||
|
|
||||||
const getStylingByKeys = (
|
const getStylingByKeys = (
|
||||||
mergedStyling: StylingConfig,
|
mergedStyling: StylingConfig,
|
||||||
keys: string | string[],
|
keys: (string | false | undefined) | (string | false | undefined)[],
|
||||||
...args: any[]
|
...args: any[]
|
||||||
): Styling => {
|
): Styling => {
|
||||||
if (keys === null) {
|
if (keys === null) {
|
||||||
|
@ -153,7 +153,9 @@ const getStylingByKeys = (
|
||||||
keys = [keys];
|
keys = [keys];
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = keys.map((key) => mergedStyling[key]).filter(Boolean);
|
const styles = keys
|
||||||
|
.map((key) => mergedStyling[key as string])
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
const props = styles.reduce(
|
const props = styles.reduce(
|
||||||
(obj, s) => {
|
(obj, s) => {
|
||||||
|
|
|
@ -27,6 +27,6 @@ export type StylingConfig = {
|
||||||
export type Theme = string | Base16Theme | StylingConfig;
|
export type Theme = string | Base16Theme | StylingConfig;
|
||||||
|
|
||||||
export type StylingFunction = (
|
export type StylingFunction = (
|
||||||
keys: string | string[],
|
keys: (string | false | undefined) | (string | false | undefined)[],
|
||||||
...rest: any[]
|
...rest: any[]
|
||||||
) => Styling;
|
) => Styling;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { hot } from 'react-hot-loader/root';
|
import { hot } from 'react-hot-loader/root';
|
||||||
|
import React, { Component } from 'react';
|
||||||
import Button from 'react-bootstrap/Button';
|
import Button from 'react-bootstrap/Button';
|
||||||
import Form from 'react-bootstrap/Form';
|
import Form from 'react-bootstrap/Form';
|
||||||
import { BsX } from 'react-icons/bs';
|
import { BsX } from 'react-icons/bs';
|
||||||
|
|
|
@ -5,7 +5,6 @@ const isProduction = process.env.NODE_ENV === 'production';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: isProduction ? 'production' : 'development',
|
mode: isProduction ? 'production' : 'development',
|
||||||
devtool: 'eval',
|
|
||||||
entry: isProduction
|
entry: isProduction
|
||||||
? ['./demo/src/index']
|
? ['./demo/src/index']
|
||||||
: [
|
: [
|
||||||
|
@ -18,10 +17,6 @@ module.exports = {
|
||||||
filename: 'bundle.js',
|
filename: 'bundle.js',
|
||||||
publicPath: isProduction ? 'static/' : '/static/',
|
publicPath: isProduction ? 'static/' : '/static/',
|
||||||
},
|
},
|
||||||
plugins: isProduction ? [] : [new webpack.HotModuleReplacementPlugin()],
|
|
||||||
resolve: {
|
|
||||||
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
|
||||||
},
|
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
|
@ -34,6 +29,10 @@ module.exports = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||||
|
},
|
||||||
|
plugins: isProduction ? [] : [new webpack.HotModuleReplacementPlugin()],
|
||||||
devServer: isProduction
|
devServer: isProduction
|
||||||
? null
|
? null
|
||||||
: {
|
: {
|
||||||
|
@ -46,4 +45,5 @@ module.exports = {
|
||||||
},
|
},
|
||||||
historyApiFallback: true,
|
historyApiFallback: true,
|
||||||
},
|
},
|
||||||
|
devtool: 'eval-source-map',
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
{
|
{
|
||||||
"presets": ["@babel/preset-env", "@babel/preset-react"],
|
"presets": [
|
||||||
|
"@babel/preset-env",
|
||||||
|
"@babel/preset-react",
|
||||||
|
"@babel/preset-typescript"
|
||||||
|
],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"@babel/plugin-transform-runtime",
|
|
||||||
"@babel/plugin-proposal-class-properties",
|
"@babel/plugin-proposal-class-properties",
|
||||||
"@babel/plugin-proposal-export-default-from",
|
"@babel/plugin-transform-runtime"
|
||||||
"@babel/plugin-proposal-do-expressions"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
1
packages/redux-devtools-inspector/.eslintignore
Normal file
1
packages/redux-devtools-inspector/.eslintignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
lib
|
29
packages/redux-devtools-inspector/.eslintrc.js
Normal file
29
packages/redux-devtools-inspector/.eslintrc.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
module.exports = {
|
||||||
|
extends: '../../.eslintrc',
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['*.ts', '*.tsx'],
|
||||||
|
extends: '../../eslintrc.ts.react.base.json',
|
||||||
|
parserOptions: {
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
project: ['./tsconfig.json'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['demo/**/*.ts', 'demo/**/*.tsx'],
|
||||||
|
extends: '../../eslintrc.ts.react.base.json',
|
||||||
|
parserOptions: {
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
project: ['./demo/tsconfig.json'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['demo/config/webpack.config.ts'],
|
||||||
|
extends: '../../eslintrc.ts.base.json',
|
||||||
|
parserOptions: {
|
||||||
|
tsconfigRootDir: __dirname,
|
||||||
|
project: ['./demo/config/tsconfig.json'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -1,8 +0,0 @@
|
||||||
static
|
|
||||||
src
|
|
||||||
demo
|
|
||||||
.*
|
|
||||||
webpack.config.js
|
|
||||||
index.html
|
|
||||||
*.gif
|
|
||||||
*.png
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"extends": "../../../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"resolveJsonModule": true
|
||||||
|
},
|
||||||
|
"include": ["webpack.config.ts"]
|
||||||
|
}
|
|
@ -1,15 +1,14 @@
|
||||||
var path = require('path');
|
import * as path from 'path';
|
||||||
var webpack = require('webpack');
|
import * as webpack from 'webpack';
|
||||||
var HtmlWebpackPlugin = require('html-webpack-plugin');
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||||
var { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
|
||||||
|
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
||||||
|
import pkg from '../../package.json';
|
||||||
|
|
||||||
var pkg = require('./package.json');
|
const isProduction = process.env.NODE_ENV === 'production';
|
||||||
|
|
||||||
var isProduction = process.env.NODE_ENV === 'production';
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: process.env.NODE_ENV || 'development',
|
mode: process.env.NODE_ENV || 'development',
|
||||||
devtool: 'eval-source-map',
|
|
||||||
entry: isProduction
|
entry: isProduction
|
||||||
? ['./demo/src/js/index']
|
? ['./demo/src/js/index']
|
||||||
: [
|
: [
|
||||||
|
@ -21,6 +20,21 @@ module.exports = {
|
||||||
path: path.join(__dirname, 'demo/dist'),
|
path: path.join(__dirname, 'demo/dist'),
|
||||||
filename: 'js/bundle.js',
|
filename: 'js/bundle.js',
|
||||||
},
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(js|ts)x?$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
include: [
|
||||||
|
path.join(__dirname, '../../src'),
|
||||||
|
path.join(__dirname, '../src/js'),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new CleanWebpackPlugin(),
|
new CleanWebpackPlugin(),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
|
@ -28,27 +42,12 @@ module.exports = {
|
||||||
template: 'demo/src/index.html',
|
template: 'demo/src/index.html',
|
||||||
package: pkg,
|
package: pkg,
|
||||||
}),
|
}),
|
||||||
new webpack.DefinePlugin({
|
new ForkTsCheckerWebpackPlugin({
|
||||||
'process.env': {
|
typescript: {
|
||||||
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
|
configFile: 'demo/tsconfig.json',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
].concat(isProduction ? [] : [new webpack.HotModuleReplacementPlugin()]),
|
].concat(isProduction ? [] : [new webpack.HotModuleReplacementPlugin()]),
|
||||||
resolve: {
|
|
||||||
extensions: ['*', '.js', '.jsx'],
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.jsx?$/,
|
|
||||||
loader: 'babel-loader',
|
|
||||||
include: [
|
|
||||||
path.join(__dirname, 'src'),
|
|
||||||
path.join(__dirname, 'demo/src/js'),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
devServer: isProduction
|
devServer: isProduction
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
|
@ -61,4 +60,5 @@ module.exports = {
|
||||||
},
|
},
|
||||||
historyApiFallback: true,
|
historyApiFallback: true,
|
||||||
},
|
},
|
||||||
|
devtool: 'eval-source-map',
|
||||||
};
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { CSSProperties } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import pkg from '../../../package.json';
|
import pkg from '../../../package.json';
|
||||||
import Button from 'react-bootstrap/Button';
|
import Button from 'react-bootstrap/Button';
|
||||||
|
@ -8,12 +8,45 @@ import FormLabel from 'react-bootstrap/FormLabel';
|
||||||
import Form from 'react-bootstrap/Form';
|
import Form from 'react-bootstrap/Form';
|
||||||
import Col from 'react-bootstrap/Col';
|
import Col from 'react-bootstrap/Col';
|
||||||
import InputGroup from 'react-bootstrap/InputGroup';
|
import InputGroup from 'react-bootstrap/InputGroup';
|
||||||
|
import Row from 'react-bootstrap/Row';
|
||||||
import * as base16 from 'base16';
|
import * as base16 from 'base16';
|
||||||
import * as inspectorThemes from '../../../src/themes';
|
|
||||||
import getOptions from './getOptions';
|
|
||||||
import { push as pushRoute } from 'connected-react-router';
|
import { push as pushRoute } from 'connected-react-router';
|
||||||
|
import { Path } from 'history';
|
||||||
|
import * as inspectorThemes from '../../../src/themes';
|
||||||
|
import getOptions, { Options } from './getOptions';
|
||||||
|
import {
|
||||||
|
AddFunctionAction,
|
||||||
|
AddHugeObjectAction,
|
||||||
|
AddImmutableMapAction,
|
||||||
|
AddIteratorAction,
|
||||||
|
AddNativeMapAction,
|
||||||
|
AddRecursiveAction,
|
||||||
|
AddSymbolAction,
|
||||||
|
ChangeImmutableNestedAction,
|
||||||
|
ChangeNestedAction,
|
||||||
|
DemoAppState,
|
||||||
|
HugePayloadAction,
|
||||||
|
IncrementAction,
|
||||||
|
PopAction,
|
||||||
|
PushAction,
|
||||||
|
PushHugeArrayAction,
|
||||||
|
ReplaceAction,
|
||||||
|
ShuffleArrayAction,
|
||||||
|
TimeoutUpdateAction,
|
||||||
|
ToggleTimeoutUpdateAction,
|
||||||
|
} from './reducers';
|
||||||
|
|
||||||
const styles = {
|
const styles: {
|
||||||
|
wrapper: CSSProperties;
|
||||||
|
header: CSSProperties;
|
||||||
|
content: CSSProperties;
|
||||||
|
buttons: CSSProperties;
|
||||||
|
muted: CSSProperties;
|
||||||
|
button: CSSProperties;
|
||||||
|
links: CSSProperties;
|
||||||
|
link: CSSProperties;
|
||||||
|
input: CSSProperties;
|
||||||
|
} = {
|
||||||
wrapper: {
|
wrapper: {
|
||||||
height: '100vh',
|
height: '100vh',
|
||||||
width: '80%',
|
width: '80%',
|
||||||
|
@ -57,18 +90,21 @@ const styles = {
|
||||||
const themeOptions = [
|
const themeOptions = [
|
||||||
...Object.keys(inspectorThemes).map((value) => ({
|
...Object.keys(inspectorThemes).map((value) => ({
|
||||||
value,
|
value,
|
||||||
label: inspectorThemes[value].scheme,
|
label: inspectorThemes[value as keyof typeof inspectorThemes].scheme,
|
||||||
})),
|
})),
|
||||||
null,
|
null,
|
||||||
...Object.keys(base16)
|
...Object.keys(base16)
|
||||||
.map((value) => ({ value, label: base16[value].scheme }))
|
.map((value) => ({
|
||||||
|
value,
|
||||||
|
label: base16[value as keyof typeof base16].scheme,
|
||||||
|
}))
|
||||||
.filter((opt) => opt.label),
|
.filter((opt) => opt.label),
|
||||||
];
|
];
|
||||||
|
|
||||||
const ROOT =
|
const ROOT =
|
||||||
process.env.NODE_ENV === 'production' ? '/redux-devtools-inspector/' : '/';
|
process.env.NODE_ENV === 'production' ? '/redux-devtools-inspector/' : '/';
|
||||||
|
|
||||||
function buildUrl(options) {
|
function buildUrl(options: Options) {
|
||||||
return (
|
return (
|
||||||
`${ROOT}?` +
|
`${ROOT}?` +
|
||||||
[
|
[
|
||||||
|
@ -82,7 +118,32 @@ function buildUrl(options) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DemoApp extends React.Component {
|
interface Props
|
||||||
|
extends Omit<DemoAppState, 'addFunction' | 'addSymbol' | 'shuffleArray'> {
|
||||||
|
toggleTimeoutUpdate: (timeoutUpdateEnabled: boolean) => void;
|
||||||
|
timeoutUpdate: () => void;
|
||||||
|
increment: () => void;
|
||||||
|
push: () => void;
|
||||||
|
pop: () => void;
|
||||||
|
replace: () => void;
|
||||||
|
changeNested: () => void;
|
||||||
|
pushHugeArray: () => void;
|
||||||
|
addIterator: () => void;
|
||||||
|
addHugeObject: () => void;
|
||||||
|
addRecursive: () => void;
|
||||||
|
addNativeMap: () => void;
|
||||||
|
addImmutableMap: () => void;
|
||||||
|
changeImmutableNested: () => void;
|
||||||
|
hugePayload: () => void;
|
||||||
|
addFunction: () => void;
|
||||||
|
addSymbol: () => void;
|
||||||
|
shuffleArray: () => void;
|
||||||
|
pushRoute: (path: Path) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DemoApp extends React.Component<Props> {
|
||||||
|
timeout?: number;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const options = getOptions(this.props.router.location);
|
const options = getOptions(this.props.router.location);
|
||||||
|
|
||||||
|
@ -98,8 +159,8 @@ class DemoApp extends React.Component {
|
||||||
</h5>
|
</h5>
|
||||||
<div style={styles.links}>
|
<div style={styles.links}>
|
||||||
<div style={styles.input}>
|
<div style={styles.input}>
|
||||||
<Form horizontal>
|
<Form>
|
||||||
<FormGroup>
|
<FormGroup as={Row}>
|
||||||
<Col as={FormLabel} sm={3}>
|
<Col as={FormLabel} sm={3}>
|
||||||
Theme:
|
Theme:
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -115,7 +176,7 @@ class DemoApp extends React.Component {
|
||||||
<option
|
<option
|
||||||
key={(theme && theme.label) || 'empty'}
|
key={(theme && theme.label) || 'empty'}
|
||||||
label={(theme && theme.label) || '──────────'}
|
label={(theme && theme.label) || '──────────'}
|
||||||
value={theme && theme.value}
|
value={theme ? theme.value : undefined}
|
||||||
disabled={!theme}
|
disabled={!theme}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
@ -151,7 +212,7 @@ class DemoApp extends React.Component {
|
||||||
<Button onClick={this.props.pushHugeArray} style={styles.button}>
|
<Button onClick={this.props.pushHugeArray} style={styles.button}>
|
||||||
Push Huge Array
|
Push Huge Array
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={this.props.addHugeObect} style={styles.button}>
|
<Button onClick={this.props.addHugeObject} style={styles.button}>
|
||||||
Add Huge Object
|
Add Huge Object
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={this.props.addIterator} style={styles.button}>
|
<Button onClick={this.props.addIterator} style={styles.button}>
|
||||||
|
@ -226,7 +287,7 @@ class DemoApp extends React.Component {
|
||||||
this.props.pushRoute(buildUrl({ ...options, dark: !options.dark }));
|
this.props.pushRoute(buildUrl({ ...options, dark: !options.dark }));
|
||||||
};
|
};
|
||||||
|
|
||||||
setTheme = (options, theme) => {
|
setTheme = (options: Options, theme: string) => {
|
||||||
this.props.pushRoute(buildUrl({ ...options, theme }));
|
this.props.pushRoute(buildUrl({ ...options, theme }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -235,37 +296,41 @@ class DemoApp extends React.Component {
|
||||||
this.props.toggleTimeoutUpdate(enabled);
|
this.props.toggleTimeoutUpdate(enabled);
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
this.timeout = setInterval(this.props.timeoutUpdate, 1000);
|
this.timeout = window.setInterval(this.props.timeoutUpdate, 1000);
|
||||||
} else {
|
} else {
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect((state) => state, {
|
export default connect((state: DemoAppState) => state, {
|
||||||
toggleTimeoutUpdate: (timeoutUpdateEnabled) => ({
|
toggleTimeoutUpdate: (
|
||||||
|
timeoutUpdateEnabled: boolean
|
||||||
|
): ToggleTimeoutUpdateAction => ({
|
||||||
type: 'TOGGLE_TIMEOUT_UPDATE',
|
type: 'TOGGLE_TIMEOUT_UPDATE',
|
||||||
timeoutUpdateEnabled,
|
timeoutUpdateEnabled,
|
||||||
}),
|
}),
|
||||||
timeoutUpdate: () => ({ type: 'TIMEOUT_UPDATE' }),
|
timeoutUpdate: (): TimeoutUpdateAction => ({ type: 'TIMEOUT_UPDATE' }),
|
||||||
increment: () => ({ type: 'INCREMENT' }),
|
increment: (): IncrementAction => ({ type: 'INCREMENT' }),
|
||||||
push: () => ({ type: 'PUSH' }),
|
push: (): PushAction => ({ type: 'PUSH' }),
|
||||||
pop: () => ({ type: 'POP' }),
|
pop: (): PopAction => ({ type: 'POP' }),
|
||||||
replace: () => ({ type: 'REPLACE' }),
|
replace: (): ReplaceAction => ({ type: 'REPLACE' }),
|
||||||
changeNested: () => ({ type: 'CHANGE_NESTED' }),
|
changeNested: (): ChangeNestedAction => ({ type: 'CHANGE_NESTED' }),
|
||||||
pushHugeArray: () => ({ type: 'PUSH_HUGE_ARRAY' }),
|
pushHugeArray: (): PushHugeArrayAction => ({ type: 'PUSH_HUGE_ARRAY' }),
|
||||||
addIterator: () => ({ type: 'ADD_ITERATOR' }),
|
addIterator: (): AddIteratorAction => ({ type: 'ADD_ITERATOR' }),
|
||||||
addHugeObect: () => ({ type: 'ADD_HUGE_OBJECT' }),
|
addHugeObject: (): AddHugeObjectAction => ({ type: 'ADD_HUGE_OBJECT' }),
|
||||||
addRecursive: () => ({ type: 'ADD_RECURSIVE' }),
|
addRecursive: (): AddRecursiveAction => ({ type: 'ADD_RECURSIVE' }),
|
||||||
addNativeMap: () => ({ type: 'ADD_NATIVE_MAP' }),
|
addNativeMap: (): AddNativeMapAction => ({ type: 'ADD_NATIVE_MAP' }),
|
||||||
addImmutableMap: () => ({ type: 'ADD_IMMUTABLE_MAP' }),
|
addImmutableMap: (): AddImmutableMapAction => ({ type: 'ADD_IMMUTABLE_MAP' }),
|
||||||
changeImmutableNested: () => ({ type: 'CHANGE_IMMUTABLE_NESTED' }),
|
changeImmutableNested: (): ChangeImmutableNestedAction => ({
|
||||||
hugePayload: () => ({
|
type: 'CHANGE_IMMUTABLE_NESTED',
|
||||||
|
}),
|
||||||
|
hugePayload: (): HugePayloadAction => ({
|
||||||
type: 'HUGE_PAYLOAD',
|
type: 'HUGE_PAYLOAD',
|
||||||
payload: Array.from({ length: 10000 }).map((_, i) => i),
|
payload: Array.from({ length: 10000 }).map((_, i) => i),
|
||||||
}),
|
}),
|
||||||
addFunction: () => ({ type: 'ADD_FUNCTION' }),
|
addFunction: (): AddFunctionAction => ({ type: 'ADD_FUNCTION' }),
|
||||||
addSymbol: () => ({ type: 'ADD_SYMBOL' }),
|
addSymbol: (): AddSymbolAction => ({ type: 'ADD_SYMBOL' }),
|
||||||
shuffleArray: () => ({ type: 'SHUFFLE_ARRAY' }),
|
shuffleArray: (): ShuffleArrayAction => ({ type: 'SHUFFLE_ARRAY' }),
|
||||||
pushRoute,
|
pushRoute,
|
||||||
})(DemoApp);
|
})(DemoApp);
|
|
@ -4,6 +4,9 @@ import { createDevTools } from 'redux-devtools';
|
||||||
import DockMonitor from 'redux-devtools-dock-monitor';
|
import DockMonitor from 'redux-devtools-dock-monitor';
|
||||||
import DevtoolsInspector from '../../../src/DevtoolsInspector';
|
import DevtoolsInspector from '../../../src/DevtoolsInspector';
|
||||||
import getOptions from './getOptions';
|
import getOptions from './getOptions';
|
||||||
|
import { base16Themes } from '../../../src/utils/createStylingFromTheme';
|
||||||
|
import { Location } from 'history';
|
||||||
|
import { DemoAppState } from './reducers';
|
||||||
|
|
||||||
const CustomComponent = () => (
|
const CustomComponent = () => (
|
||||||
<div
|
<div
|
||||||
|
@ -20,7 +23,7 @@ const CustomComponent = () => (
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getDevTools = (location) =>
|
export const getDevTools = (location: { search: string }) =>
|
||||||
createDevTools(
|
createDevTools(
|
||||||
<DockMonitor
|
<DockMonitor
|
||||||
defaultIsVisible
|
defaultIsVisible
|
||||||
|
@ -29,8 +32,7 @@ export const getDevTools = (location) =>
|
||||||
changeMonitorKey="ctrl-m"
|
changeMonitorKey="ctrl-m"
|
||||||
>
|
>
|
||||||
<DevtoolsInspector
|
<DevtoolsInspector
|
||||||
theme={getOptions(location).theme}
|
theme={getOptions(location).theme as keyof typeof base16Themes}
|
||||||
shouldPersistState
|
|
||||||
invertTheme={!getOptions(location).dark}
|
invertTheme={!getOptions(location).dark}
|
||||||
supportImmutable={getOptions(location).supportImmutable}
|
supportImmutable={getOptions(location).supportImmutable}
|
||||||
tabs={(defaultTabs) => [
|
tabs={(defaultTabs) => [
|
||||||
|
@ -44,12 +46,12 @@ export const getDevTools = (location) =>
|
||||||
</DockMonitor>
|
</DockMonitor>
|
||||||
);
|
);
|
||||||
|
|
||||||
const UnconnectedDevTools = ({ location }) => {
|
const UnconnectedDevTools = ({ location }: { location: Location }) => {
|
||||||
const DevTools = getDevTools(location);
|
const DevTools = getDevTools(location);
|
||||||
return <DevTools />;
|
return <DevTools />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state: DemoAppState) => ({
|
||||||
location: state.router.location,
|
location: state.router.location,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
export default function getOptions(location) {
|
|
||||||
return {
|
|
||||||
useExtension: location.search.indexOf('ext') !== -1,
|
|
||||||
supportImmutable: location.search.indexOf('immutable') !== -1,
|
|
||||||
theme: do {
|
|
||||||
const match = location.search.match(/theme=([^&]+)/);
|
|
||||||
match ? match[1] : 'inspector';
|
|
||||||
},
|
|
||||||
dark: location.search.indexOf('dark') !== -1,
|
|
||||||
};
|
|
||||||
}
|
|
20
packages/redux-devtools-inspector/demo/src/js/getOptions.ts
Normal file
20
packages/redux-devtools-inspector/demo/src/js/getOptions.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
export interface Options {
|
||||||
|
useExtension: boolean;
|
||||||
|
supportImmutable: boolean;
|
||||||
|
theme: string;
|
||||||
|
dark: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function getOptions(location: { search: string }) {
|
||||||
|
return {
|
||||||
|
useExtension: location.search.indexOf('ext') !== -1,
|
||||||
|
supportImmutable: location.search.indexOf('immutable') !== -1,
|
||||||
|
theme: getTheme(),
|
||||||
|
dark: location.search.indexOf('dark') !== -1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTheme() {
|
||||||
|
const match = /theme=([^&]+)/.exec(location.search);
|
||||||
|
return match ? match[1] : 'inspector';
|
||||||
|
}
|
|
@ -1,20 +1,25 @@
|
||||||
import '@babel/polyfill';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
import DemoApp from './DemoApp';
|
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import createRootReducer from './reducers';
|
import {
|
||||||
import { createStore, applyMiddleware, compose } from 'redux';
|
createStore,
|
||||||
|
applyMiddleware,
|
||||||
|
compose,
|
||||||
|
StoreEnhancerStoreCreator,
|
||||||
|
StoreEnhancer,
|
||||||
|
} from 'redux';
|
||||||
import logger from 'redux-logger';
|
import logger from 'redux-logger';
|
||||||
import { Route } from 'react-router';
|
import { Route } from 'react-router';
|
||||||
import { createBrowserHistory } from 'history';
|
import { createBrowserHistory } from 'history';
|
||||||
import { ConnectedRouter, routerMiddleware } from 'connected-react-router';
|
import { ConnectedRouter, routerMiddleware } from 'connected-react-router';
|
||||||
import { persistState } from 'redux-devtools';
|
import { persistState } from 'redux-devtools';
|
||||||
|
import DemoApp from './DemoApp';
|
||||||
|
import createRootReducer from './reducers';
|
||||||
import getOptions from './getOptions';
|
import getOptions from './getOptions';
|
||||||
import { ConnectedDevTools, getDevTools } from './DevTools';
|
import { ConnectedDevTools, getDevTools } from './DevTools';
|
||||||
|
|
||||||
function getDebugSessionKey() {
|
function getDebugSessionKey() {
|
||||||
const matches = window.location.href.match(/[?&]debug_session=([^&#]+)\b/);
|
const matches = /[?&]debug_session=([^&#]+)\b/.exec(window.location.href);
|
||||||
return matches && matches.length > 0 ? matches[1] : null;
|
return matches && matches.length > 0 ? matches[1] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,21 +31,23 @@ const DevTools = getDevTools(window.location);
|
||||||
const history = createBrowserHistory();
|
const history = createBrowserHistory();
|
||||||
|
|
||||||
const useDevtoolsExtension =
|
const useDevtoolsExtension =
|
||||||
!!window.__REDUX_DEVTOOLS_EXTENSION__ &&
|
!!((window as unknown) as { __REDUX_DEVTOOLS_EXTENSION__: unknown })
|
||||||
getOptions(window.location).useExtension;
|
.__REDUX_DEVTOOLS_EXTENSION__ && getOptions(window.location).useExtension;
|
||||||
|
|
||||||
const enhancer = compose(
|
const enhancer = compose(
|
||||||
applyMiddleware(logger, routerMiddleware(history)),
|
applyMiddleware(logger, routerMiddleware(history)),
|
||||||
(...args) => {
|
(next: StoreEnhancerStoreCreator) => {
|
||||||
const instrument = useDevtoolsExtension
|
const instrument = useDevtoolsExtension
|
||||||
? window.__REDUX_DEVTOOLS_EXTENSION__()
|
? ((window as unknown) as {
|
||||||
|
__REDUX_DEVTOOLS_EXTENSION__(): StoreEnhancer;
|
||||||
|
}).__REDUX_DEVTOOLS_EXTENSION__()
|
||||||
: DevTools.instrument();
|
: DevTools.instrument();
|
||||||
return instrument(...args);
|
return instrument(next);
|
||||||
},
|
},
|
||||||
persistState(getDebugSessionKey())
|
persistState(getDebugSessionKey())
|
||||||
);
|
);
|
||||||
|
|
||||||
const store = createStore(createRootReducer(history), {}, enhancer);
|
const store = createStore(createRootReducer(history), enhancer);
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
|
@ -1,148 +0,0 @@
|
||||||
import Immutable from 'immutable';
|
|
||||||
import shuffle from 'lodash.shuffle';
|
|
||||||
import { combineReducers } from 'redux';
|
|
||||||
import { connectRouter } from 'connected-react-router';
|
|
||||||
|
|
||||||
const NESTED = {
|
|
||||||
long: {
|
|
||||||
nested: [
|
|
||||||
{
|
|
||||||
path: {
|
|
||||||
to: {
|
|
||||||
a: 'key',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const IMMUTABLE_NESTED = Immutable.fromJS(NESTED);
|
|
||||||
|
|
||||||
/* eslint-disable babel/new-cap */
|
|
||||||
|
|
||||||
const IMMUTABLE_MAP = Immutable.Map({
|
|
||||||
map: Immutable.Map({ a: 1, b: 2, c: 3 }),
|
|
||||||
list: Immutable.List(['a', 'b', 'c']),
|
|
||||||
set: Immutable.Set(['a', 'b', 'c']),
|
|
||||||
stack: Immutable.Stack(['a', 'b', 'c']),
|
|
||||||
seq: Immutable.Seq([1, 2, 3, 4, 5, 6, 7, 8]),
|
|
||||||
});
|
|
||||||
|
|
||||||
const NATIVE_MAP = new window.Map([
|
|
||||||
[
|
|
||||||
'map',
|
|
||||||
new window.Map([
|
|
||||||
[{ first: true }, 1],
|
|
||||||
['second', 2],
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'weakMap',
|
|
||||||
new window.WeakMap([
|
|
||||||
[{ first: true }, 1],
|
|
||||||
[{ second: 1 }, 2],
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
['set', new window.Set([{ first: true }, 'second'])],
|
|
||||||
['weakSet', new window.WeakSet([{ first: true }, { second: 1 }])],
|
|
||||||
]);
|
|
||||||
|
|
||||||
/* eslint-enable babel/new-cap */
|
|
||||||
|
|
||||||
const HUGE_ARRAY = Array.from({ length: 5000 }).map((_, key) => ({
|
|
||||||
str: 'key ' + key,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const HUGE_OBJECT = Array.from({ length: 5000 }).reduce(
|
|
||||||
(o, _, key) => ((o['key ' + key] = 'item ' + key), o),
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
const FUNC = function (a, b, c) {
|
|
||||||
return a + b + c;
|
|
||||||
};
|
|
||||||
|
|
||||||
const RECURSIVE = {};
|
|
||||||
RECURSIVE.obj = RECURSIVE;
|
|
||||||
|
|
||||||
function createIterator() {
|
|
||||||
const iterable = {};
|
|
||||||
iterable[window.Symbol.iterator] = function* iterator() {
|
|
||||||
for (var i = 0; i < 333; i++) {
|
|
||||||
yield 'item ' + i;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return iterable;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DEFAULT_SHUFFLE_ARRAY = [0, 1, null, { id: 1 }, { id: 2 }, 'string'];
|
|
||||||
|
|
||||||
const createRootReducer = (history) =>
|
|
||||||
combineReducers({
|
|
||||||
router: connectRouter(history),
|
|
||||||
timeoutUpdateEnabled: (state = false, action) =>
|
|
||||||
action.type === 'TOGGLE_TIMEOUT_UPDATE'
|
|
||||||
? action.timeoutUpdateEnabled
|
|
||||||
: state,
|
|
||||||
store: (state = 0, action) =>
|
|
||||||
action.type === 'INCREMENT' ? state + 1 : state,
|
|
||||||
undefined: (state = { val: undefined }) => state,
|
|
||||||
null: (state = null) => state,
|
|
||||||
func: (state = () => {}) => state,
|
|
||||||
array: (state = [], action) =>
|
|
||||||
action.type === 'PUSH'
|
|
||||||
? [...state, Math.random()]
|
|
||||||
: action.type === 'POP'
|
|
||||||
? state.slice(0, state.length - 1)
|
|
||||||
: action.type === 'REPLACE'
|
|
||||||
? [Math.random(), ...state.slice(1)]
|
|
||||||
: state,
|
|
||||||
hugeArrays: (state = [], action) =>
|
|
||||||
action.type === 'PUSH_HUGE_ARRAY' ? [...state, ...HUGE_ARRAY] : state,
|
|
||||||
hugeObjects: (state = [], action) =>
|
|
||||||
action.type === 'ADD_HUGE_OBJECT' ? [...state, HUGE_OBJECT] : state,
|
|
||||||
iterators: (state = [], action) =>
|
|
||||||
action.type === 'ADD_ITERATOR' ? [...state, createIterator()] : state,
|
|
||||||
nested: (state = NESTED, action) =>
|
|
||||||
action.type === 'CHANGE_NESTED'
|
|
||||||
? {
|
|
||||||
...state,
|
|
||||||
long: {
|
|
||||||
nested: [
|
|
||||||
{
|
|
||||||
path: {
|
|
||||||
to: {
|
|
||||||
a: state.long.nested[0].path.to.a + '!',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: state,
|
|
||||||
recursive: (state = [], action) =>
|
|
||||||
action.type === 'ADD_RECURSIVE' ? [...state, { ...RECURSIVE }] : state,
|
|
||||||
immutables: (state = [], action) =>
|
|
||||||
action.type === 'ADD_IMMUTABLE_MAP' ? [...state, IMMUTABLE_MAP] : state,
|
|
||||||
maps: (state = [], action) =>
|
|
||||||
action.type === 'ADD_NATIVE_MAP' ? [...state, NATIVE_MAP] : state,
|
|
||||||
immutableNested: (state = IMMUTABLE_NESTED, action) =>
|
|
||||||
action.type === 'CHANGE_IMMUTABLE_NESTED'
|
|
||||||
? state.updateIn(
|
|
||||||
['long', 'nested', 0, 'path', 'to', 'a'],
|
|
||||||
(str) => str + '!'
|
|
||||||
)
|
|
||||||
: state,
|
|
||||||
addFunction: (state = null, action) =>
|
|
||||||
action.type === 'ADD_FUNCTION' ? { f: FUNC } : state,
|
|
||||||
addSymbol: (state = null, action) =>
|
|
||||||
action.type === 'ADD_SYMBOL'
|
|
||||||
? { s: window.Symbol('symbol'), error: new Error('TEST') }
|
|
||||||
: state,
|
|
||||||
shuffleArray: (state = DEFAULT_SHUFFLE_ARRAY, action) =>
|
|
||||||
action.type === 'SHUFFLE_ARRAY' ? shuffle(state) : state,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default createRootReducer;
|
|
267
packages/redux-devtools-inspector/demo/src/js/reducers.ts
Normal file
267
packages/redux-devtools-inspector/demo/src/js/reducers.ts
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
import Immutable from 'immutable';
|
||||||
|
import shuffle from 'lodash.shuffle';
|
||||||
|
import { combineReducers, Reducer } from 'redux';
|
||||||
|
import {
|
||||||
|
connectRouter,
|
||||||
|
LocationChangeAction,
|
||||||
|
RouterState,
|
||||||
|
} from 'connected-react-router';
|
||||||
|
import { History } from 'history';
|
||||||
|
|
||||||
|
type Nested = { long: { nested: { path: { to: { a: string } } }[] } };
|
||||||
|
|
||||||
|
const NESTED = {
|
||||||
|
long: {
|
||||||
|
nested: [
|
||||||
|
{
|
||||||
|
path: {
|
||||||
|
to: {
|
||||||
|
a: 'key',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const IMMUTABLE_NESTED = Immutable.fromJS(NESTED);
|
||||||
|
|
||||||
|
const IMMUTABLE_MAP = Immutable.Map({
|
||||||
|
map: Immutable.Map({ a: 1, b: 2, c: 3 }),
|
||||||
|
list: Immutable.List(['a', 'b', 'c']),
|
||||||
|
set: Immutable.Set(['a', 'b', 'c']),
|
||||||
|
stack: Immutable.Stack(['a', 'b', 'c']),
|
||||||
|
seq: Immutable.Seq([1, 2, 3, 4, 5, 6, 7, 8]),
|
||||||
|
});
|
||||||
|
|
||||||
|
type MapValue =
|
||||||
|
| Map<{ first: boolean } | string, number>
|
||||||
|
| WeakMap<{ first: boolean } | { second: number }, number>
|
||||||
|
| Set<{ first: boolean } | string>
|
||||||
|
| WeakSet<{ first: boolean } | { second: number }>;
|
||||||
|
|
||||||
|
const NATIVE_MAP = new window.Map<string, MapValue>([
|
||||||
|
[
|
||||||
|
'map',
|
||||||
|
new window.Map<{ first: boolean } | string, number>([
|
||||||
|
[{ first: true }, 1],
|
||||||
|
['second', 2],
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'weakMap',
|
||||||
|
new window.WeakMap<{ first: boolean } | { second: number }, number>([
|
||||||
|
[{ first: true }, 1],
|
||||||
|
[{ second: 1 }, 2],
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
['set', new window.Set([{ first: true }, 'second'])],
|
||||||
|
['weakSet', new window.WeakSet([{ first: true }, { second: 1 }])],
|
||||||
|
]);
|
||||||
|
|
||||||
|
const HUGE_ARRAY = Array.from({ length: 5000 }).map((_, key) => ({
|
||||||
|
str: `key ${key}`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const HUGE_OBJECT = Array.from({ length: 5000 }).reduce(
|
||||||
|
(o: { [key: string]: string }, _, key) => (
|
||||||
|
(o[`key ${key}`] = `item ${key}`), o
|
||||||
|
),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
const FUNC = function (a: number, b: number, c: number) {
|
||||||
|
return a + b + c;
|
||||||
|
};
|
||||||
|
|
||||||
|
const RECURSIVE: { obj?: unknown } = {};
|
||||||
|
RECURSIVE.obj = RECURSIVE;
|
||||||
|
|
||||||
|
function createIterator() {
|
||||||
|
const iterable: { [Symbol.iterator](): IterableIterator<string> } = {
|
||||||
|
[Symbol.iterator]: function* iterator() {
|
||||||
|
for (let i = 0; i < 333; i++) {
|
||||||
|
yield `item ${i}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return iterable;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_SHUFFLE_ARRAY = [0, 1, null, { id: 1 }, { id: 2 }, 'string'];
|
||||||
|
|
||||||
|
export interface ToggleTimeoutUpdateAction {
|
||||||
|
type: 'TOGGLE_TIMEOUT_UPDATE';
|
||||||
|
timeoutUpdateEnabled: boolean;
|
||||||
|
}
|
||||||
|
export interface TimeoutUpdateAction {
|
||||||
|
type: 'TIMEOUT_UPDATE';
|
||||||
|
}
|
||||||
|
export interface IncrementAction {
|
||||||
|
type: 'INCREMENT';
|
||||||
|
}
|
||||||
|
export interface PushAction {
|
||||||
|
type: 'PUSH';
|
||||||
|
}
|
||||||
|
export interface PopAction {
|
||||||
|
type: 'POP';
|
||||||
|
}
|
||||||
|
export interface ReplaceAction {
|
||||||
|
type: 'REPLACE';
|
||||||
|
}
|
||||||
|
export interface ChangeNestedAction {
|
||||||
|
type: 'CHANGE_NESTED';
|
||||||
|
}
|
||||||
|
export interface PushHugeArrayAction {
|
||||||
|
type: 'PUSH_HUGE_ARRAY';
|
||||||
|
}
|
||||||
|
export interface AddIteratorAction {
|
||||||
|
type: 'ADD_ITERATOR';
|
||||||
|
}
|
||||||
|
export interface AddHugeObjectAction {
|
||||||
|
type: 'ADD_HUGE_OBJECT';
|
||||||
|
}
|
||||||
|
export interface AddRecursiveAction {
|
||||||
|
type: 'ADD_RECURSIVE';
|
||||||
|
}
|
||||||
|
export interface AddNativeMapAction {
|
||||||
|
type: 'ADD_NATIVE_MAP';
|
||||||
|
}
|
||||||
|
export interface AddImmutableMapAction {
|
||||||
|
type: 'ADD_IMMUTABLE_MAP';
|
||||||
|
}
|
||||||
|
export interface ChangeImmutableNestedAction {
|
||||||
|
type: 'CHANGE_IMMUTABLE_NESTED';
|
||||||
|
}
|
||||||
|
export interface HugePayloadAction {
|
||||||
|
type: 'HUGE_PAYLOAD';
|
||||||
|
payload: number[];
|
||||||
|
}
|
||||||
|
export interface AddFunctionAction {
|
||||||
|
type: 'ADD_FUNCTION';
|
||||||
|
}
|
||||||
|
export interface AddSymbolAction {
|
||||||
|
type: 'ADD_SYMBOL';
|
||||||
|
}
|
||||||
|
export interface ShuffleArrayAction {
|
||||||
|
type: 'SHUFFLE_ARRAY';
|
||||||
|
}
|
||||||
|
type DemoAppAction =
|
||||||
|
| ToggleTimeoutUpdateAction
|
||||||
|
| TimeoutUpdateAction
|
||||||
|
| IncrementAction
|
||||||
|
| PushAction
|
||||||
|
| PopAction
|
||||||
|
| ReplaceAction
|
||||||
|
| ChangeNestedAction
|
||||||
|
| PushHugeArrayAction
|
||||||
|
| AddIteratorAction
|
||||||
|
| AddHugeObjectAction
|
||||||
|
| AddRecursiveAction
|
||||||
|
| AddNativeMapAction
|
||||||
|
| AddImmutableMapAction
|
||||||
|
| ChangeImmutableNestedAction
|
||||||
|
| HugePayloadAction
|
||||||
|
| AddFunctionAction
|
||||||
|
| AddSymbolAction
|
||||||
|
| ShuffleArrayAction
|
||||||
|
| LocationChangeAction;
|
||||||
|
|
||||||
|
export interface DemoAppState {
|
||||||
|
router: RouterState;
|
||||||
|
timeoutUpdateEnabled: boolean;
|
||||||
|
store: number;
|
||||||
|
undefined: { val: undefined };
|
||||||
|
null: null;
|
||||||
|
func: () => void;
|
||||||
|
array: number[];
|
||||||
|
hugeArrays: { str: string }[];
|
||||||
|
hugeObjects: { [key: string]: string }[];
|
||||||
|
iterators: { [Symbol.iterator](): IterableIterator<string> }[];
|
||||||
|
nested: Nested;
|
||||||
|
recursive: { obj?: unknown }[];
|
||||||
|
immutables: Immutable.Map<string, unknown>[];
|
||||||
|
maps: Map<string, MapValue>[];
|
||||||
|
immutableNested: Immutable.Map<unknown, unknown>;
|
||||||
|
addFunction: { f: (a: number, b: number, c: number) => number } | null;
|
||||||
|
addSymbol: { s: symbol; error: Error } | null;
|
||||||
|
shuffleArray: unknown[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const createRootReducer = (
|
||||||
|
history: History
|
||||||
|
): Reducer<DemoAppState, DemoAppAction> =>
|
||||||
|
combineReducers<DemoAppState, DemoAppAction>({
|
||||||
|
router: connectRouter(history) as Reducer<RouterState, DemoAppAction>,
|
||||||
|
timeoutUpdateEnabled: (state = false, action: DemoAppAction) =>
|
||||||
|
action.type === 'TOGGLE_TIMEOUT_UPDATE'
|
||||||
|
? action.timeoutUpdateEnabled
|
||||||
|
: state,
|
||||||
|
store: (state = 0, action) =>
|
||||||
|
action.type === 'INCREMENT' ? state + 1 : state,
|
||||||
|
undefined: (state = { val: undefined }) => state,
|
||||||
|
null: (state = null) => state,
|
||||||
|
func: (
|
||||||
|
state = () => {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
) => state,
|
||||||
|
array: (state = [], action: DemoAppAction) =>
|
||||||
|
action.type === 'PUSH'
|
||||||
|
? [...state, Math.random()]
|
||||||
|
: action.type === 'POP'
|
||||||
|
? state.slice(0, state.length - 1)
|
||||||
|
: action.type === 'REPLACE'
|
||||||
|
? [Math.random(), ...state.slice(1)]
|
||||||
|
: state,
|
||||||
|
hugeArrays: (state = [], action: DemoAppAction) =>
|
||||||
|
action.type === 'PUSH_HUGE_ARRAY' ? [...state, ...HUGE_ARRAY] : state,
|
||||||
|
hugeObjects: (state = [], action: DemoAppAction) =>
|
||||||
|
action.type === 'ADD_HUGE_OBJECT' ? [...state, HUGE_OBJECT] : state,
|
||||||
|
iterators: (state = [], action: DemoAppAction) =>
|
||||||
|
action.type === 'ADD_ITERATOR' ? [...state, createIterator()] : state,
|
||||||
|
nested: (state = NESTED, action: DemoAppAction) =>
|
||||||
|
action.type === 'CHANGE_NESTED'
|
||||||
|
? {
|
||||||
|
...state,
|
||||||
|
long: {
|
||||||
|
nested: [
|
||||||
|
{
|
||||||
|
path: {
|
||||||
|
to: {
|
||||||
|
a: state.long.nested[0].path.to.a + '!',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: state,
|
||||||
|
recursive: (state: { obj?: unknown }[] = [], action: DemoAppAction) =>
|
||||||
|
action.type === 'ADD_RECURSIVE' ? [...state, { ...RECURSIVE }] : state,
|
||||||
|
immutables: (
|
||||||
|
state: Immutable.Map<string, unknown>[] = [],
|
||||||
|
action: DemoAppAction
|
||||||
|
) =>
|
||||||
|
action.type === 'ADD_IMMUTABLE_MAP' ? [...state, IMMUTABLE_MAP] : state,
|
||||||
|
maps: (state: Map<string, MapValue>[] = [], action: DemoAppAction) =>
|
||||||
|
action.type === 'ADD_NATIVE_MAP' ? [...state, NATIVE_MAP] : state,
|
||||||
|
immutableNested: (state = IMMUTABLE_NESTED, action: DemoAppAction) =>
|
||||||
|
action.type === 'CHANGE_IMMUTABLE_NESTED'
|
||||||
|
? state.updateIn(
|
||||||
|
['long', 'nested', 0, 'path', 'to', 'a'],
|
||||||
|
(str: string) => str + '!'
|
||||||
|
)
|
||||||
|
: state,
|
||||||
|
addFunction: (state = null, action: DemoAppAction) =>
|
||||||
|
action.type === 'ADD_FUNCTION' ? { f: FUNC } : state,
|
||||||
|
addSymbol: (state = null, action: DemoAppAction) =>
|
||||||
|
action.type === 'ADD_SYMBOL'
|
||||||
|
? { s: window.Symbol('symbol'), error: new Error('TEST') }
|
||||||
|
: state,
|
||||||
|
shuffleArray: (state = DEFAULT_SHUFFLE_ARRAY, action: DemoAppAction) =>
|
||||||
|
action.type === 'SHUFFLE_ARRAY' ? shuffle(state) : state,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default createRootReducer;
|
7
packages/redux-devtools-inspector/demo/tsconfig.json
Normal file
7
packages/redux-devtools-inspector/demo/tsconfig.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"extends": "../../../tsconfig.react.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"resolveJsonModule": true
|
||||||
|
},
|
||||||
|
"include": ["../src", "src"]
|
||||||
|
}
|
3
packages/redux-devtools-inspector/jest.config.js
Normal file
3
packages/redux-devtools-inspector/jest.config.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
};
|
|
@ -2,70 +2,42 @@
|
||||||
"name": "redux-devtools-inspector",
|
"name": "redux-devtools-inspector",
|
||||||
"version": "0.13.1",
|
"version": "0.13.1",
|
||||||
"description": "Redux DevTools Diff Monitor",
|
"description": "Redux DevTools Diff Monitor",
|
||||||
"scripts": {
|
"homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-inspector",
|
||||||
"build": "npm run build:lib",
|
"bugs": {
|
||||||
"build:lib": "cross-env NODE_ENV=production babel src --out-dir lib",
|
"url": "https://github.com/reduxjs/redux-devtools/issues"
|
||||||
"build:demo": "cross-env NODE_ENV=production webpack -p",
|
|
||||||
"stats": "webpack --profile --json > stats.json",
|
|
||||||
"start": "webpack-dev-server",
|
|
||||||
"lint": "eslint --ext .jsx,.js --max-warnings 0 src",
|
|
||||||
"preversion": "npm run lint",
|
|
||||||
"version": "npm run build:demo && git add -A .",
|
|
||||||
"postversion": "git push",
|
|
||||||
"prepare": "npm run build:lib",
|
|
||||||
"prepublishOnly": "npm run build:lib",
|
|
||||||
"gh": "git subtree push --prefix demo/dist origin gh-pages"
|
|
||||||
},
|
|
||||||
"main": "lib/index.js",
|
|
||||||
"repository": {
|
|
||||||
"url": "https://github.com/reduxjs/redux-devtools"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@babel/cli": "^7.10.5",
|
|
||||||
"@babel/core": "^7.11.1",
|
|
||||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
|
||||||
"@babel/plugin-proposal-do-expressions": "^7.10.4",
|
|
||||||
"@babel/plugin-proposal-export-default-from": "^7.10.4",
|
|
||||||
"@babel/plugin-transform-runtime": "^7.11.0",
|
|
||||||
"@babel/polyfill": "^7.10.4",
|
|
||||||
"@babel/preset-env": "^7.11.0",
|
|
||||||
"@babel/preset-react": "^7.10.4",
|
|
||||||
"babel-loader": "^8.1.0",
|
|
||||||
"base16": "^1.0.0",
|
|
||||||
"clean-webpack-plugin": "^3.0.0",
|
|
||||||
"connected-react-router": "^6.8.0",
|
|
||||||
"cross-env": "^7.0.2",
|
|
||||||
"history": "^4.10.1",
|
|
||||||
"html-webpack-plugin": "^4.3.0",
|
|
||||||
"immutable": "^4.0.0-rc.12",
|
|
||||||
"lodash.isequalwith": "^4.4.0",
|
|
||||||
"lodash.shuffle": "^4.2.0",
|
|
||||||
"react": "^16.13.1",
|
|
||||||
"react-bootstrap": "^1.3.0",
|
|
||||||
"react-dom": "^16.13.1",
|
|
||||||
"react-redux": "^7.2.1",
|
|
||||||
"react-router": "^5.2.0",
|
|
||||||
"react-transform-hmr": "^1.0.4",
|
|
||||||
"redux": "^4.0.5",
|
|
||||||
"redux-devtools": "^3.6.1",
|
|
||||||
"redux-devtools-dock-monitor": "^1.1.4",
|
|
||||||
"redux-logger": "^3.0.6",
|
|
||||||
"seamless-immutable": "^7.1.4",
|
|
||||||
"webpack": "^4.44.1",
|
|
||||||
"webpack-cli": "^3.3.12",
|
|
||||||
"webpack-dev-server": "^3.11.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^16.3.0",
|
|
||||||
"react-dom": "^16.3.0"
|
|
||||||
},
|
},
|
||||||
|
"license": "MIT",
|
||||||
"author": "Alexander <alexkuz@gmail.com> (http://kuzya.org/)",
|
"author": "Alexander <alexkuz@gmail.com> (http://kuzya.org/)",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Mihail Diordiev <zalmoxisus@gmail.com> (https://github.com/zalmoxisus)"
|
"Mihail Diordiev <zalmoxisus@gmail.com> (https://github.com/zalmoxisus)"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"files": [
|
||||||
|
"lib",
|
||||||
|
"src"
|
||||||
|
],
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"types": "lib/index.d.ts",
|
||||||
|
"repository": {
|
||||||
|
"url": "https://github.com/reduxjs/redux-devtools"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "webpack-dev-server --config demo/config/webpack.config.ts",
|
||||||
|
"stats": "webpack --profile --json > stats.json",
|
||||||
|
"build:demo": "NODE_ENV=production webpack -p",
|
||||||
|
"build": "npm run build:types && npm run build:js",
|
||||||
|
"build:types": "tsc --emitDeclarationOnly",
|
||||||
|
"build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline",
|
||||||
|
"clean": "rimraf lib",
|
||||||
|
"lint": "eslint . --ext .ts,.tsx",
|
||||||
|
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
||||||
|
"type-check": "tsc --noEmit",
|
||||||
|
"type-check:watch": "npm run type-check -- --watch",
|
||||||
|
"preversion": "npm run type-check && npm run lint",
|
||||||
|
"prepublishOnly": "npm run clean && npm run build"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"babel-runtime": "^6.26.0",
|
"@types/dragula": "^3.7.0",
|
||||||
|
"@types/prop-types": "^15.7.3",
|
||||||
"dateformat": "^3.0.3",
|
"dateformat": "^3.0.3",
|
||||||
"hex-rgba": "^1.0.2",
|
"hex-rgba": "^1.0.2",
|
||||||
"javascript-stringify": "^2.0.1",
|
"javascript-stringify": "^2.0.1",
|
||||||
|
@ -77,7 +49,39 @@
|
||||||
"react-base16-styling": "^0.7.0",
|
"react-base16-styling": "^0.7.0",
|
||||||
"react-dragula": "^1.1.17",
|
"react-dragula": "^1.1.17",
|
||||||
"react-json-tree": "^0.12.1",
|
"react-json-tree": "^0.12.1",
|
||||||
"react-pure-render": "^1.0.2",
|
|
||||||
"redux-devtools-themes": "^1.0.0"
|
"redux-devtools-themes": "^1.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/runtime": "^7.11.2",
|
||||||
|
"@types/dateformat": "^3.0.1",
|
||||||
|
"@types/hex-rgba": "^1.0.0",
|
||||||
|
"@types/history": "^4.7.7",
|
||||||
|
"@types/lodash.debounce": "^4.0.6",
|
||||||
|
"@types/lodash.shuffle": "^4.2.6",
|
||||||
|
"@types/react": "^16.9.46",
|
||||||
|
"@types/react-dragula": "^1.1.0",
|
||||||
|
"@types/react-router": "^5.1.8",
|
||||||
|
"@types/redux-logger": "^3.0.8",
|
||||||
|
"base16": "^1.0.0",
|
||||||
|
"connected-react-router": "^6.8.0",
|
||||||
|
"history": "^4.10.1",
|
||||||
|
"immutable": "^4.0.0-rc.12",
|
||||||
|
"lodash.isequalwith": "^4.4.0",
|
||||||
|
"lodash.shuffle": "^4.2.0",
|
||||||
|
"react": "^16.13.1",
|
||||||
|
"react-bootstrap": "^1.3.0",
|
||||||
|
"react-dom": "^16.13.1",
|
||||||
|
"react-redux": "^7.2.1",
|
||||||
|
"react-router": "^5.2.0",
|
||||||
|
"redux": "^4.0.5",
|
||||||
|
"redux-devtools": "^3.6.1",
|
||||||
|
"redux-devtools-dock-monitor": "^1.1.4",
|
||||||
|
"redux-logger": "^3.0.6",
|
||||||
|
"seamless-immutable": "^7.1.4"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^16.3.18",
|
||||||
|
"react": "^16.3.0",
|
||||||
|
"redux": "^3.4.0 || ^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"import": true
|
|
||||||
}
|
|
|
@ -1,10 +1,17 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent, RefCallback } from 'react';
|
||||||
|
import { Drake } from 'dragula';
|
||||||
import dragula from 'react-dragula';
|
import dragula from 'react-dragula';
|
||||||
|
import { Action } from 'redux';
|
||||||
|
import { PerformAction } from 'redux-devtools';
|
||||||
|
import { StylingFunction } from 'react-base16-styling';
|
||||||
import ActionListRow from './ActionListRow';
|
import ActionListRow from './ActionListRow';
|
||||||
import ActionListHeader from './ActionListHeader';
|
import ActionListHeader from './ActionListHeader';
|
||||||
import shouldPureComponentUpdate from 'react-pure-render/function';
|
|
||||||
|
|
||||||
function getTimestamps(actions, actionIds, actionId) {
|
function getTimestamps<A extends Action<unknown>>(
|
||||||
|
actions: { [actionId: number]: PerformAction<A> },
|
||||||
|
actionIds: number[],
|
||||||
|
actionId: number
|
||||||
|
) {
|
||||||
const idx = actionIds.indexOf(actionId);
|
const idx = actionIds.indexOf(actionId);
|
||||||
const prevActionId = actionIds[idx - 1];
|
const prevActionId = actionIds[idx - 1];
|
||||||
|
|
||||||
|
@ -14,10 +21,37 @@ function getTimestamps(actions, actionIds, actionId) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ActionList extends Component {
|
interface Props<A extends Action<unknown>> {
|
||||||
shouldComponentUpdate = shouldPureComponentUpdate;
|
actions: { [actionId: number]: PerformAction<A> };
|
||||||
|
actionIds: number[];
|
||||||
|
isWideLayout: boolean;
|
||||||
|
searchValue: string | undefined;
|
||||||
|
selectedActionId: number | null;
|
||||||
|
startActionId: number | null;
|
||||||
|
skippedActionIds: number[];
|
||||||
|
draggableActions: boolean;
|
||||||
|
hideMainButtons: boolean | undefined;
|
||||||
|
hideActionButtons: boolean | undefined;
|
||||||
|
styling: StylingFunction;
|
||||||
|
onSearch: (value: string) => void;
|
||||||
|
onSelect: (e: React.MouseEvent<HTMLDivElement>, actionId: number) => void;
|
||||||
|
onToggleAction: (actionId: number) => void;
|
||||||
|
onJumpToState: (actionId: number) => void;
|
||||||
|
onCommit: () => void;
|
||||||
|
onSweep: () => void;
|
||||||
|
onReorderAction: (actionId: number, beforeActionId: number) => void;
|
||||||
|
currentActionId: number;
|
||||||
|
lastActionId: number;
|
||||||
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
export default class ActionList<
|
||||||
|
A extends Action<unknown>
|
||||||
|
> extends PureComponent<Props<A>> {
|
||||||
|
node?: HTMLDivElement | null;
|
||||||
|
scrollDown?: boolean;
|
||||||
|
drake?: Drake;
|
||||||
|
|
||||||
|
UNSAFE_componentWillReceiveProps(nextProps: Props<A>) {
|
||||||
const node = this.node;
|
const node = this.node;
|
||||||
if (!node) {
|
if (!node) {
|
||||||
this.scrollDown = true;
|
this.scrollDown = true;
|
||||||
|
@ -35,22 +69,22 @@ export default class ActionList extends Component {
|
||||||
this.scrollToBottom();
|
this.scrollToBottom();
|
||||||
|
|
||||||
if (!this.props.draggableActions) return;
|
if (!this.props.draggableActions) return;
|
||||||
const container = this.node;
|
const container = this.node!;
|
||||||
this.drake = dragula([container], {
|
this.drake = dragula([container], {
|
||||||
copy: false,
|
copy: false,
|
||||||
copySortSource: false,
|
copySortSource: false,
|
||||||
mirrorContainer: container,
|
mirrorContainer: container,
|
||||||
accepts: (el, target, source, sibling) =>
|
accepts: (el, target, source, sibling) =>
|
||||||
!sibling || parseInt(sibling.getAttribute('data-id')),
|
!sibling || !!parseInt(sibling.getAttribute('data-id')!),
|
||||||
moves: (el, source, handle) =>
|
moves: (el, source, handle) =>
|
||||||
parseInt(el.getAttribute('data-id')) &&
|
!!parseInt(el!.getAttribute('data-id')!) &&
|
||||||
handle.className.indexOf('selectorButton') !== 0,
|
handle!.className.indexOf('selectorButton') !== 0,
|
||||||
}).on('drop', (el, target, source, sibling) => {
|
}).on('drop', (el, target, source, sibling) => {
|
||||||
let beforeActionId = this.props.actionIds.length;
|
let beforeActionId = this.props.actionIds.length;
|
||||||
if (sibling && sibling.className.indexOf('gu-mirror') === -1) {
|
if (sibling && sibling.className.indexOf('gu-mirror') === -1) {
|
||||||
beforeActionId = parseInt(sibling.getAttribute('data-id'));
|
beforeActionId = parseInt(sibling.getAttribute('data-id')!);
|
||||||
}
|
}
|
||||||
const actionId = parseInt(el.getAttribute('data-id'));
|
const actionId = parseInt(el.getAttribute('data-id')!);
|
||||||
this.props.onReorderAction(actionId, beforeActionId);
|
this.props.onReorderAction(actionId, beforeActionId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -69,7 +103,7 @@ export default class ActionList extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getRef = (node) => {
|
getRef: RefCallback<HTMLDivElement> = (node) => {
|
||||||
this.node = node;
|
this.node = node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,8 +131,9 @@ export default class ActionList extends Component {
|
||||||
const filteredActionIds = searchValue
|
const filteredActionIds = searchValue
|
||||||
? actionIds.filter(
|
? actionIds.filter(
|
||||||
(id) =>
|
(id) =>
|
||||||
actions[id].action.type.toLowerCase().indexOf(lowerSearchValue) !==
|
(actions[id].action.type as string)
|
||||||
-1
|
.toLowerCase()
|
||||||
|
.indexOf(lowerSearchValue as string) !== -1
|
||||||
)
|
)
|
||||||
: actionIds;
|
: actionIds;
|
||||||
|
|
||||||
|
@ -129,18 +164,20 @@ export default class ActionList extends Component {
|
||||||
isSelected={
|
isSelected={
|
||||||
(startActionId !== null &&
|
(startActionId !== null &&
|
||||||
actionId >= startActionId &&
|
actionId >= startActionId &&
|
||||||
actionId <= selectedActionId) ||
|
actionId <= (selectedActionId as number)) ||
|
||||||
actionId === selectedActionId
|
actionId === selectedActionId
|
||||||
}
|
}
|
||||||
isInFuture={
|
isInFuture={
|
||||||
actionIds.indexOf(actionId) > actionIds.indexOf(currentActionId)
|
actionIds.indexOf(actionId) > actionIds.indexOf(currentActionId)
|
||||||
}
|
}
|
||||||
onSelect={(e) => onSelect(e, actionId)}
|
onSelect={(e: React.MouseEvent<HTMLDivElement>) =>
|
||||||
|
onSelect(e, actionId)
|
||||||
|
}
|
||||||
timestamps={getTimestamps(actions, actionIds, actionId)}
|
timestamps={getTimestamps(actions, actionIds, actionId)}
|
||||||
action={actions[actionId].action}
|
action={actions[actionId].action}
|
||||||
onToggleClick={() => onToggleAction(actionId)}
|
onToggleClick={() => onToggleAction(actionId)}
|
||||||
onJumpClick={() => onJumpToState(actionId)}
|
onJumpClick={() => onJumpToState(actionId)}
|
||||||
onCommitClick={() => onCommit(actionId)}
|
onCommitClick={() => onCommit()}
|
||||||
hideActionButtons={hideActionButtons}
|
hideActionButtons={hideActionButtons}
|
||||||
isSkipped={skippedActionIds.indexOf(actionId) !== -1}
|
isSkipped={skippedActionIds.indexOf(actionId) !== -1}
|
||||||
/>
|
/>
|
|
@ -1,10 +1,24 @@
|
||||||
import React from 'react';
|
import React, { FunctionComponent } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { StylingFunction } from 'react-base16-styling';
|
||||||
import RightSlider from './RightSlider';
|
import RightSlider from './RightSlider';
|
||||||
|
|
||||||
const getActiveButtons = (hasSkippedActions) =>
|
const getActiveButtons = (hasSkippedActions: boolean): ('Sweep' | 'Commit')[] =>
|
||||||
[hasSkippedActions && 'Sweep', 'Commit'].filter((a) => a);
|
[hasSkippedActions && 'Sweep', 'Commit'].filter(
|
||||||
|
(a): a is 'Sweep' | 'Commit' => !!a
|
||||||
|
);
|
||||||
|
|
||||||
const ActionListHeader = ({
|
interface Props {
|
||||||
|
styling: StylingFunction;
|
||||||
|
onSearch: (value: string) => void;
|
||||||
|
onCommit: () => void;
|
||||||
|
onSweep: () => void;
|
||||||
|
hideMainButtons: boolean | undefined;
|
||||||
|
hasSkippedActions: boolean;
|
||||||
|
hasStagedActions: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ActionListHeader: FunctionComponent<Props> = ({
|
||||||
styling,
|
styling,
|
||||||
onSearch,
|
onSearch,
|
||||||
hasSkippedActions,
|
hasSkippedActions,
|
||||||
|
@ -48,4 +62,14 @@ const ActionListHeader = ({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ActionListHeader.propTypes = {
|
||||||
|
styling: PropTypes.func.isRequired,
|
||||||
|
onSearch: PropTypes.func.isRequired,
|
||||||
|
onCommit: PropTypes.func.isRequired,
|
||||||
|
onSweep: PropTypes.func.isRequired,
|
||||||
|
hideMainButtons: PropTypes.bool,
|
||||||
|
hasSkippedActions: PropTypes.bool.isRequired,
|
||||||
|
hasStagedActions: PropTypes.bool.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default ActionListHeader;
|
export default ActionListHeader;
|
|
@ -1,15 +1,40 @@
|
||||||
import React, { Component } from 'react';
|
import React, { MouseEvent, MouseEventHandler, PureComponent } from 'react';
|
||||||
import { PropTypes } from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import shouldPureComponentUpdate from 'react-pure-render/function';
|
|
||||||
import dateformat from 'dateformat';
|
import dateformat from 'dateformat';
|
||||||
import debounce from 'lodash.debounce';
|
import debounce from 'lodash.debounce';
|
||||||
|
import { StylingFunction } from 'react-base16-styling';
|
||||||
|
import { Action } from 'redux';
|
||||||
import RightSlider from './RightSlider';
|
import RightSlider from './RightSlider';
|
||||||
|
|
||||||
const BUTTON_SKIP = 'Skip';
|
const BUTTON_SKIP = 'Skip';
|
||||||
const BUTTON_JUMP = 'Jump';
|
const BUTTON_JUMP = 'Jump';
|
||||||
|
|
||||||
export default class ActionListRow extends Component {
|
type Button = typeof BUTTON_SKIP | typeof BUTTON_JUMP;
|
||||||
state = { hover: false };
|
|
||||||
|
interface Props<A extends Action<unknown>> {
|
||||||
|
styling: StylingFunction;
|
||||||
|
actionId: number;
|
||||||
|
isInitAction: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
isInFuture: boolean;
|
||||||
|
onSelect: MouseEventHandler<HTMLDivElement>;
|
||||||
|
timestamps: { current: number; previous: number };
|
||||||
|
action: A;
|
||||||
|
onToggleClick: () => void;
|
||||||
|
onJumpClick: () => void;
|
||||||
|
onCommitClick: () => void;
|
||||||
|
hideActionButtons: boolean | undefined;
|
||||||
|
isSkipped: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
hover: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ActionListRow<
|
||||||
|
A extends Action<unknown>
|
||||||
|
> extends PureComponent<Props<A>, State> {
|
||||||
|
state: State = { hover: false };
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
styling: PropTypes.func.isRequired,
|
styling: PropTypes.func.isRequired,
|
||||||
|
@ -25,8 +50,6 @@ export default class ActionListRow extends Component {
|
||||||
isSkipped: PropTypes.bool.isRequired,
|
isSkipped: PropTypes.bool.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
shouldComponentUpdate = shouldPureComponentUpdate;
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
styling,
|
styling,
|
||||||
|
@ -44,18 +67,26 @@ export default class ActionListRow extends Component {
|
||||||
const timeDelta = timestamps.current - timestamps.previous;
|
const timeDelta = timestamps.current - timestamps.previous;
|
||||||
const showButtons = (hover && !isInitAction) || isSkipped;
|
const showButtons = (hover && !isInitAction) || isSkipped;
|
||||||
|
|
||||||
const isButtonSelected = (btn) => btn === BUTTON_SKIP && isSkipped;
|
const isButtonSelected = (btn: Button) => btn === BUTTON_SKIP && isSkipped;
|
||||||
|
|
||||||
let actionType = action.type;
|
let actionType = action.type;
|
||||||
if (typeof actionType === 'undefined') actionType = '<UNDEFINED>';
|
if (typeof actionType === 'undefined') actionType = '<UNDEFINED>';
|
||||||
else if (actionType === null) actionType = '<NULL>';
|
else if (actionType === null) actionType = '<NULL>';
|
||||||
else actionType = actionType.toString() || '<EMPTY>';
|
else actionType = (actionType as string).toString() || '<EMPTY>';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onClick={onSelect}
|
onClick={onSelect}
|
||||||
onMouseEnter={!hideActionButtons && this.handleMouseEnter}
|
onMouseEnter={
|
||||||
onMouseLeave={!hideActionButtons && this.handleMouseLeave}
|
(!hideActionButtons && this.handleMouseEnter) as MouseEventHandler<
|
||||||
|
HTMLDivElement
|
||||||
|
>
|
||||||
|
}
|
||||||
|
onMouseLeave={
|
||||||
|
(!hideActionButtons && this.handleMouseLeave) as MouseEventHandler<
|
||||||
|
HTMLDivElement
|
||||||
|
>
|
||||||
|
}
|
||||||
onMouseDown={this.handleMouseDown}
|
onMouseDown={this.handleMouseDown}
|
||||||
onMouseUp={this.handleMouseEnter}
|
onMouseUp={this.handleMouseEnter}
|
||||||
data-id={actionId}
|
data-id={actionId}
|
||||||
|
@ -76,7 +107,7 @@ export default class ActionListRow extends Component {
|
||||||
isSkipped && 'actionListItemNameSkipped',
|
isSkipped && 'actionListItemNameSkipped',
|
||||||
])}
|
])}
|
||||||
>
|
>
|
||||||
{actionType}
|
{actionType as string}
|
||||||
</div>
|
</div>
|
||||||
{hideActionButtons ? (
|
{hideActionButtons ? (
|
||||||
<RightSlider styling={styling} shown>
|
<RightSlider styling={styling} shown>
|
||||||
|
@ -103,12 +134,12 @@ export default class ActionListRow extends Component {
|
||||||
</RightSlider>
|
</RightSlider>
|
||||||
<RightSlider styling={styling} shown={showButtons} rotate>
|
<RightSlider styling={styling} shown={showButtons} rotate>
|
||||||
<div {...styling('actionListItemSelector')}>
|
<div {...styling('actionListItemSelector')}>
|
||||||
{[BUTTON_JUMP, BUTTON_SKIP].map(
|
{([BUTTON_JUMP, BUTTON_SKIP] as const).map(
|
||||||
(btn) =>
|
(btn) =>
|
||||||
(!isInitAction || btn !== BUTTON_SKIP) && (
|
(!isInitAction || btn !== BUTTON_SKIP) && (
|
||||||
<div
|
<div
|
||||||
key={btn}
|
key={btn}
|
||||||
onClick={this.handleButtonClick.bind(this, btn)}
|
onClick={(e) => this.handleButtonClick(btn, e)}
|
||||||
{...styling(
|
{...styling(
|
||||||
[
|
[
|
||||||
'selectorButton',
|
'selectorButton',
|
||||||
|
@ -131,7 +162,7 @@ export default class ActionListRow extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleButtonClick(btn, e) {
|
handleButtonClick(btn: Button, e: MouseEvent<HTMLDivElement>) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
switch (btn) {
|
switch (btn) {
|
||||||
|
@ -144,8 +175,8 @@ export default class ActionListRow extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMouseEnter = (e) => {
|
handleMouseEnter = (e: MouseEvent<HTMLDivElement>) => {
|
||||||
if (this.hover) return;
|
if (this.state.hover) return;
|
||||||
this.handleMouseLeave.cancel();
|
this.handleMouseLeave.cancel();
|
||||||
this.handleMouseEnterDebounced(e.buttons);
|
this.handleMouseEnterDebounced(e.buttons);
|
||||||
};
|
};
|
||||||
|
@ -160,8 +191,13 @@ export default class ActionListRow extends Component {
|
||||||
if (this.state.hover) this.setState({ hover: false });
|
if (this.state.hover) this.setState({ hover: false });
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
handleMouseDown = (e) => {
|
handleMouseDown = (e: MouseEvent<HTMLDivElement>) => {
|
||||||
if (e.target.className.indexOf('selectorButton') === 0) return;
|
if (
|
||||||
|
((e.target as unknown) as { className: string[] }).className.indexOf(
|
||||||
|
'selectorButton'
|
||||||
|
) === 0
|
||||||
|
)
|
||||||
|
return;
|
||||||
this.handleMouseLeave();
|
this.handleMouseLeave();
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,10 +1,43 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { DEFAULT_STATE } from './redux';
|
import { Base16Theme } from 'redux-devtools-themes';
|
||||||
|
import { Action } from 'redux';
|
||||||
|
import { StylingFunction } from 'react-base16-styling';
|
||||||
|
import { PerformAction } from 'redux-devtools';
|
||||||
|
import { Delta } from 'jsondiffpatch';
|
||||||
|
import { DEFAULT_STATE, DevtoolsInspectorState } from './redux';
|
||||||
import ActionPreviewHeader from './ActionPreviewHeader';
|
import ActionPreviewHeader from './ActionPreviewHeader';
|
||||||
import DiffTab from './tabs/DiffTab';
|
import DiffTab from './tabs/DiffTab';
|
||||||
import StateTab from './tabs/StateTab';
|
import StateTab from './tabs/StateTab';
|
||||||
import ActionTab from './tabs/ActionTab';
|
import ActionTab from './tabs/ActionTab';
|
||||||
|
|
||||||
|
export interface TabComponentProps<S, A extends Action<unknown>> {
|
||||||
|
labelRenderer: (
|
||||||
|
keyPath: (string | number)[],
|
||||||
|
nodeType: string,
|
||||||
|
expanded: boolean,
|
||||||
|
expandable: boolean
|
||||||
|
) => React.ReactNode;
|
||||||
|
styling: StylingFunction;
|
||||||
|
computedStates: { state: S; error?: string }[];
|
||||||
|
actions: { [actionId: number]: PerformAction<A> };
|
||||||
|
selectedActionId: number | null;
|
||||||
|
startActionId: number | null;
|
||||||
|
base16Theme: Base16Theme;
|
||||||
|
invertTheme: boolean;
|
||||||
|
isWideLayout: boolean;
|
||||||
|
dataTypeKey: string | undefined;
|
||||||
|
delta: Delta | null | undefined | false;
|
||||||
|
action: A;
|
||||||
|
nextState: S;
|
||||||
|
monitorState: DevtoolsInspectorState;
|
||||||
|
updateMonitorState: (monitorState: Partial<DevtoolsInspectorState>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Tab<S, A extends Action<unknown>> {
|
||||||
|
name: string;
|
||||||
|
component: React.ComponentType<TabComponentProps<S, A>>;
|
||||||
|
}
|
||||||
|
|
||||||
const DEFAULT_TABS = [
|
const DEFAULT_TABS = [
|
||||||
{
|
{
|
||||||
name: 'Action',
|
name: 'Action',
|
||||||
|
@ -20,7 +53,32 @@ const DEFAULT_TABS = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class ActionPreview extends Component {
|
interface Props<S, A extends Action<unknown>> {
|
||||||
|
base16Theme: Base16Theme;
|
||||||
|
invertTheme: boolean;
|
||||||
|
isWideLayout: boolean;
|
||||||
|
tabs: Tab<S, A>[] | ((tabs: Tab<S, A>[]) => Tab<S, A>[]);
|
||||||
|
tabName: string;
|
||||||
|
delta: Delta | null | undefined | false;
|
||||||
|
error: string | undefined;
|
||||||
|
nextState: S;
|
||||||
|
computedStates: { state: S; error?: string }[];
|
||||||
|
action: A;
|
||||||
|
actions: { [actionId: number]: PerformAction<A> };
|
||||||
|
selectedActionId: number | null;
|
||||||
|
startActionId: number | null;
|
||||||
|
dataTypeKey: string | undefined;
|
||||||
|
monitorState: DevtoolsInspectorState;
|
||||||
|
updateMonitorState: (monitorState: Partial<DevtoolsInspectorState>) => void;
|
||||||
|
styling: StylingFunction;
|
||||||
|
onInspectPath: (path: (string | number)[]) => void;
|
||||||
|
inspectedPath: (string | number)[];
|
||||||
|
onSelectTab: (tabName: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActionPreview<S, A extends Action<unknown>> extends Component<
|
||||||
|
Props<S, A>
|
||||||
|
> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
tabName: DEFAULT_STATE.tabName,
|
tabName: DEFAULT_STATE.tabName,
|
||||||
};
|
};
|
||||||
|
@ -49,21 +107,21 @@ class ActionPreview extends Component {
|
||||||
updateMonitorState,
|
updateMonitorState,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const renderedTabs =
|
const renderedTabs: Tab<S, A>[] =
|
||||||
typeof tabs === 'function'
|
typeof tabs === 'function'
|
||||||
? tabs(DEFAULT_TABS)
|
? tabs(DEFAULT_TABS as Tab<S, A>[])
|
||||||
: tabs
|
: tabs
|
||||||
? tabs
|
? tabs
|
||||||
: DEFAULT_TABS;
|
: (DEFAULT_TABS as Tab<S, A>[]);
|
||||||
|
|
||||||
const { component: TabComponent } =
|
const { component: TabComponent } =
|
||||||
renderedTabs.find((tab) => tab.name === tabName) ||
|
renderedTabs.find((tab) => tab.name === tabName) ||
|
||||||
renderedTabs.find((tab) => tab.name === DEFAULT_STATE.tabName);
|
renderedTabs.find((tab) => tab.name === DEFAULT_STATE.tabName)!;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key="actionPreview" {...styling('actionPreview')}>
|
<div key="actionPreview" {...styling('actionPreview')}>
|
||||||
<ActionPreviewHeader
|
<ActionPreviewHeader
|
||||||
tabs={renderedTabs}
|
tabs={(renderedTabs as unknown) as Tab<unknown, Action<unknown>>[]}
|
||||||
{...{ styling, inspectedPath, onInspectPath, tabName, onSelectTab }}
|
{...{ styling, inspectedPath, onInspectPath, tabName, onSelectTab }}
|
||||||
/>
|
/>
|
||||||
{!error && (
|
{!error && (
|
||||||
|
@ -94,7 +152,11 @@ class ActionPreview extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
labelRenderer = ([key, ...rest], nodeType, expanded) => {
|
labelRenderer = (
|
||||||
|
[key, ...rest]: (string | number)[],
|
||||||
|
nodeType: string,
|
||||||
|
expanded: boolean
|
||||||
|
) => {
|
||||||
const { styling, onInspectPath, inspectedPath } = this.props;
|
const { styling, onInspectPath, inspectedPath } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
|
@ -1,6 +1,22 @@
|
||||||
import React from 'react';
|
import React, { FunctionComponent } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Action } from 'redux';
|
||||||
|
import { StylingFunction } from 'react-base16-styling';
|
||||||
|
import { Tab } from './ActionPreview';
|
||||||
|
|
||||||
const ActionPreviewHeader = ({
|
interface Props<S, A extends Action<unknown>> {
|
||||||
|
tabs: Tab<S, A>[];
|
||||||
|
styling: StylingFunction;
|
||||||
|
inspectedPath: (string | number)[];
|
||||||
|
onInspectPath: (path: (string | number)[]) => void;
|
||||||
|
tabName: string;
|
||||||
|
onSelectTab: (tabName: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ActionPreviewHeader: FunctionComponent<Props<
|
||||||
|
unknown,
|
||||||
|
Action<unknown>
|
||||||
|
>> = ({
|
||||||
styling,
|
styling,
|
||||||
inspectedPath,
|
inspectedPath,
|
||||||
onInspectPath,
|
onInspectPath,
|
||||||
|
@ -57,4 +73,13 @@ const ActionPreviewHeader = ({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ActionPreviewHeader.propTypes = {
|
||||||
|
tabs: PropTypes.array.isRequired,
|
||||||
|
styling: PropTypes.func.isRequired,
|
||||||
|
inspectedPath: PropTypes.array.isRequired,
|
||||||
|
onInspectPath: PropTypes.func.isRequired,
|
||||||
|
tabName: PropTypes.string.isRequired,
|
||||||
|
onSelectTab: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default ActionPreviewHeader;
|
export default ActionPreviewHeader;
|
|
@ -1,18 +1,30 @@
|
||||||
import React, { Component } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { PropTypes } from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { Base16Theme } from 'redux-devtools-themes';
|
||||||
|
import {
|
||||||
|
getBase16Theme,
|
||||||
|
invertTheme,
|
||||||
|
StylingFunction,
|
||||||
|
} from 'react-base16-styling';
|
||||||
|
import { ActionCreators, LiftedAction, LiftedState } from 'redux-devtools';
|
||||||
|
import { Action, Dispatch } from 'redux';
|
||||||
|
import { Delta, DiffContext } from 'jsondiffpatch';
|
||||||
import {
|
import {
|
||||||
createStylingFromTheme,
|
createStylingFromTheme,
|
||||||
base16Themes,
|
base16Themes,
|
||||||
} from './utils/createStylingFromTheme';
|
} from './utils/createStylingFromTheme';
|
||||||
import shouldPureComponentUpdate from 'react-pure-render/function';
|
|
||||||
import ActionList from './ActionList';
|
import ActionList from './ActionList';
|
||||||
import ActionPreview from './ActionPreview';
|
import ActionPreview, { Tab } from './ActionPreview';
|
||||||
import getInspectedState from './utils/getInspectedState';
|
import getInspectedState from './utils/getInspectedState';
|
||||||
import createDiffPatcher from './createDiffPatcher';
|
import createDiffPatcher from './createDiffPatcher';
|
||||||
import { getBase16Theme, invertTheme } from 'react-base16-styling';
|
import {
|
||||||
import { reducer, updateMonitorState } from './redux';
|
DevtoolsInspectorAction,
|
||||||
import { ActionCreators } from 'redux-devtools';
|
DevtoolsInspectorState,
|
||||||
|
reducer,
|
||||||
|
updateMonitorState,
|
||||||
|
} from './redux';
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||||
const {
|
const {
|
||||||
commit,
|
commit,
|
||||||
sweep,
|
sweep,
|
||||||
|
@ -22,21 +34,26 @@ const {
|
||||||
reorderAction,
|
reorderAction,
|
||||||
} = ActionCreators;
|
} = ActionCreators;
|
||||||
|
|
||||||
function getLastActionId(props) {
|
function getLastActionId<S, A extends Action<unknown>>(
|
||||||
|
props: DevtoolsInspectorProps<S, A>
|
||||||
|
) {
|
||||||
return props.stagedActionIds[props.stagedActionIds.length - 1];
|
return props.stagedActionIds[props.stagedActionIds.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentActionId(props, monitorState) {
|
function getCurrentActionId<S, A extends Action<unknown>>(
|
||||||
|
props: DevtoolsInspectorProps<S, A>,
|
||||||
|
monitorState: DevtoolsInspectorState
|
||||||
|
) {
|
||||||
return monitorState.selectedActionId === null
|
return monitorState.selectedActionId === null
|
||||||
? props.stagedActionIds[props.currentStateIndex]
|
? props.stagedActionIds[props.currentStateIndex]
|
||||||
: monitorState.selectedActionId;
|
: monitorState.selectedActionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFromState(
|
function getFromState<S>(
|
||||||
actionIndex,
|
actionIndex: number,
|
||||||
stagedActionIds,
|
stagedActionIds: number[],
|
||||||
computedStates,
|
computedStates: { state: S; error?: string }[],
|
||||||
monitorState
|
monitorState: DevtoolsInspectorState
|
||||||
) {
|
) {
|
||||||
const { startActionId } = monitorState;
|
const { startActionId } = monitorState;
|
||||||
if (startActionId === null) {
|
if (startActionId === null) {
|
||||||
|
@ -47,7 +64,10 @@ function getFromState(
|
||||||
return computedStates[fromStateIdx];
|
return computedStates[fromStateIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
function createIntermediateState(props, monitorState) {
|
function createIntermediateState<S, A extends Action<unknown>>(
|
||||||
|
props: DevtoolsInspectorProps<S, A>,
|
||||||
|
monitorState: DevtoolsInspectorState
|
||||||
|
) {
|
||||||
const {
|
const {
|
||||||
supportImmutable,
|
supportImmutable,
|
||||||
computedStates,
|
computedStates,
|
||||||
|
@ -97,8 +117,10 @@ function createIntermediateState(props, monitorState) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createThemeState(props) {
|
function createThemeState<S, A extends Action<unknown>>(
|
||||||
const base16Theme = getBase16Theme(props.theme, base16Themes);
|
props: DevtoolsInspectorProps<S, A>
|
||||||
|
) {
|
||||||
|
const base16Theme = getBase16Theme(props.theme, base16Themes)!;
|
||||||
|
|
||||||
const theme = props.invertTheme ? invertTheme(props.theme) : props.theme;
|
const theme = props.invertTheme ? invertTheme(props.theme) : props.theme;
|
||||||
const styling = createStylingFromTheme(theme);
|
const styling = createStylingFromTheme(theme);
|
||||||
|
@ -106,15 +128,69 @@ function createThemeState(props) {
|
||||||
return { base16Theme, styling };
|
return { base16Theme, styling };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DevtoolsInspector extends Component {
|
interface ExternalProps<S, A extends Action<unknown>> {
|
||||||
constructor(props) {
|
dispatch: Dispatch<
|
||||||
super(props);
|
DevtoolsInspectorAction | LiftedAction<S, A, DevtoolsInspectorState>
|
||||||
this.state = {
|
>;
|
||||||
...createIntermediateState(props, props.monitorState),
|
preserveScrollTop?: boolean;
|
||||||
isWideLayout: false,
|
draggableActions: boolean;
|
||||||
themeState: createThemeState(props),
|
select: (state: S) => unknown;
|
||||||
};
|
theme: keyof typeof base16Themes | Base16Theme;
|
||||||
}
|
supportImmutable: boolean;
|
||||||
|
diffObjectHash?: (item: unknown, index: number) => string;
|
||||||
|
diffPropertyFilter?: (name: string, context: DiffContext) => boolean;
|
||||||
|
hideMainButtons?: boolean;
|
||||||
|
hideActionButtons?: boolean;
|
||||||
|
invertTheme: boolean;
|
||||||
|
dataTypeKey?: string;
|
||||||
|
tabs: Tab<S, A>[] | ((tabs: Tab<S, A>[]) => Tab<S, A>[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DefaultProps {
|
||||||
|
select: (state: unknown) => unknown;
|
||||||
|
supportImmutable: boolean;
|
||||||
|
draggableActions: boolean;
|
||||||
|
theme: keyof typeof base16Themes;
|
||||||
|
invertTheme: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DevtoolsInspectorProps<S, A extends Action<unknown>>
|
||||||
|
extends LiftedState<S, A, DevtoolsInspectorState> {
|
||||||
|
dispatch: Dispatch<
|
||||||
|
DevtoolsInspectorAction | LiftedAction<S, A, DevtoolsInspectorState>
|
||||||
|
>;
|
||||||
|
preserveScrollTop?: boolean;
|
||||||
|
draggableActions: boolean;
|
||||||
|
select: (state: S) => unknown;
|
||||||
|
theme: keyof typeof base16Themes | Base16Theme;
|
||||||
|
supportImmutable: boolean;
|
||||||
|
diffObjectHash?: (item: unknown, index: number) => string;
|
||||||
|
diffPropertyFilter?: (name: string, context: DiffContext) => boolean;
|
||||||
|
hideMainButtons?: boolean;
|
||||||
|
hideActionButtons?: boolean;
|
||||||
|
invertTheme: boolean;
|
||||||
|
dataTypeKey?: string;
|
||||||
|
tabs: Tab<S, A>[] | ((tabs: Tab<S, A>[]) => Tab<S, A>[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State<S, A extends Action<unknown>> {
|
||||||
|
delta: Delta | null | undefined | false;
|
||||||
|
nextState: S;
|
||||||
|
action: A;
|
||||||
|
error: string | undefined;
|
||||||
|
isWideLayout: boolean;
|
||||||
|
themeState: { base16Theme: Base16Theme; styling: StylingFunction };
|
||||||
|
}
|
||||||
|
|
||||||
|
class DevtoolsInspector<S, A extends Action<unknown>> extends PureComponent<
|
||||||
|
DevtoolsInspectorProps<S, A>,
|
||||||
|
State<S, A>
|
||||||
|
> {
|
||||||
|
state: State<S, A> = {
|
||||||
|
...createIntermediateState(this.props, this.props.monitorState),
|
||||||
|
isWideLayout: false,
|
||||||
|
themeState: createThemeState(this.props),
|
||||||
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
dispatch: PropTypes.func,
|
dispatch: PropTypes.func,
|
||||||
|
@ -127,7 +203,6 @@ export default class DevtoolsInspector extends Component {
|
||||||
}),
|
}),
|
||||||
preserveScrollTop: PropTypes.bool,
|
preserveScrollTop: PropTypes.bool,
|
||||||
draggableActions: PropTypes.bool,
|
draggableActions: PropTypes.bool,
|
||||||
stagedActions: PropTypes.array,
|
|
||||||
select: PropTypes.func.isRequired,
|
select: PropTypes.func.isRequired,
|
||||||
theme: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
|
theme: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
|
||||||
supportImmutable: PropTypes.bool,
|
supportImmutable: PropTypes.bool,
|
||||||
|
@ -144,38 +219,42 @@ export default class DevtoolsInspector extends Component {
|
||||||
static update = reducer;
|
static update = reducer;
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
select: (state) => state,
|
select: (state: unknown) => state,
|
||||||
supportImmutable: false,
|
supportImmutable: false,
|
||||||
draggableActions: true,
|
draggableActions: true,
|
||||||
theme: 'inspector',
|
theme: 'inspector',
|
||||||
invertTheme: true,
|
invertTheme: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
shouldComponentUpdate = shouldPureComponentUpdate;
|
updateSizeTimeout?: number;
|
||||||
|
inspectorRef?: HTMLDivElement | null;
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.updateSizeMode();
|
this.updateSizeMode();
|
||||||
this.updateSizeTimeout = setInterval(this.updateSizeMode.bind(this), 150);
|
this.updateSizeTimeout = window.setInterval(
|
||||||
|
this.updateSizeMode.bind(this),
|
||||||
|
150
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
clearTimeout(this.updateSizeTimeout);
|
clearTimeout(this.updateSizeTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateMonitorState = (monitorState) => {
|
updateMonitorState = (monitorState: Partial<DevtoolsInspectorState>) => {
|
||||||
this.props.dispatch(updateMonitorState(monitorState));
|
this.props.dispatch(updateMonitorState(monitorState));
|
||||||
};
|
};
|
||||||
|
|
||||||
updateSizeMode() {
|
updateSizeMode() {
|
||||||
const isWideLayout = this.inspectorRef.offsetWidth > 500;
|
const isWideLayout = this.inspectorRef!.offsetWidth > 500;
|
||||||
|
|
||||||
if (isWideLayout !== this.state.isWideLayout) {
|
if (isWideLayout !== this.state.isWideLayout) {
|
||||||
this.setState({ isWideLayout });
|
this.setState({ isWideLayout });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
UNSAFE_componentWillReceiveProps(nextProps: DevtoolsInspectorProps<S, A>) {
|
||||||
let nextMonitorState = nextProps.monitorState;
|
const nextMonitorState = nextProps.monitorState;
|
||||||
const monitorState = this.props.monitorState;
|
const monitorState = this.props.monitorState;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -199,7 +278,7 @@ export default class DevtoolsInspector extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inspectorCreateRef = (node) => {
|
inspectorCreateRef: React.RefCallback<HTMLDivElement> = (node) => {
|
||||||
this.inspectorRef = node;
|
this.inspectorRef = node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -289,7 +368,9 @@ export default class DevtoolsInspector extends Component {
|
||||||
monitorState={this.props.monitorState}
|
monitorState={this.props.monitorState}
|
||||||
updateMonitorState={this.updateMonitorState}
|
updateMonitorState={this.updateMonitorState}
|
||||||
styling={styling}
|
styling={styling}
|
||||||
onInspectPath={this.handleInspectPath.bind(this, inspectedPathType)}
|
onInspectPath={(path: (string | number)[]) =>
|
||||||
|
this.handleInspectPath(inspectedPathType, path)
|
||||||
|
}
|
||||||
inspectedPath={monitorState[inspectedPathType]}
|
inspectedPath={monitorState[inspectedPathType]}
|
||||||
onSelectTab={this.handleSelectTab}
|
onSelectTab={this.handleSelectTab}
|
||||||
/>
|
/>
|
||||||
|
@ -297,11 +378,11 @@ export default class DevtoolsInspector extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleToggleAction = (actionId) => {
|
handleToggleAction = (actionId: number) => {
|
||||||
this.props.dispatch(toggleAction(actionId));
|
this.props.dispatch(toggleAction(actionId));
|
||||||
};
|
};
|
||||||
|
|
||||||
handleJumpToState = (actionId) => {
|
handleJumpToState = (actionId: number) => {
|
||||||
if (jumpToAction) {
|
if (jumpToAction) {
|
||||||
this.props.dispatch(jumpToAction(actionId));
|
this.props.dispatch(jumpToAction(actionId));
|
||||||
} else {
|
} else {
|
||||||
|
@ -311,7 +392,7 @@ export default class DevtoolsInspector extends Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleReorderAction = (actionId, beforeActionId) => {
|
handleReorderAction = (actionId: number, beforeActionId: number) => {
|
||||||
if (reorderAction)
|
if (reorderAction)
|
||||||
this.props.dispatch(reorderAction(actionId, beforeActionId));
|
this.props.dispatch(reorderAction(actionId, beforeActionId));
|
||||||
};
|
};
|
||||||
|
@ -324,11 +405,14 @@ export default class DevtoolsInspector extends Component {
|
||||||
this.props.dispatch(sweep());
|
this.props.dispatch(sweep());
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSearch = (val) => {
|
handleSearch = (val: string) => {
|
||||||
this.updateMonitorState({ searchValue: val });
|
this.updateMonitorState({ searchValue: val });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSelectAction = (e, actionId) => {
|
handleSelectAction = (
|
||||||
|
e: React.MouseEvent<HTMLDivElement>,
|
||||||
|
actionId: number
|
||||||
|
) => {
|
||||||
const { monitorState } = this.props;
|
const { monitorState } = this.props;
|
||||||
let startActionId;
|
let startActionId;
|
||||||
let selectedActionId;
|
let selectedActionId;
|
||||||
|
@ -367,11 +451,25 @@ export default class DevtoolsInspector extends Component {
|
||||||
this.updateMonitorState({ startActionId, selectedActionId });
|
this.updateMonitorState({ startActionId, selectedActionId });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleInspectPath = (pathType, path) => {
|
handleInspectPath = (
|
||||||
|
pathType: 'inspectedActionPath' | 'inspectedStatePath',
|
||||||
|
path: (string | number)[]
|
||||||
|
) => {
|
||||||
this.updateMonitorState({ [pathType]: path });
|
this.updateMonitorState({ [pathType]: path });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSelectTab = (tabName) => {
|
handleSelectTab = (tabName: string) => {
|
||||||
this.updateMonitorState({ tabName });
|
this.updateMonitorState({ tabName });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default (DevtoolsInspector as unknown) as React.ComponentType<
|
||||||
|
ExternalProps<unknown, Action<unknown>>
|
||||||
|
> & {
|
||||||
|
update(
|
||||||
|
monitorProps: ExternalProps<unknown, Action<unknown>>,
|
||||||
|
state: DevtoolsInspectorState | undefined,
|
||||||
|
action: DevtoolsInspectorAction
|
||||||
|
): DevtoolsInspectorState;
|
||||||
|
defaultProps: DefaultProps;
|
||||||
|
};
|
|
@ -1,21 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { PropTypes } from 'prop-types';
|
|
||||||
|
|
||||||
const RightSlider = ({ styling, shown, children, rotate }) => (
|
|
||||||
<div
|
|
||||||
{...styling([
|
|
||||||
'rightSlider',
|
|
||||||
shown && 'rightSliderShown',
|
|
||||||
rotate && 'rightSliderRotate',
|
|
||||||
rotate && shown && 'rightSliderRotateShown',
|
|
||||||
])}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
RightSlider.propTypes = {
|
|
||||||
shown: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default RightSlider;
|
|
37
packages/redux-devtools-inspector/src/RightSlider.tsx
Normal file
37
packages/redux-devtools-inspector/src/RightSlider.tsx
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import React, { FunctionComponent } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { StylingFunction } from 'react-base16-styling';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
styling: StylingFunction;
|
||||||
|
shown?: boolean;
|
||||||
|
children: React.ReactNode;
|
||||||
|
rotate?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RightSlider: FunctionComponent<Props> = ({
|
||||||
|
styling,
|
||||||
|
shown,
|
||||||
|
children,
|
||||||
|
rotate,
|
||||||
|
}) => (
|
||||||
|
<div
|
||||||
|
{...styling([
|
||||||
|
'rightSlider',
|
||||||
|
shown && 'rightSliderShown',
|
||||||
|
rotate && 'rightSliderRotate',
|
||||||
|
rotate && shown && 'rightSliderRotateShown',
|
||||||
|
])}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
RightSlider.propTypes = {
|
||||||
|
styling: PropTypes.func.isRequired,
|
||||||
|
shown: PropTypes.bool,
|
||||||
|
children: PropTypes.any.isRequired,
|
||||||
|
rotate: PropTypes.bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RightSlider;
|
|
@ -1,28 +1,37 @@
|
||||||
import { DiffPatcher } from 'jsondiffpatch';
|
import { DiffContext, DiffPatcher } from 'jsondiffpatch';
|
||||||
|
|
||||||
const defaultObjectHash = (o, idx) =>
|
const defaultObjectHash = (o: any, idx: number) =>
|
||||||
(o === null && '$$null') ||
|
(o === null && '$$null') ||
|
||||||
(o && (o.id || o.id === 0) && `$$id:${JSON.stringify(o.id)}`) ||
|
(o && (o.id || o.id === 0) && `$$id:${JSON.stringify(o.id)}`) ||
|
||||||
(o && (o._id || o._id === 0) && `$$_id:${JSON.stringify(o._id)}`) ||
|
(o && (o._id || o._id === 0) && `$$_id:${JSON.stringify(o._id)}`) ||
|
||||||
'$$index:' + idx;
|
`$$index:${idx}`;
|
||||||
|
|
||||||
const defaultPropertyFilter = (name, context) =>
|
const defaultPropertyFilter = (name: string, context: DiffContext) =>
|
||||||
typeof context.left[name] !== 'function' &&
|
typeof context.left[name] !== 'function' &&
|
||||||
typeof context.right[name] !== 'function';
|
typeof context.right[name] !== 'function';
|
||||||
|
|
||||||
const defaultDiffPatcher = new DiffPatcher({
|
const defaultDiffPatcher = new DiffPatcher({
|
||||||
arrays: { detectMove: false },
|
arrays: { detectMove: false } as {
|
||||||
|
detectMove: boolean;
|
||||||
|
includeValueOnMove: boolean;
|
||||||
|
},
|
||||||
objectHash: defaultObjectHash,
|
objectHash: defaultObjectHash,
|
||||||
propertyFilter: defaultPropertyFilter,
|
propertyFilter: defaultPropertyFilter,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function createDiffPatcher(objectHash, propertyFilter) {
|
export default function createDiffPatcher(
|
||||||
|
objectHash: ((item: unknown, index: number) => string) | undefined,
|
||||||
|
propertyFilter: ((name: string, context: DiffContext) => boolean) | undefined
|
||||||
|
) {
|
||||||
if (!objectHash && !propertyFilter) {
|
if (!objectHash && !propertyFilter) {
|
||||||
return defaultDiffPatcher;
|
return defaultDiffPatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DiffPatcher({
|
return new DiffPatcher({
|
||||||
arrays: { detectMove: false },
|
arrays: { detectMove: false } as {
|
||||||
|
detectMove: boolean;
|
||||||
|
includeValueOnMove: boolean;
|
||||||
|
},
|
||||||
objectHash: objectHash || defaultObjectHash,
|
objectHash: objectHash || defaultObjectHash,
|
||||||
propertyFilter: propertyFilter || defaultPropertyFilter,
|
propertyFilter: propertyFilter || defaultPropertyFilter,
|
||||||
});
|
});
|
|
@ -1 +0,0 @@
|
||||||
export default from './DevtoolsInspector';
|
|
2
packages/redux-devtools-inspector/src/index.ts
Normal file
2
packages/redux-devtools-inspector/src/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
import DevtoolsInspector from './DevtoolsInspector';
|
||||||
|
export default DevtoolsInspector;
|
|
@ -1,28 +0,0 @@
|
||||||
const UPDATE_MONITOR_STATE = '@@redux-devtools-inspector/UPDATE_MONITOR_STATE';
|
|
||||||
|
|
||||||
export const DEFAULT_STATE = {
|
|
||||||
selectedActionId: null,
|
|
||||||
startActionId: null,
|
|
||||||
inspectedActionPath: [],
|
|
||||||
inspectedStatePath: [],
|
|
||||||
tabName: 'Diff',
|
|
||||||
};
|
|
||||||
|
|
||||||
export function updateMonitorState(monitorState) {
|
|
||||||
return { type: UPDATE_MONITOR_STATE, monitorState };
|
|
||||||
}
|
|
||||||
|
|
||||||
function reduceUpdateState(state, action) {
|
|
||||||
return action.type === UPDATE_MONITOR_STATE
|
|
||||||
? {
|
|
||||||
...state,
|
|
||||||
...action.monitorState,
|
|
||||||
}
|
|
||||||
: state;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function reducer(props, state = DEFAULT_STATE, action) {
|
|
||||||
return {
|
|
||||||
...reduceUpdateState(state, action),
|
|
||||||
};
|
|
||||||
}
|
|
55
packages/redux-devtools-inspector/src/redux.ts
Normal file
55
packages/redux-devtools-inspector/src/redux.ts
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
import { DevtoolsInspectorProps } from './DevtoolsInspector';
|
||||||
|
|
||||||
|
const UPDATE_MONITOR_STATE = '@@redux-devtools-inspector/UPDATE_MONITOR_STATE';
|
||||||
|
|
||||||
|
interface UpdateMonitorStateAction {
|
||||||
|
type: typeof UPDATE_MONITOR_STATE;
|
||||||
|
monitorState: Partial<DevtoolsInspectorState>;
|
||||||
|
}
|
||||||
|
export function updateMonitorState(
|
||||||
|
monitorState: Partial<DevtoolsInspectorState>
|
||||||
|
): UpdateMonitorStateAction {
|
||||||
|
return { type: UPDATE_MONITOR_STATE, monitorState };
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DevtoolsInspectorAction = UpdateMonitorStateAction;
|
||||||
|
|
||||||
|
export interface DevtoolsInspectorState {
|
||||||
|
selectedActionId: number | null;
|
||||||
|
startActionId: number | null;
|
||||||
|
inspectedActionPath: (string | number)[];
|
||||||
|
inspectedStatePath: (string | number)[];
|
||||||
|
tabName: string;
|
||||||
|
searchValue?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_STATE: DevtoolsInspectorState = {
|
||||||
|
selectedActionId: null,
|
||||||
|
startActionId: null,
|
||||||
|
inspectedActionPath: [],
|
||||||
|
inspectedStatePath: [],
|
||||||
|
tabName: 'Diff',
|
||||||
|
};
|
||||||
|
|
||||||
|
function reduceUpdateState(
|
||||||
|
state: DevtoolsInspectorState,
|
||||||
|
action: DevtoolsInspectorAction
|
||||||
|
) {
|
||||||
|
return action.type === UPDATE_MONITOR_STATE
|
||||||
|
? {
|
||||||
|
...state,
|
||||||
|
...action.monitorState,
|
||||||
|
}
|
||||||
|
: state;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function reducer<S, A extends Action<unknown>>(
|
||||||
|
props: DevtoolsInspectorProps<S, A>,
|
||||||
|
state = DEFAULT_STATE,
|
||||||
|
action: DevtoolsInspectorAction
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
...reduceUpdateState(state, action),
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,27 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import JSONTree from 'react-json-tree';
|
|
||||||
import getItemString from './getItemString';
|
|
||||||
import getJsonTreeTheme from './getJsonTreeTheme';
|
|
||||||
|
|
||||||
const ActionTab = ({
|
|
||||||
action,
|
|
||||||
styling,
|
|
||||||
base16Theme,
|
|
||||||
invertTheme,
|
|
||||||
labelRenderer,
|
|
||||||
dataTypeKey,
|
|
||||||
isWideLayout,
|
|
||||||
}) => (
|
|
||||||
<JSONTree
|
|
||||||
labelRenderer={labelRenderer}
|
|
||||||
theme={getJsonTreeTheme(base16Theme)}
|
|
||||||
data={action}
|
|
||||||
getItemString={(type, data) =>
|
|
||||||
getItemString(styling, type, data, dataTypeKey, isWideLayout)
|
|
||||||
}
|
|
||||||
invertTheme={invertTheme}
|
|
||||||
hideRoot
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default ActionTab;
|
|
43
packages/redux-devtools-inspector/src/tabs/ActionTab.tsx
Normal file
43
packages/redux-devtools-inspector/src/tabs/ActionTab.tsx
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import React, { FunctionComponent } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import JSONTree from 'react-json-tree';
|
||||||
|
import { Action } from 'redux';
|
||||||
|
import getItemString from './getItemString';
|
||||||
|
import getJsonTreeTheme from './getJsonTreeTheme';
|
||||||
|
import { TabComponentProps } from '../ActionPreview';
|
||||||
|
|
||||||
|
const ActionTab: FunctionComponent<TabComponentProps<
|
||||||
|
unknown,
|
||||||
|
Action<unknown>
|
||||||
|
>> = ({
|
||||||
|
action,
|
||||||
|
styling,
|
||||||
|
base16Theme,
|
||||||
|
invertTheme,
|
||||||
|
labelRenderer,
|
||||||
|
dataTypeKey,
|
||||||
|
isWideLayout,
|
||||||
|
}) => (
|
||||||
|
<JSONTree
|
||||||
|
labelRenderer={labelRenderer}
|
||||||
|
theme={getJsonTreeTheme(base16Theme)}
|
||||||
|
data={action}
|
||||||
|
getItemString={(type, data) =>
|
||||||
|
getItemString(styling, type, data, dataTypeKey, isWideLayout)
|
||||||
|
}
|
||||||
|
invertTheme={invertTheme}
|
||||||
|
hideRoot
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
ActionTab.propTypes = {
|
||||||
|
action: PropTypes.any.isRequired,
|
||||||
|
styling: PropTypes.func.isRequired,
|
||||||
|
base16Theme: PropTypes.any.isRequired,
|
||||||
|
invertTheme: PropTypes.bool.isRequired,
|
||||||
|
labelRenderer: PropTypes.func.isRequired,
|
||||||
|
dataTypeKey: PropTypes.string,
|
||||||
|
isWideLayout: PropTypes.bool.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ActionTab;
|
|
@ -1,24 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import JSONDiff from './JSONDiff';
|
|
||||||
|
|
||||||
const DiffTab = ({
|
|
||||||
delta,
|
|
||||||
styling,
|
|
||||||
base16Theme,
|
|
||||||
invertTheme,
|
|
||||||
labelRenderer,
|
|
||||||
isWideLayout,
|
|
||||||
}) => (
|
|
||||||
<JSONDiff
|
|
||||||
{...{
|
|
||||||
delta,
|
|
||||||
styling,
|
|
||||||
base16Theme,
|
|
||||||
invertTheme,
|
|
||||||
labelRenderer,
|
|
||||||
isWideLayout,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default DiffTab;
|
|
42
packages/redux-devtools-inspector/src/tabs/DiffTab.tsx
Normal file
42
packages/redux-devtools-inspector/src/tabs/DiffTab.tsx
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import React, { FunctionComponent } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import JSONDiff from './JSONDiff';
|
||||||
|
import { TabComponentProps } from '../ActionPreview';
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
const DiffTab: FunctionComponent<TabComponentProps<
|
||||||
|
unknown,
|
||||||
|
Action<unknown>
|
||||||
|
>> = ({
|
||||||
|
delta,
|
||||||
|
styling,
|
||||||
|
base16Theme,
|
||||||
|
invertTheme,
|
||||||
|
labelRenderer,
|
||||||
|
isWideLayout,
|
||||||
|
dataTypeKey,
|
||||||
|
}) => (
|
||||||
|
<JSONDiff
|
||||||
|
{...{
|
||||||
|
delta,
|
||||||
|
styling,
|
||||||
|
base16Theme,
|
||||||
|
invertTheme,
|
||||||
|
labelRenderer,
|
||||||
|
isWideLayout,
|
||||||
|
dataTypeKey,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
DiffTab.propTypes = {
|
||||||
|
delta: PropTypes.any,
|
||||||
|
styling: PropTypes.func.isRequired,
|
||||||
|
base16Theme: PropTypes.any.isRequired,
|
||||||
|
invertTheme: PropTypes.bool.isRequired,
|
||||||
|
labelRenderer: PropTypes.func.isRequired,
|
||||||
|
isWideLayout: PropTypes.bool.isRequired,
|
||||||
|
dataTypeKey: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DiffTab;
|
|
@ -1,10 +1,13 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import JSONTree from 'react-json-tree';
|
import JSONTree from 'react-json-tree';
|
||||||
import { stringify } from 'javascript-stringify';
|
import { stringify } from 'javascript-stringify';
|
||||||
|
import { Delta } from 'jsondiffpatch';
|
||||||
|
import { StylingFunction } from 'react-base16-styling';
|
||||||
|
import { Base16Theme } from 'redux-devtools-themes';
|
||||||
import getItemString from './getItemString';
|
import getItemString from './getItemString';
|
||||||
import getJsonTreeTheme from './getJsonTreeTheme';
|
import getJsonTreeTheme from './getJsonTreeTheme';
|
||||||
|
|
||||||
function stringifyAndShrink(val, isWideLayout) {
|
function stringifyAndShrink(val: any, isWideLayout?: boolean) {
|
||||||
if (val === null) {
|
if (val === null) {
|
||||||
return 'null';
|
return 'null';
|
||||||
}
|
}
|
||||||
|
@ -19,12 +22,16 @@ function stringifyAndShrink(val, isWideLayout) {
|
||||||
return str.length > 22 ? `${str.substr(0, 15)}…${str.substr(-5)}` : str;
|
return str.length > 22 ? `${str.substr(0, 15)}…${str.substr(-5)}` : str;
|
||||||
}
|
}
|
||||||
|
|
||||||
const expandFirstLevel = (keyName, data, level) => level <= 1;
|
const expandFirstLevel = (
|
||||||
|
keyName: (string | number)[],
|
||||||
|
data: any,
|
||||||
|
level: number
|
||||||
|
) => level <= 1;
|
||||||
|
|
||||||
function prepareDelta(value) {
|
function prepareDelta(value: any) {
|
||||||
if (value && value._t === 'a') {
|
if (value && value._t === 'a') {
|
||||||
const res = {};
|
const res: { [key: string]: any } = {};
|
||||||
for (let key in value) {
|
for (const key in value) {
|
||||||
if (key !== '_t') {
|
if (key !== '_t') {
|
||||||
if (key[0] === '_' && !value[key.substr(1)]) {
|
if (key[0] === '_' && !value[key.substr(1)]) {
|
||||||
res[key.substr(1)] = value[key];
|
res[key.substr(1)] = value[key];
|
||||||
|
@ -41,14 +48,33 @@ function prepareDelta(value) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class JSONDiff extends Component {
|
interface Props {
|
||||||
state = { data: {} };
|
delta: Delta | null | undefined | false;
|
||||||
|
styling: StylingFunction;
|
||||||
|
base16Theme: Base16Theme;
|
||||||
|
invertTheme: boolean;
|
||||||
|
labelRenderer: (
|
||||||
|
keyPath: (string | number)[],
|
||||||
|
nodeType: string,
|
||||||
|
expanded: boolean,
|
||||||
|
expandable: boolean
|
||||||
|
) => React.ReactNode;
|
||||||
|
isWideLayout: boolean;
|
||||||
|
dataTypeKey: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
data: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class JSONDiff extends Component<Props, State> {
|
||||||
|
state: State = { data: {} };
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.updateData();
|
this.updateData();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps: Props) {
|
||||||
if (prevProps.delta !== this.props.delta) {
|
if (prevProps.delta !== this.props.delta) {
|
||||||
this.updateData();
|
this.updateData();
|
||||||
}
|
}
|
||||||
|
@ -84,7 +110,7 @@ export default class JSONDiff extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getItemString = (type, data) =>
|
getItemString = (type: string, data: any) =>
|
||||||
getItemString(
|
getItemString(
|
||||||
this.props.styling,
|
this.props.styling,
|
||||||
type,
|
type,
|
||||||
|
@ -94,10 +120,10 @@ export default class JSONDiff extends Component {
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
valueRenderer = (raw, value) => {
|
valueRenderer = (raw: any, value: any) => {
|
||||||
const { styling, isWideLayout } = this.props;
|
const { styling, isWideLayout } = this.props;
|
||||||
|
|
||||||
function renderSpan(name, body) {
|
function renderSpan(name: string, body: string) {
|
||||||
return (
|
return (
|
||||||
<span key={name} {...styling(['diff', name])}>
|
<span key={name} {...styling(['diff', name])}>
|
||||||
{body}
|
{body}
|
|
@ -1,9 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import JSONTree from 'react-json-tree';
|
import JSONTree from 'react-json-tree';
|
||||||
|
import { Action } from 'redux';
|
||||||
import getItemString from './getItemString';
|
import getItemString from './getItemString';
|
||||||
import getJsonTreeTheme from './getJsonTreeTheme';
|
import getJsonTreeTheme from './getJsonTreeTheme';
|
||||||
|
import { TabComponentProps } from '../ActionPreview';
|
||||||
|
|
||||||
const StateTab = ({
|
const StateTab: React.FunctionComponent<TabComponentProps<
|
||||||
|
any,
|
||||||
|
Action<unknown>
|
||||||
|
>> = ({
|
||||||
nextState,
|
nextState,
|
||||||
styling,
|
styling,
|
||||||
base16Theme,
|
base16Theme,
|
||||||
|
@ -24,4 +30,14 @@ const StateTab = ({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
StateTab.propTypes = {
|
||||||
|
nextState: PropTypes.any.isRequired,
|
||||||
|
styling: PropTypes.func.isRequired,
|
||||||
|
base16Theme: PropTypes.any.isRequired,
|
||||||
|
invertTheme: PropTypes.bool.isRequired,
|
||||||
|
labelRenderer: PropTypes.func.isRequired,
|
||||||
|
dataTypeKey: PropTypes.string,
|
||||||
|
isWideLayout: PropTypes.bool.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default StateTab;
|
export default StateTab;
|
|
@ -1,18 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Iterable } from 'immutable';
|
import { isCollection, isIndexed, isKeyed } from 'immutable';
|
||||||
|
import { StylingFunction } from 'react-base16-styling';
|
||||||
import isIterable from '../utils/isIterable';
|
import isIterable from '../utils/isIterable';
|
||||||
|
|
||||||
const IS_IMMUTABLE_KEY = '@@__IS_IMMUTABLE__@@';
|
const IS_IMMUTABLE_KEY = '@@__IS_IMMUTABLE__@@';
|
||||||
|
|
||||||
function isImmutable(value) {
|
function isImmutable(value: any) {
|
||||||
return (
|
return isKeyed(value) || isIndexed(value) || isCollection(value);
|
||||||
Iterable.isKeyed(value) ||
|
|
||||||
Iterable.isIndexed(value) ||
|
|
||||||
Iterable.isIterable(value)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getShortTypeString(val, diff) {
|
function getShortTypeString(val: any, diff: boolean | undefined) {
|
||||||
if (diff && Array.isArray(val)) {
|
if (diff && Array.isArray(val)) {
|
||||||
val = val[val.length === 2 ? 1 : 0];
|
val = val[val.length === 2 ? 1 : 0];
|
||||||
}
|
}
|
||||||
|
@ -38,14 +35,21 @@ function getShortTypeString(val, diff) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getText(type, data, isWideLayout, isDiff) {
|
function getText(
|
||||||
|
type: string,
|
||||||
|
data: any,
|
||||||
|
isWideLayout: boolean,
|
||||||
|
isDiff: boolean | undefined
|
||||||
|
) {
|
||||||
if (type === 'Object') {
|
if (type === 'Object') {
|
||||||
const keys = Object.keys(data);
|
const keys = Object.keys(data);
|
||||||
if (!isWideLayout) return keys.length ? '{…}' : '{}';
|
if (!isWideLayout) return keys.length ? '{…}' : '{}';
|
||||||
|
|
||||||
const str = keys
|
const str = keys
|
||||||
.slice(0, 3)
|
.slice(0, 3)
|
||||||
.map((key) => `${key}: ${getShortTypeString(data[key], isDiff)}`)
|
.map(
|
||||||
|
(key) => `${key}: ${getShortTypeString(data[key], isDiff) as string}`
|
||||||
|
)
|
||||||
.concat(keys.length > 3 ? ['…'] : [])
|
.concat(keys.length > 3 ? ['…'] : [])
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
|
||||||
|
@ -55,27 +59,27 @@ function getText(type, data, isWideLayout, isDiff) {
|
||||||
|
|
||||||
const str = data
|
const str = data
|
||||||
.slice(0, 4)
|
.slice(0, 4)
|
||||||
.map((val) => getShortTypeString(val, isDiff))
|
.map((val: any) => getShortTypeString(val, isDiff))
|
||||||
.concat(data.length > 4 ? ['…'] : [])
|
.concat(data.length > 4 ? ['…'] : [])
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
|
||||||
return `[${str}]`;
|
return `[${str as string}]`;
|
||||||
} else {
|
} else {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getItemString = (
|
const getItemString = (
|
||||||
styling,
|
styling: StylingFunction,
|
||||||
type,
|
type: string,
|
||||||
data,
|
data: any,
|
||||||
dataTypeKey,
|
dataTypeKey: string | undefined,
|
||||||
isWideLayout,
|
isWideLayout: boolean,
|
||||||
isDiff
|
isDiff?: boolean
|
||||||
) => (
|
) => (
|
||||||
<span {...styling('treeItemHint')}>
|
<span {...styling('treeItemHint')}>
|
||||||
{data[IS_IMMUTABLE_KEY] ? 'Immutable' : ''}
|
{data[IS_IMMUTABLE_KEY] ? 'Immutable' : ''}
|
||||||
{dataTypeKey && data[dataTypeKey] ? data[dataTypeKey] + ' ' : ''}
|
{dataTypeKey && data[dataTypeKey] ? `${data[dataTypeKey] as string} ` : ''}
|
||||||
{getText(type, data, isWideLayout, isDiff)}
|
{getText(type, data, isWideLayout, isDiff)}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
|
@ -1,4 +1,9 @@
|
||||||
export default function getJsonTreeTheme(base16Theme) {
|
import { Base16Theme } from 'redux-devtools-themes';
|
||||||
|
import { StylingConfig } from 'react-base16-styling';
|
||||||
|
|
||||||
|
export default function getJsonTreeTheme(
|
||||||
|
base16Theme: Base16Theme
|
||||||
|
): StylingConfig {
|
||||||
return {
|
return {
|
||||||
extend: base16Theme,
|
extend: base16Theme,
|
||||||
nestedNode: ({ style }, keyPath, nodeType, expanded) => ({
|
nestedNode: ({ style }, keyPath, nodeType, expanded) => ({
|
|
@ -1,14 +1,15 @@
|
||||||
import jss from 'jss';
|
import jss, { Styles, StyleSheet } from 'jss';
|
||||||
import preset from 'jss-preset-default';
|
import preset from 'jss-preset-default';
|
||||||
import { createStyling } from 'react-base16-styling';
|
import { createStyling } from 'react-base16-styling';
|
||||||
import rgba from 'hex-rgba';
|
import rgba from 'hex-rgba';
|
||||||
|
import { Base16Theme } from 'redux-devtools-themes';
|
||||||
import inspector from '../themes/inspector';
|
import inspector from '../themes/inspector';
|
||||||
import * as reduxThemes from 'redux-devtools-themes';
|
import * as reduxThemes from 'redux-devtools-themes';
|
||||||
import * as inspectorThemes from '../themes';
|
import * as inspectorThemes from '../themes';
|
||||||
|
|
||||||
jss.setup(preset());
|
jss.setup(preset());
|
||||||
|
|
||||||
const colorMap = (theme) => ({
|
const colorMap = (theme: Base16Theme) => ({
|
||||||
TEXT_COLOR: theme.base06,
|
TEXT_COLOR: theme.base06,
|
||||||
TEXT_PLACEHOLDER_COLOR: rgba(theme.base06, 60),
|
TEXT_PLACEHOLDER_COLOR: rgba(theme.base06, 60),
|
||||||
BACKGROUND_COLOR: theme.base00,
|
BACKGROUND_COLOR: theme.base00,
|
||||||
|
@ -34,7 +35,12 @@ const colorMap = (theme) => ({
|
||||||
ERROR_COLOR: theme.base08,
|
ERROR_COLOR: theme.base08,
|
||||||
});
|
});
|
||||||
|
|
||||||
const getSheetFromColorMap = (map) => ({
|
type Color = keyof ReturnType<typeof colorMap>;
|
||||||
|
type ColorMap = {
|
||||||
|
[color in Color]: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSheetFromColorMap = (map: ColorMap) => ({
|
||||||
inspector: {
|
inspector: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
'flex-direction': 'column',
|
'flex-direction': 'column',
|
||||||
|
@ -384,9 +390,9 @@ const getSheetFromColorMap = (map) => ({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let themeSheet;
|
let themeSheet: StyleSheet;
|
||||||
|
|
||||||
const getDefaultThemeStyling = (theme) => {
|
const getDefaultThemeStyling = (theme: Base16Theme) => {
|
||||||
if (themeSheet) {
|
if (themeSheet) {
|
||||||
themeSheet.detach();
|
themeSheet.detach();
|
||||||
}
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
function deepMapCached(obj, f, ctx, cache) {
|
|
||||||
cache.push(obj);
|
|
||||||
if (Array.isArray(obj)) {
|
|
||||||
return obj.map(function (val, key) {
|
|
||||||
val = f.call(ctx, val, key);
|
|
||||||
return typeof val === 'object' && cache.indexOf(val) === -1
|
|
||||||
? deepMapCached(val, f, ctx, cache)
|
|
||||||
: val;
|
|
||||||
});
|
|
||||||
} else if (typeof obj === 'object') {
|
|
||||||
const res = {};
|
|
||||||
for (const key in obj) {
|
|
||||||
let val = obj[key];
|
|
||||||
if (val && typeof val === 'object') {
|
|
||||||
val = f.call(ctx, val, key);
|
|
||||||
res[key] =
|
|
||||||
cache.indexOf(val) === -1 ? deepMapCached(val, f, ctx, cache) : val;
|
|
||||||
} else {
|
|
||||||
res[key] = f.call(ctx, val, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
} else {
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function deepMap(obj, f, ctx) {
|
|
||||||
return deepMapCached(obj, f, ctx, []);
|
|
||||||
}
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Iterable, fromJS } from 'immutable';
|
import { fromJS, isAssociative } from 'immutable';
|
||||||
import isIterable from './isIterable';
|
import isIterable from './isIterable';
|
||||||
|
|
||||||
function iterateToKey(obj, key) {
|
function iterateToKey(obj: any, key: string | number) {
|
||||||
// maybe there's a better way, dunno
|
// maybe there's a better way, dunno
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
for (let entry of obj) {
|
for (const entry of obj) {
|
||||||
if (Array.isArray(entry)) {
|
if (Array.isArray(entry)) {
|
||||||
if (entry[0] === key) return entry[1];
|
if (entry[0] === key) return entry[1];
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,24 +15,28 @@ function iterateToKey(obj, key) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function getInspectedState(state, path, convertImmutable) {
|
export default function getInspectedState<S>(
|
||||||
|
state: S,
|
||||||
|
path: (string | number)[],
|
||||||
|
convertImmutable: boolean
|
||||||
|
): S {
|
||||||
state =
|
state =
|
||||||
path && path.length
|
path && path.length
|
||||||
? {
|
? ({
|
||||||
[path[path.length - 1]]: path.reduce((s, key) => {
|
[path[path.length - 1]]: path.reduce((s: any, key) => {
|
||||||
if (!s) {
|
if (!s) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Iterable.isAssociative(s)) {
|
if (isAssociative(s)) {
|
||||||
return s.get(key);
|
return s.get(key as number);
|
||||||
} else if (isIterable(s)) {
|
} else if (isIterable(s)) {
|
||||||
return iterateToKey(s, key);
|
return iterateToKey(s, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s[key];
|
return s[key];
|
||||||
}, state),
|
}, state),
|
||||||
}
|
} as S)
|
||||||
: state;
|
: state;
|
||||||
|
|
||||||
if (convertImmutable) {
|
if (convertImmutable) {
|
|
@ -1,4 +1,4 @@
|
||||||
export default function isIterable(obj) {
|
export default function isIterable(obj: any) {
|
||||||
return (
|
return (
|
||||||
obj !== null &&
|
obj !== null &&
|
||||||
typeof obj === 'object' &&
|
typeof obj === 'object' &&
|
8
packages/redux-devtools-inspector/tsconfig.json
Normal file
8
packages/redux-devtools-inspector/tsconfig.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.react.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "lib",
|
||||||
|
"resolveJsonModule": true
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
154
yarn.lock
154
yarn.lock
|
@ -25,7 +25,7 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/highlight" "^7.0.0"
|
"@babel/highlight" "^7.0.0"
|
||||||
|
|
||||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4":
|
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.8.3":
|
||||||
version "7.10.4"
|
version "7.10.4"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
|
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
|
||||||
integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
|
integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==
|
||||||
|
@ -1224,7 +1224,7 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.12.0"
|
regenerator-runtime "^0.12.0"
|
||||||
|
|
||||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
|
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
|
||||||
version "7.11.2"
|
version "7.11.2"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
|
||||||
integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==
|
integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==
|
||||||
|
@ -3082,6 +3082,16 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/dateformat@^3.0.1":
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
|
||||||
|
integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
|
||||||
|
|
||||||
|
"@types/dragula@*", "@types/dragula@^3.7.0":
|
||||||
|
version "3.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/dragula/-/dragula-3.7.0.tgz#62178f21c3896ab9823a33d08ed844ab9af496af"
|
||||||
|
integrity sha512-Scr3lQ7pDmwic+I4qrzDEIfPVGUhc/qo8S0VJJ9v5pzTyIIJzAXrnFajjsMSL8J84VERIkZUh7wH6wYEisY+TA==
|
||||||
|
|
||||||
"@types/eslint-visitor-keys@^1.0.0":
|
"@types/eslint-visitor-keys@^1.0.0":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
||||||
|
@ -3121,6 +3131,16 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/hex-rgba@^1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/hex-rgba/-/hex-rgba-1.0.0.tgz#b2aed2aa9fdd6152b7f0ac5e3733b974d4eba35a"
|
||||||
|
integrity sha512-u3AGV8fjRsDBqY4wOvVWhVCgKDfh2b0h3mux7KPKU1cm/6mJp14OWBINLgBypeBTM89Nm2j+eKQqIoIe7150DA==
|
||||||
|
|
||||||
|
"@types/history@*", "@types/history@^4.7.7":
|
||||||
|
version "4.7.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.7.tgz#613957d900fab9ff84c8dfb24fa3eef0c2a40896"
|
||||||
|
integrity sha512-2xtoL22/3Mv6a70i4+4RB7VgbDDORoWwjcqeNysojZA0R7NK17RbY5Gof/2QiFfJgX+KkWghbwJ+d/2SB8Ndzg==
|
||||||
|
|
||||||
"@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.0":
|
"@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.0":
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
||||||
|
@ -3195,7 +3215,7 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/jsan/-/jsan-3.1.0.tgz#128fdb14a102134ede764b11682e795d1b380c43"
|
resolved "https://registry.yarnpkg.com/@types/jsan/-/jsan-3.1.0.tgz#128fdb14a102134ede764b11682e795d1b380c43"
|
||||||
integrity sha512-V5wfm0++TqM92D0ZkAhl9MDQHPTi88fXhMNVin5LV/Y3RnuU/FUv6wML4Vt/amZmPN9WaFTmDhKW+h58kAFmIg==
|
integrity sha512-V5wfm0++TqM92D0ZkAhl9MDQHPTi88fXhMNVin5LV/Y3RnuU/FUv6wML4Vt/amZmPN9WaFTmDhKW+h58kAFmIg==
|
||||||
|
|
||||||
"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4":
|
"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5":
|
||||||
version "7.0.5"
|
version "7.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
|
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
|
||||||
integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
|
integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
|
||||||
|
@ -3214,6 +3234,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/lodash" "*"
|
"@types/lodash" "*"
|
||||||
|
|
||||||
|
"@types/lodash.shuffle@^4.2.6":
|
||||||
|
version "4.2.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/lodash.shuffle/-/lodash.shuffle-4.2.6.tgz#191b0fc66699214558352123811d1657d9ed8930"
|
||||||
|
integrity sha512-ucI9VswlV9jOZiIh43Nd0tJ4Z8pfXy3PbQ9cB6Re1gPds8gLbOdmB0l3UkVI2crZjnQB95bhyNZVEDH8DgglYA==
|
||||||
|
dependencies:
|
||||||
|
"@types/lodash" "*"
|
||||||
|
|
||||||
"@types/lodash@*", "@types/lodash@^4.14.159":
|
"@types/lodash@*", "@types/lodash@^4.14.159":
|
||||||
version "4.14.159"
|
version "4.14.159"
|
||||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.159.tgz#61089719dc6fdd9c5cb46efc827f2571d1517065"
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.159.tgz#61089719dc6fdd9c5cb46efc827f2571d1517065"
|
||||||
|
@ -3296,6 +3323,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-dragula@^1.1.0":
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-dragula/-/react-dragula-1.1.0.tgz#c7a6840891c52aa5007a8f8b87b31985fbc3c5b2"
|
||||||
|
integrity sha512-wgRIVV2jo/Gria1PK3K26II7gfRD3VTcMfPYhL0CuIApSeon7xjBTj8Xs8Ln+Vbb/FuRKWfUaJXmF4R3KUGntA==
|
||||||
|
dependencies:
|
||||||
|
"@types/dragula" "*"
|
||||||
|
|
||||||
"@types/react-native@*":
|
"@types/react-native@*":
|
||||||
version "0.63.8"
|
version "0.63.8"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.8.tgz#73ec087122c64c309eeaf150b565b8d755f0fb1f"
|
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.8.tgz#73ec087122c64c309eeaf150b565b8d755f0fb1f"
|
||||||
|
@ -3313,6 +3347,14 @@
|
||||||
hoist-non-react-statics "^3.3.0"
|
hoist-non-react-statics "^3.3.0"
|
||||||
redux "^4.0.0"
|
redux "^4.0.0"
|
||||||
|
|
||||||
|
"@types/react-router@^5.1.8":
|
||||||
|
version "5.1.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.8.tgz#4614e5ba7559657438e17766bb95ef6ed6acc3fa"
|
||||||
|
integrity sha512-HzOyJb+wFmyEhyfp4D4NYrumi+LQgQL/68HvJO+q6XtuHSDvw6Aqov7sCAhjbNq3bUPgPqbdvjXC5HeB2oEAPg==
|
||||||
|
dependencies:
|
||||||
|
"@types/history" "*"
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react-test-renderer@^16.9.3":
|
"@types/react-test-renderer@^16.9.3":
|
||||||
version "16.9.3"
|
version "16.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-16.9.3.tgz#96bab1860904366f4e848b739ba0e2f67bcae87e"
|
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-16.9.3.tgz#96bab1860904366f4e848b739ba0e2f67bcae87e"
|
||||||
|
@ -3342,6 +3384,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/base16" "*"
|
"@types/base16" "*"
|
||||||
|
|
||||||
|
"@types/redux-logger@^3.0.8":
|
||||||
|
version "3.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/redux-logger/-/redux-logger-3.0.8.tgz#1fb6d26917bb198792bb1cf57feb31cae1532c5d"
|
||||||
|
integrity sha512-zM+cxiSw6nZtRbxpVp9SE3x/X77Z7e7YAfHD1NkxJyJbAGSXJGF0E9aqajZfPOa/sTYnuwutmlCldveExuCeLw==
|
||||||
|
dependencies:
|
||||||
|
redux "^4.0.0"
|
||||||
|
|
||||||
"@types/serve-static@*":
|
"@types/serve-static@*":
|
||||||
version "1.13.5"
|
version "1.13.5"
|
||||||
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.5.tgz#3d25d941a18415d3ab092def846e135a08bbcf53"
|
resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.5.tgz#3d25d941a18415d3ab092def846e135a08bbcf53"
|
||||||
|
@ -4270,6 +4319,11 @@ asynckit@^0.4.0:
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||||
|
|
||||||
|
at-least-node@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
|
||||||
|
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
|
||||||
|
|
||||||
atoa@1.0.0:
|
atoa@1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/atoa/-/atoa-1.0.0.tgz#0cc0e91a480e738f923ebc103676471779b34a49"
|
resolved "https://registry.yarnpkg.com/atoa/-/atoa-1.0.0.tgz#0cc0e91a480e738f923ebc103676471779b34a49"
|
||||||
|
@ -7886,6 +7940,23 @@ forever-agent@~0.6.1:
|
||||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
||||||
|
|
||||||
|
fork-ts-checker-webpack-plugin@^5.1.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.1.0.tgz#586fbee24aeea950c53bab529e32017f543e71cf"
|
||||||
|
integrity sha512-vuKyEjSLGbhQbEr5bifXXOkr9iV73L6n72mHoHIv7okvrf7O7z6RKeplM6C6ATPsukoQivij+Ba1vcptL60Z2g==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.8.3"
|
||||||
|
"@types/json-schema" "^7.0.5"
|
||||||
|
chalk "^4.1.0"
|
||||||
|
cosmiconfig "^6.0.0"
|
||||||
|
deepmerge "^4.2.2"
|
||||||
|
fs-extra "^9.0.0"
|
||||||
|
memfs "^3.1.2"
|
||||||
|
minimatch "^3.0.4"
|
||||||
|
schema-utils "2.7.0"
|
||||||
|
semver "^7.3.2"
|
||||||
|
tapable "^1.0.0"
|
||||||
|
|
||||||
form-data@^2.3.1:
|
form-data@^2.3.1:
|
||||||
version "2.5.1"
|
version "2.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
|
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
|
||||||
|
@ -7972,6 +8043,16 @@ fs-extra@^8.1.0:
|
||||||
jsonfile "^4.0.0"
|
jsonfile "^4.0.0"
|
||||||
universalify "^0.1.0"
|
universalify "^0.1.0"
|
||||||
|
|
||||||
|
fs-extra@^9.0.0:
|
||||||
|
version "9.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc"
|
||||||
|
integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==
|
||||||
|
dependencies:
|
||||||
|
at-least-node "^1.0.0"
|
||||||
|
graceful-fs "^4.2.0"
|
||||||
|
jsonfile "^6.0.1"
|
||||||
|
universalify "^1.0.0"
|
||||||
|
|
||||||
fs-minipass@^1.2.5:
|
fs-minipass@^1.2.5:
|
||||||
version "1.2.7"
|
version "1.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
|
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
|
||||||
|
@ -7979,6 +8060,11 @@ fs-minipass@^1.2.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
minipass "^2.6.0"
|
minipass "^2.6.0"
|
||||||
|
|
||||||
|
fs-monkey@1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.1.tgz#4a82f36944365e619f4454d9fff106553067b781"
|
||||||
|
integrity sha512-fcSa+wyTqZa46iWweI7/ZiUfegOZl0SG8+dltIwFXo7+zYU9J9kpS3NB6pZcSlJdhvIwp81Adx2XhZorncxiaA==
|
||||||
|
|
||||||
fs-readdir-recursive@^1.1.0:
|
fs-readdir-recursive@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
|
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
|
||||||
|
@ -10248,6 +10334,15 @@ jsonfile@^4.0.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
graceful-fs "^4.1.6"
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
|
jsonfile@^6.0.1:
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179"
|
||||||
|
integrity sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==
|
||||||
|
dependencies:
|
||||||
|
universalify "^1.0.0"
|
||||||
|
optionalDependencies:
|
||||||
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
jsonify@~0.0.0:
|
jsonify@~0.0.0:
|
||||||
version "0.0.0"
|
version "0.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||||
|
@ -10866,7 +10961,7 @@ lodash.uniq@^4.5.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||||
|
|
||||||
lodash@^4.0.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1, lodash@^4.8.0:
|
lodash@^4.0.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.8.0:
|
||||||
version "4.17.19"
|
version "4.17.19"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
||||||
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
||||||
|
@ -11106,6 +11201,13 @@ media-typer@0.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||||
|
|
||||||
|
memfs@^3.1.2:
|
||||||
|
version "3.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.2.0.tgz#f9438e622b5acd1daa8a4ae160c496fdd1325b26"
|
||||||
|
integrity sha512-f/xxz2TpdKv6uDn6GtHee8ivFyxwxmPuXatBb1FBwxYNuVpbM3k/Y1Z+vC0mH/dIXXrukYfe3qe5J32Dfjg93A==
|
||||||
|
dependencies:
|
||||||
|
fs-monkey "1.0.1"
|
||||||
|
|
||||||
memory-fs@^0.4.1:
|
memory-fs@^0.4.1:
|
||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
|
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
|
||||||
|
@ -13238,11 +13340,6 @@ react-color@^2.14.1:
|
||||||
reactcss "^1.2.0"
|
reactcss "^1.2.0"
|
||||||
tinycolor2 "^1.4.1"
|
tinycolor2 "^1.4.1"
|
||||||
|
|
||||||
react-deep-force-update@^1.0.0:
|
|
||||||
version "1.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1"
|
|
||||||
integrity sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA==
|
|
||||||
|
|
||||||
react-dev-utils@^6.1.0:
|
react-dev-utils@^6.1.0:
|
||||||
version "6.1.1"
|
version "6.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-6.1.1.tgz#a07e3e8923c4609d9f27e5af5207e3ca20724895"
|
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-6.1.1.tgz#a07e3e8923c4609d9f27e5af5207e3ca20724895"
|
||||||
|
@ -13404,14 +13501,6 @@ react-overlays@^4.1.0:
|
||||||
uncontrollable "^7.0.0"
|
uncontrollable "^7.0.0"
|
||||||
warning "^4.0.3"
|
warning "^4.0.3"
|
||||||
|
|
||||||
react-proxy@^1.1.7:
|
|
||||||
version "1.1.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a"
|
|
||||||
integrity sha1-nb/Z2SdSjDqp9ETkVYw3gwq4wmo=
|
|
||||||
dependencies:
|
|
||||||
lodash "^4.6.1"
|
|
||||||
react-deep-force-update "^1.0.0"
|
|
||||||
|
|
||||||
react-pure-render@^1.0.2:
|
react-pure-render@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-pure-render/-/react-pure-render-1.0.2.tgz#9d8a928c7f2c37513c2d064e57b3e3c356e9fabb"
|
resolved "https://registry.yarnpkg.com/react-pure-render/-/react-pure-render-1.0.2.tgz#9d8a928c7f2c37513c2d064e57b3e3c356e9fabb"
|
||||||
|
@ -13487,14 +13576,6 @@ react-textarea-autosize@^7.0.4:
|
||||||
"@babel/runtime" "^7.1.2"
|
"@babel/runtime" "^7.1.2"
|
||||||
prop-types "^15.6.0"
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
react-transform-hmr@^1.0.4:
|
|
||||||
version "1.0.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz#e1a40bd0aaefc72e8dfd7a7cda09af85066397bb"
|
|
||||||
integrity sha1-4aQL0Krvxy6N/Xp82gmvhQZjl7s=
|
|
||||||
dependencies:
|
|
||||||
global "^4.3.0"
|
|
||||||
react-proxy "^1.1.7"
|
|
||||||
|
|
||||||
react-transition-group@^2.0.0:
|
react-transition-group@^2.0.0:
|
||||||
version "2.9.0"
|
version "2.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
|
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
|
||||||
|
@ -14322,6 +14403,15 @@ scheduler@^0.19.1:
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
|
|
||||||
|
schema-utils@2.7.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0:
|
||||||
|
version "2.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7"
|
||||||
|
integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==
|
||||||
|
dependencies:
|
||||||
|
"@types/json-schema" "^7.0.4"
|
||||||
|
ajv "^6.12.2"
|
||||||
|
ajv-keywords "^3.4.1"
|
||||||
|
|
||||||
schema-utils@^1.0.0:
|
schema-utils@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
|
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
|
||||||
|
@ -14331,15 +14421,6 @@ schema-utils@^1.0.0:
|
||||||
ajv-errors "^1.0.0"
|
ajv-errors "^1.0.0"
|
||||||
ajv-keywords "^3.1.0"
|
ajv-keywords "^3.1.0"
|
||||||
|
|
||||||
schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0:
|
|
||||||
version "2.7.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7"
|
|
||||||
integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==
|
|
||||||
dependencies:
|
|
||||||
"@types/json-schema" "^7.0.4"
|
|
||||||
ajv "^6.12.2"
|
|
||||||
ajv-keywords "^3.4.1"
|
|
||||||
|
|
||||||
seamless-immutable@^7.1.4:
|
seamless-immutable@^7.1.4:
|
||||||
version "7.1.4"
|
version "7.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/seamless-immutable/-/seamless-immutable-7.1.4.tgz#6e9536def083ddc4dea0207d722e0e80d0f372f8"
|
resolved "https://registry.yarnpkg.com/seamless-immutable/-/seamless-immutable-7.1.4.tgz#6e9536def083ddc4dea0207d722e0e80d0f372f8"
|
||||||
|
@ -16132,6 +16213,11 @@ universalify@^0.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||||
|
|
||||||
|
universalify@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
|
||||||
|
integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==
|
||||||
|
|
||||||
unpipe@1.0.0, unpipe@~1.0.0:
|
unpipe@1.0.0, unpipe@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user