@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
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
import { WINDOW, browserTracingIntegration, startBrowserTracingPageLoadSpan, startBrowserTracingNavigationSpan } from '@sentry/browser';
|
|
2
|
-
import { PAGELOAD_SPAN_NAME_FALLBACK, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, hasSpanStreamingEnabled, debug, addNonEnumerableProperty, spanToJSON, getCurrentScope,
|
|
2
|
+
import { extendIntegration, PAGELOAD_SPAN_NAME_FALLBACK, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, hasSpanStreamingEnabled, debug, getClient, addNonEnumerableProperty, spanToJSON, getCurrentScope, NAVIGATION_SPAN_NAME_FALLBACK } from '@sentry/core';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { DEBUG_BUILD } from '../debug-build.js';
|
|
5
5
|
import { hoistNonReactStatics } from '../hoist-non-react-statics.js';
|
|
6
6
|
import { checkRouteForAsyncHandler } from './lazy-routes.js';
|
|
7
|
-
import { getActiveRootSpan, setNavigationContext, clearNavigationContext, resolveRouteNameAndSource, transactionNameHasWildcard
|
|
7
|
+
import { getActiveRootSpan, setNavigationContext, clearNavigationContext, resolveRouteNameAndSource, transactionNameHasWildcard } from './utils.js';
|
|
8
8
|
import { SENTRY_OP, SENTRY_SEGMENT_NAME_SOURCE, URL_TEMPLATE } from '@sentry/conventions/attributes';
|
|
9
9
|
import { PAGELOAD, NAVIGATION } from '@sentry/conventions/op';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
let _matchRoutes;
|
|
16
|
-
let _enableAsyncRouteHandlers = false;
|
|
17
|
-
let _lazyRouteTimeout = 3e3;
|
|
18
|
-
let _lazyRouteManifest;
|
|
19
|
-
let _basename = "";
|
|
20
|
-
const CLIENTS_WITH_INSTRUMENT_NAVIGATION = /* @__PURE__ */ new WeakSet();
|
|
11
|
+
const reactRouterConfigByClient = /* @__PURE__ */ new WeakMap();
|
|
12
|
+
function getRouterConfig(client) {
|
|
13
|
+
return client ? reactRouterConfigByClient.get(client) : void 0;
|
|
14
|
+
}
|
|
21
15
|
const useIsomorphicLayoutEffect = WINDOW?.document ? React.useLayoutEffect : React.useEffect;
|
|
22
16
|
const activeNavigationSpans = /* @__PURE__ */ new WeakMap();
|
|
23
17
|
const allRoutes = /* @__PURE__ */ new Set();
|
|
@@ -101,11 +95,11 @@ function resolveDeferredLazyRoutePromise(span) {
|
|
|
101
95
|
}
|
|
102
96
|
}
|
|
103
97
|
}
|
|
104
|
-
function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = null, capturedSpan) {
|
|
98
|
+
function processResolvedRoutes(resolvedRoutes, config, parentRoute, currentLocation = null, capturedSpan) {
|
|
105
99
|
resolvedRoutes.forEach((child) => {
|
|
106
100
|
allRoutes.add(child);
|
|
107
|
-
if (
|
|
108
|
-
checkRouteForAsyncHandler(child, processResolvedRoutes);
|
|
101
|
+
if (config.enableAsyncRouteHandlers) {
|
|
102
|
+
checkRouteForAsyncHandler(child, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
109
103
|
}
|
|
110
104
|
});
|
|
111
105
|
if (parentRoute) {
|
|
@@ -134,29 +128,28 @@ function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = nu
|
|
|
134
128
|
activeRootSpan: targetSpan,
|
|
135
129
|
location: { pathname: location.pathname },
|
|
136
130
|
routes: Array.from(allRoutes),
|
|
137
|
-
allRoutes: Array.from(allRoutes)
|
|
131
|
+
allRoutes: Array.from(allRoutes),
|
|
132
|
+
config
|
|
138
133
|
});
|
|
139
134
|
} else if (spanOp === "navigation") {
|
|
140
|
-
updateNavigationSpan(targetSpan, location, Array.from(allRoutes), false,
|
|
135
|
+
updateNavigationSpan(targetSpan, location, Array.from(allRoutes), false, config);
|
|
141
136
|
}
|
|
142
137
|
}
|
|
143
138
|
}
|
|
144
139
|
}
|
|
145
|
-
function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false,
|
|
140
|
+
function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false, config) {
|
|
146
141
|
const { name: currentName, end_timestamp, attributes } = spanToJSON(activeRootSpan);
|
|
147
142
|
const hasBeenNamed = activeRootSpan?.__sentry_navigation_name_set__;
|
|
148
143
|
const currentNameHasWildcard = currentName && transactionNameHasWildcard(currentName);
|
|
149
144
|
const shouldUpdate = !hasBeenNamed || forceUpdate || currentNameHasWildcard;
|
|
150
145
|
if (shouldUpdate && !end_timestamp) {
|
|
151
|
-
const currentBranches = matchRoutes(allRoutes2, location);
|
|
146
|
+
const currentBranches = config.matchRoutes(allRoutes2, location);
|
|
152
147
|
const [name, source] = resolveRouteNameAndSource(
|
|
153
148
|
location,
|
|
154
149
|
allRoutes2,
|
|
155
150
|
allRoutes2,
|
|
156
151
|
currentBranches || [],
|
|
157
|
-
|
|
158
|
-
_lazyRouteManifest,
|
|
159
|
-
_enableAsyncRouteHandlers
|
|
152
|
+
config
|
|
160
153
|
);
|
|
161
154
|
const currentSource = attributes[SENTRY_SEGMENT_NAME_SOURCE];
|
|
162
155
|
const isImprovement = name && (!currentName || // No current name - always set
|
|
@@ -177,7 +170,7 @@ function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate
|
|
|
177
170
|
}
|
|
178
171
|
}
|
|
179
172
|
}
|
|
180
|
-
function setupRouterSubscription(router, routes, version,
|
|
173
|
+
function setupRouterSubscription(router, routes, version, activeRootSpan, config) {
|
|
181
174
|
let isInitialPageloadComplete = false;
|
|
182
175
|
let hasSeenPageloadSpan = !!activeRootSpan && spanToJSON(activeRootSpan).attributes[SENTRY_OP] === "pageload";
|
|
183
176
|
let hasSeenPopAfterPageload = false;
|
|
@@ -211,8 +204,8 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
|
|
|
211
204
|
routes,
|
|
212
205
|
navigationType: state.historyAction,
|
|
213
206
|
version,
|
|
214
|
-
|
|
215
|
-
|
|
207
|
+
allRoutes: Array.from(allRoutes),
|
|
208
|
+
config
|
|
216
209
|
});
|
|
217
210
|
};
|
|
218
211
|
if (state.navigation.state !== "idle") {
|
|
@@ -234,17 +227,19 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
|
|
|
234
227
|
});
|
|
235
228
|
}
|
|
236
229
|
function createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, version) {
|
|
237
|
-
if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
|
|
238
|
-
DEBUG_BUILD && debug.warn(
|
|
239
|
-
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createRouter\` function because of one or more missing parameters.`
|
|
240
|
-
);
|
|
241
|
-
return createRouterFunction;
|
|
242
|
-
}
|
|
243
230
|
return function(routes, opts) {
|
|
231
|
+
const base = getRouterConfig(getClient());
|
|
232
|
+
if (!base) {
|
|
233
|
+
DEBUG_BUILD && debug.warn(
|
|
234
|
+
`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.`
|
|
235
|
+
);
|
|
236
|
+
return createRouterFunction(routes, opts);
|
|
237
|
+
}
|
|
238
|
+
const config = { ...base, basename: opts?.basename || "" };
|
|
244
239
|
addRoutesToAllRoutes(routes);
|
|
245
|
-
if (
|
|
240
|
+
if (config.enableAsyncRouteHandlers) {
|
|
246
241
|
for (const route of routes) {
|
|
247
|
-
checkRouteForAsyncHandler(route, processResolvedRoutes);
|
|
242
|
+
checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
248
243
|
}
|
|
249
244
|
}
|
|
250
245
|
const activeRootSpan = getActiveRootSpan();
|
|
@@ -253,35 +248,35 @@ function createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, version
|
|
|
253
248
|
addNonEnumerableProperty(activeRootSpan, "__sentry_may_have_lazy_routes__", true);
|
|
254
249
|
createDeferredLazyRoutePromise(activeRootSpan);
|
|
255
250
|
}
|
|
256
|
-
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan);
|
|
251
|
+
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan, config);
|
|
257
252
|
const router = createRouterFunction(routes, wrappedOpts);
|
|
258
|
-
const basename = opts?.basename;
|
|
259
253
|
if (router.state.historyAction === "POP" && activeRootSpan) {
|
|
260
254
|
updatePageloadTransaction({
|
|
261
255
|
activeRootSpan,
|
|
262
256
|
location: router.state.location,
|
|
263
257
|
routes,
|
|
264
|
-
|
|
265
|
-
|
|
258
|
+
allRoutes: Array.from(allRoutes),
|
|
259
|
+
config
|
|
266
260
|
});
|
|
267
261
|
}
|
|
268
|
-
|
|
269
|
-
setupRouterSubscription(router, routes, version, basename, activeRootSpan);
|
|
262
|
+
setupRouterSubscription(router, routes, version, activeRootSpan, config);
|
|
270
263
|
return router;
|
|
271
264
|
};
|
|
272
265
|
}
|
|
273
266
|
function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version) {
|
|
274
|
-
if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
|
|
275
|
-
DEBUG_BUILD && debug.warn(
|
|
276
|
-
`reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createMemoryRouter\` function because of one or more missing parameters.`
|
|
277
|
-
);
|
|
278
|
-
return createRouterFunction;
|
|
279
|
-
}
|
|
280
267
|
return function(routes, opts) {
|
|
268
|
+
const base = getRouterConfig(getClient());
|
|
269
|
+
if (!base) {
|
|
270
|
+
DEBUG_BUILD && debug.warn(
|
|
271
|
+
`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.`
|
|
272
|
+
);
|
|
273
|
+
return createRouterFunction(routes, opts);
|
|
274
|
+
}
|
|
275
|
+
const config = { ...base, basename: opts?.basename || "" };
|
|
281
276
|
addRoutesToAllRoutes(routes);
|
|
282
|
-
if (
|
|
277
|
+
if (config.enableAsyncRouteHandlers) {
|
|
283
278
|
for (const route of routes) {
|
|
284
|
-
checkRouteForAsyncHandler(route, processResolvedRoutes);
|
|
279
|
+
checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
285
280
|
}
|
|
286
281
|
}
|
|
287
282
|
const memoryActiveRootSpanEarly = getActiveRootSpan();
|
|
@@ -290,9 +285,8 @@ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version)
|
|
|
290
285
|
addNonEnumerableProperty(memoryActiveRootSpanEarly, "__sentry_may_have_lazy_routes__", true);
|
|
291
286
|
createDeferredLazyRoutePromise(memoryActiveRootSpanEarly);
|
|
292
287
|
}
|
|
293
|
-
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly);
|
|
288
|
+
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly, config);
|
|
294
289
|
const router = createRouterFunction(routes, wrappedOpts);
|
|
295
|
-
const basename = opts?.basename;
|
|
296
290
|
let initialEntry = void 0;
|
|
297
291
|
const initialEntries = opts?.initialEntries;
|
|
298
292
|
const initialIndex = opts?.initialIndex;
|
|
@@ -306,19 +300,17 @@ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version)
|
|
|
306
300
|
activeRootSpan: memoryActiveRootSpan,
|
|
307
301
|
location,
|
|
308
302
|
routes,
|
|
309
|
-
|
|
310
|
-
|
|
303
|
+
allRoutes: Array.from(allRoutes),
|
|
304
|
+
config
|
|
311
305
|
});
|
|
312
306
|
}
|
|
313
|
-
|
|
314
|
-
setupRouterSubscription(router, routes, version, basename, memoryActiveRootSpan);
|
|
307
|
+
setupRouterSubscription(router, routes, version, memoryActiveRootSpan, config);
|
|
315
308
|
return router;
|
|
316
309
|
};
|
|
317
310
|
}
|
|
318
311
|
function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
319
312
|
const integration = browserTracingIntegration({ ...options, instrumentPageLoad: false, instrumentNavigation: false });
|
|
320
313
|
const {
|
|
321
|
-
useEffect,
|
|
322
314
|
useLocation,
|
|
323
315
|
useNavigationType,
|
|
324
316
|
createRoutesFromChildren,
|
|
@@ -330,15 +322,14 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
330
322
|
lazyRouteTimeout,
|
|
331
323
|
lazyRouteManifest
|
|
332
324
|
} = options;
|
|
333
|
-
return {
|
|
334
|
-
...integration,
|
|
325
|
+
return extendIntegration(integration, {
|
|
335
326
|
setup(client) {
|
|
336
|
-
integration.setup(client);
|
|
337
327
|
const finalTimeout = options.finalTimeout ?? 3e4;
|
|
338
328
|
const defaultMaxWait = (options.idleTimeout ?? 1e3) * 3;
|
|
339
329
|
const configuredMaxWait = lazyRouteTimeout ?? defaultMaxWait;
|
|
330
|
+
let resolvedLazyRouteTimeout;
|
|
340
331
|
if (configuredMaxWait === Infinity) {
|
|
341
|
-
|
|
332
|
+
resolvedLazyRouteTimeout = finalTimeout;
|
|
342
333
|
DEBUG_BUILD && debug.log(
|
|
343
334
|
"[React Router] lazyRouteTimeout set to Infinity, capping at finalTimeout:",
|
|
344
335
|
finalTimeout,
|
|
@@ -346,7 +337,7 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
346
337
|
);
|
|
347
338
|
} else if (Number.isNaN(configuredMaxWait)) {
|
|
348
339
|
DEBUG_BUILD && debug.warn("[React Router] lazyRouteTimeout must be a number, falling back to default:", defaultMaxWait);
|
|
349
|
-
|
|
340
|
+
resolvedLazyRouteTimeout = defaultMaxWait;
|
|
350
341
|
} else if (configuredMaxWait < 0) {
|
|
351
342
|
DEBUG_BUILD && debug.warn(
|
|
352
343
|
"[React Router] lazyRouteTimeout must be non-negative or Infinity, got:",
|
|
@@ -354,21 +345,30 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
354
345
|
"falling back to:",
|
|
355
346
|
defaultMaxWait
|
|
356
347
|
);
|
|
357
|
-
|
|
348
|
+
resolvedLazyRouteTimeout = defaultMaxWait;
|
|
358
349
|
} else {
|
|
359
|
-
|
|
350
|
+
resolvedLazyRouteTimeout = configuredMaxWait;
|
|
351
|
+
}
|
|
352
|
+
if (typeof useLocation === "function" && typeof useNavigationType === "function" && typeof createRoutesFromChildren === "function" && typeof matchRoutes === "function") {
|
|
353
|
+
reactRouterConfigByClient.set(client, {
|
|
354
|
+
useLocation,
|
|
355
|
+
useNavigationType,
|
|
356
|
+
createRoutesFromChildren,
|
|
357
|
+
matchRoutes,
|
|
358
|
+
stripBasename: stripBasename || false,
|
|
359
|
+
enableAsyncRouteHandlers,
|
|
360
|
+
instrumentNavigation,
|
|
361
|
+
lazyRouteTimeout: resolvedLazyRouteTimeout,
|
|
362
|
+
lazyRouteManifest,
|
|
363
|
+
basename: ""
|
|
364
|
+
});
|
|
365
|
+
} else {
|
|
366
|
+
DEBUG_BUILD && debug.warn(
|
|
367
|
+
"[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."
|
|
368
|
+
);
|
|
360
369
|
}
|
|
361
|
-
_useEffect = useEffect;
|
|
362
|
-
_useLocation = useLocation;
|
|
363
|
-
_useNavigationType = useNavigationType;
|
|
364
|
-
_matchRoutes = matchRoutes;
|
|
365
|
-
_createRoutesFromChildren = createRoutesFromChildren;
|
|
366
|
-
_enableAsyncRouteHandlers = enableAsyncRouteHandlers;
|
|
367
|
-
_lazyRouteManifest = lazyRouteManifest;
|
|
368
|
-
initializeRouterUtils(matchRoutes, stripBasename || false);
|
|
369
370
|
},
|
|
370
371
|
afterAllSetup(client) {
|
|
371
|
-
integration.afterAllSetup(client);
|
|
372
372
|
const initPathName = WINDOW.location?.pathname;
|
|
373
373
|
if (instrumentPageLoad && initPathName) {
|
|
374
374
|
startBrowserTracingPageLoadSpan(client, {
|
|
@@ -382,25 +382,14 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
382
382
|
}
|
|
383
383
|
});
|
|
384
384
|
}
|
|
385
|
-
if (instrumentNavigation) {
|
|
386
|
-
CLIENTS_WITH_INSTRUMENT_NAVIGATION.add(client);
|
|
387
|
-
}
|
|
388
385
|
}
|
|
389
|
-
};
|
|
386
|
+
});
|
|
390
387
|
}
|
|
391
388
|
function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
392
|
-
|
|
393
|
-
DEBUG_BUILD && debug.warn(
|
|
394
|
-
"reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters."
|
|
395
|
-
);
|
|
396
|
-
return origUseRoutes;
|
|
397
|
-
}
|
|
398
|
-
const SentryRoutes = (props) => {
|
|
389
|
+
const RouteReporter = ({ config, routes, locationArg }) => {
|
|
399
390
|
const isMountRenderPass = React.useRef(true);
|
|
400
|
-
const
|
|
401
|
-
const
|
|
402
|
-
const location = _useLocation();
|
|
403
|
-
const navigationType = _useNavigationType();
|
|
391
|
+
const location = config.useLocation();
|
|
392
|
+
const navigationType = config.useNavigationType();
|
|
404
393
|
const stableLocationParam = typeof locationArg === "string" || locationArg?.pathname ? locationArg : location;
|
|
405
394
|
useIsomorphicLayoutEffect(() => {
|
|
406
395
|
const added = addRoutesToAllRoutes(routes);
|
|
@@ -413,7 +402,8 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
|
413
402
|
activeRootSpan: getActiveRootSpan(),
|
|
414
403
|
location: normalizedLocation,
|
|
415
404
|
routes,
|
|
416
|
-
allRoutes: Array.from(allRoutes)
|
|
405
|
+
allRoutes: Array.from(allRoutes),
|
|
406
|
+
config
|
|
417
407
|
});
|
|
418
408
|
isMountRenderPass.current = false;
|
|
419
409
|
} else {
|
|
@@ -422,17 +412,26 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
|
422
412
|
routes,
|
|
423
413
|
navigationType,
|
|
424
414
|
version,
|
|
425
|
-
allRoutes: Array.from(allRoutes)
|
|
415
|
+
allRoutes: Array.from(allRoutes),
|
|
416
|
+
config
|
|
426
417
|
});
|
|
427
418
|
}
|
|
428
419
|
}, [navigationType, stableLocationParam]);
|
|
429
|
-
return
|
|
420
|
+
return null;
|
|
421
|
+
};
|
|
422
|
+
const SentryRoutesWrapper = ({
|
|
423
|
+
routes,
|
|
424
|
+
locationArg
|
|
425
|
+
}) => {
|
|
426
|
+
const config = getRouterConfig(getClient());
|
|
427
|
+
const routesElement = origUseRoutes(routes, locationArg);
|
|
428
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, routesElement, config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routes, locationArg }) : null);
|
|
430
429
|
};
|
|
431
430
|
return (routes, locationArg) => {
|
|
432
|
-
return /* @__PURE__ */ React.createElement(
|
|
431
|
+
return /* @__PURE__ */ React.createElement(SentryRoutesWrapper, { routes, locationArg });
|
|
433
432
|
};
|
|
434
433
|
}
|
|
435
|
-
function wrapPatchRoutesOnNavigation(opts, isMemoryRouter
|
|
434
|
+
function wrapPatchRoutesOnNavigation(opts, isMemoryRouter, capturedSpan, config) {
|
|
436
435
|
if (!opts || !("patchRoutesOnNavigation" in opts) || typeof opts.patchRoutesOnNavigation !== "function") {
|
|
437
436
|
return opts || {};
|
|
438
437
|
}
|
|
@@ -471,7 +470,7 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
471
470
|
{ pathname: targetPath, search: "", hash: "", state: null, key: "default" },
|
|
472
471
|
Array.from(allRoutes),
|
|
473
472
|
true,
|
|
474
|
-
|
|
473
|
+
config
|
|
475
474
|
);
|
|
476
475
|
}
|
|
477
476
|
return originalPatch(routeId, children);
|
|
@@ -499,7 +498,7 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
499
498
|
{ pathname, search: "", hash: "", state: null, key: "default" },
|
|
500
499
|
Array.from(allRoutes),
|
|
501
500
|
false,
|
|
502
|
-
|
|
501
|
+
config
|
|
503
502
|
);
|
|
504
503
|
}
|
|
505
504
|
}
|
|
@@ -513,10 +512,10 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
513
512
|
};
|
|
514
513
|
}
|
|
515
514
|
function handleNavigation(opts) {
|
|
516
|
-
const { location, routes, navigationType, version,
|
|
517
|
-
const branches = Array.isArray(matches) ? matches :
|
|
515
|
+
const { location, routes, navigationType, version, config, matches, allRoutes: allRoutes2 } = opts;
|
|
516
|
+
const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
|
|
518
517
|
const client = getClient();
|
|
519
|
-
if (!client || !
|
|
518
|
+
if (!client || !config.instrumentNavigation) {
|
|
520
519
|
return;
|
|
521
520
|
}
|
|
522
521
|
const activeRootSpan = getActiveRootSpan();
|
|
@@ -529,9 +528,7 @@ function handleNavigation(opts) {
|
|
|
529
528
|
allRoutes2 || routes,
|
|
530
529
|
allRoutes2 || routes,
|
|
531
530
|
branches,
|
|
532
|
-
|
|
533
|
-
_lazyRouteManifest,
|
|
534
|
-
_enableAsyncRouteHandlers
|
|
531
|
+
config
|
|
535
532
|
);
|
|
536
533
|
const locationKey = computeLocationKey(location);
|
|
537
534
|
const trackedNav = activeNavigationSpans.get(client);
|
|
@@ -596,7 +593,7 @@ function handleNavigation(opts) {
|
|
|
596
593
|
pathname: location.pathname,
|
|
597
594
|
locationKey
|
|
598
595
|
});
|
|
599
|
-
patchSpanEnd(navigationSpan, location, routes,
|
|
596
|
+
patchSpanEnd(navigationSpan, location, routes, "navigation", config);
|
|
600
597
|
} else {
|
|
601
598
|
activeNavigationSpans.delete(client);
|
|
602
599
|
}
|
|
@@ -636,20 +633,18 @@ function updatePageloadTransaction({
|
|
|
636
633
|
activeRootSpan,
|
|
637
634
|
location,
|
|
638
635
|
routes,
|
|
636
|
+
config,
|
|
639
637
|
matches,
|
|
640
|
-
basename,
|
|
641
638
|
allRoutes: allRoutes2
|
|
642
639
|
}) {
|
|
643
|
-
const branches = Array.isArray(matches) ? matches :
|
|
640
|
+
const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
|
|
644
641
|
if (branches) {
|
|
645
642
|
const [name, source] = resolveRouteNameAndSource(
|
|
646
643
|
location,
|
|
647
644
|
allRoutes2 || routes,
|
|
648
645
|
allRoutes2 || routes,
|
|
649
646
|
branches,
|
|
650
|
-
|
|
651
|
-
_lazyRouteManifest,
|
|
652
|
-
_enableAsyncRouteHandlers
|
|
647
|
+
config
|
|
653
648
|
);
|
|
654
649
|
getCurrentScope().setTransactionName(name || "/");
|
|
655
650
|
if (activeRootSpan) {
|
|
@@ -660,10 +655,10 @@ function updatePageloadTransaction({
|
|
|
660
655
|
if (source === "route") {
|
|
661
656
|
activeRootSpan.setAttribute(URL_TEMPLATE, name);
|
|
662
657
|
}
|
|
663
|
-
patchSpanEnd(activeRootSpan, location, routes,
|
|
658
|
+
patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
|
|
664
659
|
}
|
|
665
660
|
} else if (activeRootSpan) {
|
|
666
|
-
patchSpanEnd(activeRootSpan, location, routes,
|
|
661
|
+
patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
|
|
667
662
|
}
|
|
668
663
|
}
|
|
669
664
|
function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSource, allowNoCurrentName = false) {
|
|
@@ -682,7 +677,7 @@ function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSo
|
|
|
682
677
|
}
|
|
683
678
|
return false;
|
|
684
679
|
}
|
|
685
|
-
function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
680
|
+
function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes2, config) {
|
|
686
681
|
try {
|
|
687
682
|
const currentSource = spanJson.attributes[SENTRY_SEGMENT_NAME_SOURCE];
|
|
688
683
|
if (currentSource === "route" && currentName && !transactionNameHasWildcard(currentName)) {
|
|
@@ -690,19 +685,11 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
|
|
|
690
685
|
}
|
|
691
686
|
const currentAllRoutes = Array.from(allRoutes2);
|
|
692
687
|
const routesToUse = currentAllRoutes.length > 0 ? currentAllRoutes : routes;
|
|
693
|
-
const branches =
|
|
688
|
+
const branches = config.matchRoutes(routesToUse, location, config.basename);
|
|
694
689
|
if (!branches) {
|
|
695
690
|
return;
|
|
696
691
|
}
|
|
697
|
-
const [name, source] = resolveRouteNameAndSource(
|
|
698
|
-
location,
|
|
699
|
-
routesToUse,
|
|
700
|
-
routesToUse,
|
|
701
|
-
branches,
|
|
702
|
-
basename,
|
|
703
|
-
_lazyRouteManifest,
|
|
704
|
-
_enableAsyncRouteHandlers
|
|
705
|
-
);
|
|
692
|
+
const [name, source] = resolveRouteNameAndSource(location, routesToUse, routesToUse, branches, config);
|
|
706
693
|
const isImprovement = shouldUpdateWildcardSpanName(currentName, currentSource, name, source, true);
|
|
707
694
|
const spanNotEnded = spanType === "pageload" || !spanJson.end_timestamp;
|
|
708
695
|
if (isImprovement && spanNotEnded) {
|
|
@@ -719,7 +706,7 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
|
|
|
719
706
|
DEBUG_BUILD && debug.warn(`Error updating span details before ending: ${error}`);
|
|
720
707
|
}
|
|
721
708
|
}
|
|
722
|
-
function patchSpanEnd(span, location, routes,
|
|
709
|
+
function patchSpanEnd(span, location, routes, spanType, config) {
|
|
723
710
|
const patchedPropertyName = `__sentry_${spanType}_end_patched__`;
|
|
724
711
|
const hasEndBeenPatched = span?.[patchedPropertyName];
|
|
725
712
|
if (hasEndBeenPatched || !span.end) {
|
|
@@ -750,18 +737,18 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
750
737
|
const hasPendingOrMayHaveLazyRoutes = pendingPromises && pendingPromises.size > 0 || mayHaveLazyRoutes;
|
|
751
738
|
const shouldWaitForLazyRoutes = hasPendingOrMayHaveLazyRoutes && currentName && (transactionNameHasWildcard(currentName) || currentSource !== "route");
|
|
752
739
|
if (shouldWaitForLazyRoutes) {
|
|
753
|
-
if (
|
|
754
|
-
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
740
|
+
if (config.lazyRouteTimeout === 0) {
|
|
741
|
+
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
|
|
755
742
|
cleanupNavigationSpan();
|
|
756
743
|
originalEnd(endTimestamp);
|
|
757
744
|
return;
|
|
758
745
|
}
|
|
759
|
-
const timeoutPromise = new Promise((r) => setTimeout(r,
|
|
746
|
+
const timeoutPromise = new Promise((r) => setTimeout(r, config.lazyRouteTimeout));
|
|
760
747
|
let waitPromise;
|
|
761
748
|
if (pendingPromises && pendingPromises.size > 0) {
|
|
762
749
|
const allSettled = Promise.allSettled(pendingPromises).then(() => {
|
|
763
750
|
});
|
|
764
|
-
waitPromise =
|
|
751
|
+
waitPromise = config.lazyRouteTimeout === Infinity ? allSettled : Promise.race([allSettled, timeoutPromise]);
|
|
765
752
|
} else {
|
|
766
753
|
waitPromise = timeoutPromise;
|
|
767
754
|
}
|
|
@@ -773,9 +760,9 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
773
760
|
updatedSpanJson.name,
|
|
774
761
|
location,
|
|
775
762
|
routes,
|
|
776
|
-
basename,
|
|
777
763
|
spanType,
|
|
778
|
-
allRoutes
|
|
764
|
+
allRoutes,
|
|
765
|
+
config
|
|
779
766
|
);
|
|
780
767
|
cleanupNavigationSpan();
|
|
781
768
|
originalEnd(endTimestamp);
|
|
@@ -785,24 +772,23 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
785
772
|
});
|
|
786
773
|
return;
|
|
787
774
|
}
|
|
788
|
-
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
775
|
+
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
|
|
789
776
|
cleanupNavigationSpan();
|
|
790
777
|
originalEnd(endTimestamp);
|
|
791
778
|
};
|
|
792
779
|
addNonEnumerableProperty(span, patchedPropertyName, true);
|
|
793
780
|
}
|
|
794
781
|
function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
return Routes;
|
|
800
|
-
}
|
|
801
|
-
const SentryRoutes = (props) => {
|
|
782
|
+
const RouteReporter = ({
|
|
783
|
+
config,
|
|
784
|
+
routeChildren
|
|
785
|
+
}) => {
|
|
802
786
|
const isMountRenderPass = React.useRef(true);
|
|
803
|
-
const location =
|
|
804
|
-
const navigationType =
|
|
805
|
-
const routes =
|
|
787
|
+
const location = config.useLocation();
|
|
788
|
+
const navigationType = config.useNavigationType();
|
|
789
|
+
const routes = config.createRoutesFromChildren(
|
|
790
|
+
routeChildren
|
|
791
|
+
);
|
|
806
792
|
useIsomorphicLayoutEffect(() => {
|
|
807
793
|
const added = addRoutesToAllRoutes(routes);
|
|
808
794
|
return () => removeRoutesFromAllRoutes(added);
|
|
@@ -814,17 +800,36 @@ function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
|
|
|
814
800
|
activeRootSpan: getActiveRootSpan(),
|
|
815
801
|
location,
|
|
816
802
|
routes,
|
|
817
|
-
allRoutes: Array.from(allRoutes)
|
|
803
|
+
allRoutes: Array.from(allRoutes),
|
|
804
|
+
config
|
|
818
805
|
});
|
|
819
806
|
isMountRenderPass.current = false;
|
|
820
807
|
} else {
|
|
821
|
-
handleNavigation({
|
|
808
|
+
handleNavigation({
|
|
809
|
+
location,
|
|
810
|
+
routes,
|
|
811
|
+
navigationType,
|
|
812
|
+
version,
|
|
813
|
+
allRoutes: Array.from(allRoutes),
|
|
814
|
+
config
|
|
815
|
+
});
|
|
822
816
|
}
|
|
823
817
|
},
|
|
824
818
|
// Re-run only on location/navigation changes, not children changes
|
|
825
819
|
[location, navigationType]
|
|
826
820
|
);
|
|
827
|
-
return
|
|
821
|
+
return null;
|
|
822
|
+
};
|
|
823
|
+
const SentryRoutes = (props) => {
|
|
824
|
+
const config = getRouterConfig(getClient());
|
|
825
|
+
return /* @__PURE__ */ React.createElement(
|
|
826
|
+
React.Fragment,
|
|
827
|
+
null,
|
|
828
|
+
// @ts-expect-error Setting more specific React Component typing for `R` generic above
|
|
829
|
+
// will break advanced type inference done by react router params
|
|
830
|
+
/* @__PURE__ */ React.createElement(Routes, { ...props }),
|
|
831
|
+
config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routeChildren: props.children }) : null
|
|
832
|
+
);
|
|
828
833
|
};
|
|
829
834
|
hoistNonReactStatics(SentryRoutes, Routes);
|
|
830
835
|
return SentryRoutes;
|