autotel 6.1.0 → 6.2.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 (411) hide show
  1. package/dist/analysis.cjs +1 -2
  2. package/dist/analysis.d.cts +1 -2
  3. package/dist/analysis.d.ts +1 -2
  4. package/dist/analysis.js +1 -2
  5. package/dist/attribute-redacting-processor-Pk7lAzWd.d.cts +1 -2
  6. package/dist/attribute-redacting-processor-Pk7lAzWd.d.ts +1 -2
  7. package/dist/attribute-redacting-processor.cjs +1 -2
  8. package/dist/attribute-redacting-processor.js +1 -2
  9. package/dist/attributes-B7wix2VG.js +1 -2
  10. package/dist/attributes-aDmJYral.cjs +1 -2
  11. package/dist/auto.cjs +2 -3
  12. package/dist/auto.js +2 -3
  13. package/dist/business-baggage.cjs +1 -2
  14. package/dist/business-baggage.d.cts +1 -2
  15. package/dist/business-baggage.d.ts +1 -2
  16. package/dist/business-baggage.js +1 -2
  17. package/dist/canonical-log-line-processor-B4WgG-VS.d.cts +1 -2
  18. package/dist/canonical-log-line-processor-CL_J7gb5.d.ts +1 -2
  19. package/dist/canonical-log-line-processor-DOjb6Kxy.cjs +1 -2
  20. package/dist/canonical-log-line-processor-mKABvGP0.js +1 -2
  21. package/dist/config.cjs +1 -2
  22. package/dist/config.d.cts +1 -2
  23. package/dist/config.d.ts +1 -2
  24. package/dist/config.js +1 -2
  25. package/dist/correlated-events-Bzh5y-UB.js +1 -2
  26. package/dist/correlated-events-kSwLo3mi.cjs +1 -2
  27. package/dist/correlation-id.cjs +1 -1
  28. package/dist/correlation-id.d.cts +1 -2
  29. package/dist/correlation-id.d.ts +1 -2
  30. package/dist/correlation-id.js +1 -1
  31. package/dist/db.cjs +1 -2
  32. package/dist/db.d.cts +1 -2
  33. package/dist/db.d.ts +1 -2
  34. package/dist/db.js +1 -2
  35. package/dist/decorators.cjs +2 -3
  36. package/dist/decorators.d.cts +1 -2
  37. package/dist/decorators.d.ts +1 -2
  38. package/dist/decorators.js +2 -3
  39. package/dist/define-event-B2z1SBe7.d.ts +1 -2
  40. package/dist/define-event-CGG048HE.d.cts +1 -2
  41. package/dist/diagnostics.cjs +1 -2
  42. package/dist/diagnostics.d.cts +1 -2
  43. package/dist/diagnostics.d.ts +1 -2
  44. package/dist/diagnostics.js +1 -2
  45. package/dist/drain-pipeline.cjs +1 -2
  46. package/dist/drain-pipeline.d.cts +1 -2
  47. package/dist/drain-pipeline.d.ts +1 -2
  48. package/dist/drain-pipeline.js +1 -2
  49. package/dist/enrichers.cjs +1 -2
  50. package/dist/enrichers.d.cts +1 -2
  51. package/dist/enrichers.d.ts +1 -2
  52. package/dist/enrichers.js +1 -2
  53. package/dist/event-subscriber-CWh8sTGh.d.cts +1 -2
  54. package/dist/event-subscriber-CWh8sTGh.d.ts +1 -2
  55. package/dist/event-testing-CA2mIx1E.d.ts +1 -2
  56. package/dist/event-testing-D0qWfqAy.d.cts +1 -2
  57. package/dist/event-testing.cjs +1 -2
  58. package/dist/event-testing.js +1 -2
  59. package/dist/event.cjs +1 -1
  60. package/dist/event.d.cts +1 -2
  61. package/dist/event.d.ts +1 -2
  62. package/dist/event.js +1 -1
  63. package/dist/exporters.d.cts +1 -2
  64. package/dist/exporters.d.ts +1 -2
  65. package/dist/filtering-span-processor-BpDagWNa.d.cts +1 -2
  66. package/dist/filtering-span-processor-BpDagWNa.d.ts +1 -2
  67. package/dist/filtering-span-processor.cjs +1 -2
  68. package/dist/filtering-span-processor.js +1 -2
  69. package/dist/{functional-DcLBuCPz.cjs → functional-D545J0Ba.cjs} +2 -3
  70. package/dist/{functional-BnDUxnSl.js → functional-DYAZiYxr.js} +2 -3
  71. package/dist/functional.cjs +1 -1
  72. package/dist/functional.d.cts +1 -2
  73. package/dist/functional.d.ts +1 -2
  74. package/dist/functional.js +1 -1
  75. package/dist/http.cjs +2 -3
  76. package/dist/http.d.cts +1 -2
  77. package/dist/http.d.ts +1 -2
  78. package/dist/http.js +2 -3
  79. package/dist/index-BPcxVucm.d.cts +1 -2
  80. package/dist/index-DolOVX6F.d.ts +1 -2
  81. package/dist/index.cjs +3 -4
  82. package/dist/index.d.cts +2 -3
  83. package/dist/index.d.ts +2 -3
  84. package/dist/index.js +3 -4
  85. package/dist/{init-D6n2diBy.d.ts → init-BHp-kqLJ.d.ts} +12 -4
  86. package/dist/{init-XzXzrarP.d.cts → init-BoIYyB6Q.d.cts} +12 -4
  87. package/dist/{init-C3RApHKJ.cjs → init-CzNFWUd8.cjs} +38 -5
  88. package/dist/{init-R-gSEXkJ.js → init-DDkh2brw.js} +38 -5
  89. package/dist/instrumentation.cjs +2 -3
  90. package/dist/instrumentation.d.cts +1 -2
  91. package/dist/instrumentation.d.ts +1 -2
  92. package/dist/instrumentation.js +2 -3
  93. package/dist/logger-CN4xpzMd.d.cts +1 -2
  94. package/dist/logger-CN4xpzMd.d.ts +1 -2
  95. package/dist/logger-D3Ej3DII.js +1 -2
  96. package/dist/logger-thMPLpOG.cjs +1 -2
  97. package/dist/messaging-adapters.cjs +1 -2
  98. package/dist/messaging-adapters.d.cts +1 -2
  99. package/dist/messaging-adapters.d.ts +1 -2
  100. package/dist/messaging-adapters.js +1 -2
  101. package/dist/messaging-testing.cjs +1 -2
  102. package/dist/messaging-testing.d.cts +1 -2
  103. package/dist/messaging-testing.d.ts +1 -2
  104. package/dist/messaging-testing.js +1 -2
  105. package/dist/messaging.cjs +2 -3
  106. package/dist/messaging.d.cts +1 -2
  107. package/dist/messaging.d.ts +1 -2
  108. package/dist/messaging.js +2 -3
  109. package/dist/metric-helpers.cjs +1 -2
  110. package/dist/metric-helpers.d.cts +1 -2
  111. package/dist/metric-helpers.d.ts +1 -2
  112. package/dist/metric-helpers.js +1 -2
  113. package/dist/metric-testing-CWm6UhaR.d.ts +1 -2
  114. package/dist/metric-testing-CpvP3ZIa.d.cts +1 -2
  115. package/dist/metric-testing.cjs +1 -2
  116. package/dist/metric-testing.js +1 -2
  117. package/dist/metric.cjs +1 -2
  118. package/dist/metric.d.cts +1 -2
  119. package/dist/metric.d.ts +1 -2
  120. package/dist/metric.js +1 -2
  121. package/dist/node-require-PFqDihze.cjs +1 -2
  122. package/dist/node-require-vROmTeJ8.js +1 -2
  123. package/dist/parse-error.cjs +1 -2
  124. package/dist/parse-error.d.cts +1 -2
  125. package/dist/parse-error.d.ts +1 -2
  126. package/dist/parse-error.js +1 -2
  127. package/dist/pretty-console-exporter-CMzlrRNg.cjs +1 -2
  128. package/dist/pretty-console-exporter-DqKl_q9z.js +1 -2
  129. package/dist/register.cjs +1 -2
  130. package/dist/register.js +1 -2
  131. package/dist/registry-DVSmWg6Y.js +1 -2
  132. package/dist/registry-DYgvb62e.cjs +1 -2
  133. package/dist/sampling-BR9fkSwx.d.cts +1 -2
  134. package/dist/sampling-CP3e7-Yr.d.ts +1 -2
  135. package/dist/sampling.cjs +1 -2
  136. package/dist/sampling.js +1 -2
  137. package/dist/security-schema.cjs +1 -2
  138. package/dist/security-schema.d.cts +1 -2
  139. package/dist/security-schema.d.ts +1 -2
  140. package/dist/security-schema.js +1 -2
  141. package/dist/semantic-conventions-FhSxv-bK.d.cts +1 -2
  142. package/dist/semantic-conventions-FhSxv-bK.d.ts +1 -2
  143. package/dist/semantic-conventions.cjs +1 -2
  144. package/dist/semantic-conventions.js +1 -2
  145. package/dist/semantic-helpers.cjs +2 -3
  146. package/dist/semantic-helpers.d.cts +1 -2
  147. package/dist/semantic-helpers.d.ts +1 -2
  148. package/dist/semantic-helpers.js +2 -3
  149. package/dist/slo.cjs +1 -2
  150. package/dist/slo.d.cts +1 -2
  151. package/dist/slo.d.ts +1 -2
  152. package/dist/slo.js +1 -2
  153. package/dist/span-name-normalizer-CN1-8C76.d.cts +1 -2
  154. package/dist/span-name-normalizer-CN1-8C76.d.ts +1 -2
  155. package/dist/span-name-normalizer.cjs +1 -2
  156. package/dist/span-name-normalizer.js +1 -2
  157. package/dist/stable-hash-CS9BxvVQ.cjs +1 -2
  158. package/dist/stable-hash-ChFBIhNt.js +1 -2
  159. package/dist/structured-error-9--cxBay.js +1 -2
  160. package/dist/structured-error-CHg7DoIQ.cjs +1 -2
  161. package/dist/tail-sampling-processor.cjs +1 -2
  162. package/dist/tail-sampling-processor.d.cts +1 -2
  163. package/dist/tail-sampling-processor.d.ts +1 -2
  164. package/dist/tail-sampling-processor.js +1 -2
  165. package/dist/test-span-collector.cjs +1 -2
  166. package/dist/test-span-collector.d.cts +1 -2
  167. package/dist/test-span-collector.d.ts +1 -2
  168. package/dist/test-span-collector.js +1 -2
  169. package/dist/testing.cjs +1 -2
  170. package/dist/testing.d.cts +1 -2
  171. package/dist/testing.d.ts +1 -2
  172. package/dist/testing.js +1 -2
  173. package/dist/trace-context-IuyoPyNq.d.cts +1 -2
  174. package/dist/trace-context-IuyoPyNq.d.ts +1 -2
  175. package/dist/trace-factory-validation-BjVAinz6.js +1 -2
  176. package/dist/trace-factory-validation-Dc8epn87.cjs +1 -2
  177. package/dist/trace-helpers.cjs +1 -2
  178. package/dist/trace-helpers.d.cts +1 -2
  179. package/dist/trace-helpers.d.ts +1 -2
  180. package/dist/trace-helpers.js +1 -2
  181. package/dist/tracer-provider.cjs +1 -2
  182. package/dist/tracer-provider.d.cts +1 -2
  183. package/dist/tracer-provider.d.ts +1 -2
  184. package/dist/tracer-provider.js +1 -2
  185. package/dist/validate.cjs +1 -2
  186. package/dist/validate.d.cts +1 -2
  187. package/dist/validate.d.ts +1 -2
  188. package/dist/validate.js +1 -2
  189. package/dist/validation-attributes.cjs +1 -2
  190. package/dist/validation-attributes.d.cts +1 -2
  191. package/dist/validation-attributes.d.ts +1 -2
  192. package/dist/validation-attributes.js +1 -2
  193. package/dist/webhook.cjs +2 -3
  194. package/dist/webhook.d.cts +1 -2
  195. package/dist/webhook.d.ts +1 -2
  196. package/dist/webhook.js +2 -3
  197. package/dist/workflow-distributed.cjs +2 -3
  198. package/dist/workflow-distributed.d.cts +1 -2
  199. package/dist/workflow-distributed.d.ts +1 -2
  200. package/dist/workflow-distributed.js +2 -3
  201. package/dist/workflow.cjs +2 -3
  202. package/dist/workflow.d.cts +1 -2
  203. package/dist/workflow.d.ts +1 -2
  204. package/dist/workflow.js +2 -3
  205. package/dist/yaml-config.cjs +1 -2
  206. package/dist/yaml-config.d.cts +4 -5
  207. package/dist/yaml-config.d.ts +4 -5
  208. package/dist/yaml-config.js +1 -2
  209. package/package.json +47 -32
  210. package/dist/analysis.cjs.map +0 -1
  211. package/dist/analysis.d.cts.map +0 -1
  212. package/dist/analysis.d.ts.map +0 -1
  213. package/dist/analysis.js.map +0 -1
  214. package/dist/attribute-redacting-processor-Pk7lAzWd.d.cts.map +0 -1
  215. package/dist/attribute-redacting-processor-Pk7lAzWd.d.ts.map +0 -1
  216. package/dist/attribute-redacting-processor.cjs.map +0 -1
  217. package/dist/attribute-redacting-processor.js.map +0 -1
  218. package/dist/attributes-B7wix2VG.js.map +0 -1
  219. package/dist/attributes-aDmJYral.cjs.map +0 -1
  220. package/dist/auto.cjs.map +0 -1
  221. package/dist/auto.js.map +0 -1
  222. package/dist/business-baggage.cjs.map +0 -1
  223. package/dist/business-baggage.d.cts.map +0 -1
  224. package/dist/business-baggage.d.ts.map +0 -1
  225. package/dist/business-baggage.js.map +0 -1
  226. package/dist/canonical-log-line-processor-B4WgG-VS.d.cts.map +0 -1
  227. package/dist/canonical-log-line-processor-CL_J7gb5.d.ts.map +0 -1
  228. package/dist/canonical-log-line-processor-DOjb6Kxy.cjs.map +0 -1
  229. package/dist/canonical-log-line-processor-mKABvGP0.js.map +0 -1
  230. package/dist/config.cjs.map +0 -1
  231. package/dist/config.d.cts.map +0 -1
  232. package/dist/config.d.ts.map +0 -1
  233. package/dist/config.js.map +0 -1
  234. package/dist/correlated-events-Bzh5y-UB.js.map +0 -1
  235. package/dist/correlated-events-kSwLo3mi.cjs.map +0 -1
  236. package/dist/correlation-id.d.cts.map +0 -1
  237. package/dist/correlation-id.d.ts.map +0 -1
  238. package/dist/db.cjs.map +0 -1
  239. package/dist/db.d.cts.map +0 -1
  240. package/dist/db.d.ts.map +0 -1
  241. package/dist/db.js.map +0 -1
  242. package/dist/decorators.cjs.map +0 -1
  243. package/dist/decorators.d.cts.map +0 -1
  244. package/dist/decorators.d.ts.map +0 -1
  245. package/dist/decorators.js.map +0 -1
  246. package/dist/define-event-B2z1SBe7.d.ts.map +0 -1
  247. package/dist/define-event-CGG048HE.d.cts.map +0 -1
  248. package/dist/diagnostics.cjs.map +0 -1
  249. package/dist/diagnostics.d.cts.map +0 -1
  250. package/dist/diagnostics.d.ts.map +0 -1
  251. package/dist/diagnostics.js.map +0 -1
  252. package/dist/drain-pipeline.cjs.map +0 -1
  253. package/dist/drain-pipeline.d.cts.map +0 -1
  254. package/dist/drain-pipeline.d.ts.map +0 -1
  255. package/dist/drain-pipeline.js.map +0 -1
  256. package/dist/enrichers.cjs.map +0 -1
  257. package/dist/enrichers.d.cts.map +0 -1
  258. package/dist/enrichers.d.ts.map +0 -1
  259. package/dist/enrichers.js.map +0 -1
  260. package/dist/event-subscriber-CWh8sTGh.d.cts.map +0 -1
  261. package/dist/event-subscriber-CWh8sTGh.d.ts.map +0 -1
  262. package/dist/event-testing-CA2mIx1E.d.ts.map +0 -1
  263. package/dist/event-testing-D0qWfqAy.d.cts.map +0 -1
  264. package/dist/event-testing.cjs.map +0 -1
  265. package/dist/event-testing.js.map +0 -1
  266. package/dist/event.d.cts.map +0 -1
  267. package/dist/event.d.ts.map +0 -1
  268. package/dist/exporters.d.cts.map +0 -1
  269. package/dist/exporters.d.ts.map +0 -1
  270. package/dist/filtering-span-processor-BpDagWNa.d.cts.map +0 -1
  271. package/dist/filtering-span-processor-BpDagWNa.d.ts.map +0 -1
  272. package/dist/filtering-span-processor.cjs.map +0 -1
  273. package/dist/filtering-span-processor.js.map +0 -1
  274. package/dist/functional-BnDUxnSl.js.map +0 -1
  275. package/dist/functional-DcLBuCPz.cjs.map +0 -1
  276. package/dist/functional.d.cts.map +0 -1
  277. package/dist/functional.d.ts.map +0 -1
  278. package/dist/http.cjs.map +0 -1
  279. package/dist/http.d.cts.map +0 -1
  280. package/dist/http.d.ts.map +0 -1
  281. package/dist/http.js.map +0 -1
  282. package/dist/index-BPcxVucm.d.cts.map +0 -1
  283. package/dist/index-DolOVX6F.d.ts.map +0 -1
  284. package/dist/index.cjs.map +0 -1
  285. package/dist/index.d.cts.map +0 -1
  286. package/dist/index.d.ts.map +0 -1
  287. package/dist/index.js.map +0 -1
  288. package/dist/init-C3RApHKJ.cjs.map +0 -1
  289. package/dist/init-D6n2diBy.d.ts.map +0 -1
  290. package/dist/init-R-gSEXkJ.js.map +0 -1
  291. package/dist/init-XzXzrarP.d.cts.map +0 -1
  292. package/dist/instrumentation.cjs.map +0 -1
  293. package/dist/instrumentation.d.cts.map +0 -1
  294. package/dist/instrumentation.d.ts.map +0 -1
  295. package/dist/instrumentation.js.map +0 -1
  296. package/dist/logger-CN4xpzMd.d.cts.map +0 -1
  297. package/dist/logger-CN4xpzMd.d.ts.map +0 -1
  298. package/dist/logger-D3Ej3DII.js.map +0 -1
  299. package/dist/logger-thMPLpOG.cjs.map +0 -1
  300. package/dist/messaging-adapters.cjs.map +0 -1
  301. package/dist/messaging-adapters.d.cts.map +0 -1
  302. package/dist/messaging-adapters.d.ts.map +0 -1
  303. package/dist/messaging-adapters.js.map +0 -1
  304. package/dist/messaging-testing.cjs.map +0 -1
  305. package/dist/messaging-testing.d.cts.map +0 -1
  306. package/dist/messaging-testing.d.ts.map +0 -1
  307. package/dist/messaging-testing.js.map +0 -1
  308. package/dist/messaging.cjs.map +0 -1
  309. package/dist/messaging.d.cts.map +0 -1
  310. package/dist/messaging.d.ts.map +0 -1
  311. package/dist/messaging.js.map +0 -1
  312. package/dist/metric-helpers.cjs.map +0 -1
  313. package/dist/metric-helpers.d.cts.map +0 -1
  314. package/dist/metric-helpers.d.ts.map +0 -1
  315. package/dist/metric-helpers.js.map +0 -1
  316. package/dist/metric-testing-CWm6UhaR.d.ts.map +0 -1
  317. package/dist/metric-testing-CpvP3ZIa.d.cts.map +0 -1
  318. package/dist/metric-testing.cjs.map +0 -1
  319. package/dist/metric-testing.js.map +0 -1
  320. package/dist/metric.cjs.map +0 -1
  321. package/dist/metric.d.cts.map +0 -1
  322. package/dist/metric.d.ts.map +0 -1
  323. package/dist/metric.js.map +0 -1
  324. package/dist/node-require-PFqDihze.cjs.map +0 -1
  325. package/dist/node-require-vROmTeJ8.js.map +0 -1
  326. package/dist/parse-error.cjs.map +0 -1
  327. package/dist/parse-error.d.cts.map +0 -1
  328. package/dist/parse-error.d.ts.map +0 -1
  329. package/dist/parse-error.js.map +0 -1
  330. package/dist/pretty-console-exporter-CMzlrRNg.cjs.map +0 -1
  331. package/dist/pretty-console-exporter-DqKl_q9z.js.map +0 -1
  332. package/dist/register.cjs.map +0 -1
  333. package/dist/register.js.map +0 -1
  334. package/dist/registry-DVSmWg6Y.js.map +0 -1
  335. package/dist/registry-DYgvb62e.cjs.map +0 -1
  336. package/dist/sampling-BR9fkSwx.d.cts.map +0 -1
  337. package/dist/sampling-CP3e7-Yr.d.ts.map +0 -1
  338. package/dist/sampling.cjs.map +0 -1
  339. package/dist/sampling.js.map +0 -1
  340. package/dist/security-schema.cjs.map +0 -1
  341. package/dist/security-schema.d.cts.map +0 -1
  342. package/dist/security-schema.d.ts.map +0 -1
  343. package/dist/security-schema.js.map +0 -1
  344. package/dist/semantic-conventions-FhSxv-bK.d.cts.map +0 -1
  345. package/dist/semantic-conventions-FhSxv-bK.d.ts.map +0 -1
  346. package/dist/semantic-conventions.cjs.map +0 -1
  347. package/dist/semantic-conventions.js.map +0 -1
  348. package/dist/semantic-helpers.cjs.map +0 -1
  349. package/dist/semantic-helpers.d.cts.map +0 -1
  350. package/dist/semantic-helpers.d.ts.map +0 -1
  351. package/dist/semantic-helpers.js.map +0 -1
  352. package/dist/slo.cjs.map +0 -1
  353. package/dist/slo.d.cts.map +0 -1
  354. package/dist/slo.d.ts.map +0 -1
  355. package/dist/slo.js.map +0 -1
  356. package/dist/span-name-normalizer-CN1-8C76.d.cts.map +0 -1
  357. package/dist/span-name-normalizer-CN1-8C76.d.ts.map +0 -1
  358. package/dist/span-name-normalizer.cjs.map +0 -1
  359. package/dist/span-name-normalizer.js.map +0 -1
  360. package/dist/stable-hash-CS9BxvVQ.cjs.map +0 -1
  361. package/dist/stable-hash-ChFBIhNt.js.map +0 -1
  362. package/dist/structured-error-9--cxBay.js.map +0 -1
  363. package/dist/structured-error-CHg7DoIQ.cjs.map +0 -1
  364. package/dist/tail-sampling-processor.cjs.map +0 -1
  365. package/dist/tail-sampling-processor.d.cts.map +0 -1
  366. package/dist/tail-sampling-processor.d.ts.map +0 -1
  367. package/dist/tail-sampling-processor.js.map +0 -1
  368. package/dist/test-span-collector.cjs.map +0 -1
  369. package/dist/test-span-collector.d.cts.map +0 -1
  370. package/dist/test-span-collector.d.ts.map +0 -1
  371. package/dist/test-span-collector.js.map +0 -1
  372. package/dist/testing.cjs.map +0 -1
  373. package/dist/testing.d.cts.map +0 -1
  374. package/dist/testing.d.ts.map +0 -1
  375. package/dist/testing.js.map +0 -1
  376. package/dist/trace-context-IuyoPyNq.d.cts.map +0 -1
  377. package/dist/trace-context-IuyoPyNq.d.ts.map +0 -1
  378. package/dist/trace-factory-validation-BjVAinz6.js.map +0 -1
  379. package/dist/trace-factory-validation-Dc8epn87.cjs.map +0 -1
  380. package/dist/trace-helpers.cjs.map +0 -1
  381. package/dist/trace-helpers.d.cts.map +0 -1
  382. package/dist/trace-helpers.d.ts.map +0 -1
  383. package/dist/trace-helpers.js.map +0 -1
  384. package/dist/tracer-provider.cjs.map +0 -1
  385. package/dist/tracer-provider.d.cts.map +0 -1
  386. package/dist/tracer-provider.d.ts.map +0 -1
  387. package/dist/tracer-provider.js.map +0 -1
  388. package/dist/validate.cjs.map +0 -1
  389. package/dist/validate.d.cts.map +0 -1
  390. package/dist/validate.d.ts.map +0 -1
  391. package/dist/validate.js.map +0 -1
  392. package/dist/validation-attributes.cjs.map +0 -1
  393. package/dist/validation-attributes.d.cts.map +0 -1
  394. package/dist/validation-attributes.d.ts.map +0 -1
  395. package/dist/validation-attributes.js.map +0 -1
  396. package/dist/webhook.cjs.map +0 -1
  397. package/dist/webhook.d.cts.map +0 -1
  398. package/dist/webhook.d.ts.map +0 -1
  399. package/dist/webhook.js.map +0 -1
  400. package/dist/workflow-distributed.cjs.map +0 -1
  401. package/dist/workflow-distributed.d.cts.map +0 -1
  402. package/dist/workflow-distributed.d.ts.map +0 -1
  403. package/dist/workflow-distributed.js.map +0 -1
  404. package/dist/workflow.cjs.map +0 -1
  405. package/dist/workflow.d.cts.map +0 -1
  406. package/dist/workflow.d.ts.map +0 -1
  407. package/dist/workflow.js.map +0 -1
  408. package/dist/yaml-config.cjs.map +0 -1
  409. package/dist/yaml-config.d.cts.map +0 -1
  410. package/dist/yaml-config.d.ts.map +0 -1
  411. package/dist/yaml-config.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"node-require-PFqDihze.cjs","names":["nodeModule"],"sources":["../src/node-require.ts"],"sourcesContent":["/**\n * Cross-format require() helper for CJS and ESM compatibility\n *\n * Provides a synchronous `require()` function that works in both:\n * - CJS builds: Uses native `require`\n * - ESM builds: Uses `createRequire(import.meta.url)`\n *\n * This allows optional peer dependencies and dynamic module loading\n * to work synchronously in both module formats.\n */\n\n// Namespace import, not `import { createRequire }`. A static *named* import of a\n// Node builtin breaks browser bundlers: tools like Vite rewrite `node:module`\n// to a stub (`__vite-browser-external`) that exports nothing, and Rollup hard-\n// errors on the unresolved named binding (\"createRequire is not exported by\n// __vite-browser-external\") — failing the consumer's build even though this\n// code never runs in the browser. A namespace import has no named binding to\n// resolve, so it bundles cleanly; `.createRequire` is read lazily below and is\n// only ever touched in a real Node runtime.\nimport * as nodeModule from 'node:module';\n\n// `__filename` is provided by CJS and by esbuild's CJS output wrapper, but\n// is undefined under pure ESM. `import.meta.url` is provided by ESM. Pick\n// whichever is available so the helper works in:\n// - native CJS (autotel's published `.cjs`)\n// - native ESM (autotel's published `.js`)\n// - ESM-bundled-into-CJS by a downstream consumer (e.g. CDK's\n// `aws-lambda-nodejs` → esbuild with `format: cjs`). esbuild rewrites\n// `import.meta` to `{}` in this case, so `createRequire(import.meta.url)`\n// alone collapses to `createRequire(undefined)` and crashes at load.\n// `typeof __filename` does NOT throw when the identifier is undeclared, so\n// the ESM build evaluates the conditional safely.\ndeclare const __filename: string | undefined;\n\n// Build the Node `require` lazily on first use. Calling `createRequire`\n// eagerly at module load crashes in runtimes where neither `__filename` nor\n// `import.meta.url` resolves to a path — e.g. Cloudflare Workers / workerd,\n// where the bundle has no module path and `createRequire(undefined)` throws\n// synchronously at import. Deferring the call keeps merely importing this\n// module (and therefore anything that re-exports it, such as `track`)\n// side-effect-free; Node/CJS/ESM still get a real `require` on first call.\nlet cachedRequire: NodeRequire | undefined;\n\nfunction getNodeRequire(): NodeRequire {\n if (cachedRequire) return cachedRequire;\n const base = typeof __filename === 'string' ? __filename : import.meta.url;\n if (!base) {\n // No module path in this runtime. Surface as a missing-module error so\n // optional lookups via `safeRequire()` degrade gracefully to `undefined`.\n throw Object.assign(\n new Error('node require() is unavailable in this runtime'),\n { code: 'MODULE_NOT_FOUND' },\n );\n }\n cachedRequire = nodeModule.createRequire(base);\n return cachedRequire;\n}\n\n/**\n * Synchronously require a module (works in both CJS and ESM)\n *\n * @param id - Module ID to require\n * @returns The required module\n * @throws Error if module cannot be loaded\n *\n * @example\n * ```typescript\n * import { safeRequire } from './node-require';\n *\n * const traceloop = safeRequire('@traceloop/node-server-sdk');\n * if (traceloop) {\n * traceloop.initialize({ ... });\n * }\n * ```\n */\nexport function safeRequire<T = unknown>(id: string): T | undefined {\n try {\n return getNodeRequire()(id) as T;\n } catch (error) {\n if (error && (error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n // Optional dependency missing – return undefined\n return undefined;\n }\n // Any other error is a real bug: rethrow\n throw error;\n }\n}\n\n/**\n * Synchronously require a module (throws if not found)\n *\n * Use this when the module is required (not optional).\n *\n * @param id - Module ID to require\n * @returns The required module\n * @throws Error if module cannot be loaded\n *\n * @example\n * ```typescript\n * import { requireModule } from './node-require';\n *\n * const fs = requireModule<typeof import('node:fs')>('node:fs');\n * const content = fs.readFileSync('file.txt', 'utf8');\n * ```\n */\nexport function requireModule<T = unknown>(id: string): T {\n return getNodeRequire()(id) as T;\n}\n\n/**\n * Direct access to the nodeRequire function (for advanced use cases).\n *\n * Lazily resolves the underlying Node `require` on first call, so importing\n * this binding never triggers `createRequire` in runtimes that lack a module\n * path (e.g. Cloudflare Workers).\n *\n * Only the call signature and `resolve` (including `resolve.paths`) are\n * forwarded. The live, mutable members of a real `require` — `.cache`,\n * `.main`, `.extensions` — are intentionally NOT exposed: a lazy wrapper\n * can't mirror that shared state without resolving eagerly, which would\n * reintroduce the workerd crash. Use `nodeModule.createRequire` directly if\n * you need them.\n */\nconst nodeRequire = ((id: string) => getNodeRequire()(id)) as NodeRequire;\nconst lazyResolve = ((id: string, options?: { paths?: string[] }) =>\n getNodeRequire().resolve(id, options)) as NodeRequire['resolve'];\nlazyResolve.paths = (request: string) =>\n getNodeRequire().resolve.paths(request);\nnodeRequire.resolve = lazyResolve;\n\nexport { nodeRequire };\n"],"mappings":";;;;;;;;;;;;;;;AAyCA,IAAI;AAEJ,SAAS,iBAA8B;CACrC,IAAI,eAAe,OAAO;CAC1B,MAAM,OAAO,OAAO,eAAe,WAAW;CAC9C,IAAI,CAAC,MAGH,MAAM,OAAO,uBACX,IAAI,MAAM,+CAA+C,GACzD,EAAE,MAAM,mBAAmB,CAC7B;CAEF,gBAAgBA,YAAW,cAAc,IAAI;CAC7C,OAAO;AACT;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,YAAyB,IAA2B;CAClE,IAAI;EACF,OAAO,eAAe,CAAC,CAAC,EAAE;CAC5B,SAAS,OAAO;EACd,IAAI,SAAU,MAAgC,SAAS,oBAErD;EAGF,MAAM;CACR;AACF;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,cAA2B,IAAe;CACxD,OAAO,eAAe,CAAC,CAAC,EAAE;AAC5B;;;;;;;;;;;;;;;AAgBA,MAAM,gBAAgB,OAAe,eAAe,CAAC,CAAC,EAAE;AACxD,MAAM,gBAAgB,IAAY,YAChC,eAAe,CAAC,CAAC,QAAQ,IAAI,OAAO;AACtC,YAAY,SAAS,YACnB,eAAe,CAAC,CAAC,QAAQ,MAAM,OAAO;AACxC,YAAY,UAAU"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"node-require-vROmTeJ8.js","names":[],"sources":["../src/node-require.ts"],"sourcesContent":["/**\n * Cross-format require() helper for CJS and ESM compatibility\n *\n * Provides a synchronous `require()` function that works in both:\n * - CJS builds: Uses native `require`\n * - ESM builds: Uses `createRequire(import.meta.url)`\n *\n * This allows optional peer dependencies and dynamic module loading\n * to work synchronously in both module formats.\n */\n\n// Namespace import, not `import { createRequire }`. A static *named* import of a\n// Node builtin breaks browser bundlers: tools like Vite rewrite `node:module`\n// to a stub (`__vite-browser-external`) that exports nothing, and Rollup hard-\n// errors on the unresolved named binding (\"createRequire is not exported by\n// __vite-browser-external\") — failing the consumer's build even though this\n// code never runs in the browser. A namespace import has no named binding to\n// resolve, so it bundles cleanly; `.createRequire` is read lazily below and is\n// only ever touched in a real Node runtime.\nimport * as nodeModule from 'node:module';\n\n// `__filename` is provided by CJS and by esbuild's CJS output wrapper, but\n// is undefined under pure ESM. `import.meta.url` is provided by ESM. Pick\n// whichever is available so the helper works in:\n// - native CJS (autotel's published `.cjs`)\n// - native ESM (autotel's published `.js`)\n// - ESM-bundled-into-CJS by a downstream consumer (e.g. CDK's\n// `aws-lambda-nodejs` → esbuild with `format: cjs`). esbuild rewrites\n// `import.meta` to `{}` in this case, so `createRequire(import.meta.url)`\n// alone collapses to `createRequire(undefined)` and crashes at load.\n// `typeof __filename` does NOT throw when the identifier is undeclared, so\n// the ESM build evaluates the conditional safely.\ndeclare const __filename: string | undefined;\n\n// Build the Node `require` lazily on first use. Calling `createRequire`\n// eagerly at module load crashes in runtimes where neither `__filename` nor\n// `import.meta.url` resolves to a path — e.g. Cloudflare Workers / workerd,\n// where the bundle has no module path and `createRequire(undefined)` throws\n// synchronously at import. Deferring the call keeps merely importing this\n// module (and therefore anything that re-exports it, such as `track`)\n// side-effect-free; Node/CJS/ESM still get a real `require` on first call.\nlet cachedRequire: NodeRequire | undefined;\n\nfunction getNodeRequire(): NodeRequire {\n if (cachedRequire) return cachedRequire;\n const base = typeof __filename === 'string' ? __filename : import.meta.url;\n if (!base) {\n // No module path in this runtime. Surface as a missing-module error so\n // optional lookups via `safeRequire()` degrade gracefully to `undefined`.\n throw Object.assign(\n new Error('node require() is unavailable in this runtime'),\n { code: 'MODULE_NOT_FOUND' },\n );\n }\n cachedRequire = nodeModule.createRequire(base);\n return cachedRequire;\n}\n\n/**\n * Synchronously require a module (works in both CJS and ESM)\n *\n * @param id - Module ID to require\n * @returns The required module\n * @throws Error if module cannot be loaded\n *\n * @example\n * ```typescript\n * import { safeRequire } from './node-require';\n *\n * const traceloop = safeRequire('@traceloop/node-server-sdk');\n * if (traceloop) {\n * traceloop.initialize({ ... });\n * }\n * ```\n */\nexport function safeRequire<T = unknown>(id: string): T | undefined {\n try {\n return getNodeRequire()(id) as T;\n } catch (error) {\n if (error && (error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n // Optional dependency missing – return undefined\n return undefined;\n }\n // Any other error is a real bug: rethrow\n throw error;\n }\n}\n\n/**\n * Synchronously require a module (throws if not found)\n *\n * Use this when the module is required (not optional).\n *\n * @param id - Module ID to require\n * @returns The required module\n * @throws Error if module cannot be loaded\n *\n * @example\n * ```typescript\n * import { requireModule } from './node-require';\n *\n * const fs = requireModule<typeof import('node:fs')>('node:fs');\n * const content = fs.readFileSync('file.txt', 'utf8');\n * ```\n */\nexport function requireModule<T = unknown>(id: string): T {\n return getNodeRequire()(id) as T;\n}\n\n/**\n * Direct access to the nodeRequire function (for advanced use cases).\n *\n * Lazily resolves the underlying Node `require` on first call, so importing\n * this binding never triggers `createRequire` in runtimes that lack a module\n * path (e.g. Cloudflare Workers).\n *\n * Only the call signature and `resolve` (including `resolve.paths`) are\n * forwarded. The live, mutable members of a real `require` — `.cache`,\n * `.main`, `.extensions` — are intentionally NOT exposed: a lazy wrapper\n * can't mirror that shared state without resolving eagerly, which would\n * reintroduce the workerd crash. Use `nodeModule.createRequire` directly if\n * you need them.\n */\nconst nodeRequire = ((id: string) => getNodeRequire()(id)) as NodeRequire;\nconst lazyResolve = ((id: string, options?: { paths?: string[] }) =>\n getNodeRequire().resolve(id, options)) as NodeRequire['resolve'];\nlazyResolve.paths = (request: string) =>\n getNodeRequire().resolve.paths(request);\nnodeRequire.resolve = lazyResolve;\n\nexport { nodeRequire };\n"],"mappings":";;;;;;;;;;;;;AAyCA,IAAI;AAEJ,SAAS,iBAA8B;CACrC,IAAI,eAAe,OAAO;CAC1B,MAAM,OAAO,OAAO,eAAe,WAAW,aAAa,OAAO,KAAK;CACvE,IAAI,CAAC,MAGH,MAAM,OAAO,uBACX,IAAI,MAAM,+CAA+C,GACzD,EAAE,MAAM,mBAAmB,CAC7B;CAEF,gBAAgB,WAAW,cAAc,IAAI;CAC7C,OAAO;AACT;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,YAAyB,IAA2B;CAClE,IAAI;EACF,OAAO,eAAe,CAAC,CAAC,EAAE;CAC5B,SAAS,OAAO;EACd,IAAI,SAAU,MAAgC,SAAS,oBAErD;EAGF,MAAM;CACR;AACF;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,cAA2B,IAAe;CACxD,OAAO,eAAe,CAAC,CAAC,EAAE;AAC5B;;;;;;;;;;;;;;;AAgBA,MAAM,gBAAgB,OAAe,eAAe,CAAC,CAAC,EAAE;AACxD,MAAM,gBAAgB,IAAY,YAChC,eAAe,CAAC,CAAC,QAAQ,IAAI,OAAO;AACtC,YAAY,SAAS,YACnB,eAAe,CAAC,CAAC,QAAQ,MAAM,OAAO;AACxC,YAAY,UAAU"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse-error.cjs","names":[],"sources":["../src/parse-error.ts"],"sourcesContent":["import type { StructuredError } from './structured-error';\n\nexport interface ParsedError {\n message: string;\n status: number;\n why?: string;\n fix?: string;\n link?: string;\n code?: string | number;\n details?: Record<string, unknown>;\n raw: unknown;\n}\n\ntype ErrorLike = {\n message?: unknown;\n status?: unknown;\n statusCode?: unknown;\n data?: unknown;\n code?: unknown;\n why?: unknown;\n fix?: unknown;\n link?: unknown;\n details?: unknown;\n};\n\nfunction toStatus(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string') {\n const n = Number(value);\n if (Number.isFinite(n)) return n;\n }\n return undefined;\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction pickCode(value: unknown): string | number | undefined {\n if (typeof value === 'string' || typeof value === 'number') return value;\n return undefined;\n}\n\nfunction pickDetails(value: unknown): Record<string, unknown> | undefined {\n if (value && typeof value === 'object' && value.constructor === Object) {\n return value as Record<string, unknown>;\n }\n return undefined;\n}\n\nexport function parseError(error: unknown): ParsedError {\n if (error instanceof Error) {\n const structured = error as StructuredError;\n return {\n message: error.message || 'An error occurred',\n status: toStatus(structured.status) ?? 500,\n why: pickString(structured.why),\n fix: pickString(structured.fix),\n link: pickString(structured.link),\n code: pickCode(structured.code),\n details: pickDetails(structured.details),\n raw: error,\n };\n }\n\n if (error && typeof error === 'object') {\n const err = error as ErrorLike;\n const data =\n err.data && typeof err.data === 'object'\n ? (err.data as Record<string, unknown>)\n : undefined;\n const nested =\n data?.data && typeof data.data === 'object'\n ? (data.data as Record<string, unknown>)\n : undefined;\n const payload = nested ?? data;\n\n const message =\n pickString(data?.statusText) ||\n pickString(data?.statusMessage) ||\n pickString(data?.message) ||\n pickString(payload?.statusText) ||\n pickString(payload?.statusMessage) ||\n pickString(payload?.message) ||\n pickString(err.message) ||\n 'An error occurred';\n\n const status =\n toStatus(payload?.status) ||\n toStatus(payload?.statusCode) ||\n toStatus(err.status) ||\n toStatus(err.statusCode) ||\n 500;\n\n return {\n message,\n status,\n why: pickString(payload?.why) || pickString(err.why),\n fix: pickString(payload?.fix) || pickString(err.fix),\n link: pickString(payload?.link) || pickString(err.link),\n code: pickCode(payload?.code) || pickCode(err.code),\n details: pickDetails(payload?.details) || pickDetails(err.details),\n raw: error,\n };\n }\n\n return {\n message: String(error),\n status: 500,\n raw: error,\n };\n}\n"],"mappings":";;;AAyBA,SAAS,SAAS,OAAoC;CACpD,IAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG,OAAO;CAChE,IAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,IAAI,OAAO,KAAK;EACtB,IAAI,OAAO,SAAS,CAAC,GAAG,OAAO;CACjC;AAEF;AAEA,SAAS,WAAW,OAAoC;CACtD,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAEA,SAAS,SAAS,OAA6C;CAC7D,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU,OAAO;AAErE;AAEA,SAAS,YAAY,OAAqD;CACxE,IAAI,SAAS,OAAO,UAAU,YAAY,MAAM,gBAAgB,QAC9D,OAAO;AAGX;AAEA,SAAgB,WAAW,OAA6B;CACtD,IAAI,iBAAiB,OAAO;EAC1B,MAAM,aAAa;EACnB,OAAO;GACL,SAAS,MAAM,WAAW;GAC1B,QAAQ,SAAS,WAAW,MAAM,KAAK;GACvC,KAAK,WAAW,WAAW,GAAG;GAC9B,KAAK,WAAW,WAAW,GAAG;GAC9B,MAAM,WAAW,WAAW,IAAI;GAChC,MAAM,SAAS,WAAW,IAAI;GAC9B,SAAS,YAAY,WAAW,OAAO;GACvC,KAAK;EACP;CACF;CAEA,IAAI,SAAS,OAAO,UAAU,UAAU;EACtC,MAAM,MAAM;EACZ,MAAM,OACJ,IAAI,QAAQ,OAAO,IAAI,SAAS,WAC3B,IAAI,OACL;EAKN,MAAM,WAHJ,MAAM,QAAQ,OAAO,KAAK,SAAS,WAC9B,KAAK,OACN,WACoB;EAmB1B,OAAO;GACL,SAjBA,WAAW,MAAM,UAAU,KAC3B,WAAW,MAAM,aAAa,KAC9B,WAAW,MAAM,OAAO,KACxB,WAAW,SAAS,UAAU,KAC9B,WAAW,SAAS,aAAa,KACjC,WAAW,SAAS,OAAO,KAC3B,WAAW,IAAI,OAAO,KACtB;GAWA,QARA,SAAS,SAAS,MAAM,KACxB,SAAS,SAAS,UAAU,KAC5B,SAAS,IAAI,MAAM,KACnB,SAAS,IAAI,UAAU,KACvB;GAKA,KAAK,WAAW,SAAS,GAAG,KAAK,WAAW,IAAI,GAAG;GACnD,KAAK,WAAW,SAAS,GAAG,KAAK,WAAW,IAAI,GAAG;GACnD,MAAM,WAAW,SAAS,IAAI,KAAK,WAAW,IAAI,IAAI;GACtD,MAAM,SAAS,SAAS,IAAI,KAAK,SAAS,IAAI,IAAI;GAClD,SAAS,YAAY,SAAS,OAAO,KAAK,YAAY,IAAI,OAAO;GACjE,KAAK;EACP;CACF;CAEA,OAAO;EACL,SAAS,OAAO,KAAK;EACrB,QAAQ;EACR,KAAK;CACP;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse-error.d.cts","names":[],"sources":["../src/parse-error.ts"],"mappings":";UAEiB;EACf;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;;iBAwCc,WAAW,iBAAiB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse-error.d.ts","names":[],"sources":["../src/parse-error.ts"],"mappings":";UAEiB;EACf;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;;iBAwCc,WAAW,iBAAiB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse-error.js","names":[],"sources":["../src/parse-error.ts"],"sourcesContent":["import type { StructuredError } from './structured-error';\n\nexport interface ParsedError {\n message: string;\n status: number;\n why?: string;\n fix?: string;\n link?: string;\n code?: string | number;\n details?: Record<string, unknown>;\n raw: unknown;\n}\n\ntype ErrorLike = {\n message?: unknown;\n status?: unknown;\n statusCode?: unknown;\n data?: unknown;\n code?: unknown;\n why?: unknown;\n fix?: unknown;\n link?: unknown;\n details?: unknown;\n};\n\nfunction toStatus(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string') {\n const n = Number(value);\n if (Number.isFinite(n)) return n;\n }\n return undefined;\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction pickCode(value: unknown): string | number | undefined {\n if (typeof value === 'string' || typeof value === 'number') return value;\n return undefined;\n}\n\nfunction pickDetails(value: unknown): Record<string, unknown> | undefined {\n if (value && typeof value === 'object' && value.constructor === Object) {\n return value as Record<string, unknown>;\n }\n return undefined;\n}\n\nexport function parseError(error: unknown): ParsedError {\n if (error instanceof Error) {\n const structured = error as StructuredError;\n return {\n message: error.message || 'An error occurred',\n status: toStatus(structured.status) ?? 500,\n why: pickString(structured.why),\n fix: pickString(structured.fix),\n link: pickString(structured.link),\n code: pickCode(structured.code),\n details: pickDetails(structured.details),\n raw: error,\n };\n }\n\n if (error && typeof error === 'object') {\n const err = error as ErrorLike;\n const data =\n err.data && typeof err.data === 'object'\n ? (err.data as Record<string, unknown>)\n : undefined;\n const nested =\n data?.data && typeof data.data === 'object'\n ? (data.data as Record<string, unknown>)\n : undefined;\n const payload = nested ?? data;\n\n const message =\n pickString(data?.statusText) ||\n pickString(data?.statusMessage) ||\n pickString(data?.message) ||\n pickString(payload?.statusText) ||\n pickString(payload?.statusMessage) ||\n pickString(payload?.message) ||\n pickString(err.message) ||\n 'An error occurred';\n\n const status =\n toStatus(payload?.status) ||\n toStatus(payload?.statusCode) ||\n toStatus(err.status) ||\n toStatus(err.statusCode) ||\n 500;\n\n return {\n message,\n status,\n why: pickString(payload?.why) || pickString(err.why),\n fix: pickString(payload?.fix) || pickString(err.fix),\n link: pickString(payload?.link) || pickString(err.link),\n code: pickCode(payload?.code) || pickCode(err.code),\n details: pickDetails(payload?.details) || pickDetails(err.details),\n raw: error,\n };\n }\n\n return {\n message: String(error),\n status: 500,\n raw: error,\n };\n}\n"],"mappings":";AAyBA,SAAS,SAAS,OAAoC;CACpD,IAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG,OAAO;CAChE,IAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,IAAI,OAAO,KAAK;EACtB,IAAI,OAAO,SAAS,CAAC,GAAG,OAAO;CACjC;AAEF;AAEA,SAAS,WAAW,OAAoC;CACtD,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAEA,SAAS,SAAS,OAA6C;CAC7D,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU,OAAO;AAErE;AAEA,SAAS,YAAY,OAAqD;CACxE,IAAI,SAAS,OAAO,UAAU,YAAY,MAAM,gBAAgB,QAC9D,OAAO;AAGX;AAEA,SAAgB,WAAW,OAA6B;CACtD,IAAI,iBAAiB,OAAO;EAC1B,MAAM,aAAa;EACnB,OAAO;GACL,SAAS,MAAM,WAAW;GAC1B,QAAQ,SAAS,WAAW,MAAM,KAAK;GACvC,KAAK,WAAW,WAAW,GAAG;GAC9B,KAAK,WAAW,WAAW,GAAG;GAC9B,MAAM,WAAW,WAAW,IAAI;GAChC,MAAM,SAAS,WAAW,IAAI;GAC9B,SAAS,YAAY,WAAW,OAAO;GACvC,KAAK;EACP;CACF;CAEA,IAAI,SAAS,OAAO,UAAU,UAAU;EACtC,MAAM,MAAM;EACZ,MAAM,OACJ,IAAI,QAAQ,OAAO,IAAI,SAAS,WAC3B,IAAI,OACL;EAKN,MAAM,WAHJ,MAAM,QAAQ,OAAO,KAAK,SAAS,WAC9B,KAAK,OACN,WACoB;EAmB1B,OAAO;GACL,SAjBA,WAAW,MAAM,UAAU,KAC3B,WAAW,MAAM,aAAa,KAC9B,WAAW,MAAM,OAAO,KACxB,WAAW,SAAS,UAAU,KAC9B,WAAW,SAAS,aAAa,KACjC,WAAW,SAAS,OAAO,KAC3B,WAAW,IAAI,OAAO,KACtB;GAWA,QARA,SAAS,SAAS,MAAM,KACxB,SAAS,SAAS,UAAU,KAC5B,SAAS,IAAI,MAAM,KACnB,SAAS,IAAI,UAAU,KACvB;GAKA,KAAK,WAAW,SAAS,GAAG,KAAK,WAAW,IAAI,GAAG;GACnD,KAAK,WAAW,SAAS,GAAG,KAAK,WAAW,IAAI,GAAG;GACnD,MAAM,WAAW,SAAS,IAAI,KAAK,WAAW,IAAI,IAAI;GACtD,MAAM,SAAS,SAAS,IAAI,KAAK,SAAS,IAAI,IAAI;GAClD,SAAS,YAAY,SAAS,OAAO,KAAK,YAAY,IAAI,OAAO;GACjE,KAAK;EACP;CACF;CAEA,OAAO;EACL,SAAS,OAAO,KAAK;EACrB,QAAQ;EACR,KAAK;CACP;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pretty-console-exporter-CMzlrRNg.cjs","names":["SpanStatusCode"],"sources":["../src/pretty-console-exporter.ts"],"sourcesContent":["/**\n * Pretty Console Exporter\n *\n * A developer-friendly span exporter that displays colorized, hierarchical\n * trace output in the terminal. Zero external dependencies - uses ANSI escape codes.\n *\n * @example Basic usage\n * ```typescript\n * init({\n * service: 'my-app',\n * debug: 'pretty' // Uses PrettyConsoleExporter\n * })\n * ```\n *\n * @example Explicit usage with options\n * ```typescript\n * import { PrettyConsoleExporter } from 'autotel/exporters'\n *\n * init({\n * service: 'my-app',\n * spanExporters: [new PrettyConsoleExporter({\n * colors: true,\n * showAttributes: true,\n * hideAttributes: ['http.user_agent']\n * })]\n * })\n * ```\n */\n\nimport type { SpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base';\nimport { SpanStatusCode } from '@opentelemetry/api';\n\n/**\n * Export result code constants (avoid importing @opentelemetry/core)\n */\nconst ExportResultCode = {\n SUCCESS: 0,\n FAILED: 1,\n} as const;\n\n/**\n * Export result type for SpanExporter callback\n */\ninterface ExportResult {\n code: number;\n error?: Error;\n}\n\n/**\n * ANSI escape codes for terminal colors (zero dependencies)\n */\nconst ANSI = {\n reset: '\\u001B[0m',\n bold: '\\u001B[1m',\n dim: '\\u001B[2m',\n green: '\\u001B[32m',\n red: '\\u001B[31m',\n yellow: '\\u001B[33m',\n blue: '\\u001B[34m',\n cyan: '\\u001B[36m',\n gray: '\\u001B[90m',\n} as const;\n\ntype AnsiColor = keyof typeof ANSI;\n\n/**\n * Configuration options for PrettyConsoleExporter\n */\nexport interface PrettyConsoleExporterOptions {\n /**\n * Enable ANSI colors in output\n * @default auto-detect TTY\n */\n colors?: boolean;\n\n /**\n * Show span attributes in output\n * @default true\n */\n showAttributes?: boolean;\n\n /**\n * Maximum length for attribute values before truncation\n * @default 50\n */\n maxValueLength?: number;\n\n /**\n * Show instrumentation scope name (e.g., [http], [pg])\n * @default true\n */\n showScope?: boolean;\n\n /**\n * Attribute keys to always hide from output\n * @default []\n */\n hideAttributes?: string[];\n\n /**\n * Show trace ID for each root span\n * @default false\n */\n showTraceId?: boolean;\n}\n\n/**\n * Internal node structure for building span trees\n */\ninterface SpanNode {\n span: ReadableSpan;\n children: SpanNode[];\n}\n\n/**\n * Pretty Console Exporter - colorized, hierarchical span output for development\n *\n * Features:\n * - Colorized status indicators (✓ green, ✗ red)\n * - Duration with color coding (fast=green, medium=yellow, slow=red)\n * - Hierarchical tree view showing parent-child relationships\n * - Attribute display with truncation\n * - Error message highlighting\n */\nexport class PrettyConsoleExporter implements SpanExporter {\n private readonly options: Required<PrettyConsoleExporterOptions>;\n\n constructor(options: PrettyConsoleExporterOptions = {}) {\n this.options = {\n colors: options.colors ?? process.stdout?.isTTY ?? false,\n showAttributes: options.showAttributes ?? true,\n maxValueLength: options.maxValueLength ?? 50,\n showScope: options.showScope ?? true,\n hideAttributes: options.hideAttributes ?? [],\n showTraceId: options.showTraceId ?? false,\n };\n }\n\n /**\n * Export spans with pretty formatting\n */\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void,\n ): void {\n if (spans.length === 0) {\n resultCallback({ code: ExportResultCode.SUCCESS });\n return;\n }\n\n try {\n // Group spans by trace ID\n const traceGroups = this.groupByTrace(spans);\n\n // Print each trace group\n for (const [traceId, traceSpans] of traceGroups) {\n this.printTrace(traceId, traceSpans);\n }\n\n resultCallback({ code: ExportResultCode.SUCCESS });\n } catch {\n // Fail-open: don't crash the app if formatting fails\n resultCallback({ code: ExportResultCode.SUCCESS });\n }\n }\n\n /**\n * Group spans by their trace ID\n */\n private groupByTrace(spans: ReadableSpan[]): Map<string, ReadableSpan[]> {\n const groups = new Map<string, ReadableSpan[]>();\n\n for (const span of spans) {\n const traceId = span.spanContext().traceId;\n const group = groups.get(traceId) ?? [];\n group.push(span);\n groups.set(traceId, group);\n }\n\n return groups;\n }\n\n /**\n * Print a single trace with all its spans as a tree\n */\n private printTrace(traceId: string, spans: ReadableSpan[]): void {\n // Sort by start time\n const sorted = [...spans].toSorted((a, b) => {\n const aTime = hrTimeToMs(a.startTime);\n const bTime = hrTimeToMs(b.startTime);\n return aTime - bTime;\n });\n\n // Build tree structure\n const tree = this.buildSpanTree(sorted);\n\n // Print trace ID header if enabled\n if (this.options.showTraceId && tree.length > 0) {\n console.log(this.color(`trace: ${traceId}`, 'gray'));\n }\n\n // Print each root span and its children\n for (const node of tree) {\n this.printNode(node, 0, false);\n }\n\n // Add blank line between traces\n console.log('');\n }\n\n /**\n * Build a tree structure from flat spans using parent-child relationships\n */\n private buildSpanTree(spans: ReadableSpan[]): SpanNode[] {\n const spanMap = new Map<string, SpanNode>();\n const roots: SpanNode[] = [];\n\n // Create nodes for all spans\n for (const span of spans) {\n const spanId = span.spanContext().spanId;\n spanMap.set(spanId, { span, children: [] });\n }\n\n // Build parent-child relationships\n for (const span of spans) {\n const spanId = span.spanContext().spanId;\n const parentId = span.parentSpanContext?.spanId;\n const node = spanMap.get(spanId)!;\n\n if (parentId && spanMap.has(parentId)) {\n // Has parent in this batch - add as child\n spanMap.get(parentId)!.children.push(node);\n } else {\n // No parent or parent not in batch - treat as root\n roots.push(node);\n }\n }\n\n return roots;\n }\n\n /**\n * Print a span node with indentation and tree characters\n */\n private printNode(node: SpanNode, depth: number, isLast: boolean): void {\n const { span } = node;\n\n // Build tree prefix\n const prefix =\n depth === 0 ? '' : ' '.repeat(depth - 1) + (isLast ? '└─ ' : '├─ ');\n\n // Status indicator\n const isError = span.status.code === SpanStatusCode.ERROR;\n const statusChar = isError ? '✗' : '✓';\n const statusColor: AnsiColor = isError ? 'red' : 'green';\n\n // Duration formatting\n const durationMs = hrTimeToMs(span.duration);\n const durationStr = formatDuration(durationMs);\n const durationColor = getDurationColor(durationMs);\n\n // Scope name (instrumentation library)\n const scopeName = this.options.showScope\n ? this.color(` [${this.getScopeName(span)}]`, 'gray')\n : '';\n\n // Build the main line\n const line = [\n prefix,\n this.color(statusChar, statusColor),\n ' ',\n span.name.padEnd(Math.max(35 - prefix.length, 10)),\n this.color(durationStr.padStart(8), durationColor),\n scopeName,\n ].join('');\n\n console.log(line);\n\n // Print attributes on next line (indented)\n if (this.options.showAttributes) {\n const attrs = this.formatAttributes(span);\n if (attrs) {\n const attrIndent = ' '.repeat(depth) + ' ';\n console.log(this.color(`${attrIndent}${attrs}`, 'dim'));\n }\n }\n\n // Print error message if present\n if (isError && span.status.message) {\n const errorIndent = ' '.repeat(depth) + ' ';\n console.log(\n this.color(`${errorIndent}Error: ${span.status.message}`, 'red'),\n );\n }\n\n // Print children\n const childCount = node.children.length;\n let index = 0;\n for (const child of node.children) {\n this.printNode(child, depth + 1, index === childCount - 1);\n index++;\n }\n }\n\n /**\n * Get short scope name from instrumentation scope\n */\n private getScopeName(span: ReadableSpan): string {\n const name = span.instrumentationScope?.name ?? 'unknown';\n // Extract short name from @opentelemetry/instrumentation-xxx format\n const match = name.match(/@opentelemetry\\/instrumentation-(.+)/);\n if (match?.[1]) return match[1];\n // Fall back to last part of name or full name\n const lastPart = name.split('/').at(-1);\n return lastPart ?? name;\n }\n\n /**\n * Format span attributes as a comma-separated string\n */\n private formatAttributes(span: ReadableSpan): string {\n const attrs = span.attributes;\n if (!attrs || Object.keys(attrs).length === 0) {\n return '';\n }\n\n const pairs: string[] = [];\n for (const [key, value] of Object.entries(attrs)) {\n // Skip hidden attributes\n if (this.options.hideAttributes.includes(key)) continue;\n\n // Skip undefined/null values\n if (value === undefined || value === null) continue;\n\n // Format value\n const strValue = this.truncate(\n Array.isArray(value) ? `[${value.join(', ')}]` : String(value),\n this.options.maxValueLength,\n );\n pairs.push(`${key}=${strValue}`);\n }\n\n return pairs.join(', ');\n }\n\n /**\n * Truncate string to max length with ellipsis\n */\n private truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 3) + '...';\n }\n\n /**\n * Apply ANSI color if colors are enabled\n */\n private color(text: string, color: AnsiColor): string {\n if (!this.options.colors) return text;\n return `${ANSI[color]}${text}${ANSI.reset}`;\n }\n\n /**\n * Shutdown (no-op for console exporter)\n */\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Force flush (no-op for console exporter)\n */\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n}\n\n/**\n * Convert HrTime [seconds, nanoseconds] to milliseconds\n */\nfunction hrTimeToMs(hrTime: [number, number]): number {\n const [seconds, nanos] = hrTime;\n return seconds * 1000 + nanos / 1_000_000;\n}\n\n/**\n * Format duration with appropriate units\n */\nfunction formatDuration(ms: number): string {\n if (ms < 1) {\n // Sub-millisecond: show as microseconds\n return `${(ms * 1000).toFixed(0)}µs`;\n }\n if (ms < 1000) {\n // Under 1 second: show as milliseconds\n return `${ms.toFixed(0)}ms`;\n }\n // 1 second or more: show as seconds\n return `${(ms / 1000).toFixed(2)}s`;\n}\n\n/**\n * Get color based on duration (fast=green, medium=yellow, slow=red)\n */\nfunction getDurationColor(ms: number): AnsiColor {\n if (ms < 100) return 'green';\n if (ms < 500) return 'yellow';\n return 'red';\n}\n\n/**\n * Export utility functions for testing\n */\nexport { formatDuration, getDurationColor, hrTimeToMs };\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pretty-console-exporter-DqKl_q9z.js","names":[],"sources":["../src/pretty-console-exporter.ts"],"sourcesContent":["/**\n * Pretty Console Exporter\n *\n * A developer-friendly span exporter that displays colorized, hierarchical\n * trace output in the terminal. Zero external dependencies - uses ANSI escape codes.\n *\n * @example Basic usage\n * ```typescript\n * init({\n * service: 'my-app',\n * debug: 'pretty' // Uses PrettyConsoleExporter\n * })\n * ```\n *\n * @example Explicit usage with options\n * ```typescript\n * import { PrettyConsoleExporter } from 'autotel/exporters'\n *\n * init({\n * service: 'my-app',\n * spanExporters: [new PrettyConsoleExporter({\n * colors: true,\n * showAttributes: true,\n * hideAttributes: ['http.user_agent']\n * })]\n * })\n * ```\n */\n\nimport type { SpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base';\nimport { SpanStatusCode } from '@opentelemetry/api';\n\n/**\n * Export result code constants (avoid importing @opentelemetry/core)\n */\nconst ExportResultCode = {\n SUCCESS: 0,\n FAILED: 1,\n} as const;\n\n/**\n * Export result type for SpanExporter callback\n */\ninterface ExportResult {\n code: number;\n error?: Error;\n}\n\n/**\n * ANSI escape codes for terminal colors (zero dependencies)\n */\nconst ANSI = {\n reset: '\\u001B[0m',\n bold: '\\u001B[1m',\n dim: '\\u001B[2m',\n green: '\\u001B[32m',\n red: '\\u001B[31m',\n yellow: '\\u001B[33m',\n blue: '\\u001B[34m',\n cyan: '\\u001B[36m',\n gray: '\\u001B[90m',\n} as const;\n\ntype AnsiColor = keyof typeof ANSI;\n\n/**\n * Configuration options for PrettyConsoleExporter\n */\nexport interface PrettyConsoleExporterOptions {\n /**\n * Enable ANSI colors in output\n * @default auto-detect TTY\n */\n colors?: boolean;\n\n /**\n * Show span attributes in output\n * @default true\n */\n showAttributes?: boolean;\n\n /**\n * Maximum length for attribute values before truncation\n * @default 50\n */\n maxValueLength?: number;\n\n /**\n * Show instrumentation scope name (e.g., [http], [pg])\n * @default true\n */\n showScope?: boolean;\n\n /**\n * Attribute keys to always hide from output\n * @default []\n */\n hideAttributes?: string[];\n\n /**\n * Show trace ID for each root span\n * @default false\n */\n showTraceId?: boolean;\n}\n\n/**\n * Internal node structure for building span trees\n */\ninterface SpanNode {\n span: ReadableSpan;\n children: SpanNode[];\n}\n\n/**\n * Pretty Console Exporter - colorized, hierarchical span output for development\n *\n * Features:\n * - Colorized status indicators (✓ green, ✗ red)\n * - Duration with color coding (fast=green, medium=yellow, slow=red)\n * - Hierarchical tree view showing parent-child relationships\n * - Attribute display with truncation\n * - Error message highlighting\n */\nexport class PrettyConsoleExporter implements SpanExporter {\n private readonly options: Required<PrettyConsoleExporterOptions>;\n\n constructor(options: PrettyConsoleExporterOptions = {}) {\n this.options = {\n colors: options.colors ?? process.stdout?.isTTY ?? false,\n showAttributes: options.showAttributes ?? true,\n maxValueLength: options.maxValueLength ?? 50,\n showScope: options.showScope ?? true,\n hideAttributes: options.hideAttributes ?? [],\n showTraceId: options.showTraceId ?? false,\n };\n }\n\n /**\n * Export spans with pretty formatting\n */\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void,\n ): void {\n if (spans.length === 0) {\n resultCallback({ code: ExportResultCode.SUCCESS });\n return;\n }\n\n try {\n // Group spans by trace ID\n const traceGroups = this.groupByTrace(spans);\n\n // Print each trace group\n for (const [traceId, traceSpans] of traceGroups) {\n this.printTrace(traceId, traceSpans);\n }\n\n resultCallback({ code: ExportResultCode.SUCCESS });\n } catch {\n // Fail-open: don't crash the app if formatting fails\n resultCallback({ code: ExportResultCode.SUCCESS });\n }\n }\n\n /**\n * Group spans by their trace ID\n */\n private groupByTrace(spans: ReadableSpan[]): Map<string, ReadableSpan[]> {\n const groups = new Map<string, ReadableSpan[]>();\n\n for (const span of spans) {\n const traceId = span.spanContext().traceId;\n const group = groups.get(traceId) ?? [];\n group.push(span);\n groups.set(traceId, group);\n }\n\n return groups;\n }\n\n /**\n * Print a single trace with all its spans as a tree\n */\n private printTrace(traceId: string, spans: ReadableSpan[]): void {\n // Sort by start time\n const sorted = [...spans].toSorted((a, b) => {\n const aTime = hrTimeToMs(a.startTime);\n const bTime = hrTimeToMs(b.startTime);\n return aTime - bTime;\n });\n\n // Build tree structure\n const tree = this.buildSpanTree(sorted);\n\n // Print trace ID header if enabled\n if (this.options.showTraceId && tree.length > 0) {\n console.log(this.color(`trace: ${traceId}`, 'gray'));\n }\n\n // Print each root span and its children\n for (const node of tree) {\n this.printNode(node, 0, false);\n }\n\n // Add blank line between traces\n console.log('');\n }\n\n /**\n * Build a tree structure from flat spans using parent-child relationships\n */\n private buildSpanTree(spans: ReadableSpan[]): SpanNode[] {\n const spanMap = new Map<string, SpanNode>();\n const roots: SpanNode[] = [];\n\n // Create nodes for all spans\n for (const span of spans) {\n const spanId = span.spanContext().spanId;\n spanMap.set(spanId, { span, children: [] });\n }\n\n // Build parent-child relationships\n for (const span of spans) {\n const spanId = span.spanContext().spanId;\n const parentId = span.parentSpanContext?.spanId;\n const node = spanMap.get(spanId)!;\n\n if (parentId && spanMap.has(parentId)) {\n // Has parent in this batch - add as child\n spanMap.get(parentId)!.children.push(node);\n } else {\n // No parent or parent not in batch - treat as root\n roots.push(node);\n }\n }\n\n return roots;\n }\n\n /**\n * Print a span node with indentation and tree characters\n */\n private printNode(node: SpanNode, depth: number, isLast: boolean): void {\n const { span } = node;\n\n // Build tree prefix\n const prefix =\n depth === 0 ? '' : ' '.repeat(depth - 1) + (isLast ? '└─ ' : '├─ ');\n\n // Status indicator\n const isError = span.status.code === SpanStatusCode.ERROR;\n const statusChar = isError ? '✗' : '✓';\n const statusColor: AnsiColor = isError ? 'red' : 'green';\n\n // Duration formatting\n const durationMs = hrTimeToMs(span.duration);\n const durationStr = formatDuration(durationMs);\n const durationColor = getDurationColor(durationMs);\n\n // Scope name (instrumentation library)\n const scopeName = this.options.showScope\n ? this.color(` [${this.getScopeName(span)}]`, 'gray')\n : '';\n\n // Build the main line\n const line = [\n prefix,\n this.color(statusChar, statusColor),\n ' ',\n span.name.padEnd(Math.max(35 - prefix.length, 10)),\n this.color(durationStr.padStart(8), durationColor),\n scopeName,\n ].join('');\n\n console.log(line);\n\n // Print attributes on next line (indented)\n if (this.options.showAttributes) {\n const attrs = this.formatAttributes(span);\n if (attrs) {\n const attrIndent = ' '.repeat(depth) + ' ';\n console.log(this.color(`${attrIndent}${attrs}`, 'dim'));\n }\n }\n\n // Print error message if present\n if (isError && span.status.message) {\n const errorIndent = ' '.repeat(depth) + ' ';\n console.log(\n this.color(`${errorIndent}Error: ${span.status.message}`, 'red'),\n );\n }\n\n // Print children\n const childCount = node.children.length;\n let index = 0;\n for (const child of node.children) {\n this.printNode(child, depth + 1, index === childCount - 1);\n index++;\n }\n }\n\n /**\n * Get short scope name from instrumentation scope\n */\n private getScopeName(span: ReadableSpan): string {\n const name = span.instrumentationScope?.name ?? 'unknown';\n // Extract short name from @opentelemetry/instrumentation-xxx format\n const match = name.match(/@opentelemetry\\/instrumentation-(.+)/);\n if (match?.[1]) return match[1];\n // Fall back to last part of name or full name\n const lastPart = name.split('/').at(-1);\n return lastPart ?? name;\n }\n\n /**\n * Format span attributes as a comma-separated string\n */\n private formatAttributes(span: ReadableSpan): string {\n const attrs = span.attributes;\n if (!attrs || Object.keys(attrs).length === 0) {\n return '';\n }\n\n const pairs: string[] = [];\n for (const [key, value] of Object.entries(attrs)) {\n // Skip hidden attributes\n if (this.options.hideAttributes.includes(key)) continue;\n\n // Skip undefined/null values\n if (value === undefined || value === null) continue;\n\n // Format value\n const strValue = this.truncate(\n Array.isArray(value) ? `[${value.join(', ')}]` : String(value),\n this.options.maxValueLength,\n );\n pairs.push(`${key}=${strValue}`);\n }\n\n return pairs.join(', ');\n }\n\n /**\n * Truncate string to max length with ellipsis\n */\n private truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 3) + '...';\n }\n\n /**\n * Apply ANSI color if colors are enabled\n */\n private color(text: string, color: AnsiColor): string {\n if (!this.options.colors) return text;\n return `${ANSI[color]}${text}${ANSI.reset}`;\n }\n\n /**\n * Shutdown (no-op for console exporter)\n */\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Force flush (no-op for console exporter)\n */\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n}\n\n/**\n * Convert HrTime [seconds, nanoseconds] to milliseconds\n */\nfunction hrTimeToMs(hrTime: [number, number]): number {\n const [seconds, nanos] = hrTime;\n return seconds * 1000 + nanos / 1_000_000;\n}\n\n/**\n * Format duration with appropriate units\n */\nfunction formatDuration(ms: number): string {\n if (ms < 1) {\n // Sub-millisecond: show as microseconds\n return `${(ms * 1000).toFixed(0)}µs`;\n }\n if (ms < 1000) {\n // Under 1 second: show as milliseconds\n return `${ms.toFixed(0)}ms`;\n }\n // 1 second or more: show as seconds\n return `${(ms / 1000).toFixed(2)}s`;\n}\n\n/**\n * Get color based on duration (fast=green, medium=yellow, slow=red)\n */\nfunction getDurationColor(ms: number): AnsiColor {\n if (ms < 100) return 'green';\n if (ms < 500) return 'yellow';\n return 'red';\n}\n\n/**\n * Export utility functions for testing\n */\nexport { formatDuration, getDurationColor, hrTimeToMs };\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"register.cjs","names":["nodeModule"],"sources":["../src/register.ts"],"sourcesContent":["/**\n * ESM instrumentation registration for Node.js 18.19+\n *\n * This module registers the OpenTelemetry ESM loader hook using the modern\n * node:module register() API. This eliminates the need for NODE_OPTIONS or\n * --experimental-loader flags.\n *\n * Usage in instrumentation.mjs:\n * ```typescript\n * import 'autotel/register'; // MUST be first import!\n * import { init } from 'autotel';\n *\n * init({\n * service: 'my-app',\n * instrumentations: [...], // or autoInstrumentations: ['express', 'http', 'pino']\n * });\n * ```\n *\n * Then run:\n * ```bash\n * node --import ./instrumentation.mjs src/index.js\n * # or with tsx:\n * tsx --import ./instrumentation.mjs src/index.ts\n * ```\n *\n * No NODE_OPTIONS or --experimental-loader needed!\n *\n * @requires Node.js 18.19.0 or later\n * @see https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md\n * @see https://nodejs.org/api/module.html#moduleregisterspecifier-parenturl-options\n */\n\n// namespace import for browser-bundler compat — see node-require.ts\nimport * as nodeModule from 'node:module';\n\n// Use the official OpenTelemetry instrumentation hook which wraps import-in-the-middle\n// This ensures proper integration with OTel's instrumentation system\nnodeModule.register('@opentelemetry/instrumentation/hook.mjs', import.meta.url);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCAA,YAAW,SAAS,wFAA0D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"register.js","names":[],"sources":["../src/register.ts"],"sourcesContent":["/**\n * ESM instrumentation registration for Node.js 18.19+\n *\n * This module registers the OpenTelemetry ESM loader hook using the modern\n * node:module register() API. This eliminates the need for NODE_OPTIONS or\n * --experimental-loader flags.\n *\n * Usage in instrumentation.mjs:\n * ```typescript\n * import 'autotel/register'; // MUST be first import!\n * import { init } from 'autotel';\n *\n * init({\n * service: 'my-app',\n * instrumentations: [...], // or autoInstrumentations: ['express', 'http', 'pino']\n * });\n * ```\n *\n * Then run:\n * ```bash\n * node --import ./instrumentation.mjs src/index.js\n * # or with tsx:\n * tsx --import ./instrumentation.mjs src/index.ts\n * ```\n *\n * No NODE_OPTIONS or --experimental-loader needed!\n *\n * @requires Node.js 18.19.0 or later\n * @see https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md\n * @see https://nodejs.org/api/module.html#moduleregisterspecifier-parenturl-options\n */\n\n// namespace import for browser-bundler compat — see node-require.ts\nimport * as nodeModule from 'node:module';\n\n// Use the official OpenTelemetry instrumentation hook which wraps import-in-the-middle\n// This ensures proper integration with OTel's instrumentation system\nnodeModule.register('@opentelemetry/instrumentation/hook.mjs', import.meta.url);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,WAAW,SAAS,2CAA2C,OAAO,KAAK,GAAG"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry-DVSmWg6Y.js","names":[],"sources":["../src/attributes/registry.ts"],"sourcesContent":["/**\n * OpenTelemetry attribute registry\n * Central source of truth for attribute keys, types, and metadata\n */\n\nexport const UserAttributes = {\n id: 'user.id' as const,\n email: 'user.email' as const,\n name: 'user.name' as const,\n fullName: 'user.full_name' as const,\n hash: 'user.hash' as const,\n roles: 'user.roles' as const,\n} as const;\n\nexport const SessionAttributes = {\n id: 'session.id' as const,\n previousId: 'session.previous_id' as const,\n} as const;\n\nexport const DeviceAttributes = {\n id: 'device.id' as const,\n manufacturer: 'device.manufacturer' as const,\n modelIdentifier: 'device.model.identifier' as const,\n modelName: 'device.model.name' as const,\n} as const;\n\nexport const HTTPAttributes = {\n connectionState: 'http.connection.state' as const,\n requestMethod: 'http.request.method' as const,\n requestMethodOriginal: 'http.request.method_original' as const,\n requestResendCount: 'http.request.resend_count' as const,\n requestSize: 'http.request.size' as const,\n requestBodySize: 'http.request.body.size' as const,\n responseSize: 'http.response.size' as const,\n responseBodySize: 'http.response.body.size' as const,\n responseStatusCode: 'http.response.status_code' as const,\n route: 'http.route' as const,\n} as const;\n\nexport const DBAttributes = {\n clientConnectionPoolName: 'db.client.connection.pool.name' as const,\n clientConnectionState: 'db.client.connection.state' as const,\n collectionName: 'db.collection.name' as const,\n namespace: 'db.namespace' as const,\n operationBatchSize: 'db.operation.batch.size' as const,\n operationName: 'db.operation.name' as const,\n querySummary: 'db.query.summary' as const,\n queryText: 'db.query.text' as const,\n responseReturnedRows: 'db.response.returned_rows' as const,\n responseStatusCode: 'db.response.status_code' as const,\n systemName: 'db.system.name' as const,\n statement: 'db.statement' as const,\n} as const;\n\nexport const ServiceAttributes = {\n name: 'service.name' as const,\n instance: 'service.instance.id' as const,\n version: 'service.version' as const,\n} as const;\n\nexport const NetworkAttributes = {\n peerAddress: 'network.peer.address' as const,\n peerPort: 'network.peer.port' as const,\n transport: 'network.transport' as const,\n type: 'network.type' as const,\n protocolName: 'network.protocol.name' as const,\n protocolVersion: 'network.protocol.version' as const,\n} as const;\n\nexport const ServerAddressAttributes = {\n address: 'server.address' as const,\n port: 'server.port' as const,\n socketAddress: 'server.socket.address' as const,\n} as const;\n\nexport const URLAttributes = {\n scheme: 'url.scheme' as const,\n full: 'url.full' as const,\n path: 'url.path' as const,\n query: 'url.query' as const,\n fragment: 'url.fragment' as const,\n} as const;\n\nexport const ErrorAttributes = {\n type: 'error.type' as const,\n message: 'error.message' as const,\n stackTrace: 'error.stack' as const,\n code: 'error.code' as const,\n} as const;\n\nexport const ExceptionAttributes = {\n escaped: 'exception.escaped' as const,\n message: 'exception.message' as const,\n stackTrace: 'exception.stacktrace' as const,\n type: 'exception.type' as const,\n moduleName: 'exception.module' as const,\n} as const;\n\nexport const ProcessAttributes = {\n pid: 'process.pid' as const,\n executablePath: 'process.executable.path' as const,\n command: 'process.command' as const,\n owner: 'process.owner' as const,\n commandArgs: 'process.command_args' as const,\n} as const;\n\nexport const ThreadAttributes = {\n id: 'thread.id' as const,\n name: 'thread.name' as const,\n} as const;\n\nexport const ContainerAttributes = {\n id: 'container.id' as const,\n name: 'container.name' as const,\n image: 'container.image.name' as const,\n tag: 'container.image.tag' as const,\n} as const;\n\nexport const K8sAttributes = {\n podName: 'k8s.pod.name' as const,\n namespaceName: 'k8s.namespace.name' as const,\n deploymentName: 'k8s.deployment.name' as const,\n state: 'k8s.state.name' as const,\n} as const;\n\nexport const CloudAttributes = {\n provider: 'cloud.provider' as const,\n accountId: 'cloud.account.id' as const,\n region: 'cloud.region' as const,\n availabilityZone: 'cloud.availability_zone' as const,\n platform: 'cloud.platform' as const,\n} as const;\n\nexport const FaaSAttributes = {\n name: 'faas.name' as const,\n version: 'faas.version' as const,\n instance: 'faas.instance' as const,\n execution: 'faas.execution' as const,\n coldstart: 'faas.coldstart' as const,\n} as const;\n\nexport const FeatureFlagAttributes = {\n key: 'feature.flag.key' as const,\n provider: 'feature.flag.provider_name' as const,\n variant: 'feature.flag.variant.name' as const,\n} as const;\n\nexport const MessagingAttributes = {\n system: 'messaging.system' as const,\n destination: 'messaging.destination.name' as const,\n operation: 'messaging.operation' as const,\n messageId: 'messaging.message.id' as const,\n conversationId: 'messaging.conversation_id' as const,\n batchMessageCount: 'messaging.batch.message_count' as const,\n consumerGroup: 'messaging.consumer.group' as const,\n} as const;\n\n// GenAI attribute registry moved to the `autotel-genai` package, which uses the\n// canonical `gen_ai.*` namespace (these legacy `gen.ai.*` keys were non-spec).\n\nexport const RPCAttributes = {\n system: 'rpc.system' as const,\n service: 'rpc.service' as const,\n method: 'rpc.method' as const,\n grpcStatusCode: 'rpc.grpc.status_code' as const,\n} as const;\n\nexport const GraphQLAttributes = {\n document: 'graphql.document' as const,\n operationName: 'graphql.operation.name' as const,\n operationType: 'graphql.operation.type' as const,\n} as const;\n\nexport const PeerAttributes = {\n service: 'peer.service' as const,\n} as const;\n\nexport const ClientAttributes = {\n address: 'client.address' as const,\n port: 'client.port' as const,\n socketAddress: 'client.socket.address' as const,\n} as const;\n\nexport const DeploymentAttributes = {\n environment: 'deployment.environment' as const,\n id: 'deployment.environment.id' as const,\n} as const;\n\nexport const OTelAttributes = {\n libraryName: 'otel.library.name' as const,\n libraryVersion: 'otel.library.version' as const,\n statusCode: 'otel.status_code' as const,\n} as const;\n\nexport const CodeAttributes = {\n namespace: 'code.namespace' as const,\n filepath: 'code.filepath' as const,\n function: 'code.function' as const,\n class: 'code.class' as const,\n method: 'code.method' as const,\n column: 'code.column' as const,\n lineNumber: 'code.lineno' as const,\n repository: 'code.repository' as const,\n revision: 'code.revision' as const,\n} as const;\n\nexport const TLSAttributes = {\n protocolVersion: 'tls.protocol.version' as const,\n cipher: 'tls.cipher' as const,\n curveName: 'tls.curve.name' as const,\n resumed: 'tls.resumed' as const,\n} as const;\n\nexport const BrowserAttributes = {\n platform: 'browser.platform' as const,\n language: 'browser.language' as const,\n brand: 'browser.brand' as const,\n mobile: 'browser.mobile' as const,\n} as const;\n\nexport const AndroidAttributes = {\n appVersion: 'android.app.version' as const,\n package: 'android.package' as const,\n activityName: 'android.activity.name' as const,\n} as const;\n\nexport const IOSAttributes = {\n deviceModel: 'ios.device.model' as const,\n version: 'ios.version' as const,\n} as const;\n\nexport const GeoAttributes = {\n cityName: 'geo.city.name' as const,\n countryCode: 'geo.country.name' as const,\n continentCode: 'geo.continent.code' as const,\n} as const;\n\nexport const UserAgentAttributes = {\n original: 'user_agent.original' as const,\n} as const;\n\nexport const AWSAttributes = {\n ecsClusterArn: 'aws.ecs.cluster.arn' as const,\n ecsContainerArn: 'aws.ecs.container.arn' as const,\n logGroupName: 'aws.log.group.name' as const,\n requestId: 'aws.requestId' as const,\n} as const;\n\nexport const AzureAttributes = {\n subscriptionId: 'azure.subscription.id' as const,\n tenantId: 'azure.tenant.id' as const,\n} as const;\n\nexport const GCPAttributes = {\n project: 'gcp.project.id' as const,\n instanceName: 'gcp.instance.name' as const,\n zone: 'gcp.zone' as const,\n} as const;\n\nexport const CassandraAttributes = {\n consistencyLevel: 'cassandra.consistency.level' as const,\n coordinatorId: 'cassandra.coordinator.id' as const,\n dataCenter: 'cassandra.coordinator.dc' as const,\n pageSize: 'cassandra.page.size' as const,\n} as const;\n\nexport const ElasticsearchAttributes = {\n clusterName: 'elasticsearch.cluster.name' as const,\n nodeId: 'elasticsearch.node.name' as const,\n} as const;\n\nexport const MongoDBAttributes = {\n collectionName: 'mongodb.collection.name' as const,\n} as const;\n\nexport const RedisAttributes = {\n databaseIndex: 'redis.database.index' as const,\n} as const;\n\nexport const MSSQLAttributes = {\n instanceName: 'mssql.instance.name' as const,\n} as const;\n\nexport const PostgreSQLAttributes = {\n databaseName: 'postgresql.database.name' as const,\n} as const;\n\nexport const AWSLambdaAttributes = {\n requestId: 'aws.lambda.invoked_arn' as const,\n requestFunction: 'aws.lambda.invoked_function_arn' as const,\n} as const;\n\nexport const OpenAIAttributes = {\n requestId: 'openai.request.id' as const,\n responseModel: 'openai.response.model' as const,\n responseOrganization: 'openai.response.organization' as const,\n} as const;\n\nexport const AzureAIAAttributes = {\n resource: 'azure.ai.inference.resource' as const,\n deploymentId: 'azure.ai.inference.deployment.id' as const,\n} as const;\n\nexport const AWSBedrockAttributes = {\n requestId: 'aws.bedrock.requestId' as const,\n responseModel: 'aws.bedrock.responseModel' as const,\n} as const;\n\nexport const TestAttributes = {\n framework: 'test.framework' as const,\n name: 'test.name' as const,\n} as const;\n\nexport const ArtifactAttributes = {\n type: 'artifact.type' as const,\n id: 'artifact.id' as const,\n checksum: 'artifact.checksum' as const,\n} as const;\n\nexport const CICDAttributes = {\n pipelineName: 'ci.pipeline.name' as const,\n pipelineRunId: 'ci.pipeline.run.id' as const,\n} as const;\n"],"mappings":";;;;;AAKA,MAAa,iBAAiB;CAC5B,IAAI;CACJ,OAAO;CACP,MAAM;CACN,UAAU;CACV,MAAM;CACN,OAAO;AACT;AAEA,MAAa,oBAAoB;CAC/B,IAAI;CACJ,YAAY;AACd;AAEA,MAAa,mBAAmB;CAC9B,IAAI;CACJ,cAAc;CACd,iBAAiB;CACjB,WAAW;AACb;AAEA,MAAa,iBAAiB;CAC5B,iBAAiB;CACjB,eAAe;CACf,uBAAuB;CACvB,oBAAoB;CACpB,aAAa;CACb,iBAAiB;CACjB,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,OAAO;AACT;AAEA,MAAa,eAAe;CAC1B,0BAA0B;CAC1B,uBAAuB;CACvB,gBAAgB;CAChB,WAAW;CACX,oBAAoB;CACpB,eAAe;CACf,cAAc;CACd,WAAW;CACX,sBAAsB;CACtB,oBAAoB;CACpB,YAAY;CACZ,WAAW;AACb;AAEA,MAAa,oBAAoB;CAC/B,MAAM;CACN,UAAU;CACV,SAAS;AACX;AAEA,MAAa,oBAAoB;CAC/B,aAAa;CACb,UAAU;CACV,WAAW;CACX,MAAM;CACN,cAAc;CACd,iBAAiB;AACnB;AAEA,MAAa,0BAA0B;CACrC,SAAS;CACT,MAAM;CACN,eAAe;AACjB;AAEA,MAAa,gBAAgB;CAC3B,QAAQ;CACR,MAAM;CACN,MAAM;CACN,OAAO;CACP,UAAU;AACZ;AAEA,MAAa,kBAAkB;CAC7B,MAAM;CACN,SAAS;CACT,YAAY;CACZ,MAAM;AACR;AAEA,MAAa,sBAAsB;CACjC,SAAS;CACT,SAAS;CACT,YAAY;CACZ,MAAM;CACN,YAAY;AACd;AAEA,MAAa,oBAAoB;CAC/B,KAAK;CACL,gBAAgB;CAChB,SAAS;CACT,OAAO;CACP,aAAa;AACf;AAEA,MAAa,mBAAmB;CAC9B,IAAI;CACJ,MAAM;AACR;AAEA,MAAa,sBAAsB;CACjC,IAAI;CACJ,MAAM;CACN,OAAO;CACP,KAAK;AACP;AAEA,MAAa,gBAAgB;CAC3B,SAAS;CACT,eAAe;CACf,gBAAgB;CAChB,OAAO;AACT;AAEA,MAAa,kBAAkB;CAC7B,UAAU;CACV,WAAW;CACX,QAAQ;CACR,kBAAkB;CAClB,UAAU;AACZ;AAEA,MAAa,iBAAiB;CAC5B,MAAM;CACN,SAAS;CACT,UAAU;CACV,WAAW;CACX,WAAW;AACb;AAEA,MAAa,wBAAwB;CACnC,KAAK;CACL,UAAU;CACV,SAAS;AACX;AAEA,MAAa,sBAAsB;CACjC,QAAQ;CACR,aAAa;CACb,WAAW;CACX,WAAW;CACX,gBAAgB;CAChB,mBAAmB;CACnB,eAAe;AACjB;AAKA,MAAa,gBAAgB;CAC3B,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,gBAAgB;AAClB;AAEA,MAAa,oBAAoB;CAC/B,UAAU;CACV,eAAe;CACf,eAAe;AACjB;AAiBA,MAAa,iBAAiB;CAC5B,aAAa;CACb,gBAAgB;CAChB,YAAY;AACd;AAEA,MAAa,iBAAiB;CAC5B,WAAW;CACX,UAAU;CACV,UAAU;CACV,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,YAAY;CACZ,YAAY;CACZ,UAAU;AACZ;AAEA,MAAa,gBAAgB;CAC3B,iBAAiB;CACjB,QAAQ;CACR,WAAW;CACX,SAAS;AACX"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"registry-DYgvb62e.cjs","names":[],"sources":["../src/attributes/registry.ts"],"sourcesContent":["/**\n * OpenTelemetry attribute registry\n * Central source of truth for attribute keys, types, and metadata\n */\n\nexport const UserAttributes = {\n id: 'user.id' as const,\n email: 'user.email' as const,\n name: 'user.name' as const,\n fullName: 'user.full_name' as const,\n hash: 'user.hash' as const,\n roles: 'user.roles' as const,\n} as const;\n\nexport const SessionAttributes = {\n id: 'session.id' as const,\n previousId: 'session.previous_id' as const,\n} as const;\n\nexport const DeviceAttributes = {\n id: 'device.id' as const,\n manufacturer: 'device.manufacturer' as const,\n modelIdentifier: 'device.model.identifier' as const,\n modelName: 'device.model.name' as const,\n} as const;\n\nexport const HTTPAttributes = {\n connectionState: 'http.connection.state' as const,\n requestMethod: 'http.request.method' as const,\n requestMethodOriginal: 'http.request.method_original' as const,\n requestResendCount: 'http.request.resend_count' as const,\n requestSize: 'http.request.size' as const,\n requestBodySize: 'http.request.body.size' as const,\n responseSize: 'http.response.size' as const,\n responseBodySize: 'http.response.body.size' as const,\n responseStatusCode: 'http.response.status_code' as const,\n route: 'http.route' as const,\n} as const;\n\nexport const DBAttributes = {\n clientConnectionPoolName: 'db.client.connection.pool.name' as const,\n clientConnectionState: 'db.client.connection.state' as const,\n collectionName: 'db.collection.name' as const,\n namespace: 'db.namespace' as const,\n operationBatchSize: 'db.operation.batch.size' as const,\n operationName: 'db.operation.name' as const,\n querySummary: 'db.query.summary' as const,\n queryText: 'db.query.text' as const,\n responseReturnedRows: 'db.response.returned_rows' as const,\n responseStatusCode: 'db.response.status_code' as const,\n systemName: 'db.system.name' as const,\n statement: 'db.statement' as const,\n} as const;\n\nexport const ServiceAttributes = {\n name: 'service.name' as const,\n instance: 'service.instance.id' as const,\n version: 'service.version' as const,\n} as const;\n\nexport const NetworkAttributes = {\n peerAddress: 'network.peer.address' as const,\n peerPort: 'network.peer.port' as const,\n transport: 'network.transport' as const,\n type: 'network.type' as const,\n protocolName: 'network.protocol.name' as const,\n protocolVersion: 'network.protocol.version' as const,\n} as const;\n\nexport const ServerAddressAttributes = {\n address: 'server.address' as const,\n port: 'server.port' as const,\n socketAddress: 'server.socket.address' as const,\n} as const;\n\nexport const URLAttributes = {\n scheme: 'url.scheme' as const,\n full: 'url.full' as const,\n path: 'url.path' as const,\n query: 'url.query' as const,\n fragment: 'url.fragment' as const,\n} as const;\n\nexport const ErrorAttributes = {\n type: 'error.type' as const,\n message: 'error.message' as const,\n stackTrace: 'error.stack' as const,\n code: 'error.code' as const,\n} as const;\n\nexport const ExceptionAttributes = {\n escaped: 'exception.escaped' as const,\n message: 'exception.message' as const,\n stackTrace: 'exception.stacktrace' as const,\n type: 'exception.type' as const,\n moduleName: 'exception.module' as const,\n} as const;\n\nexport const ProcessAttributes = {\n pid: 'process.pid' as const,\n executablePath: 'process.executable.path' as const,\n command: 'process.command' as const,\n owner: 'process.owner' as const,\n commandArgs: 'process.command_args' as const,\n} as const;\n\nexport const ThreadAttributes = {\n id: 'thread.id' as const,\n name: 'thread.name' as const,\n} as const;\n\nexport const ContainerAttributes = {\n id: 'container.id' as const,\n name: 'container.name' as const,\n image: 'container.image.name' as const,\n tag: 'container.image.tag' as const,\n} as const;\n\nexport const K8sAttributes = {\n podName: 'k8s.pod.name' as const,\n namespaceName: 'k8s.namespace.name' as const,\n deploymentName: 'k8s.deployment.name' as const,\n state: 'k8s.state.name' as const,\n} as const;\n\nexport const CloudAttributes = {\n provider: 'cloud.provider' as const,\n accountId: 'cloud.account.id' as const,\n region: 'cloud.region' as const,\n availabilityZone: 'cloud.availability_zone' as const,\n platform: 'cloud.platform' as const,\n} as const;\n\nexport const FaaSAttributes = {\n name: 'faas.name' as const,\n version: 'faas.version' as const,\n instance: 'faas.instance' as const,\n execution: 'faas.execution' as const,\n coldstart: 'faas.coldstart' as const,\n} as const;\n\nexport const FeatureFlagAttributes = {\n key: 'feature.flag.key' as const,\n provider: 'feature.flag.provider_name' as const,\n variant: 'feature.flag.variant.name' as const,\n} as const;\n\nexport const MessagingAttributes = {\n system: 'messaging.system' as const,\n destination: 'messaging.destination.name' as const,\n operation: 'messaging.operation' as const,\n messageId: 'messaging.message.id' as const,\n conversationId: 'messaging.conversation_id' as const,\n batchMessageCount: 'messaging.batch.message_count' as const,\n consumerGroup: 'messaging.consumer.group' as const,\n} as const;\n\n// GenAI attribute registry moved to the `autotel-genai` package, which uses the\n// canonical `gen_ai.*` namespace (these legacy `gen.ai.*` keys were non-spec).\n\nexport const RPCAttributes = {\n system: 'rpc.system' as const,\n service: 'rpc.service' as const,\n method: 'rpc.method' as const,\n grpcStatusCode: 'rpc.grpc.status_code' as const,\n} as const;\n\nexport const GraphQLAttributes = {\n document: 'graphql.document' as const,\n operationName: 'graphql.operation.name' as const,\n operationType: 'graphql.operation.type' as const,\n} as const;\n\nexport const PeerAttributes = {\n service: 'peer.service' as const,\n} as const;\n\nexport const ClientAttributes = {\n address: 'client.address' as const,\n port: 'client.port' as const,\n socketAddress: 'client.socket.address' as const,\n} as const;\n\nexport const DeploymentAttributes = {\n environment: 'deployment.environment' as const,\n id: 'deployment.environment.id' as const,\n} as const;\n\nexport const OTelAttributes = {\n libraryName: 'otel.library.name' as const,\n libraryVersion: 'otel.library.version' as const,\n statusCode: 'otel.status_code' as const,\n} as const;\n\nexport const CodeAttributes = {\n namespace: 'code.namespace' as const,\n filepath: 'code.filepath' as const,\n function: 'code.function' as const,\n class: 'code.class' as const,\n method: 'code.method' as const,\n column: 'code.column' as const,\n lineNumber: 'code.lineno' as const,\n repository: 'code.repository' as const,\n revision: 'code.revision' as const,\n} as const;\n\nexport const TLSAttributes = {\n protocolVersion: 'tls.protocol.version' as const,\n cipher: 'tls.cipher' as const,\n curveName: 'tls.curve.name' as const,\n resumed: 'tls.resumed' as const,\n} as const;\n\nexport const BrowserAttributes = {\n platform: 'browser.platform' as const,\n language: 'browser.language' as const,\n brand: 'browser.brand' as const,\n mobile: 'browser.mobile' as const,\n} as const;\n\nexport const AndroidAttributes = {\n appVersion: 'android.app.version' as const,\n package: 'android.package' as const,\n activityName: 'android.activity.name' as const,\n} as const;\n\nexport const IOSAttributes = {\n deviceModel: 'ios.device.model' as const,\n version: 'ios.version' as const,\n} as const;\n\nexport const GeoAttributes = {\n cityName: 'geo.city.name' as const,\n countryCode: 'geo.country.name' as const,\n continentCode: 'geo.continent.code' as const,\n} as const;\n\nexport const UserAgentAttributes = {\n original: 'user_agent.original' as const,\n} as const;\n\nexport const AWSAttributes = {\n ecsClusterArn: 'aws.ecs.cluster.arn' as const,\n ecsContainerArn: 'aws.ecs.container.arn' as const,\n logGroupName: 'aws.log.group.name' as const,\n requestId: 'aws.requestId' as const,\n} as const;\n\nexport const AzureAttributes = {\n subscriptionId: 'azure.subscription.id' as const,\n tenantId: 'azure.tenant.id' as const,\n} as const;\n\nexport const GCPAttributes = {\n project: 'gcp.project.id' as const,\n instanceName: 'gcp.instance.name' as const,\n zone: 'gcp.zone' as const,\n} as const;\n\nexport const CassandraAttributes = {\n consistencyLevel: 'cassandra.consistency.level' as const,\n coordinatorId: 'cassandra.coordinator.id' as const,\n dataCenter: 'cassandra.coordinator.dc' as const,\n pageSize: 'cassandra.page.size' as const,\n} as const;\n\nexport const ElasticsearchAttributes = {\n clusterName: 'elasticsearch.cluster.name' as const,\n nodeId: 'elasticsearch.node.name' as const,\n} as const;\n\nexport const MongoDBAttributes = {\n collectionName: 'mongodb.collection.name' as const,\n} as const;\n\nexport const RedisAttributes = {\n databaseIndex: 'redis.database.index' as const,\n} as const;\n\nexport const MSSQLAttributes = {\n instanceName: 'mssql.instance.name' as const,\n} as const;\n\nexport const PostgreSQLAttributes = {\n databaseName: 'postgresql.database.name' as const,\n} as const;\n\nexport const AWSLambdaAttributes = {\n requestId: 'aws.lambda.invoked_arn' as const,\n requestFunction: 'aws.lambda.invoked_function_arn' as const,\n} as const;\n\nexport const OpenAIAttributes = {\n requestId: 'openai.request.id' as const,\n responseModel: 'openai.response.model' as const,\n responseOrganization: 'openai.response.organization' as const,\n} as const;\n\nexport const AzureAIAAttributes = {\n resource: 'azure.ai.inference.resource' as const,\n deploymentId: 'azure.ai.inference.deployment.id' as const,\n} as const;\n\nexport const AWSBedrockAttributes = {\n requestId: 'aws.bedrock.requestId' as const,\n responseModel: 'aws.bedrock.responseModel' as const,\n} as const;\n\nexport const TestAttributes = {\n framework: 'test.framework' as const,\n name: 'test.name' as const,\n} as const;\n\nexport const ArtifactAttributes = {\n type: 'artifact.type' as const,\n id: 'artifact.id' as const,\n checksum: 'artifact.checksum' as const,\n} as const;\n\nexport const CICDAttributes = {\n pipelineName: 'ci.pipeline.name' as const,\n pipelineRunId: 'ci.pipeline.run.id' as const,\n} as const;\n"],"mappings":";;;;;;AAKA,MAAa,iBAAiB;CAC5B,IAAI;CACJ,OAAO;CACP,MAAM;CACN,UAAU;CACV,MAAM;CACN,OAAO;AACT;AAEA,MAAa,oBAAoB;CAC/B,IAAI;CACJ,YAAY;AACd;AAEA,MAAa,mBAAmB;CAC9B,IAAI;CACJ,cAAc;CACd,iBAAiB;CACjB,WAAW;AACb;AAEA,MAAa,iBAAiB;CAC5B,iBAAiB;CACjB,eAAe;CACf,uBAAuB;CACvB,oBAAoB;CACpB,aAAa;CACb,iBAAiB;CACjB,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,OAAO;AACT;AAEA,MAAa,eAAe;CAC1B,0BAA0B;CAC1B,uBAAuB;CACvB,gBAAgB;CAChB,WAAW;CACX,oBAAoB;CACpB,eAAe;CACf,cAAc;CACd,WAAW;CACX,sBAAsB;CACtB,oBAAoB;CACpB,YAAY;CACZ,WAAW;AACb;AAEA,MAAa,oBAAoB;CAC/B,MAAM;CACN,UAAU;CACV,SAAS;AACX;AAEA,MAAa,oBAAoB;CAC/B,aAAa;CACb,UAAU;CACV,WAAW;CACX,MAAM;CACN,cAAc;CACd,iBAAiB;AACnB;AAEA,MAAa,0BAA0B;CACrC,SAAS;CACT,MAAM;CACN,eAAe;AACjB;AAEA,MAAa,gBAAgB;CAC3B,QAAQ;CACR,MAAM;CACN,MAAM;CACN,OAAO;CACP,UAAU;AACZ;AAEA,MAAa,kBAAkB;CAC7B,MAAM;CACN,SAAS;CACT,YAAY;CACZ,MAAM;AACR;AAEA,MAAa,sBAAsB;CACjC,SAAS;CACT,SAAS;CACT,YAAY;CACZ,MAAM;CACN,YAAY;AACd;AAEA,MAAa,oBAAoB;CAC/B,KAAK;CACL,gBAAgB;CAChB,SAAS;CACT,OAAO;CACP,aAAa;AACf;AAEA,MAAa,mBAAmB;CAC9B,IAAI;CACJ,MAAM;AACR;AAEA,MAAa,sBAAsB;CACjC,IAAI;CACJ,MAAM;CACN,OAAO;CACP,KAAK;AACP;AAEA,MAAa,gBAAgB;CAC3B,SAAS;CACT,eAAe;CACf,gBAAgB;CAChB,OAAO;AACT;AAEA,MAAa,kBAAkB;CAC7B,UAAU;CACV,WAAW;CACX,QAAQ;CACR,kBAAkB;CAClB,UAAU;AACZ;AAEA,MAAa,iBAAiB;CAC5B,MAAM;CACN,SAAS;CACT,UAAU;CACV,WAAW;CACX,WAAW;AACb;AAEA,MAAa,wBAAwB;CACnC,KAAK;CACL,UAAU;CACV,SAAS;AACX;AAEA,MAAa,sBAAsB;CACjC,QAAQ;CACR,aAAa;CACb,WAAW;CACX,WAAW;CACX,gBAAgB;CAChB,mBAAmB;CACnB,eAAe;AACjB;AAKA,MAAa,gBAAgB;CAC3B,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,gBAAgB;AAClB;AAEA,MAAa,oBAAoB;CAC/B,UAAU;CACV,eAAe;CACf,eAAe;AACjB;AAiBA,MAAa,iBAAiB;CAC5B,aAAa;CACb,gBAAgB;CAChB,YAAY;AACd;AAEA,MAAa,iBAAiB;CAC5B,WAAW;CACX,UAAU;CACV,UAAU;CACV,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,YAAY;CACZ,YAAY;CACZ,UAAU;AACZ;AAEA,MAAa,gBAAgB;CAC3B,iBAAiB;CACjB,QAAQ;CACR,WAAW;CACX,SAAS;AACX"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sampling-BR9fkSwx.d.cts","names":[],"sources":["../src/sampling.ts"],"mappings":";;;;;;cA+Ba;cACA;;;;;;;;cAUA;;;;;;;;;;;;;;;iBA0BG,iBAAiB;;;;UAoBhB;;;;;;;EAOf,aAAa,SAAS;;;;;;;EAQtB;;;;;;;;;EAUA,iBAAiB,SAAS,iBAAiB,QAAQ;;;;;;;;;;EAWnD,YAAY,SAAS;;;;;UAMN;;EAEf;;EAEA;;EAEA,WAAW;;EAEX,QAAQ;;;;;UAMO;;EAEf;;EAEA;;EAEA,QAAQ;;;;;;;;;;cAWG,yBAAyB;mBACP;EAAA,YAAA;EAM7B,aAAa,UAAU;EAIvB;;;;;cAQW,yBAAyB;EACpC,aAAa,UAAU;;;;;cAQZ,wBAAwB;EACnC,aAAa,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAsCZ,2BAA2B;UAC9B;UACA;UACA;UACA;UACA;UACA;UACA;mBAGS;mBAEA;EAGf,YAAA;IACE;IACA;IACA;IACA;;IAEA;;IAEA;IACA,SAAS;;EAmBb;EAKA,aAAa,SAAS;;;;;;;;;;EAoBtB,eAAe,OAAO;;;;;;;;;;;EAoBtB,gBAAgB,SAAS,iBAAiB,QAAQ;;;;;;;;;;;;;;;;;cAuEvC,yBAAyB;UAC5B;UACA;UACA;UACA;EAEI,YAAA;IACV;IACA;IACA,gBAAgB;IAChB,SAAS;;EAQX,aAAa,SAAS;;;;EA4BtB,wBAAwB;;;;EASxB,2BAA2B;;;;UASnB;;;;;;;;;;;;;;;;;;cAqBG,gCAAgC;mBAC1B;mBACA;EAEL,YAAA;;IAEV;;IAEA,MAAM,SAAS;;EASjB,aAAa,SAAS;EAStB;;;;;;;;;;;;;;;;;;;;;;;cA6BW,gCAAgC;mBAC1B;mBACA;mBACA;mBACA;UACT;UACA;UACA;EAEI,YAAA;;IAEV,MAAM,SAAS;;IAEf;;IAEA;;IAEA;;;UAgBM;;;;;;;UAmBA;EAQR,aAAa,SAAS;EAQtB,WAAW,SAAS;;;;;;;;;;;;;;;cAkBT,4BAA4B;mBACV;EAAA,YAAA,UAAU;EAMvC,aAAa,SAAS;;;;;;;;;;;;;;;;;cAoBX,8BAA8B;UACjC;UACA;UACA;UAIA;EAEI,YAAA;IACV;IACA;IACA,eACE,iBACA,WAAW;IAEb,SAAS;;EAQX,aAAa,SAAS;;;;EAsBtB,wBAAwB;;;;EASxB,2BAA2B;;;;;;KAejB;;;;;;;;;;;;;;cAgBC;;;;;;;;;EAec,aAAA;IACvB;IACA;IACA;IACA;QACD;;;;;;;;;;iBAmBa,sBAAsB,QAAQ,iBAAiB;;;;;;;;;;;;;;;;;;;;;;iBA+C/C,sBACd,SAAS,wBACT,aAAa,aACZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8Ca,sBACd,UAAU;GAAS;IACnB,sBACC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sampling-CP3e7-Yr.d.ts","names":[],"sources":["../src/sampling.ts"],"mappings":";;;;;;cA+Ba;cACA;;;;;;;;cAUA;;;;;;;;;;;;;;;iBA0BG,iBAAiB;;;;UAoBhB;;;;;;;EAOf,aAAa,SAAS;;;;;;;EAQtB;;;;;;;;;EAUA,iBAAiB,SAAS,iBAAiB,QAAQ;;;;;;;;;;EAWnD,YAAY,SAAS;;;;;UAMN;;EAEf;;EAEA;;EAEA,WAAW;;EAEX,QAAQ;;;;;UAMO;;EAEf;;EAEA;;EAEA,QAAQ;;;;;;;;;;cAWG,yBAAyB;mBACP;EAAA,YAAA;EAM7B,aAAa,UAAU;EAIvB;;;;;cAQW,yBAAyB;EACpC,aAAa,UAAU;;;;;cAQZ,wBAAwB;EACnC,aAAa,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAsCZ,2BAA2B;UAC9B;UACA;UACA;UACA;UACA;UACA;UACA;mBAGS;mBAEA;EAGf,YAAA;IACE;IACA;IACA;IACA;;IAEA;;IAEA;IACA,SAAS;;EAmBb;EAKA,aAAa,SAAS;;;;;;;;;;EAoBtB,eAAe,OAAO;;;;;;;;;;;EAoBtB,gBAAgB,SAAS,iBAAiB,QAAQ;;;;;;;;;;;;;;;;;cAuEvC,yBAAyB;UAC5B;UACA;UACA;UACA;EAEI,YAAA;IACV;IACA;IACA,gBAAgB;IAChB,SAAS;;EAQX,aAAa,SAAS;;;;EA4BtB,wBAAwB;;;;EASxB,2BAA2B;;;;UASnB;;;;;;;;;;;;;;;;;;cAqBG,gCAAgC;mBAC1B;mBACA;EAEL,YAAA;;IAEV;;IAEA,MAAM,SAAS;;EASjB,aAAa,SAAS;EAStB;;;;;;;;;;;;;;;;;;;;;;;cA6BW,gCAAgC;mBAC1B;mBACA;mBACA;mBACA;UACT;UACA;UACA;EAEI,YAAA;;IAEV,MAAM,SAAS;;IAEf;;IAEA;;IAEA;;;UAgBM;;;;;;;UAmBA;EAQR,aAAa,SAAS;EAQtB,WAAW,SAAS;;;;;;;;;;;;;;;cAkBT,4BAA4B;mBACV;EAAA,YAAA,UAAU;EAMvC,aAAa,SAAS;;;;;;;;;;;;;;;;;cAoBX,8BAA8B;UACjC;UACA;UACA;UAIA;EAEI,YAAA;IACV;IACA;IACA,eACE,iBACA,WAAW;IAEb,SAAS;;EAQX,aAAa,SAAS;;;;EAsBtB,wBAAwB;;;;EASxB,2BAA2B;;;;;;KAejB;;;;;;;;;;;;;;cAgBC;;;;;;;;;EAec,aAAA;IACvB;IACA;IACA;IACA;QACD;;;;;;;;;;iBAmBa,sBAAsB,QAAQ,iBAAiB;;;;;;;;;;;;;;;;;;;;;;iBA+C/C,sBACd,SAAS,wBACT,aAAa,aACZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8Ca,sBACd,UAAU;GAAS;IACnB,sBACC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sampling.cjs","names":["TraceFlags"],"sources":["../src/sampling.ts"],"sourcesContent":["/**\n * Sampling Strategies\n *\n * Provides intelligent sampling beyond simple random rates.\n * Helps reduce telemetry costs while capturing critical data.\n *\n * Key strategies:\n * - Always trace errors and slow requests (critical for debugging)\n * - Sample by user ID for consistent request tracing\n * - Adaptive sampling based on load\n * - Sample by feature flags for A/B testing correlation\n *\n * @example\n * ```typescript\n * import { AlwaysOnErrorSampler, UserIdSampler } from './sampling'\n *\n * @Instrumented({\n * serviceName: 'user',\n * sampler: new AlwaysOnErrorSampler(0.1) // 10% baseline, 100% on errors\n * })\n * class UserService { }\n * ```\n */\n\nimport type { Link, Attributes } from '@opentelemetry/api';\nimport { TraceFlags } from '@opentelemetry/api';\nimport { type Logger } from './logger';\n\n/**\n * Tail sampling attribute keys (autotel-internal, not OTel semconv)\n */\nexport const AUTOTEL_SAMPLING_TAIL_KEEP = 'autotel.sampling.tail.keep';\nexport const AUTOTEL_SAMPLING_TAIL_EVALUATED =\n 'autotel.sampling.tail.evaluated';\n\n/**\n * How many events each kept event stands for, expressed as \"1 in N\".\n *\n * A query that counts sampled spans undercounts the population. Multiplying\n * each kept event by this rate restores the estimate. Autotel records the\n * attribute only when N exceeds 1, so fully captured spans stay clean.\n */\nexport const AUTOTEL_SAMPLING_RATE = 'autotel.sampling.rate';\n\n/**\n * Convert a keep probability into the \"1 in N\" rate reported on spans.\n *\n * Keeping 10% of traces means each survivor stands for 10, so the two numbers\n * are reciprocals and easy to publish the wrong way round.\n */\nfunction toSampleRate(probability: number): number {\n return probability > 0 ? 1 / probability : 0;\n}\n\n/**\n * Map a string to a stable, evenly spread position in the unit interval.\n *\n * Two processes that hash the same key reach the same number, which is what\n * lets independent services agree on one trace's sampling decision.\n *\n * The spread matters as much as the stability. Real sampling keys share long\n * prefixes: `user_1000`, `user_1001`, `checkout-trace-0001`. A plain\n * multiply-and-add hash lets that shared prefix dominate the high bits, so a\n * whole key family lands in one narrow band and a rate of 0.1 keeps all of\n * them or none of them. FNV-1a followed by the murmur3 finalizer mixes the\n * low bits back through the word, so keys that differ in one character land\n * far apart.\n */\nexport function hashUnitInterval(value: string): number {\n let hash = 0x81_1c_9d_c5; // FNV-1a 32-bit offset basis\n for (let i = 0; i < value.length; i++) {\n hash ^= value.codePointAt(i) ?? 0;\n hash = Math.imul(hash, 0x01_00_01_93); // FNV prime\n }\n\n // murmur3 fmix32 avalanche\n hash ^= hash >>> 16;\n hash = Math.imul(hash, 0x85_eb_ca_6b);\n hash ^= hash >>> 13;\n hash = Math.imul(hash, 0xc2_b2_ae_35);\n hash ^= hash >>> 16;\n\n return (hash >>> 0) / 4_294_967_296;\n}\n\n/**\n * Sampler interface - return true to trace, false to skip\n */\nexport interface Sampler {\n /**\n * Decide whether to trace this operation\n *\n * @param context - Sampling context\n * @returns true to trace, false to skip\n */\n shouldSample(context: SamplingContext): boolean;\n\n /**\n * Whether this sampler needs tail sampling (post-execution decision)\n * If true, spans are always created and shouldKeepTrace() is called after execution\n *\n * @returns true if this sampler needs to evaluate after operation completes\n */\n needsTailSampling?(): boolean;\n\n /**\n * Re-evaluate sampling decision after operation completes (tail sampling)\n * Only called if needsTailSampling() returns true\n *\n * @param context - Sampling context\n * @param result - Operation result\n * @returns true if this trace should be kept, false to drop it\n */\n shouldKeepTrace?(context: SamplingContext, result: OperationResult): boolean;\n\n /**\n * How many events a kept event represents, as \"1 in N\".\n *\n * Autotel writes the result to {@link AUTOTEL_SAMPLING_RATE} so an analyst\n * can reweight counts. Return 1 when the sampler keeps everything.\n *\n * @param context - Sampling context\n * @returns Events represented per kept event\n */\n sampleRate?(context: SamplingContext): number;\n}\n\n/**\n * Context information for sampling decisions\n */\nexport interface SamplingContext {\n /** Operation name */\n operationName: string;\n /** Method arguments (for extracting user IDs, etc.) */\n args: unknown[];\n /** Optional metadata (e.g., feature flags, request headers) */\n metadata?: Record<string, unknown>;\n /** Optional span links for links-based sampling */\n links?: Link[];\n}\n\n/**\n * Result of a trace operation (for post-execution sampling)\n */\nexport interface OperationResult {\n /** Whether the operation succeeded */\n success: boolean;\n /** Duration in milliseconds */\n duration: number;\n /** Error if operation failed */\n error?: Error;\n}\n\n/**\n * Simple random sampler\n *\n * @example\n * ```typescript\n * new RandomSampler(0.1) // Sample 10% of requests\n * ```\n */\nexport class RandomSampler implements Sampler {\n constructor(private readonly rate: number) {\n if (rate < 0 || rate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n }\n\n shouldSample(_context: SamplingContext): boolean {\n return Math.random() < this.rate;\n }\n\n sampleRate(): number {\n return toSampleRate(this.rate);\n }\n}\n\n/**\n * Always sample (100% tracing)\n */\nexport class AlwaysSampler implements Sampler {\n shouldSample(_context: SamplingContext): boolean {\n return true;\n }\n}\n\n/**\n * Never sample (0% tracing)\n */\nexport class NeverSampler implements Sampler {\n shouldSample(_context: SamplingContext): boolean {\n return false;\n }\n}\n\n/**\n * Adaptive sampler that always traces errors and slow requests\n *\n * This is the recommended sampler for production use.\n * It ensures you never miss critical issues while keeping costs down.\n *\n * Strategy:\n * - Always trace errors (critical for debugging)\n * - Always trace slow requests (performance issues)\n * - Use baseline sample rate for successful fast requests\n *\n * **IMPORTANT - Tail Sampling Requirement:**\n * This sampler uses tail sampling (makes decisions AFTER execution).\n * You MUST use TailSamplingSpanProcessor for it to work correctly:\n *\n * - If using initInstrumentation(): TailSamplingSpanProcessor is auto-configured\n * - If using custom TracerProvider: You MUST manually register TailSamplingSpanProcessor\n *\n * Without TailSamplingSpanProcessor, ALL spans are exported (defeating the cost savings).\n *\n * @see TailSamplingSpanProcessor\n * @see README.md \"Tail Sampling with Custom Providers\" section\n *\n * @example\n * ```typescript\n * new AdaptiveSampler({\n * baselineSampleRate: 0.1, // 10% of normal requests\n * slowThresholdMs: 1000, // Requests > 1s are \"slow\"\n * alwaysSampleErrors: true, // Always trace errors\n * alwaysSampleSlow: true // Always trace slow requests\n * })\n * ```\n */\nexport class AdaptiveSampler implements Sampler {\n private baselineSampleRate: number;\n private slowThresholdMs: number;\n private alwaysSampleErrors: boolean;\n private alwaysSampleSlow: boolean;\n private linksBased: boolean;\n private linksRate: number;\n private logger?: Logger;\n\n // Track whether we should sample this request\n private readonly samplingDecisions = new WeakMap<unknown[], boolean>();\n // Track operation results to enable post-execution decision\n private readonly operationResults = new WeakMap<unknown[], OperationResult>();\n\n constructor(\n options: {\n baselineSampleRate?: number;\n slowThresholdMs?: number;\n alwaysSampleErrors?: boolean;\n alwaysSampleSlow?: boolean;\n /** Enable links-based sampling for event-driven architectures */\n linksBased?: boolean;\n /** Sampling rate for spans linked to sampled spans (0.0-1.0) */\n linksRate?: number;\n logger?: Logger;\n } = {},\n ) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.slowThresholdMs = options.slowThresholdMs ?? 1000;\n this.alwaysSampleErrors = options.alwaysSampleErrors ?? true;\n this.alwaysSampleSlow = options.alwaysSampleSlow ?? true;\n this.linksBased = options.linksBased ?? false;\n this.linksRate = options.linksRate ?? 1;\n this.logger = options.logger;\n\n if (this.baselineSampleRate < 0 || this.baselineSampleRate > 1) {\n throw new Error('Baseline sample rate must be between 0 and 1');\n }\n if (this.linksRate < 0 || this.linksRate > 1) {\n throw new Error('Links rate must be between 0 and 1');\n }\n }\n\n needsTailSampling(): boolean {\n // AdaptiveSampler ALWAYS needs tail sampling to implement error/slow capture\n return true;\n }\n\n shouldSample(context: SamplingContext): boolean {\n // For tail sampling, we optimistically create spans for all requests\n // The real decision happens in shouldKeepTrace() after execution\n // We still store the baseline decision for shouldKeepTrace() to use\n const baselineDecision = Math.random() < this.baselineSampleRate;\n this.samplingDecisions.set(context.args, baselineDecision);\n\n // Always return true to create the span (tail sampling will decide if we keep it)\n return true;\n }\n\n /**\n * Check if any links point to sampled spans.\n *\n * A span is considered linked to a sampled span if any of its links\n * have trace_flags with the sampled bit set (0x01).\n *\n * @param links - Array of span links to check\n * @returns true if any linked span is sampled, false otherwise\n */\n hasSampledLink(links: Link[]): boolean {\n if (!links || links.length === 0) {\n return false;\n }\n return links.some(\n (link) =>\n link.context && (link.context.traceFlags & TraceFlags.SAMPLED) !== 0,\n );\n }\n\n /**\n * Re-evaluate sampling decision after operation completes\n *\n * This allows us to always capture errors and slow requests,\n * even if they weren't initially sampled.\n *\n * @param context - Sampling context\n * @param result - Operation result\n * @returns true if this operation should be kept (not discarded)\n */\n shouldKeepTrace(context: SamplingContext, result: OperationResult): boolean {\n const baselineDecision = this.samplingDecisions.get(context.args) ?? false;\n\n // Always keep errors\n if (this.alwaysSampleErrors && !result.success) {\n if (!baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n error: result.error?.message,\n },\n 'Adaptive sampling: Keeping error trace',\n );\n }\n return true;\n }\n\n // Always keep slow requests\n if (this.alwaysSampleSlow && result.duration >= this.slowThresholdMs) {\n if (!baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n duration: result.duration,\n },\n 'Adaptive sampling: Keeping slow trace',\n );\n }\n return true;\n }\n\n // Check for sampled links (links-based sampling for event-driven systems)\n if (\n this.linksBased &&\n context.links &&\n this.hasSampledLink(context.links)\n ) {\n // Use linksRate to decide whether to keep the linked span\n const keepLinked = Math.random() < this.linksRate;\n if (keepLinked && !baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n linkCount: context.links.length,\n },\n 'Adaptive sampling: Keeping trace due to sampled link',\n );\n }\n return keepLinked;\n }\n\n // Otherwise, use baseline decision\n return baselineDecision;\n }\n}\n\n/**\n * User-based sampler for consistent tracing\n *\n * Always samples requests from specific user IDs.\n * Useful for debugging specific user issues or monitoring VIP users.\n *\n * @example\n * ```typescript\n * new UserIdSampler({\n * baselineSampleRate: 0.01, // 1% of normal users\n * alwaysSampleUsers: ['vip_123'], // Always trace VIP users\n * extractUserId: (args) => args[0]?.userId // Extract user ID from first arg\n * })\n * ```\n */\nexport class UserIdSampler implements Sampler {\n private baselineSampleRate: number;\n private alwaysSampleUsers: Set<string>;\n private extractUserId: (args: unknown[]) => string | undefined;\n private logger?: Logger;\n\n constructor(options: {\n baselineSampleRate?: number;\n alwaysSampleUsers?: string[];\n extractUserId: (args: unknown[]) => string | undefined;\n logger?: Logger;\n }) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.alwaysSampleUsers = new Set(options.alwaysSampleUsers || []);\n this.extractUserId = options.extractUserId;\n this.logger = options.logger;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const userId = this.extractUserId(context.args);\n\n // Always sample specific users\n if (userId && this.alwaysSampleUsers.has(userId)) {\n this.logger?.debug(\n {\n operation: context.operationName,\n userId,\n },\n 'Sampling user request',\n );\n return true;\n }\n\n // For consistent per-user sampling, hash the user ID\n if (userId) {\n const hash = this.hashString(userId);\n return hash < this.baselineSampleRate;\n }\n\n // Fallback to random sampling if no user ID\n return Math.random() < this.baselineSampleRate;\n }\n\n /**\n * Add user IDs to always-sample list\n */\n addAlwaysSampleUsers(...userIds: string[]): void {\n for (const userId of userIds) {\n this.alwaysSampleUsers.add(userId);\n }\n }\n\n /**\n * Remove user IDs from always-sample list\n */\n removeAlwaysSampleUsers(...userIds: string[]): void {\n for (const userId of userIds) {\n this.alwaysSampleUsers.delete(userId);\n }\n }\n\n /**\n * Simple hash function for consistent user sampling\n */\n private hashString(str: string): number {\n return hashUnitInterval(str);\n }\n}\n\n/**\n * Consistent sampler: every service reaches the same verdict for one trace.\n *\n * `RandomSampler` rolls the dice per process, so an upstream service can keep\n * a trace that its downstream drops, leaving a waterfall with holes in it.\n * Hashing a key that travels with the request removes the disagreement. Pass\n * the trace id, or any identifier every hop already shares.\n *\n * @example\n * ```typescript\n * new DeterministicSampler({\n * sampleRate: 0.1,\n * key: (context) => trace.getActiveSpan()?.spanContext().traceId,\n * })\n * ```\n */\nexport class DeterministicSampler implements Sampler {\n private readonly rate: number;\n private readonly key: (context: SamplingContext) => string | undefined;\n\n constructor(options: {\n /** Fraction of traces to keep, 0-1. */\n sampleRate: number;\n /** Identifier shared by every hop of the trace. */\n key: (context: SamplingContext) => string | undefined;\n }) {\n if (options.sampleRate < 0 || options.sampleRate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n this.rate = options.sampleRate;\n this.key = options.key;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const key = this.key(context);\n // No shared key means no agreement to preserve, so fall back to chance.\n if (key === undefined) {\n return Math.random() < this.rate;\n }\n return hashUnitInterval(key) < this.rate;\n }\n\n sampleRate(): number {\n return toSampleRate(this.rate);\n }\n}\n\n/** Bucket for keys seen after the tracked map fills up. */\nconst OVERFLOW_KEY = '__overflow__';\n\n/**\n * Per-key target-rate sampler for workloads with uneven traffic.\n *\n * A single rate serves a skewed workload badly: 1% floods storage with the\n * busiest endpoint and still loses the rare tenant whose failures you need.\n * This sampler counts traffic per key over a rolling window, then sets each\n * key its own rate so every key contributes roughly `targetPerKey` events.\n * Quiet keys survive intact; loud keys get thinned.\n *\n * The first window keeps everything, because no traffic history exists yet.\n * Rates take effect from the second window onward.\n *\n * @example\n * ```typescript\n * new KeyTargetRateSampler({\n * key: (context) => context.operationName,\n * targetPerKey: 10, // ~10 events per key per window\n * windowMs: 30_000,\n * })\n * ```\n */\nexport class KeyTargetRateSampler implements Sampler {\n private readonly key: (context: SamplingContext) => string | undefined;\n private readonly targetPerKey: number;\n private readonly windowMs: number;\n private readonly maxKeys: number;\n private counts = new Map<string, number>();\n private rates = new Map<string, number>();\n private windowStart = Date.now();\n\n constructor(options: {\n /** Groups traffic. Use the operation, route, tenant, or status. */\n key: (context: SamplingContext) => string | undefined;\n /** Events to keep per key per window. Default 10. */\n targetPerKey?: number;\n /** Length of the counting window in milliseconds. Default 30000. */\n windowMs?: number;\n /** Distinct keys to track before overflowing into one bucket. Default 1000. */\n maxKeys?: number;\n }) {\n this.key = options.key;\n this.targetPerKey = options.targetPerKey ?? 10;\n this.windowMs = options.windowMs ?? 30_000;\n this.maxKeys = options.maxKeys ?? 1000;\n\n if (this.targetPerKey <= 0) {\n throw new Error('Target per key must be greater than 0');\n }\n if (this.windowMs <= 0) {\n throw new Error('Window must be greater than 0');\n }\n }\n\n /** Turn the window's observed counts into the next window's rates. */\n private roll(now: number): void {\n if (now - this.windowStart < this.windowMs) {\n return;\n }\n const rates = new Map<string, number>();\n for (const [key, count] of this.counts) {\n rates.set(key, Math.max(1, count / this.targetPerKey));\n }\n this.rates = rates;\n this.counts = new Map();\n this.windowStart = now;\n }\n\n /**\n * Resolve the key, collapsing into one bucket once the map is full.\n *\n * An unbounded key function would otherwise grow the map without limit,\n * which turns a sampler meant to cut cost into a memory leak.\n */\n private resolveKey(context: SamplingContext): string {\n const key = this.key(context) ?? OVERFLOW_KEY;\n if (this.counts.has(key) || this.counts.size < this.maxKeys) {\n return key;\n }\n return OVERFLOW_KEY;\n }\n\n shouldSample(context: SamplingContext): boolean {\n this.roll(Date.now());\n const key = this.resolveKey(context);\n this.counts.set(key, (this.counts.get(key) ?? 0) + 1);\n const rate = this.rates.get(key) ?? 1;\n return rate <= 1 || Math.random() < 1 / rate;\n }\n\n sampleRate(context: SamplingContext): number {\n return this.rates.get(this.resolveKey(context)) ?? 1;\n }\n}\n\n/**\n * Composite sampler that combines multiple samplers\n *\n * Samples if ANY of the child samplers returns true.\n *\n * @example\n * ```typescript\n * new CompositeSampler([\n * new UserIdSampler({ extractUserId: (args) => args[0]?.userId }),\n * new AdaptiveSampler({ baselineSampleRate: 0.1 })\n * ])\n * ```\n */\nexport class CompositeSampler implements Sampler {\n constructor(private readonly samplers: Sampler[]) {\n if (samplers.length === 0) {\n throw new Error('CompositeSampler requires at least one child sampler');\n }\n }\n\n shouldSample(context: SamplingContext): boolean {\n return this.samplers.some((sampler) => sampler.shouldSample(context));\n }\n}\n\n/**\n * Feature flag sampler\n *\n * Always samples requests with specific feature flags enabled.\n * Perfect for correlating A/B test experiments with metrics.\n *\n * @example\n * ```typescript\n * new FeatureFlagSampler({\n * baselineSampleRate: 0.01,\n * alwaysSampleFlags: ['new_checkout', 'experimental_ui'],\n * extractFlags: (args, metadata) => metadata?.featureFlags\n * })\n * ```\n */\nexport class FeatureFlagSampler implements Sampler {\n private baselineSampleRate: number;\n private alwaysSampleFlags: Set<string>;\n private extractFlags: (\n args: unknown[],\n metadata?: Record<string, unknown>,\n ) => string[] | undefined;\n private logger?: Logger;\n\n constructor(options: {\n baselineSampleRate?: number;\n alwaysSampleFlags?: string[];\n extractFlags: (\n args: unknown[],\n metadata?: Record<string, unknown>,\n ) => string[] | undefined;\n logger?: Logger;\n }) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.alwaysSampleFlags = new Set(options.alwaysSampleFlags || []);\n this.extractFlags = options.extractFlags;\n this.logger = options.logger;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const flags = this.extractFlags(context.args, context.metadata);\n\n // Always sample if any monitored flag is enabled\n if (flags && flags.some((flag) => this.alwaysSampleFlags.has(flag))) {\n this.logger?.debug(\n {\n operation: context.operationName,\n flags,\n },\n 'Sampling feature flag request',\n );\n return true;\n }\n\n // Fallback to random sampling\n return Math.random() < this.baselineSampleRate;\n }\n\n /**\n * Add feature flags to always-sample list\n */\n addAlwaysSampleFlags(...flags: string[]): void {\n for (const flag of flags) {\n this.alwaysSampleFlags.add(flag);\n }\n }\n\n /**\n * Remove feature flags from always-sample list\n */\n removeAlwaysSampleFlags(...flags: string[]): void {\n for (const flag of flags) {\n this.alwaysSampleFlags.delete(flag);\n }\n }\n}\n\n// ============================================================================\n// Sampling Presets\n// ============================================================================\n\n/**\n * Named sampling presets for common environments.\n * Use with `init({ sampling: 'production' })` or directly via factories.\n */\nexport type SamplingPreset =\n 'development' | 'errors-only' | 'production' | 'off';\n\n/**\n * Sampling preset factories.\n *\n * For most users, the string shorthand on `init()` is simpler:\n * ```typescript\n * init({ service: 'my-app', sampling: 'production' })\n * ```\n *\n * Use factories when you need to customize:\n * ```typescript\n * init({ service: 'my-app', sampler: samplingPresets.production({ baselineSampleRate: 0.05 }) })\n * ```\n */\nexport const samplingPresets = {\n /** Capture everything — best for local development and debugging */\n development: () => new AlwaysSampler(),\n\n /** Only bad outcomes — zero baseline, errors always kept */\n errorsOnly: () =>\n new AdaptiveSampler({\n baselineSampleRate: 0,\n alwaysSampleErrors: true,\n }),\n\n /**\n * Balanced production defaults — 10% baseline + errors + slow traces.\n * Pass overrides to tune (uses the same option names as AdaptiveSampler).\n */\n production: (overrides?: {\n baselineSampleRate?: number;\n slowThresholdMs?: number;\n alwaysSampleErrors?: boolean;\n alwaysSampleSlow?: boolean;\n }) =>\n new AdaptiveSampler({\n baselineSampleRate: 0.1,\n alwaysSampleErrors: true,\n alwaysSampleSlow: true,\n slowThresholdMs: 1000,\n ...overrides,\n }),\n\n /** Disable sampling entirely */\n off: () => new NeverSampler(),\n};\n\n/**\n * Resolve a preset string to a Sampler instance.\n * Used internally by `init()` when `sampling` string is provided.\n *\n * @throws Error if preset is not recognized\n */\nexport function resolveSamplingPreset(preset: SamplingPreset): Sampler {\n switch (preset) {\n case 'development': {\n return samplingPresets.development();\n }\n case 'errors-only': {\n return samplingPresets.errorsOnly();\n }\n case 'production': {\n return samplingPresets.production();\n }\n case 'off': {\n return samplingPresets.off();\n }\n default: {\n throw new Error(\n `Unknown sampling preset: \"${preset}\". Valid presets: development, errors-only, production, off`,\n );\n }\n }\n}\n\n// ============================================================================\n// Link Helper Functions\n// ============================================================================\n\n/**\n * Create a Link from W3C trace context headers (e.g., from a message queue).\n *\n * This is useful for message consumers that need to link to the producer span.\n * The headers should contain at least a `traceparent` header in W3C format.\n *\n * @param headers - Dictionary containing traceparent/tracestate headers\n * @param attributes - Optional attributes for the link\n * @returns Link object if context could be extracted, null otherwise\n *\n * @example\n * ```typescript\n * // In a Kafka consumer\n * const headers = { traceparent: '00-abc123...-def456...-01' };\n * const link = createLinkFromHeaders(headers);\n * if (link) {\n * // Use with tracer.startActiveSpan options or ctx.addLink()\n * tracer.startActiveSpan('process.message', { links: [link] }, span => { ... });\n * }\n * ```\n */\nexport function createLinkFromHeaders(\n headers: Record<string, string>,\n attributes?: Attributes,\n): Link | null {\n // Parse W3C traceparent header directly for reliability\n // Format: version-traceId-spanId-traceFlags (e.g., 00-abc123...-def456...-01)\n const traceparent = headers.traceparent || headers['traceparent'];\n if (!traceparent) {\n return null;\n }\n\n const spanContext = parseTraceparent(traceparent);\n if (!spanContext || !isValidSpanContext(spanContext)) {\n return null;\n }\n\n return {\n context: spanContext,\n attributes: attributes ?? {},\n };\n}\n\n/**\n * Extract Links from a batch of messages for fan-in scenarios.\n *\n * Useful for batch processing where multiple producer spans should be linked.\n * This enables tracing causality in event-driven architectures where a single\n * consumer processes messages from multiple producers.\n *\n * @param messages - List of message objects\n * @param headersKey - Key in each message containing trace headers (default: 'headers')\n * @returns List of Link objects for all valid trace contexts\n *\n * @example\n * ```typescript\n * // Processing a batch of SQS/Kafka messages\n * const messages = [\n * { body: '...', headers: { traceparent: '...' } },\n * { body: '...', headers: { traceparent: '...' } },\n * ];\n * const links = extractLinksFromBatch(messages);\n *\n * tracer.startActiveSpan('process.batch', { links }, span => {\n * for (const msg of messages) {\n * processMessage(msg);\n * }\n * });\n * ```\n */\nexport function extractLinksFromBatch(\n messages: Array<{ [key: string]: unknown }>,\n headersKey: string = 'headers',\n): Link[] {\n const links: Link[] = [];\n\n for (const msg of messages) {\n const msgHeaders = msg[headersKey];\n if (msgHeaders && typeof msgHeaders === 'object' && msgHeaders !== null) {\n const link = createLinkFromHeaders(msgHeaders as Record<string, string>, {\n 'messaging.batch.message_index': links.length,\n });\n if (link) {\n links.push(link);\n }\n }\n }\n\n return links;\n}\n\n/**\n * Parse W3C traceparent header into SpanContext\n * Format: version-traceId-spanId-traceFlags (e.g., 00-abc123...-def456...-01)\n *\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\nfunction parseTraceparent(\n traceparent: string,\n): import('@opentelemetry/api').SpanContext | null {\n // W3C traceparent format: version-traceId-parentId-traceFlags\n // Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01\n const TRACEPARENT_REGEX =\n /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/i;\n\n const match = traceparent.match(TRACEPARENT_REGEX);\n if (!match || match.length < 5) {\n return null;\n }\n\n const version = match[1];\n const traceId = match[2];\n const spanId = match[3];\n const flags = match[4];\n\n // Validate all parts are present (TypeScript narrowing)\n if (!version || !traceId || !spanId || !flags) {\n return null;\n }\n\n // Version 00 is currently the only version, but we should be forward compatible\n if (version === 'ff') {\n // Version ff is invalid according to spec\n return null;\n }\n\n return {\n traceId,\n spanId,\n traceFlags: Number.parseInt(flags, 16),\n isRemote: true,\n };\n}\n\n/**\n * Check if a SpanContext is valid (has non-zero trace and span IDs)\n */\nfunction isValidSpanContext(\n spanContext: import('@opentelemetry/api').SpanContext | null,\n): spanContext is import('@opentelemetry/api').SpanContext {\n if (!spanContext) return false;\n // TraceId should not be all zeros (00000000000000000000000000000000)\n // SpanId should not be all zeros (0000000000000000)\n return (\n spanContext.traceId !== '00000000000000000000000000000000' &&\n spanContext.spanId !== '0000000000000000'\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sampling.js","names":[],"sources":["../src/sampling.ts"],"sourcesContent":["/**\n * Sampling Strategies\n *\n * Provides intelligent sampling beyond simple random rates.\n * Helps reduce telemetry costs while capturing critical data.\n *\n * Key strategies:\n * - Always trace errors and slow requests (critical for debugging)\n * - Sample by user ID for consistent request tracing\n * - Adaptive sampling based on load\n * - Sample by feature flags for A/B testing correlation\n *\n * @example\n * ```typescript\n * import { AlwaysOnErrorSampler, UserIdSampler } from './sampling'\n *\n * @Instrumented({\n * serviceName: 'user',\n * sampler: new AlwaysOnErrorSampler(0.1) // 10% baseline, 100% on errors\n * })\n * class UserService { }\n * ```\n */\n\nimport type { Link, Attributes } from '@opentelemetry/api';\nimport { TraceFlags } from '@opentelemetry/api';\nimport { type Logger } from './logger';\n\n/**\n * Tail sampling attribute keys (autotel-internal, not OTel semconv)\n */\nexport const AUTOTEL_SAMPLING_TAIL_KEEP = 'autotel.sampling.tail.keep';\nexport const AUTOTEL_SAMPLING_TAIL_EVALUATED =\n 'autotel.sampling.tail.evaluated';\n\n/**\n * How many events each kept event stands for, expressed as \"1 in N\".\n *\n * A query that counts sampled spans undercounts the population. Multiplying\n * each kept event by this rate restores the estimate. Autotel records the\n * attribute only when N exceeds 1, so fully captured spans stay clean.\n */\nexport const AUTOTEL_SAMPLING_RATE = 'autotel.sampling.rate';\n\n/**\n * Convert a keep probability into the \"1 in N\" rate reported on spans.\n *\n * Keeping 10% of traces means each survivor stands for 10, so the two numbers\n * are reciprocals and easy to publish the wrong way round.\n */\nfunction toSampleRate(probability: number): number {\n return probability > 0 ? 1 / probability : 0;\n}\n\n/**\n * Map a string to a stable, evenly spread position in the unit interval.\n *\n * Two processes that hash the same key reach the same number, which is what\n * lets independent services agree on one trace's sampling decision.\n *\n * The spread matters as much as the stability. Real sampling keys share long\n * prefixes: `user_1000`, `user_1001`, `checkout-trace-0001`. A plain\n * multiply-and-add hash lets that shared prefix dominate the high bits, so a\n * whole key family lands in one narrow band and a rate of 0.1 keeps all of\n * them or none of them. FNV-1a followed by the murmur3 finalizer mixes the\n * low bits back through the word, so keys that differ in one character land\n * far apart.\n */\nexport function hashUnitInterval(value: string): number {\n let hash = 0x81_1c_9d_c5; // FNV-1a 32-bit offset basis\n for (let i = 0; i < value.length; i++) {\n hash ^= value.codePointAt(i) ?? 0;\n hash = Math.imul(hash, 0x01_00_01_93); // FNV prime\n }\n\n // murmur3 fmix32 avalanche\n hash ^= hash >>> 16;\n hash = Math.imul(hash, 0x85_eb_ca_6b);\n hash ^= hash >>> 13;\n hash = Math.imul(hash, 0xc2_b2_ae_35);\n hash ^= hash >>> 16;\n\n return (hash >>> 0) / 4_294_967_296;\n}\n\n/**\n * Sampler interface - return true to trace, false to skip\n */\nexport interface Sampler {\n /**\n * Decide whether to trace this operation\n *\n * @param context - Sampling context\n * @returns true to trace, false to skip\n */\n shouldSample(context: SamplingContext): boolean;\n\n /**\n * Whether this sampler needs tail sampling (post-execution decision)\n * If true, spans are always created and shouldKeepTrace() is called after execution\n *\n * @returns true if this sampler needs to evaluate after operation completes\n */\n needsTailSampling?(): boolean;\n\n /**\n * Re-evaluate sampling decision after operation completes (tail sampling)\n * Only called if needsTailSampling() returns true\n *\n * @param context - Sampling context\n * @param result - Operation result\n * @returns true if this trace should be kept, false to drop it\n */\n shouldKeepTrace?(context: SamplingContext, result: OperationResult): boolean;\n\n /**\n * How many events a kept event represents, as \"1 in N\".\n *\n * Autotel writes the result to {@link AUTOTEL_SAMPLING_RATE} so an analyst\n * can reweight counts. Return 1 when the sampler keeps everything.\n *\n * @param context - Sampling context\n * @returns Events represented per kept event\n */\n sampleRate?(context: SamplingContext): number;\n}\n\n/**\n * Context information for sampling decisions\n */\nexport interface SamplingContext {\n /** Operation name */\n operationName: string;\n /** Method arguments (for extracting user IDs, etc.) */\n args: unknown[];\n /** Optional metadata (e.g., feature flags, request headers) */\n metadata?: Record<string, unknown>;\n /** Optional span links for links-based sampling */\n links?: Link[];\n}\n\n/**\n * Result of a trace operation (for post-execution sampling)\n */\nexport interface OperationResult {\n /** Whether the operation succeeded */\n success: boolean;\n /** Duration in milliseconds */\n duration: number;\n /** Error if operation failed */\n error?: Error;\n}\n\n/**\n * Simple random sampler\n *\n * @example\n * ```typescript\n * new RandomSampler(0.1) // Sample 10% of requests\n * ```\n */\nexport class RandomSampler implements Sampler {\n constructor(private readonly rate: number) {\n if (rate < 0 || rate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n }\n\n shouldSample(_context: SamplingContext): boolean {\n return Math.random() < this.rate;\n }\n\n sampleRate(): number {\n return toSampleRate(this.rate);\n }\n}\n\n/**\n * Always sample (100% tracing)\n */\nexport class AlwaysSampler implements Sampler {\n shouldSample(_context: SamplingContext): boolean {\n return true;\n }\n}\n\n/**\n * Never sample (0% tracing)\n */\nexport class NeverSampler implements Sampler {\n shouldSample(_context: SamplingContext): boolean {\n return false;\n }\n}\n\n/**\n * Adaptive sampler that always traces errors and slow requests\n *\n * This is the recommended sampler for production use.\n * It ensures you never miss critical issues while keeping costs down.\n *\n * Strategy:\n * - Always trace errors (critical for debugging)\n * - Always trace slow requests (performance issues)\n * - Use baseline sample rate for successful fast requests\n *\n * **IMPORTANT - Tail Sampling Requirement:**\n * This sampler uses tail sampling (makes decisions AFTER execution).\n * You MUST use TailSamplingSpanProcessor for it to work correctly:\n *\n * - If using initInstrumentation(): TailSamplingSpanProcessor is auto-configured\n * - If using custom TracerProvider: You MUST manually register TailSamplingSpanProcessor\n *\n * Without TailSamplingSpanProcessor, ALL spans are exported (defeating the cost savings).\n *\n * @see TailSamplingSpanProcessor\n * @see README.md \"Tail Sampling with Custom Providers\" section\n *\n * @example\n * ```typescript\n * new AdaptiveSampler({\n * baselineSampleRate: 0.1, // 10% of normal requests\n * slowThresholdMs: 1000, // Requests > 1s are \"slow\"\n * alwaysSampleErrors: true, // Always trace errors\n * alwaysSampleSlow: true // Always trace slow requests\n * })\n * ```\n */\nexport class AdaptiveSampler implements Sampler {\n private baselineSampleRate: number;\n private slowThresholdMs: number;\n private alwaysSampleErrors: boolean;\n private alwaysSampleSlow: boolean;\n private linksBased: boolean;\n private linksRate: number;\n private logger?: Logger;\n\n // Track whether we should sample this request\n private readonly samplingDecisions = new WeakMap<unknown[], boolean>();\n // Track operation results to enable post-execution decision\n private readonly operationResults = new WeakMap<unknown[], OperationResult>();\n\n constructor(\n options: {\n baselineSampleRate?: number;\n slowThresholdMs?: number;\n alwaysSampleErrors?: boolean;\n alwaysSampleSlow?: boolean;\n /** Enable links-based sampling for event-driven architectures */\n linksBased?: boolean;\n /** Sampling rate for spans linked to sampled spans (0.0-1.0) */\n linksRate?: number;\n logger?: Logger;\n } = {},\n ) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.slowThresholdMs = options.slowThresholdMs ?? 1000;\n this.alwaysSampleErrors = options.alwaysSampleErrors ?? true;\n this.alwaysSampleSlow = options.alwaysSampleSlow ?? true;\n this.linksBased = options.linksBased ?? false;\n this.linksRate = options.linksRate ?? 1;\n this.logger = options.logger;\n\n if (this.baselineSampleRate < 0 || this.baselineSampleRate > 1) {\n throw new Error('Baseline sample rate must be between 0 and 1');\n }\n if (this.linksRate < 0 || this.linksRate > 1) {\n throw new Error('Links rate must be between 0 and 1');\n }\n }\n\n needsTailSampling(): boolean {\n // AdaptiveSampler ALWAYS needs tail sampling to implement error/slow capture\n return true;\n }\n\n shouldSample(context: SamplingContext): boolean {\n // For tail sampling, we optimistically create spans for all requests\n // The real decision happens in shouldKeepTrace() after execution\n // We still store the baseline decision for shouldKeepTrace() to use\n const baselineDecision = Math.random() < this.baselineSampleRate;\n this.samplingDecisions.set(context.args, baselineDecision);\n\n // Always return true to create the span (tail sampling will decide if we keep it)\n return true;\n }\n\n /**\n * Check if any links point to sampled spans.\n *\n * A span is considered linked to a sampled span if any of its links\n * have trace_flags with the sampled bit set (0x01).\n *\n * @param links - Array of span links to check\n * @returns true if any linked span is sampled, false otherwise\n */\n hasSampledLink(links: Link[]): boolean {\n if (!links || links.length === 0) {\n return false;\n }\n return links.some(\n (link) =>\n link.context && (link.context.traceFlags & TraceFlags.SAMPLED) !== 0,\n );\n }\n\n /**\n * Re-evaluate sampling decision after operation completes\n *\n * This allows us to always capture errors and slow requests,\n * even if they weren't initially sampled.\n *\n * @param context - Sampling context\n * @param result - Operation result\n * @returns true if this operation should be kept (not discarded)\n */\n shouldKeepTrace(context: SamplingContext, result: OperationResult): boolean {\n const baselineDecision = this.samplingDecisions.get(context.args) ?? false;\n\n // Always keep errors\n if (this.alwaysSampleErrors && !result.success) {\n if (!baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n error: result.error?.message,\n },\n 'Adaptive sampling: Keeping error trace',\n );\n }\n return true;\n }\n\n // Always keep slow requests\n if (this.alwaysSampleSlow && result.duration >= this.slowThresholdMs) {\n if (!baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n duration: result.duration,\n },\n 'Adaptive sampling: Keeping slow trace',\n );\n }\n return true;\n }\n\n // Check for sampled links (links-based sampling for event-driven systems)\n if (\n this.linksBased &&\n context.links &&\n this.hasSampledLink(context.links)\n ) {\n // Use linksRate to decide whether to keep the linked span\n const keepLinked = Math.random() < this.linksRate;\n if (keepLinked && !baselineDecision) {\n this.logger?.debug(\n {\n operation: context.operationName,\n linkCount: context.links.length,\n },\n 'Adaptive sampling: Keeping trace due to sampled link',\n );\n }\n return keepLinked;\n }\n\n // Otherwise, use baseline decision\n return baselineDecision;\n }\n}\n\n/**\n * User-based sampler for consistent tracing\n *\n * Always samples requests from specific user IDs.\n * Useful for debugging specific user issues or monitoring VIP users.\n *\n * @example\n * ```typescript\n * new UserIdSampler({\n * baselineSampleRate: 0.01, // 1% of normal users\n * alwaysSampleUsers: ['vip_123'], // Always trace VIP users\n * extractUserId: (args) => args[0]?.userId // Extract user ID from first arg\n * })\n * ```\n */\nexport class UserIdSampler implements Sampler {\n private baselineSampleRate: number;\n private alwaysSampleUsers: Set<string>;\n private extractUserId: (args: unknown[]) => string | undefined;\n private logger?: Logger;\n\n constructor(options: {\n baselineSampleRate?: number;\n alwaysSampleUsers?: string[];\n extractUserId: (args: unknown[]) => string | undefined;\n logger?: Logger;\n }) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.alwaysSampleUsers = new Set(options.alwaysSampleUsers || []);\n this.extractUserId = options.extractUserId;\n this.logger = options.logger;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const userId = this.extractUserId(context.args);\n\n // Always sample specific users\n if (userId && this.alwaysSampleUsers.has(userId)) {\n this.logger?.debug(\n {\n operation: context.operationName,\n userId,\n },\n 'Sampling user request',\n );\n return true;\n }\n\n // For consistent per-user sampling, hash the user ID\n if (userId) {\n const hash = this.hashString(userId);\n return hash < this.baselineSampleRate;\n }\n\n // Fallback to random sampling if no user ID\n return Math.random() < this.baselineSampleRate;\n }\n\n /**\n * Add user IDs to always-sample list\n */\n addAlwaysSampleUsers(...userIds: string[]): void {\n for (const userId of userIds) {\n this.alwaysSampleUsers.add(userId);\n }\n }\n\n /**\n * Remove user IDs from always-sample list\n */\n removeAlwaysSampleUsers(...userIds: string[]): void {\n for (const userId of userIds) {\n this.alwaysSampleUsers.delete(userId);\n }\n }\n\n /**\n * Simple hash function for consistent user sampling\n */\n private hashString(str: string): number {\n return hashUnitInterval(str);\n }\n}\n\n/**\n * Consistent sampler: every service reaches the same verdict for one trace.\n *\n * `RandomSampler` rolls the dice per process, so an upstream service can keep\n * a trace that its downstream drops, leaving a waterfall with holes in it.\n * Hashing a key that travels with the request removes the disagreement. Pass\n * the trace id, or any identifier every hop already shares.\n *\n * @example\n * ```typescript\n * new DeterministicSampler({\n * sampleRate: 0.1,\n * key: (context) => trace.getActiveSpan()?.spanContext().traceId,\n * })\n * ```\n */\nexport class DeterministicSampler implements Sampler {\n private readonly rate: number;\n private readonly key: (context: SamplingContext) => string | undefined;\n\n constructor(options: {\n /** Fraction of traces to keep, 0-1. */\n sampleRate: number;\n /** Identifier shared by every hop of the trace. */\n key: (context: SamplingContext) => string | undefined;\n }) {\n if (options.sampleRate < 0 || options.sampleRate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n this.rate = options.sampleRate;\n this.key = options.key;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const key = this.key(context);\n // No shared key means no agreement to preserve, so fall back to chance.\n if (key === undefined) {\n return Math.random() < this.rate;\n }\n return hashUnitInterval(key) < this.rate;\n }\n\n sampleRate(): number {\n return toSampleRate(this.rate);\n }\n}\n\n/** Bucket for keys seen after the tracked map fills up. */\nconst OVERFLOW_KEY = '__overflow__';\n\n/**\n * Per-key target-rate sampler for workloads with uneven traffic.\n *\n * A single rate serves a skewed workload badly: 1% floods storage with the\n * busiest endpoint and still loses the rare tenant whose failures you need.\n * This sampler counts traffic per key over a rolling window, then sets each\n * key its own rate so every key contributes roughly `targetPerKey` events.\n * Quiet keys survive intact; loud keys get thinned.\n *\n * The first window keeps everything, because no traffic history exists yet.\n * Rates take effect from the second window onward.\n *\n * @example\n * ```typescript\n * new KeyTargetRateSampler({\n * key: (context) => context.operationName,\n * targetPerKey: 10, // ~10 events per key per window\n * windowMs: 30_000,\n * })\n * ```\n */\nexport class KeyTargetRateSampler implements Sampler {\n private readonly key: (context: SamplingContext) => string | undefined;\n private readonly targetPerKey: number;\n private readonly windowMs: number;\n private readonly maxKeys: number;\n private counts = new Map<string, number>();\n private rates = new Map<string, number>();\n private windowStart = Date.now();\n\n constructor(options: {\n /** Groups traffic. Use the operation, route, tenant, or status. */\n key: (context: SamplingContext) => string | undefined;\n /** Events to keep per key per window. Default 10. */\n targetPerKey?: number;\n /** Length of the counting window in milliseconds. Default 30000. */\n windowMs?: number;\n /** Distinct keys to track before overflowing into one bucket. Default 1000. */\n maxKeys?: number;\n }) {\n this.key = options.key;\n this.targetPerKey = options.targetPerKey ?? 10;\n this.windowMs = options.windowMs ?? 30_000;\n this.maxKeys = options.maxKeys ?? 1000;\n\n if (this.targetPerKey <= 0) {\n throw new Error('Target per key must be greater than 0');\n }\n if (this.windowMs <= 0) {\n throw new Error('Window must be greater than 0');\n }\n }\n\n /** Turn the window's observed counts into the next window's rates. */\n private roll(now: number): void {\n if (now - this.windowStart < this.windowMs) {\n return;\n }\n const rates = new Map<string, number>();\n for (const [key, count] of this.counts) {\n rates.set(key, Math.max(1, count / this.targetPerKey));\n }\n this.rates = rates;\n this.counts = new Map();\n this.windowStart = now;\n }\n\n /**\n * Resolve the key, collapsing into one bucket once the map is full.\n *\n * An unbounded key function would otherwise grow the map without limit,\n * which turns a sampler meant to cut cost into a memory leak.\n */\n private resolveKey(context: SamplingContext): string {\n const key = this.key(context) ?? OVERFLOW_KEY;\n if (this.counts.has(key) || this.counts.size < this.maxKeys) {\n return key;\n }\n return OVERFLOW_KEY;\n }\n\n shouldSample(context: SamplingContext): boolean {\n this.roll(Date.now());\n const key = this.resolveKey(context);\n this.counts.set(key, (this.counts.get(key) ?? 0) + 1);\n const rate = this.rates.get(key) ?? 1;\n return rate <= 1 || Math.random() < 1 / rate;\n }\n\n sampleRate(context: SamplingContext): number {\n return this.rates.get(this.resolveKey(context)) ?? 1;\n }\n}\n\n/**\n * Composite sampler that combines multiple samplers\n *\n * Samples if ANY of the child samplers returns true.\n *\n * @example\n * ```typescript\n * new CompositeSampler([\n * new UserIdSampler({ extractUserId: (args) => args[0]?.userId }),\n * new AdaptiveSampler({ baselineSampleRate: 0.1 })\n * ])\n * ```\n */\nexport class CompositeSampler implements Sampler {\n constructor(private readonly samplers: Sampler[]) {\n if (samplers.length === 0) {\n throw new Error('CompositeSampler requires at least one child sampler');\n }\n }\n\n shouldSample(context: SamplingContext): boolean {\n return this.samplers.some((sampler) => sampler.shouldSample(context));\n }\n}\n\n/**\n * Feature flag sampler\n *\n * Always samples requests with specific feature flags enabled.\n * Perfect for correlating A/B test experiments with metrics.\n *\n * @example\n * ```typescript\n * new FeatureFlagSampler({\n * baselineSampleRate: 0.01,\n * alwaysSampleFlags: ['new_checkout', 'experimental_ui'],\n * extractFlags: (args, metadata) => metadata?.featureFlags\n * })\n * ```\n */\nexport class FeatureFlagSampler implements Sampler {\n private baselineSampleRate: number;\n private alwaysSampleFlags: Set<string>;\n private extractFlags: (\n args: unknown[],\n metadata?: Record<string, unknown>,\n ) => string[] | undefined;\n private logger?: Logger;\n\n constructor(options: {\n baselineSampleRate?: number;\n alwaysSampleFlags?: string[];\n extractFlags: (\n args: unknown[],\n metadata?: Record<string, unknown>,\n ) => string[] | undefined;\n logger?: Logger;\n }) {\n this.baselineSampleRate = options.baselineSampleRate ?? 0.1;\n this.alwaysSampleFlags = new Set(options.alwaysSampleFlags || []);\n this.extractFlags = options.extractFlags;\n this.logger = options.logger;\n }\n\n shouldSample(context: SamplingContext): boolean {\n const flags = this.extractFlags(context.args, context.metadata);\n\n // Always sample if any monitored flag is enabled\n if (flags && flags.some((flag) => this.alwaysSampleFlags.has(flag))) {\n this.logger?.debug(\n {\n operation: context.operationName,\n flags,\n },\n 'Sampling feature flag request',\n );\n return true;\n }\n\n // Fallback to random sampling\n return Math.random() < this.baselineSampleRate;\n }\n\n /**\n * Add feature flags to always-sample list\n */\n addAlwaysSampleFlags(...flags: string[]): void {\n for (const flag of flags) {\n this.alwaysSampleFlags.add(flag);\n }\n }\n\n /**\n * Remove feature flags from always-sample list\n */\n removeAlwaysSampleFlags(...flags: string[]): void {\n for (const flag of flags) {\n this.alwaysSampleFlags.delete(flag);\n }\n }\n}\n\n// ============================================================================\n// Sampling Presets\n// ============================================================================\n\n/**\n * Named sampling presets for common environments.\n * Use with `init({ sampling: 'production' })` or directly via factories.\n */\nexport type SamplingPreset =\n 'development' | 'errors-only' | 'production' | 'off';\n\n/**\n * Sampling preset factories.\n *\n * For most users, the string shorthand on `init()` is simpler:\n * ```typescript\n * init({ service: 'my-app', sampling: 'production' })\n * ```\n *\n * Use factories when you need to customize:\n * ```typescript\n * init({ service: 'my-app', sampler: samplingPresets.production({ baselineSampleRate: 0.05 }) })\n * ```\n */\nexport const samplingPresets = {\n /** Capture everything — best for local development and debugging */\n development: () => new AlwaysSampler(),\n\n /** Only bad outcomes — zero baseline, errors always kept */\n errorsOnly: () =>\n new AdaptiveSampler({\n baselineSampleRate: 0,\n alwaysSampleErrors: true,\n }),\n\n /**\n * Balanced production defaults — 10% baseline + errors + slow traces.\n * Pass overrides to tune (uses the same option names as AdaptiveSampler).\n */\n production: (overrides?: {\n baselineSampleRate?: number;\n slowThresholdMs?: number;\n alwaysSampleErrors?: boolean;\n alwaysSampleSlow?: boolean;\n }) =>\n new AdaptiveSampler({\n baselineSampleRate: 0.1,\n alwaysSampleErrors: true,\n alwaysSampleSlow: true,\n slowThresholdMs: 1000,\n ...overrides,\n }),\n\n /** Disable sampling entirely */\n off: () => new NeverSampler(),\n};\n\n/**\n * Resolve a preset string to a Sampler instance.\n * Used internally by `init()` when `sampling` string is provided.\n *\n * @throws Error if preset is not recognized\n */\nexport function resolveSamplingPreset(preset: SamplingPreset): Sampler {\n switch (preset) {\n case 'development': {\n return samplingPresets.development();\n }\n case 'errors-only': {\n return samplingPresets.errorsOnly();\n }\n case 'production': {\n return samplingPresets.production();\n }\n case 'off': {\n return samplingPresets.off();\n }\n default: {\n throw new Error(\n `Unknown sampling preset: \"${preset}\". Valid presets: development, errors-only, production, off`,\n );\n }\n }\n}\n\n// ============================================================================\n// Link Helper Functions\n// ============================================================================\n\n/**\n * Create a Link from W3C trace context headers (e.g., from a message queue).\n *\n * This is useful for message consumers that need to link to the producer span.\n * The headers should contain at least a `traceparent` header in W3C format.\n *\n * @param headers - Dictionary containing traceparent/tracestate headers\n * @param attributes - Optional attributes for the link\n * @returns Link object if context could be extracted, null otherwise\n *\n * @example\n * ```typescript\n * // In a Kafka consumer\n * const headers = { traceparent: '00-abc123...-def456...-01' };\n * const link = createLinkFromHeaders(headers);\n * if (link) {\n * // Use with tracer.startActiveSpan options or ctx.addLink()\n * tracer.startActiveSpan('process.message', { links: [link] }, span => { ... });\n * }\n * ```\n */\nexport function createLinkFromHeaders(\n headers: Record<string, string>,\n attributes?: Attributes,\n): Link | null {\n // Parse W3C traceparent header directly for reliability\n // Format: version-traceId-spanId-traceFlags (e.g., 00-abc123...-def456...-01)\n const traceparent = headers.traceparent || headers['traceparent'];\n if (!traceparent) {\n return null;\n }\n\n const spanContext = parseTraceparent(traceparent);\n if (!spanContext || !isValidSpanContext(spanContext)) {\n return null;\n }\n\n return {\n context: spanContext,\n attributes: attributes ?? {},\n };\n}\n\n/**\n * Extract Links from a batch of messages for fan-in scenarios.\n *\n * Useful for batch processing where multiple producer spans should be linked.\n * This enables tracing causality in event-driven architectures where a single\n * consumer processes messages from multiple producers.\n *\n * @param messages - List of message objects\n * @param headersKey - Key in each message containing trace headers (default: 'headers')\n * @returns List of Link objects for all valid trace contexts\n *\n * @example\n * ```typescript\n * // Processing a batch of SQS/Kafka messages\n * const messages = [\n * { body: '...', headers: { traceparent: '...' } },\n * { body: '...', headers: { traceparent: '...' } },\n * ];\n * const links = extractLinksFromBatch(messages);\n *\n * tracer.startActiveSpan('process.batch', { links }, span => {\n * for (const msg of messages) {\n * processMessage(msg);\n * }\n * });\n * ```\n */\nexport function extractLinksFromBatch(\n messages: Array<{ [key: string]: unknown }>,\n headersKey: string = 'headers',\n): Link[] {\n const links: Link[] = [];\n\n for (const msg of messages) {\n const msgHeaders = msg[headersKey];\n if (msgHeaders && typeof msgHeaders === 'object' && msgHeaders !== null) {\n const link = createLinkFromHeaders(msgHeaders as Record<string, string>, {\n 'messaging.batch.message_index': links.length,\n });\n if (link) {\n links.push(link);\n }\n }\n }\n\n return links;\n}\n\n/**\n * Parse W3C traceparent header into SpanContext\n * Format: version-traceId-spanId-traceFlags (e.g., 00-abc123...-def456...-01)\n *\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\nfunction parseTraceparent(\n traceparent: string,\n): import('@opentelemetry/api').SpanContext | null {\n // W3C traceparent format: version-traceId-parentId-traceFlags\n // Example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01\n const TRACEPARENT_REGEX =\n /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/i;\n\n const match = traceparent.match(TRACEPARENT_REGEX);\n if (!match || match.length < 5) {\n return null;\n }\n\n const version = match[1];\n const traceId = match[2];\n const spanId = match[3];\n const flags = match[4];\n\n // Validate all parts are present (TypeScript narrowing)\n if (!version || !traceId || !spanId || !flags) {\n return null;\n }\n\n // Version 00 is currently the only version, but we should be forward compatible\n if (version === 'ff') {\n // Version ff is invalid according to spec\n return null;\n }\n\n return {\n traceId,\n spanId,\n traceFlags: Number.parseInt(flags, 16),\n isRemote: true,\n };\n}\n\n/**\n * Check if a SpanContext is valid (has non-zero trace and span IDs)\n */\nfunction isValidSpanContext(\n spanContext: import('@opentelemetry/api').SpanContext | null,\n): spanContext is import('@opentelemetry/api').SpanContext {\n if (!spanContext) return false;\n // TraceId should not be all zeros (00000000000000000000000000000000)\n // SpanId should not be all zeros (0000000000000000)\n return (\n spanContext.traceId !== '00000000000000000000000000000000' &&\n spanContext.spanId !== '0000000000000000'\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"security-schema.cjs","names":[],"sources":["../src/security-schema.ts"],"sourcesContent":["/**\n * Security telemetry wire schema — the single source of truth for the\n * `security.*` span-attribute contract emitted by `autotel-audit`\n * (`securityEvent()`, `withSecurity()`, `createSecuritySignalProcessor()`)\n * and consumed by `autotel-subscribers`, `autotel-devtools`, and the\n * `autotel security` CLI commands.\n *\n * Dependency-free and side-effect-free by design: safe to import from\n * browser bundles (devtools widget) and anything else that only needs\n * the constants, without pulling in the OpenTelemetry SDK.\n */\n\nexport type SecuritySeverity = 'info' | 'warning' | 'error' | 'critical';\n\n/** All severities, lowest first. */\nexport const SECURITY_SEVERITIES: readonly SecuritySeverity[] = [\n 'info',\n 'warning',\n 'error',\n 'critical',\n];\n\n/** Numeric rank per severity for threshold comparisons. */\nexport const SECURITY_SEVERITY_RANK: Record<SecuritySeverity, number> = {\n info: 0,\n warning: 1,\n error: 2,\n critical: 3,\n};\n\n/**\n * Parse an untrusted value (span attribute, event payload field) into a\n * severity, falling back when it is missing or malformed.\n */\nexport function parseSecuritySeverity(\n value: unknown,\n fallback: SecuritySeverity = 'info',\n): SecuritySeverity {\n return typeof value === 'string' && value in SECURITY_SEVERITY_RANK\n ? (value as SecuritySeverity)\n : fallback;\n}\n\n/** `true` when `severity` meets or exceeds `min`. */\nexport function securitySeverityAtLeast(\n severity: SecuritySeverity,\n min: SecuritySeverity,\n): boolean {\n return SECURITY_SEVERITY_RANK[severity] >= SECURITY_SEVERITY_RANK[min];\n}\n\n/** The higher-ranked of two severities (e.g. escalate failures to ≥ error). */\nexport function escalateSecuritySeverity(\n severity: SecuritySeverity,\n floor: SecuritySeverity,\n): SecuritySeverity {\n return SECURITY_SEVERITY_RANK[severity] >= SECURITY_SEVERITY_RANK[floor]\n ? severity\n : floor;\n}\n\n/**\n * Span attribute keys of the security schema. Emitters and consumers must\n * reference these instead of re-typing the strings.\n */\nexport const SECURITY_ATTR = {\n /** Marker set on every span carrying a security event. */\n marker: 'autotel.security',\n /** Set when the event was force-kept through tail sampling. */\n forceKeep: 'autotel.security.force_keep',\n event: 'security.event',\n category: 'security.category',\n outcome: 'security.outcome',\n severity: 'security.severity',\n actorId: 'security.actor_id',\n targetType: 'security.target_type',\n targetId: 'security.target_id',\n tenantId: 'security.tenant_id',\n reason: 'security.reason',\n /** Custom metadata keys dropped because they looked credential-shaped. */\n droppedKeys: 'security.dropped_keys',\n /** Set by the signal processor on suspicious request paths. */\n suspiciousRequest: 'security.suspicious_request',\n /** Pattern name that flagged a suspicious request, e.g. `path_traversal`. */\n signal: 'security.signal',\n} as const;\n\n/** Metric names emitted by the security instrumentation. */\nexport const SECURITY_METRICS = {\n events: 'autotel.security.events',\n httpSuspicious: 'autotel.security.http.suspicious',\n httpDenied: 'autotel.security.http.denied',\n anomaly: 'autotel.security.anomaly',\n heartbeat: 'autotel.security.heartbeat',\n} as const;\n\n/** HTTP statuses counted as denied responses by default. */\nexport const SECURITY_DENIED_STATUSES: readonly number[] = [401, 403, 429];\n\n/**\n * Span attributes carrying the HTTP response status, current semconv\n * first, legacy fallback second.\n */\nexport const HTTP_STATUS_ATTRIBUTES: readonly string[] = [\n 'http.response.status_code',\n 'http.status_code',\n];\n"],"mappings":";;;;AAeA,MAAa,sBAAmD;CAC9D;CACA;CACA;CACA;AACF;;AAGA,MAAa,yBAA2D;CACtE,MAAM;CACN,SAAS;CACT,OAAO;CACP,UAAU;AACZ;;;;;AAMA,SAAgB,sBACd,OACA,WAA6B,QACX;CAClB,OAAO,OAAO,UAAU,YAAY,SAAS,yBACxC,QACD;AACN;;AAGA,SAAgB,wBACd,UACA,KACS;CACT,OAAO,uBAAuB,aAAa,uBAAuB;AACpE;;AAGA,SAAgB,yBACd,UACA,OACkB;CAClB,OAAO,uBAAuB,aAAa,uBAAuB,SAC9D,WACA;AACN;;;;;AAMA,MAAa,gBAAgB;;CAE3B,QAAQ;;CAER,WAAW;CACX,OAAO;CACP,UAAU;CACV,SAAS;CACT,UAAU;CACV,SAAS;CACT,YAAY;CACZ,UAAU;CACV,UAAU;CACV,QAAQ;;CAER,aAAa;;CAEb,mBAAmB;;CAEnB,QAAQ;AACV;;AAGA,MAAa,mBAAmB;CAC9B,QAAQ;CACR,gBAAgB;CAChB,YAAY;CACZ,SAAS;CACT,WAAW;AACb;;AAGA,MAAa,2BAA8C;CAAC;CAAK;CAAK;AAAG;;;;;AAMzE,MAAa,yBAA4C,CACvD,6BACA,kBACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"security-schema.d.cts","names":[],"sources":["../src/security-schema.ts"],"mappings":";;;;;;;;;;;;KAYY;;cAGC,8BAA8B;;cAQ9B,wBAAwB,OAAO;;;;;iBAW5B,sBACd,gBACA,WAAU,mBACT;;iBAOa,wBACd,UAAU,kBACV,KAAK;;iBAMS,yBACd,UAAU,kBACV,OAAO,mBACN;;;;;cAUU;;;;;;;;;;;;;;;;;;;;;;cAuBA;;;;;;;;cASA;;;;;cAMA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"security-schema.d.ts","names":[],"sources":["../src/security-schema.ts"],"mappings":";;;;;;;;;;;;KAYY;;cAGC,8BAA8B;;cAQ9B,wBAAwB,OAAO;;;;;iBAW5B,sBACd,gBACA,WAAU,mBACT;;iBAOa,wBACd,UAAU,kBACV,KAAK;;iBAMS,yBACd,UAAU,kBACV,OAAO,mBACN;;;;;cAUU;;;;;;;;;;;;;;;;;;;;;;cAuBA;;;;;;;;cASA;;;;;cAMA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"security-schema.js","names":[],"sources":["../src/security-schema.ts"],"sourcesContent":["/**\n * Security telemetry wire schema — the single source of truth for the\n * `security.*` span-attribute contract emitted by `autotel-audit`\n * (`securityEvent()`, `withSecurity()`, `createSecuritySignalProcessor()`)\n * and consumed by `autotel-subscribers`, `autotel-devtools`, and the\n * `autotel security` CLI commands.\n *\n * Dependency-free and side-effect-free by design: safe to import from\n * browser bundles (devtools widget) and anything else that only needs\n * the constants, without pulling in the OpenTelemetry SDK.\n */\n\nexport type SecuritySeverity = 'info' | 'warning' | 'error' | 'critical';\n\n/** All severities, lowest first. */\nexport const SECURITY_SEVERITIES: readonly SecuritySeverity[] = [\n 'info',\n 'warning',\n 'error',\n 'critical',\n];\n\n/** Numeric rank per severity for threshold comparisons. */\nexport const SECURITY_SEVERITY_RANK: Record<SecuritySeverity, number> = {\n info: 0,\n warning: 1,\n error: 2,\n critical: 3,\n};\n\n/**\n * Parse an untrusted value (span attribute, event payload field) into a\n * severity, falling back when it is missing or malformed.\n */\nexport function parseSecuritySeverity(\n value: unknown,\n fallback: SecuritySeverity = 'info',\n): SecuritySeverity {\n return typeof value === 'string' && value in SECURITY_SEVERITY_RANK\n ? (value as SecuritySeverity)\n : fallback;\n}\n\n/** `true` when `severity` meets or exceeds `min`. */\nexport function securitySeverityAtLeast(\n severity: SecuritySeverity,\n min: SecuritySeverity,\n): boolean {\n return SECURITY_SEVERITY_RANK[severity] >= SECURITY_SEVERITY_RANK[min];\n}\n\n/** The higher-ranked of two severities (e.g. escalate failures to ≥ error). */\nexport function escalateSecuritySeverity(\n severity: SecuritySeverity,\n floor: SecuritySeverity,\n): SecuritySeverity {\n return SECURITY_SEVERITY_RANK[severity] >= SECURITY_SEVERITY_RANK[floor]\n ? severity\n : floor;\n}\n\n/**\n * Span attribute keys of the security schema. Emitters and consumers must\n * reference these instead of re-typing the strings.\n */\nexport const SECURITY_ATTR = {\n /** Marker set on every span carrying a security event. */\n marker: 'autotel.security',\n /** Set when the event was force-kept through tail sampling. */\n forceKeep: 'autotel.security.force_keep',\n event: 'security.event',\n category: 'security.category',\n outcome: 'security.outcome',\n severity: 'security.severity',\n actorId: 'security.actor_id',\n targetType: 'security.target_type',\n targetId: 'security.target_id',\n tenantId: 'security.tenant_id',\n reason: 'security.reason',\n /** Custom metadata keys dropped because they looked credential-shaped. */\n droppedKeys: 'security.dropped_keys',\n /** Set by the signal processor on suspicious request paths. */\n suspiciousRequest: 'security.suspicious_request',\n /** Pattern name that flagged a suspicious request, e.g. `path_traversal`. */\n signal: 'security.signal',\n} as const;\n\n/** Metric names emitted by the security instrumentation. */\nexport const SECURITY_METRICS = {\n events: 'autotel.security.events',\n httpSuspicious: 'autotel.security.http.suspicious',\n httpDenied: 'autotel.security.http.denied',\n anomaly: 'autotel.security.anomaly',\n heartbeat: 'autotel.security.heartbeat',\n} as const;\n\n/** HTTP statuses counted as denied responses by default. */\nexport const SECURITY_DENIED_STATUSES: readonly number[] = [401, 403, 429];\n\n/**\n * Span attributes carrying the HTTP response status, current semconv\n * first, legacy fallback second.\n */\nexport const HTTP_STATUS_ATTRIBUTES: readonly string[] = [\n 'http.response.status_code',\n 'http.status_code',\n];\n"],"mappings":";;AAeA,MAAa,sBAAmD;CAC9D;CACA;CACA;CACA;AACF;;AAGA,MAAa,yBAA2D;CACtE,MAAM;CACN,SAAS;CACT,OAAO;CACP,UAAU;AACZ;;;;;AAMA,SAAgB,sBACd,OACA,WAA6B,QACX;CAClB,OAAO,OAAO,UAAU,YAAY,SAAS,yBACxC,QACD;AACN;;AAGA,SAAgB,wBACd,UACA,KACS;CACT,OAAO,uBAAuB,aAAa,uBAAuB;AACpE;;AAGA,SAAgB,yBACd,UACA,OACkB;CAClB,OAAO,uBAAuB,aAAa,uBAAuB,SAC9D,WACA;AACN;;;;;AAMA,MAAa,gBAAgB;;CAE3B,QAAQ;;CAER,WAAW;CACX,OAAO;CACP,UAAU;CACV,SAAS;CACT,UAAU;CACV,SAAS;CACT,YAAY;CACZ,UAAU;CACV,UAAU;CACV,QAAQ;;CAER,aAAa;;CAEb,mBAAmB;;CAEnB,QAAQ;AACV;;AAGA,MAAa,mBAAmB;CAC9B,QAAQ;CACR,gBAAgB;CAChB,YAAY;CACZ,SAAS;CACT,WAAW;AACb;;AAGA,MAAa,2BAA8C;CAAC;CAAK;CAAK;AAAG;;;;;AAMzE,MAAa,yBAA4C,CACvD,6BACA,kBACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"semantic-conventions-FhSxv-bK.d.cts","names":[],"sources":["../src/attributes/registry.ts","../src/semantic-conventions.ts"],"mappings":";cA0Ba;;;;;;;;;;;;cA4BA;;;;;cAqBA;;;;;;;;;iBC3EG,2BAA2B;iBAI3B,4BAA4B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"semantic-conventions-FhSxv-bK.d.ts","names":[],"sources":["../src/attributes/registry.ts","../src/semantic-conventions.ts"],"mappings":";cA0Ba;;;;;;;;;;;;cA4BA;;;;;cAqBA;;;;;;;;;iBC3EG,2BAA2B;iBAI3B,4BAA4B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"semantic-conventions.cjs","names":[],"sources":["../src/semantic-conventions.ts"],"sourcesContent":["export function httpRequestHeaderAttribute(name: string): string {\n return `http.request.header.${name.toLowerCase()}`;\n}\n\nexport function httpResponseHeaderAttribute(name: string): string {\n return `http.response.header.${name.toLowerCase()}`;\n}\n\nexport {\n HTTPAttributes,\n ServiceAttributes,\n URLAttributes,\n} from './attributes/registry';\n"],"mappings":";;;;AAAA,SAAgB,2BAA2B,MAAsB;CAC/D,OAAO,uBAAuB,KAAK,YAAY;AACjD;AAEA,SAAgB,4BAA4B,MAAsB;CAChE,OAAO,wBAAwB,KAAK,YAAY;AAClD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"semantic-conventions.js","names":[],"sources":["../src/semantic-conventions.ts"],"sourcesContent":["export function httpRequestHeaderAttribute(name: string): string {\n return `http.request.header.${name.toLowerCase()}`;\n}\n\nexport function httpResponseHeaderAttribute(name: string): string {\n return `http.response.header.${name.toLowerCase()}`;\n}\n\nexport {\n HTTPAttributes,\n ServiceAttributes,\n URLAttributes,\n} from './attributes/registry';\n"],"mappings":";;;AAAA,SAAgB,2BAA2B,MAAsB;CAC/D,OAAO,uBAAuB,KAAK,YAAY;AACjD;AAEA,SAAgB,4BAA4B,MAAsB;CAChE,OAAO,wBAAwB,KAAK,YAAY;AAClD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"semantic-helpers.cjs","names":["withTracing","SpanKind"],"sources":["../src/semantic-helpers.ts"],"sourcesContent":["/**\n * Semantic convention helpers for OpenTelemetry\n *\n * Pre-configured trace helpers that follow OpenTelemetry semantic conventions\n * for common operation types. Reduces boilerplate and ensures consistency.\n *\n * Based on: https://opentelemetry.io/docs/specs/semconv/\n */\n\nimport { withTracing } from './functional';\nimport { assertTraceFactory } from './trace-factory-validation';\nimport type { TraceContext } from './trace-context';\nimport { SpanKind, type Attributes } from '@opentelemetry/api';\n\ntype SemanticHandler<TArgs extends unknown[], TReturn> = (\n ...args: TArgs\n) => TReturn | Promise<TReturn>;\n\ntype SemanticFactory<TArgs extends unknown[], TReturn> = (\n ctx: TraceContext,\n) => SemanticHandler<TArgs, TReturn>;\n\nfunction setConfiguredAttributes(\n ctx: TraceContext,\n attributes?: Attributes,\n): void {\n if (!attributes) return;\n for (const [key, value] of Object.entries(attributes)) {\n if (value === undefined || value === null) continue;\n const attributeValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attributeValue);\n }\n}\n\n/**\n * Shared tail of `traceDB`/`traceHTTP`/`traceMessaging`: wrap `fn` directly\n * when given, otherwise return the curried factory-acceptor form.\n */\nfunction wrapSemantic<TArgs extends unknown[], TReturn>(\n helperName: string,\n name: string,\n spanKind: SpanKind,\n configure: (ctx: TraceContext) => void,\n fn?: SemanticHandler<TArgs, TReturn>,\n):\n | SemanticHandler<TArgs, TReturn>\n | (<TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => SemanticHandler<TFactoryArgs, TFactoryReturn>) {\n if (fn) {\n assertTraceFactory(helperName, fn);\n return withTracing<TArgs, TReturn>({ name, spanKind })(\n (ctx: TraceContext) => {\n configure(ctx);\n return fn;\n },\n );\n }\n return <TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => {\n assertTraceFactory(helperName, factory);\n return withTracing<TFactoryArgs, TFactoryReturn>({ name, spanKind })(\n (ctx: TraceContext) => {\n configure(ctx);\n const handler = factory(ctx);\n assertTraceFactory(helperName, handler, 'result');\n return handler;\n },\n );\n };\n}\n\n/**\n * Configuration for database operations\n *\n * Follows DB semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/database/\n */\nexport interface DBConfig {\n /** Database system (e.g., 'postgresql', 'mongodb', 'redis') */\n system: string;\n /** Operation type (e.g., 'SELECT', 'INSERT', 'find', 'get') */\n operation?: string;\n /** Database name */\n database?: string;\n /** Collection/table name */\n collection?: string;\n /** Low-cardinality query summary used as the preferred span name */\n querySummary?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Configuration for HTTP client operations\n *\n * Follows HTTP semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/http/\n */\nexport interface HTTPConfig {\n /** HTTP method (e.g., 'GET', 'POST') */\n method?: string;\n /** Target URL or URL template */\n url?: string;\n /** Low-cardinality server route used in the span name */\n route?: string;\n /** Low-cardinality client URL template used in the span name */\n urlTemplate?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Configuration for messaging operations\n *\n * Follows Messaging semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/messaging/\n */\nexport interface MessagingConfig {\n /** Messaging system (e.g., 'kafka', 'rabbitmq', 'sqs') */\n system: string;\n /** Operation type */\n operation?: 'publish' | 'receive' | 'process';\n /** Destination name (queue/topic) */\n destination?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\n}\n\n/**\n * Trace database operations with DB semantic conventions\n *\n * Automatically adds standard attributes for database operations:\n * - db.system.name\n * - db.operation.name\n * - db.namespace\n * - db.collection.name (for NoSQL)\n *\n * **Use Cases:**\n * - SQL queries (PostgreSQL, MySQL, SQLite)\n * - NoSQL operations (MongoDB, DynamoDB, Redis)\n * - ORM queries (Prisma, TypeORM, Drizzle)\n *\n * @param config - Database operation configuration\n * @returns Traced function factory with DB attributes\n *\n * @example PostgreSQL query\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { pool } from './db'\n *\n * export const getUser = traceDB({\n * system: 'postgresql',\n * operation: 'SELECT',\n * database: 'app_db',\n * collection: 'users',\n * querySummary: 'SELECT users'\n * })(ctx => async (userId: string) => {\n * const query = 'SELECT * FROM users WHERE id = $1'\n * const result = await pool.query(query, [userId])\n * ctx.setAttribute('db.rows_affected', result.rowCount)\n *\n * return result.rows[0]\n * })\n * ```\n *\n * @example MongoDB with Mongoose\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { User } from './models/User'\n *\n * export const findUsers = traceDB({\n * system: 'mongodb',\n * operation: 'find',\n * database: 'app_db',\n * collection: 'users'\n * })(ctx => async (filter: object) => {\n * ctx.setAttribute('db.mongodb.filter', JSON.stringify(filter))\n *\n * const users = await User.find(filter).limit(100)\n * ctx.setAttribute('db.response.count', users.length)\n *\n * return users\n * })\n * ```\n *\n * @example Redis operations\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { redis } from './redis'\n *\n * export const cacheGet = traceDB({\n * system: 'redis',\n * operation: 'GET'\n * })(ctx => async (key: string) => {\n * ctx.setAttribute('db.redis.key', key)\n *\n * const value = await redis.get(key)\n * ctx.setAttribute('db.response.cache_hit', value !== null)\n *\n * return value\n * })\n * ```\n *\n * @example Prisma with detailed query info\n * ```typescript\n * import { traceDB } from 'autotel/semantic-helpers'\n * import { prisma } from './prisma'\n *\n * export const createPost = traceDB({\n * system: 'postgresql',\n * operation: 'INSERT',\n * database: 'app_db',\n * collection: 'posts'\n * })(ctx => async (data: { title: string; content: string; authorId: string }) => {\n * ctx.setAttribute('db.prisma.model', 'Post')\n * ctx.setAttribute('db.prisma.action', 'create')\n *\n * const post = await prisma.post.create({ data })\n *\n * ctx.setAttribute('db.response.id', post.id)\n * return post\n * })\n * ```\n *\n * @public\n */\nexport function traceDB(\n config: DBConfig,\n): <TArgs extends unknown[], TReturn>(\n factory: SemanticFactory<TArgs, TReturn>,\n) => SemanticHandler<TArgs, TReturn>;\nexport function traceDB<TArgs extends unknown[], TReturn>(\n config: DBConfig,\n fn: SemanticHandler<TArgs, TReturn>,\n): SemanticHandler<TArgs, TReturn>;\nexport function traceDB<TArgs extends unknown[], TReturn>(\n config: DBConfig,\n fn?: SemanticHandler<TArgs, TReturn>,\n):\n | SemanticHandler<TArgs, TReturn>\n | (<TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => SemanticHandler<TFactoryArgs, TFactoryReturn>) {\n if (!config || typeof config !== 'object') {\n throw new TypeError('traceDB: config must be an object');\n }\n if (typeof config.system !== 'string' || config.system.trim() === '') {\n throw new TypeError('traceDB: config.system must be a non-empty string');\n }\n const target = config.collection ?? config.database;\n const name =\n config.querySummary ?? [config.operation, target].filter(Boolean).join(' ');\n const spanName = name || config.system;\n const configure = (ctx: TraceContext) => {\n // Emit current stable names plus legacy aliases for dashboard compatibility.\n ctx.setAttribute('db.system.name', config.system);\n ctx.setAttribute('db.system', config.system);\n if (config.operation) {\n ctx.setAttribute('db.operation.name', config.operation);\n ctx.setAttribute('db.operation', config.operation);\n }\n if (config.database) {\n ctx.setAttribute('db.namespace', config.database);\n ctx.setAttribute('db.name', config.database);\n }\n if (config.collection) {\n ctx.setAttribute('db.collection.name', config.collection);\n }\n if (config.querySummary) {\n ctx.setAttribute('db.query.summary', config.querySummary);\n }\n setConfiguredAttributes(ctx, config.attributes);\n };\n return wrapSemantic('traceDB', spanName, SpanKind.CLIENT, configure, fn);\n}\n\n/**\n * Trace HTTP client operations with HTTP semantic conventions\n *\n * Automatically adds standard attributes for HTTP requests:\n * - http.request.method\n * - url.full\n *\n * **Use Cases:**\n * - External API calls\n * - Microservice communication\n * - Third-party integrations\n *\n * @param config - HTTP operation configuration\n * @returns Traced function factory with HTTP attributes\n *\n * @example Fetch API\n * ```typescript\n * import { traceHTTP } from 'autotel/semantic-helpers'\n *\n * export const fetchUser = traceHTTP({\n * method: 'GET',\n * urlTemplate: '/users/{id}'\n * })(ctx => async (userId: string) => {\n * const url = `https://api.example.com/users/${userId}`\n * ctx.setAttribute('url.full', url)\n *\n * const response = await fetch(url)\n * ctx.setAttribute('http.response.status_code', response.status)\n *\n * if (!response.ok) {\n * ctx.setAttribute('error', true)\n * throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n * }\n *\n * return response.json()\n * })\n * ```\n *\n * @example Axios with retry logic\n * ```typescript\n * import { traceHTTP } from 'autotel/semantic-helpers'\n * import axios from 'axios'\n *\n * export const sendWebhook = traceHTTP({\n * method: 'POST',\n * url: 'https://webhook.example.com/events'\n * })(ctx => async (payload: object) => {\n * let attempts = 0\n * const maxAttempts = 3\n *\n * while (attempts < maxAttempts) {\n * try {\n * attempts++\n * ctx.setAttribute('http.request.resend_count', attempts - 1)\n *\n * const response = await axios.post('https://webhook.example.com/events', payload)\n * ctx.setAttribute('http.response.status_code', response.status)\n * return response.data\n * } catch (error) {\n * if (attempts >= maxAttempts) throw error\n * await new Promise(resolve => setTimeout(resolve, 1000 * attempts))\n * }\n * }\n * })\n * ```\n *\n * @public\n */\nexport function traceHTTP(\n config: HTTPConfig,\n): <TArgs extends unknown[], TReturn>(\n factory: SemanticFactory<TArgs, TReturn>,\n) => SemanticHandler<TArgs, TReturn>;\nexport function traceHTTP<TArgs extends unknown[], TReturn>(\n config: HTTPConfig,\n fn: SemanticHandler<TArgs, TReturn>,\n): SemanticHandler<TArgs, TReturn>;\nexport function traceHTTP<TArgs extends unknown[], TReturn>(\n config: HTTPConfig,\n fn?: SemanticHandler<TArgs, TReturn>,\n):\n | SemanticHandler<TArgs, TReturn>\n | (<TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => SemanticHandler<TFactoryArgs, TFactoryReturn>) {\n if (!config || typeof config !== 'object') {\n throw new TypeError('traceHTTP: config must be an object');\n }\n const method = config.method?.toUpperCase() || 'HTTP';\n const target = config.route ?? config.urlTemplate;\n const spanName = target ? `${method} ${target}` : method;\n const configure = (ctx: TraceContext) => {\n if (config.method) ctx.setAttribute('http.request.method', method);\n if (config.url) ctx.setAttribute('url.full', config.url);\n if (config.route) ctx.setAttribute('http.route', config.route);\n if (config.urlTemplate) {\n ctx.setAttribute('url.template', config.urlTemplate);\n }\n setConfiguredAttributes(ctx, config.attributes);\n };\n return wrapSemantic('traceHTTP', spanName, SpanKind.CLIENT, configure, fn);\n}\n\n/**\n * Trace messaging operations with Messaging semantic conventions\n *\n * Automatically adds standard attributes for messaging:\n * - messaging.system\n * - messaging.operation\n * - messaging.destination.name\n *\n * **Use Cases:**\n * - Publishing messages to queues/topics\n * - Consuming messages from queues/topics\n * - Event-driven architectures\n *\n * @param config - Messaging operation configuration\n * @returns Traced function factory with Messaging attributes\n *\n * @example Publishing to Kafka\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { kafka } from './kafka'\n *\n * const producer = kafka.producer()\n *\n * export const publishEvent = traceMessaging({\n * system: 'kafka',\n * operation: 'publish',\n * destination: 'user-events'\n * })(ctx => async (event: { type: string; userId: string; data: object }) => {\n * ctx.setAttribute('messaging.message.type', event.type)\n * ctx.setAttribute('messaging.kafka.partition', 0)\n *\n * await producer.send({\n * topic: 'user-events',\n * messages: [\n * {\n * key: event.userId,\n * value: JSON.stringify(event.data)\n * }\n * ]\n * })\n *\n * ctx.setAttribute('messaging.message.id', event.userId)\n * })\n * ```\n *\n * @example Consuming from RabbitMQ\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { channel } from './rabbitmq'\n *\n * export const processOrder = traceMessaging({\n * system: 'rabbitmq',\n * operation: 'process',\n * destination: 'orders'\n * })(ctx => async (message: { orderId: string; items: object[] }) => {\n * ctx.setAttribute('messaging.message.id', message.orderId)\n * ctx.setAttribute('messaging.message.body.size', JSON.stringify(message).length)\n *\n * // Process order logic\n * const result = await processOrderInternal(message)\n *\n * ctx.setAttribute('messaging.operation.result', 'success')\n * return result\n * })\n * ```\n *\n * @example AWS SQS with batch processing\n * ```typescript\n * import { traceMessaging } from 'autotel/semantic-helpers'\n * import { SQS } from '@aws-sdk/client-sqs'\n *\n * const sqs = new SQS()\n *\n * export const sendBatch = traceMessaging({\n * system: 'aws_sqs',\n * operation: 'publish',\n * destination: 'notifications-queue'\n * })(ctx => async (messages: Array<{ id: string; body: object }>) => {\n * ctx.setAttribute('messaging.batch.message_count', messages.length)\n *\n * const result = await sqs.sendMessageBatch({\n * QueueUrl: process.env.QUEUE_URL,\n * Entries: messages.map(msg => ({\n * Id: msg.id,\n * MessageBody: JSON.stringify(msg.body)\n * }))\n * })\n *\n * ctx.setAttribute('messaging.operation.success_count', result.Successful?.length || 0)\n * ctx.setAttribute('messaging.operation.failed_count', result.Failed?.length || 0)\n *\n * return result\n * })\n * ```\n *\n * @public\n */\nexport function traceMessaging(\n config: MessagingConfig,\n): <TArgs extends unknown[], TReturn>(\n factory: SemanticFactory<TArgs, TReturn>,\n) => SemanticHandler<TArgs, TReturn>;\nexport function traceMessaging<TArgs extends unknown[], TReturn>(\n config: MessagingConfig,\n fn: SemanticHandler<TArgs, TReturn>,\n): SemanticHandler<TArgs, TReturn>;\nexport function traceMessaging<TArgs extends unknown[], TReturn>(\n config: MessagingConfig,\n fn?: SemanticHandler<TArgs, TReturn>,\n):\n | SemanticHandler<TArgs, TReturn>\n | (<TFactoryArgs extends unknown[], TFactoryReturn>(\n factory: SemanticFactory<TFactoryArgs, TFactoryReturn>,\n ) => SemanticHandler<TFactoryArgs, TFactoryReturn>) {\n if (!config || typeof config !== 'object') {\n throw new TypeError('traceMessaging: config must be an object');\n }\n if (typeof config.system !== 'string' || config.system.trim() === '') {\n throw new TypeError(\n 'traceMessaging: config.system must be a non-empty string',\n );\n }\n const operation = config.operation ?? 'messaging';\n const spanName = [operation, config.destination].filter(Boolean).join(' ');\n const operationType = operation === 'publish' ? 'send' : operation;\n const spanKind =\n operation === 'publish'\n ? SpanKind.PRODUCER\n : operation === 'process'\n ? SpanKind.CONSUMER\n : operation === 'receive'\n ? SpanKind.CLIENT\n : SpanKind.INTERNAL;\n const configure = (ctx: TraceContext) => {\n ctx.setAttribute('messaging.system', config.system);\n if (config.operation) {\n ctx.setAttribute('messaging.operation.name', config.operation);\n ctx.setAttribute('messaging.operation.type', operationType);\n ctx.setAttribute('messaging.operation', config.operation);\n }\n if (config.destination) {\n ctx.setAttribute('messaging.destination.name', config.destination);\n }\n setConfiguredAttributes(ctx, config.attributes);\n };\n return wrapSemantic('traceMessaging', spanName, spanKind, configure, fn);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"semantic-helpers.d.cts","names":[],"sources":["../src/semantic-helpers.ts"],"mappings":";;;KAcK,gBAAgB,yBAAyB,eACzC,MAAM,UACN,UAAU,QAAQ;KAElB,gBAAgB,yBAAyB,YAC5C,KAAK,iBACF,gBAAgB,OAAO;;;;;;;UAgEX;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,aAAa;;;;;;;;UASE;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA,aAAa;;;;;;;;UASE;;EAEf;;EAEA;;EAEA;;EAEA,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqGC,QACd,QAAQ,YACN,yBAAyB,SAC3B,SAAS,gBAAgB,OAAO,aAC7B,gBAAgB,OAAO;iBACZ,QAAQ,yBAAyB,SAC/C,QAAQ,UACR,IAAI,gBAAgB,OAAO,WAC1B,gBAAgB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8GV,UACd,QAAQ,cACN,yBAAyB,SAC3B,SAAS,gBAAgB,OAAO,aAC7B,gBAAgB,OAAO;iBACZ,UAAU,yBAAyB,SACjD,QAAQ,YACR,IAAI,gBAAgB,OAAO,WAC1B,gBAAgB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4HV,eACd,QAAQ,mBACN,yBAAyB,SAC3B,SAAS,gBAAgB,OAAO,aAC7B,gBAAgB,OAAO;iBACZ,eAAe,yBAAyB,SACtD,QAAQ,iBACR,IAAI,gBAAgB,OAAO,WAC1B,gBAAgB,OAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"semantic-helpers.d.ts","names":[],"sources":["../src/semantic-helpers.ts"],"mappings":";;;KAcK,gBAAgB,yBAAyB,eACzC,MAAM,UACN,UAAU,QAAQ;KAElB,gBAAgB,yBAAyB,YAC5C,KAAK,iBACF,gBAAgB,OAAO;;;;;;;UAgEX;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,aAAa;;;;;;;;UASE;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA,aAAa;;;;;;;;UASE;;EAEf;;EAEA;;EAEA;;EAEA,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqGC,QACd,QAAQ,YACN,yBAAyB,SAC3B,SAAS,gBAAgB,OAAO,aAC7B,gBAAgB,OAAO;iBACZ,QAAQ,yBAAyB,SAC/C,QAAQ,UACR,IAAI,gBAAgB,OAAO,WAC1B,gBAAgB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8GV,UACd,QAAQ,cACN,yBAAyB,SAC3B,SAAS,gBAAgB,OAAO,aAC7B,gBAAgB,OAAO;iBACZ,UAAU,yBAAyB,SACjD,QAAQ,YACR,IAAI,gBAAgB,OAAO,WAC1B,gBAAgB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4HV,eACd,QAAQ,mBACN,yBAAyB,SAC3B,SAAS,gBAAgB,OAAO,aAC7B,gBAAgB,OAAO;iBACZ,eAAe,yBAAyB,SACtD,QAAQ,iBACR,IAAI,gBAAgB,OAAO,WAC1B,gBAAgB,OAAO"}