@sentry/react 11.0.0-beta.1 → 11.0.0-rc.0
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 +149 -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/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 +151 -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/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/types.d.ts +16 -0
- package/build/types/types.d.ts.map +1 -1
- package/package.json +34 -6
|
@@ -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,35 @@ 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);
|
|
144
|
+
const spanPathname = activeRootSpan?.__sentry_navigation_pathname__;
|
|
145
|
+
if (spanPathname !== void 0 && spanPathname !== location.pathname) {
|
|
146
|
+
debugBuild.DEBUG_BUILD && core.debug.log(
|
|
147
|
+
`[React Router] Not renaming the navigation span for "${spanPathname}" with the route of "${location.pathname}"`
|
|
148
|
+
);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
149
151
|
const hasBeenNamed = activeRootSpan?.__sentry_navigation_name_set__;
|
|
150
152
|
const currentNameHasWildcard = currentName && utils.transactionNameHasWildcard(currentName);
|
|
151
153
|
const shouldUpdate = !hasBeenNamed || forceUpdate || currentNameHasWildcard;
|
|
152
154
|
if (shouldUpdate && !end_timestamp) {
|
|
153
|
-
const currentBranches = matchRoutes(allRoutes2, location);
|
|
155
|
+
const currentBranches = config.matchRoutes(allRoutes2, location);
|
|
154
156
|
const [name, source] = utils.resolveRouteNameAndSource(
|
|
155
157
|
location,
|
|
156
158
|
allRoutes2,
|
|
157
159
|
allRoutes2,
|
|
158
160
|
currentBranches || [],
|
|
159
|
-
|
|
160
|
-
_lazyRouteManifest,
|
|
161
|
-
_enableAsyncRouteHandlers
|
|
161
|
+
config
|
|
162
162
|
);
|
|
163
163
|
const currentSource = attributes$1[attributes.SENTRY_SEGMENT_NAME_SOURCE];
|
|
164
164
|
const isImprovement = name && (!currentName || // No current name - always set
|
|
@@ -179,7 +179,7 @@ function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate
|
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
-
function setupRouterSubscription(router, routes, version,
|
|
182
|
+
function setupRouterSubscription(router, routes, version, activeRootSpan, config) {
|
|
183
183
|
let isInitialPageloadComplete = false;
|
|
184
184
|
let hasSeenPageloadSpan = !!activeRootSpan && core.spanToJSON(activeRootSpan).attributes[attributes.SENTRY_OP] === "pageload";
|
|
185
185
|
let hasSeenPopAfterPageload = false;
|
|
@@ -213,8 +213,8 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
|
|
|
213
213
|
routes,
|
|
214
214
|
navigationType: state.historyAction,
|
|
215
215
|
version,
|
|
216
|
-
|
|
217
|
-
|
|
216
|
+
allRoutes: Array.from(allRoutes),
|
|
217
|
+
config
|
|
218
218
|
});
|
|
219
219
|
};
|
|
220
220
|
if (state.navigation.state !== "idle") {
|
|
@@ -236,17 +236,19 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
|
|
|
236
236
|
});
|
|
237
237
|
}
|
|
238
238
|
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
239
|
return function(routes, opts) {
|
|
240
|
+
const base = getRouterConfig(core.getClient());
|
|
241
|
+
if (!base) {
|
|
242
|
+
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
243
|
+
`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.`
|
|
244
|
+
);
|
|
245
|
+
return createRouterFunction(routes, opts);
|
|
246
|
+
}
|
|
247
|
+
const config = { ...base, basename: opts?.basename || "" };
|
|
246
248
|
addRoutesToAllRoutes(routes);
|
|
247
|
-
if (
|
|
249
|
+
if (config.enableAsyncRouteHandlers) {
|
|
248
250
|
for (const route of routes) {
|
|
249
|
-
lazyRoutes.checkRouteForAsyncHandler(route, processResolvedRoutes);
|
|
251
|
+
lazyRoutes.checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
250
252
|
}
|
|
251
253
|
}
|
|
252
254
|
const activeRootSpan = utils.getActiveRootSpan();
|
|
@@ -255,35 +257,35 @@ function createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, version
|
|
|
255
257
|
core.addNonEnumerableProperty(activeRootSpan, "__sentry_may_have_lazy_routes__", true);
|
|
256
258
|
createDeferredLazyRoutePromise(activeRootSpan);
|
|
257
259
|
}
|
|
258
|
-
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan);
|
|
260
|
+
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan, config);
|
|
259
261
|
const router = createRouterFunction(routes, wrappedOpts);
|
|
260
|
-
const basename = opts?.basename;
|
|
261
262
|
if (router.state.historyAction === "POP" && activeRootSpan) {
|
|
262
263
|
updatePageloadTransaction({
|
|
263
264
|
activeRootSpan,
|
|
264
265
|
location: router.state.location,
|
|
265
266
|
routes,
|
|
266
|
-
|
|
267
|
-
|
|
267
|
+
allRoutes: Array.from(allRoutes),
|
|
268
|
+
config
|
|
268
269
|
});
|
|
269
270
|
}
|
|
270
|
-
|
|
271
|
-
setupRouterSubscription(router, routes, version, basename, activeRootSpan);
|
|
271
|
+
setupRouterSubscription(router, routes, version, activeRootSpan, config);
|
|
272
272
|
return router;
|
|
273
273
|
};
|
|
274
274
|
}
|
|
275
275
|
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
276
|
return function(routes, opts) {
|
|
277
|
+
const base = getRouterConfig(core.getClient());
|
|
278
|
+
if (!base) {
|
|
279
|
+
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
280
|
+
`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.`
|
|
281
|
+
);
|
|
282
|
+
return createRouterFunction(routes, opts);
|
|
283
|
+
}
|
|
284
|
+
const config = { ...base, basename: opts?.basename || "" };
|
|
283
285
|
addRoutesToAllRoutes(routes);
|
|
284
|
-
if (
|
|
286
|
+
if (config.enableAsyncRouteHandlers) {
|
|
285
287
|
for (const route of routes) {
|
|
286
|
-
lazyRoutes.checkRouteForAsyncHandler(route, processResolvedRoutes);
|
|
288
|
+
lazyRoutes.checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
|
|
287
289
|
}
|
|
288
290
|
}
|
|
289
291
|
const memoryActiveRootSpanEarly = utils.getActiveRootSpan();
|
|
@@ -292,9 +294,8 @@ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version)
|
|
|
292
294
|
core.addNonEnumerableProperty(memoryActiveRootSpanEarly, "__sentry_may_have_lazy_routes__", true);
|
|
293
295
|
createDeferredLazyRoutePromise(memoryActiveRootSpanEarly);
|
|
294
296
|
}
|
|
295
|
-
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly);
|
|
297
|
+
const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly, config);
|
|
296
298
|
const router = createRouterFunction(routes, wrappedOpts);
|
|
297
|
-
const basename = opts?.basename;
|
|
298
299
|
let initialEntry = void 0;
|
|
299
300
|
const initialEntries = opts?.initialEntries;
|
|
300
301
|
const initialIndex = opts?.initialIndex;
|
|
@@ -308,19 +309,17 @@ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version)
|
|
|
308
309
|
activeRootSpan: memoryActiveRootSpan,
|
|
309
310
|
location,
|
|
310
311
|
routes,
|
|
311
|
-
|
|
312
|
-
|
|
312
|
+
allRoutes: Array.from(allRoutes),
|
|
313
|
+
config
|
|
313
314
|
});
|
|
314
315
|
}
|
|
315
|
-
|
|
316
|
-
setupRouterSubscription(router, routes, version, basename, memoryActiveRootSpan);
|
|
316
|
+
setupRouterSubscription(router, routes, version, memoryActiveRootSpan, config);
|
|
317
317
|
return router;
|
|
318
318
|
};
|
|
319
319
|
}
|
|
320
320
|
function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
321
321
|
const integration = browser.browserTracingIntegration({ ...options, instrumentPageLoad: false, instrumentNavigation: false });
|
|
322
322
|
const {
|
|
323
|
-
useEffect,
|
|
324
323
|
useLocation,
|
|
325
324
|
useNavigationType,
|
|
326
325
|
createRoutesFromChildren,
|
|
@@ -332,15 +331,14 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
332
331
|
lazyRouteTimeout,
|
|
333
332
|
lazyRouteManifest
|
|
334
333
|
} = options;
|
|
335
|
-
return {
|
|
336
|
-
...integration,
|
|
334
|
+
return core.extendIntegration(integration, {
|
|
337
335
|
setup(client) {
|
|
338
|
-
integration.setup(client);
|
|
339
336
|
const finalTimeout = options.finalTimeout ?? 3e4;
|
|
340
337
|
const defaultMaxWait = (options.idleTimeout ?? 1e3) * 3;
|
|
341
338
|
const configuredMaxWait = lazyRouteTimeout ?? defaultMaxWait;
|
|
339
|
+
let resolvedLazyRouteTimeout;
|
|
342
340
|
if (configuredMaxWait === Infinity) {
|
|
343
|
-
|
|
341
|
+
resolvedLazyRouteTimeout = finalTimeout;
|
|
344
342
|
debugBuild.DEBUG_BUILD && core.debug.log(
|
|
345
343
|
"[React Router] lazyRouteTimeout set to Infinity, capping at finalTimeout:",
|
|
346
344
|
finalTimeout,
|
|
@@ -348,7 +346,7 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
348
346
|
);
|
|
349
347
|
} else if (Number.isNaN(configuredMaxWait)) {
|
|
350
348
|
debugBuild.DEBUG_BUILD && core.debug.warn("[React Router] lazyRouteTimeout must be a number, falling back to default:", defaultMaxWait);
|
|
351
|
-
|
|
349
|
+
resolvedLazyRouteTimeout = defaultMaxWait;
|
|
352
350
|
} else if (configuredMaxWait < 0) {
|
|
353
351
|
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
354
352
|
"[React Router] lazyRouteTimeout must be non-negative or Infinity, got:",
|
|
@@ -356,21 +354,30 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
356
354
|
"falling back to:",
|
|
357
355
|
defaultMaxWait
|
|
358
356
|
);
|
|
359
|
-
|
|
357
|
+
resolvedLazyRouteTimeout = defaultMaxWait;
|
|
360
358
|
} else {
|
|
361
|
-
|
|
359
|
+
resolvedLazyRouteTimeout = configuredMaxWait;
|
|
360
|
+
}
|
|
361
|
+
if (typeof useLocation === "function" && typeof useNavigationType === "function" && typeof createRoutesFromChildren === "function" && typeof matchRoutes === "function") {
|
|
362
|
+
reactRouterConfigByClient.set(client, {
|
|
363
|
+
useLocation,
|
|
364
|
+
useNavigationType,
|
|
365
|
+
createRoutesFromChildren,
|
|
366
|
+
matchRoutes,
|
|
367
|
+
stripBasename: stripBasename || false,
|
|
368
|
+
enableAsyncRouteHandlers,
|
|
369
|
+
instrumentNavigation,
|
|
370
|
+
lazyRouteTimeout: resolvedLazyRouteTimeout,
|
|
371
|
+
lazyRouteManifest,
|
|
372
|
+
basename: ""
|
|
373
|
+
});
|
|
374
|
+
} else {
|
|
375
|
+
debugBuild.DEBUG_BUILD && core.debug.warn(
|
|
376
|
+
"[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."
|
|
377
|
+
);
|
|
362
378
|
}
|
|
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
379
|
},
|
|
372
380
|
afterAllSetup(client) {
|
|
373
|
-
integration.afterAllSetup(client);
|
|
374
381
|
const initPathName = browser.WINDOW.location?.pathname;
|
|
375
382
|
if (instrumentPageLoad && initPathName) {
|
|
376
383
|
browser.startBrowserTracingPageLoadSpan(client, {
|
|
@@ -384,25 +391,14 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
384
391
|
}
|
|
385
392
|
});
|
|
386
393
|
}
|
|
387
|
-
if (instrumentNavigation) {
|
|
388
|
-
CLIENTS_WITH_INSTRUMENT_NAVIGATION.add(client);
|
|
389
|
-
}
|
|
390
394
|
}
|
|
391
|
-
};
|
|
395
|
+
});
|
|
392
396
|
}
|
|
393
397
|
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) => {
|
|
398
|
+
const RouteReporter = ({ config, routes, locationArg }) => {
|
|
401
399
|
const isMountRenderPass = React.useRef(true);
|
|
402
|
-
const
|
|
403
|
-
const
|
|
404
|
-
const location = _useLocation();
|
|
405
|
-
const navigationType = _useNavigationType();
|
|
400
|
+
const location = config.useLocation();
|
|
401
|
+
const navigationType = config.useNavigationType();
|
|
406
402
|
const stableLocationParam = typeof locationArg === "string" || locationArg?.pathname ? locationArg : location;
|
|
407
403
|
useIsomorphicLayoutEffect(() => {
|
|
408
404
|
const added = addRoutesToAllRoutes(routes);
|
|
@@ -415,7 +411,8 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
|
415
411
|
activeRootSpan: utils.getActiveRootSpan(),
|
|
416
412
|
location: normalizedLocation,
|
|
417
413
|
routes,
|
|
418
|
-
allRoutes: Array.from(allRoutes)
|
|
414
|
+
allRoutes: Array.from(allRoutes),
|
|
415
|
+
config
|
|
419
416
|
});
|
|
420
417
|
isMountRenderPass.current = false;
|
|
421
418
|
} else {
|
|
@@ -424,17 +421,26 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
|
|
|
424
421
|
routes,
|
|
425
422
|
navigationType,
|
|
426
423
|
version,
|
|
427
|
-
allRoutes: Array.from(allRoutes)
|
|
424
|
+
allRoutes: Array.from(allRoutes),
|
|
425
|
+
config
|
|
428
426
|
});
|
|
429
427
|
}
|
|
430
428
|
}, [navigationType, stableLocationParam]);
|
|
431
|
-
return
|
|
429
|
+
return null;
|
|
430
|
+
};
|
|
431
|
+
const SentryRoutesWrapper = ({
|
|
432
|
+
routes,
|
|
433
|
+
locationArg
|
|
434
|
+
}) => {
|
|
435
|
+
const config = getRouterConfig(core.getClient());
|
|
436
|
+
const routesElement = origUseRoutes(routes, locationArg);
|
|
437
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, routesElement, config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routes, locationArg }) : null);
|
|
432
438
|
};
|
|
433
439
|
return (routes, locationArg) => {
|
|
434
|
-
return /* @__PURE__ */ React.createElement(
|
|
440
|
+
return /* @__PURE__ */ React.createElement(SentryRoutesWrapper, { routes, locationArg });
|
|
435
441
|
};
|
|
436
442
|
}
|
|
437
|
-
function wrapPatchRoutesOnNavigation(opts, isMemoryRouter
|
|
443
|
+
function wrapPatchRoutesOnNavigation(opts, isMemoryRouter, capturedSpan, config) {
|
|
438
444
|
if (!opts || !("patchRoutesOnNavigation" in opts) || typeof opts.patchRoutesOnNavigation !== "function") {
|
|
439
445
|
return opts || {};
|
|
440
446
|
}
|
|
@@ -473,7 +479,7 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
473
479
|
{ pathname: targetPath, search: "", hash: "", state: null, key: "default" },
|
|
474
480
|
Array.from(allRoutes),
|
|
475
481
|
true,
|
|
476
|
-
|
|
482
|
+
config
|
|
477
483
|
);
|
|
478
484
|
}
|
|
479
485
|
return originalPatch(routeId, children);
|
|
@@ -501,7 +507,7 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
501
507
|
{ pathname, search: "", hash: "", state: null, key: "default" },
|
|
502
508
|
Array.from(allRoutes),
|
|
503
509
|
false,
|
|
504
|
-
|
|
510
|
+
config
|
|
505
511
|
);
|
|
506
512
|
}
|
|
507
513
|
}
|
|
@@ -515,10 +521,10 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
515
521
|
};
|
|
516
522
|
}
|
|
517
523
|
function handleNavigation(opts) {
|
|
518
|
-
const { location, routes, navigationType, version,
|
|
519
|
-
const branches = Array.isArray(matches) ? matches :
|
|
524
|
+
const { location, routes, navigationType, version, config, matches, allRoutes: allRoutes2 } = opts;
|
|
525
|
+
const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
|
|
520
526
|
const client = core.getClient();
|
|
521
|
-
if (!client || !
|
|
527
|
+
if (!client || !config.instrumentNavigation) {
|
|
522
528
|
return;
|
|
523
529
|
}
|
|
524
530
|
const activeRootSpan = utils.getActiveRootSpan();
|
|
@@ -531,9 +537,7 @@ function handleNavigation(opts) {
|
|
|
531
537
|
allRoutes2 || routes,
|
|
532
538
|
allRoutes2 || routes,
|
|
533
539
|
branches,
|
|
534
|
-
|
|
535
|
-
_lazyRouteManifest,
|
|
536
|
-
_enableAsyncRouteHandlers
|
|
540
|
+
config
|
|
537
541
|
);
|
|
538
542
|
const locationKey = computeLocationKey(location);
|
|
539
543
|
const trackedNav = activeNavigationSpans.get(client);
|
|
@@ -591,6 +595,7 @@ function handleNavigation(opts) {
|
|
|
591
595
|
throw e;
|
|
592
596
|
}
|
|
593
597
|
if (navigationSpan) {
|
|
598
|
+
core.addNonEnumerableProperty(navigationSpan, "__sentry_navigation_pathname__", location.pathname);
|
|
594
599
|
activeNavigationSpans.set(client, {
|
|
595
600
|
span: navigationSpan,
|
|
596
601
|
routeName: placeholderEntry.routeName,
|
|
@@ -598,7 +603,7 @@ function handleNavigation(opts) {
|
|
|
598
603
|
pathname: location.pathname,
|
|
599
604
|
locationKey
|
|
600
605
|
});
|
|
601
|
-
patchSpanEnd(navigationSpan, location, routes,
|
|
606
|
+
patchSpanEnd(navigationSpan, location, routes, "navigation", config);
|
|
602
607
|
} else {
|
|
603
608
|
activeNavigationSpans.delete(client);
|
|
604
609
|
}
|
|
@@ -638,20 +643,18 @@ function updatePageloadTransaction({
|
|
|
638
643
|
activeRootSpan,
|
|
639
644
|
location,
|
|
640
645
|
routes,
|
|
646
|
+
config,
|
|
641
647
|
matches,
|
|
642
|
-
basename,
|
|
643
648
|
allRoutes: allRoutes2
|
|
644
649
|
}) {
|
|
645
|
-
const branches = Array.isArray(matches) ? matches :
|
|
650
|
+
const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
|
|
646
651
|
if (branches) {
|
|
647
652
|
const [name, source] = utils.resolveRouteNameAndSource(
|
|
648
653
|
location,
|
|
649
654
|
allRoutes2 || routes,
|
|
650
655
|
allRoutes2 || routes,
|
|
651
656
|
branches,
|
|
652
|
-
|
|
653
|
-
_lazyRouteManifest,
|
|
654
|
-
_enableAsyncRouteHandlers
|
|
657
|
+
config
|
|
655
658
|
);
|
|
656
659
|
core.getCurrentScope().setTransactionName(name || "/");
|
|
657
660
|
if (activeRootSpan) {
|
|
@@ -662,10 +665,10 @@ function updatePageloadTransaction({
|
|
|
662
665
|
if (source === "route") {
|
|
663
666
|
activeRootSpan.setAttribute(attributes.URL_TEMPLATE, name);
|
|
664
667
|
}
|
|
665
|
-
patchSpanEnd(activeRootSpan, location, routes,
|
|
668
|
+
patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
|
|
666
669
|
}
|
|
667
670
|
} else if (activeRootSpan) {
|
|
668
|
-
patchSpanEnd(activeRootSpan, location, routes,
|
|
671
|
+
patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
|
|
669
672
|
}
|
|
670
673
|
}
|
|
671
674
|
function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSource, allowNoCurrentName = false) {
|
|
@@ -684,7 +687,7 @@ function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSo
|
|
|
684
687
|
}
|
|
685
688
|
return false;
|
|
686
689
|
}
|
|
687
|
-
function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
690
|
+
function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes2, config) {
|
|
688
691
|
try {
|
|
689
692
|
const currentSource = spanJson.attributes[attributes.SENTRY_SEGMENT_NAME_SOURCE];
|
|
690
693
|
if (currentSource === "route" && currentName && !utils.transactionNameHasWildcard(currentName)) {
|
|
@@ -692,19 +695,11 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
|
|
|
692
695
|
}
|
|
693
696
|
const currentAllRoutes = Array.from(allRoutes2);
|
|
694
697
|
const routesToUse = currentAllRoutes.length > 0 ? currentAllRoutes : routes;
|
|
695
|
-
const branches =
|
|
698
|
+
const branches = config.matchRoutes(routesToUse, location, config.basename);
|
|
696
699
|
if (!branches) {
|
|
697
700
|
return;
|
|
698
701
|
}
|
|
699
|
-
const [name, source] = utils.resolveRouteNameAndSource(
|
|
700
|
-
location,
|
|
701
|
-
routesToUse,
|
|
702
|
-
routesToUse,
|
|
703
|
-
branches,
|
|
704
|
-
basename,
|
|
705
|
-
_lazyRouteManifest,
|
|
706
|
-
_enableAsyncRouteHandlers
|
|
707
|
-
);
|
|
702
|
+
const [name, source] = utils.resolveRouteNameAndSource(location, routesToUse, routesToUse, branches, config);
|
|
708
703
|
const isImprovement = shouldUpdateWildcardSpanName(currentName, currentSource, name, source, true);
|
|
709
704
|
const spanNotEnded = spanType === "pageload" || !spanJson.end_timestamp;
|
|
710
705
|
if (isImprovement && spanNotEnded) {
|
|
@@ -721,7 +716,7 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
|
|
|
721
716
|
debugBuild.DEBUG_BUILD && core.debug.warn(`Error updating span details before ending: ${error}`);
|
|
722
717
|
}
|
|
723
718
|
}
|
|
724
|
-
function patchSpanEnd(span, location, routes,
|
|
719
|
+
function patchSpanEnd(span, location, routes, spanType, config) {
|
|
725
720
|
const patchedPropertyName = `__sentry_${spanType}_end_patched__`;
|
|
726
721
|
const hasEndBeenPatched = span?.[patchedPropertyName];
|
|
727
722
|
if (hasEndBeenPatched || !span.end) {
|
|
@@ -752,18 +747,18 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
752
747
|
const hasPendingOrMayHaveLazyRoutes = pendingPromises && pendingPromises.size > 0 || mayHaveLazyRoutes;
|
|
753
748
|
const shouldWaitForLazyRoutes = hasPendingOrMayHaveLazyRoutes && currentName && (utils.transactionNameHasWildcard(currentName) || currentSource !== "route");
|
|
754
749
|
if (shouldWaitForLazyRoutes) {
|
|
755
|
-
if (
|
|
756
|
-
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
750
|
+
if (config.lazyRouteTimeout === 0) {
|
|
751
|
+
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
|
|
757
752
|
cleanupNavigationSpan();
|
|
758
753
|
originalEnd(endTimestamp);
|
|
759
754
|
return;
|
|
760
755
|
}
|
|
761
|
-
const timeoutPromise = new Promise((r) => setTimeout(r,
|
|
756
|
+
const timeoutPromise = new Promise((r) => setTimeout(r, config.lazyRouteTimeout));
|
|
762
757
|
let waitPromise;
|
|
763
758
|
if (pendingPromises && pendingPromises.size > 0) {
|
|
764
759
|
const allSettled = Promise.allSettled(pendingPromises).then(() => {
|
|
765
760
|
});
|
|
766
|
-
waitPromise =
|
|
761
|
+
waitPromise = config.lazyRouteTimeout === Infinity ? allSettled : Promise.race([allSettled, timeoutPromise]);
|
|
767
762
|
} else {
|
|
768
763
|
waitPromise = timeoutPromise;
|
|
769
764
|
}
|
|
@@ -775,9 +770,9 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
775
770
|
updatedSpanJson.name,
|
|
776
771
|
location,
|
|
777
772
|
routes,
|
|
778
|
-
basename,
|
|
779
773
|
spanType,
|
|
780
|
-
allRoutes
|
|
774
|
+
allRoutes,
|
|
775
|
+
config
|
|
781
776
|
);
|
|
782
777
|
cleanupNavigationSpan();
|
|
783
778
|
originalEnd(endTimestamp);
|
|
@@ -787,24 +782,23 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
787
782
|
});
|
|
788
783
|
return;
|
|
789
784
|
}
|
|
790
|
-
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes,
|
|
785
|
+
tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
|
|
791
786
|
cleanupNavigationSpan();
|
|
792
787
|
originalEnd(endTimestamp);
|
|
793
788
|
};
|
|
794
789
|
core.addNonEnumerableProperty(span, patchedPropertyName, true);
|
|
795
790
|
}
|
|
796
791
|
function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
return Routes;
|
|
802
|
-
}
|
|
803
|
-
const SentryRoutes = (props) => {
|
|
792
|
+
const RouteReporter = ({
|
|
793
|
+
config,
|
|
794
|
+
routeChildren
|
|
795
|
+
}) => {
|
|
804
796
|
const isMountRenderPass = React.useRef(true);
|
|
805
|
-
const location =
|
|
806
|
-
const navigationType =
|
|
807
|
-
const routes =
|
|
797
|
+
const location = config.useLocation();
|
|
798
|
+
const navigationType = config.useNavigationType();
|
|
799
|
+
const routes = config.createRoutesFromChildren(
|
|
800
|
+
routeChildren
|
|
801
|
+
);
|
|
808
802
|
useIsomorphicLayoutEffect(() => {
|
|
809
803
|
const added = addRoutesToAllRoutes(routes);
|
|
810
804
|
return () => removeRoutesFromAllRoutes(added);
|
|
@@ -816,17 +810,36 @@ function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
|
|
|
816
810
|
activeRootSpan: utils.getActiveRootSpan(),
|
|
817
811
|
location,
|
|
818
812
|
routes,
|
|
819
|
-
allRoutes: Array.from(allRoutes)
|
|
813
|
+
allRoutes: Array.from(allRoutes),
|
|
814
|
+
config
|
|
820
815
|
});
|
|
821
816
|
isMountRenderPass.current = false;
|
|
822
817
|
} else {
|
|
823
|
-
handleNavigation({
|
|
818
|
+
handleNavigation({
|
|
819
|
+
location,
|
|
820
|
+
routes,
|
|
821
|
+
navigationType,
|
|
822
|
+
version,
|
|
823
|
+
allRoutes: Array.from(allRoutes),
|
|
824
|
+
config
|
|
825
|
+
});
|
|
824
826
|
}
|
|
825
827
|
},
|
|
826
828
|
// Re-run only on location/navigation changes, not children changes
|
|
827
829
|
[location, navigationType]
|
|
828
830
|
);
|
|
829
|
-
return
|
|
831
|
+
return null;
|
|
832
|
+
};
|
|
833
|
+
const SentryRoutes = (props) => {
|
|
834
|
+
const config = getRouterConfig(core.getClient());
|
|
835
|
+
return /* @__PURE__ */ React.createElement(
|
|
836
|
+
React.Fragment,
|
|
837
|
+
null,
|
|
838
|
+
// @ts-expect-error Setting more specific React Component typing for `R` generic above
|
|
839
|
+
// will break advanced type inference done by react router params
|
|
840
|
+
/* @__PURE__ */ React.createElement(Routes, { ...props }),
|
|
841
|
+
config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routeChildren: props.children }) : null
|
|
842
|
+
);
|
|
830
843
|
};
|
|
831
844
|
hoistNonReactStatics.hoistNonReactStatics(SentryRoutes, Routes);
|
|
832
845
|
return SentryRoutes;
|