diff --git a/packages/react-base16-styling/src/index.ts b/packages/react-base16-styling/src/index.ts index f53667f2..43c4e27f 100644 --- a/packages/react-base16-styling/src/index.ts +++ b/packages/react-base16-styling/src/index.ts @@ -142,7 +142,7 @@ const mergeStylings = ( const getStylingByKeys = ( mergedStyling: StylingConfig, - keys: (string | false) | (string | false)[], + keys: (string | false | undefined) | (string | false | undefined)[], ...args: any[] ): Styling => { if (keys === null) { diff --git a/packages/react-base16-styling/src/types.ts b/packages/react-base16-styling/src/types.ts index 2896d1f6..6ec9dc98 100644 --- a/packages/react-base16-styling/src/types.ts +++ b/packages/react-base16-styling/src/types.ts @@ -27,6 +27,6 @@ export type StylingConfig = { export type Theme = string | Base16Theme | StylingConfig; export type StylingFunction = ( - keys: (string | false) | (string | false)[], + keys: (string | false | undefined) | (string | false | undefined)[], ...rest: any[] ) => Styling; diff --git a/packages/react-dock/webpack.config.ts b/packages/react-dock/webpack.config.ts index 6bb05aae..4207ba56 100644 --- a/packages/react-dock/webpack.config.ts +++ b/packages/react-dock/webpack.config.ts @@ -5,7 +5,6 @@ const isProduction = process.env.NODE_ENV === 'production'; module.exports = { mode: isProduction ? 'production' : 'development', - devtool: 'eval', entry: isProduction ? ['./demo/src/index'] : [ @@ -18,10 +17,6 @@ module.exports = { filename: 'bundle.js', publicPath: isProduction ? 'static/' : '/static/', }, - plugins: isProduction ? [] : [new webpack.HotModuleReplacementPlugin()], - resolve: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - }, module: { rules: [ { @@ -34,6 +29,10 @@ module.exports = { }, ], }, + resolve: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + plugins: isProduction ? [] : [new webpack.HotModuleReplacementPlugin()], devServer: isProduction ? null : { @@ -46,4 +45,5 @@ module.exports = { }, historyApiFallback: true, }, + devtool: 'eval-source-map', }; diff --git a/packages/redux-devtools-inspector/package.json b/packages/redux-devtools-inspector/package.json index ba8b19d9..61acb6d4 100644 --- a/packages/redux-devtools-inspector/package.json +++ b/packages/redux-devtools-inspector/package.json @@ -53,6 +53,7 @@ }, "devDependencies": { "@types/dateformat": "^3.0.1", + "@types/hex-rgba": "^1.0.0", "@types/lodash.debounce": "^4.0.6", "@types/react": "^16.9.46", "@types/react-dragula": "^1.1.0", diff --git a/packages/redux-devtools-inspector/src/ActionList.tsx b/packages/redux-devtools-inspector/src/ActionList.tsx index 05080dfb..8d1c5cd1 100644 --- a/packages/redux-devtools-inspector/src/ActionList.tsx +++ b/packages/redux-devtools-inspector/src/ActionList.tsx @@ -164,18 +164,20 @@ export default class ActionList< isSelected={ (startActionId !== null && actionId >= startActionId && - actionId <= selectedActionId) || + actionId <= (selectedActionId as number)) || actionId === selectedActionId } isInFuture={ actionIds.indexOf(actionId) > actionIds.indexOf(currentActionId) } - onSelect={(e) => onSelect(e, actionId)} + onSelect={(e: React.MouseEvent) => + onSelect(e, actionId) + } timestamps={getTimestamps(actions, actionIds, actionId)} action={actions[actionId].action} onToggleClick={() => onToggleAction(actionId)} onJumpClick={() => onJumpToState(actionId)} - onCommitClick={() => onCommit(actionId)} + onCommitClick={() => onCommit()} hideActionButtons={hideActionButtons} isSkipped={skippedActionIds.indexOf(actionId) !== -1} /> diff --git a/packages/redux-devtools-inspector/src/ActionListHeader.tsx b/packages/redux-devtools-inspector/src/ActionListHeader.tsx index d7a1e708..f913b2ed 100644 --- a/packages/redux-devtools-inspector/src/ActionListHeader.tsx +++ b/packages/redux-devtools-inspector/src/ActionListHeader.tsx @@ -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'; -const getActiveButtons = (hasSkippedActions) => - [hasSkippedActions && 'Sweep', 'Commit'].filter((a) => a); +const getActiveButtons = (hasSkippedActions: boolean): ('Sweep' | 'Commit')[] => + [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 = ({ styling, onSearch, hasSkippedActions, @@ -48,4 +62,14 @@ const ActionListHeader = ({ ); +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; diff --git a/packages/redux-devtools-inspector/src/ActionPreview.tsx b/packages/redux-devtools-inspector/src/ActionPreview.tsx index 8de51b1c..37c7d887 100644 --- a/packages/redux-devtools-inspector/src/ActionPreview.tsx +++ b/packages/redux-devtools-inspector/src/ActionPreview.tsx @@ -1,10 +1,43 @@ 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 DiffTab from './tabs/DiffTab'; import StateTab from './tabs/StateTab'; import ActionTab from './tabs/ActionTab'; +export interface TabComponentProps> { + labelRenderer: ( + keyPath: (string | number)[], + nodeType: string, + expanded: boolean, + expandable: boolean + ) => React.ReactNode; + styling: StylingFunction; + computedStates: { state: S; error?: string }[]; + actions: { [actionId: number]: PerformAction }; + 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) => void; +} + +export interface Tab> { + name: string; + component: React.ComponentType>; +} + const DEFAULT_TABS = [ { name: 'Action', @@ -20,7 +53,32 @@ const DEFAULT_TABS = [ }, ]; -class ActionPreview extends Component { +interface Props> { + base16Theme: Base16Theme; + invertTheme: boolean; + isWideLayout: boolean; + tabs: Tab[] | ((tabs: Tab[]) => Tab[]); + tabName: string; + delta: Delta | null | undefined | false; + error: string | undefined; + nextState: S; + computedStates: { state: S; error?: string }[]; + action: A; + actions: { [actionId: number]: PerformAction }; + selectedActionId: number | null; + startActionId: number | null; + dataTypeKey: string | undefined; + monitorState: DevtoolsInspectorState; + updateMonitorState: (monitorState: Partial) => void; + styling: StylingFunction; + onInspectPath: (path: (string | number)[]) => void; + inspectedPath: (string | number)[]; + onSelectTab: (tabName: string) => void; +} + +class ActionPreview> extends Component< + Props +> { static defaultProps = { tabName: DEFAULT_STATE.tabName, }; @@ -49,21 +107,21 @@ class ActionPreview extends Component { updateMonitorState, } = this.props; - const renderedTabs = + const renderedTabs: Tab[] = typeof tabs === 'function' - ? tabs(DEFAULT_TABS) + ? tabs(DEFAULT_TABS as Tab[]) : tabs ? tabs - : DEFAULT_TABS; + : (DEFAULT_TABS as Tab[]); const { component: TabComponent } = renderedTabs.find((tab) => tab.name === tabName) || - renderedTabs.find((tab) => tab.name === DEFAULT_STATE.tabName); + renderedTabs.find((tab) => tab.name === DEFAULT_STATE.tabName)!; return (
>[]} {...{ styling, inspectedPath, onInspectPath, tabName, onSelectTab }} /> {!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; return ( diff --git a/packages/redux-devtools-inspector/src/ActionPreviewHeader.tsx b/packages/redux-devtools-inspector/src/ActionPreviewHeader.tsx index 1b65c579..ed930d5a 100644 --- a/packages/redux-devtools-inspector/src/ActionPreviewHeader.tsx +++ b/packages/redux-devtools-inspector/src/ActionPreviewHeader.tsx @@ -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> { + tabs: Tab[]; + styling: StylingFunction; + inspectedPath: (string | number)[]; + onInspectPath: (path: (string | number)[]) => void; + tabName: string; + onSelectTab: (tabName: string) => void; +} + +const ActionPreviewHeader: FunctionComponent +>> = ({ styling, inspectedPath, onInspectPath, @@ -57,4 +73,13 @@ const ActionPreviewHeader = ({
); +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; diff --git a/packages/redux-devtools-inspector/src/DevtoolsInspector.tsx b/packages/redux-devtools-inspector/src/DevtoolsInspector.tsx index 8fa95302..25d42721 100644 --- a/packages/redux-devtools-inspector/src/DevtoolsInspector.tsx +++ b/packages/redux-devtools-inspector/src/DevtoolsInspector.tsx @@ -14,7 +14,7 @@ import { base16Themes, } from './utils/createStylingFromTheme'; import ActionList from './ActionList'; -import ActionPreview from './ActionPreview'; +import ActionPreview, { Tab } from './ActionPreview'; import getInspectedState from './utils/getInspectedState'; import createDiffPatcher from './createDiffPatcher'; import { @@ -144,7 +144,7 @@ export interface DevtoolsInspectorProps> hideActionButtons?: boolean; invertTheme: boolean; dataTypeKey?: string; - tabs: unknown; + tabs: Tab[] | ((tabs: Tab[]) => Tab[]); } interface State> { @@ -342,7 +342,9 @@ export default class DevtoolsInspector< monitorState={this.props.monitorState} updateMonitorState={this.updateMonitorState} styling={styling} - onInspectPath={this.handleInspectPath.bind(this, inspectedPathType)} + onInspectPath={(path: (string | number)[]) => + this.handleInspectPath(inspectedPathType, path) + } inspectedPath={monitorState[inspectedPathType]} onSelectTab={this.handleSelectTab} /> diff --git a/packages/redux-devtools-inspector/src/RightSlider.tsx b/packages/redux-devtools-inspector/src/RightSlider.tsx index 0b65307f..ee95bfa3 100644 --- a/packages/redux-devtools-inspector/src/RightSlider.tsx +++ b/packages/redux-devtools-inspector/src/RightSlider.tsx @@ -1,7 +1,20 @@ -import React from 'react'; +import React, { FunctionComponent } from 'react'; import PropTypes from 'prop-types'; +import { StylingFunction } from 'react-base16-styling'; -const RightSlider = ({ styling, shown, children, rotate }) => ( +interface Props { + styling: StylingFunction; + shown?: boolean; + children: React.ReactNode; + rotate?: boolean; +} + +const RightSlider: FunctionComponent = ({ + styling, + shown, + children, + rotate, +}) => (
( ); RightSlider.propTypes = { + styling: PropTypes.func.isRequired, shown: PropTypes.bool, + children: PropTypes.any.isRequired, + rotate: PropTypes.bool, }; export default RightSlider; diff --git a/packages/redux-devtools-inspector/src/createDiffPatcher.ts b/packages/redux-devtools-inspector/src/createDiffPatcher.ts index 53a7d4fc..41a8c097 100644 --- a/packages/redux-devtools-inspector/src/createDiffPatcher.ts +++ b/packages/redux-devtools-inspector/src/createDiffPatcher.ts @@ -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 && (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.right[name] !== 'function'; const defaultDiffPatcher = new DiffPatcher({ - arrays: { detectMove: false }, + arrays: { detectMove: false } as { + detectMove: boolean; + includeValueOnMove: boolean; + }, objectHash: defaultObjectHash, 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) { return defaultDiffPatcher; } return new DiffPatcher({ - arrays: { detectMove: false }, + arrays: { detectMove: false } as { + detectMove: boolean; + includeValueOnMove: boolean; + }, objectHash: objectHash || defaultObjectHash, propertyFilter: propertyFilter || defaultPropertyFilter, }); diff --git a/packages/redux-devtools-inspector/src/tabs/ActionTab.tsx b/packages/redux-devtools-inspector/src/tabs/ActionTab.tsx index c5cb77c8..056a72cc 100644 --- a/packages/redux-devtools-inspector/src/tabs/ActionTab.tsx +++ b/packages/redux-devtools-inspector/src/tabs/ActionTab.tsx @@ -1,9 +1,15 @@ -import React from 'react'; +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 = ({ +const ActionTab: FunctionComponent +>> = ({ action, styling, base16Theme, @@ -24,4 +30,14 @@ const ActionTab = ({ /> ); +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; diff --git a/packages/redux-devtools-inspector/src/tabs/DiffTab.tsx b/packages/redux-devtools-inspector/src/tabs/DiffTab.tsx index cb73ef3c..2d1c6224 100644 --- a/packages/redux-devtools-inspector/src/tabs/DiffTab.tsx +++ b/packages/redux-devtools-inspector/src/tabs/DiffTab.tsx @@ -1,13 +1,20 @@ -import React from 'react'; +import React, { FunctionComponent } from 'react'; +import PropTypes from 'prop-types'; import JSONDiff from './JSONDiff'; +import { TabComponentProps } from '../ActionPreview'; +import { Action } from 'redux'; -const DiffTab = ({ +const DiffTab: FunctionComponent +>> = ({ 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; diff --git a/packages/redux-devtools-inspector/src/tabs/JSONDiff.tsx b/packages/redux-devtools-inspector/src/tabs/JSONDiff.tsx index dac8d716..efcd8038 100644 --- a/packages/redux-devtools-inspector/src/tabs/JSONDiff.tsx +++ b/packages/redux-devtools-inspector/src/tabs/JSONDiff.tsx @@ -1,10 +1,13 @@ import React, { Component } from 'react'; import JSONTree from 'react-json-tree'; 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 getJsonTreeTheme from './getJsonTreeTheme'; -function stringifyAndShrink(val, isWideLayout) { +function stringifyAndShrink(val: any, isWideLayout?: boolean) { if (val === null) { return 'null'; } @@ -19,12 +22,16 @@ function stringifyAndShrink(val, isWideLayout) { 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') { - const res = {}; - for (let key in value) { + const res: { [key: string]: any } = {}; + for (const key in value) { if (key !== '_t') { if (key[0] === '_' && !value[key.substr(1)]) { res[key.substr(1)] = value[key]; @@ -41,14 +48,33 @@ function prepareDelta(value) { return value; } -export default class JSONDiff extends Component { - state = { data: {} }; +interface Props { + 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 { + state: State = { data: {} }; componentDidMount() { this.updateData(); } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: Props) { if (prevProps.delta !== this.props.delta) { this.updateData(); } @@ -84,7 +110,7 @@ export default class JSONDiff extends Component { ); } - getItemString = (type, data) => + getItemString = (type: string, data: any) => getItemString( this.props.styling, type, @@ -94,10 +120,10 @@ export default class JSONDiff extends Component { true ); - valueRenderer = (raw, value) => { + valueRenderer = (raw: any, value: any) => { const { styling, isWideLayout } = this.props; - function renderSpan(name, body) { + function renderSpan(name: string, body: string) { return ( {body} diff --git a/packages/redux-devtools-inspector/src/tabs/StateTab.tsx b/packages/redux-devtools-inspector/src/tabs/StateTab.tsx index c2991458..328f0380 100644 --- a/packages/redux-devtools-inspector/src/tabs/StateTab.tsx +++ b/packages/redux-devtools-inspector/src/tabs/StateTab.tsx @@ -1,9 +1,15 @@ import React 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 StateTab = ({ +const StateTab: React.FunctionComponent +>> = ({ nextState, styling, 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; diff --git a/packages/redux-devtools-inspector/src/tabs/getItemString.tsx b/packages/redux-devtools-inspector/src/tabs/getItemString.tsx index 598dd4ff..85eb261a 100644 --- a/packages/redux-devtools-inspector/src/tabs/getItemString.tsx +++ b/packages/redux-devtools-inspector/src/tabs/getItemString.tsx @@ -1,18 +1,15 @@ 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'; const IS_IMMUTABLE_KEY = '@@__IS_IMMUTABLE__@@'; -function isImmutable(value) { - return ( - Iterable.isKeyed(value) || - Iterable.isIndexed(value) || - Iterable.isIterable(value) - ); +function isImmutable(value: any) { + return isKeyed(value) || isIndexed(value) || isCollection(value); } -function getShortTypeString(val, diff) { +function getShortTypeString(val: any, diff: boolean | undefined) { if (diff && Array.isArray(val)) { 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') { const keys = Object.keys(data); if (!isWideLayout) return keys.length ? '{…}' : '{}'; const str = keys .slice(0, 3) - .map((key) => `${key}: ${getShortTypeString(data[key], isDiff)}`) + .map( + (key) => `${key}: ${getShortTypeString(data[key], isDiff) as string}` + ) .concat(keys.length > 3 ? ['…'] : []) .join(', '); @@ -55,27 +59,27 @@ function getText(type, data, isWideLayout, isDiff) { const str = data .slice(0, 4) - .map((val) => getShortTypeString(val, isDiff)) + .map((val: any) => getShortTypeString(val, isDiff)) .concat(data.length > 4 ? ['…'] : []) .join(', '); - return `[${str}]`; + return `[${str as string}]`; } else { return type; } } const getItemString = ( - styling, - type, - data, - dataTypeKey, - isWideLayout, - isDiff + styling: StylingFunction, + type: string, + data: any, + dataTypeKey: string | undefined, + isWideLayout: boolean, + isDiff?: boolean ) => ( {data[IS_IMMUTABLE_KEY] ? 'Immutable' : ''} - {dataTypeKey && data[dataTypeKey] ? data[dataTypeKey] + ' ' : ''} + {dataTypeKey && data[dataTypeKey] ? `${data[dataTypeKey] as string} ` : ''} {getText(type, data, isWideLayout, isDiff)} ); diff --git a/packages/redux-devtools-inspector/src/tabs/getJsonTreeTheme.ts b/packages/redux-devtools-inspector/src/tabs/getJsonTreeTheme.ts index e936f291..1ca64cfa 100644 --- a/packages/redux-devtools-inspector/src/tabs/getJsonTreeTheme.ts +++ b/packages/redux-devtools-inspector/src/tabs/getJsonTreeTheme.ts @@ -1,4 +1,9 @@ -export default function getJsonTreeTheme(base16Theme) { +import { Base16Theme } from 'base16'; +import { StylingConfig } from 'react-base16-styling'; + +export default function getJsonTreeTheme( + base16Theme: Base16Theme +): StylingConfig { return { extend: base16Theme, nestedNode: ({ style }, keyPath, nodeType, expanded) => ({ diff --git a/packages/redux-devtools-inspector/src/utils/createStylingFromTheme.ts b/packages/redux-devtools-inspector/src/utils/createStylingFromTheme.ts index 0af17dcb..e1db41f8 100644 --- a/packages/redux-devtools-inspector/src/utils/createStylingFromTheme.ts +++ b/packages/redux-devtools-inspector/src/utils/createStylingFromTheme.ts @@ -1,14 +1,15 @@ -import jss from 'jss'; +import jss, { Styles, StyleSheet } from 'jss'; import preset from 'jss-preset-default'; import { createStyling } from 'react-base16-styling'; import rgba from 'hex-rgba'; +import { Base16Theme } from 'redux-devtools-themes'; import inspector from '../themes/inspector'; import * as reduxThemes from 'redux-devtools-themes'; import * as inspectorThemes from '../themes'; jss.setup(preset()); -const colorMap = (theme) => ({ +const colorMap = (theme: Base16Theme) => ({ TEXT_COLOR: theme.base06, TEXT_PLACEHOLDER_COLOR: rgba(theme.base06, 60), BACKGROUND_COLOR: theme.base00, @@ -34,7 +35,12 @@ const colorMap = (theme) => ({ ERROR_COLOR: theme.base08, }); -const getSheetFromColorMap = (map) => ({ +type Color = keyof ReturnType; +type ColorMap = { + [color in Color]: string; +}; + +const getSheetFromColorMap = (map: ColorMap) => ({ inspector: { display: 'flex', 'flex-direction': 'column', @@ -384,9 +390,9 @@ const getSheetFromColorMap = (map) => ({ }, }); -let themeSheet; +let themeSheet: StyleSheet; -const getDefaultThemeStyling = (theme) => { +const getDefaultThemeStyling = (theme: Base16Theme) => { if (themeSheet) { themeSheet.detach(); } diff --git a/packages/redux-devtools-inspector/src/utils/deepMap.ts b/packages/redux-devtools-inspector/src/utils/deepMap.ts deleted file mode 100644 index b76e1217..00000000 --- a/packages/redux-devtools-inspector/src/utils/deepMap.ts +++ /dev/null @@ -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, []); -} diff --git a/packages/redux-devtools-inspector/src/utils/getInspectedState.ts b/packages/redux-devtools-inspector/src/utils/getInspectedState.ts index dd62c471..09fa708b 100644 --- a/packages/redux-devtools-inspector/src/utils/getInspectedState.ts +++ b/packages/redux-devtools-inspector/src/utils/getInspectedState.ts @@ -1,10 +1,10 @@ -import { Iterable, fromJS } from 'immutable'; +import { fromJS, isAssociative } from 'immutable'; import isIterable from './isIterable'; -function iterateToKey(obj, key) { +function iterateToKey(obj: any, key: string | number) { // maybe there's a better way, dunno let idx = 0; - for (let entry of obj) { + for (const entry of obj) { if (Array.isArray(entry)) { if (entry[0] === key) return entry[1]; } else { @@ -15,24 +15,28 @@ function iterateToKey(obj, key) { } } -export default function getInspectedState(state, path, convertImmutable) { +export default function getInspectedState( + state: S, + path: (string | number)[], + convertImmutable: boolean +): S { state = path && path.length - ? { - [path[path.length - 1]]: path.reduce((s, key) => { + ? ({ + [path[path.length - 1]]: path.reduce((s: any, key) => { if (!s) { return s; } - if (Iterable.isAssociative(s)) { - return s.get(key); + if (isAssociative(s)) { + return s.get(key as number); } else if (isIterable(s)) { return iterateToKey(s, key); } return s[key]; }, state), - } + } as S) : state; if (convertImmutable) { diff --git a/packages/redux-devtools-inspector/src/utils/isIterable.ts b/packages/redux-devtools-inspector/src/utils/isIterable.ts index 45f33b64..a7226ad0 100644 --- a/packages/redux-devtools-inspector/src/utils/isIterable.ts +++ b/packages/redux-devtools-inspector/src/utils/isIterable.ts @@ -1,4 +1,4 @@ -export default function isIterable(obj) { +export default function isIterable(obj: any) { return ( obj !== null && typeof obj === 'object' && diff --git a/packages/redux-devtools-inspector/webpack.config.ts b/packages/redux-devtools-inspector/webpack.config.ts index e86ec804..d383d031 100644 --- a/packages/redux-devtools-inspector/webpack.config.ts +++ b/packages/redux-devtools-inspector/webpack.config.ts @@ -9,7 +9,6 @@ const isProduction = process.env.NODE_ENV === 'production'; module.exports = { mode: process.env.NODE_ENV || 'development', - devtool: 'eval-source-map', entry: isProduction ? ['./demo/src/js/index'] : [ @@ -21,26 +20,10 @@ module.exports = { path: path.join(__dirname, 'demo/dist'), filename: 'js/bundle.js', }, - plugins: [ - new CleanWebpackPlugin(), - new HtmlWebpackPlugin({ - inject: true, - template: 'demo/src/index.html', - package: pkg, - }), - new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: JSON.stringify(process.env.NODE_ENV), - }, - }), - ].concat(isProduction ? [] : [new webpack.HotModuleReplacementPlugin()]), - resolve: { - extensions: ['*', '.js', '.jsx'], - }, module: { rules: [ { - test: /\.jsx?$/, + test: /\.(js|ts)x?$/, loader: 'babel-loader', include: [ path.join(__dirname, 'src'), @@ -49,6 +32,17 @@ module.exports = { }, ], }, + resolve: { + extensions: ['*', '.js', '.jsx'], + }, + plugins: [ + new CleanWebpackPlugin(), + new HtmlWebpackPlugin({ + inject: true, + template: 'demo/src/index.html', + package: pkg, + }), + ].concat(isProduction ? [] : [new webpack.HotModuleReplacementPlugin()]), devServer: isProduction ? {} : { @@ -61,4 +55,5 @@ module.exports = { }, historyApiFallback: true, }, + devtool: 'eval-source-map', }; diff --git a/yarn.lock b/yarn.lock index f60c3011..28bf49fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3131,6 +3131,11 @@ dependencies: "@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/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.0": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"