{"version":3,"file":"browserTracingIntegration.js","sources":["../../../../../src/tracing/browserTracingIntegration.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport type {\n Client,\n IntegrationFn,\n RequestHookInfo,\n ResponseHookInfo,\n Span,\n StartSpanOptions,\n TransactionSource,\n} from '@sentry/core';\nimport {\n addNonEnumerableProperty,\n browserPerformanceTimeOrigin,\n dateTimestampInSeconds,\n debug,\n generateSpanId,\n generateTraceId,\n getClient,\n getCurrentScope,\n getDynamicSamplingContextFromSpan,\n getIsolationScope,\n getLocationHref,\n GLOBAL_OBJ,\n hasSpansEnabled,\n parseStringToURLObject,\n propagationContextFromHeaders,\n registerSpanErrorInstrumentation,\n SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanIsSampled,\n spanToJSON,\n startIdleSpan,\n startInactiveSpan,\n timestampInSeconds,\n TRACING_DEFAULTS,\n} from '@sentry/core';\nimport {\n addHistoryInstrumentationHandler,\n addPerformanceEntries,\n registerInpInteractionListener,\n startTrackingElementTiming,\n startTrackingINP,\n startTrackingInteractions,\n startTrackingLongAnimationFrames,\n startTrackingLongTasks,\n startTrackingWebVitals,\n} from '@sentry-internal/browser-utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { getHttpRequestData, WINDOW } from '../helpers';\nimport { registerBackgroundTabDetection } from './backgroundtab';\nimport { linkTraces } from './linkedTraces';\nimport { defaultRequestInstrumentationOptions, instrumentOutgoingRequests } from './request';\n\nexport const BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';\n\ninterface RouteInfo {\n name: string | undefined;\n source: TransactionSource | undefined;\n}\n\n/** Options for Browser Tracing integration */\nexport interface BrowserTracingOptions {\n /**\n * The time that has to pass without any span being created.\n * If this time is exceeded, the idle span will finish.\n *\n * Default: 1000 (ms)\n */\n idleTimeout: number;\n\n /**\n * The max. time an idle span may run.\n * If this time is exceeded, the idle span will finish no matter what.\n *\n * Default: 30000 (ms)\n */\n finalTimeout: number;\n\n /**\n The max. time an idle span may run.\n * If this time is exceeded, the idle span will finish no matter what.\n *\n * Default: 15000 (ms)\n */\n childSpanTimeout: number;\n\n /**\n * If a span should be created on page load.\n * If this is set to `false`, this integration will not start the default page load span.\n * Default: true\n */\n instrumentPageLoad: boolean;\n\n /**\n * If a span should be created on navigation (history change).\n * If this is set to `false`, this integration will not start the default navigation spans.\n * Default: true\n */\n instrumentNavigation: boolean;\n\n /**\n * Flag spans where tabs moved to background with \"cancelled\". Browser background tab timing is\n * not suited towards doing precise measurements of operations. By default, we recommend that this option\n * be enabled as background transactions can mess up your statistics in nondeterministic ways.\n *\n * Default: true\n */\n markBackgroundSpan: boolean;\n\n /**\n * If true, Sentry will capture long tasks and add them to the corresponding transaction.\n *\n * Default: true\n */\n enableLongTask: boolean;\n\n /**\n * If true, Sentry will capture long animation frames and add them to the corresponding transaction.\n *\n * Default: false\n */\n enableLongAnimationFrame: boolean;\n\n /**\n * If true, Sentry will capture first input delay and add it to the corresponding transaction.\n *\n * Default: true\n */\n enableInp: boolean;\n\n /**\n * If true, Sentry will capture [element timing](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceElementTiming)\n * information and add it to the corresponding transaction.\n *\n * Default: true\n */\n enableElementTiming: boolean;\n\n /**\n * Flag to disable patching all together for fetch requests.\n *\n * Default: true\n */\n traceFetch: boolean;\n\n /**\n * Flag to disable patching all together for xhr requests.\n *\n * Default: true\n */\n traceXHR: boolean;\n\n /**\n * Flag to disable tracking of long-lived streams, like server-sent events (SSE) via fetch.\n * Do not enable this in case you have live streams or very long running streams.\n *\n * Default: false\n */\n trackFetchStreamPerformance: boolean;\n\n /**\n * If true, Sentry will capture http timings and add them to the corresponding http spans.\n *\n * Default: true\n */\n enableHTTPTimings: boolean;\n\n /**\n * Resource spans with `op`s matching strings in the array will not be emitted.\n *\n * Default: []\n */\n ignoreResourceSpans: Array<'resouce.script' | 'resource.css' | 'resource.img' | 'resource.other' | string>;\n\n /**\n * Spans created from the following browser Performance APIs,\n *\n * - [`performance.mark(...)`](https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark)\n * - [`performance.measure(...)`](https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure)\n *\n * will not be emitted if their names match strings in this array.\n *\n * This is useful, if you come across `mark` or `measure` spans in your Sentry traces\n * that you want to ignore. For example, sometimes, browser extensions or libraries\n * emit these entries on their own, which might not be relevant to your application.\n *\n * * @example\n * ```ts\n * Sentry.init({\n * integrations: [\n * Sentry.browserTracingIntegration({\n * ignorePerformanceApiSpans: ['myMeasurement', /myMark/],\n * }),\n * ],\n * });\n *\n * // no spans will be created for these:\n * performance.mark('myMark');\n * performance.measure('myMeasurement');\n *\n * // spans will be created for these:\n * performance.mark('authenticated');\n * performance.measure('input-duration', ...);\n * ```\n *\n * Default: [] - By default, all `mark` and `measure` entries are sent as spans.\n */\n ignorePerformanceApiSpans: Array;\n\n /**\n * By default, the SDK will try to detect redirects and avoid creating separate spans for them.\n * If you want to opt-out of this behavior, you can set this option to `false`.\n *\n * Default: true\n */\n detectRedirects: boolean;\n\n /**\n * Link the currently started trace to a previous trace (e.g. a prior pageload, navigation or\n * manually started span). When enabled, this option will allow you to navigate between traces\n * in the Sentry UI.\n *\n * You can set this option to the following values:\n *\n * - `'in-memory'`: The previous trace data will be stored in memory.\n * This is useful for single-page applications and enabled by default.\n *\n * - `'session-storage'`: The previous trace data will be stored in the `sessionStorage`.\n * This is useful for multi-page applications or static sites but it means that the\n * Sentry SDK writes to the browser's `sessionStorage`.\n *\n * - `'off'`: The previous trace data will not be stored or linked.\n *\n * You can also use {@link BrowserTracingOptions.consistentTraceSampling} to get\n * consistent trace sampling of subsequent traces. Otherwise, by default, your\n * `tracesSampleRate` or `tracesSampler` config significantly influences how often\n * traces will be linked.\n *\n * @default 'in-memory' - see explanation above\n */\n linkPreviousTrace: 'in-memory' | 'session-storage' | 'off';\n\n /**\n * If true, Sentry will consistently sample subsequent traces based on the\n * sampling decision of the initial trace. For example, if the initial page\n * load trace was sampled positively, all subsequent traces (e.g. navigations)\n * are also sampled positively. In case the initial trace was sampled negatively,\n * all subsequent traces are also sampled negatively.\n *\n * This option allows you to get consistent, linked traces within a user journey\n * while maintaining an overall quota based on your trace sampling settings.\n *\n * This option is only effective if {@link BrowserTracingOptions.linkPreviousTrace}\n * is enabled (i.e. not set to `'off'`).\n *\n * @default `false` - this is an opt-in feature.\n */\n consistentTraceSampling: boolean;\n\n /**\n * If set to `true`, the pageload span will not end itself automatically, unless it\n * runs until the {@link BrowserTracingOptions.finalTimeout} (30 seconds by default) is reached.\n *\n * Set this option to `true`, if you want full control over the pageload span duration.\n * You can use `Sentry.reportPageLoaded()` to manually end the pageload span whenever convenient.\n * Be aware that you have to ensure that this is always called, regardless of the chosen route\n * or path in the application.\n *\n * @default `false`. By default, the pageload span will end itself automatically, based on\n * the {@link BrowserTracingOptions.finalTimeout}, {@link BrowserTracingOptions.idleTimeout}\n * and {@link BrowserTracingOptions.childSpanTimeout}. This is more convenient to use but means\n * that the pageload duration can be arbitrary and might not be fully representative of a perceived\n * page load time.\n */\n enableReportPageLoaded: boolean;\n\n /**\n * _experiments allows the user to send options to define how this integration works.\n *\n * Default: undefined\n */\n _experiments: Partial<{\n enableInteractions: boolean;\n enableStandaloneClsSpans: boolean;\n enableStandaloneLcpSpans: boolean;\n }>;\n\n /**\n * A callback which is called before a span for a pageload or navigation is started.\n * It receives the options passed to `startSpan`, and expects to return an updated options object.\n */\n beforeStartSpan?: (options: StartSpanOptions) => StartSpanOptions;\n\n /**\n * This function will be called before creating a span for a request with the given url.\n * Return false if you don't want a span for the given url.\n *\n * Default: (url: string) => true\n */\n shouldCreateSpanForRequest?(this: void, url: string): boolean;\n\n /**\n * This callback is invoked directly after a span is started for an outgoing fetch or XHR request.\n * You can use it to annotate the span with additional data or attributes, for example by setting\n * attributes based on the passed request headers.\n */\n onRequestSpanStart?(span: Span, requestInformation: RequestHookInfo): void;\n\n /**\n * Is called when spans end for outgoing requests, providing access to response headers.\n */\n onRequestSpanEnd?(span: Span, responseInformation: ResponseHookInfo): void;\n}\n\nconst DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingOptions = {\n ...TRACING_DEFAULTS,\n instrumentNavigation: true,\n instrumentPageLoad: true,\n markBackgroundSpan: true,\n enableLongTask: true,\n enableLongAnimationFrame: true,\n enableInp: true,\n enableElementTiming: true,\n ignoreResourceSpans: [],\n ignorePerformanceApiSpans: [],\n detectRedirects: true,\n linkPreviousTrace: 'in-memory',\n consistentTraceSampling: false,\n enableReportPageLoaded: false,\n _experiments: {},\n ...defaultRequestInstrumentationOptions,\n};\n\n/**\n * The Browser Tracing integration automatically instruments browser pageload/navigation\n * actions as transactions, and captures requests, metrics and errors as spans.\n *\n * The integration can be configured with a variety of options, and can be extended to use\n * any routing library.\n *\n * We explicitly export the proper type here, as this has to be extended in some cases.\n */\nexport const browserTracingIntegration = ((options: Partial = {}) => {\n const latestRoute: RouteInfo = {\n name: undefined,\n source: undefined,\n };\n\n /**\n * This is just a small wrapper that makes `document` optional.\n * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.\n */\n const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined;\n\n const {\n enableInp,\n enableElementTiming,\n enableLongTask,\n enableLongAnimationFrame,\n _experiments: { enableInteractions, enableStandaloneClsSpans, enableStandaloneLcpSpans },\n beforeStartSpan,\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n markBackgroundSpan,\n traceFetch,\n traceXHR,\n trackFetchStreamPerformance,\n shouldCreateSpanForRequest,\n enableHTTPTimings,\n ignoreResourceSpans,\n ignorePerformanceApiSpans,\n instrumentPageLoad,\n instrumentNavigation,\n detectRedirects,\n linkPreviousTrace,\n consistentTraceSampling,\n enableReportPageLoaded,\n onRequestSpanStart,\n onRequestSpanEnd,\n } = {\n ...DEFAULT_BROWSER_TRACING_OPTIONS,\n ...options,\n };\n\n let _collectWebVitals: undefined | (() => void);\n let lastInteractionTimestamp: number | undefined;\n\n let _pageloadSpan: Span | undefined;\n\n /** Create routing idle transaction. */\n function _createRouteSpan(client: Client, startSpanOptions: StartSpanOptions, makeActive = true): void {\n const isPageloadSpan = startSpanOptions.op === 'pageload';\n\n const initialSpanName = startSpanOptions.name;\n const finalStartSpanOptions: StartSpanOptions = beforeStartSpan\n ? beforeStartSpan(startSpanOptions)\n : startSpanOptions;\n\n const attributes = finalStartSpanOptions.attributes || {};\n\n // If `finalStartSpanOptions.name` is different than `startSpanOptions.name`\n // it is because `beforeStartSpan` set a custom name. Therefore we set the source to 'custom'.\n if (initialSpanName !== finalStartSpanOptions.name) {\n attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'custom';\n finalStartSpanOptions.attributes = attributes;\n }\n\n if (!makeActive) {\n // We want to ensure this has 0s duration\n const now = dateTimestampInSeconds();\n startInactiveSpan({\n ...finalStartSpanOptions,\n startTime: now,\n }).end(now);\n return;\n }\n\n latestRoute.name = finalStartSpanOptions.name;\n latestRoute.source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n\n const idleSpan = startIdleSpan(finalStartSpanOptions, {\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n // should wait for finish signal if it's a pageload transaction\n disableAutoFinish: isPageloadSpan,\n beforeSpanEnd: span => {\n // This will generally always be defined here, because it is set in `setup()` of the integration\n // but technically, it is optional, so we guard here to be extra safe\n _collectWebVitals?.();\n addPerformanceEntries(span, {\n recordClsOnPageloadSpan: !enableStandaloneClsSpans,\n recordLcpOnPageloadSpan: !enableStandaloneLcpSpans,\n ignoreResourceSpans,\n ignorePerformanceApiSpans,\n });\n setActiveIdleSpan(client, undefined);\n\n // A trace should stay consistent over the entire timespan of one route - even after the pageload/navigation ended.\n // Only when another navigation happens, we want to create a new trace.\n // This way, e.g. errors that occur after the pageload span ended are still associated to the pageload trace.\n const scope = getCurrentScope();\n const oldPropagationContext = scope.getPropagationContext();\n\n scope.setPropagationContext({\n ...oldPropagationContext,\n traceId: idleSpan.spanContext().traceId,\n sampled: spanIsSampled(idleSpan),\n dsc: getDynamicSamplingContextFromSpan(span),\n });\n\n if (isPageloadSpan) {\n // clean up the stored pageload span on the intergration.\n _pageloadSpan = undefined;\n }\n },\n trimIdleSpanEndTimestamp: !enableReportPageLoaded,\n });\n\n if (isPageloadSpan && enableReportPageLoaded) {\n _pageloadSpan = idleSpan;\n }\n\n setActiveIdleSpan(client, idleSpan);\n\n function emitFinish(): void {\n if (optionalWindowDocument && ['interactive', 'complete'].includes(optionalWindowDocument.readyState)) {\n client.emit('idleSpanEnableAutoFinish', idleSpan);\n }\n }\n\n // Enable auto finish of the pageload span if users are not explicitly ending it\n if (isPageloadSpan && !enableReportPageLoaded && optionalWindowDocument) {\n optionalWindowDocument.addEventListener('readystatechange', () => {\n emitFinish();\n });\n\n emitFinish();\n }\n }\n\n return {\n name: BROWSER_TRACING_INTEGRATION_ID,\n setup(client) {\n registerSpanErrorInstrumentation();\n\n _collectWebVitals = startTrackingWebVitals({\n recordClsStandaloneSpans: enableStandaloneClsSpans || false,\n recordLcpStandaloneSpans: enableStandaloneLcpSpans || false,\n client,\n });\n\n if (enableInp) {\n startTrackingINP();\n }\n\n if (enableElementTiming) {\n startTrackingElementTiming();\n }\n\n if (\n enableLongAnimationFrame &&\n GLOBAL_OBJ.PerformanceObserver &&\n PerformanceObserver.supportedEntryTypes &&\n PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')\n ) {\n startTrackingLongAnimationFrames();\n } else if (enableLongTask) {\n startTrackingLongTasks();\n }\n\n if (enableInteractions) {\n startTrackingInteractions();\n }\n\n if (detectRedirects && optionalWindowDocument) {\n const interactionHandler = (): void => {\n lastInteractionTimestamp = timestampInSeconds();\n };\n addEventListener('click', interactionHandler, { capture: true });\n addEventListener('keydown', interactionHandler, { capture: true, passive: true });\n }\n\n function maybeEndActiveSpan(): void {\n const activeSpan = getActiveIdleSpan(client);\n\n if (activeSpan && !spanToJSON(activeSpan).timestamp) {\n DEBUG_BUILD && debug.log(`[Tracing] Finishing current active span with op: ${spanToJSON(activeSpan).op}`);\n // If there's an open active span, we need to finish it before creating an new one.\n activeSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, 'cancelled');\n activeSpan.end();\n }\n }\n\n client.on('startNavigationSpan', (startSpanOptions, navigationOptions) => {\n if (getClient() !== client) {\n return;\n }\n\n if (navigationOptions?.isRedirect) {\n DEBUG_BUILD &&\n debug.warn('[Tracing] Detected redirect, navigation span will not be the root span, but a child span.');\n _createRouteSpan(\n client,\n {\n op: 'navigation.redirect',\n ...startSpanOptions,\n },\n false,\n );\n return;\n }\n\n // Reset the last interaction timestamp since we now start a new navigation.\n // Any subsequent navigation span starts could again be a redirect, so we\n // should reset our heuristic detectors.\n lastInteractionTimestamp = undefined;\n\n maybeEndActiveSpan();\n\n getIsolationScope().setPropagationContext({\n traceId: generateTraceId(),\n sampleRand: Math.random(),\n propagationSpanId: hasSpansEnabled() ? undefined : generateSpanId(),\n });\n\n const scope = getCurrentScope();\n scope.setPropagationContext({\n traceId: generateTraceId(),\n sampleRand: Math.random(),\n propagationSpanId: hasSpansEnabled() ? undefined : generateSpanId(),\n });\n\n // We reset this to ensure we do not have lingering incorrect data here\n // places that call this hook may set this where appropriate - else, the URL at span sending time is used\n scope.setSDKProcessingMetadata({\n normalizedRequest: undefined,\n });\n\n _createRouteSpan(client, {\n op: 'navigation',\n ...startSpanOptions,\n // Navigation starts a new trace and is NOT parented under any active interaction (e.g. ui.action.click)\n parentSpan: null,\n forceTransaction: true,\n });\n });\n\n client.on('startPageLoadSpan', (startSpanOptions, traceOptions = {}) => {\n if (getClient() !== client) {\n return;\n }\n maybeEndActiveSpan();\n\n const sentryTrace =\n traceOptions.sentryTrace || getMetaContent('sentry-trace') || getServerTiming('sentry-trace');\n const baggage = traceOptions.baggage || getMetaContent('baggage') || getServerTiming('baggage');\n\n const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);\n\n const scope = getCurrentScope();\n scope.setPropagationContext(propagationContext);\n if (!hasSpansEnabled()) {\n // for browser, we wanna keep the spanIds consistent during the entire lifetime of the trace\n // this works by setting the propagationSpanId to a random spanId so that we have a consistent\n // span id to propagate in TwP mode (!hasSpansEnabled())\n scope.getPropagationContext().propagationSpanId = generateSpanId();\n }\n\n // We store the normalized request data on the scope, so we get the request data at time of span creation\n // otherwise, the URL etc. may already be of the following navigation, and we'd report the wrong URL\n scope.setSDKProcessingMetadata({\n normalizedRequest: getHttpRequestData(),\n });\n\n _createRouteSpan(client, {\n op: 'pageload',\n ...startSpanOptions,\n });\n });\n\n client.on('endPageloadSpan', () => {\n if (enableReportPageLoaded && _pageloadSpan) {\n _pageloadSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, 'reportPageLoaded');\n _pageloadSpan.end();\n }\n });\n },\n\n afterAllSetup(client) {\n let startingUrl: string | undefined = getLocationHref();\n\n if (linkPreviousTrace !== 'off') {\n linkTraces(client, { linkPreviousTrace, consistentTraceSampling });\n }\n\n if (WINDOW.location) {\n if (instrumentPageLoad) {\n const origin = browserPerformanceTimeOrigin();\n startBrowserTracingPageLoadSpan(client, {\n name: WINDOW.location.pathname,\n // pageload should always start at timeOrigin (and needs to be in s, not ms)\n startTime: origin ? origin / 1000 : undefined,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser',\n },\n });\n }\n\n if (instrumentNavigation) {\n addHistoryInstrumentationHandler(({ to, from }) => {\n /**\n * This early return is there to account for some cases where a navigation transaction starts right after\n * long-running pageload. We make sure that if `from` is undefined and a valid `startingURL` exists, we don't\n * create an uneccessary navigation transaction.\n *\n * This was hard to duplicate, but this behavior stopped as soon as this fix was applied. This issue might also\n * only be caused in certain development environments where the usage of a hot module reloader is causing\n * errors.\n */\n if (from === undefined && startingUrl?.indexOf(to) !== -1) {\n startingUrl = undefined;\n return;\n }\n\n startingUrl = undefined;\n const parsed = parseStringToURLObject(to);\n const activeSpan = getActiveIdleSpan(client);\n const navigationIsRedirect =\n activeSpan && detectRedirects && isRedirect(activeSpan, lastInteractionTimestamp);\n\n startBrowserTracingNavigationSpan(\n client,\n {\n name: parsed?.pathname || WINDOW.location.pathname,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.browser',\n },\n },\n { url: to, isRedirect: navigationIsRedirect },\n );\n });\n }\n }\n\n if (markBackgroundSpan) {\n registerBackgroundTabDetection();\n }\n\n if (enableInteractions) {\n registerInteractionListener(client, idleTimeout, finalTimeout, childSpanTimeout, latestRoute);\n }\n\n if (enableInp) {\n registerInpInteractionListener();\n }\n\n instrumentOutgoingRequests(client, {\n traceFetch,\n traceXHR,\n trackFetchStreamPerformance,\n tracePropagationTargets: client.getOptions().tracePropagationTargets,\n shouldCreateSpanForRequest,\n enableHTTPTimings,\n onRequestSpanStart,\n onRequestSpanEnd,\n });\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Manually start a page load span.\n * This will only do something if a browser tracing integration integration has been setup.\n *\n * If you provide a custom `traceOptions` object, it will be used to continue the trace\n * instead of the default behavior, which is to look it up on the tags.\n */\nexport function startBrowserTracingPageLoadSpan(\n client: Client,\n spanOptions: StartSpanOptions,\n traceOptions?: { sentryTrace?: string | undefined; baggage?: string | undefined },\n): Span | undefined {\n client.emit('startPageLoadSpan', spanOptions, traceOptions);\n getCurrentScope().setTransactionName(spanOptions.name);\n\n const pageloadSpan = getActiveIdleSpan(client);\n\n if (pageloadSpan) {\n client.emit('afterStartPageLoadSpan', pageloadSpan);\n }\n\n return pageloadSpan;\n}\n\n/**\n * Manually start a navigation span.\n * This will only do something if a browser tracing integration has been setup.\n */\nexport function startBrowserTracingNavigationSpan(\n client: Client,\n spanOptions: StartSpanOptions,\n options?: { url?: string; isRedirect?: boolean },\n): Span | undefined {\n const { url, isRedirect } = options || {};\n client.emit('beforeStartNavigationSpan', spanOptions, { isRedirect });\n client.emit('startNavigationSpan', spanOptions, { isRedirect });\n\n const scope = getCurrentScope();\n scope.setTransactionName(spanOptions.name);\n\n // We store the normalized request data on the scope, so we get the request data at time of span creation\n // otherwise, the URL etc. may already be of the following navigation, and we'd report the wrong URL\n if (url && !isRedirect) {\n scope.setSDKProcessingMetadata({\n normalizedRequest: {\n ...getHttpRequestData(),\n url,\n },\n });\n }\n\n return getActiveIdleSpan(client);\n}\n\n/** Returns the value of a meta tag */\nexport function getMetaContent(metaName: string): string | undefined {\n /**\n * This is just a small wrapper that makes `document` optional.\n * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.\n */\n const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined;\n\n const metaTag = optionalWindowDocument?.querySelector(`meta[name=${metaName}]`);\n return metaTag?.getAttribute('content') || undefined;\n}\n\n/** Returns the description of a server timing entry */\nexport function getServerTiming(name: string): string | undefined {\n const navigation = WINDOW.performance?.getEntriesByType?.('navigation')[0] as PerformanceNavigationTiming | undefined;\n const entry = navigation?.serverTiming?.find(entry => entry.name === name);\n return entry?.description;\n}\n\n/** Start listener for interaction transactions */\nfunction registerInteractionListener(\n client: Client,\n idleTimeout: BrowserTracingOptions['idleTimeout'],\n finalTimeout: BrowserTracingOptions['finalTimeout'],\n childSpanTimeout: BrowserTracingOptions['childSpanTimeout'],\n latestRoute: RouteInfo,\n): void {\n /**\n * This is just a small wrapper that makes `document` optional.\n * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.\n */\n const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined;\n\n let inflightInteractionSpan: Span | undefined;\n const registerInteractionTransaction = (): void => {\n const op = 'ui.action.click';\n\n const activeIdleSpan = getActiveIdleSpan(client);\n if (activeIdleSpan) {\n const currentRootSpanOp = spanToJSON(activeIdleSpan).op;\n if (['navigation', 'pageload'].includes(currentRootSpanOp as string)) {\n DEBUG_BUILD &&\n debug.warn(`[Tracing] Did not create ${op} span because a pageload or navigation span is in progress.`);\n return undefined;\n }\n }\n\n if (inflightInteractionSpan) {\n inflightInteractionSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, 'interactionInterrupted');\n inflightInteractionSpan.end();\n inflightInteractionSpan = undefined;\n }\n\n if (!latestRoute.name) {\n DEBUG_BUILD && debug.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`);\n return undefined;\n }\n\n inflightInteractionSpan = startIdleSpan(\n {\n name: latestRoute.name,\n op,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: latestRoute.source || 'url',\n },\n },\n {\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n },\n );\n };\n\n if (optionalWindowDocument) {\n addEventListener('click', registerInteractionTransaction, { capture: true });\n }\n}\n\n// We store the active idle span on the client object, so we can access it from exported functions\nconst ACTIVE_IDLE_SPAN_PROPERTY = '_sentry_idleSpan';\nfunction getActiveIdleSpan(client: Client): Span | undefined {\n return (client as { [ACTIVE_IDLE_SPAN_PROPERTY]?: Span })[ACTIVE_IDLE_SPAN_PROPERTY];\n}\n\nfunction setActiveIdleSpan(client: Client, span: Span | undefined): void {\n addNonEnumerableProperty(client, ACTIVE_IDLE_SPAN_PROPERTY, span);\n}\n\n// The max. time in seconds between two pageload/navigation spans that makes us consider the second one a redirect\nconst REDIRECT_THRESHOLD = 1.5;\n\nfunction isRedirect(activeSpan: Span, lastInteractionTimestamp: number | undefined): boolean {\n const spanData = spanToJSON(activeSpan);\n\n const now = dateTimestampInSeconds();\n\n // More than REDIRECT_THRESHOLD seconds since last navigation/pageload span?\n // --> never consider this a redirect\n const startTimestamp = spanData.start_timestamp;\n if (now - startTimestamp > REDIRECT_THRESHOLD) {\n return false;\n }\n\n // A click happened in the last REDIRECT_THRESHOLD seconds?\n // --> never consider this a redirect\n if (lastInteractionTimestamp && now - lastInteractionTimestamp <= REDIRECT_THRESHOLD) {\n return false;\n }\n\n return true;\n}\n"],"names":["TRACING_DEFAULTS","defaultRequestInstrumentationOptions","WINDOW","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","dateTimestampInSeconds","startInactiveSpan","startIdleSpan","addPerformanceEntries","getCurrentScope","spanIsSampled","getDynamicSamplingContextFromSpan","registerSpanErrorInstrumentation","startTrackingWebVitals","startTrackingINP","startTrackingElementTiming","GLOBAL_OBJ","startTrackingLongAnimationFrames","startTrackingLongTasks","startTrackingInteractions","timestampInSeconds","spanToJSON","DEBUG_BUILD","debug","SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON","getClient","getIsolationScope","generateTraceId","hasSpansEnabled","generateSpanId","propagationContextFromHeaders","getHttpRequestData","getLocationHref","linkTraces","browserPerformanceTimeOrigin","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","addHistoryInstrumentationHandler","parseStringToURLObject","registerBackgroundTabDetection","registerInpInteractionListener","instrumentOutgoingRequests","addNonEnumerableProperty"],"mappings":"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"}