@sentry/react 7.0.0-alpha.1 → 7.0.0-beta.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 +2 -3
- package/cjs/constants.js +12 -5
- package/cjs/constants.js.map +1 -1
- package/cjs/errorboundary.js +139 -112
- package/cjs/errorboundary.js.map +1 -1
- package/cjs/flags.js +7 -3
- package/cjs/flags.js.map +1 -1
- package/cjs/index.js +30 -21
- package/cjs/index.js.map +1 -1
- package/cjs/profiler.js +178 -147
- package/cjs/profiler.js.map +1 -1
- package/cjs/reactrouter.js +147 -100
- package/cjs/reactrouter.js.map +1 -1
- package/cjs/reactrouterv3.js +107 -83
- package/cjs/reactrouterv3.js.map +1 -1
- package/cjs/reactrouterv6.js +163 -0
- package/cjs/reactrouterv6.js.map +1 -0
- package/cjs/redux.js +51 -42
- package/cjs/redux.js.map +1 -1
- package/cjs/sdk.js +18 -15
- package/cjs/sdk.js.map +1 -1
- package/esm/constants.js +8 -4
- package/esm/constants.js.map +1 -1
- package/esm/errorboundary.js +124 -107
- package/esm/errorboundary.js.map +1 -1
- package/esm/flags.js +5 -2
- package/esm/flags.js.map +1 -1
- package/esm/index.js +8 -7
- package/esm/index.js.map +1 -1
- package/esm/profiler.js +161 -140
- package/esm/profiler.js.map +1 -1
- package/esm/reactrouter.js +133 -94
- package/esm/reactrouter.js.map +1 -1
- package/esm/reactrouterv3.js +103 -79
- package/esm/reactrouterv3.js.map +1 -1
- package/esm/reactrouterv6.js +153 -0
- package/esm/reactrouterv6.js.map +1 -0
- package/esm/redux.js +49 -41
- package/esm/redux.js.map +1 -1
- package/esm/sdk.js +17 -14
- package/esm/sdk.js.map +1 -1
- package/package.json +5 -5
- package/types/errorboundary.d.ts +1 -0
- package/types/errorboundary.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/reactrouterv6.d.ts +27 -0
- package/types/reactrouterv6.d.ts.map +1 -0
- package/cjs/constants.d.ts +0 -4
- package/cjs/constants.d.ts.map +0 -1
- package/cjs/errorboundary.d.ts +0 -62
- package/cjs/errorboundary.d.ts.map +0 -1
- package/cjs/flags.d.ts +0 -3
- package/cjs/flags.d.ts.map +0 -1
- package/cjs/index.d.ts +0 -8
- package/cjs/index.d.ts.map +0 -1
- package/cjs/profiler.d.ts +0 -54
- package/cjs/profiler.d.ts.map +0 -1
- package/cjs/reactrouter.d.ts +0 -25
- package/cjs/reactrouter.d.ts.map +0 -1
- package/cjs/reactrouterv3.d.ts +0 -26
- package/cjs/reactrouterv3.d.ts.map +0 -1
- package/cjs/redux.d.ts +0 -33
- package/cjs/redux.d.ts.map +0 -1
- package/cjs/sdk.d.ts +0 -6
- package/cjs/sdk.d.ts.map +0 -1
- package/cjs/types.d.ts +0 -8
- package/cjs/types.d.ts.map +0 -1
- package/cjs/types.js +0 -2
- package/cjs/types.js.map +0 -1
- package/esm/constants.d.ts +0 -4
- package/esm/constants.d.ts.map +0 -1
- package/esm/errorboundary.d.ts +0 -62
- package/esm/errorboundary.d.ts.map +0 -1
- package/esm/flags.d.ts +0 -3
- package/esm/flags.d.ts.map +0 -1
- package/esm/index.d.ts +0 -8
- package/esm/index.d.ts.map +0 -1
- package/esm/profiler.d.ts +0 -54
- package/esm/profiler.d.ts.map +0 -1
- package/esm/reactrouter.d.ts +0 -25
- package/esm/reactrouter.d.ts.map +0 -1
- package/esm/reactrouterv3.d.ts +0 -26
- package/esm/reactrouterv3.d.ts.map +0 -1
- package/esm/redux.d.ts +0 -33
- package/esm/redux.d.ts.map +0 -1
- package/esm/sdk.d.ts +0 -6
- package/esm/sdk.d.ts.map +0 -1
- package/esm/types.d.ts +0 -8
- package/esm/types.d.ts.map +0 -1
- package/esm/types.js +0 -1
- package/esm/types.js.map +0 -1
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
var {
|
|
2
|
+
_interopDefault
|
|
3
|
+
} = require('@sentry/utils/cjs/buildPolyfills');
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
6
|
+
|
|
7
|
+
var utils = require('@sentry/utils');
|
|
8
|
+
var hoistNonReactStatics = require('hoist-non-react-statics');
|
|
9
|
+
var React = require('react');
|
|
10
|
+
var flags = require('./flags.js');
|
|
11
|
+
|
|
12
|
+
var hoistNonReactStatics__default = /*#__PURE__*/_interopDefault(hoistNonReactStatics);
|
|
13
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
14
|
+
|
|
15
|
+
var _jsxFileName = "/home/runner/work/sentry-javascript/sentry-javascript/packages/react/src/reactrouterv6.tsx";
|
|
16
|
+
|
|
17
|
+
let activeTransaction;
|
|
18
|
+
|
|
19
|
+
let _useEffect;
|
|
20
|
+
let _useLocation;
|
|
21
|
+
let _useNavigationType;
|
|
22
|
+
let _createRoutesFromChildren;
|
|
23
|
+
let _matchRoutes;
|
|
24
|
+
let _customStartTransaction;
|
|
25
|
+
let _startTransactionOnLocationChange;
|
|
26
|
+
|
|
27
|
+
var global = utils.getGlobalObject();
|
|
28
|
+
|
|
29
|
+
var SENTRY_TAGS = {
|
|
30
|
+
'routing.instrumentation': 'react-router-v6',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function getInitPathName() {
|
|
34
|
+
if (global && global.location) {
|
|
35
|
+
return global.location.pathname;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function reactRouterV6Instrumentation(
|
|
42
|
+
useEffect,
|
|
43
|
+
useLocation,
|
|
44
|
+
useNavigationType,
|
|
45
|
+
createRoutesFromChildren,
|
|
46
|
+
matchRoutes,
|
|
47
|
+
) {
|
|
48
|
+
return (
|
|
49
|
+
customStartTransaction,
|
|
50
|
+
startTransactionOnPageLoad = true,
|
|
51
|
+
startTransactionOnLocationChange = true,
|
|
52
|
+
) => {
|
|
53
|
+
var initPathName = getInitPathName();
|
|
54
|
+
if (startTransactionOnPageLoad && initPathName) {
|
|
55
|
+
activeTransaction = customStartTransaction({
|
|
56
|
+
name: initPathName,
|
|
57
|
+
op: 'pageload',
|
|
58
|
+
tags: SENTRY_TAGS,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
_useEffect = useEffect;
|
|
63
|
+
_useLocation = useLocation;
|
|
64
|
+
_useNavigationType = useNavigationType;
|
|
65
|
+
_matchRoutes = matchRoutes;
|
|
66
|
+
_createRoutesFromChildren = createRoutesFromChildren;
|
|
67
|
+
|
|
68
|
+
_customStartTransaction = customStartTransaction;
|
|
69
|
+
_startTransactionOnLocationChange = startTransactionOnLocationChange;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
var getTransactionName = (routes, location, matchRoutes) => {
|
|
74
|
+
if (!routes || routes.length === 0 || !matchRoutes) {
|
|
75
|
+
return location.pathname;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var branches = matchRoutes(routes, location);
|
|
79
|
+
|
|
80
|
+
if (branches) {
|
|
81
|
+
for (let x = 0; x < branches.length; x++) {
|
|
82
|
+
if (branches[x].route && branches[x].route.path && branches[x].pathname === location.pathname) {
|
|
83
|
+
return branches[x].route.path || location.pathname;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return location.pathname;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
function withSentryReactRouterV6Routing(Routes) {
|
|
92
|
+
if (
|
|
93
|
+
!_useEffect ||
|
|
94
|
+
!_useLocation ||
|
|
95
|
+
!_useNavigationType ||
|
|
96
|
+
!_createRoutesFromChildren ||
|
|
97
|
+
!_matchRoutes ||
|
|
98
|
+
!_customStartTransaction
|
|
99
|
+
) {
|
|
100
|
+
flags.IS_DEBUG_BUILD &&
|
|
101
|
+
utils.logger.warn('reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters.');
|
|
102
|
+
|
|
103
|
+
return Routes;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let isBaseLocation = false;
|
|
107
|
+
let routes;
|
|
108
|
+
|
|
109
|
+
var SentryRoutes = (props) => {
|
|
110
|
+
var location = _useLocation();
|
|
111
|
+
var navigationType = _useNavigationType();
|
|
112
|
+
|
|
113
|
+
_useEffect(() => {
|
|
114
|
+
// Performance concern:
|
|
115
|
+
// This is repeated when <Routes /> is rendered.
|
|
116
|
+
routes = _createRoutesFromChildren(props.children);
|
|
117
|
+
isBaseLocation = true;
|
|
118
|
+
|
|
119
|
+
if (activeTransaction) {
|
|
120
|
+
activeTransaction.setName(getTransactionName(routes, location, _matchRoutes));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
}, [props.children]);
|
|
124
|
+
|
|
125
|
+
_useEffect(() => {
|
|
126
|
+
if (isBaseLocation) {
|
|
127
|
+
if (activeTransaction) {
|
|
128
|
+
activeTransaction.finish();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {
|
|
135
|
+
if (activeTransaction) {
|
|
136
|
+
activeTransaction.finish();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
activeTransaction = _customStartTransaction({
|
|
140
|
+
name: getTransactionName(routes, location, _matchRoutes),
|
|
141
|
+
op: 'navigation',
|
|
142
|
+
tags: SENTRY_TAGS,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}, [props.children, location, navigationType, isBaseLocation]);
|
|
146
|
+
|
|
147
|
+
isBaseLocation = false;
|
|
148
|
+
|
|
149
|
+
// @ts-ignore Setting more specific React Component typing for `R` generic above
|
|
150
|
+
// will break advanced type inference done by react router params
|
|
151
|
+
return React__default.createElement(Routes, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 172}} );
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
hoistNonReactStatics__default(SentryRoutes, Routes);
|
|
155
|
+
|
|
156
|
+
// @ts-ignore Setting more specific React Component typing for `R` generic above
|
|
157
|
+
// will break advanced type inference done by react router params
|
|
158
|
+
return SentryRoutes;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
exports.reactRouterV6Instrumentation = reactRouterV6Instrumentation;
|
|
162
|
+
exports.withSentryReactRouterV6Routing = withSentryReactRouterV6Routing;
|
|
163
|
+
//# sourceMappingURL=reactrouterv6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactrouterv6.js","sources":["../../src/reactrouterv6.tsx"],"sourcesContent":["// Inspired from Donnie McNeal's solution:\n// https://gist.github.com/wontondon/e8c4bdf2888875e4c755712e99279536\n\nimport { Transaction, TransactionContext } from '@sentry/types';\nimport { getGlobalObject, logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport React from 'react';\n\nimport { IS_DEBUG_BUILD } from './flags';\nimport { Action, Location } from './types';\n\ninterface RouteObject {\n caseSensitive?: boolean;\n children?: RouteObject[];\n element?: React.ReactNode;\n index?: boolean;\n path?: string;\n}\n\ntype Params<Key extends string = string> = {\n readonly [key in Key]: string | undefined;\n};\n\ninterface RouteMatch<ParamKey extends string = string> {\n params: Params<ParamKey>;\n pathname: string;\n route: RouteObject;\n}\n\ntype UseEffect = (cb: () => void, deps: unknown[]) => void;\ntype UseLocation = () => Location;\ntype UseNavigationType = () => Action;\ntype CreateRoutesFromChildren = (children: JSX.Element[]) => RouteObject[];\ntype MatchRoutes = (routes: RouteObject[], location: Location) => RouteMatch[] | null;\n\nlet activeTransaction: Transaction | undefined;\n\nlet _useEffect: UseEffect;\nlet _useLocation: UseLocation;\nlet _useNavigationType: UseNavigationType;\nlet _createRoutesFromChildren: CreateRoutesFromChildren;\nlet _matchRoutes: MatchRoutes;\nlet _customStartTransaction: (context: TransactionContext) => Transaction | undefined;\nlet _startTransactionOnLocationChange: boolean;\n\nconst global = getGlobalObject<Window>();\n\nconst SENTRY_TAGS = {\n 'routing.instrumentation': 'react-router-v6',\n};\n\nfunction getInitPathName(): string | undefined {\n if (global && global.location) {\n return global.location.pathname;\n }\n\n return undefined;\n}\n\nexport function reactRouterV6Instrumentation(\n useEffect: UseEffect,\n useLocation: UseLocation,\n useNavigationType: UseNavigationType,\n createRoutesFromChildren: CreateRoutesFromChildren,\n matchRoutes: MatchRoutes,\n) {\n return (\n customStartTransaction: (context: TransactionContext) => Transaction | undefined,\n startTransactionOnPageLoad = true,\n startTransactionOnLocationChange = true,\n ): void => {\n const initPathName = getInitPathName();\n if (startTransactionOnPageLoad && initPathName) {\n activeTransaction = customStartTransaction({\n name: initPathName,\n op: 'pageload',\n tags: SENTRY_TAGS,\n });\n }\n\n _useEffect = useEffect;\n _useLocation = useLocation;\n _useNavigationType = useNavigationType;\n _matchRoutes = matchRoutes;\n _createRoutesFromChildren = createRoutesFromChildren;\n\n _customStartTransaction = customStartTransaction;\n _startTransactionOnLocationChange = startTransactionOnLocationChange;\n };\n}\n\nconst getTransactionName = (routes: RouteObject[], location: Location, matchRoutes: MatchRoutes): string => {\n if (!routes || routes.length === 0 || !matchRoutes) {\n return location.pathname;\n }\n\n const branches = matchRoutes(routes, location);\n\n if (branches) {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n if (branches[x].route && branches[x].route.path && branches[x].pathname === location.pathname) {\n return branches[x].route.path || location.pathname;\n }\n }\n }\n\n return location.pathname;\n};\n\nexport function withSentryReactRouterV6Routing<P extends Record<string, any>, R extends React.FC<P>>(Routes: R): R {\n if (\n !_useEffect ||\n !_useLocation ||\n !_useNavigationType ||\n !_createRoutesFromChildren ||\n !_matchRoutes ||\n !_customStartTransaction\n ) {\n IS_DEBUG_BUILD &&\n logger.warn('reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters.');\n\n return Routes;\n }\n\n let isBaseLocation: boolean = false;\n let routes: RouteObject[];\n\n const SentryRoutes: React.FC<P> = (props: P) => {\n const location = _useLocation();\n const navigationType = _useNavigationType();\n\n _useEffect(() => {\n // Performance concern:\n // This is repeated when <Routes /> is rendered.\n routes = _createRoutesFromChildren(props.children);\n isBaseLocation = true;\n\n if (activeTransaction) {\n activeTransaction.setName(getTransactionName(routes, location, _matchRoutes));\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.children]);\n\n _useEffect(() => {\n if (isBaseLocation) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n return;\n }\n\n if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n activeTransaction = _customStartTransaction({\n name: getTransactionName(routes, location, _matchRoutes),\n op: 'navigation',\n tags: SENTRY_TAGS,\n });\n }\n }, [props.children, location, navigationType, isBaseLocation]);\n\n isBaseLocation = false;\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return <Routes {...props} />;\n };\n\n hoistNonReactStatics(SentryRoutes, Routes);\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return SentryRoutes;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA;;AAmCA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;;;;;AAMA;;;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;;;AAwBA;;AAEA;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuEA;;;"}
|
package/cjs/redux.js
CHANGED
|
@@ -1,56 +1,65 @@
|
|
|
1
|
-
Object.defineProperty(exports,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
|
|
3
|
+
var browser = require('@sentry/browser');
|
|
4
|
+
|
|
5
5
|
var ACTION_BREADCRUMB_CATEGORY = 'redux.action';
|
|
6
6
|
var ACTION_BREADCRUMB_TYPE = 'info';
|
|
7
7
|
var STATE_CONTEXT_KEY = 'redux.state';
|
|
8
|
+
|
|
8
9
|
var defaultOptions = {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
actionTransformer: action => action,
|
|
11
|
+
stateTransformer: state => state || null,
|
|
11
12
|
};
|
|
13
|
+
|
|
12
14
|
/**
|
|
13
15
|
* Creates an enhancer that would be passed to Redux's createStore to log actions and the latest state to Sentry.
|
|
14
16
|
*
|
|
15
17
|
* @param enhancerOptions Options to pass to the enhancer
|
|
16
18
|
*/
|
|
17
19
|
function createReduxEnhancer(enhancerOptions) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
20
|
+
// Note: We return an any type as to not have type conflicts.
|
|
21
|
+
var options = {
|
|
22
|
+
...defaultOptions,
|
|
23
|
+
...enhancerOptions,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return (next) =>
|
|
27
|
+
(reducer, initialState) => {
|
|
28
|
+
var sentryReducer = (state, action) => {
|
|
29
|
+
var newState = reducer(state, action);
|
|
30
|
+
|
|
31
|
+
browser.configureScope(scope => {
|
|
32
|
+
/* Action breadcrumbs */
|
|
33
|
+
var transformedAction = options.actionTransformer(action);
|
|
34
|
+
if (typeof transformedAction !== 'undefined' && transformedAction !== null) {
|
|
35
|
+
scope.addBreadcrumb({
|
|
36
|
+
category: ACTION_BREADCRUMB_CATEGORY,
|
|
37
|
+
data: transformedAction,
|
|
38
|
+
type: ACTION_BREADCRUMB_TYPE,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Set latest state to scope */
|
|
43
|
+
var transformedState = options.stateTransformer(newState);
|
|
44
|
+
if (typeof transformedState !== 'undefined' && transformedState !== null) {
|
|
45
|
+
scope.setContext(STATE_CONTEXT_KEY, transformedState);
|
|
46
|
+
} else {
|
|
47
|
+
scope.setContext(STATE_CONTEXT_KEY, null);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Allow user to configure scope with latest state */
|
|
51
|
+
const { configureScopeWithState } = options;
|
|
52
|
+
if (typeof configureScopeWithState === 'function') {
|
|
53
|
+
configureScopeWithState(scope, newState);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return newState;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return next(sentryReducer, initialState);
|
|
53
61
|
};
|
|
54
62
|
}
|
|
63
|
+
|
|
55
64
|
exports.createReduxEnhancer = createReduxEnhancer;
|
|
56
|
-
//# sourceMappingURL=redux.js.map
|
|
65
|
+
//# sourceMappingURL=redux.js.map
|
package/cjs/redux.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redux.js","
|
|
1
|
+
{"version":3,"file":"redux.js","sources":["../../src/redux.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { configureScope } from '@sentry/browser';\nimport { Scope } from '@sentry/types';\n\ninterface Action<T = any> {\n type: T;\n}\n\ninterface AnyAction extends Action {\n [extraProps: string]: any;\n}\n\ntype Reducer<S = any, A extends Action = AnyAction> = (state: S | undefined, action: A) => S;\n\ntype Dispatch<A extends Action = AnyAction> = <T extends A>(action: T, ...extraArgs: any[]) => T;\n\ntype ExtendState<State, Extension> = [Extension] extends [never] ? State : State & Extension;\n\ntype Unsubscribe = () => void;\n\ninterface Store<S = any, A extends Action = AnyAction, StateExt = never, Ext = Record<string, unknown>> {\n dispatch: Dispatch<A>;\n getState(): S;\n subscribe(listener: () => void): Unsubscribe;\n replaceReducer<NewState, NewActions extends Action>(\n nextReducer: Reducer<NewState, NewActions>,\n ): Store<ExtendState<NewState, StateExt>, NewActions, StateExt, Ext> & Ext;\n}\n\ndeclare const $CombinedState: unique symbol;\n\ntype CombinedState<S> = { readonly [$CombinedState]?: undefined } & S;\n\ntype PreloadedState<S> = Required<S> extends {\n [$CombinedState]: undefined;\n}\n ? S extends CombinedState<infer S1>\n ? { [K in keyof S1]?: S1[K] extends Record<string, unknown> ? PreloadedState<S1[K]> : S1[K] }\n : never\n : { [K in keyof S]: S[K] extends string | number | boolean | symbol ? S[K] : PreloadedState<S[K]> };\n\ntype StoreEnhancerStoreCreator<Ext = Record<string, unknown>, StateExt = never> = <\n S = any,\n A extends Action = AnyAction,\n>(\n reducer: Reducer<S, A>,\n preloadedState?: PreloadedState<S>,\n) => Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext;\n\nexport interface SentryEnhancerOptions<S = any> {\n /**\n * Transforms the state before attaching it to an event.\n * Use this to remove any private data before sending it to Sentry.\n * Return null to not attach the state.\n */\n stateTransformer(state: S | undefined): (S & any) | null;\n /**\n * Transforms the action before sending it as a breadcrumb.\n * Use this to remove any private data before sending it to Sentry.\n * Return null to not send the breadcrumb.\n */\n actionTransformer(action: AnyAction): AnyAction | null;\n /**\n * Called on every state update, configure the Sentry Scope with the redux state.\n */\n configureScopeWithState?(scope: Scope, state: S): void;\n}\n\nconst ACTION_BREADCRUMB_CATEGORY = 'redux.action';\nconst ACTION_BREADCRUMB_TYPE = 'info';\nconst STATE_CONTEXT_KEY = 'redux.state';\n\nconst defaultOptions: SentryEnhancerOptions = {\n actionTransformer: action => action,\n stateTransformer: state => state || null,\n};\n\n/**\n * Creates an enhancer that would be passed to Redux's createStore to log actions and the latest state to Sentry.\n *\n * @param enhancerOptions Options to pass to the enhancer\n */\nfunction createReduxEnhancer(enhancerOptions?: Partial<SentryEnhancerOptions>): any {\n // Note: We return an any type as to not have type conflicts.\n const options = {\n ...defaultOptions,\n ...enhancerOptions,\n };\n\n return (next: StoreEnhancerStoreCreator): StoreEnhancerStoreCreator =>\n <S = any, A extends Action = AnyAction>(reducer: Reducer<S, A>, initialState?: PreloadedState<S>) => {\n const sentryReducer: Reducer<S, A> = (state, action): S => {\n const newState = reducer(state, action);\n\n configureScope(scope => {\n /* Action breadcrumbs */\n const transformedAction = options.actionTransformer(action);\n if (typeof transformedAction !== 'undefined' && transformedAction !== null) {\n scope.addBreadcrumb({\n category: ACTION_BREADCRUMB_CATEGORY,\n data: transformedAction,\n type: ACTION_BREADCRUMB_TYPE,\n });\n }\n\n /* Set latest state to scope */\n const transformedState = options.stateTransformer(newState);\n if (typeof transformedState !== 'undefined' && transformedState !== null) {\n scope.setContext(STATE_CONTEXT_KEY, transformedState);\n } else {\n scope.setContext(STATE_CONTEXT_KEY, null);\n }\n\n /* Allow user to configure scope with latest state */\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const { configureScopeWithState } = options;\n if (typeof configureScopeWithState === 'function') {\n configureScopeWithState(scope, newState);\n }\n });\n\n return newState;\n };\n\n return next(sentryReducer, initialState);\n };\n}\n\nexport { createReduxEnhancer };\n"],"names":[],"mappings":";;;;AAoEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;"}
|
package/cjs/sdk.js
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
Object.defineProperty(exports,
|
|
2
|
-
|
|
1
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
+
|
|
3
|
+
var browser = require('@sentry/browser');
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Inits the React SDK
|
|
5
7
|
*/
|
|
6
8
|
function init(options) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
options._metadata = options._metadata || {};
|
|
10
|
+
options._metadata.sdk = options._metadata.sdk || {
|
|
11
|
+
name: 'sentry.javascript.react',
|
|
12
|
+
packages: [
|
|
13
|
+
{
|
|
14
|
+
name: 'npm:@sentry/react',
|
|
15
|
+
version: browser.SDK_VERSION,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
version: browser.SDK_VERSION,
|
|
19
|
+
};
|
|
20
|
+
browser.init(options);
|
|
19
21
|
}
|
|
22
|
+
|
|
20
23
|
exports.init = init;
|
|
21
|
-
//# sourceMappingURL=sdk.js.map
|
|
24
|
+
//# sourceMappingURL=sdk.js.map
|
package/cjs/sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","
|
|
1
|
+
{"version":3,"file":"sdk.js","sources":["../../src/sdk.ts"],"sourcesContent":["import { BrowserOptions, init as browserInit, SDK_VERSION } from '@sentry/browser';\n\n/**\n * Inits the React SDK\n */\nexport function init(options: BrowserOptions): void {\n options._metadata = options._metadata || {};\n options._metadata.sdk = options._metadata.sdk || {\n name: 'sentry.javascript.react',\n packages: [\n {\n name: 'npm:@sentry/react',\n version: SDK_VERSION,\n },\n ],\n version: SDK_VERSION,\n };\n browserInit(options);\n}\n"],"names":[],"mappings":";;;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;"}
|
package/esm/constants.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
var REACT_RENDER_OP = 'ui.react.render';
|
|
2
|
+
|
|
3
|
+
var REACT_UPDATE_OP = 'ui.react.update';
|
|
4
|
+
|
|
5
|
+
var REACT_MOUNT_OP = 'ui.react.mount';
|
|
6
|
+
|
|
7
|
+
export { REACT_MOUNT_OP, REACT_RENDER_OP, REACT_UPDATE_OP };
|
|
8
|
+
//# sourceMappingURL=constants.js.map
|
package/esm/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../src/constants.ts"],"sourcesContent":["export const REACT_RENDER_OP = 'ui.react.render';\n\nexport const REACT_UPDATE_OP = 'ui.react.update';\n\nexport const REACT_MOUNT_OP = 'ui.react.mount';\n"],"names":[],"mappings":";AACA;;AAEA;;;;;"}
|
package/esm/errorboundary.js
CHANGED
|
@@ -1,122 +1,139 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { captureException, showReportDialog, withScope } from '@sentry/browser';
|
|
1
|
+
import { withScope, captureException, showReportDialog } from '@sentry/browser';
|
|
3
2
|
import { logger } from '@sentry/utils';
|
|
4
3
|
import hoistNonReactStatics from 'hoist-non-react-statics';
|
|
5
4
|
import * as React from 'react';
|
|
6
|
-
import { IS_DEBUG_BUILD } from './flags';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
import { IS_DEBUG_BUILD } from './flags.js';
|
|
6
|
+
|
|
7
|
+
var _jsxFileName = "/home/runner/work/sentry-javascript/sentry-javascript/packages/react/src/errorboundary.tsx";
|
|
8
|
+
function isAtLeastReact17(version) {
|
|
9
|
+
var major = version.match(/^([^.]+)/);
|
|
10
|
+
return major !== null && parseInt(major[0]) >= 17;
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
var UNKNOWN_COMPONENT = 'unknown';
|
|
14
|
+
|
|
12
15
|
var INITIAL_STATE = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
componentStack: null,
|
|
17
|
+
error: null,
|
|
18
|
+
eventId: null,
|
|
16
19
|
};
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* A ErrorBoundary component that logs errors to Sentry. Requires React >= 16.
|
|
19
23
|
* NOTE: If you are a Sentry user, and you are seeing this stack frame, it means the
|
|
20
24
|
* Sentry React SDK ErrorBoundary caught an error invoking your application code. This
|
|
21
25
|
* is expected behavior and NOT indicative of a bug with the Sentry React SDK.
|
|
22
26
|
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
27
|
+
class ErrorBoundary extends React.Component {constructor(...args) { super(...args); ErrorBoundary.prototype.__init.call(this);ErrorBoundary.prototype.__init2.call(this); }
|
|
28
|
+
__init() {this.state = INITIAL_STATE;}
|
|
29
|
+
|
|
30
|
+
componentDidCatch(error, { componentStack }) {
|
|
31
|
+
const { beforeCapture, onError, showDialog, dialogOptions } = this.props;
|
|
32
|
+
|
|
33
|
+
withScope(scope => {
|
|
34
|
+
// If on React version >= 17, create stack trace from componentStack param and links
|
|
35
|
+
// to to the original error using `error.cause` otherwise relies on error param for stacktrace.
|
|
36
|
+
// Linking errors requires the `LinkedErrors` integration be enabled.
|
|
37
|
+
if (isAtLeastReact17(React.version)) {
|
|
38
|
+
var errorBoundaryError = new Error(error.message);
|
|
39
|
+
errorBoundaryError.name = `React ErrorBoundary ${errorBoundaryError.name}`;
|
|
40
|
+
errorBoundaryError.stack = componentStack;
|
|
41
|
+
|
|
42
|
+
// Using the `LinkedErrors` integration to link the errors together.
|
|
43
|
+
error.cause = errorBoundaryError;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (beforeCapture) {
|
|
47
|
+
beforeCapture(scope, error, componentStack);
|
|
48
|
+
}
|
|
49
|
+
var eventId = captureException(error, { contexts: { react: { componentStack } } });
|
|
50
|
+
if (onError) {
|
|
51
|
+
onError(error, componentStack, eventId);
|
|
52
|
+
}
|
|
53
|
+
if (showDialog) {
|
|
54
|
+
showReportDialog({ ...dialogOptions, eventId });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// componentDidCatch is used over getDerivedStateFromError
|
|
58
|
+
// so that componentStack is accessible through state.
|
|
59
|
+
this.setState({ error, componentStack, eventId });
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
componentDidMount() {
|
|
64
|
+
const { onMount } = this.props;
|
|
65
|
+
if (onMount) {
|
|
66
|
+
onMount();
|
|
37
67
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (React.isValidElement(element)) {
|
|
93
|
-
return element;
|
|
94
|
-
}
|
|
95
|
-
if (fallback) {
|
|
96
|
-
IS_DEBUG_BUILD && logger.warn('fallback did not produce a valid ReactElement');
|
|
97
|
-
}
|
|
98
|
-
// Fail gracefully if no fallback provided or is not valid
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
if (typeof children === 'function') {
|
|
102
|
-
return children();
|
|
103
|
-
}
|
|
104
|
-
return children;
|
|
105
|
-
};
|
|
106
|
-
return ErrorBoundary;
|
|
107
|
-
}(React.Component));
|
|
108
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
|
-
function withErrorBoundary(WrappedComponent, errorBoundaryOptions) {
|
|
110
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
componentWillUnmount() {
|
|
71
|
+
const { error, componentStack, eventId } = this.state;
|
|
72
|
+
const { onUnmount } = this.props;
|
|
73
|
+
if (onUnmount) {
|
|
74
|
+
onUnmount(error, componentStack, eventId);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
__init2() {this.resetErrorBoundary = () => {
|
|
79
|
+
const { onReset } = this.props;
|
|
80
|
+
const { error, componentStack, eventId } = this.state;
|
|
81
|
+
if (onReset) {
|
|
82
|
+
onReset(error, componentStack, eventId);
|
|
83
|
+
}
|
|
84
|
+
this.setState(INITIAL_STATE);
|
|
85
|
+
};}
|
|
86
|
+
|
|
87
|
+
render() {
|
|
88
|
+
const { fallback, children } = this.props;
|
|
89
|
+
const { error, componentStack, eventId } = this.state;
|
|
90
|
+
|
|
91
|
+
if (error) {
|
|
92
|
+
let element = undefined;
|
|
93
|
+
if (typeof fallback === 'function') {
|
|
94
|
+
element = fallback({ error, componentStack, resetError: this.resetErrorBoundary, eventId });
|
|
95
|
+
} else {
|
|
96
|
+
element = fallback;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (React.isValidElement(element)) {
|
|
100
|
+
return element;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (fallback) {
|
|
104
|
+
IS_DEBUG_BUILD && logger.warn('fallback did not produce a valid ReactElement');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Fail gracefully if no fallback provided or is not valid
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (typeof children === 'function') {
|
|
112
|
+
return (children )();
|
|
113
|
+
}
|
|
114
|
+
return children;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function withErrorBoundary(
|
|
119
|
+
WrappedComponent,
|
|
120
|
+
errorBoundaryOptions,
|
|
121
|
+
) {
|
|
111
122
|
var componentDisplayName = WrappedComponent.displayName || WrappedComponent.name || UNKNOWN_COMPONENT;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
|
|
124
|
+
var Wrapped = (props) => (
|
|
125
|
+
React.createElement(ErrorBoundary, { ...errorBoundaryOptions, __self: this, __source: {fileName: _jsxFileName, lineNumber: 170}}
|
|
126
|
+
, React.createElement(WrappedComponent, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 171}} )
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
Wrapped.displayName = `errorBoundary(${componentDisplayName})`;
|
|
131
|
+
|
|
132
|
+
// Copy over static methods from Wrapped component to Profiler HOC
|
|
133
|
+
// See: https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over
|
|
134
|
+
hoistNonReactStatics(Wrapped, WrappedComponent);
|
|
135
|
+
return Wrapped;
|
|
120
136
|
}
|
|
121
|
-
|
|
122
|
-
|
|
137
|
+
|
|
138
|
+
export { ErrorBoundary, UNKNOWN_COMPONENT, isAtLeastReact17, withErrorBoundary };
|
|
139
|
+
//# sourceMappingURL=errorboundary.js.map
|