@depup/sentry__react 10.48.0-depup.0 → 10.68.0-depup.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.
Files changed (122) hide show
  1. package/README.md +9 -3
  2. package/build/cjs/constants.js +3 -5
  3. package/build/cjs/constants.js.map +1 -1
  4. package/build/cjs/debug-build.js +0 -5
  5. package/build/cjs/debug-build.js.map +1 -1
  6. package/build/cjs/error.js +14 -77
  7. package/build/cjs/error.js.map +1 -1
  8. package/build/cjs/errorboundary.js +22 -77
  9. package/build/cjs/errorboundary.js.map +1 -1
  10. package/build/cjs/hoist-non-react-statics.js +16 -84
  11. package/build/cjs/hoist-non-react-statics.js.map +1 -1
  12. package/build/cjs/index.js +6 -0
  13. package/build/cjs/index.js.map +1 -1
  14. package/build/cjs/isSyntheticEvent.js +10 -0
  15. package/build/cjs/isSyntheticEvent.js.map +1 -0
  16. package/build/cjs/profiler.js +35 -110
  17. package/build/cjs/profiler.js.map +1 -1
  18. package/build/cjs/reactrouter-compat-utils/instrumentation.js +236 -692
  19. package/build/cjs/reactrouter-compat-utils/instrumentation.js.map +1 -1
  20. package/build/cjs/reactrouter-compat-utils/lazy-routes.js +24 -85
  21. package/build/cjs/reactrouter-compat-utils/lazy-routes.js.map +1 -1
  22. package/build/cjs/reactrouter-compat-utils/route-manifest.js +18 -96
  23. package/build/cjs/reactrouter-compat-utils/route-manifest.js.map +1 -1
  24. package/build/cjs/reactrouter-compat-utils/utils.js +82 -193
  25. package/build/cjs/reactrouter-compat-utils/utils.js.map +1 -1
  26. package/build/cjs/reactrouter.compat.js +29 -0
  27. package/build/cjs/reactrouter.compat.js.map +1 -0
  28. package/build/cjs/reactrouter.js +34 -111
  29. package/build/cjs/reactrouter.js.map +1 -1
  30. package/build/cjs/reactrouterv3.js +31 -60
  31. package/build/cjs/reactrouterv3.js.map +1 -1
  32. package/build/cjs/reactrouterv6.js +10 -42
  33. package/build/cjs/reactrouterv6.js.map +1 -1
  34. package/build/cjs/reactrouterv7.js +10 -42
  35. package/build/cjs/reactrouterv7.js.map +1 -1
  36. package/build/cjs/redux.js +61 -90
  37. package/build/cjs/redux.js.map +1 -1
  38. package/build/cjs/sdk.js +15 -10
  39. package/build/cjs/sdk.js.map +1 -1
  40. package/build/cjs/tanstackrouter.js +90 -92
  41. package/build/cjs/tanstackrouter.js.map +1 -1
  42. package/build/esm/constants.js +3 -5
  43. package/build/esm/constants.js.map +1 -1
  44. package/build/esm/debug-build.js +0 -5
  45. package/build/esm/debug-build.js.map +1 -1
  46. package/build/esm/error.js +13 -76
  47. package/build/esm/error.js.map +1 -1
  48. package/build/esm/errorboundary.js +22 -77
  49. package/build/esm/errorboundary.js.map +1 -1
  50. package/build/esm/hoist-non-react-statics.js +16 -84
  51. package/build/esm/hoist-non-react-statics.js.map +1 -1
  52. package/build/esm/index.js +1 -0
  53. package/build/esm/index.js.map +1 -1
  54. package/build/esm/isSyntheticEvent.js +8 -0
  55. package/build/esm/isSyntheticEvent.js.map +1 -0
  56. package/build/esm/package.json +1 -1
  57. package/build/esm/profiler.js +35 -110
  58. package/build/esm/profiler.js.map +1 -1
  59. package/build/esm/reactrouter-compat-utils/instrumentation.js +237 -693
  60. package/build/esm/reactrouter-compat-utils/instrumentation.js.map +1 -1
  61. package/build/esm/reactrouter-compat-utils/lazy-routes.js +24 -85
  62. package/build/esm/reactrouter-compat-utils/lazy-routes.js.map +1 -1
  63. package/build/esm/reactrouter-compat-utils/route-manifest.js +18 -96
  64. package/build/esm/reactrouter-compat-utils/route-manifest.js.map +1 -1
  65. package/build/esm/reactrouter-compat-utils/utils.js +80 -191
  66. package/build/esm/reactrouter-compat-utils/utils.js.map +1 -1
  67. package/build/esm/reactrouter.compat.js +23 -0
  68. package/build/esm/reactrouter.compat.js.map +1 -0
  69. package/build/esm/reactrouter.js +34 -111
  70. package/build/esm/reactrouter.js.map +1 -1
  71. package/build/esm/reactrouterv3.js +29 -58
  72. package/build/esm/reactrouterv3.js.map +1 -1
  73. package/build/esm/reactrouterv6.js +10 -42
  74. package/build/esm/reactrouterv6.js.map +1 -1
  75. package/build/esm/reactrouterv7.js +10 -42
  76. package/build/esm/reactrouterv7.js.map +1 -1
  77. package/build/esm/redux.js +61 -90
  78. package/build/esm/redux.js.map +1 -1
  79. package/build/esm/sdk.js +15 -10
  80. package/build/esm/sdk.js.map +1 -1
  81. package/build/esm/tanstackrouter.js +91 -93
  82. package/build/esm/tanstackrouter.js.map +1 -1
  83. package/build/types/error.d.ts.map +1 -1
  84. package/build/types/index.d.ts +1 -0
  85. package/build/types/index.d.ts.map +1 -1
  86. package/build/types/isSyntheticEvent.d.ts +10 -0
  87. package/build/types/isSyntheticEvent.d.ts.map +1 -0
  88. package/build/types/reactrouter-compat-utils/instrumentation.d.ts +1 -1
  89. package/build/types/reactrouter-compat-utils/instrumentation.d.ts.map +1 -1
  90. package/build/types/reactrouter-compat-utils/utils.d.ts +1 -1
  91. package/build/types/reactrouter-compat-utils/utils.d.ts.map +1 -1
  92. package/build/types/reactrouter.compat.d.ts +42 -0
  93. package/build/types/reactrouter.compat.d.ts.map +1 -0
  94. package/build/types/reactrouter.d.ts.map +1 -1
  95. package/build/types/reactrouterv3.d.ts +1 -1
  96. package/build/types/reactrouterv3.d.ts.map +1 -1
  97. package/build/types/reactrouterv6.d.ts +10 -0
  98. package/build/types/reactrouterv6.d.ts.map +1 -1
  99. package/build/types/reactrouterv7.d.ts +10 -0
  100. package/build/types/reactrouterv7.d.ts.map +1 -1
  101. package/build/types/redux.d.ts +1 -1
  102. package/build/types/redux.d.ts.map +1 -1
  103. package/build/types/sdk.d.ts +1 -1
  104. package/build/types/sdk.d.ts.map +1 -1
  105. package/build/types/tanstackrouter.d.ts +1 -1
  106. package/build/types/tanstackrouter.d.ts.map +1 -1
  107. package/build/types/vendor/tanstackrouter-types.d.ts +2 -1
  108. package/build/types/vendor/tanstackrouter-types.d.ts.map +1 -1
  109. package/build/types-ts3.8/index.d.ts +1 -0
  110. package/build/types-ts3.8/isSyntheticEvent.d.ts +10 -0
  111. package/build/types-ts3.8/reactrouter-compat-utils/instrumentation.d.ts +1 -1
  112. package/build/types-ts3.8/reactrouter-compat-utils/utils.d.ts +1 -1
  113. package/build/types-ts3.8/reactrouter.compat.d.ts +42 -0
  114. package/build/types-ts3.8/reactrouterv3.d.ts +1 -1
  115. package/build/types-ts3.8/reactrouterv6.d.ts +10 -0
  116. package/build/types-ts3.8/reactrouterv7.d.ts +10 -0
  117. package/build/types-ts3.8/redux.d.ts +1 -1
  118. package/build/types-ts3.8/sdk.d.ts +1 -1
  119. package/build/types-ts3.8/tanstackrouter.d.ts +1 -1
  120. package/build/types-ts3.8/vendor/tanstackrouter-types.d.ts +2 -1
  121. package/changes.json +8 -3
  122. package/package.json +18 -8
@@ -7,53 +7,29 @@ const debugBuild = require('../debug-build.js');
7
7
  const hoistNonReactStatics = require('../hoist-non-react-statics.js');
8
8
  const lazyRoutes = require('./lazy-routes.js');
9
9
  const utils = require('./utils.js');
10
-
11
- /* eslint-disable max-lines */
12
- // Inspired from Donnie McNeal's solution:
13
- // https://gist.github.com/wontondon/e8c4bdf2888875e4c755712e99279536
14
-
10
+ const attributes = require('@sentry/conventions/attributes');
15
11
 
16
12
  let _useEffect;
17
13
  let _useLocation;
18
14
  let _useNavigationType;
19
15
  let _createRoutesFromChildren;
20
16
  let _matchRoutes;
21
-
22
17
  let _enableAsyncRouteHandlers = false;
23
- let _lazyRouteTimeout = 3000;
18
+ let _lazyRouteTimeout = 3e3;
24
19
  let _lazyRouteManifest;
25
- let _basename = '';
26
-
27
- const CLIENTS_WITH_INSTRUMENT_NAVIGATION = new WeakSet();
28
-
29
- // Prevents duplicate spans when router.subscribe fires multiple times
30
- const activeNavigationSpans = new WeakMap
31
-
32
- ();
33
-
34
- // Exported for testing only
35
- const allRoutes = new Set();
36
-
37
- // Tracks lazy route loads to wait before finalizing span names
38
- const pendingLazyRouteLoads = new WeakMap();
39
-
40
- // Tracks deferred lazy route promises that can be resolved when patchRoutesOnNavigation is called
41
- const deferredLazyRouteResolvers = new WeakMap();
42
-
43
- /**
44
- * Schedules a callback using requestAnimationFrame when available (browser),
45
- * or falls back to setTimeout for SSR environments (Node.js, createMemoryRouter tests).
46
- */
20
+ let _basename = "";
21
+ const CLIENTS_WITH_INSTRUMENT_NAVIGATION = /* @__PURE__ */ new WeakSet();
22
+ const useIsomorphicLayoutEffect = browser.WINDOW?.document ? React.useLayoutEffect : React.useEffect;
23
+ const activeNavigationSpans = /* @__PURE__ */ new WeakMap();
24
+ const allRoutes = /* @__PURE__ */ new Set();
25
+ const pendingLazyRouteLoads = /* @__PURE__ */ new WeakMap();
26
+ const deferredLazyRouteResolvers = /* @__PURE__ */ new WeakMap();
47
27
  function scheduleCallback(callback) {
48
28
  if (browser.WINDOW?.requestAnimationFrame) {
49
29
  return browser.WINDOW.requestAnimationFrame(callback);
50
30
  }
51
- return setTimeout(callback, 0) ;
31
+ return setTimeout(callback, 0);
52
32
  }
53
-
54
- /**
55
- * Cancels a scheduled callback, handling both RAF (browser) and timeout (SSR) IDs.
56
- */
57
33
  function cancelScheduledCallback(id) {
58
34
  if (browser.WINDOW?.cancelAnimationFrame) {
59
35
  browser.WINDOW.cancelAnimationFrame(id);
@@ -61,103 +37,48 @@ function cancelScheduledCallback(id) {
61
37
  clearTimeout(id);
62
38
  }
63
39
  }
64
-
65
- /**
66
- * Computes location key for duplicate detection. Normalizes undefined/null to empty strings.
67
- * Exported for testing.
68
- */
69
40
  function computeLocationKey(location) {
70
- return `${location.pathname}${location.search || ''}${location.hash || ''}`;
41
+ return `${location.pathname}${location.search || ""}${location.hash || ""}`;
71
42
  }
72
-
73
- /**
74
- * Checks if a route name is parameterized (contains route parameters like :id or wildcards like *)
75
- * vs a raw URL path.
76
- */
77
43
  function isParameterizedRoute(routeName) {
78
- return routeName.includes(':') || routeName.includes('*');
44
+ return routeName.includes(":") || routeName.includes("*");
79
45
  }
80
-
81
- /**
82
- * Determines if a navigation should be skipped as a duplicate, and if an existing span should be updated.
83
- * Exported for testing.
84
- *
85
- * @returns An object with:
86
- * - skip: boolean - Whether to skip creating a new span
87
- * - shouldUpdate: boolean - Whether to update the existing span name (wildcard upgrade)
88
- */
89
- function shouldSkipNavigation(
90
- trackedNav
91
-
92
- ,
93
- locationKey,
94
- proposedName,
95
- spanHasEnded,
96
- ) {
46
+ function shouldSkipNavigation(trackedNav, locationKey, proposedName, spanHasEnded) {
97
47
  if (!trackedNav) {
98
48
  return { skip: false, shouldUpdate: false };
99
49
  }
100
-
101
- // Check if this is a duplicate navigation (same location)
102
- // 1. If it's a placeholder, it's always a duplicate (we're waiting for the real one)
103
- // 2. If it's a real span, it's a duplicate only if it hasn't ended yet
104
50
  const isDuplicate = trackedNav.locationKey === locationKey && (trackedNav.isPlaceholder || !spanHasEnded);
105
-
106
51
  if (isDuplicate) {
107
- // Check if we should update the span name with a better route
108
- // Allow updates if:
109
- // 1. Current has wildcard and new doesn't (wildcard → parameterized upgrade)
110
- // 2. Current is raw path and new is parameterized (raw → parameterized upgrade)
111
- // 3. New name is different and more specific (longer, indicating nested routes resolved)
112
52
  const currentHasWildcard = !!trackedNav.routeName && utils.transactionNameHasWildcard(trackedNav.routeName);
113
53
  const proposedHasWildcard = utils.transactionNameHasWildcard(proposedName);
114
54
  const currentIsParameterized = !!trackedNav.routeName && isParameterizedRoute(trackedNav.routeName);
115
55
  const proposedIsParameterized = isParameterizedRoute(proposedName);
116
-
117
56
  const isWildcardUpgrade = currentHasWildcard && !proposedHasWildcard;
118
57
  const isRawToParameterized = !currentIsParameterized && proposedIsParameterized;
119
- const isMoreSpecific =
120
- proposedName !== trackedNav.routeName &&
121
- proposedName.length > (trackedNav.routeName?.length || 0) &&
122
- !proposedHasWildcard;
123
-
58
+ const isMoreSpecific = proposedName !== trackedNav.routeName && proposedName.length > (trackedNav.routeName?.length || 0) && !proposedHasWildcard;
124
59
  const shouldUpdate = !!(trackedNav.routeName && (isWildcardUpgrade || isRawToParameterized || isMoreSpecific));
125
-
126
60
  return { skip: true, shouldUpdate };
127
61
  }
128
-
129
62
  return { skip: false, shouldUpdate: false };
130
63
  }
131
-
132
64
  function addResolvedRoutesToParent(resolvedRoutes, parentRoute) {
133
65
  const existingChildren = parentRoute.children || [];
134
-
135
66
  const newRoutes = resolvedRoutes.filter(
136
- newRoute =>
137
- !existingChildren.some(
138
- existing =>
139
- existing === newRoute ||
140
- (newRoute.path && existing.path === newRoute.path) ||
141
- (newRoute.id && existing.id === newRoute.id),
142
- ),
67
+ (newRoute) => !existingChildren.some(
68
+ (existing) => existing === newRoute || newRoute.path && existing.path === newRoute.path || newRoute.id && existing.id === newRoute.id
69
+ )
143
70
  );
144
-
145
71
  if (newRoutes.length > 0) {
146
72
  parentRoute.children = [...existingChildren, ...newRoutes];
147
73
  }
148
74
  }
149
-
150
- /** Registers a pending lazy route load promise for a span. */
151
75
  function trackLazyRouteLoad(span, promise) {
152
76
  let promises = pendingLazyRouteLoads.get(span);
153
77
  if (!promises) {
154
- promises = new Set();
78
+ promises = /* @__PURE__ */ new Set();
155
79
  pendingLazyRouteLoads.set(span, promises);
156
80
  }
157
81
  promises.add(promise);
158
-
159
- // Clean up when promise resolves/rejects
160
- // oxlint-disable-next-line typescript/no-floating-promises
161
82
  promise.finally(() => {
162
83
  const currentPromises = pendingLazyRouteLoads.get(span);
163
84
  if (currentPromises) {
@@ -165,192 +86,125 @@ function trackLazyRouteLoad(span, promise) {
165
86
  }
166
87
  });
167
88
  }
168
-
169
- /**
170
- * Creates a deferred promise for a span that will be resolved when patchRoutesOnNavigation is called.
171
- * This ensures that patchedEnd waits for patchRoutesOnNavigation to be called before ending the span.
172
- */
173
89
  function createDeferredLazyRoutePromise(span) {
174
- const deferredPromise = new Promise(resolve => {
90
+ const deferredPromise = new Promise((resolve) => {
175
91
  deferredLazyRouteResolvers.set(span, resolve);
176
92
  });
177
-
178
93
  trackLazyRouteLoad(span, deferredPromise);
179
94
  }
180
-
181
- /**
182
- * Resolves the deferred lazy route promise for a span.
183
- * Called when patchRoutesOnNavigation is invoked.
184
- */
185
95
  function resolveDeferredLazyRoutePromise(span) {
186
96
  const resolver = deferredLazyRouteResolvers.get(span);
187
97
  if (resolver) {
188
98
  resolver();
189
99
  deferredLazyRouteResolvers.delete(span);
190
- // Clear the flag so patchSpanEnd doesn't wait unnecessarily for routes that have already loaded
191
- if ((span ).__sentry_may_have_lazy_routes__) {
192
- (span ).__sentry_may_have_lazy_routes__ = false;
100
+ if (span.__sentry_may_have_lazy_routes__) {
101
+ span.__sentry_may_have_lazy_routes__ = false;
193
102
  }
194
103
  }
195
104
  }
196
-
197
- /**
198
- * Processes resolved routes by adding them to allRoutes and checking for nested async handlers.
199
- * When capturedSpan is provided, updates that specific span instead of the current active span.
200
- * This prevents race conditions where a lazy handler resolves after the user has navigated away.
201
- */
202
- function processResolvedRoutes(
203
- resolvedRoutes,
204
- parentRoute,
205
- currentLocation = null,
206
- capturedSpan,
207
- ) {
208
- resolvedRoutes.forEach(child => {
105
+ function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = null, capturedSpan) {
106
+ resolvedRoutes.forEach((child) => {
209
107
  allRoutes.add(child);
210
- // Only check for async handlers if the feature is enabled
211
108
  if (_enableAsyncRouteHandlers) {
212
109
  lazyRoutes.checkRouteForAsyncHandler(child, processResolvedRoutes);
213
110
  }
214
111
  });
215
-
216
112
  if (parentRoute) {
217
- // If a parent route is provided, add the resolved routes as children to the parent route
218
113
  addResolvedRoutesToParent(resolvedRoutes, parentRoute);
219
114
  }
220
-
221
- // Use captured span if provided, otherwise fall back to current active span
222
115
  const targetSpan = capturedSpan ?? utils.getActiveRootSpan();
223
116
  if (targetSpan) {
224
117
  const spanJson = core.spanToJSON(targetSpan);
225
-
226
- // Skip update if span has already ended (timestamp is set when span.end() is called)
227
118
  if (spanJson.timestamp) {
228
- debugBuild.DEBUG_BUILD && core.debug.warn('[React Router] Lazy handler resolved after span ended - skipping update');
119
+ debugBuild.DEBUG_BUILD && core.debug.warn("[React Router] Lazy handler resolved after span ended - skipping update");
229
120
  return;
230
121
  }
231
-
232
122
  const spanOp = spanJson.op;
233
-
234
- // Use captured location for route matching (ensures we match against the correct route)
235
- // Fall back to window.location only if no captured location and no captured span
236
- // (i.e., this is not from an async handler)
237
123
  let location = currentLocation;
238
124
  if (!location && !capturedSpan) {
239
- if (typeof browser.WINDOW !== 'undefined') {
125
+ if (typeof browser.WINDOW !== "undefined") {
240
126
  const globalLocation = browser.WINDOW.location;
241
127
  if (globalLocation?.pathname) {
242
128
  location = { pathname: globalLocation.pathname };
243
129
  }
244
130
  }
245
131
  }
246
-
247
132
  if (location) {
248
- if (spanOp === 'pageload') {
249
- // Re-run the pageload transaction update with the newly loaded routes
133
+ if (spanOp === "pageload") {
250
134
  updatePageloadTransaction({
251
135
  activeRootSpan: targetSpan,
252
136
  location: { pathname: location.pathname },
253
137
  routes: Array.from(allRoutes),
254
- allRoutes: Array.from(allRoutes),
138
+ allRoutes: Array.from(allRoutes)
255
139
  });
256
- } else if (spanOp === 'navigation') {
257
- // For navigation spans, update the name with the newly loaded routes
140
+ } else if (spanOp === "navigation") {
258
141
  updateNavigationSpan(targetSpan, location, Array.from(allRoutes), false, _matchRoutes);
259
142
  }
260
143
  }
261
144
  }
262
145
  }
263
-
264
- /**
265
- * Updates a navigation span with the correct route name after lazy routes have been loaded.
266
- */
267
- function updateNavigationSpan(
268
- activeRootSpan,
269
- location,
270
- allRoutes,
271
- forceUpdate = false,
272
- matchRoutes,
273
- ) {
146
+ function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false, matchRoutes) {
274
147
  const spanJson = core.spanToJSON(activeRootSpan);
275
148
  const currentName = spanJson.description;
276
-
277
- const hasBeenNamed = (activeRootSpan )?.__sentry_navigation_name_set__;
149
+ const hasBeenNamed = activeRootSpan?.__sentry_navigation_name_set__;
278
150
  const currentNameHasWildcard = currentName && utils.transactionNameHasWildcard(currentName);
279
151
  const shouldUpdate = !hasBeenNamed || forceUpdate || currentNameHasWildcard;
280
-
281
152
  if (shouldUpdate && !spanJson.timestamp) {
282
- const currentBranches = matchRoutes(allRoutes, location);
153
+ const currentBranches = matchRoutes(allRoutes2, location);
283
154
  const [name, source] = utils.resolveRouteNameAndSource(
284
155
  location,
285
- allRoutes,
286
- allRoutes,
287
- (currentBranches ) || [],
156
+ allRoutes2,
157
+ allRoutes2,
158
+ currentBranches || [],
288
159
  _basename,
289
160
  _lazyRouteManifest,
290
- _enableAsyncRouteHandlers,
161
+ _enableAsyncRouteHandlers
291
162
  );
292
-
293
163
  const currentSource = spanJson.data?.[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
294
- const isImprovement =
295
- name &&
296
- (!currentName || // No current name - always set
297
- (!hasBeenNamed && (currentSource !== 'route' || source === 'route')) || // Not finalized - allow unless downgrading route→url
298
- (currentSource !== 'route' && source === 'route') || // URL → route upgrade
299
- (currentSource === 'route' && source === 'route' && currentNameHasWildcard)); // Route → better route (only if current has wildcard)
164
+ const isImprovement = name && (!currentName || // No current name - always set
165
+ !hasBeenNamed && (currentSource !== "route" || source === "route") || // Not finalized - allow unless downgrading route→url
166
+ currentSource !== "route" && source === "route" || // URL → route upgrade
167
+ currentSource === "route" && source === "route" && currentNameHasWildcard);
300
168
  if (isImprovement) {
301
169
  activeRootSpan.updateName(name);
302
170
  activeRootSpan.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source);
303
-
304
- // Only mark as finalized for non-wildcard route names (allows URL→route upgrades).
305
- if (!utils.transactionNameHasWildcard(name) && source === 'route') {
171
+ if (source === "route") {
172
+ activeRootSpan.setAttribute(attributes.URL_TEMPLATE, name);
173
+ }
174
+ if (!utils.transactionNameHasWildcard(name) && source === "route") {
306
175
  core.addNonEnumerableProperty(
307
- activeRootSpan ,
308
- '__sentry_navigation_name_set__',
309
- true,
176
+ activeRootSpan,
177
+ "__sentry_navigation_name_set__",
178
+ true
310
179
  );
311
180
  }
312
181
  }
313
182
  }
314
183
  }
315
-
316
- function setupRouterSubscription(
317
- router,
318
- routes,
319
- version,
320
- basename,
321
- activeRootSpan,
322
- ) {
184
+ function setupRouterSubscription(router, routes, version, basename, activeRootSpan) {
323
185
  let isInitialPageloadComplete = false;
324
- let hasSeenPageloadSpan = !!activeRootSpan && core.spanToJSON(activeRootSpan).op === 'pageload';
186
+ let hasSeenPageloadSpan = !!activeRootSpan && core.spanToJSON(activeRootSpan).op === "pageload";
325
187
  let hasSeenPopAfterPageload = false;
326
188
  let scheduledNavigationHandler = null;
327
189
  let lastHandledPathname = null;
328
-
329
190
  router.subscribe((state) => {
330
191
  if (!isInitialPageloadComplete) {
331
192
  const currentRootSpan = utils.getActiveRootSpan();
332
- const isCurrentlyInPageload = currentRootSpan && core.spanToJSON(currentRootSpan).op === 'pageload';
333
-
193
+ const isCurrentlyInPageload = currentRootSpan && core.spanToJSON(currentRootSpan).op === "pageload";
334
194
  if (isCurrentlyInPageload) {
335
195
  hasSeenPageloadSpan = true;
336
196
  } else if (hasSeenPageloadSpan) {
337
- if (state.historyAction === 'POP' && !hasSeenPopAfterPageload) {
197
+ if (state.historyAction === "POP" && !hasSeenPopAfterPageload) {
338
198
  hasSeenPopAfterPageload = true;
339
199
  } else {
340
200
  isInitialPageloadComplete = true;
341
201
  }
342
202
  }
343
203
  }
344
-
345
- const shouldHandleNavigation =
346
- state.historyAction === 'PUSH' || (state.historyAction === 'POP' && isInitialPageloadComplete);
347
-
204
+ const shouldHandleNavigation = state.historyAction === "PUSH" || state.historyAction === "POP" && isInitialPageloadComplete;
348
205
  if (shouldHandleNavigation) {
349
- // Include search and hash to allow query/hash-only navigations
350
- // Use computeLocationKey() to ensure undefined/null values are normalized to empty strings
351
206
  const currentLocationKey = computeLocationKey(state.location);
352
207
  const navigationHandler = () => {
353
- // Prevent multiple calls for the same location within the same navigation cycle
354
208
  if (lastHandledPathname === currentLocationKey) {
355
209
  return;
356
210
  }
@@ -362,207 +216,119 @@ function setupRouterSubscription(
362
216
  navigationType: state.historyAction,
363
217
  version,
364
218
  basename,
365
- allRoutes: Array.from(allRoutes),
219
+ allRoutes: Array.from(allRoutes)
366
220
  });
367
221
  };
368
-
369
- if (state.navigation.state !== 'idle') {
370
- // Navigation in progress - reset if location changed
222
+ if (state.navigation.state !== "idle") {
371
223
  if (lastHandledPathname !== currentLocationKey) {
372
224
  lastHandledPathname = null;
373
225
  }
374
- // Cancel any previously scheduled handler to avoid duplicates
375
226
  if (scheduledNavigationHandler !== null) {
376
227
  cancelScheduledCallback(scheduledNavigationHandler);
377
228
  }
378
229
  scheduledNavigationHandler = scheduleCallback(navigationHandler);
379
230
  } else {
380
- // Navigation completed - cancel scheduled handler if any, then call immediately
381
231
  if (scheduledNavigationHandler !== null) {
382
232
  cancelScheduledCallback(scheduledNavigationHandler);
383
233
  scheduledNavigationHandler = null;
384
234
  }
385
235
  navigationHandler();
386
- // Don't reset - next navigation cycle resets to prevent duplicates within same cycle.
387
236
  }
388
237
  }
389
238
  });
390
239
  }
391
-
392
- /**
393
- * Creates a wrapCreateBrowserRouter function that can be used with all React Router v6 compatible versions.
394
- */
395
- function createV6CompatibleWrapCreateBrowserRouter
396
-
397
- (
398
- createRouterFunction,
399
- version,
400
- ) {
240
+ function createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, version) {
401
241
  if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
402
- debugBuild.DEBUG_BUILD &&
403
- core.debug.warn(
404
- `reactRouterV${version}Instrumentation was unable to wrap the \`createRouter\` function because of one or more missing parameters.`,
405
- );
406
-
242
+ debugBuild.DEBUG_BUILD && core.debug.warn(
243
+ `reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createRouter\` function because of one or more missing parameters.`
244
+ );
407
245
  return createRouterFunction;
408
246
  }
409
-
410
- return function (routes, opts) {
247
+ return function(routes, opts) {
411
248
  addRoutesToAllRoutes(routes);
412
-
413
249
  if (_enableAsyncRouteHandlers) {
414
250
  for (const route of routes) {
415
251
  lazyRoutes.checkRouteForAsyncHandler(route, processResolvedRoutes);
416
252
  }
417
253
  }
418
-
419
- // Capture the active span BEFORE creating the router.
420
- // This is important because the span might end (due to idle timeout) before
421
- // patchRoutesOnNavigation is called by React Router.
422
254
  const activeRootSpan = utils.getActiveRootSpan();
423
-
424
- // If patchRoutesOnNavigation is provided and we have an active span,
425
- // mark the span as having potential lazy routes and create a deferred promise.
426
- const hasPatchRoutesOnNavigation =
427
- opts && 'patchRoutesOnNavigation' in opts && typeof opts.patchRoutesOnNavigation === 'function';
255
+ const hasPatchRoutesOnNavigation = opts && "patchRoutesOnNavigation" in opts && typeof opts.patchRoutesOnNavigation === "function";
428
256
  if (hasPatchRoutesOnNavigation && activeRootSpan) {
429
- // Mark the span as potentially having lazy routes
430
257
  core.addNonEnumerableProperty(
431
- activeRootSpan ,
432
- '__sentry_may_have_lazy_routes__',
433
- true,
258
+ activeRootSpan,
259
+ "__sentry_may_have_lazy_routes__",
260
+ true
434
261
  );
435
262
  createDeferredLazyRoutePromise(activeRootSpan);
436
263
  }
437
-
438
- // Pass the captured span to wrapPatchRoutesOnNavigation so it uses the same span
439
- // even if the span has ended by the time patchRoutesOnNavigation is called.
440
264
  const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan);
441
265
  const router = createRouterFunction(routes, wrappedOpts);
442
266
  const basename = opts?.basename;
443
-
444
- if (router.state.historyAction === 'POP' && activeRootSpan) {
267
+ if (router.state.historyAction === "POP" && activeRootSpan) {
445
268
  updatePageloadTransaction({
446
269
  activeRootSpan,
447
270
  location: router.state.location,
448
271
  routes,
449
272
  basename,
450
- allRoutes: Array.from(allRoutes),
273
+ allRoutes: Array.from(allRoutes)
451
274
  });
452
275
  }
453
-
454
- // Store basename for use in updateNavigationSpan
455
- _basename = basename || '';
456
-
276
+ _basename = basename || "";
457
277
  setupRouterSubscription(router, routes, version, basename, activeRootSpan);
458
-
459
278
  return router;
460
279
  };
461
280
  }
462
-
463
- /**
464
- * Creates a wrapCreateMemoryRouter function that can be used with all React Router v6 compatible versions.
465
- */
466
- function createV6CompatibleWrapCreateMemoryRouter
467
-
468
- (
469
- createRouterFunction,
470
- version,
471
- ) {
281
+ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version) {
472
282
  if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
473
- debugBuild.DEBUG_BUILD &&
474
- core.debug.warn(
475
- `reactRouterV${version}Instrumentation was unable to wrap the \`createMemoryRouter\` function because of one or more missing parameters.`,
476
- );
477
-
283
+ debugBuild.DEBUG_BUILD && core.debug.warn(
284
+ `reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createMemoryRouter\` function because of one or more missing parameters.`
285
+ );
478
286
  return createRouterFunction;
479
287
  }
480
-
481
- return function (
482
- routes,
483
- opts
484
-
485
- ,
486
- ) {
288
+ return function(routes, opts) {
487
289
  addRoutesToAllRoutes(routes);
488
-
489
290
  if (_enableAsyncRouteHandlers) {
490
291
  for (const route of routes) {
491
292
  lazyRoutes.checkRouteForAsyncHandler(route, processResolvedRoutes);
492
293
  }
493
294
  }
494
-
495
- // Capture the active span BEFORE creating the router (same as browser router)
496
295
  const memoryActiveRootSpanEarly = utils.getActiveRootSpan();
497
-
498
- // If patchRoutesOnNavigation is provided and we have an active span,
499
- // mark the span as having potential lazy routes and create a deferred promise.
500
- const hasPatchRoutesOnNavigation =
501
- opts && 'patchRoutesOnNavigation' in opts && typeof opts.patchRoutesOnNavigation === 'function';
296
+ const hasPatchRoutesOnNavigation = opts && "patchRoutesOnNavigation" in opts && typeof opts.patchRoutesOnNavigation === "function";
502
297
  if (hasPatchRoutesOnNavigation && memoryActiveRootSpanEarly) {
503
298
  core.addNonEnumerableProperty(
504
- memoryActiveRootSpanEarly ,
505
- '__sentry_may_have_lazy_routes__',
506
- true,
299
+ memoryActiveRootSpanEarly,
300
+ "__sentry_may_have_lazy_routes__",
301
+ true
507
302
  );
508
303
  createDeferredLazyRoutePromise(memoryActiveRootSpanEarly);
509
304
  }
510
-
511
305
  const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly);
512
-
513
306
  const router = createRouterFunction(routes, wrappedOpts);
514
307
  const basename = opts?.basename;
515
-
516
- let initialEntry = undefined;
517
-
308
+ let initialEntry = void 0;
518
309
  const initialEntries = opts?.initialEntries;
519
310
  const initialIndex = opts?.initialIndex;
520
-
521
311
  const hasOnlyOneInitialEntry = initialEntries?.length === 1;
522
- const hasIndexedEntry = initialIndex !== undefined && initialEntries?.[initialIndex];
523
-
524
- initialEntry = hasOnlyOneInitialEntry
525
- ? initialEntries[0]
526
- : hasIndexedEntry
527
- ? initialEntries[initialIndex]
528
- : undefined;
529
-
530
- const location = initialEntry
531
- ? typeof initialEntry === 'string'
532
- ? { pathname: initialEntry }
533
- : initialEntry
534
- : router.state.location;
535
-
312
+ const hasIndexedEntry = initialIndex !== void 0 && initialEntries?.[initialIndex];
313
+ initialEntry = hasOnlyOneInitialEntry ? initialEntries[0] : hasIndexedEntry ? initialEntries[initialIndex] : void 0;
314
+ const location = initialEntry ? typeof initialEntry === "string" ? { pathname: initialEntry } : initialEntry : router.state.location;
536
315
  const memoryActiveRootSpan = utils.getActiveRootSpan();
537
-
538
- if (router.state.historyAction === 'POP' && memoryActiveRootSpan) {
316
+ if (router.state.historyAction === "POP" && memoryActiveRootSpan) {
539
317
  updatePageloadTransaction({
540
318
  activeRootSpan: memoryActiveRootSpan,
541
319
  location,
542
320
  routes,
543
321
  basename,
544
- allRoutes: Array.from(allRoutes),
322
+ allRoutes: Array.from(allRoutes)
545
323
  });
546
324
  }
547
-
548
- // Store basename for use in updateNavigationSpan
549
- _basename = basename || '';
550
-
325
+ _basename = basename || "";
551
326
  setupRouterSubscription(router, routes, version, basename, memoryActiveRootSpan);
552
-
553
327
  return router;
554
328
  };
555
329
  }
556
-
557
- /**
558
- * Creates a browser tracing integration that can be used with all React Router v6 compatible versions.
559
- */
560
- function createReactRouterV6CompatibleTracingIntegration(
561
- options,
562
- version,
563
- ) {
330
+ function createReactRouterV6CompatibleTracingIntegration(options, version) {
564
331
  const integration = browser.browserTracingIntegration({ ...options, instrumentPageLoad: false, instrumentNavigation: false });
565
-
566
332
  const {
567
333
  useEffect,
568
334
  useLocation,
@@ -574,44 +340,36 @@ function createReactRouterV6CompatibleTracingIntegration(
574
340
  instrumentPageLoad = true,
575
341
  instrumentNavigation = true,
576
342
  lazyRouteTimeout,
577
- lazyRouteManifest,
343
+ lazyRouteManifest
578
344
  } = options;
579
-
580
345
  return {
581
346
  ...integration,
582
347
  setup(client) {
583
348
  integration.setup(client);
584
-
585
- const finalTimeout = options.finalTimeout ?? 30000;
586
- const defaultMaxWait = (options.idleTimeout ?? 1000) * 3;
349
+ const finalTimeout = options.finalTimeout ?? 3e4;
350
+ const defaultMaxWait = (options.idleTimeout ?? 1e3) * 3;
587
351
  const configuredMaxWait = lazyRouteTimeout ?? defaultMaxWait;
588
-
589
- // Cap Infinity at finalTimeout to prevent indefinite hangs
590
352
  if (configuredMaxWait === Infinity) {
591
353
  _lazyRouteTimeout = finalTimeout;
592
- debugBuild.DEBUG_BUILD &&
593
- core.debug.log(
594
- '[React Router] lazyRouteTimeout set to Infinity, capping at finalTimeout:',
595
- finalTimeout,
596
- 'ms to prevent indefinite hangs',
597
- );
354
+ debugBuild.DEBUG_BUILD && core.debug.log(
355
+ "[React Router] lazyRouteTimeout set to Infinity, capping at finalTimeout:",
356
+ finalTimeout,
357
+ "ms to prevent indefinite hangs"
358
+ );
598
359
  } else if (Number.isNaN(configuredMaxWait)) {
599
- debugBuild.DEBUG_BUILD &&
600
- core.debug.warn('[React Router] lazyRouteTimeout must be a number, falling back to default:', defaultMaxWait);
360
+ debugBuild.DEBUG_BUILD && core.debug.warn("[React Router] lazyRouteTimeout must be a number, falling back to default:", defaultMaxWait);
601
361
  _lazyRouteTimeout = defaultMaxWait;
602
362
  } else if (configuredMaxWait < 0) {
603
- debugBuild.DEBUG_BUILD &&
604
- core.debug.warn(
605
- '[React Router] lazyRouteTimeout must be non-negative or Infinity, got:',
606
- configuredMaxWait,
607
- 'falling back to:',
608
- defaultMaxWait,
609
- );
363
+ debugBuild.DEBUG_BUILD && core.debug.warn(
364
+ "[React Router] lazyRouteTimeout must be non-negative or Infinity, got:",
365
+ configuredMaxWait,
366
+ "falling back to:",
367
+ defaultMaxWait
368
+ );
610
369
  _lazyRouteTimeout = defaultMaxWait;
611
370
  } else {
612
371
  _lazyRouteTimeout = configuredMaxWait;
613
372
  }
614
-
615
373
  _useEffect = useEffect;
616
374
  _useLocation = useLocation;
617
375
  _useNavigationType = useNavigationType;
@@ -619,278 +377,191 @@ function createReactRouterV6CompatibleTracingIntegration(
619
377
  _createRoutesFromChildren = createRoutesFromChildren;
620
378
  _enableAsyncRouteHandlers = enableAsyncRouteHandlers;
621
379
  _lazyRouteManifest = lazyRouteManifest;
622
-
623
- // Initialize the router utils with the required dependencies
624
380
  utils.initializeRouterUtils(matchRoutes, stripBasename || false);
625
381
  },
626
382
  afterAllSetup(client) {
627
383
  integration.afterAllSetup(client);
628
-
629
384
  const initPathName = browser.WINDOW.location?.pathname;
630
385
  if (instrumentPageLoad && initPathName) {
631
386
  browser.startBrowserTracingPageLoadSpan(client, {
632
387
  name: initPathName,
633
388
  attributes: {
634
- [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
635
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',
636
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.pageload.react.reactrouter_v${version}`,
637
- },
389
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
390
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "pageload",
391
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.pageload.react.reactrouter${version ? `_v${version}` : ""}`
392
+ }
638
393
  });
639
394
  }
640
-
641
395
  if (instrumentNavigation) {
642
396
  CLIENTS_WITH_INSTRUMENT_NAVIGATION.add(client);
643
397
  }
644
- },
398
+ }
645
399
  };
646
400
  }
647
-
648
401
  function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
649
402
  if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
650
- debugBuild.DEBUG_BUILD &&
651
- core.debug.warn(
652
- 'reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.',
653
- );
654
-
403
+ debugBuild.DEBUG_BUILD && core.debug.warn(
404
+ "reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters."
405
+ );
655
406
  return origUseRoutes;
656
407
  }
657
-
658
- const SentryRoutes
659
-
660
- = (props) => {
408
+ const SentryRoutes = (props) => {
661
409
  const isMountRenderPass = React.useRef(true);
662
410
  const { routes, locationArg } = props;
663
-
664
411
  const Routes = origUseRoutes(routes, locationArg);
665
-
666
412
  const location = _useLocation();
667
413
  const navigationType = _useNavigationType();
668
-
669
- // A value with stable identity to either pick `locationArg` if available or `location` if not
670
- const stableLocationParam =
671
- typeof locationArg === 'string' || locationArg?.pathname ? (locationArg ) : location;
672
-
673
- _useEffect(() => {
674
- const normalizedLocation =
675
- typeof stableLocationParam === 'string' ? { pathname: stableLocationParam } : stableLocationParam;
676
-
414
+ const stableLocationParam = typeof locationArg === "string" || locationArg?.pathname ? locationArg : location;
415
+ useIsomorphicLayoutEffect(() => {
416
+ const normalizedLocation = typeof stableLocationParam === "string" ? { pathname: stableLocationParam } : stableLocationParam;
677
417
  if (isMountRenderPass.current) {
678
418
  addRoutesToAllRoutes(routes);
679
-
680
419
  updatePageloadTransaction({
681
420
  activeRootSpan: utils.getActiveRootSpan(),
682
421
  location: normalizedLocation,
683
422
  routes,
684
- allRoutes: Array.from(allRoutes),
423
+ allRoutes: Array.from(allRoutes)
685
424
  });
686
425
  isMountRenderPass.current = false;
687
426
  } else {
688
- // Note: Component-based routes don't support lazy route tracking via lazyRouteTimeout
689
- // because React.lazy() loads happen at the component level, not the router level.
690
- // Use createBrowserRouter with patchRoutesOnNavigation for lazy route tracking.
691
427
  handleNavigation({
692
428
  location: normalizedLocation,
693
429
  routes,
694
430
  navigationType,
695
431
  version,
696
- allRoutes: Array.from(allRoutes),
432
+ allRoutes: Array.from(allRoutes)
697
433
  });
698
434
  }
699
435
  }, [navigationType, stableLocationParam]);
700
-
701
436
  return Routes;
702
437
  };
703
-
704
- // eslint-disable-next-line react/display-name
705
438
  return (routes, locationArg) => {
706
- return React.createElement(SentryRoutes, { routes: routes, locationArg: locationArg,} );
439
+ return /* @__PURE__ */ React.createElement(SentryRoutes, { routes, locationArg });
707
440
  };
708
441
  }
709
- function wrapPatchRoutesOnNavigation(
710
- opts,
711
- isMemoryRouter = false,
712
- capturedSpan,
713
- ) {
714
- if (!opts || !('patchRoutesOnNavigation' in opts) || typeof opts.patchRoutesOnNavigation !== 'function') {
442
+ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan) {
443
+ if (!opts || !("patchRoutesOnNavigation" in opts) || typeof opts.patchRoutesOnNavigation !== "function") {
715
444
  return opts || {};
716
445
  }
717
-
718
446
  const originalPatchRoutes = opts.patchRoutesOnNavigation;
719
447
  return {
720
448
  ...opts,
721
449
  patchRoutesOnNavigation: async (args) => {
722
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
723
- const targetPath = (args )?.path;
724
-
725
- // Use current active span if available, otherwise fall back to captured span (from router creation time).
726
- // This ensures navigation spans use their own span (not the stale pageload span), while still
727
- // supporting pageload spans that may have ended before patchRoutesOnNavigation is called.
450
+ const targetPath = args?.path;
728
451
  const activeRootSpan = utils.getActiveRootSpan() ?? capturedSpan;
729
-
730
452
  if (!isMemoryRouter) {
731
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
732
- const originalPatch = (args )?.patch;
733
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
734
- const matches = (args )?.matches ;
453
+ const originalPatch = args?.patch;
454
+ const matches = args?.matches;
735
455
  if (originalPatch) {
736
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
737
- (args ).patch = (routeId, children) => {
456
+ args.patch = (routeId, children) => {
738
457
  addRoutesToAllRoutes(children);
739
-
740
- // Find the parent route from matches and attach children to it in allRoutes.
741
- // React Router's patch attaches children to its internal route copies, but we need
742
- // to update the route objects in our allRoutes Set for proper route matching.
743
458
  if (matches && matches.length > 0) {
744
459
  const leafMatch = matches[matches.length - 1];
745
460
  const leafRoute = leafMatch?.route;
746
461
  if (leafRoute) {
747
- // Find the matching route in allRoutes by id, reference, or path
748
- const matchingRoute = Array.from(allRoutes).find(route => {
749
- const idMatches = route.id !== undefined && route.id === routeId;
462
+ const matchingRoute = Array.from(allRoutes).find((route) => {
463
+ const idMatches = route.id !== void 0 && route.id === routeId;
750
464
  const referenceMatches = route === leafRoute;
751
- const pathMatches =
752
- route.path !== undefined && leafRoute.path !== undefined && route.path === leafRoute.path;
753
-
465
+ const pathMatches = route.path !== void 0 && leafRoute.path !== void 0 && route.path === leafRoute.path;
754
466
  return idMatches || referenceMatches || pathMatches;
755
467
  });
756
-
757
468
  if (matchingRoute) {
758
469
  addResolvedRoutesToParent(children, matchingRoute);
759
470
  }
760
471
  }
761
472
  }
762
-
763
- // Use the captured activeRootSpan instead of getActiveRootSpan() to avoid race conditions
764
- // where user navigates away during lazy route loading and we'd update the wrong span
765
- const spanJson = activeRootSpan ? core.spanToJSON(activeRootSpan) : undefined;
766
- // Only update if we have a valid targetPath (patchRoutesOnNavigation can be called without path),
767
- // the captured span exists, hasn't ended, and is a navigation span
768
- if (
769
- targetPath &&
770
- activeRootSpan &&
771
- spanJson &&
772
- !spanJson.timestamp && // Span hasn't ended yet
773
- spanJson.op === 'navigation'
774
- ) {
473
+ const spanJson = activeRootSpan ? core.spanToJSON(activeRootSpan) : void 0;
474
+ if (targetPath && activeRootSpan && spanJson && !spanJson.timestamp && // Span hasn't ended yet
475
+ spanJson.op === "navigation") {
775
476
  updateNavigationSpan(
776
477
  activeRootSpan,
777
- { pathname: targetPath, search: '', hash: '', state: null, key: 'default' },
478
+ { pathname: targetPath, search: "", hash: "", state: null, key: "default" },
778
479
  Array.from(allRoutes),
779
480
  true,
780
- _matchRoutes,
481
+ _matchRoutes
781
482
  );
782
483
  }
783
484
  return originalPatch(routeId, children);
784
485
  };
785
486
  }
786
487
  }
787
-
788
488
  const lazyLoadPromise = (async () => {
789
- // Set context so async handlers can access correct targetPath and span
790
489
  const contextToken = utils.setNavigationContext(targetPath, activeRootSpan);
791
490
  let result;
792
491
  try {
793
492
  result = await originalPatchRoutes(args);
794
493
  } finally {
795
494
  utils.clearNavigationContext(contextToken);
796
- // Resolve the deferred promise now that patchRoutesOnNavigation has completed.
797
- // This ensures patchedEnd has waited long enough for the lazy routes to load.
798
495
  if (activeRootSpan) {
799
496
  resolveDeferredLazyRoutePromise(activeRootSpan);
800
497
  }
801
498
  }
802
-
803
- // Use the captured activeRootSpan instead of getActiveRootSpan() to avoid race conditions
804
- // where user navigates away during lazy route loading and we'd update the wrong span
805
- const spanJson = activeRootSpan ? core.spanToJSON(activeRootSpan) : undefined;
806
- if (
807
- activeRootSpan &&
808
- spanJson &&
809
- !spanJson.timestamp && // Span hasn't ended yet
810
- spanJson.op === 'navigation'
811
- ) {
812
- // Use targetPath consistently - don't fall back to WINDOW.location which may have changed
813
- // if the user navigated away during async loading
499
+ const spanJson = activeRootSpan ? core.spanToJSON(activeRootSpan) : void 0;
500
+ if (activeRootSpan && spanJson && !spanJson.timestamp && // Span hasn't ended yet
501
+ spanJson.op === "navigation") {
814
502
  const pathname = targetPath;
815
-
816
503
  if (pathname) {
817
504
  updateNavigationSpan(
818
505
  activeRootSpan,
819
- { pathname, search: '', hash: '', state: null, key: 'default' },
506
+ { pathname, search: "", hash: "", state: null, key: "default" },
820
507
  Array.from(allRoutes),
821
508
  false,
822
- _matchRoutes,
509
+ _matchRoutes
823
510
  );
824
511
  }
825
512
  }
826
-
827
513
  return result;
828
514
  })();
829
-
830
515
  if (activeRootSpan) {
831
516
  trackLazyRouteLoad(activeRootSpan, lazyLoadPromise);
832
517
  }
833
-
834
518
  return lazyLoadPromise;
835
- },
519
+ }
836
520
  };
837
521
  }
838
-
839
- // eslint-disable-next-line complexity
840
- function handleNavigation(opts
841
-
842
- ) {
843
- const { location, routes, navigationType, version, matches, basename, allRoutes } = opts;
844
- const branches = Array.isArray(matches) ? matches : _matchRoutes(allRoutes || routes, location, basename);
845
-
522
+ function handleNavigation(opts) {
523
+ const { location, routes, navigationType, version, matches, basename, allRoutes: allRoutes2 } = opts;
524
+ const branches = Array.isArray(matches) ? matches : _matchRoutes(allRoutes2 || routes, location, basename);
846
525
  const client = core.getClient();
847
526
  if (!client || !CLIENTS_WITH_INSTRUMENT_NAVIGATION.has(client)) {
848
527
  return;
849
528
  }
850
-
851
529
  const activeRootSpan = utils.getActiveRootSpan();
852
- if (activeRootSpan && core.spanToJSON(activeRootSpan).op === 'pageload' && navigationType === 'POP') {
530
+ if (activeRootSpan && core.spanToJSON(activeRootSpan).op === "pageload" && navigationType === "POP") {
853
531
  return;
854
532
  }
855
-
856
- if ((navigationType === 'PUSH' || navigationType === 'POP') && branches) {
533
+ if ((navigationType === "PUSH" || navigationType === "POP") && branches) {
857
534
  const [name, source] = utils.resolveRouteNameAndSource(
858
535
  location,
859
- allRoutes || routes,
860
- allRoutes || routes,
861
- branches ,
536
+ allRoutes2 || routes,
537
+ allRoutes2 || routes,
538
+ branches,
862
539
  basename,
863
540
  _lazyRouteManifest,
864
- _enableAsyncRouteHandlers,
541
+ _enableAsyncRouteHandlers
865
542
  );
866
-
867
543
  const locationKey = computeLocationKey(location);
868
544
  const trackedNav = activeNavigationSpans.get(client);
869
-
870
- // Determine if this navigation should be skipped as a duplicate
871
- const trackedSpanHasEnded =
872
- trackedNav && !trackedNav.isPlaceholder ? !!core.spanToJSON(trackedNav.span).timestamp : false;
545
+ const trackedSpanHasEnded = trackedNav && !trackedNav.isPlaceholder ? !!core.spanToJSON(trackedNav.span).timestamp : false;
873
546
  const { skip, shouldUpdate } = shouldSkipNavigation(trackedNav, locationKey, name, trackedSpanHasEnded);
874
-
875
547
  if (skip) {
876
548
  if (shouldUpdate && trackedNav) {
877
549
  const oldName = trackedNav.routeName;
878
-
879
550
  if (trackedNav.isPlaceholder) {
880
- // Update placeholder's route name - the real span will be created with this name
881
551
  trackedNav.routeName = name;
882
- debugBuild.DEBUG_BUILD &&
883
- core.debug.log(
884
- `[Tracing] Updated placeholder navigation name from "${oldName}" to "${name}" (will apply to real span)`,
885
- );
552
+ debugBuild.DEBUG_BUILD && core.debug.log(
553
+ `[Tracing] Updated placeholder navigation name from "${oldName}" to "${name}" (will apply to real span)`
554
+ );
886
555
  } else {
887
- // Update existing real span from wildcard to parameterized route name
888
556
  trackedNav.span.updateName(name);
889
- trackedNav.span.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source );
557
+ trackedNav.span.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source);
558
+ if (source === "route") {
559
+ trackedNav.span.setAttribute(attributes.URL_TEMPLATE, name);
560
+ }
890
561
  core.addNonEnumerableProperty(
891
- trackedNav.span ,
892
- '__sentry_navigation_name_set__',
893
- true,
562
+ trackedNav.span,
563
+ "__sentry_navigation_name_set__",
564
+ true
894
565
  );
895
566
  trackedNav.routeName = name;
896
567
  debugBuild.DEBUG_BUILD && core.debug.log(`[Tracing] Updated navigation span name from "${oldName}" to "${name}"`);
@@ -900,191 +571,128 @@ function handleNavigation(opts
900
571
  }
901
572
  return;
902
573
  }
903
-
904
- // Create new navigation span (first navigation or legitimate new navigation)
905
- // Reserve the spot in the map first to prevent race conditions
906
- // Mark as placeholder to prevent concurrent handleNavigation calls from creating duplicates
907
- const placeholderSpan = { end: () => {} } ;
574
+ const placeholderSpan = { end: () => {
575
+ } };
908
576
  const placeholderEntry = {
909
577
  span: placeholderSpan,
910
578
  routeName: name,
911
579
  pathname: location.pathname,
912
580
  locationKey,
913
- isPlaceholder: true ,
581
+ isPlaceholder: true
914
582
  };
915
583
  activeNavigationSpans.set(client, placeholderEntry);
916
-
917
584
  let navigationSpan;
918
585
  try {
919
586
  navigationSpan = browser.startBrowserTracingNavigationSpan(client, {
920
- name: placeholderEntry.routeName, // Use placeholder's routeName in case it was updated
587
+ name: placeholderEntry.routeName,
588
+ // Use placeholder's routeName in case it was updated
921
589
  attributes: {
922
590
  [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,
923
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
924
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.navigation.react.reactrouter_v${version}`,
925
- },
591
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
592
+ [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.navigation.react.reactrouter${version ? `_v${version}` : ""}`,
593
+ ...source === "route" && { [attributes.URL_TEMPLATE]: placeholderEntry.routeName }
594
+ }
926
595
  });
927
596
  } catch (e) {
928
- // If span creation fails, remove the placeholder so we don't block future navigations
929
597
  activeNavigationSpans.delete(client);
930
598
  throw e;
931
599
  }
932
-
933
600
  if (navigationSpan) {
934
- // Update the map with the real span (isPlaceholder omitted, defaults to false)
935
601
  activeNavigationSpans.set(client, {
936
602
  span: navigationSpan,
937
- routeName: placeholderEntry.routeName, // Use the (potentially updated) placeholder routeName
603
+ routeName: placeholderEntry.routeName,
604
+ // Use the (potentially updated) placeholder routeName
938
605
  pathname: location.pathname,
939
- locationKey,
606
+ locationKey
940
607
  });
941
- patchSpanEnd(navigationSpan, location, routes, basename, 'navigation');
608
+ patchSpanEnd(navigationSpan, location, routes, basename, "navigation");
942
609
  } else {
943
- // If no span was created, remove the placeholder
944
610
  activeNavigationSpans.delete(client);
945
611
  }
946
612
  }
947
613
  }
948
-
949
- /* Only exported for testing purposes */
950
614
  function addRoutesToAllRoutes(routes) {
951
- routes.forEach(route => {
615
+ routes.forEach((route) => {
952
616
  const extractedChildRoutes = getChildRoutesRecursively(route);
953
-
954
- extractedChildRoutes.forEach(r => {
617
+ extractedChildRoutes.forEach((r) => {
955
618
  allRoutes.add(r);
956
619
  });
957
620
  });
958
621
  }
959
-
960
- function getChildRoutesRecursively(route, allRoutes = new Set()) {
961
- if (!allRoutes.has(route)) {
962
- allRoutes.add(route);
963
-
622
+ function getChildRoutesRecursively(route, allRoutes2 = /* @__PURE__ */ new Set()) {
623
+ if (!allRoutes2.has(route)) {
624
+ allRoutes2.add(route);
964
625
  if (route.children && !route.index) {
965
- route.children.forEach(child => {
966
- const childRoutes = getChildRoutesRecursively(child, allRoutes);
967
-
968
- childRoutes.forEach(r => {
969
- allRoutes.add(r);
626
+ route.children.forEach((child) => {
627
+ const childRoutes = getChildRoutesRecursively(child, allRoutes2);
628
+ childRoutes.forEach((r) => {
629
+ allRoutes2.add(r);
970
630
  });
971
631
  });
972
632
  }
973
633
  }
974
-
975
- return allRoutes;
634
+ return allRoutes2;
976
635
  }
977
-
978
636
  function updatePageloadTransaction({
979
637
  activeRootSpan,
980
638
  location,
981
639
  routes,
982
640
  matches,
983
641
  basename,
984
- allRoutes,
985
- }
986
-
987
- ) {
988
- const branches = Array.isArray(matches)
989
- ? matches
990
- : (_matchRoutes(allRoutes || routes, location, basename) );
991
-
642
+ allRoutes: allRoutes2
643
+ }) {
644
+ const branches = Array.isArray(matches) ? matches : _matchRoutes(allRoutes2 || routes, location, basename);
992
645
  if (branches) {
993
646
  const [name, source] = utils.resolveRouteNameAndSource(
994
647
  location,
995
- allRoutes || routes,
996
- allRoutes || routes,
648
+ allRoutes2 || routes,
649
+ allRoutes2 || routes,
997
650
  branches,
998
651
  basename,
999
652
  _lazyRouteManifest,
1000
- _enableAsyncRouteHandlers,
653
+ _enableAsyncRouteHandlers
1001
654
  );
1002
-
1003
- core.getCurrentScope().setTransactionName(name || '/');
1004
-
655
+ core.getCurrentScope().setTransactionName(name || "/");
1005
656
  if (activeRootSpan) {
1006
657
  activeRootSpan.updateName(name);
1007
658
  activeRootSpan.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source);
1008
-
1009
- // Patch span.end() to ensure we update the name one last time before the span is sent
1010
- patchSpanEnd(activeRootSpan, location, routes, basename, 'pageload');
659
+ if (source === "route") {
660
+ activeRootSpan.setAttribute(attributes.URL_TEMPLATE, name);
661
+ }
662
+ patchSpanEnd(activeRootSpan, location, routes, basename, "pageload");
1011
663
  }
1012
664
  } else if (activeRootSpan) {
1013
- // Even if branches is null (can happen when lazy routes haven't loaded yet),
1014
- // we still need to patch span.end() so that when lazy routes load and the span ends,
1015
- // we can update the transaction name correctly.
1016
- patchSpanEnd(activeRootSpan, location, routes, basename, 'pageload');
665
+ patchSpanEnd(activeRootSpan, location, routes, basename, "pageload");
1017
666
  }
1018
667
  }
1019
-
1020
- /**
1021
- * Determines if a span name should be updated during wildcard route resolution.
1022
- *
1023
- * Update conditions (in priority order):
1024
- * 1. No current name + allowNoCurrentName: true → always update (pageload spans)
1025
- * 2. Current name has wildcard + new is route without wildcard → upgrade (e.g., "/users/*" → "/users/:id")
1026
- * 3. Current source is not 'route' + new source is 'route' → upgrade (e.g., URL → parameterized route)
1027
- *
1028
- * @param currentName - The current span name (may be undefined)
1029
- * @param currentSource - The current span source ('route', 'url', or undefined)
1030
- * @param newName - The proposed new span name
1031
- * @param newSource - The proposed new span source
1032
- * @param allowNoCurrentName - If true, allow updates when there's no current name (for pageload spans)
1033
- * @returns true if the span name should be updated
1034
- */
1035
- function shouldUpdateWildcardSpanName(
1036
- currentName,
1037
- currentSource,
1038
- newName,
1039
- newSource,
1040
- allowNoCurrentName = false,
1041
- ) {
668
+ function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSource, allowNoCurrentName = false) {
1042
669
  if (!newName) {
1043
670
  return false;
1044
671
  }
1045
-
1046
672
  if (!currentName && allowNoCurrentName) {
1047
673
  return true;
1048
674
  }
1049
-
1050
675
  const hasWildcard = currentName && utils.transactionNameHasWildcard(currentName);
1051
-
1052
- if (hasWildcard && newSource === 'route' && !utils.transactionNameHasWildcard(newName)) {
676
+ if (hasWildcard && newSource === "route" && !utils.transactionNameHasWildcard(newName)) {
1053
677
  return true;
1054
678
  }
1055
-
1056
- if (currentSource !== 'route' && newSource === 'route') {
679
+ if (currentSource !== "route" && newSource === "route") {
1057
680
  return true;
1058
681
  }
1059
-
1060
682
  return false;
1061
683
  }
1062
-
1063
- function tryUpdateSpanNameBeforeEnd(
1064
- span,
1065
- spanJson,
1066
- currentName,
1067
- location,
1068
- routes,
1069
- basename,
1070
- spanType,
1071
- allRoutes,
1072
- ) {
684
+ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutes2) {
1073
685
  try {
1074
686
  const currentSource = spanJson.data?.[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
1075
-
1076
- if (currentSource === 'route' && currentName && !utils.transactionNameHasWildcard(currentName)) {
687
+ if (currentSource === "route" && currentName && !utils.transactionNameHasWildcard(currentName)) {
1077
688
  return;
1078
689
  }
1079
-
1080
- const currentAllRoutes = Array.from(allRoutes);
690
+ const currentAllRoutes = Array.from(allRoutes2);
1081
691
  const routesToUse = currentAllRoutes.length > 0 ? currentAllRoutes : routes;
1082
- const branches = _matchRoutes(routesToUse, location, basename) ;
1083
-
692
+ const branches = _matchRoutes(routesToUse, location, basename);
1084
693
  if (!branches) {
1085
694
  return;
1086
695
  }
1087
-
1088
696
  const [name, source] = utils.resolveRouteNameAndSource(
1089
697
  location,
1090
698
  routesToUse,
@@ -1092,82 +700,51 @@ function tryUpdateSpanNameBeforeEnd(
1092
700
  branches,
1093
701
  basename,
1094
702
  _lazyRouteManifest,
1095
- _enableAsyncRouteHandlers,
703
+ _enableAsyncRouteHandlers
1096
704
  );
1097
-
1098
705
  const isImprovement = shouldUpdateWildcardSpanName(currentName, currentSource, name, source, true);
1099
- const spanNotEnded = spanType === 'pageload' || !spanJson.timestamp;
1100
-
706
+ const spanNotEnded = spanType === "pageload" || !spanJson.timestamp;
1101
707
  if (isImprovement && spanNotEnded) {
1102
708
  span.updateName(name);
1103
709
  span.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source);
710
+ if (source === "route") {
711
+ span.setAttribute(attributes.URL_TEMPLATE, name);
712
+ }
1104
713
  }
1105
714
  } catch (error) {
1106
715
  debugBuild.DEBUG_BUILD && core.debug.warn(`Error updating span details before ending: ${error}`);
1107
716
  }
1108
717
  }
1109
-
1110
- /**
1111
- * Patches the span.end() method to update the transaction name one last time before the span is sent.
1112
- * This handles cases where the span is cancelled early (e.g., document.hidden) before lazy routes have finished loading.
1113
- */
1114
- function patchSpanEnd(
1115
- span,
1116
- location,
1117
- routes,
1118
- basename,
1119
- spanType,
1120
- ) {
1121
- const patchedPropertyName = `__sentry_${spanType}_end_patched__` ;
1122
- const hasEndBeenPatched = (span )?.[patchedPropertyName];
1123
-
718
+ function patchSpanEnd(span, location, routes, basename, spanType) {
719
+ const patchedPropertyName = `__sentry_${spanType}_end_patched__`;
720
+ const hasEndBeenPatched = span?.[patchedPropertyName];
1124
721
  if (hasEndBeenPatched || !span.end) {
1125
722
  return;
1126
723
  }
1127
-
1128
- // Uses global allRoutes to access lazy-loaded routes added after this function was called.
1129
-
1130
724
  const originalEnd = span.end.bind(span);
1131
725
  let endCalled = false;
1132
-
1133
726
  span.end = function patchedEnd(...args) {
1134
727
  if (endCalled) {
1135
728
  return;
1136
729
  }
1137
730
  endCalled = true;
1138
-
1139
- // Capture timestamp immediately to avoid delay from async operations
1140
- // If no timestamp was provided, capture the current time now
1141
- const endTimestamp = args.length > 0 ? args[0] : Date.now() / 1000;
1142
-
731
+ const endTimestamp = args.length > 0 ? args[0] : Date.now() / 1e3;
1143
732
  const spanJson = core.spanToJSON(span);
1144
733
  const currentName = spanJson.description;
1145
734
  const currentSource = spanJson.data?.[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
1146
-
1147
- // Helper to clean up activeNavigationSpans after span ends
1148
735
  const cleanupNavigationSpan = () => {
1149
736
  const client = core.getClient();
1150
- if (client && spanType === 'navigation') {
737
+ if (client && spanType === "navigation") {
1151
738
  const trackedNav = activeNavigationSpans.get(client);
1152
739
  if (trackedNav && trackedNav.span === span) {
1153
740
  activeNavigationSpans.delete(client);
1154
741
  }
1155
742
  }
1156
743
  };
1157
-
1158
744
  const pendingPromises = pendingLazyRouteLoads.get(span);
1159
- const mayHaveLazyRoutes = (span ).__sentry_may_have_lazy_routes__;
1160
-
1161
- // Wait for lazy routes if:
1162
- // 1. (There are pending promises OR the span was marked as potentially having lazy routes) AND
1163
- // 2. Current name exists AND
1164
- // 3. Either the name has a wildcard OR the source is not 'route' (URL-based names)
1165
- const hasPendingOrMayHaveLazyRoutes = (pendingPromises && pendingPromises.size > 0) || mayHaveLazyRoutes;
1166
- const shouldWaitForLazyRoutes =
1167
- hasPendingOrMayHaveLazyRoutes &&
1168
- currentName &&
1169
- (utils.transactionNameHasWildcard(currentName) || currentSource !== 'route');
1170
-
745
+ const mayHaveLazyRoutes = span.__sentry_may_have_lazy_routes__;
746
+ const hasPendingOrMayHaveLazyRoutes = pendingPromises && pendingPromises.size > 0 || mayHaveLazyRoutes;
747
+ const shouldWaitForLazyRoutes = hasPendingOrMayHaveLazyRoutes && currentName && (utils.transactionNameHasWildcard(currentName) || currentSource !== "route");
1171
748
  if (shouldWaitForLazyRoutes) {
1172
749
  if (_lazyRouteTimeout === 0) {
1173
750
  tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutes);
@@ -1175,107 +752,74 @@ function patchSpanEnd(
1175
752
  originalEnd(endTimestamp);
1176
753
  return;
1177
754
  }
1178
-
1179
- // If we have pending promises, wait for them. Otherwise, just wait for the timeout.
1180
- // This handles the case where we know lazy routes might load but patchRoutesOnNavigation
1181
- // hasn't been called yet.
1182
- const timeoutPromise = new Promise(r => setTimeout(r, _lazyRouteTimeout));
755
+ const timeoutPromise = new Promise((r) => setTimeout(r, _lazyRouteTimeout));
1183
756
  let waitPromise;
1184
-
1185
757
  if (pendingPromises && pendingPromises.size > 0) {
1186
- const allSettled = Promise.allSettled(pendingPromises).then(() => {});
758
+ const allSettled = Promise.allSettled(pendingPromises).then(() => {
759
+ });
1187
760
  waitPromise = _lazyRouteTimeout === Infinity ? allSettled : Promise.race([allSettled, timeoutPromise]);
1188
761
  } else {
1189
- // No pending promises yet, but we know lazy routes might load
1190
- // Wait for the timeout to give React Router time to call patchRoutesOnNavigation
1191
762
  waitPromise = timeoutPromise;
1192
763
  }
1193
-
1194
- waitPromise
1195
- .then(() => {
1196
- const updatedSpanJson = core.spanToJSON(span);
1197
- tryUpdateSpanNameBeforeEnd(
1198
- span,
1199
- updatedSpanJson,
1200
- updatedSpanJson.description,
1201
- location,
1202
- routes,
1203
- basename,
1204
- spanType,
1205
- allRoutes,
1206
- );
1207
- cleanupNavigationSpan();
1208
- originalEnd(endTimestamp);
1209
- })
1210
- .catch(() => {
1211
- cleanupNavigationSpan();
1212
- originalEnd(endTimestamp);
1213
- });
764
+ waitPromise.then(() => {
765
+ const updatedSpanJson = core.spanToJSON(span);
766
+ tryUpdateSpanNameBeforeEnd(
767
+ span,
768
+ updatedSpanJson,
769
+ updatedSpanJson.description,
770
+ location,
771
+ routes,
772
+ basename,
773
+ spanType,
774
+ allRoutes
775
+ );
776
+ cleanupNavigationSpan();
777
+ originalEnd(endTimestamp);
778
+ }).catch(() => {
779
+ cleanupNavigationSpan();
780
+ originalEnd(endTimestamp);
781
+ });
1214
782
  return;
1215
783
  }
1216
-
1217
784
  tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutes);
1218
785
  cleanupNavigationSpan();
1219
786
  originalEnd(endTimestamp);
1220
787
  };
1221
-
1222
- core.addNonEnumerableProperty(span , patchedPropertyName, true);
788
+ core.addNonEnumerableProperty(span, patchedPropertyName, true);
1223
789
  }
1224
-
1225
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1226
- function createV6CompatibleWithSentryReactRouterRouting(
1227
- Routes,
1228
- version,
1229
- ) {
790
+ function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
1230
791
  if (!_useEffect || !_useLocation || !_useNavigationType || !_createRoutesFromChildren || !_matchRoutes) {
1231
- debugBuild.DEBUG_BUILD &&
1232
- core.debug.warn(`reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters.
792
+ debugBuild.DEBUG_BUILD && core.debug.warn(`reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters.
1233
793
  useEffect: ${_useEffect}. useLocation: ${_useLocation}. useNavigationType: ${_useNavigationType}.
1234
794
  createRoutesFromChildren: ${_createRoutesFromChildren}. matchRoutes: ${_matchRoutes}.`);
1235
-
1236
795
  return Routes;
1237
796
  }
1238
-
1239
797
  const SentryRoutes = (props) => {
1240
798
  const isMountRenderPass = React.useRef(true);
1241
-
1242
799
  const location = _useLocation();
1243
800
  const navigationType = _useNavigationType();
1244
-
1245
- _useEffect(
801
+ useIsomorphicLayoutEffect(
1246
802
  () => {
1247
- const routes = _createRoutesFromChildren(props.children) ;
1248
-
803
+ const routes = _createRoutesFromChildren(props.children);
1249
804
  if (isMountRenderPass.current) {
1250
805
  addRoutesToAllRoutes(routes);
1251
-
1252
806
  updatePageloadTransaction({
1253
807
  activeRootSpan: utils.getActiveRootSpan(),
1254
808
  location,
1255
809
  routes,
1256
- allRoutes: Array.from(allRoutes),
810
+ allRoutes: Array.from(allRoutes)
1257
811
  });
1258
812
  isMountRenderPass.current = false;
1259
813
  } else {
1260
- // Note: Component-based routes don't support lazy route tracking via lazyRouteTimeout
1261
- // because React.lazy() loads happen at the component level, not the router level.
1262
- // Use createBrowserRouter with patchRoutesOnNavigation for lazy route tracking.
1263
814
  handleNavigation({ location, routes, navigationType, version, allRoutes: Array.from(allRoutes) });
1264
815
  }
1265
816
  },
1266
817
  // Re-run only on location/navigation changes, not children changes
1267
- [location, navigationType],
818
+ [location, navigationType]
1268
819
  );
1269
-
1270
- // @ts-expect-error Setting more specific React Component typing for `R` generic above
1271
- // will break advanced type inference done by react router params
1272
- return React.createElement(Routes, { ...props,} );
820
+ return /* @__PURE__ */ React.createElement(Routes, { ...props });
1273
821
  };
1274
-
1275
822
  hoistNonReactStatics.hoistNonReactStatics(SentryRoutes, Routes);
1276
-
1277
- // @ts-expect-error Setting more specific React Component typing for `R` generic above
1278
- // will break advanced type inference done by react router params
1279
823
  return SentryRoutes;
1280
824
  }
1281
825