@sentry/cloudflare 11.0.0-alpha.1 → 11.0.0-beta.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 (415) hide show
  1. package/build/cjs/dev/baseSdk.js +20 -8
  2. package/build/cjs/dev/baseSdk.js.map +1 -1
  3. package/build/cjs/dev/client.js +118 -25
  4. package/build/cjs/dev/client.js.map +1 -1
  5. package/build/cjs/dev/clientCache.js +15 -0
  6. package/build/cjs/dev/clientCache.js.map +1 -0
  7. package/build/cjs/dev/defineCloudflareOptions.js.map +1 -1
  8. package/build/cjs/dev/durableobject.js +4 -62
  9. package/build/cjs/dev/durableobject.js.map +1 -1
  10. package/build/cjs/dev/flush.js +6 -4
  11. package/build/cjs/dev/flush.js.map +1 -1
  12. package/build/cjs/dev/index.js +8 -7
  13. package/build/cjs/dev/index.js.map +1 -1
  14. package/build/cjs/dev/instrumentations/agents/instrumentAgentCallableRpc.js +3 -1
  15. package/build/cjs/dev/instrumentations/agents/instrumentAgentCallableRpc.js.map +1 -1
  16. package/build/cjs/dev/instrumentations/instrumentDurableObjectHandlers.js +123 -0
  17. package/build/cjs/dev/instrumentations/instrumentDurableObjectHandlers.js.map +1 -0
  18. package/build/cjs/dev/instrumentations/instrumentDurableObjectNamespace.js +4 -4
  19. package/build/cjs/dev/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  20. package/build/cjs/dev/instrumentations/instrumentDurableObjectStorage.js +3 -1
  21. package/build/cjs/dev/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
  22. package/build/cjs/dev/instrumentations/instrumentDurableObjectSyncKvStorage.js +3 -1
  23. package/build/cjs/dev/instrumentations/instrumentDurableObjectSyncKvStorage.js.map +1 -1
  24. package/build/cjs/dev/instrumentations/instrumentSqlStorage.js +6 -3
  25. package/build/cjs/dev/instrumentations/instrumentSqlStorage.js.map +1 -1
  26. package/build/cjs/dev/instrumentations/instrumentWorkerEntrypoint.js +9 -16
  27. package/build/cjs/dev/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
  28. package/build/cjs/dev/instrumentations/worker/instrumentD1.js +10 -3
  29. package/build/cjs/dev/instrumentations/worker/instrumentD1.js.map +1 -1
  30. package/build/cjs/dev/instrumentations/worker/instrumentEmail.js +4 -2
  31. package/build/cjs/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
  32. package/build/cjs/dev/instrumentations/worker/instrumentEnv.js +5 -12
  33. package/build/cjs/dev/instrumentations/worker/instrumentEnv.js.map +1 -1
  34. package/build/cjs/dev/instrumentations/worker/instrumentFetch.js +8 -8
  35. package/build/cjs/dev/instrumentations/worker/instrumentFetch.js.map +1 -1
  36. package/build/cjs/dev/instrumentations/worker/instrumentQueue.js +4 -2
  37. package/build/cjs/dev/instrumentations/worker/instrumentQueue.js.map +1 -1
  38. package/build/cjs/dev/instrumentations/worker/instrumentQueueProducer.js +3 -2
  39. package/build/cjs/dev/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
  40. package/build/cjs/dev/instrumentations/worker/instrumentR2.js +21 -18
  41. package/build/cjs/dev/instrumentations/worker/instrumentR2.js.map +1 -1
  42. package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js +4 -2
  43. package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
  44. package/build/cjs/dev/instrumentations/worker/instrumentTail.js +2 -0
  45. package/build/cjs/dev/instrumentations/worker/instrumentTail.js.map +1 -1
  46. package/build/cjs/dev/integrations/fetch.js +1 -11
  47. package/build/cjs/dev/integrations/fetch.js.map +1 -1
  48. package/build/cjs/dev/opentelemetry/tracer.js +2 -40
  49. package/build/cjs/dev/opentelemetry/tracer.js.map +1 -1
  50. package/build/cjs/dev/pages-plugin.js +2 -2
  51. package/build/cjs/dev/pages-plugin.js.map +1 -1
  52. package/build/cjs/dev/request.js +2 -123
  53. package/build/cjs/dev/request.js.map +1 -1
  54. package/build/cjs/dev/sdk.js +11 -6
  55. package/build/cjs/dev/sdk.js.map +1 -1
  56. package/build/cjs/dev/transport.js +1 -1
  57. package/build/cjs/dev/transport.js.map +1 -1
  58. package/build/cjs/dev/utils/invocationContext.js +41 -0
  59. package/build/cjs/dev/utils/invocationContext.js.map +1 -0
  60. package/build/cjs/dev/utils/invocationScope.js +7 -2
  61. package/build/cjs/dev/utils/invocationScope.js.map +1 -1
  62. package/build/cjs/dev/utils/isBinding.js +0 -4
  63. package/build/cjs/dev/utils/isBinding.js.map +1 -1
  64. package/build/cjs/dev/utils/rpcPropagation.js +15 -0
  65. package/build/cjs/dev/utils/rpcPropagation.js.map +1 -0
  66. package/build/cjs/dev/vendor/stacktrace.js +2 -1
  67. package/build/cjs/dev/vendor/stacktrace.js.map +1 -1
  68. package/build/cjs/dev/vite/autoInstrument.js +2 -1
  69. package/build/cjs/dev/vite/autoInstrument.js.map +1 -1
  70. package/build/cjs/dev/vite/index.js.map +1 -1
  71. package/build/cjs/dev/vite/transform.js +30 -5
  72. package/build/cjs/dev/vite/transform.js.map +1 -1
  73. package/build/cjs/dev/vite/wranglerConfig.js +21 -1
  74. package/build/cjs/dev/vite/wranglerConfig.js.map +1 -1
  75. package/build/cjs/dev/withSentry.js.map +1 -1
  76. package/build/cjs/dev/workflows.js +45 -33
  77. package/build/cjs/dev/workflows.js.map +1 -1
  78. package/build/cjs/dev/wrapMethodWithSentry.js +51 -15
  79. package/build/cjs/dev/wrapMethodWithSentry.js.map +1 -1
  80. package/build/cjs/dev/wrapRequestHandlerWithInit.js +134 -0
  81. package/build/cjs/dev/wrapRequestHandlerWithInit.js.map +1 -0
  82. package/build/cjs/prod/baseSdk.js +20 -8
  83. package/build/cjs/prod/baseSdk.js.map +1 -1
  84. package/build/cjs/prod/client.js +118 -25
  85. package/build/cjs/prod/client.js.map +1 -1
  86. package/build/cjs/prod/clientCache.js +15 -0
  87. package/build/cjs/prod/clientCache.js.map +1 -0
  88. package/build/cjs/prod/defineCloudflareOptions.js.map +1 -1
  89. package/build/cjs/prod/durableobject.js +4 -62
  90. package/build/cjs/prod/durableobject.js.map +1 -1
  91. package/build/cjs/prod/flush.js +6 -4
  92. package/build/cjs/prod/flush.js.map +1 -1
  93. package/build/cjs/prod/index.js +8 -7
  94. package/build/cjs/prod/index.js.map +1 -1
  95. package/build/cjs/prod/instrumentations/agents/instrumentAgentCallableRpc.js +3 -1
  96. package/build/cjs/prod/instrumentations/agents/instrumentAgentCallableRpc.js.map +1 -1
  97. package/build/cjs/prod/instrumentations/instrumentDurableObjectHandlers.js +123 -0
  98. package/build/cjs/prod/instrumentations/instrumentDurableObjectHandlers.js.map +1 -0
  99. package/build/cjs/prod/instrumentations/instrumentDurableObjectNamespace.js +4 -4
  100. package/build/cjs/prod/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  101. package/build/cjs/prod/instrumentations/instrumentDurableObjectStorage.js +3 -1
  102. package/build/cjs/prod/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
  103. package/build/cjs/prod/instrumentations/instrumentDurableObjectSyncKvStorage.js +3 -1
  104. package/build/cjs/prod/instrumentations/instrumentDurableObjectSyncKvStorage.js.map +1 -1
  105. package/build/cjs/prod/instrumentations/instrumentSqlStorage.js +6 -3
  106. package/build/cjs/prod/instrumentations/instrumentSqlStorage.js.map +1 -1
  107. package/build/cjs/prod/instrumentations/instrumentWorkerEntrypoint.js +9 -16
  108. package/build/cjs/prod/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
  109. package/build/cjs/prod/instrumentations/worker/instrumentD1.js +10 -3
  110. package/build/cjs/prod/instrumentations/worker/instrumentD1.js.map +1 -1
  111. package/build/cjs/prod/instrumentations/worker/instrumentEmail.js +4 -2
  112. package/build/cjs/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
  113. package/build/cjs/prod/instrumentations/worker/instrumentEnv.js +5 -12
  114. package/build/cjs/prod/instrumentations/worker/instrumentEnv.js.map +1 -1
  115. package/build/cjs/prod/instrumentations/worker/instrumentFetch.js +8 -8
  116. package/build/cjs/prod/instrumentations/worker/instrumentFetch.js.map +1 -1
  117. package/build/cjs/prod/instrumentations/worker/instrumentQueue.js +4 -2
  118. package/build/cjs/prod/instrumentations/worker/instrumentQueue.js.map +1 -1
  119. package/build/cjs/prod/instrumentations/worker/instrumentQueueProducer.js +3 -2
  120. package/build/cjs/prod/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
  121. package/build/cjs/prod/instrumentations/worker/instrumentR2.js +21 -18
  122. package/build/cjs/prod/instrumentations/worker/instrumentR2.js.map +1 -1
  123. package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js +4 -2
  124. package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
  125. package/build/cjs/prod/instrumentations/worker/instrumentTail.js +2 -0
  126. package/build/cjs/prod/instrumentations/worker/instrumentTail.js.map +1 -1
  127. package/build/cjs/prod/integrations/fetch.js +1 -11
  128. package/build/cjs/prod/integrations/fetch.js.map +1 -1
  129. package/build/cjs/prod/opentelemetry/tracer.js +2 -40
  130. package/build/cjs/prod/opentelemetry/tracer.js.map +1 -1
  131. package/build/cjs/prod/pages-plugin.js +2 -2
  132. package/build/cjs/prod/pages-plugin.js.map +1 -1
  133. package/build/cjs/prod/request.js +2 -123
  134. package/build/cjs/prod/request.js.map +1 -1
  135. package/build/cjs/prod/sdk.js +11 -6
  136. package/build/cjs/prod/sdk.js.map +1 -1
  137. package/build/cjs/prod/transport.js +1 -1
  138. package/build/cjs/prod/transport.js.map +1 -1
  139. package/build/cjs/prod/utils/invocationContext.js +41 -0
  140. package/build/cjs/prod/utils/invocationContext.js.map +1 -0
  141. package/build/cjs/prod/utils/invocationScope.js +7 -2
  142. package/build/cjs/prod/utils/invocationScope.js.map +1 -1
  143. package/build/cjs/prod/utils/isBinding.js +0 -4
  144. package/build/cjs/prod/utils/isBinding.js.map +1 -1
  145. package/build/cjs/prod/utils/rpcPropagation.js +15 -0
  146. package/build/cjs/prod/utils/rpcPropagation.js.map +1 -0
  147. package/build/cjs/prod/vendor/stacktrace.js +2 -1
  148. package/build/cjs/prod/vendor/stacktrace.js.map +1 -1
  149. package/build/cjs/prod/vite/autoInstrument.js +2 -1
  150. package/build/cjs/prod/vite/autoInstrument.js.map +1 -1
  151. package/build/cjs/prod/vite/index.js.map +1 -1
  152. package/build/cjs/prod/vite/transform.js +30 -5
  153. package/build/cjs/prod/vite/transform.js.map +1 -1
  154. package/build/cjs/prod/vite/wranglerConfig.js +21 -1
  155. package/build/cjs/prod/vite/wranglerConfig.js.map +1 -1
  156. package/build/cjs/prod/withSentry.js.map +1 -1
  157. package/build/cjs/prod/workflows.js +45 -33
  158. package/build/cjs/prod/workflows.js.map +1 -1
  159. package/build/cjs/prod/wrapMethodWithSentry.js +51 -15
  160. package/build/cjs/prod/wrapMethodWithSentry.js.map +1 -1
  161. package/build/cjs/prod/wrapRequestHandlerWithInit.js +134 -0
  162. package/build/cjs/prod/wrapRequestHandlerWithInit.js.map +1 -0
  163. package/build/esm/dev/baseSdk.js +21 -9
  164. package/build/esm/dev/baseSdk.js.map +1 -1
  165. package/build/esm/dev/client.js +118 -25
  166. package/build/esm/dev/client.js.map +1 -1
  167. package/build/esm/dev/clientCache.js +12 -0
  168. package/build/esm/dev/clientCache.js.map +1 -0
  169. package/build/esm/dev/defineCloudflareOptions.js.map +1 -1
  170. package/build/esm/dev/durableobject.js +5 -63
  171. package/build/esm/dev/durableobject.js.map +1 -1
  172. package/build/esm/dev/flush.js +6 -4
  173. package/build/esm/dev/flush.js.map +1 -1
  174. package/build/esm/dev/index.js +4 -4
  175. package/build/esm/dev/instrumentations/agents/instrumentAgentCallableRpc.js +4 -2
  176. package/build/esm/dev/instrumentations/agents/instrumentAgentCallableRpc.js.map +1 -1
  177. package/build/esm/dev/instrumentations/instrumentDurableObjectHandlers.js +121 -0
  178. package/build/esm/dev/instrumentations/instrumentDurableObjectHandlers.js.map +1 -0
  179. package/build/esm/dev/instrumentations/instrumentDurableObjectNamespace.js +4 -4
  180. package/build/esm/dev/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  181. package/build/esm/dev/instrumentations/instrumentDurableObjectStorage.js +3 -1
  182. package/build/esm/dev/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
  183. package/build/esm/dev/instrumentations/instrumentDurableObjectSyncKvStorage.js +3 -1
  184. package/build/esm/dev/instrumentations/instrumentDurableObjectSyncKvStorage.js.map +1 -1
  185. package/build/esm/dev/instrumentations/instrumentSqlStorage.js +5 -2
  186. package/build/esm/dev/instrumentations/instrumentSqlStorage.js.map +1 -1
  187. package/build/esm/dev/instrumentations/instrumentWorkerEntrypoint.js +9 -16
  188. package/build/esm/dev/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
  189. package/build/esm/dev/instrumentations/worker/instrumentD1.js +11 -4
  190. package/build/esm/dev/instrumentations/worker/instrumentD1.js.map +1 -1
  191. package/build/esm/dev/instrumentations/worker/instrumentEmail.js +7 -5
  192. package/build/esm/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
  193. package/build/esm/dev/instrumentations/worker/instrumentEnv.js +6 -13
  194. package/build/esm/dev/instrumentations/worker/instrumentEnv.js.map +1 -1
  195. package/build/esm/dev/instrumentations/worker/instrumentFetch.js +1 -1
  196. package/build/esm/dev/instrumentations/worker/instrumentFetch.js.map +1 -1
  197. package/build/esm/dev/instrumentations/worker/instrumentQueue.js +7 -5
  198. package/build/esm/dev/instrumentations/worker/instrumentQueue.js.map +1 -1
  199. package/build/esm/dev/instrumentations/worker/instrumentQueueProducer.js +4 -3
  200. package/build/esm/dev/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
  201. package/build/esm/dev/instrumentations/worker/instrumentR2.js +22 -19
  202. package/build/esm/dev/instrumentations/worker/instrumentR2.js.map +1 -1
  203. package/build/esm/dev/instrumentations/worker/instrumentScheduled.js +7 -5
  204. package/build/esm/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
  205. package/build/esm/dev/instrumentations/worker/instrumentTail.js +2 -0
  206. package/build/esm/dev/instrumentations/worker/instrumentTail.js.map +1 -1
  207. package/build/esm/dev/integrations/fetch.js +2 -12
  208. package/build/esm/dev/integrations/fetch.js.map +1 -1
  209. package/build/esm/dev/opentelemetry/tracer.js +2 -40
  210. package/build/esm/dev/opentelemetry/tracer.js.map +1 -1
  211. package/build/esm/dev/package.json +1 -1
  212. package/build/esm/dev/pages-plugin.js +1 -1
  213. package/build/esm/dev/pages-plugin.js.map +1 -1
  214. package/build/esm/dev/request.js +2 -122
  215. package/build/esm/dev/request.js.map +1 -1
  216. package/build/esm/dev/sdk.js +11 -7
  217. package/build/esm/dev/sdk.js.map +1 -1
  218. package/build/esm/dev/transport.js +1 -1
  219. package/build/esm/dev/transport.js.map +1 -1
  220. package/build/esm/dev/utils/invocationContext.js +37 -0
  221. package/build/esm/dev/utils/invocationContext.js.map +1 -0
  222. package/build/esm/dev/utils/invocationScope.js +7 -2
  223. package/build/esm/dev/utils/invocationScope.js.map +1 -1
  224. package/build/esm/dev/utils/isBinding.js +1 -4
  225. package/build/esm/dev/utils/isBinding.js.map +1 -1
  226. package/build/esm/dev/utils/rpcPropagation.js +13 -0
  227. package/build/esm/dev/utils/rpcPropagation.js.map +1 -0
  228. package/build/esm/dev/utils/traceLinks.js +1 -1
  229. package/build/esm/dev/vendor/stacktrace.js +2 -1
  230. package/build/esm/dev/vendor/stacktrace.js.map +1 -1
  231. package/build/esm/dev/vite/autoInstrument.js +2 -1
  232. package/build/esm/dev/vite/autoInstrument.js.map +1 -1
  233. package/build/esm/dev/vite/index.js.map +1 -1
  234. package/build/esm/dev/vite/transform.js +30 -5
  235. package/build/esm/dev/vite/transform.js.map +1 -1
  236. package/build/esm/dev/vite/wranglerConfig.js +21 -2
  237. package/build/esm/dev/vite/wranglerConfig.js.map +1 -1
  238. package/build/esm/dev/withSentry.js.map +1 -1
  239. package/build/esm/dev/workflows.js +48 -36
  240. package/build/esm/dev/workflows.js.map +1 -1
  241. package/build/esm/dev/wrapMethodWithSentry.js +53 -17
  242. package/build/esm/dev/wrapMethodWithSentry.js.map +1 -1
  243. package/build/esm/dev/wrapRequestHandlerWithInit.js +132 -0
  244. package/build/esm/dev/wrapRequestHandlerWithInit.js.map +1 -0
  245. package/build/esm/prod/baseSdk.js +21 -9
  246. package/build/esm/prod/baseSdk.js.map +1 -1
  247. package/build/esm/prod/client.js +118 -25
  248. package/build/esm/prod/client.js.map +1 -1
  249. package/build/esm/prod/clientCache.js +12 -0
  250. package/build/esm/prod/clientCache.js.map +1 -0
  251. package/build/esm/prod/defineCloudflareOptions.js.map +1 -1
  252. package/build/esm/prod/durableobject.js +5 -63
  253. package/build/esm/prod/durableobject.js.map +1 -1
  254. package/build/esm/prod/flush.js +6 -4
  255. package/build/esm/prod/flush.js.map +1 -1
  256. package/build/esm/prod/index.js +4 -4
  257. package/build/esm/prod/instrumentations/agents/instrumentAgentCallableRpc.js +4 -2
  258. package/build/esm/prod/instrumentations/agents/instrumentAgentCallableRpc.js.map +1 -1
  259. package/build/esm/prod/instrumentations/instrumentDurableObjectHandlers.js +121 -0
  260. package/build/esm/prod/instrumentations/instrumentDurableObjectHandlers.js.map +1 -0
  261. package/build/esm/prod/instrumentations/instrumentDurableObjectNamespace.js +4 -4
  262. package/build/esm/prod/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
  263. package/build/esm/prod/instrumentations/instrumentDurableObjectStorage.js +3 -1
  264. package/build/esm/prod/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
  265. package/build/esm/prod/instrumentations/instrumentDurableObjectSyncKvStorage.js +3 -1
  266. package/build/esm/prod/instrumentations/instrumentDurableObjectSyncKvStorage.js.map +1 -1
  267. package/build/esm/prod/instrumentations/instrumentSqlStorage.js +5 -2
  268. package/build/esm/prod/instrumentations/instrumentSqlStorage.js.map +1 -1
  269. package/build/esm/prod/instrumentations/instrumentWorkerEntrypoint.js +9 -16
  270. package/build/esm/prod/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
  271. package/build/esm/prod/instrumentations/worker/instrumentD1.js +11 -4
  272. package/build/esm/prod/instrumentations/worker/instrumentD1.js.map +1 -1
  273. package/build/esm/prod/instrumentations/worker/instrumentEmail.js +7 -5
  274. package/build/esm/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
  275. package/build/esm/prod/instrumentations/worker/instrumentEnv.js +6 -13
  276. package/build/esm/prod/instrumentations/worker/instrumentEnv.js.map +1 -1
  277. package/build/esm/prod/instrumentations/worker/instrumentFetch.js +1 -1
  278. package/build/esm/prod/instrumentations/worker/instrumentFetch.js.map +1 -1
  279. package/build/esm/prod/instrumentations/worker/instrumentQueue.js +7 -5
  280. package/build/esm/prod/instrumentations/worker/instrumentQueue.js.map +1 -1
  281. package/build/esm/prod/instrumentations/worker/instrumentQueueProducer.js +4 -3
  282. package/build/esm/prod/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
  283. package/build/esm/prod/instrumentations/worker/instrumentR2.js +22 -19
  284. package/build/esm/prod/instrumentations/worker/instrumentR2.js.map +1 -1
  285. package/build/esm/prod/instrumentations/worker/instrumentScheduled.js +7 -5
  286. package/build/esm/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
  287. package/build/esm/prod/instrumentations/worker/instrumentTail.js +2 -0
  288. package/build/esm/prod/instrumentations/worker/instrumentTail.js.map +1 -1
  289. package/build/esm/prod/integrations/fetch.js +2 -12
  290. package/build/esm/prod/integrations/fetch.js.map +1 -1
  291. package/build/esm/prod/opentelemetry/tracer.js +2 -40
  292. package/build/esm/prod/opentelemetry/tracer.js.map +1 -1
  293. package/build/esm/prod/package.json +1 -1
  294. package/build/esm/prod/pages-plugin.js +1 -1
  295. package/build/esm/prod/pages-plugin.js.map +1 -1
  296. package/build/esm/prod/request.js +2 -122
  297. package/build/esm/prod/request.js.map +1 -1
  298. package/build/esm/prod/sdk.js +11 -7
  299. package/build/esm/prod/sdk.js.map +1 -1
  300. package/build/esm/prod/transport.js +1 -1
  301. package/build/esm/prod/transport.js.map +1 -1
  302. package/build/esm/prod/utils/invocationContext.js +37 -0
  303. package/build/esm/prod/utils/invocationContext.js.map +1 -0
  304. package/build/esm/prod/utils/invocationScope.js +7 -2
  305. package/build/esm/prod/utils/invocationScope.js.map +1 -1
  306. package/build/esm/prod/utils/isBinding.js +1 -4
  307. package/build/esm/prod/utils/isBinding.js.map +1 -1
  308. package/build/esm/prod/utils/rpcPropagation.js +13 -0
  309. package/build/esm/prod/utils/rpcPropagation.js.map +1 -0
  310. package/build/esm/prod/utils/traceLinks.js +1 -1
  311. package/build/esm/prod/vendor/stacktrace.js +2 -1
  312. package/build/esm/prod/vendor/stacktrace.js.map +1 -1
  313. package/build/esm/prod/vite/autoInstrument.js +2 -1
  314. package/build/esm/prod/vite/autoInstrument.js.map +1 -1
  315. package/build/esm/prod/vite/index.js.map +1 -1
  316. package/build/esm/prod/vite/transform.js +30 -5
  317. package/build/esm/prod/vite/transform.js.map +1 -1
  318. package/build/esm/prod/vite/wranglerConfig.js +21 -2
  319. package/build/esm/prod/vite/wranglerConfig.js.map +1 -1
  320. package/build/esm/prod/withSentry.js.map +1 -1
  321. package/build/esm/prod/workflows.js +48 -36
  322. package/build/esm/prod/workflows.js.map +1 -1
  323. package/build/esm/prod/wrapMethodWithSentry.js +53 -17
  324. package/build/esm/prod/wrapMethodWithSentry.js.map +1 -1
  325. package/build/esm/prod/wrapRequestHandlerWithInit.js +132 -0
  326. package/build/esm/prod/wrapRequestHandlerWithInit.js.map +1 -0
  327. package/build/types/baseSdk.d.ts +8 -0
  328. package/build/types/baseSdk.d.ts.map +1 -1
  329. package/build/types/client.d.ts +91 -18
  330. package/build/types/client.d.ts.map +1 -1
  331. package/build/types/clientCache.d.ts +8 -0
  332. package/build/types/clientCache.d.ts.map +1 -0
  333. package/build/types/defineCloudflareOptions.d.ts +3 -2
  334. package/build/types/defineCloudflareOptions.d.ts.map +1 -1
  335. package/build/types/durableobject.d.ts +5 -7
  336. package/build/types/durableobject.d.ts.map +1 -1
  337. package/build/types/flush.d.ts +2 -0
  338. package/build/types/flush.d.ts.map +1 -1
  339. package/build/types/index.d.ts +4 -4
  340. package/build/types/index.d.ts.map +1 -1
  341. package/build/types/instrumentations/agents/instrumentAgentCallableRpc.d.ts.map +1 -1
  342. package/build/types/instrumentations/instrumentDurableObjectHandlers.d.ts +28 -0
  343. package/build/types/instrumentations/instrumentDurableObjectHandlers.d.ts.map +1 -0
  344. package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts +2 -1
  345. package/build/types/instrumentations/instrumentDurableObjectNamespace.d.ts.map +1 -1
  346. package/build/types/instrumentations/instrumentDurableObjectStorage.d.ts.map +1 -1
  347. package/build/types/instrumentations/instrumentDurableObjectSyncKvStorage.d.ts.map +1 -1
  348. package/build/types/instrumentations/instrumentSqlStorage.d.ts.map +1 -1
  349. package/build/types/instrumentations/instrumentWorkerEntrypoint.d.ts +2 -3
  350. package/build/types/instrumentations/instrumentWorkerEntrypoint.d.ts.map +1 -1
  351. package/build/types/instrumentations/worker/instrumentD1.d.ts.map +1 -1
  352. package/build/types/instrumentations/worker/instrumentEmail.d.ts.map +1 -1
  353. package/build/types/instrumentations/worker/instrumentEnv.d.ts +0 -1
  354. package/build/types/instrumentations/worker/instrumentEnv.d.ts.map +1 -1
  355. package/build/types/instrumentations/worker/instrumentQueue.d.ts.map +1 -1
  356. package/build/types/instrumentations/worker/instrumentQueueProducer.d.ts.map +1 -1
  357. package/build/types/instrumentations/worker/instrumentR2.d.ts.map +1 -1
  358. package/build/types/instrumentations/worker/instrumentScheduled.d.ts.map +1 -1
  359. package/build/types/instrumentations/worker/instrumentTail.d.ts.map +1 -1
  360. package/build/types/integrations/fetch.d.ts.map +1 -1
  361. package/build/types/opentelemetry/tracer.d.ts.map +1 -1
  362. package/build/types/pages-plugin.d.ts +3 -1
  363. package/build/types/pages-plugin.d.ts.map +1 -1
  364. package/build/types/request.d.ts +5 -31
  365. package/build/types/request.d.ts.map +1 -1
  366. package/build/types/sdk.d.ts +13 -4
  367. package/build/types/sdk.d.ts.map +1 -1
  368. package/build/types/transport.d.ts.map +1 -1
  369. package/build/types/types.d.ts +28 -0
  370. package/build/types/types.d.ts.map +1 -1
  371. package/build/types/utils/invocationContext.d.ts +58 -0
  372. package/build/types/utils/invocationContext.d.ts.map +1 -0
  373. package/build/types/utils/invocationScope.d.ts +2 -1
  374. package/build/types/utils/invocationScope.d.ts.map +1 -1
  375. package/build/types/utils/isBinding.d.ts +1 -9
  376. package/build/types/utils/isBinding.d.ts.map +1 -1
  377. package/build/types/utils/rpcPropagation.d.ts +10 -0
  378. package/build/types/utils/rpcPropagation.d.ts.map +1 -0
  379. package/build/types/vendor/stacktrace.d.ts.map +1 -1
  380. package/build/types/vite/autoInstrument.d.ts.map +1 -1
  381. package/build/types/vite/index.d.ts +4 -0
  382. package/build/types/vite/index.d.ts.map +1 -1
  383. package/build/types/vite/transform.d.ts +3 -0
  384. package/build/types/vite/transform.d.ts.map +1 -1
  385. package/build/types/vite/wranglerConfig.d.ts +13 -0
  386. package/build/types/vite/wranglerConfig.d.ts.map +1 -1
  387. package/build/types/withSentry.d.ts +2 -3
  388. package/build/types/withSentry.d.ts.map +1 -1
  389. package/build/types/workflows.d.ts +3 -3
  390. package/build/types/workflows.d.ts.map +1 -1
  391. package/build/types/wrapMethodWithSentry.d.ts +6 -1
  392. package/build/types/wrapMethodWithSentry.d.ts.map +1 -1
  393. package/build/types/wrapRequestHandlerWithInit.d.ts +31 -0
  394. package/build/types/wrapRequestHandlerWithInit.d.ts.map +1 -0
  395. package/package.json +6 -4
  396. package/build/cjs/dev/instrumentations/worker/instrumentRateLimit.js +0 -29
  397. package/build/cjs/dev/instrumentations/worker/instrumentRateLimit.js.map +0 -1
  398. package/build/cjs/dev/integrations/tracing/vercelai.js +0 -18
  399. package/build/cjs/dev/integrations/tracing/vercelai.js.map +0 -1
  400. package/build/cjs/prod/instrumentations/worker/instrumentRateLimit.js +0 -29
  401. package/build/cjs/prod/instrumentations/worker/instrumentRateLimit.js.map +0 -1
  402. package/build/cjs/prod/integrations/tracing/vercelai.js +0 -18
  403. package/build/cjs/prod/integrations/tracing/vercelai.js.map +0 -1
  404. package/build/esm/dev/instrumentations/worker/instrumentRateLimit.js +0 -27
  405. package/build/esm/dev/instrumentations/worker/instrumentRateLimit.js.map +0 -1
  406. package/build/esm/dev/integrations/tracing/vercelai.js +0 -16
  407. package/build/esm/dev/integrations/tracing/vercelai.js.map +0 -1
  408. package/build/esm/prod/instrumentations/worker/instrumentRateLimit.js +0 -27
  409. package/build/esm/prod/instrumentations/worker/instrumentRateLimit.js.map +0 -1
  410. package/build/esm/prod/integrations/tracing/vercelai.js +0 -16
  411. package/build/esm/prod/integrations/tracing/vercelai.js.map +0 -1
  412. package/build/types/instrumentations/worker/instrumentRateLimit.d.ts +0 -6
  413. package/build/types/instrumentations/worker/instrumentRateLimit.d.ts.map +0 -1
  414. package/build/types/integrations/tracing/vercelai.d.ts +0 -39
  415. package/build/types/integrations/tracing/vercelai.d.ts.map +0 -1
@@ -1,5 +1,7 @@
1
- import { ServerRuntimeClient, applySdkMetadata, debug, spanIsSampled, _INTERNAL_clearAiProviderSkips } from '@sentry/core';
1
+ import { applySdkMetadata, debug, spanIsSampled, _INTERNAL_clearAiProviderSkips, _INTERNAL_flushLogsBuffer, _INTERNAL_flushMetricsBuffer } from '@sentry/core';
2
+ import { ServerRuntimeClient } from '@sentry/core/server';
2
3
  import { DEBUG_BUILD } from './debug-build.js';
4
+ import { getInvocationState, getInvocationWaitUntil } from './utils/invocationContext.js';
3
5
 
4
6
  class CloudflareClient extends ServerRuntimeClient {
5
7
  /**
@@ -24,30 +26,36 @@ class CloudflareClient extends ServerRuntimeClient {
24
26
  this._resolveSpanCompletion = null;
25
27
  this._unsubscribeSpanStart = null;
26
28
  this._unsubscribeSpanEnd = null;
29
+ // True while a boundary `flush()` is draining; envelopes created by that drain ride it
30
+ // and must not each start their own eager transport flush.
31
+ this._inBoundaryFlush = false;
27
32
  this._flushLock = flushLock;
28
- this._unsubscribeSpanStart = this.on("spanStart", (span) => {
29
- const spanId = span.spanContext().spanId;
30
- DEBUG_BUILD && debug.log("[CloudflareClient] Span started:", spanId);
31
- if (!spanIsSampled(span)) {
32
- return;
33
- }
34
- this._pendingSpans.add(spanId);
35
- if (!this._spanCompletionPromise) {
36
- this._spanCompletionPromise = new Promise((resolve) => {
37
- this._resolveSpanCompletion = resolve;
38
- });
39
- }
40
- });
41
- this._unsubscribeSpanEnd = this.on("spanEnd", (span) => {
42
- const spanId = span.spanContext().spanId;
43
- DEBUG_BUILD && debug.log("[CloudflareClient] Span ended:", spanId);
44
- this._pendingSpans.delete(spanId);
45
- if (this._pendingSpans.size === 0 && this._resolveSpanCompletion) {
46
- DEBUG_BUILD && debug.log("[CloudflareClient] All spans completed, resolving promise");
47
- this._resolveSpanCompletion();
48
- this._resetSpanCompletionPromise();
49
- }
50
- });
33
+ this.isCachedClient = options.cacheClient === true;
34
+ if (!this.isCachedClient) {
35
+ this._unsubscribeSpanStart = this.on("spanStart", (span) => {
36
+ const spanId = span.spanContext().spanId;
37
+ DEBUG_BUILD && debug.log("[CloudflareClient] Span started:", spanId);
38
+ if (!spanIsSampled(span)) {
39
+ return;
40
+ }
41
+ this._pendingSpans.add(spanId);
42
+ if (!this._spanCompletionPromise) {
43
+ this._spanCompletionPromise = new Promise((resolve) => {
44
+ this._resolveSpanCompletion = resolve;
45
+ });
46
+ }
47
+ });
48
+ this._unsubscribeSpanEnd = this.on("spanEnd", (span) => {
49
+ const spanId = span.spanContext().spanId;
50
+ DEBUG_BUILD && debug.log("[CloudflareClient] Span ended:", spanId);
51
+ this._pendingSpans.delete(spanId);
52
+ if (this._pendingSpans.size === 0 && this._resolveSpanCompletion) {
53
+ DEBUG_BUILD && debug.log("[CloudflareClient] All spans completed, preparing to flush");
54
+ this._resolveSpanCompletion();
55
+ this._resetSpanCompletionPromise();
56
+ }
57
+ });
58
+ }
51
59
  }
52
60
  /**
53
61
  * Flushes pending operations and ensures all data is processed.
@@ -76,7 +84,12 @@ class CloudflareClient extends ServerRuntimeClient {
76
84
  ]);
77
85
  await spanCompletionRace;
78
86
  }
79
- return super.flush(timeout);
87
+ this._inBoundaryFlush = true;
88
+ try {
89
+ return await super.flush(timeout);
90
+ } finally {
91
+ this._inBoundaryFlush = false;
92
+ }
80
93
  }
81
94
  /**
82
95
  * Disposes of the client and releases all resources.
@@ -105,6 +118,16 @@ class CloudflareClient extends ServerRuntimeClient {
105
118
  _setupIntegrations() {
106
119
  _INTERNAL_clearAiProviderSkips();
107
120
  super._setupIntegrations();
121
+ if (this.isCachedClient) {
122
+ this.on("flush", () => {
123
+ const invocationState = getInvocationState();
124
+ if (invocationState) {
125
+ invocationState.flushPointReached = true;
126
+ }
127
+ });
128
+ this._setupEagerEnvelopeDelivery();
129
+ this._setupEagerBufferDelivery();
130
+ }
108
131
  }
109
132
  /**
110
133
  * Resets the span completion promise and resolve function.
@@ -114,6 +137,76 @@ class CloudflareClient extends ServerRuntimeClient {
114
137
  this._spanCompletionPromise = null;
115
138
  this._resolveSpanCompletion = null;
116
139
  }
140
+ /**
141
+ * Drains the transport after an envelope has been accepted past the invocation's
142
+ * flush point. The transport queues request producers until `flush()`; before the
143
+ * flush point the boundary `flush()` drains everything, but envelopes created after
144
+ * it (post-response `waitUntil` work, detached continuations) have no later flush to
145
+ * ride. The drain is registered with the invocation's `waitUntil` to keep the fetch
146
+ * alive; outside any instrumented invocation it always runs.
147
+ */
148
+ _setupEagerEnvelopeDelivery() {
149
+ this.on("afterEnvelope", () => {
150
+ const transport = this.getTransport();
151
+ const invocationState = getInvocationState();
152
+ if (!transport || this._inBoundaryFlush || invocationState && !invocationState.flushPointReached) {
153
+ return;
154
+ }
155
+ this._registerWithInvocationWaitUntil(transport.flush(2e3));
156
+ });
157
+ }
158
+ /**
159
+ * Turns spans, logs and metrics captured past the invocation's flush point into
160
+ * envelopes. Before the flush point the boundary `flush()` drains their buffers; after
161
+ * it (or outside any instrumented invocation) nothing else would: the log/metric idle
162
+ * timer is disabled for this runtime (`_flushInterval: 0`) and the span buffer's own 5s
163
+ * timer fires outside any invocation, where the runtime suspends the send. Each capture
164
+ * drains only its own bucket (the ended span's trace, the log buffer, the metric
165
+ * buffer), so a fan-out of concurrent traces stays one envelope per trace. RPC method
166
+ * spans never reach this path: `wrapMethodWithSentry` runs the boundary flush after the
167
+ * method span has ended, so only work past that (e.g. detached continuations) lands here.
168
+ */
169
+ _setupEagerBufferDelivery() {
170
+ this.on("afterSpanEnd", (span) => {
171
+ const traceId = span.spanContext().traceId;
172
+ this._eagerDrain(() => this.emit("flushTraceSpans", traceId));
173
+ });
174
+ this.on("afterCaptureLog", () => this._eagerDrain(() => _INTERNAL_flushLogsBuffer(this)));
175
+ this.on("afterCaptureMetric", () => this._eagerDrain(() => _INTERNAL_flushMetricsBuffer(this)));
176
+ }
177
+ /**
178
+ * Runs `drain` unless the owning invocation has not reached its flush point yet
179
+ * (before it the boundary `flush()` delivers the buffers).
180
+ */
181
+ _eagerDrain(drain) {
182
+ const invocationState = getInvocationState();
183
+ if (invocationState && !invocationState.flushPointReached) {
184
+ return;
185
+ }
186
+ drain();
187
+ }
188
+ /**
189
+ * Attaches a promise to the `waitUntil` of the invocation that owns the current
190
+ * async context, so the runtime keeps the send alive after the response is returned.
191
+ * Outside any instrumented invocation (or where the context has no `waitUntil`,
192
+ * e.g. Astro prerendering) the send is fire-and-forget.
193
+ */
194
+ _registerWithInvocationWaitUntil(promise) {
195
+ const invocationState = getInvocationState();
196
+ const waitUntil = invocationState && getInvocationWaitUntil(invocationState);
197
+ if (!waitUntil) {
198
+ return;
199
+ }
200
+ try {
201
+ waitUntil(
202
+ Promise.resolve(promise).then(
203
+ () => void 0,
204
+ () => void 0
205
+ )
206
+ );
207
+ } catch {
208
+ }
209
+ }
117
210
  }
118
211
 
119
212
  export { CloudflareClient };
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sources":["../../../src/client.ts"],"sourcesContent":["import type { ClientOptions, Options, ServerRuntimeClientOptions } from '@sentry/core';\nimport {\n _INTERNAL_clearAiProviderSkips,\n applySdkMetadata,\n debug,\n ServerRuntimeClient,\n spanIsSampled,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { ExecutionContextCompat } from './executionContext';\nimport type { makeFlushLock } from './flush';\nimport type { CloudflareTransportOptions } from './transport';\n\n/**\n * The Sentry Cloudflare SDK Client.\n *\n * @see CloudflareClientOptions for documentation on configuration options.\n * @see ServerRuntimeClient for usage documentation.\n */\nexport class CloudflareClient extends ServerRuntimeClient {\n private readonly _flushLock: ReturnType<typeof makeFlushLock> | void;\n private _pendingSpans: Set<string> = new Set();\n private _spanCompletionPromise: Promise<void> | null = null;\n private _resolveSpanCompletion: (() => void) | null = null;\n\n private _unsubscribeSpanStart: (() => void) | null = null;\n private _unsubscribeSpanEnd: (() => void) | null = null;\n\n /**\n * Creates a new Cloudflare SDK instance.\n * @param options Configuration options for this SDK.\n */\n public constructor(options: CloudflareClientOptions) {\n applySdkMetadata(options, 'cloudflare');\n options._metadata = options._metadata || {};\n const { flushLock, ...serverOptions } = options;\n\n const clientOptions: ServerRuntimeClientOptions = {\n ...serverOptions,\n platform: 'javascript',\n // TODO: Grab version information\n runtime: { name: 'cloudflare' },\n // TODO: Add server name\n _flushInterval: 0,\n };\n\n super(clientOptions);\n this._flushLock = flushLock;\n\n // Track span lifecycle to know when to flush\n this._unsubscribeSpanStart = this.on('spanStart', span => {\n const spanId = span.spanContext().spanId;\n DEBUG_BUILD && debug.log('[CloudflareClient] Span started:', spanId);\n\n // Negatively sampled spans never emit spanEnd,\n // so tracking them would cause _pendingSpans to grow unboundedly.\n // We should fix the inconsistent behavior for NonRecordingSpans in the future but\n // for now, we just ignore them.\n if (!spanIsSampled(span)) {\n return;\n }\n\n this._pendingSpans.add(spanId);\n\n if (!this._spanCompletionPromise) {\n this._spanCompletionPromise = new Promise(resolve => {\n this._resolveSpanCompletion = resolve;\n });\n }\n });\n\n this._unsubscribeSpanEnd = this.on('spanEnd', span => {\n const spanId = span.spanContext().spanId;\n DEBUG_BUILD && debug.log('[CloudflareClient] Span ended:', spanId);\n this._pendingSpans.delete(spanId);\n\n // If no more pending spans, resolve the completion promise\n if (this._pendingSpans.size === 0 && this._resolveSpanCompletion) {\n DEBUG_BUILD && debug.log('[CloudflareClient] All spans completed, resolving promise');\n this._resolveSpanCompletion();\n this._resetSpanCompletionPromise();\n }\n });\n }\n\n /**\n * Flushes pending operations and ensures all data is processed.\n * If a timeout is provided, the operation will be completed within the specified time limit.\n *\n * It will wait for all pending spans to complete before flushing.\n *\n * @param {number} [timeout] - Optional timeout in milliseconds to force the completion of the flush operation.\n * @return {Promise<boolean>} A promise that resolves to a boolean indicating whether the flush operation was successful.\n */\n public async flush(timeout?: number): Promise<boolean> {\n if (this._flushLock) {\n await this._flushLock.finalize();\n }\n\n if (this._pendingSpans.size > 0 && this._spanCompletionPromise) {\n DEBUG_BUILD &&\n debug.log('[CloudflareClient] Waiting for', this._pendingSpans.size, 'pending spans to complete...');\n\n const timeoutMs = timeout ?? 5000;\n const spanCompletionRace = Promise.race([\n this._spanCompletionPromise,\n new Promise(resolve =>\n setTimeout(() => {\n DEBUG_BUILD &&\n debug.log('[CloudflareClient] Span completion timeout after', timeoutMs, 'ms, flushing anyway');\n resolve(undefined);\n }, timeoutMs),\n ),\n ]);\n\n await spanCompletionRace;\n }\n\n return super.flush(timeout);\n }\n\n /**\n * Disposes of the client and releases all resources.\n *\n * This method clears all Cloudflare-specific state in addition to the base client cleanup.\n * It unsubscribes from span lifecycle events and clears pending span tracking.\n *\n * Call this method after flushing to allow the client to be garbage collected.\n * After calling dispose(), the client should not be used anymore.\n */\n public override dispose(): void {\n DEBUG_BUILD && debug.log('[CloudflareClient] Disposing client...');\n\n super.dispose();\n\n if (this._unsubscribeSpanStart) {\n this._unsubscribeSpanStart();\n this._unsubscribeSpanStart = null;\n }\n if (this._unsubscribeSpanEnd) {\n this._unsubscribeSpanEnd();\n this._unsubscribeSpanEnd = null;\n }\n\n this._resetSpanCompletionPromise();\n (this as unknown as { _flushLock: ReturnType<typeof makeFlushLock> | void })._flushLock = undefined;\n }\n\n /** @inheritDoc */\n protected override _setupIntegrations(): void {\n // Clear AI provider skip registrations before setting up integrations.\n // The registry is module-global and Cloudflare calls `init()` per request, so without this a\n // single `ai` SDK call would suppress direct `env.AI.run` spans for the rest of the isolate's\n // life. Mirrors the same reset in the Node client.\n _INTERNAL_clearAiProviderSkips();\n super._setupIntegrations();\n }\n\n /**\n * Resets the span completion promise and resolve function.\n */\n private _resetSpanCompletionPromise(): void {\n this._pendingSpans.clear();\n this._spanCompletionPromise = null;\n this._resolveSpanCompletion = null;\n }\n}\n\ninterface BaseCloudflareOptions {\n /**\n * @ignore Used internally to disable the deDupeIntegration for workflows.\n * @hidden Used internally to disable the deDupeIntegration for workflows.\n * @default true\n */\n enableDedupe?: boolean;\n\n /**\n * The Cloudflare SDK is not OpenTelemetry native. By default (`false`) it does not set up a tracer\n * provider; spans are emitted via the SDK's own instrumentation and scopes are isolated with\n * AsyncLocalStorage.\n *\n * Set this to `true` to opt into the OpenTelemetry compatibility tracer, which captures spans\n * emitted via `@opentelemetry/api`. Big caveat: it does not handle custom context, always working\n * off the current scope. This is good enough for many, but not all, integrations.\n *\n * @default false\n */\n enableOpenTelemetrySetup?: boolean;\n\n /**\n * Enable trace propagation for RPC calls between Workers, Durable Objects, and Service Bindings.\n *\n * When enabled, trace context (sentry-trace + baggage) is propagated across:\n * - `stub.fetch()` calls to Durable Objects (via HTTP headers)\n * - Service binding `fetch()` calls (via HTTP headers)\n * - RPC method calls to Durable Objects and WorkerEntrypoints (via trailing argument)\n *\n * When enabled on the **receiver side** (DurableObject or WorkerEntrypoint), the SDK will also:\n * - Extract and continue traces from incoming RPC calls\n * - Create spans for each RPC method invocation\n * - Capture errors thrown by RPC methods\n *\n * **Important:** This option is enabled by default. Set it to `false` to opt out, e.g. if you\n * do not want trace context to leave your Worker via RPC calls.\n *\n * @default true\n * @example\n * ```ts\n * // Opt out of RPC trace propagation\n * export default Sentry.withSentry(\n * (env) => ({\n * dsn: env.SENTRY_DSN,\n * enableRpcTracePropagation: false,\n * }),\n * handler,\n * );\n * ```\n */\n enableRpcTracePropagation?: boolean;\n\n /**\n * Table names that should stay instrumented even though they match the reserved `cf_` prefix used\n * by Durable Object frameworks (`agents`, `partyserver`, ...) for their internal SQLite tables.\n *\n * By default, `exec` queries against `cf_`-prefixed tables are treated as framework noise and no\n * `db.query` span is created for them. If one of your own tables happens to use this prefix, add it\n * here to opt it back into instrumentation. Entries are matched against each table name in the\n * query summary — strings must match exactly, while regular expressions give you prefix/pattern\n * matching.\n *\n * @default []\n * @example\n * ```ts\n * export default Sentry.withSentry(\n * (env) => ({\n * dsn: env.SENTRY_DSN,\n * durableObjectSqlSpanAllowlist: ['cf_my_table', /^cf_reports_/],\n * }),\n * handler,\n * );\n * ```\n */\n durableObjectSqlSpanAllowlist?: Array<string | RegExp>;\n\n /**\n * KV keys that should stay instrumented even though they match a reserved prefix used by Durable\n * Object frameworks (`agents`, `partyserver`, ...) for their internal storage entries.\n *\n * By default, KV reads/writes (`get`, `put`, `delete`, `list`) of `cf_`- or `__ps_`-prefixed keys\n * are treated as framework noise and no `durable_object_storage_*` span is created for them,\n * mirroring how `cf_`-prefixed SQL tables are handled (see {@link durableObjectSqlSpanAllowlist}).\n * If one of your own keys happens to use such a prefix, add it here to opt it back into\n * instrumentation. Strings must match exactly, while regular expressions give you prefix/pattern\n * matching.\n *\n * @default []\n * @example\n * ```ts\n * export default Sentry.withSentry(\n * (env) => ({\n * dsn: env.SENTRY_DSN,\n * durableObjectStorageSpanAllowlist: ['cf_my_key', /^cf_reports_/],\n * }),\n * handler,\n * );\n * ```\n */\n durableObjectStorageSpanAllowlist?: Array<string | RegExp>;\n\n /**\n * If you use Spotlight by Sentry during development, use\n * this option to forward captured Sentry events to Spotlight.\n *\n * Either set it to true, or provide a specific Spotlight Sidecar URL.\n *\n * More details: https://spotlightjs.com/\n *\n * IMPORTANT: Only set this option to `true` while developing, not in production!\n */\n spotlight?: boolean | string;\n}\n\n/**\n * Configuration options for the Sentry Cloudflare SDK\n *\n * @see @sentry/core Options for more information.\n */\nexport interface CloudflareOptions extends Options<CloudflareTransportOptions>, BaseCloudflareOptions {\n ctx?: ExecutionContextCompat;\n}\n\n/**\n * Configuration options for the Sentry Cloudflare SDK Client class\n *\n * @see CloudflareClient for more information.\n */\nexport interface CloudflareClientOptions extends ClientOptions<CloudflareTransportOptions>, BaseCloudflareOptions {\n flushLock?: ReturnType<typeof makeFlushLock>;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sources":["../../../src/client.ts"],"sourcesContent":["import type { ClientOptions, Options, TracePropagationTargets } from '@sentry/core';\nimport {\n _INTERNAL_clearAiProviderSkips,\n _INTERNAL_flushLogsBuffer,\n _INTERNAL_flushMetricsBuffer,\n applySdkMetadata,\n debug,\n spanIsSampled,\n} from '@sentry/core';\nimport type { ServerRuntimeClientOptions } from '@sentry/core/server';\nimport { ServerRuntimeClient } from '@sentry/core/server';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { ExecutionContextCompat } from './executionContext';\nimport type { makeFlushLock } from './flush';\nimport type { CloudflareTransportOptions } from './transport';\nimport { getInvocationState, getInvocationWaitUntil } from './utils/invocationContext';\n\n/**\n * The Sentry Cloudflare SDK Client.\n *\n * @see CloudflareClientOptions for documentation on configuration options.\n * @see ServerRuntimeClient for usage documentation.\n */\nexport class CloudflareClient extends ServerRuntimeClient {\n private readonly _flushLock: ReturnType<typeof makeFlushLock> | void;\n private _pendingSpans: Set<string> = new Set();\n private _spanCompletionPromise: Promise<void> | null = null;\n private _resolveSpanCompletion: (() => void) | null = null;\n\n private _unsubscribeSpanStart: (() => void) | null = null;\n private _unsubscribeSpanEnd: (() => void) | null = null;\n\n // True while a boundary `flush()` is draining; envelopes created by that drain ride it\n // and must not each start their own eager transport flush.\n private _inBoundaryFlush = false;\n\n /**\n * Whether this client is a cached, cross-invocation client (`cacheClient`).\n * Cached clients are never disposed at an invocation boundary, so their spans/events\n * are delivered eagerly instead of waiting for a per-invocation flush.\n */\n public readonly isCachedClient: boolean;\n\n /**\n * Creates a new Cloudflare SDK instance.\n * @param options Configuration options for this SDK.\n */\n public constructor(options: CloudflareClientOptions) {\n applySdkMetadata(options, 'cloudflare');\n options._metadata = options._metadata || {};\n const { flushLock, ...serverOptions } = options;\n\n const clientOptions: ServerRuntimeClientOptions = {\n ...serverOptions,\n platform: 'javascript',\n // TODO: Grab version information\n runtime: { name: 'cloudflare' },\n // TODO: Add server name\n _flushInterval: 0,\n };\n\n super(clientOptions);\n this._flushLock = flushLock;\n this.isCachedClient = options.cacheClient === true;\n\n // Track span lifecycle to know when to flush. Skipped for cached clients\n // (`cacheClient`): they are never disposed, so spans that end after\n // a flush are still delivered. Per-invocation clients are disposed right after\n // the boundary flush, so the flush must wait for open spans to end otherwise\n // their transaction never gets emitted.\n if (!this.isCachedClient) {\n this._unsubscribeSpanStart = this.on('spanStart', span => {\n const spanId = span.spanContext().spanId;\n DEBUG_BUILD && debug.log('[CloudflareClient] Span started:', spanId);\n\n // Negatively sampled spans never emit spanEnd,\n // so tracking them would cause _pendingSpans to grow unboundedly.\n // We should fix the inconsistent behavior for NonRecordingSpans in the future but\n // for now, we just ignore them.\n if (!spanIsSampled(span)) {\n return;\n }\n\n this._pendingSpans.add(spanId);\n\n if (!this._spanCompletionPromise) {\n this._spanCompletionPromise = new Promise(resolve => {\n this._resolveSpanCompletion = resolve;\n });\n }\n });\n\n this._unsubscribeSpanEnd = this.on('spanEnd', span => {\n const spanId = span.spanContext().spanId;\n DEBUG_BUILD && debug.log('[CloudflareClient] Span ended:', spanId);\n this._pendingSpans.delete(spanId);\n\n // If no more pending spans, resolve the completion promise\n if (this._pendingSpans.size === 0 && this._resolveSpanCompletion) {\n DEBUG_BUILD && debug.log('[CloudflareClient] All spans completed, preparing to flush');\n this._resolveSpanCompletion();\n this._resetSpanCompletionPromise();\n }\n });\n }\n }\n\n /**\n * Flushes pending operations and ensures all data is processed.\n * If a timeout is provided, the operation will be completed within the specified time limit.\n *\n * It will wait for all pending spans to complete before flushing.\n *\n * @param {number} [timeout] - Optional timeout in milliseconds to force the completion of the flush operation.\n * @return {Promise<boolean>} A promise that resolves to a boolean indicating whether the flush operation was successful.\n */\n public async flush(timeout?: number): Promise<boolean> {\n // Wait for user waitUntil-registered work to settle before draining, so events\n // captured in that work are still in the buffer. Without this the final flush\n // can drain (and the client be disposed) before background captures land.\n if (this._flushLock) {\n await this._flushLock.finalize();\n }\n\n if (this._pendingSpans.size > 0 && this._spanCompletionPromise) {\n DEBUG_BUILD &&\n debug.log('[CloudflareClient] Waiting for', this._pendingSpans.size, 'pending spans to complete...');\n\n const timeoutMs = timeout ?? 5000;\n const spanCompletionRace = Promise.race([\n this._spanCompletionPromise,\n new Promise(resolve =>\n setTimeout(() => {\n DEBUG_BUILD &&\n debug.log('[CloudflareClient] Span completion timeout after', timeoutMs, 'ms, flushing anyway');\n resolve(undefined);\n }, timeoutMs),\n ),\n ]);\n\n await spanCompletionRace;\n }\n\n // Envelopes created while this flush drains (log/metric/span buffers turning into\n // envelopes on the `flush` emit) ride its own transport drain; without the flag each\n // of them would also start an eager drain and a `waitUntil` registration.\n this._inBoundaryFlush = true;\n try {\n return await super.flush(timeout);\n } finally {\n this._inBoundaryFlush = false;\n }\n }\n\n /**\n * Disposes of the client and releases all resources.\n *\n * This method clears all Cloudflare-specific state in addition to the base client cleanup.\n * It unsubscribes from span lifecycle events and clears pending span tracking.\n *\n * Call this method after flushing to allow the client to be garbage collected.\n * After calling dispose(), the client should not be used anymore.\n */\n public override dispose(): void {\n DEBUG_BUILD && debug.log('[CloudflareClient] Disposing client...');\n\n super.dispose();\n\n if (this._unsubscribeSpanStart) {\n this._unsubscribeSpanStart();\n this._unsubscribeSpanStart = null;\n }\n if (this._unsubscribeSpanEnd) {\n this._unsubscribeSpanEnd();\n this._unsubscribeSpanEnd = null;\n }\n\n this._resetSpanCompletionPromise();\n (this as unknown as { _flushLock: ReturnType<typeof makeFlushLock> | void })._flushLock = undefined;\n }\n\n /** @inheritDoc */\n protected override _setupIntegrations(): void {\n // Clear AI provider skip registrations before setting up integrations.\n // The registry is module-global and Cloudflare calls `init()` per request, so without this a\n // single `ai` SDK call would suppress direct `env.AI.run` spans for the rest of the isolate's\n // life. Mirrors the same reset in the Node client.\n _INTERNAL_clearAiProviderSkips();\n super._setupIntegrations();\n\n // Registered after the integrations on purpose: the flush-point marker must run\n // after core and the span buffer have turned their buffers into envelopes on the\n // same `flush` emit (so those envelopes ride the boundary drain instead of starting\n // eager ones), and the eager span handler relies on `spanStreamingIntegration`\n // having already buffered the span that triggers it.\n if (this.isCachedClient) {\n // Marks the invocation's natural flush point: anything captured from now on\n // (post-response `waitUntil` work, detached continuations) has no later flush\n // to ride and is delivered eagerly by the hooks below.\n this.on('flush', () => {\n const invocationState = getInvocationState();\n if (invocationState) {\n invocationState.flushPointReached = true;\n }\n });\n this._setupEagerEnvelopeDelivery();\n this._setupEagerBufferDelivery();\n }\n }\n\n /**\n * Resets the span completion promise and resolve function.\n */\n private _resetSpanCompletionPromise(): void {\n this._pendingSpans.clear();\n this._spanCompletionPromise = null;\n this._resolveSpanCompletion = null;\n }\n\n /**\n * Drains the transport after an envelope has been accepted past the invocation's\n * flush point. The transport queues request producers until `flush()`; before the\n * flush point the boundary `flush()` drains everything, but envelopes created after\n * it (post-response `waitUntil` work, detached continuations) have no later flush to\n * ride. The drain is registered with the invocation's `waitUntil` to keep the fetch\n * alive; outside any instrumented invocation it always runs.\n */\n private _setupEagerEnvelopeDelivery(): void {\n this.on('afterEnvelope', () => {\n const transport = this.getTransport();\n const invocationState = getInvocationState();\n\n if (!transport || this._inBoundaryFlush || (invocationState && !invocationState.flushPointReached)) {\n return;\n }\n\n this._registerWithInvocationWaitUntil(transport.flush(2000));\n });\n }\n\n /**\n * Turns spans, logs and metrics captured past the invocation's flush point into\n * envelopes. Before the flush point the boundary `flush()` drains their buffers; after\n * it (or outside any instrumented invocation) nothing else would: the log/metric idle\n * timer is disabled for this runtime (`_flushInterval: 0`) and the span buffer's own 5s\n * timer fires outside any invocation, where the runtime suspends the send. Each capture\n * drains only its own bucket (the ended span's trace, the log buffer, the metric\n * buffer), so a fan-out of concurrent traces stays one envelope per trace. RPC method\n * spans never reach this path: `wrapMethodWithSentry` runs the boundary flush after the\n * method span has ended, so only work past that (e.g. detached continuations) lands here.\n */\n private _setupEagerBufferDelivery(): void {\n this.on('afterSpanEnd', span => {\n // The trace id must come from the span, not the current scope: `continueTrace`\n // writes the propagation context to the *current* scope, so the forked\n // isolation scope's propagation context carries a different trace id and\n // flushing by it silently no-ops.\n const traceId = span.spanContext().traceId;\n this._eagerDrain(() => this.emit('flushTraceSpans', traceId));\n });\n this.on('afterCaptureLog', () => this._eagerDrain(() => _INTERNAL_flushLogsBuffer(this)));\n this.on('afterCaptureMetric', () => this._eagerDrain(() => _INTERNAL_flushMetricsBuffer(this)));\n }\n\n /**\n * Runs `drain` unless the owning invocation has not reached its flush point yet\n * (before it the boundary `flush()` delivers the buffers).\n */\n private _eagerDrain(drain: () => void): void {\n const invocationState = getInvocationState();\n\n if (invocationState && !invocationState.flushPointReached) {\n return;\n }\n\n drain();\n }\n\n /**\n * Attaches a promise to the `waitUntil` of the invocation that owns the current\n * async context, so the runtime keeps the send alive after the response is returned.\n * Outside any instrumented invocation (or where the context has no `waitUntil`,\n * e.g. Astro prerendering) the send is fire-and-forget.\n */\n private _registerWithInvocationWaitUntil(promise: PromiseLike<unknown>): void {\n const invocationState = getInvocationState();\n const waitUntil = invocationState && getInvocationWaitUntil(invocationState);\n if (!waitUntil) {\n return;\n }\n\n try {\n waitUntil(\n Promise.resolve(promise).then(\n () => undefined,\n () => undefined,\n ),\n );\n } catch {\n // The owning invocation already ended; the send races isolate teardown either way.\n }\n }\n}\n\ninterface BaseCloudflareOptions {\n /**\n * @ignore Used internally to disable the deDupeIntegration for workflows.\n * @hidden Used internally to disable the deDupeIntegration for workflows.\n * @default true\n */\n enableDedupe?: boolean;\n\n /**\n * The Cloudflare SDK is not OpenTelemetry native. By default (`false`) it does not set up a tracer\n * provider; spans are emitted via the SDK's own instrumentation and scopes are isolated with\n * AsyncLocalStorage.\n *\n * Set this to `true` to opt into the OpenTelemetry compatibility tracer, which captures spans\n * emitted via `@opentelemetry/api`. Big caveat: it does not handle custom context, always working\n * off the current scope. This is good enough for many, but not all, integrations.\n *\n * @default false\n */\n enableOpenTelemetrySetup?: boolean;\n\n /**\n * The bindings on `env` that outgoing RPC calls propagate trace context to.\n *\n * Strings match a binding name exactly, regular expressions match by pattern. An empty array\n * (the default) propagates to nothing.\n *\n * RPC has no headers to carry trace context, so the SDK appends it as a trailing argument to\n * every RPC method call on a matching binding. Only a Sentry-instrumented receiver strips that\n * argument again. Anywhere else it arrives as a real argument and changes what the method was\n * called with, so list only the bindings whose receiver you know runs Sentry.\n *\n * Propagation over `stub.fetch()` and service binding `fetch()` uses HTTP headers and is not\n * affected by this option.\n *\n * Strings match a binding name exactly, regular expressions match by pattern. Both match\n * case-insensitively.\n *\n * When you build with the Sentry Cloudflare Vite plugin, bindings that resolve to *this* worker\n * (its own Durable Objects, its self service bindings) are added for you, because the plugin\n * instruments those receivers itself. Whatever you list here is added on top of them.\n *\n * @default []\n * @example\n * ```ts\n * // Propagate to `env.ORDERS` and every `env.SVC_*` binding\n * export default Sentry.withSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * rpcTracePropagationBindings: ['ORDERS', /^SVC_/],\n * }),\n * handler,\n * );\n * ```\n */\n rpcTracePropagationBindings?: TracePropagationTargets;\n\n /**\n * Table names that should stay instrumented even though they match the reserved `cf_` prefix used\n * by Durable Object frameworks (`agents`, `partyserver`, ...) for their internal SQLite tables.\n *\n * By default, `exec` queries against `cf_`-prefixed tables are treated as framework noise and no\n * `db.query` span is created for them. If one of your own tables happens to use this prefix, add it\n * here to opt it back into instrumentation. Entries are matched against each table name in the\n * query summary — strings must match exactly, while regular expressions give you prefix/pattern\n * matching.\n *\n * @default []\n * @example\n * ```ts\n * export default Sentry.withSentry(\n * (env) => ({\n * dsn: env.SENTRY_DSN,\n * durableObjectSqlSpanAllowlist: ['cf_my_table', /^cf_reports_/],\n * }),\n * handler,\n * );\n * ```\n */\n durableObjectSqlSpanAllowlist?: Array<string | RegExp>;\n\n /**\n * KV keys that should stay instrumented even though they match a reserved prefix used by Durable\n * Object frameworks (`agents`, `partyserver`, ...) for their internal storage entries.\n *\n * By default, KV reads/writes (`get`, `put`, `delete`, `list`) of `cf_`- or `__ps_`-prefixed keys\n * are treated as framework noise and no `durable_object_storage_*` span is created for them,\n * mirroring how `cf_`-prefixed SQL tables are handled (see {@link durableObjectSqlSpanAllowlist}).\n * If one of your own keys happens to use such a prefix, add it here to opt it back into\n * instrumentation. Strings must match exactly, while regular expressions give you prefix/pattern\n * matching.\n *\n * @default []\n * @example\n * ```ts\n * export default Sentry.withSentry(\n * (env) => ({\n * dsn: env.SENTRY_DSN,\n * durableObjectStorageSpanAllowlist: ['cf_my_key', /^cf_reports_/],\n * }),\n * handler,\n * );\n * ```\n */\n durableObjectStorageSpanAllowlist?: Array<string | RegExp>;\n\n /**\n * Sets an optional server name (device name).\n *\n * This is useful for identifying which server or instance is sending events.\n */\n serverName?: string;\n\n /**\n * If you use Spotlight by Sentry during development, use\n * this option to forward captured Sentry events to Spotlight.\n *\n * Either set it to true, or provide a specific Spotlight Sidecar URL.\n *\n * More details: https://spotlightjs.com/\n *\n * IMPORTANT: Only set this option to `true` while developing, not in production!\n */\n spotlight?: boolean | string;\n\n /**\n * Cache the client and reuse it across invocations within the same isolate.\n *\n * The SDK creates one client per isolate and reuses it for all requests/DO\n * handlers in that isolate. This avoids the per-invocation cost of\n * constructing a new client.\n *\n * Since a cached client outlives any single invocation, data captured after an\n * invocation's flush point (post-response `waitUntil` work, detached background\n * work) is delivered eagerly instead of waiting for a flush that never comes.\n *\n * The first `init()` in an isolate decides the cached client's options; later\n * `init()` calls with different options (e.g. another DSN) reuse the cached client\n * unchanged (a debug warning is logged for a DSN change). Use `cacheClient: false`\n * when options must differ per invocation.\n *\n * When disabled, a new client is created per invocation and disposed after the\n * handler completes.\n *\n * @default true\n */\n cacheClient?: boolean;\n}\n\n/**\n * Configuration options for the Sentry Cloudflare SDK\n *\n * @see @sentry/core Options for more information.\n */\nexport interface CloudflareOptions extends Options<CloudflareTransportOptions>, BaseCloudflareOptions {\n ctx?: ExecutionContextCompat;\n}\n\n/**\n * Configuration options for the Sentry Cloudflare SDK Client class\n *\n * @see CloudflareClient for more information.\n */\nexport interface CloudflareClientOptions extends ClientOptions<CloudflareTransportOptions>, BaseCloudflareOptions {\n flushLock?: ReturnType<typeof makeFlushLock>;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { GLOBAL_OBJ } from '@sentry/core';
2
+
3
+ const GLOBAL_CLIENT_KEY = "__SENTRY_CLOUDFLARE_CLIENT__";
4
+ function getCachedClient() {
5
+ return GLOBAL_OBJ[GLOBAL_CLIENT_KEY];
6
+ }
7
+ function cacheClient(client) {
8
+ GLOBAL_OBJ[GLOBAL_CLIENT_KEY] = client;
9
+ }
10
+
11
+ export { cacheClient, getCachedClient };
12
+ //# sourceMappingURL=clientCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clientCache.js","sources":["../../../src/clientCache.ts"],"sourcesContent":["import { GLOBAL_OBJ } from '@sentry/core';\nimport type { CloudflareClient } from './client';\n\nconst GLOBAL_CLIENT_KEY = '__SENTRY_CLOUDFLARE_CLIENT__' as const;\n\ntype GlobalWithCloudflareClient = typeof GLOBAL_OBJ & {\n [GLOBAL_CLIENT_KEY]?: CloudflareClient;\n};\n\n/** Returns the one cached Cloudflare client for this isolate. */\nexport function getCachedClient(): CloudflareClient | undefined {\n return (GLOBAL_OBJ as GlobalWithCloudflareClient)[GLOBAL_CLIENT_KEY];\n}\n\n/** Stores the one Cloudflare client reused by every invocation in this isolate. */\nexport function cacheClient(client: CloudflareClient): void {\n (GLOBAL_OBJ as GlobalWithCloudflareClient)[GLOBAL_CLIENT_KEY] = client;\n}\n\n/** @hidden Only for testing - clears the isolate's cached Cloudflare client. */\nexport function _clearGlobalClientCache(): void {\n (GLOBAL_OBJ as GlobalWithCloudflareClient)[GLOBAL_CLIENT_KEY] = undefined;\n}\n"],"names":[],"mappings":";;AAGA,MAAM,iBAAA,GAAoB,8BAAA;AAOnB,SAAS,eAAA,GAAgD;AAC9D,EAAA,OAAQ,WAA0C,iBAAiB,CAAA;AACrE;AAGO,SAAS,YAAY,MAAA,EAAgC;AAC1D,EAAC,UAAA,CAA0C,iBAAiB,CAAA,GAAI,MAAA;AAClE;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"defineCloudflareOptions.js","sources":["../../../src/defineCloudflareOptions.ts"],"sourcesContent":["import type { CloudflareOptions } from './client';\nimport type { DefaultEnv } from './types';\n\n/**\n * Define the Sentry options for a Cloudflare Worker in a dedicated module.\n *\n * This is the recommended way to configure the SDK when using the Vite plugin's\n * auto-instrumentation: place an `instrument.server.{ts,js,mjs}` file next to\n * the worker entry whose **default export** is the result of this function. The\n * plugin picks it up automatically and hands it to `withSentry`.\n *\n * Unlike Node's `Sentry.init(...)`, the options cannot be applied at module\n * load time on Cloudflare: the DSN and other settings typically come from the\n * per-request `env`, which only exists inside the handler. Pass a callback to\n * read from `env`, or a static object when no `env` access is needed — either\n * way you get full type-checking and autocomplete on {@link CloudflareOptions}.\n *\n * At runtime this is a thin pass-through; it only normalizes a static object\n * into a callback so the plugin always imports a `(env) => options` function.\n *\n * @example\n * ```ts\n * // src/instrument.server.ts\n * import { defineCloudflareOptions } from '@sentry/cloudflare';\n *\n * export default defineCloudflareOptions((env) => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }));\n * ```\n *\n * @example\n * ```ts\n * // Static options — no `env` access needed\n * export default defineCloudflareOptions({ tracesSampleRate: 1.0 });\n * ```\n */\nexport function defineCloudflareOptions<Env = DefaultEnv>(\n optionsOrCallback: CloudflareOptions | ((env: Env) => CloudflareOptions | undefined),\n): (env: Env) => CloudflareOptions | undefined {\n if (typeof optionsOrCallback === 'function') {\n return optionsOrCallback;\n }\n\n return () => optionsOrCallback;\n}\n"],"names":[],"mappings":"AAqCO,SAAS,wBACd,iBAAA,EAC6C;AAC7C,EAAA,IAAI,OAAO,sBAAsB,UAAA,EAAY;AAC3C,IAAA,OAAO,iBAAA;AAAA,EACT;AAEA,EAAA,OAAO,MAAM,iBAAA;AACf;;;;"}
1
+ {"version":3,"file":"defineCloudflareOptions.js","sources":["../../../src/defineCloudflareOptions.ts"],"sourcesContent":["import type { CloudflareOptions } from './client';\nimport type { DefaultEnv, StrictCloudflareOptions } from './types';\n\n/**\n * Define the Sentry options for a Cloudflare Worker in a dedicated module.\n *\n * This is the recommended way to configure the SDK when using the Vite plugin's\n * auto-instrumentation: place an `instrument.server.{ts,js,mjs}` file next to\n * the worker entry whose **default export** is the result of this function. The\n * plugin picks it up automatically and hands it to `withSentry`.\n *\n * Unlike Node's `Sentry.init(...)`, the options cannot be applied at module\n * load time on Cloudflare: the DSN and other settings typically come from the\n * per-request `env`, which only exists inside the handler. Pass a callback to\n * read from `env`, or a static object when no `env` access is needed — either\n * way you get full type-checking and autocomplete on {@link CloudflareOptions}.\n *\n * At runtime this is a thin pass-through; it only normalizes a static object\n * into a callback so the plugin always imports a `(env) => options` function.\n *\n * @example\n * ```ts\n * // src/instrument.server.ts\n * import { defineCloudflareOptions } from '@sentry/cloudflare';\n *\n * export default defineCloudflareOptions((env) => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }));\n * ```\n *\n * @example\n * ```ts\n * // Static options — no `env` access needed\n * export default defineCloudflareOptions({ tracesSampleRate: 1.0 });\n * ```\n */\n// Overloads rather than a union parameter: TypeScript does not infer `O` out of a union member,\n// so a union signature falls back to the default and the unknown-key check never runs. The object\n// overload stays on plain `CloudflareOptions` — a direct object literal is still excess property\n// checked, and a callback cannot match it.\nexport function defineCloudflareOptions<Env = DefaultEnv, O = unknown>(\n callback: (env: Env) => StrictCloudflareOptions<O> | undefined,\n): (env: Env) => CloudflareOptions | undefined;\nexport function defineCloudflareOptions<Env = DefaultEnv>(\n options: CloudflareOptions,\n): (env: Env) => CloudflareOptions | undefined;\nexport function defineCloudflareOptions<Env = DefaultEnv>(\n optionsOrCallback: CloudflareOptions | ((env: Env) => CloudflareOptions | undefined),\n): (env: Env) => CloudflareOptions | undefined {\n if (typeof optionsOrCallback === 'function') {\n return optionsOrCallback;\n }\n\n return () => optionsOrCallback;\n}\n"],"names":[],"mappings":"AA+CO,SAAS,wBACd,iBAAA,EAC6C;AAC7C,EAAA,IAAI,OAAO,sBAAsB,UAAA,EAAY;AAC3C,IAAA,OAAO,iBAAA;AAAA,EACT;AAEA,EAAA,OAAO,MAAM,iBAAA;AACf;;;;"}
@@ -1,10 +1,10 @@
1
- import { isObjectLike, captureException } from '@sentry/core';
1
+ import { RPC } from '@sentry/conventions/op';
2
+ import { isObjectLike } from '@sentry/core';
2
3
  import { setAsyncLocalStorageAsyncContextStrategy } from '@sentry/server-utils/no-diagnostic-channels';
3
- import { ensureInstrumented, markAsInstrumented, getInstrumented } from './instrument.js';
4
+ import { markAsInstrumented, getInstrumented } from './instrument.js';
5
+ import { instrumentDurableObjectHandlers } from './instrumentations/instrumentDurableObjectHandlers.js';
4
6
  import { instrumentEnv } from './instrumentations/worker/instrumentEnv.js';
5
7
  import { getFinalOptions } from './options.js';
6
- import { wrapRequestHandlerWithInit } from './request.js';
7
- import { init } from './sdk.js';
8
8
  import { instrumentContext } from './utils/instrumentContext.js';
9
9
  import { hasRpcMeta } from './utils/rpcMeta.js';
10
10
  import { instrumentCloudflareAgent } from './instrumentations/agents/index.js';
@@ -59,61 +59,6 @@ function resolveFrameworkManagedMethods(prototype, obj, methodsBeforeConstructio
59
59
  frameworkManagedMethodsCache.set(prototype, managed);
60
60
  return managed;
61
61
  }
62
- function instrumentDurableObjectHandlers(obj, options, context) {
63
- if (obj.fetch && typeof obj.fetch === "function") {
64
- obj.fetch = ensureInstrumented(
65
- obj.fetch.bind(obj),
66
- (original) => new Proxy(original, {
67
- apply(target, thisArg, args) {
68
- return wrapRequestHandlerWithInit(
69
- { options, request: args[0], context },
70
- () => {
71
- return Reflect.apply(target, thisArg, args);
72
- },
73
- init
74
- );
75
- }
76
- })
77
- );
78
- }
79
- if (obj.alarm && typeof obj.alarm === "function") {
80
- obj.alarm = wrapMethodWithSentry(
81
- {
82
- options,
83
- context,
84
- spanName: "alarm",
85
- spanOp: "function",
86
- startNewTrace: true,
87
- origin: "auto.faas.cloudflare.durable_object"
88
- },
89
- obj.alarm.bind(obj)
90
- );
91
- }
92
- if (obj.webSocketMessage && typeof obj.webSocketMessage === "function") {
93
- obj.webSocketMessage = wrapMethodWithSentry(
94
- { options, context, spanName: "webSocketMessage", origin: "auto.faas.cloudflare.durable_object" },
95
- obj.webSocketMessage.bind(obj)
96
- );
97
- }
98
- if (obj.webSocketClose && typeof obj.webSocketClose === "function") {
99
- obj.webSocketClose = wrapMethodWithSentry(
100
- { options, context, spanName: "webSocketClose", origin: "auto.faas.cloudflare.durable_object" },
101
- obj.webSocketClose.bind(obj)
102
- );
103
- }
104
- if (obj.webSocketError && typeof obj.webSocketError === "function") {
105
- obj.webSocketError = wrapMethodWithSentry(
106
- { options, context, spanName: "webSocketError", origin: "auto.faas.cloudflare.durable_object" },
107
- obj.webSocketError.bind(obj),
108
- (_, error) => captureException(error, {
109
- mechanism: {
110
- type: "auto.faas.cloudflare.durable_object_websocket",
111
- handled: false
112
- }
113
- })
114
- );
115
- }
116
- }
117
62
  const RESERVED_RPC_METHOD_NAMES = /* @__PURE__ */ new Set([
118
63
  "constructor",
119
64
  "fetch",
@@ -126,9 +71,6 @@ const RESERVED_RPC_METHOD_NAMES = /* @__PURE__ */ new Set([
126
71
  ]);
127
72
  const rpcInstanceStates = /* @__PURE__ */ new WeakMap();
128
73
  function finalizeWithRpcInstrumentation(obj, options, context, excludedMethods) {
129
- if (options.enableRpcTracePropagation === false) {
130
- return obj;
131
- }
132
74
  rpcInstanceStates.set(obj, { options, context });
133
75
  instrumentPrototypeRpcMethods(obj, excludedMethods);
134
76
  return obj;
@@ -178,7 +120,7 @@ function createRpcPrototypeWrapper(methodName, originalMethod) {
178
120
  options: state.options,
179
121
  context: state.context,
180
122
  spanName: methodName,
181
- spanOp: "rpc",
123
+ spanOp: RPC,
182
124
  origin: "auto.faas.cloudflare.durable_object"
183
125
  },
184
126
  originalMethod,
@@ -1 +1 @@
1
- {"version":3,"file":"durableobject.js","sources":["../../../src/durableobject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport { captureException, isObjectLike } from '@sentry/core';\nimport type { DurableObject } from 'cloudflare:workers';\nimport { setAsyncLocalStorageAsyncContextStrategy } from '@sentry/server-utils/no-diagnostic-channels';\nimport type { CloudflareOptions } from './client';\nimport { ensureInstrumented, getInstrumented, markAsInstrumented } from './instrument';\nimport { instrumentEnv } from './instrumentations/worker/instrumentEnv';\nimport { getFinalOptions } from './options';\nimport { wrapRequestHandlerWithInit } from './request';\nimport { init } from './sdk';\nimport { instrumentContext } from './utils/instrumentContext';\nimport { hasRpcMeta } from './utils/rpcMeta';\nimport { instrumentCloudflareAgent } from './instrumentations/agents';\nimport type { DefaultEnv, ResolveEnv } from './types';\nimport { type UncheckedMethod, wrapMethodWithSentry } from './wrapMethodWithSentry';\n\n/**\n * The instrumented context passed between the shared construction helpers.\n *\n * This is intentionally `any` rather than `ReturnType<typeof instrumentContext<DurableObjectState>>`.\n * A concrete `DurableObjectState` here forces `tsc` to structurally relate its `storage: SqlStorage`\n * graph against the `ExecutionContext | InstrumentedDurableObjectState` parameter of\n * `wrapMethodWithSentry`, while the RPC-branded `DurableObject` from `cloudflare:workers` is also in\n * scope. That union comparison explodes (1296×1296) and hangs the type build. The original inline\n * implementation avoided this only incidentally, because `ctx` reached it as `any` through the Proxy\n * `construct` trap. Keeping the shared context `any` preserves that behavior.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InstrumentedDurableObjectContext = any;\n\n/**\n * Constructs a Durable Object instance and instruments its built-in handler methods\n * (`fetch`, `alarm`, `webSocketMessage`, `webSocketClose`, `webSocketError`).\n *\n * This is the shared construction path used by both {@link instrumentDurableObjectWithSentry}\n * and {@link instrumentAgentWithSentry}. It intentionally does NOT apply the RPC prototype-method\n * instrumentation — callers apply that last via {@link finalizeWithRpcInstrumentation}, after any\n * additional per-instance instrumentation has been layered onto the returned object.\n *\n * @internal\n */\nexport function constructInstrumentedDurableObject<E, T extends DurableObject<E>>(\n target: new (state: DurableObjectState, env: E) => T,\n ctx: DurableObjectState,\n env: E,\n newTarget: NewableFunction,\n optionsCallback: (env: E) => CloudflareOptions,\n): {\n obj: T;\n options: CloudflareOptions;\n context: InstrumentedDurableObjectContext;\n frameworkManagedMethods: ReadonlySet<string>;\n} {\n setAsyncLocalStorageAsyncContextStrategy();\n const options = getFinalOptions(optionsCallback(env), env);\n // See InstrumentedDurableObjectContext — `ctx` is widened to `any` so the concrete\n // `DurableObjectState` type never enters the checker's relation graph in this module.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const context = instrumentContext(ctx as any);\n const instrumentedEnv = instrumentEnv(env as Record<string, unknown>, options);\n\n const prototype = (newTarget as unknown as { prototype?: object }).prototype ?? target.prototype;\n const cachedFrameworkManagedMethods = frameworkManagedMethodsCache.get(prototype);\n const methodsBeforeConstruction = cachedFrameworkManagedMethods ? undefined : resolvePrototypeMethods(prototype);\n\n // Pass `newTarget` so that subclasses of the instrumented class (e.g. the wrapper classes\n // created by wrangler's local dev tooling or `@cloudflare/vitest-pool-workers`) keep their\n // own prototype — otherwise subclass methods disappear and `instanceof` checks break.\n const obj = Reflect.construct(target, [context, instrumentedEnv], newTarget) as T;\n\n const frameworkManagedMethods = resolveFrameworkManagedMethods(\n prototype,\n obj,\n methodsBeforeConstruction,\n cachedFrameworkManagedMethods,\n );\n\n instrumentDurableObjectHandlers(obj, options, context);\n\n return { obj, options, context, frameworkManagedMethods };\n}\n\nconst frameworkManagedMethodsCache = new WeakMap<object, ReadonlySet<string>>();\n\n/**\n * Collects the methods visible from a prototype, using normal property lookup precedence.\n * Methods inherited from `Object.prototype` are excluded because they cannot be Durable Object RPC methods.\n */\nfunction resolvePrototypeMethods(prototype: object | null): Map<string, unknown> {\n const methods = new Map<string, unknown>();\n\n for (let current = prototype; current && current !== Object.prototype; current = Object.getPrototypeOf(current)) {\n for (const name of Object.getOwnPropertyNames(current)) {\n // The first occurrence wins, mirroring what a property lookup on the instance would find\n if (name === 'constructor' || methods.has(name)) {\n continue;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(current, name);\n\n if (descriptor && typeof descriptor.value === 'function') {\n methods.set(name, descriptor.value);\n }\n }\n }\n\n return methods;\n}\n\n/**\n * Finds methods that a framework replaced while constructing the first instance.\n *\n * Some frameworks register methods by function identity, so replacing one of their wrappers would\n * break dispatch. The result is cached because frameworks commonly install their wrappers only\n * once; later constructions would no longer reveal which methods they manage.\n */\nfunction resolveFrameworkManagedMethods(\n prototype: object,\n obj: object,\n methodsBeforeConstruction: Map<string, unknown> | undefined,\n cached: ReadonlySet<string> | undefined,\n): ReadonlySet<string> {\n if (cached) {\n return cached;\n }\n\n const methodsAfterConstruction = resolvePrototypeMethods(Object.getPrototypeOf(obj) as object);\n const managed = new Set<string>();\n\n for (const [name, method] of methodsAfterConstruction) {\n const before = methodsBeforeConstruction?.get(name);\n\n if (before && before !== method) {\n managed.add(name);\n }\n }\n\n frameworkManagedMethodsCache.set(prototype, managed);\n\n return managed;\n}\n\n/**\n * Instruments the built-in Durable Object handler methods on a constructed instance.\n *\n * These are the methods that are available on a Durable Object\n * ref: https://developers.cloudflare.com/durable-objects/api/base/\n * - obj.alarm\n * - obj.fetch\n * - obj.webSocketError\n * - obj.webSocketClose\n * - obj.webSocketMessage\n *\n * Any other public methods on the Durable Object instance are RPC calls.\n */\nfunction instrumentDurableObjectHandlers<E, T extends DurableObject<E>>(\n obj: T,\n options: CloudflareOptions,\n context: InstrumentedDurableObjectContext,\n): void {\n // Bind each built-in handler to this instance before wrapping.\n // See https://github.com/getsentry/sentry-javascript/issues/22328\n if (obj.fetch && typeof obj.fetch === 'function') {\n obj.fetch = ensureInstrumented(\n obj.fetch.bind(obj),\n original =>\n new Proxy(original, {\n apply(target, thisArg, args) {\n return wrapRequestHandlerWithInit(\n { options, request: args[0], context },\n () => {\n return Reflect.apply(target, thisArg, args);\n },\n init,\n );\n },\n }),\n );\n }\n\n if (obj.alarm && typeof obj.alarm === 'function') {\n // Alarms are independent invocations, so we start a new trace and link to the previous alarm\n obj.alarm = wrapMethodWithSentry(\n {\n options,\n context,\n spanName: 'alarm',\n spanOp: 'function',\n startNewTrace: true,\n origin: 'auto.faas.cloudflare.durable_object',\n },\n obj.alarm.bind(obj),\n );\n }\n\n if (obj.webSocketMessage && typeof obj.webSocketMessage === 'function') {\n obj.webSocketMessage = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketMessage', origin: 'auto.faas.cloudflare.durable_object' },\n obj.webSocketMessage.bind(obj),\n );\n }\n\n if (obj.webSocketClose && typeof obj.webSocketClose === 'function') {\n obj.webSocketClose = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketClose', origin: 'auto.faas.cloudflare.durable_object' },\n obj.webSocketClose.bind(obj),\n );\n }\n\n if (obj.webSocketError && typeof obj.webSocketError === 'function') {\n obj.webSocketError = wrapMethodWithSentry(\n { options, context, spanName: 'webSocketError', origin: 'auto.faas.cloudflare.durable_object' },\n obj.webSocketError.bind(obj),\n (_, error) =>\n captureException(error, {\n mechanism: {\n type: 'auto.faas.cloudflare.durable_object_websocket',\n handled: false,\n },\n }),\n );\n }\n}\n\ntype RpcInstanceState = {\n options: CloudflareOptions;\n context: InstrumentedDurableObjectContext;\n /** Per-instance cache of the traced method wrappers, keyed by method name. Created on first use. */\n tracedMethods?: Map<string, UncheckedMethod>;\n};\n\n/**\n * Method names the runtime never dispatches over RPC, so wrapping them buys no tracing.\n *\n * Mirrors `isReservedName` in workerd (`src/workerd/api/worker-rpc.c++`): the runtime rejects these\n * before any property lookup happens. `fetch`, `alarm` and the `webSocket*` handlers are also\n * instrumented per-instance as own properties, and `constructor` is on every prototype.\n */\nconst RESERVED_RPC_METHOD_NAMES: ReadonlySet<string> = new Set([\n 'constructor',\n 'fetch',\n 'connect',\n 'alarm',\n 'webSocketMessage',\n 'webSocketClose',\n 'webSocketError',\n 'dup',\n]);\n\n// Prototype wrappers are shared by all instances, while SDK options and traced method caches are not.\nconst rpcInstanceStates = new WeakMap<object, RpcInstanceState>();\n\n/**\n * Adds trace propagation to a constructed Durable Object's RPC methods.\n *\n * RPC methods are wrapped on the prototype because Cloudflare dispatches them with the Durable\n * Object instance as the receiver. This preserves native private-field access and keeps the methods\n * visible to Cloudflare's RPC dispatcher. Built-in handlers, Agent handlers, and methods managed by\n * another framework are left untouched.\n *\n * Call this after all per-instance instrumentation has been applied. If RPC trace propagation is\n * disabled, the object is returned unchanged.\n *\n * @param obj The constructed Durable Object instance.\n * @param options The resolved SDK options for this instance.\n * @param context The instrumented execution context for this instance.\n * @param excludedMethods Method names owned by another framework and therefore not safe to wrap.\n * @returns The same Durable Object instance, with eligible prototype methods instrumented.\n * @internal\n */\nexport function finalizeWithRpcInstrumentation<T extends object>(\n obj: T,\n options: CloudflareOptions,\n context: InstrumentedDurableObjectContext,\n excludedMethods?: ReadonlySet<string>,\n): T {\n // Skip RPC instrumentation only when explicitly opted out (enabled by default)\n if (options.enableRpcTracePropagation === false) {\n return obj;\n }\n\n rpcInstanceStates.set(obj, { options, context });\n\n instrumentPrototypeRpcMethods(obj, excludedMethods);\n\n return obj;\n}\n\n/**\n * Returns a prototype method when it is eligible for RPC instrumentation.\n */\nfunction getRpcMethodDescriptor(\n obj: object,\n prototype: object,\n methodName: string,\n excludedMethods?: ReadonlySet<string>,\n): PropertyDescriptor | undefined {\n if (\n RESERVED_RPC_METHOD_NAMES.has(methodName) ||\n Object.prototype.hasOwnProperty.call(obj, methodName) ||\n excludedMethods?.has(methodName)\n ) {\n return undefined;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(prototype, methodName);\n\n if (!descriptor || typeof descriptor.value !== 'function' || getInstrumented(descriptor.value)) {\n return undefined;\n }\n\n return descriptor;\n}\n\n/**\n * Wraps eligible methods on the instance's prototype chain once per class.\n */\nfunction instrumentPrototypeRpcMethods(obj: object, excludedMethods?: ReadonlySet<string>): void {\n let prototype: object | null = Object.getPrototypeOf(obj);\n\n while (prototype && prototype !== Object.prototype) {\n for (const methodName of Object.getOwnPropertyNames(prototype)) {\n const descriptor = getRpcMethodDescriptor(obj, prototype, methodName, excludedMethods);\n\n if (!descriptor) {\n continue;\n }\n\n const wrapped = createRpcPrototypeWrapper(methodName, descriptor.value as UncheckedMethod);\n\n try {\n Object.defineProperty(prototype, methodName, { ...descriptor, value: wrapped });\n } catch {}\n\n // Only the wrapper is marked, not the original method: `wrapMethodWithSentry` resolves\n // through the same global map and must not resolve the original to this wrapper,\n // which would recurse.\n markAsInstrumented(wrapped);\n }\n\n prototype = Object.getPrototypeOf(prototype);\n }\n}\n\n/**\n * Creates a prototype wrapper that traces RPC calls carrying Sentry metadata.\n *\n * The wrapper looks up SDK state from its receiver, allowing one prototype function to serve every\n * instance. Calls without RPC metadata or instance state use the original method directly. The\n * original function name and arity are preserved because frameworks may inspect them for dispatch.\n */\nfunction createRpcPrototypeWrapper(methodName: string, originalMethod: UncheckedMethod): UncheckedMethod {\n const wrapper = function (this: unknown, ...args: unknown[]): unknown {\n // Untraced calls are the common case — every internal call the instance makes to one of its\n // own methods lands here too — so check the arguments before touching per-instance state.\n if (!hasRpcMeta(args)) {\n return Reflect.apply(originalMethod, this, args);\n }\n\n const state = isObjectLike(this) ? rpcInstanceStates.get(this) : undefined;\n\n if (!state) {\n return Reflect.apply(originalMethod, this, args);\n }\n\n const tracedMethods = (state.tracedMethods ??= new Map());\n let traced = tracedMethods.get(methodName);\n\n if (!traced) {\n traced = wrapMethodWithSentry(\n {\n options: state.options,\n context: state.context,\n spanName: methodName,\n spanOp: 'rpc',\n origin: 'auto.faas.cloudflare.durable_object',\n },\n originalMethod,\n undefined,\n true,\n );\n tracedMethods.set(methodName, traced);\n }\n\n return Reflect.apply(traced, this, args);\n };\n\n Object.defineProperties(wrapper, {\n name: { value: originalMethod.name, configurable: true },\n length: { value: originalMethod.length, configurable: true },\n });\n\n return wrapper as UncheckedMethod;\n}\n\n/**\n * Instruments a Durable Object class to capture errors and performance data.\n *\n * Instruments the following methods by default:\n * - fetch\n * - alarm\n * - webSocketMessage\n * - webSocketClose\n * - webSocketError\n *\n * RPC methods (prototype methods) are instrumented by default. Set `enableRpcTracePropagation`\n * to `false` to opt out.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param DurableObjectClass The Durable Object class to instrument.\n * @returns The instrumented Durable Object class.\n *\n * @example\n * ```ts\n * class MyDurableObjectBase extends DurableObject {\n * constructor(ctx: DurableObjectState, env: Env) {\n * super(ctx, env);\n * }\n * }\n *\n * export const MyDurableObject = instrumentDurableObjectWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyDurableObjectBase,\n * );\n * ```\n */\nexport function instrumentDurableObjectWithSentry<\n Env = DefaultEnv,\n // oxlint-disable-next-line typescript/no-explicit-any\n T extends DurableObject<any> = DurableObject<Env>,\n // oxlint-disable-next-line typescript/no-explicit-any\n C extends new (state: DurableObjectState, env: any) => T = new (state: DurableObjectState, env: any) => T,\n>(optionsCallback: (env: ResolveEnv<C, Env>) => CloudflareOptions, DurableObjectClass: C): C {\n return new Proxy(DurableObjectClass, {\n construct(target, [ctx, env], newTarget) {\n const { obj, options, context, frameworkManagedMethods } = constructInstrumentedDurableObject(\n target,\n ctx,\n env,\n newTarget,\n optionsCallback,\n );\n\n return finalizeWithRpcInstrumentation(obj, options, context, frameworkManagedMethods);\n },\n });\n}\n\n/**\n * Instruments a Cloudflare [`agents`](https://www.npmjs.com/package/agents) Agent class with Sentry.\n *\n * An `Agent` is a Durable Object under the hood, so this applies the same instrumentation as\n * {@link instrumentDurableObjectWithSentry} (request transactions, `alarm`, WebSocket handlers, RPC\n * trace propagation, SQL spans) and additionally captures Agent-specific telemetry via\n * `instrumentCloudflareAgent`:\n *\n * - **Callable RPC spans** — a span (op `rpc`) for each `@callable()` method invoked over WebSocket.\n * - **Breadcrumbs** — for every Agent observability event (`rpc`, `state:update`, `connect`,\n * `disconnect`, `schedule:*`, `queue:*`, `workflow:*`, `email:*`, `mcp:*`, ...).\n *\n * Cloudflare Workers cannot auto-instrument, so the Agent class must be wrapped manually.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param AgentClass The Agent class to instrument.\n * @returns The instrumented Agent class.\n *\n * @example\n * ```ts\n * import { Agent, callable, routeAgentRequest } from 'agents';\n * import * as Sentry from '@sentry/cloudflare';\n *\n * class MyAgentBase extends Agent<Env> {\n * @callable()\n * async greet(name: string): Promise<string> {\n * return `Hello, ${name}!`;\n * }\n * }\n *\n * export const MyAgent = Sentry.instrumentAgentWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyAgentBase,\n * );\n * ```\n */\nexport function instrumentAgentWithSentry<\n Env = DefaultEnv,\n // oxlint-disable-next-line typescript/no-explicit-any\n T extends DurableObject<any> = DurableObject<Env>,\n // oxlint-disable-next-line typescript/no-explicit-any\n C extends new (state: DurableObjectState, env: any) => T = new (state: DurableObjectState, env: any) => T,\n>(optionsCallback: (env: ResolveEnv<C, Env>) => CloudflareOptions, AgentClass: C): C {\n return new Proxy(AgentClass, {\n construct(target, [ctx, env], newTarget) {\n const { obj, options, context, frameworkManagedMethods } = constructInstrumentedDurableObject(\n target,\n ctx,\n env,\n newTarget,\n optionsCallback,\n );\n\n instrumentCloudflareAgent(obj);\n\n // Apply RPC prototype-method instrumentation last, so the Agent-specific own-property\n // handlers we just installed are excluded from RPC method tracing. Methods the Agent\n // framework installed itself are excluded too — `instrumentCloudflareAgent` traces those by\n // wrapping the dispatch instead of the method.\n return finalizeWithRpcInstrumentation(obj, options, context, frameworkManagedMethods);\n },\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"durableobject.js","sources":["../../../src/durableobject.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport { RPC } from '@sentry/conventions/op';\nimport { isObjectLike } from '@sentry/core';\nimport type { DurableObject } from 'cloudflare:workers';\nimport { setAsyncLocalStorageAsyncContextStrategy } from '@sentry/server-utils/no-diagnostic-channels';\nimport type { CloudflareOptions } from './client';\nimport { getInstrumented, markAsInstrumented } from './instrument';\nimport { instrumentDurableObjectHandlers } from './instrumentations/instrumentDurableObjectHandlers';\nimport { instrumentEnv } from './instrumentations/worker/instrumentEnv';\nimport { getFinalOptions } from './options';\nimport { instrumentContext } from './utils/instrumentContext';\nimport { hasRpcMeta } from './utils/rpcMeta';\nimport { instrumentCloudflareAgent } from './instrumentations/agents';\nimport type { DefaultEnv, ResolveEnv, StrictCloudflareOptions } from './types';\nimport { type UncheckedMethod, wrapMethodWithSentry } from './wrapMethodWithSentry';\n\n/**\n * The instrumented context passed between the shared construction helpers.\n *\n * This is intentionally `any` rather than `ReturnType<typeof instrumentContext<DurableObjectState>>`.\n * A concrete `DurableObjectState` here forces `tsc` to structurally relate its `storage: SqlStorage`\n * graph against the `ExecutionContext | InstrumentedDurableObjectState` parameter of\n * `wrapMethodWithSentry`, while the RPC-branded `DurableObject` from `cloudflare:workers` is also in\n * scope. That union comparison explodes (1296×1296) and hangs the type build. The original inline\n * implementation avoided this only incidentally, because `ctx` reached it as `any` through the Proxy\n * `construct` trap. Keeping the shared context `any` preserves that behavior.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InstrumentedDurableObjectContext = any;\n\n/**\n * Constructs a Durable Object instance and instruments its built-in handler methods\n * (`fetch`, `alarm`, `webSocketMessage`, `webSocketClose`, `webSocketError`).\n *\n * This is the shared construction path used by both {@link instrumentDurableObjectWithSentry}\n * and {@link instrumentAgentWithSentry}. It intentionally does NOT apply the RPC prototype-method\n * instrumentation — callers apply that last via {@link finalizeWithRpcInstrumentation}, after any\n * additional per-instance instrumentation has been layered onto the returned object.\n *\n * @internal\n */\nexport function constructInstrumentedDurableObject<E, T extends DurableObject<E>>(\n target: new (state: DurableObjectState, env: E) => T,\n ctx: DurableObjectState,\n env: E,\n newTarget: NewableFunction,\n optionsCallback: (env: E) => CloudflareOptions,\n): {\n obj: T;\n options: CloudflareOptions;\n context: InstrumentedDurableObjectContext;\n frameworkManagedMethods: ReadonlySet<string>;\n} {\n setAsyncLocalStorageAsyncContextStrategy();\n const options = getFinalOptions(optionsCallback(env), env);\n // See InstrumentedDurableObjectContext — `ctx` is widened to `any` so the concrete\n // `DurableObjectState` type never enters the checker's relation graph in this module.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const context = instrumentContext(ctx as any);\n const instrumentedEnv = instrumentEnv(env as Record<string, unknown>, options);\n\n const prototype = (newTarget as unknown as { prototype?: object }).prototype ?? target.prototype;\n const cachedFrameworkManagedMethods = frameworkManagedMethodsCache.get(prototype);\n const methodsBeforeConstruction = cachedFrameworkManagedMethods ? undefined : resolvePrototypeMethods(prototype);\n\n // Pass `newTarget` so that subclasses of the instrumented class (e.g. the wrapper classes\n // created by wrangler's local dev tooling or `@cloudflare/vitest-pool-workers`) keep their\n // own prototype — otherwise subclass methods disappear and `instanceof` checks break.\n const obj = Reflect.construct(target, [context, instrumentedEnv], newTarget) as T;\n\n const frameworkManagedMethods = resolveFrameworkManagedMethods(\n prototype,\n obj,\n methodsBeforeConstruction,\n cachedFrameworkManagedMethods,\n );\n\n instrumentDurableObjectHandlers(obj, options, context);\n\n return { obj, options, context, frameworkManagedMethods };\n}\n\nconst frameworkManagedMethodsCache = new WeakMap<object, ReadonlySet<string>>();\n\n/**\n * Collects the methods visible from a prototype, using normal property lookup precedence.\n * Methods inherited from `Object.prototype` are excluded because they cannot be Durable Object RPC methods.\n */\nfunction resolvePrototypeMethods(prototype: object | null): Map<string, unknown> {\n const methods = new Map<string, unknown>();\n\n for (let current = prototype; current && current !== Object.prototype; current = Object.getPrototypeOf(current)) {\n for (const name of Object.getOwnPropertyNames(current)) {\n // The first occurrence wins, mirroring what a property lookup on the instance would find\n if (name === 'constructor' || methods.has(name)) {\n continue;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(current, name);\n\n if (descriptor && typeof descriptor.value === 'function') {\n methods.set(name, descriptor.value);\n }\n }\n }\n\n return methods;\n}\n\n/**\n * Finds methods that a framework replaced while constructing the first instance.\n *\n * Some frameworks register methods by function identity, so replacing one of their wrappers would\n * break dispatch. The result is cached because frameworks commonly install their wrappers only\n * once; later constructions would no longer reveal which methods they manage.\n */\nfunction resolveFrameworkManagedMethods(\n prototype: object,\n obj: object,\n methodsBeforeConstruction: Map<string, unknown> | undefined,\n cached: ReadonlySet<string> | undefined,\n): ReadonlySet<string> {\n if (cached) {\n return cached;\n }\n\n const methodsAfterConstruction = resolvePrototypeMethods(Object.getPrototypeOf(obj) as object);\n const managed = new Set<string>();\n\n for (const [name, method] of methodsAfterConstruction) {\n const before = methodsBeforeConstruction?.get(name);\n\n if (before && before !== method) {\n managed.add(name);\n }\n }\n\n frameworkManagedMethodsCache.set(prototype, managed);\n\n return managed;\n}\n\ntype RpcInstanceState = {\n options: CloudflareOptions;\n context: InstrumentedDurableObjectContext;\n /** Per-instance cache of the traced method wrappers, keyed by method name. Created on first use. */\n tracedMethods?: Map<string, UncheckedMethod>;\n};\n\n/**\n * Method names the runtime never dispatches over RPC, so wrapping them buys no tracing.\n *\n * Mirrors `isReservedName` in workerd (`src/workerd/api/worker-rpc.c++`): the runtime rejects these\n * before any property lookup happens. `fetch`, `alarm` and the `webSocket*` handlers are also\n * instrumented per-instance as own properties, and `constructor` is on every prototype.\n */\nconst RESERVED_RPC_METHOD_NAMES: ReadonlySet<string> = new Set([\n 'constructor',\n 'fetch',\n 'connect',\n 'alarm',\n 'webSocketMessage',\n 'webSocketClose',\n 'webSocketError',\n 'dup',\n]);\n\n// Prototype wrappers are shared by all instances, while SDK options and traced method caches are not.\nconst rpcInstanceStates = new WeakMap<object, RpcInstanceState>();\n\n/**\n * Adds trace propagation to a constructed Durable Object's RPC methods.\n *\n * RPC methods are wrapped on the prototype because Cloudflare dispatches them with the Durable\n * Object instance as the receiver. This preserves native private-field access and keeps the methods\n * visible to Cloudflare's RPC dispatcher. Built-in handlers, Agent handlers, and methods managed by\n * another framework are left untouched.\n *\n * Call this after all per-instance instrumentation has been applied.\n *\n * @param obj The constructed Durable Object instance.\n * @param options The resolved SDK options for this instance.\n * @param context The instrumented execution context for this instance.\n * @param excludedMethods Method names owned by another framework and therefore not safe to wrap.\n * @returns The same Durable Object instance, with eligible prototype methods instrumented.\n * @internal\n */\nexport function finalizeWithRpcInstrumentation<T extends object>(\n obj: T,\n options: CloudflareOptions,\n context: InstrumentedDurableObjectContext,\n excludedMethods?: ReadonlySet<string>,\n): T {\n rpcInstanceStates.set(obj, { options, context });\n\n instrumentPrototypeRpcMethods(obj, excludedMethods);\n\n return obj;\n}\n\n/**\n * Returns a prototype method when it is eligible for RPC instrumentation.\n */\nfunction getRpcMethodDescriptor(\n obj: object,\n prototype: object,\n methodName: string,\n excludedMethods?: ReadonlySet<string>,\n): PropertyDescriptor | undefined {\n if (\n RESERVED_RPC_METHOD_NAMES.has(methodName) ||\n Object.prototype.hasOwnProperty.call(obj, methodName) ||\n excludedMethods?.has(methodName)\n ) {\n return undefined;\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(prototype, methodName);\n\n if (!descriptor || typeof descriptor.value !== 'function' || getInstrumented(descriptor.value)) {\n return undefined;\n }\n\n return descriptor;\n}\n\n/**\n * Wraps eligible methods on the instance's prototype chain once per class.\n */\nfunction instrumentPrototypeRpcMethods(obj: object, excludedMethods?: ReadonlySet<string>): void {\n let prototype: object | null = Object.getPrototypeOf(obj);\n\n while (prototype && prototype !== Object.prototype) {\n for (const methodName of Object.getOwnPropertyNames(prototype)) {\n const descriptor = getRpcMethodDescriptor(obj, prototype, methodName, excludedMethods);\n\n if (!descriptor) {\n continue;\n }\n\n const wrapped = createRpcPrototypeWrapper(methodName, descriptor.value as UncheckedMethod);\n\n try {\n Object.defineProperty(prototype, methodName, { ...descriptor, value: wrapped });\n } catch {}\n\n // Only the wrapper is marked, not the original method: `wrapMethodWithSentry` resolves\n // through the same global map and must not resolve the original to this wrapper,\n // which would recurse.\n markAsInstrumented(wrapped);\n }\n\n prototype = Object.getPrototypeOf(prototype);\n }\n}\n\n/**\n * Creates a prototype wrapper that traces RPC calls carrying Sentry metadata.\n *\n * The wrapper looks up SDK state from its receiver, allowing one prototype function to serve every\n * instance. Calls without RPC metadata or instance state use the original method directly. The\n * original function name and arity are preserved because frameworks may inspect them for dispatch.\n */\nfunction createRpcPrototypeWrapper(methodName: string, originalMethod: UncheckedMethod): UncheckedMethod {\n const wrapper = function (this: unknown, ...args: unknown[]): unknown {\n // Untraced calls are the common case — every internal call the instance makes to one of its\n // own methods lands here too — so check the arguments before touching per-instance state.\n if (!hasRpcMeta(args)) {\n return Reflect.apply(originalMethod, this, args);\n }\n\n const state = isObjectLike(this) ? rpcInstanceStates.get(this) : undefined;\n\n if (!state) {\n return Reflect.apply(originalMethod, this, args);\n }\n\n const tracedMethods = (state.tracedMethods ??= new Map());\n let traced = tracedMethods.get(methodName);\n\n if (!traced) {\n traced = wrapMethodWithSentry(\n {\n options: state.options,\n context: state.context,\n spanName: methodName,\n spanOp: RPC,\n origin: 'auto.faas.cloudflare.durable_object',\n },\n originalMethod,\n undefined,\n true,\n );\n tracedMethods.set(methodName, traced);\n }\n\n return Reflect.apply(traced, this, args);\n };\n\n Object.defineProperties(wrapper, {\n name: { value: originalMethod.name, configurable: true },\n length: { value: originalMethod.length, configurable: true },\n });\n\n return wrapper as UncheckedMethod;\n}\n\n/**\n * Instruments a Durable Object class to capture errors and performance data.\n *\n * Instruments the following methods by default:\n * - fetch\n * - alarm\n * - webSocketMessage\n * - webSocketClose\n * - webSocketError\n *\n * RPC methods (prototype methods) are instrumented too, so an incoming trace continues into them.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param DurableObjectClass The Durable Object class to instrument.\n * @returns The instrumented Durable Object class.\n *\n * @example\n * ```ts\n * class MyDurableObjectBase extends DurableObject {\n * constructor(ctx: DurableObjectState, env: Env) {\n * super(ctx, env);\n * }\n * }\n *\n * export const MyDurableObject = instrumentDurableObjectWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyDurableObjectBase,\n * );\n * ```\n */\nexport function instrumentDurableObjectWithSentry<\n Env = DefaultEnv,\n // oxlint-disable-next-line typescript/no-explicit-any\n T extends DurableObject<any> = DurableObject<Env>,\n // oxlint-disable-next-line typescript/no-explicit-any\n C extends new (state: DurableObjectState, env: any) => T = new (state: DurableObjectState, env: any) => T,\n O = unknown,\n>(optionsCallback: (env: ResolveEnv<C, Env>) => StrictCloudflareOptions<O>, DurableObjectClass: C): C {\n return new Proxy(DurableObjectClass, {\n construct(target, [ctx, env], newTarget) {\n const { obj, options, context, frameworkManagedMethods } = constructInstrumentedDurableObject(\n target,\n ctx,\n env,\n newTarget,\n optionsCallback,\n );\n\n return finalizeWithRpcInstrumentation(obj, options, context, frameworkManagedMethods);\n },\n });\n}\n\n/**\n * Instruments a Cloudflare [`agents`](https://www.npmjs.com/package/agents) Agent class with Sentry.\n *\n * An `Agent` is a Durable Object under the hood, so this applies the same instrumentation as\n * {@link instrumentDurableObjectWithSentry} (request transactions, `alarm`, WebSocket handlers, RPC\n * trace propagation, SQL spans) and additionally captures Agent-specific telemetry via\n * `instrumentCloudflareAgent`:\n *\n * - **Callable RPC spans** — a span (op `rpc`) for each `@callable()` method invoked over WebSocket.\n * - **Breadcrumbs** — for every Agent observability event (`rpc`, `state:update`, `connect`,\n * `disconnect`, `schedule:*`, `queue:*`, `workflow:*`, `email:*`, `mcp:*`, ...).\n *\n * Cloudflare Workers cannot auto-instrument, so the Agent class must be wrapped manually.\n *\n * @param optionsCallback Function that returns the options for the SDK initialization.\n * @param AgentClass The Agent class to instrument.\n * @returns The instrumented Agent class.\n *\n * @example\n * ```ts\n * import { Agent, callable, routeAgentRequest } from 'agents';\n * import * as Sentry from '@sentry/cloudflare';\n *\n * class MyAgentBase extends Agent<Env> {\n * @callable()\n * async greet(name: string): Promise<string> {\n * return `Hello, ${name}!`;\n * }\n * }\n *\n * export const MyAgent = Sentry.instrumentAgentWithSentry(\n * env => ({\n * dsn: env.SENTRY_DSN,\n * tracesSampleRate: 1.0,\n * }),\n * MyAgentBase,\n * );\n * ```\n */\nexport function instrumentAgentWithSentry<\n Env = DefaultEnv,\n // oxlint-disable-next-line typescript/no-explicit-any\n T extends DurableObject<any> = DurableObject<Env>,\n // oxlint-disable-next-line typescript/no-explicit-any\n C extends new (state: DurableObjectState, env: any) => T = new (state: DurableObjectState, env: any) => T,\n O = unknown,\n>(optionsCallback: (env: ResolveEnv<C, Env>) => StrictCloudflareOptions<O>, AgentClass: C): C {\n return new Proxy(AgentClass, {\n construct(target, [ctx, env], newTarget) {\n const { obj, options, context, frameworkManagedMethods } = constructInstrumentedDurableObject(\n target,\n ctx,\n env,\n newTarget,\n optionsCallback,\n );\n\n instrumentCloudflareAgent(obj);\n\n // Apply RPC prototype-method instrumentation last, so the Agent-specific own-property\n // handlers we just installed are excluded from RPC method tracing. Methods the Agent\n // framework installed itself are excluded too — `instrumentCloudflareAgent` traces those by\n // wrapping the dispatch instead of the method.\n return finalizeWithRpcInstrumentation(obj, options, context, frameworkManagedMethods);\n },\n });\n}\n"],"names":[],"mappings":"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"}
@@ -71,10 +71,12 @@ async function flushAndDispose(client, timeout = 2e3) {
71
71
  } catch (e) {
72
72
  DEBUG_BUILD && debug.warn("Failed to flush client", e);
73
73
  } finally {
74
- try {
75
- client?.dispose();
76
- } catch (e) {
77
- DEBUG_BUILD && debug.warn("Failed to dispose client", e);
74
+ if (!client?.isCachedClient) {
75
+ try {
76
+ client?.dispose();
77
+ } catch (e) {
78
+ DEBUG_BUILD && debug.warn("Failed to dispose client", e);
79
+ }
78
80
  }
79
81
  }
80
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"flush.js","sources":["../../../src/flush.ts"],"sourcesContent":["import type { ExecutionContext } from '@cloudflare/workers-types';\nimport type { Client } from '@sentry/core';\nimport { debug, flush } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { ExecutionContextCompat } from './executionContext';\n\ntype FlushLock = {\n readonly ready: Promise<void>;\n readonly finalize: () => Promise<void>;\n};\n\ntype FlushLockRegistry = {\n readonly locks: Set<FlushLockInternal>;\n readonly originalWaitUntil: ExecutionContext['waitUntil'];\n};\n\ntype FlushLockInternal = FlushLock & {\n readonly acquire: () => void;\n readonly release: () => void;\n};\n\nconst flushLockRegistries = new WeakMap<ExecutionContext['waitUntil'], FlushLockRegistry>();\n\n/**\n * Returns the original (un-instrumented) waitUntil function for a context.\n * This should be used when calling waitUntil with flushAndDispose to avoid deadlock.\n *\n * The flush lock mechanism wraps context.waitUntil to track pending tasks.\n * If we call waitUntil(flushAndDispose(client)) through the instrumented version,\n * it creates a deadlock because:\n * 1. The instrumented waitUntil acquires the flush lock\n * 2. flushAndDispose calls client.flush() which waits for the lock to be released\n * 3. The lock won't be released until the waitUntil promise completes\n * 4. The waitUntil promise won't complete until flush() returns\n *\n * By using the original waitUntil for flush operations, we bypass this issue.\n */\nexport function getOriginalWaitUntil(context: ExecutionContextCompat): ExecutionContext['waitUntil'] {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const currentWaitUntil = context.waitUntil;\n const original = flushLockRegistries.get(currentWaitUntil)?.originalWaitUntil;\n return original ?? currentWaitUntil;\n}\n\n/**\n * Enhances the given execution context by wrapping its `waitUntil` method with a proxy\n * to monitor pending tasks, and provides a flusher function to ensure all tasks\n * have been completed before executing any subsequent logic.\n *\n * @param {ExecutionContext} context - The execution context to be enhanced. If no context is provided, the function returns undefined.\n * @return {FlushLock} Returns a flusher function if a valid context is provided, otherwise undefined.\n */\nexport function makeFlushLock(context: ExecutionContextCompat): FlushLock {\n const registry = getOrCreateFlushLockRegistry(context);\n let resolveAllDone: () => void = () => undefined;\n const allDone = new Promise<void>(res => {\n resolveAllDone = res;\n });\n let pending = 0;\n\n const lock: FlushLockInternal = {\n ready: allDone,\n acquire: () => {\n pending++;\n },\n release: () => {\n if (--pending === 0) {\n registry.locks.delete(lock);\n resolveAllDone();\n }\n },\n finalize: () => {\n if (pending === 0) {\n registry.locks.delete(lock);\n resolveAllDone();\n }\n return allDone;\n },\n };\n\n registry.locks.add(lock);\n return Object.freeze(lock);\n}\n\nfunction getOrCreateFlushLockRegistry(context: ExecutionContextCompat): FlushLockRegistry {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const waitUntil = context.waitUntil;\n const existingRegistry = flushLockRegistries.get(waitUntil);\n\n if (existingRegistry) {\n return existingRegistry;\n }\n\n const originalWaitUntil = context.waitUntil.bind(context) as typeof context.waitUntil;\n const registry: FlushLockRegistry = { locks: new Set(), originalWaitUntil };\n const instrumentedWaitUntil: typeof context.waitUntil = promise => {\n // Snapshot active locks so locks created after this call do not wait for earlier waitUntil work.\n const locks = [...registry.locks];\n\n for (const lock of locks) {\n lock.acquire();\n }\n\n return originalWaitUntil(\n promise.finally(() => {\n for (const lock of locks) {\n lock.release();\n }\n }),\n );\n };\n\n flushLockRegistries.set(instrumentedWaitUntil, registry);\n context.waitUntil = instrumentedWaitUntil;\n\n return registry;\n}\n\n/**\n * Flushes the client and then disposes of it to allow garbage collection.\n * This should be called at the end of each request to prevent memory leaks.\n *\n * This function never rejects. On Workers, a rejected promise passed to\n * `ctx.waitUntil` marks the whole invocation as `outcome: exception` even when\n * the handler itself completed successfully. Since flush/dispose is internal\n * SDK housekeeping, a failure here must not fail the user's invocation.\n *\n * @param client - The CloudflareClient instance to flush and dispose\n * @param timeout - Timeout in milliseconds for the flush operation\n * @returns A promise that resolves when flush and dispose are complete\n */\nexport async function flushAndDispose(client: Client | undefined, timeout = 2000): Promise<void> {\n try {\n if (!client) {\n await flush(timeout);\n return;\n }\n await client.flush(timeout);\n } catch (e) {\n DEBUG_BUILD && debug.warn('Failed to flush client', e);\n } finally {\n try {\n client?.dispose();\n } catch (e) {\n DEBUG_BUILD && debug.warn('Failed to dispose client', e);\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flush.js","sources":["../../../src/flush.ts"],"sourcesContent":["import type { ExecutionContext } from '@cloudflare/workers-types';\nimport type { Client } from '@sentry/core';\nimport { debug, flush } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport type { ExecutionContextCompat } from './executionContext';\n\ntype FlushLock = {\n readonly ready: Promise<void>;\n readonly finalize: () => Promise<void>;\n};\n\ntype FlushLockRegistry = {\n readonly locks: Set<FlushLockInternal>;\n readonly originalWaitUntil: ExecutionContext['waitUntil'];\n};\n\ntype FlushLockInternal = FlushLock & {\n readonly acquire: () => void;\n readonly release: () => void;\n};\n\nconst flushLockRegistries = new WeakMap<ExecutionContext['waitUntil'], FlushLockRegistry>();\n\n/**\n * Returns the original (un-instrumented) waitUntil function for a context.\n * This should be used when calling waitUntil with flushAndDispose to avoid deadlock.\n *\n * The flush lock mechanism wraps context.waitUntil to track pending tasks.\n * If we call waitUntil(flushAndDispose(client)) through the instrumented version,\n * it creates a deadlock because:\n * 1. The instrumented waitUntil acquires the flush lock\n * 2. flushAndDispose calls client.flush() which waits for the lock to be released\n * 3. The lock won't be released until the waitUntil promise completes\n * 4. The waitUntil promise won't complete until flush() returns\n *\n * By using the original waitUntil for flush operations, we bypass this issue.\n */\nexport function getOriginalWaitUntil(context: ExecutionContextCompat): ExecutionContext['waitUntil'] {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const currentWaitUntil = context.waitUntil;\n const original = flushLockRegistries.get(currentWaitUntil)?.originalWaitUntil;\n return original ?? currentWaitUntil;\n}\n\n/**\n * Enhances the given execution context by wrapping its `waitUntil` method with a proxy\n * to monitor pending tasks, and provides a flusher function to ensure all tasks\n * have been completed before executing any subsequent logic.\n *\n * @param {ExecutionContext} context - The execution context to be enhanced. If no context is provided, the function returns undefined.\n * @return {FlushLock} Returns a flusher function if a valid context is provided, otherwise undefined.\n */\nexport function makeFlushLock(context: ExecutionContextCompat): FlushLock {\n const registry = getOrCreateFlushLockRegistry(context);\n let resolveAllDone: () => void = () => undefined;\n const allDone = new Promise<void>(res => {\n resolveAllDone = res;\n });\n let pending = 0;\n\n const lock: FlushLockInternal = {\n ready: allDone,\n acquire: () => {\n pending++;\n },\n release: () => {\n if (--pending === 0) {\n registry.locks.delete(lock);\n resolveAllDone();\n }\n },\n finalize: () => {\n if (pending === 0) {\n registry.locks.delete(lock);\n resolveAllDone();\n }\n return allDone;\n },\n };\n\n registry.locks.add(lock);\n return Object.freeze(lock);\n}\n\nfunction getOrCreateFlushLockRegistry(context: ExecutionContextCompat): FlushLockRegistry {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const waitUntil = context.waitUntil;\n const existingRegistry = flushLockRegistries.get(waitUntil);\n\n if (existingRegistry) {\n return existingRegistry;\n }\n\n const originalWaitUntil = context.waitUntil.bind(context) as typeof context.waitUntil;\n const registry: FlushLockRegistry = { locks: new Set(), originalWaitUntil };\n const instrumentedWaitUntil: typeof context.waitUntil = promise => {\n // Snapshot active locks so locks created after this call do not wait for earlier waitUntil work.\n const locks = [...registry.locks];\n\n for (const lock of locks) {\n lock.acquire();\n }\n\n return originalWaitUntil(\n promise.finally(() => {\n for (const lock of locks) {\n lock.release();\n }\n }),\n );\n };\n\n flushLockRegistries.set(instrumentedWaitUntil, registry);\n context.waitUntil = instrumentedWaitUntil;\n\n return registry;\n}\n\n/**\n * Flushes the client and then disposes of it to allow garbage collection.\n * This should be called at the end of each request to prevent memory leaks.\n * Cached clients (`cacheClient`) are reused across invocations, so\n * they are flushed but not disposed.\n *\n * This function never rejects. On Workers, a rejected promise passed to\n * `ctx.waitUntil` marks the whole invocation as `outcome: exception` even when\n * the handler itself completed successfully. Since flush/dispose is internal\n * SDK housekeeping, a failure here must not fail the user's invocation.\n *\n * @param client - The CloudflareClient instance to flush and dispose\n * @param timeout - Timeout in milliseconds for the flush operation\n * @returns A promise that resolves when flush and dispose are complete\n */\nexport async function flushAndDispose(client: Client | undefined, timeout = 2000): Promise<void> {\n try {\n if (!client) {\n await flush(timeout);\n return;\n }\n await client.flush(timeout);\n } catch (e) {\n DEBUG_BUILD && debug.warn('Failed to flush client', e);\n } finally {\n // Only dispose per-invocation clients. Cached clients (`cacheClient`)\n // are reused across invocations and must not be disposed at an invocation boundary.\n if (!(client as { isCachedClient?: boolean } | undefined)?.isCachedClient) {\n try {\n client?.dispose();\n } catch (e) {\n DEBUG_BUILD && debug.warn('Failed to dispose client', e);\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,15 +1,15 @@
1
- export { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Scope, addBreadcrumb, addEventProcessor, addIntegration, bindScopeToEmitter, captureCheckIn, captureConsoleIntegration, captureEvent, captureException, captureFeedback, captureMessage, close, consoleIntegration, consoleLoggingIntegration, continueTrace, createConsolaReporter, createTransport, dedupeIntegration, eventFiltersIntegration, extraErrorDataIntegration, featureFlagsIntegration, flush, functionToStringIntegration, getActiveSpan, getClient, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, getSpanDescendants, getSpanStatusFromHttpCode, getTraceData, getTraceMetaTags, growthbookIntegration, instrumentPostgresJsSql, instrumentSupabaseClient, isEnabled, isInitialized, lastEventId, linkedErrorsIntegration, logger, metrics, moduleMetadataIntegration, requestDataIntegration, rewriteFramesIntegration, setAttribute, setAttributes, setContext, setConversationId, setCurrentClient, setExtra, setExtras, setHttpStatus, setMeasurement, setTag, setTags, setUser, spanStreamingIntegration, spanToBaggageHeader, spanToJSON, spanToStaticSpanJSON, spanToTraceHeader, startInactiveSpan, startNewTrace, startSpan, startSpanManual, supabaseIntegration, suppressTracing, trpcMiddleware, updateSpanName, withActiveSpan, withIsolationScope, withMonitor, withScope, withStaticSpan, withStreamedSpan, wrapMcpServerWithSentry, zodErrorsIntegration } from '@sentry/core';
1
+ export { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SENTRY_SEGMENT_NAME_SOURCE, Scope, addBreadcrumb, addEventProcessor, addIntegration, bindScopeToEmitter, captureCheckIn, captureConsoleIntegration, captureEvent, captureException, captureFeedback, captureMessage, close, consoleIntegration, consoleLoggingIntegration, continueTrace, createConsolaReporter, createTransport, dedupeIntegration, eventFiltersIntegration, extraErrorDataIntegration, featureFlagsIntegration, flush, functionToStringIntegration, getActiveSpan, getClient, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, getSpanDescendants, getSpanStatusFromHttpCode, getTraceData, getTraceMetaTags, growthbookIntegration, instrumentSupabaseClient, isEnabled, isInitialized, lastEventId, linkedErrorsIntegration, logger, metrics, moduleMetadataIntegration, requestDataIntegration, rewriteFramesIntegration, setAttribute, setAttributes, setContext, setConversationId, setCurrentClient, setExtra, setExtras, setHttpStatus, setMeasurement, setTag, setTags, setUser, spanStreamingIntegration, spanToBaggageHeader, spanToJSON, spanToStaticSpanJSON, spanToTraceHeader, startInactiveSpan, startNewTrace, startSpan, startSpanManual, supabaseIntegration, suppressTracing, updateSpanName, withActiveSpan, withIsolationScope, withMonitor, withScope, withStaticSpan, withStreamedSpan, zodErrorsIntegration } from '@sentry/core';
2
+ export { instrumentPostgresJsSql, trpcMiddleware, wrapMcpServerWithSentry } from '@sentry/core/server';
2
3
  export { withSentry } from './withSentry.js';
3
4
  export { defineCloudflareOptions } from './defineCloudflareOptions.js';
4
5
  export { instrumentAgentWithSentry, instrumentDurableObjectWithSentry } from './durableobject.js';
5
6
  export { sentryPagesPlugin } from './pages-plugin.js';
6
7
  export { CloudflareClient } from './client.js';
7
- export { getDefaultIntegrations } from './sdk.js';
8
+ export { _INTERNAL_wrapRequestHandler, getDefaultIntegrations } from './sdk.js';
8
9
  export { httpServerIntegration } from './integrations/httpServer.js';
9
10
  export { fetchIntegration } from './integrations/fetch.js';
10
11
  export { spotlightIntegration } from './integrations/spotlight.js';
11
- export { vercelAIIntegration } from './integrations/tracing/vercelai.js';
12
- export { createLangChainCallbackHandler, getOtlpTracesEndpoint, instrumentAnthropicAiClient, instrumentCreateReactAgent, instrumentGoogleGenAIClient, instrumentLangChainEmbeddings, instrumentOpenAiClient, instrumentStateGraph, instrumentWorkersAiClient, otlpIntegration, prismaIntegration } from '@sentry/server-utils';
12
+ export { createLangChainCallbackHandler, getOtlpTracesEndpoint, instrumentAnthropicAiClient, instrumentCreateReactAgent, instrumentGoogleGenAIClient, instrumentLangChainEmbeddings, instrumentOpenAiClient, instrumentStateGraph, instrumentWorkersAiClient, openTelemetryIntegration, prismaIntegration, vercelAIIntegration } from '@sentry/server-utils';
13
13
  export { instrumentWorkflowWithSentry } from './workflows.js';
14
14
  export { setAsyncLocalStorageAsyncContextStrategy } from '@sentry/server-utils/no-diagnostic-channels';
15
15
  //# sourceMappingURL=index.js.map