@sentry/react 11.0.0-alpha.0 → 11.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/profiler.js +12 -15
- package/build/cjs/profiler.js.map +1 -1
- package/build/cjs/reactrouter-compat-utils/instrumentation.js +43 -33
- package/build/cjs/reactrouter-compat-utils/instrumentation.js.map +1 -1
- package/build/cjs/reactrouter-compat-utils/utils.js +2 -1
- package/build/cjs/reactrouter-compat-utils/utils.js.map +1 -1
- package/build/cjs/reactrouter.js +8 -6
- package/build/cjs/reactrouter.js.map +1 -1
- package/build/cjs/reactrouterv3.js +6 -4
- package/build/cjs/reactrouterv3.js.map +1 -1
- package/build/cjs/tanstackrouter.js +20 -9
- package/build/cjs/tanstackrouter.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/profiler.js +14 -17
- package/build/esm/profiler.js.map +1 -1
- package/build/esm/reactrouter-compat-utils/instrumentation.js +45 -35
- package/build/esm/reactrouter-compat-utils/instrumentation.js.map +1 -1
- package/build/esm/reactrouter-compat-utils/utils.js +2 -1
- package/build/esm/reactrouter-compat-utils/utils.js.map +1 -1
- package/build/esm/reactrouter.js +10 -8
- package/build/esm/reactrouter.js.map +1 -1
- package/build/esm/reactrouterv3.js +8 -6
- package/build/esm/reactrouterv3.js.map +1 -1
- package/build/esm/tanstackrouter.js +23 -12
- package/build/esm/tanstackrouter.js.map +1 -1
- package/build/types/profiler.d.ts.map +1 -1
- package/build/types/reactrouter-compat-utils/instrumentation.d.ts.map +1 -1
- package/build/types/reactrouter-compat-utils/utils.d.ts.map +1 -1
- package/build/types/reactrouter.d.ts.map +1 -1
- package/build/types/reactrouterv3.d.ts.map +1 -1
- package/build/types/tanstackrouter.d.ts.map +1 -1
- package/build/types/vendor/tanstackrouter-types.d.ts +1 -0
- package/build/types/vendor/tanstackrouter-types.d.ts.map +1 -1
- package/package.json +5 -4
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { WINDOW, browserTracingIntegration, startBrowserTracingPageLoadSpan, startBrowserTracingNavigationSpan } from '@sentry/browser';
|
|
2
|
-
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP,
|
|
2
|
+
import { PAGELOAD_SPAN_NAME_FALLBACK, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, hasSpanStreamingEnabled, debug, addNonEnumerableProperty, spanToJSON, getCurrentScope, getClient, NAVIGATION_SPAN_NAME_FALLBACK } from '@sentry/core';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { DEBUG_BUILD } from '../debug-build.js';
|
|
5
5
|
import { hoistNonReactStatics } from '../hoist-non-react-statics.js';
|
|
6
6
|
import { checkRouteForAsyncHandler } from './lazy-routes.js';
|
|
7
7
|
import { getActiveRootSpan, setNavigationContext, clearNavigationContext, resolveRouteNameAndSource, transactionNameHasWildcard, initializeRouterUtils } from './utils.js';
|
|
8
|
-
import { URL_TEMPLATE } from '@sentry/conventions/attributes';
|
|
8
|
+
import { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP, URL_TEMPLATE } from '@sentry/conventions/attributes';
|
|
9
9
|
|
|
10
10
|
let _useEffect;
|
|
11
11
|
let _useLocation;
|
|
@@ -112,12 +112,12 @@ function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = nu
|
|
|
112
112
|
}
|
|
113
113
|
const targetSpan = capturedSpan ?? getActiveRootSpan();
|
|
114
114
|
if (targetSpan) {
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
115
|
+
const { end_timestamp, attributes } = spanToJSON(targetSpan);
|
|
116
|
+
if (end_timestamp) {
|
|
117
117
|
DEBUG_BUILD && debug.warn("[React Router] Lazy handler resolved after span ended - skipping update");
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
|
-
const spanOp =
|
|
120
|
+
const spanOp = attributes[SENTRY_OP];
|
|
121
121
|
let location = currentLocation;
|
|
122
122
|
if (!location && !capturedSpan) {
|
|
123
123
|
if (typeof WINDOW !== "undefined") {
|
|
@@ -142,12 +142,11 @@ function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = nu
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false, matchRoutes) {
|
|
145
|
-
const
|
|
146
|
-
const currentName = spanJson.description;
|
|
145
|
+
const { name: currentName, end_timestamp, attributes } = spanToJSON(activeRootSpan);
|
|
147
146
|
const hasBeenNamed = activeRootSpan?.__sentry_navigation_name_set__;
|
|
148
147
|
const currentNameHasWildcard = currentName && transactionNameHasWildcard(currentName);
|
|
149
148
|
const shouldUpdate = !hasBeenNamed || forceUpdate || currentNameHasWildcard;
|
|
150
|
-
if (shouldUpdate && !
|
|
149
|
+
if (shouldUpdate && !end_timestamp) {
|
|
151
150
|
const currentBranches = matchRoutes(allRoutes2, location);
|
|
152
151
|
const [name, source] = resolveRouteNameAndSource(
|
|
153
152
|
location,
|
|
@@ -158,14 +157,16 @@ function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate
|
|
|
158
157
|
_lazyRouteManifest,
|
|
159
158
|
_enableAsyncRouteHandlers
|
|
160
159
|
);
|
|
161
|
-
const currentSource =
|
|
160
|
+
const currentSource = attributes[SENTRY_SEGMENT_NAME_SOURCE];
|
|
162
161
|
const isImprovement = name && (!currentName || // No current name - always set
|
|
163
162
|
!hasBeenNamed && (currentSource !== "route" || source === "route") || // Not finalized - allow unless downgrading route→url
|
|
164
163
|
currentSource !== "route" && source === "route" || // URL → route upgrade
|
|
165
164
|
currentSource === "route" && source === "route" && currentNameHasWildcard);
|
|
166
165
|
if (isImprovement) {
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
const client = getClient();
|
|
167
|
+
const isUnparameterizedStreamedNavigation = source !== "route" && !!client && hasSpanStreamingEnabled(client);
|
|
168
|
+
activeRootSpan.updateName(isUnparameterizedStreamedNavigation ? NAVIGATION_SPAN_NAME_FALLBACK : name);
|
|
169
|
+
activeRootSpan.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, source);
|
|
169
170
|
if (source === "route") {
|
|
170
171
|
activeRootSpan.setAttribute(URL_TEMPLATE, name);
|
|
171
172
|
}
|
|
@@ -177,14 +178,14 @@ function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate
|
|
|
177
178
|
}
|
|
178
179
|
function setupRouterSubscription(router, routes, version, basename, activeRootSpan) {
|
|
179
180
|
let isInitialPageloadComplete = false;
|
|
180
|
-
let hasSeenPageloadSpan = !!activeRootSpan && spanToJSON(activeRootSpan).
|
|
181
|
+
let hasSeenPageloadSpan = !!activeRootSpan && spanToJSON(activeRootSpan).attributes[SENTRY_OP] === "pageload";
|
|
181
182
|
let hasSeenPopAfterPageload = false;
|
|
182
183
|
let scheduledNavigationHandler = null;
|
|
183
184
|
let lastHandledPathname = null;
|
|
184
185
|
router.subscribe((state) => {
|
|
185
186
|
if (!isInitialPageloadComplete) {
|
|
186
187
|
const currentRootSpan = getActiveRootSpan();
|
|
187
|
-
const isCurrentlyInPageload = currentRootSpan && spanToJSON(currentRootSpan).
|
|
188
|
+
const isCurrentlyInPageload = currentRootSpan && spanToJSON(currentRootSpan).attributes[SENTRY_OP] === "pageload";
|
|
188
189
|
if (isCurrentlyInPageload) {
|
|
189
190
|
hasSeenPageloadSpan = true;
|
|
190
191
|
} else if (hasSeenPageloadSpan) {
|
|
@@ -370,9 +371,11 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
|
|
|
370
371
|
const initPathName = WINDOW.location?.pathname;
|
|
371
372
|
if (instrumentPageLoad && initPathName) {
|
|
372
373
|
startBrowserTracingPageLoadSpan(client, {
|
|
373
|
-
|
|
374
|
+
// With span streaming, span names have to be low cardinality. The route is only resolved
|
|
375
|
+
// once the router renders, which updates the span name then.
|
|
376
|
+
name: hasSpanStreamingEnabled(client) ? PAGELOAD_SPAN_NAME_FALLBACK : initPathName,
|
|
374
377
|
attributes: {
|
|
375
|
-
[
|
|
378
|
+
[SENTRY_SEGMENT_NAME_SOURCE]: "url",
|
|
376
379
|
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: "pageload",
|
|
377
380
|
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.pageload.react.reactrouter${version ? `_v${version}` : ""}`
|
|
378
381
|
}
|
|
@@ -460,8 +463,8 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
460
463
|
}
|
|
461
464
|
}
|
|
462
465
|
const spanJson = activeRootSpan ? spanToJSON(activeRootSpan) : void 0;
|
|
463
|
-
if (targetPath && activeRootSpan && spanJson && !spanJson.
|
|
464
|
-
spanJson.
|
|
466
|
+
if (targetPath && activeRootSpan && spanJson && !spanJson.end_timestamp && // Span hasn't ended yet
|
|
467
|
+
spanJson.attributes[SENTRY_OP] === "navigation") {
|
|
465
468
|
updateNavigationSpan(
|
|
466
469
|
activeRootSpan,
|
|
467
470
|
{ pathname: targetPath, search: "", hash: "", state: null, key: "default" },
|
|
@@ -486,8 +489,8 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
|
|
|
486
489
|
}
|
|
487
490
|
}
|
|
488
491
|
const spanJson = activeRootSpan ? spanToJSON(activeRootSpan) : void 0;
|
|
489
|
-
if (activeRootSpan && spanJson && !spanJson.
|
|
490
|
-
spanJson.
|
|
492
|
+
if (activeRootSpan && spanJson && !spanJson.end_timestamp && // Span hasn't ended yet
|
|
493
|
+
spanJson.attributes[SENTRY_OP] === "navigation") {
|
|
491
494
|
const pathname = targetPath;
|
|
492
495
|
if (pathname) {
|
|
493
496
|
updateNavigationSpan(
|
|
@@ -516,7 +519,7 @@ function handleNavigation(opts) {
|
|
|
516
519
|
return;
|
|
517
520
|
}
|
|
518
521
|
const activeRootSpan = getActiveRootSpan();
|
|
519
|
-
if (activeRootSpan && spanToJSON(activeRootSpan).
|
|
522
|
+
if (activeRootSpan && spanToJSON(activeRootSpan).attributes[SENTRY_OP] === "pageload" && navigationType === "POP") {
|
|
520
523
|
return;
|
|
521
524
|
}
|
|
522
525
|
if ((navigationType === "PUSH" || navigationType === "POP") && branches) {
|
|
@@ -531,7 +534,7 @@ function handleNavigation(opts) {
|
|
|
531
534
|
);
|
|
532
535
|
const locationKey = computeLocationKey(location);
|
|
533
536
|
const trackedNav = activeNavigationSpans.get(client);
|
|
534
|
-
const trackedSpanHasEnded = trackedNav && !trackedNav.isPlaceholder ? !!spanToJSON(trackedNav.span).
|
|
537
|
+
const trackedSpanHasEnded = trackedNav && !trackedNav.isPlaceholder ? !!spanToJSON(trackedNav.span).end_timestamp : false;
|
|
535
538
|
const { skip, shouldUpdate } = shouldSkipNavigation(trackedNav, locationKey, name, trackedSpanHasEnded);
|
|
536
539
|
if (skip) {
|
|
537
540
|
if (shouldUpdate && trackedNav) {
|
|
@@ -542,8 +545,9 @@ function handleNavigation(opts) {
|
|
|
542
545
|
`[Tracing] Updated placeholder navigation name from "${oldName}" to "${name}" (will apply to real span)`
|
|
543
546
|
);
|
|
544
547
|
} else {
|
|
545
|
-
|
|
546
|
-
trackedNav.span.
|
|
548
|
+
const isUnparameterizedStreamedNavigation = source !== "route" && hasSpanStreamingEnabled(client);
|
|
549
|
+
trackedNav.span.updateName(isUnparameterizedStreamedNavigation ? NAVIGATION_SPAN_NAME_FALLBACK : name);
|
|
550
|
+
trackedNav.span.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, source);
|
|
547
551
|
if (source === "route") {
|
|
548
552
|
trackedNav.span.setAttribute(URL_TEMPLATE, name);
|
|
549
553
|
}
|
|
@@ -569,10 +573,11 @@ function handleNavigation(opts) {
|
|
|
569
573
|
let navigationSpan;
|
|
570
574
|
try {
|
|
571
575
|
navigationSpan = startBrowserTracingNavigationSpan(client, {
|
|
572
|
-
|
|
573
|
-
//
|
|
576
|
+
// Use placeholder's routeName in case it was updated. With span streaming, span names have to
|
|
577
|
+
// be low cardinality, so we can't fall back to the URL.
|
|
578
|
+
name: source === "route" || !hasSpanStreamingEnabled(client) ? placeholderEntry.routeName : NAVIGATION_SPAN_NAME_FALLBACK,
|
|
574
579
|
attributes: {
|
|
575
|
-
[
|
|
580
|
+
[SENTRY_SEGMENT_NAME_SOURCE]: source,
|
|
576
581
|
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
|
|
577
582
|
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.navigation.react.reactrouter${version ? `_v${version}` : ""}`,
|
|
578
583
|
...source === "route" && { [URL_TEMPLATE]: placeholderEntry.routeName }
|
|
@@ -647,8 +652,10 @@ function updatePageloadTransaction({
|
|
|
647
652
|
);
|
|
648
653
|
getCurrentScope().setTransactionName(name || "/");
|
|
649
654
|
if (activeRootSpan) {
|
|
650
|
-
|
|
651
|
-
|
|
655
|
+
const client = getClient();
|
|
656
|
+
const isUnparameterizedStreamedPageload = source !== "route" && !!client && hasSpanStreamingEnabled(client);
|
|
657
|
+
activeRootSpan.updateName(isUnparameterizedStreamedPageload ? PAGELOAD_SPAN_NAME_FALLBACK : name);
|
|
658
|
+
activeRootSpan.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, source);
|
|
652
659
|
if (source === "route") {
|
|
653
660
|
activeRootSpan.setAttribute(URL_TEMPLATE, name);
|
|
654
661
|
}
|
|
@@ -676,7 +683,7 @@ function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSo
|
|
|
676
683
|
}
|
|
677
684
|
function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutes2) {
|
|
678
685
|
try {
|
|
679
|
-
const currentSource = spanJson.
|
|
686
|
+
const currentSource = spanJson.attributes[SENTRY_SEGMENT_NAME_SOURCE];
|
|
680
687
|
if (currentSource === "route" && currentName && !transactionNameHasWildcard(currentName)) {
|
|
681
688
|
return;
|
|
682
689
|
}
|
|
@@ -696,10 +703,13 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
|
|
|
696
703
|
_enableAsyncRouteHandlers
|
|
697
704
|
);
|
|
698
705
|
const isImprovement = shouldUpdateWildcardSpanName(currentName, currentSource, name, source, true);
|
|
699
|
-
const spanNotEnded = spanType === "pageload" || !spanJson.
|
|
706
|
+
const spanNotEnded = spanType === "pageload" || !spanJson.end_timestamp;
|
|
700
707
|
if (isImprovement && spanNotEnded) {
|
|
701
|
-
|
|
702
|
-
|
|
708
|
+
const client = getClient();
|
|
709
|
+
const isUnparameterizedStreamedSpan = source !== "route" && !!client && hasSpanStreamingEnabled(client);
|
|
710
|
+
const fallbackName = spanType === "pageload" ? PAGELOAD_SPAN_NAME_FALLBACK : NAVIGATION_SPAN_NAME_FALLBACK;
|
|
711
|
+
span.updateName(isUnparameterizedStreamedSpan ? fallbackName : name);
|
|
712
|
+
span.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, source);
|
|
703
713
|
if (source === "route") {
|
|
704
714
|
span.setAttribute(URL_TEMPLATE, name);
|
|
705
715
|
}
|
|
@@ -723,8 +733,8 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
723
733
|
endCalled = true;
|
|
724
734
|
const endTimestamp = args.length > 0 ? args[0] : Date.now() / 1e3;
|
|
725
735
|
const spanJson = spanToJSON(span);
|
|
726
|
-
const currentName = spanJson.
|
|
727
|
-
const currentSource = spanJson.
|
|
736
|
+
const currentName = spanJson.name;
|
|
737
|
+
const currentSource = spanJson.attributes[SENTRY_SEGMENT_NAME_SOURCE];
|
|
728
738
|
const cleanupNavigationSpan = () => {
|
|
729
739
|
const client = getClient();
|
|
730
740
|
if (client && spanType === "navigation") {
|
|
@@ -759,7 +769,7 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
|
|
|
759
769
|
tryUpdateSpanNameBeforeEnd(
|
|
760
770
|
span,
|
|
761
771
|
updatedSpanJson,
|
|
762
|
-
updatedSpanJson.
|
|
772
|
+
updatedSpanJson.name,
|
|
763
773
|
location,
|
|
764
774
|
routes,
|
|
765
775
|
basename,
|