@sentry/core 10.37.0 → 10.39.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/build/cjs/attributes.js.map +1 -1
  2. package/build/cjs/client.js +22 -12
  3. package/build/cjs/client.js.map +1 -1
  4. package/build/cjs/envelope.js +41 -7
  5. package/build/cjs/envelope.js.map +1 -1
  6. package/build/cjs/index.js +131 -79
  7. package/build/cjs/index.js.map +1 -1
  8. package/build/cjs/integration.js +12 -0
  9. package/build/cjs/integration.js.map +1 -1
  10. package/build/cjs/integrations/captureconsole.js +2 -2
  11. package/build/cjs/integrations/captureconsole.js.map +1 -1
  12. package/build/cjs/integrations/eventFilters.js +1 -1
  13. package/build/cjs/integrations/eventFilters.js.map +1 -1
  14. package/build/cjs/integrations/mcp-server/correlation.js +54 -10
  15. package/build/cjs/integrations/mcp-server/correlation.js.map +1 -1
  16. package/build/cjs/integrations/mcp-server/errorCapture.js +2 -2
  17. package/build/cjs/integrations/mcp-server/errorCapture.js.map +1 -1
  18. package/build/cjs/integrations/mcp-server/sessionManagement.js +50 -16
  19. package/build/cjs/integrations/mcp-server/sessionManagement.js.map +1 -1
  20. package/build/cjs/integrations/requestdata.js +72 -6
  21. package/build/cjs/integrations/requestdata.js.map +1 -1
  22. package/build/cjs/integrations/spanStreaming.js +54 -0
  23. package/build/cjs/integrations/spanStreaming.js.map +1 -0
  24. package/build/cjs/integrations/supabase.js +4 -4
  25. package/build/cjs/integrations/supabase.js.map +1 -1
  26. package/build/cjs/metrics/public-api.js +3 -3
  27. package/build/cjs/metrics/public-api.js.map +1 -1
  28. package/build/cjs/scope.js +1 -1
  29. package/build/cjs/scope.js.map +1 -1
  30. package/build/cjs/semanticAttributes.js +84 -0
  31. package/build/cjs/semanticAttributes.js.map +1 -1
  32. package/build/cjs/spans/captureSpan.js +104 -0
  33. package/build/cjs/spans/captureSpan.js.map +1 -0
  34. package/build/cjs/spans/spanBuffer.js +121 -0
  35. package/build/cjs/spans/spanBuffer.js.map +1 -0
  36. package/build/cjs/spans/spanFirstUtils.js +186 -0
  37. package/build/cjs/spans/spanFirstUtils.js.map +1 -0
  38. package/build/cjs/tracing/ai/gen-ai-attributes.js +6 -0
  39. package/build/cjs/tracing/ai/gen-ai-attributes.js.map +1 -1
  40. package/build/cjs/tracing/anthropic-ai/index.js +3 -3
  41. package/build/cjs/tracing/anthropic-ai/index.js.map +1 -1
  42. package/build/cjs/tracing/anthropic-ai/streaming.js +3 -3
  43. package/build/cjs/tracing/anthropic-ai/streaming.js.map +1 -1
  44. package/build/cjs/tracing/anthropic-ai/utils.js +2 -2
  45. package/build/cjs/tracing/anthropic-ai/utils.js.map +1 -1
  46. package/build/cjs/tracing/google-genai/index.js +3 -3
  47. package/build/cjs/tracing/google-genai/index.js.map +1 -1
  48. package/build/cjs/tracing/google-genai/streaming.js +2 -2
  49. package/build/cjs/tracing/google-genai/streaming.js.map +1 -1
  50. package/build/cjs/tracing/langchain/index.js +4 -4
  51. package/build/cjs/tracing/langchain/index.js.map +1 -1
  52. package/build/cjs/tracing/langgraph/index.js +3 -3
  53. package/build/cjs/tracing/langgraph/index.js.map +1 -1
  54. package/build/cjs/tracing/openai/index.js +136 -53
  55. package/build/cjs/tracing/openai/index.js.map +1 -1
  56. package/build/cjs/tracing/openai/streaming.js +2 -2
  57. package/build/cjs/tracing/openai/streaming.js.map +1 -1
  58. package/build/cjs/tracing/sentrySpan.js +32 -0
  59. package/build/cjs/tracing/sentrySpan.js.map +1 -1
  60. package/build/cjs/tracing/trace.js +1 -0
  61. package/build/cjs/tracing/trace.js.map +1 -1
  62. package/build/cjs/tracing/vercel-ai/constants.js +4 -0
  63. package/build/cjs/tracing/vercel-ai/constants.js.map +1 -1
  64. package/build/cjs/tracing/vercel-ai/index.js +14 -0
  65. package/build/cjs/tracing/vercel-ai/index.js.map +1 -1
  66. package/build/cjs/tracing/vercel-ai/utils.js +71 -22
  67. package/build/cjs/tracing/vercel-ai/utils.js.map +1 -1
  68. package/build/cjs/transports/base.js +18 -2
  69. package/build/cjs/transports/base.js.map +1 -1
  70. package/build/cjs/transports/offline.js +16 -17
  71. package/build/cjs/transports/offline.js.map +1 -1
  72. package/build/cjs/trpc.js +3 -3
  73. package/build/cjs/trpc.js.map +1 -1
  74. package/build/cjs/utils/aggregate-errors.js +13 -5
  75. package/build/cjs/utils/aggregate-errors.js.map +1 -1
  76. package/build/cjs/utils/beforeSendSpan.js +36 -0
  77. package/build/cjs/utils/beforeSendSpan.js.map +1 -0
  78. package/build/cjs/utils/envToBool.js +32 -0
  79. package/build/cjs/utils/envToBool.js.map +1 -0
  80. package/build/cjs/utils/exports.js +7 -7
  81. package/build/cjs/utils/exports.js.map +1 -1
  82. package/build/cjs/utils/featureFlags.js +1 -0
  83. package/build/cjs/utils/featureFlags.js.map +1 -1
  84. package/build/cjs/utils/flushIfServerless.js +2 -2
  85. package/build/cjs/utils/flushIfServerless.js.map +1 -1
  86. package/build/cjs/utils/hasSpanStreamingEnabled.js +21 -0
  87. package/build/cjs/utils/hasSpanStreamingEnabled.js.map +1 -0
  88. package/build/cjs/utils/prepareEvent.js +6 -1
  89. package/build/cjs/utils/prepareEvent.js.map +1 -1
  90. package/build/cjs/utils/promisebuffer.js +5 -3
  91. package/build/cjs/utils/promisebuffer.js.map +1 -1
  92. package/build/cjs/utils/scopeData.js +4 -0
  93. package/build/cjs/utils/scopeData.js.map +1 -1
  94. package/build/cjs/utils/sdkMetadata.js +7 -11
  95. package/build/cjs/utils/sdkMetadata.js.map +1 -1
  96. package/build/cjs/utils/should-ignore-span.js +31 -9
  97. package/build/cjs/utils/should-ignore-span.js.map +1 -1
  98. package/build/cjs/utils/spanUtils.js +90 -2
  99. package/build/cjs/utils/spanUtils.js.map +1 -1
  100. package/build/cjs/utils/timer.js +20 -0
  101. package/build/cjs/utils/timer.js.map +1 -0
  102. package/build/cjs/utils/traceData.js +2 -2
  103. package/build/cjs/utils/traceData.js.map +1 -1
  104. package/build/cjs/utils/tracePropagationTargets.js +38 -0
  105. package/build/cjs/utils/tracePropagationTargets.js.map +1 -0
  106. package/build/cjs/utils/version.js +1 -1
  107. package/build/cjs/utils/version.js.map +1 -1
  108. package/build/esm/attributes.js.map +1 -1
  109. package/build/esm/client.js +18 -8
  110. package/build/esm/client.js.map +1 -1
  111. package/build/esm/envelope.js +41 -8
  112. package/build/esm/envelope.js.map +1 -1
  113. package/build/esm/exports.js +2 -2
  114. package/build/esm/feedback.js +1 -1
  115. package/build/esm/index.js +12 -3
  116. package/build/esm/index.js.map +1 -1
  117. package/build/esm/integration.js +12 -1
  118. package/build/esm/integration.js.map +1 -1
  119. package/build/esm/integrations/eventFilters.js +1 -1
  120. package/build/esm/integrations/eventFilters.js.map +1 -1
  121. package/build/esm/integrations/mcp-server/correlation.js +54 -10
  122. package/build/esm/integrations/mcp-server/correlation.js.map +1 -1
  123. package/build/esm/integrations/mcp-server/sessionManagement.js +50 -16
  124. package/build/esm/integrations/mcp-server/sessionManagement.js.map +1 -1
  125. package/build/esm/integrations/moduleMetadata.js +1 -1
  126. package/build/esm/integrations/requestdata.js +72 -6
  127. package/build/esm/integrations/requestdata.js.map +1 -1
  128. package/build/esm/integrations/spanStreaming.js +52 -0
  129. package/build/esm/integrations/spanStreaming.js.map +1 -0
  130. package/build/esm/integrations/third-party-errors-filter.js +1 -1
  131. package/build/esm/logs/internal.js +1 -1
  132. package/build/esm/metrics/public-api.js +3 -3
  133. package/build/esm/metrics/public-api.js.map +1 -1
  134. package/build/esm/package.json +1 -1
  135. package/build/esm/scope.js +1 -1
  136. package/build/esm/scope.js.map +1 -1
  137. package/build/esm/semanticAttributes.js +57 -1
  138. package/build/esm/semanticAttributes.js.map +1 -1
  139. package/build/esm/spans/captureSpan.js +102 -0
  140. package/build/esm/spans/captureSpan.js.map +1 -0
  141. package/build/esm/spans/spanBuffer.js +119 -0
  142. package/build/esm/spans/spanBuffer.js.map +1 -0
  143. package/build/esm/spans/spanFirstUtils.js +182 -0
  144. package/build/esm/spans/spanFirstUtils.js.map +1 -0
  145. package/build/esm/tracing/ai/gen-ai-attributes.js +6 -1
  146. package/build/esm/tracing/ai/gen-ai-attributes.js.map +1 -1
  147. package/build/esm/tracing/measurement.js +1 -1
  148. package/build/esm/tracing/openai/index.js +134 -51
  149. package/build/esm/tracing/openai/index.js.map +1 -1
  150. package/build/esm/tracing/sentrySpan.js +33 -1
  151. package/build/esm/tracing/sentrySpan.js.map +1 -1
  152. package/build/esm/tracing/trace.js +4 -3
  153. package/build/esm/tracing/trace.js.map +1 -1
  154. package/build/esm/tracing/vercel-ai/constants.js +4 -1
  155. package/build/esm/tracing/vercel-ai/constants.js.map +1 -1
  156. package/build/esm/tracing/vercel-ai/index.js +15 -1
  157. package/build/esm/tracing/vercel-ai/index.js.map +1 -1
  158. package/build/esm/tracing/vercel-ai/utils.js +73 -24
  159. package/build/esm/tracing/vercel-ai/utils.js.map +1 -1
  160. package/build/esm/transports/base.js +18 -2
  161. package/build/esm/transports/base.js.map +1 -1
  162. package/build/esm/transports/offline.js +16 -17
  163. package/build/esm/transports/offline.js.map +1 -1
  164. package/build/esm/utils/aggregate-errors.js +13 -5
  165. package/build/esm/utils/aggregate-errors.js.map +1 -1
  166. package/build/esm/utils/beforeSendSpan.js +33 -0
  167. package/build/esm/utils/beforeSendSpan.js.map +1 -0
  168. package/build/esm/utils/envToBool.js +28 -0
  169. package/build/esm/utils/envToBool.js.map +1 -0
  170. package/build/esm/utils/exports.js +7 -7
  171. package/build/esm/utils/exports.js.map +1 -1
  172. package/build/esm/utils/featureFlags.js +1 -0
  173. package/build/esm/utils/featureFlags.js.map +1 -1
  174. package/build/esm/utils/flushIfServerless.js.map +1 -1
  175. package/build/esm/utils/hasSpanStreamingEnabled.js +19 -0
  176. package/build/esm/utils/hasSpanStreamingEnabled.js.map +1 -0
  177. package/build/esm/utils/prepareEvent.js +6 -1
  178. package/build/esm/utils/prepareEvent.js.map +1 -1
  179. package/build/esm/utils/promisebuffer.js +5 -3
  180. package/build/esm/utils/promisebuffer.js.map +1 -1
  181. package/build/esm/utils/scopeData.js +4 -0
  182. package/build/esm/utils/scopeData.js.map +1 -1
  183. package/build/esm/utils/sdkMetadata.js +7 -11
  184. package/build/esm/utils/sdkMetadata.js.map +1 -1
  185. package/build/esm/utils/should-ignore-span.js +31 -9
  186. package/build/esm/utils/should-ignore-span.js.map +1 -1
  187. package/build/esm/utils/spanUtils.js +87 -3
  188. package/build/esm/utils/spanUtils.js.map +1 -1
  189. package/build/esm/utils/timer.js +18 -0
  190. package/build/esm/utils/timer.js.map +1 -0
  191. package/build/esm/utils/tracePropagationTargets.js +36 -0
  192. package/build/esm/utils/tracePropagationTargets.js.map +1 -0
  193. package/build/esm/utils/version.js +1 -1
  194. package/build/esm/utils/version.js.map +1 -1
  195. package/build/types/attributes.d.ts +1 -1
  196. package/build/types/attributes.d.ts.map +1 -1
  197. package/build/types/client.d.ts +40 -2
  198. package/build/types/client.d.ts.map +1 -1
  199. package/build/types/envelope.d.ts +6 -1
  200. package/build/types/envelope.d.ts.map +1 -1
  201. package/build/types/index.d.ts +13 -4
  202. package/build/types/index.d.ts.map +1 -1
  203. package/build/types/integration.d.ts +4 -0
  204. package/build/types/integration.d.ts.map +1 -1
  205. package/build/types/integrations/mcp-server/correlation.d.ts +6 -2
  206. package/build/types/integrations/mcp-server/correlation.d.ts.map +1 -1
  207. package/build/types/integrations/mcp-server/sessionManagement.d.ts +8 -2
  208. package/build/types/integrations/mcp-server/sessionManagement.d.ts.map +1 -1
  209. package/build/types/integrations/requestdata.d.ts.map +1 -1
  210. package/build/types/integrations/spanStreaming.d.ts +11 -0
  211. package/build/types/integrations/spanStreaming.d.ts.map +1 -0
  212. package/build/types/metrics/public-api.d.ts +3 -3
  213. package/build/types/semanticAttributes.d.ts +38 -0
  214. package/build/types/semanticAttributes.d.ts.map +1 -1
  215. package/build/types/spans/captureSpan.d.ts +10 -0
  216. package/build/types/spans/captureSpan.d.ts.map +1 -0
  217. package/build/types/spans/spanBuffer.d.ts +35 -0
  218. package/build/types/spans/spanBuffer.d.ts.map +1 -0
  219. package/build/types/spans/spanFirstUtils.d.ts +20 -0
  220. package/build/types/spans/spanFirstUtils.d.ts.map +1 -0
  221. package/build/types/tracing/ai/gen-ai-attributes.d.ts +4 -0
  222. package/build/types/tracing/ai/gen-ai-attributes.d.ts.map +1 -1
  223. package/build/types/tracing/openai/index.d.ts.map +1 -1
  224. package/build/types/tracing/sentrySpan.d.ts +10 -1
  225. package/build/types/tracing/sentrySpan.d.ts.map +1 -1
  226. package/build/types/tracing/vercel-ai/constants.d.ts +1 -0
  227. package/build/types/tracing/vercel-ai/constants.d.ts.map +1 -1
  228. package/build/types/tracing/vercel-ai/index.d.ts.map +1 -1
  229. package/build/types/tracing/vercel-ai/utils.d.ts +2 -2
  230. package/build/types/tracing/vercel-ai/utils.d.ts.map +1 -1
  231. package/build/types/transports/base.d.ts.map +1 -1
  232. package/build/types/transports/offline.d.ts.map +1 -1
  233. package/build/types/types-hoist/attributes.d.ts +19 -0
  234. package/build/types/types-hoist/attributes.d.ts.map +1 -0
  235. package/build/types/types-hoist/envelope.d.ts +22 -2
  236. package/build/types/types-hoist/envelope.d.ts.map +1 -1
  237. package/build/types/types-hoist/feedback/index.d.ts.map +1 -1
  238. package/build/types/types-hoist/integration.d.ts +7 -0
  239. package/build/types/types-hoist/integration.d.ts.map +1 -1
  240. package/build/types/types-hoist/link.d.ts +2 -2
  241. package/build/types/types-hoist/link.d.ts.map +1 -1
  242. package/build/types/types-hoist/options.d.ts +18 -2
  243. package/build/types/types-hoist/options.d.ts.map +1 -1
  244. package/build/types/types-hoist/span.d.ts +27 -0
  245. package/build/types/types-hoist/span.d.ts.map +1 -1
  246. package/build/types/utils/beforeSendSpan.d.ts +22 -0
  247. package/build/types/utils/beforeSendSpan.d.ts.map +1 -0
  248. package/build/types/utils/envToBool.d.ts +13 -0
  249. package/build/types/utils/envToBool.d.ts.map +1 -0
  250. package/build/types/utils/featureFlags.d.ts.map +1 -1
  251. package/build/types/utils/flushIfServerless.d.ts.map +1 -1
  252. package/build/types/utils/hasSpanStreamingEnabled.d.ts +9 -0
  253. package/build/types/utils/hasSpanStreamingEnabled.d.ts.map +1 -0
  254. package/build/types/utils/prepareEvent.d.ts.map +1 -1
  255. package/build/types/utils/promisebuffer.d.ts.map +1 -1
  256. package/build/types/utils/scopeData.d.ts.map +1 -1
  257. package/build/types/utils/sdkMetadata.d.ts.map +1 -1
  258. package/build/types/utils/should-ignore-span.d.ts +3 -3
  259. package/build/types/utils/should-ignore-span.d.ts.map +1 -1
  260. package/build/types/utils/spanUtils.d.ts +22 -2
  261. package/build/types/utils/spanUtils.d.ts.map +1 -1
  262. package/build/types/utils/timer.d.ts +11 -0
  263. package/build/types/utils/timer.d.ts.map +1 -0
  264. package/build/types/utils/tracePropagationTargets.d.ts +9 -0
  265. package/build/types/utils/tracePropagationTargets.d.ts.map +1 -0
  266. package/build/types-ts3.8/attributes.d.ts +1 -1
  267. package/build/types-ts3.8/client.d.ts +40 -2
  268. package/build/types-ts3.8/envelope.d.ts +6 -1
  269. package/build/types-ts3.8/index.d.ts +13 -4
  270. package/build/types-ts3.8/integration.d.ts +4 -0
  271. package/build/types-ts3.8/integrations/mcp-server/correlation.d.ts +6 -2
  272. package/build/types-ts3.8/integrations/mcp-server/sessionManagement.d.ts +8 -2
  273. package/build/types-ts3.8/integrations/spanStreaming.d.ts +11 -0
  274. package/build/types-ts3.8/metrics/public-api.d.ts +3 -3
  275. package/build/types-ts3.8/semanticAttributes.d.ts +38 -0
  276. package/build/types-ts3.8/spans/captureSpan.d.ts +10 -0
  277. package/build/types-ts3.8/spans/spanBuffer.d.ts +35 -0
  278. package/build/types-ts3.8/spans/spanFirstUtils.d.ts +20 -0
  279. package/build/types-ts3.8/tracing/ai/gen-ai-attributes.d.ts +4 -0
  280. package/build/types-ts3.8/tracing/sentrySpan.d.ts +10 -1
  281. package/build/types-ts3.8/tracing/vercel-ai/constants.d.ts +1 -0
  282. package/build/types-ts3.8/tracing/vercel-ai/utils.d.ts +2 -2
  283. package/build/types-ts3.8/types-hoist/attributes.d.ts +19 -0
  284. package/build/types-ts3.8/types-hoist/envelope.d.ts +22 -2
  285. package/build/types-ts3.8/types-hoist/integration.d.ts +7 -0
  286. package/build/types-ts3.8/types-hoist/link.d.ts +2 -2
  287. package/build/types-ts3.8/types-hoist/options.d.ts +18 -2
  288. package/build/types-ts3.8/types-hoist/span.d.ts +27 -0
  289. package/build/types-ts3.8/utils/beforeSendSpan.d.ts +22 -0
  290. package/build/types-ts3.8/utils/envToBool.d.ts +13 -0
  291. package/build/types-ts3.8/utils/hasSpanStreamingEnabled.d.ts +9 -0
  292. package/build/types-ts3.8/utils/should-ignore-span.d.ts +3 -3
  293. package/build/types-ts3.8/utils/spanUtils.d.ts +22 -2
  294. package/build/types-ts3.8/utils/timer.d.ts +11 -0
  295. package/build/types-ts3.8/utils/tracePropagationTargets.d.ts +9 -0
  296. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sources":["../../../src/transports/base.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport type { EventDropReason } from '../types-hoist/clientreport';\nimport type { Envelope, EnvelopeItem } from '../types-hoist/envelope';\nimport type {\n InternalBaseTransportOptions,\n Transport,\n TransportMakeRequestResponse,\n TransportRequestExecutor,\n} from '../types-hoist/transport';\nimport { debug } from '../utils/debug-logger';\nimport {\n createEnvelope,\n envelopeContainsItemType,\n envelopeItemTypeToDataCategory,\n forEachEnvelopeItem,\n serializeEnvelope,\n} from '../utils/envelope';\nimport { makePromiseBuffer, type PromiseBuffer, SENTRY_BUFFER_FULL_ERROR } from '../utils/promisebuffer';\nimport { isRateLimited, type RateLimits, updateRateLimits } from '../utils/ratelimit';\n\nexport const DEFAULT_TRANSPORT_BUFFER_SIZE = 64;\n\n/**\n * Creates an instance of a Sentry `Transport`\n *\n * @param options\n * @param makeRequest\n */\nexport function createTransport(\n options: InternalBaseTransportOptions,\n makeRequest: TransportRequestExecutor,\n buffer: PromiseBuffer<TransportMakeRequestResponse> = makePromiseBuffer(\n options.bufferSize || DEFAULT_TRANSPORT_BUFFER_SIZE,\n ),\n): Transport {\n let rateLimits: RateLimits = {};\n const flush = (timeout?: number): PromiseLike<boolean> => buffer.drain(timeout);\n\n function send(envelope: Envelope): PromiseLike<TransportMakeRequestResponse> {\n const filteredEnvelopeItems: EnvelopeItem[] = [];\n\n // Drop rate limited items from envelope\n forEachEnvelopeItem(envelope, (item, type) => {\n const dataCategory = envelopeItemTypeToDataCategory(type);\n if (isRateLimited(rateLimits, dataCategory)) {\n options.recordDroppedEvent('ratelimit_backoff', dataCategory);\n } else {\n filteredEnvelopeItems.push(item);\n }\n });\n\n // Skip sending if envelope is empty after filtering out rate limited events\n if (filteredEnvelopeItems.length === 0) {\n return Promise.resolve({});\n }\n\n const filteredEnvelope: Envelope = createEnvelope(envelope[0], filteredEnvelopeItems as (typeof envelope)[1]);\n\n // Creates client report for each item in an envelope\n const recordEnvelopeLoss = (reason: EventDropReason): void => {\n // Don't record outcomes for client reports - we don't want to create a feedback loop if client reports themselves fail to send\n if (envelopeContainsItemType(filteredEnvelope, ['client_report'])) {\n DEBUG_BUILD && debug.warn(`Dropping client report. Will not send outcomes (reason: ${reason}).`);\n return;\n }\n forEachEnvelopeItem(filteredEnvelope, (item, type) => {\n options.recordDroppedEvent(reason, envelopeItemTypeToDataCategory(type));\n });\n };\n\n const requestTask = (): PromiseLike<TransportMakeRequestResponse> =>\n makeRequest({ body: serializeEnvelope(filteredEnvelope) }).then(\n response => {\n // We don't want to throw on NOK responses, but we want to at least log them\n if (response.statusCode !== undefined && (response.statusCode < 200 || response.statusCode >= 300)) {\n DEBUG_BUILD && debug.warn(`Sentry responded with status code ${response.statusCode} to sent event.`);\n }\n\n rateLimits = updateRateLimits(rateLimits, response);\n return response;\n },\n error => {\n recordEnvelopeLoss('network_error');\n DEBUG_BUILD && debug.error('Encountered error running transport request:', error);\n throw error;\n },\n );\n\n return buffer.add(requestTask).then(\n result => result,\n error => {\n if (error === SENTRY_BUFFER_FULL_ERROR) {\n DEBUG_BUILD && debug.error('Skipped sending event because buffer is full.');\n recordEnvelopeLoss('queue_overflow');\n return Promise.resolve({});\n } else {\n throw error;\n }\n },\n );\n }\n\n return {\n send,\n flush,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.js","sources":["../../../src/transports/base.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport type { EventDropReason } from '../types-hoist/clientreport';\nimport type { Envelope, EnvelopeItem } from '../types-hoist/envelope';\nimport type {\n InternalBaseTransportOptions,\n Transport,\n TransportMakeRequestResponse,\n TransportRequestExecutor,\n} from '../types-hoist/transport';\nimport { debug } from '../utils/debug-logger';\nimport {\n createEnvelope,\n envelopeContainsItemType,\n envelopeItemTypeToDataCategory,\n forEachEnvelopeItem,\n serializeEnvelope,\n} from '../utils/envelope';\nimport { makePromiseBuffer, type PromiseBuffer, SENTRY_BUFFER_FULL_ERROR } from '../utils/promisebuffer';\nimport { isRateLimited, type RateLimits, updateRateLimits } from '../utils/ratelimit';\n\nexport const DEFAULT_TRANSPORT_BUFFER_SIZE = 64;\n\n/**\n * Creates an instance of a Sentry `Transport`\n *\n * @param options\n * @param makeRequest\n */\nexport function createTransport(\n options: InternalBaseTransportOptions,\n makeRequest: TransportRequestExecutor,\n buffer: PromiseBuffer<TransportMakeRequestResponse> = makePromiseBuffer(\n options.bufferSize || DEFAULT_TRANSPORT_BUFFER_SIZE,\n ),\n): Transport {\n let rateLimits: RateLimits = {};\n const flush = (timeout?: number): PromiseLike<boolean> => buffer.drain(timeout);\n\n function send(envelope: Envelope): PromiseLike<TransportMakeRequestResponse> {\n const filteredEnvelopeItems: EnvelopeItem[] = [];\n\n // Drop rate limited items from envelope\n forEachEnvelopeItem(envelope, (item, type) => {\n const dataCategory = envelopeItemTypeToDataCategory(type);\n if (isRateLimited(rateLimits, dataCategory)) {\n options.recordDroppedEvent('ratelimit_backoff', dataCategory);\n } else {\n filteredEnvelopeItems.push(item);\n }\n });\n\n // Skip sending if envelope is empty after filtering out rate limited events\n if (filteredEnvelopeItems.length === 0) {\n return Promise.resolve({});\n }\n\n const filteredEnvelope: Envelope = createEnvelope(envelope[0], filteredEnvelopeItems as (typeof envelope)[1]);\n\n // Creates client report for each item in an envelope\n const recordEnvelopeLoss = (reason: EventDropReason): void => {\n // Don't record outcomes for client reports - we don't want to create a feedback loop if client reports themselves fail to send\n if (envelopeContainsItemType(filteredEnvelope, ['client_report'])) {\n DEBUG_BUILD && debug.warn(`Dropping client report. Will not send outcomes (reason: ${reason}).`);\n return;\n }\n forEachEnvelopeItem(filteredEnvelope, (item, type) => {\n options.recordDroppedEvent(reason, envelopeItemTypeToDataCategory(type));\n });\n };\n\n const requestTask = (): PromiseLike<TransportMakeRequestResponse> =>\n makeRequest({ body: serializeEnvelope(filteredEnvelope) }).then(\n response => {\n // Handle 413 Content Too Large\n // Loss of envelope content is expected so we record a send_error client report\n // https://develop.sentry.dev/sdk/expected-features/#dealing-with-network-failures\n if (response.statusCode === 413) {\n DEBUG_BUILD &&\n debug.error(\n 'Sentry responded with status code 413. Envelope was discarded due to exceeding size limits.',\n );\n recordEnvelopeLoss('send_error');\n return response;\n }\n\n // We don't want to throw on NOK responses, but we want to at least log them\n if (\n DEBUG_BUILD &&\n response.statusCode !== undefined &&\n (response.statusCode < 200 || response.statusCode >= 300)\n ) {\n debug.warn(`Sentry responded with status code ${response.statusCode} to sent event.`);\n }\n\n rateLimits = updateRateLimits(rateLimits, response);\n return response;\n },\n error => {\n recordEnvelopeLoss('network_error');\n DEBUG_BUILD && debug.error('Encountered error running transport request:', error);\n throw error;\n },\n );\n\n return buffer.add(requestTask).then(\n result => result,\n error => {\n if (error === SENTRY_BUFFER_FULL_ERROR) {\n DEBUG_BUILD && debug.error('Skipped sending event because buffer is full.');\n recordEnvelopeLoss('queue_overflow');\n return Promise.resolve({});\n } else {\n throw error;\n }\n },\n );\n }\n\n return {\n send,\n flush,\n };\n}\n"],"names":[],"mappings":";;;;;;AAoBO,MAAM,6BAAA,GAAgC;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe;AAC/B,EAAE,OAAO;AACT,EAAE,WAAW;AACb,EAAE,MAAM,GAAgD,iBAAiB;AACzE,IAAI,OAAO,CAAC,UAAA,IAAc,6BAA6B;AACvD,GAAG;AACH,EAAa;AACb,EAAE,IAAI,UAAU,GAAe,EAAE;AACjC,EAAE,MAAM,KAAA,GAAQ,CAAC,OAAO,KAAoC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;;AAEjF,EAAE,SAAS,IAAI,CAAC,QAAQ,EAAuD;AAC/E,IAAI,MAAM,qBAAqB,GAAmB,EAAE;;AAEpD;AACA,IAAI,mBAAmB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK;AAClD,MAAM,MAAM,YAAA,GAAe,8BAA8B,CAAC,IAAI,CAAC;AAC/D,MAAM,IAAI,aAAa,CAAC,UAAU,EAAE,YAAY,CAAC,EAAE;AACnD,QAAQ,OAAO,CAAC,kBAAkB,CAAC,mBAAmB,EAAE,YAAY,CAAC;AACrE,MAAM,OAAO;AACb,QAAQ,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;AACxC,MAAM;AACN,IAAI,CAAC,CAAC;;AAEN;AACA,IAAI,IAAI,qBAAqB,CAAC,MAAA,KAAW,CAAC,EAAE;AAC5C,MAAM,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;AAChC,IAAI;;AAEJ,IAAI,MAAM,gBAAgB,GAAa,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,qBAAA,EAA8C;;AAEjH;AACA,IAAI,MAAM,kBAAA,GAAqB,CAAC,MAAM,KAA4B;AAClE;AACA,MAAM,IAAI,wBAAwB,CAAC,gBAAgB,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE;AACzE,QAAQ,WAAA,IAAe,KAAK,CAAC,IAAI,CAAC,CAAC,wDAAwD,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AACxG,QAAQ;AACR,MAAM;AACN,MAAM,mBAAmB,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK;AAC5D,QAAQ,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,8BAA8B,CAAC,IAAI,CAAC,CAAC;AAChF,MAAM,CAAC,CAAC;AACR,IAAI,CAAC;;AAEL,IAAI,MAAM,WAAA,GAAc;AACxB,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,gBAAgB,CAAA,EAAG,CAAC,CAAC,IAAI;AACrE,QAAQ,YAAY;AACpB;AACA;AACA;AACA,UAAU,IAAI,QAAQ,CAAC,UAAA,KAAe,GAAG,EAAE;AAC3C,YAAY,WAAA;AACZ,cAAc,KAAK,CAAC,KAAK;AACzB,gBAAgB,6FAA6F;AAC7G,eAAe;AACf,YAAY,kBAAkB,CAAC,YAAY,CAAC;AAC5C,YAAY,OAAO,QAAQ;AAC3B,UAAU;;AAEV;AACA,UAAU;AACV,YAAY,WAAA;AACZ,YAAY,QAAQ,CAAC,UAAA,KAAe,SAAA;AACpC,aAAa,QAAQ,CAAC,UAAA,GAAa,GAAA,IAAO,QAAQ,CAAC,UAAA,IAAc,GAAG;AACpE,YAAY;AACZ,YAAY,KAAK,CAAC,IAAI,CAAC,CAAC,kCAAkC,EAAE,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;AACjG,UAAU;;AAEV,UAAU,aAAa,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC;AAC7D,UAAU,OAAO,QAAQ;AACzB,QAAQ,CAAC;AACT,QAAQ,SAAS;AACjB,UAAU,kBAAkB,CAAC,eAAe,CAAC;AAC7C,UAAU,WAAA,IAAe,KAAK,CAAC,KAAK,CAAC,8CAA8C,EAAE,KAAK,CAAC;AAC3F,UAAU,MAAM,KAAK;AACrB,QAAQ,CAAC;AACT,OAAO;;AAEP,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI;AACvC,MAAM,MAAA,IAAU,MAAM;AACtB,MAAM,SAAS;AACf,QAAQ,IAAI,KAAA,KAAU,wBAAwB,EAAE;AAChD,UAAU,eAAe,KAAK,CAAC,KAAK,CAAC,+CAA+C,CAAC;AACrF,UAAU,kBAAkB,CAAC,gBAAgB,CAAC;AAC9C,UAAU,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;AACpC,QAAQ,OAAO;AACf,UAAU,MAAM,KAAK;AACrB,QAAQ;AACR,MAAM,CAAC;AACP,KAAK;AACL,EAAE;;AAEF,EAAE,OAAO;AACT,IAAI,IAAI;AACR,IAAI,KAAK;AACT,GAAG;AACH;;;;"}
@@ -2,6 +2,7 @@ import { DEBUG_BUILD } from '../debug-build.js';
2
2
  import { debug } from '../utils/debug-logger.js';
3
3
  import { envelopeContainsItemType } from '../utils/envelope.js';
4
4
  import { parseRetryAfterHeader } from '../utils/ratelimit.js';
5
+ import { safeUnref } from '../utils/timer.js';
5
6
 
6
7
  const MIN_DELAY = 100; // 100 ms
7
8
  const START_DELAY = 5000; // 5 seconds
@@ -49,26 +50,24 @@ function makeOfflineTransport(
49
50
  clearTimeout(flushTimer );
50
51
  }
51
52
 
52
- flushTimer = setTimeout(async () => {
53
- flushTimer = undefined;
54
-
55
- const found = await store.shift();
56
- if (found) {
57
- log('Attempting to send previously queued event');
53
+ // We need to unref the timer in node.js, otherwise the node process never exit.
54
+ flushTimer = safeUnref(
55
+ setTimeout(async () => {
56
+ flushTimer = undefined;
58
57
 
59
- // We should to update the sent_at timestamp to the current time.
60
- found[0].sent_at = new Date().toISOString();
58
+ const found = await store.shift();
59
+ if (found) {
60
+ log('Attempting to send previously queued event');
61
61
 
62
- void send(found, true).catch(e => {
63
- log('Failed to retry sending', e);
64
- });
65
- }
66
- }, delay) ;
62
+ // We should to update the sent_at timestamp to the current time.
63
+ found[0].sent_at = new Date().toISOString();
67
64
 
68
- // We need to unref the timer in node.js, otherwise the node process never exit.
69
- if (typeof flushTimer !== 'number' && flushTimer.unref) {
70
- flushTimer.unref();
71
- }
65
+ void send(found, true).catch(e => {
66
+ log('Failed to retry sending', e);
67
+ });
68
+ }
69
+ }, delay),
70
+ ) ;
72
71
  }
73
72
 
74
73
  function flushWithBackOff() {
@@ -1 +1 @@
1
- {"version":3,"file":"offline.js","sources":["../../../src/transports/offline.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport type { Envelope } from '../types-hoist/envelope';\nimport type { InternalBaseTransportOptions, Transport, TransportMakeRequestResponse } from '../types-hoist/transport';\nimport { debug } from '../utils/debug-logger';\nimport { envelopeContainsItemType } from '../utils/envelope';\nimport { parseRetryAfterHeader } from '../utils/ratelimit';\n\nexport const MIN_DELAY = 100; // 100 ms\nexport const START_DELAY = 5_000; // 5 seconds\nconst MAX_DELAY = 3.6e6; // 1 hour\n\nexport interface OfflineStore {\n push(env: Envelope): Promise<void>;\n unshift(env: Envelope): Promise<void>;\n shift(): Promise<Envelope | undefined>;\n}\n\nexport type CreateOfflineStore = (options: OfflineTransportOptions) => OfflineStore;\n\nexport interface OfflineTransportOptions extends InternalBaseTransportOptions {\n /**\n * A function that creates the offline store instance.\n */\n createStore?: CreateOfflineStore;\n\n /**\n * Flush the offline store shortly after startup.\n *\n * Defaults: false\n */\n flushAtStartup?: boolean;\n\n /**\n * Called before an event is stored.\n *\n * Return false to drop the envelope rather than store it.\n *\n * @param envelope The envelope that failed to send.\n * @param error The error that occurred.\n * @param retryDelay The current retry delay in milliseconds.\n * @returns Whether the envelope should be stored.\n */\n shouldStore?: (envelope: Envelope, error: Error, retryDelay: number) => boolean | Promise<boolean>;\n\n /**\n * Should an attempt be made to send the envelope to Sentry.\n *\n * If this function is supplied and returns false, `shouldStore` will be called to determine if the envelope should be stored.\n *\n * @param envelope The envelope that will be sent.\n * @returns Whether we should attempt to send the envelope\n */\n shouldSend?: (envelope: Envelope) => boolean | Promise<boolean>;\n}\n\ntype Timer = number | { unref?: () => void };\n\n/**\n * Wraps a transport and stores and retries events when they fail to send.\n *\n * @param createTransport The transport to wrap.\n */\nexport function makeOfflineTransport<TO>(\n createTransport: (options: TO) => Transport,\n): (options: TO & OfflineTransportOptions) => Transport {\n function log(...args: unknown[]): void {\n DEBUG_BUILD && debug.log('[Offline]:', ...args);\n }\n\n return options => {\n const transport = createTransport(options);\n\n if (!options.createStore) {\n throw new Error('No `createStore` function was provided');\n }\n\n const store = options.createStore(options);\n\n let retryDelay = START_DELAY;\n let flushTimer: Timer | undefined;\n\n function shouldQueue(env: Envelope, error: Error, retryDelay: number): boolean | Promise<boolean> {\n // We want to drop client reports because they can be generated when we retry sending events while offline.\n if (envelopeContainsItemType(env, ['client_report'])) {\n return false;\n }\n\n if (options.shouldStore) {\n return options.shouldStore(env, error, retryDelay);\n }\n\n return true;\n }\n\n function flushIn(delay: number): void {\n if (flushTimer) {\n clearTimeout(flushTimer as ReturnType<typeof setTimeout>);\n }\n\n flushTimer = setTimeout(async () => {\n flushTimer = undefined;\n\n const found = await store.shift();\n if (found) {\n log('Attempting to send previously queued event');\n\n // We should to update the sent_at timestamp to the current time.\n found[0].sent_at = new Date().toISOString();\n\n void send(found, true).catch(e => {\n log('Failed to retry sending', e);\n });\n }\n }, delay) as Timer;\n\n // We need to unref the timer in node.js, otherwise the node process never exit.\n if (typeof flushTimer !== 'number' && flushTimer.unref) {\n flushTimer.unref();\n }\n }\n\n function flushWithBackOff(): void {\n if (flushTimer) {\n return;\n }\n\n flushIn(retryDelay);\n\n retryDelay = Math.min(retryDelay * 2, MAX_DELAY);\n }\n\n async function send(envelope: Envelope, isRetry: boolean = false): Promise<TransportMakeRequestResponse> {\n // We queue all replay envelopes to avoid multiple replay envelopes being sent at the same time. If one fails, we\n // need to retry them in order.\n if (!isRetry && envelopeContainsItemType(envelope, ['replay_event', 'replay_recording'])) {\n await store.push(envelope);\n flushIn(MIN_DELAY);\n return {};\n }\n\n try {\n if (options.shouldSend && (await options.shouldSend(envelope)) === false) {\n throw new Error('Envelope not sent because `shouldSend` callback returned false');\n }\n\n const result = await transport.send(envelope);\n\n let delay = MIN_DELAY;\n\n if (result) {\n // If there's a retry-after header, use that as the next delay.\n if (result.headers?.['retry-after']) {\n delay = parseRetryAfterHeader(result.headers['retry-after']);\n } else if (result.headers?.['x-sentry-rate-limits']) {\n delay = 60_000; // 60 seconds\n } // If we have a server error, return now so we don't flush the queue.\n else if ((result.statusCode || 0) >= 400) {\n return result;\n }\n }\n\n flushIn(delay);\n retryDelay = START_DELAY;\n return result;\n } catch (e) {\n if (await shouldQueue(envelope, e as Error, retryDelay)) {\n // If this envelope was a retry, we want to add it to the front of the queue so it's retried again first.\n if (isRetry) {\n await store.unshift(envelope);\n } else {\n await store.push(envelope);\n }\n flushWithBackOff();\n log('Error sending. Event queued.', e as Error);\n return {};\n } else {\n throw e;\n }\n }\n }\n\n if (options.flushAtStartup) {\n flushWithBackOff();\n }\n\n return {\n send,\n flush: timeout => {\n // If there's no timeout, we should attempt to flush the offline queue.\n if (timeout === undefined) {\n retryDelay = START_DELAY;\n flushIn(MIN_DELAY);\n }\n\n return transport.flush(timeout);\n },\n };\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"offline.js","sources":["../../../src/transports/offline.ts"],"sourcesContent":["import { DEBUG_BUILD } from '../debug-build';\nimport type { Envelope } from '../types-hoist/envelope';\nimport type { InternalBaseTransportOptions, Transport, TransportMakeRequestResponse } from '../types-hoist/transport';\nimport { debug } from '../utils/debug-logger';\nimport { envelopeContainsItemType } from '../utils/envelope';\nimport { parseRetryAfterHeader } from '../utils/ratelimit';\nimport { safeUnref } from '../utils/timer';\n\nexport const MIN_DELAY = 100; // 100 ms\nexport const START_DELAY = 5_000; // 5 seconds\nconst MAX_DELAY = 3.6e6; // 1 hour\n\nexport interface OfflineStore {\n push(env: Envelope): Promise<void>;\n unshift(env: Envelope): Promise<void>;\n shift(): Promise<Envelope | undefined>;\n}\n\nexport type CreateOfflineStore = (options: OfflineTransportOptions) => OfflineStore;\n\nexport interface OfflineTransportOptions extends InternalBaseTransportOptions {\n /**\n * A function that creates the offline store instance.\n */\n createStore?: CreateOfflineStore;\n\n /**\n * Flush the offline store shortly after startup.\n *\n * Defaults: false\n */\n flushAtStartup?: boolean;\n\n /**\n * Called before an event is stored.\n *\n * Return false to drop the envelope rather than store it.\n *\n * @param envelope The envelope that failed to send.\n * @param error The error that occurred.\n * @param retryDelay The current retry delay in milliseconds.\n * @returns Whether the envelope should be stored.\n */\n shouldStore?: (envelope: Envelope, error: Error, retryDelay: number) => boolean | Promise<boolean>;\n\n /**\n * Should an attempt be made to send the envelope to Sentry.\n *\n * If this function is supplied and returns false, `shouldStore` will be called to determine if the envelope should be stored.\n *\n * @param envelope The envelope that will be sent.\n * @returns Whether we should attempt to send the envelope\n */\n shouldSend?: (envelope: Envelope) => boolean | Promise<boolean>;\n}\n\ntype Timer = number | { unref?: () => void };\n\n/**\n * Wraps a transport and stores and retries events when they fail to send.\n *\n * @param createTransport The transport to wrap.\n */\nexport function makeOfflineTransport<TO>(\n createTransport: (options: TO) => Transport,\n): (options: TO & OfflineTransportOptions) => Transport {\n function log(...args: unknown[]): void {\n DEBUG_BUILD && debug.log('[Offline]:', ...args);\n }\n\n return options => {\n const transport = createTransport(options);\n\n if (!options.createStore) {\n throw new Error('No `createStore` function was provided');\n }\n\n const store = options.createStore(options);\n\n let retryDelay = START_DELAY;\n let flushTimer: Timer | undefined;\n\n function shouldQueue(env: Envelope, error: Error, retryDelay: number): boolean | Promise<boolean> {\n // We want to drop client reports because they can be generated when we retry sending events while offline.\n if (envelopeContainsItemType(env, ['client_report'])) {\n return false;\n }\n\n if (options.shouldStore) {\n return options.shouldStore(env, error, retryDelay);\n }\n\n return true;\n }\n\n function flushIn(delay: number): void {\n if (flushTimer) {\n clearTimeout(flushTimer as ReturnType<typeof setTimeout>);\n }\n\n // We need to unref the timer in node.js, otherwise the node process never exit.\n flushTimer = safeUnref(\n setTimeout(async () => {\n flushTimer = undefined;\n\n const found = await store.shift();\n if (found) {\n log('Attempting to send previously queued event');\n\n // We should to update the sent_at timestamp to the current time.\n found[0].sent_at = new Date().toISOString();\n\n void send(found, true).catch(e => {\n log('Failed to retry sending', e);\n });\n }\n }, delay),\n ) as Timer;\n }\n\n function flushWithBackOff(): void {\n if (flushTimer) {\n return;\n }\n\n flushIn(retryDelay);\n\n retryDelay = Math.min(retryDelay * 2, MAX_DELAY);\n }\n\n async function send(envelope: Envelope, isRetry: boolean = false): Promise<TransportMakeRequestResponse> {\n // We queue all replay envelopes to avoid multiple replay envelopes being sent at the same time. If one fails, we\n // need to retry them in order.\n if (!isRetry && envelopeContainsItemType(envelope, ['replay_event', 'replay_recording'])) {\n await store.push(envelope);\n flushIn(MIN_DELAY);\n return {};\n }\n\n try {\n if (options.shouldSend && (await options.shouldSend(envelope)) === false) {\n throw new Error('Envelope not sent because `shouldSend` callback returned false');\n }\n\n const result = await transport.send(envelope);\n\n let delay = MIN_DELAY;\n\n if (result) {\n // If there's a retry-after header, use that as the next delay.\n if (result.headers?.['retry-after']) {\n delay = parseRetryAfterHeader(result.headers['retry-after']);\n } else if (result.headers?.['x-sentry-rate-limits']) {\n delay = 60_000; // 60 seconds\n } // If we have a server error, return now so we don't flush the queue.\n else if ((result.statusCode || 0) >= 400) {\n return result;\n }\n }\n\n flushIn(delay);\n retryDelay = START_DELAY;\n return result;\n } catch (e) {\n if (await shouldQueue(envelope, e as Error, retryDelay)) {\n // If this envelope was a retry, we want to add it to the front of the queue so it's retried again first.\n if (isRetry) {\n await store.unshift(envelope);\n } else {\n await store.push(envelope);\n }\n flushWithBackOff();\n log('Error sending. Event queued.', e as Error);\n return {};\n } else {\n throw e;\n }\n }\n }\n\n if (options.flushAtStartup) {\n flushWithBackOff();\n }\n\n return {\n send,\n flush: timeout => {\n // If there's no timeout, we should attempt to flush the offline queue.\n if (timeout === undefined) {\n retryDelay = START_DELAY;\n flushIn(MIN_DELAY);\n }\n\n return transport.flush(timeout);\n },\n };\n };\n}\n"],"names":[],"mappings":"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"}
@@ -52,7 +52,7 @@ function aggregateExceptionsFromError(
52
52
 
53
53
  // Recursively call this function in order to walk down a chain of errors
54
54
  if (isInstanceOf(error[key], Error)) {
55
- applyExceptionGroupFieldsForParentException(exception, exceptionId);
55
+ applyExceptionGroupFieldsForParentException(exception, exceptionId, error);
56
56
  const newException = exceptionFromErrorImplementation(parser, error[key] );
57
57
  const newExceptionId = newExceptions.length;
58
58
  applyExceptionGroupFieldsForChildException(newException, key, newExceptionId, exceptionId);
@@ -70,10 +70,10 @@ function aggregateExceptionsFromError(
70
70
 
71
71
  // This will create exception grouping for AggregateErrors
72
72
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError
73
- if (Array.isArray(error.errors)) {
73
+ if (isExceptionGroup(error)) {
74
74
  error.errors.forEach((childError, i) => {
75
75
  if (isInstanceOf(childError, Error)) {
76
- applyExceptionGroupFieldsForParentException(exception, exceptionId);
76
+ applyExceptionGroupFieldsForParentException(exception, exceptionId, error);
77
77
  const newException = exceptionFromErrorImplementation(parser, childError );
78
78
  const newExceptionId = newExceptions.length;
79
79
  applyExceptionGroupFieldsForChildException(newException, `errors[${i}]`, newExceptionId, exceptionId);
@@ -94,12 +94,20 @@ function aggregateExceptionsFromError(
94
94
  return newExceptions;
95
95
  }
96
96
 
97
- function applyExceptionGroupFieldsForParentException(exception, exceptionId) {
97
+ function isExceptionGroup(error) {
98
+ return Array.isArray(error.errors);
99
+ }
100
+
101
+ function applyExceptionGroupFieldsForParentException(
102
+ exception,
103
+ exceptionId,
104
+ error,
105
+ ) {
98
106
  exception.mechanism = {
99
107
  handled: true,
100
108
  type: 'auto.core.linked_errors',
109
+ ...(isExceptionGroup(error) && { is_exception_group: true }),
101
110
  ...exception.mechanism,
102
- ...(exception.type === 'AggregateError' && { is_exception_group: true }),
103
111
  exception_id: exceptionId,
104
112
  };
105
113
  }
@@ -1 +1 @@
1
- {"version":3,"file":"aggregate-errors.js","sources":["../../../src/utils/aggregate-errors.ts"],"sourcesContent":["import type { ExtendedError } from '../types-hoist/error';\nimport type { Event, EventHint } from '../types-hoist/event';\nimport type { Exception } from '../types-hoist/exception';\nimport type { StackParser } from '../types-hoist/stacktrace';\nimport { isInstanceOf } from './is';\n\n/**\n * Creates exceptions inside `event.exception.values` for errors that are nested on properties based on the `key` parameter.\n */\nexport function applyAggregateErrorsToEvent(\n exceptionFromErrorImplementation: (stackParser: StackParser, ex: Error) => Exception,\n parser: StackParser,\n key: string,\n limit: number,\n event: Event,\n hint?: EventHint,\n): void {\n if (!event.exception?.values || !hint || !isInstanceOf(hint.originalException, Error)) {\n return;\n }\n\n // Generally speaking the last item in `event.exception.values` is the exception originating from the original Error\n const originalException: Exception | undefined =\n event.exception.values.length > 0 ? event.exception.values[event.exception.values.length - 1] : undefined;\n\n // We only create exception grouping if there is an exception in the event.\n if (originalException) {\n event.exception.values = aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n hint.originalException as ExtendedError,\n key,\n event.exception.values,\n originalException,\n 0,\n );\n }\n}\n\nfunction aggregateExceptionsFromError(\n exceptionFromErrorImplementation: (stackParser: StackParser, ex: Error) => Exception,\n parser: StackParser,\n limit: number,\n error: ExtendedError,\n key: string,\n prevExceptions: Exception[],\n exception: Exception,\n exceptionId: number,\n): Exception[] {\n if (prevExceptions.length >= limit + 1) {\n return prevExceptions;\n }\n\n let newExceptions = [...prevExceptions];\n\n // Recursively call this function in order to walk down a chain of errors\n if (isInstanceOf(error[key], Error)) {\n applyExceptionGroupFieldsForParentException(exception, exceptionId);\n const newException = exceptionFromErrorImplementation(parser, error[key] as Error);\n const newExceptionId = newExceptions.length;\n applyExceptionGroupFieldsForChildException(newException, key, newExceptionId, exceptionId);\n newExceptions = aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n error[key] as ExtendedError,\n key,\n [newException, ...newExceptions],\n newException,\n newExceptionId,\n );\n }\n\n // This will create exception grouping for AggregateErrors\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError\n if (Array.isArray(error.errors)) {\n error.errors.forEach((childError, i) => {\n if (isInstanceOf(childError, Error)) {\n applyExceptionGroupFieldsForParentException(exception, exceptionId);\n const newException = exceptionFromErrorImplementation(parser, childError as Error);\n const newExceptionId = newExceptions.length;\n applyExceptionGroupFieldsForChildException(newException, `errors[${i}]`, newExceptionId, exceptionId);\n newExceptions = aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n childError as ExtendedError,\n key,\n [newException, ...newExceptions],\n newException,\n newExceptionId,\n );\n }\n });\n }\n\n return newExceptions;\n}\n\nfunction applyExceptionGroupFieldsForParentException(exception: Exception, exceptionId: number): void {\n exception.mechanism = {\n handled: true,\n type: 'auto.core.linked_errors',\n ...exception.mechanism,\n ...(exception.type === 'AggregateError' && { is_exception_group: true }),\n exception_id: exceptionId,\n };\n}\n\nfunction applyExceptionGroupFieldsForChildException(\n exception: Exception,\n source: string,\n exceptionId: number,\n parentId: number | undefined,\n): void {\n exception.mechanism = {\n handled: true,\n ...exception.mechanism,\n type: 'chained',\n source,\n exception_id: exceptionId,\n parent_id: parentId,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"aggregate-errors.js","sources":["../../../src/utils/aggregate-errors.ts"],"sourcesContent":["import type { ExtendedError } from '../types-hoist/error';\nimport type { Event, EventHint } from '../types-hoist/event';\nimport type { Exception } from '../types-hoist/exception';\nimport type { StackParser } from '../types-hoist/stacktrace';\nimport { isInstanceOf } from './is';\n\n/**\n * Creates exceptions inside `event.exception.values` for errors that are nested on properties based on the `key` parameter.\n */\nexport function applyAggregateErrorsToEvent(\n exceptionFromErrorImplementation: (stackParser: StackParser, ex: Error) => Exception,\n parser: StackParser,\n key: string,\n limit: number,\n event: Event,\n hint?: EventHint,\n): void {\n if (!event.exception?.values || !hint || !isInstanceOf(hint.originalException, Error)) {\n return;\n }\n\n // Generally speaking the last item in `event.exception.values` is the exception originating from the original Error\n const originalException: Exception | undefined =\n event.exception.values.length > 0 ? event.exception.values[event.exception.values.length - 1] : undefined;\n\n // We only create exception grouping if there is an exception in the event.\n if (originalException) {\n event.exception.values = aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n hint.originalException as ExtendedError,\n key,\n event.exception.values,\n originalException,\n 0,\n );\n }\n}\n\nfunction aggregateExceptionsFromError(\n exceptionFromErrorImplementation: (stackParser: StackParser, ex: Error) => Exception,\n parser: StackParser,\n limit: number,\n error: ExtendedError,\n key: string,\n prevExceptions: Exception[],\n exception: Exception,\n exceptionId: number,\n): Exception[] {\n if (prevExceptions.length >= limit + 1) {\n return prevExceptions;\n }\n\n let newExceptions = [...prevExceptions];\n\n // Recursively call this function in order to walk down a chain of errors\n if (isInstanceOf(error[key], Error)) {\n applyExceptionGroupFieldsForParentException(exception, exceptionId, error);\n const newException = exceptionFromErrorImplementation(parser, error[key] as Error);\n const newExceptionId = newExceptions.length;\n applyExceptionGroupFieldsForChildException(newException, key, newExceptionId, exceptionId);\n newExceptions = aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n error[key] as ExtendedError,\n key,\n [newException, ...newExceptions],\n newException,\n newExceptionId,\n );\n }\n\n // This will create exception grouping for AggregateErrors\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError\n if (isExceptionGroup(error)) {\n error.errors.forEach((childError, i) => {\n if (isInstanceOf(childError, Error)) {\n applyExceptionGroupFieldsForParentException(exception, exceptionId, error);\n const newException = exceptionFromErrorImplementation(parser, childError as Error);\n const newExceptionId = newExceptions.length;\n applyExceptionGroupFieldsForChildException(newException, `errors[${i}]`, newExceptionId, exceptionId);\n newExceptions = aggregateExceptionsFromError(\n exceptionFromErrorImplementation,\n parser,\n limit,\n childError as ExtendedError,\n key,\n [newException, ...newExceptions],\n newException,\n newExceptionId,\n );\n }\n });\n }\n\n return newExceptions;\n}\n\nfunction isExceptionGroup(error: ExtendedError): error is ExtendedError & { errors: unknown[] } {\n return Array.isArray(error.errors);\n}\n\nfunction applyExceptionGroupFieldsForParentException(\n exception: Exception,\n exceptionId: number,\n error: ExtendedError,\n): void {\n exception.mechanism = {\n handled: true,\n type: 'auto.core.linked_errors',\n ...(isExceptionGroup(error) && { is_exception_group: true }),\n ...exception.mechanism,\n exception_id: exceptionId,\n };\n}\n\nfunction applyExceptionGroupFieldsForChildException(\n exception: Exception,\n source: string,\n exceptionId: number,\n parentId: number | undefined,\n): void {\n exception.mechanism = {\n handled: true,\n ...exception.mechanism,\n type: 'chained',\n source,\n exception_id: exceptionId,\n parent_id: parentId,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { addNonEnumerableProperty } from './object.js';
2
+
3
+ /**
4
+ * A wrapper to use the new span format in your `beforeSendSpan` callback.
5
+ *
6
+ * @example
7
+ *
8
+ * Sentry.init({
9
+ * beforeSendSpan: withStreamSpan((span) => {
10
+ * return span;
11
+ * }),
12
+ * });
13
+ *
14
+ * @param callback
15
+ * @returns
16
+ */
17
+ function withStreamSpan(callback) {
18
+ addNonEnumerableProperty(callback, '_v2', true);
19
+ // type-casting here because TS can't infer the type correctly
20
+ return callback ;
21
+ }
22
+
23
+ /**
24
+ * Typesafe check to identify the expected span json format of the `beforeSendSpan` callback.
25
+ */
26
+ function isV2BeforeSendSpanCallback(
27
+ callback,
28
+ ) {
29
+ return !!callback && '_v2' in callback && !!callback._v2;
30
+ }
31
+
32
+ export { isV2BeforeSendSpanCallback, withStreamSpan };
33
+ //# sourceMappingURL=beforeSendSpan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"beforeSendSpan.js","sources":["../../../src/utils/beforeSendSpan.ts"],"sourcesContent":["import type { ClientOptions, SpanV2CompatibleBeforeSendSpanCallback } from '../types-hoist/options';\nimport type { SpanV2JSON } from '../types-hoist/span';\nimport { addNonEnumerableProperty } from './object';\n\n/**\n * A wrapper to use the new span format in your `beforeSendSpan` callback.\n *\n * @example\n *\n * Sentry.init({\n * beforeSendSpan: withStreamSpan((span) => {\n * return span;\n * }),\n * });\n *\n * @param callback\n * @returns\n */\nexport function withStreamSpan(callback: (span: SpanV2JSON) => SpanV2JSON): SpanV2CompatibleBeforeSendSpanCallback {\n addNonEnumerableProperty(callback, '_v2', true);\n // type-casting here because TS can't infer the type correctly\n return callback as SpanV2CompatibleBeforeSendSpanCallback;\n}\n\n/**\n * Typesafe check to identify the expected span json format of the `beforeSendSpan` callback.\n */\nexport function isV2BeforeSendSpanCallback(\n callback: ClientOptions['beforeSendSpan'],\n): callback is SpanV2CompatibleBeforeSendSpanCallback {\n return !!callback && '_v2' in callback && !!callback._v2;\n}\n"],"names":[],"mappings":";;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,cAAc,CAAC,QAAQ,EAA4E;AACnH,EAAE,wBAAwB,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC;AACjD;AACA,EAAE,OAAO,QAAA;AACT;;AAEA;AACA;AACA;AACO,SAAS,0BAA0B;AAC1C,EAAE,QAAQ;AACV,EAAsD;AACtD,EAAE,OAAO,CAAC,CAAC,QAAA,IAAY,KAAA,IAAS,QAAA,IAAY,CAAC,CAAC,QAAQ,CAAC,GAAG;AAC1D;;;;"}
@@ -0,0 +1,28 @@
1
+ const FALSY_ENV_VALUES = new Set(['false', 'f', 'n', 'no', 'off', '0']);
2
+ const TRUTHY_ENV_VALUES = new Set(['true', 't', 'y', 'yes', 'on', '1']);
3
+
4
+ /**
5
+ * A helper function which casts an ENV variable value to `true` or `false` using the constants defined above.
6
+ * In strict mode, it may return `null` if the value doesn't match any of the predefined values.
7
+ *
8
+ * @param value The value of the env variable
9
+ * @param options -- Only has `strict` key for now, which requires a strict match for `true` in TRUTHY_ENV_VALUES
10
+ * @returns true/false if the lowercase value matches the predefined values above. If not, null in strict mode,
11
+ * and Boolean(value) in loose mode.
12
+ */
13
+ function envToBool(value, options) {
14
+ const normalized = String(value).toLowerCase();
15
+
16
+ if (FALSY_ENV_VALUES.has(normalized)) {
17
+ return false;
18
+ }
19
+
20
+ if (TRUTHY_ENV_VALUES.has(normalized)) {
21
+ return true;
22
+ }
23
+
24
+ return options?.strict ? null : Boolean(value);
25
+ }
26
+
27
+ export { FALSY_ENV_VALUES, TRUTHY_ENV_VALUES, envToBool };
28
+ //# sourceMappingURL=envToBool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envToBool.js","sources":["../../../src/utils/envToBool.ts"],"sourcesContent":["export const FALSY_ENV_VALUES = new Set(['false', 'f', 'n', 'no', 'off', '0']);\nexport const TRUTHY_ENV_VALUES = new Set(['true', 't', 'y', 'yes', 'on', '1']);\n\nexport type StrictBoolCast = {\n strict: true;\n};\n\nexport type LooseBoolCast = {\n strict?: false;\n};\n\nexport type BoolCastOptions = StrictBoolCast | LooseBoolCast;\n\nexport function envToBool(value: unknown, options?: LooseBoolCast): boolean;\nexport function envToBool(value: unknown, options: StrictBoolCast): boolean | null;\nexport function envToBool(value: unknown, options?: BoolCastOptions): boolean | null;\n/**\n * A helper function which casts an ENV variable value to `true` or `false` using the constants defined above.\n * In strict mode, it may return `null` if the value doesn't match any of the predefined values.\n *\n * @param value The value of the env variable\n * @param options -- Only has `strict` key for now, which requires a strict match for `true` in TRUTHY_ENV_VALUES\n * @returns true/false if the lowercase value matches the predefined values above. If not, null in strict mode,\n * and Boolean(value) in loose mode.\n */\nexport function envToBool(value: unknown, options?: BoolCastOptions): boolean | null {\n const normalized = String(value).toLowerCase();\n\n if (FALSY_ENV_VALUES.has(normalized)) {\n return false;\n }\n\n if (TRUTHY_ENV_VALUES.has(normalized)) {\n return true;\n }\n\n return options?.strict ? null : Boolean(value);\n}\n"],"names":[],"mappings":"MAAa,gBAAA,GAAmB,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC;MAChE,iBAAA,GAAoB,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC;;AAe7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,SAAS,CAAC,KAAK,EAAW,OAAO,EAAoC;AACrF,EAAE,MAAM,UAAA,GAAa,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE;;AAEhD,EAAE,IAAI,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;AACxC,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF,EAAE,IAAI,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;AACzC,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF,EAAE,OAAO,OAAO,EAAE,MAAA,GAAS,OAAO,OAAO,CAAC,KAAK,CAAC;AAChD;;;;"}
@@ -8,11 +8,11 @@
8
8
  * @returns void
9
9
  */
10
10
  function replaceExports(
11
- exports,
11
+ exports$1,
12
12
  exportName,
13
13
  wrappedConstructor,
14
14
  ) {
15
- const original = exports[exportName];
15
+ const original = exports$1[exportName];
16
16
 
17
17
  if (typeof original !== 'function') {
18
18
  return;
@@ -20,10 +20,10 @@ function replaceExports(
20
20
 
21
21
  // Replace the named export - handle read-only properties
22
22
  try {
23
- exports[exportName] = wrappedConstructor;
23
+ exports$1[exportName] = wrappedConstructor;
24
24
  } catch (error) {
25
25
  // If direct assignment fails, override the property descriptor
26
- Object.defineProperty(exports, exportName, {
26
+ Object.defineProperty(exports$1, exportName, {
27
27
  value: wrappedConstructor,
28
28
  writable: true,
29
29
  configurable: true,
@@ -32,11 +32,11 @@ function replaceExports(
32
32
  }
33
33
 
34
34
  // Replace the default export if it points to the original constructor
35
- if (exports.default === original) {
35
+ if (exports$1.default === original) {
36
36
  try {
37
- exports.default = wrappedConstructor;
37
+ exports$1.default = wrappedConstructor;
38
38
  } catch (error) {
39
- Object.defineProperty(exports, 'default', {
39
+ Object.defineProperty(exports$1, 'default', {
40
40
  value: wrappedConstructor,
41
41
  writable: true,
42
42
  configurable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"exports.js","sources":["../../../src/utils/exports.ts"],"sourcesContent":["/**\n * Replaces constructor functions in module exports, handling read-only properties,\n * and both default and named exports by wrapping them with the constructor.\n *\n * @param exports The module exports object to modify\n * @param exportName The name of the export to replace (e.g., 'GoogleGenAI', 'Anthropic', 'OpenAI')\n * @param wrappedConstructor The wrapped constructor function to replace the original with\n * @returns void\n */\nexport function replaceExports(\n exports: { [key: string]: unknown },\n exportName: string,\n wrappedConstructor: unknown,\n): void {\n const original = exports[exportName];\n\n if (typeof original !== 'function') {\n return;\n }\n\n // Replace the named export - handle read-only properties\n try {\n exports[exportName] = wrappedConstructor;\n } catch (error) {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, exportName, {\n value: wrappedConstructor,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Replace the default export if it points to the original constructor\n if (exports.default === original) {\n try {\n exports.default = wrappedConstructor;\n } catch (error) {\n Object.defineProperty(exports, 'default', {\n value: wrappedConstructor,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n}\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,cAAc;AAC9B,EAAE,OAAO;AACT,EAAE,UAAU;AACZ,EAAE,kBAAkB;AACpB,EAAQ;AACR,EAAE,MAAM,QAAA,GAAW,OAAO,CAAC,UAAU,CAAC;;AAEtC,EAAE,IAAI,OAAO,QAAA,KAAa,UAAU,EAAE;AACtC,IAAI;AACJ,EAAE;;AAEF;AACA,EAAE,IAAI;AACN,IAAI,OAAO,CAAC,UAAU,CAAA,GAAI,kBAAkB;AAC5C,EAAE,CAAA,CAAE,OAAO,KAAK,EAAE;AAClB;AACA,IAAI,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE;AAC/C,MAAM,KAAK,EAAE,kBAAkB;AAC/B,MAAM,QAAQ,EAAE,IAAI;AACpB,MAAM,YAAY,EAAE,IAAI;AACxB,MAAM,UAAU,EAAE,IAAI;AACtB,KAAK,CAAC;AACN,EAAE;;AAEF;AACA,EAAE,IAAI,OAAO,CAAC,OAAA,KAAY,QAAQ,EAAE;AACpC,IAAI,IAAI;AACR,MAAM,OAAO,CAAC,OAAA,GAAU,kBAAkB;AAC1C,IAAI,CAAA,CAAE,OAAO,KAAK,EAAE;AACpB,MAAM,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE;AAChD,QAAQ,KAAK,EAAE,kBAAkB;AACjC,QAAQ,QAAQ,EAAE,IAAI;AACtB,QAAQ,YAAY,EAAE,IAAI;AAC1B,QAAQ,UAAU,EAAE,IAAI;AACxB,OAAO,CAAC;AACR,IAAI;AACJ,EAAE;AACF;;;;"}
1
+ {"version":3,"file":"exports.js","sources":["../../../src/utils/exports.ts"],"sourcesContent":["/**\n * Replaces constructor functions in module exports, handling read-only properties,\n * and both default and named exports by wrapping them with the constructor.\n *\n * @param exports The module exports object to modify\n * @param exportName The name of the export to replace (e.g., 'GoogleGenAI', 'Anthropic', 'OpenAI')\n * @param wrappedConstructor The wrapped constructor function to replace the original with\n * @returns void\n */\nexport function replaceExports(\n exports: { [key: string]: unknown },\n exportName: string,\n wrappedConstructor: unknown,\n): void {\n const original = exports[exportName];\n\n if (typeof original !== 'function') {\n return;\n }\n\n // Replace the named export - handle read-only properties\n try {\n exports[exportName] = wrappedConstructor;\n } catch (error) {\n // If direct assignment fails, override the property descriptor\n Object.defineProperty(exports, exportName, {\n value: wrappedConstructor,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n\n // Replace the default export if it points to the original constructor\n if (exports.default === original) {\n try {\n exports.default = wrappedConstructor;\n } catch (error) {\n Object.defineProperty(exports, 'default', {\n value: wrappedConstructor,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n }\n }\n}\n"],"names":["exports"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,cAAc;AAC9B,EAAEA,SAAO;AACT,EAAE,UAAU;AACZ,EAAE,kBAAkB;AACpB,EAAQ;AACR,EAAE,MAAM,QAAA,GAAWA,SAAO,CAAC,UAAU,CAAC;;AAEtC,EAAE,IAAI,OAAO,QAAA,KAAa,UAAU,EAAE;AACtC,IAAI;AACJ,EAAE;;AAEF;AACA,EAAE,IAAI;AACN,IAAIA,SAAO,CAAC,UAAU,CAAA,GAAI,kBAAkB;AAC5C,EAAE,CAAA,CAAE,OAAO,KAAK,EAAE;AAClB;AACA,IAAI,MAAM,CAAC,cAAc,CAACA,SAAO,EAAE,UAAU,EAAE;AAC/C,MAAM,KAAK,EAAE,kBAAkB;AAC/B,MAAM,QAAQ,EAAE,IAAI;AACpB,MAAM,YAAY,EAAE,IAAI;AACxB,MAAM,UAAU,EAAE,IAAI;AACtB,KAAK,CAAC;AACN,EAAE;;AAEF;AACA,EAAE,IAAIA,SAAO,CAAC,OAAA,KAAY,QAAQ,EAAE;AACpC,IAAI,IAAI;AACR,MAAMA,SAAO,CAAC,OAAA,GAAU,kBAAkB;AAC1C,IAAI,CAAA,CAAE,OAAO,KAAK,EAAE;AACpB,MAAM,MAAM,CAAC,cAAc,CAACA,SAAO,EAAE,SAAS,EAAE;AAChD,QAAQ,KAAK,EAAE,kBAAkB;AACjC,QAAQ,QAAQ,EAAE,IAAI;AACtB,QAAQ,YAAY,EAAE,IAAI;AAC1B,QAAQ,UAAU,EAAE,IAAI;AACxB,OAAO,CAAC;AACR,IAAI;AACJ,EAAE;AACF;;;;"}
@@ -24,6 +24,7 @@ const SPAN_FLAG_ATTRIBUTE_PREFIX = 'flag.evaluation.';
24
24
  /**
25
25
  * Copies feature flags that are in current scope context to the event context
26
26
  */
27
+ // TODO (span-streaming): should flags be added to (segment) spans? If so, probably do this via globally applying context data to spans
27
28
  function _INTERNAL_copyFlagsFromScopeToEvent(event) {
28
29
  const scope = getCurrentScope();
29
30
  const flagContext = scope.getScopeData().contexts.flags;
@@ -1 +1 @@
1
- {"version":3,"file":"featureFlags.js","sources":["../../../src/utils/featureFlags.ts"],"sourcesContent":["import { getCurrentScope } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { type Event } from '../types-hoist/event';\nimport { debug } from './debug-logger';\nimport { getActiveSpan, spanToJSON } from './spanUtils';\n\n/**\n * Ordered LRU cache for storing feature flags in the scope context. The name\n * of each flag in the buffer is unique, and the output of getAll() is ordered\n * from oldest to newest.\n */\n\nexport type FeatureFlag = { readonly flag: string; readonly result: boolean };\n\n/**\n * Max size of the LRU flag buffer stored in Sentry scope and event contexts.\n */\nexport const _INTERNAL_FLAG_BUFFER_SIZE = 100;\n\n/**\n * Max number of flag evaluations to record per span.\n */\nexport const _INTERNAL_MAX_FLAGS_PER_SPAN = 10;\n\nconst SPAN_FLAG_ATTRIBUTE_PREFIX = 'flag.evaluation.';\n\n/**\n * Copies feature flags that are in current scope context to the event context\n */\nexport function _INTERNAL_copyFlagsFromScopeToEvent(event: Event): Event {\n const scope = getCurrentScope();\n const flagContext = scope.getScopeData().contexts.flags;\n const flagBuffer = flagContext ? flagContext.values : [];\n\n if (!flagBuffer.length) {\n return event;\n }\n\n if (event.contexts === undefined) {\n event.contexts = {};\n }\n event.contexts.flags = { values: [...flagBuffer] };\n return event;\n}\n\n/**\n * Inserts a flag into the current scope's context while maintaining ordered LRU properties.\n * Not thread-safe. After inserting:\n * - The flag buffer is sorted in order of recency, with the newest evaluation at the end.\n * - The names in the buffer are always unique.\n * - The length of the buffer never exceeds `maxSize`.\n *\n * @param name Name of the feature flag to insert.\n * @param value Value of the feature flag.\n * @param maxSize Max number of flags the buffer should store. Default value should always be used in production.\n */\nexport function _INTERNAL_insertFlagToScope(\n name: string,\n value: unknown,\n maxSize: number = _INTERNAL_FLAG_BUFFER_SIZE,\n): void {\n const scopeContexts = getCurrentScope().getScopeData().contexts;\n if (!scopeContexts.flags) {\n scopeContexts.flags = { values: [] };\n }\n const flags = scopeContexts.flags.values;\n _INTERNAL_insertToFlagBuffer(flags, name, value, maxSize);\n}\n\n/**\n * Exported for tests only. Currently only accepts boolean values (otherwise no-op).\n * Inserts a flag into a FeatureFlag array while maintaining the following properties:\n * - Flags are sorted in order of recency, with the newest evaluation at the end.\n * - The flag names are always unique.\n * - The length of the array never exceeds `maxSize`.\n *\n * @param flags The buffer to insert the flag into.\n * @param name Name of the feature flag to insert.\n * @param value Value of the feature flag.\n * @param maxSize Max number of flags the buffer should store. Default value should always be used in production.\n */\nexport function _INTERNAL_insertToFlagBuffer(\n flags: FeatureFlag[],\n name: string,\n value: unknown,\n maxSize: number,\n): void {\n if (typeof value !== 'boolean') {\n return;\n }\n\n if (flags.length > maxSize) {\n DEBUG_BUILD && debug.error(`[Feature Flags] insertToFlagBuffer called on a buffer larger than maxSize=${maxSize}`);\n return;\n }\n\n // Check if the flag is already in the buffer - O(n)\n const index = flags.findIndex(f => f.flag === name);\n\n if (index !== -1) {\n // The flag was found, remove it from its current position - O(n)\n flags.splice(index, 1);\n }\n\n if (flags.length === maxSize) {\n // If at capacity, pop the earliest flag - O(n)\n flags.shift();\n }\n\n // Push the flag to the end - O(1)\n flags.push({\n flag: name,\n result: value,\n });\n}\n\n/**\n * Records a feature flag evaluation for the active span. This is a no-op for non-boolean values.\n * The flag and its value is stored in span attributes with the `flag.evaluation` prefix. Once the\n * unique flags for a span reaches maxFlagsPerSpan, subsequent flags are dropped.\n *\n * @param name Name of the feature flag.\n * @param value Value of the feature flag. Non-boolean values are ignored.\n * @param maxFlagsPerSpan Max number of flags a buffer should store. Default value should always be used in production.\n */\nexport function _INTERNAL_addFeatureFlagToActiveSpan(\n name: string,\n value: unknown,\n maxFlagsPerSpan: number = _INTERNAL_MAX_FLAGS_PER_SPAN,\n): void {\n if (typeof value !== 'boolean') {\n return;\n }\n\n const span = getActiveSpan();\n if (!span) {\n return;\n }\n\n const attributes = spanToJSON(span).data;\n\n // If the flag already exists, always update it\n if (`${SPAN_FLAG_ATTRIBUTE_PREFIX}${name}` in attributes) {\n span.setAttribute(`${SPAN_FLAG_ATTRIBUTE_PREFIX}${name}`, value);\n return;\n }\n\n // Else, add the flag to the span if we have not reached the max number of flags\n const numOfAddedFlags = Object.keys(attributes).filter(key => key.startsWith(SPAN_FLAG_ATTRIBUTE_PREFIX)).length;\n if (numOfAddedFlags < maxFlagsPerSpan) {\n span.setAttribute(`${SPAN_FLAG_ATTRIBUTE_PREFIX}${name}`, value);\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"featureFlags.js","sources":["../../../src/utils/featureFlags.ts"],"sourcesContent":["import { getCurrentScope } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { type Event } from '../types-hoist/event';\nimport { debug } from './debug-logger';\nimport { getActiveSpan, spanToJSON } from './spanUtils';\n\n/**\n * Ordered LRU cache for storing feature flags in the scope context. The name\n * of each flag in the buffer is unique, and the output of getAll() is ordered\n * from oldest to newest.\n */\n\nexport type FeatureFlag = { readonly flag: string; readonly result: boolean };\n\n/**\n * Max size of the LRU flag buffer stored in Sentry scope and event contexts.\n */\nexport const _INTERNAL_FLAG_BUFFER_SIZE = 100;\n\n/**\n * Max number of flag evaluations to record per span.\n */\nexport const _INTERNAL_MAX_FLAGS_PER_SPAN = 10;\n\nconst SPAN_FLAG_ATTRIBUTE_PREFIX = 'flag.evaluation.';\n\n/**\n * Copies feature flags that are in current scope context to the event context\n */\n// TODO (span-streaming): should flags be added to (segment) spans? If so, probably do this via globally applying context data to spans\nexport function _INTERNAL_copyFlagsFromScopeToEvent(event: Event): Event {\n const scope = getCurrentScope();\n const flagContext = scope.getScopeData().contexts.flags;\n const flagBuffer = flagContext ? flagContext.values : [];\n\n if (!flagBuffer.length) {\n return event;\n }\n\n if (event.contexts === undefined) {\n event.contexts = {};\n }\n event.contexts.flags = { values: [...flagBuffer] };\n return event;\n}\n\n/**\n * Inserts a flag into the current scope's context while maintaining ordered LRU properties.\n * Not thread-safe. After inserting:\n * - The flag buffer is sorted in order of recency, with the newest evaluation at the end.\n * - The names in the buffer are always unique.\n * - The length of the buffer never exceeds `maxSize`.\n *\n * @param name Name of the feature flag to insert.\n * @param value Value of the feature flag.\n * @param maxSize Max number of flags the buffer should store. Default value should always be used in production.\n */\nexport function _INTERNAL_insertFlagToScope(\n name: string,\n value: unknown,\n maxSize: number = _INTERNAL_FLAG_BUFFER_SIZE,\n): void {\n const scopeContexts = getCurrentScope().getScopeData().contexts;\n if (!scopeContexts.flags) {\n scopeContexts.flags = { values: [] };\n }\n const flags = scopeContexts.flags.values;\n _INTERNAL_insertToFlagBuffer(flags, name, value, maxSize);\n}\n\n/**\n * Exported for tests only. Currently only accepts boolean values (otherwise no-op).\n * Inserts a flag into a FeatureFlag array while maintaining the following properties:\n * - Flags are sorted in order of recency, with the newest evaluation at the end.\n * - The flag names are always unique.\n * - The length of the array never exceeds `maxSize`.\n *\n * @param flags The buffer to insert the flag into.\n * @param name Name of the feature flag to insert.\n * @param value Value of the feature flag.\n * @param maxSize Max number of flags the buffer should store. Default value should always be used in production.\n */\nexport function _INTERNAL_insertToFlagBuffer(\n flags: FeatureFlag[],\n name: string,\n value: unknown,\n maxSize: number,\n): void {\n if (typeof value !== 'boolean') {\n return;\n }\n\n if (flags.length > maxSize) {\n DEBUG_BUILD && debug.error(`[Feature Flags] insertToFlagBuffer called on a buffer larger than maxSize=${maxSize}`);\n return;\n }\n\n // Check if the flag is already in the buffer - O(n)\n const index = flags.findIndex(f => f.flag === name);\n\n if (index !== -1) {\n // The flag was found, remove it from its current position - O(n)\n flags.splice(index, 1);\n }\n\n if (flags.length === maxSize) {\n // If at capacity, pop the earliest flag - O(n)\n flags.shift();\n }\n\n // Push the flag to the end - O(1)\n flags.push({\n flag: name,\n result: value,\n });\n}\n\n/**\n * Records a feature flag evaluation for the active span. This is a no-op for non-boolean values.\n * The flag and its value is stored in span attributes with the `flag.evaluation` prefix. Once the\n * unique flags for a span reaches maxFlagsPerSpan, subsequent flags are dropped.\n *\n * @param name Name of the feature flag.\n * @param value Value of the feature flag. Non-boolean values are ignored.\n * @param maxFlagsPerSpan Max number of flags a buffer should store. Default value should always be used in production.\n */\nexport function _INTERNAL_addFeatureFlagToActiveSpan(\n name: string,\n value: unknown,\n maxFlagsPerSpan: number = _INTERNAL_MAX_FLAGS_PER_SPAN,\n): void {\n if (typeof value !== 'boolean') {\n return;\n }\n\n const span = getActiveSpan();\n if (!span) {\n return;\n }\n\n const attributes = spanToJSON(span).data;\n\n // If the flag already exists, always update it\n if (`${SPAN_FLAG_ATTRIBUTE_PREFIX}${name}` in attributes) {\n span.setAttribute(`${SPAN_FLAG_ATTRIBUTE_PREFIX}${name}`, value);\n return;\n }\n\n // Else, add the flag to the span if we have not reached the max number of flags\n const numOfAddedFlags = Object.keys(attributes).filter(key => key.startsWith(SPAN_FLAG_ATTRIBUTE_PREFIX)).length;\n if (numOfAddedFlags < maxFlagsPerSpan) {\n span.setAttribute(`${SPAN_FLAG_ATTRIBUTE_PREFIX}${name}`, value);\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"flushIfServerless.js","sources":["../../../src/utils/flushIfServerless.ts"],"sourcesContent":["import { flush } from '../exports';\nimport { debug } from './debug-logger';\nimport { vercelWaitUntil } from './vercelWaitUntil';\nimport { GLOBAL_OBJ } from './worldwide';\n\ntype MinimalCloudflareContext = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n waitUntil(promise: Promise<any>): void;\n};\n\nasync function flushWithTimeout(timeout: number): Promise<void> {\n try {\n debug.log('Flushing events...');\n await flush(timeout);\n debug.log('Done flushing events');\n } catch (e) {\n debug.log('Error while flushing events:\\n', e);\n }\n}\n\n/**\n * Flushes the event queue with a timeout in serverless environments to ensure that events are sent to Sentry before the\n * serverless function execution ends.\n *\n * The function is async, but in environments that support a `waitUntil` mechanism, it will run synchronously.\n *\n * This function is aware of the following serverless platforms:\n * - Cloudflare: If a Cloudflare context is provided, it will use `ctx.waitUntil()` to flush events (keeps the `this` context of `ctx`).\n * If a `cloudflareWaitUntil` function is provided, it will use that to flush events (looses the `this` context of `ctx`).\n * - Vercel: It detects the Vercel environment and uses Vercel's `waitUntil` function.\n * - Other Serverless (AWS Lambda, Google Cloud, etc.): It detects the environment via environment variables\n * and uses a regular `await flush()`.\n *\n * @internal This function is supposed for internal Sentry SDK usage only.\n * @hidden\n */\nexport async function flushIfServerless(\n params: // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | { timeout?: number; cloudflareWaitUntil?: (task: Promise<any>) => void }\n | { timeout?: number; cloudflareCtx?: MinimalCloudflareContext } = {},\n): Promise<void> {\n const { timeout = 2000 } = params;\n\n if ('cloudflareWaitUntil' in params && typeof params?.cloudflareWaitUntil === 'function') {\n params.cloudflareWaitUntil(flushWithTimeout(timeout));\n return;\n }\n\n if ('cloudflareCtx' in params && typeof params.cloudflareCtx?.waitUntil === 'function') {\n params.cloudflareCtx.waitUntil(flushWithTimeout(timeout));\n return;\n }\n\n // Note: vercelWaitUntil only does something in Vercel Edge runtime\n // In Node runtime, we use process.on('SIGTERM') instead\n // @ts-expect-error This is not typed\n if (GLOBAL_OBJ[Symbol.for('@vercel/request-context')]) {\n // Vercel has a waitUntil equivalent that works without execution context\n vercelWaitUntil(flushWithTimeout(timeout));\n return;\n }\n\n if (typeof process === 'undefined') {\n return;\n }\n\n const isServerless =\n !!process.env.FUNCTIONS_WORKER_RUNTIME || // Azure Functions\n !!process.env.LAMBDA_TASK_ROOT || // AWS Lambda\n !!process.env.K_SERVICE || // Google Cloud Run\n !!process.env.CF_PAGES || // Cloudflare Pages\n !!process.env.VERCEL ||\n !!process.env.NETLIFY;\n\n if (isServerless) {\n // Use regular flush for environments without a generic waitUntil mechanism\n await flushWithTimeout(timeout);\n }\n}\n"],"names":[],"mappings":";;;;;AAUA,eAAe,gBAAgB,CAAC,OAAO,EAAyB;AAChE,EAAE,IAAI;AACN,IAAI,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC;AACnC,IAAI,MAAM,KAAK,CAAC,OAAO,CAAC;AACxB,IAAI,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC;AACrC,EAAE,CAAA,CAAE,OAAO,CAAC,EAAE;AACd,IAAI,KAAK,CAAC,GAAG,CAAC,gCAAgC,EAAE,CAAC,CAAC;AAClD,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,iBAAiB;AACvC,EAAE;;AAEE,GAAmE,EAAE;AACzE,EAAiB;AACjB,EAAE,MAAM,EAAE,OAAA,GAAU,IAAA,EAAK,GAAI,MAAM;;AAEnC,EAAE,IAAI,qBAAA,IAAyB,MAAA,IAAU,OAAO,MAAM,EAAE,mBAAA,KAAwB,UAAU,EAAE;AAC5F,IAAI,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACzD,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,eAAA,IAAmB,UAAU,OAAO,MAAM,CAAC,aAAa,EAAE,SAAA,KAAc,UAAU,EAAE;AAC1F,IAAI,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC7D,IAAI;AACJ,EAAE;;AAEF;AACA;AACA;AACA,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,EAAE;AACzD;AACA,IAAI,eAAe,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC9C,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,OAAO,OAAA,KAAY,WAAW,EAAE;AACtC,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,YAAA;AACR,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO;;AAEzB,EAAE,IAAI,YAAY,EAAE;AACpB;AACA,IAAI,MAAM,gBAAgB,CAAC,OAAO,CAAC;AACnC,EAAE;AACF;;;;"}
1
+ {"version":3,"file":"flushIfServerless.js","sources":["../../../src/utils/flushIfServerless.ts"],"sourcesContent":["import { flush } from '../exports';\nimport { debug } from './debug-logger';\nimport { vercelWaitUntil } from './vercelWaitUntil';\nimport { GLOBAL_OBJ } from './worldwide';\n\ntype MinimalCloudflareContext = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n waitUntil(promise: Promise<any>): void;\n};\n\nasync function flushWithTimeout(timeout: number): Promise<void> {\n try {\n debug.log('Flushing events...');\n await flush(timeout);\n debug.log('Done flushing events');\n } catch (e) {\n debug.log('Error while flushing events:\\n', e);\n }\n}\n\n/**\n * Flushes the event queue with a timeout in serverless environments to ensure that events are sent to Sentry before the\n * serverless function execution ends.\n *\n * The function is async, but in environments that support a `waitUntil` mechanism, it will run synchronously.\n *\n * This function is aware of the following serverless platforms:\n * - Cloudflare: If a Cloudflare context is provided, it will use `ctx.waitUntil()` to flush events (keeps the `this` context of `ctx`).\n * If a `cloudflareWaitUntil` function is provided, it will use that to flush events (looses the `this` context of `ctx`).\n * - Vercel: It detects the Vercel environment and uses Vercel's `waitUntil` function.\n * - Other Serverless (AWS Lambda, Google Cloud, etc.): It detects the environment via environment variables\n * and uses a regular `await flush()`.\n *\n * @internal This function is supposed for internal Sentry SDK usage only.\n * @hidden\n */\nexport async function flushIfServerless(\n params: // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | { timeout?: number; cloudflareWaitUntil?: (task: Promise<any>) => void }\n | { timeout?: number; cloudflareCtx?: MinimalCloudflareContext } = {},\n): Promise<void> {\n const { timeout = 2000 } = params;\n\n if ('cloudflareWaitUntil' in params && typeof params?.cloudflareWaitUntil === 'function') {\n params.cloudflareWaitUntil(flushWithTimeout(timeout));\n return;\n }\n\n if ('cloudflareCtx' in params && typeof params.cloudflareCtx?.waitUntil === 'function') {\n params.cloudflareCtx.waitUntil(flushWithTimeout(timeout));\n return;\n }\n\n // Note: vercelWaitUntil only does something in Vercel Edge runtime\n // In Node runtime, we use process.on('SIGTERM') instead\n // @ts-expect-error This is not typed\n if (GLOBAL_OBJ[Symbol.for('@vercel/request-context')]) {\n // Vercel has a waitUntil equivalent that works without execution context\n vercelWaitUntil(flushWithTimeout(timeout));\n return;\n }\n\n if (typeof process === 'undefined') {\n return;\n }\n\n const isServerless =\n !!process.env.FUNCTIONS_WORKER_RUNTIME || // Azure Functions\n !!process.env.LAMBDA_TASK_ROOT || // AWS Lambda\n !!process.env.K_SERVICE || // Google Cloud Run\n !!process.env.CF_PAGES || // Cloudflare Pages\n !!process.env.VERCEL ||\n !!process.env.NETLIFY;\n\n if (isServerless) {\n // Use regular flush for environments without a generic waitUntil mechanism\n await flushWithTimeout(timeout);\n }\n}\n"],"names":[],"mappings":";;;;;AAUA,eAAe,gBAAgB,CAAC,OAAO,EAAyB;AAChE,EAAE,IAAI;AACN,IAAI,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC;AACnC,IAAI,MAAM,KAAK,CAAC,OAAO,CAAC;AACxB,IAAI,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC;AACrC,EAAE,CAAA,CAAE,OAAO,CAAC,EAAE;AACd,IAAI,KAAK,CAAC,GAAG,CAAC,gCAAgC,EAAE,CAAC,CAAC;AAClD,EAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,iBAAiB;AACvC,EAAE;;AAEE,GAAmE,EAAE;AACzE,EAAiB;AACjB,EAAE,MAAM,EAAE,OAAA,GAAU,IAAA,EAAK,GAAI,MAAM;;AAEnC,EAAE,IAAI,qBAAA,IAAyB,MAAA,IAAU,OAAO,MAAM,EAAE,mBAAA,KAAwB,UAAU,EAAE;AAC5F,IAAI,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AACzD,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,eAAA,IAAmB,UAAU,OAAO,MAAM,CAAC,aAAa,EAAE,SAAA,KAAc,UAAU,EAAE;AAC1F,IAAI,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC7D,IAAI;AACJ,EAAE;;AAEF;AACA;AACA;AACA,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,EAAE;AACzD;AACA,IAAI,eAAe,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC9C,IAAI;AACJ,EAAE;;AAEF,EAAE,IAAI,OAAO,OAAA,KAAY,WAAW,EAAE;AACtC,IAAI;AACJ,EAAE;;AAEF,EAAE,MAAM,YAAA;AACR,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,SAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAA;AAClB,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO;;AAEzB,EAAE,IAAI,YAAY,EAAE;AACpB;AACA,IAAI,MAAM,gBAAgB,CAAC,OAAO,CAAC;AACnC,EAAE;AACF;;;;"}
@@ -0,0 +1,19 @@
1
+ import { getClient } from '../currentScopes.js';
2
+
3
+ // Treeshakable guard to remove all code related to tracing
4
+
5
+ /**
6
+ * Determines if the SDK is configured for span streaming.
7
+ * Span streaming is enabled when `traceLifecycle` is set to `stream`.
8
+ * (In Browser, users must add `spanStreamingIntegration` as well but it
9
+ * already checks itself and configures `traceLifecycle` appropriately)
10
+ */
11
+ function hasSpanStreamingEnabled(maybeClient = getClient()) {
12
+ if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) {
13
+ return false;
14
+ }
15
+ return (maybeClient ?? getClient())?.getOptions()?.traceLifecycle === 'stream';
16
+ }
17
+
18
+ export { hasSpanStreamingEnabled };
19
+ //# sourceMappingURL=hasSpanStreamingEnabled.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasSpanStreamingEnabled.js","sources":["../../../src/utils/hasSpanStreamingEnabled.ts"],"sourcesContent":["import type { Client } from '../client';\nimport { getClient } from '../currentScopes';\n\n// Treeshakable guard to remove all code related to tracing\ndeclare const __SENTRY_TRACING__: boolean | undefined;\n\n/**\n * Determines if the SDK is configured for span streaming.\n * Span streaming is enabled when `traceLifecycle` is set to `stream`.\n * (In Browser, users must add `spanStreamingIntegration` as well but it\n * already checks itself and configures `traceLifecycle` appropriately)\n */\nexport function hasSpanStreamingEnabled(maybeClient: Client | undefined = getClient()): boolean {\n if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) {\n return false;\n }\n return (maybeClient ?? getClient())?.getOptions()?.traceLifecycle === 'stream';\n}\n"],"names":[],"mappings":";;AAGA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB,CAAC,WAAW,GAAuB,SAAS,EAAE,EAAW;AAChG,EAAE,IAAI,OAAO,kBAAA,KAAuB,SAAA,IAAa,CAAC,kBAAkB,EAAE;AACtE,IAAI,OAAO,KAAK;AAChB,EAAE;AACF,EAAE,OAAO,CAAC,WAAA,IAAe,SAAS,EAAE,GAAG,UAAU,EAAE,EAAE,cAAA,KAAmB,QAAQ;AAChF;;;;"}
@@ -6,6 +6,7 @@ import { uuid4, addExceptionMechanism } from './misc.js';
6
6
  import { normalize } from './normalize.js';
7
7
  import { getCombinedScopeData, applyScopeDataToEvent } from './scopeData.js';
8
8
  import { truncate } from './string.js';
9
+ import { resolvedSyncPromise } from './syncpromise.js';
9
10
  import { dateTimestampInSeconds } from './time.js';
10
11
 
11
12
  /**
@@ -85,7 +86,11 @@ function prepareEvent(
85
86
  ...data.eventProcessors,
86
87
  ];
87
88
 
88
- const result = notifyEventProcessors(eventProcessors, prepared, hint);
89
+ // Skip event processors for internal exceptions to prevent recursion
90
+ const isInternalException = hint.data && (hint.data ).__sentry__ === true;
91
+ const result = isInternalException
92
+ ? resolvedSyncPromise(prepared)
93
+ : notifyEventProcessors(eventProcessors, prepared, hint);
89
94
 
90
95
  return result.then(evt => {
91
96
  if (evt) {
@@ -1 +1 @@
1
- {"version":3,"file":"prepareEvent.js","sources":["../../../src/utils/prepareEvent.ts"],"sourcesContent":["import type { Client } from '../client';\nimport { DEFAULT_ENVIRONMENT } from '../constants';\nimport { notifyEventProcessors } from '../eventProcessors';\nimport type { CaptureContext, ScopeContext } from '../scope';\nimport { Scope } from '../scope';\nimport type { Event, EventHint } from '../types-hoist/event';\nimport type { ClientOptions } from '../types-hoist/options';\nimport type { StackParser } from '../types-hoist/stacktrace';\nimport { getFilenameToDebugIdMap } from './debug-ids';\nimport { addExceptionMechanism, uuid4 } from './misc';\nimport { normalize } from './normalize';\nimport { applyScopeDataToEvent, getCombinedScopeData } from './scopeData';\nimport { truncate } from './string';\nimport { dateTimestampInSeconds } from './time';\n\n/**\n * This type makes sure that we get either a CaptureContext, OR an EventHint.\n * It does not allow mixing them, which could lead to unexpected outcomes, e.g. this is disallowed:\n * { user: { id: '123' }, mechanism: { handled: false } }\n */\nexport type ExclusiveEventHintOrCaptureContext =\n | (CaptureContext & Partial<{ [key in keyof EventHint]: never }>)\n | (EventHint & Partial<{ [key in keyof ScopeContext]: never }>);\n\n/**\n * Adds common information to events.\n *\n * The information includes release and environment from `options`,\n * breadcrumbs and context (extra, tags and user) from the scope.\n *\n * Information that is already present in the event is never overwritten. For\n * nested objects, such as the context, keys are merged.\n *\n * @param event The original event.\n * @param hint May contain additional information about the original exception.\n * @param scope A scope containing event metadata.\n * @returns A new event with more information.\n * @hidden\n */\nexport function prepareEvent(\n options: ClientOptions,\n event: Event,\n hint: EventHint,\n scope?: Scope,\n client?: Client,\n isolationScope?: Scope,\n): PromiseLike<Event | null> {\n const { normalizeDepth = 3, normalizeMaxBreadth = 1_000 } = options;\n const prepared: Event = {\n ...event,\n event_id: event.event_id || hint.event_id || uuid4(),\n timestamp: event.timestamp || dateTimestampInSeconds(),\n };\n const integrations = hint.integrations || options.integrations.map(i => i.name);\n\n applyClientOptions(prepared, options);\n applyIntegrationsMetadata(prepared, integrations);\n\n if (client) {\n client.emit('applyFrameMetadata', event);\n }\n\n // Only put debug IDs onto frames for error events.\n if (event.type === undefined) {\n applyDebugIds(prepared, options.stackParser);\n }\n\n // If we have scope given to us, use it as the base for further modifications.\n // This allows us to prevent unnecessary copying of data if `captureContext` is not provided.\n const finalScope = getFinalScope(scope, hint.captureContext);\n\n if (hint.mechanism) {\n addExceptionMechanism(prepared, hint.mechanism);\n }\n\n const clientEventProcessors = client ? client.getEventProcessors() : [];\n\n // This should be the last thing called, since we want that\n // {@link Scope.addEventProcessor} gets the finished prepared event.\n // Merge scope data together\n const data = getCombinedScopeData(isolationScope, finalScope);\n\n const attachments = [...(hint.attachments || []), ...data.attachments];\n if (attachments.length) {\n hint.attachments = attachments;\n }\n\n applyScopeDataToEvent(prepared, data);\n\n const eventProcessors = [\n ...clientEventProcessors,\n // Run scope event processors _after_ all other processors\n ...data.eventProcessors,\n ];\n\n const result = notifyEventProcessors(eventProcessors, prepared, hint);\n\n return result.then(evt => {\n if (evt) {\n // We apply the debug_meta field only after all event processors have ran, so that if any event processors modified\n // file names (e.g.the RewriteFrames integration) the filename -> debug ID relationship isn't destroyed.\n // This should not cause any PII issues, since we're only moving data that is already on the event and not adding\n // any new data\n applyDebugMeta(evt);\n }\n\n if (typeof normalizeDepth === 'number' && normalizeDepth > 0) {\n return normalizeEvent(evt, normalizeDepth, normalizeMaxBreadth);\n }\n return evt;\n });\n}\n\n/**\n * Enhances event using the client configuration.\n * It takes care of all \"static\" values like environment, release and `dist`,\n * as well as truncating overly long values.\n *\n * Only exported for tests.\n *\n * @param event event instance to be enhanced\n */\nexport function applyClientOptions(event: Event, options: ClientOptions): void {\n const { environment, release, dist, maxValueLength } = options;\n\n // empty strings do not make sense for environment, release, and dist\n // so we handle them the same as if they were not provided\n event.environment = event.environment || environment || DEFAULT_ENVIRONMENT;\n\n if (!event.release && release) {\n event.release = release;\n }\n\n if (!event.dist && dist) {\n event.dist = dist;\n }\n\n const request = event.request;\n if (request?.url && maxValueLength) {\n request.url = truncate(request.url, maxValueLength);\n }\n\n if (maxValueLength) {\n event.exception?.values?.forEach(exception => {\n if (exception.value) {\n // Truncates error messages\n exception.value = truncate(exception.value, maxValueLength);\n }\n });\n }\n}\n\n/**\n * Puts debug IDs into the stack frames of an error event.\n */\nexport function applyDebugIds(event: Event, stackParser: StackParser): void {\n // Build a map of filename -> debug_id\n const filenameDebugIdMap = getFilenameToDebugIdMap(stackParser);\n\n event.exception?.values?.forEach(exception => {\n exception.stacktrace?.frames?.forEach(frame => {\n if (frame.filename) {\n frame.debug_id = filenameDebugIdMap[frame.filename];\n }\n });\n });\n}\n\n/**\n * Moves debug IDs from the stack frames of an error event into the debug_meta field.\n */\nexport function applyDebugMeta(event: Event): void {\n // Extract debug IDs and filenames from the stack frames on the event.\n const filenameDebugIdMap: Record<string, string> = {};\n event.exception?.values?.forEach(exception => {\n exception.stacktrace?.frames?.forEach(frame => {\n if (frame.debug_id) {\n if (frame.abs_path) {\n filenameDebugIdMap[frame.abs_path] = frame.debug_id;\n } else if (frame.filename) {\n filenameDebugIdMap[frame.filename] = frame.debug_id;\n }\n delete frame.debug_id;\n }\n });\n });\n\n if (Object.keys(filenameDebugIdMap).length === 0) {\n return;\n }\n\n // Fill debug_meta information\n event.debug_meta = event.debug_meta || {};\n event.debug_meta.images = event.debug_meta.images || [];\n const images = event.debug_meta.images;\n Object.entries(filenameDebugIdMap).forEach(([filename, debug_id]) => {\n images.push({\n type: 'sourcemap',\n code_file: filename,\n debug_id,\n });\n });\n}\n\n/**\n * This function adds all used integrations to the SDK info in the event.\n * @param event The event that will be filled with all integrations.\n */\nfunction applyIntegrationsMetadata(event: Event, integrationNames: string[]): void {\n if (integrationNames.length > 0) {\n event.sdk = event.sdk || {};\n event.sdk.integrations = [...(event.sdk.integrations || []), ...integrationNames];\n }\n}\n\n/**\n * Applies `normalize` function on necessary `Event` attributes to make them safe for serialization.\n * Normalized keys:\n * - `breadcrumbs.data`\n * - `user`\n * - `contexts`\n * - `extra`\n * @param event Event\n * @returns Normalized event\n */\nfunction normalizeEvent(event: Event | null, depth: number, maxBreadth: number): Event | null {\n if (!event) {\n return null;\n }\n\n const normalized: Event = {\n ...event,\n ...(event.breadcrumbs && {\n breadcrumbs: event.breadcrumbs.map(b => ({\n ...b,\n ...(b.data && {\n data: normalize(b.data, depth, maxBreadth),\n }),\n })),\n }),\n ...(event.user && {\n user: normalize(event.user, depth, maxBreadth),\n }),\n ...(event.contexts && {\n contexts: normalize(event.contexts, depth, maxBreadth),\n }),\n ...(event.extra && {\n extra: normalize(event.extra, depth, maxBreadth),\n }),\n };\n\n // event.contexts.trace stores information about a Transaction. Similarly,\n // event.spans[] stores information about child Spans. Given that a\n // Transaction is conceptually a Span, normalization should apply to both\n // Transactions and Spans consistently.\n // For now the decision is to skip normalization of Transactions and Spans,\n // so this block overwrites the normalized event to add back the original\n // Transaction information prior to normalization.\n if (event.contexts?.trace && normalized.contexts) {\n normalized.contexts.trace = event.contexts.trace;\n\n // event.contexts.trace.data may contain circular/dangerous data so we need to normalize it\n if (event.contexts.trace.data) {\n normalized.contexts.trace.data = normalize(event.contexts.trace.data, depth, maxBreadth);\n }\n }\n\n // event.spans[].data may contain circular/dangerous data so we need to normalize it\n if (event.spans) {\n normalized.spans = event.spans.map(span => {\n return {\n ...span,\n ...(span.data && {\n data: normalize(span.data, depth, maxBreadth),\n }),\n };\n });\n }\n\n // event.contexts.flags (FeatureFlagContext) stores context for our feature\n // flag integrations. It has a greater nesting depth than our other typed\n // Contexts, so we re-normalize with a fixed depth of 3 here. We do not want\n // to skip this in case of conflicting, user-provided context.\n if (event.contexts?.flags && normalized.contexts) {\n normalized.contexts.flags = normalize(event.contexts.flags, 3, maxBreadth);\n }\n\n return normalized;\n}\n\nfunction getFinalScope(scope: Scope | undefined, captureContext: CaptureContext | undefined): Scope | undefined {\n if (!captureContext) {\n return scope;\n }\n\n const finalScope = scope ? scope.clone() : new Scope();\n finalScope.update(captureContext);\n return finalScope;\n}\n\n/**\n * Parse either an `EventHint` directly, or convert a `CaptureContext` to an `EventHint`.\n * This is used to allow to update method signatures that used to accept a `CaptureContext` but should now accept an `EventHint`.\n */\nexport function parseEventHintOrCaptureContext(\n hint: ExclusiveEventHintOrCaptureContext | undefined,\n): EventHint | undefined {\n if (!hint) {\n return undefined;\n }\n\n // If you pass a Scope or `() => Scope` as CaptureContext, we just return this as captureContext\n if (hintIsScopeOrFunction(hint)) {\n return { captureContext: hint };\n }\n\n if (hintIsScopeContext(hint)) {\n return {\n captureContext: hint,\n };\n }\n\n return hint;\n}\n\nfunction hintIsScopeOrFunction(hint: CaptureContext | EventHint): hint is Scope | ((scope: Scope) => Scope) {\n return hint instanceof Scope || typeof hint === 'function';\n}\n\ntype ScopeContextProperty = keyof ScopeContext;\nconst captureContextKeys: readonly ScopeContextProperty[] = [\n 'user',\n 'level',\n 'extra',\n 'contexts',\n 'tags',\n 'fingerprint',\n 'propagationContext',\n] as const;\n\nfunction hintIsScopeContext(hint: Partial<ScopeContext> | EventHint): hint is Partial<ScopeContext> {\n return Object.keys(hint).some(key => captureContextKeys.includes(key as ScopeContextProperty));\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prepareEvent.js","sources":["../../../src/utils/prepareEvent.ts"],"sourcesContent":["import type { Client } from '../client';\nimport { DEFAULT_ENVIRONMENT } from '../constants';\nimport { notifyEventProcessors } from '../eventProcessors';\nimport type { CaptureContext, ScopeContext } from '../scope';\nimport { Scope } from '../scope';\nimport type { Event, EventHint } from '../types-hoist/event';\nimport type { ClientOptions } from '../types-hoist/options';\nimport type { StackParser } from '../types-hoist/stacktrace';\nimport { getFilenameToDebugIdMap } from './debug-ids';\nimport { addExceptionMechanism, uuid4 } from './misc';\nimport { normalize } from './normalize';\nimport { applyScopeDataToEvent, getCombinedScopeData } from './scopeData';\nimport { truncate } from './string';\nimport { resolvedSyncPromise } from './syncpromise';\nimport { dateTimestampInSeconds } from './time';\n\n/**\n * This type makes sure that we get either a CaptureContext, OR an EventHint.\n * It does not allow mixing them, which could lead to unexpected outcomes, e.g. this is disallowed:\n * { user: { id: '123' }, mechanism: { handled: false } }\n */\nexport type ExclusiveEventHintOrCaptureContext =\n | (CaptureContext & Partial<{ [key in keyof EventHint]: never }>)\n | (EventHint & Partial<{ [key in keyof ScopeContext]: never }>);\n\n/**\n * Adds common information to events.\n *\n * The information includes release and environment from `options`,\n * breadcrumbs and context (extra, tags and user) from the scope.\n *\n * Information that is already present in the event is never overwritten. For\n * nested objects, such as the context, keys are merged.\n *\n * @param event The original event.\n * @param hint May contain additional information about the original exception.\n * @param scope A scope containing event metadata.\n * @returns A new event with more information.\n * @hidden\n */\nexport function prepareEvent(\n options: ClientOptions,\n event: Event,\n hint: EventHint,\n scope?: Scope,\n client?: Client,\n isolationScope?: Scope,\n): PromiseLike<Event | null> {\n const { normalizeDepth = 3, normalizeMaxBreadth = 1_000 } = options;\n const prepared: Event = {\n ...event,\n event_id: event.event_id || hint.event_id || uuid4(),\n timestamp: event.timestamp || dateTimestampInSeconds(),\n };\n const integrations = hint.integrations || options.integrations.map(i => i.name);\n\n applyClientOptions(prepared, options);\n applyIntegrationsMetadata(prepared, integrations);\n\n if (client) {\n client.emit('applyFrameMetadata', event);\n }\n\n // Only put debug IDs onto frames for error events.\n if (event.type === undefined) {\n applyDebugIds(prepared, options.stackParser);\n }\n\n // If we have scope given to us, use it as the base for further modifications.\n // This allows us to prevent unnecessary copying of data if `captureContext` is not provided.\n const finalScope = getFinalScope(scope, hint.captureContext);\n\n if (hint.mechanism) {\n addExceptionMechanism(prepared, hint.mechanism);\n }\n\n const clientEventProcessors = client ? client.getEventProcessors() : [];\n\n // This should be the last thing called, since we want that\n // {@link Scope.addEventProcessor} gets the finished prepared event.\n // Merge scope data together\n const data = getCombinedScopeData(isolationScope, finalScope);\n\n const attachments = [...(hint.attachments || []), ...data.attachments];\n if (attachments.length) {\n hint.attachments = attachments;\n }\n\n applyScopeDataToEvent(prepared, data);\n\n const eventProcessors = [\n ...clientEventProcessors,\n // Run scope event processors _after_ all other processors\n ...data.eventProcessors,\n ];\n\n // Skip event processors for internal exceptions to prevent recursion\n const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true;\n const result = isInternalException\n ? resolvedSyncPromise(prepared)\n : notifyEventProcessors(eventProcessors, prepared, hint);\n\n return result.then(evt => {\n if (evt) {\n // We apply the debug_meta field only after all event processors have ran, so that if any event processors modified\n // file names (e.g.the RewriteFrames integration) the filename -> debug ID relationship isn't destroyed.\n // This should not cause any PII issues, since we're only moving data that is already on the event and not adding\n // any new data\n applyDebugMeta(evt);\n }\n\n if (typeof normalizeDepth === 'number' && normalizeDepth > 0) {\n return normalizeEvent(evt, normalizeDepth, normalizeMaxBreadth);\n }\n return evt;\n });\n}\n\n/**\n * Enhances event using the client configuration.\n * It takes care of all \"static\" values like environment, release and `dist`,\n * as well as truncating overly long values.\n *\n * Only exported for tests.\n *\n * @param event event instance to be enhanced\n */\nexport function applyClientOptions(event: Event, options: ClientOptions): void {\n const { environment, release, dist, maxValueLength } = options;\n\n // empty strings do not make sense for environment, release, and dist\n // so we handle them the same as if they were not provided\n event.environment = event.environment || environment || DEFAULT_ENVIRONMENT;\n\n if (!event.release && release) {\n event.release = release;\n }\n\n if (!event.dist && dist) {\n event.dist = dist;\n }\n\n const request = event.request;\n if (request?.url && maxValueLength) {\n request.url = truncate(request.url, maxValueLength);\n }\n\n if (maxValueLength) {\n event.exception?.values?.forEach(exception => {\n if (exception.value) {\n // Truncates error messages\n exception.value = truncate(exception.value, maxValueLength);\n }\n });\n }\n}\n\n/**\n * Puts debug IDs into the stack frames of an error event.\n */\nexport function applyDebugIds(event: Event, stackParser: StackParser): void {\n // Build a map of filename -> debug_id\n const filenameDebugIdMap = getFilenameToDebugIdMap(stackParser);\n\n event.exception?.values?.forEach(exception => {\n exception.stacktrace?.frames?.forEach(frame => {\n if (frame.filename) {\n frame.debug_id = filenameDebugIdMap[frame.filename];\n }\n });\n });\n}\n\n/**\n * Moves debug IDs from the stack frames of an error event into the debug_meta field.\n */\nexport function applyDebugMeta(event: Event): void {\n // Extract debug IDs and filenames from the stack frames on the event.\n const filenameDebugIdMap: Record<string, string> = {};\n event.exception?.values?.forEach(exception => {\n exception.stacktrace?.frames?.forEach(frame => {\n if (frame.debug_id) {\n if (frame.abs_path) {\n filenameDebugIdMap[frame.abs_path] = frame.debug_id;\n } else if (frame.filename) {\n filenameDebugIdMap[frame.filename] = frame.debug_id;\n }\n delete frame.debug_id;\n }\n });\n });\n\n if (Object.keys(filenameDebugIdMap).length === 0) {\n return;\n }\n\n // Fill debug_meta information\n event.debug_meta = event.debug_meta || {};\n event.debug_meta.images = event.debug_meta.images || [];\n const images = event.debug_meta.images;\n Object.entries(filenameDebugIdMap).forEach(([filename, debug_id]) => {\n images.push({\n type: 'sourcemap',\n code_file: filename,\n debug_id,\n });\n });\n}\n\n/**\n * This function adds all used integrations to the SDK info in the event.\n * @param event The event that will be filled with all integrations.\n */\nfunction applyIntegrationsMetadata(event: Event, integrationNames: string[]): void {\n if (integrationNames.length > 0) {\n event.sdk = event.sdk || {};\n event.sdk.integrations = [...(event.sdk.integrations || []), ...integrationNames];\n }\n}\n\n/**\n * Applies `normalize` function on necessary `Event` attributes to make them safe for serialization.\n * Normalized keys:\n * - `breadcrumbs.data`\n * - `user`\n * - `contexts`\n * - `extra`\n * @param event Event\n * @returns Normalized event\n */\nfunction normalizeEvent(event: Event | null, depth: number, maxBreadth: number): Event | null {\n if (!event) {\n return null;\n }\n\n const normalized: Event = {\n ...event,\n ...(event.breadcrumbs && {\n breadcrumbs: event.breadcrumbs.map(b => ({\n ...b,\n ...(b.data && {\n data: normalize(b.data, depth, maxBreadth),\n }),\n })),\n }),\n ...(event.user && {\n user: normalize(event.user, depth, maxBreadth),\n }),\n ...(event.contexts && {\n contexts: normalize(event.contexts, depth, maxBreadth),\n }),\n ...(event.extra && {\n extra: normalize(event.extra, depth, maxBreadth),\n }),\n };\n\n // event.contexts.trace stores information about a Transaction. Similarly,\n // event.spans[] stores information about child Spans. Given that a\n // Transaction is conceptually a Span, normalization should apply to both\n // Transactions and Spans consistently.\n // For now the decision is to skip normalization of Transactions and Spans,\n // so this block overwrites the normalized event to add back the original\n // Transaction information prior to normalization.\n if (event.contexts?.trace && normalized.contexts) {\n normalized.contexts.trace = event.contexts.trace;\n\n // event.contexts.trace.data may contain circular/dangerous data so we need to normalize it\n if (event.contexts.trace.data) {\n normalized.contexts.trace.data = normalize(event.contexts.trace.data, depth, maxBreadth);\n }\n }\n\n // event.spans[].data may contain circular/dangerous data so we need to normalize it\n if (event.spans) {\n normalized.spans = event.spans.map(span => {\n return {\n ...span,\n ...(span.data && {\n data: normalize(span.data, depth, maxBreadth),\n }),\n };\n });\n }\n\n // event.contexts.flags (FeatureFlagContext) stores context for our feature\n // flag integrations. It has a greater nesting depth than our other typed\n // Contexts, so we re-normalize with a fixed depth of 3 here. We do not want\n // to skip this in case of conflicting, user-provided context.\n if (event.contexts?.flags && normalized.contexts) {\n normalized.contexts.flags = normalize(event.contexts.flags, 3, maxBreadth);\n }\n\n return normalized;\n}\n\nfunction getFinalScope(scope: Scope | undefined, captureContext: CaptureContext | undefined): Scope | undefined {\n if (!captureContext) {\n return scope;\n }\n\n const finalScope = scope ? scope.clone() : new Scope();\n finalScope.update(captureContext);\n return finalScope;\n}\n\n/**\n * Parse either an `EventHint` directly, or convert a `CaptureContext` to an `EventHint`.\n * This is used to allow to update method signatures that used to accept a `CaptureContext` but should now accept an `EventHint`.\n */\nexport function parseEventHintOrCaptureContext(\n hint: ExclusiveEventHintOrCaptureContext | undefined,\n): EventHint | undefined {\n if (!hint) {\n return undefined;\n }\n\n // If you pass a Scope or `() => Scope` as CaptureContext, we just return this as captureContext\n if (hintIsScopeOrFunction(hint)) {\n return { captureContext: hint };\n }\n\n if (hintIsScopeContext(hint)) {\n return {\n captureContext: hint,\n };\n }\n\n return hint;\n}\n\nfunction hintIsScopeOrFunction(hint: CaptureContext | EventHint): hint is Scope | ((scope: Scope) => Scope) {\n return hint instanceof Scope || typeof hint === 'function';\n}\n\ntype ScopeContextProperty = keyof ScopeContext;\nconst captureContextKeys: readonly ScopeContextProperty[] = [\n 'user',\n 'level',\n 'extra',\n 'contexts',\n 'tags',\n 'fingerprint',\n 'propagationContext',\n] as const;\n\nfunction hintIsScopeContext(hint: Partial<ScopeContext> | EventHint): hint is Partial<ScopeContext> {\n return Object.keys(hint).some(key => captureContextKeys.includes(key as ScopeContextProperty));\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { resolvedSyncPromise, rejectedSyncPromise } from './syncpromise.js';
2
+ import { safeUnref } from './timer.js';
2
3
 
3
4
  const SENTRY_BUFFER_FULL_ERROR = Symbol.for('SentryBufferFullError');
4
5
 
@@ -69,10 +70,11 @@ function makePromiseBuffer(limit = 100) {
69
70
  return drainPromise;
70
71
  }
71
72
 
72
- const promises = [drainPromise, new Promise(resolve => setTimeout(() => resolve(false), timeout))];
73
+ const promises = [
74
+ drainPromise,
75
+ new Promise(resolve => safeUnref(setTimeout(() => resolve(false), timeout))),
76
+ ];
73
77
 
74
- // Promise.race will resolve to the first promise that resolves or rejects
75
- // So if the drainPromise resolves, the timeout promise will be ignored
76
78
  return Promise.race(promises);
77
79
  }
78
80