autotel 2.25.3 → 2.25.5

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 (68) hide show
  1. package/dist/{chunk-FXKB7EPR.cjs → chunk-A5ZUL2RZ.cjs} +5 -5
  2. package/dist/{chunk-FXKB7EPR.cjs.map → chunk-A5ZUL2RZ.cjs.map} +1 -1
  3. package/dist/{chunk-SR35DG5A.js → chunk-BBBWDIYQ.js} +27 -13
  4. package/dist/chunk-BBBWDIYQ.js.map +1 -0
  5. package/dist/{chunk-3ZLYWPMY.js → chunk-CMUM4JQI.js} +3 -3
  6. package/dist/{chunk-3ZLYWPMY.js.map → chunk-CMUM4JQI.js.map} +1 -1
  7. package/dist/{chunk-AQXPGGQK.cjs → chunk-EEJGUBWV.cjs} +5 -5
  8. package/dist/{chunk-AQXPGGQK.cjs.map → chunk-EEJGUBWV.cjs.map} +1 -1
  9. package/dist/{chunk-W4EUTSB2.cjs → chunk-HZ3FYBJG.cjs} +27 -12
  10. package/dist/chunk-HZ3FYBJG.cjs.map +1 -0
  11. package/dist/{chunk-WOWTZ4EB.cjs → chunk-I6JPSD4R.cjs} +5 -5
  12. package/dist/{chunk-WOWTZ4EB.cjs.map → chunk-I6JPSD4R.cjs.map} +1 -1
  13. package/dist/{chunk-XRKAL7WJ.cjs → chunk-JSNUWSBH.cjs} +6 -6
  14. package/dist/chunk-JSNUWSBH.cjs.map +1 -0
  15. package/dist/{chunk-OWXXS4JB.cjs → chunk-MN6PZ4AN.cjs} +7 -7
  16. package/dist/{chunk-OWXXS4JB.cjs.map → chunk-MN6PZ4AN.cjs.map} +1 -1
  17. package/dist/{chunk-JM63D22M.js → chunk-OPTGXEVN.js} +368 -349
  18. package/dist/chunk-OPTGXEVN.js.map +1 -0
  19. package/dist/{chunk-PKXD2RMI.js → chunk-QDREXAD7.js} +3 -3
  20. package/dist/{chunk-PKXD2RMI.js.map → chunk-QDREXAD7.js.map} +1 -1
  21. package/dist/{chunk-RMGSBMQF.cjs → chunk-QQLP4M6W.cjs} +372 -353
  22. package/dist/chunk-QQLP4M6W.cjs.map +1 -0
  23. package/dist/{chunk-USSL3D6L.js → chunk-S4OFEXLA.js} +6 -6
  24. package/dist/chunk-S4OFEXLA.js.map +1 -0
  25. package/dist/{chunk-VVYSQXQL.js → chunk-WYP6OOCT.js} +3 -3
  26. package/dist/{chunk-VVYSQXQL.js.map → chunk-WYP6OOCT.js.map} +1 -1
  27. package/dist/{chunk-IFKDBL65.js → chunk-XB2GITM5.js} +3 -3
  28. package/dist/{chunk-IFKDBL65.js.map → chunk-XB2GITM5.js.map} +1 -1
  29. package/dist/correlation-id.cjs +10 -9
  30. package/dist/correlation-id.d.cts +4 -1
  31. package/dist/correlation-id.d.ts +4 -1
  32. package/dist/correlation-id.js +2 -1
  33. package/dist/decorators.cjs +4 -4
  34. package/dist/decorators.js +3 -3
  35. package/dist/event.cjs +6 -5
  36. package/dist/event.js +3 -2
  37. package/dist/functional.cjs +10 -10
  38. package/dist/functional.js +3 -3
  39. package/dist/http.cjs +2 -2
  40. package/dist/http.js +1 -1
  41. package/dist/index.cjs +45 -45
  42. package/dist/index.js +10 -10
  43. package/dist/messaging.cjs +7 -7
  44. package/dist/messaging.js +4 -4
  45. package/dist/semantic-helpers.cjs +8 -8
  46. package/dist/semantic-helpers.js +4 -4
  47. package/dist/test-span-collector.cjs.map +1 -1
  48. package/dist/test-span-collector.d.cts +5 -2
  49. package/dist/test-span-collector.d.ts +5 -2
  50. package/dist/test-span-collector.js.map +1 -1
  51. package/dist/webhook.cjs +4 -4
  52. package/dist/webhook.js +3 -3
  53. package/dist/workflow-distributed.cjs +5 -5
  54. package/dist/workflow-distributed.js +3 -3
  55. package/dist/workflow.cjs +8 -8
  56. package/dist/workflow.js +4 -4
  57. package/package.json +1 -1
  58. package/src/correlation-id.ts +10 -5
  59. package/src/functional.ts +440 -420
  60. package/src/test-span-collector.ts +5 -2
  61. package/src/trace-context.test.ts +73 -0
  62. package/src/trace-context.ts +44 -12
  63. package/dist/chunk-JM63D22M.js.map +0 -1
  64. package/dist/chunk-RMGSBMQF.cjs.map +0 -1
  65. package/dist/chunk-SR35DG5A.js.map +0 -1
  66. package/dist/chunk-USSL3D6L.js.map +0 -1
  67. package/dist/chunk-W4EUTSB2.cjs.map +0 -1
  68. package/dist/chunk-XRKAL7WJ.cjs.map +0 -1
@@ -36,8 +36,11 @@ type SerializableValue =
36
36
  /**
37
37
  * Portable serialized span for embedding in test metadata.
38
38
  * `startTimeMs` is derived from OTel HrTime — epoch-based wall-clock ms in the current SDK.
39
+ *
40
+ * Defined as a `type` (not `interface`) so it is assignable to
41
+ * `Record<string, unknown>` in TypeScript 6+ strict mode.
39
42
  */
40
- export interface SerializedSpan {
43
+ export type SerializedSpan = {
41
44
  spanId: string;
42
45
  parentSpanId?: string;
43
46
  name: string;
@@ -46,7 +49,7 @@ export interface SerializedSpan {
46
49
  status: 'ok' | 'error' | 'unset';
47
50
  statusMessage?: string;
48
51
  attributes?: Record<string, SerializableValue>;
49
- }
52
+ };
50
53
 
51
54
  export class TestSpanCollector implements SpanExporter {
52
55
  private traces = new Map<string, ReadableSpan[]>();
@@ -0,0 +1,73 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { enterOrRun } from './trace-context';
3
+
4
+ type Box<T> = { value: T };
5
+
6
+ function createFakeStorage<T>(initialValue?: T) {
7
+ let currentStore =
8
+ initialValue === undefined ? undefined : { value: initialValue };
9
+ const runCalls: Array<Box<T>> = [];
10
+ const enterWithCalls: Array<Box<T>> = [];
11
+
12
+ const storage = {
13
+ getStore() {
14
+ return currentStore;
15
+ },
16
+ run(store: Box<T>, fn: () => void) {
17
+ runCalls.push(store);
18
+ const previousStore = currentStore;
19
+ currentStore = store;
20
+ try {
21
+ fn();
22
+ } finally {
23
+ currentStore = previousStore;
24
+ }
25
+ },
26
+ enterWith(store: Box<T>) {
27
+ enterWithCalls.push(store);
28
+ currentStore = store;
29
+ },
30
+ };
31
+
32
+ return {
33
+ enterWithCalls,
34
+ runCalls,
35
+ storage: storage as unknown as {
36
+ enterWith?: (store: Box<T>) => void;
37
+ getStore: () => Box<T> | undefined;
38
+ run: (store: Box<T>, fn: () => void) => void;
39
+ },
40
+ };
41
+ }
42
+
43
+ describe('enterOrRun', () => {
44
+ it('mutates the existing store when already inside a run scope', () => {
45
+ const { storage } = createFakeStorage('outer');
46
+
47
+ enterOrRun(storage as never, 'updated');
48
+
49
+ expect(storage.getStore()?.value).toBe('updated');
50
+ });
51
+
52
+ it('falls back to run() when enterWith throws', () => {
53
+ const { runCalls, storage } = createFakeStorage<string>();
54
+ storage.enterWith = () => {
55
+ throw new Error('enterWith not supported');
56
+ };
57
+
58
+ enterOrRun(storage as never, 'worker-value');
59
+
60
+ expect(runCalls).toHaveLength(1);
61
+ expect(runCalls[0]?.value).toBe('worker-value');
62
+ });
63
+
64
+ it('prefers enterWith() when no store exists and the runtime supports it', () => {
65
+ const { enterWithCalls, storage } = createFakeStorage<string>();
66
+
67
+ enterOrRun(storage as never, 'node-value');
68
+
69
+ expect(enterWithCalls).toHaveLength(1);
70
+ expect(enterWithCalls[0]?.value).toBe('node-value');
71
+ expect(storage.getStore()?.value).toBe('node-value');
72
+ });
73
+ });
@@ -13,16 +13,20 @@ import type {
13
13
  import { context, propagation } from '@opentelemetry/api';
14
14
  import { AsyncLocalStorage } from 'node:async_hooks';
15
15
 
16
+ type AsyncLocalBox<T> = {
17
+ value: T;
18
+ };
19
+
16
20
  /**
17
21
  * AsyncLocalStorage for storing the active context with baggage
18
22
  * This allows setters to update the context and have it persist
19
23
  */
20
- const contextStorage = new AsyncLocalStorage<Context>();
24
+ const contextStorage = new AsyncLocalStorage<AsyncLocalBox<Context>>();
21
25
 
22
26
  /**
23
27
  * Get the context storage instance (for initialization in functional.ts)
24
28
  */
25
- export function getContextStorage(): AsyncLocalStorage<Context> {
29
+ export function getContextStorage(): AsyncLocalStorage<AsyncLocalBox<Context>> {
26
30
  return contextStorage;
27
31
  }
28
32
 
@@ -33,10 +37,38 @@ export function getContextStorage(): AsyncLocalStorage<Context> {
33
37
  export function getActiveContextWithBaggage(): Context {
34
38
  // Check stored context first (from setters), then fall back to active context
35
39
  // This ensures ctx.setBaggage() changes are visible to OpenTelemetry operations
36
- const stored = contextStorage.getStore();
40
+ const stored = contextStorage.getStore()?.value;
37
41
  return stored ?? context.active();
38
42
  }
39
43
 
44
+ /**
45
+ * Set a value in AsyncLocalStorage, preferring enterWith() when available
46
+ * (Node.js) and falling back to run() for environments that only support
47
+ * run() (e.g. Cloudflare Workers).
48
+ *
49
+ * On runtimes without enterWith() we mutate the existing run() scope when one
50
+ * exists. This is what allows baggage/correlation updates to remain visible
51
+ * for the rest of the traced callback in Workers.
52
+ */
53
+ export function enterOrRun<T>(
54
+ storage: AsyncLocalStorage<AsyncLocalBox<T>>,
55
+ value: T,
56
+ ): void {
57
+ const existingStore = storage.getStore();
58
+ if (existingStore) {
59
+ existingStore.value = value;
60
+ return;
61
+ }
62
+
63
+ const boxedValue = { value };
64
+ try {
65
+ storage.enterWith(boxedValue);
66
+ } catch {
67
+ // Cloudflare Workers define enterWith but throw at runtime
68
+ storage.run(boxedValue, () => {});
69
+ }
70
+ }
71
+
40
72
  /**
41
73
  * Try to keep OpenTelemetry's context manager in sync with baggage updates
42
74
  */
@@ -47,7 +79,7 @@ type ContextManagerLike = {
47
79
 
48
80
  function updateActiveContext(newContext: Context): void {
49
81
  // Update our storage first so any helper reads see the new context
50
- contextStorage.enterWith(newContext);
82
+ enterOrRun(contextStorage, newContext);
51
83
 
52
84
  const contextWithManager = context as unknown as {
53
85
  _getContextManager?: () => ContextManagerLike;
@@ -240,10 +272,10 @@ export function createTraceContext<
240
272
  // Store the current active context in AsyncLocalStorage so baggage setters can update it
241
273
  // This ensures ctx.setBaggage() changes persist and are visible to OpenTelemetry operations
242
274
  // IMPORTANT: Only initialize if not already set (preserve baggage updates from parent spans)
243
- const existingStored = contextStorage.getStore();
275
+ const existingStored = contextStorage.getStore()?.value;
244
276
  if (!existingStored) {
245
277
  const activeContext = context.active();
246
- contextStorage.enterWith(activeContext);
278
+ enterOrRun(contextStorage, activeContext);
247
279
  }
248
280
 
249
281
  // Baggage helpers that always use the current active context
@@ -256,7 +288,7 @@ export function createTraceContext<
256
288
  const activeCtx = context.active();
257
289
  let baggage = propagation.getBaggage(activeCtx);
258
290
  if (!baggage) {
259
- const storedContext = contextStorage.getStore();
291
+ const storedContext = contextStorage.getStore()?.value;
260
292
  if (storedContext) {
261
293
  baggage = propagation.getBaggage(storedContext);
262
294
  }
@@ -268,7 +300,7 @@ export function createTraceContext<
268
300
  // OpenTelemetry contexts are immutable, so we create a new context with updated baggage
269
301
  // Check active context first (may have baggage from withBaggage), then stored context
270
302
  const activeCtx = context.active();
271
- const storedContext = contextStorage.getStore();
303
+ const storedContext = contextStorage.getStore()?.value;
272
304
  const currentContext = storedContext ?? activeCtx;
273
305
  const baggage =
274
306
  propagation.getBaggage(currentContext) ?? propagation.createBaggage();
@@ -283,7 +315,7 @@ export function createTraceContext<
283
315
  deleteBaggage(key: string): void {
284
316
  // Check active context first, then stored context
285
317
  const activeCtx = context.active();
286
- const storedContext = contextStorage.getStore();
318
+ const storedContext = contextStorage.getStore()?.value;
287
319
  const currentContext = storedContext ?? activeCtx;
288
320
  const baggage = propagation.getBaggage(currentContext);
289
321
  if (baggage) {
@@ -299,7 +331,7 @@ export function createTraceContext<
299
331
  const activeCtx = context.active();
300
332
  let baggage = propagation.getBaggage(activeCtx);
301
333
  if (!baggage) {
302
- const storedContext = contextStorage.getStore();
334
+ const storedContext = contextStorage.getStore()?.value;
303
335
  if (storedContext) {
304
336
  baggage = propagation.getBaggage(storedContext);
305
337
  }
@@ -324,7 +356,7 @@ export function createTraceContext<
324
356
  const activeCtx = context.active();
325
357
  let baggage = propagation.getBaggage(activeCtx);
326
358
  if (!baggage) {
327
- const storedContext = contextStorage.getStore();
359
+ const storedContext = contextStorage.getStore()?.value;
328
360
  if (storedContext) {
329
361
  baggage = propagation.getBaggage(storedContext);
330
362
  }
@@ -356,7 +388,7 @@ export function createTraceContext<
356
388
  ) => {
357
389
  // Check active context first, then stored context
358
390
  const activeCtx = context.active();
359
- const storedContext = contextStorage.getStore();
391
+ const storedContext = contextStorage.getStore()?.value;
360
392
  const currentContext = storedContext ?? activeCtx;
361
393
  let baggage =
362
394
  propagation.getBaggage(currentContext) ?? propagation.createBaggage();