mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-27 00:19:55 +03:00
stash
This commit is contained in:
parent
6266d6bd5a
commit
2bfeb49b43
|
@ -20,6 +20,9 @@ import {
|
||||||
UPDATE_REPORTS,
|
UPDATE_REPORTS,
|
||||||
REMOVE_INSTANCE,
|
REMOVE_INSTANCE,
|
||||||
SET_STATE,
|
SET_STATE,
|
||||||
|
GET_REPORT_ERROR,
|
||||||
|
GET_REPORT_SUCCESS,
|
||||||
|
ERROR,
|
||||||
} from '../constants/actionTypes';
|
} from '../constants/actionTypes';
|
||||||
import {
|
import {
|
||||||
AUTH_ERROR,
|
AUTH_ERROR,
|
||||||
|
@ -41,6 +44,7 @@ import { Action } from 'redux';
|
||||||
import { Features, State } from '../reducers/instances';
|
import { Features, State } from '../reducers/instances';
|
||||||
import { MonitorStateMonitorState } from '../reducers/monitor';
|
import { MonitorStateMonitorState } from '../reducers/monitor';
|
||||||
import { LiftedAction } from 'redux-devtools-instrument';
|
import { LiftedAction } from 'redux-devtools-instrument';
|
||||||
|
import { Data } from '../reducers/reports';
|
||||||
|
|
||||||
let monitorReducer: (
|
let monitorReducer: (
|
||||||
monitorProps: unknown,
|
monitorProps: unknown,
|
||||||
|
@ -95,49 +99,73 @@ export interface MonitorActionAction {
|
||||||
) => unknown;
|
) => unknown;
|
||||||
monitorProps: unknown;
|
monitorProps: unknown;
|
||||||
}
|
}
|
||||||
interface JumpToStateAction {
|
export interface JumpToStateAction {
|
||||||
type: 'JUMP_TO_STATE';
|
type: 'JUMP_TO_STATE';
|
||||||
index: number;
|
index: number;
|
||||||
actionId: number;
|
actionId: number;
|
||||||
}
|
}
|
||||||
interface JumpToActionAction {
|
export interface JumpToActionAction {
|
||||||
type: 'JUMP_TO_ACTION';
|
type: 'JUMP_TO_ACTION';
|
||||||
index: number;
|
index: number;
|
||||||
actionId: number;
|
actionId: number;
|
||||||
}
|
}
|
||||||
interface PauseRecordingAction {
|
export interface PauseRecordingAction {
|
||||||
type: 'PAUSE_RECORDING';
|
type: 'PAUSE_RECORDING';
|
||||||
status: boolean;
|
status: boolean;
|
||||||
}
|
}
|
||||||
interface LockChangesAction {
|
export interface LockChangesAction {
|
||||||
type: 'LOCK_CHANGES';
|
type: 'LOCK_CHANGES';
|
||||||
status: boolean;
|
status: boolean;
|
||||||
}
|
}
|
||||||
export interface LiftedActionDispatchAction {
|
export interface ToggleActionAction {
|
||||||
type: typeof LIFTED_ACTION;
|
type: 'TOGGLE_ACTION';
|
||||||
message: 'DISPATCH';
|
}
|
||||||
action:
|
export interface RollbackAction {
|
||||||
| JumpToStateAction
|
type: 'ROLLBACK';
|
||||||
| JumpToActionAction
|
}
|
||||||
| PauseRecordingAction
|
export interface SweepAction {
|
||||||
| LockChangesAction;
|
type: 'SWEEP';
|
||||||
|
}
|
||||||
|
export type DispatchAction =
|
||||||
|
| JumpToStateAction
|
||||||
|
| JumpToActionAction
|
||||||
|
| PauseRecordingAction
|
||||||
|
| LockChangesAction
|
||||||
|
| ToggleActionAction
|
||||||
|
| RollbackAction
|
||||||
|
| SweepAction;
|
||||||
|
interface LiftedActionActionBase {
|
||||||
|
action?: DispatchAction | string | CustomAction;
|
||||||
|
state?: string;
|
||||||
toAll?: boolean;
|
toAll?: boolean;
|
||||||
}
|
}
|
||||||
interface LiftedActionImportAction {
|
export interface LiftedActionDispatchAction extends LiftedActionActionBase {
|
||||||
|
type: typeof LIFTED_ACTION;
|
||||||
|
message: 'DISPATCH';
|
||||||
|
action: DispatchAction;
|
||||||
|
toAll?: boolean;
|
||||||
|
}
|
||||||
|
interface LiftedActionImportAction extends LiftedActionActionBase {
|
||||||
type: typeof LIFTED_ACTION;
|
type: typeof LIFTED_ACTION;
|
||||||
message: 'IMPORT';
|
message: 'IMPORT';
|
||||||
state: string;
|
state: string;
|
||||||
preloadedState: unknown | undefined;
|
preloadedState: unknown | undefined;
|
||||||
}
|
}
|
||||||
interface LiftedActionActionAction {
|
interface LiftedActionActionAction extends LiftedActionActionBase {
|
||||||
type: typeof LIFTED_ACTION;
|
type: typeof LIFTED_ACTION;
|
||||||
message: 'ACTION';
|
message: 'ACTION';
|
||||||
action: Action<unknown>;
|
action: string | CustomAction;
|
||||||
|
}
|
||||||
|
interface LiftedActionExportAction extends LiftedActionActionBase {
|
||||||
|
type: typeof LIFTED_ACTION;
|
||||||
|
message: 'EXPORT';
|
||||||
|
toExport: boolean;
|
||||||
}
|
}
|
||||||
export type LiftedActionAction =
|
export type LiftedActionAction =
|
||||||
| LiftedActionDispatchAction
|
| LiftedActionDispatchAction
|
||||||
| LiftedActionImportAction
|
| LiftedActionImportAction
|
||||||
| LiftedActionActionAction;
|
| LiftedActionActionAction
|
||||||
|
| LiftedActionExportAction;
|
||||||
export function liftedDispatch(
|
export function liftedDispatch(
|
||||||
action:
|
action:
|
||||||
| InitMonitorAction
|
| InitMonitorAction
|
||||||
|
@ -237,8 +265,14 @@ export function pauseRecording(status: boolean): LiftedActionDispatchAction {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CustomAction {
|
||||||
|
name: string;
|
||||||
|
selected: number;
|
||||||
|
args: (string | undefined)[];
|
||||||
|
rest: string;
|
||||||
|
}
|
||||||
export function dispatchRemotely(
|
export function dispatchRemotely(
|
||||||
action: Action<unknown>
|
action: string | CustomAction
|
||||||
): LiftedActionActionAction {
|
): LiftedActionActionAction {
|
||||||
return { type: LIFTED_ACTION, message: 'ACTION', action };
|
return { type: LIFTED_ACTION, message: 'ACTION', action };
|
||||||
}
|
}
|
||||||
|
@ -317,6 +351,7 @@ export function getReport(report: unknown): GetReportRequest {
|
||||||
|
|
||||||
export interface ActionCreator {
|
export interface ActionCreator {
|
||||||
args: string[];
|
args: string[];
|
||||||
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LibConfig {
|
interface LibConfig {
|
||||||
|
@ -337,6 +372,7 @@ export interface RequestBase {
|
||||||
computedStates?: string;
|
computedStates?: string;
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
payload?: {} | string;
|
payload?: {} | string;
|
||||||
|
liftedState?: Partial<State>;
|
||||||
}
|
}
|
||||||
interface InitRequest extends RequestBase {
|
interface InitRequest extends RequestBase {
|
||||||
type: 'INIT';
|
type: 'INIT';
|
||||||
|
@ -344,6 +380,10 @@ interface InitRequest extends RequestBase {
|
||||||
}
|
}
|
||||||
interface ActionRequest extends RequestBase {
|
interface ActionRequest extends RequestBase {
|
||||||
type: 'ACTION';
|
type: 'ACTION';
|
||||||
|
isExcess: boolean;
|
||||||
|
nextActionId: number;
|
||||||
|
maxAge: number;
|
||||||
|
batched: boolean;
|
||||||
}
|
}
|
||||||
interface StateRequest extends RequestBase {
|
interface StateRequest extends RequestBase {
|
||||||
type: 'STATE';
|
type: 'STATE';
|
||||||
|
@ -352,16 +392,22 @@ interface StateRequest extends RequestBase {
|
||||||
interface PartialStateRequest extends RequestBase {
|
interface PartialStateRequest extends RequestBase {
|
||||||
type: 'PARTIAL_STATE';
|
type: 'PARTIAL_STATE';
|
||||||
committedState: unknown;
|
committedState: unknown;
|
||||||
|
maxAge: number;
|
||||||
}
|
}
|
||||||
interface LiftedRequest extends RequestBase {
|
interface LiftedRequest extends RequestBase {
|
||||||
type: 'LIFTED';
|
type: 'LIFTED';
|
||||||
}
|
}
|
||||||
|
export interface ExportRequest extends RequestBase {
|
||||||
|
type: 'EXPORT';
|
||||||
|
committedState: unknown;
|
||||||
|
}
|
||||||
export type Request =
|
export type Request =
|
||||||
| InitRequest
|
| InitRequest
|
||||||
| ActionRequest
|
| ActionRequest
|
||||||
| StateRequest
|
| StateRequest
|
||||||
| PartialStateRequest
|
| PartialStateRequest
|
||||||
| LiftedRequest;
|
| LiftedRequest
|
||||||
|
| ExportRequest;
|
||||||
|
|
||||||
interface UpdateStateAction {
|
interface UpdateStateAction {
|
||||||
type: typeof UPDATE_STATE;
|
type: typeof UPDATE_STATE;
|
||||||
|
@ -445,10 +491,47 @@ interface UnsubscribeAction {
|
||||||
channel: string;
|
channel: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EmitAction {
|
export interface EmitAction {
|
||||||
type: typeof EMIT;
|
type: typeof EMIT;
|
||||||
message: string;
|
message: string;
|
||||||
id: string;
|
id?: string | false;
|
||||||
|
instanceId?: string;
|
||||||
|
action?: unknown;
|
||||||
|
state?: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ListRequest {
|
||||||
|
type: 'list';
|
||||||
|
data: Data;
|
||||||
|
}
|
||||||
|
interface AddRequest {
|
||||||
|
type: 'add';
|
||||||
|
data: Data;
|
||||||
|
}
|
||||||
|
interface RemoveRequest {
|
||||||
|
type: 'remove';
|
||||||
|
data: Data;
|
||||||
|
id: unknown;
|
||||||
|
}
|
||||||
|
type UpdateReportsRequest = ListRequest | AddRequest | RemoveRequest;
|
||||||
|
interface UpdateReportsAction {
|
||||||
|
type: typeof UPDATE_REPORTS;
|
||||||
|
request: UpdateReportsRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GetReportError {
|
||||||
|
type: typeof GET_REPORT_ERROR;
|
||||||
|
error: Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GetReportSuccess {
|
||||||
|
type: typeof GET_REPORT_SUCCESS;
|
||||||
|
data: { payload: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ErrorAction {
|
||||||
|
type: typeof ERROR;
|
||||||
|
payload: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type StoreAction =
|
export type StoreAction =
|
||||||
|
@ -483,4 +566,8 @@ export type StoreAction =
|
||||||
| SubscribeSuccessAction
|
| SubscribeSuccessAction
|
||||||
| SubscribeErrorAction
|
| SubscribeErrorAction
|
||||||
| UnsubscribeAction
|
| UnsubscribeAction
|
||||||
| EmitAction;
|
| EmitAction
|
||||||
|
| UpdateReportsAction
|
||||||
|
| GetReportError
|
||||||
|
| GetReportSuccess
|
||||||
|
| ErrorAction;
|
||||||
|
|
|
@ -21,7 +21,8 @@ class Settings extends Component<{}, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Tabs
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
<Tabs<{}>
|
||||||
toRight
|
toRight
|
||||||
tabs={this.tabs}
|
tabs={this.tabs}
|
||||||
selected={this.state.selected}
|
selected={this.state.selected}
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
import socketCluster from 'socketcluster-client';
|
import socketCluster from 'socketcluster-client';
|
||||||
|
|
||||||
|
interface States {
|
||||||
|
CLOSED: 'closed';
|
||||||
|
CONNECTING: 'connecting';
|
||||||
|
OPEN: 'open';
|
||||||
|
AUTHENTICATED: 'authenticated';
|
||||||
|
PENDING: 'pending';
|
||||||
|
UNAUTHENTICATED: 'unauthenticated';
|
||||||
|
}
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
CLOSED,
|
CLOSED,
|
||||||
CONNECTING,
|
CONNECTING,
|
||||||
|
@ -7,7 +16,7 @@ export const {
|
||||||
AUTHENTICATED,
|
AUTHENTICATED,
|
||||||
PENDING,
|
PENDING,
|
||||||
UNAUTHENTICATED,
|
UNAUTHENTICATED,
|
||||||
} = socketCluster.SCClientSocket;
|
} = (socketCluster.SCClientSocket as unknown) as States;
|
||||||
export const CONNECT_REQUEST = 'socket/CONNECT_REQUEST';
|
export const CONNECT_REQUEST = 'socket/CONNECT_REQUEST';
|
||||||
export const CONNECT_SUCCESS = 'socket/CONNECT_SUCCESS';
|
export const CONNECT_SUCCESS = 'socket/CONNECT_SUCCESS';
|
||||||
export const CONNECT_ERROR = 'socket/CONNECT_ERROR';
|
export const CONNECT_ERROR = 'socket/CONNECT_ERROR';
|
||||||
|
|
|
@ -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 { Container } from 'devui';
|
import { Container } from 'devui';
|
||||||
import SliderMonitor from './monitors/Slider';
|
import SliderMonitor from './monitors/Slider';
|
||||||
|
@ -55,16 +54,6 @@ class Actions extends Component<Props> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Actions.propTypes = {
|
|
||||||
liftedDispatch: PropTypes.func.isRequired,
|
|
||||||
liftedState: PropTypes.object.isRequired,
|
|
||||||
monitorState: PropTypes.object,
|
|
||||||
options: PropTypes.object.isRequired,
|
|
||||||
monitor: PropTypes.string,
|
|
||||||
dispatcherIsOpen: PropTypes.bool,
|
|
||||||
sliderIsOpen: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => {
|
const mapStateToProps = (state: StoreState) => {
|
||||||
const instances = state.instances;
|
const instances = state.instances;
|
||||||
const id = getActiveInstance(instances);
|
const id = getActiveInstance(instances);
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React, { Component } from 'react';
|
||||||
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 getMonitor from '../utils/getMonitor';
|
import getMonitor from '../utils/getMonitor';
|
||||||
import { InitMonitorAction } from '../actions';
|
import { InitMonitorAction } from '../actions';
|
||||||
import { Features, State } from '../reducers/instances';
|
import { Features, State } from '../reducers/instances';
|
||||||
|
@ -22,13 +21,15 @@ interface Props {
|
||||||
|
|
||||||
class DevTools extends Component<Props> {
|
class DevTools extends Component<Props> {
|
||||||
monitorProps: unknown;
|
monitorProps: unknown;
|
||||||
Monitor?: Monitor<
|
Monitor?: React.ComponentType<
|
||||||
unknown,
|
LiftedState<unknown, Action<unknown>, unknown>
|
||||||
Action<unknown>,
|
> & {
|
||||||
LiftedState<unknown, Action<unknown>, unknown>,
|
update(
|
||||||
unknown,
|
monitorProps: unknown,
|
||||||
Action<unknown>
|
state: unknown | undefined,
|
||||||
>;
|
action: Action<unknown>
|
||||||
|
): unknown;
|
||||||
|
};
|
||||||
preventRender?: boolean;
|
preventRender?: boolean;
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
|
@ -41,6 +42,7 @@ class DevTools extends Component<Props> {
|
||||||
this.monitorProps = monitorElement.props;
|
this.monitorProps = monitorElement.props;
|
||||||
this.Monitor = monitorElement.type;
|
this.Monitor = monitorElement.type;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||||
const update = this.Monitor!.update;
|
const update = this.Monitor!.update;
|
||||||
if (update) {
|
if (update) {
|
||||||
let newMonitorState;
|
let newMonitorState;
|
||||||
|
@ -51,7 +53,11 @@ class DevTools extends Component<Props> {
|
||||||
) {
|
) {
|
||||||
newMonitorState = monitorState;
|
newMonitorState = monitorState;
|
||||||
} else {
|
} else {
|
||||||
newMonitorState = update(this.monitorProps, undefined, {});
|
newMonitorState = update(
|
||||||
|
this.monitorProps,
|
||||||
|
undefined,
|
||||||
|
{} as Action<unknown>
|
||||||
|
);
|
||||||
if (newMonitorState !== monitorState) {
|
if (newMonitorState !== monitorState) {
|
||||||
this.preventRender = true;
|
this.preventRender = true;
|
||||||
}
|
}
|
||||||
|
@ -95,9 +101,10 @@ class DevTools extends Component<Props> {
|
||||||
...this.props.liftedState,
|
...this.props.liftedState,
|
||||||
monitorState: this.props.monitorState,
|
monitorState: this.props.monitorState,
|
||||||
};
|
};
|
||||||
|
const MonitorAsAny = this.Monitor as any;
|
||||||
return (
|
return (
|
||||||
<div className={`monitor monitor-${this.props.monitor}`}>
|
<div className={`monitor monitor-${this.props.monitor}`}>
|
||||||
<this.Monitor
|
<MonitorAsAny
|
||||||
{...liftedState}
|
{...liftedState}
|
||||||
{...this.monitorProps}
|
{...this.monitorProps}
|
||||||
features={this.props.features}
|
features={this.props.features}
|
||||||
|
|
|
@ -35,6 +35,8 @@ class ChartMonitorWrapper extends Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
<ChartMonitor
|
<ChartMonitor
|
||||||
defaultIsVisible
|
defaultIsVisible
|
||||||
invertTheme
|
invertTheme
|
||||||
|
|
|
@ -53,15 +53,15 @@ interface OwnProps {
|
||||||
type Props = DispatchProps & OwnProps;
|
type Props = DispatchProps & OwnProps;
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
selected: string;
|
selected: 'default' | number;
|
||||||
customAction: string;
|
customAction: string;
|
||||||
args: unknown[];
|
args: (string | undefined)[];
|
||||||
rest: string;
|
rest: string;
|
||||||
changed: boolean;
|
changed: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Dispatcher extends Component<Props, State> {
|
class Dispatcher extends Component<Props, State> {
|
||||||
state = {
|
state: State = {
|
||||||
selected: 'default',
|
selected: 'default',
|
||||||
customAction:
|
customAction:
|
||||||
this.props.options.lib === 'redux' ? "{\n type: ''\n}" : 'this.',
|
this.props.options.lib === 'redux' ? "{\n type: ''\n}" : 'this.',
|
||||||
|
@ -89,7 +89,7 @@ class Dispatcher extends Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
selectActionCreator = (selected) => {
|
selectActionCreator = (selected: 'default' | 'actions-help' | number) => {
|
||||||
if (selected === 'actions-help') {
|
if (selected === 'actions-help') {
|
||||||
window.open(
|
window.open(
|
||||||
'https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/' +
|
'https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/' +
|
||||||
|
@ -98,14 +98,14 @@ class Dispatcher extends Component<Props, State> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = [];
|
const args: string[] = [];
|
||||||
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 });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleArg = (argIndex) => (value) => {
|
handleArg = (argIndex: number) => (value: string) => {
|
||||||
const args = [
|
const args = [
|
||||||
...this.state.args.slice(0, argIndex),
|
...this.state.args.slice(0, argIndex),
|
||||||
value || undefined,
|
value || undefined,
|
||||||
|
@ -114,26 +114,26 @@ class Dispatcher extends Component<Props, State> {
|
||||||
this.setState({ args, changed: true });
|
this.setState({ args, changed: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleRest = (rest) => {
|
handleRest = (rest: string) => {
|
||||||
this.setState({ rest, changed: true });
|
this.setState({ rest, changed: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
handleCustomAction = (customAction) => {
|
handleCustomAction = (customAction: string) => {
|
||||||
this.setState({ customAction, changed: true });
|
this.setState({ customAction, changed: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
dispatchAction = () => {
|
dispatchAction = () => {
|
||||||
const { selected, customAction, args, rest } = this.state;
|
const { selected, customAction, args, rest } = this.state;
|
||||||
|
|
||||||
if (this.state.selected !== 'default') {
|
if (selected !== 'default') {
|
||||||
// remove trailing `undefined` arguments
|
// remove trailing `undefined` arguments
|
||||||
let i = args.length - 1;
|
let i = args.length - 1;
|
||||||
while (i >= 0 && typeof args[i] === 'undefined') {
|
while (i >= 0 && typeof args[i] === 'undefined') {
|
||||||
args.pop(i);
|
args.pop();
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
this.props.dispatch({
|
this.props.dispatch({
|
||||||
name: this.props.options.actionCreators[selected].name,
|
name: this.props.options.actionCreators![selected].name,
|
||||||
selected,
|
selected,
|
||||||
args,
|
args,
|
||||||
rest,
|
rest,
|
||||||
|
@ -182,7 +182,9 @@ class Dispatcher extends Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let options = [{ value: 'default', label: 'Custom action' }];
|
let options: { value: string | number; label: string }[] = [
|
||||||
|
{ value: 'default', label: 'Custom action' },
|
||||||
|
];
|
||||||
if (actionCreators && actionCreators.length > 0) {
|
if (actionCreators && actionCreators.length > 0) {
|
||||||
options = options.concat(
|
options = options.concat(
|
||||||
actionCreators.map(({ name, args }, i) => ({
|
actionCreators.map(({ name, args }, i) => ({
|
||||||
|
|
|
@ -72,20 +72,20 @@ class ChartTab extends Component<Props> {
|
||||||
style: {
|
style: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
node: {
|
node: ({
|
||||||
colors: {
|
colors: {
|
||||||
default: theme.base0B,
|
default: theme.base0B,
|
||||||
collapsed: theme.base0B,
|
collapsed: theme.base0B,
|
||||||
parent: theme.base0E,
|
parent: theme.base0E,
|
||||||
},
|
},
|
||||||
radius: 7,
|
radius: 7,
|
||||||
},
|
} as unknown) as string,
|
||||||
text: {
|
text: ({
|
||||||
colors: {
|
colors: {
|
||||||
default: theme.base0D,
|
default: theme.base0D,
|
||||||
hover: theme.base06,
|
hover: theme.base06,
|
||||||
},
|
},
|
||||||
},
|
} as unknown) as string,
|
||||||
},
|
},
|
||||||
onClickText: this.onClickText,
|
onClickText: this.onClickText,
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@ import RawTab from './RawTab';
|
||||||
import ChartTab from './ChartTab';
|
import ChartTab from './ChartTab';
|
||||||
import VisualDiffTab from './VisualDiffTab';
|
import VisualDiffTab from './VisualDiffTab';
|
||||||
import { StoreState } from '../../../reducers';
|
import { StoreState } from '../../../reducers';
|
||||||
|
import { Delta } from 'jsondiffpatch';
|
||||||
|
|
||||||
type StateProps = ReturnType<typeof mapStateToProps>;
|
type StateProps = ReturnType<typeof mapStateToProps>;
|
||||||
type DispatchProps = ResolveThunks<typeof actionCreators>;
|
type DispatchProps = ResolveThunks<typeof actionCreators>;
|
||||||
|
@ -19,7 +20,7 @@ type Props = StateProps &
|
||||||
TabComponentProps<unknown, Action<unknown>>;
|
TabComponentProps<unknown, Action<unknown>>;
|
||||||
|
|
||||||
class SubTabs extends Component<Props> {
|
class SubTabs extends Component<Props> {
|
||||||
tabs?: Tab<unknown>[];
|
tabs?: (Tab<Props> | Tab<{ data: unknown }> | Tab<{ data?: Delta }>)[];
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -56,7 +57,7 @@ class SubTabs extends Component<Props> {
|
||||||
{
|
{
|
||||||
name: 'Raw',
|
name: 'Raw',
|
||||||
component: VisualDiffTab,
|
component: VisualDiffTab,
|
||||||
selector: this.selector,
|
selector: this.selector as () => { data?: Delta },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
return;
|
return;
|
||||||
|
@ -88,7 +89,7 @@ class SubTabs extends Component<Props> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
tabs={this.tabs!}
|
tabs={this.tabs! as any}
|
||||||
selected={selected || 'Tree'}
|
selected={selected || 'Tree'}
|
||||||
onClick={this.props.selectMonitorTab}
|
onClick={this.props.selectMonitorTab}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import styled, { withTheme } from 'styled-components';
|
import styled, { withTheme } from 'styled-components';
|
||||||
import SliderMonitor from 'redux-devtools-slider-monitor';
|
import SliderMonitor from 'redux-devtools-slider-monitor';
|
||||||
import { LiftedAction, LiftedState } from 'redux-devtools-instrument';
|
import { LiftedAction } from 'redux-devtools-instrument';
|
||||||
import { Action, Dispatch } from 'redux';
|
import { Action } from 'redux';
|
||||||
import { ThemeFromProvider } from 'devui';
|
import { ThemeFromProvider } from 'devui';
|
||||||
|
import { State } from '../../reducers/instances';
|
||||||
|
|
||||||
const SliderWrapper = styled.div`
|
const SliderWrapper = styled.div`
|
||||||
border-color: ${(props) => props.theme.base02};
|
border-color: ${(props) => props.theme.base02};
|
||||||
|
@ -12,8 +13,8 @@ const SliderWrapper = styled.div`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
liftedState: LiftedState<unknown, Action<unknown>, unknown>;
|
liftedState: State;
|
||||||
dispatch: Dispatch<LiftedAction<unknown, Action<unknown>, unknown>>;
|
dispatch: (action: LiftedAction<unknown, Action<unknown>, unknown>) => void;
|
||||||
theme: ThemeFromProvider;
|
theme: ThemeFromProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +30,8 @@ class Slider extends Component<Props> {
|
||||||
<SliderWrapper>
|
<SliderWrapper>
|
||||||
<SliderMonitor
|
<SliderMonitor
|
||||||
{...this.props.liftedState}
|
{...this.props.liftedState}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
dispatch={this.props.dispatch}
|
dispatch={this.props.dispatch}
|
||||||
theme={this.props.theme}
|
theme={this.props.theme}
|
||||||
hideResetButton
|
hideResetButton
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'devui/lib/presets';
|
import 'devui/lib/presets';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { Store } from 'redux';
|
import { Store } from 'redux';
|
||||||
import configureStore from './store/configureStore';
|
import configureStore from './store/configureStore';
|
||||||
|
@ -21,7 +20,8 @@ class Root extends Component<Props> {
|
||||||
this.store = store;
|
this.store = store;
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: CONNECT_REQUEST,
|
type: CONNECT_REQUEST,
|
||||||
options: preloadedState!.connection || this.props.socketOptions,
|
options: (preloadedState!.connection ||
|
||||||
|
this.props.socketOptions) as ConnectionOptions,
|
||||||
});
|
});
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
});
|
});
|
||||||
|
@ -29,21 +29,13 @@ class Root extends Component<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.store) return null;
|
if (!this.store) return null;
|
||||||
|
const AppAsAny = App as any;
|
||||||
return (
|
return (
|
||||||
<Provider store={this.store}>
|
<Provider store={this.store}>
|
||||||
<App {...this.props} />
|
<AppAsAny {...this.props} />
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Root.propTypes = {
|
|
||||||
socketOptions: PropTypes.shape({
|
|
||||||
hostname: PropTypes.string,
|
|
||||||
port: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
||||||
autoReconnect: PropTypes.bool,
|
|
||||||
secure: PropTypes.bool,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Root;
|
export default Root;
|
||||||
|
|
|
@ -13,23 +13,36 @@ import {
|
||||||
GET_REPORT_ERROR,
|
GET_REPORT_ERROR,
|
||||||
GET_REPORT_SUCCESS,
|
GET_REPORT_SUCCESS,
|
||||||
} from '../constants/actionTypes';
|
} from '../constants/actionTypes';
|
||||||
import { showNotification, importState, StoreAction } from '../actions';
|
import {
|
||||||
|
showNotification,
|
||||||
|
importState,
|
||||||
|
StoreAction,
|
||||||
|
EmitAction,
|
||||||
|
LiftedActionAction,
|
||||||
|
Request,
|
||||||
|
DispatchAction,
|
||||||
|
} from '../actions';
|
||||||
import { nonReduxDispatch } from '../utils/monitorActions';
|
import { nonReduxDispatch } from '../utils/monitorActions';
|
||||||
import { StoreState } from '../reducers';
|
import { StoreState } from '../reducers';
|
||||||
|
|
||||||
let socket: SCClientSocket;
|
let socket: SCClientSocket;
|
||||||
let store: MiddlewareAPI<Dispatch<StoreAction>, StoreState>;
|
let store: MiddlewareAPI<Dispatch<StoreAction>, StoreState>;
|
||||||
|
|
||||||
function emit({ message: type, id, instanceId, action, state }) {
|
function emit({ message: type, id, instanceId, action, state }: EmitAction) {
|
||||||
socket.emit(id ? 'sc-' + id : 'respond', { type, action, state, instanceId });
|
socket.emit(id ? 'sc-' + id : 'respond', { type, action, state, instanceId });
|
||||||
}
|
}
|
||||||
|
|
||||||
function startMonitoring(channel) {
|
function startMonitoring(channel: string) {
|
||||||
if (channel !== store.getState().socket.baseChannel) return;
|
if (channel !== store.getState().socket.baseChannel) return;
|
||||||
store.dispatch({ type: actions.EMIT, message: 'START' });
|
store.dispatch({ type: actions.EMIT, message: 'START' });
|
||||||
}
|
}
|
||||||
|
|
||||||
function dispatchRemoteAction({ message, action, state, toAll }) {
|
function dispatchRemoteAction({
|
||||||
|
message,
|
||||||
|
action,
|
||||||
|
state,
|
||||||
|
toAll,
|
||||||
|
}: LiftedActionAction) {
|
||||||
const instances = store.getState().instances;
|
const instances = store.getState().instances;
|
||||||
const instanceId = getActiveInstance(instances);
|
const instanceId = getActiveInstance(instances);
|
||||||
const id = !toAll && instances.options[instanceId].connectionId;
|
const id = !toAll && instances.options[instanceId].connectionId;
|
||||||
|
@ -41,7 +54,7 @@ function dispatchRemoteAction({ message, action, state, toAll }) {
|
||||||
store,
|
store,
|
||||||
message,
|
message,
|
||||||
instanceId,
|
instanceId,
|
||||||
action,
|
action as DispatchAction,
|
||||||
state,
|
state,
|
||||||
instances
|
instances
|
||||||
),
|
),
|
||||||
|
@ -50,21 +63,32 @@ function dispatchRemoteAction({ message, action, state, toAll }) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DisconnectedAction {
|
interface RequestBase {
|
||||||
|
id?: string;
|
||||||
|
instanceId?: string;
|
||||||
|
}
|
||||||
|
interface DisconnectedAction extends RequestBase {
|
||||||
type: 'DISCONNECTED';
|
type: 'DISCONNECTED';
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
interface StartAction {
|
interface StartAction extends RequestBase {
|
||||||
type: 'START';
|
type: 'START';
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
interface ErrorAction {
|
interface ErrorAction extends RequestBase {
|
||||||
type: 'ERROR';
|
type: 'ERROR';
|
||||||
payload: string;
|
payload: string;
|
||||||
}
|
}
|
||||||
type Request = DisconnectedAction | StartAction | ErrorAction;
|
interface RequestWithData extends RequestBase {
|
||||||
|
data: Request;
|
||||||
|
}
|
||||||
|
type MonitoringRequest =
|
||||||
|
| DisconnectedAction
|
||||||
|
| StartAction
|
||||||
|
| ErrorAction
|
||||||
|
| Request;
|
||||||
|
|
||||||
function monitoring(request: Request) {
|
function monitoring(request: MonitoringRequest) {
|
||||||
if (request.type === 'DISCONNECTED') {
|
if (request.type === 'DISCONNECTED') {
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: REMOVE_INSTANCE,
|
type: REMOVE_INSTANCE,
|
||||||
|
@ -84,7 +108,9 @@ function monitoring(request: Request) {
|
||||||
|
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: UPDATE_STATE,
|
type: UPDATE_STATE,
|
||||||
request: request.data ? { ...request.data, id: request.id } : request,
|
request: ((request as unknown) as RequestWithData).data
|
||||||
|
? { ...((request as unknown) as RequestWithData).data, id: request.id }
|
||||||
|
: request,
|
||||||
});
|
});
|
||||||
|
|
||||||
const instances = store.getState().instances;
|
const instances = store.getState().instances;
|
||||||
|
@ -110,7 +136,7 @@ function subscribe(
|
||||||
const channel = socket.subscribe(channelName);
|
const channel = socket.subscribe(channelName);
|
||||||
if (subscription === UPDATE_STATE) channel.watch(monitoring);
|
if (subscription === UPDATE_STATE) channel.watch(monitoring);
|
||||||
else {
|
else {
|
||||||
const watcher = (request) => {
|
const watcher = (request: Request) => {
|
||||||
store.dispatch({ type: subscription, request });
|
store.dispatch({ type: subscription, request });
|
||||||
};
|
};
|
||||||
channel.watch(watcher);
|
channel.watch(watcher);
|
||||||
|
@ -201,15 +227,19 @@ function login() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReport(reportId) {
|
function getReport(reportId: unknown) {
|
||||||
socket.emit('getReport', reportId, (error, data) => {
|
socket.emit(
|
||||||
if (error) {
|
'getReport',
|
||||||
store.dispatch({ type: GET_REPORT_ERROR, error });
|
reportId,
|
||||||
return;
|
(error: Error, data: { payload: string }) => {
|
||||||
|
if (error) {
|
||||||
|
store.dispatch({ type: GET_REPORT_ERROR, error });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
store.dispatch({ type: GET_REPORT_SUCCESS, data });
|
||||||
|
store.dispatch(importState(data.payload));
|
||||||
}
|
}
|
||||||
store.dispatch({ type: GET_REPORT_SUCCESS, data });
|
);
|
||||||
store.dispatch(importState(data.payload));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function api(
|
export default function api(
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import stringifyJSON from '../utils/stringifyJSON';
|
import stringifyJSON from '../utils/stringifyJSON';
|
||||||
import { UPDATE_STATE, LIFTED_ACTION, EXPORT } from '../constants/actionTypes';
|
import { UPDATE_STATE, LIFTED_ACTION, EXPORT } from '../constants/actionTypes';
|
||||||
import { getActiveInstance } from '../reducers/instances';
|
import { getActiveInstance } from '../reducers/instances';
|
||||||
|
import { Dispatch, MiddlewareAPI } from 'redux';
|
||||||
|
import { ExportRequest, StoreAction } from '../actions';
|
||||||
|
import { StoreState } from '../reducers';
|
||||||
|
|
||||||
let toExport;
|
let toExport: string | undefined;
|
||||||
|
|
||||||
function download(state) {
|
function download(state: string) {
|
||||||
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');
|
||||||
|
@ -19,15 +22,17 @@ function download(state) {
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const exportState = (store) => (next) => (action) => {
|
const exportState = (
|
||||||
|
store: MiddlewareAPI<Dispatch<StoreAction>, StoreState>
|
||||||
|
) => (next: Dispatch<StoreAction>) => (action: StoreAction) => {
|
||||||
const result = next(action);
|
const result = next(action);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
toExport &&
|
toExport &&
|
||||||
action.type === UPDATE_STATE &&
|
action.type === UPDATE_STATE &&
|
||||||
action.request.type === 'EXPORT'
|
action.request!.type === 'EXPORT'
|
||||||
) {
|
) {
|
||||||
const request = action.request;
|
const request = action.request!;
|
||||||
const id = request.instanceId || request.id;
|
const id = request.instanceId || request.id;
|
||||||
if (id === toExport) {
|
if (id === toExport) {
|
||||||
toExport = undefined;
|
toExport = undefined;
|
||||||
|
@ -35,7 +40,7 @@ const exportState = (store) => (next) => (action) => {
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
{
|
{
|
||||||
payload: request.payload,
|
payload: request.payload,
|
||||||
preloadedState: request.committedState,
|
preloadedState: (request as ExportRequest).committedState,
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
'\t'
|
'\t'
|
||||||
|
|
|
@ -89,19 +89,20 @@ function updateState(
|
||||||
id: string,
|
id: string,
|
||||||
serialize: boolean | undefined
|
serialize: boolean | undefined
|
||||||
) {
|
) {
|
||||||
let payload = request.payload;
|
let payload: State = request.payload as State;
|
||||||
const actionsById = request.actionsById;
|
const actionsById = request.actionsById;
|
||||||
if (actionsById) {
|
if (actionsById) {
|
||||||
payload = {
|
payload = {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
...payload,
|
...payload,
|
||||||
actionsById: parseJSON(actionsById, serialize),
|
actionsById: parseJSON(actionsById, serialize),
|
||||||
computedStates: parseJSON(request.computedStates, serialize),
|
computedStates: parseJSON(request.computedStates, serialize),
|
||||||
};
|
} as State;
|
||||||
if (request.type === 'STATE' && request.committedState) {
|
if (request.type === 'STATE' && request.committedState) {
|
||||||
payload.committedState = payload.computedStates[0].state;
|
payload.committedState = payload.computedStates[0].state;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
payload = parseJSON(payload, serialize);
|
payload = parseJSON((payload as unknown) as string, serialize) as State;
|
||||||
}
|
}
|
||||||
|
|
||||||
let newState;
|
let newState;
|
||||||
|
@ -112,11 +113,11 @@ function updateState(
|
||||||
case 'INIT':
|
case 'INIT':
|
||||||
newState = recompute(state.default, payload, {
|
newState = recompute(state.default, payload, {
|
||||||
action: { type: '@@INIT' },
|
action: { type: '@@INIT' },
|
||||||
timestamp: action.timestamp || Date.now(),
|
timestamp: (action as { timestamp?: unknown }).timestamp || Date.now(),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'ACTION': {
|
case 'ACTION': {
|
||||||
let isExcess = request.isExcess;
|
const isExcess = request.isExcess;
|
||||||
const nextActionId = request.nextActionId || liftedState.nextActionId + 1;
|
const nextActionId = request.nextActionId || liftedState.nextActionId + 1;
|
||||||
const maxAge = request.maxAge;
|
const maxAge = request.maxAge;
|
||||||
if (Array.isArray(action)) {
|
if (Array.isArray(action)) {
|
||||||
|
@ -125,7 +126,7 @@ function updateState(
|
||||||
for (let i = 0; i < action.length; i++) {
|
for (let i = 0; i < action.length; i++) {
|
||||||
newState = recompute(
|
newState = recompute(
|
||||||
newState,
|
newState,
|
||||||
request.batched ? payload : payload[i],
|
request.batched ? payload : ((payload as unknown) as State[])[i],
|
||||||
action[i],
|
action[i],
|
||||||
newState.nextActionId + 1,
|
newState.nextActionId + 1,
|
||||||
maxAge,
|
maxAge,
|
||||||
|
|
|
@ -36,13 +36,12 @@ export function dispatchMonitorAction(
|
||||||
): MonitorState {
|
): MonitorState {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
monitorState:
|
monitorState: (action.action.newMonitorState ||
|
||||||
action.action.newMonitorState ||
|
|
||||||
action.monitorReducer(
|
action.monitorReducer(
|
||||||
action.monitorProps,
|
action.monitorProps,
|
||||||
state.monitorState,
|
state.monitorState,
|
||||||
action.action
|
action.action
|
||||||
),
|
)) as MonitorStateMonitorState,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,12 @@ import {
|
||||||
} from '../constants/actionTypes';
|
} from '../constants/actionTypes';
|
||||||
import { StoreAction } from '../actions';
|
import { StoreAction } from '../actions';
|
||||||
|
|
||||||
|
export interface Data {
|
||||||
|
id: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ReportsState {
|
export interface ReportsState {
|
||||||
data: unknown[];
|
data: Data[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: ReportsState = {
|
const initialState: ReportsState = {
|
||||||
|
|
|
@ -6,8 +6,10 @@ export interface SocketState {
|
||||||
id: string | null;
|
id: string | null;
|
||||||
channels: string[];
|
channels: string[];
|
||||||
socketState: States;
|
socketState: States;
|
||||||
authState: AuthStates;
|
authState: AuthStates | 'pending';
|
||||||
error: Error | undefined;
|
error: Error | undefined;
|
||||||
|
baseChannel?: string;
|
||||||
|
authToken?: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: SocketState = {
|
const initialState: SocketState = {
|
||||||
|
@ -18,7 +20,10 @@ const initialState: SocketState = {
|
||||||
error: undefined,
|
error: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function socket(state = initialState, action: StoreAction) {
|
export default function socket(
|
||||||
|
state = initialState,
|
||||||
|
action: StoreAction
|
||||||
|
): SocketState {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case actions.CONNECT_REQUEST: {
|
case actions.CONNECT_REQUEST: {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -25,15 +25,23 @@ export default function configureStore(
|
||||||
deserialize: (data: unknown) => data,
|
deserialize: (data: unknown) => data,
|
||||||
} as unknown) as PersistorConfig;
|
} as unknown) as PersistorConfig;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
getStoredState<StoreState>(persistConfig, (err, restoredState) => {
|
getStoredState<StoreState>(persistConfig, (err, restoredState) => {
|
||||||
let composeEnhancers = compose;
|
let composeEnhancers = compose;
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
if (window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) {
|
if (
|
||||||
composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
|
((window as unknown) as {
|
||||||
|
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
|
||||||
|
}).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
||||||
|
) {
|
||||||
|
composeEnhancers = ((window as unknown) as {
|
||||||
|
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__: typeof compose;
|
||||||
|
}).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
|
||||||
}
|
}
|
||||||
if (module.hot) {
|
if (module.hot) {
|
||||||
// Enable Webpack hot module replacement for reducers
|
// Enable Webpack hot module replacement for reducers
|
||||||
module.hot.accept('../reducers', () => {
|
module.hot.accept('../reducers', () => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const nextReducer = require('../reducers'); // eslint-disable-line global-require
|
const nextReducer = require('../reducers'); // eslint-disable-line global-require
|
||||||
store.replaceReducer(nextReducer);
|
store.replaceReducer(nextReducer);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
// Based on https://github.com/gaearon/redux-devtools/pull/241
|
// Based on https://github.com/gaearon/redux-devtools/pull/241
|
||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
|
|
||||||
export default function commitExcessActions(liftedState, n = 1) {
|
import { State } from '../reducers/instances';
|
||||||
|
|
||||||
|
export default function commitExcessActions(liftedState: State, n = 1) {
|
||||||
// Auto-commits n-number of excess actions.
|
// Auto-commits n-number of excess actions.
|
||||||
let excess = n;
|
let excess = n;
|
||||||
let idsToDelete = liftedState.stagedActionIds.slice(1, excess + 1);
|
let idsToDelete = liftedState.stagedActionIds.slice(1, excess + 1);
|
||||||
|
|
|
@ -2,7 +2,10 @@ 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';
|
import { InstancesState, State } from '../reducers/instances';
|
||||||
|
import { Dispatch, MiddlewareAPI } from 'redux';
|
||||||
|
import { DispatchAction, StoreAction } from '../actions';
|
||||||
|
import { StoreState } from '../reducers';
|
||||||
|
|
||||||
export function sweep(state: State): State {
|
export function sweep(state: State): State {
|
||||||
return {
|
return {
|
||||||
|
@ -18,12 +21,12 @@ export function sweep(state: State): State {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function nonReduxDispatch(
|
export function nonReduxDispatch(
|
||||||
store,
|
store: MiddlewareAPI<Dispatch<StoreAction>, StoreState>,
|
||||||
message,
|
message: string,
|
||||||
instanceId,
|
instanceId: string,
|
||||||
action,
|
action: DispatchAction,
|
||||||
initialState,
|
initialState: string | undefined,
|
||||||
preInstances
|
preInstances: InstancesState
|
||||||
) {
|
) {
|
||||||
const instances = preInstances || store.getState().instances;
|
const instances = preInstances || store.getState().instances;
|
||||||
const state = instances.states[instanceId];
|
const state = instances.states[instanceId];
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import jsan from 'jsan';
|
import jsan from 'jsan';
|
||||||
import { DATA_TYPE_KEY, DATA_REF_KEY } from '../constants/dataTypes';
|
import { DATA_TYPE_KEY, DATA_REF_KEY } from '../constants/dataTypes';
|
||||||
|
|
||||||
export function reviver(key, value) {
|
export function reviver(key: string, value: unknown) {
|
||||||
if (
|
if (
|
||||||
typeof value === 'object' &&
|
typeof value === 'object' &&
|
||||||
value !== null &&
|
value !== null &&
|
||||||
'__serializedType__' in value &&
|
'__serializedType__' in value &&
|
||||||
typeof value.data === 'object'
|
typeof (value as any).data === 'object'
|
||||||
) {
|
) {
|
||||||
const data = value.data;
|
const data = (value as any).data;
|
||||||
data[DATA_TYPE_KEY] = value.__serializedType__;
|
data[DATA_TYPE_KEY] = (value as any).__serializedType__;
|
||||||
if ('__serializedRef__' in value)
|
if ('__serializedRef__' in value)
|
||||||
data[DATA_REF_KEY] = value.__serializedRef__;
|
data[DATA_REF_KEY] = (value as any).__serializedRef__;
|
||||||
/*
|
/*
|
||||||
if (Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
data.__serializedType__ = value.__serializedType__;
|
data.__serializedType__ = value.__serializedType__;
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
import jsan from 'jsan';
|
import jsan from 'jsan';
|
||||||
import { DATA_TYPE_KEY, DATA_REF_KEY } from '../constants/dataTypes';
|
import { DATA_TYPE_KEY, DATA_REF_KEY } from '../constants/dataTypes';
|
||||||
|
|
||||||
function replacer(key, value) {
|
function replacer(key: string, value: unknown) {
|
||||||
if (typeof value === 'object' && value !== null && DATA_TYPE_KEY in value) {
|
if (typeof value === 'object' && value !== null && DATA_TYPE_KEY in value) {
|
||||||
const __serializedType__ = value[DATA_TYPE_KEY];
|
const __serializedType__ = (value as any)[DATA_TYPE_KEY];
|
||||||
const clone = { ...value };
|
const clone = { ...value };
|
||||||
delete clone[DATA_TYPE_KEY]; // eslint-disable-line no-param-reassign
|
delete (clone as any)[DATA_TYPE_KEY]; // eslint-disable-line no-param-reassign
|
||||||
const r = { data: clone, __serializedType__ };
|
const r = { data: clone, __serializedType__ };
|
||||||
if (DATA_REF_KEY in value) r.__serializedRef__ = clone[DATA_REF_KEY];
|
if (DATA_REF_KEY in value)
|
||||||
|
(r as any).__serializedRef__ = (clone as any)[DATA_REF_KEY];
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function stringifyJSON(data, serialize) {
|
export default function stringifyJSON(data: unknown, serialize: boolean) {
|
||||||
return serialize
|
return serialize
|
||||||
? jsan.stringify(data, replacer, null, true)
|
? jsan.stringify(data, replacer, (null as unknown) as undefined, true)
|
||||||
: jsan.stringify(data);
|
: jsan.stringify(data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import commitExcessActions from './commitExcessActions';
|
import commitExcessActions from './commitExcessActions';
|
||||||
import { State } from '../reducers/instances';
|
import { State } from '../reducers/instances';
|
||||||
|
import { Action } from 'redux';
|
||||||
|
import { PerformAction } from 'redux-devtools-instrument';
|
||||||
|
|
||||||
export function recompute(
|
export function recompute(
|
||||||
previousLiftedState: State,
|
previousLiftedState: State,
|
||||||
storeState,
|
storeState: State,
|
||||||
action,
|
action: Action<unknown>,
|
||||||
nextActionId = 1,
|
nextActionId = 1,
|
||||||
maxAge?: number,
|
maxAge?: number,
|
||||||
isExcess?: boolean
|
isExcess?: boolean
|
||||||
|
@ -21,12 +23,14 @@ export function recompute(
|
||||||
liftedState.stagedActionIds = [...liftedState.stagedActionIds, actionId];
|
liftedState.stagedActionIds = [...liftedState.stagedActionIds, actionId];
|
||||||
liftedState.actionsById = { ...liftedState.actionsById };
|
liftedState.actionsById = { ...liftedState.actionsById };
|
||||||
if (action.type === 'PERFORM_ACTION') {
|
if (action.type === 'PERFORM_ACTION') {
|
||||||
liftedState.actionsById[actionId] = action;
|
liftedState.actionsById[actionId] = action as PerformAction<
|
||||||
|
Action<unknown>
|
||||||
|
>;
|
||||||
} else {
|
} else {
|
||||||
liftedState.actionsById[actionId] = {
|
liftedState.actionsById[actionId] = {
|
||||||
action: action.action || action,
|
action: (action as any).action || action,
|
||||||
timestamp: action.timestamp || Date.now(),
|
timestamp: (action as any).timestamp || Date.now(),
|
||||||
stack: action.stack,
|
stack: (action as any).stack,
|
||||||
type: 'PERFORM_ACTION',
|
type: 'PERFORM_ACTION',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,53 @@
|
||||||
const ERROR = '@@redux-devtools/ERROR';
|
const ERROR = '@@redux-devtools/ERROR';
|
||||||
|
|
||||||
export default function catchErrors(sendError) {
|
interface ErrorAction {
|
||||||
|
type: typeof ERROR;
|
||||||
|
message?: Event | string;
|
||||||
|
url?: string | undefined;
|
||||||
|
lineNo?: number | undefined;
|
||||||
|
columnNo?: number | undefined;
|
||||||
|
stack?: string;
|
||||||
|
error?: Error;
|
||||||
|
isFatal?: boolean;
|
||||||
|
sourceURL?: string;
|
||||||
|
line?: number;
|
||||||
|
column?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function catchErrors(
|
||||||
|
sendError: (errorAction: ErrorAction) => void
|
||||||
|
) {
|
||||||
if (typeof window === 'object' && typeof window.onerror === 'object') {
|
if (typeof window === 'object' && typeof window.onerror === 'object') {
|
||||||
window.onerror = function (message, url, lineNo, columnNo, error) {
|
window.onerror = function (message, url, lineNo, columnNo, error) {
|
||||||
const errorAction = { type: ERROR, message, url, lineNo, columnNo };
|
const errorAction: ErrorAction = {
|
||||||
|
type: ERROR,
|
||||||
|
message,
|
||||||
|
url,
|
||||||
|
lineNo,
|
||||||
|
columnNo,
|
||||||
|
};
|
||||||
if (error && error.stack) errorAction.stack = error.stack;
|
if (error && error.stack) errorAction.stack = error.stack;
|
||||||
sendError(errorAction);
|
sendError(errorAction);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
} else if (typeof global !== 'undefined' && global.ErrorUtils) {
|
} else if (typeof global !== 'undefined' && (global as any).ErrorUtils) {
|
||||||
global.ErrorUtils.setGlobalHandler((error, isFatal) => {
|
(global as any).ErrorUtils.setGlobalHandler(
|
||||||
sendError({ type: ERROR, error, isFatal });
|
(error: Error, isFatal: boolean) => {
|
||||||
});
|
sendError({ type: ERROR, error, isFatal });
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
if (
|
if (
|
||||||
typeof console === 'object' &&
|
typeof console === 'object' &&
|
||||||
typeof console.error === 'function' &&
|
typeof console.error === 'function' &&
|
||||||
!console.beforeRemotedev
|
!(console as any).beforeRemotedev
|
||||||
) {
|
) {
|
||||||
console.beforeRemotedev = console.error.bind(console);
|
(console as any).beforeRemotedev = console.error.bind(console);
|
||||||
console.error = function () {
|
console.error = function () {
|
||||||
let errorAction = { type: ERROR };
|
let errorAction: ErrorAction = { type: ERROR };
|
||||||
|
// eslint-disable-next-line prefer-rest-params
|
||||||
const error = arguments[0];
|
const error = arguments[0];
|
||||||
errorAction.message = error.message ? error.message : error;
|
errorAction.message = error.message ? error.message : error;
|
||||||
if (error.sourceURL) {
|
if (error.sourceURL) {
|
||||||
|
@ -35,7 +60,8 @@ export default function catchErrors(sendError) {
|
||||||
}
|
}
|
||||||
if (error.stack) errorAction.stack = error.stack;
|
if (error.stack) errorAction.stack = error.stack;
|
||||||
sendError(errorAction);
|
sendError(errorAction);
|
||||||
console.beforeRemotedev.apply(null, arguments);
|
// eslint-disable-next-line prefer-rest-params
|
||||||
|
(console as any).beforeRemotedev.apply(null, arguments);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/* eslint-enable no-console */
|
/* eslint-enable no-console */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user