|
1 | 1 | /* eslint-disable max-lines */ |
2 | | -import type { Client, IntegrationFn, RequestHookInfo, ResponseHookInfo, Span, StartSpanOptions } from '@sentry/core'; |
| 2 | +import type { |
| 3 | + Client, |
| 4 | + Integration, |
| 5 | + IntegrationFn, |
| 6 | + RequestHookInfo, |
| 7 | + ResponseHookInfo, |
| 8 | + Span, |
| 9 | + StartSpanOptions, |
| 10 | +} from '@sentry/core'; |
3 | 11 | import { |
4 | 12 | addNonEnumerableProperty, |
5 | 13 | consoleSandbox, |
@@ -39,7 +47,7 @@ import { DEBUG_BUILD } from '../debug-build'; |
39 | 47 | import { filterCollectedUrl } from '@sentry/core'; |
40 | 48 | import { getHttpRequestData, WINDOW } from '../helpers'; |
41 | 49 | import type { WebVitalsOptions } from '../integrations/webVitals'; |
42 | | -import { WEB_VITALS_INTEGRATION_NAME, webVitalsIntegration } from '../integrations/webVitals'; |
| 50 | +import { webVitalsIntegration } from '../integrations/webVitals'; |
43 | 51 | import { registerBackgroundTabDetection } from './backgroundtab'; |
44 | 52 | import { linkTraces } from './linkedTraces'; |
45 | 53 | import { defaultRequestInstrumentationOptions, instrumentOutgoingRequests } from './request'; |
@@ -274,16 +282,20 @@ export interface BrowserTracingOptions { |
274 | 282 | onRequestSpanEnd?(span: Span, responseInformation: ResponseHookInfo): void; |
275 | 283 | } |
276 | 284 |
|
277 | | -const DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingOptions = { |
| 285 | +/** |
| 286 | + * Options for `browserTracingCoreIntegration`: the options of `browserTracingIntegration`, minus the ones |
| 287 | + * for features that `browserTracingIntegration` registers as standalone integrations. |
| 288 | + */ |
| 289 | +export type BrowserTracingCoreOptions = Omit<BrowserTracingOptions, 'enableInp' | 'webVitals' | 'enableElementTiming'>; |
| 290 | + |
| 291 | +const DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingCoreOptions = { |
278 | 292 | ...TRACING_DEFAULTS, |
279 | 293 | instrumentNavigation: true, |
280 | 294 | instrumentBfcacheRestore: true, |
281 | 295 | instrumentPageLoad: true, |
282 | 296 | markBackgroundSpan: true, |
283 | 297 | enableLongTask: true, |
284 | 298 | enableLongAnimationFrame: true, |
285 | | - // oxlint-disable-next-line typescript/no-deprecated -- still honoured until it is removed |
286 | | - enableInp: true, |
287 | 299 | ignoreResourceSpans: [], |
288 | 300 | detectRedirects: true, |
289 | 301 | linkPreviousTrace: 'in-memory', |
@@ -311,18 +323,48 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption |
311 | 323 | }); |
312 | 324 | } |
313 | 325 |
|
| 326 | + // oxlint-disable-next-line typescript/no-deprecated -- still honoured until it is removed |
| 327 | + const { enableInp = true, webVitals } = options; |
| 328 | + |
| 329 | + return _browserTracingIntegration(options, client => { |
| 330 | + // Custom clients and test doubles may not implement it. |
| 331 | + if (!client.addIntegration) { |
| 332 | + return; |
| 333 | + } |
| 334 | + |
| 335 | + const ignore = webVitals?.ignore ?? []; |
| 336 | + client.addIntegration( |
| 337 | + webVitalsIntegration({ |
| 338 | + ...webVitals, |
| 339 | + ignore: enableInp || ignore.includes('inp') ? ignore : [...ignore, 'inp'], |
| 340 | + }), |
| 341 | + ); |
| 342 | + }); |
| 343 | +}) satisfies IntegrationFn; |
| 344 | + |
| 345 | +/** |
| 346 | + * The pageload and navigation spans of `browserTracingIntegration`, without the features it registers as |
| 347 | + * standalone integrations (such as `webVitalsIntegration`). |
| 348 | + * |
| 349 | + * Use it instead of `browserTracingIntegration` to only bundle the integrations you add yourself. |
| 350 | + */ |
| 351 | +export const browserTracingCoreIntegration = ((options: Partial<BrowserTracingCoreOptions> = {}) => |
| 352 | + _browserTracingIntegration(options)) satisfies IntegrationFn; |
| 353 | + |
| 354 | +function _browserTracingIntegration( |
| 355 | + options: Partial<BrowserTracingCoreOptions>, |
| 356 | + // Runs before the pageload span starts, so the integrations it adds can hook into it. |
| 357 | + addDefaultIntegrations?: (client: Client) => void, |
| 358 | +) { |
314 | 359 | /** |
315 | 360 | * This is just a small wrapper that makes `document` optional. |
316 | 361 | * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up. |
317 | 362 | */ |
318 | 363 | const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined; |
319 | 364 |
|
320 | 365 | const { |
321 | | - // oxlint-disable-next-line typescript/no-deprecated -- still honoured until it is removed |
322 | | - enableInp, |
323 | 366 | enableLongTask, |
324 | 367 | enableLongAnimationFrame, |
325 | | - webVitals, |
326 | 368 | beforeStartSpan, |
327 | 369 | idleTimeout, |
328 | 370 | finalTimeout, |
@@ -619,18 +661,9 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption |
619 | 661 | // purely rely on manual startSpan calls. |
620 | 662 | _INTERNAL_ensureBrowserSpanStreaming(client); |
621 | 663 |
|
622 | | - // Auto-register webVitalsIntegration if the user hasn't added one. We do this in |
623 | | - // afterAllSetup so that a user-provided webVitalsIntegration - which may be ordered after |
624 | | - // browserTracingIntegration in the integrations array - has already been installed. |
625 | | - if (client.addIntegration && !client.getIntegrationByName?.(WEB_VITALS_INTEGRATION_NAME)) { |
626 | | - const ignore = webVitals?.ignore ?? []; |
627 | | - client.addIntegration( |
628 | | - webVitalsIntegration({ |
629 | | - ...webVitals, |
630 | | - ignore: enableInp || ignore.includes('inp') ? ignore : [...ignore, 'inp'], |
631 | | - }), |
632 | | - ); |
633 | | - } |
| 664 | + // This runs in afterAllSetup so that integrations the user added themselves, which may be |
| 665 | + // ordered after this one in the integrations array, are already installed. `addIntegration` skips those. |
| 666 | + addDefaultIntegrations?.(client); |
634 | 667 |
|
635 | 668 | let startingUrl: string | undefined = getLocationHref(); |
636 | 669 |
|
@@ -747,8 +780,8 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption |
747 | 780 | onRequestSpanEnd, |
748 | 781 | }); |
749 | 782 | }, |
750 | | - }; |
751 | | -}) satisfies IntegrationFn; |
| 783 | + } satisfies Integration; |
| 784 | +} |
752 | 785 |
|
753 | 786 | /** |
754 | 787 | * Manually start a page load span. |
|
0 commit comments