@sentry/react 7.105.0 → 8.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/cjs/errorboundary.js +5 -6
- package/cjs/errorboundary.js.map +1 -1
- package/cjs/index.js +0 -4
- package/cjs/index.js.map +1 -1
- package/cjs/profiler.js +24 -16
- package/cjs/profiler.js.map +1 -1
- package/cjs/reactrouter.js +3 -29
- package/cjs/reactrouter.js.map +1 -1
- package/cjs/reactrouterv3.js +1 -9
- package/cjs/reactrouterv3.js.map +1 -1
- package/cjs/reactrouterv6.js +0 -41
- package/cjs/reactrouterv6.js.map +1 -1
- package/cjs/redux.js +1 -1
- package/cjs/redux.js.map +1 -1
- package/esm/errorboundary.js +5 -6
- package/esm/errorboundary.js.map +1 -1
- package/esm/index.js +3 -3
- package/esm/profiler.js +25 -17
- package/esm/profiler.js.map +1 -1
- package/esm/reactrouter.js +5 -29
- package/esm/reactrouter.js.map +1 -1
- package/esm/reactrouterv3.js +3 -10
- package/esm/reactrouterv3.js.map +1 -1
- package/esm/reactrouterv6.js +1 -41
- package/esm/reactrouterv6.js.map +1 -1
- package/esm/redux.js +2 -2
- package/esm/redux.js.map +1 -1
- package/package.json +7 -7
- package/types/errorboundary.d.ts +3 -2
- package/types/errorboundary.d.ts.map +1 -1
- package/types/index.d.ts +3 -3
- package/types/index.d.ts.map +1 -1
- package/types/profiler.d.ts.map +1 -1
- package/types/reactrouter.d.ts +1 -9
- package/types/reactrouter.d.ts.map +1 -1
- package/types/reactrouterv3.d.ts +1 -12
- package/types/reactrouterv3.d.ts.map +1 -1
- package/types-ts3.8/errorboundary.d.ts +3 -2
- package/types-ts3.8/index.d.ts +3 -3
- package/types-ts3.8/reactrouter.d.ts +1 -9
- package/types-ts3.8/reactrouterv3.d.ts +1 -12
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ To use this SDK, call `Sentry.init(options)` before you mount your React compone
|
|
|
20
20
|
|
|
21
21
|
```javascript
|
|
22
22
|
import React from 'react';
|
|
23
|
-
import ReactDOM from
|
|
23
|
+
import ReactDOM from 'react-dom';
|
|
24
24
|
import * as Sentry from '@sentry/react';
|
|
25
25
|
|
|
26
26
|
Sentry.init({
|
|
@@ -39,17 +39,16 @@ ReactDOM.render(<App />, rootNode);
|
|
|
39
39
|
### ErrorBoundary
|
|
40
40
|
|
|
41
41
|
`@sentry/react` exports an ErrorBoundary component that will automatically send Javascript errors from inside a
|
|
42
|
-
component tree to Sentry, and set a fallback UI.
|
|
42
|
+
component tree to Sentry, and set a fallback UI.
|
|
43
43
|
|
|
44
44
|
> app.js
|
|
45
|
+
|
|
45
46
|
```javascript
|
|
46
47
|
import React from 'react';
|
|
47
48
|
import * as Sentry from '@sentry/react';
|
|
48
49
|
|
|
49
50
|
function FallbackComponent() {
|
|
50
|
-
return
|
|
51
|
-
<div>An error has occured</div>
|
|
52
|
-
)
|
|
51
|
+
return <div>An error has occured</div>;
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
class App extends React.Component {
|
|
@@ -58,7 +57,7 @@ class App extends React.Component {
|
|
|
58
57
|
<Sentry.ErrorBoundary fallback={FallbackComponent} showDialog>
|
|
59
58
|
<OtherComponents />
|
|
60
59
|
</Sentry.ErrorBoundary>
|
|
61
|
-
)
|
|
60
|
+
);
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
|
|
@@ -67,11 +66,12 @@ export default App;
|
|
|
67
66
|
|
|
68
67
|
### Profiler
|
|
69
68
|
|
|
70
|
-
`@sentry/react` exports a Profiler component that leverages the tracing features to add React-related
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
`@sentry/react` exports a Profiler component that leverages the tracing features to add React-related spans to
|
|
70
|
+
transactions. If tracing is not enabled, the Profiler component will not work. The Profiler tracks component mount,
|
|
71
|
+
render duration and updates.
|
|
73
72
|
|
|
74
73
|
> app.js
|
|
74
|
+
|
|
75
75
|
```javascript
|
|
76
76
|
import React from 'react';
|
|
77
77
|
import * as Sentry from '@sentry/react';
|
|
@@ -83,7 +83,7 @@ class App extends React.Component {
|
|
|
83
83
|
<InsideComponent someProp={2} />
|
|
84
84
|
<AnotherComponent />
|
|
85
85
|
</FancyComponent>
|
|
86
|
-
)
|
|
86
|
+
);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
package/cjs/errorboundary.js
CHANGED
|
@@ -58,7 +58,7 @@ function setCause(error, cause) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
* A ErrorBoundary component that logs errors to Sentry.
|
|
61
|
+
* A ErrorBoundary component that logs errors to Sentry.
|
|
62
62
|
* NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the
|
|
63
63
|
* Sentry React SDK ErrorBoundary caught an error invoking your application code. This
|
|
64
64
|
* is expected behavior and NOT indicative of a bug with the Sentry React SDK.
|
|
@@ -71,11 +71,10 @@ class ErrorBoundary extends React__namespace.Component {
|
|
|
71
71
|
this._openFallbackReportDialog = true;
|
|
72
72
|
|
|
73
73
|
const client = browser.getClient();
|
|
74
|
-
if (client &&
|
|
74
|
+
if (client && props.showDialog) {
|
|
75
75
|
this._openFallbackReportDialog = false;
|
|
76
76
|
client.on('afterSendEvent', event => {
|
|
77
|
-
if (!event.type && event.event_id === this._lastEventId) {
|
|
78
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
77
|
+
if (!event.type && this._lastEventId && event.event_id === this._lastEventId) {
|
|
79
78
|
browser.showReportDialog({ ...props.dialogOptions, eventId: this._lastEventId });
|
|
80
79
|
}
|
|
81
80
|
});
|
|
@@ -198,8 +197,8 @@ function withErrorBoundary(
|
|
|
198
197
|
const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;
|
|
199
198
|
|
|
200
199
|
const Wrapped = (props) => (
|
|
201
|
-
React__namespace.createElement(ErrorBoundary, { ...errorBoundaryOptions, __self: this, __source: {fileName: _jsxFileName, lineNumber:
|
|
202
|
-
, React__namespace.createElement(WrappedComponent, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber:
|
|
200
|
+
React__namespace.createElement(ErrorBoundary, { ...errorBoundaryOptions, __self: this, __source: {fileName: _jsxFileName, lineNumber: 237}}
|
|
201
|
+
, React__namespace.createElement(WrappedComponent, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 238}} )
|
|
203
202
|
)
|
|
204
203
|
);
|
|
205
204
|
|
package/cjs/errorboundary.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorboundary.js","sources":["../../src/errorboundary.tsx"],"sourcesContent":["import type { ReportDialogOptions, Scope } from '@sentry/browser';\nimport { captureException, getClient, showReportDialog, withScope } from '@sentry/browser';\nimport { isError, logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { DEBUG_BUILD } from './debug-build';\n\nexport function isAtLeastReact17(version: string): boolean {\n const major = version.match(/^([^.]+)/);\n return major !== null && parseInt(major[0]) >= 17;\n}\n\nexport const UNKNOWN_COMPONENT = 'unknown';\n\nexport type FallbackRender = (errorData: {\n error: Error;\n componentStack: string;\n eventId: string;\n resetError(): void;\n}) => React.ReactElement;\n\nexport type ErrorBoundaryProps = {\n children?: React.ReactNode | (() => React.ReactNode);\n /** If a Sentry report dialog should be rendered on error */\n showDialog?: boolean | undefined;\n /**\n * Options to be passed into the Sentry report dialog.\n * No-op if {@link showDialog} is false.\n */\n // eslint-disable-next-line deprecation/deprecation\n dialogOptions?: Omit<ReportDialogOptions, 'eventId'> | undefined;\n /**\n * A fallback component that gets rendered when the error boundary encounters an error.\n *\n * Can either provide a React Component, or a function that returns React Component as\n * a valid fallback prop. If a function is provided, the function will be called with\n * the error, the component stack, and an function that resets the error boundary on error.\n *\n */\n fallback?: React.ReactElement | FallbackRender | undefined;\n /** Called when the error boundary encounters an error */\n onError?: ((error: Error, componentStack: string, eventId: string) => void) | undefined;\n /** Called on componentDidMount() */\n onMount?: (() => void) | undefined;\n /** Called if resetError() is called from the fallback render props function */\n onReset?: ((error: Error | null, componentStack: string | null, eventId: string | null) => void) | undefined;\n /** Called on componentWillUnmount() */\n onUnmount?: ((error: Error | null, componentStack: string | null, eventId: string | null) => void) | undefined;\n /** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */\n beforeCapture?: ((scope: Scope, error: Error | null, componentStack: string | null) => void) | undefined;\n};\n\ntype ErrorBoundaryState =\n | {\n componentStack: null;\n error: null;\n eventId: null;\n }\n | {\n componentStack: React.ErrorInfo['componentStack'];\n error: Error;\n eventId: string;\n };\n\nconst INITIAL_STATE = {\n componentStack: null,\n error: null,\n eventId: null,\n};\n\nfunction setCause(error: Error & { cause?: Error }, cause: Error): void {\n const seenErrors = new WeakMap<Error, boolean>();\n\n function recurse(error: Error & { cause?: Error }, cause: Error): void {\n // If we've already seen the error, there is a recursive loop somewhere in the error's\n // cause chain. Let's just bail out then to prevent a stack overflow.\n if (seenErrors.has(error)) {\n return;\n }\n if (error.cause) {\n seenErrors.set(error, true);\n return recurse(error.cause, cause);\n }\n error.cause = cause;\n }\n\n recurse(error, cause);\n}\n\n/**\n * A ErrorBoundary component that logs errors to Sentry. Requires React >= 16.\n * NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the\n * Sentry React SDK ErrorBoundary caught an error invoking your application code. This\n * is expected behavior and NOT indicative of a bug with the Sentry React SDK.\n */\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n public state: ErrorBoundaryState;\n\n private readonly _openFallbackReportDialog: boolean;\n\n private _lastEventId?: string;\n\n public constructor(props: ErrorBoundaryProps) {\n super(props);\n\n this.state = INITIAL_STATE;\n this._openFallbackReportDialog = true;\n\n const client = getClient();\n if (client && client.on && props.showDialog) {\n this._openFallbackReportDialog = false;\n client.on('afterSendEvent', event => {\n if (!event.type && event.event_id === this._lastEventId) {\n // eslint-disable-next-line deprecation/deprecation\n showReportDialog({ ...props.dialogOptions, eventId: this._lastEventId });\n }\n });\n }\n }\n\n public componentDidCatch(error: Error & { cause?: Error }, { componentStack }: React.ErrorInfo): void {\n const { beforeCapture, onError, showDialog, dialogOptions } = this.props;\n withScope(scope => {\n // If on React version >= 17, create stack trace from componentStack param and links\n // to to the original error using `error.cause` otherwise relies on error param for stacktrace.\n // Linking errors requires the `LinkedErrors` integration be enabled.\n // See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks\n //\n // Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked\n // with non-error objects. This is why we need to check if the error is an error-like object.\n // See: https://github.com/getsentry/sentry-javascript/issues/6167\n if (isAtLeastReact17(React.version) && isError(error)) {\n const errorBoundaryError = new Error(error.message);\n errorBoundaryError.name = `React ErrorBoundary ${error.name}`;\n errorBoundaryError.stack = componentStack;\n\n // Using the `LinkedErrors` integration to link the errors together.\n setCause(error, errorBoundaryError);\n }\n\n if (beforeCapture) {\n beforeCapture(scope, error, componentStack);\n }\n\n const eventId = captureException(error, {\n captureContext: {\n contexts: { react: { componentStack } },\n },\n mechanism: { handled: false },\n });\n\n if (onError) {\n onError(error, componentStack, eventId);\n }\n if (showDialog) {\n this._lastEventId = eventId;\n if (this._openFallbackReportDialog) {\n showReportDialog({ ...dialogOptions, eventId });\n }\n }\n\n // componentDidCatch is used over getDerivedStateFromError\n // so that componentStack is accessible through state.\n this.setState({ error, componentStack, eventId });\n });\n }\n\n public componentDidMount(): void {\n const { onMount } = this.props;\n if (onMount) {\n onMount();\n }\n }\n\n public componentWillUnmount(): void {\n const { error, componentStack, eventId } = this.state;\n const { onUnmount } = this.props;\n if (onUnmount) {\n onUnmount(error, componentStack, eventId);\n }\n }\n\n public resetErrorBoundary: () => void = () => {\n const { onReset } = this.props;\n const { error, componentStack, eventId } = this.state;\n if (onReset) {\n onReset(error, componentStack, eventId);\n }\n this.setState(INITIAL_STATE);\n };\n\n public render(): React.ReactNode {\n const { fallback, children } = this.props;\n const state = this.state;\n\n if (state.error) {\n let element: React.ReactElement | undefined = undefined;\n if (typeof fallback === 'function') {\n element = fallback({\n error: state.error,\n componentStack: state.componentStack,\n resetError: this.resetErrorBoundary,\n eventId: state.eventId,\n });\n } else {\n element = fallback;\n }\n\n if (React.isValidElement(element)) {\n return element;\n }\n\n if (fallback) {\n DEBUG_BUILD && logger.warn('fallback did not produce a valid ReactElement');\n }\n\n // Fail gracefully if no fallback provided or is not valid\n return null;\n }\n\n if (typeof children === 'function') {\n return (children as () => React.ReactNode)();\n }\n return children;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n errorBoundaryOptions: ErrorBoundaryProps,\n): React.FC<P> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;\n\n const Wrapped: React.FC<P> = (props: P) => (\n <ErrorBoundary {...errorBoundaryOptions}>\n <WrappedComponent {...props} />\n </ErrorBoundary>\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n Wrapped.displayName = `errorBoundary(${componentDisplayName})`;\n\n // Copy over static methods from Wrapped component to Profiler HOC\n // See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over\n hoistNonReactStatics(Wrapped, WrappedComponent);\n return Wrapped;\n}\n\nexport { ErrorBoundary, withErrorBoundary };\n"],"names":["React","getClient","showReportDialog","withScope","isError","captureException","DEBUG_BUILD","logger","hoistNonReactStatics"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"errorboundary.js","sources":["../../src/errorboundary.tsx"],"sourcesContent":["import type { ReportDialogOptions } from '@sentry/browser';\nimport { captureException, getClient, showReportDialog, withScope } from '@sentry/browser';\nimport type { Scope } from '@sentry/types';\nimport { isError, logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { DEBUG_BUILD } from './debug-build';\n\nexport function isAtLeastReact17(version: string): boolean {\n const major = version.match(/^([^.]+)/);\n return major !== null && parseInt(major[0]) >= 17;\n}\n\nexport const UNKNOWN_COMPONENT = 'unknown';\n\nexport type FallbackRender = (errorData: {\n error: Error;\n componentStack: string;\n eventId: string;\n resetError(): void;\n}) => React.ReactElement;\n\nexport type ErrorBoundaryProps = {\n children?: React.ReactNode | (() => React.ReactNode);\n /** If a Sentry report dialog should be rendered on error */\n showDialog?: boolean | undefined;\n /**\n * Options to be passed into the Sentry report dialog.\n * No-op if {@link showDialog} is false.\n */\n dialogOptions?: Omit<ReportDialogOptions, 'eventId'> | undefined;\n /**\n * A fallback component that gets rendered when the error boundary encounters an error.\n *\n * Can either provide a React Component, or a function that returns React Component as\n * a valid fallback prop. If a function is provided, the function will be called with\n * the error, the component stack, and an function that resets the error boundary on error.\n *\n */\n fallback?: React.ReactElement | FallbackRender | undefined;\n /** Called when the error boundary encounters an error */\n onError?: ((error: Error, componentStack: string, eventId: string) => void) | undefined;\n /** Called on componentDidMount() */\n onMount?: (() => void) | undefined;\n /** Called if resetError() is called from the fallback render props function */\n onReset?: ((error: Error | null, componentStack: string | null, eventId: string | null) => void) | undefined;\n /** Called on componentWillUnmount() */\n onUnmount?: ((error: Error | null, componentStack: string | null, eventId: string | null) => void) | undefined;\n /** Called before the error is captured by Sentry, allows for you to add tags or context using the scope */\n beforeCapture?: ((scope: Scope, error: Error | null, componentStack: string | null) => void) | undefined;\n};\n\ntype ErrorBoundaryState =\n | {\n componentStack: null;\n error: null;\n eventId: null;\n }\n | {\n componentStack: React.ErrorInfo['componentStack'];\n error: Error;\n eventId: string;\n };\n\nconst INITIAL_STATE = {\n componentStack: null,\n error: null,\n eventId: null,\n};\n\nfunction setCause(error: Error & { cause?: Error }, cause: Error): void {\n const seenErrors = new WeakMap<Error, boolean>();\n\n function recurse(error: Error & { cause?: Error }, cause: Error): void {\n // If we've already seen the error, there is a recursive loop somewhere in the error's\n // cause chain. Let's just bail out then to prevent a stack overflow.\n if (seenErrors.has(error)) {\n return;\n }\n if (error.cause) {\n seenErrors.set(error, true);\n return recurse(error.cause, cause);\n }\n error.cause = cause;\n }\n\n recurse(error, cause);\n}\n\n/**\n * A ErrorBoundary component that logs errors to Sentry.\n * NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the\n * Sentry React SDK ErrorBoundary caught an error invoking your application code. This\n * is expected behavior and NOT indicative of a bug with the Sentry React SDK.\n */\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n public state: ErrorBoundaryState;\n\n private readonly _openFallbackReportDialog: boolean;\n\n private _lastEventId?: string;\n\n public constructor(props: ErrorBoundaryProps) {\n super(props);\n\n this.state = INITIAL_STATE;\n this._openFallbackReportDialog = true;\n\n const client = getClient();\n if (client && props.showDialog) {\n this._openFallbackReportDialog = false;\n client.on('afterSendEvent', event => {\n if (!event.type && this._lastEventId && event.event_id === this._lastEventId) {\n showReportDialog({ ...props.dialogOptions, eventId: this._lastEventId });\n }\n });\n }\n }\n\n public componentDidCatch(error: Error & { cause?: Error }, { componentStack }: React.ErrorInfo): void {\n const { beforeCapture, onError, showDialog, dialogOptions } = this.props;\n withScope(scope => {\n // If on React version >= 17, create stack trace from componentStack param and links\n // to to the original error using `error.cause` otherwise relies on error param for stacktrace.\n // Linking errors requires the `LinkedErrors` integration be enabled.\n // See: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#native-component-stacks\n //\n // Although `componentDidCatch` is typed to accept an `Error` object, it can also be invoked\n // with non-error objects. This is why we need to check if the error is an error-like object.\n // See: https://github.com/getsentry/sentry-javascript/issues/6167\n if (isAtLeastReact17(React.version) && isError(error)) {\n const errorBoundaryError = new Error(error.message);\n errorBoundaryError.name = `React ErrorBoundary ${error.name}`;\n errorBoundaryError.stack = componentStack;\n\n // Using the `LinkedErrors` integration to link the errors together.\n setCause(error, errorBoundaryError);\n }\n\n if (beforeCapture) {\n beforeCapture(scope, error, componentStack);\n }\n\n const eventId = captureException(error, {\n captureContext: {\n contexts: { react: { componentStack } },\n },\n mechanism: { handled: false },\n });\n\n if (onError) {\n onError(error, componentStack, eventId);\n }\n if (showDialog) {\n this._lastEventId = eventId;\n if (this._openFallbackReportDialog) {\n showReportDialog({ ...dialogOptions, eventId });\n }\n }\n\n // componentDidCatch is used over getDerivedStateFromError\n // so that componentStack is accessible through state.\n this.setState({ error, componentStack, eventId });\n });\n }\n\n public componentDidMount(): void {\n const { onMount } = this.props;\n if (onMount) {\n onMount();\n }\n }\n\n public componentWillUnmount(): void {\n const { error, componentStack, eventId } = this.state;\n const { onUnmount } = this.props;\n if (onUnmount) {\n onUnmount(error, componentStack, eventId);\n }\n }\n\n public resetErrorBoundary: () => void = () => {\n const { onReset } = this.props;\n const { error, componentStack, eventId } = this.state;\n if (onReset) {\n onReset(error, componentStack, eventId);\n }\n this.setState(INITIAL_STATE);\n };\n\n public render(): React.ReactNode {\n const { fallback, children } = this.props;\n const state = this.state;\n\n if (state.error) {\n let element: React.ReactElement | undefined = undefined;\n if (typeof fallback === 'function') {\n element = fallback({\n error: state.error,\n componentStack: state.componentStack,\n resetError: this.resetErrorBoundary,\n eventId: state.eventId,\n });\n } else {\n element = fallback;\n }\n\n if (React.isValidElement(element)) {\n return element;\n }\n\n if (fallback) {\n DEBUG_BUILD && logger.warn('fallback did not produce a valid ReactElement');\n }\n\n // Fail gracefully if no fallback provided or is not valid\n return null;\n }\n\n if (typeof children === 'function') {\n return (children as () => React.ReactNode)();\n }\n return children;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n errorBoundaryOptions: ErrorBoundaryProps,\n): React.FC<P> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;\n\n const Wrapped: React.FC<P> = (props: P) => (\n <ErrorBoundary {...errorBoundaryOptions}>\n <WrappedComponent {...props} />\n </ErrorBoundary>\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n Wrapped.displayName = `errorBoundary(${componentDisplayName})`;\n\n // Copy over static methods from Wrapped component to Profiler HOC\n // See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over\n hoistNonReactStatics(Wrapped, WrappedComponent);\n return Wrapped;\n}\n\nexport { ErrorBoundary, withErrorBoundary };\n"],"names":["React","getClient","showReportDialog","withScope","isError","captureException","DEBUG_BUILD","logger","hoistNonReactStatics"],"mappings":"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"}
|
package/cjs/index.js
CHANGED
|
@@ -19,14 +19,10 @@ exports.ErrorBoundary = errorboundary.ErrorBoundary;
|
|
|
19
19
|
exports.withErrorBoundary = errorboundary.withErrorBoundary;
|
|
20
20
|
exports.createReduxEnhancer = redux.createReduxEnhancer;
|
|
21
21
|
exports.reactRouterV3BrowserTracingIntegration = reactrouterv3.reactRouterV3BrowserTracingIntegration;
|
|
22
|
-
exports.reactRouterV3Instrumentation = reactrouterv3.reactRouterV3Instrumentation;
|
|
23
22
|
exports.reactRouterV4BrowserTracingIntegration = reactrouter.reactRouterV4BrowserTracingIntegration;
|
|
24
|
-
exports.reactRouterV4Instrumentation = reactrouter.reactRouterV4Instrumentation;
|
|
25
23
|
exports.reactRouterV5BrowserTracingIntegration = reactrouter.reactRouterV5BrowserTracingIntegration;
|
|
26
|
-
exports.reactRouterV5Instrumentation = reactrouter.reactRouterV5Instrumentation;
|
|
27
24
|
exports.withSentryRouting = reactrouter.withSentryRouting;
|
|
28
25
|
exports.reactRouterV6BrowserTracingIntegration = reactrouterv6.reactRouterV6BrowserTracingIntegration;
|
|
29
|
-
exports.reactRouterV6Instrumentation = reactrouterv6.reactRouterV6Instrumentation;
|
|
30
26
|
exports.withSentryReactRouterV6Routing = reactrouterv6.withSentryReactRouterV6Routing;
|
|
31
27
|
exports.wrapCreateBrowserRouter = reactrouterv6.wrapCreateBrowserRouter;
|
|
32
28
|
exports.wrapUseRoutes = reactrouterv6.wrapUseRoutes;
|
package/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/cjs/profiler.js
CHANGED
|
@@ -60,8 +60,10 @@ class Profiler extends React__namespace.Component {
|
|
|
60
60
|
name: `<${name}>`,
|
|
61
61
|
onlyIfParent: true,
|
|
62
62
|
op: constants.REACT_MOUNT_OP,
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
attributes: {
|
|
64
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',
|
|
65
|
+
'ui.component_name': name,
|
|
66
|
+
},
|
|
65
67
|
});
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -87,9 +89,9 @@ class Profiler extends React__namespace.Component {
|
|
|
87
89
|
name: `<${this.props.name}>`,
|
|
88
90
|
onlyIfParent: true,
|
|
89
91
|
op: constants.REACT_UPDATE_OP,
|
|
90
|
-
|
|
91
|
-
startTimestamp: now,
|
|
92
|
+
startTime: now,
|
|
92
93
|
attributes: {
|
|
94
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',
|
|
93
95
|
'ui.component_name': this.props.name,
|
|
94
96
|
'ui.react.changed_props': changedProps,
|
|
95
97
|
},
|
|
@@ -115,15 +117,17 @@ class Profiler extends React__namespace.Component {
|
|
|
115
117
|
const { name, includeRender = true } = this.props;
|
|
116
118
|
|
|
117
119
|
if (this._mountSpan && includeRender) {
|
|
118
|
-
const
|
|
120
|
+
const startTime = core.spanToJSON(this._mountSpan).timestamp;
|
|
119
121
|
core.withActiveSpan(this._mountSpan, () => {
|
|
120
122
|
const renderSpan = browser.startInactiveSpan({
|
|
121
123
|
onlyIfParent: true,
|
|
122
124
|
name: `<${name}>`,
|
|
123
125
|
op: constants.REACT_RENDER_OP,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
startTime,
|
|
127
|
+
attributes: {
|
|
128
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',
|
|
129
|
+
'ui.component_name': name,
|
|
130
|
+
},
|
|
127
131
|
});
|
|
128
132
|
if (renderSpan) {
|
|
129
133
|
// Have to cast to Span because the type of _mountSpan is Span | undefined
|
|
@@ -157,8 +161,8 @@ function withProfiler(
|
|
|
157
161
|
(options && options.name) || WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;
|
|
158
162
|
|
|
159
163
|
const Wrapped = (props) => (
|
|
160
|
-
React__namespace.createElement(Profiler, { ...options, name: componentDisplayName, updateProps: props, __self: this, __source: {fileName: _jsxFileName, lineNumber:
|
|
161
|
-
, React__namespace.createElement(WrappedComponent, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber:
|
|
164
|
+
React__namespace.createElement(Profiler, { ...options, name: componentDisplayName, updateProps: props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 163}}
|
|
165
|
+
, React__namespace.createElement(WrappedComponent, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 164}} )
|
|
162
166
|
)
|
|
163
167
|
);
|
|
164
168
|
|
|
@@ -193,8 +197,10 @@ function useProfiler(
|
|
|
193
197
|
name: `<${name}>`,
|
|
194
198
|
onlyIfParent: true,
|
|
195
199
|
op: constants.REACT_MOUNT_OP,
|
|
196
|
-
|
|
197
|
-
|
|
200
|
+
attributes: {
|
|
201
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',
|
|
202
|
+
'ui.component_name': name,
|
|
203
|
+
},
|
|
198
204
|
});
|
|
199
205
|
});
|
|
200
206
|
|
|
@@ -205,16 +211,18 @@ function useProfiler(
|
|
|
205
211
|
|
|
206
212
|
return () => {
|
|
207
213
|
if (mountSpan && options.hasRenderSpan) {
|
|
208
|
-
const
|
|
214
|
+
const startTime = core.spanToJSON(mountSpan).timestamp;
|
|
209
215
|
const endTimestamp = utils.timestampInSeconds();
|
|
210
216
|
|
|
211
217
|
const renderSpan = browser.startInactiveSpan({
|
|
212
218
|
name: `<${name}>`,
|
|
213
219
|
onlyIfParent: true,
|
|
214
220
|
op: constants.REACT_RENDER_OP,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
221
|
+
startTime,
|
|
222
|
+
attributes: {
|
|
223
|
+
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',
|
|
224
|
+
'ui.component_name': name,
|
|
225
|
+
},
|
|
218
226
|
});
|
|
219
227
|
if (renderSpan) {
|
|
220
228
|
// Have to cast to Span because the type of _mountSpan is Span | undefined
|
package/cjs/profiler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profiler.js","sources":["../../src/profiler.tsx"],"sourcesContent":["import { startInactiveSpan } from '@sentry/browser';\nimport { spanToJSON, withActiveSpan } from '@sentry/core';\nimport type { Span } from '@sentry/types';\nimport { timestampInSeconds } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { REACT_MOUNT_OP, REACT_RENDER_OP, REACT_UPDATE_OP } from './constants';\n\nexport const UNKNOWN_COMPONENT = 'unknown';\n\nexport type ProfilerProps = {\n // The name of the component being profiled.\n name: string;\n // If the Profiler is disabled. False by default. This is useful if you want to disable profilers\n // in certain environments.\n disabled?: boolean;\n // If time component is on page should be displayed as spans. True by default.\n includeRender?: boolean;\n // If component updates should be displayed as spans. True by default.\n includeUpdates?: boolean;\n // Component that is being profiled.\n children?: React.ReactNode;\n // props given to component being profiled.\n updateProps: { [key: string]: unknown };\n};\n\n/**\n * The Profiler component leverages Sentry's Tracing integration to generate\n * spans based on component lifecycles.\n */\nclass Profiler extends React.Component<ProfilerProps> {\n /**\n * The span of the mount activity\n * Made protected for the React Native SDK to access\n */\n protected _mountSpan: Span | undefined;\n /**\n * The span that represents the duration of time between shouldComponentUpdate and componentDidUpdate\n */\n protected _updateSpan: Span | undefined;\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n public static defaultProps: Partial<ProfilerProps> = {\n disabled: false,\n includeRender: true,\n includeUpdates: true,\n };\n\n public constructor(props: ProfilerProps) {\n super(props);\n const { name, disabled = false } = this.props;\n\n if (disabled) {\n return;\n }\n\n this._mountSpan = startInactiveSpan({\n name: `<${name}>`,\n onlyIfParent: true,\n op: REACT_MOUNT_OP,\n origin: 'auto.ui.react.profiler',\n attributes: { 'ui.component_name': name },\n });\n }\n\n // If a component mounted, we can finish the mount activity.\n public componentDidMount(): void {\n if (this._mountSpan) {\n this._mountSpan.end();\n }\n }\n\n public shouldComponentUpdate({ updateProps, includeUpdates = true }: ProfilerProps): boolean {\n // Only generate an update span if includeUpdates is true, if there is a valid mountSpan,\n // and if the updateProps have changed. It is ok to not do a deep equality check here as it is expensive.\n // We are just trying to give baseline clues for further investigation.\n if (includeUpdates && this._mountSpan && updateProps !== this.props.updateProps) {\n // See what props haved changed between the previous props, and the current props. This is\n // set as data on the span. We just store the prop keys as the values could be potenially very large.\n const changedProps = Object.keys(updateProps).filter(k => updateProps[k] !== this.props.updateProps[k]);\n if (changedProps.length > 0) {\n const now = timestampInSeconds();\n this._updateSpan = withActiveSpan(this._mountSpan, () => {\n return startInactiveSpan({\n name: `<${this.props.name}>`,\n onlyIfParent: true,\n op: REACT_UPDATE_OP,\n origin: 'auto.ui.react.profiler',\n startTimestamp: now,\n attributes: {\n 'ui.component_name': this.props.name,\n 'ui.react.changed_props': changedProps,\n },\n });\n });\n }\n }\n\n return true;\n }\n\n public componentDidUpdate(): void {\n if (this._updateSpan) {\n this._updateSpan.end();\n this._updateSpan = undefined;\n }\n }\n\n // If a component is unmounted, we can say it is no longer on the screen.\n // This means we can finish the span representing the component render.\n public componentWillUnmount(): void {\n const endTimestamp = timestampInSeconds();\n const { name, includeRender = true } = this.props;\n\n if (this._mountSpan && includeRender) {\n const startTimestamp = spanToJSON(this._mountSpan).timestamp;\n withActiveSpan(this._mountSpan, () => {\n const renderSpan = startInactiveSpan({\n onlyIfParent: true,\n name: `<${name}>`,\n op: REACT_RENDER_OP,\n origin: 'auto.ui.react.profiler',\n startTimestamp,\n attributes: { 'ui.component_name': name },\n });\n if (renderSpan) {\n // Have to cast to Span because the type of _mountSpan is Span | undefined\n // and not getting narrowed properly\n renderSpan.end(endTimestamp);\n }\n });\n }\n }\n\n public render(): React.ReactNode {\n return this.props.children;\n }\n}\n\n/**\n * withProfiler is a higher order component that wraps a\n * component in a {@link Profiler} component. It is recommended that\n * the higher order component be used over the regular {@link Profiler} component.\n *\n * @param WrappedComponent component that is wrapped by Profiler\n * @param options the {@link ProfilerProps} you can pass into the Profiler\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withProfiler<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n // We do not want to have `updateProps` given in options, it is instead filled through the HOC.\n options?: Pick<Partial<ProfilerProps>, Exclude<keyof ProfilerProps, 'updateProps' | 'children'>>,\n): React.FC<P> {\n const componentDisplayName =\n (options && options.name) || WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;\n\n const Wrapped: React.FC<P> = (props: P) => (\n <Profiler {...options} name={componentDisplayName} updateProps={props}>\n <WrappedComponent {...props} />\n </Profiler>\n );\n\n Wrapped.displayName = `profiler(${componentDisplayName})`;\n\n // Copy over static methods from Wrapped component to Profiler HOC\n // See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over\n hoistNonReactStatics(Wrapped, WrappedComponent);\n return Wrapped;\n}\n\n/**\n *\n * `useProfiler` is a React hook that profiles a React component.\n *\n * Requires React 16.8 or above.\n * @param name displayName of component being profiled\n */\nfunction useProfiler(\n name: string,\n options: { disabled?: boolean; hasRenderSpan?: boolean } = {\n disabled: false,\n hasRenderSpan: true,\n },\n): void {\n const [mountSpan] = React.useState(() => {\n if (options && options.disabled) {\n return undefined;\n }\n\n return startInactiveSpan({\n name: `<${name}>`,\n onlyIfParent: true,\n op: REACT_MOUNT_OP,\n origin: 'auto.ui.react.profiler',\n attributes: { 'ui.component_name': name },\n });\n });\n\n React.useEffect(() => {\n if (mountSpan) {\n mountSpan.end();\n }\n\n return (): void => {\n if (mountSpan && options.hasRenderSpan) {\n const startTimestamp = spanToJSON(mountSpan).timestamp;\n const endTimestamp = timestampInSeconds();\n\n const renderSpan = startInactiveSpan({\n name: `<${name}>`,\n onlyIfParent: true,\n op: REACT_RENDER_OP,\n origin: 'auto.ui.react.profiler',\n startTimestamp,\n attributes: { 'ui.component_name': name },\n });\n if (renderSpan) {\n // Have to cast to Span because the type of _mountSpan is Span | undefined\n // and not getting narrowed properly\n renderSpan.end(endTimestamp);\n }\n }\n };\n // We only want this to run once.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n}\n\nexport { withProfiler, Profiler, useProfiler };\n"],"names":["React","startInactiveSpan","REACT_MOUNT_OP","timestampInSeconds","withActiveSpan","REACT_UPDATE_OP","spanToJSON","REACT_RENDER_OP","hoistNonReactStatics"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"profiler.js","sources":["../../src/profiler.tsx"],"sourcesContent":["import { startInactiveSpan } from '@sentry/browser';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, spanToJSON, withActiveSpan } from '@sentry/core';\nimport type { Span } from '@sentry/types';\nimport { timestampInSeconds } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { REACT_MOUNT_OP, REACT_RENDER_OP, REACT_UPDATE_OP } from './constants';\n\nexport const UNKNOWN_COMPONENT = 'unknown';\n\nexport type ProfilerProps = {\n // The name of the component being profiled.\n name: string;\n // If the Profiler is disabled. False by default. This is useful if you want to disable profilers\n // in certain environments.\n disabled?: boolean;\n // If time component is on page should be displayed as spans. True by default.\n includeRender?: boolean;\n // If component updates should be displayed as spans. True by default.\n includeUpdates?: boolean;\n // Component that is being profiled.\n children?: React.ReactNode;\n // props given to component being profiled.\n updateProps: { [key: string]: unknown };\n};\n\n/**\n * The Profiler component leverages Sentry's Tracing integration to generate\n * spans based on component lifecycles.\n */\nclass Profiler extends React.Component<ProfilerProps> {\n /**\n * The span of the mount activity\n * Made protected for the React Native SDK to access\n */\n protected _mountSpan: Span | undefined;\n /**\n * The span that represents the duration of time between shouldComponentUpdate and componentDidUpdate\n */\n protected _updateSpan: Span | undefined;\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n public static defaultProps: Partial<ProfilerProps> = {\n disabled: false,\n includeRender: true,\n includeUpdates: true,\n };\n\n public constructor(props: ProfilerProps) {\n super(props);\n const { name, disabled = false } = this.props;\n\n if (disabled) {\n return;\n }\n\n this._mountSpan = startInactiveSpan({\n name: `<${name}>`,\n onlyIfParent: true,\n op: REACT_MOUNT_OP,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',\n 'ui.component_name': name,\n },\n });\n }\n\n // If a component mounted, we can finish the mount activity.\n public componentDidMount(): void {\n if (this._mountSpan) {\n this._mountSpan.end();\n }\n }\n\n public shouldComponentUpdate({ updateProps, includeUpdates = true }: ProfilerProps): boolean {\n // Only generate an update span if includeUpdates is true, if there is a valid mountSpan,\n // and if the updateProps have changed. It is ok to not do a deep equality check here as it is expensive.\n // We are just trying to give baseline clues for further investigation.\n if (includeUpdates && this._mountSpan && updateProps !== this.props.updateProps) {\n // See what props haved changed between the previous props, and the current props. This is\n // set as data on the span. We just store the prop keys as the values could be potenially very large.\n const changedProps = Object.keys(updateProps).filter(k => updateProps[k] !== this.props.updateProps[k]);\n if (changedProps.length > 0) {\n const now = timestampInSeconds();\n this._updateSpan = withActiveSpan(this._mountSpan, () => {\n return startInactiveSpan({\n name: `<${this.props.name}>`,\n onlyIfParent: true,\n op: REACT_UPDATE_OP,\n startTime: now,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',\n 'ui.component_name': this.props.name,\n 'ui.react.changed_props': changedProps,\n },\n });\n });\n }\n }\n\n return true;\n }\n\n public componentDidUpdate(): void {\n if (this._updateSpan) {\n this._updateSpan.end();\n this._updateSpan = undefined;\n }\n }\n\n // If a component is unmounted, we can say it is no longer on the screen.\n // This means we can finish the span representing the component render.\n public componentWillUnmount(): void {\n const endTimestamp = timestampInSeconds();\n const { name, includeRender = true } = this.props;\n\n if (this._mountSpan && includeRender) {\n const startTime = spanToJSON(this._mountSpan).timestamp;\n withActiveSpan(this._mountSpan, () => {\n const renderSpan = startInactiveSpan({\n onlyIfParent: true,\n name: `<${name}>`,\n op: REACT_RENDER_OP,\n startTime,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',\n 'ui.component_name': name,\n },\n });\n if (renderSpan) {\n // Have to cast to Span because the type of _mountSpan is Span | undefined\n // and not getting narrowed properly\n renderSpan.end(endTimestamp);\n }\n });\n }\n }\n\n public render(): React.ReactNode {\n return this.props.children;\n }\n}\n\n/**\n * withProfiler is a higher order component that wraps a\n * component in a {@link Profiler} component. It is recommended that\n * the higher order component be used over the regular {@link Profiler} component.\n *\n * @param WrappedComponent component that is wrapped by Profiler\n * @param options the {@link ProfilerProps} you can pass into the Profiler\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction withProfiler<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n // We do not want to have `updateProps` given in options, it is instead filled through the HOC.\n options?: Pick<Partial<ProfilerProps>, Exclude<keyof ProfilerProps, 'updateProps' | 'children'>>,\n): React.FC<P> {\n const componentDisplayName =\n (options && options.name) || WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;\n\n const Wrapped: React.FC<P> = (props: P) => (\n <Profiler {...options} name={componentDisplayName} updateProps={props}>\n <WrappedComponent {...props} />\n </Profiler>\n );\n\n Wrapped.displayName = `profiler(${componentDisplayName})`;\n\n // Copy over static methods from Wrapped component to Profiler HOC\n // See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over\n hoistNonReactStatics(Wrapped, WrappedComponent);\n return Wrapped;\n}\n\n/**\n *\n * `useProfiler` is a React hook that profiles a React component.\n *\n * Requires React 16.8 or above.\n * @param name displayName of component being profiled\n */\nfunction useProfiler(\n name: string,\n options: { disabled?: boolean; hasRenderSpan?: boolean } = {\n disabled: false,\n hasRenderSpan: true,\n },\n): void {\n const [mountSpan] = React.useState(() => {\n if (options && options.disabled) {\n return undefined;\n }\n\n return startInactiveSpan({\n name: `<${name}>`,\n onlyIfParent: true,\n op: REACT_MOUNT_OP,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',\n 'ui.component_name': name,\n },\n });\n });\n\n React.useEffect(() => {\n if (mountSpan) {\n mountSpan.end();\n }\n\n return (): void => {\n if (mountSpan && options.hasRenderSpan) {\n const startTime = spanToJSON(mountSpan).timestamp;\n const endTimestamp = timestampInSeconds();\n\n const renderSpan = startInactiveSpan({\n name: `<${name}>`,\n onlyIfParent: true,\n op: REACT_RENDER_OP,\n startTime,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.react.profiler',\n 'ui.component_name': name,\n },\n });\n if (renderSpan) {\n // Have to cast to Span because the type of _mountSpan is Span | undefined\n // and not getting narrowed properly\n renderSpan.end(endTimestamp);\n }\n }\n };\n // We only want this to run once.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n}\n\nexport { withProfiler, Profiler, useProfiler };\n"],"names":["React","startInactiveSpan","REACT_MOUNT_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","timestampInSeconds","withActiveSpan","REACT_UPDATE_OP","spanToJSON","REACT_RENDER_OP","hoistNonReactStatics"],"mappings":"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"}
|
package/cjs/reactrouter.js
CHANGED
|
@@ -58,8 +58,7 @@ function reactRouterV4BrowserTracingIntegration(
|
|
|
58
58
|
return undefined;
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
const instrumentation = reactRouterV4Instrumentation(history, routes, matchPath);
|
|
61
|
+
const instrumentation = createReactRouterInstrumentation(history, 'reactrouter_v4', routes, matchPath);
|
|
63
62
|
|
|
64
63
|
// Now instrument page load & navigation with correct settings
|
|
65
64
|
instrumentation(startPageloadCallback, instrumentPageLoad, false);
|
|
@@ -98,8 +97,7 @@ function reactRouterV5BrowserTracingIntegration(
|
|
|
98
97
|
return undefined;
|
|
99
98
|
};
|
|
100
99
|
|
|
101
|
-
|
|
102
|
-
const instrumentation = reactRouterV5Instrumentation(history, routes, matchPath);
|
|
100
|
+
const instrumentation = createReactRouterInstrumentation(history, 'reactrouter_v5', routes, matchPath);
|
|
103
101
|
|
|
104
102
|
// Now instrument page load & navigation with correct settings
|
|
105
103
|
instrumentation(startPageloadCallback, options.instrumentPageLoad, false);
|
|
@@ -108,28 +106,6 @@ function reactRouterV5BrowserTracingIntegration(
|
|
|
108
106
|
};
|
|
109
107
|
}
|
|
110
108
|
|
|
111
|
-
/**
|
|
112
|
-
* @deprecated Use `browserTracingReactRouterV4()` instead.
|
|
113
|
-
*/
|
|
114
|
-
function reactRouterV4Instrumentation(
|
|
115
|
-
history,
|
|
116
|
-
routes,
|
|
117
|
-
matchPath,
|
|
118
|
-
) {
|
|
119
|
-
return createReactRouterInstrumentation(history, 'reactrouter_v4', routes, matchPath);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* @deprecated Use `browserTracingReactRouterV5()` instead.
|
|
124
|
-
*/
|
|
125
|
-
function reactRouterV5Instrumentation(
|
|
126
|
-
history,
|
|
127
|
-
routes,
|
|
128
|
-
matchPath,
|
|
129
|
-
) {
|
|
130
|
-
return createReactRouterInstrumentation(history, 'reactrouter_v5', routes, matchPath);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
109
|
function createReactRouterInstrumentation(
|
|
134
110
|
history,
|
|
135
111
|
instrumentationName,
|
|
@@ -257,7 +233,7 @@ function withSentryRouting(Route) {
|
|
|
257
233
|
// @ts-expect-error Setting more specific React Component typing for `R` generic above
|
|
258
234
|
// will break advanced type inference done by react router params:
|
|
259
235
|
// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164
|
|
260
|
-
return React__namespace.createElement(Route, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber:
|
|
236
|
+
return React__namespace.createElement(Route, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 253}} );
|
|
261
237
|
};
|
|
262
238
|
|
|
263
239
|
WrappedRoute.displayName = `sentryRoute(${componentDisplayName})`;
|
|
@@ -289,8 +265,6 @@ function getActiveRootSpan() {
|
|
|
289
265
|
}
|
|
290
266
|
|
|
291
267
|
exports.reactRouterV4BrowserTracingIntegration = reactRouterV4BrowserTracingIntegration;
|
|
292
|
-
exports.reactRouterV4Instrumentation = reactRouterV4Instrumentation;
|
|
293
268
|
exports.reactRouterV5BrowserTracingIntegration = reactRouterV5BrowserTracingIntegration;
|
|
294
|
-
exports.reactRouterV5Instrumentation = reactRouterV5Instrumentation;
|
|
295
269
|
exports.withSentryRouting = withSentryRouting;
|
|
296
270
|
//# sourceMappingURL=reactrouter.js.map
|
package/cjs/reactrouter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactrouter.js","sources":["../../src/reactrouter.tsx"],"sourcesContent":["import {\n WINDOW,\n browserTracingIntegration,\n startBrowserTracingNavigationSpan,\n startBrowserTracingPageLoadSpan,\n} from '@sentry/browser';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n getActiveSpan,\n getRootSpan,\n spanToJSON,\n} from '@sentry/core';\nimport type { Integration, Span, StartSpanOptions, Transaction, TransactionSource } from '@sentry/types';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport type { Action, Location, ReactRouterInstrumentation } from './types';\n\n// We need to disable eslint no-explict-any because any is required for the\n// react-router typings.\ntype Match = { path: string; url: string; params: Record<string, any>; isExact: boolean }; // eslint-disable-line @typescript-eslint/no-explicit-any\n\nexport type RouterHistory = {\n location?: Location;\n listen?(cb: (location: Location, action: Action) => void): void;\n} & Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n\nexport type RouteConfig = {\n [propName: string]: unknown;\n path?: string | string[];\n exact?: boolean;\n component?: JSX.Element;\n routes?: RouteConfig[];\n};\n\nexport type MatchPath = (pathname: string, props: string | string[] | any, parent?: Match | null) => Match | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n\ninterface ReactRouterOptions {\n history: RouterHistory;\n routes?: RouteConfig[];\n matchPath?: MatchPath;\n}\n\nlet activeTransaction: Transaction | undefined;\n\n/**\n * A browser tracing integration that uses React Router v4 to instrument navigations.\n * Expects `history` (and optionally `routes` and `matchPath`) to be passed as options.\n */\nexport function reactRouterV4BrowserTracingIntegration(\n options: Parameters<typeof browserTracingIntegration>[0] & ReactRouterOptions,\n): Integration {\n const integration = browserTracingIntegration({\n ...options,\n instrumentPageLoad: false,\n instrumentNavigation: false,\n });\n\n const { history, routes, matchPath, instrumentPageLoad = true, instrumentNavigation = true } = options;\n\n return {\n ...integration,\n afterAllSetup(client) {\n integration.afterAllSetup(client);\n\n const startPageloadCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingPageLoadSpan(client, startSpanOptions);\n return undefined;\n };\n\n const startNavigationCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingNavigationSpan(client, startSpanOptions);\n return undefined;\n };\n\n // eslint-disable-next-line deprecation/deprecation\n const instrumentation = reactRouterV4Instrumentation(history, routes, matchPath);\n\n // Now instrument page load & navigation with correct settings\n instrumentation(startPageloadCallback, instrumentPageLoad, false);\n instrumentation(startNavigationCallback, false, instrumentNavigation);\n },\n };\n}\n\n/**\n * A browser tracing integration that uses React Router v5 to instrument navigations.\n * Expects `history` (and optionally `routes` and `matchPath`) to be passed as options.\n */\nexport function reactRouterV5BrowserTracingIntegration(\n options: Parameters<typeof browserTracingIntegration>[0] & ReactRouterOptions,\n): Integration {\n const integration = browserTracingIntegration({\n ...options,\n instrumentPageLoad: false,\n instrumentNavigation: false,\n });\n\n const { history, routes, matchPath } = options;\n\n return {\n ...integration,\n afterAllSetup(client) {\n integration.afterAllSetup(client);\n\n const startPageloadCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingPageLoadSpan(client, startSpanOptions);\n return undefined;\n };\n\n const startNavigationCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingNavigationSpan(client, startSpanOptions);\n return undefined;\n };\n\n // eslint-disable-next-line deprecation/deprecation\n const instrumentation = reactRouterV5Instrumentation(history, routes, matchPath);\n\n // Now instrument page load & navigation with correct settings\n instrumentation(startPageloadCallback, options.instrumentPageLoad, false);\n instrumentation(startNavigationCallback, false, options.instrumentNavigation);\n },\n };\n}\n\n/**\n * @deprecated Use `browserTracingReactRouterV4()` instead.\n */\nexport function reactRouterV4Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'reactrouter_v4', routes, matchPath);\n}\n\n/**\n * @deprecated Use `browserTracingReactRouterV5()` instead.\n */\nexport function reactRouterV5Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'reactrouter_v5', routes, matchPath);\n}\n\nfunction createReactRouterInstrumentation(\n history: RouterHistory,\n instrumentationName: string,\n allRoutes: RouteConfig[] = [],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n function getInitPathName(): string | undefined {\n if (history && history.location) {\n return history.location.pathname;\n }\n\n if (WINDOW && WINDOW.location) {\n return WINDOW.location.pathname;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a transaction name. Returns the new name as well as the\n * source of the transaction.\n *\n * @param pathname The initial pathname we normalize\n */\n function normalizeTransactionName(pathname: string): [string, TransactionSource] {\n if (allRoutes.length === 0 || !matchPath) {\n return [pathname, 'url'];\n }\n\n const branches = matchRoutes(allRoutes, pathname, matchPath);\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n if (branches[x].match.isExact) {\n return [branches[x].match.path, 'route'];\n }\n }\n\n return [pathname, 'url'];\n }\n\n return (customStartTransaction, startTransactionOnPageLoad = true, startTransactionOnLocationChange = true): void => {\n const initPathName = getInitPathName();\n\n if (startTransactionOnPageLoad && initPathName) {\n const [name, source] = normalizeTransactionName(initPathName);\n activeTransaction = customStartTransaction({\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.pageload.react.${instrumentationName}`,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n },\n });\n }\n\n if (startTransactionOnLocationChange && history.listen) {\n history.listen((location, action) => {\n if (action && (action === 'PUSH' || action === 'POP')) {\n if (activeTransaction) {\n activeTransaction.end();\n }\n\n const [name, source] = normalizeTransactionName(location.pathname);\n activeTransaction = customStartTransaction({\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.navigation.react.${instrumentationName}`,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n },\n });\n }\n });\n }\n };\n}\n\n/**\n * Matches a set of routes to a pathname\n * Based on implementation from\n */\nfunction matchRoutes(\n routes: RouteConfig[],\n pathname: string,\n matchPath: MatchPath,\n branch: Array<{ route: RouteConfig; match: Match }> = [],\n): Array<{ route: RouteConfig; match: Match }> {\n routes.some(route => {\n const match = route.path\n ? matchPath(pathname, route)\n : branch.length\n ? branch[branch.length - 1].match // use parent match\n : computeRootMatch(pathname); // use default \"root\" match\n\n if (match) {\n branch.push({ route, match });\n\n if (route.routes) {\n matchRoutes(route.routes, pathname, matchPath, branch);\n }\n }\n\n return !!match;\n });\n\n return branch;\n}\n\nfunction computeRootMatch(pathname: string): Match {\n return { path: '/', url: '/', params: {}, isExact: pathname === '/' };\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\nexport function withSentryRouting<P extends Record<string, any>, R extends React.ComponentType<P>>(Route: R): R {\n const componentDisplayName = (Route as any).displayName || (Route as any).name;\n\n const activeRootSpan = getActiveRootSpan();\n\n const WrappedRoute: React.FC<P> = (props: P) => {\n if (activeRootSpan && props && props.computedMatch && props.computedMatch.isExact) {\n activeRootSpan.updateName(props.computedMatch.path);\n activeRootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n\n // @ts-expect-error Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return <Route {...props} />;\n };\n\n WrappedRoute.displayName = `sentryRoute(${componentDisplayName})`;\n hoistNonReactStatics(WrappedRoute, Route);\n // @ts-expect-error Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return WrappedRoute;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\n\nfunction getActiveRootSpan(): Span | undefined {\n // Legacy behavior for \"old\" react router instrumentation\n if (activeTransaction) {\n return activeTransaction;\n }\n\n const span = getActiveSpan();\n const rootSpan = span ? getRootSpan(span) : undefined;\n\n if (!rootSpan) {\n return undefined;\n }\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n"],"names":["browserTracingIntegration","startBrowserTracingPageLoadSpan","startBrowserTracingNavigationSpan","WINDOW","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","React","hoistNonReactStatics","getActiveSpan","getRootSpan","spanToJSON"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reactrouter.js","sources":["../../src/reactrouter.tsx"],"sourcesContent":["import {\n WINDOW,\n browserTracingIntegration,\n startBrowserTracingNavigationSpan,\n startBrowserTracingPageLoadSpan,\n} from '@sentry/browser';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n getActiveSpan,\n getRootSpan,\n spanToJSON,\n} from '@sentry/core';\nimport type { Integration, Span, StartSpanOptions, Transaction, TransactionSource } from '@sentry/types';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport type { Action, Location, ReactRouterInstrumentation } from './types';\n\n// We need to disable eslint no-explict-any because any is required for the\n// react-router typings.\ntype Match = { path: string; url: string; params: Record<string, any>; isExact: boolean }; // eslint-disable-line @typescript-eslint/no-explicit-any\n\nexport type RouterHistory = {\n location?: Location;\n listen?(cb: (location: Location, action: Action) => void): void;\n} & Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n\nexport type RouteConfig = {\n [propName: string]: unknown;\n path?: string | string[];\n exact?: boolean;\n component?: JSX.Element;\n routes?: RouteConfig[];\n};\n\nexport type MatchPath = (pathname: string, props: string | string[] | any, parent?: Match | null) => Match | null; // eslint-disable-line @typescript-eslint/no-explicit-any\n\ninterface ReactRouterOptions {\n history: RouterHistory;\n routes?: RouteConfig[];\n matchPath?: MatchPath;\n}\n\nlet activeTransaction: Transaction | undefined;\n\n/**\n * A browser tracing integration that uses React Router v4 to instrument navigations.\n * Expects `history` (and optionally `routes` and `matchPath`) to be passed as options.\n */\nexport function reactRouterV4BrowserTracingIntegration(\n options: Parameters<typeof browserTracingIntegration>[0] & ReactRouterOptions,\n): Integration {\n const integration = browserTracingIntegration({\n ...options,\n instrumentPageLoad: false,\n instrumentNavigation: false,\n });\n\n const { history, routes, matchPath, instrumentPageLoad = true, instrumentNavigation = true } = options;\n\n return {\n ...integration,\n afterAllSetup(client) {\n integration.afterAllSetup(client);\n\n const startPageloadCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingPageLoadSpan(client, startSpanOptions);\n return undefined;\n };\n\n const startNavigationCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingNavigationSpan(client, startSpanOptions);\n return undefined;\n };\n\n const instrumentation = createReactRouterInstrumentation(history, 'reactrouter_v4', routes, matchPath);\n\n // Now instrument page load & navigation with correct settings\n instrumentation(startPageloadCallback, instrumentPageLoad, false);\n instrumentation(startNavigationCallback, false, instrumentNavigation);\n },\n };\n}\n\n/**\n * A browser tracing integration that uses React Router v5 to instrument navigations.\n * Expects `history` (and optionally `routes` and `matchPath`) to be passed as options.\n */\nexport function reactRouterV5BrowserTracingIntegration(\n options: Parameters<typeof browserTracingIntegration>[0] & ReactRouterOptions,\n): Integration {\n const integration = browserTracingIntegration({\n ...options,\n instrumentPageLoad: false,\n instrumentNavigation: false,\n });\n\n const { history, routes, matchPath } = options;\n\n return {\n ...integration,\n afterAllSetup(client) {\n integration.afterAllSetup(client);\n\n const startPageloadCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingPageLoadSpan(client, startSpanOptions);\n return undefined;\n };\n\n const startNavigationCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingNavigationSpan(client, startSpanOptions);\n return undefined;\n };\n\n const instrumentation = createReactRouterInstrumentation(history, 'reactrouter_v5', routes, matchPath);\n\n // Now instrument page load & navigation with correct settings\n instrumentation(startPageloadCallback, options.instrumentPageLoad, false);\n instrumentation(startNavigationCallback, false, options.instrumentNavigation);\n },\n };\n}\n\nfunction createReactRouterInstrumentation(\n history: RouterHistory,\n instrumentationName: string,\n allRoutes: RouteConfig[] = [],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n function getInitPathName(): string | undefined {\n if (history && history.location) {\n return history.location.pathname;\n }\n\n if (WINDOW && WINDOW.location) {\n return WINDOW.location.pathname;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a transaction name. Returns the new name as well as the\n * source of the transaction.\n *\n * @param pathname The initial pathname we normalize\n */\n function normalizeTransactionName(pathname: string): [string, TransactionSource] {\n if (allRoutes.length === 0 || !matchPath) {\n return [pathname, 'url'];\n }\n\n const branches = matchRoutes(allRoutes, pathname, matchPath);\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n if (branches[x].match.isExact) {\n return [branches[x].match.path, 'route'];\n }\n }\n\n return [pathname, 'url'];\n }\n\n return (customStartTransaction, startTransactionOnPageLoad = true, startTransactionOnLocationChange = true): void => {\n const initPathName = getInitPathName();\n\n if (startTransactionOnPageLoad && initPathName) {\n const [name, source] = normalizeTransactionName(initPathName);\n activeTransaction = customStartTransaction({\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.pageload.react.${instrumentationName}`,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n },\n });\n }\n\n if (startTransactionOnLocationChange && history.listen) {\n history.listen((location, action) => {\n if (action && (action === 'PUSH' || action === 'POP')) {\n if (activeTransaction) {\n activeTransaction.end();\n }\n\n const [name, source] = normalizeTransactionName(location.pathname);\n activeTransaction = customStartTransaction({\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.navigation.react.${instrumentationName}`,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n },\n });\n }\n });\n }\n };\n}\n\n/**\n * Matches a set of routes to a pathname\n * Based on implementation from\n */\nfunction matchRoutes(\n routes: RouteConfig[],\n pathname: string,\n matchPath: MatchPath,\n branch: Array<{ route: RouteConfig; match: Match }> = [],\n): Array<{ route: RouteConfig; match: Match }> {\n routes.some(route => {\n const match = route.path\n ? matchPath(pathname, route)\n : branch.length\n ? branch[branch.length - 1].match // use parent match\n : computeRootMatch(pathname); // use default \"root\" match\n\n if (match) {\n branch.push({ route, match });\n\n if (route.routes) {\n matchRoutes(route.routes, pathname, matchPath, branch);\n }\n }\n\n return !!match;\n });\n\n return branch;\n}\n\nfunction computeRootMatch(pathname: string): Match {\n return { path: '/', url: '/', params: {}, isExact: pathname === '/' };\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\nexport function withSentryRouting<P extends Record<string, any>, R extends React.ComponentType<P>>(Route: R): R {\n const componentDisplayName = (Route as any).displayName || (Route as any).name;\n\n const activeRootSpan = getActiveRootSpan();\n\n const WrappedRoute: React.FC<P> = (props: P) => {\n if (activeRootSpan && props && props.computedMatch && props.computedMatch.isExact) {\n activeRootSpan.updateName(props.computedMatch.path);\n activeRootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n\n // @ts-expect-error Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return <Route {...props} />;\n };\n\n WrappedRoute.displayName = `sentryRoute(${componentDisplayName})`;\n hoistNonReactStatics(WrappedRoute, Route);\n // @ts-expect-error Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return WrappedRoute;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\n\nfunction getActiveRootSpan(): Span | undefined {\n // Legacy behavior for \"old\" react router instrumentation\n if (activeTransaction) {\n return activeTransaction;\n }\n\n const span = getActiveSpan();\n const rootSpan = span ? getRootSpan(span) : undefined;\n\n if (!rootSpan) {\n return undefined;\n }\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n"],"names":["browserTracingIntegration","startBrowserTracingPageLoadSpan","startBrowserTracingNavigationSpan","WINDOW","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","React","hoistNonReactStatics","getActiveSpan","getRootSpan","spanToJSON"],"mappings":"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"}
|
package/cjs/reactrouterv3.js
CHANGED
|
@@ -36,7 +36,6 @@ function reactRouterV3BrowserTracingIntegration(
|
|
|
36
36
|
return undefined;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
40
39
|
const instrumentation = reactRouterV3Instrumentation(history, routes, match);
|
|
41
40
|
|
|
42
41
|
// Now instrument page load & navigation with correct settings
|
|
@@ -53,14 +52,8 @@ function reactRouterV3BrowserTracingIntegration(
|
|
|
53
52
|
* @param history object from the `history` library
|
|
54
53
|
* @param routes a list of all routes, should be
|
|
55
54
|
* @param match `Router.match` utility
|
|
56
|
-
*
|
|
57
|
-
* @deprecated Use `reactRouterV3BrowserTracingIntegration()` instead
|
|
58
55
|
*/
|
|
59
|
-
function reactRouterV3Instrumentation(
|
|
60
|
-
history,
|
|
61
|
-
routes,
|
|
62
|
-
match,
|
|
63
|
-
) {
|
|
56
|
+
function reactRouterV3Instrumentation(history, routes, match) {
|
|
64
57
|
return (
|
|
65
58
|
startTransaction,
|
|
66
59
|
startTransactionOnPageLoad = true,
|
|
@@ -173,5 +166,4 @@ function getRouteStringFromRoutes(routes) {
|
|
|
173
166
|
}
|
|
174
167
|
|
|
175
168
|
exports.reactRouterV3BrowserTracingIntegration = reactRouterV3BrowserTracingIntegration;
|
|
176
|
-
exports.reactRouterV3Instrumentation = reactRouterV3Instrumentation;
|
|
177
169
|
//# sourceMappingURL=reactrouterv3.js.map
|
package/cjs/reactrouterv3.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactrouterv3.js","sources":["../../src/reactrouterv3.ts"],"sourcesContent":["import {\n WINDOW,\n browserTracingIntegration,\n startBrowserTracingNavigationSpan,\n startBrowserTracingPageLoadSpan,\n} from '@sentry/browser';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type {\n Integration,\n SpanAttributes,\n StartSpanOptions,\n Transaction,\n TransactionContext,\n TransactionSource,\n} from '@sentry/types';\n\nimport type { Location, ReactRouterInstrumentation } from './types';\n\n// Many of the types below had to be mocked out to prevent typescript issues\n// these types are required for correct functionality.\n\ntype HistoryV3 = {\n location?: Location;\n listen?(cb: (location: Location) => void): void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n} & Record<string, any>;\n\nexport type Route = { path?: string; childRoutes?: Route[] };\n\nexport type Match = (\n props: { location: Location; routes: Route[] },\n cb: (error?: Error, _redirectLocation?: Location, renderProps?: { routes?: Route[] }) => void,\n) => void;\n\ntype ReactRouterV3TransactionSource = Extract<TransactionSource, 'url' | 'route'>;\n\ninterface ReactRouterOptions {\n history: HistoryV3;\n routes: Route[];\n match: Match;\n}\n\n/**\n * A browser tracing integration that uses React Router v3 to instrument navigations.\n * Expects `history` (and optionally `routes` and `matchPath`) to be passed as options.\n */\nexport function reactRouterV3BrowserTracingIntegration(\n options: Parameters<typeof browserTracingIntegration>[0] & ReactRouterOptions,\n): Integration {\n const integration = browserTracingIntegration({\n ...options,\n instrumentPageLoad: false,\n instrumentNavigation: false,\n });\n\n const { history, routes, match, instrumentPageLoad = true, instrumentNavigation = true } = options;\n\n return {\n ...integration,\n afterAllSetup(client) {\n integration.afterAllSetup(client);\n\n const startPageloadCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingPageLoadSpan(client, startSpanOptions);\n return undefined;\n };\n\n const startNavigationCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingNavigationSpan(client, startSpanOptions);\n return undefined;\n };\n\n // eslint-disable-next-line deprecation/deprecation\n const instrumentation = reactRouterV3Instrumentation(history, routes, match);\n\n // Now instrument page load & navigation with correct settings\n instrumentation(startPageloadCallback, instrumentPageLoad, false);\n instrumentation(startNavigationCallback, false, instrumentNavigation);\n },\n };\n}\n\n/**\n * Creates routing instrumentation for React Router v3\n * Works for React Router >= 3.2.0 and < 4.0.0\n *\n * @param history object from the `history` library\n * @param routes a list of all routes, should be\n * @param match `Router.match` utility\n *\n * @deprecated Use `reactRouterV3BrowserTracingIntegration()` instead\n */\nexport function reactRouterV3Instrumentation(\n history: HistoryV3,\n routes: Route[],\n match: Match,\n): ReactRouterInstrumentation {\n return (\n startTransaction: (context: TransactionContext) => Transaction | undefined,\n startTransactionOnPageLoad: boolean = true,\n startTransactionOnLocationChange: boolean = true,\n ) => {\n let activeTransaction: Transaction | undefined;\n let prevName: string | undefined;\n\n // Have to use window.location because history.location might not be defined.\n if (startTransactionOnPageLoad && WINDOW && WINDOW.location) {\n normalizeTransactionName(\n routes,\n WINDOW.location as unknown as Location,\n match,\n (localName: string, source: ReactRouterV3TransactionSource = 'url') => {\n prevName = localName;\n activeTransaction = startTransaction({\n name: prevName,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react.reactrouter_v3',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n },\n });\n },\n );\n }\n\n if (startTransactionOnLocationChange && history.listen) {\n history.listen(location => {\n if (location.action === 'PUSH' || location.action === 'POP') {\n if (activeTransaction) {\n activeTransaction.end();\n }\n normalizeTransactionName(routes, location, match, (localName: string, source: TransactionSource = 'url') => {\n prevName = localName;\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react.reactrouter_v3',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n };\n\n activeTransaction = startTransaction({\n name: prevName,\n attributes,\n });\n });\n }\n });\n }\n };\n}\n\n/**\n * Normalize transaction names using `Router.match`\n */\nfunction normalizeTransactionName(\n appRoutes: Route[],\n location: Location,\n match: Match,\n callback: (pathname: string, source?: ReactRouterV3TransactionSource) => void,\n): void {\n let name = location.pathname;\n match(\n {\n location,\n routes: appRoutes,\n },\n (error, _redirectLocation, renderProps) => {\n if (error || !renderProps) {\n return callback(name);\n }\n\n const routePath = getRouteStringFromRoutes(renderProps.routes || []);\n if (routePath.length === 0 || routePath === '/*') {\n return callback(name);\n }\n\n name = routePath;\n return callback(name, 'route');\n },\n );\n}\n\n/**\n * Generate route name from array of routes\n */\nfunction getRouteStringFromRoutes(routes: Route[]): string {\n if (!Array.isArray(routes) || routes.length === 0) {\n return '';\n }\n\n const routesWithPaths: Route[] = routes.filter((route: Route) => !!route.path);\n\n let index = -1;\n for (let x = routesWithPaths.length - 1; x >= 0; x--) {\n const route = routesWithPaths[x];\n if (route.path && route.path.startsWith('/')) {\n index = x;\n break;\n }\n }\n\n return routesWithPaths\n .slice(index)\n .filter(({ path }) => !!path)\n .map(({ path }) => path)\n .join('');\n}\n"],"names":["browserTracingIntegration","startBrowserTracingPageLoadSpan","startBrowserTracingNavigationSpan","WINDOW","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reactrouterv3.js","sources":["../../src/reactrouterv3.ts"],"sourcesContent":["import {\n WINDOW,\n browserTracingIntegration,\n startBrowserTracingNavigationSpan,\n startBrowserTracingPageLoadSpan,\n} from '@sentry/browser';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type {\n Integration,\n SpanAttributes,\n StartSpanOptions,\n Transaction,\n TransactionContext,\n TransactionSource,\n} from '@sentry/types';\n\nimport type { Location, ReactRouterInstrumentation } from './types';\n\n// Many of the types below had to be mocked out to prevent typescript issues\n// these types are required for correct functionality.\n\ntype HistoryV3 = {\n location?: Location;\n listen?(cb: (location: Location) => void): void;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n} & Record<string, any>;\n\nexport type Route = { path?: string; childRoutes?: Route[] };\n\nexport type Match = (\n props: { location: Location; routes: Route[] },\n cb: (error?: Error, _redirectLocation?: Location, renderProps?: { routes?: Route[] }) => void,\n) => void;\n\ntype ReactRouterV3TransactionSource = Extract<TransactionSource, 'url' | 'route'>;\n\ninterface ReactRouterOptions {\n history: HistoryV3;\n routes: Route[];\n match: Match;\n}\n\n/**\n * A browser tracing integration that uses React Router v3 to instrument navigations.\n * Expects `history` (and optionally `routes` and `matchPath`) to be passed as options.\n */\nexport function reactRouterV3BrowserTracingIntegration(\n options: Parameters<typeof browserTracingIntegration>[0] & ReactRouterOptions,\n): Integration {\n const integration = browserTracingIntegration({\n ...options,\n instrumentPageLoad: false,\n instrumentNavigation: false,\n });\n\n const { history, routes, match, instrumentPageLoad = true, instrumentNavigation = true } = options;\n\n return {\n ...integration,\n afterAllSetup(client) {\n integration.afterAllSetup(client);\n\n const startPageloadCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingPageLoadSpan(client, startSpanOptions);\n return undefined;\n };\n\n const startNavigationCallback = (startSpanOptions: StartSpanOptions): undefined => {\n startBrowserTracingNavigationSpan(client, startSpanOptions);\n return undefined;\n };\n\n const instrumentation = reactRouterV3Instrumentation(history, routes, match);\n\n // Now instrument page load & navigation with correct settings\n instrumentation(startPageloadCallback, instrumentPageLoad, false);\n instrumentation(startNavigationCallback, false, instrumentNavigation);\n },\n };\n}\n\n/**\n * Creates routing instrumentation for React Router v3\n * Works for React Router >= 3.2.0 and < 4.0.0\n *\n * @param history object from the `history` library\n * @param routes a list of all routes, should be\n * @param match `Router.match` utility\n */\nfunction reactRouterV3Instrumentation(history: HistoryV3, routes: Route[], match: Match): ReactRouterInstrumentation {\n return (\n startTransaction: (context: TransactionContext) => Transaction | undefined,\n startTransactionOnPageLoad: boolean = true,\n startTransactionOnLocationChange: boolean = true,\n ) => {\n let activeTransaction: Transaction | undefined;\n let prevName: string | undefined;\n\n // Have to use window.location because history.location might not be defined.\n if (startTransactionOnPageLoad && WINDOW && WINDOW.location) {\n normalizeTransactionName(\n routes,\n WINDOW.location as unknown as Location,\n match,\n (localName: string, source: ReactRouterV3TransactionSource = 'url') => {\n prevName = localName;\n activeTransaction = startTransaction({\n name: prevName,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react.reactrouter_v3',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n },\n });\n },\n );\n }\n\n if (startTransactionOnLocationChange && history.listen) {\n history.listen(location => {\n if (location.action === 'PUSH' || location.action === 'POP') {\n if (activeTransaction) {\n activeTransaction.end();\n }\n normalizeTransactionName(routes, location, match, (localName: string, source: TransactionSource = 'url') => {\n prevName = localName;\n\n const attributes: SpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react.reactrouter_v3',\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n };\n\n activeTransaction = startTransaction({\n name: prevName,\n attributes,\n });\n });\n }\n });\n }\n };\n}\n\n/**\n * Normalize transaction names using `Router.match`\n */\nfunction normalizeTransactionName(\n appRoutes: Route[],\n location: Location,\n match: Match,\n callback: (pathname: string, source?: ReactRouterV3TransactionSource) => void,\n): void {\n let name = location.pathname;\n match(\n {\n location,\n routes: appRoutes,\n },\n (error, _redirectLocation, renderProps) => {\n if (error || !renderProps) {\n return callback(name);\n }\n\n const routePath = getRouteStringFromRoutes(renderProps.routes || []);\n if (routePath.length === 0 || routePath === '/*') {\n return callback(name);\n }\n\n name = routePath;\n return callback(name, 'route');\n },\n );\n}\n\n/**\n * Generate route name from array of routes\n */\nfunction getRouteStringFromRoutes(routes: Route[]): string {\n if (!Array.isArray(routes) || routes.length === 0) {\n return '';\n }\n\n const routesWithPaths: Route[] = routes.filter((route: Route) => !!route.path);\n\n let index = -1;\n for (let x = routesWithPaths.length - 1; x >= 0; x--) {\n const route = routesWithPaths[x];\n if (route.path && route.path.startsWith('/')) {\n index = x;\n break;\n }\n }\n\n return routesWithPaths\n .slice(index)\n .filter(({ path }) => !!path)\n .map(({ path }) => path)\n .join('');\n}\n"],"names":["browserTracingIntegration","startBrowserTracingPageLoadSpan","startBrowserTracingNavigationSpan","WINDOW","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE"],"mappings":"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"}
|