@sentry/browser 10.61.0 → 10.63.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 (161) hide show
  1. package/build/npm/cjs/dev/integrations/breadcrumbs.js.map +1 -1
  2. package/build/npm/cjs/dev/integrations/browserapierrors.js.map +1 -1
  3. package/build/npm/cjs/dev/integrations/browsersession.js +11 -2
  4. package/build/npm/cjs/dev/integrations/browsersession.js.map +1 -1
  5. package/build/npm/cjs/dev/integrations/contextlines.js.map +1 -1
  6. package/build/npm/cjs/dev/integrations/culturecontext.js.map +1 -1
  7. package/build/npm/cjs/dev/integrations/featureFlags/launchdarkly/integration.js.map +1 -1
  8. package/build/npm/cjs/dev/integrations/featureFlags/openfeature/integration.js.map +1 -1
  9. package/build/npm/cjs/dev/integrations/featureFlags/statsig/integration.js.map +1 -1
  10. package/build/npm/cjs/dev/integrations/featureFlags/unleash/integration.js.map +1 -1
  11. package/build/npm/cjs/dev/integrations/fetchStreamPerformance.js.map +1 -1
  12. package/build/npm/cjs/dev/integrations/globalhandlers.js.map +1 -1
  13. package/build/npm/cjs/dev/integrations/graphqlClient.js.map +1 -1
  14. package/build/npm/cjs/dev/integrations/httpclient.js.map +1 -1
  15. package/build/npm/cjs/dev/integrations/httpcontext.js.map +1 -1
  16. package/build/npm/cjs/dev/integrations/linkederrors.js.map +1 -1
  17. package/build/npm/cjs/dev/integrations/reportingobserver.js.map +1 -1
  18. package/build/npm/cjs/dev/integrations/spanstreaming.js.map +1 -1
  19. package/build/npm/cjs/dev/integrations/spotlight.js.map +1 -1
  20. package/build/npm/cjs/dev/integrations/view-hierarchy.js.map +1 -1
  21. package/build/npm/cjs/dev/integrations/webVitals.js.map +1 -1
  22. package/build/npm/cjs/dev/integrations/webWorker.js.map +1 -1
  23. package/build/npm/cjs/dev/profiling/integration.js.map +1 -1
  24. package/build/npm/cjs/prod/integrations/breadcrumbs.js.map +1 -1
  25. package/build/npm/cjs/prod/integrations/browserapierrors.js.map +1 -1
  26. package/build/npm/cjs/prod/integrations/browsersession.js +11 -2
  27. package/build/npm/cjs/prod/integrations/browsersession.js.map +1 -1
  28. package/build/npm/cjs/prod/integrations/contextlines.js.map +1 -1
  29. package/build/npm/cjs/prod/integrations/culturecontext.js.map +1 -1
  30. package/build/npm/cjs/prod/integrations/featureFlags/launchdarkly/integration.js.map +1 -1
  31. package/build/npm/cjs/prod/integrations/featureFlags/openfeature/integration.js.map +1 -1
  32. package/build/npm/cjs/prod/integrations/featureFlags/statsig/integration.js.map +1 -1
  33. package/build/npm/cjs/prod/integrations/featureFlags/unleash/integration.js.map +1 -1
  34. package/build/npm/cjs/prod/integrations/fetchStreamPerformance.js.map +1 -1
  35. package/build/npm/cjs/prod/integrations/globalhandlers.js.map +1 -1
  36. package/build/npm/cjs/prod/integrations/graphqlClient.js.map +1 -1
  37. package/build/npm/cjs/prod/integrations/httpclient.js.map +1 -1
  38. package/build/npm/cjs/prod/integrations/httpcontext.js.map +1 -1
  39. package/build/npm/cjs/prod/integrations/linkederrors.js.map +1 -1
  40. package/build/npm/cjs/prod/integrations/reportingobserver.js.map +1 -1
  41. package/build/npm/cjs/prod/integrations/spanstreaming.js.map +1 -1
  42. package/build/npm/cjs/prod/integrations/spotlight.js.map +1 -1
  43. package/build/npm/cjs/prod/integrations/view-hierarchy.js.map +1 -1
  44. package/build/npm/cjs/prod/integrations/webVitals.js.map +1 -1
  45. package/build/npm/cjs/prod/integrations/webWorker.js.map +1 -1
  46. package/build/npm/cjs/prod/profiling/integration.js.map +1 -1
  47. package/build/npm/esm/dev/integrations/breadcrumbs.js.map +1 -1
  48. package/build/npm/esm/dev/integrations/browserapierrors.js.map +1 -1
  49. package/build/npm/esm/dev/integrations/browsersession.js +12 -3
  50. package/build/npm/esm/dev/integrations/browsersession.js.map +1 -1
  51. package/build/npm/esm/dev/integrations/contextlines.js.map +1 -1
  52. package/build/npm/esm/dev/integrations/culturecontext.js.map +1 -1
  53. package/build/npm/esm/dev/integrations/featureFlags/launchdarkly/integration.js.map +1 -1
  54. package/build/npm/esm/dev/integrations/featureFlags/openfeature/integration.js.map +1 -1
  55. package/build/npm/esm/dev/integrations/featureFlags/statsig/integration.js.map +1 -1
  56. package/build/npm/esm/dev/integrations/featureFlags/unleash/integration.js.map +1 -1
  57. package/build/npm/esm/dev/integrations/fetchStreamPerformance.js.map +1 -1
  58. package/build/npm/esm/dev/integrations/globalhandlers.js.map +1 -1
  59. package/build/npm/esm/dev/integrations/graphqlClient.js.map +1 -1
  60. package/build/npm/esm/dev/integrations/httpclient.js.map +1 -1
  61. package/build/npm/esm/dev/integrations/httpcontext.js.map +1 -1
  62. package/build/npm/esm/dev/integrations/linkederrors.js.map +1 -1
  63. package/build/npm/esm/dev/integrations/reportingobserver.js.map +1 -1
  64. package/build/npm/esm/dev/integrations/spanstreaming.js.map +1 -1
  65. package/build/npm/esm/dev/integrations/spotlight.js.map +1 -1
  66. package/build/npm/esm/dev/integrations/view-hierarchy.js.map +1 -1
  67. package/build/npm/esm/dev/integrations/webVitals.js.map +1 -1
  68. package/build/npm/esm/dev/integrations/webWorker.js.map +1 -1
  69. package/build/npm/esm/dev/package.json +1 -1
  70. package/build/npm/esm/dev/profiling/integration.js.map +1 -1
  71. package/build/npm/esm/prod/integrations/breadcrumbs.js.map +1 -1
  72. package/build/npm/esm/prod/integrations/browserapierrors.js.map +1 -1
  73. package/build/npm/esm/prod/integrations/browsersession.js +12 -3
  74. package/build/npm/esm/prod/integrations/browsersession.js.map +1 -1
  75. package/build/npm/esm/prod/integrations/contextlines.js.map +1 -1
  76. package/build/npm/esm/prod/integrations/culturecontext.js.map +1 -1
  77. package/build/npm/esm/prod/integrations/featureFlags/launchdarkly/integration.js.map +1 -1
  78. package/build/npm/esm/prod/integrations/featureFlags/openfeature/integration.js.map +1 -1
  79. package/build/npm/esm/prod/integrations/featureFlags/statsig/integration.js.map +1 -1
  80. package/build/npm/esm/prod/integrations/featureFlags/unleash/integration.js.map +1 -1
  81. package/build/npm/esm/prod/integrations/fetchStreamPerformance.js.map +1 -1
  82. package/build/npm/esm/prod/integrations/globalhandlers.js.map +1 -1
  83. package/build/npm/esm/prod/integrations/graphqlClient.js.map +1 -1
  84. package/build/npm/esm/prod/integrations/httpclient.js.map +1 -1
  85. package/build/npm/esm/prod/integrations/httpcontext.js.map +1 -1
  86. package/build/npm/esm/prod/integrations/linkederrors.js.map +1 -1
  87. package/build/npm/esm/prod/integrations/reportingobserver.js.map +1 -1
  88. package/build/npm/esm/prod/integrations/spanstreaming.js.map +1 -1
  89. package/build/npm/esm/prod/integrations/spotlight.js.map +1 -1
  90. package/build/npm/esm/prod/integrations/view-hierarchy.js.map +1 -1
  91. package/build/npm/esm/prod/integrations/webVitals.js.map +1 -1
  92. package/build/npm/esm/prod/integrations/webWorker.js.map +1 -1
  93. package/build/npm/esm/prod/package.json +1 -1
  94. package/build/npm/esm/prod/profiling/integration.js.map +1 -1
  95. package/build/npm/types/integrations/breadcrumbs.d.ts +3 -1
  96. package/build/npm/types/integrations/breadcrumbs.d.ts.map +1 -1
  97. package/build/npm/types/integrations/browserapierrors.d.ts +3 -1
  98. package/build/npm/types/integrations/browserapierrors.d.ts.map +1 -1
  99. package/build/npm/types/integrations/browsersession.d.ts +3 -1
  100. package/build/npm/types/integrations/browsersession.d.ts.map +1 -1
  101. package/build/npm/types/integrations/contextlines.d.ts +3 -1
  102. package/build/npm/types/integrations/contextlines.d.ts.map +1 -1
  103. package/build/npm/types/integrations/culturecontext.d.ts +3 -1
  104. package/build/npm/types/integrations/culturecontext.d.ts.map +1 -1
  105. package/build/npm/types/integrations/featureFlags/launchdarkly/integration.d.ts +3 -1
  106. package/build/npm/types/integrations/featureFlags/launchdarkly/integration.d.ts.map +1 -1
  107. package/build/npm/types/integrations/featureFlags/openfeature/integration.d.ts +3 -1
  108. package/build/npm/types/integrations/featureFlags/openfeature/integration.d.ts.map +1 -1
  109. package/build/npm/types/integrations/featureFlags/statsig/integration.d.ts +3 -1
  110. package/build/npm/types/integrations/featureFlags/statsig/integration.d.ts.map +1 -1
  111. package/build/npm/types/integrations/featureFlags/unleash/integration.d.ts +3 -1
  112. package/build/npm/types/integrations/featureFlags/unleash/integration.d.ts.map +1 -1
  113. package/build/npm/types/integrations/fetchStreamPerformance.d.ts +3 -1
  114. package/build/npm/types/integrations/fetchStreamPerformance.d.ts.map +1 -1
  115. package/build/npm/types/integrations/globalhandlers.d.ts +3 -1
  116. package/build/npm/types/integrations/globalhandlers.d.ts.map +1 -1
  117. package/build/npm/types/integrations/graphqlClient.d.ts +3 -1
  118. package/build/npm/types/integrations/graphqlClient.d.ts.map +1 -1
  119. package/build/npm/types/integrations/httpclient.d.ts +3 -1
  120. package/build/npm/types/integrations/httpclient.d.ts.map +1 -1
  121. package/build/npm/types/integrations/httpcontext.d.ts +3 -1
  122. package/build/npm/types/integrations/httpcontext.d.ts.map +1 -1
  123. package/build/npm/types/integrations/linkederrors.d.ts +3 -1
  124. package/build/npm/types/integrations/linkederrors.d.ts.map +1 -1
  125. package/build/npm/types/integrations/reportingobserver.d.ts +3 -1
  126. package/build/npm/types/integrations/reportingobserver.d.ts.map +1 -1
  127. package/build/npm/types/integrations/spanstreaming.d.ts +3 -1
  128. package/build/npm/types/integrations/spanstreaming.d.ts.map +1 -1
  129. package/build/npm/types/integrations/spotlight.d.ts +4 -2
  130. package/build/npm/types/integrations/spotlight.d.ts.map +1 -1
  131. package/build/npm/types/integrations/view-hierarchy.d.ts +3 -1
  132. package/build/npm/types/integrations/view-hierarchy.d.ts.map +1 -1
  133. package/build/npm/types/integrations/webVitals.d.ts +4 -2
  134. package/build/npm/types/integrations/webVitals.d.ts.map +1 -1
  135. package/build/npm/types/integrations/webWorker.d.ts +1 -1
  136. package/build/npm/types/integrations/webWorker.d.ts.map +1 -1
  137. package/build/npm/types/profiling/integration.d.ts +3 -1
  138. package/build/npm/types/profiling/integration.d.ts.map +1 -1
  139. package/build/npm/types-ts3.8/integrations/breadcrumbs.d.ts +3 -1
  140. package/build/npm/types-ts3.8/integrations/browserapierrors.d.ts +3 -1
  141. package/build/npm/types-ts3.8/integrations/browsersession.d.ts +3 -1
  142. package/build/npm/types-ts3.8/integrations/contextlines.d.ts +3 -1
  143. package/build/npm/types-ts3.8/integrations/culturecontext.d.ts +3 -1
  144. package/build/npm/types-ts3.8/integrations/featureFlags/launchdarkly/integration.d.ts +3 -1
  145. package/build/npm/types-ts3.8/integrations/featureFlags/openfeature/integration.d.ts +3 -1
  146. package/build/npm/types-ts3.8/integrations/featureFlags/statsig/integration.d.ts +3 -1
  147. package/build/npm/types-ts3.8/integrations/featureFlags/unleash/integration.d.ts +3 -1
  148. package/build/npm/types-ts3.8/integrations/fetchStreamPerformance.d.ts +3 -1
  149. package/build/npm/types-ts3.8/integrations/globalhandlers.d.ts +3 -1
  150. package/build/npm/types-ts3.8/integrations/graphqlClient.d.ts +3 -1
  151. package/build/npm/types-ts3.8/integrations/httpclient.d.ts +3 -1
  152. package/build/npm/types-ts3.8/integrations/httpcontext.d.ts +3 -1
  153. package/build/npm/types-ts3.8/integrations/linkederrors.d.ts +3 -1
  154. package/build/npm/types-ts3.8/integrations/reportingobserver.d.ts +3 -1
  155. package/build/npm/types-ts3.8/integrations/spanstreaming.d.ts +3 -1
  156. package/build/npm/types-ts3.8/integrations/spotlight.d.ts +4 -2
  157. package/build/npm/types-ts3.8/integrations/view-hierarchy.d.ts +3 -1
  158. package/build/npm/types-ts3.8/integrations/webVitals.d.ts +4 -2
  159. package/build/npm/types-ts3.8/integrations/webWorker.d.ts +1 -1
  160. package/build/npm/types-ts3.8/profiling/integration.d.ts +3 -1
  161. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"view-hierarchy.js","sources":["../../../../../src/integrations/view-hierarchy.ts"],"sourcesContent":["import type { Attachment, Event, EventHint, ViewHierarchyData, ViewHierarchyWindow } from '@sentry/core/browser';\nimport { defineIntegration, getComponentName } from '@sentry/core/browser';\nimport { WINDOW } from '../helpers';\n\ninterface OnElementArgs {\n /**\n * The element being processed.\n */\n element: HTMLElement;\n /**\n * Lowercase tag name of the element.\n */\n tagName: string;\n /**\n * The component name of the element.\n */\n componentName?: string;\n\n /**\n * The current depth of the element in the view hierarchy. The root element will have a depth of 0.\n *\n * This allows you to limit the traversal depth for large DOM trees.\n */\n depth?: number;\n}\n\ninterface Options {\n /**\n * Whether to attach the view hierarchy to the event.\n *\n * Default: Always attach.\n */\n shouldAttach?: (event: Event, hint: EventHint) => boolean;\n\n /**\n * A function that returns the root element to start walking the DOM from.\n *\n * Default: `window.document.body`\n */\n rootElement?: () => HTMLElement | undefined;\n\n /**\n * Called for each HTMLElement as we walk the DOM.\n *\n * Return an object to include the element with any additional properties.\n * Return `skip` to exclude the element and its children.\n * Return `children` to skip the element but include its children.\n */\n onElement?: (prop: OnElementArgs) => Record<string, string | number | boolean> | 'skip' | 'children';\n}\n\n/**\n * An integration to include a view hierarchy attachment which contains the DOM.\n */\nexport const viewHierarchyIntegration = defineIntegration((options: Options = {}) => {\n const skipHtmlTags = ['script'];\n\n /** Walk an element */\n function walk(element: HTMLElement, windows: ViewHierarchyWindow[], depth = 0): void {\n if (!element) {\n return;\n }\n\n // With Web Components, we need to walk into shadow DOMs\n const children = 'shadowRoot' in element && element.shadowRoot ? element.shadowRoot.children : element.children;\n\n for (const child of children) {\n if (!(child instanceof HTMLElement)) {\n continue;\n }\n\n const componentName = getComponentName(child, 1) || undefined;\n const tagName = child.tagName.toLowerCase();\n\n if (skipHtmlTags.includes(tagName)) {\n continue;\n }\n\n const result = options.onElement?.({ element: child, componentName, tagName, depth }) || {};\n\n if (result === 'skip') {\n continue;\n }\n\n // Skip this element but include its children\n if (result === 'children') {\n walk(child, windows, depth + 1);\n continue;\n }\n\n const { x, y, width, height } = child.getBoundingClientRect();\n\n const window: ViewHierarchyWindow = {\n identifier: (child.id || undefined) as string,\n type: componentName || tagName,\n visible: true,\n alpha: 1,\n height,\n width,\n x,\n y,\n ...result,\n };\n\n const children: ViewHierarchyWindow[] = [];\n window.children = children;\n\n // Recursively walk the children\n walk(child, window.children, depth + 1);\n\n windows.push(window);\n }\n }\n\n return {\n name: 'ViewHierarchy',\n processEvent: (event, hint) => {\n // only capture for error events\n if (event.type !== undefined || options.shouldAttach?.(event, hint) === false) {\n return event;\n }\n\n const root: ViewHierarchyData = {\n rendering_system: 'DOM',\n positioning: 'absolute',\n windows: [],\n };\n\n walk(options.rootElement?.() || WINDOW.document.body, root.windows);\n\n const attachment: Attachment = {\n filename: 'view-hierarchy.json',\n attachmentType: 'event.view_hierarchy',\n contentType: 'application/json',\n data: JSON.stringify(root),\n };\n\n hint.attachments = hint.attachments || [];\n hint.attachments.push(attachment);\n\n return event;\n },\n };\n});\n"],"names":["defineIntegration","getComponentName","children","WINDOW"],"mappings":"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"}
1
+ {"version":3,"file":"view-hierarchy.js","sources":["../../../../../src/integrations/view-hierarchy.ts"],"sourcesContent":["import type { Attachment, Event, EventHint, ViewHierarchyData, ViewHierarchyWindow } from '@sentry/core/browser';\nimport { defineIntegration, getComponentName } from '@sentry/core/browser';\nimport { WINDOW } from '../helpers';\n\ninterface OnElementArgs {\n /**\n * The element being processed.\n */\n element: HTMLElement;\n /**\n * Lowercase tag name of the element.\n */\n tagName: string;\n /**\n * The component name of the element.\n */\n componentName?: string;\n\n /**\n * The current depth of the element in the view hierarchy. The root element will have a depth of 0.\n *\n * This allows you to limit the traversal depth for large DOM trees.\n */\n depth?: number;\n}\n\ninterface Options {\n /**\n * Whether to attach the view hierarchy to the event.\n *\n * Default: Always attach.\n */\n shouldAttach?: (event: Event, hint: EventHint) => boolean;\n\n /**\n * A function that returns the root element to start walking the DOM from.\n *\n * Default: `window.document.body`\n */\n rootElement?: () => HTMLElement | undefined;\n\n /**\n * Called for each HTMLElement as we walk the DOM.\n *\n * Return an object to include the element with any additional properties.\n * Return `skip` to exclude the element and its children.\n * Return `children` to skip the element but include its children.\n */\n onElement?: (prop: OnElementArgs) => Record<string, string | number | boolean> | 'skip' | 'children';\n}\n\n/**\n * An integration to include a view hierarchy attachment which contains the DOM.\n */\nexport const viewHierarchyIntegration = defineIntegration((options: Options = {}) => {\n const skipHtmlTags = ['script'];\n\n /** Walk an element */\n function walk(element: HTMLElement, windows: ViewHierarchyWindow[], depth = 0): void {\n if (!element) {\n return;\n }\n\n // With Web Components, we need to walk into shadow DOMs\n const children = 'shadowRoot' in element && element.shadowRoot ? element.shadowRoot.children : element.children;\n\n for (const child of children) {\n if (!(child instanceof HTMLElement)) {\n continue;\n }\n\n const componentName = getComponentName(child, 1) || undefined;\n const tagName = child.tagName.toLowerCase();\n\n if (skipHtmlTags.includes(tagName)) {\n continue;\n }\n\n const result = options.onElement?.({ element: child, componentName, tagName, depth }) || {};\n\n if (result === 'skip') {\n continue;\n }\n\n // Skip this element but include its children\n if (result === 'children') {\n walk(child, windows, depth + 1);\n continue;\n }\n\n const { x, y, width, height } = child.getBoundingClientRect();\n\n const window: ViewHierarchyWindow = {\n identifier: (child.id || undefined) as string,\n type: componentName || tagName,\n visible: true,\n alpha: 1,\n height,\n width,\n x,\n y,\n ...result,\n };\n\n const children: ViewHierarchyWindow[] = [];\n window.children = children;\n\n // Recursively walk the children\n walk(child, window.children, depth + 1);\n\n windows.push(window);\n }\n }\n\n return {\n name: 'ViewHierarchy' as const,\n processEvent: (event, hint) => {\n // only capture for error events\n if (event.type !== undefined || options.shouldAttach?.(event, hint) === false) {\n return event;\n }\n\n const root: ViewHierarchyData = {\n rendering_system: 'DOM',\n positioning: 'absolute',\n windows: [],\n };\n\n walk(options.rootElement?.() || WINDOW.document.body, root.windows);\n\n const attachment: Attachment = {\n filename: 'view-hierarchy.json',\n attachmentType: 'event.view_hierarchy',\n contentType: 'application/json',\n data: JSON.stringify(root),\n };\n\n hint.attachments = hint.attachments || [];\n hint.attachments.push(attachment);\n\n return event;\n },\n };\n});\n"],"names":["defineIntegration","getComponentName","children","WINDOW"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"webVitals.js","sources":["../../../../../src/integrations/webVitals.ts"],"sourcesContent":["import type { IntegrationFn, Span } from '@sentry/core/browser';\nimport { defineIntegration, hasSpanStreamingEnabled } from '@sentry/core/browser';\nimport {\n addWebVitalsToSpan,\n registerInpInteractionListener,\n startTrackingINP,\n startTrackingWebVitals,\n trackClsAsSpan,\n trackInpAsSpan,\n trackLcpAsSpan,\n} from '@sentry/browser-utils';\n\nexport const WEB_VITALS_INTEGRATION_NAME = 'WebVitals';\n\nexport type WebVitalName = 'cls' | 'inp' | 'lcp';\n\nexport interface WebVitalsOptions {\n /**\n * Web vitals to skip.\n */\n ignore?: WebVitalName[];\n\n /**\n * @experimental\n */\n _experiments?: Partial<{\n enableStandaloneClsSpans: boolean;\n enableStandaloneLcpSpans: boolean;\n }>;\n}\n\n/**\n * Captures Core Web Vitals (LCP, CLS, INP) and related pageload vitals.\n *\n * `browserTracingIntegration` auto-registers this integration if no\n * `webVitalsIntegration` is already present, so explicit registration is only\n * needed to customize options or to use it without `browserTracingIntegration`.\n */\nexport const webVitalsIntegration = defineIntegration((options: WebVitalsOptions = {}) => {\n const ignored = new Set(options.ignore ?? []);\n\n return {\n name: WEB_VITALS_INTEGRATION_NAME,\n setup(client) {\n const spanStreamingEnabled = hasSpanStreamingEnabled(client);\n const { enableStandaloneClsSpans, enableStandaloneLcpSpans } = options._experiments ?? {};\n\n const recordClsStandaloneSpans =\n spanStreamingEnabled || ignored.has('cls') ? undefined : enableStandaloneClsSpans || false;\n const recordLcpStandaloneSpans =\n spanStreamingEnabled || ignored.has('lcp') ? undefined : enableStandaloneLcpSpans || false;\n\n // eslint-disable-next-line typescript/no-deprecated\n const finalizeWebVitals = startTrackingWebVitals({\n recordClsStandaloneSpans,\n recordLcpStandaloneSpans,\n client,\n });\n\n const pageloadSpans = new WeakSet<Span>();\n\n client.on('afterStartPageLoadSpan', span => {\n pageloadSpans.add(span);\n });\n\n client.on('spanEnd', span => {\n if (!pageloadSpans.delete(span)) {\n return;\n }\n\n finalizeWebVitals();\n addWebVitalsToSpan(span, {\n // CLS/LCP are recorded as pageload span measurements only when they're neither\n // tracked as standalone spans nor handled by span streaming (and not ignored).\n recordClsOnPageloadSpan: recordClsStandaloneSpans === false,\n recordLcpOnPageloadSpan: recordLcpStandaloneSpans === false,\n spanStreamingEnabled,\n });\n });\n\n if (spanStreamingEnabled) {\n if (!ignored.has('lcp')) {\n trackLcpAsSpan(client);\n }\n if (!ignored.has('cls')) {\n trackClsAsSpan(client);\n }\n if (!ignored.has('inp')) {\n trackInpAsSpan();\n }\n } else if (!ignored.has('inp')) {\n startTrackingINP();\n }\n },\n afterAllSetup() {\n if (!ignored.has('inp')) {\n registerInpInteractionListener();\n }\n },\n };\n}) satisfies IntegrationFn;\n"],"names":["defineIntegration","hasSpanStreamingEnabled","startTrackingWebVitals","addWebVitalsToSpan","trackLcpAsSpan","trackClsAsSpan","trackInpAsSpan","startTrackingINP","registerInpInteractionListener"],"mappings":";;;;;AAYO,MAAM,2BAAA,GAA8B;AA0BpC,MAAM,oBAAA,GAAuBA,yBAAA,CAAkB,CAAC,OAAA,GAA4B,EAAC,KAAM;AACxF,EAAA,MAAM,UAAU,IAAI,GAAA,CAAI,OAAA,CAAQ,MAAA,IAAU,EAAE,CAAA;AAE5C,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,2BAAA;AAAA,IACN,MAAM,MAAA,EAAQ;AACZ,MAAA,MAAM,oBAAA,GAAuBC,gCAAwB,MAAM,CAAA;AAC3D,MAAA,MAAM,EAAE,wBAAA,EAA0B,wBAAA,EAAyB,GAAI,OAAA,CAAQ,gBAAgB,EAAC;AAExF,MAAA,MAAM,2BACJ,oBAAA,IAAwB,OAAA,CAAQ,IAAI,KAAK,CAAA,GAAI,SAAY,wBAAA,IAA4B,KAAA;AACvF,MAAA,MAAM,2BACJ,oBAAA,IAAwB,OAAA,CAAQ,IAAI,KAAK,CAAA,GAAI,SAAY,wBAAA,IAA4B,KAAA;AAGvF,MAAA,MAAM,oBAAoBC,mCAAA,CAAuB;AAAA,QAC/C,wBAAA;AAAA,QACA,wBAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,MAAM,aAAA,uBAAoB,OAAA,EAAc;AAExC,MAAA,MAAA,CAAO,EAAA,CAAG,0BAA0B,CAAA,IAAA,KAAQ;AAC1C,QAAA,aAAA,CAAc,IAAI,IAAI,CAAA;AAAA,MACxB,CAAC,CAAA;AAED,MAAA,MAAA,CAAO,EAAA,CAAG,WAAW,CAAA,IAAA,KAAQ;AAC3B,QAAA,IAAI,CAAC,aAAA,CAAc,MAAA,CAAO,IAAI,CAAA,EAAG;AAC/B,UAAA;AAAA,QACF;AAEA,QAAA,iBAAA,EAAkB;AAClB,QAAAC,+BAAA,CAAmB,IAAA,EAAM;AAAA;AAAA;AAAA,UAGvB,yBAAyB,wBAAA,KAA6B,KAAA;AAAA,UACtD,yBAAyB,wBAAA,KAA6B,KAAA;AAAA,UACtD;AAAA,SACD,CAAA;AAAA,MACH,CAAC,CAAA;AAED,MAAA,IAAI,oBAAA,EAAsB;AACxB,QAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACvB,UAAAC,2BAAA,CAAe,MAAM,CAAA;AAAA,QACvB;AACA,QAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACvB,UAAAC,2BAAA,CAAe,MAAM,CAAA;AAAA,QACvB;AACA,QAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACvB,UAAAC,2BAAA,EAAe;AAAA,QACjB;AAAA,MACF,CAAA,MAAA,IAAW,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,QAAAC,6BAAA,EAAiB;AAAA,MACnB;AAAA,IACF,CAAA;AAAA,IACA,aAAA,GAAgB;AACd,MAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACvB,QAAAC,2CAAA,EAA+B;AAAA,MACjC;AAAA,IACF;AAAA,GACF;AACF,CAAC;;;;;"}
1
+ {"version":3,"file":"webVitals.js","sources":["../../../../../src/integrations/webVitals.ts"],"sourcesContent":["import type { IntegrationFn, Span } from '@sentry/core/browser';\nimport { defineIntegration, hasSpanStreamingEnabled } from '@sentry/core/browser';\nimport {\n addWebVitalsToSpan,\n registerInpInteractionListener,\n startTrackingINP,\n startTrackingWebVitals,\n trackClsAsSpan,\n trackInpAsSpan,\n trackLcpAsSpan,\n} from '@sentry/browser-utils';\n\nexport const WEB_VITALS_INTEGRATION_NAME = 'WebVitals' as const;\n\nexport type WebVitalName = 'cls' | 'inp' | 'lcp';\n\nexport interface WebVitalsOptions {\n /**\n * Web vitals to skip.\n */\n ignore?: WebVitalName[];\n\n /**\n * @experimental\n */\n _experiments?: Partial<{\n enableStandaloneClsSpans: boolean;\n enableStandaloneLcpSpans: boolean;\n }>;\n}\n\n/**\n * Captures Core Web Vitals (LCP, CLS, INP) and related pageload vitals.\n *\n * `browserTracingIntegration` auto-registers this integration if no\n * `webVitalsIntegration` is already present, so explicit registration is only\n * needed to customize options or to use it without `browserTracingIntegration`.\n */\nexport const webVitalsIntegration = defineIntegration((options: WebVitalsOptions = {}) => {\n const ignored = new Set(options.ignore ?? []);\n\n return {\n name: WEB_VITALS_INTEGRATION_NAME,\n setup(client) {\n const spanStreamingEnabled = hasSpanStreamingEnabled(client);\n const { enableStandaloneClsSpans, enableStandaloneLcpSpans } = options._experiments ?? {};\n\n const recordClsStandaloneSpans =\n spanStreamingEnabled || ignored.has('cls') ? undefined : enableStandaloneClsSpans || false;\n const recordLcpStandaloneSpans =\n spanStreamingEnabled || ignored.has('lcp') ? undefined : enableStandaloneLcpSpans || false;\n\n // eslint-disable-next-line typescript/no-deprecated\n const finalizeWebVitals = startTrackingWebVitals({\n recordClsStandaloneSpans,\n recordLcpStandaloneSpans,\n client,\n });\n\n const pageloadSpans = new WeakSet<Span>();\n\n client.on('afterStartPageLoadSpan', span => {\n pageloadSpans.add(span);\n });\n\n client.on('spanEnd', span => {\n if (!pageloadSpans.delete(span)) {\n return;\n }\n\n finalizeWebVitals();\n addWebVitalsToSpan(span, {\n // CLS/LCP are recorded as pageload span measurements only when they're neither\n // tracked as standalone spans nor handled by span streaming (and not ignored).\n recordClsOnPageloadSpan: recordClsStandaloneSpans === false,\n recordLcpOnPageloadSpan: recordLcpStandaloneSpans === false,\n spanStreamingEnabled,\n });\n });\n\n if (spanStreamingEnabled) {\n if (!ignored.has('lcp')) {\n trackLcpAsSpan(client);\n }\n if (!ignored.has('cls')) {\n trackClsAsSpan(client);\n }\n if (!ignored.has('inp')) {\n trackInpAsSpan();\n }\n } else if (!ignored.has('inp')) {\n startTrackingINP();\n }\n },\n afterAllSetup() {\n if (!ignored.has('inp')) {\n registerInpInteractionListener();\n }\n },\n };\n}) satisfies IntegrationFn;\n"],"names":["defineIntegration","hasSpanStreamingEnabled","startTrackingWebVitals","addWebVitalsToSpan","trackLcpAsSpan","trackClsAsSpan","trackInpAsSpan","startTrackingINP","registerInpInteractionListener"],"mappings":";;;;;AAYO,MAAM,2BAAA,GAA8B;AA0BpC,MAAM,oBAAA,GAAuBA,yBAAA,CAAkB,CAAC,OAAA,GAA4B,EAAC,KAAM;AACxF,EAAA,MAAM,UAAU,IAAI,GAAA,CAAI,OAAA,CAAQ,MAAA,IAAU,EAAE,CAAA;AAE5C,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,2BAAA;AAAA,IACN,MAAM,MAAA,EAAQ;AACZ,MAAA,MAAM,oBAAA,GAAuBC,gCAAwB,MAAM,CAAA;AAC3D,MAAA,MAAM,EAAE,wBAAA,EAA0B,wBAAA,EAAyB,GAAI,OAAA,CAAQ,gBAAgB,EAAC;AAExF,MAAA,MAAM,2BACJ,oBAAA,IAAwB,OAAA,CAAQ,IAAI,KAAK,CAAA,GAAI,SAAY,wBAAA,IAA4B,KAAA;AACvF,MAAA,MAAM,2BACJ,oBAAA,IAAwB,OAAA,CAAQ,IAAI,KAAK,CAAA,GAAI,SAAY,wBAAA,IAA4B,KAAA;AAGvF,MAAA,MAAM,oBAAoBC,mCAAA,CAAuB;AAAA,QAC/C,wBAAA;AAAA,QACA,wBAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,MAAM,aAAA,uBAAoB,OAAA,EAAc;AAExC,MAAA,MAAA,CAAO,EAAA,CAAG,0BAA0B,CAAA,IAAA,KAAQ;AAC1C,QAAA,aAAA,CAAc,IAAI,IAAI,CAAA;AAAA,MACxB,CAAC,CAAA;AAED,MAAA,MAAA,CAAO,EAAA,CAAG,WAAW,CAAA,IAAA,KAAQ;AAC3B,QAAA,IAAI,CAAC,aAAA,CAAc,MAAA,CAAO,IAAI,CAAA,EAAG;AAC/B,UAAA;AAAA,QACF;AAEA,QAAA,iBAAA,EAAkB;AAClB,QAAAC,+BAAA,CAAmB,IAAA,EAAM;AAAA;AAAA;AAAA,UAGvB,yBAAyB,wBAAA,KAA6B,KAAA;AAAA,UACtD,yBAAyB,wBAAA,KAA6B,KAAA;AAAA,UACtD;AAAA,SACD,CAAA;AAAA,MACH,CAAC,CAAA;AAED,MAAA,IAAI,oBAAA,EAAsB;AACxB,QAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACvB,UAAAC,2BAAA,CAAe,MAAM,CAAA;AAAA,QACvB;AACA,QAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACvB,UAAAC,2BAAA,CAAe,MAAM,CAAA;AAAA,QACvB;AACA,QAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACvB,UAAAC,2BAAA,EAAe;AAAA,QACjB;AAAA,MACF,CAAA,MAAA,IAAW,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,QAAAC,6BAAA,EAAiB;AAAA,MACnB;AAAA,IACF,CAAA;AAAA,IACA,aAAA,GAAgB;AACd,MAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AACvB,QAAAC,2CAAA,EAA+B;AAAA,MACjC;AAAA,IACF;AAAA,GACF;AACF,CAAC;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"webWorker.js","sources":["../../../../../src/integrations/webWorker.ts"],"sourcesContent":["import type { DebugImage, Integration, IntegrationFn } from '@sentry/core/browser';\nimport { captureEvent, debug, defineIntegration, getClient, isPlainObject, isPrimitive } from '@sentry/core/browser';\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","worker","DEBUG_BUILD","debug","WINDOW","isPlainObject","getClient","isPrimitive","_eventFromRejectionWithPrimitive","eventFromUnknownInput","captureEvent","_getUnhandledRejectionError"],"mappings":";;;;;;;;AAOO,MAAM,gBAAA,GAAmB;AAgGzB,MAAM,oBAAA,GAAuBA,yBAAA,CAAkB,CAAC,EAAE,QAAO,MAAoC;AAAA,EAClG,IAAA,EAAM,gBAAA;AAAA,EACN,WAAW,MAAM;AACf,IAAA,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAI,MAAA,GAAS,CAAC,MAAM,CAAA,EAAG,OAAA,CAAQ,CAAA,CAAA,KAAK,uBAAA,CAAwB,CAAC,CAAC,CAAA;AAAA,EACrF,CAAA;AAAA,EACA,SAAA,EAAW,CAACC,OAAAA,KAAmB,uBAAA,CAAwBA,OAAM;AAC/D,CAAA,CAAE;AAEF,SAAS,wBAAwB,MAAA,EAAsB;AACrD,EAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,CAAA,KAAA,KAAS;AAC1C,IAAA,IAAI,eAAA,CAAgB,KAAA,CAAM,IAAI,CAAA,EAAG;AAC/B,MAAA,KAAA,CAAM,wBAAA,EAAyB;AAG/B,MAAA,IAAI,KAAA,CAAM,KAAK,eAAA,EAAiB;AAC9B,QAAAC,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,4CAAA,EAA8C,KAAA,CAAM,IAAI,CAAA;AACjF,QAAAC,cAAA,CAAO,eAAA,GAAkB;AAAA,UACvB,GAAG,MAAM,IAAA,CAAK,eAAA;AAAA;AAAA,UAEd,GAAGA,cAAA,CAAO;AAAA,SACZ;AAAA,MACF;AAGA,MAAA,IAAI,KAAA,CAAM,KAAK,qBAAA,EAAuB;AACpC,QAAAF,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,oDAAA,EAAsD,KAAA,CAAM,IAAI,CAAA;AAGzF,QAAAC,cAAA,CAAO,qBAAA,GAAwB;AAAA,UAC7B,GAAG,MAAM,IAAA,CAAK,qBAAA;AAAA;AAAA,UAEd,GAAGA,cAAA,CAAO;AAAA,SACZ;AAAA,MACF;AAGA,MAAA,IAAI,KAAA,CAAM,KAAK,iBAAA,EAAmB;AAChC,QAAAF,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,gDAAA,EAAkD,KAAA,CAAM,IAAI,CAAA;AACrF,QAAA,MAAM,cAAA,GACHC,cAAA,CAAqE,iBAAA,IAAqB,EAAC;AAC9F,QAAA,MAAM,SAAA,GAAY,KAAA,CAAM,IAAA,CAAK,iBAAA,CAAkB,MAAA;AAAA,UAC7C,CAAC,MAAA,KACCC,qBAAA,CAAc,MAAM,CAAA,IACpB,OAAO,MAAA,CAAO,SAAA,KAAc,QAAA,IAC5B,CAAC,eAAe,IAAA,CAAK,CAAA,QAAA,KAAY,QAAA,CAAS,SAAA,KAAc,OAAO,SAAS;AAAA,SAC5E;AACA,QAACD,eAAqE,iBAAA,GAAoB;AAAA,UACxF,GAAG,cAAA;AAAA,UACH,GAAG;AAAA,SACL;AAAA,MACF;AAGA,MAAA,IAAI,KAAA,CAAM,KAAK,kBAAA,EAAoB;AACjC,QAAAF,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,0CAAA,EAA4C,KAAA,CAAM,KAAK,kBAAkB,CAAA;AAClG,QAAA,8BAAA,CAA+B,KAAA,CAAM,KAAK,kBAAkB,CAAA;AAAA,MAC9D;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH;AAEA,SAAS,+BAA+B,WAAA,EAA0C;AAChF,EAAA,MAAM,SAASG,iBAAA,EAAU;AACzB,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,UAAA,EAAW,CAAE,WAAA;AACxC,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAAO,UAAA,EAAW,CAAE,gBAAA;AAE7C,EAAA,MAAM,QAAQ,WAAA,CAAY,MAAA;AAI1B,EAAA,MAAM,KAAA,GAAQC,mBAAA,CAAY,KAAK,CAAA,GAC3BC,+CAAA,CAAiC,KAAK,CAAA,GACtCC,kCAAA,CAAsB,WAAA,EAAa,KAAA,EAAO,MAAA,EAAW,gBAAA,EAAkB,IAAI,CAAA;AAE/E,EAAA,KAAA,CAAM,KAAA,GAAQ,OAAA;AAGd,EAAA,IAAI,YAAY,QAAA,EAAU;AACxB,IAAA,KAAA,CAAM,QAAA,GAAW;AAAA,MACf,GAAG,KAAA,CAAM,QAAA;AAAA,MACT,MAAA,EAAQ;AAAA,QACN,UAAU,WAAA,CAAY;AAAA;AACxB,KACF;AAAA,EACF;AAEA,EAAAC,oBAAA,CAAa,KAAA,EAAO;AAAA,IAClB,iBAAA,EAAmB,KAAA;AAAA,IACnB,SAAA,EAAW;AAAA,MACT,OAAA,EAAS,KAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR,GACD,CAAA;AAED,EAAAR,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,qCAAA,EAAuC,KAAK,CAAA;AACvE;AAiDO,SAAS,iBAAA,CAAkB,EAAE,IAAA,EAAK,EAAmC;AAG1E,EAAA,IAAA,CAAK,WAAA,CAAY;AAAA,IACf,cAAA,EAAgB,IAAA;AAAA,IAChB,eAAA,EAAiB,KAAK,eAAA,IAAmB,MAAA;AAAA,IACzC,qBAAA,EAAuB,KAAK,qBAAA,IAAyB;AAAA,GACtD,CAAA;AAKD,EAAA,IAAA,CAAK,gBAAA,CAAiB,oBAAA,EAAsB,CAAC,KAAA,KAAmB;AAC9D,IAAA,MAAM,MAAA,GAASQ,2CAA4B,KAAK,CAAA;AAIhD,IAAA,MAAM,eAAA,GAAyC;AAAA,MAC7C,MAAA;AAAA,MACA,QAAA,EAAU,KAAK,QAAA,EAAU;AAAA,KAC3B;AAGA,IAAA,IAAA,CAAK,WAAA,CAAY;AAAA,MACf,cAAA,EAAgB,IAAA;AAAA,MAChB,kBAAA,EAAoB;AAAA,KACrB,CAAA;AAED,IAAAT,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,0DAAA,EAA4D,eAAe,CAAA;AAAA,EACtG,CAAC,CAAA;AAED,EAAAD,sBAAA,IAAeC,aAAA,CAAM,IAAI,qEAAqE,CAAA;AAChG;AAEA,SAAS,gBAAgB,SAAA,EAAmD;AAC1E,EAAA,IAAI,CAACE,qBAAA,CAAc,SAAS,CAAA,IAAK,SAAA,CAAU,mBAAmB,IAAA,EAAM;AAClE,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,cAAc,iBAAA,IAAqB,SAAA;AACzC,EAAA,MAAM,oBAAoB,uBAAA,IAA2B,SAAA;AACrD,EAAA,MAAM,iBAAiB,oBAAA,IAAwB,SAAA;AAC/C,EAAA,MAAM,gBAAgB,mBAAA,IAAuB,SAAA;AAE7C,EAAA,IAAI,CAAC,WAAA,IAAe,CAAC,qBAAqB,CAAC,cAAA,IAAkB,CAAC,aAAA,EAAe;AAC3E,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,WAAA,IAAe,EAAEA,qBAAA,CAAc,SAAA,CAAU,eAAe,CAAA,IAAK,SAAA,CAAU,oBAAoB,MAAA,CAAA,EAAY;AACzG,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IACE,iBAAA,IACA,EAAEA,qBAAA,CAAc,SAAA,CAAU,qBAAqB,CAAA,IAAK,SAAA,CAAU,0BAA0B,MAAA,CAAA,EACxF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,cAAA,IAAkB,CAACA,qBAAA,CAAc,SAAA,CAAU,kBAAkB,CAAA,EAAG;AAClE,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IACE,aAAA,KACC,CAAC,KAAA,CAAM,OAAA,CAAQ,UAAU,iBAAiB,CAAA,IACzC,CAAC,SAAA,CAAU,iBAAA,CAAkB,KAAA;AAAA,IAC3B,CAAC,GAAA,KAAiBA,qBAAA,CAAc,GAAG,CAAA,IAAK,OAAQ,IAAgC,SAAA,KAAc;AAAA,GAChG,CAAA,EACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA;AACT;;;;;;"}
1
+ {"version":3,"file":"webWorker.js","sources":["../../../../../src/integrations/webWorker.ts"],"sourcesContent":["import type { DebugImage, Integration, IntegrationFn } from '@sentry/core/browser';\nimport { captureEvent, debug, defineIntegration, getClient, isPlainObject, isPrimitive } from '@sentry/core/browser';\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' as const;\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","worker","DEBUG_BUILD","debug","WINDOW","isPlainObject","getClient","isPrimitive","_eventFromRejectionWithPrimitive","eventFromUnknownInput","captureEvent","_getUnhandledRejectionError"],"mappings":";;;;;;;;AAOO,MAAM,gBAAA,GAAmB;AAgGzB,MAAM,oBAAA,GAAuBA,yBAAA,CAAkB,CAAC,EAAE,QAAO,MAAoC;AAAA,EAClG,IAAA,EAAM,gBAAA;AAAA,EACN,WAAW,MAAM;AACf,IAAA,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAI,MAAA,GAAS,CAAC,MAAM,CAAA,EAAG,OAAA,CAAQ,CAAA,CAAA,KAAK,uBAAA,CAAwB,CAAC,CAAC,CAAA;AAAA,EACrF,CAAA;AAAA,EACA,SAAA,EAAW,CAACC,OAAAA,KAAmB,uBAAA,CAAwBA,OAAM;AAC/D,CAAA,CAAE;AAEF,SAAS,wBAAwB,MAAA,EAAsB;AACrD,EAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,CAAA,KAAA,KAAS;AAC1C,IAAA,IAAI,eAAA,CAAgB,KAAA,CAAM,IAAI,CAAA,EAAG;AAC/B,MAAA,KAAA,CAAM,wBAAA,EAAyB;AAG/B,MAAA,IAAI,KAAA,CAAM,KAAK,eAAA,EAAiB;AAC9B,QAAAC,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,4CAAA,EAA8C,KAAA,CAAM,IAAI,CAAA;AACjF,QAAAC,cAAA,CAAO,eAAA,GAAkB;AAAA,UACvB,GAAG,MAAM,IAAA,CAAK,eAAA;AAAA;AAAA,UAEd,GAAGA,cAAA,CAAO;AAAA,SACZ;AAAA,MACF;AAGA,MAAA,IAAI,KAAA,CAAM,KAAK,qBAAA,EAAuB;AACpC,QAAAF,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,oDAAA,EAAsD,KAAA,CAAM,IAAI,CAAA;AAGzF,QAAAC,cAAA,CAAO,qBAAA,GAAwB;AAAA,UAC7B,GAAG,MAAM,IAAA,CAAK,qBAAA;AAAA;AAAA,UAEd,GAAGA,cAAA,CAAO;AAAA,SACZ;AAAA,MACF;AAGA,MAAA,IAAI,KAAA,CAAM,KAAK,iBAAA,EAAmB;AAChC,QAAAF,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,gDAAA,EAAkD,KAAA,CAAM,IAAI,CAAA;AACrF,QAAA,MAAM,cAAA,GACHC,cAAA,CAAqE,iBAAA,IAAqB,EAAC;AAC9F,QAAA,MAAM,SAAA,GAAY,KAAA,CAAM,IAAA,CAAK,iBAAA,CAAkB,MAAA;AAAA,UAC7C,CAAC,MAAA,KACCC,qBAAA,CAAc,MAAM,CAAA,IACpB,OAAO,MAAA,CAAO,SAAA,KAAc,QAAA,IAC5B,CAAC,eAAe,IAAA,CAAK,CAAA,QAAA,KAAY,QAAA,CAAS,SAAA,KAAc,OAAO,SAAS;AAAA,SAC5E;AACA,QAACD,eAAqE,iBAAA,GAAoB;AAAA,UACxF,GAAG,cAAA;AAAA,UACH,GAAG;AAAA,SACL;AAAA,MACF;AAGA,MAAA,IAAI,KAAA,CAAM,KAAK,kBAAA,EAAoB;AACjC,QAAAF,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,0CAAA,EAA4C,KAAA,CAAM,KAAK,kBAAkB,CAAA;AAClG,QAAA,8BAAA,CAA+B,KAAA,CAAM,KAAK,kBAAkB,CAAA;AAAA,MAC9D;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH;AAEA,SAAS,+BAA+B,WAAA,EAA0C;AAChF,EAAA,MAAM,SAASG,iBAAA,EAAU;AACzB,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,UAAA,EAAW,CAAE,WAAA;AACxC,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAAO,UAAA,EAAW,CAAE,gBAAA;AAE7C,EAAA,MAAM,QAAQ,WAAA,CAAY,MAAA;AAI1B,EAAA,MAAM,KAAA,GAAQC,mBAAA,CAAY,KAAK,CAAA,GAC3BC,+CAAA,CAAiC,KAAK,CAAA,GACtCC,kCAAA,CAAsB,WAAA,EAAa,KAAA,EAAO,MAAA,EAAW,gBAAA,EAAkB,IAAI,CAAA;AAE/E,EAAA,KAAA,CAAM,KAAA,GAAQ,OAAA;AAGd,EAAA,IAAI,YAAY,QAAA,EAAU;AACxB,IAAA,KAAA,CAAM,QAAA,GAAW;AAAA,MACf,GAAG,KAAA,CAAM,QAAA;AAAA,MACT,MAAA,EAAQ;AAAA,QACN,UAAU,WAAA,CAAY;AAAA;AACxB,KACF;AAAA,EACF;AAEA,EAAAC,oBAAA,CAAa,KAAA,EAAO;AAAA,IAClB,iBAAA,EAAmB,KAAA;AAAA,IACnB,SAAA,EAAW;AAAA,MACT,OAAA,EAAS,KAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR,GACD,CAAA;AAED,EAAAR,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,qCAAA,EAAuC,KAAK,CAAA;AACvE;AAiDO,SAAS,iBAAA,CAAkB,EAAE,IAAA,EAAK,EAAmC;AAG1E,EAAA,IAAA,CAAK,WAAA,CAAY;AAAA,IACf,cAAA,EAAgB,IAAA;AAAA,IAChB,eAAA,EAAiB,KAAK,eAAA,IAAmB,MAAA;AAAA,IACzC,qBAAA,EAAuB,KAAK,qBAAA,IAAyB;AAAA,GACtD,CAAA;AAKD,EAAA,IAAA,CAAK,gBAAA,CAAiB,oBAAA,EAAsB,CAAC,KAAA,KAAmB;AAC9D,IAAA,MAAM,MAAA,GAASQ,2CAA4B,KAAK,CAAA;AAIhD,IAAA,MAAM,eAAA,GAAyC;AAAA,MAC7C,MAAA;AAAA,MACA,QAAA,EAAU,KAAK,QAAA,EAAU;AAAA,KAC3B;AAGA,IAAA,IAAA,CAAK,WAAA,CAAY;AAAA,MACf,cAAA,EAAgB,IAAA;AAAA,MAChB,kBAAA,EAAoB;AAAA,KACrB,CAAA;AAED,IAAAT,sBAAA,IAAeC,aAAA,CAAM,GAAA,CAAI,0DAAA,EAA4D,eAAe,CAAA;AAAA,EACtG,CAAC,CAAA;AAED,EAAAD,sBAAA,IAAeC,aAAA,CAAM,IAAI,qEAAqE,CAAA;AAChG;AAEA,SAAS,gBAAgB,SAAA,EAAmD;AAC1E,EAAA,IAAI,CAACE,qBAAA,CAAc,SAAS,CAAA,IAAK,SAAA,CAAU,mBAAmB,IAAA,EAAM;AAClE,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,cAAc,iBAAA,IAAqB,SAAA;AACzC,EAAA,MAAM,oBAAoB,uBAAA,IAA2B,SAAA;AACrD,EAAA,MAAM,iBAAiB,oBAAA,IAAwB,SAAA;AAC/C,EAAA,MAAM,gBAAgB,mBAAA,IAAuB,SAAA;AAE7C,EAAA,IAAI,CAAC,WAAA,IAAe,CAAC,qBAAqB,CAAC,cAAA,IAAkB,CAAC,aAAA,EAAe;AAC3E,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,WAAA,IAAe,EAAEA,qBAAA,CAAc,SAAA,CAAU,eAAe,CAAA,IAAK,SAAA,CAAU,oBAAoB,MAAA,CAAA,EAAY;AACzG,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IACE,iBAAA,IACA,EAAEA,qBAAA,CAAc,SAAA,CAAU,qBAAqB,CAAA,IAAK,SAAA,CAAU,0BAA0B,MAAA,CAAA,EACxF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IAAI,cAAA,IAAkB,CAACA,qBAAA,CAAc,SAAA,CAAU,kBAAkB,CAAA,EAAG;AAClE,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IACE,aAAA,KACC,CAAC,KAAA,CAAM,OAAA,CAAQ,UAAU,iBAAiB,CAAA,IACzC,CAAC,SAAA,CAAU,iBAAA,CAAkB,KAAA;AAAA,IAC3B,CAAC,GAAA,KAAiBA,qBAAA,CAAc,GAAG,CAAA,IAAK,OAAQ,IAAgC,SAAA,KAAc;AAAA,GAChG,CAAA,EACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA;AACT;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"integration.js","sources":["../../../../../src/profiling/integration.ts"],"sourcesContent":["import type { EventEnvelope, IntegrationFn, Profile, Span } from '@sentry/core/browser';\nimport { debug, defineIntegration, getActiveSpan, getRootSpan, hasSpansEnabled } from '@sentry/core/browser';\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 createProfilingEvent,\n findProfiledTransactionsFromEnvelope,\n getActiveProfilesCount,\n hasLegacyProfiling,\n isAutomatedPageLoadSpan,\n PROFILED_ROOT_SPANS,\n setThreadAttributes,\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 typescript/no-deprecated\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 const rootSpan = getRootSpan(span);\n if (span === rootSpan) {\n if (shouldProfileSpanLegacy(span)) {\n startProfileForSpan(span);\n }\n } else if (PROFILED_ROOT_SPANS.has(rootSpan)) {\n setThreadAttributes(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 };\n}) satisfies IntegrationFn;\n\nexport const browserProfilingIntegration = defineIntegration(_browserProfilingIntegration);\n"],"names":["UIProfiler","hasLegacyProfiling","DEBUG_BUILD","debug","getActiveSpan","getRootSpan","hasSpansEnabled","WINDOW","isAutomatedPageLoadSpan","shouldProfileSpanLegacy","startProfileForSpan","rootSpan","PROFILED_ROOT_SPANS","setThreadAttributes","getActiveProfilesCount","findProfiledTransactionsFromEnvelope","takeProfileFromGlobalCache","createProfilingEvent","addProfilesToEnvelope","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/browser';\nimport { debug, defineIntegration, getActiveSpan, getRootSpan, hasSpansEnabled } from '@sentry/core/browser';\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 createProfilingEvent,\n findProfiledTransactionsFromEnvelope,\n getActiveProfilesCount,\n hasLegacyProfiling,\n isAutomatedPageLoadSpan,\n PROFILED_ROOT_SPANS,\n setThreadAttributes,\n shouldProfileSpanLegacy,\n takeProfileFromGlobalCache,\n} from './utils';\n\nconst INTEGRATION_NAME = 'BrowserProfiling' as const;\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 typescript/no-deprecated\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 const rootSpan = getRootSpan(span);\n if (span === rootSpan) {\n if (shouldProfileSpanLegacy(span)) {\n startProfileForSpan(span);\n }\n } else if (PROFILED_ROOT_SPANS.has(rootSpan)) {\n setThreadAttributes(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 };\n}) satisfies IntegrationFn;\n\nexport const browserProfilingIntegration = defineIntegration(_browserProfilingIntegration);\n"],"names":["UIProfiler","hasLegacyProfiling","DEBUG_BUILD","debug","getActiveSpan","getRootSpan","hasSpansEnabled","WINDOW","isAutomatedPageLoadSpan","shouldProfileSpanLegacy","startProfileForSpan","rootSpan","PROFILED_ROOT_SPANS","setThreadAttributes","getActiveProfilesCount","findProfiledTransactionsFromEnvelope","takeProfileFromGlobalCache","createProfilingEvent","addProfilesToEnvelope","defineIntegration"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"breadcrumbs.js","sources":["../../../../../src/integrations/breadcrumbs.ts"],"sourcesContent":["/* eslint-disable max-lines */\n\nimport type {\n Breadcrumb,\n Client,\n Event as SentryEvent,\n FetchBreadcrumbData,\n FetchBreadcrumbHint,\n HandlerDataConsole,\n HandlerDataDom,\n HandlerDataFetch,\n HandlerDataHistory,\n HandlerDataXhr,\n IntegrationFn,\n XhrBreadcrumbData,\n XhrBreadcrumbHint,\n} from '@sentry/core/browser';\nimport {\n addBreadcrumb,\n addConsoleInstrumentationHandler,\n addFetchInstrumentationHandler,\n debug,\n defineIntegration,\n getBreadcrumbLogLevelFromHttpStatusCode,\n getClient,\n getComponentName,\n getEventDescription,\n parseUrl,\n safeJoin,\n severityLevelFromString,\n} from '@sentry/core/browser';\nimport type { FetchHint, XhrHint } from '@sentry/browser-utils';\nimport {\n addClickKeypressInstrumentationHandler,\n addHistoryInstrumentationHandler,\n addXhrInstrumentationHandler,\n htmlTreeAsString,\n SENTRY_XHR_DATA_KEY,\n} from '@sentry/browser-utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\n\ninterface BreadcrumbsOptions {\n console: boolean;\n dom:\n | boolean\n | {\n serializeAttribute?: string | string[];\n maxStringLength?: number;\n };\n fetch: boolean;\n history: boolean;\n sentry: boolean;\n xhr: boolean;\n}\n\n/** maxStringLength gets capped to prevent 100 breadcrumbs exceeding 1MB event payload size */\nconst MAX_ALLOWED_STRING_LENGTH = 1024;\n\nconst INTEGRATION_NAME = 'Breadcrumbs';\n\nconst _breadcrumbsIntegration = ((options: Partial<BreadcrumbsOptions> = {}) => {\n const _options = {\n console: true,\n dom: true,\n fetch: true,\n history: true,\n sentry: true,\n xhr: true,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n // TODO(v11): Remove this functionality and use `consoleIntegration` from @sentry/core instead.\n if (_options.console) {\n addConsoleInstrumentationHandler(_getConsoleBreadcrumbHandler(client));\n }\n if (_options.dom) {\n addClickKeypressInstrumentationHandler(_getDomBreadcrumbHandler(client, _options.dom));\n }\n if (_options.xhr) {\n addXhrInstrumentationHandler(_getXhrBreadcrumbHandler(client));\n }\n if (_options.fetch) {\n addFetchInstrumentationHandler(_getFetchBreadcrumbHandler(client));\n }\n if (_options.history) {\n addHistoryInstrumentationHandler(_getHistoryBreadcrumbHandler(client));\n }\n if (_options.sentry) {\n client.on('beforeSendEvent', _getSentryBreadcrumbHandler(client));\n }\n },\n };\n}) satisfies IntegrationFn;\n\nexport const breadcrumbsIntegration = defineIntegration(_breadcrumbsIntegration);\n\n/**\n * Adds a breadcrumb for Sentry events or transactions if this option is enabled.\n */\nfunction _getSentryBreadcrumbHandler(client: Client): (event: SentryEvent) => void {\n return function addSentryBreadcrumb(event: SentryEvent): void {\n if (getClient() !== client) {\n return;\n }\n\n addBreadcrumb(\n {\n category: `sentry.${event.type === 'transaction' ? 'transaction' : 'event'}`,\n event_id: event.event_id,\n level: event.level,\n message: getEventDescription(event),\n },\n {\n event,\n },\n );\n };\n}\n\n/**\n * A HOC that creates a function that creates breadcrumbs from DOM API calls.\n * This is a HOC so that we get access to dom options in the closure.\n */\nfunction _getDomBreadcrumbHandler(\n client: Client,\n dom: BreadcrumbsOptions['dom'],\n): (handlerData: HandlerDataDom) => void {\n return function _innerDomBreadcrumb(handlerData: HandlerDataDom): void {\n if (getClient() !== client) {\n return;\n }\n\n let target;\n let componentName;\n let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;\n\n let maxStringLength =\n typeof dom === 'object' && typeof dom.maxStringLength === 'number' ? dom.maxStringLength : undefined;\n if (maxStringLength && maxStringLength > MAX_ALLOWED_STRING_LENGTH) {\n DEBUG_BUILD &&\n debug.warn(\n `\\`dom.maxStringLength\\` cannot exceed ${MAX_ALLOWED_STRING_LENGTH}, but a value of ${maxStringLength} was configured. Sentry will use ${MAX_ALLOWED_STRING_LENGTH} instead.`,\n );\n maxStringLength = MAX_ALLOWED_STRING_LENGTH;\n }\n\n if (typeof keyAttrs === 'string') {\n keyAttrs = [keyAttrs];\n }\n\n // Accessing event.target can throw (see getsentry/raven-js#838, #768)\n try {\n const event = handlerData.event as Event | Node;\n const element = _isEvent(event) ? event.target : event;\n\n target = htmlTreeAsString(element, { keyAttrs, maxStringLength });\n componentName = getComponentName(element);\n } catch {\n target = '<unknown>';\n }\n\n if (target.length === 0) {\n return;\n }\n\n const breadcrumb: Breadcrumb = {\n category: `ui.${handlerData.name}`,\n message: target,\n };\n\n if (componentName) {\n breadcrumb.data = { 'ui.component_name': componentName };\n }\n\n addBreadcrumb(breadcrumb, {\n event: handlerData.event,\n name: handlerData.name,\n global: handlerData.global,\n });\n };\n}\n\n/**\n * Creates breadcrumbs from console API calls\n */\nfunction _getConsoleBreadcrumbHandler(client: Client): (handlerData: HandlerDataConsole) => void {\n return function _consoleBreadcrumb(handlerData: HandlerDataConsole): void {\n if (getClient() !== client) {\n return;\n }\n\n const breadcrumb = {\n category: 'console',\n data: {\n arguments: handlerData.args,\n logger: 'console',\n },\n level: severityLevelFromString(handlerData.level),\n message: safeJoin(handlerData.args, ' '),\n };\n\n if (handlerData.level === 'assert') {\n if (handlerData.args[0] === false) {\n breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;\n breadcrumb.data.arguments = handlerData.args.slice(1);\n } else {\n // Don't capture a breadcrumb for passed assertions\n return;\n }\n }\n\n addBreadcrumb(breadcrumb, {\n input: handlerData.args,\n level: handlerData.level,\n });\n };\n}\n\n/**\n * Creates breadcrumbs from XHR API calls\n */\nfunction _getXhrBreadcrumbHandler(client: Client): (handlerData: HandlerDataXhr) => void {\n return function _xhrBreadcrumb(handlerData: HandlerDataXhr): void {\n if (getClient() !== client) {\n return;\n }\n\n const { startTimestamp, endTimestamp } = handlerData;\n\n const sentryXhrData = handlerData.xhr[SENTRY_XHR_DATA_KEY];\n\n // We only capture complete, non-sentry requests\n if (!startTimestamp || !endTimestamp || !sentryXhrData) {\n return;\n }\n\n const { method, url, status_code, body } = sentryXhrData;\n\n const data: XhrBreadcrumbData = {\n method,\n url,\n status_code,\n };\n\n const hint: XhrBreadcrumbHint = {\n xhr: handlerData.xhr,\n input: body,\n startTimestamp,\n endTimestamp,\n };\n\n const breadcrumb = {\n category: 'xhr',\n data,\n type: 'http',\n level: getBreadcrumbLogLevelFromHttpStatusCode(status_code),\n };\n\n client.emit('beforeOutgoingRequestBreadcrumb', breadcrumb, hint as XhrHint);\n\n addBreadcrumb(breadcrumb, hint);\n };\n}\n\n/**\n * Creates breadcrumbs from fetch API calls\n */\nfunction _getFetchBreadcrumbHandler(client: Client): (handlerData: HandlerDataFetch) => void {\n return function _fetchBreadcrumb(handlerData: HandlerDataFetch): void {\n if (getClient() !== client) {\n return;\n }\n\n const { startTimestamp, endTimestamp } = handlerData;\n\n // We only capture complete fetch requests\n if (!endTimestamp) {\n return;\n }\n\n if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {\n // We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)\n return;\n }\n\n if (handlerData.error) {\n const hint: FetchBreadcrumbHint = {\n data: handlerData.error,\n input: handlerData.args,\n startTimestamp,\n endTimestamp,\n };\n\n const breadcrumb = {\n category: 'fetch',\n data: handlerData.fetchData,\n level: 'error',\n type: 'http',\n } satisfies Breadcrumb;\n\n client.emit('beforeOutgoingRequestBreadcrumb', breadcrumb, hint as FetchHint);\n\n addBreadcrumb(breadcrumb, hint);\n } else {\n const response = handlerData.response as Response | undefined;\n const data: FetchBreadcrumbData = {\n ...handlerData.fetchData,\n status_code: response?.status,\n };\n\n const hint: FetchBreadcrumbHint = {\n input: handlerData.args,\n response,\n startTimestamp,\n endTimestamp,\n };\n\n const breadcrumb = {\n category: 'fetch',\n data,\n type: 'http',\n level: getBreadcrumbLogLevelFromHttpStatusCode(data.status_code),\n };\n\n client.emit('beforeOutgoingRequestBreadcrumb', breadcrumb, hint as FetchHint);\n\n addBreadcrumb(breadcrumb, hint);\n }\n };\n}\n\n/**\n * Creates breadcrumbs from history API calls\n */\nfunction _getHistoryBreadcrumbHandler(client: Client): (handlerData: HandlerDataHistory) => void {\n return function _historyBreadcrumb(handlerData: HandlerDataHistory): void {\n if (getClient() !== client) {\n return;\n }\n\n let from: string | undefined = handlerData.from;\n let to: string | undefined = handlerData.to;\n const parsedLoc = parseUrl(WINDOW.location.href);\n let parsedFrom = from ? parseUrl(from) : undefined;\n const parsedTo = parseUrl(to);\n\n // Initial pushState doesn't provide `from` information\n if (!parsedFrom?.path) {\n parsedFrom = parsedLoc;\n }\n\n // Use only the path component of the URL if the URL matches the current\n // document (almost all the time when using pushState)\n if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {\n to = parsedTo.relative;\n }\n if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {\n from = parsedFrom.relative;\n }\n\n addBreadcrumb({\n category: 'navigation',\n data: {\n from,\n to,\n },\n });\n };\n}\n\nfunction _isEvent(event: unknown): event is Event {\n return !!event && !!(event as Record<string, unknown>).target;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"breadcrumbs.js","sources":["../../../../../src/integrations/breadcrumbs.ts"],"sourcesContent":["/* eslint-disable max-lines */\n\nimport type {\n Breadcrumb,\n Client,\n Event as SentryEvent,\n FetchBreadcrumbData,\n FetchBreadcrumbHint,\n HandlerDataConsole,\n HandlerDataDom,\n HandlerDataFetch,\n HandlerDataHistory,\n HandlerDataXhr,\n IntegrationFn,\n XhrBreadcrumbData,\n XhrBreadcrumbHint,\n} from '@sentry/core/browser';\nimport {\n addBreadcrumb,\n addConsoleInstrumentationHandler,\n addFetchInstrumentationHandler,\n debug,\n defineIntegration,\n getBreadcrumbLogLevelFromHttpStatusCode,\n getClient,\n getComponentName,\n getEventDescription,\n parseUrl,\n safeJoin,\n severityLevelFromString,\n} from '@sentry/core/browser';\nimport type { FetchHint, XhrHint } from '@sentry/browser-utils';\nimport {\n addClickKeypressInstrumentationHandler,\n addHistoryInstrumentationHandler,\n addXhrInstrumentationHandler,\n htmlTreeAsString,\n SENTRY_XHR_DATA_KEY,\n} from '@sentry/browser-utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\n\ninterface BreadcrumbsOptions {\n console: boolean;\n dom:\n | boolean\n | {\n serializeAttribute?: string | string[];\n maxStringLength?: number;\n };\n fetch: boolean;\n history: boolean;\n sentry: boolean;\n xhr: boolean;\n}\n\n/** maxStringLength gets capped to prevent 100 breadcrumbs exceeding 1MB event payload size */\nconst MAX_ALLOWED_STRING_LENGTH = 1024;\n\nconst INTEGRATION_NAME = 'Breadcrumbs' as const;\n\nconst _breadcrumbsIntegration = ((options: Partial<BreadcrumbsOptions> = {}) => {\n const _options = {\n console: true,\n dom: true,\n fetch: true,\n history: true,\n sentry: true,\n xhr: true,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n // TODO(v11): Remove this functionality and use `consoleIntegration` from @sentry/core instead.\n if (_options.console) {\n addConsoleInstrumentationHandler(_getConsoleBreadcrumbHandler(client));\n }\n if (_options.dom) {\n addClickKeypressInstrumentationHandler(_getDomBreadcrumbHandler(client, _options.dom));\n }\n if (_options.xhr) {\n addXhrInstrumentationHandler(_getXhrBreadcrumbHandler(client));\n }\n if (_options.fetch) {\n addFetchInstrumentationHandler(_getFetchBreadcrumbHandler(client));\n }\n if (_options.history) {\n addHistoryInstrumentationHandler(_getHistoryBreadcrumbHandler(client));\n }\n if (_options.sentry) {\n client.on('beforeSendEvent', _getSentryBreadcrumbHandler(client));\n }\n },\n };\n}) satisfies IntegrationFn;\n\nexport const breadcrumbsIntegration = defineIntegration(_breadcrumbsIntegration);\n\n/**\n * Adds a breadcrumb for Sentry events or transactions if this option is enabled.\n */\nfunction _getSentryBreadcrumbHandler(client: Client): (event: SentryEvent) => void {\n return function addSentryBreadcrumb(event: SentryEvent): void {\n if (getClient() !== client) {\n return;\n }\n\n addBreadcrumb(\n {\n category: `sentry.${event.type === 'transaction' ? 'transaction' : 'event'}`,\n event_id: event.event_id,\n level: event.level,\n message: getEventDescription(event),\n },\n {\n event,\n },\n );\n };\n}\n\n/**\n * A HOC that creates a function that creates breadcrumbs from DOM API calls.\n * This is a HOC so that we get access to dom options in the closure.\n */\nfunction _getDomBreadcrumbHandler(\n client: Client,\n dom: BreadcrumbsOptions['dom'],\n): (handlerData: HandlerDataDom) => void {\n return function _innerDomBreadcrumb(handlerData: HandlerDataDom): void {\n if (getClient() !== client) {\n return;\n }\n\n let target;\n let componentName;\n let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;\n\n let maxStringLength =\n typeof dom === 'object' && typeof dom.maxStringLength === 'number' ? dom.maxStringLength : undefined;\n if (maxStringLength && maxStringLength > MAX_ALLOWED_STRING_LENGTH) {\n DEBUG_BUILD &&\n debug.warn(\n `\\`dom.maxStringLength\\` cannot exceed ${MAX_ALLOWED_STRING_LENGTH}, but a value of ${maxStringLength} was configured. Sentry will use ${MAX_ALLOWED_STRING_LENGTH} instead.`,\n );\n maxStringLength = MAX_ALLOWED_STRING_LENGTH;\n }\n\n if (typeof keyAttrs === 'string') {\n keyAttrs = [keyAttrs];\n }\n\n // Accessing event.target can throw (see getsentry/raven-js#838, #768)\n try {\n const event = handlerData.event as Event | Node;\n const element = _isEvent(event) ? event.target : event;\n\n target = htmlTreeAsString(element, { keyAttrs, maxStringLength });\n componentName = getComponentName(element);\n } catch {\n target = '<unknown>';\n }\n\n if (target.length === 0) {\n return;\n }\n\n const breadcrumb: Breadcrumb = {\n category: `ui.${handlerData.name}`,\n message: target,\n };\n\n if (componentName) {\n breadcrumb.data = { 'ui.component_name': componentName };\n }\n\n addBreadcrumb(breadcrumb, {\n event: handlerData.event,\n name: handlerData.name,\n global: handlerData.global,\n });\n };\n}\n\n/**\n * Creates breadcrumbs from console API calls\n */\nfunction _getConsoleBreadcrumbHandler(client: Client): (handlerData: HandlerDataConsole) => void {\n return function _consoleBreadcrumb(handlerData: HandlerDataConsole): void {\n if (getClient() !== client) {\n return;\n }\n\n const breadcrumb = {\n category: 'console',\n data: {\n arguments: handlerData.args,\n logger: 'console',\n },\n level: severityLevelFromString(handlerData.level),\n message: safeJoin(handlerData.args, ' '),\n };\n\n if (handlerData.level === 'assert') {\n if (handlerData.args[0] === false) {\n breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;\n breadcrumb.data.arguments = handlerData.args.slice(1);\n } else {\n // Don't capture a breadcrumb for passed assertions\n return;\n }\n }\n\n addBreadcrumb(breadcrumb, {\n input: handlerData.args,\n level: handlerData.level,\n });\n };\n}\n\n/**\n * Creates breadcrumbs from XHR API calls\n */\nfunction _getXhrBreadcrumbHandler(client: Client): (handlerData: HandlerDataXhr) => void {\n return function _xhrBreadcrumb(handlerData: HandlerDataXhr): void {\n if (getClient() !== client) {\n return;\n }\n\n const { startTimestamp, endTimestamp } = handlerData;\n\n const sentryXhrData = handlerData.xhr[SENTRY_XHR_DATA_KEY];\n\n // We only capture complete, non-sentry requests\n if (!startTimestamp || !endTimestamp || !sentryXhrData) {\n return;\n }\n\n const { method, url, status_code, body } = sentryXhrData;\n\n const data: XhrBreadcrumbData = {\n method,\n url,\n status_code,\n };\n\n const hint: XhrBreadcrumbHint = {\n xhr: handlerData.xhr,\n input: body,\n startTimestamp,\n endTimestamp,\n };\n\n const breadcrumb = {\n category: 'xhr',\n data,\n type: 'http',\n level: getBreadcrumbLogLevelFromHttpStatusCode(status_code),\n };\n\n client.emit('beforeOutgoingRequestBreadcrumb', breadcrumb, hint as XhrHint);\n\n addBreadcrumb(breadcrumb, hint);\n };\n}\n\n/**\n * Creates breadcrumbs from fetch API calls\n */\nfunction _getFetchBreadcrumbHandler(client: Client): (handlerData: HandlerDataFetch) => void {\n return function _fetchBreadcrumb(handlerData: HandlerDataFetch): void {\n if (getClient() !== client) {\n return;\n }\n\n const { startTimestamp, endTimestamp } = handlerData;\n\n // We only capture complete fetch requests\n if (!endTimestamp) {\n return;\n }\n\n if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {\n // We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)\n return;\n }\n\n if (handlerData.error) {\n const hint: FetchBreadcrumbHint = {\n data: handlerData.error,\n input: handlerData.args,\n startTimestamp,\n endTimestamp,\n };\n\n const breadcrumb = {\n category: 'fetch',\n data: handlerData.fetchData,\n level: 'error',\n type: 'http',\n } satisfies Breadcrumb;\n\n client.emit('beforeOutgoingRequestBreadcrumb', breadcrumb, hint as FetchHint);\n\n addBreadcrumb(breadcrumb, hint);\n } else {\n const response = handlerData.response as Response | undefined;\n const data: FetchBreadcrumbData = {\n ...handlerData.fetchData,\n status_code: response?.status,\n };\n\n const hint: FetchBreadcrumbHint = {\n input: handlerData.args,\n response,\n startTimestamp,\n endTimestamp,\n };\n\n const breadcrumb = {\n category: 'fetch',\n data,\n type: 'http',\n level: getBreadcrumbLogLevelFromHttpStatusCode(data.status_code),\n };\n\n client.emit('beforeOutgoingRequestBreadcrumb', breadcrumb, hint as FetchHint);\n\n addBreadcrumb(breadcrumb, hint);\n }\n };\n}\n\n/**\n * Creates breadcrumbs from history API calls\n */\nfunction _getHistoryBreadcrumbHandler(client: Client): (handlerData: HandlerDataHistory) => void {\n return function _historyBreadcrumb(handlerData: HandlerDataHistory): void {\n if (getClient() !== client) {\n return;\n }\n\n let from: string | undefined = handlerData.from;\n let to: string | undefined = handlerData.to;\n const parsedLoc = parseUrl(WINDOW.location.href);\n let parsedFrom = from ? parseUrl(from) : undefined;\n const parsedTo = parseUrl(to);\n\n // Initial pushState doesn't provide `from` information\n if (!parsedFrom?.path) {\n parsedFrom = parsedLoc;\n }\n\n // Use only the path component of the URL if the URL matches the current\n // document (almost all the time when using pushState)\n if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {\n to = parsedTo.relative;\n }\n if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {\n from = parsedFrom.relative;\n }\n\n addBreadcrumb({\n category: 'navigation',\n data: {\n from,\n to,\n },\n });\n };\n}\n\nfunction _isEvent(event: unknown): event is Event {\n return !!event && !!(event as Record<string, unknown>).target;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"browserapierrors.js","sources":["../../../../../src/integrations/browserapierrors.ts"],"sourcesContent":["import type { IntegrationFn, WrappedFunction } from '@sentry/core/browser';\nimport { defineIntegration, fill, getFunctionName, getOriginalFunction } from '@sentry/core/browser';\nimport { WINDOW, wrap } from '../helpers';\n\n// Using a comma-separated string and split for smaller bundle size vs an array literal\nconst DEFAULT_EVENT_TARGET =\n 'EventTarget,Window,Node,ApplicationCache,AudioTrackList,BroadcastChannel,ChannelMergerNode,CryptoOperation,EventSource,FileReader,HTMLUnknownElement,IDBDatabase,IDBRequest,IDBTransaction,KeyOperation,MediaController,MessagePort,ModalWindow,Notification,SVGElementInstance,Screen,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebSocket,WebSocketWorker,Worker,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload'.split(\n ',',\n );\n\nconst INTEGRATION_NAME = 'BrowserApiErrors';\n\ntype XMLHttpRequestProp = 'onload' | 'onerror' | 'onprogress' | 'onreadystatechange';\n\ninterface BrowserApiErrorsOptions {\n setTimeout: boolean;\n setInterval: boolean;\n requestAnimationFrame: boolean;\n XMLHttpRequest: boolean;\n eventTarget: boolean | string[];\n\n /**\n * If you experience issues with this integration causing double-invocations of event listeners,\n * try setting this option to `true`. It will unregister the original callbacks from the event targets\n * before adding the instrumented callback.\n *\n * @default false\n */\n unregisterOriginalCallbacks: boolean;\n}\n\nconst _browserApiErrorsIntegration = ((options: Partial<BrowserApiErrorsOptions> = {}) => {\n const _options = {\n XMLHttpRequest: true,\n eventTarget: true,\n requestAnimationFrame: true,\n setInterval: true,\n setTimeout: true,\n unregisterOriginalCallbacks: false,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n // TODO: This currently only works for the first client this is setup\n // We may want to adjust this to check for client etc.\n setupOnce() {\n if (_options.setTimeout) {\n fill(WINDOW, 'setTimeout', _wrapTimeFunction);\n }\n\n if (_options.setInterval) {\n fill(WINDOW, 'setInterval', _wrapTimeFunction);\n }\n\n if (_options.requestAnimationFrame) {\n fill(WINDOW, 'requestAnimationFrame', _wrapRAF);\n }\n\n if (_options.XMLHttpRequest && 'XMLHttpRequest' in WINDOW) {\n fill(XMLHttpRequest.prototype, 'send', _wrapXHR);\n }\n\n const eventTargetOption = _options.eventTarget;\n if (eventTargetOption) {\n const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;\n eventTarget.forEach(target => _wrapEventTarget(target, _options));\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Wrap timer functions and event targets to catch errors and provide better meta data.\n */\nexport const browserApiErrorsIntegration = defineIntegration(_browserApiErrorsIntegration);\n\nfunction _wrapTimeFunction(original: () => void): () => number {\n return function (this: unknown, ...args: unknown[]): number {\n const originalCallback = args[0];\n args[0] = wrap(originalCallback, {\n mechanism: {\n handled: false,\n type: `auto.browser.browserapierrors.${getFunctionName(original)}`,\n },\n });\n return original.apply(this, args);\n };\n}\n\nfunction _wrapRAF(original: () => void): (callback: () => void) => unknown {\n return function (this: unknown, callback: () => void): () => void {\n return original.apply(this, [\n wrap(callback, {\n mechanism: {\n data: {\n handler: getFunctionName(original),\n },\n handled: false,\n type: 'auto.browser.browserapierrors.requestAnimationFrame',\n },\n }),\n ]);\n };\n}\n\nfunction _wrapXHR(originalSend: () => void): () => void {\n return function (this: XMLHttpRequest, ...args: unknown[]): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const xhr = this;\n const xmlHttpRequestProps: XMLHttpRequestProp[] = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];\n\n xmlHttpRequestProps.forEach(prop => {\n if (prop in xhr && typeof xhr[prop] === 'function') {\n fill(xhr, prop, function (original) {\n const wrapOptions = {\n mechanism: {\n data: {\n handler: getFunctionName(original),\n },\n handled: false,\n type: `auto.browser.browserapierrors.xhr.${prop}`,\n },\n };\n\n // If Instrument integration has been called before BrowserApiErrors, get the name of original function\n const originalFunction = getOriginalFunction(original);\n if (originalFunction) {\n wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);\n }\n\n // Otherwise wrap directly\n return wrap(original, wrapOptions);\n });\n }\n });\n\n return originalSend.apply(this, args);\n };\n}\n\nfunction _wrapEventTarget(target: string, integrationOptions: BrowserApiErrorsOptions): void {\n const globalObject = WINDOW as unknown as Record<string, { prototype?: object }>;\n const proto = globalObject[target]?.prototype;\n\n // eslint-disable-next-line no-prototype-builtins\n if (!proto?.hasOwnProperty?.('addEventListener')) {\n return;\n }\n\n fill(proto, 'addEventListener', function (original: VoidFunction): (\n ...args: Parameters<typeof WINDOW.addEventListener>\n ) => ReturnType<typeof WINDOW.addEventListener> {\n return function (this: unknown, eventName, fn, options): VoidFunction {\n try {\n if (isEventListenerObject(fn)) {\n // ESlint disable explanation:\n // First, it is generally safe to call `wrap` with an unbound function. Furthermore, using `.bind()` would\n // introduce a bug here, because bind returns a new function that doesn't have our\n // flags(like __sentry_original__) attached. `wrap` checks for those flags to avoid unnecessary wrapping.\n // Without those flags, every call to addEventListener wraps the function again, causing a memory leak.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n fn.handleEvent = wrap(fn.handleEvent, {\n mechanism: {\n data: {\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'auto.browser.browserapierrors.handleEvent',\n },\n });\n }\n } catch {\n // can sometimes get 'Permission denied to access property \"handle Event'\n }\n\n if (integrationOptions.unregisterOriginalCallbacks) {\n unregisterOriginalCallback(this, eventName, fn);\n }\n\n return original.apply(this, [\n eventName,\n wrap(fn, {\n mechanism: {\n data: {\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'auto.browser.browserapierrors.addEventListener',\n },\n }),\n options,\n ]);\n };\n });\n\n fill(proto, 'removeEventListener', function (originalRemoveEventListener: VoidFunction): (\n this: unknown,\n ...args: Parameters<typeof WINDOW.removeEventListener>\n ) => ReturnType<typeof WINDOW.removeEventListener> {\n return function (this: unknown, eventName, fn, options): VoidFunction {\n /**\n * There are 2 possible scenarios here:\n *\n * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified\n * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function\n * as a pass-through, and call original `removeEventListener` with it.\n *\n * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using\n * our wrapped version of `addEventListener`, which internally calls `wrap` helper.\n * This helper \"wraps\" whole callback inside a try/catch statement, and attached appropriate metadata to it,\n * in order for us to make a distinction between wrapped/non-wrapped functions possible.\n * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.\n *\n * When someone adds a handler prior to initialization, and then do it again, but after,\n * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible\n * to get rid of the initial handler and it'd stick there forever.\n */\n try {\n // Check via hasOwnProperty so a `__sentry_wrapped__` inherited from a wrapped\n // `Function.prototype` doesn't cause removal of the wrong handler.\n if (Object.prototype.hasOwnProperty.call(fn, '__sentry_wrapped__')) {\n const originalEventHandler = (fn as WrappedFunction).__sentry_wrapped__;\n if (originalEventHandler) {\n originalRemoveEventListener.call(this, eventName, originalEventHandler, options);\n }\n }\n } catch {\n // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments\n }\n return originalRemoveEventListener.call(this, eventName, fn, options);\n };\n });\n}\n\nfunction isEventListenerObject(obj: unknown): obj is EventListenerObject {\n return typeof (obj as EventListenerObject).handleEvent === 'function';\n}\n\nfunction unregisterOriginalCallback(target: unknown, eventName: string, fn: EventListenerOrEventListenerObject): void {\n if (\n target &&\n typeof target === 'object' &&\n 'removeEventListener' in target &&\n typeof target.removeEventListener === 'function'\n ) {\n target.removeEventListener(eventName, fn);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browserapierrors.js","sources":["../../../../../src/integrations/browserapierrors.ts"],"sourcesContent":["import type { IntegrationFn, WrappedFunction } from '@sentry/core/browser';\nimport { defineIntegration, fill, getFunctionName, getOriginalFunction } from '@sentry/core/browser';\nimport { WINDOW, wrap } from '../helpers';\n\n// Using a comma-separated string and split for smaller bundle size vs an array literal\nconst DEFAULT_EVENT_TARGET =\n 'EventTarget,Window,Node,ApplicationCache,AudioTrackList,BroadcastChannel,ChannelMergerNode,CryptoOperation,EventSource,FileReader,HTMLUnknownElement,IDBDatabase,IDBRequest,IDBTransaction,KeyOperation,MediaController,MessagePort,ModalWindow,Notification,SVGElementInstance,Screen,SharedWorker,TextTrack,TextTrackCue,TextTrackList,WebSocket,WebSocketWorker,Worker,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload'.split(\n ',',\n );\n\nconst INTEGRATION_NAME = 'BrowserApiErrors' as const;\n\ntype XMLHttpRequestProp = 'onload' | 'onerror' | 'onprogress' | 'onreadystatechange';\n\ninterface BrowserApiErrorsOptions {\n setTimeout: boolean;\n setInterval: boolean;\n requestAnimationFrame: boolean;\n XMLHttpRequest: boolean;\n eventTarget: boolean | string[];\n\n /**\n * If you experience issues with this integration causing double-invocations of event listeners,\n * try setting this option to `true`. It will unregister the original callbacks from the event targets\n * before adding the instrumented callback.\n *\n * @default false\n */\n unregisterOriginalCallbacks: boolean;\n}\n\nconst _browserApiErrorsIntegration = ((options: Partial<BrowserApiErrorsOptions> = {}) => {\n const _options = {\n XMLHttpRequest: true,\n eventTarget: true,\n requestAnimationFrame: true,\n setInterval: true,\n setTimeout: true,\n unregisterOriginalCallbacks: false,\n ...options,\n };\n\n return {\n name: INTEGRATION_NAME,\n // TODO: This currently only works for the first client this is setup\n // We may want to adjust this to check for client etc.\n setupOnce() {\n if (_options.setTimeout) {\n fill(WINDOW, 'setTimeout', _wrapTimeFunction);\n }\n\n if (_options.setInterval) {\n fill(WINDOW, 'setInterval', _wrapTimeFunction);\n }\n\n if (_options.requestAnimationFrame) {\n fill(WINDOW, 'requestAnimationFrame', _wrapRAF);\n }\n\n if (_options.XMLHttpRequest && 'XMLHttpRequest' in WINDOW) {\n fill(XMLHttpRequest.prototype, 'send', _wrapXHR);\n }\n\n const eventTargetOption = _options.eventTarget;\n if (eventTargetOption) {\n const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;\n eventTarget.forEach(target => _wrapEventTarget(target, _options));\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Wrap timer functions and event targets to catch errors and provide better meta data.\n */\nexport const browserApiErrorsIntegration = defineIntegration(_browserApiErrorsIntegration);\n\nfunction _wrapTimeFunction(original: () => void): () => number {\n return function (this: unknown, ...args: unknown[]): number {\n const originalCallback = args[0];\n args[0] = wrap(originalCallback, {\n mechanism: {\n handled: false,\n type: `auto.browser.browserapierrors.${getFunctionName(original)}`,\n },\n });\n return original.apply(this, args);\n };\n}\n\nfunction _wrapRAF(original: () => void): (callback: () => void) => unknown {\n return function (this: unknown, callback: () => void): () => void {\n return original.apply(this, [\n wrap(callback, {\n mechanism: {\n data: {\n handler: getFunctionName(original),\n },\n handled: false,\n type: 'auto.browser.browserapierrors.requestAnimationFrame',\n },\n }),\n ]);\n };\n}\n\nfunction _wrapXHR(originalSend: () => void): () => void {\n return function (this: XMLHttpRequest, ...args: unknown[]): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const xhr = this;\n const xmlHttpRequestProps: XMLHttpRequestProp[] = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];\n\n xmlHttpRequestProps.forEach(prop => {\n if (prop in xhr && typeof xhr[prop] === 'function') {\n fill(xhr, prop, function (original) {\n const wrapOptions = {\n mechanism: {\n data: {\n handler: getFunctionName(original),\n },\n handled: false,\n type: `auto.browser.browserapierrors.xhr.${prop}`,\n },\n };\n\n // If Instrument integration has been called before BrowserApiErrors, get the name of original function\n const originalFunction = getOriginalFunction(original);\n if (originalFunction) {\n wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);\n }\n\n // Otherwise wrap directly\n return wrap(original, wrapOptions);\n });\n }\n });\n\n return originalSend.apply(this, args);\n };\n}\n\nfunction _wrapEventTarget(target: string, integrationOptions: BrowserApiErrorsOptions): void {\n const globalObject = WINDOW as unknown as Record<string, { prototype?: object }>;\n const proto = globalObject[target]?.prototype;\n\n // eslint-disable-next-line no-prototype-builtins\n if (!proto?.hasOwnProperty?.('addEventListener')) {\n return;\n }\n\n fill(proto, 'addEventListener', function (original: VoidFunction): (\n ...args: Parameters<typeof WINDOW.addEventListener>\n ) => ReturnType<typeof WINDOW.addEventListener> {\n return function (this: unknown, eventName, fn, options): VoidFunction {\n try {\n if (isEventListenerObject(fn)) {\n // ESlint disable explanation:\n // First, it is generally safe to call `wrap` with an unbound function. Furthermore, using `.bind()` would\n // introduce a bug here, because bind returns a new function that doesn't have our\n // flags(like __sentry_original__) attached. `wrap` checks for those flags to avoid unnecessary wrapping.\n // Without those flags, every call to addEventListener wraps the function again, causing a memory leak.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n fn.handleEvent = wrap(fn.handleEvent, {\n mechanism: {\n data: {\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'auto.browser.browserapierrors.handleEvent',\n },\n });\n }\n } catch {\n // can sometimes get 'Permission denied to access property \"handle Event'\n }\n\n if (integrationOptions.unregisterOriginalCallbacks) {\n unregisterOriginalCallback(this, eventName, fn);\n }\n\n return original.apply(this, [\n eventName,\n wrap(fn, {\n mechanism: {\n data: {\n handler: getFunctionName(fn),\n target,\n },\n handled: false,\n type: 'auto.browser.browserapierrors.addEventListener',\n },\n }),\n options,\n ]);\n };\n });\n\n fill(proto, 'removeEventListener', function (originalRemoveEventListener: VoidFunction): (\n this: unknown,\n ...args: Parameters<typeof WINDOW.removeEventListener>\n ) => ReturnType<typeof WINDOW.removeEventListener> {\n return function (this: unknown, eventName, fn, options): VoidFunction {\n /**\n * There are 2 possible scenarios here:\n *\n * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified\n * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function\n * as a pass-through, and call original `removeEventListener` with it.\n *\n * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using\n * our wrapped version of `addEventListener`, which internally calls `wrap` helper.\n * This helper \"wraps\" whole callback inside a try/catch statement, and attached appropriate metadata to it,\n * in order for us to make a distinction between wrapped/non-wrapped functions possible.\n * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.\n *\n * When someone adds a handler prior to initialization, and then do it again, but after,\n * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible\n * to get rid of the initial handler and it'd stick there forever.\n */\n try {\n // Check via hasOwnProperty so a `__sentry_wrapped__` inherited from a wrapped\n // `Function.prototype` doesn't cause removal of the wrong handler.\n if (Object.prototype.hasOwnProperty.call(fn, '__sentry_wrapped__')) {\n const originalEventHandler = (fn as WrappedFunction).__sentry_wrapped__;\n if (originalEventHandler) {\n originalRemoveEventListener.call(this, eventName, originalEventHandler, options);\n }\n }\n } catch {\n // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments\n }\n return originalRemoveEventListener.call(this, eventName, fn, options);\n };\n });\n}\n\nfunction isEventListenerObject(obj: unknown): obj is EventListenerObject {\n return typeof (obj as EventListenerObject).handleEvent === 'function';\n}\n\nfunction unregisterOriginalCallback(target: unknown, eventName: string, fn: EventListenerOrEventListenerObject): void {\n if (\n target &&\n typeof target === 'object' &&\n 'removeEventListener' in target &&\n typeof target.removeEventListener === 'function'\n ) {\n target.removeEventListener(eventName, fn);\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { defineIntegration, debug, startSession, captureSession, getIsolationScope } from '@sentry/core/browser';
2
- import { addHistoryInstrumentationHandler } from '@sentry/browser-utils';
2
+ import { whenIdleOrHidden, addHistoryInstrumentationHandler } from '@sentry/browser-utils';
3
3
  import { DEBUG_BUILD } from '../debug-build.js';
4
4
  import { WINDOW } from '../helpers.js';
5
5
 
@@ -13,14 +13,22 @@ const browserSessionIntegration = defineIntegration((options = {}) => {
13
13
  return;
14
14
  }
15
15
  startSession({ ignoreDuration: true });
16
- captureSession();
16
+ let initialSessionSent = false;
17
+ whenIdleOrHidden(() => {
18
+ if (!initialSessionSent) {
19
+ captureSession();
20
+ initialSessionSent = true;
21
+ }
22
+ });
17
23
  const isolationScope = getIsolationScope();
18
24
  let previousUser = isolationScope.getUser();
19
25
  isolationScope.addScopeListener((scope) => {
20
26
  const maybeNewUser = scope.getUser();
21
27
  if (previousUser?.id !== maybeNewUser?.id || previousUser?.ip_address !== maybeNewUser?.ip_address) {
22
- captureSession();
23
28
  previousUser = maybeNewUser;
29
+ if (initialSessionSent) {
30
+ captureSession();
31
+ }
24
32
  }
25
33
  });
26
34
  if (lifecycle === "route") {
@@ -28,6 +36,7 @@ const browserSessionIntegration = defineIntegration((options = {}) => {
28
36
  if (from !== to) {
29
37
  startSession({ ignoreDuration: true });
30
38
  captureSession();
39
+ initialSessionSent = true;
31
40
  }
32
41
  });
33
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"browsersession.js","sources":["../../../../../src/integrations/browsersession.ts"],"sourcesContent":["import { captureSession, debug, defineIntegration, getIsolationScope, startSession } from '@sentry/core/browser';\nimport { addHistoryInstrumentationHandler } from '@sentry/browser-utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\n\ninterface BrowserSessionOptions {\n /**\n * Controls the session lifecycle - when new sessions are created.\n *\n * - `'route'`: A session is created on page load and on every navigation.\n * This is the default behavior.\n * - `'page'`: A session is created once when the page is loaded. Session is not\n * updated on navigation. This is useful for webviews or single-page apps where\n * URL changes should not trigger new sessions.\n *\n * @default 'route'\n */\n lifecycle?: 'route' | 'page';\n}\n\n/**\n * When added, automatically creates sessions which allow you to track adoption and crashes (crash free rate) in your Releases in Sentry.\n * More information: https://docs.sentry.io/product/releases/health/\n *\n * Note: In order for session tracking to work, you need to set up Releases: https://docs.sentry.io/product/releases/\n */\nexport const browserSessionIntegration = defineIntegration((options: BrowserSessionOptions = {}) => {\n const lifecycle = options.lifecycle ?? 'route';\n\n return {\n name: 'BrowserSession',\n setupOnce() {\n if (typeof WINDOW.document === 'undefined') {\n DEBUG_BUILD &&\n debug.warn('Using the `browserSessionIntegration` in non-browser environments is not supported.');\n return;\n }\n\n // The session duration for browser sessions does not track a meaningful\n // concept that can be used as a metric.\n // Automatically captured sessions are akin to page views, and thus we\n // discard their duration.\n startSession({ ignoreDuration: true });\n captureSession();\n\n // User data can be set at any time, for example async after Sentry.init has run and the initial session\n // envelope was already sent, but still on the initial page.\n // Therefore, we have to update the ongoing session with the new user data if it exists, to send the `did`.\n // In theory, sessions, as well as user data is always put onto the isolation scope. So we listen to the\n // isolation scope for changes and update the session with the new user data if it exists.\n // This will not catch users set onto other scopes, like the current scope. For now, we'll accept this limitation.\n // The alternative is to update and capture the session from within the scope. This could be too costly or would not\n // play well with session aggregates on the server side. Since this happens in the scope class, we'd need change\n // scope behaviour in the browser.\n const isolationScope = getIsolationScope();\n let previousUser = isolationScope.getUser();\n isolationScope.addScopeListener(scope => {\n const maybeNewUser = scope.getUser();\n // sessions only care about user id and ip address, so we only need to capture the session if the user has changed\n if (previousUser?.id !== maybeNewUser?.id || previousUser?.ip_address !== maybeNewUser?.ip_address) {\n // the scope class already writes the user to its session, so we only need to capture the session here\n captureSession();\n previousUser = maybeNewUser;\n }\n });\n\n if (lifecycle === 'route') {\n // We want to create a session for every navigation as well\n addHistoryInstrumentationHandler(({ from, to }) => {\n // Don't create an additional session for the initial route or if the location did not change\n if (from !== to) {\n startSession({ ignoreDuration: true });\n captureSession();\n }\n });\n }\n },\n };\n});\n"],"names":[],"mappings":";;;;;AA0BO,MAAM,yBAAA,GAA4B,iBAAA,CAAkB,CAAC,OAAA,GAAiC,EAAC,KAAM;AAClG,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,OAAA;AAEvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,SAAA,GAAY;AACV,MAAA,IAAI,OAAO,MAAA,CAAO,QAAA,KAAa,WAAA,EAAa;AAC1C,QAAA,WAAA,IACE,KAAA,CAAM,KAAK,qFAAqF,CAAA;AAClG,QAAA;AAAA,MACF;AAMA,MAAA,YAAA,CAAa,EAAE,cAAA,EAAgB,IAAA,EAAM,CAAA;AACrC,MAAA,cAAA,EAAe;AAWf,MAAA,MAAM,iBAAiB,iBAAA,EAAkB;AACzC,MAAA,IAAI,YAAA,GAAe,eAAe,OAAA,EAAQ;AAC1C,MAAA,cAAA,CAAe,iBAAiB,CAAA,KAAA,KAAS;AACvC,QAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAQ;AAEnC,QAAA,IAAI,cAAc,EAAA,KAAO,YAAA,EAAc,MAAM,YAAA,EAAc,UAAA,KAAe,cAAc,UAAA,EAAY;AAElG,UAAA,cAAA,EAAe;AACf,UAAA,YAAA,GAAe,YAAA;AAAA,QACjB;AAAA,MACF,CAAC,CAAA;AAED,MAAA,IAAI,cAAc,OAAA,EAAS;AAEzB,QAAA,gCAAA,CAAiC,CAAC,EAAE,IAAA,EAAM,EAAA,EAAG,KAAM;AAEjD,UAAA,IAAI,SAAS,EAAA,EAAI;AACf,YAAA,YAAA,CAAa,EAAE,cAAA,EAAgB,IAAA,EAAM,CAAA;AACrC,YAAA,cAAA,EAAe;AAAA,UACjB;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAAA,IACF;AAAA,GACF;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"browsersession.js","sources":["../../../../../src/integrations/browsersession.ts"],"sourcesContent":["import { captureSession, debug, defineIntegration, getIsolationScope, startSession } from '@sentry/core/browser';\nimport { addHistoryInstrumentationHandler, whenIdleOrHidden } from '@sentry/browser-utils';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\n\ninterface BrowserSessionOptions {\n /**\n * Controls the session lifecycle - when new sessions are created.\n *\n * - `'route'`: A session is created on page load and on every navigation.\n * This is the default behavior.\n * - `'page'`: A session is created once when the page is loaded. Session is not\n * updated on navigation. This is useful for webviews or single-page apps where\n * URL changes should not trigger new sessions.\n *\n * @default 'route'\n */\n lifecycle?: 'route' | 'page';\n}\n\n/**\n * When added, automatically creates sessions which allow you to track adoption and crashes (crash free rate) in your Releases in Sentry.\n * More information: https://docs.sentry.io/product/releases/health/\n *\n * Note: In order for session tracking to work, you need to set up Releases: https://docs.sentry.io/product/releases/\n */\nexport const browserSessionIntegration = defineIntegration((options: BrowserSessionOptions = {}) => {\n const lifecycle = options.lifecycle ?? 'route';\n\n return {\n name: 'BrowserSession' as const,\n setupOnce() {\n if (typeof WINDOW.document === 'undefined') {\n DEBUG_BUILD &&\n debug.warn('Using the `browserSessionIntegration` in non-browser environments is not supported.');\n return;\n }\n\n // The session duration for browser sessions does not track a meaningful\n // concept that can be used as a metric.\n // Automatically captured sessions are akin to page views, and thus we\n // discard their duration.\n startSession({ ignoreDuration: true });\n\n // Sending the session envelope synchronously in `init()` runs the full send\n // pipeline during page load, competing with critical resources for the network and\n // adding overhead that measurably hurts LCP. We defer the initial send until the\n // browser is idle; `whenIdleOrHidden` flushes it on page-hide so we don't lose short\n // (page-view-like) sessions.\n let initialSessionSent = false;\n whenIdleOrHidden(() => {\n // A navigation (in `'route'` lifecycle) may start and send a new session before this\n // deferred callback fires. In that case the current session was already sent, so\n // re-capturing here would send it a second time - guard against that.\n if (!initialSessionSent) {\n captureSession();\n initialSessionSent = true;\n }\n });\n\n // User data can be set at any time, for example async after Sentry.init has run and the initial session\n // envelope was already sent, but still on the initial page.\n // Therefore, we have to update the ongoing session with the new user data if it exists, to send the `did`.\n // In theory, sessions, as well as user data is always put onto the isolation scope. So we listen to the\n // isolation scope for changes and update the session with the new user data if it exists.\n // This will not catch users set onto other scopes, like the current scope. For now, we'll accept this limitation.\n // The alternative is to update and capture the session from within the scope. This could be too costly or would not\n // play well with session aggregates on the server side. Since this happens in the scope class, we'd need change\n // scope behaviour in the browser.\n const isolationScope = getIsolationScope();\n let previousUser = isolationScope.getUser();\n isolationScope.addScopeListener(scope => {\n const maybeNewUser = scope.getUser();\n // sessions only care about user id and ip address, so we only need to capture the session if the user has changed\n if (previousUser?.id !== maybeNewUser?.id || previousUser?.ip_address !== maybeNewUser?.ip_address) {\n previousUser = maybeNewUser;\n // Only emit a dedicated update envelope for user data that arrives _after_ the\n // deferred initial session was sent. User data set during page load is already\n // reflected in that session (the scope writes it onto the session), so capturing\n // here would send a redundant envelope - and do so during page load, which is\n // exactly the overhead we're deferring away from.\n if (initialSessionSent) {\n captureSession();\n }\n }\n });\n\n if (lifecycle === 'route') {\n // We want to create a session for every navigation as well\n addHistoryInstrumentationHandler(({ from, to }) => {\n // Don't create an additional session for the initial route or if the location did not change\n if (from !== to) {\n startSession({ ignoreDuration: true });\n captureSession();\n // A session has now been sent, so the deferred initial capture (if still pending)\n // must not re-send this navigation session.\n initialSessionSent = true;\n }\n });\n }\n },\n };\n});\n"],"names":[],"mappings":";;;;;AA0BO,MAAM,yBAAA,GAA4B,iBAAA,CAAkB,CAAC,OAAA,GAAiC,EAAC,KAAM;AAClG,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,OAAA;AAEvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,SAAA,GAAY;AACV,MAAA,IAAI,OAAO,MAAA,CAAO,QAAA,KAAa,WAAA,EAAa;AAC1C,QAAA,WAAA,IACE,KAAA,CAAM,KAAK,qFAAqF,CAAA;AAClG,QAAA;AAAA,MACF;AAMA,MAAA,YAAA,CAAa,EAAE,cAAA,EAAgB,IAAA,EAAM,CAAA;AAOrC,MAAA,IAAI,kBAAA,GAAqB,KAAA;AACzB,MAAA,gBAAA,CAAiB,MAAM;AAIrB,QAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,UAAA,cAAA,EAAe;AACf,UAAA,kBAAA,GAAqB,IAAA;AAAA,QACvB;AAAA,MACF,CAAC,CAAA;AAWD,MAAA,MAAM,iBAAiB,iBAAA,EAAkB;AACzC,MAAA,IAAI,YAAA,GAAe,eAAe,OAAA,EAAQ;AAC1C,MAAA,cAAA,CAAe,iBAAiB,CAAA,KAAA,KAAS;AACvC,QAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAQ;AAEnC,QAAA,IAAI,cAAc,EAAA,KAAO,YAAA,EAAc,MAAM,YAAA,EAAc,UAAA,KAAe,cAAc,UAAA,EAAY;AAClG,UAAA,YAAA,GAAe,YAAA;AAMf,UAAA,IAAI,kBAAA,EAAoB;AACtB,YAAA,cAAA,EAAe;AAAA,UACjB;AAAA,QACF;AAAA,MACF,CAAC,CAAA;AAED,MAAA,IAAI,cAAc,OAAA,EAAS;AAEzB,QAAA,gCAAA,CAAiC,CAAC,EAAE,IAAA,EAAM,EAAA,EAAG,KAAM;AAEjD,UAAA,IAAI,SAAS,EAAA,EAAI;AACf,YAAA,YAAA,CAAa,EAAE,cAAA,EAAgB,IAAA,EAAM,CAAA;AACrC,YAAA,cAAA,EAAe;AAGf,YAAA,kBAAA,GAAqB,IAAA;AAAA,UACvB;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAAA,IACF;AAAA,GACF;AACF,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"contextlines.js","sources":["../../../../../src/integrations/contextlines.ts"],"sourcesContent":["import type { Event, IntegrationFn, StackFrame } from '@sentry/core/browser';\nimport { addContextToFrame, defineIntegration, GLOBAL_OBJ, stripUrlQueryAndFragment } from '@sentry/core/browser';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nconst DEFAULT_LINES_OF_CONTEXT = 7;\n\nconst INTEGRATION_NAME = 'ContextLines';\n\n// TODO(v11): Use `dataCollection.frameContextLines` default (5)\ninterface ContextLinesOptions {\n /**\n * Sets the number of context lines for each frame when loading a file.\n * Defaults to 7.\n *\n * Set to 0 to disable loading and inclusion of source files.\n *\n * When set, this option takes precedence over `dataCollection.frameContextLines`.\n **/\n frameContextLines?: number;\n}\n\nconst _contextLinesIntegration = ((options: ContextLinesOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n processEvent(event, _hint, client) {\n const contextLines =\n options.frameContextLines ?? client?.getDataCollectionOptions().frameContextLines ?? DEFAULT_LINES_OF_CONTEXT;\n return addSourceContext(event, contextLines);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Collects source context lines around the lines of stackframes pointing to JS embedded in\n * the current page's HTML.\n *\n * This integration DOES NOT work for stack frames pointing to JS files that are loaded by the browser.\n * For frames pointing to files, context lines are added during ingestion and symbolication\n * by attempting to download the JS files to the Sentry backend.\n *\n * Use this integration if you have inline JS code in HTML pages that can't be accessed\n * by our backend (e.g. due to a login-protected page).\n */\nexport const contextLinesIntegration = defineIntegration(_contextLinesIntegration);\n\n/**\n * Processes an event and adds context lines.\n */\nfunction addSourceContext(event: Event, contextLines: number): Event {\n const doc = WINDOW.document;\n const htmlFilename = WINDOW.location && stripUrlQueryAndFragment(WINDOW.location.href);\n if (!doc || !htmlFilename) {\n return event;\n }\n\n const exceptions = event.exception?.values;\n if (!exceptions?.length) {\n return event;\n }\n\n const html = doc.documentElement.innerHTML;\n if (!html) {\n return event;\n }\n\n const htmlLines = ['<!DOCTYPE html>', '<html>', ...html.split('\\n'), '</html>'];\n\n exceptions.forEach(exception => {\n const stacktrace = exception.stacktrace;\n if (stacktrace?.frames) {\n stacktrace.frames = stacktrace.frames.map(frame =>\n applySourceContextToFrame(frame, htmlLines, htmlFilename, contextLines),\n );\n }\n });\n\n return event;\n}\n\n/**\n * Only exported for testing\n */\nexport function applySourceContextToFrame(\n frame: StackFrame,\n htmlLines: string[],\n htmlFilename: string,\n linesOfContext: number,\n): StackFrame {\n if (frame.filename !== htmlFilename || !frame.lineno || !htmlLines.length) {\n return frame;\n }\n\n addContextToFrame(htmlLines, frame, linesOfContext);\n\n return frame;\n}\n"],"names":[],"mappings":";;AAGA,MAAM,MAAA,GAAS,UAAA;AAEf,MAAM,wBAAA,GAA2B,CAAA;AAEjC,MAAM,gBAAA,GAAmB,cAAA;AAezB,MAAM,wBAAA,IAA4B,CAAC,OAAA,GAA+B,EAAC,KAAM;AACvE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,YAAA,CAAa,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ;AACjC,MAAA,MAAM,eACJ,OAAA,CAAQ,iBAAA,IAAqB,MAAA,EAAQ,wBAAA,GAA2B,iBAAA,IAAqB,wBAAA;AACvF,MAAA,OAAO,gBAAA,CAAiB,OAAO,YAAY,CAAA;AAAA,IAC7C;AAAA,GACF;AACF,CAAA,CAAA;AAaO,MAAM,uBAAA,GAA0B,kBAAkB,wBAAwB;AAKjF,SAAS,gBAAA,CAAiB,OAAc,YAAA,EAA6B;AACnE,EAAA,MAAM,MAAM,MAAA,CAAO,QAAA;AACnB,EAAA,MAAM,eAAe,MAAA,CAAO,QAAA,IAAY,wBAAA,CAAyB,MAAA,CAAO,SAAS,IAAI,CAAA;AACrF,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,YAAA,EAAc;AACzB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAAa,MAAM,SAAA,EAAW,MAAA;AACpC,EAAA,IAAI,CAAC,YAAY,MAAA,EAAQ;AACvB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB,SAAA;AACjC,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,iBAAA,EAAmB,QAAA,EAAU,GAAG,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,EAAG,SAAS,CAAA;AAE9E,EAAA,UAAA,CAAW,QAAQ,CAAA,SAAA,KAAa;AAC9B,IAAA,MAAM,aAAa,SAAA,CAAU,UAAA;AAC7B,IAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,MAAA,UAAA,CAAW,MAAA,GAAS,WAAW,MAAA,CAAO,GAAA;AAAA,QAAI,CAAA,KAAA,KACxC,yBAAA,CAA0B,KAAA,EAAO,SAAA,EAAW,cAAc,YAAY;AAAA,OACxE;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,yBAAA,CACd,KAAA,EACA,SAAA,EACA,YAAA,EACA,cAAA,EACY;AACZ,EAAA,IAAI,KAAA,CAAM,aAAa,YAAA,IAAgB,CAAC,MAAM,MAAA,IAAU,CAAC,UAAU,MAAA,EAAQ;AACzE,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,iBAAA,CAAkB,SAAA,EAAW,OAAO,cAAc,CAAA;AAElD,EAAA,OAAO,KAAA;AACT;;;;"}
1
+ {"version":3,"file":"contextlines.js","sources":["../../../../../src/integrations/contextlines.ts"],"sourcesContent":["import type { Event, IntegrationFn, StackFrame } from '@sentry/core/browser';\nimport { addContextToFrame, defineIntegration, GLOBAL_OBJ, stripUrlQueryAndFragment } from '@sentry/core/browser';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nconst DEFAULT_LINES_OF_CONTEXT = 7;\n\nconst INTEGRATION_NAME = 'ContextLines' as const;\n\n// TODO(v11): Use `dataCollection.frameContextLines` default (5)\ninterface ContextLinesOptions {\n /**\n * Sets the number of context lines for each frame when loading a file.\n * Defaults to 7.\n *\n * Set to 0 to disable loading and inclusion of source files.\n *\n * When set, this option takes precedence over `dataCollection.frameContextLines`.\n **/\n frameContextLines?: number;\n}\n\nconst _contextLinesIntegration = ((options: ContextLinesOptions = {}) => {\n return {\n name: INTEGRATION_NAME,\n processEvent(event, _hint, client) {\n const contextLines =\n options.frameContextLines ?? client?.getDataCollectionOptions().frameContextLines ?? DEFAULT_LINES_OF_CONTEXT;\n return addSourceContext(event, contextLines);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Collects source context lines around the lines of stackframes pointing to JS embedded in\n * the current page's HTML.\n *\n * This integration DOES NOT work for stack frames pointing to JS files that are loaded by the browser.\n * For frames pointing to files, context lines are added during ingestion and symbolication\n * by attempting to download the JS files to the Sentry backend.\n *\n * Use this integration if you have inline JS code in HTML pages that can't be accessed\n * by our backend (e.g. due to a login-protected page).\n */\nexport const contextLinesIntegration = defineIntegration(_contextLinesIntegration);\n\n/**\n * Processes an event and adds context lines.\n */\nfunction addSourceContext(event: Event, contextLines: number): Event {\n const doc = WINDOW.document;\n const htmlFilename = WINDOW.location && stripUrlQueryAndFragment(WINDOW.location.href);\n if (!doc || !htmlFilename) {\n return event;\n }\n\n const exceptions = event.exception?.values;\n if (!exceptions?.length) {\n return event;\n }\n\n const html = doc.documentElement.innerHTML;\n if (!html) {\n return event;\n }\n\n const htmlLines = ['<!DOCTYPE html>', '<html>', ...html.split('\\n'), '</html>'];\n\n exceptions.forEach(exception => {\n const stacktrace = exception.stacktrace;\n if (stacktrace?.frames) {\n stacktrace.frames = stacktrace.frames.map(frame =>\n applySourceContextToFrame(frame, htmlLines, htmlFilename, contextLines),\n );\n }\n });\n\n return event;\n}\n\n/**\n * Only exported for testing\n */\nexport function applySourceContextToFrame(\n frame: StackFrame,\n htmlLines: string[],\n htmlFilename: string,\n linesOfContext: number,\n): StackFrame {\n if (frame.filename !== htmlFilename || !frame.lineno || !htmlLines.length) {\n return frame;\n }\n\n addContextToFrame(htmlLines, frame, linesOfContext);\n\n return frame;\n}\n"],"names":[],"mappings":";;AAGA,MAAM,MAAA,GAAS,UAAA;AAEf,MAAM,wBAAA,GAA2B,CAAA;AAEjC,MAAM,gBAAA,GAAmB,cAAA;AAezB,MAAM,wBAAA,IAA4B,CAAC,OAAA,GAA+B,EAAC,KAAM;AACvE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,YAAA,CAAa,KAAA,EAAO,KAAA,EAAO,MAAA,EAAQ;AACjC,MAAA,MAAM,eACJ,OAAA,CAAQ,iBAAA,IAAqB,MAAA,EAAQ,wBAAA,GAA2B,iBAAA,IAAqB,wBAAA;AACvF,MAAA,OAAO,gBAAA,CAAiB,OAAO,YAAY,CAAA;AAAA,IAC7C;AAAA,GACF;AACF,CAAA,CAAA;AAaO,MAAM,uBAAA,GAA0B,kBAAkB,wBAAwB;AAKjF,SAAS,gBAAA,CAAiB,OAAc,YAAA,EAA6B;AACnE,EAAA,MAAM,MAAM,MAAA,CAAO,QAAA;AACnB,EAAA,MAAM,eAAe,MAAA,CAAO,QAAA,IAAY,wBAAA,CAAyB,MAAA,CAAO,SAAS,IAAI,CAAA;AACrF,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,YAAA,EAAc;AACzB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAAa,MAAM,SAAA,EAAW,MAAA;AACpC,EAAA,IAAI,CAAC,YAAY,MAAA,EAAQ;AACvB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB,SAAA;AACjC,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,iBAAA,EAAmB,QAAA,EAAU,GAAG,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,EAAG,SAAS,CAAA;AAE9E,EAAA,UAAA,CAAW,QAAQ,CAAA,SAAA,KAAa;AAC9B,IAAA,MAAM,aAAa,SAAA,CAAU,UAAA;AAC7B,IAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,MAAA,UAAA,CAAW,MAAA,GAAS,WAAW,MAAA,CAAO,GAAA;AAAA,QAAI,CAAA,KAAA,KACxC,yBAAA,CAA0B,KAAA,EAAO,SAAA,EAAW,cAAc,YAAY;AAAA,OACxE;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,yBAAA,CACd,KAAA,EACA,SAAA,EACA,YAAA,EACA,cAAA,EACY;AACZ,EAAA,IAAI,KAAA,CAAM,aAAa,YAAA,IAAgB,CAAC,MAAM,MAAA,IAAU,CAAC,UAAU,MAAA,EAAQ;AACzE,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,iBAAA,CAAkB,SAAA,EAAW,OAAO,cAAc,CAAA;AAElD,EAAA,OAAO,KAAA;AACT;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"culturecontext.js","sources":["../../../../../src/integrations/culturecontext.ts"],"sourcesContent":["import type { CultureContext, IntegrationFn } from '@sentry/core/browser';\nimport { defineIntegration, safeSetSpanJSONAttributes } from '@sentry/core/browser';\nimport { WINDOW } from '../helpers';\n\nconst INTEGRATION_NAME = 'CultureContext';\n\nconst _cultureContextIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n preprocessEvent(event) {\n const culture = getCultureContext();\n\n if (culture) {\n event.contexts = {\n ...event.contexts,\n culture: { ...culture, ...event.contexts?.culture },\n };\n }\n },\n processSegmentSpan(span) {\n const culture = getCultureContext();\n\n if (culture) {\n safeSetSpanJSONAttributes(span, {\n 'culture.locale': culture.locale,\n 'culture.timezone': culture.timezone,\n 'culture.calendar': culture.calendar,\n });\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Captures culture context from the browser.\n *\n * Enabled by default.\n *\n * @example\n * ```js\n * import * as Sentry from '@sentry/browser';\n *\n * Sentry.init({\n * integrations: [Sentry.cultureContextIntegration()],\n * });\n * ```\n */\nexport const cultureContextIntegration = defineIntegration(_cultureContextIntegration);\n\n/**\n * Returns the culture context from the browser's Intl API.\n */\nfunction getCultureContext(): CultureContext | undefined {\n try {\n const intl = (WINDOW as { Intl?: typeof Intl }).Intl;\n if (!intl) {\n return undefined;\n }\n\n const options = intl.DateTimeFormat().resolvedOptions();\n\n return {\n locale: options.locale,\n timezone: options.timeZone,\n calendar: options.calendar,\n };\n } catch {\n // Ignore errors\n return undefined;\n }\n}\n"],"names":[],"mappings":";;;AAIA,MAAM,gBAAA,GAAmB,gBAAA;AAEzB,MAAM,8BAA8B,MAAM;AACxC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,gBAAgB,KAAA,EAAO;AACrB,MAAA,MAAM,UAAU,iBAAA,EAAkB;AAElC,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,KAAA,CAAM,QAAA,GAAW;AAAA,UACf,GAAG,KAAA,CAAM,QAAA;AAAA,UACT,SAAS,EAAE,GAAG,SAAS,GAAG,KAAA,CAAM,UAAU,OAAA;AAAQ,SACpD;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,mBAAmB,IAAA,EAAM;AACvB,MAAA,MAAM,UAAU,iBAAA,EAAkB;AAElC,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,yBAAA,CAA0B,IAAA,EAAM;AAAA,UAC9B,kBAAkB,OAAA,CAAQ,MAAA;AAAA,UAC1B,oBAAoB,OAAA,CAAQ,QAAA;AAAA,UAC5B,oBAAoB,OAAA,CAAQ;AAAA,SAC7B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,GACF;AACF,CAAA,CAAA;AAgBO,MAAM,yBAAA,GAA4B,kBAAkB,0BAA0B;AAKrF,SAAS,iBAAA,GAAgD;AACvD,EAAA,IAAI;AACF,IAAA,MAAM,OAAQ,MAAA,CAAkC,IAAA;AAChD,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,cAAA,EAAe,CAAE,eAAA,EAAgB;AAEtD,IAAA,OAAO;AAAA,MACL,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,UAAU,OAAA,CAAQ;AAAA,KACpB;AAAA,EACF,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;;;;"}
1
+ {"version":3,"file":"culturecontext.js","sources":["../../../../../src/integrations/culturecontext.ts"],"sourcesContent":["import type { CultureContext, IntegrationFn } from '@sentry/core/browser';\nimport { defineIntegration, safeSetSpanJSONAttributes } from '@sentry/core/browser';\nimport { WINDOW } from '../helpers';\n\nconst INTEGRATION_NAME = 'CultureContext' as const;\n\nconst _cultureContextIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n preprocessEvent(event) {\n const culture = getCultureContext();\n\n if (culture) {\n event.contexts = {\n ...event.contexts,\n culture: { ...culture, ...event.contexts?.culture },\n };\n }\n },\n processSegmentSpan(span) {\n const culture = getCultureContext();\n\n if (culture) {\n safeSetSpanJSONAttributes(span, {\n 'culture.locale': culture.locale,\n 'culture.timezone': culture.timezone,\n 'culture.calendar': culture.calendar,\n });\n }\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Captures culture context from the browser.\n *\n * Enabled by default.\n *\n * @example\n * ```js\n * import * as Sentry from '@sentry/browser';\n *\n * Sentry.init({\n * integrations: [Sentry.cultureContextIntegration()],\n * });\n * ```\n */\nexport const cultureContextIntegration = defineIntegration(_cultureContextIntegration);\n\n/**\n * Returns the culture context from the browser's Intl API.\n */\nfunction getCultureContext(): CultureContext | undefined {\n try {\n const intl = (WINDOW as { Intl?: typeof Intl }).Intl;\n if (!intl) {\n return undefined;\n }\n\n const options = intl.DateTimeFormat().resolvedOptions();\n\n return {\n locale: options.locale,\n timezone: options.timeZone,\n calendar: options.calendar,\n };\n } catch {\n // Ignore errors\n return undefined;\n }\n}\n"],"names":[],"mappings":";;;AAIA,MAAM,gBAAA,GAAmB,gBAAA;AAEzB,MAAM,8BAA8B,MAAM;AACxC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,gBAAgB,KAAA,EAAO;AACrB,MAAA,MAAM,UAAU,iBAAA,EAAkB;AAElC,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,KAAA,CAAM,QAAA,GAAW;AAAA,UACf,GAAG,KAAA,CAAM,QAAA;AAAA,UACT,SAAS,EAAE,GAAG,SAAS,GAAG,KAAA,CAAM,UAAU,OAAA;AAAQ,SACpD;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,mBAAmB,IAAA,EAAM;AACvB,MAAA,MAAM,UAAU,iBAAA,EAAkB;AAElC,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,yBAAA,CAA0B,IAAA,EAAM;AAAA,UAC9B,kBAAkB,OAAA,CAAQ,MAAA;AAAA,UAC1B,oBAAoB,OAAA,CAAQ,QAAA;AAAA,UAC5B,oBAAoB,OAAA,CAAQ;AAAA,SAC7B,CAAA;AAAA,MACH;AAAA,IACF;AAAA,GACF;AACF,CAAA,CAAA;AAgBO,MAAM,yBAAA,GAA4B,kBAAkB,0BAA0B;AAKrF,SAAS,iBAAA,GAAgD;AACvD,EAAA,IAAI;AACF,IAAA,MAAM,OAAQ,MAAA,CAAkC,IAAA;AAChD,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,cAAA,EAAe,CAAE,eAAA,EAAgB;AAEtD,IAAA,OAAO;AAAA,MACL,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,UAAU,OAAA,CAAQ;AAAA,KACpB;AAAA,EACF,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"integration.js","sources":["../../../../../../../src/integrations/featureFlags/launchdarkly/integration.ts"],"sourcesContent":["import type { Client, Event, EventHint, IntegrationFn } from '@sentry/core/browser';\nimport {\n _INTERNAL_addFeatureFlagToActiveSpan,\n _INTERNAL_copyFlagsFromScopeToEvent,\n _INTERNAL_insertFlagToScope,\n defineIntegration,\n} from '@sentry/core/browser';\nimport type { LDContext, LDEvaluationDetail, LDInspectionFlagUsedHandler } from './types';\n\n/**\n * Sentry integration for capturing feature flag evaluations from LaunchDarkly.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import * as Sentry from '@sentry/browser';\n * import {launchDarklyIntegration, buildLaunchDarklyFlagUsedInspector} from '@sentry/browser';\n * import * as LaunchDarkly from 'launchdarkly-js-client-sdk';\n *\n * Sentry.init(..., integrations: [launchDarklyIntegration()])\n * const ldClient = LaunchDarkly.initialize(..., {inspectors: [buildLaunchDarklyFlagUsedHandler()]});\n * ```\n */\nexport const launchDarklyIntegration = defineIntegration(() => {\n return {\n name: 'LaunchDarkly',\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n return _INTERNAL_copyFlagsFromScopeToEvent(event);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * LaunchDarkly hook to listen for and buffer flag evaluations. This needs to\n * be registered as an 'inspector' in LaunchDarkly initialize() options,\n * separately from `launchDarklyIntegration`. Both the hook and the integration\n * are needed to capture LaunchDarkly flags.\n */\nexport function buildLaunchDarklyFlagUsedHandler(): LDInspectionFlagUsedHandler {\n return {\n name: 'sentry-flag-auditor',\n type: 'flag-used',\n\n synchronous: true,\n\n /**\n * Handle a flag evaluation by storing its name and value on the current scope.\n */\n method: (flagKey: string, flagDetail: LDEvaluationDetail, _context: LDContext) => {\n _INTERNAL_insertFlagToScope(flagKey, flagDetail.value);\n _INTERNAL_addFeatureFlagToActiveSpan(flagKey, flagDetail.value);\n },\n };\n}\n"],"names":[],"mappings":";;AAwBO,MAAM,uBAAA,GAA0B,kBAAkB,MAAM;AAC7D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,cAAA;AAAA,IAEN,YAAA,CAAa,KAAA,EAAc,KAAA,EAAkB,OAAA,EAAwB;AACnE,MAAA,OAAO,oCAAoC,KAAK,CAAA;AAAA,IAClD;AAAA,GACF;AACF,CAAC;AAQM,SAAS,gCAAA,GAAgE;AAC9E,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,qBAAA;AAAA,IACN,IAAA,EAAM,WAAA;AAAA,IAEN,WAAA,EAAa,IAAA;AAAA;AAAA;AAAA;AAAA,IAKb,MAAA,EAAQ,CAAC,OAAA,EAAiB,UAAA,EAAgC,QAAA,KAAwB;AAChF,MAAA,2BAAA,CAA4B,OAAA,EAAS,WAAW,KAAK,CAAA;AACrD,MAAA,oCAAA,CAAqC,OAAA,EAAS,WAAW,KAAK,CAAA;AAAA,IAChE;AAAA,GACF;AACF;;;;"}
1
+ {"version":3,"file":"integration.js","sources":["../../../../../../../src/integrations/featureFlags/launchdarkly/integration.ts"],"sourcesContent":["import type { Client, Event, EventHint, IntegrationFn } from '@sentry/core/browser';\nimport {\n _INTERNAL_addFeatureFlagToActiveSpan,\n _INTERNAL_copyFlagsFromScopeToEvent,\n _INTERNAL_insertFlagToScope,\n defineIntegration,\n} from '@sentry/core/browser';\nimport type { LDContext, LDEvaluationDetail, LDInspectionFlagUsedHandler } from './types';\n\n/**\n * Sentry integration for capturing feature flag evaluations from LaunchDarkly.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import * as Sentry from '@sentry/browser';\n * import {launchDarklyIntegration, buildLaunchDarklyFlagUsedInspector} from '@sentry/browser';\n * import * as LaunchDarkly from 'launchdarkly-js-client-sdk';\n *\n * Sentry.init(..., integrations: [launchDarklyIntegration()])\n * const ldClient = LaunchDarkly.initialize(..., {inspectors: [buildLaunchDarklyFlagUsedHandler()]});\n * ```\n */\nexport const launchDarklyIntegration = defineIntegration(() => {\n return {\n name: 'LaunchDarkly' as const,\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n return _INTERNAL_copyFlagsFromScopeToEvent(event);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * LaunchDarkly hook to listen for and buffer flag evaluations. This needs to\n * be registered as an 'inspector' in LaunchDarkly initialize() options,\n * separately from `launchDarklyIntegration`. Both the hook and the integration\n * are needed to capture LaunchDarkly flags.\n */\nexport function buildLaunchDarklyFlagUsedHandler(): LDInspectionFlagUsedHandler {\n return {\n name: 'sentry-flag-auditor',\n type: 'flag-used',\n\n synchronous: true,\n\n /**\n * Handle a flag evaluation by storing its name and value on the current scope.\n */\n method: (flagKey: string, flagDetail: LDEvaluationDetail, _context: LDContext) => {\n _INTERNAL_insertFlagToScope(flagKey, flagDetail.value);\n _INTERNAL_addFeatureFlagToActiveSpan(flagKey, flagDetail.value);\n },\n };\n}\n"],"names":[],"mappings":";;AAwBO,MAAM,uBAAA,GAA0B,kBAAkB,MAAM;AAC7D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,cAAA;AAAA,IAEN,YAAA,CAAa,KAAA,EAAc,KAAA,EAAkB,OAAA,EAAwB;AACnE,MAAA,OAAO,oCAAoC,KAAK,CAAA;AAAA,IAClD;AAAA,GACF;AACF,CAAC;AAQM,SAAS,gCAAA,GAAgE;AAC9E,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,qBAAA;AAAA,IACN,IAAA,EAAM,WAAA;AAAA,IAEN,WAAA,EAAa,IAAA;AAAA;AAAA;AAAA;AAAA,IAKb,MAAA,EAAQ,CAAC,OAAA,EAAiB,UAAA,EAAgC,QAAA,KAAwB;AAChF,MAAA,2BAAA,CAA4B,OAAA,EAAS,WAAW,KAAK,CAAA;AACrD,MAAA,oCAAA,CAAqC,OAAA,EAAS,WAAW,KAAK,CAAA;AAAA,IAChE;AAAA,GACF;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"integration.js","sources":["../../../../../../../src/integrations/featureFlags/openfeature/integration.ts"],"sourcesContent":["/**\n * Sentry integration for capturing OpenFeature feature flag evaluations.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import * as Sentry from \"@sentry/browser\";\n * import { OpenFeature } from \"@openfeature/web-sdk\";\n *\n * Sentry.init(..., integrations: [Sentry.openFeatureIntegration()]);\n * OpenFeature.setProvider(new MyProviderOfChoice());\n * OpenFeature.addHooks(new Sentry.OpenFeatureIntegrationHook());\n * ```\n */\nimport type { Client, Event, EventHint, IntegrationFn } from '@sentry/core/browser';\nimport {\n _INTERNAL_addFeatureFlagToActiveSpan,\n _INTERNAL_copyFlagsFromScopeToEvent,\n _INTERNAL_insertFlagToScope,\n defineIntegration,\n} from '@sentry/core/browser';\nimport type { EvaluationDetails, HookContext, HookHints, JsonValue, OpenFeatureHook } from './types';\n\nexport const openFeatureIntegration = defineIntegration(() => {\n return {\n name: 'OpenFeature',\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n return _INTERNAL_copyFlagsFromScopeToEvent(event);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * OpenFeature Hook class implementation.\n */\nexport class OpenFeatureIntegrationHook implements OpenFeatureHook {\n /**\n * Successful evaluation result.\n */\n public after(_hookContext: Readonly<HookContext<JsonValue>>, evaluationDetails: EvaluationDetails<JsonValue>): void {\n _INTERNAL_insertFlagToScope(evaluationDetails.flagKey, evaluationDetails.value);\n _INTERNAL_addFeatureFlagToActiveSpan(evaluationDetails.flagKey, evaluationDetails.value);\n }\n\n /**\n * On error evaluation result.\n */\n public error(hookContext: Readonly<HookContext<JsonValue>>, _error: unknown, _hookHints?: HookHints): void {\n _INTERNAL_insertFlagToScope(hookContext.flagKey, hookContext.defaultValue);\n _INTERNAL_addFeatureFlagToActiveSpan(hookContext.flagKey, hookContext.defaultValue);\n }\n}\n"],"names":[],"mappings":";;AAwBO,MAAM,sBAAA,GAAyB,kBAAkB,MAAM;AAC5D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,aAAA;AAAA,IAEN,YAAA,CAAa,KAAA,EAAc,KAAA,EAAkB,OAAA,EAAwB;AACnE,MAAA,OAAO,oCAAoC,KAAK,CAAA;AAAA,IAClD;AAAA,GACF;AACF,CAAC;AAKM,MAAM,0BAAA,CAAsD;AAAA;AAAA;AAAA;AAAA,EAI1D,KAAA,CAAM,cAAgD,iBAAA,EAAuD;AAClH,IAAA,2BAAA,CAA4B,iBAAA,CAAkB,OAAA,EAAS,iBAAA,CAAkB,KAAK,CAAA;AAC9E,IAAA,oCAAA,CAAqC,iBAAA,CAAkB,OAAA,EAAS,iBAAA,CAAkB,KAAK,CAAA;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA,EAKO,KAAA,CAAM,WAAA,EAA+C,MAAA,EAAiB,UAAA,EAA8B;AACzG,IAAA,2BAAA,CAA4B,WAAA,CAAY,OAAA,EAAS,WAAA,CAAY,YAAY,CAAA;AACzE,IAAA,oCAAA,CAAqC,WAAA,CAAY,OAAA,EAAS,WAAA,CAAY,YAAY,CAAA;AAAA,EACpF;AACF;;;;"}
1
+ {"version":3,"file":"integration.js","sources":["../../../../../../../src/integrations/featureFlags/openfeature/integration.ts"],"sourcesContent":["/**\n * Sentry integration for capturing OpenFeature feature flag evaluations.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import * as Sentry from \"@sentry/browser\";\n * import { OpenFeature } from \"@openfeature/web-sdk\";\n *\n * Sentry.init(..., integrations: [Sentry.openFeatureIntegration()]);\n * OpenFeature.setProvider(new MyProviderOfChoice());\n * OpenFeature.addHooks(new Sentry.OpenFeatureIntegrationHook());\n * ```\n */\nimport type { Client, Event, EventHint, IntegrationFn } from '@sentry/core/browser';\nimport {\n _INTERNAL_addFeatureFlagToActiveSpan,\n _INTERNAL_copyFlagsFromScopeToEvent,\n _INTERNAL_insertFlagToScope,\n defineIntegration,\n} from '@sentry/core/browser';\nimport type { EvaluationDetails, HookContext, HookHints, JsonValue, OpenFeatureHook } from './types';\n\nexport const openFeatureIntegration = defineIntegration(() => {\n return {\n name: 'OpenFeature' as const,\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n return _INTERNAL_copyFlagsFromScopeToEvent(event);\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * OpenFeature Hook class implementation.\n */\nexport class OpenFeatureIntegrationHook implements OpenFeatureHook {\n /**\n * Successful evaluation result.\n */\n public after(_hookContext: Readonly<HookContext<JsonValue>>, evaluationDetails: EvaluationDetails<JsonValue>): void {\n _INTERNAL_insertFlagToScope(evaluationDetails.flagKey, evaluationDetails.value);\n _INTERNAL_addFeatureFlagToActiveSpan(evaluationDetails.flagKey, evaluationDetails.value);\n }\n\n /**\n * On error evaluation result.\n */\n public error(hookContext: Readonly<HookContext<JsonValue>>, _error: unknown, _hookHints?: HookHints): void {\n _INTERNAL_insertFlagToScope(hookContext.flagKey, hookContext.defaultValue);\n _INTERNAL_addFeatureFlagToActiveSpan(hookContext.flagKey, hookContext.defaultValue);\n }\n}\n"],"names":[],"mappings":";;AAwBO,MAAM,sBAAA,GAAyB,kBAAkB,MAAM;AAC5D,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,aAAA;AAAA,IAEN,YAAA,CAAa,KAAA,EAAc,KAAA,EAAkB,OAAA,EAAwB;AACnE,MAAA,OAAO,oCAAoC,KAAK,CAAA;AAAA,IAClD;AAAA,GACF;AACF,CAAC;AAKM,MAAM,0BAAA,CAAsD;AAAA;AAAA;AAAA;AAAA,EAI1D,KAAA,CAAM,cAAgD,iBAAA,EAAuD;AAClH,IAAA,2BAAA,CAA4B,iBAAA,CAAkB,OAAA,EAAS,iBAAA,CAAkB,KAAK,CAAA;AAC9E,IAAA,oCAAA,CAAqC,iBAAA,CAAkB,OAAA,EAAS,iBAAA,CAAkB,KAAK,CAAA;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA,EAKO,KAAA,CAAM,WAAA,EAA+C,MAAA,EAAiB,UAAA,EAA8B;AACzG,IAAA,2BAAA,CAA4B,WAAA,CAAY,OAAA,EAAS,WAAA,CAAY,YAAY,CAAA;AACzE,IAAA,oCAAA,CAAqC,WAAA,CAAY,OAAA,EAAS,WAAA,CAAY,YAAY,CAAA;AAAA,EACpF;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"integration.js","sources":["../../../../../../../src/integrations/featureFlags/statsig/integration.ts"],"sourcesContent":["import type { Client, Event, EventHint, IntegrationFn } from '@sentry/core/browser';\nimport {\n _INTERNAL_addFeatureFlagToActiveSpan,\n _INTERNAL_copyFlagsFromScopeToEvent,\n _INTERNAL_insertFlagToScope,\n defineIntegration,\n} from '@sentry/core/browser';\nimport type { FeatureGate, StatsigClient } from './types';\n\n/**\n * Sentry integration for capturing feature flag evaluations from the Statsig js-client SDK.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import { StatsigClient } from '@statsig/js-client';\n * import * as Sentry from '@sentry/browser';\n *\n * const statsigClient = new StatsigClient();\n *\n * Sentry.init({\n * dsn: '___PUBLIC_DSN___',\n * integrations: [Sentry.statsigIntegration({featureFlagClient: statsigClient})],\n * });\n *\n * await statsigClient.initializeAsync(); // or statsigClient.initializeSync();\n *\n * const result = statsigClient.checkGate('my-feature-gate');\n * Sentry.captureException(new Error('something went wrong'));\n * ```\n */\nexport const statsigIntegration = defineIntegration(\n ({ featureFlagClient: statsigClient }: { featureFlagClient: StatsigClient }) => {\n return {\n name: 'Statsig',\n\n setup(_client: Client) {\n statsigClient.on('gate_evaluation', (event: { gate: FeatureGate }) => {\n _INTERNAL_insertFlagToScope(event.gate.name, event.gate.value);\n _INTERNAL_addFeatureFlagToActiveSpan(event.gate.name, event.gate.value);\n });\n },\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n return _INTERNAL_copyFlagsFromScopeToEvent(event);\n },\n };\n },\n) satisfies IntegrationFn;\n"],"names":[],"mappings":";;AAgCO,MAAM,kBAAA,GAAqB,iBAAA;AAAA,EAChC,CAAC,EAAE,iBAAA,EAAmB,aAAA,EAAc,KAA4C;AAC9E,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,SAAA;AAAA,MAEN,MAAM,OAAA,EAAiB;AACrB,QAAA,aAAA,CAAc,EAAA,CAAG,iBAAA,EAAmB,CAAC,KAAA,KAAiC;AACpE,UAAA,2BAAA,CAA4B,KAAA,CAAM,IAAA,CAAK,IAAA,EAAM,KAAA,CAAM,KAAK,KAAK,CAAA;AAC7D,UAAA,oCAAA,CAAqC,KAAA,CAAM,IAAA,CAAK,IAAA,EAAM,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,QACxE,CAAC,CAAA;AAAA,MACH,CAAA;AAAA,MAEA,YAAA,CAAa,KAAA,EAAc,KAAA,EAAkB,OAAA,EAAwB;AACnE,QAAA,OAAO,oCAAoC,KAAK,CAAA;AAAA,MAClD;AAAA,KACF;AAAA,EACF;AACF;;;;"}
1
+ {"version":3,"file":"integration.js","sources":["../../../../../../../src/integrations/featureFlags/statsig/integration.ts"],"sourcesContent":["import type { Client, Event, EventHint, IntegrationFn } from '@sentry/core/browser';\nimport {\n _INTERNAL_addFeatureFlagToActiveSpan,\n _INTERNAL_copyFlagsFromScopeToEvent,\n _INTERNAL_insertFlagToScope,\n defineIntegration,\n} from '@sentry/core/browser';\nimport type { FeatureGate, StatsigClient } from './types';\n\n/**\n * Sentry integration for capturing feature flag evaluations from the Statsig js-client SDK.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import { StatsigClient } from '@statsig/js-client';\n * import * as Sentry from '@sentry/browser';\n *\n * const statsigClient = new StatsigClient();\n *\n * Sentry.init({\n * dsn: '___PUBLIC_DSN___',\n * integrations: [Sentry.statsigIntegration({featureFlagClient: statsigClient})],\n * });\n *\n * await statsigClient.initializeAsync(); // or statsigClient.initializeSync();\n *\n * const result = statsigClient.checkGate('my-feature-gate');\n * Sentry.captureException(new Error('something went wrong'));\n * ```\n */\nexport const statsigIntegration = defineIntegration(\n ({ featureFlagClient: statsigClient }: { featureFlagClient: StatsigClient }) => {\n return {\n name: 'Statsig' as const,\n\n setup(_client: Client) {\n statsigClient.on('gate_evaluation', (event: { gate: FeatureGate }) => {\n _INTERNAL_insertFlagToScope(event.gate.name, event.gate.value);\n _INTERNAL_addFeatureFlagToActiveSpan(event.gate.name, event.gate.value);\n });\n },\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n return _INTERNAL_copyFlagsFromScopeToEvent(event);\n },\n };\n },\n) satisfies IntegrationFn;\n"],"names":[],"mappings":";;AAgCO,MAAM,kBAAA,GAAqB,iBAAA;AAAA,EAChC,CAAC,EAAE,iBAAA,EAAmB,aAAA,EAAc,KAA4C;AAC9E,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,SAAA;AAAA,MAEN,MAAM,OAAA,EAAiB;AACrB,QAAA,aAAA,CAAc,EAAA,CAAG,iBAAA,EAAmB,CAAC,KAAA,KAAiC;AACpE,UAAA,2BAAA,CAA4B,KAAA,CAAM,IAAA,CAAK,IAAA,EAAM,KAAA,CAAM,KAAK,KAAK,CAAA;AAC7D,UAAA,oCAAA,CAAqC,KAAA,CAAM,IAAA,CAAK,IAAA,EAAM,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,QACxE,CAAC,CAAA;AAAA,MACH,CAAA;AAAA,MAEA,YAAA,CAAa,KAAA,EAAc,KAAA,EAAkB,OAAA,EAAwB;AACnE,QAAA,OAAO,oCAAoC,KAAK,CAAA;AAAA,MAClD;AAAA,KACF;AAAA,EACF;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"integration.js","sources":["../../../../../../../src/integrations/featureFlags/unleash/integration.ts"],"sourcesContent":["import type { Client, Event, EventHint, IntegrationFn } from '@sentry/core/browser';\nimport {\n _INTERNAL_addFeatureFlagToActiveSpan,\n _INTERNAL_copyFlagsFromScopeToEvent,\n _INTERNAL_insertFlagToScope,\n debug,\n defineIntegration,\n fill,\n} from '@sentry/core/browser';\nimport { DEBUG_BUILD } from '../../../debug-build';\nimport type { UnleashClient, UnleashClientClass } from './types';\n\ntype UnleashIntegrationOptions = {\n featureFlagClientClass: UnleashClientClass;\n};\n\n/**\n * Sentry integration for capturing feature flag evaluations from the Unleash SDK.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import { UnleashClient } from 'unleash-proxy-client';\n * import * as Sentry from '@sentry/browser';\n *\n * Sentry.init({\n * dsn: '___PUBLIC_DSN___',\n * integrations: [Sentry.unleashIntegration({featureFlagClientClass: UnleashClient})],\n * });\n *\n * const unleash = new UnleashClient(...);\n * unleash.start();\n *\n * unleash.isEnabled('my-feature');\n * Sentry.captureException(new Error('something went wrong'));\n * ```\n */\nexport const unleashIntegration = defineIntegration(\n ({ featureFlagClientClass: unleashClientClass }: UnleashIntegrationOptions) => {\n return {\n name: 'Unleash',\n\n setupOnce() {\n const unleashClientPrototype = unleashClientClass.prototype as UnleashClient;\n fill(unleashClientPrototype, 'isEnabled', _wrappedIsEnabled);\n },\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n return _INTERNAL_copyFlagsFromScopeToEvent(event);\n },\n };\n },\n) satisfies IntegrationFn;\n\n/**\n * Wraps the UnleashClient.isEnabled method to capture feature flag evaluations. Its only side effect is writing to Sentry scope.\n *\n * This wrapper is safe for all isEnabled signatures. If the signature does not match (this: UnleashClient, toggleName: string, ...args: unknown[]) => boolean,\n * we log an error and return the original result.\n *\n * @param original - The original method.\n * @returns Wrapped method. Results should match the original.\n */\nfunction _wrappedIsEnabled(\n original: (this: UnleashClient, ...args: unknown[]) => unknown,\n): (this: UnleashClient, ...args: unknown[]) => unknown {\n return function (this: UnleashClient, ...args: unknown[]): unknown {\n const toggleName = args[0];\n const result = original.apply(this, args);\n\n if (typeof toggleName === 'string' && typeof result === 'boolean') {\n _INTERNAL_insertFlagToScope(toggleName, result);\n _INTERNAL_addFeatureFlagToActiveSpan(toggleName, result);\n } else if (DEBUG_BUILD) {\n debug.error(\n `[Feature Flags] UnleashClient.isEnabled does not match expected signature. arg0: ${toggleName} (${typeof toggleName}), result: ${result} (${typeof result})`,\n );\n }\n return result;\n };\n}\n"],"names":[],"mappings":";;;AAsCO,MAAM,kBAAA,GAAqB,iBAAA;AAAA,EAChC,CAAC,EAAE,sBAAA,EAAwB,kBAAA,EAAmB,KAAiC;AAC7E,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,SAAA;AAAA,MAEN,SAAA,GAAY;AACV,QAAA,MAAM,yBAAyB,kBAAA,CAAmB,SAAA;AAClD,QAAA,IAAA,CAAK,sBAAA,EAAwB,aAAa,iBAAiB,CAAA;AAAA,MAC7D,CAAA;AAAA,MAEA,YAAA,CAAa,KAAA,EAAc,KAAA,EAAkB,OAAA,EAAwB;AACnE,QAAA,OAAO,oCAAoC,KAAK,CAAA;AAAA,MAClD;AAAA,KACF;AAAA,EACF;AACF;AAWA,SAAS,kBACP,QAAA,EACsD;AACtD,EAAA,OAAO,YAAkC,IAAA,EAA0B;AACjE,IAAA,MAAM,UAAA,GAAa,KAAK,CAAC,CAAA;AACzB,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,IAAA,EAAM,IAAI,CAAA;AAExC,IAAA,IAAI,OAAO,UAAA,KAAe,QAAA,IAAY,OAAO,WAAW,SAAA,EAAW;AACjE,MAAA,2BAAA,CAA4B,YAAY,MAAM,CAAA;AAC9C,MAAA,oCAAA,CAAqC,YAAY,MAAM,CAAA;AAAA,IACzD,WAAW,WAAA,EAAa;AACtB,MAAA,KAAA,CAAM,KAAA;AAAA,QACJ,CAAA,iFAAA,EAAoF,UAAU,CAAA,EAAA,EAAK,OAAO,UAAU,CAAA,WAAA,EAAc,MAAM,CAAA,EAAA,EAAK,OAAO,MAAM,CAAA,CAAA;AAAA,OAC5J;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AACF;;;;"}
1
+ {"version":3,"file":"integration.js","sources":["../../../../../../../src/integrations/featureFlags/unleash/integration.ts"],"sourcesContent":["import type { Client, Event, EventHint, IntegrationFn } from '@sentry/core/browser';\nimport {\n _INTERNAL_addFeatureFlagToActiveSpan,\n _INTERNAL_copyFlagsFromScopeToEvent,\n _INTERNAL_insertFlagToScope,\n debug,\n defineIntegration,\n fill,\n} from '@sentry/core/browser';\nimport { DEBUG_BUILD } from '../../../debug-build';\nimport type { UnleashClient, UnleashClientClass } from './types';\n\ntype UnleashIntegrationOptions = {\n featureFlagClientClass: UnleashClientClass;\n};\n\n/**\n * Sentry integration for capturing feature flag evaluations from the Unleash SDK.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import { UnleashClient } from 'unleash-proxy-client';\n * import * as Sentry from '@sentry/browser';\n *\n * Sentry.init({\n * dsn: '___PUBLIC_DSN___',\n * integrations: [Sentry.unleashIntegration({featureFlagClientClass: UnleashClient})],\n * });\n *\n * const unleash = new UnleashClient(...);\n * unleash.start();\n *\n * unleash.isEnabled('my-feature');\n * Sentry.captureException(new Error('something went wrong'));\n * ```\n */\nexport const unleashIntegration = defineIntegration(\n ({ featureFlagClientClass: unleashClientClass }: UnleashIntegrationOptions) => {\n return {\n name: 'Unleash' as const,\n\n setupOnce() {\n const unleashClientPrototype = unleashClientClass.prototype as UnleashClient;\n fill(unleashClientPrototype, 'isEnabled', _wrappedIsEnabled);\n },\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n return _INTERNAL_copyFlagsFromScopeToEvent(event);\n },\n };\n },\n) satisfies IntegrationFn;\n\n/**\n * Wraps the UnleashClient.isEnabled method to capture feature flag evaluations. Its only side effect is writing to Sentry scope.\n *\n * This wrapper is safe for all isEnabled signatures. If the signature does not match (this: UnleashClient, toggleName: string, ...args: unknown[]) => boolean,\n * we log an error and return the original result.\n *\n * @param original - The original method.\n * @returns Wrapped method. Results should match the original.\n */\nfunction _wrappedIsEnabled(\n original: (this: UnleashClient, ...args: unknown[]) => unknown,\n): (this: UnleashClient, ...args: unknown[]) => unknown {\n return function (this: UnleashClient, ...args: unknown[]): unknown {\n const toggleName = args[0];\n const result = original.apply(this, args);\n\n if (typeof toggleName === 'string' && typeof result === 'boolean') {\n _INTERNAL_insertFlagToScope(toggleName, result);\n _INTERNAL_addFeatureFlagToActiveSpan(toggleName, result);\n } else if (DEBUG_BUILD) {\n debug.error(\n `[Feature Flags] UnleashClient.isEnabled does not match expected signature. arg0: ${toggleName} (${typeof toggleName}), result: ${result} (${typeof result})`,\n );\n }\n return result;\n };\n}\n"],"names":[],"mappings":";;;AAsCO,MAAM,kBAAA,GAAqB,iBAAA;AAAA,EAChC,CAAC,EAAE,sBAAA,EAAwB,kBAAA,EAAmB,KAAiC;AAC7E,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,SAAA;AAAA,MAEN,SAAA,GAAY;AACV,QAAA,MAAM,yBAAyB,kBAAA,CAAmB,SAAA;AAClD,QAAA,IAAA,CAAK,sBAAA,EAAwB,aAAa,iBAAiB,CAAA;AAAA,MAC7D,CAAA;AAAA,MAEA,YAAA,CAAa,KAAA,EAAc,KAAA,EAAkB,OAAA,EAAwB;AACnE,QAAA,OAAO,oCAAoC,KAAK,CAAA;AAAA,MAClD;AAAA,KACF;AAAA,EACF;AACF;AAWA,SAAS,kBACP,QAAA,EACsD;AACtD,EAAA,OAAO,YAAkC,IAAA,EAA0B;AACjE,IAAA,MAAM,UAAA,GAAa,KAAK,CAAC,CAAA;AACzB,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,IAAA,EAAM,IAAI,CAAA;AAExC,IAAA,IAAI,OAAO,UAAA,KAAe,QAAA,IAAY,OAAO,WAAW,SAAA,EAAW;AACjE,MAAA,2BAAA,CAA4B,YAAY,MAAM,CAAA;AAC9C,MAAA,oCAAA,CAAqC,YAAY,MAAM,CAAA;AAAA,IACzD,WAAW,WAAA,EAAa;AACtB,MAAA,KAAA,CAAM,KAAA;AAAA,QACJ,CAAA,iFAAA,EAAoF,UAAU,CAAA,EAAA,EAAK,OAAO,UAAU,CAAA,WAAA,EAAc,MAAM,CAAA,EAAA,EAAK,OAAO,MAAM,CAAA,CAAA;AAAA,OAC5J;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AACF;;;;"}