@sentry/browser 10.37.0 → 10.39.0-alpha.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 (167) hide show
  1. package/build/npm/cjs/dev/client.js +7 -0
  2. package/build/npm/cjs/dev/client.js.map +1 -1
  3. package/build/npm/cjs/dev/index.js +21 -16
  4. package/build/npm/cjs/dev/index.js.map +1 -1
  5. package/build/npm/cjs/dev/integrations/browsersession.js +13 -9
  6. package/build/npm/cjs/dev/integrations/browsersession.js.map +1 -1
  7. package/build/npm/cjs/dev/integrations/culturecontext.js +64 -0
  8. package/build/npm/cjs/dev/integrations/culturecontext.js.map +1 -0
  9. package/build/npm/cjs/dev/integrations/httpcontext.js +25 -1
  10. package/build/npm/cjs/dev/integrations/httpcontext.js.map +1 -1
  11. package/build/npm/cjs/dev/integrations/spanstreaming.js +87 -0
  12. package/build/npm/cjs/dev/integrations/spanstreaming.js.map +1 -0
  13. package/build/npm/cjs/dev/integrations/spotlight.js +5 -4
  14. package/build/npm/cjs/dev/integrations/spotlight.js.map +1 -1
  15. package/build/npm/cjs/dev/integrations/webWorker.js +31 -2
  16. package/build/npm/cjs/dev/integrations/webWorker.js.map +1 -1
  17. package/build/npm/cjs/dev/profiling/UIProfiler.js +10 -0
  18. package/build/npm/cjs/dev/profiling/UIProfiler.js.map +1 -1
  19. package/build/npm/cjs/dev/profiling/integration.js +10 -0
  20. package/build/npm/cjs/dev/profiling/integration.js.map +1 -1
  21. package/build/npm/cjs/dev/sdk.js +2 -0
  22. package/build/npm/cjs/dev/sdk.js.map +1 -1
  23. package/build/npm/cjs/dev/tracing/browserTracingIntegration.js +18 -11
  24. package/build/npm/cjs/dev/tracing/browserTracingIntegration.js.map +1 -1
  25. package/build/npm/cjs/dev/tracing/linkedTraces.js +1 -0
  26. package/build/npm/cjs/dev/tracing/linkedTraces.js.map +1 -1
  27. package/build/npm/cjs/dev/tracing/request.js +1 -0
  28. package/build/npm/cjs/dev/tracing/request.js.map +1 -1
  29. package/build/npm/cjs/prod/client.js +7 -0
  30. package/build/npm/cjs/prod/client.js.map +1 -1
  31. package/build/npm/cjs/prod/index.js +21 -16
  32. package/build/npm/cjs/prod/index.js.map +1 -1
  33. package/build/npm/cjs/prod/integrations/browsersession.js +13 -9
  34. package/build/npm/cjs/prod/integrations/browsersession.js.map +1 -1
  35. package/build/npm/cjs/prod/integrations/culturecontext.js +64 -0
  36. package/build/npm/cjs/prod/integrations/culturecontext.js.map +1 -0
  37. package/build/npm/cjs/prod/integrations/httpcontext.js +25 -1
  38. package/build/npm/cjs/prod/integrations/httpcontext.js.map +1 -1
  39. package/build/npm/cjs/prod/integrations/spanstreaming.js +87 -0
  40. package/build/npm/cjs/prod/integrations/spanstreaming.js.map +1 -0
  41. package/build/npm/cjs/prod/integrations/spotlight.js +5 -4
  42. package/build/npm/cjs/prod/integrations/spotlight.js.map +1 -1
  43. package/build/npm/cjs/prod/integrations/webWorker.js +31 -2
  44. package/build/npm/cjs/prod/integrations/webWorker.js.map +1 -1
  45. package/build/npm/cjs/prod/profiling/UIProfiler.js +10 -0
  46. package/build/npm/cjs/prod/profiling/UIProfiler.js.map +1 -1
  47. package/build/npm/cjs/prod/profiling/integration.js +10 -0
  48. package/build/npm/cjs/prod/profiling/integration.js.map +1 -1
  49. package/build/npm/cjs/prod/sdk.js +2 -0
  50. package/build/npm/cjs/prod/sdk.js.map +1 -1
  51. package/build/npm/cjs/prod/tracing/browserTracingIntegration.js +18 -11
  52. package/build/npm/cjs/prod/tracing/browserTracingIntegration.js.map +1 -1
  53. package/build/npm/cjs/prod/tracing/linkedTraces.js +1 -0
  54. package/build/npm/cjs/prod/tracing/linkedTraces.js.map +1 -1
  55. package/build/npm/cjs/prod/tracing/request.js +1 -0
  56. package/build/npm/cjs/prod/tracing/request.js.map +1 -1
  57. package/build/npm/esm/dev/client.js +7 -0
  58. package/build/npm/esm/dev/client.js.map +1 -1
  59. package/build/npm/esm/dev/index.js +4 -2
  60. package/build/npm/esm/dev/index.js.map +1 -1
  61. package/build/npm/esm/dev/integrations/browsersession.js +13 -9
  62. package/build/npm/esm/dev/integrations/browsersession.js.map +1 -1
  63. package/build/npm/esm/dev/integrations/culturecontext.js +62 -0
  64. package/build/npm/esm/dev/integrations/culturecontext.js.map +1 -0
  65. package/build/npm/esm/dev/integrations/httpcontext.js +26 -2
  66. package/build/npm/esm/dev/integrations/httpcontext.js.map +1 -1
  67. package/build/npm/esm/dev/integrations/spanstreaming.js +85 -0
  68. package/build/npm/esm/dev/integrations/spanstreaming.js.map +1 -0
  69. package/build/npm/esm/dev/integrations/spotlight.js +5 -4
  70. package/build/npm/esm/dev/integrations/spotlight.js.map +1 -1
  71. package/build/npm/esm/dev/integrations/webWorker.js +32 -3
  72. package/build/npm/esm/dev/integrations/webWorker.js.map +1 -1
  73. package/build/npm/esm/dev/package.json +1 -1
  74. package/build/npm/esm/dev/profiling/UIProfiler.js +10 -0
  75. package/build/npm/esm/dev/profiling/UIProfiler.js.map +1 -1
  76. package/build/npm/esm/dev/profiling/integration.js +10 -0
  77. package/build/npm/esm/dev/profiling/integration.js.map +1 -1
  78. package/build/npm/esm/dev/sdk.js +2 -0
  79. package/build/npm/esm/dev/sdk.js.map +1 -1
  80. package/build/npm/esm/dev/tracing/browserTracingIntegration.js +19 -13
  81. package/build/npm/esm/dev/tracing/browserTracingIntegration.js.map +1 -1
  82. package/build/npm/esm/dev/tracing/linkedTraces.js +1 -0
  83. package/build/npm/esm/dev/tracing/linkedTraces.js.map +1 -1
  84. package/build/npm/esm/dev/tracing/request.js +2 -1
  85. package/build/npm/esm/dev/tracing/request.js.map +1 -1
  86. package/build/npm/esm/prod/client.js +7 -0
  87. package/build/npm/esm/prod/client.js.map +1 -1
  88. package/build/npm/esm/prod/index.js +4 -2
  89. package/build/npm/esm/prod/index.js.map +1 -1
  90. package/build/npm/esm/prod/integrations/browsersession.js +13 -9
  91. package/build/npm/esm/prod/integrations/browsersession.js.map +1 -1
  92. package/build/npm/esm/prod/integrations/culturecontext.js +62 -0
  93. package/build/npm/esm/prod/integrations/culturecontext.js.map +1 -0
  94. package/build/npm/esm/prod/integrations/httpcontext.js +26 -2
  95. package/build/npm/esm/prod/integrations/httpcontext.js.map +1 -1
  96. package/build/npm/esm/prod/integrations/spanstreaming.js +85 -0
  97. package/build/npm/esm/prod/integrations/spanstreaming.js.map +1 -0
  98. package/build/npm/esm/prod/integrations/spotlight.js +5 -4
  99. package/build/npm/esm/prod/integrations/spotlight.js.map +1 -1
  100. package/build/npm/esm/prod/integrations/webWorker.js +32 -3
  101. package/build/npm/esm/prod/integrations/webWorker.js.map +1 -1
  102. package/build/npm/esm/prod/package.json +1 -1
  103. package/build/npm/esm/prod/profiling/UIProfiler.js +10 -0
  104. package/build/npm/esm/prod/profiling/UIProfiler.js.map +1 -1
  105. package/build/npm/esm/prod/profiling/integration.js +10 -0
  106. package/build/npm/esm/prod/profiling/integration.js.map +1 -1
  107. package/build/npm/esm/prod/sdk.js +2 -0
  108. package/build/npm/esm/prod/sdk.js.map +1 -1
  109. package/build/npm/esm/prod/tracing/browserTracingIntegration.js +19 -13
  110. package/build/npm/esm/prod/tracing/browserTracingIntegration.js.map +1 -1
  111. package/build/npm/esm/prod/tracing/linkedTraces.js +1 -0
  112. package/build/npm/esm/prod/tracing/linkedTraces.js.map +1 -1
  113. package/build/npm/esm/prod/tracing/request.js +2 -1
  114. package/build/npm/esm/prod/tracing/request.js.map +1 -1
  115. package/build/npm/types/client.d.ts.map +1 -1
  116. package/build/npm/types/exports.d.ts +1 -0
  117. package/build/npm/types/exports.d.ts.map +1 -1
  118. package/build/npm/types/index.bundle.logs.metrics.d.ts +5 -0
  119. package/build/npm/types/index.bundle.logs.metrics.d.ts.map +1 -0
  120. package/build/npm/types/index.bundle.replay.logs.metrics.d.ts +6 -0
  121. package/build/npm/types/index.bundle.replay.logs.metrics.d.ts.map +1 -0
  122. package/build/npm/types/index.bundle.tracing.d.ts +2 -1
  123. package/build/npm/types/index.bundle.tracing.d.ts.map +1 -1
  124. package/build/npm/types/index.bundle.tracing.logs.metrics.d.ts +2 -1
  125. package/build/npm/types/index.bundle.tracing.logs.metrics.d.ts.map +1 -1
  126. package/build/npm/types/index.bundle.tracing.replay.d.ts +2 -1
  127. package/build/npm/types/index.bundle.tracing.replay.d.ts.map +1 -1
  128. package/build/npm/types/index.bundle.tracing.replay.feedback.d.ts +2 -1
  129. package/build/npm/types/index.bundle.tracing.replay.feedback.d.ts.map +1 -1
  130. package/build/npm/types/index.bundle.tracing.replay.feedback.logs.metrics.d.ts +2 -1
  131. package/build/npm/types/index.bundle.tracing.replay.feedback.logs.metrics.d.ts.map +1 -1
  132. package/build/npm/types/index.bundle.tracing.replay.logs.metrics.d.ts +11 -0
  133. package/build/npm/types/index.bundle.tracing.replay.logs.metrics.d.ts.map +1 -0
  134. package/build/npm/types/index.d.ts +3 -2
  135. package/build/npm/types/index.d.ts.map +1 -1
  136. package/build/npm/types/integrations/browsersession.d.ts +16 -1
  137. package/build/npm/types/integrations/browsersession.d.ts.map +1 -1
  138. package/build/npm/types/integrations/culturecontext.d.ts +16 -0
  139. package/build/npm/types/integrations/culturecontext.d.ts.map +1 -0
  140. package/build/npm/types/integrations/httpcontext.d.ts.map +1 -1
  141. package/build/npm/types/integrations/spanstreaming.d.ts +5 -0
  142. package/build/npm/types/integrations/spanstreaming.d.ts.map +1 -0
  143. package/build/npm/types/integrations/spotlight.d.ts.map +1 -1
  144. package/build/npm/types/integrations/webWorker.d.ts.map +1 -1
  145. package/build/npm/types/profiling/UIProfiler.d.ts +4 -0
  146. package/build/npm/types/profiling/UIProfiler.d.ts.map +1 -1
  147. package/build/npm/types/profiling/integration.d.ts.map +1 -1
  148. package/build/npm/types/sdk.d.ts.map +1 -1
  149. package/build/npm/types/tracing/browserTracingIntegration.d.ts +10 -0
  150. package/build/npm/types/tracing/browserTracingIntegration.d.ts.map +1 -1
  151. package/build/npm/types/tracing/request.d.ts.map +1 -1
  152. package/build/npm/types-ts3.8/exports.d.ts +1 -0
  153. package/build/npm/types-ts3.8/index.bundle.logs.metrics.d.ts +5 -0
  154. package/build/npm/types-ts3.8/index.bundle.replay.logs.metrics.d.ts +6 -0
  155. package/build/npm/types-ts3.8/index.bundle.tracing.d.ts +2 -1
  156. package/build/npm/types-ts3.8/index.bundle.tracing.logs.metrics.d.ts +2 -1
  157. package/build/npm/types-ts3.8/index.bundle.tracing.replay.d.ts +2 -1
  158. package/build/npm/types-ts3.8/index.bundle.tracing.replay.feedback.d.ts +2 -1
  159. package/build/npm/types-ts3.8/index.bundle.tracing.replay.feedback.logs.metrics.d.ts +2 -1
  160. package/build/npm/types-ts3.8/index.bundle.tracing.replay.logs.metrics.d.ts +11 -0
  161. package/build/npm/types-ts3.8/index.d.ts +3 -2
  162. package/build/npm/types-ts3.8/integrations/browsersession.d.ts +16 -1
  163. package/build/npm/types-ts3.8/integrations/culturecontext.d.ts +16 -0
  164. package/build/npm/types-ts3.8/integrations/spanstreaming.d.ts +5 -0
  165. package/build/npm/types-ts3.8/profiling/UIProfiler.d.ts +4 -0
  166. package/build/npm/types-ts3.8/tracing/browserTracingIntegration.d.ts +10 -0
  167. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"webWorker.js","sources":["../../../../../src/integrations/webWorker.ts"],"sourcesContent":["import type { Integration, IntegrationFn } from '@sentry/core';\nimport { captureEvent, debug, defineIntegration, getClient, isPlainObject, isPrimitive } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { eventFromUnknownInput } from '../eventbuilder';\nimport { WINDOW } from '../helpers';\nimport { _eventFromRejectionWithPrimitive, _getUnhandledRejectionError } from './globalhandlers';\n\nexport const INTEGRATION_NAME = 'WebWorker';\n\ninterface WebWorkerMessage {\n _sentryMessage: boolean;\n _sentryDebugIds?: Record<string, string>;\n _sentryModuleMetadata?: Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n _sentryWorkerError?: SerializedWorkerError;\n}\n\ninterface SerializedWorkerError {\n reason: unknown;\n filename?: string;\n}\n\ninterface WebWorkerIntegrationOptions {\n worker: Worker | Array<Worker>;\n}\n\ninterface WebWorkerIntegration extends Integration {\n addWorker: (worker: Worker) => void;\n}\n\n/**\n * Use this integration to set up Sentry with web workers.\n *\n * IMPORTANT: This integration must be added **before** you start listening to\n * any messages from the worker. Otherwise, your message handlers will receive\n * messages from the Sentry SDK which you need to ignore.\n *\n * This integration only has an effect, if you call `Sentry.registerWebWorker(self)`\n * from within the worker(s) you're adding to the integration.\n *\n * Given that you want to initialize the SDK as early as possible, you most likely\n * want to add this integration **after** initializing the SDK:\n *\n * @example:\n * ```ts filename={main.js}\n * import * as Sentry from '@sentry/<your-sdk>';\n *\n * // some time earlier:\n * Sentry.init(...)\n *\n * // 1. Initialize the worker\n * const worker = new Worker(new URL('./worker.ts', import.meta.url));\n *\n * // 2. Add the integration\n * const webWorkerIntegration = Sentry.webWorkerIntegration({ worker });\n * Sentry.addIntegration(webWorkerIntegration);\n *\n * // 3. Register message listeners on the worker\n * worker.addEventListener('message', event => {\n * // ...\n * });\n * ```\n *\n * If you initialize multiple workers at the same time, you can also pass an array of workers\n * to the integration:\n *\n * ```ts filename={main.js}\n * const webWorkerIntegration = Sentry.webWorkerIntegration({ worker: [worker1, worker2] });\n * Sentry.addIntegration(webWorkerIntegration);\n * ```\n *\n * If you have any additional workers that you initialize at a later point,\n * you can add them to the integration as follows:\n *\n * ```ts filename={main.js}\n * const webWorkerIntegration = Sentry.webWorkerIntegration({ worker: worker1 });\n * Sentry.addIntegration(webWorkerIntegration);\n *\n * // sometime later:\n * webWorkerIntegration.addWorker(worker2);\n * ```\n *\n * Of course, you can also directly add the integration in Sentry.init:\n * ```ts filename={main.js}\n * import * as Sentry from '@sentry/<your-sdk>';\n *\n * // 1. Initialize the worker\n * const worker = new Worker(new URL('./worker.ts', import.meta.url));\n *\n * // 2. Initialize the SDK\n * Sentry.init({\n * integrations: [Sentry.webWorkerIntegration({ worker })]\n * });\n *\n * // 3. Register message listeners on the worker\n * worker.addEventListener('message', event => {\n * // ...\n * });\n * ```\n *\n * @param options {WebWorkerIntegrationOptions} Integration options:\n * - `worker`: The worker instance.\n */\nexport const webWorkerIntegration = defineIntegration(({ worker }: WebWorkerIntegrationOptions) => ({\n name: INTEGRATION_NAME,\n setupOnce: () => {\n (Array.isArray(worker) ? worker : [worker]).forEach(w => listenForSentryMessages(w));\n },\n addWorker: (worker: Worker) => listenForSentryMessages(worker),\n})) as IntegrationFn<WebWorkerIntegration>;\n\nfunction listenForSentryMessages(worker: Worker): void {\n worker.addEventListener('message', event => {\n if (isSentryMessage(event.data)) {\n event.stopImmediatePropagation(); // other listeners should not receive this message\n\n // Handle debug IDs\n if (event.data._sentryDebugIds) {\n DEBUG_BUILD && debug.log('Sentry debugId web worker message received', event.data);\n WINDOW._sentryDebugIds = {\n ...event.data._sentryDebugIds,\n // debugIds of the main thread have precedence over the worker's in case of a collision.\n ...WINDOW._sentryDebugIds,\n };\n }\n\n // Handle module metadata\n if (event.data._sentryModuleMetadata) {\n DEBUG_BUILD && debug.log('Sentry module metadata web worker message received', event.data);\n // Merge worker's raw metadata into the global object\n // It will be parsed lazily when needed by getMetadataForUrl\n WINDOW._sentryModuleMetadata = {\n ...event.data._sentryModuleMetadata,\n // Module metadata of the main thread have precedence over the worker's in case of a collision.\n ...WINDOW._sentryModuleMetadata,\n };\n }\n\n // Handle unhandled rejections forwarded from worker\n if (event.data._sentryWorkerError) {\n DEBUG_BUILD && debug.log('Sentry worker rejection message received', event.data._sentryWorkerError);\n handleForwardedWorkerRejection(event.data._sentryWorkerError);\n }\n }\n });\n}\n\nfunction handleForwardedWorkerRejection(workerError: SerializedWorkerError): void {\n const client = getClient();\n if (!client) {\n return;\n }\n\n const stackParser = client.getOptions().stackParser;\n const attachStacktrace = client.getOptions().attachStacktrace;\n\n const error = workerError.reason;\n\n // Follow same pattern as globalHandlers for unhandledrejection\n // Handle both primitives and errors the same way\n const event = isPrimitive(error)\n ? _eventFromRejectionWithPrimitive(error)\n : eventFromUnknownInput(stackParser, error, undefined, attachStacktrace, true);\n\n event.level = 'error';\n\n // Add worker-specific context\n if (workerError.filename) {\n event.contexts = {\n ...event.contexts,\n worker: {\n filename: workerError.filename,\n },\n };\n }\n\n captureEvent(event, {\n originalException: error,\n mechanism: {\n handled: false,\n type: 'auto.browser.web_worker.onunhandledrejection',\n },\n });\n\n DEBUG_BUILD && debug.log('Captured worker unhandled rejection', error);\n}\n\n/**\n * Minimal interface for DedicatedWorkerGlobalScope, only requiring the postMessage method.\n * (which is the only thing we need from the worker's global object)\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope\n *\n * We can't use the actual type because it breaks everyone who doesn't have {\"lib\": [\"WebWorker\"]}\n * but uses {\"skipLibCheck\": true} in their tsconfig.json.\n */\ninterface MinimalDedicatedWorkerGlobalScope {\n postMessage: (message: unknown) => void;\n addEventListener: (type: string, listener: (event: unknown) => void) => void;\n location?: { href?: string };\n}\n\ninterface RegisterWebWorkerOptions {\n self: MinimalDedicatedWorkerGlobalScope & {\n _sentryDebugIds?: Record<string, string>;\n _sentryModuleMetadata?: Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n };\n}\n\n/**\n * Use this function to register the worker with the Sentry SDK.\n *\n * This function will:\n * - Send debug IDs to the parent thread\n * - Send module metadata to the parent thread (for thirdPartyErrorFilterIntegration)\n * - Set up a handler for unhandled rejections in the worker\n * - Forward unhandled rejections to the parent thread for capture\n *\n * Note: Synchronous errors in workers are already captured by globalHandlers.\n * This only handles unhandled promise rejections which don't bubble to the parent.\n *\n * @example\n * ```ts filename={worker.js}\n * import * as Sentry from '@sentry/<your-sdk>';\n *\n * // Do this as early as possible in your worker.\n * Sentry.registerWebWorker({ self });\n *\n * // continue setting up your worker\n * self.postMessage(...)\n * ```\n * @param options {RegisterWebWorkerOptions} Integration options:\n * - `self`: The worker instance you're calling this function from (self).\n */\nexport function registerWebWorker({ self }: RegisterWebWorkerOptions): void {\n // Send debug IDs and raw module metadata to parent thread\n // The metadata will be parsed lazily on the main thread when needed\n self.postMessage({\n _sentryMessage: true,\n _sentryDebugIds: self._sentryDebugIds ?? undefined,\n _sentryModuleMetadata: self._sentryModuleMetadata ?? undefined,\n });\n\n // Set up unhandledrejection handler inside the worker\n // Following the same pattern as globalHandlers\n // unhandled rejections don't bubble to the parent thread, so we need to handle them here\n self.addEventListener('unhandledrejection', (event: unknown) => {\n const reason = _getUnhandledRejectionError(event);\n\n // Forward the raw reason to parent thread\n // The parent will handle primitives vs errors the same way globalHandlers does\n const serializedError: SerializedWorkerError = {\n reason: reason,\n filename: self.location?.href,\n };\n\n // Forward to parent thread\n self.postMessage({\n _sentryMessage: true,\n _sentryWorkerError: serializedError,\n });\n\n DEBUG_BUILD && debug.log('[Sentry Worker] Forwarding unhandled rejection to parent', serializedError);\n });\n\n DEBUG_BUILD && debug.log('[Sentry Worker] Registered worker with unhandled rejection handling');\n}\n\nfunction isSentryMessage(eventData: unknown): eventData is WebWorkerMessage {\n if (!isPlainObject(eventData) || eventData._sentryMessage !== true) {\n return false;\n }\n\n // Must have at least one of: debug IDs, module metadata, or worker error\n const hasDebugIds = '_sentryDebugIds' in eventData;\n const hasModuleMetadata = '_sentryModuleMetadata' in eventData;\n const hasWorkerError = '_sentryWorkerError' in eventData;\n\n if (!hasDebugIds && !hasModuleMetadata && !hasWorkerError) {\n return false;\n }\n\n // Validate debug IDs if present\n if (hasDebugIds && !(isPlainObject(eventData._sentryDebugIds) || eventData._sentryDebugIds === undefined)) {\n return false;\n }\n\n // Validate module metadata if present\n if (\n hasModuleMetadata &&\n !(isPlainObject(eventData._sentryModuleMetadata) || eventData._sentryModuleMetadata === undefined)\n ) {\n return false;\n }\n\n // Validate worker error if present\n if (hasWorkerError && !isPlainObject(eventData._sentryWorkerError)) {\n return false;\n }\n\n return true;\n}\n"],"names":["defineIntegration","DEBUG_BUILD","debug","WINDOW","getClient","isPrimitive","_eventFromRejectionWithPrimitive","eventFromUnknownInput","captureEvent","_getUnhandledRejectionError","isPlainObject"],"mappings":"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"}
1
+ {"version":3,"file":"webWorker.js","sources":["../../../../../src/integrations/webWorker.ts"],"sourcesContent":["import type { DebugImage, Integration, IntegrationFn } from '@sentry/core';\nimport { captureEvent, debug, defineIntegration, getClient, isPlainObject, isPrimitive } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { eventFromUnknownInput } from '../eventbuilder';\nimport { WINDOW } from '../helpers';\nimport { _eventFromRejectionWithPrimitive, _getUnhandledRejectionError } from './globalhandlers';\n\nexport const INTEGRATION_NAME = 'WebWorker';\n\ninterface WebWorkerMessage {\n _sentryMessage: boolean;\n _sentryDebugIds?: Record<string, string>;\n _sentryModuleMetadata?: Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n _sentryWorkerError?: SerializedWorkerError;\n _sentryWasmImages?: Array<DebugImage>;\n}\n\ninterface SerializedWorkerError {\n reason: unknown;\n filename?: string;\n}\n\ninterface WebWorkerIntegrationOptions {\n worker: Worker | Array<Worker>;\n}\n\ninterface WebWorkerIntegration extends Integration {\n addWorker: (worker: Worker) => void;\n}\n\n/**\n * Use this integration to set up Sentry with web workers.\n *\n * IMPORTANT: This integration must be added **before** you start listening to\n * any messages from the worker. Otherwise, your message handlers will receive\n * messages from the Sentry SDK which you need to ignore.\n *\n * This integration only has an effect, if you call `Sentry.registerWebWorker(self)`\n * from within the worker(s) you're adding to the integration.\n *\n * Given that you want to initialize the SDK as early as possible, you most likely\n * want to add this integration **after** initializing the SDK:\n *\n * @example:\n * ```ts filename={main.js}\n * import * as Sentry from '@sentry/<your-sdk>';\n *\n * // some time earlier:\n * Sentry.init(...)\n *\n * // 1. Initialize the worker\n * const worker = new Worker(new URL('./worker.ts', import.meta.url));\n *\n * // 2. Add the integration\n * const webWorkerIntegration = Sentry.webWorkerIntegration({ worker });\n * Sentry.addIntegration(webWorkerIntegration);\n *\n * // 3. Register message listeners on the worker\n * worker.addEventListener('message', event => {\n * // ...\n * });\n * ```\n *\n * If you initialize multiple workers at the same time, you can also pass an array of workers\n * to the integration:\n *\n * ```ts filename={main.js}\n * const webWorkerIntegration = Sentry.webWorkerIntegration({ worker: [worker1, worker2] });\n * Sentry.addIntegration(webWorkerIntegration);\n * ```\n *\n * If you have any additional workers that you initialize at a later point,\n * you can add them to the integration as follows:\n *\n * ```ts filename={main.js}\n * const webWorkerIntegration = Sentry.webWorkerIntegration({ worker: worker1 });\n * Sentry.addIntegration(webWorkerIntegration);\n *\n * // sometime later:\n * webWorkerIntegration.addWorker(worker2);\n * ```\n *\n * Of course, you can also directly add the integration in Sentry.init:\n * ```ts filename={main.js}\n * import * as Sentry from '@sentry/<your-sdk>';\n *\n * // 1. Initialize the worker\n * const worker = new Worker(new URL('./worker.ts', import.meta.url));\n *\n * // 2. Initialize the SDK\n * Sentry.init({\n * integrations: [Sentry.webWorkerIntegration({ worker })]\n * });\n *\n * // 3. Register message listeners on the worker\n * worker.addEventListener('message', event => {\n * // ...\n * });\n * ```\n *\n * @param options {WebWorkerIntegrationOptions} Integration options:\n * - `worker`: The worker instance.\n */\nexport const webWorkerIntegration = defineIntegration(({ worker }: WebWorkerIntegrationOptions) => ({\n name: INTEGRATION_NAME,\n setupOnce: () => {\n (Array.isArray(worker) ? worker : [worker]).forEach(w => listenForSentryMessages(w));\n },\n addWorker: (worker: Worker) => listenForSentryMessages(worker),\n})) as IntegrationFn<WebWorkerIntegration>;\n\nfunction listenForSentryMessages(worker: Worker): void {\n worker.addEventListener('message', event => {\n if (isSentryMessage(event.data)) {\n event.stopImmediatePropagation(); // other listeners should not receive this message\n\n // Handle debug IDs\n if (event.data._sentryDebugIds) {\n DEBUG_BUILD && debug.log('Sentry debugId web worker message received', event.data);\n WINDOW._sentryDebugIds = {\n ...event.data._sentryDebugIds,\n // debugIds of the main thread have precedence over the worker's in case of a collision.\n ...WINDOW._sentryDebugIds,\n };\n }\n\n // Handle module metadata\n if (event.data._sentryModuleMetadata) {\n DEBUG_BUILD && debug.log('Sentry module metadata web worker message received', event.data);\n // Merge worker's raw metadata into the global object\n // It will be parsed lazily when needed by getMetadataForUrl\n WINDOW._sentryModuleMetadata = {\n ...event.data._sentryModuleMetadata,\n // Module metadata of the main thread have precedence over the worker's in case of a collision.\n ...WINDOW._sentryModuleMetadata,\n };\n }\n\n // Handle WASM images from worker\n if (event.data._sentryWasmImages) {\n DEBUG_BUILD && debug.log('Sentry WASM images web worker message received', event.data);\n const existingImages =\n (WINDOW as typeof WINDOW & { _sentryWasmImages?: Array<DebugImage> })._sentryWasmImages || [];\n const newImages = event.data._sentryWasmImages.filter(\n (newImg: unknown) =>\n isPlainObject(newImg) &&\n typeof newImg.code_file === 'string' &&\n !existingImages.some(existing => existing.code_file === newImg.code_file),\n );\n (WINDOW as typeof WINDOW & { _sentryWasmImages?: Array<DebugImage> })._sentryWasmImages = [\n ...existingImages,\n ...newImages,\n ];\n }\n\n // Handle unhandled rejections forwarded from worker\n if (event.data._sentryWorkerError) {\n DEBUG_BUILD && debug.log('Sentry worker rejection message received', event.data._sentryWorkerError);\n handleForwardedWorkerRejection(event.data._sentryWorkerError);\n }\n }\n });\n}\n\nfunction handleForwardedWorkerRejection(workerError: SerializedWorkerError): void {\n const client = getClient();\n if (!client) {\n return;\n }\n\n const stackParser = client.getOptions().stackParser;\n const attachStacktrace = client.getOptions().attachStacktrace;\n\n const error = workerError.reason;\n\n // Follow same pattern as globalHandlers for unhandledrejection\n // Handle both primitives and errors the same way\n const event = isPrimitive(error)\n ? _eventFromRejectionWithPrimitive(error)\n : eventFromUnknownInput(stackParser, error, undefined, attachStacktrace, true);\n\n event.level = 'error';\n\n // Add worker-specific context\n if (workerError.filename) {\n event.contexts = {\n ...event.contexts,\n worker: {\n filename: workerError.filename,\n },\n };\n }\n\n captureEvent(event, {\n originalException: error,\n mechanism: {\n handled: false,\n type: 'auto.browser.web_worker.onunhandledrejection',\n },\n });\n\n DEBUG_BUILD && debug.log('Captured worker unhandled rejection', error);\n}\n\n/**\n * Minimal interface for DedicatedWorkerGlobalScope, only requiring the postMessage method.\n * (which is the only thing we need from the worker's global object)\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope\n *\n * We can't use the actual type because it breaks everyone who doesn't have {\"lib\": [\"WebWorker\"]}\n * but uses {\"skipLibCheck\": true} in their tsconfig.json.\n */\ninterface MinimalDedicatedWorkerGlobalScope {\n postMessage: (message: unknown) => void;\n addEventListener: (type: string, listener: (event: unknown) => void) => void;\n location?: { href?: string };\n}\n\ninterface RegisterWebWorkerOptions {\n self: MinimalDedicatedWorkerGlobalScope & {\n _sentryDebugIds?: Record<string, string>;\n _sentryModuleMetadata?: Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n };\n}\n\n/**\n * Use this function to register the worker with the Sentry SDK.\n *\n * This function will:\n * - Send debug IDs to the parent thread\n * - Send module metadata to the parent thread (for thirdPartyErrorFilterIntegration)\n * - Set up a handler for unhandled rejections in the worker\n * - Forward unhandled rejections to the parent thread for capture\n *\n * Note: Synchronous errors in workers are already captured by globalHandlers.\n * This only handles unhandled promise rejections which don't bubble to the parent.\n *\n * @example\n * ```ts filename={worker.js}\n * import * as Sentry from '@sentry/<your-sdk>';\n *\n * // Do this as early as possible in your worker.\n * Sentry.registerWebWorker({ self });\n *\n * // continue setting up your worker\n * self.postMessage(...)\n * ```\n * @param options {RegisterWebWorkerOptions} Integration options:\n * - `self`: The worker instance you're calling this function from (self).\n */\nexport function registerWebWorker({ self }: RegisterWebWorkerOptions): void {\n // Send debug IDs and raw module metadata to parent thread\n // The metadata will be parsed lazily on the main thread when needed\n self.postMessage({\n _sentryMessage: true,\n _sentryDebugIds: self._sentryDebugIds ?? undefined,\n _sentryModuleMetadata: self._sentryModuleMetadata ?? undefined,\n });\n\n // Set up unhandledrejection handler inside the worker\n // Following the same pattern as globalHandlers\n // unhandled rejections don't bubble to the parent thread, so we need to handle them here\n self.addEventListener('unhandledrejection', (event: unknown) => {\n const reason = _getUnhandledRejectionError(event);\n\n // Forward the raw reason to parent thread\n // The parent will handle primitives vs errors the same way globalHandlers does\n const serializedError: SerializedWorkerError = {\n reason: reason,\n filename: self.location?.href,\n };\n\n // Forward to parent thread\n self.postMessage({\n _sentryMessage: true,\n _sentryWorkerError: serializedError,\n });\n\n DEBUG_BUILD && debug.log('[Sentry Worker] Forwarding unhandled rejection to parent', serializedError);\n });\n\n DEBUG_BUILD && debug.log('[Sentry Worker] Registered worker with unhandled rejection handling');\n}\n\nfunction isSentryMessage(eventData: unknown): eventData is WebWorkerMessage {\n if (!isPlainObject(eventData) || eventData._sentryMessage !== true) {\n return false;\n }\n\n // Must have at least one of: debug IDs, module metadata, worker error, or WASM images\n const hasDebugIds = '_sentryDebugIds' in eventData;\n const hasModuleMetadata = '_sentryModuleMetadata' in eventData;\n const hasWorkerError = '_sentryWorkerError' in eventData;\n const hasWasmImages = '_sentryWasmImages' in eventData;\n\n if (!hasDebugIds && !hasModuleMetadata && !hasWorkerError && !hasWasmImages) {\n return false;\n }\n\n // Validate debug IDs if present\n if (hasDebugIds && !(isPlainObject(eventData._sentryDebugIds) || eventData._sentryDebugIds === undefined)) {\n return false;\n }\n\n // Validate module metadata if present\n if (\n hasModuleMetadata &&\n !(isPlainObject(eventData._sentryModuleMetadata) || eventData._sentryModuleMetadata === undefined)\n ) {\n return false;\n }\n\n // Validate worker error if present\n if (hasWorkerError && !isPlainObject(eventData._sentryWorkerError)) {\n return false;\n }\n\n // Validate WASM images if present\n if (\n hasWasmImages &&\n (!Array.isArray(eventData._sentryWasmImages) ||\n !eventData._sentryWasmImages.every(\n (img: unknown) => isPlainObject(img) && typeof (img as { code_file?: unknown }).code_file === 'string',\n ))\n ) {\n return false;\n }\n\n return true;\n}\n"],"names":["defineIntegration","DEBUG_BUILD","debug","WINDOW","isPlainObject","getClient","isPrimitive","_eventFromRejectionWithPrimitive","eventFromUnknownInput","captureEvent","_getUnhandledRejectionError"],"mappings":"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"}
@@ -106,6 +106,16 @@ class UIProfiler {
106
106
  this._endProfiling();
107
107
  }
108
108
 
109
+ /** Returns the current profiler session ID, or undefined if not initialized. */
110
+ getProfilerId() {
111
+ return this._profilerId;
112
+ }
113
+
114
+ /** Returns whether the profiler is currently running (recording). */
115
+ isRunning() {
116
+ return this._isRunning;
117
+ }
118
+
109
119
  /** Handle an already-active root span at integration setup time (used only in trace mode). */
110
120
  notifyRootSpanActive(rootSpan) {
111
121
  if (this._lifecycleMode !== 'trace' || !this._sessionSampled) {
@@ -1 +1 @@
1
- {"version":3,"file":"UIProfiler.js","sources":["../../../../../src/profiling/UIProfiler.ts"],"sourcesContent":["import type { Client, ContinuousProfiler, ProfileChunk, ProfileChunkEnvelope, Span } from '@sentry/core';\nimport {\n createEnvelope,\n debug,\n dsnToString,\n getGlobalScope,\n getRootSpan,\n getSdkMetadataForEnvelopeHeader,\n uuid4,\n} from '@sentry/core';\nimport type { BrowserOptions } from '../client';\nimport { DEBUG_BUILD } from './../debug-build';\nimport type { JSSelfProfiler } from './jsSelfProfiling';\nimport { createProfileChunkPayload, shouldProfileSession, startJSSelfProfile, validateProfileChunk } from './utils';\n\nconst CHUNK_INTERVAL_MS = 60_000; // 1 minute\n// Maximum length for trace lifecycle profiling per root span (e.g. if spanEnd never fires)\nconst MAX_ROOT_SPAN_PROFILE_MS = 300_000; // 5 minutes max per root span in trace mode\n\n/**\n * UIProfiler (Profiling V2):\n * Supports two lifecycle modes:\n * - 'manual': controlled explicitly via start()/stop()\n * - 'trace': automatically runs while there are active sampled root spans\n *\n * Profiles are emitted as standalone `profile_chunk` envelopes either when:\n * - there are no more sampled root spans, or\n * - the 60s chunk timer elapses while profiling is running.\n */\nexport class UIProfiler implements ContinuousProfiler<Client> {\n private _client: Client | undefined;\n private _profiler: JSSelfProfiler | undefined;\n private _chunkTimer: ReturnType<typeof setTimeout> | undefined;\n\n // Manual + Trace\n private _profilerId: string | undefined; // one per Profiler session\n private _isRunning: boolean; // current profiler instance active flag\n private _sessionSampled: boolean; // sampling decision for entire session\n private _lifecycleMode: 'manual' | 'trace' | undefined;\n\n // Trace-only\n private _activeRootSpanIds: Set<string>;\n private _rootSpanTimeouts: Map<string, ReturnType<typeof setTimeout>>;\n\n public constructor() {\n this._client = undefined;\n this._profiler = undefined;\n this._chunkTimer = undefined;\n\n this._profilerId = undefined;\n this._isRunning = false;\n this._sessionSampled = false;\n this._lifecycleMode = undefined;\n\n this._activeRootSpanIds = new Set();\n this._rootSpanTimeouts = new Map();\n }\n\n /**\n * Initialize the profiler with client, session sampling and lifecycle mode.\n */\n public initialize(client: Client): void {\n const lifecycleMode = (client.getOptions() as BrowserOptions).profileLifecycle;\n const sessionSampled = shouldProfileSession(client.getOptions());\n\n DEBUG_BUILD && debug.log(`[Profiling] Initializing profiler (lifecycle='${lifecycleMode}').`);\n\n if (!sessionSampled) {\n DEBUG_BUILD && debug.log('[Profiling] Session not sampled. Skipping lifecycle profiler initialization.');\n }\n\n // One Profiler ID per profiling session (user session)\n this._profilerId = uuid4();\n this._client = client;\n this._sessionSampled = sessionSampled;\n this._lifecycleMode = lifecycleMode;\n\n if (lifecycleMode === 'trace') {\n this._setupTraceLifecycleListeners(client);\n }\n }\n\n /** Starts UI profiling (only effective in 'manual' mode and when sampled). */\n public start(): void {\n if (this._lifecycleMode === 'trace') {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] `profileLifecycle` is set to \"trace\". Calls to `uiProfiler.start()` are ignored in trace mode.',\n );\n return;\n }\n\n if (this._isRunning) {\n DEBUG_BUILD && debug.warn('[Profiling] Profile session is already running, `uiProfiler.start()` is a no-op.');\n return;\n }\n\n if (!this._sessionSampled) {\n DEBUG_BUILD && debug.warn('[Profiling] Session is not sampled, `uiProfiler.start()` is a no-op.');\n return;\n }\n\n this._beginProfiling();\n }\n\n /** Stops UI profiling (only effective in 'manual' mode). */\n public stop(): void {\n if (this._lifecycleMode === 'trace') {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] `profileLifecycle` is set to \"trace\". Calls to `uiProfiler.stop()` are ignored in trace mode.',\n );\n return;\n }\n\n if (!this._isRunning) {\n DEBUG_BUILD && debug.warn('[Profiling] Profiler is not running, `uiProfiler.stop()` is a no-op.');\n return;\n }\n\n this._endProfiling();\n }\n\n /** Handle an already-active root span at integration setup time (used only in trace mode). */\n public notifyRootSpanActive(rootSpan: Span): void {\n if (this._lifecycleMode !== 'trace' || !this._sessionSampled) {\n return;\n }\n\n const spanId = rootSpan.spanContext().spanId;\n if (!spanId || this._activeRootSpanIds.has(spanId)) {\n return;\n }\n\n this._registerTraceRootSpan(spanId);\n\n const rootSpanCount = this._activeRootSpanIds.size;\n\n if (rootSpanCount === 1) {\n DEBUG_BUILD &&\n debug.log('[Profiling] Detected already active root span during setup. Active root spans now:', rootSpanCount);\n\n this._beginProfiling();\n }\n }\n\n /**\n * Begin profiling if not already running.\n */\n private _beginProfiling(): void {\n if (this._isRunning) {\n return;\n }\n this._isRunning = true;\n\n DEBUG_BUILD && debug.log('[Profiling] Started profiling with profiler ID:', this._profilerId);\n\n // Expose profiler_id to match root spans with profiles\n getGlobalScope().setContext('profile', { profiler_id: this._profilerId });\n\n this._startProfilerInstance();\n\n if (!this._profiler) {\n DEBUG_BUILD && debug.log('[Profiling] Failed to start JS Profiler; stopping.');\n this._resetProfilerInfo();\n return;\n }\n\n this._startPeriodicChunking();\n }\n\n /** End profiling session; final chunk will be collected and sent. */\n private _endProfiling(): void {\n if (!this._isRunning) {\n return;\n }\n this._isRunning = false;\n\n if (this._chunkTimer) {\n clearTimeout(this._chunkTimer);\n this._chunkTimer = undefined;\n }\n\n this._clearAllRootSpanTimeouts();\n\n // Collect whatever was currently recording\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk on `stop()`:', e);\n });\n\n // Manual: Clear profiling context so spans outside start()/stop() aren't marked as profiled\n // Trace: Profile context is kept for the whole session duration\n if (this._lifecycleMode === 'manual') {\n getGlobalScope().setContext('profile', {});\n }\n }\n\n /** Trace-mode: attach spanStart/spanEnd listeners. */\n private _setupTraceLifecycleListeners(client: Client): void {\n client.on('spanStart', span => {\n if (!this._sessionSampled) {\n DEBUG_BUILD &&\n debug.log('[Profiling] Span not profiled because of negative sampling decision for user session.');\n return;\n }\n if (span !== getRootSpan(span)) {\n return; // only care about root spans\n }\n // Only count sampled root spans\n if (!span.isRecording()) {\n DEBUG_BUILD && debug.log('[Profiling] Discarding profile because root span was not sampled.');\n return;\n }\n\n const spanId = span.spanContext().spanId;\n if (!spanId || this._activeRootSpanIds.has(spanId)) {\n return;\n }\n\n this._registerTraceRootSpan(spanId);\n\n const rootSpanCount = this._activeRootSpanIds.size;\n if (rootSpanCount === 1) {\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Root span ${spanId} started. Profiling active while there are active root spans (count=${rootSpanCount}).`,\n );\n this._beginProfiling();\n }\n });\n\n client.on('spanEnd', span => {\n if (!this._sessionSampled) {\n return;\n }\n const spanId = span.spanContext().spanId;\n if (!spanId || !this._activeRootSpanIds.has(spanId)) {\n return;\n }\n this._activeRootSpanIds.delete(spanId);\n const rootSpanCount = this._activeRootSpanIds.size;\n\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Root span with ID ${spanId} ended. Will continue profiling for as long as there are active root spans (currently: ${rootSpanCount}).`,\n );\n if (rootSpanCount === 0) {\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk on last `spanEnd`:', e);\n });\n this._endProfiling();\n }\n });\n }\n\n /**\n * Resets profiling information from scope and resets running state (used on failure)\n */\n private _resetProfilerInfo(): void {\n this._isRunning = false;\n getGlobalScope().setContext('profile', {});\n }\n\n /**\n * Clear and reset all per-root-span timeouts.\n */\n private _clearAllRootSpanTimeouts(): void {\n this._rootSpanTimeouts.forEach(timeout => clearTimeout(timeout));\n this._rootSpanTimeouts.clear();\n }\n\n /** Keep track of root spans and schedule safeguard timeout (trace mode). */\n private _registerTraceRootSpan(spanId: string): void {\n this._activeRootSpanIds.add(spanId);\n const timeout = setTimeout(() => this._onRootSpanTimeout(spanId), MAX_ROOT_SPAN_PROFILE_MS);\n this._rootSpanTimeouts.set(spanId, timeout);\n }\n\n /**\n * Start a profiler instance if needed.\n */\n private _startProfilerInstance(): void {\n if (this._profiler?.stopped === false) {\n return; // already running\n }\n const profiler = startJSSelfProfile();\n if (!profiler) {\n DEBUG_BUILD && debug.log('[Profiling] Failed to start JS Profiler.');\n return;\n }\n this._profiler = profiler;\n }\n\n /**\n * Schedule the next 60s chunk while running.\n * Each tick collects a chunk and restarts the profiler.\n * A chunk should be closed when there are no active root spans anymore OR when the maximum chunk interval is reached.\n */\n private _startPeriodicChunking(): void {\n if (!this._isRunning) {\n return;\n }\n\n this._chunkTimer = setTimeout(() => {\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk during periodic chunking:', e);\n });\n\n if (this._isRunning) {\n this._startProfilerInstance();\n\n if (!this._profiler) {\n // If restart failed, stop scheduling further chunks and reset context.\n this._resetProfilerInfo();\n return;\n }\n\n this._startPeriodicChunking();\n }\n }, CHUNK_INTERVAL_MS);\n }\n\n /**\n * Handle timeout for a specific root span ID to avoid indefinitely running profiler if `spanEnd` never fires.\n * If this was the last active root span, collect the current chunk and stop profiling.\n */\n private _onRootSpanTimeout(rootSpanId: string): void {\n // If span already ended, ignore\n if (!this._rootSpanTimeouts.has(rootSpanId)) {\n return;\n }\n this._rootSpanTimeouts.delete(rootSpanId);\n\n if (!this._activeRootSpanIds.has(rootSpanId)) {\n return;\n }\n\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Reached 5-minute timeout for root span ${rootSpanId}. You likely started a manual root span that never called \\`.end()\\`.`,\n );\n\n this._activeRootSpanIds.delete(rootSpanId);\n\n if (this._activeRootSpanIds.size === 0) {\n this._endProfiling();\n }\n }\n\n /**\n * Stop current profiler instance, convert profile to chunk & send.\n */\n private async _collectCurrentChunk(): Promise<void> {\n const prevProfiler = this._profiler;\n this._profiler = undefined;\n\n if (!prevProfiler) {\n return;\n }\n\n try {\n const profile = await prevProfiler.stop();\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const chunk = createProfileChunkPayload(profile, this._client!, this._profilerId);\n\n // Validate chunk before sending\n const validationReturn = validateProfileChunk(chunk);\n if ('reason' in validationReturn) {\n DEBUG_BUILD &&\n debug.log(\n '[Profiling] Discarding invalid profile chunk (this is probably a bug in the SDK):',\n validationReturn.reason,\n );\n return;\n }\n\n this._sendProfileChunk(chunk);\n\n DEBUG_BUILD && debug.log('[Profiling] Collected browser profile chunk.');\n } catch (e) {\n DEBUG_BUILD && debug.log('[Profiling] Error while stopping JS Profiler for chunk:', e);\n }\n }\n\n /**\n * Send a profile chunk as a standalone envelope.\n */\n private _sendProfileChunk(chunk: ProfileChunk): void {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const client = this._client!;\n\n const sdkInfo = getSdkMetadataForEnvelopeHeader(client.getSdkMetadata?.());\n const dsn = client.getDsn();\n const tunnel = client.getOptions().tunnel;\n\n const envelope = createEnvelope<ProfileChunkEnvelope>(\n {\n event_id: uuid4(),\n sent_at: new Date().toISOString(),\n ...(sdkInfo && { sdk: sdkInfo }),\n ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n },\n [[{ type: 'profile_chunk', platform: 'javascript' }, chunk]],\n );\n\n client.sendEnvelope(envelope).then(null, reason => {\n DEBUG_BUILD && debug.error('Error while sending profile chunk envelope:', reason);\n });\n }\n}\n"],"names":["shouldProfileSession","DEBUG_BUILD","debug","uuid4","getGlobalScope","getRootSpan","startJSSelfProfile","createProfileChunkPayload","validateProfileChunk","getSdkMetadataForEnvelopeHeader","createEnvelope","dsnToString"],"mappings":"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"}
1
+ {"version":3,"file":"UIProfiler.js","sources":["../../../../../src/profiling/UIProfiler.ts"],"sourcesContent":["import type { Client, ContinuousProfiler, ProfileChunk, ProfileChunkEnvelope, Span } from '@sentry/core';\nimport {\n createEnvelope,\n debug,\n dsnToString,\n getGlobalScope,\n getRootSpan,\n getSdkMetadataForEnvelopeHeader,\n uuid4,\n} from '@sentry/core';\nimport type { BrowserOptions } from '../client';\nimport { DEBUG_BUILD } from './../debug-build';\nimport type { JSSelfProfiler } from './jsSelfProfiling';\nimport { createProfileChunkPayload, shouldProfileSession, startJSSelfProfile, validateProfileChunk } from './utils';\n\nconst CHUNK_INTERVAL_MS = 60_000; // 1 minute\n// Maximum length for trace lifecycle profiling per root span (e.g. if spanEnd never fires)\nconst MAX_ROOT_SPAN_PROFILE_MS = 300_000; // 5 minutes max per root span in trace mode\n\n/**\n * UIProfiler (Profiling V2):\n * Supports two lifecycle modes:\n * - 'manual': controlled explicitly via start()/stop()\n * - 'trace': automatically runs while there are active sampled root spans\n *\n * Profiles are emitted as standalone `profile_chunk` envelopes either when:\n * - there are no more sampled root spans, or\n * - the 60s chunk timer elapses while profiling is running.\n */\nexport class UIProfiler implements ContinuousProfiler<Client> {\n private _client: Client | undefined;\n private _profiler: JSSelfProfiler | undefined;\n private _chunkTimer: ReturnType<typeof setTimeout> | undefined;\n\n // Manual + Trace\n private _profilerId: string | undefined; // one per Profiler session\n private _isRunning: boolean; // current profiler instance active flag\n private _sessionSampled: boolean; // sampling decision for entire session\n private _lifecycleMode: 'manual' | 'trace' | undefined;\n\n // Trace-only\n private _activeRootSpanIds: Set<string>;\n private _rootSpanTimeouts: Map<string, ReturnType<typeof setTimeout>>;\n\n public constructor() {\n this._client = undefined;\n this._profiler = undefined;\n this._chunkTimer = undefined;\n\n this._profilerId = undefined;\n this._isRunning = false;\n this._sessionSampled = false;\n this._lifecycleMode = undefined;\n\n this._activeRootSpanIds = new Set();\n this._rootSpanTimeouts = new Map();\n }\n\n /**\n * Initialize the profiler with client, session sampling and lifecycle mode.\n */\n public initialize(client: Client): void {\n const lifecycleMode = (client.getOptions() as BrowserOptions).profileLifecycle;\n const sessionSampled = shouldProfileSession(client.getOptions());\n\n DEBUG_BUILD && debug.log(`[Profiling] Initializing profiler (lifecycle='${lifecycleMode}').`);\n\n if (!sessionSampled) {\n DEBUG_BUILD && debug.log('[Profiling] Session not sampled. Skipping lifecycle profiler initialization.');\n }\n\n // One Profiler ID per profiling session (user session)\n this._profilerId = uuid4();\n this._client = client;\n this._sessionSampled = sessionSampled;\n this._lifecycleMode = lifecycleMode;\n\n if (lifecycleMode === 'trace') {\n this._setupTraceLifecycleListeners(client);\n }\n }\n\n /** Starts UI profiling (only effective in 'manual' mode and when sampled). */\n public start(): void {\n if (this._lifecycleMode === 'trace') {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] `profileLifecycle` is set to \"trace\". Calls to `uiProfiler.start()` are ignored in trace mode.',\n );\n return;\n }\n\n if (this._isRunning) {\n DEBUG_BUILD && debug.warn('[Profiling] Profile session is already running, `uiProfiler.start()` is a no-op.');\n return;\n }\n\n if (!this._sessionSampled) {\n DEBUG_BUILD && debug.warn('[Profiling] Session is not sampled, `uiProfiler.start()` is a no-op.');\n return;\n }\n\n this._beginProfiling();\n }\n\n /** Stops UI profiling (only effective in 'manual' mode). */\n public stop(): void {\n if (this._lifecycleMode === 'trace') {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] `profileLifecycle` is set to \"trace\". Calls to `uiProfiler.stop()` are ignored in trace mode.',\n );\n return;\n }\n\n if (!this._isRunning) {\n DEBUG_BUILD && debug.warn('[Profiling] Profiler is not running, `uiProfiler.stop()` is a no-op.');\n return;\n }\n\n this._endProfiling();\n }\n\n /** Returns the current profiler session ID, or undefined if not initialized. */\n public getProfilerId(): string | undefined {\n return this._profilerId;\n }\n\n /** Returns whether the profiler is currently running (recording). */\n public isRunning(): boolean {\n return this._isRunning;\n }\n\n /** Handle an already-active root span at integration setup time (used only in trace mode). */\n public notifyRootSpanActive(rootSpan: Span): void {\n if (this._lifecycleMode !== 'trace' || !this._sessionSampled) {\n return;\n }\n\n const spanId = rootSpan.spanContext().spanId;\n if (!spanId || this._activeRootSpanIds.has(spanId)) {\n return;\n }\n\n this._registerTraceRootSpan(spanId);\n\n const rootSpanCount = this._activeRootSpanIds.size;\n\n if (rootSpanCount === 1) {\n DEBUG_BUILD &&\n debug.log('[Profiling] Detected already active root span during setup. Active root spans now:', rootSpanCount);\n\n this._beginProfiling();\n }\n }\n\n /**\n * Begin profiling if not already running.\n */\n private _beginProfiling(): void {\n if (this._isRunning) {\n return;\n }\n this._isRunning = true;\n\n DEBUG_BUILD && debug.log('[Profiling] Started profiling with profiler ID:', this._profilerId);\n\n // Expose profiler_id to match root spans with profiles\n getGlobalScope().setContext('profile', { profiler_id: this._profilerId });\n\n this._startProfilerInstance();\n\n if (!this._profiler) {\n DEBUG_BUILD && debug.log('[Profiling] Failed to start JS Profiler; stopping.');\n this._resetProfilerInfo();\n return;\n }\n\n this._startPeriodicChunking();\n }\n\n /** End profiling session; final chunk will be collected and sent. */\n private _endProfiling(): void {\n if (!this._isRunning) {\n return;\n }\n this._isRunning = false;\n\n if (this._chunkTimer) {\n clearTimeout(this._chunkTimer);\n this._chunkTimer = undefined;\n }\n\n this._clearAllRootSpanTimeouts();\n\n // Collect whatever was currently recording\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk on `stop()`:', e);\n });\n\n // Manual: Clear profiling context so spans outside start()/stop() aren't marked as profiled\n // Trace: Profile context is kept for the whole session duration\n if (this._lifecycleMode === 'manual') {\n getGlobalScope().setContext('profile', {});\n }\n }\n\n /** Trace-mode: attach spanStart/spanEnd listeners. */\n private _setupTraceLifecycleListeners(client: Client): void {\n client.on('spanStart', span => {\n if (!this._sessionSampled) {\n DEBUG_BUILD &&\n debug.log('[Profiling] Span not profiled because of negative sampling decision for user session.');\n return;\n }\n if (span !== getRootSpan(span)) {\n return; // only care about root spans\n }\n // Only count sampled root spans\n if (!span.isRecording()) {\n DEBUG_BUILD && debug.log('[Profiling] Discarding profile because root span was not sampled.');\n return;\n }\n\n const spanId = span.spanContext().spanId;\n if (!spanId || this._activeRootSpanIds.has(spanId)) {\n return;\n }\n\n this._registerTraceRootSpan(spanId);\n\n const rootSpanCount = this._activeRootSpanIds.size;\n if (rootSpanCount === 1) {\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Root span ${spanId} started. Profiling active while there are active root spans (count=${rootSpanCount}).`,\n );\n this._beginProfiling();\n }\n });\n\n client.on('spanEnd', span => {\n if (!this._sessionSampled) {\n return;\n }\n const spanId = span.spanContext().spanId;\n if (!spanId || !this._activeRootSpanIds.has(spanId)) {\n return;\n }\n this._activeRootSpanIds.delete(spanId);\n const rootSpanCount = this._activeRootSpanIds.size;\n\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Root span with ID ${spanId} ended. Will continue profiling for as long as there are active root spans (currently: ${rootSpanCount}).`,\n );\n if (rootSpanCount === 0) {\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk on last `spanEnd`:', e);\n });\n this._endProfiling();\n }\n });\n }\n\n /**\n * Resets profiling information from scope and resets running state (used on failure)\n */\n private _resetProfilerInfo(): void {\n this._isRunning = false;\n getGlobalScope().setContext('profile', {});\n }\n\n /**\n * Clear and reset all per-root-span timeouts.\n */\n private _clearAllRootSpanTimeouts(): void {\n this._rootSpanTimeouts.forEach(timeout => clearTimeout(timeout));\n this._rootSpanTimeouts.clear();\n }\n\n /** Keep track of root spans and schedule safeguard timeout (trace mode). */\n private _registerTraceRootSpan(spanId: string): void {\n this._activeRootSpanIds.add(spanId);\n const timeout = setTimeout(() => this._onRootSpanTimeout(spanId), MAX_ROOT_SPAN_PROFILE_MS);\n this._rootSpanTimeouts.set(spanId, timeout);\n }\n\n /**\n * Start a profiler instance if needed.\n */\n private _startProfilerInstance(): void {\n if (this._profiler?.stopped === false) {\n return; // already running\n }\n const profiler = startJSSelfProfile();\n if (!profiler) {\n DEBUG_BUILD && debug.log('[Profiling] Failed to start JS Profiler.');\n return;\n }\n this._profiler = profiler;\n }\n\n /**\n * Schedule the next 60s chunk while running.\n * Each tick collects a chunk and restarts the profiler.\n * A chunk should be closed when there are no active root spans anymore OR when the maximum chunk interval is reached.\n */\n private _startPeriodicChunking(): void {\n if (!this._isRunning) {\n return;\n }\n\n this._chunkTimer = setTimeout(() => {\n this._collectCurrentChunk().catch(e => {\n DEBUG_BUILD && debug.error('[Profiling] Failed to collect current profile chunk during periodic chunking:', e);\n });\n\n if (this._isRunning) {\n this._startProfilerInstance();\n\n if (!this._profiler) {\n // If restart failed, stop scheduling further chunks and reset context.\n this._resetProfilerInfo();\n return;\n }\n\n this._startPeriodicChunking();\n }\n }, CHUNK_INTERVAL_MS);\n }\n\n /**\n * Handle timeout for a specific root span ID to avoid indefinitely running profiler if `spanEnd` never fires.\n * If this was the last active root span, collect the current chunk and stop profiling.\n */\n private _onRootSpanTimeout(rootSpanId: string): void {\n // If span already ended, ignore\n if (!this._rootSpanTimeouts.has(rootSpanId)) {\n return;\n }\n this._rootSpanTimeouts.delete(rootSpanId);\n\n if (!this._activeRootSpanIds.has(rootSpanId)) {\n return;\n }\n\n DEBUG_BUILD &&\n debug.log(\n `[Profiling] Reached 5-minute timeout for root span ${rootSpanId}. You likely started a manual root span that never called \\`.end()\\`.`,\n );\n\n this._activeRootSpanIds.delete(rootSpanId);\n\n if (this._activeRootSpanIds.size === 0) {\n this._endProfiling();\n }\n }\n\n /**\n * Stop current profiler instance, convert profile to chunk & send.\n */\n private async _collectCurrentChunk(): Promise<void> {\n const prevProfiler = this._profiler;\n this._profiler = undefined;\n\n if (!prevProfiler) {\n return;\n }\n\n try {\n const profile = await prevProfiler.stop();\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const chunk = createProfileChunkPayload(profile, this._client!, this._profilerId);\n\n // Validate chunk before sending\n const validationReturn = validateProfileChunk(chunk);\n if ('reason' in validationReturn) {\n DEBUG_BUILD &&\n debug.log(\n '[Profiling] Discarding invalid profile chunk (this is probably a bug in the SDK):',\n validationReturn.reason,\n );\n return;\n }\n\n this._sendProfileChunk(chunk);\n\n DEBUG_BUILD && debug.log('[Profiling] Collected browser profile chunk.');\n } catch (e) {\n DEBUG_BUILD && debug.log('[Profiling] Error while stopping JS Profiler for chunk:', e);\n }\n }\n\n /**\n * Send a profile chunk as a standalone envelope.\n */\n private _sendProfileChunk(chunk: ProfileChunk): void {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const client = this._client!;\n\n const sdkInfo = getSdkMetadataForEnvelopeHeader(client.getSdkMetadata?.());\n const dsn = client.getDsn();\n const tunnel = client.getOptions().tunnel;\n\n const envelope = createEnvelope<ProfileChunkEnvelope>(\n {\n event_id: uuid4(),\n sent_at: new Date().toISOString(),\n ...(sdkInfo && { sdk: sdkInfo }),\n ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n },\n [[{ type: 'profile_chunk', platform: 'javascript' }, chunk]],\n );\n\n client.sendEnvelope(envelope).then(null, reason => {\n DEBUG_BUILD && debug.error('Error while sending profile chunk envelope:', reason);\n });\n }\n}\n"],"names":["shouldProfileSession","DEBUG_BUILD","debug","uuid4","getGlobalScope","getRootSpan","startJSSelfProfile","createProfileChunkPayload","validateProfileChunk","getSdkMetadataForEnvelopeHeader","createEnvelope","dsnToString"],"mappings":"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"}
@@ -72,6 +72,16 @@ const _browserProfilingIntegration = (() => {
72
72
  }
73
73
  }, 0);
74
74
  }
75
+
76
+ // Attach profilerId to every span when the profiler is active (for correlation with profile chunks)
77
+ client.on('spanStart', (span) => {
78
+ if (profiler.isRunning()) {
79
+ const profilerId = profiler.getProfilerId();
80
+ if (profilerId) {
81
+ span.setAttribute('sentry.profiler_id', profilerId);
82
+ }
83
+ }
84
+ });
75
85
  } else {
76
86
  // LEGACY PROFILING (v1)
77
87
  if (rootSpan && utils.isAutomatedPageLoadSpan(rootSpan)) {
@@ -1 +1 @@
1
- {"version":3,"file":"integration.js","sources":["../../../../../src/profiling/integration.ts"],"sourcesContent":["import type { EventEnvelope, IntegrationFn, Profile, Span } from '@sentry/core';\nimport { debug, defineIntegration, getActiveSpan, getRootSpan, hasSpansEnabled } from '@sentry/core';\nimport type { BrowserOptions } from '../client';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport { startProfileForSpan } from './startProfileForSpan';\nimport { UIProfiler } from './UIProfiler';\nimport type { ProfiledEvent } from './utils';\nimport {\n addProfilesToEnvelope,\n attachProfiledThreadToEvent,\n createProfilingEvent,\n findProfiledTransactionsFromEnvelope,\n getActiveProfilesCount,\n hasLegacyProfiling,\n isAutomatedPageLoadSpan,\n shouldProfileSpanLegacy,\n takeProfileFromGlobalCache,\n} from './utils';\n\nconst INTEGRATION_NAME = 'BrowserProfiling';\n\nconst _browserProfilingIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n const options = client.getOptions() as BrowserOptions;\n const profiler = new UIProfiler();\n\n if (!hasLegacyProfiling(options) && !options.profileLifecycle) {\n // Set default lifecycle mode\n options.profileLifecycle = 'manual';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n if (hasLegacyProfiling(options) && !options.profilesSampleRate) {\n DEBUG_BUILD && debug.log('[Profiling] Profiling disabled, no profiling options found.');\n return;\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (hasLegacyProfiling(options) && options.profileSessionSampleRate !== undefined) {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] Both legacy profiling (`profilesSampleRate`) and UI profiling settings are defined. `profileSessionSampleRate` has no effect when legacy profiling is enabled.',\n );\n }\n\n // UI PROFILING (Profiling V2)\n if (!hasLegacyProfiling(options)) {\n const lifecycleMode = options.profileLifecycle;\n\n // Registering hooks in all lifecycle modes to be able to notify users in case they want to start/stop the profiler manually in `trace` mode\n client.on('startUIProfiler', () => profiler.start());\n client.on('stopUIProfiler', () => profiler.stop());\n\n if (lifecycleMode === 'manual') {\n profiler.initialize(client);\n } else if (lifecycleMode === 'trace') {\n if (!hasSpansEnabled(options)) {\n DEBUG_BUILD &&\n debug.warn(\n \"[Profiling] `profileLifecycle` is 'trace' but tracing is disabled. Set a `tracesSampleRate` or `tracesSampler` to enable span tracing.\",\n );\n return;\n }\n\n profiler.initialize(client);\n\n // If there is an active, sampled root span already, notify the profiler\n if (rootSpan) {\n profiler.notifyRootSpanActive(rootSpan);\n }\n\n // In case rootSpan is created slightly after setup -> schedule microtask to re-check and notify.\n WINDOW.setTimeout(() => {\n const laterActiveSpan = getActiveSpan();\n const laterRootSpan = laterActiveSpan && getRootSpan(laterActiveSpan);\n if (laterRootSpan) {\n profiler.notifyRootSpanActive(laterRootSpan);\n }\n }, 0);\n }\n } else {\n // LEGACY PROFILING (v1)\n if (rootSpan && isAutomatedPageLoadSpan(rootSpan)) {\n if (shouldProfileSpanLegacy(rootSpan)) {\n startProfileForSpan(rootSpan);\n }\n }\n\n client.on('spanStart', (span: Span) => {\n if (span === getRootSpan(span) && shouldProfileSpanLegacy(span)) {\n startProfileForSpan(span);\n }\n });\n\n client.on('beforeEnvelope', (envelope): void => {\n // if not profiles are in queue, there is nothing to add to the envelope.\n if (!getActiveProfilesCount()) {\n return;\n }\n\n const profiledTransactionEvents = findProfiledTransactionsFromEnvelope(envelope);\n if (!profiledTransactionEvents.length) {\n return;\n }\n\n const profilesToAddToEnvelope: Profile[] = [];\n\n for (const profiledTransaction of profiledTransactionEvents) {\n const context = profiledTransaction?.contexts;\n const profile_id = context?.profile?.['profile_id'];\n const start_timestamp = context?.profile?.['start_timestamp'];\n\n if (typeof profile_id !== 'string') {\n DEBUG_BUILD && debug.log('[Profiling] cannot find profile for a span without a profile context');\n continue;\n }\n\n if (!profile_id) {\n DEBUG_BUILD && debug.log('[Profiling] cannot find profile for a span without a profile context');\n continue;\n }\n\n // Remove the profile from the span context before sending, relay will take care of the rest.\n if (context?.profile) {\n delete context.profile;\n }\n\n const profile = takeProfileFromGlobalCache(profile_id);\n if (!profile) {\n DEBUG_BUILD && debug.log(`[Profiling] Could not retrieve profile for span: ${profile_id}`);\n continue;\n }\n\n const profileEvent = createProfilingEvent(\n profile_id,\n start_timestamp as number | undefined,\n profile,\n profiledTransaction as ProfiledEvent,\n );\n if (profileEvent) {\n profilesToAddToEnvelope.push(profileEvent);\n }\n }\n\n addProfilesToEnvelope(envelope as EventEnvelope, profilesToAddToEnvelope);\n });\n }\n },\n processEvent(event) {\n return attachProfiledThreadToEvent(event);\n },\n };\n}) satisfies IntegrationFn;\n\nexport const browserProfilingIntegration = defineIntegration(_browserProfilingIntegration);\n"],"names":["UIProfiler","hasLegacyProfiling","DEBUG_BUILD","debug","getActiveSpan","getRootSpan","hasSpansEnabled","WINDOW","isAutomatedPageLoadSpan","shouldProfileSpanLegacy","startProfileForSpan","getActiveProfilesCount","findProfiledTransactionsFromEnvelope","takeProfileFromGlobalCache","createProfilingEvent","addProfilesToEnvelope","attachProfiledThreadToEvent","defineIntegration"],"mappings":"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"}
1
+ {"version":3,"file":"integration.js","sources":["../../../../../src/profiling/integration.ts"],"sourcesContent":["import type { EventEnvelope, IntegrationFn, Profile, Span } from '@sentry/core';\nimport { debug, defineIntegration, getActiveSpan, getRootSpan, hasSpansEnabled } from '@sentry/core';\nimport type { BrowserOptions } from '../client';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport { startProfileForSpan } from './startProfileForSpan';\nimport { UIProfiler } from './UIProfiler';\nimport type { ProfiledEvent } from './utils';\nimport {\n addProfilesToEnvelope,\n attachProfiledThreadToEvent,\n createProfilingEvent,\n findProfiledTransactionsFromEnvelope,\n getActiveProfilesCount,\n hasLegacyProfiling,\n isAutomatedPageLoadSpan,\n shouldProfileSpanLegacy,\n takeProfileFromGlobalCache,\n} from './utils';\n\nconst INTEGRATION_NAME = 'BrowserProfiling';\n\nconst _browserProfilingIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n const options = client.getOptions() as BrowserOptions;\n const profiler = new UIProfiler();\n\n if (!hasLegacyProfiling(options) && !options.profileLifecycle) {\n // Set default lifecycle mode\n options.profileLifecycle = 'manual';\n }\n\n // eslint-disable-next-line deprecation/deprecation\n if (hasLegacyProfiling(options) && !options.profilesSampleRate) {\n DEBUG_BUILD && debug.log('[Profiling] Profiling disabled, no profiling options found.');\n return;\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (hasLegacyProfiling(options) && options.profileSessionSampleRate !== undefined) {\n DEBUG_BUILD &&\n debug.warn(\n '[Profiling] Both legacy profiling (`profilesSampleRate`) and UI profiling settings are defined. `profileSessionSampleRate` has no effect when legacy profiling is enabled.',\n );\n }\n\n // UI PROFILING (Profiling V2)\n if (!hasLegacyProfiling(options)) {\n const lifecycleMode = options.profileLifecycle;\n\n // Registering hooks in all lifecycle modes to be able to notify users in case they want to start/stop the profiler manually in `trace` mode\n client.on('startUIProfiler', () => profiler.start());\n client.on('stopUIProfiler', () => profiler.stop());\n\n if (lifecycleMode === 'manual') {\n profiler.initialize(client);\n } else if (lifecycleMode === 'trace') {\n if (!hasSpansEnabled(options)) {\n DEBUG_BUILD &&\n debug.warn(\n \"[Profiling] `profileLifecycle` is 'trace' but tracing is disabled. Set a `tracesSampleRate` or `tracesSampler` to enable span tracing.\",\n );\n return;\n }\n\n profiler.initialize(client);\n\n // If there is an active, sampled root span already, notify the profiler\n if (rootSpan) {\n profiler.notifyRootSpanActive(rootSpan);\n }\n\n // In case rootSpan is created slightly after setup -> schedule microtask to re-check and notify.\n WINDOW.setTimeout(() => {\n const laterActiveSpan = getActiveSpan();\n const laterRootSpan = laterActiveSpan && getRootSpan(laterActiveSpan);\n if (laterRootSpan) {\n profiler.notifyRootSpanActive(laterRootSpan);\n }\n }, 0);\n }\n\n // Attach profilerId to every span when the profiler is active (for correlation with profile chunks)\n client.on('spanStart', (span: Span) => {\n if (profiler.isRunning()) {\n const profilerId = profiler.getProfilerId();\n if (profilerId) {\n span.setAttribute('sentry.profiler_id', profilerId);\n }\n }\n });\n } else {\n // LEGACY PROFILING (v1)\n if (rootSpan && isAutomatedPageLoadSpan(rootSpan)) {\n if (shouldProfileSpanLegacy(rootSpan)) {\n startProfileForSpan(rootSpan);\n }\n }\n\n client.on('spanStart', (span: Span) => {\n if (span === getRootSpan(span) && shouldProfileSpanLegacy(span)) {\n startProfileForSpan(span);\n }\n });\n\n client.on('beforeEnvelope', (envelope): void => {\n // if not profiles are in queue, there is nothing to add to the envelope.\n if (!getActiveProfilesCount()) {\n return;\n }\n\n const profiledTransactionEvents = findProfiledTransactionsFromEnvelope(envelope);\n if (!profiledTransactionEvents.length) {\n return;\n }\n\n const profilesToAddToEnvelope: Profile[] = [];\n\n for (const profiledTransaction of profiledTransactionEvents) {\n const context = profiledTransaction?.contexts;\n const profile_id = context?.profile?.['profile_id'];\n const start_timestamp = context?.profile?.['start_timestamp'];\n\n if (typeof profile_id !== 'string') {\n DEBUG_BUILD && debug.log('[Profiling] cannot find profile for a span without a profile context');\n continue;\n }\n\n if (!profile_id) {\n DEBUG_BUILD && debug.log('[Profiling] cannot find profile for a span without a profile context');\n continue;\n }\n\n // Remove the profile from the span context before sending, relay will take care of the rest.\n if (context?.profile) {\n delete context.profile;\n }\n\n const profile = takeProfileFromGlobalCache(profile_id);\n if (!profile) {\n DEBUG_BUILD && debug.log(`[Profiling] Could not retrieve profile for span: ${profile_id}`);\n continue;\n }\n\n const profileEvent = createProfilingEvent(\n profile_id,\n start_timestamp as number | undefined,\n profile,\n profiledTransaction as ProfiledEvent,\n );\n if (profileEvent) {\n profilesToAddToEnvelope.push(profileEvent);\n }\n }\n\n addProfilesToEnvelope(envelope as EventEnvelope, profilesToAddToEnvelope);\n });\n }\n },\n processEvent(event) {\n return attachProfiledThreadToEvent(event);\n },\n };\n}) satisfies IntegrationFn;\n\nexport const browserProfilingIntegration = defineIntegration(_browserProfilingIntegration);\n"],"names":["UIProfiler","hasLegacyProfiling","DEBUG_BUILD","debug","getActiveSpan","getRootSpan","hasSpansEnabled","WINDOW","isAutomatedPageLoadSpan","shouldProfileSpanLegacy","startProfileForSpan","getActiveProfilesCount","findProfiledTransactionsFromEnvelope","takeProfileFromGlobalCache","createProfilingEvent","addProfilesToEnvelope","attachProfiledThreadToEvent","defineIntegration"],"mappings":"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"}
@@ -5,6 +5,7 @@ const client = require('./client.js');
5
5
  const breadcrumbs = require('./integrations/breadcrumbs.js');
6
6
  const browserapierrors = require('./integrations/browserapierrors.js');
7
7
  const browsersession = require('./integrations/browsersession.js');
8
+ const culturecontext = require('./integrations/culturecontext.js');
8
9
  const globalhandlers = require('./integrations/globalhandlers.js');
9
10
  const httpcontext = require('./integrations/httpcontext.js');
10
11
  const linkederrors = require('./integrations/linkederrors.js');
@@ -31,6 +32,7 @@ function getDefaultIntegrations(_options) {
31
32
  linkederrors.linkedErrorsIntegration(),
32
33
  core.dedupeIntegration(),
33
34
  httpcontext.httpContextIntegration(),
35
+ culturecontext.cultureContextIntegration(),
34
36
  browsersession.browserSessionIntegration(),
35
37
  ];
36
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sources":["../../../../src/sdk.ts"],"sourcesContent":["import type { Client, Integration, Options } from '@sentry/core';\nimport {\n conversationIdIntegration,\n dedupeIntegration,\n functionToStringIntegration,\n getIntegrationsToSetup,\n inboundFiltersIntegration,\n initAndBind,\n stackParserFromStackParserOptions,\n} from '@sentry/core';\nimport type { BrowserClientOptions, BrowserOptions } from './client';\nimport { BrowserClient } from './client';\nimport { breadcrumbsIntegration } from './integrations/breadcrumbs';\nimport { browserApiErrorsIntegration } from './integrations/browserapierrors';\nimport { browserSessionIntegration } from './integrations/browsersession';\nimport { globalHandlersIntegration } from './integrations/globalhandlers';\nimport { httpContextIntegration } from './integrations/httpcontext';\nimport { linkedErrorsIntegration } from './integrations/linkederrors';\nimport { spotlightBrowserIntegration } from './integrations/spotlight';\nimport { defaultStackParser } from './stack-parsers';\nimport { makeFetchTransport } from './transports/fetch';\nimport { checkAndWarnIfIsEmbeddedBrowserExtension } from './utils/detectBrowserExtension';\n\n/** Get the default integrations for the browser SDK. */\nexport function getDefaultIntegrations(_options: Options): Integration[] {\n /**\n * Note: Please make sure this stays in sync with Angular SDK, which re-exports\n * `getDefaultIntegrations` but with an adjusted set of integrations.\n */\n return [\n // TODO(v11): Replace with `eventFiltersIntegration` once we remove the deprecated `inboundFiltersIntegration`\n // eslint-disable-next-line deprecation/deprecation\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n conversationIdIntegration(),\n browserApiErrorsIntegration(),\n breadcrumbsIntegration(),\n globalHandlersIntegration(),\n linkedErrorsIntegration(),\n dedupeIntegration(),\n httpContextIntegration(),\n browserSessionIntegration(),\n ];\n}\n\n/**\n * The Sentry Browser SDK Client.\n *\n * To use this SDK, call the {@link init} function as early as possible when\n * loading the web page. To set context information or send manual events, use\n * the provided methods.\n *\n * @example\n *\n * ```\n *\n * import { init } from '@sentry/browser';\n *\n * init({\n * dsn: '__DSN__',\n * // ...\n * });\n * ```\n *\n * @example\n * ```\n *\n * import { addBreadcrumb } from '@sentry/browser';\n * addBreadcrumb({\n * message: 'My Breadcrumb',\n * // ...\n * });\n * ```\n *\n * @example\n *\n * ```\n *\n * import * as Sentry from '@sentry/browser';\n * Sentry.captureMessage('Hello, world!');\n * Sentry.captureException(new Error('Good bye'));\n * Sentry.captureEvent({\n * message: 'Manual',\n * stacktrace: [\n * // ...\n * ],\n * });\n * ```\n *\n * @see {@link BrowserOptions} for documentation on configuration options.\n */\nexport function init(options: BrowserOptions = {}): Client | undefined {\n const shouldDisableBecauseIsBrowserExtenstion =\n !options.skipBrowserExtensionCheck && checkAndWarnIfIsEmbeddedBrowserExtension();\n\n let defaultIntegrations =\n options.defaultIntegrations == null ? getDefaultIntegrations(options) : options.defaultIntegrations;\n\n /* rollup-include-development-only */\n if (options.spotlight) {\n if (!defaultIntegrations) {\n defaultIntegrations = [];\n }\n const args = typeof options.spotlight === 'string' ? { sidecarUrl: options.spotlight } : undefined;\n defaultIntegrations.push(spotlightBrowserIntegration(args));\n }\n /* rollup-include-development-only-end */\n\n const clientOptions: BrowserClientOptions = {\n ...options,\n enabled: shouldDisableBecauseIsBrowserExtenstion ? false : options.enabled,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n integrations: getIntegrationsToSetup({\n integrations: options.integrations,\n defaultIntegrations,\n }),\n transport: options.transport || makeFetchTransport,\n };\n return initAndBind(BrowserClient, clientOptions);\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nexport function forceLoad(): void {\n // Noop\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nexport function onLoad(callback: () => void): void {\n callback();\n}\n"],"names":["inboundFiltersIntegration","functionToStringIntegration","conversationIdIntegration","browserApiErrorsIntegration","breadcrumbsIntegration","globalHandlersIntegration","linkedErrorsIntegration","dedupeIntegration","httpContextIntegration","browserSessionIntegration","checkAndWarnIfIsEmbeddedBrowserExtension","spotlightBrowserIntegration","stackParserFromStackParserOptions","defaultStackParser","getIntegrationsToSetup","makeFetchTransport","initAndBind","BrowserClient"],"mappings":";;;;;;;;;;;;;;;AAuBA;AACO,SAAS,sBAAsB,CAAC,QAAQ,EAA0B;AACzE;AACA;AACA;AACA;AACA,EAAE,OAAO;AACT;AACA;AACA,IAAIA,8BAAyB,EAAE;AAC/B,IAAIC,gCAA2B,EAAE;AACjC,IAAIC,8BAAyB,EAAE;AAC/B,IAAIC,4CAA2B,EAAE;AACjC,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,wCAAyB,EAAE;AAC/B,IAAIC,oCAAuB,EAAE;AAC7B,IAAIC,sBAAiB,EAAE;AACvB,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,wCAAyB,EAAE;AAC/B,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,GAAmB,EAAE,EAAsB;AACvE,EAAE,MAAM,uCAAA;AACR,IAAI,CAAC,OAAO,CAAC,6BAA6BC,+DAAwC,EAAE;;AAEpF,EAAE,IAAI,mBAAA;AACN,IAAI,OAAO,CAAC,mBAAA,IAAuB,IAAA,GAAO,sBAAsB,CAAQ,CAAA,GAAI,OAAO,CAAC,mBAAmB;;AAEvG;AACA,EAAE,IAAI,OAAO,CAAC,SAAS,EAAE;AACzB,IAAI,IAAI,CAAC,mBAAmB,EAAE;AAC9B,MAAM,mBAAA,GAAsB,EAAE;AAC9B,IAAI;AACJ,IAAI,MAAM,IAAA,GAAO,OAAO,OAAO,CAAC,cAAc,QAAA,GAAW,EAAE,UAAU,EAAE,OAAO,CAAC,SAAA,EAAU,GAAI,SAAS;AACtG,IAAI,mBAAmB,CAAC,IAAI,CAACC,qCAA2B,CAAC,IAAI,CAAC,CAAC;AAC/D,EAAE;AACF;;AAEA,EAAE,MAAM,aAAa,GAAyB;AAC9C,IAAI,GAAG,OAAO;AACd,IAAI,OAAO,EAAE,uCAAA,GAA0C,QAAQ,OAAO,CAAC,OAAO;AAC9E,IAAI,WAAW,EAAEC,sCAAiC,CAAC,OAAO,CAAC,WAAA,IAAeC,+BAAkB,CAAC;AAC7F,IAAI,YAAY,EAAEC,2BAAsB,CAAC;AACzC,MAAM,YAAY,EAAE,OAAO,CAAC,YAAY;AACxC,MAAM,mBAAmB;AACzB,KAAK,CAAC;AACN,IAAI,SAAS,EAAE,OAAO,CAAC,SAAA,IAAaC,wBAAkB;AACtD,GAAG;AACH,EAAE,OAAOC,gBAAW,CAACC,oBAAa,EAAE,aAAa,CAAC;AAClD;;AAEA;AACA;AACA;AACA;AACO,SAAS,SAAS,GAAS;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACO,SAAS,MAAM,CAAC,QAAQ,EAAoB;AACnD,EAAE,QAAQ,EAAE;AACZ;;;;;;;"}
1
+ {"version":3,"file":"sdk.js","sources":["../../../../src/sdk.ts"],"sourcesContent":["import type { Client, Integration, Options } from '@sentry/core';\nimport {\n conversationIdIntegration,\n dedupeIntegration,\n functionToStringIntegration,\n getIntegrationsToSetup,\n inboundFiltersIntegration,\n initAndBind,\n stackParserFromStackParserOptions,\n} from '@sentry/core';\nimport type { BrowserClientOptions, BrowserOptions } from './client';\nimport { BrowserClient } from './client';\nimport { breadcrumbsIntegration } from './integrations/breadcrumbs';\nimport { browserApiErrorsIntegration } from './integrations/browserapierrors';\nimport { browserSessionIntegration } from './integrations/browsersession';\nimport { cultureContextIntegration } from './integrations/culturecontext';\nimport { globalHandlersIntegration } from './integrations/globalhandlers';\nimport { httpContextIntegration } from './integrations/httpcontext';\nimport { linkedErrorsIntegration } from './integrations/linkederrors';\nimport { spotlightBrowserIntegration } from './integrations/spotlight';\nimport { defaultStackParser } from './stack-parsers';\nimport { makeFetchTransport } from './transports/fetch';\nimport { checkAndWarnIfIsEmbeddedBrowserExtension } from './utils/detectBrowserExtension';\n\n/** Get the default integrations for the browser SDK. */\nexport function getDefaultIntegrations(_options: Options): Integration[] {\n /**\n * Note: Please make sure this stays in sync with Angular SDK, which re-exports\n * `getDefaultIntegrations` but with an adjusted set of integrations.\n */\n return [\n // TODO(v11): Replace with `eventFiltersIntegration` once we remove the deprecated `inboundFiltersIntegration`\n // eslint-disable-next-line deprecation/deprecation\n inboundFiltersIntegration(),\n functionToStringIntegration(),\n conversationIdIntegration(),\n browserApiErrorsIntegration(),\n breadcrumbsIntegration(),\n globalHandlersIntegration(),\n linkedErrorsIntegration(),\n dedupeIntegration(),\n httpContextIntegration(),\n cultureContextIntegration(),\n browserSessionIntegration(),\n ];\n}\n\n/**\n * The Sentry Browser SDK Client.\n *\n * To use this SDK, call the {@link init} function as early as possible when\n * loading the web page. To set context information or send manual events, use\n * the provided methods.\n *\n * @example\n *\n * ```\n *\n * import { init } from '@sentry/browser';\n *\n * init({\n * dsn: '__DSN__',\n * // ...\n * });\n * ```\n *\n * @example\n * ```\n *\n * import { addBreadcrumb } from '@sentry/browser';\n * addBreadcrumb({\n * message: 'My Breadcrumb',\n * // ...\n * });\n * ```\n *\n * @example\n *\n * ```\n *\n * import * as Sentry from '@sentry/browser';\n * Sentry.captureMessage('Hello, world!');\n * Sentry.captureException(new Error('Good bye'));\n * Sentry.captureEvent({\n * message: 'Manual',\n * stacktrace: [\n * // ...\n * ],\n * });\n * ```\n *\n * @see {@link BrowserOptions} for documentation on configuration options.\n */\nexport function init(options: BrowserOptions = {}): Client | undefined {\n const shouldDisableBecauseIsBrowserExtenstion =\n !options.skipBrowserExtensionCheck && checkAndWarnIfIsEmbeddedBrowserExtension();\n\n let defaultIntegrations =\n options.defaultIntegrations == null ? getDefaultIntegrations(options) : options.defaultIntegrations;\n\n /* rollup-include-development-only */\n if (options.spotlight) {\n if (!defaultIntegrations) {\n defaultIntegrations = [];\n }\n const args = typeof options.spotlight === 'string' ? { sidecarUrl: options.spotlight } : undefined;\n defaultIntegrations.push(spotlightBrowserIntegration(args));\n }\n /* rollup-include-development-only-end */\n\n const clientOptions: BrowserClientOptions = {\n ...options,\n enabled: shouldDisableBecauseIsBrowserExtenstion ? false : options.enabled,\n stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n integrations: getIntegrationsToSetup({\n integrations: options.integrations,\n defaultIntegrations,\n }),\n transport: options.transport || makeFetchTransport,\n };\n return initAndBind(BrowserClient, clientOptions);\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nexport function forceLoad(): void {\n // Noop\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nexport function onLoad(callback: () => void): void {\n callback();\n}\n"],"names":["inboundFiltersIntegration","functionToStringIntegration","conversationIdIntegration","browserApiErrorsIntegration","breadcrumbsIntegration","globalHandlersIntegration","linkedErrorsIntegration","dedupeIntegration","httpContextIntegration","cultureContextIntegration","browserSessionIntegration","checkAndWarnIfIsEmbeddedBrowserExtension","spotlightBrowserIntegration","stackParserFromStackParserOptions","defaultStackParser","getIntegrationsToSetup","makeFetchTransport","initAndBind","BrowserClient"],"mappings":";;;;;;;;;;;;;;;;AAwBA;AACO,SAAS,sBAAsB,CAAC,QAAQ,EAA0B;AACzE;AACA;AACA;AACA;AACA,EAAE,OAAO;AACT;AACA;AACA,IAAIA,8BAAyB,EAAE;AAC/B,IAAIC,gCAA2B,EAAE;AACjC,IAAIC,8BAAyB,EAAE;AAC/B,IAAIC,4CAA2B,EAAE;AACjC,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,wCAAyB,EAAE;AAC/B,IAAIC,oCAAuB,EAAE;AAC7B,IAAIC,sBAAiB,EAAE;AACvB,IAAIC,kCAAsB,EAAE;AAC5B,IAAIC,wCAAyB,EAAE;AAC/B,IAAIC,wCAAyB,EAAE;AAC/B,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,GAAmB,EAAE,EAAsB;AACvE,EAAE,MAAM,uCAAA;AACR,IAAI,CAAC,OAAO,CAAC,6BAA6BC,+DAAwC,EAAE;;AAEpF,EAAE,IAAI,mBAAA;AACN,IAAI,OAAO,CAAC,mBAAA,IAAuB,IAAA,GAAO,sBAAsB,CAAQ,CAAA,GAAI,OAAO,CAAC,mBAAmB;;AAEvG;AACA,EAAE,IAAI,OAAO,CAAC,SAAS,EAAE;AACzB,IAAI,IAAI,CAAC,mBAAmB,EAAE;AAC9B,MAAM,mBAAA,GAAsB,EAAE;AAC9B,IAAI;AACJ,IAAI,MAAM,IAAA,GAAO,OAAO,OAAO,CAAC,cAAc,QAAA,GAAW,EAAE,UAAU,EAAE,OAAO,CAAC,SAAA,EAAU,GAAI,SAAS;AACtG,IAAI,mBAAmB,CAAC,IAAI,CAACC,qCAA2B,CAAC,IAAI,CAAC,CAAC;AAC/D,EAAE;AACF;;AAEA,EAAE,MAAM,aAAa,GAAyB;AAC9C,IAAI,GAAG,OAAO;AACd,IAAI,OAAO,EAAE,uCAAA,GAA0C,QAAQ,OAAO,CAAC,OAAO;AAC9E,IAAI,WAAW,EAAEC,sCAAiC,CAAC,OAAO,CAAC,WAAA,IAAeC,+BAAkB,CAAC;AAC7F,IAAI,YAAY,EAAEC,2BAAsB,CAAC;AACzC,MAAM,YAAY,EAAE,OAAO,CAAC,YAAY;AACxC,MAAM,mBAAmB;AACzB,KAAK,CAAC;AACN,IAAI,SAAS,EAAE,OAAO,CAAC,SAAA,IAAaC,wBAAkB;AACtD,GAAG;AACH,EAAE,OAAOC,gBAAW,CAACC,oBAAa,EAAE,aAAa,CAAC;AAClD;;AAEA;AACA;AACA;AACA;AACO,SAAS,SAAS,GAAS;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACO,SAAS,MAAM,CAAC,QAAQ,EAAoB;AACnD,EAAE,QAAQ,EAAE;AACZ;;;;;;;"}
@@ -55,7 +55,7 @@ const browserTracingIntegration = ((options = {}) => {
55
55
  enableElementTiming,
56
56
  enableLongTask,
57
57
  enableLongAnimationFrame,
58
- _experiments: { enableInteractions, enableStandaloneClsSpans, enableStandaloneLcpSpans },
58
+ _experiments: { enableInteractions },
59
59
  beforeStartSpan,
60
60
  idleTimeout,
61
61
  finalTimeout,
@@ -117,6 +117,8 @@ const browserTracingIntegration = ((options = {}) => {
117
117
  latestRoute.name = finalStartSpanOptions.name;
118
118
  latestRoute.source = attributes[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];
119
119
 
120
+ const isSpanStreaming = core.hasSpanStreamingEnabled(client);
121
+
120
122
  const idleSpan = core.startIdleSpan(finalStartSpanOptions, {
121
123
  idleTimeout,
122
124
  finalTimeout,
@@ -128,8 +130,8 @@ const browserTracingIntegration = ((options = {}) => {
128
130
  // but technically, it is optional, so we guard here to be extra safe
129
131
  _collectWebVitals?.();
130
132
  browserUtils.addPerformanceEntries(span, {
131
- recordClsOnPageloadSpan: !enableStandaloneClsSpans,
132
- recordLcpOnPageloadSpan: !enableStandaloneLcpSpans,
133
+ recordClsOnPageloadSpan: !isSpanStreaming,
134
+ recordLcpOnPageloadSpan: !isSpanStreaming,
133
135
  ignoreResourceSpans,
134
136
  ignorePerformanceApiSpans,
135
137
  });
@@ -183,14 +185,10 @@ const browserTracingIntegration = ((options = {}) => {
183
185
  setup(client) {
184
186
  core.registerSpanErrorInstrumentation();
185
187
 
186
- _collectWebVitals = browserUtils.startTrackingWebVitals({
187
- recordClsStandaloneSpans: enableStandaloneClsSpans || false,
188
- recordLcpStandaloneSpans: enableStandaloneLcpSpans || false,
189
- client,
190
- });
188
+ _collectWebVitals = browserUtils.startTrackingWebVitals({ client });
191
189
 
192
190
  if (enableInp) {
193
- browserUtils.startTrackingINP();
191
+ browserUtils.startTrackingINP(core.hasSpanStreamingEnabled(client));
194
192
  }
195
193
 
196
194
  if (enableElementTiming) {
@@ -291,8 +289,9 @@ const browserTracingIntegration = ((options = {}) => {
291
289
  }
292
290
  maybeEndActiveSpan();
293
291
 
294
- const sentryTrace = traceOptions.sentryTrace || getMetaContent('sentry-trace');
295
- const baggage = traceOptions.baggage || getMetaContent('baggage');
292
+ const sentryTrace =
293
+ traceOptions.sentryTrace || getMetaContent('sentry-trace') || getServerTiming('sentry-trace');
294
+ const baggage = traceOptions.baggage || getMetaContent('baggage') || getServerTiming('baggage');
296
295
 
297
296
  const propagationContext = core.propagationContextFromHeaders(sentryTrace, baggage);
298
297
 
@@ -475,6 +474,13 @@ function getMetaContent(metaName) {
475
474
  return metaTag?.getAttribute('content') || undefined;
476
475
  }
477
476
 
477
+ /** Returns the description of a server timing entry */
478
+ function getServerTiming(name) {
479
+ const navigation = helpers.WINDOW.performance?.getEntriesByType?.('navigation')[0] ;
480
+ const entry = navigation?.serverTiming?.find(entry => entry.name === name);
481
+ return entry?.description;
482
+ }
483
+
478
484
  /** Start listener for interaction transactions */
479
485
  function registerInteractionListener(
480
486
  client,
@@ -572,6 +578,7 @@ function isRedirect(activeSpan, lastInteractionTimestamp) {
572
578
  exports.BROWSER_TRACING_INTEGRATION_ID = BROWSER_TRACING_INTEGRATION_ID;
573
579
  exports.browserTracingIntegration = browserTracingIntegration;
574
580
  exports.getMetaContent = getMetaContent;
581
+ exports.getServerTiming = getServerTiming;
575
582
  exports.startBrowserTracingNavigationSpan = startBrowserTracingNavigationSpan;
576
583
  exports.startBrowserTracingPageLoadSpan = startBrowserTracingPageLoadSpan;
577
584
  //# sourceMappingURL=browserTracingIntegration.js.map