@sentry/react 10.53.1 → 10.55.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 (78) hide show
  1. package/build/cjs/constants.js +3 -5
  2. package/build/cjs/constants.js.map +1 -1
  3. package/build/cjs/debug-build.js +0 -5
  4. package/build/cjs/debug-build.js.map +1 -1
  5. package/build/cjs/error.js +12 -72
  6. package/build/cjs/error.js.map +1 -1
  7. package/build/cjs/errorboundary.js +22 -77
  8. package/build/cjs/errorboundary.js.map +1 -1
  9. package/build/cjs/hoist-non-react-statics.js +16 -84
  10. package/build/cjs/hoist-non-react-statics.js.map +1 -1
  11. package/build/cjs/isSyntheticEvent.js +10 -0
  12. package/build/cjs/isSyntheticEvent.js.map +1 -0
  13. package/build/cjs/profiler.js +35 -110
  14. package/build/cjs/profiler.js.map +1 -1
  15. package/build/cjs/reactrouter-compat-utils/instrumentation.js +219 -690
  16. package/build/cjs/reactrouter-compat-utils/instrumentation.js.map +1 -1
  17. package/build/cjs/reactrouter-compat-utils/lazy-routes.js +24 -85
  18. package/build/cjs/reactrouter-compat-utils/lazy-routes.js.map +1 -1
  19. package/build/cjs/reactrouter-compat-utils/route-manifest.js +17 -95
  20. package/build/cjs/reactrouter-compat-utils/route-manifest.js.map +1 -1
  21. package/build/cjs/reactrouter-compat-utils/utils.js +48 -190
  22. package/build/cjs/reactrouter-compat-utils/utils.js.map +1 -1
  23. package/build/cjs/reactrouter.js +33 -113
  24. package/build/cjs/reactrouter.js.map +1 -1
  25. package/build/cjs/reactrouterv3.js +27 -59
  26. package/build/cjs/reactrouterv3.js.map +1 -1
  27. package/build/cjs/reactrouterv6.js +8 -41
  28. package/build/cjs/reactrouterv6.js.map +1 -1
  29. package/build/cjs/reactrouterv7.js +8 -41
  30. package/build/cjs/reactrouterv7.js.map +1 -1
  31. package/build/cjs/redux.js +60 -88
  32. package/build/cjs/redux.js.map +1 -1
  33. package/build/cjs/sdk.js +13 -8
  34. package/build/cjs/sdk.js.map +1 -1
  35. package/build/cjs/tanstackrouter.js +24 -64
  36. package/build/cjs/tanstackrouter.js.map +1 -1
  37. package/build/esm/constants.js +3 -5
  38. package/build/esm/constants.js.map +1 -1
  39. package/build/esm/debug-build.js +0 -5
  40. package/build/esm/debug-build.js.map +1 -1
  41. package/build/esm/error.js +12 -72
  42. package/build/esm/error.js.map +1 -1
  43. package/build/esm/errorboundary.js +22 -77
  44. package/build/esm/errorboundary.js.map +1 -1
  45. package/build/esm/hoist-non-react-statics.js +16 -84
  46. package/build/esm/hoist-non-react-statics.js.map +1 -1
  47. package/build/esm/isSyntheticEvent.js +8 -0
  48. package/build/esm/isSyntheticEvent.js.map +1 -0
  49. package/build/esm/package.json +1 -1
  50. package/build/esm/profiler.js +35 -110
  51. package/build/esm/profiler.js.map +1 -1
  52. package/build/esm/reactrouter-compat-utils/instrumentation.js +219 -690
  53. package/build/esm/reactrouter-compat-utils/instrumentation.js.map +1 -1
  54. package/build/esm/reactrouter-compat-utils/lazy-routes.js +24 -85
  55. package/build/esm/reactrouter-compat-utils/lazy-routes.js.map +1 -1
  56. package/build/esm/reactrouter-compat-utils/route-manifest.js +17 -95
  57. package/build/esm/reactrouter-compat-utils/route-manifest.js.map +1 -1
  58. package/build/esm/reactrouter-compat-utils/utils.js +48 -190
  59. package/build/esm/reactrouter-compat-utils/utils.js.map +1 -1
  60. package/build/esm/reactrouter.js +33 -113
  61. package/build/esm/reactrouter.js.map +1 -1
  62. package/build/esm/reactrouterv3.js +27 -59
  63. package/build/esm/reactrouterv3.js.map +1 -1
  64. package/build/esm/reactrouterv6.js +8 -41
  65. package/build/esm/reactrouterv6.js.map +1 -1
  66. package/build/esm/reactrouterv7.js +8 -41
  67. package/build/esm/reactrouterv7.js.map +1 -1
  68. package/build/esm/redux.js +60 -88
  69. package/build/esm/redux.js.map +1 -1
  70. package/build/esm/sdk.js +15 -10
  71. package/build/esm/sdk.js.map +1 -1
  72. package/build/esm/tanstackrouter.js +24 -64
  73. package/build/esm/tanstackrouter.js.map +1 -1
  74. package/build/types/isSyntheticEvent.d.ts +10 -0
  75. package/build/types/isSyntheticEvent.d.ts.map +1 -0
  76. package/build/types/sdk.d.ts.map +1 -1
  77. package/build/types-ts3.8/isSyntheticEvent.d.ts +10 -0
  78. package/package.json +3 -3
@@ -1,82 +1,49 @@
1
1
  import { debug } from '@sentry/core/browser';
2
2
  import { DEBUG_BUILD } from '../debug-build.js';
3
3
 
4
- /**
5
- * Strip the basename from a pathname if exists.
6
- *
7
- * Vendored and modified from `react-router`
8
- * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038
9
- */
10
4
  function stripBasenameFromPathname(pathname, basename) {
11
- if (!basename || basename === '/') {
5
+ if (!basename || basename === "/") {
12
6
  return pathname;
13
7
  }
14
-
15
8
  if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
16
9
  return pathname;
17
10
  }
18
-
19
- // We want to leave trailing slash behavior in the user's control, so if they
20
- // specify a basename with a trailing slash, we should support it
21
- const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length;
11
+ const startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length;
22
12
  const nextChar = pathname.charAt(startIndex);
23
- if (nextChar && nextChar !== '/') {
24
- // pathname does not start with basename/
13
+ if (nextChar && nextChar !== "/") {
25
14
  return pathname;
26
15
  }
27
-
28
- return pathname.slice(startIndex) || '/';
16
+ return pathname.slice(startIndex) || "/";
29
17
  }
30
-
31
- // Cache for sorted manifests - keyed by manifest array reference
32
- const SORTED_MANIFEST_CACHE = new WeakMap();
33
-
34
- /**
35
- * Matches a pathname against a route manifest and returns the matching pattern.
36
- * Optionally strips a basename prefix before matching.
37
- */
18
+ const SORTED_MANIFEST_CACHE = /* @__PURE__ */ new WeakMap();
38
19
  function matchRouteManifest(pathname, manifest, basename) {
39
20
  if (!pathname || !manifest?.length) {
40
21
  return null;
41
22
  }
42
-
43
23
  const normalizedPathname = basename ? stripBasenameFromPathname(pathname, basename) : pathname;
44
-
45
24
  let sorted = SORTED_MANIFEST_CACHE.get(manifest);
46
25
  if (!sorted) {
47
26
  sorted = sortBySpecificity(manifest);
48
27
  SORTED_MANIFEST_CACHE.set(manifest, sorted);
49
- DEBUG_BUILD && debug.log('[React Router] Sorted route manifest by specificity:', sorted.length, 'patterns');
28
+ DEBUG_BUILD && debug.log("[React Router] Sorted route manifest by specificity:", sorted.length, "patterns");
50
29
  }
51
-
52
30
  for (const pattern of sorted) {
53
31
  if (matchesPattern(normalizedPathname, pattern)) {
54
- DEBUG_BUILD && debug.log('[React Router] Matched pathname', normalizedPathname, 'to pattern', pattern);
32
+ DEBUG_BUILD && debug.log("[React Router] Matched pathname", normalizedPathname, "to pattern", pattern);
55
33
  return pattern;
56
34
  }
57
35
  }
58
-
59
- DEBUG_BUILD && debug.log('[React Router] No manifest match found for pathname:', normalizedPathname);
36
+ DEBUG_BUILD && debug.log("[React Router] No manifest match found for pathname:", normalizedPathname);
60
37
  return null;
61
38
  }
62
-
63
- /**
64
- * Checks if a pathname matches a route pattern.
65
- */
66
39
  function matchesPattern(pathname, pattern) {
67
- // Handle root path special case
68
- if (pattern === '/') {
69
- return pathname === '/' || pathname === '';
40
+ if (pattern === "/") {
41
+ return pathname === "/" || pathname === "";
70
42
  }
71
-
72
43
  const pathSegments = splitPath(pathname);
73
44
  const patternSegments = splitPath(pattern);
74
-
75
- // Handle wildcard at end
76
- const hasWildcard = patternSegments.length > 0 && patternSegments[patternSegments.length - 1] === '*';
77
-
45
+ const hasWildcard = patternSegments.length > 0 && patternSegments[patternSegments.length - 1] === "*";
78
46
  if (hasWildcard) {
79
- // Pattern with wildcard: path must have at least as many segments as pattern (minus wildcard)
80
47
  const patternSegmentsWithoutWildcard = patternSegments.slice(0, -1);
81
48
  if (pathSegments.length < patternSegmentsWithoutWildcard.length) {
82
49
  return false;
@@ -88,101 +55,56 @@ function matchesPattern(pathname, pattern) {
88
55
  }
89
56
  return true;
90
57
  }
91
-
92
- // Exact segment count match required
93
58
  if (pathSegments.length !== patternSegments.length) {
94
59
  return false;
95
60
  }
96
-
97
61
  for (const [i, patternSegment] of patternSegments.entries()) {
98
62
  if (!segmentMatches(pathSegments[i], patternSegment)) {
99
63
  return false;
100
64
  }
101
65
  }
102
-
103
66
  return true;
104
67
  }
105
-
106
- /**
107
- * Checks if a path segment matches a pattern segment.
108
- */
109
68
  function segmentMatches(pathSegment, patternSegment) {
110
- if (pathSegment === undefined || patternSegment === undefined) {
69
+ if (pathSegment === void 0 || patternSegment === void 0) {
111
70
  return false;
112
71
  }
113
- // Parameter matches anything
114
72
  if (PARAM_RE.test(patternSegment)) {
115
73
  return true;
116
74
  }
117
- // Literal must match exactly
118
75
  return pathSegment === patternSegment;
119
76
  }
120
-
121
- /**
122
- * Splits a path into segments, filtering out empty strings.
123
- */
124
77
  function splitPath(path) {
125
- return path.split('/').filter(Boolean);
78
+ return path.split("/").filter(Boolean);
126
79
  }
127
-
128
- /**
129
- * React Router scoring weights and param detection.
130
- * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts
131
- */
132
80
  const PARAM_RE = /^:[\w-]+$/;
133
81
  const STATIC_SEGMENT_SCORE = 10;
134
82
  const DYNAMIC_SEGMENT_SCORE = 3;
135
83
  const EMPTY_SEGMENT_SCORE = 1;
136
84
  const SPLAT_PENALTY = -2;
137
-
138
- /**
139
- * Computes a specificity score for a route pattern.
140
- * Matches React Router's computeScore() algorithm exactly.
141
- */
142
85
  function computeScore(pattern) {
143
- const segments = pattern.split('/');
144
-
145
- // Base score is segment count (including empty segment from leading slash)
86
+ const segments = pattern.split("/");
146
87
  let score = segments.length;
147
-
148
- // Apply splat penalty once if pattern contains wildcard
149
- if (segments.includes('*')) {
88
+ if (segments.includes("*")) {
150
89
  score += SPLAT_PENALTY;
151
90
  }
152
-
153
91
  for (const segment of segments) {
154
- if (segment === '*') {
155
- // Splat penalty already applied globally above
92
+ if (segment === "*") {
156
93
  continue;
157
94
  } else if (PARAM_RE.test(segment)) {
158
95
  score += DYNAMIC_SEGMENT_SCORE;
159
- } else if (segment === '') {
96
+ } else if (segment === "") {
160
97
  score += EMPTY_SEGMENT_SCORE;
161
98
  } else {
162
99
  score += STATIC_SEGMENT_SCORE;
163
100
  }
164
101
  }
165
-
166
102
  return score;
167
103
  }
168
-
169
- /**
170
- * Sorts route patterns by specificity (most specific first).
171
- * Implements React Router's ranking algorithm from computeScore():
172
- * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts
173
- *
174
- * React Router scoring: base=segments.length, static=+10, dynamic=+3, empty=+1, splat=-2 (once)
175
- * Higher score = more specific pattern.
176
- * Equal scores preserve manifest order (same as React Router).
177
- *
178
- * Note: Users should order their manifest from most specific to least specific
179
- * when patterns have equal specificity (e.g., `/users/:id/settings` and `/:type/123/settings`).
180
- */
181
104
  function sortBySpecificity(manifest) {
182
105
  return [...manifest].sort((a, b) => {
183
106
  const aScore = computeScore(a);
184
107
  const bScore = computeScore(b);
185
-
186
108
  return bScore - aScore;
187
109
  });
188
110
  }
@@ -1 +1 @@
1
- {"version":3,"file":"route-manifest.js","sources":["../../../src/reactrouter-compat-utils/route-manifest.ts"],"sourcesContent":["import { debug } from '@sentry/core/browser';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/**\n * Strip the basename from a pathname if exists.\n *\n * Vendored and modified from `react-router`\n * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038\n */\nexport function stripBasenameFromPathname(pathname: string, basename: string): string {\n if (!basename || basename === '/') {\n return pathname;\n }\n\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return pathname;\n }\n\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length;\n const nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== '/') {\n // pathname does not start with basename/\n return pathname;\n }\n\n return pathname.slice(startIndex) || '/';\n}\n\n// Cache for sorted manifests - keyed by manifest array reference\nconst SORTED_MANIFEST_CACHE = new WeakMap<string[], string[]>();\n\n/**\n * Matches a pathname against a route manifest and returns the matching pattern.\n * Optionally strips a basename prefix before matching.\n */\nexport function matchRouteManifest(pathname: string, manifest: string[], basename?: string): string | null {\n if (!pathname || !manifest?.length) {\n return null;\n }\n\n const normalizedPathname = basename ? stripBasenameFromPathname(pathname, basename) : pathname;\n\n let sorted = SORTED_MANIFEST_CACHE.get(manifest);\n if (!sorted) {\n sorted = sortBySpecificity(manifest);\n SORTED_MANIFEST_CACHE.set(manifest, sorted);\n DEBUG_BUILD && debug.log('[React Router] Sorted route manifest by specificity:', sorted.length, 'patterns');\n }\n\n for (const pattern of sorted) {\n if (matchesPattern(normalizedPathname, pattern)) {\n DEBUG_BUILD && debug.log('[React Router] Matched pathname', normalizedPathname, 'to pattern', pattern);\n return pattern;\n }\n }\n\n DEBUG_BUILD && debug.log('[React Router] No manifest match found for pathname:', normalizedPathname);\n return null;\n}\n\n/**\n * Checks if a pathname matches a route pattern.\n */\nfunction matchesPattern(pathname: string, pattern: string): boolean {\n // Handle root path special case\n if (pattern === '/') {\n return pathname === '/' || pathname === '';\n }\n\n const pathSegments = splitPath(pathname);\n const patternSegments = splitPath(pattern);\n\n // Handle wildcard at end\n const hasWildcard = patternSegments.length > 0 && patternSegments[patternSegments.length - 1] === '*';\n\n if (hasWildcard) {\n // Pattern with wildcard: path must have at least as many segments as pattern (minus wildcard)\n const patternSegmentsWithoutWildcard = patternSegments.slice(0, -1);\n if (pathSegments.length < patternSegmentsWithoutWildcard.length) {\n return false;\n }\n for (const [i, patternSegment] of patternSegmentsWithoutWildcard.entries()) {\n if (!segmentMatches(pathSegments[i], patternSegment)) {\n return false;\n }\n }\n return true;\n }\n\n // Exact segment count match required\n if (pathSegments.length !== patternSegments.length) {\n return false;\n }\n\n for (const [i, patternSegment] of patternSegments.entries()) {\n if (!segmentMatches(pathSegments[i], patternSegment)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Checks if a path segment matches a pattern segment.\n */\nfunction segmentMatches(pathSegment: string | undefined, patternSegment: string | undefined): boolean {\n if (pathSegment === undefined || patternSegment === undefined) {\n return false;\n }\n // Parameter matches anything\n if (PARAM_RE.test(patternSegment)) {\n return true;\n }\n // Literal must match exactly\n return pathSegment === patternSegment;\n}\n\n/**\n * Splits a path into segments, filtering out empty strings.\n */\nfunction splitPath(path: string): string[] {\n return path.split('/').filter(Boolean);\n}\n\n/**\n * React Router scoring weights and param detection.\n * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts\n */\nconst PARAM_RE = /^:[\\w-]+$/;\nconst STATIC_SEGMENT_SCORE = 10;\nconst DYNAMIC_SEGMENT_SCORE = 3;\nconst EMPTY_SEGMENT_SCORE = 1;\nconst SPLAT_PENALTY = -2;\n\n/**\n * Computes a specificity score for a route pattern.\n * Matches React Router's computeScore() algorithm exactly.\n */\nfunction computeScore(pattern: string): number {\n const segments = pattern.split('/');\n\n // Base score is segment count (including empty segment from leading slash)\n let score = segments.length;\n\n // Apply splat penalty once if pattern contains wildcard\n if (segments.includes('*')) {\n score += SPLAT_PENALTY;\n }\n\n for (const segment of segments) {\n if (segment === '*') {\n // Splat penalty already applied globally above\n continue;\n } else if (PARAM_RE.test(segment)) {\n score += DYNAMIC_SEGMENT_SCORE;\n } else if (segment === '') {\n score += EMPTY_SEGMENT_SCORE;\n } else {\n score += STATIC_SEGMENT_SCORE;\n }\n }\n\n return score;\n}\n\n/**\n * Sorts route patterns by specificity (most specific first).\n * Implements React Router's ranking algorithm from computeScore():\n * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts\n *\n * React Router scoring: base=segments.length, static=+10, dynamic=+3, empty=+1, splat=-2 (once)\n * Higher score = more specific pattern.\n * Equal scores preserve manifest order (same as React Router).\n *\n * Note: Users should order their manifest from most specific to least specific\n * when patterns have equal specificity (e.g., `/users/:id/settings` and `/:type/123/settings`).\n */\nfunction sortBySpecificity(manifest: string[]): string[] {\n return [...manifest].sort((a, b) => {\n const aScore = computeScore(a);\n const bScore = computeScore(b);\n\n return bScore - aScore;\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route-manifest.js","sources":["../../../src/reactrouter-compat-utils/route-manifest.ts"],"sourcesContent":["import { debug } from '@sentry/core/browser';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/**\n * Strip the basename from a pathname if exists.\n *\n * Vendored and modified from `react-router`\n * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038\n */\nexport function stripBasenameFromPathname(pathname: string, basename: string): string {\n if (!basename || basename === '/') {\n return pathname;\n }\n\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return pathname;\n }\n\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length;\n const nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== '/') {\n // pathname does not start with basename/\n return pathname;\n }\n\n return pathname.slice(startIndex) || '/';\n}\n\n// Cache for sorted manifests - keyed by manifest array reference\nconst SORTED_MANIFEST_CACHE = new WeakMap<string[], string[]>();\n\n/**\n * Matches a pathname against a route manifest and returns the matching pattern.\n * Optionally strips a basename prefix before matching.\n */\nexport function matchRouteManifest(pathname: string, manifest: string[], basename?: string): string | null {\n if (!pathname || !manifest?.length) {\n return null;\n }\n\n const normalizedPathname = basename ? stripBasenameFromPathname(pathname, basename) : pathname;\n\n let sorted = SORTED_MANIFEST_CACHE.get(manifest);\n if (!sorted) {\n sorted = sortBySpecificity(manifest);\n SORTED_MANIFEST_CACHE.set(manifest, sorted);\n DEBUG_BUILD && debug.log('[React Router] Sorted route manifest by specificity:', sorted.length, 'patterns');\n }\n\n for (const pattern of sorted) {\n if (matchesPattern(normalizedPathname, pattern)) {\n DEBUG_BUILD && debug.log('[React Router] Matched pathname', normalizedPathname, 'to pattern', pattern);\n return pattern;\n }\n }\n\n DEBUG_BUILD && debug.log('[React Router] No manifest match found for pathname:', normalizedPathname);\n return null;\n}\n\n/**\n * Checks if a pathname matches a route pattern.\n */\nfunction matchesPattern(pathname: string, pattern: string): boolean {\n // Handle root path special case\n if (pattern === '/') {\n return pathname === '/' || pathname === '';\n }\n\n const pathSegments = splitPath(pathname);\n const patternSegments = splitPath(pattern);\n\n // Handle wildcard at end\n const hasWildcard = patternSegments.length > 0 && patternSegments[patternSegments.length - 1] === '*';\n\n if (hasWildcard) {\n // Pattern with wildcard: path must have at least as many segments as pattern (minus wildcard)\n const patternSegmentsWithoutWildcard = patternSegments.slice(0, -1);\n if (pathSegments.length < patternSegmentsWithoutWildcard.length) {\n return false;\n }\n for (const [i, patternSegment] of patternSegmentsWithoutWildcard.entries()) {\n if (!segmentMatches(pathSegments[i], patternSegment)) {\n return false;\n }\n }\n return true;\n }\n\n // Exact segment count match required\n if (pathSegments.length !== patternSegments.length) {\n return false;\n }\n\n for (const [i, patternSegment] of patternSegments.entries()) {\n if (!segmentMatches(pathSegments[i], patternSegment)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Checks if a path segment matches a pattern segment.\n */\nfunction segmentMatches(pathSegment: string | undefined, patternSegment: string | undefined): boolean {\n if (pathSegment === undefined || patternSegment === undefined) {\n return false;\n }\n // Parameter matches anything\n if (PARAM_RE.test(patternSegment)) {\n return true;\n }\n // Literal must match exactly\n return pathSegment === patternSegment;\n}\n\n/**\n * Splits a path into segments, filtering out empty strings.\n */\nfunction splitPath(path: string): string[] {\n return path.split('/').filter(Boolean);\n}\n\n/**\n * React Router scoring weights and param detection.\n * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts\n */\nconst PARAM_RE = /^:[\\w-]+$/;\nconst STATIC_SEGMENT_SCORE = 10;\nconst DYNAMIC_SEGMENT_SCORE = 3;\nconst EMPTY_SEGMENT_SCORE = 1;\nconst SPLAT_PENALTY = -2;\n\n/**\n * Computes a specificity score for a route pattern.\n * Matches React Router's computeScore() algorithm exactly.\n */\nfunction computeScore(pattern: string): number {\n const segments = pattern.split('/');\n\n // Base score is segment count (including empty segment from leading slash)\n let score = segments.length;\n\n // Apply splat penalty once if pattern contains wildcard\n if (segments.includes('*')) {\n score += SPLAT_PENALTY;\n }\n\n for (const segment of segments) {\n if (segment === '*') {\n // Splat penalty already applied globally above\n continue;\n } else if (PARAM_RE.test(segment)) {\n score += DYNAMIC_SEGMENT_SCORE;\n } else if (segment === '') {\n score += EMPTY_SEGMENT_SCORE;\n } else {\n score += STATIC_SEGMENT_SCORE;\n }\n }\n\n return score;\n}\n\n/**\n * Sorts route patterns by specificity (most specific first).\n * Implements React Router's ranking algorithm from computeScore():\n * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts\n *\n * React Router scoring: base=segments.length, static=+10, dynamic=+3, empty=+1, splat=-2 (once)\n * Higher score = more specific pattern.\n * Equal scores preserve manifest order (same as React Router).\n *\n * Note: Users should order their manifest from most specific to least specific\n * when patterns have equal specificity (e.g., `/users/:id/settings` and `/:type/123/settings`).\n */\nfunction sortBySpecificity(manifest: string[]): string[] {\n return [...manifest].sort((a, b) => {\n const aScore = computeScore(a);\n const bScore = computeScore(b);\n\n return bScore - aScore;\n });\n}\n"],"names":[],"mappings":"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"}
@@ -2,183 +2,102 @@ import { getActiveSpan, getRootSpan, spanToJSON, debug } from '@sentry/core/brow
2
2
  import { DEBUG_BUILD } from '../debug-build.js';
3
3
  import { matchRouteManifest, stripBasenameFromPathname } from './route-manifest.js';
4
4
 
5
- // Global variables that these utilities depend on
6
5
  let _matchRoutes;
7
6
  let _stripBasename = false;
8
-
9
- // Navigation context stack for nested/concurrent patchRoutesOnNavigation calls.
10
- // Required because window.location hasn't updated yet when handlers are invoked.
11
-
12
7
  const _navigationContextStack = [];
13
8
  const MAX_CONTEXT_STACK_SIZE = 10;
14
-
15
- /**
16
- * Pushes a navigation context and returns a unique token for cleanup.
17
- * The token uses object identity for uniqueness (no counter needed).
18
- */
19
9
  function setNavigationContext(targetPath, span) {
20
10
  const token = {};
21
- // Prevent unbounded stack growth - oldest (likely stale) contexts are evicted first
22
11
  if (_navigationContextStack.length >= MAX_CONTEXT_STACK_SIZE) {
23
- DEBUG_BUILD && debug.warn('[React Router] Navigation context stack overflow - removing oldest context');
12
+ DEBUG_BUILD && debug.warn("[React Router] Navigation context stack overflow - removing oldest context");
24
13
  _navigationContextStack.shift();
25
14
  }
26
15
  _navigationContextStack.push({ token, targetPath, span });
27
16
  return token;
28
17
  }
29
-
30
- /**
31
- * Clears the navigation context if it's on top of the stack (LIFO).
32
- * If our context is not on top (out-of-order completion), we leave it -
33
- * it will be cleaned up by overflow protection when the stack fills up.
34
- */
35
18
  function clearNavigationContext(token) {
36
19
  const top = _navigationContextStack[_navigationContextStack.length - 1];
37
20
  if (top?.token === token) {
38
21
  _navigationContextStack.pop();
39
22
  }
40
23
  }
41
-
42
- /** Gets the current (most recent) navigation context if inside a patchRoutesOnNavigation call. */
43
24
  function getNavigationContext() {
44
25
  const length = _navigationContextStack.length;
45
- // The `?? null` converts undefined (from array access) to null to match return type
46
- return length > 0 ? (_navigationContextStack[length - 1] ?? null) : null;
26
+ return length > 0 ? _navigationContextStack[length - 1] ?? null : null;
47
27
  }
48
-
49
- /**
50
- * Initialize function to set dependencies that the router utilities need.
51
- * Must be called before using any of the exported utility functions.
52
- */
53
28
  function initializeRouterUtils(matchRoutes, stripBasename = false) {
54
29
  _matchRoutes = matchRoutes;
55
30
  _stripBasename = stripBasename;
56
31
  }
57
-
58
- // Helper functions
59
32
  function pickPath(match) {
60
- return trimWildcard(match.route.path || '');
33
+ return trimWildcard(match.route.path || "");
61
34
  }
62
-
63
35
  function pickSplat(match) {
64
- return match.params['*'] || '';
36
+ return match.params["*"] || "";
65
37
  }
66
-
67
38
  function trimWildcard(path) {
68
- return path[path.length - 1] === '*' ? path.slice(0, -1) : path;
39
+ return path[path.length - 1] === "*" ? path.slice(0, -1) : path;
69
40
  }
70
-
71
41
  function trimSlash(path) {
72
- return path[path.length - 1] === '/' ? path.slice(0, -1) : path;
42
+ return path[path.length - 1] === "/" ? path.slice(0, -1) : path;
73
43
  }
74
-
75
- /**
76
- * Checks if a path ends with a wildcard character (*).
77
- */
78
44
  function pathEndsWithWildcard(path) {
79
- return path.endsWith('*');
45
+ return path.endsWith("*");
80
46
  }
81
-
82
- /** Checks if transaction name has wildcard (/* or ends with *). */
83
47
  function transactionNameHasWildcard(name) {
84
- return name.includes('/*') || name.endsWith('*');
48
+ return name.includes("/*") || name.endsWith("*");
85
49
  }
86
-
87
- /**
88
- * Checks if a path is a wildcard and has child routes.
89
- */
90
50
  function pathIsWildcardAndHasChildren(path, branch) {
91
- return (pathEndsWithWildcard(path) && !!branch.route.children?.length) || false;
51
+ return pathEndsWithWildcard(path) && !!branch.route.children?.length || false;
92
52
  }
93
-
94
- /** Check if route is in descendant route (<Routes> within <Routes>) */
95
53
  function routeIsDescendant(route) {
96
- return !!(!route.children && route.element && route.path?.endsWith('/*'));
54
+ return !!(!route.children && route.element && route.path?.endsWith("/*"));
97
55
  }
98
-
99
56
  function sendIndexPath(pathBuilder, pathname, basename) {
100
- const reconstructedPath =
101
- pathBuilder && pathBuilder.length > 0
102
- ? pathBuilder
103
- : _stripBasename
104
- ? stripBasenameFromPathname(pathname, basename)
105
- : pathname;
106
-
107
- let formattedPath =
57
+ const reconstructedPath = pathBuilder && pathBuilder.length > 0 ? pathBuilder : _stripBasename ? stripBasenameFromPathname(pathname, basename) : pathname;
58
+ let formattedPath = (
108
59
  // If the path ends with a wildcard suffix, remove both the slash and the asterisk
109
- reconstructedPath.slice(-2) === '/*' ? reconstructedPath.slice(0, -2) : reconstructedPath;
110
-
111
- // If the path ends with a slash, remove it (but keep single '/')
112
- if (formattedPath.length > 1 && formattedPath[formattedPath.length - 1] === '/') {
60
+ reconstructedPath.slice(-2) === "/*" ? reconstructedPath.slice(0, -2) : reconstructedPath
61
+ );
62
+ if (formattedPath.length > 1 && formattedPath[formattedPath.length - 1] === "/") {
113
63
  formattedPath = formattedPath.slice(0, -1);
114
64
  }
115
-
116
- return [formattedPath, 'route'];
65
+ return [formattedPath, "route"];
117
66
  }
118
-
119
- /**
120
- * Returns the number of URL segments in the given URL string.
121
- * Splits at '/' or '\/' to handle regex URLs correctly.
122
- *
123
- * @param url - The URL string to segment.
124
- * @returns The number of segments in the URL.
125
- */
126
67
  function getNumberOfUrlSegments(url) {
127
- // split at '/' or at '\/' to split regex urls correctly
128
- return url.split(/\\?\//).filter(s => s.length > 0 && s !== ',').length;
68
+ return url.split(/\\?\//).filter((s) => s.length > 0 && s !== ",").length;
129
69
  }
130
-
131
- // Exported utility functions
132
-
133
- /**
134
- * Ensures a path string starts with a forward slash.
135
- */
136
70
  function prefixWithSlash(path) {
137
- return path[0] === '/' ? path : `/${path}`;
71
+ return path[0] === "/" ? path : `/${path}`;
138
72
  }
139
-
140
- /**
141
- * Rebuilds the route path from all available routes by matching against the current location.
142
- */
143
73
  function rebuildRoutePathFromAllRoutes(allRoutes, location) {
144
- const matchedRoutes = _matchRoutes(allRoutes, location) ;
145
-
74
+ const matchedRoutes = _matchRoutes(allRoutes, location);
146
75
  if (!matchedRoutes || matchedRoutes.length === 0) {
147
- return '';
76
+ return "";
148
77
  }
149
-
150
78
  for (const match of matchedRoutes) {
151
- if (match.route.path && match.route.path !== '*') {
79
+ if (match.route.path && match.route.path !== "*") {
152
80
  const path = pickPath(match);
153
81
  const strippedPath = stripBasenameFromPathname(location.pathname, prefixWithSlash(match.pathnameBase));
154
-
155
82
  if (location.pathname === strippedPath) {
156
83
  return trimSlash(strippedPath);
157
84
  }
158
-
159
85
  return trimSlash(
160
- trimSlash(path || '') +
161
- prefixWithSlash(
162
- rebuildRoutePathFromAllRoutes(
163
- allRoutes.filter(route => route !== match.route),
164
- {
165
- pathname: strippedPath,
166
- },
167
- ),
168
- ),
86
+ trimSlash(path || "") + prefixWithSlash(
87
+ rebuildRoutePathFromAllRoutes(
88
+ allRoutes.filter((route) => route !== match.route),
89
+ {
90
+ pathname: strippedPath
91
+ }
92
+ )
93
+ )
169
94
  );
170
95
  }
171
96
  }
172
-
173
- return '';
97
+ return "";
174
98
  }
175
-
176
- /**
177
- * Checks if the current location is inside a descendant route (route with splat parameter).
178
- */
179
99
  function locationIsInsideDescendantRoute(location, routes) {
180
- const matchedRoutes = _matchRoutes(routes, location) ;
181
-
100
+ const matchedRoutes = _matchRoutes(routes, location);
182
101
  if (matchedRoutes) {
183
102
  for (const match of matchedRoutes) {
184
103
  if (routeIsDescendant(match.route) && pickSplat(match)) {
@@ -186,134 +105,73 @@ function locationIsInsideDescendantRoute(location, routes) {
186
105
  }
187
106
  }
188
107
  }
189
-
190
108
  return false;
191
109
  }
192
-
193
- /**
194
- * Returns a fallback transaction name from location pathname.
195
- */
196
110
  function getFallbackTransactionName(location, basename) {
197
- return _stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname || '';
111
+ return _stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname || "";
198
112
  }
199
-
200
- /**
201
- * Gets a normalized route name and transaction source from the current routes and location.
202
- */
203
- function getNormalizedName(
204
- routes,
205
- location,
206
- branches,
207
- basename = '',
208
- ) {
113
+ function getNormalizedName(routes, location, branches, basename = "") {
209
114
  if (!routes || routes.length === 0) {
210
- return [_stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname, 'url'];
115
+ return [_stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname, "url"];
211
116
  }
212
-
213
117
  if (!branches) {
214
- return [getFallbackTransactionName(location, basename), 'url'];
118
+ return [getFallbackTransactionName(location, basename), "url"];
215
119
  }
216
-
217
- let pathBuilder = '';
218
-
120
+ let pathBuilder = "";
219
121
  for (const branch of branches) {
220
122
  const route = branch.route;
221
123
  if (!route) {
222
124
  continue;
223
125
  }
224
-
225
- // Early return for index routes
226
126
  if (route.index) {
227
127
  return sendIndexPath(pathBuilder, branch.pathname, basename);
228
128
  }
229
-
230
129
  const path = route.path;
231
130
  if (!path || pathIsWildcardAndHasChildren(path, branch)) {
232
131
  continue;
233
132
  }
234
-
235
- // Build the route path
236
- const newPath = path[0] === '/' || pathBuilder[pathBuilder.length - 1] === '/' ? path : `/${path}`;
133
+ const newPath = path[0] === "/" || pathBuilder[pathBuilder.length - 1] === "/" ? path : `/${path}`;
237
134
  pathBuilder = trimSlash(pathBuilder) + prefixWithSlash(newPath);
238
-
239
- // Check if this path matches the current location
240
135
  if (trimSlash(location.pathname) !== trimSlash(basename + branch.pathname)) {
241
136
  continue;
242
137
  }
243
-
244
- // Check if this is a parameterized route like /stores/:storeId/products/:productId
245
- if (
246
- getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname) &&
247
- !pathEndsWithWildcard(pathBuilder)
248
- ) {
249
- return [(_stripBasename ? '' : basename) + newPath, 'route'];
138
+ if (getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname) && !pathEndsWithWildcard(pathBuilder)) {
139
+ return [(_stripBasename ? "" : basename) + newPath, "route"];
250
140
  }
251
-
252
- // Handle wildcard routes with children - strip trailing wildcard
253
141
  if (pathIsWildcardAndHasChildren(pathBuilder, branch)) {
254
142
  pathBuilder = pathBuilder.slice(0, -1);
255
143
  }
256
-
257
- return [(_stripBasename ? '' : basename) + pathBuilder, 'route'];
144
+ return [(_stripBasename ? "" : basename) + pathBuilder, "route"];
258
145
  }
259
-
260
- // Fallback when no matching route found
261
- return [getFallbackTransactionName(location, basename), 'url'];
146
+ return [getFallbackTransactionName(location, basename), "url"];
262
147
  }
263
-
264
- /**
265
- * Shared helper function to resolve route name and source
266
- */
267
- function resolveRouteNameAndSource(
268
- location,
269
- routes,
270
- allRoutes,
271
- branches,
272
- basename = '',
273
- lazyRouteManifest,
274
- enableAsyncRouteHandlers,
275
- ) {
276
- // When lazy route manifest is provided, use it as the primary source for transaction names
148
+ function resolveRouteNameAndSource(location, routes, allRoutes, branches, basename = "", lazyRouteManifest, enableAsyncRouteHandlers) {
277
149
  if (enableAsyncRouteHandlers && lazyRouteManifest && lazyRouteManifest.length > 0) {
278
150
  const manifestMatch = matchRouteManifest(location.pathname, lazyRouteManifest, basename);
279
151
  if (manifestMatch) {
280
- return [(_stripBasename ? '' : basename) + manifestMatch, 'route'];
152
+ return [(_stripBasename ? "" : basename) + manifestMatch, "route"];
281
153
  }
282
154
  }
283
-
284
- // Fall back to React Router route matching
285
155
  let name;
286
- let source = 'url';
287
-
156
+ let source = "url";
288
157
  const isInDescendantRoute = locationIsInsideDescendantRoute(location, allRoutes);
289
-
290
158
  if (isInDescendantRoute) {
291
159
  name = prefixWithSlash(rebuildRoutePathFromAllRoutes(allRoutes, location));
292
- source = 'route';
160
+ source = "route";
293
161
  }
294
-
295
162
  if (!isInDescendantRoute || !name) {
296
163
  [name, source] = getNormalizedName(routes, location, branches, basename);
297
164
  }
298
-
299
165
  return [name || location.pathname, source];
300
166
  }
301
-
302
- /**
303
- * Gets the active root span if it's a pageload or navigation span.
304
- */
305
167
  function getActiveRootSpan() {
306
168
  const span = getActiveSpan();
307
- const rootSpan = span ? getRootSpan(span) : undefined;
308
-
169
+ const rootSpan = span ? getRootSpan(span) : void 0;
309
170
  if (!rootSpan) {
310
- return undefined;
171
+ return void 0;
311
172
  }
312
-
313
173
  const op = spanToJSON(rootSpan).op;
314
-
315
- // Only use this root span if it is a pageload or navigation span
316
- return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;
174
+ return op === "navigation" || op === "pageload" ? rootSpan : void 0;
317
175
  }
318
176
 
319
177
  export { clearNavigationContext, getActiveRootSpan, getNavigationContext, getNormalizedName, getNumberOfUrlSegments, initializeRouterUtils, locationIsInsideDescendantRoute, pathEndsWithWildcard, pathIsWildcardAndHasChildren, prefixWithSlash, rebuildRoutePathFromAllRoutes, resolveRouteNameAndSource, routeIsDescendant, setNavigationContext, transactionNameHasWildcard };