mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2024-11-25 19:13:56 +03:00
65205f9078
* Replace Action<unknown> with Action<string> In anticipation of Redux 5 type changes * Fix lint errors * Create yellow-steaks-marry.md
153 lines
4.1 KiB
TypeScript
153 lines
4.1 KiB
TypeScript
import React, { Component } from 'react';
|
|
|
|
import { getStackFrames } from './react-error-overlay/utils/getStackFrames';
|
|
import StackTrace from './react-error-overlay/containers/StackTrace';
|
|
import openFile from './openFile';
|
|
import { Action } from 'redux';
|
|
import { TabComponentProps } from '@redux-devtools/inspector-monitor';
|
|
import StackFrame from './react-error-overlay/utils/stack-frame';
|
|
import { ErrorLocation } from './react-error-overlay/utils/parseCompileError';
|
|
|
|
const rootStyle = { padding: '5px 10px' };
|
|
|
|
interface Props<S, A extends Action<string>> extends TabComponentProps<S, A> {
|
|
openFile: (
|
|
fileName: string,
|
|
lineNumber: number,
|
|
stackFrame: StackFrame,
|
|
) => void;
|
|
}
|
|
|
|
interface State {
|
|
stackFrames: StackFrame[];
|
|
currentError?: Error;
|
|
showDocsLink?: boolean;
|
|
}
|
|
|
|
export class TraceTab<S, A extends Action<string>> extends Component<
|
|
Props<S, A>,
|
|
State
|
|
> {
|
|
static defaultProps = {
|
|
openFile,
|
|
};
|
|
|
|
state: State = {
|
|
stackFrames: [],
|
|
};
|
|
|
|
componentDidMount() {
|
|
// console.log("StackTraceTab mounted");
|
|
this.checkForStackTrace();
|
|
}
|
|
|
|
componentDidUpdate(prevProps: Props<S, A>) {
|
|
const { action, actions } = prevProps;
|
|
|
|
if (action !== this.props.action || actions !== this.props.actions) {
|
|
this.checkForStackTrace();
|
|
}
|
|
}
|
|
|
|
checkForStackTrace() {
|
|
const { action, actions: liftedActionsById } = this.props;
|
|
|
|
if (!action) {
|
|
return;
|
|
}
|
|
|
|
const liftedActions = Object.values(liftedActionsById);
|
|
const liftedAction = liftedActions.find(
|
|
(liftedAction) => liftedAction.action === action,
|
|
);
|
|
|
|
if (liftedAction && typeof liftedAction.stack === 'string') {
|
|
const deserializedError = Object.assign(new Error(), {
|
|
stack: liftedAction.stack,
|
|
});
|
|
|
|
getStackFrames(deserializedError)
|
|
.then((stackFrames) => {
|
|
this.setState({
|
|
stackFrames: stackFrames!,
|
|
currentError: deserializedError,
|
|
});
|
|
})
|
|
.catch(() => {
|
|
// noop
|
|
});
|
|
} else {
|
|
this.setState({
|
|
stackFrames: [],
|
|
showDocsLink:
|
|
!!liftedAction!.action &&
|
|
!!liftedAction!.action.type &&
|
|
liftedAction!.action.type !== '@@INIT',
|
|
});
|
|
}
|
|
}
|
|
|
|
onStackLocationClicked = (fileLocation: Partial<ErrorLocation> = {}) => {
|
|
// console.log("Stack location args: ", ...args);
|
|
|
|
const { fileName, lineNumber } = fileLocation;
|
|
|
|
if (fileName && lineNumber) {
|
|
const matchingStackFrame = this.state.stackFrames.find((stackFrame) => {
|
|
const matches =
|
|
(stackFrame._originalFileName === fileName &&
|
|
stackFrame._originalLineNumber === lineNumber) ||
|
|
(stackFrame.fileName === fileName &&
|
|
stackFrame.lineNumber === lineNumber);
|
|
return matches;
|
|
});
|
|
|
|
// console.log("Matching stack frame: ", matchingStackFrame);
|
|
|
|
if (matchingStackFrame) {
|
|
/*
|
|
const frameIndex = this.state.stackFrames.indexOf(matchingStackFrame);
|
|
const originalStackFrame = parsedFramesNoSourcemaps[frameIndex];
|
|
console.log("Original stack frame: ", originalStackFrame);
|
|
*/
|
|
this.props.openFile(fileName, lineNumber, matchingStackFrame);
|
|
}
|
|
}
|
|
};
|
|
|
|
openDocs: React.MouseEventHandler<HTMLAnchorElement> = (e) => {
|
|
e.stopPropagation();
|
|
window.open(
|
|
'https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/Features/Trace.md',
|
|
);
|
|
};
|
|
|
|
render() {
|
|
const { stackFrames, showDocsLink } = this.state;
|
|
|
|
if (showDocsLink) {
|
|
return (
|
|
<div style={rootStyle}>
|
|
To enable tracing action calls, you should set `trace` option to
|
|
`true` for Redux DevTools enhancer. Refer to{' '}
|
|
<a href="#" onClick={this.openDocs}>
|
|
this page
|
|
</a>{' '}
|
|
for more details.
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div style={rootStyle}>
|
|
<StackTrace
|
|
stackFrames={stackFrames}
|
|
errorName="N/A"
|
|
contextSize={3}
|
|
editorHandler={this.onStackLocationClicked}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
}
|