This commit is contained in:
Nathan Bierema 2020-10-23 11:15:48 -04:00
parent 2cbdf7b13e
commit 8486fe058f
18 changed files with 232 additions and 103 deletions

View File

@ -19,6 +19,7 @@ import {
UPDATE_STATE, UPDATE_STATE,
UPDATE_REPORTS, UPDATE_REPORTS,
REMOVE_INSTANCE, REMOVE_INSTANCE,
SET_STATE,
} from '../constants/actionTypes'; } from '../constants/actionTypes';
import { import {
AUTH_ERROR, AUTH_ERROR,
@ -37,6 +38,9 @@ import {
UNSUBSCRIBE, UNSUBSCRIBE,
} from '../constants/socketActionTypes'; } from '../constants/socketActionTypes';
import { Action } from 'redux'; import { Action } from 'redux';
import { Features, State } from '../reducers/instances';
import { MonitorStateMonitorState } from '../reducers/monitor';
import { LiftedAction } from 'redux-devtools-instrument';
let monitorReducer: ( let monitorReducer: (
monitorProps: unknown, monitorProps: unknown,
@ -91,10 +95,33 @@ export interface MonitorActionAction {
) => unknown; ) => unknown;
monitorProps: unknown; monitorProps: unknown;
} }
interface LiftedActionDispatchAction { interface JumpToStateAction {
type: 'JUMP_TO_STATE';
index: number;
actionId: number;
}
interface JumpToActionAction {
type: 'JUMP_TO_ACTION';
index: number;
actionId: number;
}
interface PauseRecordingAction {
type: 'PAUSE_RECORDING';
status: boolean;
}
interface LockChangesAction {
type: 'LOCK_CHANGES';
status: boolean;
}
export interface LiftedActionDispatchAction {
type: typeof LIFTED_ACTION; type: typeof LIFTED_ACTION;
message: 'DISPATCH'; message: 'DISPATCH';
action: Action<unknown>; action:
| JumpToStateAction
| JumpToActionAction
| PauseRecordingAction
| LockChangesAction;
toAll?: boolean;
} }
interface LiftedActionImportAction { interface LiftedActionImportAction {
type: typeof LIFTED_ACTION; type: typeof LIFTED_ACTION;
@ -102,18 +129,39 @@ interface LiftedActionImportAction {
state: string; state: string;
preloadedState: unknown | undefined; preloadedState: unknown | undefined;
} }
export type LiftedActionAction = LiftedActionDispatchAction; interface LiftedActionActionAction {
type: typeof LIFTED_ACTION;
message: 'ACTION';
action: Action<unknown>;
}
export type LiftedActionAction =
| LiftedActionDispatchAction
| LiftedActionImportAction
| LiftedActionActionAction;
export function liftedDispatch( export function liftedDispatch(
action: InitMonitorAction action:
| InitMonitorAction
| JumpToStateAction
| JumpToActionAction
| LiftedAction<unknown, Action<unknown>, unknown>
): MonitorActionAction | LiftedActionDispatchAction { ): MonitorActionAction | LiftedActionDispatchAction {
if (action.type[0] === '@') { if (action.type[0] === '@') {
if (action.type === '@@INIT_MONITOR') { if (action.type === '@@INIT_MONITOR') {
monitorReducer = action.update; monitorReducer = action.update;
monitorProps = action.monitorProps; monitorProps = action.monitorProps;
} }
return { type: MONITOR_ACTION, action, monitorReducer, monitorProps }; return {
type: MONITOR_ACTION,
action,
monitorReducer,
monitorProps,
} as MonitorActionAction;
} }
return { type: LIFTED_ACTION, message: 'DISPATCH', action }; return {
type: LIFTED_ACTION,
message: 'DISPATCH',
action,
} as LiftedActionDispatchAction;
} }
interface SelectInstanceAction { interface SelectInstanceAction {
@ -127,20 +175,21 @@ export function selectInstance(selected: string): SelectInstanceAction {
interface SelectMonitorAction { interface SelectMonitorAction {
type: typeof SELECT_MONITOR; type: typeof SELECT_MONITOR;
monitor: string; monitor: string;
monitorState?: unknown; monitorState?: MonitorStateMonitorState;
} }
export function selectMonitor(monitor: string): SelectMonitorAction { export function selectMonitor(monitor: string): SelectMonitorAction {
return { type: SELECT_MONITOR, monitor }; return { type: SELECT_MONITOR, monitor };
} }
export function selectMonitorWithState( export function selectMonitorWithState(
value: string, value: string,
monitorState: unknown monitorState: MonitorStateMonitorState
): SelectMonitorAction { ): SelectMonitorAction {
return { type: SELECT_MONITOR, monitor: value, monitorState }; return { type: SELECT_MONITOR, monitor: value, monitorState };
} }
interface NextState { interface NextState {
subTabName: string; subTabName: string;
inspectedStatePath?: string[];
} }
interface UpdateMonitorStateAction { interface UpdateMonitorStateAction {
type: typeof UPDATE_MONITOR_STATE; type: typeof UPDATE_MONITOR_STATE;
@ -150,7 +199,9 @@ export function selectMonitorTab(subTabName: string): UpdateMonitorStateAction {
return { type: UPDATE_MONITOR_STATE, nextState: { subTabName } }; return { type: UPDATE_MONITOR_STATE, nextState: { subTabName } };
} }
export function updateMonitorState(nextState) { export function updateMonitorState(
nextState: NextState
): UpdateMonitorStateAction {
return { type: UPDATE_MONITOR_STATE, nextState }; return { type: UPDATE_MONITOR_STATE, nextState };
} }
@ -168,7 +219,7 @@ export function exportState(): ExportAction {
return { type: EXPORT }; return { type: EXPORT };
} }
export function lockChanges(status) { export function lockChanges(status: boolean): LiftedActionDispatchAction {
return { return {
type: LIFTED_ACTION, type: LIFTED_ACTION,
message: 'DISPATCH', message: 'DISPATCH',
@ -177,7 +228,7 @@ export function lockChanges(status) {
}; };
} }
export function pauseRecording(status) { export function pauseRecording(status: boolean): LiftedActionDispatchAction {
return { return {
type: LIFTED_ACTION, type: LIFTED_ACTION,
message: 'DISPATCH', message: 'DISPATCH',
@ -186,7 +237,9 @@ export function pauseRecording(status) {
}; };
} }
export function dispatchRemotely(action) { export function dispatchRemotely(
action: Action<unknown>
): LiftedActionActionAction {
return { type: LIFTED_ACTION, message: 'ACTION', action }; return { type: LIFTED_ACTION, message: 'ACTION', action };
} }
@ -254,12 +307,67 @@ export function clearNotification(): ClearNotificationAction {
return { type: CLEAR_NOTIFICATION }; return { type: CLEAR_NOTIFICATION };
} }
export function getReport(report) { interface GetReportRequest {
readonly type: typeof GET_REPORT_REQUEST;
readonly report: unknown;
}
export function getReport(report: unknown): GetReportRequest {
return { type: GET_REPORT_REQUEST, report }; return { type: GET_REPORT_REQUEST, report };
} }
interface LibConfig {
actionCreators?: string;
name?: string;
type?: string;
features?: Features;
serialize?: boolean;
}
export interface RequestBase {
id: string;
instanceId?: string;
action?: string;
name?: string;
libConfig?: LibConfig;
actionsById?: string;
computedStates?: string;
// eslint-disable-next-line @typescript-eslint/ban-types
payload?: {} | string;
}
interface InitRequest extends RequestBase {
type: 'INIT';
action: string;
}
interface ActionRequest extends RequestBase {
type: 'ACTION';
}
interface StateRequest extends RequestBase {
type: 'STATE';
committedState: unknown;
}
interface PartialStateRequest extends RequestBase {
type: 'PARTIAL_STATE';
committedState: unknown;
}
interface LiftedRequest extends RequestBase {
type: 'LIFTED';
}
export type Request =
| InitRequest
| ActionRequest
| StateRequest
| PartialStateRequest
| LiftedRequest;
interface UpdateStateAction { interface UpdateStateAction {
type: typeof UPDATE_STATE; type: typeof UPDATE_STATE;
request?: Request;
id?: string;
}
interface SetStateAction {
type: typeof SET_STATE;
newState: State;
} }
interface RemoveInstanceAction { interface RemoveInstanceAction {
@ -355,6 +463,8 @@ export type StoreAction =
| ReconnectAction | ReconnectAction
| ShowNotificationAction | ShowNotificationAction
| ClearNotificationAction | ClearNotificationAction
| GetReportRequest
| SetStateAction
| UpdateStateAction | UpdateStateAction
| RemoveInstanceAction | RemoveInstanceAction
| ConnectRequestAction | ConnectRequestAction

View File

@ -8,10 +8,12 @@ import PrintButton from './buttons/PrintButton';
import DispatcherButton from './buttons/DispatcherButton'; import DispatcherButton from './buttons/DispatcherButton';
import SliderButton from './buttons/SliderButton'; import SliderButton from './buttons/SliderButton';
import MonitorSelector from './MonitorSelector'; import MonitorSelector from './MonitorSelector';
import { Options } from '../reducers/instances';
interface Props { interface Props {
dispatcherIsOpen: boolean; dispatcherIsOpen: boolean;
sliderIsOpen: boolean; sliderIsOpen: boolean;
options: Options;
} }
export default class BottomButtons extends Component<Props> { export default class BottomButtons extends Component<Props> {

View File

@ -2,18 +2,21 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { ActionCreators, LiftedAction } from 'redux-devtools-instrument'; import { ActionCreators, LiftedAction } from 'redux-devtools-instrument';
import { Button, Toolbar, Divider } from 'devui'; import { Button, Toolbar, Divider } from 'devui';
import { Action } from 'redux';
import RecordButton from './buttons/RecordButton'; import RecordButton from './buttons/RecordButton';
import PersistButton from './buttons/PersistButton'; import PersistButton from './buttons/PersistButton';
import LockButton from './buttons/LockButton'; import LockButton from './buttons/LockButton';
import InstanceSelector from './InstanceSelector'; import InstanceSelector from './InstanceSelector';
import SyncButton from './buttons/SyncButton'; import SyncButton from './buttons/SyncButton';
import { Action } from 'redux'; import { Options, State } from '../reducers/instances';
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
const { reset, rollback, commit, sweep } = ActionCreators; const { reset, rollback, commit, sweep } = ActionCreators;
interface Props { interface Props {
dispatch: (action: LiftedAction<unknown, Action<unknown>, unknown>) => void; dispatch: (action: LiftedAction<unknown, Action<unknown>, unknown>) => void;
liftedState: State;
options: Options;
} }
export default class TopButtons extends Component<Props> { export default class TopButtons extends Component<Props> {

View File

@ -1,19 +1,19 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Button } from 'devui'; import { Button } from 'devui';
import { IoIosLock } from 'react-icons/io'; import { IoIosLock } from 'react-icons/io';
import { lockChanges, StoreAction } from '../../actions'; import { lockChanges, StoreAction } from '../../actions';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
class LockButton extends Component { type DispatchProps = ReturnType<typeof mapDispatchToProps>;
static propTypes = { interface OwnProps {
locked: PropTypes.bool, locked: boolean | undefined;
disabled: PropTypes.bool, disabled: boolean;
lockChanges: PropTypes.func.isRequired, }
}; type Props = DispatchProps & OwnProps;
shouldComponentUpdate(nextProps) { class LockButton extends Component<Props> {
shouldComponentUpdate(nextProps: Props) {
return nextProps.locked !== this.props.locked; return nextProps.locked !== this.props.locked;
} }

View File

@ -8,15 +8,12 @@ import { StoreState } from '../../reducers';
type StateProps = ReturnType<typeof mapStateToProps>; type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = ResolveThunks<typeof actionCreators>; type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = StateProps & DispatchProps; interface OwnProps {
disabled?: boolean;
}
type Props = StateProps & DispatchProps & OwnProps;
class LockButton extends Component<Props> { class LockButton extends Component<Props> {
static propTypes = {
persisted: PropTypes.bool,
disabled: PropTypes.bool,
onClick: PropTypes.func.isRequired,
};
shouldComponentUpdate(nextProps: Props) { shouldComponentUpdate(nextProps: Props) {
return nextProps.persisted !== this.props.persisted; return nextProps.persisted !== this.props.persisted;
} }

View File

@ -1,17 +1,18 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Button } from 'devui'; import { Button } from 'devui';
import { MdFiberManualRecord } from 'react-icons/md'; import { MdFiberManualRecord } from 'react-icons/md';
import { pauseRecording } from '../../actions'; import { pauseRecording, StoreAction } from '../../actions';
import { Dispatch } from 'redux';
class RecordButton extends Component { type DispatchProps = ReturnType<typeof mapDispatchToProps>;
static propTypes = { interface OwnProps {
paused: PropTypes.bool, paused: boolean | undefined;
pauseRecording: PropTypes.func.isRequired, }
}; type Props = DispatchProps & OwnProps;
shouldComponentUpdate(nextProps) { class RecordButton extends Component<Props> {
shouldComponentUpdate(nextProps: Props) {
return nextProps.paused !== this.props.paused; return nextProps.paused !== this.props.paused;
} }
@ -29,7 +30,10 @@ class RecordButton extends Component {
} }
} }
function mapDispatchToProps(dispatch, ownProps) { function mapDispatchToProps(
dispatch: Dispatch<StoreAction>,
ownProps: OwnProps
) {
return { return {
pauseRecording: () => dispatch(pauseRecording(!ownProps.paused)), pauseRecording: () => dispatch(pauseRecording(!ownProps.paused)),
}; };

View File

@ -1,5 +1,4 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect, ResolveThunks } from 'react-redux'; import { connect, ResolveThunks } from 'react-redux';
import { Button } from 'devui'; import { Button } from 'devui';
import { TiArrowSync } from 'react-icons/ti'; import { TiArrowSync } from 'react-icons/ti';
@ -11,11 +10,6 @@ type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = StateProps & DispatchProps; type Props = StateProps & DispatchProps;
class SyncButton extends Component<Props> { class SyncButton extends Component<Props> {
static propTypes = {
sync: PropTypes.bool,
onClick: PropTypes.func.isRequired,
};
shouldComponentUpdate(nextProps: Props) { shouldComponentUpdate(nextProps: Props) {
return nextProps.sync !== this.props.sync; return nextProps.sync !== this.props.sync;
} }

View File

@ -1,17 +1,23 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withTheme } from 'styled-components'; import { withTheme } from 'styled-components';
import { LiftedAction, LiftedState } from 'redux-devtools-instrument'; import { LiftedAction, LiftedState } from 'redux-devtools-instrument';
import { Action } from 'redux'; import { Action } from 'redux';
import { Monitor } from 'redux-devtools'; import { Monitor } from 'redux-devtools';
import getMonitor from '../utils/getMonitor'; import getMonitor from '../utils/getMonitor';
import { InitMonitorAction } from '../actions'; import { InitMonitorAction } from '../actions';
import { Features, State } from '../reducers/instances';
import { MonitorStateMonitorState } from '../reducers/monitor';
import { ThemeFromProvider } from 'devui';
interface Props { interface Props {
monitor: string; monitor: string;
liftedState: State;
monitorState: MonitorStateMonitorState | undefined;
dispatch: ( dispatch: (
action: LiftedAction<unknown, Action<unknown>, unknown> | InitMonitorAction action: LiftedAction<unknown, Action<unknown>, unknown> | InitMonitorAction
) => void; ) => void;
features: Features | undefined;
theme: ThemeFromProvider;
} }
class DevTools extends Component<Props> { class DevTools extends Component<Props> {
@ -30,7 +36,7 @@ class DevTools extends Component<Props> {
this.getMonitor(props, props.monitorState); this.getMonitor(props, props.monitorState);
} }
getMonitor(props: Props, skipUpdate: unknown) { getMonitor(props: Props, skipUpdate?: unknown) {
const monitorElement = getMonitor(props); const monitorElement = getMonitor(props);
this.monitorProps = monitorElement.props; this.monitorProps = monitorElement.props;
this.Monitor = monitorElement.type; this.Monitor = monitorElement.type;
@ -59,15 +65,15 @@ class DevTools extends Component<Props> {
} }
} }
UNSAFE_componentWillUpdate(nextProps) { UNSAFE_componentWillUpdate(nextProps: Props) {
if (nextProps.monitor !== this.props.monitor) this.getMonitor(nextProps); if (nextProps.monitor !== this.props.monitor) this.getMonitor(nextProps);
} }
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps: Props) {
return ( return (
nextProps.monitor !== this.props.monitor || nextProps.monitor !== this.props.monitor ||
nextProps.liftedState !== this.props.liftedState || nextProps.liftedState !== this.props.liftedState ||
nextProps.monitorState !== this.props.liftedState || nextProps.monitorState !== this.props.monitorState ||
nextProps.features !== this.props.features || nextProps.features !== this.props.features ||
nextProps.theme.scheme !== this.props.theme.scheme nextProps.theme.scheme !== this.props.theme.scheme
); );
@ -103,13 +109,4 @@ class DevTools extends Component<Props> {
} }
} }
DevTools.propTypes = {
liftedState: PropTypes.object,
monitorState: PropTypes.object,
dispatch: PropTypes.func.isRequired,
monitor: PropTypes.string,
features: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
};
export default withTheme(DevTools); export default withTheme(DevTools);

View File

@ -9,7 +9,7 @@ export function getPath(obj: NodeWithId, inspectedStatePath: string[]) {
if (!parent) return; if (!parent) return;
getPath(parent, inspectedStatePath); getPath(parent, inspectedStatePath);
let name = obj.name; let name = obj.name;
const item = name.match(/.+\[(\d+)]/); const item = /.+\[(\d+)]/.exec(name);
if (item) name = item[1]; if (item) name = item[1];
inspectedStatePath.push(name); inspectedStatePath.push(name);
} }

View File

@ -1,11 +1,11 @@
// Based on https://github.com/YoruNoHikage/redux-devtools-dispatch // Based on https://github.com/YoruNoHikage/redux-devtools-dispatch
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components'; import styled from 'styled-components';
import { Button, Select, Editor, Toolbar } from 'devui'; import { Button, Select, Editor, Toolbar } from 'devui';
import { connect, ResolveThunks } from 'react-redux'; import { connect, ResolveThunks } from 'react-redux';
import { dispatchRemotely } from '../../actions'; import { dispatchRemotely } from '../../actions';
import { Options } from '../../reducers/instances';
export const DispatcherContainer = styled.div` export const DispatcherContainer = styled.div`
display: flex; display: flex;
@ -47,14 +47,20 @@ export const ActionContainer = styled.div`
`; `;
type DispatchProps = ResolveThunks<typeof actionCreators>; type DispatchProps = ResolveThunks<typeof actionCreators>;
type Props = DispatchProps; interface OwnProps {
options: Options;
}
type Props = DispatchProps & OwnProps;
class Dispatcher extends Component<Props> { interface State {
static propTypes = { selected: string;
options: PropTypes.object.isRequired, customAction: string;
dispatch: PropTypes.func.isRequired, args: unknown[];
}; rest: string;
changed: boolean;
}
class Dispatcher extends Component<Props, State> {
state = { state = {
selected: 'default', selected: 'default',
customAction: customAction:
@ -64,7 +70,7 @@ class Dispatcher extends Component<Props> {
changed: false, changed: false,
}; };
UNSAFE_componentWillReceiveProps(nextProps) { UNSAFE_componentWillReceiveProps(nextProps: Props) {
if ( if (
this.state.selected !== 'default' && this.state.selected !== 'default' &&
!nextProps.options.actionCreators !nextProps.options.actionCreators
@ -76,7 +82,7 @@ class Dispatcher extends Component<Props> {
} }
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps: Props, nextState: State) {
return ( return (
nextState !== this.state || nextState !== this.state ||
nextProps.options.actionCreators !== this.props.options.actionCreators nextProps.options.actionCreators !== this.props.options.actionCreators
@ -94,7 +100,7 @@ class Dispatcher extends Component<Props> {
const args = []; const args = [];
if (selected !== 'default') { if (selected !== 'default') {
args.length = this.props.options.actionCreators[selected].args.length; args.length = this.props.options.actionCreators![selected].args.length;
} }
this.setState({ selected, args, rest: '[]', changed: false }); this.setState({ selected, args, rest: '[]', changed: false });
}; };

View File

@ -1,5 +1,4 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect, ResolveThunks } from 'react-redux'; import { connect, ResolveThunks } from 'react-redux';
import { Tab, Tabs } from 'devui'; import { Tab, Tabs } from 'devui';
import { TabComponentProps } from 'redux-devtools-inspector-monitor'; import { TabComponentProps } from 'redux-devtools-inspector-monitor';
@ -97,18 +96,9 @@ class SubTabs extends Component<Props> {
} }
} }
SubTabs.propTypes = {
selected: PropTypes.string,
parentTab: PropTypes.string,
selectMonitorTab: PropTypes.func.isRequired,
action: PropTypes.object,
delta: PropTypes.object,
nextState: PropTypes.object,
};
const mapStateToProps = (state: StoreState) => ({ const mapStateToProps = (state: StoreState) => ({
parentTab: state.monitor.monitorState.tabName, parentTab: state.monitor.monitorState!.tabName,
selected: state.monitor.monitorState.subTabName, selected: state.monitor.monitorState!.subTabName,
}); });
const actionCreators = { const actionCreators = {

View File

@ -8,7 +8,7 @@ function download(state) {
const blob = new Blob([state], { type: 'octet/stream' }); const blob = new Blob([state], { type: 'octet/stream' });
const href = window.URL.createObjectURL(blob); const href = window.URL.createObjectURL(blob);
const a = document.createElement('a'); const a = document.createElement('a');
a.style = 'display: none'; a.style.display = 'none';
a.download = 'state.json'; a.download = 'state.json';
a.href = href; a.href = href;
document.body.appendChild(a); document.body.appendChild(a);

View File

@ -12,12 +12,12 @@ import {
import { DISCONNECTED } from '../constants/socketActionTypes'; import { DISCONNECTED } from '../constants/socketActionTypes';
import parseJSON from '../utils/parseJSON'; import parseJSON from '../utils/parseJSON';
import { recompute } from '../utils/updateState'; import { recompute } from '../utils/updateState';
import { LiftedActionAction, StoreAction } from '../actions'; import { LiftedActionDispatchAction, Request, StoreAction } from '../actions';
interface Features { export interface Features {
lock?: boolean; lock?: boolean;
export?: boolean; export?: string | boolean;
import?: string; import?: string | boolean;
persist?: boolean; persist?: boolean;
pause?: boolean; pause?: boolean;
reorder?: boolean; reorder?: boolean;
@ -28,7 +28,7 @@ interface Features {
test?: boolean; test?: boolean;
} }
interface Options { export interface Options {
name?: string; name?: string;
connectionId?: string; connectionId?: string;
explicitLib?: string; explicitLib?: string;
@ -38,13 +38,16 @@ interface Options {
serialize?: boolean; serialize?: boolean;
} }
interface State { export interface State {
actionsById: { [actionId: number]: PerformAction<Action<unknown>> }; actionsById: { [actionId: number]: PerformAction<Action<unknown>> };
computedStates: { state: unknown; error?: string }[]; computedStates: { state: unknown; error?: string }[];
currentStateIndex: number; currentStateIndex: number;
nextActionId: number; nextActionId: number;
skippedActionIds: number[]; skippedActionIds: number[];
stagedActionIds: number[]; stagedActionIds: number[];
committedState?: unknown;
isLocked?: boolean;
isPaused?: boolean;
} }
export interface InstancesState { export interface InstancesState {
@ -77,7 +80,7 @@ export const initialState: InstancesState = {
function updateState( function updateState(
state: { [id: string]: State }, state: { [id: string]: State },
request, request: Request,
id: string, id: string,
serialize: boolean | undefined serialize: boolean | undefined
) { ) {
@ -201,7 +204,7 @@ function updateState(
export function dispatchAction( export function dispatchAction(
state: InstancesState, state: InstancesState,
{ action }: LiftedActionAction { action }: LiftedActionDispatchAction
) { ) {
if (action.type === 'JUMP_TO_STATE' || action.type === 'JUMP_TO_ACTION') { if (action.type === 'JUMP_TO_STATE' || action.type === 'JUMP_TO_ACTION') {
const id = state.selected || state.current; const id = state.selected || state.current;
@ -256,7 +259,11 @@ function removeState(state: InstancesState, connectionId: string) {
}; };
} }
function init({ type, action, name, libConfig = {} }, connectionId, current) { function init(
{ type, action, name, libConfig = {} }: Request,
connectionId: string,
current: string
): Options {
let lib; let lib;
let actionCreators; let actionCreators;
let creators = libConfig.actionCreators || action; let creators = libConfig.actionCreators || action;

View File

@ -7,14 +7,23 @@ import {
} from '../constants/actionTypes'; } from '../constants/actionTypes';
import { MonitorActionAction, StoreAction } from '../actions'; import { MonitorActionAction, StoreAction } from '../actions';
export interface MonitorStateMonitorState {
inspectedStatePath?: string[];
tabName?: string;
subTabName?: string;
selectedActionId?: number | null;
startActionId?: number | null;
inspectedActionPath?: string[];
__overwritten__?: string;
}
export interface MonitorState { export interface MonitorState {
selected: string; selected: string;
monitorState: unknown | undefined; monitorState: MonitorStateMonitorState | undefined;
sliderIsOpen: boolean; sliderIsOpen: boolean;
dispatcherIsOpen: boolean; dispatcherIsOpen: boolean;
} }
const initialState = { const initialState: MonitorState = {
selected: 'InspectorMonitor', selected: 'InspectorMonitor',
monitorState: undefined, monitorState: undefined,
sliderIsOpen: true, sliderIsOpen: true,
@ -24,7 +33,7 @@ const initialState = {
export function dispatchMonitorAction( export function dispatchMonitorAction(
state: MonitorState, state: MonitorState,
action: MonitorActionAction action: MonitorActionAction
) { ): MonitorState {
return { return {
...state, ...state,
monitorState: monitorState:
@ -37,7 +46,10 @@ export function dispatchMonitorAction(
}; };
} }
export default function monitor(state = initialState, action: StoreAction) { export default function monitor(
state = initialState,
action: StoreAction
): MonitorState {
switch (action.type) { switch (action.type) {
case MONITOR_ACTION: case MONITOR_ACTION:
return dispatchMonitorAction(state, action); return dispatchMonitorAction(state, action);
@ -56,7 +68,7 @@ export default function monitor(state = initialState, action: StoreAction) {
}; };
} }
case UPDATE_MONITOR_STATE: { case UPDATE_MONITOR_STATE: {
let inspectedStatePath = state.monitorState.inspectedStatePath; let inspectedStatePath = state.monitorState!.inspectedStatePath!;
if (action.nextState.inspectedStatePath) { if (action.nextState.inspectedStatePath) {
inspectedStatePath = [ inspectedStatePath = [
...inspectedStatePath.slice(0, -1), ...inspectedStatePath.slice(0, -1),

View File

@ -3,9 +3,11 @@ import {
} from '../constants/actionTypes'; } from '../constants/actionTypes';
import { StoreAction } from '../actions'; import { StoreAction } from '../actions';
export interface ReportsState {} export interface ReportsState {
data: unknown[];
}
const initialState = { const initialState: ReportsState = {
data: [], data: [],
}; };

View File

@ -2,8 +2,9 @@ import difference from 'lodash/difference';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
import stringifyJSON from './stringifyJSON'; import stringifyJSON from './stringifyJSON';
import { SET_STATE } from '../constants/actionTypes'; import { SET_STATE } from '../constants/actionTypes';
import { State } from '../reducers/instances';
export function sweep(state) { export function sweep(state: State): State {
return { return {
...state, ...state,
actionsById: omit(state.actionsById, state.skippedActionIds), actionsById: omit(state.actionsById, state.skippedActionIds),

View File

@ -26,7 +26,10 @@ export function reviver(key, value) {
return value; return value;
} }
export default function parseJSON(data, serialize) { export default function parseJSON(
data: string | undefined,
serialize?: boolean
) {
if (typeof data !== 'string') return data; if (typeof data !== 'string') return data;
try { try {
return serialize ? jsan.parse(data, reviver) : jsan.parse(data); return serialize ? jsan.parse(data, reviver) : jsan.parse(data);

View File

@ -1,12 +1,13 @@
import commitExcessActions from './commitExcessActions'; import commitExcessActions from './commitExcessActions';
import { State } from '../reducers/instances';
export function recompute( export function recompute(
previousLiftedState, previousLiftedState: State,
storeState, storeState,
action, action,
nextActionId = 1, nextActionId = 1,
maxAge, maxAge?: number,
isExcess isExcess?: boolean
) { ) {
const actionId = nextActionId - 1; const actionId = nextActionId - 1;
const liftedState = { ...previousLiftedState }; const liftedState = { ...previousLiftedState };