autotel 2.1.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 (272) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1946 -0
  3. package/dist/chunk-2LNRY4QK.js +273 -0
  4. package/dist/chunk-2LNRY4QK.js.map +1 -0
  5. package/dist/chunk-3HENGDW2.js +587 -0
  6. package/dist/chunk-3HENGDW2.js.map +1 -0
  7. package/dist/chunk-4OAT42CA.cjs +73 -0
  8. package/dist/chunk-4OAT42CA.cjs.map +1 -0
  9. package/dist/chunk-5GWX5LFW.js +70 -0
  10. package/dist/chunk-5GWX5LFW.js.map +1 -0
  11. package/dist/chunk-5R2M36QB.js +195 -0
  12. package/dist/chunk-5R2M36QB.js.map +1 -0
  13. package/dist/chunk-5ZN622AO.js +73 -0
  14. package/dist/chunk-5ZN622AO.js.map +1 -0
  15. package/dist/chunk-77MSMAUQ.cjs +498 -0
  16. package/dist/chunk-77MSMAUQ.cjs.map +1 -0
  17. package/dist/chunk-ABPEQ6RK.cjs +596 -0
  18. package/dist/chunk-ABPEQ6RK.cjs.map +1 -0
  19. package/dist/chunk-BWYGJKRB.js +95 -0
  20. package/dist/chunk-BWYGJKRB.js.map +1 -0
  21. package/dist/chunk-BZHG5IZ4.js +73 -0
  22. package/dist/chunk-BZHG5IZ4.js.map +1 -0
  23. package/dist/chunk-G7VZBCD6.cjs +35 -0
  24. package/dist/chunk-G7VZBCD6.cjs.map +1 -0
  25. package/dist/chunk-GVLK7YUU.cjs +30 -0
  26. package/dist/chunk-GVLK7YUU.cjs.map +1 -0
  27. package/dist/chunk-HCCXC7XG.js +205 -0
  28. package/dist/chunk-HCCXC7XG.js.map +1 -0
  29. package/dist/chunk-HE6T6FIX.cjs +203 -0
  30. package/dist/chunk-HE6T6FIX.cjs.map +1 -0
  31. package/dist/chunk-KIXWPOCO.cjs +100 -0
  32. package/dist/chunk-KIXWPOCO.cjs.map +1 -0
  33. package/dist/chunk-KVGNW3FC.js +87 -0
  34. package/dist/chunk-KVGNW3FC.js.map +1 -0
  35. package/dist/chunk-LITNXTTT.js +3 -0
  36. package/dist/chunk-LITNXTTT.js.map +1 -0
  37. package/dist/chunk-M4ANN7RL.js +114 -0
  38. package/dist/chunk-M4ANN7RL.js.map +1 -0
  39. package/dist/chunk-NC52UBR2.cjs +32 -0
  40. package/dist/chunk-NC52UBR2.cjs.map +1 -0
  41. package/dist/chunk-NHCNRQD3.cjs +212 -0
  42. package/dist/chunk-NHCNRQD3.cjs.map +1 -0
  43. package/dist/chunk-NZ72VDNY.cjs +4 -0
  44. package/dist/chunk-NZ72VDNY.cjs.map +1 -0
  45. package/dist/chunk-P6JUDYNO.js +57 -0
  46. package/dist/chunk-P6JUDYNO.js.map +1 -0
  47. package/dist/chunk-RJYY7BWX.js +1349 -0
  48. package/dist/chunk-RJYY7BWX.js.map +1 -0
  49. package/dist/chunk-TRI4V5BF.cjs +126 -0
  50. package/dist/chunk-TRI4V5BF.cjs.map +1 -0
  51. package/dist/chunk-UL33I6IS.js +139 -0
  52. package/dist/chunk-UL33I6IS.js.map +1 -0
  53. package/dist/chunk-URRW6M2C.cjs +61 -0
  54. package/dist/chunk-URRW6M2C.cjs.map +1 -0
  55. package/dist/chunk-UY3UYPBZ.cjs +77 -0
  56. package/dist/chunk-UY3UYPBZ.cjs.map +1 -0
  57. package/dist/chunk-W3253FGB.cjs +277 -0
  58. package/dist/chunk-W3253FGB.cjs.map +1 -0
  59. package/dist/chunk-W7LHZVQF.js +26 -0
  60. package/dist/chunk-W7LHZVQF.js.map +1 -0
  61. package/dist/chunk-WBWNM6LB.cjs +1360 -0
  62. package/dist/chunk-WBWNM6LB.cjs.map +1 -0
  63. package/dist/chunk-WFJ7L2RV.js +494 -0
  64. package/dist/chunk-WFJ7L2RV.js.map +1 -0
  65. package/dist/chunk-X4RMFFMR.js +28 -0
  66. package/dist/chunk-X4RMFFMR.js.map +1 -0
  67. package/dist/chunk-Y4Y2S7BM.cjs +92 -0
  68. package/dist/chunk-Y4Y2S7BM.cjs.map +1 -0
  69. package/dist/chunk-YLPNXZFI.cjs +143 -0
  70. package/dist/chunk-YLPNXZFI.cjs.map +1 -0
  71. package/dist/chunk-YTXEZ4SD.cjs +77 -0
  72. package/dist/chunk-YTXEZ4SD.cjs.map +1 -0
  73. package/dist/chunk-Z6ZWNWWR.js +30 -0
  74. package/dist/chunk-Z6ZWNWWR.js.map +1 -0
  75. package/dist/config.cjs +26 -0
  76. package/dist/config.cjs.map +1 -0
  77. package/dist/config.d.cts +75 -0
  78. package/dist/config.d.ts +75 -0
  79. package/dist/config.js +5 -0
  80. package/dist/config.js.map +1 -0
  81. package/dist/db.cjs +233 -0
  82. package/dist/db.cjs.map +1 -0
  83. package/dist/db.d.cts +123 -0
  84. package/dist/db.d.ts +123 -0
  85. package/dist/db.js +228 -0
  86. package/dist/db.js.map +1 -0
  87. package/dist/decorators.cjs +67 -0
  88. package/dist/decorators.cjs.map +1 -0
  89. package/dist/decorators.d.cts +91 -0
  90. package/dist/decorators.d.ts +91 -0
  91. package/dist/decorators.js +65 -0
  92. package/dist/decorators.js.map +1 -0
  93. package/dist/event-subscriber.cjs +6 -0
  94. package/dist/event-subscriber.cjs.map +1 -0
  95. package/dist/event-subscriber.d.cts +116 -0
  96. package/dist/event-subscriber.d.ts +116 -0
  97. package/dist/event-subscriber.js +3 -0
  98. package/dist/event-subscriber.js.map +1 -0
  99. package/dist/event-testing.cjs +21 -0
  100. package/dist/event-testing.cjs.map +1 -0
  101. package/dist/event-testing.d.cts +110 -0
  102. package/dist/event-testing.d.ts +110 -0
  103. package/dist/event-testing.js +4 -0
  104. package/dist/event-testing.js.map +1 -0
  105. package/dist/event.cjs +30 -0
  106. package/dist/event.cjs.map +1 -0
  107. package/dist/event.d.cts +282 -0
  108. package/dist/event.d.ts +282 -0
  109. package/dist/event.js +13 -0
  110. package/dist/event.js.map +1 -0
  111. package/dist/exporters.cjs +17 -0
  112. package/dist/exporters.cjs.map +1 -0
  113. package/dist/exporters.d.cts +1 -0
  114. package/dist/exporters.d.ts +1 -0
  115. package/dist/exporters.js +4 -0
  116. package/dist/exporters.js.map +1 -0
  117. package/dist/functional.cjs +46 -0
  118. package/dist/functional.cjs.map +1 -0
  119. package/dist/functional.d.cts +478 -0
  120. package/dist/functional.d.ts +478 -0
  121. package/dist/functional.js +13 -0
  122. package/dist/functional.js.map +1 -0
  123. package/dist/http.cjs +189 -0
  124. package/dist/http.cjs.map +1 -0
  125. package/dist/http.d.cts +169 -0
  126. package/dist/http.d.ts +169 -0
  127. package/dist/http.js +184 -0
  128. package/dist/http.js.map +1 -0
  129. package/dist/index.cjs +333 -0
  130. package/dist/index.cjs.map +1 -0
  131. package/dist/index.d.cts +758 -0
  132. package/dist/index.d.ts +758 -0
  133. package/dist/index.js +143 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/instrumentation.cjs +182 -0
  136. package/dist/instrumentation.cjs.map +1 -0
  137. package/dist/instrumentation.d.cts +49 -0
  138. package/dist/instrumentation.d.ts +49 -0
  139. package/dist/instrumentation.js +179 -0
  140. package/dist/instrumentation.js.map +1 -0
  141. package/dist/logger.cjs +19 -0
  142. package/dist/logger.cjs.map +1 -0
  143. package/dist/logger.d.cts +146 -0
  144. package/dist/logger.d.ts +146 -0
  145. package/dist/logger.js +6 -0
  146. package/dist/logger.js.map +1 -0
  147. package/dist/metric-helpers.cjs +31 -0
  148. package/dist/metric-helpers.cjs.map +1 -0
  149. package/dist/metric-helpers.d.cts +13 -0
  150. package/dist/metric-helpers.d.ts +13 -0
  151. package/dist/metric-helpers.js +6 -0
  152. package/dist/metric-helpers.js.map +1 -0
  153. package/dist/metric-testing.cjs +21 -0
  154. package/dist/metric-testing.cjs.map +1 -0
  155. package/dist/metric-testing.d.cts +110 -0
  156. package/dist/metric-testing.d.ts +110 -0
  157. package/dist/metric-testing.js +4 -0
  158. package/dist/metric-testing.js.map +1 -0
  159. package/dist/metric.cjs +26 -0
  160. package/dist/metric.cjs.map +1 -0
  161. package/dist/metric.d.cts +240 -0
  162. package/dist/metric.d.ts +240 -0
  163. package/dist/metric.js +9 -0
  164. package/dist/metric.js.map +1 -0
  165. package/dist/processors.cjs +17 -0
  166. package/dist/processors.cjs.map +1 -0
  167. package/dist/processors.d.cts +1 -0
  168. package/dist/processors.d.ts +1 -0
  169. package/dist/processors.js +4 -0
  170. package/dist/processors.js.map +1 -0
  171. package/dist/sampling.cjs +40 -0
  172. package/dist/sampling.cjs.map +1 -0
  173. package/dist/sampling.d.cts +260 -0
  174. package/dist/sampling.d.ts +260 -0
  175. package/dist/sampling.js +7 -0
  176. package/dist/sampling.js.map +1 -0
  177. package/dist/semantic-helpers.cjs +35 -0
  178. package/dist/semantic-helpers.cjs.map +1 -0
  179. package/dist/semantic-helpers.d.cts +442 -0
  180. package/dist/semantic-helpers.d.ts +442 -0
  181. package/dist/semantic-helpers.js +14 -0
  182. package/dist/semantic-helpers.js.map +1 -0
  183. package/dist/tail-sampling-processor.cjs +13 -0
  184. package/dist/tail-sampling-processor.cjs.map +1 -0
  185. package/dist/tail-sampling-processor.d.cts +27 -0
  186. package/dist/tail-sampling-processor.d.ts +27 -0
  187. package/dist/tail-sampling-processor.js +4 -0
  188. package/dist/tail-sampling-processor.js.map +1 -0
  189. package/dist/testing.cjs +286 -0
  190. package/dist/testing.cjs.map +1 -0
  191. package/dist/testing.d.cts +291 -0
  192. package/dist/testing.d.ts +291 -0
  193. package/dist/testing.js +263 -0
  194. package/dist/testing.js.map +1 -0
  195. package/dist/trace-context-DRZdUvVY.d.cts +181 -0
  196. package/dist/trace-context-DRZdUvVY.d.ts +181 -0
  197. package/dist/trace-helpers.cjs +54 -0
  198. package/dist/trace-helpers.cjs.map +1 -0
  199. package/dist/trace-helpers.d.cts +524 -0
  200. package/dist/trace-helpers.d.ts +524 -0
  201. package/dist/trace-helpers.js +5 -0
  202. package/dist/trace-helpers.js.map +1 -0
  203. package/dist/tracer-provider.cjs +21 -0
  204. package/dist/tracer-provider.cjs.map +1 -0
  205. package/dist/tracer-provider.d.cts +169 -0
  206. package/dist/tracer-provider.d.ts +169 -0
  207. package/dist/tracer-provider.js +4 -0
  208. package/dist/tracer-provider.js.map +1 -0
  209. package/package.json +280 -0
  210. package/src/baggage-span-processor.test.ts +202 -0
  211. package/src/baggage-span-processor.ts +98 -0
  212. package/src/circuit-breaker.test.ts +341 -0
  213. package/src/circuit-breaker.ts +184 -0
  214. package/src/config.test.ts +94 -0
  215. package/src/config.ts +169 -0
  216. package/src/db.test.ts +252 -0
  217. package/src/db.ts +447 -0
  218. package/src/decorators.test.ts +203 -0
  219. package/src/decorators.ts +188 -0
  220. package/src/env-config.test.ts +246 -0
  221. package/src/env-config.ts +158 -0
  222. package/src/event-queue.test.ts +222 -0
  223. package/src/event-queue.ts +203 -0
  224. package/src/event-subscriber.ts +136 -0
  225. package/src/event-testing.ts +197 -0
  226. package/src/event.test.ts +718 -0
  227. package/src/event.ts +556 -0
  228. package/src/exporters.ts +96 -0
  229. package/src/functional.test.ts +1059 -0
  230. package/src/functional.ts +2295 -0
  231. package/src/http.test.ts +487 -0
  232. package/src/http.ts +424 -0
  233. package/src/index.ts +158 -0
  234. package/src/init.customization.test.ts +210 -0
  235. package/src/init.integrations.test.ts +366 -0
  236. package/src/init.openllmetry.test.ts +282 -0
  237. package/src/init.protocol.test.ts +215 -0
  238. package/src/init.ts +1426 -0
  239. package/src/instrumentation.test.ts +108 -0
  240. package/src/instrumentation.ts +308 -0
  241. package/src/logger.test.ts +117 -0
  242. package/src/logger.ts +246 -0
  243. package/src/metric-helpers.ts +47 -0
  244. package/src/metric-testing.ts +197 -0
  245. package/src/metric.ts +434 -0
  246. package/src/metrics.test.ts +205 -0
  247. package/src/operation-context.ts +93 -0
  248. package/src/processors.ts +106 -0
  249. package/src/rate-limiter.test.ts +199 -0
  250. package/src/rate-limiter.ts +98 -0
  251. package/src/sampling.test.ts +513 -0
  252. package/src/sampling.ts +428 -0
  253. package/src/semantic-helpers.test.ts +311 -0
  254. package/src/semantic-helpers.ts +584 -0
  255. package/src/shutdown.test.ts +311 -0
  256. package/src/shutdown.ts +222 -0
  257. package/src/stub.integration.test.ts +361 -0
  258. package/src/tail-sampling-processor.test.ts +226 -0
  259. package/src/tail-sampling-processor.ts +51 -0
  260. package/src/testing.ts +670 -0
  261. package/src/trace-context.ts +470 -0
  262. package/src/trace-helpers.new.test.ts +278 -0
  263. package/src/trace-helpers.test.ts +242 -0
  264. package/src/trace-helpers.ts +690 -0
  265. package/src/tracer-provider.test.ts +183 -0
  266. package/src/tracer-provider.ts +266 -0
  267. package/src/track.test.ts +153 -0
  268. package/src/track.ts +120 -0
  269. package/src/validation.test.ts +306 -0
  270. package/src/validation.ts +239 -0
  271. package/src/variable-name-inference.test.ts +178 -0
  272. package/src/variable-name-inference.ts +242 -0
@@ -0,0 +1,205 @@
1
+ import { __export, __esm } from './chunk-Z6ZWNWWR.js';
2
+ import { context, propagation } from '@opentelemetry/api';
3
+ import { AsyncLocalStorage } from 'async_hooks';
4
+
5
+ // src/trace-context.ts
6
+ var trace_context_exports = {};
7
+ __export(trace_context_exports, {
8
+ createTraceContext: () => createTraceContext,
9
+ defineBaggageSchema: () => defineBaggageSchema,
10
+ getActiveContextWithBaggage: () => getActiveContextWithBaggage,
11
+ getContextStorage: () => getContextStorage
12
+ });
13
+ function getContextStorage() {
14
+ return contextStorage;
15
+ }
16
+ function getActiveContextWithBaggage() {
17
+ const stored = contextStorage.getStore();
18
+ return stored ?? context.active();
19
+ }
20
+ function updateActiveContext(newContext) {
21
+ contextStorage.enterWith(newContext);
22
+ const contextWithManager = context;
23
+ const manager = contextWithManager._getContextManager?.();
24
+ if (!manager) return;
25
+ const asyncLocal = manager._asyncLocalStorage ?? void 0;
26
+ if (asyncLocal?.enterWith) {
27
+ asyncLocal.enterWith(newContext);
28
+ return;
29
+ }
30
+ if (typeof manager.with === "function") {
31
+ manager.with(newContext, () => {
32
+ });
33
+ }
34
+ }
35
+ function createTraceContext(span) {
36
+ const spanContext = span.spanContext();
37
+ const existingStored = contextStorage.getStore();
38
+ if (!existingStored) {
39
+ const activeContext = context.active();
40
+ contextStorage.enterWith(activeContext);
41
+ }
42
+ const baggageHelpers = {
43
+ getBaggage(key) {
44
+ const activeCtx = context.active();
45
+ let baggage = propagation.getBaggage(activeCtx);
46
+ if (!baggage) {
47
+ const storedContext = contextStorage.getStore();
48
+ if (storedContext) {
49
+ baggage = propagation.getBaggage(storedContext);
50
+ }
51
+ }
52
+ return baggage?.getEntry(key)?.value;
53
+ },
54
+ setBaggage(key, value) {
55
+ const activeCtx = context.active();
56
+ const storedContext = contextStorage.getStore();
57
+ const currentContext = storedContext ?? activeCtx;
58
+ const baggage = propagation.getBaggage(currentContext) ?? propagation.createBaggage();
59
+ const updated = baggage.setEntry(key, { value });
60
+ const newContext = propagation.setBaggage(currentContext, updated);
61
+ updateActiveContext(newContext);
62
+ return value;
63
+ },
64
+ deleteBaggage(key) {
65
+ const activeCtx = context.active();
66
+ const storedContext = contextStorage.getStore();
67
+ const currentContext = storedContext ?? activeCtx;
68
+ const baggage = propagation.getBaggage(currentContext);
69
+ if (baggage) {
70
+ const updated = baggage.removeEntry(key);
71
+ const newContext = propagation.setBaggage(currentContext, updated);
72
+ updateActiveContext(newContext);
73
+ }
74
+ },
75
+ getAllBaggage() {
76
+ const activeCtx = context.active();
77
+ let baggage = propagation.getBaggage(activeCtx);
78
+ if (!baggage) {
79
+ const storedContext = contextStorage.getStore();
80
+ if (storedContext) {
81
+ baggage = propagation.getBaggage(storedContext);
82
+ }
83
+ }
84
+ if (!baggage) {
85
+ return /* @__PURE__ */ new Map();
86
+ }
87
+ const entries = /* @__PURE__ */ new Map();
88
+ for (const [key, entry] of baggage.getAllEntries()) {
89
+ entries.set(key, entry);
90
+ }
91
+ return entries;
92
+ },
93
+ // Typed baggage helpers (used by defineBaggageSchema)
94
+ getTypedBaggage: ((namespace) => {
95
+ const activeCtx = context.active();
96
+ let baggage = propagation.getBaggage(activeCtx);
97
+ if (!baggage) {
98
+ const storedContext = contextStorage.getStore();
99
+ if (storedContext) {
100
+ baggage = propagation.getBaggage(storedContext);
101
+ }
102
+ }
103
+ if (!baggage) return;
104
+ const prefix = namespace ? `${namespace}.` : "";
105
+ const result = {};
106
+ for (const [key, entry] of baggage.getAllEntries()) {
107
+ if (namespace && key.startsWith(prefix)) {
108
+ const fieldName = key.slice(prefix.length);
109
+ result[fieldName] = entry.value;
110
+ } else if (!namespace) {
111
+ result[key] = entry.value;
112
+ }
113
+ }
114
+ return Object.keys(result).length > 0 ? result : void 0;
115
+ }),
116
+ setTypedBaggage: ((namespace, value) => {
117
+ const activeCtx = context.active();
118
+ const storedContext = contextStorage.getStore();
119
+ const currentContext = storedContext ?? activeCtx;
120
+ let baggage = propagation.getBaggage(currentContext) ?? propagation.createBaggage();
121
+ const prefix = namespace ? `${namespace}.` : "";
122
+ for (const [key, val] of Object.entries(value)) {
123
+ if (val !== void 0) {
124
+ const baggageKey = `${prefix}${key}`;
125
+ baggage = baggage.setEntry(baggageKey, { value: String(val) });
126
+ }
127
+ }
128
+ const newContext = propagation.setBaggage(currentContext, baggage);
129
+ updateActiveContext(newContext);
130
+ })
131
+ };
132
+ return {
133
+ traceId: spanContext.traceId,
134
+ spanId: spanContext.spanId,
135
+ correlationId: spanContext.traceId.slice(0, 16),
136
+ setAttribute: span.setAttribute.bind(span),
137
+ setAttributes: span.setAttributes.bind(span),
138
+ setStatus: span.setStatus.bind(span),
139
+ recordException: span.recordException.bind(span),
140
+ ...baggageHelpers
141
+ };
142
+ }
143
+ function defineBaggageSchema(namespace) {
144
+ return {
145
+ /**
146
+ * Get typed baggage from context
147
+ * @param ctx - Trace context
148
+ * @returns Partial baggage object or undefined if no baggage is set
149
+ */
150
+ get: (ctx) => {
151
+ if (!ctx.getTypedBaggage) return void 0;
152
+ return ctx.getTypedBaggage(namespace);
153
+ },
154
+ /**
155
+ * Set typed baggage in context
156
+ *
157
+ * Note: For proper scoping across async boundaries, use the `with` method instead
158
+ *
159
+ * @param ctx - Trace context
160
+ * @param value - Partial baggage object to set
161
+ */
162
+ set: (ctx, value) => {
163
+ if (!ctx.setTypedBaggage) return;
164
+ ctx.setTypedBaggage(namespace, value);
165
+ },
166
+ /**
167
+ * Run a function with typed baggage properly scoped
168
+ *
169
+ * This is the recommended way to set baggage as it ensures proper
170
+ * scoping across async boundaries.
171
+ *
172
+ * @param ctx - Trace context (can be omitted, will use active context)
173
+ * @param value - Partial baggage object to set
174
+ * @param fn - Function to execute with the baggage
175
+ */
176
+ with: (ctxOrValue, valueOrFn, maybeFn) => {
177
+ const value = maybeFn ? valueOrFn : ctxOrValue;
178
+ const fn = maybeFn || valueOrFn;
179
+ const prefix = namespace ? `${namespace}.` : "";
180
+ const flatBaggage = {};
181
+ for (const [key, val] of Object.entries(value)) {
182
+ if (val !== void 0) {
183
+ flatBaggage[`${prefix}${key}`] = String(val);
184
+ }
185
+ }
186
+ const currentContext = context.active();
187
+ let baggage = propagation.getBaggage(currentContext) ?? propagation.createBaggage();
188
+ for (const [key, val] of Object.entries(flatBaggage)) {
189
+ baggage = baggage.setEntry(key, { value: val });
190
+ }
191
+ const newContext = propagation.setBaggage(currentContext, baggage);
192
+ return context.with(newContext, fn);
193
+ }
194
+ };
195
+ }
196
+ var contextStorage;
197
+ var init_trace_context = __esm({
198
+ "src/trace-context.ts"() {
199
+ contextStorage = new AsyncLocalStorage();
200
+ }
201
+ });
202
+
203
+ export { createTraceContext, defineBaggageSchema, getActiveContextWithBaggage, getContextStorage, init_trace_context, trace_context_exports };
204
+ //# sourceMappingURL=chunk-HCCXC7XG.js.map
205
+ //# sourceMappingURL=chunk-HCCXC7XG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/trace-context.ts"],"names":[],"mappings":"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","file":"chunk-HCCXC7XG.js","sourcesContent":["/**\n * Trace context types and utilities\n */\n\nimport type {\n Span,\n SpanStatusCode,\n BaggageEntry,\n Context,\n} from '@opentelemetry/api';\nimport { context, propagation } from '@opentelemetry/api';\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\n/**\n * AsyncLocalStorage for storing the active context with baggage\n * This allows setters to update the context and have it persist\n */\nconst contextStorage = new AsyncLocalStorage<Context>();\n\n/**\n * Get the context storage instance (for initialization in functional.ts)\n */\nexport function getContextStorage(): AsyncLocalStorage<Context> {\n return contextStorage;\n}\n\n/**\n * Get the active context, checking our stored context first\n * This ensures baggage setters work with OpenTelemetry's propagation\n */\nexport function getActiveContextWithBaggage(): Context {\n // Check stored context first (from setters), then fall back to active context\n // This ensures ctx.setBaggage() changes are visible to OpenTelemetry operations\n const stored = contextStorage.getStore();\n return stored ?? context.active();\n}\n\n/**\n * Try to keep OpenTelemetry's context manager in sync with baggage updates\n */\ntype ContextManagerLike = {\n with?: (ctx: Context, fn: () => void) => void;\n _asyncLocalStorage?: { enterWith?: (ctx: Context) => void };\n};\n\nfunction updateActiveContext(newContext: Context): void {\n // Update our storage first so any helper reads see the new context\n contextStorage.enterWith(newContext);\n\n const contextWithManager = context as unknown as {\n _getContextManager?: () => ContextManagerLike;\n };\n\n const manager = contextWithManager._getContextManager?.();\n if (!manager) return;\n\n const asyncLocal =\n (manager as { _asyncLocalStorage?: { enterWith?: (ctx: Context) => void } })\n ._asyncLocalStorage ?? undefined;\n if (asyncLocal?.enterWith) {\n asyncLocal.enterWith(newContext);\n return;\n }\n\n if (typeof manager.with === 'function') {\n manager.with(newContext, () => {});\n }\n}\n\n/**\n * Base trace context containing trace identifiers\n */\nexport interface TraceContextBase {\n traceId: string;\n spanId: string;\n correlationId: string;\n}\n\n/**\n * Span methods available on trace context\n */\nexport interface SpanMethods {\n setAttribute(key: string, value: string | number | boolean): void;\n setAttributes(attrs: Record<string, string | number | boolean>): void;\n setStatus(status: { code: SpanStatusCode; message?: string }): void;\n recordException(exception: Error): void;\n}\n\n/**\n * Baggage methods available on trace context\n *\n * @template TBaggage - Optional type for typed baggage (defaults to undefined for untyped)\n */\nexport interface BaggageMethods<\n TBaggage extends Record<string, unknown> | undefined = undefined,\n> {\n /**\n * Get a baggage entry by key\n * @param key - Baggage key\n * @returns Baggage entry value or undefined\n */\n getBaggage(key: string): string | undefined;\n\n /**\n * Set a baggage entry\n *\n * Note: OpenTelemetry contexts are immutable. For proper scoping across async\n * boundaries, use withBaggage() instead. This method updates baggage in the\n * current context which may not propagate to all child operations.\n *\n * @param key - Baggage key\n * @param value - Baggage value\n * @returns The baggage value that was set (for chaining)\n *\n * @example Using withBaggage() (recommended)\n * ```typescript\n * await withBaggage({ baggage: { 'key': 'value' }, fn: async () => {\n * // Baggage is available here and in child spans\n * });\n * ```\n */\n setBaggage(key: string, value: string): string;\n\n /**\n * Delete a baggage entry\n *\n * Note: OpenTelemetry contexts are immutable. For proper scoping across async\n * boundaries, use withBaggage() with only the entries you want instead.\n *\n * @param key - Baggage key\n */\n deleteBaggage(key: string): void;\n\n /**\n * Get all baggage entries\n * @returns Map of all baggage entries\n */\n getAllBaggage(): Map<string, BaggageEntry>;\n\n /**\n * Get typed baggage (only available when TBaggage is defined)\n * This is used internally by defineBaggageSchema()\n *\n * @internal\n */\n getTypedBaggage?: TBaggage extends Record<string, unknown>\n ? <T extends TBaggage>(namespace?: string) => Partial<T> | undefined\n : never;\n\n /**\n * Set typed baggage (only available when TBaggage is defined)\n * This is used internally by defineBaggageSchema()\n *\n * @internal\n */\n setTypedBaggage?: TBaggage extends Record<string, unknown>\n ? <T extends TBaggage>(\n namespace: string | undefined,\n value: Partial<T>,\n ) => void\n : never;\n}\n\n/**\n * Complete trace context that merges base context, span methods, and baggage methods\n *\n * This is the ctx parameter passed to factory functions in trace().\n * It provides access to trace IDs, span manipulation methods, and baggage operations.\n *\n * @template TBaggage - Optional type for typed baggage support\n *\n * @example Untyped (default)\n * ```typescript\n * export const handler = trace((ctx) => async () => {\n * ctx.getBaggage('key'); // returns string | undefined\n * });\n * ```\n *\n * @example Typed baggage\n * ```typescript\n * type TenantBaggage = { tenantId: string; region?: string };\n *\n * export const handler = trace<TenantBaggage>((ctx) => async () => {\n * // Use typed schema helper for type-safe access\n * const schema = defineBaggageSchema<TenantBaggage>('tenant');\n * const tenant = schema.get(ctx); // Partial<TenantBaggage> | undefined\n * });\n * ```\n */\nexport type TraceContext<\n TBaggage extends Record<string, unknown> | undefined = undefined,\n> = TraceContextBase & SpanMethods & BaggageMethods<TBaggage>;\n\n/**\n * Create a TraceContext from an OpenTelemetry Span\n *\n * This utility extracts trace context information from a span\n * and provides span manipulation methods and baggage operations in a consistent format.\n *\n * Note: Baggage methods always operate on the currently active context,\n * which may differ from the context when createTraceContext was called.\n */\nexport function createTraceContext<\n TBaggage extends Record<string, unknown> | undefined = undefined,\n>(span: Span): TraceContext<TBaggage> {\n const spanContext = span.spanContext();\n\n // Store the current active context in AsyncLocalStorage so baggage setters can update it\n // This ensures ctx.setBaggage() changes persist and are visible to OpenTelemetry operations\n // IMPORTANT: Only initialize if not already set (preserve baggage updates from parent spans)\n const existingStored = contextStorage.getStore();\n if (!existingStored) {\n const activeContext = context.active();\n contextStorage.enterWith(activeContext);\n }\n\n // Baggage helpers that always use the current active context\n // This ensures baggage operations work correctly even if context changes\n const baggageHelpers: BaggageMethods<TBaggage> = {\n getBaggage(key: string): string | undefined {\n // Check active context first (from withBaggage, context.with, etc.)\n // Then check stored context (from setters)\n // This ensures both withBaggage() and ctx.setBaggage() work correctly\n const activeCtx = context.active();\n let baggage = propagation.getBaggage(activeCtx);\n if (!baggage) {\n const storedContext = contextStorage.getStore();\n if (storedContext) {\n baggage = propagation.getBaggage(storedContext);\n }\n }\n return baggage?.getEntry(key)?.value;\n },\n\n setBaggage(key: string, value: string): string {\n // OpenTelemetry contexts are immutable, so we create a new context with updated baggage\n // Check active context first (may have baggage from withBaggage), then stored context\n const activeCtx = context.active();\n const storedContext = contextStorage.getStore();\n const currentContext = storedContext ?? activeCtx;\n const baggage =\n propagation.getBaggage(currentContext) ?? propagation.createBaggage();\n const updated = baggage.setEntry(key, { value });\n const newContext = propagation.setBaggage(currentContext, updated);\n\n updateActiveContext(newContext);\n\n return value;\n },\n\n deleteBaggage(key: string): void {\n // Check active context first, then stored context\n const activeCtx = context.active();\n const storedContext = contextStorage.getStore();\n const currentContext = storedContext ?? activeCtx;\n const baggage = propagation.getBaggage(currentContext);\n if (baggage) {\n const updated = baggage.removeEntry(key);\n const newContext = propagation.setBaggage(currentContext, updated);\n\n updateActiveContext(newContext);\n }\n },\n\n getAllBaggage(): Map<string, BaggageEntry> {\n // Check active context first, then stored context\n const activeCtx = context.active();\n let baggage = propagation.getBaggage(activeCtx);\n if (!baggage) {\n const storedContext = contextStorage.getStore();\n if (storedContext) {\n baggage = propagation.getBaggage(storedContext);\n }\n }\n if (!baggage) {\n return new Map();\n }\n\n // Convert baggage entries to a Map\n const entries = new Map<string, BaggageEntry>();\n for (const [key, entry] of baggage.getAllEntries()) {\n entries.set(key, entry);\n }\n return entries;\n },\n\n // Typed baggage helpers (used by defineBaggageSchema)\n getTypedBaggage: (<T extends Record<string, unknown>>(\n namespace?: string,\n ) => {\n // Check active context first, then stored context\n const activeCtx = context.active();\n let baggage = propagation.getBaggage(activeCtx);\n if (!baggage) {\n const storedContext = contextStorage.getStore();\n if (storedContext) {\n baggage = propagation.getBaggage(storedContext);\n }\n }\n if (!baggage) return;\n\n const prefix = namespace ? `${namespace}.` : '';\n const result: Record<string, unknown> = {};\n\n for (const [key, entry] of baggage.getAllEntries()) {\n if (namespace && key.startsWith(prefix)) {\n const fieldName = key.slice(prefix.length);\n result[fieldName] = entry.value;\n } else if (!namespace) {\n result[key] = entry.value;\n }\n }\n\n return Object.keys(result).length > 0\n ? (result as Partial<T>)\n : undefined;\n }) as TBaggage extends Record<string, unknown>\n ? <T extends TBaggage>(namespace?: string) => Partial<T> | undefined\n : never,\n\n setTypedBaggage: (<T extends Record<string, unknown>>(\n namespace: string | undefined,\n value: Partial<T>,\n ) => {\n // Check active context first, then stored context\n const activeCtx = context.active();\n const storedContext = contextStorage.getStore();\n const currentContext = storedContext ?? activeCtx;\n let baggage =\n propagation.getBaggage(currentContext) ?? propagation.createBaggage();\n\n const prefix = namespace ? `${namespace}.` : '';\n for (const [key, val] of Object.entries(value)) {\n if (val !== undefined) {\n const baggageKey = `${prefix}${key}`;\n baggage = baggage.setEntry(baggageKey, { value: String(val) });\n }\n }\n\n const newContext = propagation.setBaggage(currentContext, baggage);\n updateActiveContext(newContext);\n }) as TBaggage extends Record<string, unknown>\n ? <T extends TBaggage>(\n namespace: string | undefined,\n value: Partial<T>,\n ) => void\n : never,\n };\n\n return {\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n correlationId: spanContext.traceId.slice(0, 16),\n setAttribute: span.setAttribute.bind(span),\n setAttributes: span.setAttributes.bind(span),\n setStatus: span.setStatus.bind(span),\n recordException: span.recordException.bind(span),\n ...baggageHelpers,\n };\n}\n\n/**\n * Define a typed baggage schema for type-safe baggage operations\n *\n * This helper provides a type-safe API for working with baggage entries.\n * The namespace parameter is optional and prefixes all keys to avoid collisions.\n *\n * @template T - The baggage schema type (all fields are treated as optional)\n * @param namespace - Optional namespace to prefix baggage keys\n *\n * @example Basic usage\n * ```typescript\n * type TenantBaggage = { tenantId: string; region?: string };\n * const tenantBaggage = defineBaggageSchema<TenantBaggage>('tenant');\n *\n * export const handler = trace<TenantBaggage>((ctx) => async () => {\n * // Get typed baggage\n * const tenant = tenantBaggage.get(ctx);\n * if (tenant?.tenantId) {\n * console.log('Tenant:', tenant.tenantId);\n * }\n *\n * // Set typed baggage\n * tenantBaggage.set(ctx, { tenantId: 't1', region: 'us-east-1' });\n * });\n * ```\n *\n * @example With withBaggage helper\n * ```typescript\n * const tenantBaggage = defineBaggageSchema<TenantBaggage>('tenant');\n *\n * export const handler = trace<TenantBaggage>((ctx) => async () => {\n * return await tenantBaggage.with(ctx, { tenantId: 't1' }, async () => {\n * // Baggage is available here and in child spans\n * const tenant = tenantBaggage.get(ctx);\n * });\n * });\n * ```\n */\nexport function defineBaggageSchema<T extends Record<string, unknown>>(\n namespace?: string,\n) {\n return {\n /**\n * Get typed baggage from context\n * @param ctx - Trace context\n * @returns Partial baggage object or undefined if no baggage is set\n */\n get: (ctx: TraceContext<T>): Partial<T> | undefined => {\n if (!ctx.getTypedBaggage) return undefined;\n return ctx.getTypedBaggage<T>(namespace);\n },\n\n /**\n * Set typed baggage in context\n *\n * Note: For proper scoping across async boundaries, use the `with` method instead\n *\n * @param ctx - Trace context\n * @param value - Partial baggage object to set\n */\n set: (ctx: TraceContext<T>, value: Partial<T>): void => {\n if (!ctx.setTypedBaggage) return;\n ctx.setTypedBaggage<T>(namespace, value);\n },\n\n /**\n * Run a function with typed baggage properly scoped\n *\n * This is the recommended way to set baggage as it ensures proper\n * scoping across async boundaries.\n *\n * @param ctx - Trace context (can be omitted, will use active context)\n * @param value - Partial baggage object to set\n * @param fn - Function to execute with the baggage\n */\n with: <R>(\n ctxOrValue: TraceContext<T> | Partial<T>,\n valueOrFn: Partial<T> | (() => R | Promise<R>),\n maybeFn?: () => R | Promise<R>,\n ): R | Promise<R> => {\n // Support both with(ctx, value, fn) and with(value, fn)\n const value = maybeFn\n ? (valueOrFn as Partial<T>)\n : (ctxOrValue as Partial<T>);\n const fn = maybeFn || (valueOrFn as () => R | Promise<R>);\n\n // Serialize typed baggage to flat key-value pairs\n const prefix = namespace ? `${namespace}.` : '';\n const flatBaggage: Record<string, string> = {};\n for (const [key, val] of Object.entries(value)) {\n if (val !== undefined) {\n flatBaggage[`${prefix}${key}`] = String(val);\n }\n }\n\n // Use the existing withBaggage helper\n const currentContext = context.active();\n let baggage =\n propagation.getBaggage(currentContext) ?? propagation.createBaggage();\n\n for (const [key, val] of Object.entries(flatBaggage)) {\n baggage = baggage.setEntry(key, { value: val });\n }\n\n const newContext = propagation.setBaggage(currentContext, baggage);\n return context.with(newContext, fn);\n },\n };\n}\n"]}
@@ -0,0 +1,203 @@
1
+ 'use strict';
2
+
3
+ // src/sampling.ts
4
+ var RandomSampler = class {
5
+ constructor(sampleRate) {
6
+ this.sampleRate = sampleRate;
7
+ if (sampleRate < 0 || sampleRate > 1) {
8
+ throw new Error("Sample rate must be between 0 and 1");
9
+ }
10
+ }
11
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
12
+ shouldSample(_context) {
13
+ return Math.random() < this.sampleRate;
14
+ }
15
+ };
16
+ var AlwaysSampler = class {
17
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
18
+ shouldSample(_context) {
19
+ return true;
20
+ }
21
+ };
22
+ var NeverSampler = class {
23
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
24
+ shouldSample(_context) {
25
+ return false;
26
+ }
27
+ };
28
+ var AdaptiveSampler = class {
29
+ baselineSampleRate;
30
+ slowThresholdMs;
31
+ alwaysSampleErrors;
32
+ alwaysSampleSlow;
33
+ logger;
34
+ // Track whether we should sample this request
35
+ samplingDecisions = /* @__PURE__ */ new WeakMap();
36
+ // Track operation results to enable post-execution decision
37
+ operationResults = /* @__PURE__ */ new WeakMap();
38
+ constructor(options = {}) {
39
+ this.baselineSampleRate = options.baselineSampleRate ?? 0.1;
40
+ this.slowThresholdMs = options.slowThresholdMs ?? 1e3;
41
+ this.alwaysSampleErrors = options.alwaysSampleErrors ?? true;
42
+ this.alwaysSampleSlow = options.alwaysSampleSlow ?? true;
43
+ this.logger = options.logger;
44
+ if (this.baselineSampleRate < 0 || this.baselineSampleRate > 1) {
45
+ throw new Error("Baseline sample rate must be between 0 and 1");
46
+ }
47
+ }
48
+ needsTailSampling() {
49
+ return true;
50
+ }
51
+ shouldSample(context) {
52
+ const baselineDecision = Math.random() < this.baselineSampleRate;
53
+ this.samplingDecisions.set(context.args, baselineDecision);
54
+ return true;
55
+ }
56
+ /**
57
+ * Re-evaluate sampling decision after operation completes
58
+ *
59
+ * This allows us to always capture errors and slow requests,
60
+ * even if they weren't initially sampled.
61
+ *
62
+ * @param context - Sampling context
63
+ * @param result - Operation result
64
+ * @returns true if this operation should be kept (not discarded)
65
+ */
66
+ shouldKeepTrace(context, result) {
67
+ const baselineDecision = this.samplingDecisions.get(context.args) ?? false;
68
+ if (this.alwaysSampleErrors && !result.success) {
69
+ if (!baselineDecision) {
70
+ this.logger?.debug("Adaptive sampling: Keeping error trace", {
71
+ operation: context.operationName,
72
+ error: result.error?.message
73
+ });
74
+ }
75
+ return true;
76
+ }
77
+ if (this.alwaysSampleSlow && result.duration >= this.slowThresholdMs) {
78
+ if (!baselineDecision) {
79
+ this.logger?.debug("Adaptive sampling: Keeping slow trace", {
80
+ operation: context.operationName,
81
+ duration: result.duration
82
+ });
83
+ }
84
+ return true;
85
+ }
86
+ return baselineDecision;
87
+ }
88
+ };
89
+ var UserIdSampler = class {
90
+ baselineSampleRate;
91
+ alwaysSampleUsers;
92
+ extractUserId;
93
+ logger;
94
+ constructor(options) {
95
+ this.baselineSampleRate = options.baselineSampleRate ?? 0.1;
96
+ this.alwaysSampleUsers = new Set(options.alwaysSampleUsers || []);
97
+ this.extractUserId = options.extractUserId;
98
+ this.logger = options.logger;
99
+ }
100
+ shouldSample(context) {
101
+ const userId = this.extractUserId(context.args);
102
+ if (userId && this.alwaysSampleUsers.has(userId)) {
103
+ this.logger?.debug("Sampling user request", {
104
+ operation: context.operationName,
105
+ userId
106
+ });
107
+ return true;
108
+ }
109
+ if (userId) {
110
+ const hash = this.hashString(userId);
111
+ return hash < this.baselineSampleRate;
112
+ }
113
+ return Math.random() < this.baselineSampleRate;
114
+ }
115
+ /**
116
+ * Add user IDs to always-sample list
117
+ */
118
+ addAlwaysSampleUsers(...userIds) {
119
+ for (const userId of userIds) {
120
+ this.alwaysSampleUsers.add(userId);
121
+ }
122
+ }
123
+ /**
124
+ * Remove user IDs from always-sample list
125
+ */
126
+ removeAlwaysSampleUsers(...userIds) {
127
+ for (const userId of userIds) {
128
+ this.alwaysSampleUsers.delete(userId);
129
+ }
130
+ }
131
+ /**
132
+ * Simple hash function for consistent user sampling
133
+ */
134
+ hashString(str) {
135
+ let hash = 0;
136
+ for (let i = 0; i < str.length; i++) {
137
+ const char = str.codePointAt(i) ?? 0;
138
+ hash = (hash << 5) - hash + char;
139
+ hash = hash & hash;
140
+ }
141
+ return Math.abs(hash) / 2147483647;
142
+ }
143
+ };
144
+ var CompositeSampler = class {
145
+ constructor(samplers) {
146
+ this.samplers = samplers;
147
+ if (samplers.length === 0) {
148
+ throw new Error("CompositeSampler requires at least one child sampler");
149
+ }
150
+ }
151
+ shouldSample(context) {
152
+ return this.samplers.some((sampler) => sampler.shouldSample(context));
153
+ }
154
+ };
155
+ var FeatureFlagSampler = class {
156
+ baselineSampleRate;
157
+ alwaysSampleFlags;
158
+ extractFlags;
159
+ logger;
160
+ constructor(options) {
161
+ this.baselineSampleRate = options.baselineSampleRate ?? 0.1;
162
+ this.alwaysSampleFlags = new Set(options.alwaysSampleFlags || []);
163
+ this.extractFlags = options.extractFlags;
164
+ this.logger = options.logger;
165
+ }
166
+ shouldSample(context) {
167
+ const flags = this.extractFlags(context.args, context.metadata);
168
+ if (flags && flags.some((flag) => this.alwaysSampleFlags.has(flag))) {
169
+ this.logger?.debug("Sampling feature flag request", {
170
+ operation: context.operationName,
171
+ flags
172
+ });
173
+ return true;
174
+ }
175
+ return Math.random() < this.baselineSampleRate;
176
+ }
177
+ /**
178
+ * Add feature flags to always-sample list
179
+ */
180
+ addAlwaysSampleFlags(...flags) {
181
+ for (const flag of flags) {
182
+ this.alwaysSampleFlags.add(flag);
183
+ }
184
+ }
185
+ /**
186
+ * Remove feature flags from always-sample list
187
+ */
188
+ removeAlwaysSampleFlags(...flags) {
189
+ for (const flag of flags) {
190
+ this.alwaysSampleFlags.delete(flag);
191
+ }
192
+ }
193
+ };
194
+
195
+ exports.AdaptiveSampler = AdaptiveSampler;
196
+ exports.AlwaysSampler = AlwaysSampler;
197
+ exports.CompositeSampler = CompositeSampler;
198
+ exports.FeatureFlagSampler = FeatureFlagSampler;
199
+ exports.NeverSampler = NeverSampler;
200
+ exports.RandomSampler = RandomSampler;
201
+ exports.UserIdSampler = UserIdSampler;
202
+ //# sourceMappingURL=chunk-HE6T6FIX.cjs.map
203
+ //# sourceMappingURL=chunk-HE6T6FIX.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sampling.ts"],"names":[],"mappings":"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","file":"chunk-HE6T6FIX.cjs","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 Logger } from './logger';\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/**\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}\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 sampleRate: number) {\n if (sampleRate < 0 || sampleRate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n shouldSample(_context: SamplingContext): boolean {\n return Math.random() < this.sampleRate;\n }\n}\n\n/**\n * Always sample (100% tracing)\n */\nexport class AlwaysSampler implements Sampler {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n shouldSample(_context: SamplingContext): boolean {\n return true;\n }\n}\n\n/**\n * Never sample (0% tracing)\n */\nexport class NeverSampler implements Sampler {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\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 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 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.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 }\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 * 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('Adaptive sampling: Keeping error trace', {\n operation: context.operationName,\n error: result.error?.message,\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('Adaptive sampling: Keeping slow trace', {\n operation: context.operationName,\n duration: result.duration,\n });\n }\n return true;\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('Sampling user request', {\n operation: context.operationName,\n userId,\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 let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.codePointAt(i) ?? 0;\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash) / 2_147_483_647; // Normalize to 0-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('Sampling feature flag request', {\n operation: context.operationName,\n flags,\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"]}
@@ -0,0 +1,100 @@
1
+ 'use strict';
2
+
3
+ var chunkWBWNM6LB_cjs = require('./chunk-WBWNM6LB.cjs');
4
+
5
+ // src/semantic-helpers.ts
6
+ function traceLLM(config) {
7
+ return (fnFactory) => {
8
+ return chunkWBWNM6LB_cjs.trace((ctx) => {
9
+ ctx.setAttribute("gen.ai.request.model", config.model);
10
+ ctx.setAttribute("gen.ai.operation.name", config.operation || "chat");
11
+ if (config.system) {
12
+ ctx.setAttribute("gen.ai.system", config.system);
13
+ }
14
+ if (config.attributes) {
15
+ for (const [key, value] of Object.entries(config.attributes)) {
16
+ if (value !== void 0 && value !== null) {
17
+ const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
18
+ ctx.setAttribute(key, attrValue);
19
+ }
20
+ }
21
+ }
22
+ return fnFactory(ctx);
23
+ });
24
+ };
25
+ }
26
+ function traceDB(config) {
27
+ return (fnFactory) => {
28
+ return chunkWBWNM6LB_cjs.trace((ctx) => {
29
+ ctx.setAttribute("db.system", config.system);
30
+ if (config.operation) {
31
+ ctx.setAttribute("db.operation", config.operation);
32
+ }
33
+ if (config.dbName) {
34
+ ctx.setAttribute("db.name", config.dbName);
35
+ }
36
+ if (config.collection) {
37
+ ctx.setAttribute("db.collection.name", config.collection);
38
+ }
39
+ if (config.attributes) {
40
+ for (const [key, value] of Object.entries(config.attributes)) {
41
+ if (value !== void 0 && value !== null) {
42
+ const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
43
+ ctx.setAttribute(key, attrValue);
44
+ }
45
+ }
46
+ }
47
+ return fnFactory(ctx);
48
+ });
49
+ };
50
+ }
51
+ function traceHTTP(config) {
52
+ return (fnFactory) => {
53
+ return chunkWBWNM6LB_cjs.trace((ctx) => {
54
+ if (config.method) {
55
+ ctx.setAttribute("http.request.method", config.method);
56
+ }
57
+ if (config.url) {
58
+ ctx.setAttribute("url.full", config.url);
59
+ }
60
+ if (config.attributes) {
61
+ for (const [key, value] of Object.entries(config.attributes)) {
62
+ if (value !== void 0 && value !== null) {
63
+ const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
64
+ ctx.setAttribute(key, attrValue);
65
+ }
66
+ }
67
+ }
68
+ return fnFactory(ctx);
69
+ });
70
+ };
71
+ }
72
+ function traceMessaging(config) {
73
+ return (fnFactory) => {
74
+ return chunkWBWNM6LB_cjs.trace((ctx) => {
75
+ ctx.setAttribute("messaging.system", config.system);
76
+ if (config.operation) {
77
+ ctx.setAttribute("messaging.operation", config.operation);
78
+ }
79
+ if (config.destination) {
80
+ ctx.setAttribute("messaging.destination.name", config.destination);
81
+ }
82
+ if (config.attributes) {
83
+ for (const [key, value] of Object.entries(config.attributes)) {
84
+ if (value !== void 0 && value !== null) {
85
+ const attrValue = typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : JSON.stringify(value);
86
+ ctx.setAttribute(key, attrValue);
87
+ }
88
+ }
89
+ }
90
+ return fnFactory(ctx);
91
+ });
92
+ };
93
+ }
94
+
95
+ exports.traceDB = traceDB;
96
+ exports.traceHTTP = traceHTTP;
97
+ exports.traceLLM = traceLLM;
98
+ exports.traceMessaging = traceMessaging;
99
+ //# sourceMappingURL=chunk-KIXWPOCO.cjs.map
100
+ //# sourceMappingURL=chunk-KIXWPOCO.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/semantic-helpers.ts"],"names":["trace"],"mappings":";;;;;AAiLO,SAAS,SAA2C,MAAA,EAAmB;AAC5E,EAAA,OAAO,CACL,SAAA,KAC2C;AAC3C,IAAA,OAAOA,uBAAA,CAAsB,CAAC,GAAA,KAAQ;AAEpC,MAAA,GAAA,CAAI,YAAA,CAAa,sBAAA,EAAwB,MAAA,CAAO,KAAK,CAAA;AACrD,MAAA,GAAA,CAAI,YAAA,CAAa,uBAAA,EAAyB,MAAA,CAAO,SAAA,IAAa,MAAM,CAAA;AACpE,MAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,QAAA,GAAA,CAAI,YAAA,CAAa,eAAA,EAAiB,MAAA,CAAO,MAAM,CAAA;AAAA,MACjD;AACA,MAAA,IAAI,OAAO,UAAA,EAAY;AACrB,QAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,EAAG;AAC5D,UAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAGzC,YAAA,MAAM,SAAA,GACJ,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,SAAA,GACb,KAAA,GACA,IAAA,CAAK,UAAU,KAAK,CAAA;AAC1B,YAAA,GAAA,CAAI,YAAA,CAAa,KAAK,SAAS,CAAA;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAGA,MAAA,OAAO,UAAU,GAAG,CAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH,CAAA;AACF;AAqGO,SAAS,QAA0C,MAAA,EAAkB;AAC1E,EAAA,OAAO,CACL,SAAA,KAC2C;AAC3C,IAAA,OAAOA,uBAAA,CAAsB,CAAC,GAAA,KAAQ;AAEpC,MAAA,GAAA,CAAI,YAAA,CAAa,WAAA,EAAa,MAAA,CAAO,MAAM,CAAA;AAC3C,MAAA,IAAI,OAAO,SAAA,EAAW;AACpB,QAAA,GAAA,CAAI,YAAA,CAAa,cAAA,EAAgB,MAAA,CAAO,SAAS,CAAA;AAAA,MACnD;AACA,MAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,QAAA,GAAA,CAAI,YAAA,CAAa,SAAA,EAAW,MAAA,CAAO,MAAM,CAAA;AAAA,MAC3C;AACA,MAAA,IAAI,OAAO,UAAA,EAAY;AACrB,QAAA,GAAA,CAAI,YAAA,CAAa,oBAAA,EAAsB,MAAA,CAAO,UAAU,CAAA;AAAA,MAC1D;AACA,MAAA,IAAI,OAAO,UAAA,EAAY;AACrB,QAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,EAAG;AAC5D,UAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAGzC,YAAA,MAAM,SAAA,GACJ,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,SAAA,GACb,KAAA,GACA,IAAA,CAAK,UAAU,KAAK,CAAA;AAC1B,YAAA,GAAA,CAAI,YAAA,CAAa,KAAK,SAAS,CAAA;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAGA,MAAA,OAAO,UAAU,GAAG,CAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH,CAAA;AACF;AAsEO,SAAS,UACd,MAAA,EACA;AACA,EAAA,OAAO,CACL,SAAA,KAC2C;AAC3C,IAAA,OAAOA,uBAAA,CAAsB,CAAC,GAAA,KAAQ;AAEpC,MAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,QAAA,GAAA,CAAI,YAAA,CAAa,qBAAA,EAAuB,MAAA,CAAO,MAAM,CAAA;AAAA,MACvD;AACA,MAAA,IAAI,OAAO,GAAA,EAAK;AACd,QAAA,GAAA,CAAI,YAAA,CAAa,UAAA,EAAY,MAAA,CAAO,GAAG,CAAA;AAAA,MACzC;AACA,MAAA,IAAI,OAAO,UAAA,EAAY;AACrB,QAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,EAAG;AAC5D,UAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAGzC,YAAA,MAAM,SAAA,GACJ,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,SAAA,GACb,KAAA,GACA,IAAA,CAAK,UAAU,KAAK,CAAA;AAC1B,YAAA,GAAA,CAAI,YAAA,CAAa,KAAK,SAAS,CAAA;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAGA,MAAA,OAAO,UAAU,GAAG,CAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH,CAAA;AACF;AAmGO,SAAS,eACd,MAAA,EACA;AACA,EAAA,OAAO,CACL,SAAA,KAC2C;AAC3C,IAAA,OAAOA,uBAAA,CAAsB,CAAC,GAAA,KAAQ;AAEpC,MAAA,GAAA,CAAI,YAAA,CAAa,kBAAA,EAAoB,MAAA,CAAO,MAAM,CAAA;AAClD,MAAA,IAAI,OAAO,SAAA,EAAW;AACpB,QAAA,GAAA,CAAI,YAAA,CAAa,qBAAA,EAAuB,MAAA,CAAO,SAAS,CAAA;AAAA,MAC1D;AACA,MAAA,IAAI,OAAO,WAAA,EAAa;AACtB,QAAA,GAAA,CAAI,YAAA,CAAa,4BAAA,EAA8B,MAAA,CAAO,WAAW,CAAA;AAAA,MACnE;AACA,MAAA,IAAI,OAAO,UAAA,EAAY;AACrB,QAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,EAAG;AAC5D,UAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAGzC,YAAA,MAAM,SAAA,GACJ,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,QAAA,IACjB,OAAO,KAAA,KAAU,SAAA,GACb,KAAA,GACA,IAAA,CAAK,UAAU,KAAK,CAAA;AAC1B,YAAA,GAAA,CAAI,YAAA,CAAa,KAAK,SAAS,CAAA;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAGA,MAAA,OAAO,UAAU,GAAG,CAAA;AAAA,IACtB,CAAC,CAAA;AAAA,EACH,CAAA;AACF","file":"chunk-KIXWPOCO.cjs","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 { trace } from './functional';\nimport type { TraceContext } from './trace-context';\nimport type { Attributes } from '@opentelemetry/api';\n\n/**\n * Configuration for LLM (Large Language Model) operations\n *\n * Follows Gen AI semantic conventions:\n * https://opentelemetry.io/docs/specs/semconv/gen-ai/\n */\nexport interface LLMConfig {\n /** Model name (e.g., 'gpt-4', 'claude-3-opus') */\n model: string;\n /** Operation type */\n operation?: 'chat' | 'completion' | 'embedding';\n /** Model provider (e.g., 'openai', 'anthropic', 'cohere') */\n system?: string;\n /** Additional attributes to add to the span */\n attributes?: Attributes;\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 dbName?: string;\n /** Collection/table name */\n collection?: 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 /** 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 LLM operations with Gen AI semantic conventions\n *\n * Automatically adds standard attributes for LLM operations:\n * - gen.ai.request.model\n * - gen.ai.operation.name\n * - gen.ai.system\n *\n * **Use Cases:**\n * - Chat completions\n * - Text generation\n * - Embeddings\n * - Multi-step LLM workflows\n *\n * @param config - LLM operation configuration\n * @returns Traced function factory with Gen AI attributes\n *\n * @example Chat completion with OpenAI\n * ```typescript\n * import { traceLLM } from 'autotel/semantic-helpers'\n * import OpenAI from 'openai'\n *\n * const openai = new OpenAI()\n *\n * export const generateResponse = traceLLM({\n * model: 'gpt-4-turbo',\n * operation: 'chat',\n * system: 'openai'\n * })(ctx => async (prompt: string) => {\n * const response = await openai.chat.completions.create({\n * model: 'gpt-4-turbo',\n * messages: [{ role: 'user', content: prompt }]\n * })\n *\n * // Add usage metrics to span\n * ctx.setAttribute('gen.ai.usage.completion_tokens', response.usage?.completion_tokens)\n * ctx.setAttribute('gen.ai.usage.prompt_tokens', response.usage?.prompt_tokens)\n *\n * return response.choices[0].message.content\n * })\n * ```\n *\n * @example Anthropic Claude with streaming\n * ```typescript\n * import { traceLLM } from 'autotel/semantic-helpers'\n * import Anthropic from '@anthropic-ai/sdk'\n *\n * const anthropic = new Anthropic()\n *\n * export const streamResponse = traceLLM({\n * model: 'claude-3-opus-20240229',\n * operation: 'chat',\n * system: 'anthropic'\n * })(ctx => async function* (prompt: string) {\n * const stream = await anthropic.messages.create({\n * model: 'claude-3-opus-20240229',\n * messages: [{ role: 'user', content: prompt }],\n * stream: true,\n * max_tokens: 1024\n * })\n *\n * let totalTokens = 0\n * for await (const event of stream) {\n * if (event.type === 'content_block_delta') {\n * yield event.delta.text\n * }\n * if (event.type === 'message_stop') {\n * ctx.setAttribute('gen.ai.usage.completion_tokens', event.message.usage.output_tokens)\n * totalTokens = event.message.usage.output_tokens\n * }\n * }\n *\n * return totalTokens\n * })\n * ```\n *\n * @example Embeddings\n * ```typescript\n * import { traceLLM } from 'autotel/semantic-helpers'\n * import { OpenAIEmbeddings } from '@langchain/openai'\n *\n * const embeddings = new OpenAIEmbeddings()\n *\n * export const embed = traceLLM({\n * model: 'text-embedding-3-small',\n * operation: 'embedding',\n * system: 'openai'\n * })(ctx => async (text: string) => {\n * const result = await embeddings.embedQuery(text)\n * ctx.setAttribute('gen.ai.response.embedding_length', result.length)\n * return result\n * })\n * ```\n *\n * @public\n */\nexport function traceLLM<TArgs extends unknown[], TReturn>(config: LLMConfig) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n ctx.setAttribute('gen.ai.request.model', config.model);\n ctx.setAttribute('gen.ai.operation.name', config.operation || 'chat');\n if (config.system) {\n ctx.setAttribute('gen.ai.system', config.system);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\n}\n\n/**\n * Trace database operations with DB semantic conventions\n *\n * Automatically adds standard attributes for database operations:\n * - db.system\n * - db.operation\n * - db.name\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 * dbName: 'app_db',\n * collection: 'users'\n * })(ctx => async (userId: string) => {\n * const query = 'SELECT * FROM users WHERE id = $1'\n * ctx.setAttribute('db.statement', query)\n *\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 * dbName: '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 * dbName: '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<TArgs extends unknown[], TReturn>(config: DBConfig) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n ctx.setAttribute('db.system', config.system);\n if (config.operation) {\n ctx.setAttribute('db.operation', config.operation);\n }\n if (config.dbName) {\n ctx.setAttribute('db.name', config.dbName);\n }\n if (config.collection) {\n ctx.setAttribute('db.collection.name', config.collection);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\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 * url: 'https://api.example.com/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<TArgs extends unknown[], TReturn>(\n config: HTTPConfig,\n) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n if (config.method) {\n ctx.setAttribute('http.request.method', config.method);\n }\n if (config.url) {\n ctx.setAttribute('url.full', config.url);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\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<TArgs extends unknown[], TReturn>(\n config: MessagingConfig,\n) {\n return (\n fnFactory: (ctx: TraceContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>((ctx) => {\n // Set semantic convention attributes\n ctx.setAttribute('messaging.system', config.system);\n if (config.operation) {\n ctx.setAttribute('messaging.operation', config.operation);\n }\n if (config.destination) {\n ctx.setAttribute('messaging.destination.name', config.destination);\n }\n if (config.attributes) {\n for (const [key, value] of Object.entries(config.attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute only accepts primitives (string | number | boolean)\n // Arrays and objects should be serialized\n const attrValue =\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value\n : JSON.stringify(value);\n ctx.setAttribute(key, attrValue);\n }\n }\n }\n\n // Call the user's factory to get their function and return it\n return fnFactory(ctx);\n });\n };\n}\n"]}