@sentry/react 11.0.0-beta.0 → 11.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/build/cjs/react-router.js +21 -0
- package/build/cjs/react-router.js.map +1 -0
- package/build/cjs/reactrouter-compat-utils/instrumentation.js +141 -136
- package/build/cjs/reactrouter-compat-utils/instrumentation.js.map +1 -1
- package/build/cjs/reactrouter-compat-utils/utils.js +28 -32
- package/build/cjs/reactrouter-compat-utils/utils.js.map +1 -1
- package/build/cjs/reactrouter.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/react-router.js +16 -0
- package/build/esm/react-router.js.map +1 -0
- package/build/esm/reactrouter-compat-utils/instrumentation.js +143 -138
- package/build/esm/reactrouter-compat-utils/instrumentation.js.map +1 -1
- package/build/esm/reactrouter-compat-utils/utils.js +29 -32
- package/build/esm/reactrouter-compat-utils/utils.js.map +1 -1
- package/build/esm/reactrouter.js.map +1 -1
- package/build/types/react-router.d.ts +26 -0
- package/build/types/react-router.d.ts.map +1 -0
- package/build/types/reactrouter-compat-utils/index.d.ts +1 -1
- package/build/types/reactrouter-compat-utils/index.d.ts.map +1 -1
- package/build/types/reactrouter-compat-utils/instrumentation.d.ts +9 -5
- package/build/types/reactrouter-compat-utils/instrumentation.d.ts.map +1 -1
- package/build/types/reactrouter-compat-utils/utils.d.ts +5 -10
- package/build/types/reactrouter-compat-utils/utils.d.ts.map +1 -1
- package/build/types/reactrouter.d.ts +16 -0
- package/build/types/reactrouter.d.ts.map +1 -1
- package/build/types/types.d.ts +16 -0
- package/build/types/types.d.ts.map +1 -1
- package/package.json +33 -5
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const reactRouter = require('react-router');
|
|
4
|
+
const reactrouter_compat = require('./reactrouter.compat.js');
|
|
5
|
+
|
|
6
|
+
function reactRouterBrowserTracingIntegration(options = {}) {
|
|
7
|
+
return reactrouter_compat.reactRouterBrowserTracingIntegration({
|
|
8
|
+
useLocation: reactRouter.useLocation,
|
|
9
|
+
useNavigationType: reactRouter.useNavigationType,
|
|
10
|
+
createRoutesFromChildren: reactRouter.createRoutesFromChildren,
|
|
11
|
+
matchRoutes: reactRouter.matchRoutes,
|
|
12
|
+
...options
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.wrapCreateBrowserRouter = reactrouter_compat.wrapCreateBrowserRouter;
|
|
17
|
+
exports.wrapCreateMemoryRouter = reactrouter_compat.wrapCreateMemoryRouter;
|
|
18
|
+
exports.wrapReactRouterRouting = reactrouter_compat.wrapReactRouterRouting;
|
|
19
|
+
exports.wrapUseRoutes = reactrouter_compat.wrapUseRoutes;
|
|
20
|
+
exports.reactRouterBrowserTracingIntegration = reactRouterBrowserTracingIntegration;
|
|
21
|
+
//# sourceMappingURL=react-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-router.js","sources":["../../src/react-router.ts"],"sourcesContent":["import type { browserTracingIntegration } from '@sentry/browser';\nimport type { Integration } from '@sentry/core';\nimport { createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from 'react-router';\nimport type { ReactRouterOptions } from './reactrouter-compat-utils';\nimport { reactRouterBrowserTracingIntegration as reactRouterBrowserTracingIntegrationBase } from './reactrouter.compat';\n\n// The routing wrappers (`wrapReactRouterRouting`, `wrapUseRoutes`, `wrapCreateBrowserRouter`,\n// `wrapCreateMemoryRouter`) do not need the hooks - they read the config the integration below stored on\n// the client - so they are re-exported unchanged from the main entry point.\nexport {\n wrapReactRouterRouting,\n wrapCreateBrowserRouter,\n wrapCreateMemoryRouter,\n wrapUseRoutes,\n} from './reactrouter.compat';\n\ntype BrowserTracingOptions = Parameters<typeof browserTracingIntegration>[0];\n\n/**\n * A browser tracing integration for React Router v6, v7 and v8.\n *\n * Unlike {@link reactRouterBrowserTracingIntegration} exported from `@sentry/react`, this variant pulls the\n * required router hooks (`useLocation`, `useNavigationType`, `createRoutesFromChildren` and `matchRoutes`)\n * directly from `react-router`, so you don't have to pass them in:\n *\n * ```ts\n * import { reactRouterBrowserTracingIntegration } from '@sentry/react/react-router';\n *\n * Sentry.init({ integrations: [reactRouterBrowserTracingIntegration()] });\n * ```\n *\n * Any of the hooks can still be overridden via `options` (e.g. to supply the `react-router-dom` versions in v6).\n *\n * This requires `react-router` to be resolvable (it is declared as an optional peer dependency). If you are on\n * React Router v6 with only `react-router-dom` installed, either add `react-router` as a dependency or import\n * `reactRouterBrowserTracingIntegration` from `@sentry/react` and pass the hooks explicitly.\n */\nexport function reactRouterBrowserTracingIntegration(\n options: BrowserTracingOptions & Partial<ReactRouterOptions> = {},\n): Integration {\n return reactRouterBrowserTracingIntegrationBase({\n useLocation,\n useNavigationType,\n createRoutesFromChildren,\n matchRoutes,\n ...options,\n });\n}\n"],"names":["reactRouterBrowserTracingIntegrationBase","useLocation","useNavigationType","createRoutesFromChildren","matchRoutes"],"mappings":";;;;;AAqCO,SAAS,oCAAA,CACd,OAAA,GAA+D,EAAC,EACnD;AACb,EAAA,OAAOA,uDAAA,CAAyC;AAAA,iBAC9CC,uBAAA;AAAA,uBACAC,6BAAA;AAAA,8BACAC,oCAAA;AAAA,iBACAC,uBAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH;;;;;;;;"}
|
|
@@ -10,16 +10,10 @@ const utils = require('./utils.js');
|
|
|
10
10
|
const attributes = require('@sentry/conventions/attributes');
|
|
11
11
|
const op = require('@sentry/conventions/op');
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
let _matchRoutes;
|
|
18
|
-
let _enableAsyncRouteHandlers = false;
|
|
19
|
-
let _lazyRouteTimeout = 3e3;
|
|
20
|
-
let _lazyRouteManifest;
|
|
21
|
-
let _basename = "";
|
|
22
|
-
const CLIENTS_WITH_INSTRUMENT_NAVIGATION = /* @__PURE__ */ new WeakSet();
|
|
13
|
+
const reactRouterConfigByClient = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
function getRouterConfig(client) {
|
|
15
|
+
return client ? reactRouterConfigByClient.get(client) : void 0;
|
|
16
|
+
}
|
|
23
17
|
const useIsomorphicLayoutEffect = browser.WINDOW?.document ? React.useLayoutEffect : React.useEffect;
|
|
24
18
|
const activeNavigationSpans = /* @__PURE__ */ new WeakMap();
|
|
25
19
|
const allRoutes = /* @__PURE__ */ new Set();
|
|
@@ -103,11 +97,11 @@ function resolveDeferredLazyRoutePromise(span) {
|
|
|
103
97
|
}
|
|
104
98
|
}
|
|
105
99
|
}
|
|
106
|
-
function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = null, capturedSpan) {
|
|
100
|
+
function processResolvedRoutes(resolvedRoutes, config, parentRoute, currentLocation = null, capturedSpan) {
|
|
107
101
|
resolvedRoutes.forEach((child) => {
|
|
108
102
|
allRoutes.add(child);
|
|
109
|
-
if (
|
|
110
|
-
lazyRoutes.checkRouteForAsyncHandler(child, processResolvedRoutes);
|
|
103
|
+
if (config.enableAsyncRouteHandlers) {
|
|
104
|
+
lazyRoutes.checkRouteForAsyncHandler(child, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
111
105
|
}
|
|
112
106
|
});
|
|
113
107
|
if (parentRoute) {
|
|
@@ -136,29 +130,28 @@ function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = nu
|
|
|
136
130
|
activeRootSpan: targetSpan,
|
|
137
131
|
location: { pathname: location.pathname },
|
|
138
132
|
routes: Array.from(allRoutes),
|
|
139
|
-
allRoutes: Array.from(allRoutes)
|
|
133
|
+
allRoutes: Array.from(allRoutes),
|
|
134
|
+
config
|
|
140
135
|
});
|
|
141
136
|
} else if (spanOp === "navigation") {
|
|
142
|
-
updateNavigationSpan(targetSpan, location, Array.from(allRoutes), false,
|
|
137
|
+
updateNavigationSpan(targetSpan, location, Array.from(allRoutes), false, config);
|
|
143
138
|
}
|
|
144
139
|
}
|
|
145
140
|
}
|
|
146
141
|
}
|
|
147
|
-
function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false,
|
|
142
|
+
function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false, config) {
|
|
148
143
|
const { name: currentName, end_timestamp, attributes: attributes$1 } = core.spanToJSON(activeRootSpan);
|
|
149
144
|
const hasBeenNamed = activeRootSpan?.__sentry_navigation_name_set__;
|
|
150
145
|
const currentNameHasWildcard = currentName && utils.transactionNameHasWildcard(currentName);
|
|
151
146
|
const shouldUpdate = !hasBeenNamed || forceUpdate || currentNameHasWildcard;
|
|
152
147
|
if (shouldUpdate && !end_timestamp) {
|
|
153
|
-
const currentBranches = matchRoutes(allRoutes2, location);
|
|
148
|
+
const currentBranches = config.matchRoutes(allRoutes2, location);
|
|
154
149
|
const [name, source] = utils.resolveRouteNameAndSource(
|
|
155
150
|
location,
|
|
156
151
|
allRoutes2,
|
|
157
152
|
allRoutes2,
|
|
158
153
|
currentBranches || [],
|
|
159
|
-
|
|
160
|
-
_lazyRouteManifest,
|
|
161
|
-
_enableAsyncRouteHandlers
|
|
154
|
+
config
|
|
162
155
|
);
|
|
163
156
|
const currentSource = attributes$1[attributes.SENTRY_SEGMENT_NAME_SOURCE];
|
|
164
157
|
const isImprovement = name && (!currentName || // No current name - always set
|
|
@@ -179,7 +172,7 @@ function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate
|
|
|
179
172
|
}
|
|
180
173
|
}
|
|
181
174
|
}
|
|
182
|
-
function setupRouterSubscription(router, routes, version,
|
|
175
|
+
function setupRouterSubscription(router, routes, version, activeRootSpan, config) {
|
|
183
176
|
let isInitialPageloadComplete = false;
|
|
184
177
|
let hasSeenPageloadSpan = !!activeRootSpan && core.spanToJSON(activeRootSpan).attributes[attributes.SENTRY_OP] === "pageload";
|
|
185
178
|
let hasSeenPopAfterPageload = false;
|
|
@@ -213,8 +206,8 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
|
|
|
213
206
|
routes,
|
|
214
207
|
navigationType: state.historyAction,
|
|
215
208
|
version,
|
|
216
|
-
|
|
217
|
-
|
|
209
|
+
allRoutes: Array.from(allRoutes),
|
|
210
|
+
config
|
|
218
211
|
});
|
|
219
212
|
};
|
|
220
213
|
if (state.navigation.state !== "idle") {
|
|
@@ -236,17 +229,19 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
|
|
|
236
229
|
});
|
|
237
230
|
}
|
|
238
231
|
function createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, version) {
|
|
239
|
-
if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
|
|
240
|
-
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
241
|
-
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createRouter\` function because of one or more missing parameters.`
|
|
242
|
-
);
|
|
243
|
-
return createRouterFunction;
|
|
244
|
-
}
|
|
245
232
|
return function(routes, opts) {
|
|
233
|
+
const base = getRouterConfig(core.getClient());
|
|
234
|
+
if (!base) {
|
|
235
|
+
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
236
|
+
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createRouter\` function because the React Router browser tracing integration was not set up. Make sure \`Sentry.init()\` runs before the router is created.`
|
|
237
|
+
);
|
|
238
|
+
return createRouterFunction(routes, opts);
|
|
239
|
+
}
|
|
240
|
+
const config = { ...base, basename: opts?.basename || "" };
|
|
246
241
|
addRoutesToAllRoutes(routes);
|
|
247
|
-
if (
|
|
242
|
+
if (config.enableAsyncRouteHandlers) {
|
|
248
243
|
for (const route of routes) {
|
|
249
|
-
lazyRoutes.checkRouteForAsyncHandler(route, processResolvedRoutes);
|
|
244
|
+
lazyRoutes.checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
250
245
|
}
|
|
251
246
|
}
|
|
252
247
|
const activeRootSpan = utils.getActiveRootSpan();
|
|
@@ -255,35 +250,35 @@ function createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, version
|
|
|
255
250
|
core.addNonEnumerableProperty(activeRootSpan, "__sentry_may_have_lazy_routes__", true);
|
|
256
251
|
createDeferredLazyRoutePromise(activeRootSpan);
|
|
257
252
|
}
|
|
258
|
-
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan);
|
|
253
|
+
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan, config);
|
|
259
254
|
const router = createRouterFunction(routes, wrappedOpts);
|
|
260
|
-
const basename = opts?.basename;
|
|
261
255
|
if (router.state.historyAction === "POP" && activeRootSpan) {
|
|
262
256
|
updatePageloadTransaction({
|
|
263
257
|
activeRootSpan,
|
|
264
258
|
location: router.state.location,
|
|
265
259
|
routes,
|
|
266
|
-
|
|
267
|
-
|
|
260
|
+
allRoutes: Array.from(allRoutes),
|
|
261
|
+
config
|
|
268
262
|
});
|
|
269
263
|
}
|
|
270
|
-
|
|
271
|
-
setupRouterSubscription(router, routes, version, basename, activeRootSpan);
|
|
264
|
+
setupRouterSubscription(router, routes, version, activeRootSpan, config);
|
|
272
265
|
return router;
|
|
273
266
|
};
|
|
274
267
|
}
|
|
275
268
|
function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version) {
|
|
276
|
-
if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
|
|
277
|
-
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
278
|
-
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createMemoryRouter\` function because of one or more missing parameters.`
|
|
279
|
-
);
|
|
280
|
-
return createRouterFunction;
|
|
281
|
-
}
|
|
282
269
|
return function(routes, opts) {
|
|
270
|
+
const base = getRouterConfig(core.getClient());
|
|
271
|
+
if (!base) {
|
|
272
|
+
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
273
|
+
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createMemoryRouter\` function because the React Router browser tracing integration was not set up. Make sure \`Sentry.init()\` runs before the router is created.`
|
|
274
|
+
);
|
|
275
|
+
return createRouterFunction(routes, opts);
|
|
276
|
+
}
|
|
277
|
+
const config = { ...base, basename: opts?.basename || "" };
|
|
283
278
|
addRoutesToAllRoutes(routes);
|
|
284
|
-
if (
|
|
279
|
+
if (config.enableAsyncRouteHandlers) {
|
|
285
280
|
for (const route of routes) {
|
|
286
|
-
lazyRoutes.checkRouteForAsyncHandler(route, processResolvedRoutes);
|
|
281
|
+
lazyRoutes.checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
287
282
|
}
|
|
288
283
|
}
|
|
289
284
|
const memoryActiveRootSpanEarly = utils.getActiveRootSpan();
|
|
@@ -292,9 +287,8 @@ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version)
|
|
|
292
287
|
core.addNonEnumerableProperty(memoryActiveRootSpanEarly, "__sentry_may_have_lazy_routes__", true);
|
|
293
288
|
createDeferredLazyRoutePromise(memoryActiveRootSpanEarly);
|
|
294
289
|
}
|
|
295
|
-
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly);
|
|
290
|
+
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly, config);
|
|
296
291
|
const router = createRouterFunction(routes, wrappedOpts);
|
|
297
|
-
const basename = opts?.basename;
|
|
298
292
|
let initialEntry = void 0;
|
|
299
293
|
const initialEntries = opts?.initialEntries;
|
|
300
294
|
const initialIndex = opts?.initialIndex;
|
|
@@ -308,19 +302,17 @@ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version)
|
|
|
308
302
|
activeRootSpan: memoryActiveRootSpan,
|
|
309
303
|
location,
|
|
310
304
|
routes,
|
|
311
|
-
|
|
312
|
-
|
|
305
|
+
allRoutes: Array.from(allRoutes),
|
|
306
|
+
config
|
|
313
307
|
});
|
|
314
308
|
}
|
|
315
|
-
|
|
316
|
-
setupRouterSubscription(router, routes, version, basename, memoryActiveRootSpan);
|
|
309
|
+
setupRouterSubscription(router, routes, version, memoryActiveRootSpan, config);
|
|
317
310
|
return router;
|
|
318
311
|
};
|
|
319
312
|
}
|
|
320
313
|
function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
321
314
|
const integration = browser.browserTracingIntegration({ ...options, instrumentPageLoad: false, instrumentNavigation: false });
|
|
322
315
|
const {
|
|
323
|
-
useEffect,
|
|
324
316
|
useLocation,
|
|
325
317
|
useNavigationType,
|
|
326
318
|
createRoutesFromChildren,
|
|
@@ -332,15 +324,14 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
332
324
|
lazyRouteTimeout,
|
|
333
325
|
lazyRouteManifest
|
|
334
326
|
} = options;
|
|
335
|
-
return {
|
|
336
|
-
...integration,
|
|
327
|
+
return core.extendIntegration(integration, {
|
|
337
328
|
setup(client) {
|
|
338
|
-
integration.setup(client);
|
|
339
329
|
const finalTimeout = options.finalTimeout ?? 3e4;
|
|
340
330
|
const defaultMaxWait = (options.idleTimeout ?? 1e3) * 3;
|
|
341
331
|
const configuredMaxWait = lazyRouteTimeout ?? defaultMaxWait;
|
|
332
|
+
let resolvedLazyRouteTimeout;
|
|
342
333
|
if (configuredMaxWait === Infinity) {
|
|
343
|
-
|
|
334
|
+
resolvedLazyRouteTimeout = finalTimeout;
|
|
344
335
|
debugBuild.DEBUG_BUILD && core.debug.log(
|
|
345
336
|
"[React Router] lazyRouteTimeout set to Infinity, capping at finalTimeout:",
|
|
346
337
|
finalTimeout,
|
|
@@ -348,7 +339,7 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
348
339
|
);
|
|
349
340
|
} else if (Number.isNaN(configuredMaxWait)) {
|
|
350
341
|
debugBuild.DEBUG_BUILD && core.debug.warn("[React Router] lazyRouteTimeout must be a number, falling back to default:", defaultMaxWait);
|
|
351
|
-
|
|
342
|
+
resolvedLazyRouteTimeout = defaultMaxWait;
|
|
352
343
|
} else if (configuredMaxWait < 0) {
|
|
353
344
|
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
354
345
|
"[React Router] lazyRouteTimeout must be non-negative or Infinity, got:",
|
|
@@ -356,21 +347,30 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
356
347
|
"falling back to:",
|
|
357
348
|
defaultMaxWait
|
|
358
349
|
);
|
|
359
|
-
|
|
350
|
+
resolvedLazyRouteTimeout = defaultMaxWait;
|
|
360
351
|
} else {
|
|
361
|
-
|
|
352
|
+
resolvedLazyRouteTimeout = configuredMaxWait;
|
|
353
|
+
}
|
|
354
|
+
if (typeof useLocation === "function" && typeof useNavigationType === "function" && typeof createRoutesFromChildren === "function" && typeof matchRoutes === "function") {
|
|
355
|
+
reactRouterConfigByClient.set(client, {
|
|
356
|
+
useLocation,
|
|
357
|
+
useNavigationType,
|
|
358
|
+
createRoutesFromChildren,
|
|
359
|
+
matchRoutes,
|
|
360
|
+
stripBasename: stripBasename || false,
|
|
361
|
+
enableAsyncRouteHandlers,
|
|
362
|
+
instrumentNavigation,
|
|
363
|
+
lazyRouteTimeout: resolvedLazyRouteTimeout,
|
|
364
|
+
lazyRouteManifest,
|
|
365
|
+
basename: ""
|
|
366
|
+
});
|
|
367
|
+
} else {
|
|
368
|
+
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
369
|
+
"[React Router] Skipping route instrumentation because `useLocation`, `useNavigationType`, `createRoutesFromChildren` or `matchRoutes` was not provided. Pass them to `reactRouterBrowserTracingIntegration`, or import it from `@sentry/react/react-router` to have them supplied automatically."
|
|
370
|
+
);
|
|
362
371
|
}
|
|
363
|
-
_useEffect = useEffect;
|
|
364
|
-
_useLocation = useLocation;
|
|
365
|
-
_useNavigationType = useNavigationType;
|
|
366
|
-
_matchRoutes = matchRoutes;
|
|
367
|
-
_createRoutesFromChildren = createRoutesFromChildren;
|
|
368
|
-
_enableAsyncRouteHandlers = enableAsyncRouteHandlers;
|
|
369
|
-
_lazyRouteManifest = lazyRouteManifest;
|
|
370
|
-
utils.initializeRouterUtils(matchRoutes, stripBasename || false);
|
|
371
372
|
},
|
|
372
373
|
afterAllSetup(client) {
|
|
373
|
-
integration.afterAllSetup(client);
|
|
374
374
|
const initPathName = browser.WINDOW.location?.pathname;
|
|
375
375
|
if (instrumentPageLoad && initPathName) {
|
|
376
376
|
browser.startBrowserTracingPageLoadSpan(client, {
|
|
@@ -384,25 +384,14 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
384
384
|
}
|
|
385
385
|
});
|
|
386
386
|
}
|
|
387
|
-
if (instrumentNavigation) {
|
|
388
|
-
CLIENTS_WITH_INSTRUMENT_NAVIGATION.add(client);
|
|
389
|
-
}
|
|
390
387
|
}
|
|
391
|
-
};
|
|
388
|
+
});
|
|
392
389
|
}
|
|
393
390
|
function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
394
|
-
|
|
395
|
-
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
396
|
-
"reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters."
|
|
397
|
-
);
|
|
398
|
-
return origUseRoutes;
|
|
399
|
-
}
|
|
400
|
-
const SentryRoutes = (props) => {
|
|
391
|
+
const RouteReporter = ({ config, routes, locationArg }) => {
|
|
401
392
|
const isMountRenderPass = React.useRef(true);
|
|
402
|
-
const
|
|
403
|
-
const
|
|
404
|
-
const location = _useLocation();
|
|
405
|
-
const navigationType = _useNavigationType();
|
|
393
|
+
const location = config.useLocation();
|
|
394
|
+
const navigationType = config.useNavigationType();
|
|
406
395
|
const stableLocationParam = typeof locationArg === "string" || locationArg?.pathname ? locationArg : location;
|
|
407
396
|
useIsomorphicLayoutEffect(() => {
|
|
408
397
|
const added = addRoutesToAllRoutes(routes);
|
|
@@ -415,7 +404,8 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
|
415
404
|
activeRootSpan: utils.getActiveRootSpan(),
|
|
416
405
|
location: normalizedLocation,
|
|
417
406
|
routes,
|
|
418
|
-
allRoutes: Array.from(allRoutes)
|
|
407
|
+
allRoutes: Array.from(allRoutes),
|
|
408
|
+
config
|
|
419
409
|
});
|
|
420
410
|
isMountRenderPass.current = false;
|
|
421
411
|
} else {
|
|
@@ -424,17 +414,26 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
|
424
414
|
routes,
|
|
425
415
|
navigationType,
|
|
426
416
|
version,
|
|
427
|
-
allRoutes: Array.from(allRoutes)
|
|
417
|
+
allRoutes: Array.from(allRoutes),
|
|
418
|
+
config
|
|
428
419
|
});
|
|
429
420
|
}
|
|
430
421
|
}, [navigationType, stableLocationParam]);
|
|
431
|
-
return
|
|
422
|
+
return null;
|
|
423
|
+
};
|
|
424
|
+
const SentryRoutesWrapper = ({
|
|
425
|
+
routes,
|
|
426
|
+
locationArg
|
|
427
|
+
}) => {
|
|
428
|
+
const config = getRouterConfig(core.getClient());
|
|
429
|
+
const routesElement = origUseRoutes(routes, locationArg);
|
|
430
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, routesElement, config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routes, locationArg }) : null);
|
|
432
431
|
};
|
|
433
432
|
return (routes, locationArg) => {
|
|
434
|
-
return /* @__PURE__ */ React.createElement(
|
|
433
|
+
return /* @__PURE__ */ React.createElement(SentryRoutesWrapper, { routes, locationArg });
|
|
435
434
|
};
|
|
436
435
|
}
|
|
437
|
-
function wrapPatchRoutesOnNavigation(opts, isMemoryRouter
|
|
436
|
+
function wrapPatchRoutesOnNavigation(opts, isMemoryRouter, capturedSpan, config) {
|
|
438
437
|
if (!opts || !("patchRoutesOnNavigation" in opts) || typeof opts.patchRoutesOnNavigation !== "function") {
|
|
439
438
|
return opts || {};
|
|
440
439
|
}
|
|
@@ -473,7 +472,7 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
473
472
|
{ pathname: targetPath, search: "", hash: "", state: null, key: "default" },
|
|
474
473
|
Array.from(allRoutes),
|
|
475
474
|
true,
|
|
476
|
-
|
|
475
|
+
config
|
|
477
476
|
);
|
|
478
477
|
}
|
|
479
478
|
return originalPatch(routeId, children);
|
|
@@ -501,7 +500,7 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
501
500
|
{ pathname, search: "", hash: "", state: null, key: "default" },
|
|
502
501
|
Array.from(allRoutes),
|
|
503
502
|
false,
|
|
504
|
-
|
|
503
|
+
config
|
|
505
504
|
);
|
|
506
505
|
}
|
|
507
506
|
}
|
|
@@ -515,10 +514,10 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
515
514
|
};
|
|
516
515
|
}
|
|
517
516
|
function handleNavigation(opts) {
|
|
518
|
-
const { location, routes, navigationType, version,
|
|
519
|
-
const branches = Array.isArray(matches) ? matches :
|
|
517
|
+
const { location, routes, navigationType, version, config, matches, allRoutes: allRoutes2 } = opts;
|
|
518
|
+
const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
|
|
520
519
|
const client = core.getClient();
|
|
521
|
-
if (!client || !
|
|
520
|
+
if (!client || !config.instrumentNavigation) {
|
|
522
521
|
return;
|
|
523
522
|
}
|
|
524
523
|
const activeRootSpan = utils.getActiveRootSpan();
|
|
@@ -531,9 +530,7 @@ function handleNavigation(opts) {
|
|
|
531
530
|
allRoutes2 || routes,
|
|
532
531
|
allRoutes2 || routes,
|
|
533
532
|
branches,
|
|
534
|
-
|
|
535
|
-
_lazyRouteManifest,
|
|
536
|
-
_enableAsyncRouteHandlers
|
|
533
|
+
config
|
|
537
534
|
);
|
|
538
535
|
const locationKey = computeLocationKey(location);
|
|
539
536
|
const trackedNav = activeNavigationSpans.get(client);
|
|
@@ -598,7 +595,7 @@ function handleNavigation(opts) {
|
|
|
598
595
|
pathname: location.pathname,
|
|
599
596
|
locationKey
|
|
600
597
|
});
|
|
601
|
-
patchSpanEnd(navigationSpan, location, routes,
|
|
598
|
+
patchSpanEnd(navigationSpan, location, routes, "navigation", config);
|
|
602
599
|
} else {
|
|
603
600
|
activeNavigationSpans.delete(client);
|
|
604
601
|
}
|
|
@@ -638,20 +635,18 @@ function updatePageloadTransaction({
|
|
|
638
635
|
activeRootSpan,
|
|
639
636
|
location,
|
|
640
637
|
routes,
|
|
638
|
+
config,
|
|
641
639
|
matches,
|
|
642
|
-
basename,
|
|
643
640
|
allRoutes: allRoutes2
|
|
644
641
|
}) {
|
|
645
|
-
const branches = Array.isArray(matches) ? matches :
|
|
642
|
+
const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
|
|
646
643
|
if (branches) {
|
|
647
644
|
const [name, source] = utils.resolveRouteNameAndSource(
|
|
648
645
|
location,
|
|
649
646
|
allRoutes2 || routes,
|
|
650
647
|
allRoutes2 || routes,
|
|
651
648
|
branches,
|
|
652
|
-
|
|
653
|
-
_lazyRouteManifest,
|
|
654
|
-
_enableAsyncRouteHandlers
|
|
649
|
+
config
|
|
655
650
|
);
|
|
656
651
|
core.getCurrentScope().setTransactionName(name || "/");
|
|
657
652
|
if (activeRootSpan) {
|
|
@@ -662,10 +657,10 @@ function updatePageloadTransaction({
|
|
|
662
657
|
if (source === "route") {
|
|
663
658
|
activeRootSpan.setAttribute(attributes.URL_TEMPLATE, name);
|
|
664
659
|
}
|
|
665
|
-
patchSpanEnd(activeRootSpan, location, routes,
|
|
660
|
+
patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
|
|
666
661
|
}
|
|
667
662
|
} else if (activeRootSpan) {
|
|
668
|
-
patchSpanEnd(activeRootSpan, location, routes,
|
|
663
|
+
patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
|
|
669
664
|
}
|
|
670
665
|
}
|
|
671
666
|
function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSource, allowNoCurrentName = false) {
|
|
@@ -684,7 +679,7 @@ function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSo
|
|
|
684
679
|
}
|
|
685
680
|
return false;
|
|
686
681
|
}
|
|
687
|
-
function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
682
|
+
function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes2, config) {
|
|
688
683
|
try {
|
|
689
684
|
const currentSource = spanJson.attributes[attributes.SENTRY_SEGMENT_NAME_SOURCE];
|
|
690
685
|
if (currentSource === "route" && currentName && !utils.transactionNameHasWildcard(currentName)) {
|
|
@@ -692,19 +687,11 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
|
|
|
692
687
|
}
|
|
693
688
|
const currentAllRoutes = Array.from(allRoutes2);
|
|
694
689
|
const routesToUse = currentAllRoutes.length > 0 ? currentAllRoutes : routes;
|
|
695
|
-
const branches =
|
|
690
|
+
const branches = config.matchRoutes(routesToUse, location, config.basename);
|
|
696
691
|
if (!branches) {
|
|
697
692
|
return;
|
|
698
693
|
}
|
|
699
|
-
const [name, source] = utils.resolveRouteNameAndSource(
|
|
700
|
-
location,
|
|
701
|
-
routesToUse,
|
|
702
|
-
routesToUse,
|
|
703
|
-
branches,
|
|
704
|
-
basename,
|
|
705
|
-
_lazyRouteManifest,
|
|
706
|
-
_enableAsyncRouteHandlers
|
|
707
|
-
);
|
|
694
|
+
const [name, source] = utils.resolveRouteNameAndSource(location, routesToUse, routesToUse, branches, config);
|
|
708
695
|
const isImprovement = shouldUpdateWildcardSpanName(currentName, currentSource, name, source, true);
|
|
709
696
|
const spanNotEnded = spanType === "pageload" || !spanJson.end_timestamp;
|
|
710
697
|
if (isImprovement && spanNotEnded) {
|
|
@@ -721,7 +708,7 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
|
|
|
721
708
|
debugBuild.DEBUG_BUILD && core.debug.warn(`Error updating span details before ending: ${error}`);
|
|
722
709
|
}
|
|
723
710
|
}
|
|
724
|
-
function patchSpanEnd(span, location, routes,
|
|
711
|
+
function patchSpanEnd(span, location, routes, spanType, config) {
|
|
725
712
|
const patchedPropertyName = `__sentry_${spanType}_end_patched__`;
|
|
726
713
|
const hasEndBeenPatched = span?.[patchedPropertyName];
|
|
727
714
|
if (hasEndBeenPatched || !span.end) {
|
|
@@ -752,18 +739,18 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
752
739
|
const hasPendingOrMayHaveLazyRoutes = pendingPromises && pendingPromises.size > 0 || mayHaveLazyRoutes;
|
|
753
740
|
const shouldWaitForLazyRoutes = hasPendingOrMayHaveLazyRoutes && currentName && (utils.transactionNameHasWildcard(currentName) || currentSource !== "route");
|
|
754
741
|
if (shouldWaitForLazyRoutes) {
|
|
755
|
-
if (
|
|
756
|
-
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
742
|
+
if (config.lazyRouteTimeout === 0) {
|
|
743
|
+
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
|
|
757
744
|
cleanupNavigationSpan();
|
|
758
745
|
originalEnd(endTimestamp);
|
|
759
746
|
return;
|
|
760
747
|
}
|
|
761
|
-
const timeoutPromise = new Promise((r) => setTimeout(r,
|
|
748
|
+
const timeoutPromise = new Promise((r) => setTimeout(r, config.lazyRouteTimeout));
|
|
762
749
|
let waitPromise;
|
|
763
750
|
if (pendingPromises && pendingPromises.size > 0) {
|
|
764
751
|
const allSettled = Promise.allSettled(pendingPromises).then(() => {
|
|
765
752
|
});
|
|
766
|
-
waitPromise =
|
|
753
|
+
waitPromise = config.lazyRouteTimeout === Infinity ? allSettled : Promise.race([allSettled, timeoutPromise]);
|
|
767
754
|
} else {
|
|
768
755
|
waitPromise = timeoutPromise;
|
|
769
756
|
}
|
|
@@ -775,9 +762,9 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
775
762
|
updatedSpanJson.name,
|
|
776
763
|
location,
|
|
777
764
|
routes,
|
|
778
|
-
basename,
|
|
779
765
|
spanType,
|
|
780
|
-
allRoutes
|
|
766
|
+
allRoutes,
|
|
767
|
+
config
|
|
781
768
|
);
|
|
782
769
|
cleanupNavigationSpan();
|
|
783
770
|
originalEnd(endTimestamp);
|
|
@@ -787,24 +774,23 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
787
774
|
});
|
|
788
775
|
return;
|
|
789
776
|
}
|
|
790
|
-
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
777
|
+
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
|
|
791
778
|
cleanupNavigationSpan();
|
|
792
779
|
originalEnd(endTimestamp);
|
|
793
780
|
};
|
|
794
781
|
core.addNonEnumerableProperty(span, patchedPropertyName, true);
|
|
795
782
|
}
|
|
796
783
|
function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
return Routes;
|
|
802
|
-
}
|
|
803
|
-
const SentryRoutes = (props) => {
|
|
784
|
+
const RouteReporter = ({
|
|
785
|
+
config,
|
|
786
|
+
routeChildren
|
|
787
|
+
}) => {
|
|
804
788
|
const isMountRenderPass = React.useRef(true);
|
|
805
|
-
const location =
|
|
806
|
-
const navigationType =
|
|
807
|
-
const routes =
|
|
789
|
+
const location = config.useLocation();
|
|
790
|
+
const navigationType = config.useNavigationType();
|
|
791
|
+
const routes = config.createRoutesFromChildren(
|
|
792
|
+
routeChildren
|
|
793
|
+
);
|
|
808
794
|
useIsomorphicLayoutEffect(() => {
|
|
809
795
|
const added = addRoutesToAllRoutes(routes);
|
|
810
796
|
return () => removeRoutesFromAllRoutes(added);
|
|
@@ -816,17 +802,36 @@ function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
|
|
|
816
802
|
activeRootSpan: utils.getActiveRootSpan(),
|
|
817
803
|
location,
|
|
818
804
|
routes,
|
|
819
|
-
allRoutes: Array.from(allRoutes)
|
|
805
|
+
allRoutes: Array.from(allRoutes),
|
|
806
|
+
config
|
|
820
807
|
});
|
|
821
808
|
isMountRenderPass.current = false;
|
|
822
809
|
} else {
|
|
823
|
-
handleNavigation({
|
|
810
|
+
handleNavigation({
|
|
811
|
+
location,
|
|
812
|
+
routes,
|
|
813
|
+
navigationType,
|
|
814
|
+
version,
|
|
815
|
+
allRoutes: Array.from(allRoutes),
|
|
816
|
+
config
|
|
817
|
+
});
|
|
824
818
|
}
|
|
825
819
|
},
|
|
826
820
|
// Re-run only on location/navigation changes, not children changes
|
|
827
821
|
[location, navigationType]
|
|
828
822
|
);
|
|
829
|
-
return
|
|
823
|
+
return null;
|
|
824
|
+
};
|
|
825
|
+
const SentryRoutes = (props) => {
|
|
826
|
+
const config = getRouterConfig(core.getClient());
|
|
827
|
+
return /* @__PURE__ */ React.createElement(
|
|
828
|
+
React.Fragment,
|
|
829
|
+
null,
|
|
830
|
+
// @ts-expect-error Setting more specific React Component typing for `R` generic above
|
|
831
|
+
// will break advanced type inference done by react router params
|
|
832
|
+
/* @__PURE__ */ React.createElement(Routes, { ...props }),
|
|
833
|
+
config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routeChildren: props.children }) : null
|
|
834
|
+
);
|
|
830
835
|
};
|
|
831
836
|
hoistNonReactStatics.hoistNonReactStatics(SentryRoutes, Routes);
|
|
832
837
|
return SentryRoutes;
|