autotel 3.0.6 → 3.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 (168) hide show
  1. package/dist/attribute-redacting-processor.cjs +0 -1
  2. package/dist/attribute-redacting-processor.js +0 -1
  3. package/dist/attributes.cjs +0 -1
  4. package/dist/attributes.js +0 -1
  5. package/dist/auto.cjs +5 -6
  6. package/dist/auto.cjs.map +1 -1
  7. package/dist/auto.js +3 -4
  8. package/dist/auto.js.map +1 -1
  9. package/dist/business-baggage.cjs +0 -1
  10. package/dist/business-baggage.js +0 -1
  11. package/dist/{chunk-HLAVN3JR.js → chunk-5GQOWMEY.js} +3 -3
  12. package/dist/{chunk-HLAVN3JR.js.map → chunk-5GQOWMEY.js.map} +1 -1
  13. package/dist/{chunk-3SDILILG.js → chunk-7NDHLHZK.js} +3 -3
  14. package/dist/{chunk-3SDILILG.js.map → chunk-7NDHLHZK.js.map} +1 -1
  15. package/dist/{chunk-K4UDKM3P.cjs → chunk-A7VZ7CSC.cjs} +11 -11
  16. package/dist/{chunk-K4UDKM3P.cjs.map → chunk-A7VZ7CSC.cjs.map} +1 -1
  17. package/dist/{chunk-DAZ7EGR4.cjs → chunk-ADZDAWNV.cjs} +17 -17
  18. package/dist/{chunk-DAZ7EGR4.cjs.map → chunk-ADZDAWNV.cjs.map} +1 -1
  19. package/dist/{chunk-NCSMD3TK.cjs → chunk-BGAR6MCX.cjs} +4 -4
  20. package/dist/{chunk-NCSMD3TK.cjs.map → chunk-BGAR6MCX.cjs.map} +1 -1
  21. package/dist/{chunk-H5YFU4SF.js → chunk-BJDZXR3Y.js} +4 -4
  22. package/dist/{chunk-H5YFU4SF.js.map → chunk-BJDZXR3Y.js.map} +1 -1
  23. package/dist/{chunk-OC6X2VIN.cjs → chunk-BTEPYWDF.cjs} +4 -4
  24. package/dist/{chunk-OC6X2VIN.cjs.map → chunk-BTEPYWDF.cjs.map} +1 -1
  25. package/dist/{chunk-S4S4AINO.js → chunk-D6ELKUMF.js} +19 -6
  26. package/dist/chunk-D6ELKUMF.js.map +1 -0
  27. package/dist/chunk-EQIY6C3X.cjs +25 -0
  28. package/dist/chunk-EQIY6C3X.cjs.map +1 -0
  29. package/dist/{chunk-TY4NXDYR.cjs → chunk-H5P4ZTCX.cjs} +50 -36
  30. package/dist/chunk-H5P4ZTCX.cjs.map +1 -0
  31. package/dist/{chunk-XCFDXZF3.cjs → chunk-I36M5IZD.cjs} +7 -7
  32. package/dist/{chunk-XCFDXZF3.cjs.map → chunk-I36M5IZD.cjs.map} +1 -1
  33. package/dist/{chunk-Z7VAOK5X.js → chunk-IC4AZUGC.js} +3 -3
  34. package/dist/{chunk-Z7VAOK5X.js.map → chunk-IC4AZUGC.js.map} +1 -1
  35. package/dist/{chunk-BPO2PQ3T.cjs → chunk-ISEHXVMD.cjs} +30 -26
  36. package/dist/chunk-ISEHXVMD.cjs.map +1 -0
  37. package/dist/{chunk-KKGM42RQ.cjs → chunk-KAELJC6T.cjs} +13 -13
  38. package/dist/{chunk-KKGM42RQ.cjs.map → chunk-KAELJC6T.cjs.map} +1 -1
  39. package/dist/{chunk-33WTKH7X.js → chunk-KPNV2GPW.js} +4 -4
  40. package/dist/chunk-KPNV2GPW.js.map +1 -0
  41. package/dist/{chunk-OM4OSBOP.js → chunk-MAITXZFR.js} +4 -4
  42. package/dist/{chunk-OM4OSBOP.js.map → chunk-MAITXZFR.js.map} +1 -1
  43. package/dist/{chunk-DSMSIVTG.js → chunk-MBEHEGQE.js} +3 -3
  44. package/dist/{chunk-DSMSIVTG.js.map → chunk-MBEHEGQE.js.map} +1 -1
  45. package/dist/{chunk-ZDPIWKWD.js → chunk-SIMG4IGE.js} +18 -14
  46. package/dist/chunk-SIMG4IGE.js.map +1 -0
  47. package/dist/{chunk-ZJ5E5OFB.js → chunk-TDJXVXM4.js} +3 -3
  48. package/dist/{chunk-ZJ5E5OFB.js.map → chunk-TDJXVXM4.js.map} +1 -1
  49. package/dist/{chunk-IRJHH6PH.cjs → chunk-ZUOASZED.cjs} +5 -5
  50. package/dist/{chunk-IRJHH6PH.cjs.map → chunk-ZUOASZED.cjs.map} +1 -1
  51. package/dist/config.cjs +0 -1
  52. package/dist/config.js +0 -1
  53. package/dist/correlation-id.cjs +12 -13
  54. package/dist/correlation-id.js +4 -5
  55. package/dist/db.cjs +0 -1
  56. package/dist/db.cjs.map +1 -1
  57. package/dist/db.js +0 -1
  58. package/dist/db.js.map +1 -1
  59. package/dist/decorators.cjs +7 -8
  60. package/dist/decorators.cjs.map +1 -1
  61. package/dist/decorators.js +6 -7
  62. package/dist/decorators.js.map +1 -1
  63. package/dist/drain-pipeline.cjs +0 -1
  64. package/dist/drain-pipeline.js +0 -1
  65. package/dist/enrichers.cjs +0 -2
  66. package/dist/enrichers.cjs.map +1 -1
  67. package/dist/enrichers.js +0 -2
  68. package/dist/enrichers.js.map +1 -1
  69. package/dist/event-testing.cjs +0 -1
  70. package/dist/event-testing.js +0 -1
  71. package/dist/event.cjs +8 -9
  72. package/dist/event.js +5 -6
  73. package/dist/exporters.cjs +0 -1
  74. package/dist/exporters.js +0 -1
  75. package/dist/filtering-span-processor.cjs +0 -1
  76. package/dist/filtering-span-processor.js +0 -1
  77. package/dist/functional.cjs +17 -14
  78. package/dist/functional.d.cts +21 -1
  79. package/dist/functional.d.ts +21 -1
  80. package/dist/functional.js +6 -7
  81. package/dist/http.cjs +5 -6
  82. package/dist/http.cjs.map +1 -1
  83. package/dist/http.js +4 -5
  84. package/dist/http.js.map +1 -1
  85. package/dist/index.cjs +86 -83
  86. package/dist/index.cjs.map +1 -1
  87. package/dist/index.d.cts +2 -2
  88. package/dist/index.d.ts +2 -2
  89. package/dist/index.js +14 -15
  90. package/dist/index.js.map +1 -1
  91. package/dist/{init-D6JfWEjL.d.ts → init-BSyIyDs5.d.ts} +36 -1
  92. package/dist/{init-CMuTaFAV.d.cts → init-D9Bxx39e.d.cts} +36 -1
  93. package/dist/instrumentation.cjs +11 -12
  94. package/dist/instrumentation.cjs.map +1 -1
  95. package/dist/instrumentation.js +3 -4
  96. package/dist/instrumentation.js.map +1 -1
  97. package/dist/logger.cjs +0 -1
  98. package/dist/logger.js +0 -1
  99. package/dist/messaging-adapters.cjs +1 -1
  100. package/dist/messaging-adapters.js +1 -1
  101. package/dist/messaging-testing.cjs +0 -2
  102. package/dist/messaging-testing.cjs.map +1 -1
  103. package/dist/messaging-testing.js +0 -2
  104. package/dist/messaging-testing.js.map +1 -1
  105. package/dist/messaging.cjs +10 -11
  106. package/dist/messaging.js +7 -8
  107. package/dist/metric-helpers.cjs +0 -1
  108. package/dist/metric-helpers.js +0 -1
  109. package/dist/metric-testing.cjs +0 -1
  110. package/dist/metric-testing.js +0 -1
  111. package/dist/metric.cjs +0 -1
  112. package/dist/metric.js +0 -1
  113. package/dist/parse-error.cjs +0 -1
  114. package/dist/parse-error.js +0 -1
  115. package/dist/processors.cjs +0 -1
  116. package/dist/processors.js +0 -1
  117. package/dist/sampling.cjs +0 -1
  118. package/dist/sampling.js +0 -1
  119. package/dist/semantic-conventions.cjs +0 -1
  120. package/dist/semantic-conventions.js +0 -1
  121. package/dist/semantic-helpers.cjs +11 -12
  122. package/dist/semantic-helpers.js +7 -8
  123. package/dist/span-name-normalizer.cjs +0 -1
  124. package/dist/span-name-normalizer.js +0 -1
  125. package/dist/tail-sampling-processor.cjs +0 -1
  126. package/dist/tail-sampling-processor.js +0 -1
  127. package/dist/test-span-collector.cjs +1 -1
  128. package/dist/test-span-collector.js +1 -1
  129. package/dist/testing.cjs +0 -1
  130. package/dist/testing.cjs.map +1 -1
  131. package/dist/testing.js +0 -1
  132. package/dist/testing.js.map +1 -1
  133. package/dist/trace-helpers.cjs +14 -15
  134. package/dist/trace-helpers.js +2 -3
  135. package/dist/tracer-provider.cjs +0 -1
  136. package/dist/tracer-provider.js +0 -1
  137. package/dist/webhook.cjs +8 -9
  138. package/dist/webhook.cjs.map +1 -1
  139. package/dist/webhook.js +6 -7
  140. package/dist/webhook.js.map +1 -1
  141. package/dist/workflow-distributed.cjs +8 -9
  142. package/dist/workflow-distributed.cjs.map +1 -1
  143. package/dist/workflow-distributed.js +6 -7
  144. package/dist/workflow-distributed.js.map +1 -1
  145. package/dist/workflow.cjs +11 -12
  146. package/dist/workflow.js +7 -8
  147. package/dist/yaml-config.cjs +5 -6
  148. package/dist/yaml-config.d.cts +1 -1
  149. package/dist/yaml-config.d.ts +1 -1
  150. package/dist/yaml-config.js +2 -3
  151. package/package.json +1 -1
  152. package/src/functional.test.ts +25 -0
  153. package/src/functional.ts +49 -0
  154. package/src/index.ts +1 -0
  155. package/src/init.customization.test.ts +80 -0
  156. package/src/init.ts +78 -15
  157. package/src/node-require.ts +7 -5
  158. package/dist/chunk-33WTKH7X.js.map +0 -1
  159. package/dist/chunk-BPO2PQ3T.cjs.map +0 -1
  160. package/dist/chunk-DGUM43GV.js +0 -10
  161. package/dist/chunk-DGUM43GV.js.map +0 -1
  162. package/dist/chunk-JEQ2X3Z6.cjs +0 -12
  163. package/dist/chunk-JEQ2X3Z6.cjs.map +0 -1
  164. package/dist/chunk-S4S4AINO.js.map +0 -1
  165. package/dist/chunk-TY4NXDYR.cjs.map +0 -1
  166. package/dist/chunk-YS6C2YJE.cjs +0 -25
  167. package/dist/chunk-YS6C2YJE.cjs.map +0 -1
  168. package/dist/chunk-ZDPIWKWD.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/circuit-breaker.ts","../src/events-config.ts","../src/event.ts"],"names":[],"mappings":"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","file":"chunk-OM4OSBOP.js","sourcesContent":["/**\n * Circuit breaker for event subscribers\n *\n * Prevents cascading failures by fast-failing when an (subscriber) is unhealthy.\n * Uses the circuit breaker pattern with three states:\n * - CLOSED: Normal operation ((subscriber) working)\n * - OPEN: Fast-fail mode ((subscriber) down)\n * - HALF_OPEN: Testing if (subscriber) recovered\n */\n\nexport interface CircuitBreakerConfig {\n /** Number of failures before opening circuit (default: 5) */\n failureThreshold: number;\n /** Time to wait before trying again in ms (default: 30000 = 30s) */\n resetTimeout: number;\n /** Time window for counting failures in ms (default: 60000 = 1min) */\n windowSize: number;\n}\n\nconst DEFAULT_CONFIG: CircuitBreakerConfig = {\n failureThreshold: 5,\n resetTimeout: 30_000, // 30 seconds\n windowSize: 60_000, // 1 minute\n};\n\nexport type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';\n\nexport const CircuitState = {\n CLOSED: 'CLOSED' as const, // Normal operation\n OPEN: 'OPEN' as const, // Fast-fail mode\n HALF_OPEN: 'HALF_OPEN' as const, // Testing recovery\n} as const;\n\ninterface FailureRecord {\n timestamp: number;\n error: string;\n}\n\n/**\n * Circuit breaker implementation\n *\n * Tracks failures and automatically opens the circuit to prevent\n * overwhelming failing subscribers.\n */\nexport class CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failures: FailureRecord[] = [];\n private lastFailureTime: number = 0;\n private readonly config: CircuitBreakerConfig;\n private readonly name: string;\n\n constructor(name: string, config?: Partial<CircuitBreakerConfig>) {\n this.name = name;\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Execute a function with circuit breaker protection\n * Throws CircuitOpenError if circuit is open\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n // Check if circuit is open\n if (this.state === CircuitState.OPEN) {\n // Check if we should transition to half-open\n const now = Date.now();\n if (now - this.lastFailureTime >= this.config.resetTimeout) {\n this.state = CircuitState.HALF_OPEN;\n } else {\n throw new CircuitOpenError(\n `Circuit breaker is OPEN for ${this.name}. ` +\n `Will retry in ${Math.ceil((this.config.resetTimeout - (now - this.lastFailureTime)) / 1000)}s`,\n );\n }\n }\n\n try {\n const result = await fn();\n\n // Success! Close circuit if it was half-open\n if (this.state === CircuitState.HALF_OPEN) {\n this.reset();\n }\n\n return result;\n } catch (error) {\n this.recordFailure(error);\n throw error;\n }\n }\n\n /**\n * Record a failure and potentially open the circuit\n */\n private recordFailure(error: unknown): void {\n const now = Date.now();\n\n // Remove old failures outside the time window\n this.failures = this.failures.filter(\n (f) => now - f.timestamp < this.config.windowSize,\n );\n\n // Record new failure\n this.failures.push({\n timestamp: now,\n error: error instanceof Error ? error.message : String(error),\n });\n\n this.lastFailureTime = now;\n\n // Check if we should open the circuit\n if (this.failures.length >= this.config.failureThreshold) {\n if (this.state === CircuitState.HALF_OPEN) {\n // Failed during test - reopen circuit\n this.state = CircuitState.OPEN;\n } else if (this.state === CircuitState.CLOSED) {\n // Too many failures - open circuit\n this.state = CircuitState.OPEN;\n }\n }\n }\n\n /**\n * Reset the circuit breaker (on success)\n */\n private reset(): void {\n this.state = CircuitState.CLOSED;\n this.failures = [];\n this.lastFailureTime = 0;\n }\n\n /**\n * Get current state (for monitoring)\n */\n getState(): CircuitState {\n return this.state;\n }\n\n /**\n * Get failure count in current window\n */\n getFailureCount(): number {\n const now = Date.now();\n // Clean up old failures\n this.failures = this.failures.filter(\n (f) => now - f.timestamp < this.config.windowSize,\n );\n return this.failures.length;\n }\n\n /**\n * Get recent failures (for debugging)\n */\n getRecentFailures(): FailureRecord[] {\n const now = Date.now();\n return this.failures.filter(\n (f) => now - f.timestamp < this.config.windowSize,\n );\n }\n\n /**\n * Manually reset the circuit breaker (for testing or manual intervention)\n */\n forceReset(): void {\n this.reset();\n }\n\n /**\n * Manually open the circuit (for testing or manual intervention)\n */\n forceOpen(): void {\n this.state = CircuitState.OPEN;\n this.lastFailureTime = Date.now();\n }\n}\n\n/**\n * Error thrown when circuit is open\n */\nexport class CircuitOpenError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CircuitOpenError';\n }\n}\n","/**\n * Events configuration types for trace context, correlation IDs, and enrichment\n *\n * @example Basic usage\n * ```typescript\n * import { init } from 'autotel';\n *\n * init({\n * service: 'my-app',\n * events: {\n * includeTraceContext: true,\n * traceUrl: (ctx) => `https://grafana.internal/explore?traceId=${ctx.traceId}`\n * }\n * });\n * ```\n */\n\n/**\n * Context passed to the traceUrl function for generating clickable trace URLs\n */\nexport interface TraceUrlContext {\n /** Trace ID (32 hex chars) - may be undefined outside a trace */\n traceId?: string;\n /** Span ID (16 hex chars) - may be undefined outside a trace */\n spanId?: string;\n /** Correlation ID (always present, 16 hex chars) */\n correlationId: string;\n /** Service name from init config */\n serviceName: string;\n /** Environment from init config */\n environment?: string;\n}\n\n/**\n * Per-key transform options for baggage enrichment\n */\nexport type BaggageTransform = 'plain' | 'hash' | ((value: string) => string);\n\n/**\n * Baggage enrichment configuration with guardrails\n */\nexport interface EnrichFromBaggageConfig {\n /**\n * Allowlist of baggage keys to include in events\n * Supports exact matches and patterns (e.g., 'tenant.*')\n */\n allow: string[];\n\n /**\n * Optional denylist of baggage keys to exclude\n * Takes precedence over allow list\n */\n deny?: string[];\n\n /**\n * Optional prefix to add to all enriched keys\n * @example 'ctx.' results in 'ctx.tenant.id'\n */\n prefix?: string;\n\n /**\n * Maximum number of keys to include (default: 10)\n * Prevents payload bloat from excessive baggage\n */\n maxKeys?: number;\n\n /**\n * Maximum total bytes for enriched values (default: 1024)\n * Prevents payload bloat from large baggage values\n */\n maxBytes?: number;\n\n /**\n * Per-key transform options\n * - 'plain': Include value as-is\n * - 'hash': Hash the value (for PII protection)\n * - function: Custom transform function\n *\n * @example\n * ```typescript\n * transform: {\n * 'user.id': 'hash', // Hash user ID for privacy\n * 'tenant.id': 'plain', // Include tenant ID as-is\n * 'session.id': (v) => v.slice(0, 8) // Custom truncation\n * }\n * ```\n */\n transform?: Record<string, BaggageTransform>;\n}\n\n/**\n * Events configuration for trace context and enrichment\n */\nexport interface EventsConfig {\n /**\n * Include trace context in events (default: false)\n *\n * When enabled, events automatically include:\n * - autotel.trace_id (32 hex chars)\n * - autotel.span_id (16 hex chars)\n * - autotel.trace_flags (2 hex chars)\n * - autotel.trace_state (raw tracestate string, if present)\n * - autotel.correlation_id (always present, 16 hex chars)\n *\n * Subscribers map these to platform-specific names:\n * - PostHog: $trace_id, $span_id\n * - Mixpanel: trace_id, span_id\n */\n includeTraceContext?: boolean;\n\n /**\n * Include full array of linked trace IDs for batch/fan-in scenarios (default: false)\n *\n * When false (default), batch/fan-in events include:\n * - autotel.linked_trace_id_count: Number of linked parents\n * - autotel.linked_trace_id_hash: Stable hash of sorted IDs (keeps payload lean)\n *\n * When true, events also include:\n * - autotel.linked_trace_ids: Full array of linked trace IDs\n */\n includeLinkedTraceIds?: boolean;\n\n /**\n * Generate clickable trace URL from context\n *\n * @param ctx - Trace context with traceId, spanId, correlationId, serviceName, environment\n * @returns URL string or undefined to skip\n *\n * @example Grafana Tempo\n * ```typescript\n * traceUrl: (ctx) => ctx.traceId\n * ? `https://grafana.internal/explore?traceId=${ctx.traceId}`\n * : undefined\n * ```\n *\n * @example Datadog\n * ```typescript\n * traceUrl: (ctx) => ctx.traceId\n * ? `https://app.datadoghq.com/apm/traces?traceId=${ctx.traceId}`\n * : undefined\n * ```\n *\n * @example Jaeger\n * ```typescript\n * traceUrl: (ctx) => ctx.traceId\n * ? `https://jaeger.internal/trace/${ctx.traceId}`\n * : undefined\n * ```\n */\n traceUrl?: (ctx: TraceUrlContext) => string | undefined;\n\n /**\n * Auto-enrich events from baggage with guardrails\n *\n * Automatically includes baggage entries in events without manual code.\n * Apply allow/deny lists and per-key transforms for PII protection.\n *\n * @example Basic allowlist\n * ```typescript\n * enrichFromBaggage: {\n * allow: ['tenant.id', 'user.id', 'request.id']\n * }\n * // Events include: tenant.id, user.id, request.id from baggage\n * ```\n *\n * @example With prefix and transforms\n * ```typescript\n * enrichFromBaggage: {\n * allow: ['tenant.id', 'user.id', 'user.email'],\n * deny: ['user.ssn'],\n * prefix: 'ctx.',\n * transform: {\n * 'user.id': 'hash',\n * 'user.email': 'hash'\n * }\n * }\n * // Events include: ctx.tenant.id, ctx.user.id (hashed), ctx.user.email (hashed)\n * ```\n */\n enrichFromBaggage?: EnrichFromBaggageConfig;\n}\n\n/**\n * Autotel context object attached to event envelopes\n *\n * This structured object is attached to events and subscribers\n * decide how to map/flatten for their platform.\n */\nexport interface AutotelEventContext {\n /** Trace ID (32 hex chars) - present when inside a trace */\n trace_id?: string;\n /** Span ID (16 hex chars) - present when inside a span */\n span_id?: string;\n /** Trace flags (2 hex chars, e.g., '01' for sampled) */\n trace_flags?: string;\n /** Raw tracestate string - present if tracestate exists */\n trace_state?: string;\n /** Clickable trace URL - present if traceUrl config is set */\n trace_url?: string;\n /** Correlation ID (always present, 16 hex chars) */\n correlation_id: string;\n /** Number of linked parent traces (batch/fan-in scenarios) */\n linked_trace_id_count?: number;\n /** Stable hash of linked trace IDs (default for batch/fan-in) */\n linked_trace_id_hash?: string;\n /** Full array of linked trace IDs (only if includeLinkedTraceIds: true) */\n linked_trace_ids?: string[];\n}\n\n/**\n * Hash a string value for PII protection\n *\n * Uses a simple, fast hash function suitable for correlation.\n * NOT cryptographically secure - use for PII masking, not security.\n */\nexport function hashValue(value: string): string {\n let hash = 0;\n for (let i = 0; i < value.length; i++) {\n const char = value.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n // Convert to positive hex string\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\n/**\n * Create a stable hash of an array of trace IDs\n *\n * Sorts the array first to ensure deterministic output regardless of order.\n */\nexport function hashLinkedTraceIds(traceIds: string[]): string {\n const sorted = [...traceIds].sort();\n return hashValue(sorted.join(','));\n}\n","/**\n * Events API for product events platforms\n *\n * Track user behavior, business events, and critical actions.\n * Sends to product events platforms (PostHog, Mixpanel, Amplitude) via subscribers.\n * For business people who think in events/funnels.\n *\n * For OpenTelemetry metrics (Prometheus/Grafana), use the Metrics class instead.\n *\n * @example Recommended: Configure subscribers in init(), use track() function\n * ```typescript\n * import { init, track } from 'autotel';\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * init({\n * service: 'my-app',\n * subscribers: [new PostHogSubscriber({ apiKey: 'phc_...' })]\n * });\n *\n * // Track events - uses subscribers from init()\n * track('application.submitted', { jobId: '123', userId: '456' });\n * ```\n *\n * @example Create Event instance (inherits subscribers from init)\n * ```typescript\n * import { Event } from 'autotel/event';\n *\n * // Uses subscribers configured in init()\n * const event = new Event('job-application');\n * event.trackEvent('application.submitted', { jobId: '123' });\n * ```\n *\n * @example Override subscribers for specific Event instance\n * ```typescript\n * import { Event } from 'autotel/event';\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * // Override: use different subscribers for this instance\n * const event = new Event('job-application', {\n * subscribers: [new PostHogSubscriber({ apiKey: 'phc_different_project' })]\n * });\n *\n * event.trackEvent('application.submitted', { jobId: '123' });\n * ```\n */\n\nimport { trace, propagation, context, TraceFlags } from '@opentelemetry/api';\nimport { type Logger } from './logger';\nimport {\n getLogger,\n getValidationConfig,\n getConfig,\n getEventsConfig,\n} from './init';\nimport {\n type EventSubscriber,\n type EventAttributes,\n type EventAttributesInput,\n type FunnelStatus,\n type OutcomeStatus,\n type AutotelEventContext,\n} from './event-subscriber';\nimport { type EventCollector } from './event-testing';\nimport { CircuitBreaker, CircuitOpenError } from './circuit-breaker';\nimport { validateEvent } from './validation';\nimport { getOperationContext } from './operation-context';\nimport {\n type EnrichFromBaggageConfig,\n hashValue,\n hashLinkedTraceIds,\n} from './events-config';\nimport { getOrCreateCorrelationId } from './correlation-id';\n\n// Re-export types for convenience\nexport type {\n EventAttributes,\n EventAttributesInput,\n FunnelStatus,\n OutcomeStatus,\n} from './event-subscriber';\n\n/**\n * Events class for tracking user behavior and product events\n *\n * Track critical indicators such as:\n * - User events (signups, purchases, feature usage)\n * - Conversion funnels (signup → activation → purchase)\n * - Business outcomes (success/failure rates)\n * - Product metrics (revenue, engagement, retention)\n *\n * All events are sent to events platforms via subscribers (PostHog, Mixpanel, etc.).\n * For OpenTelemetry metrics, use the Metrics class instead.\n */\n/**\n * Events options\n */\nexport interface EventsOptions {\n /** Optional logger for audit trail */\n logger?: Logger;\n /** Optional collector for testing (captures events in memory) */\n collector?: EventCollector;\n /**\n * Optional subscribers to send events to other platforms\n * (e.g., PostHog, Mixpanel, Amplitude)\n *\n * **Subscriber Resolution**:\n * - If provided → uses these subscribers (instance override)\n * - If not provided → falls back to subscribers from `init()` (global config)\n * - If neither → no subscribers (events logged only)\n *\n * Install `autotel-subscribers` package for ready-made subscribers\n */\n subscribers?: EventSubscriber[];\n}\n\nexport class Event {\n private serviceName: string;\n private logger?: Logger;\n private collector?: EventCollector;\n private subscribers: EventSubscriber[];\n private hasSubscribers: boolean; // Cached for performance\n private circuitBreakers: Map<EventSubscriber, CircuitBreaker>; // One per subscriber\n\n /**\n * Create a new Event instance\n *\n * **Note**: Most users should use `init()` + `track()` instead of creating Event instances directly.\n *\n * **Subscriber Resolution**:\n * - If `subscribers` provided in options → uses those (instance override)\n * - If `subscribers` not provided → falls back to subscribers from `init()` (global config)\n * - If neither → no subscribers (events logged only)\n *\n * @param serviceName - Service name for identifying events\n * @param options - Optional configuration (logger, collector, subscribers)\n *\n * @example Recommended: Use track() with init()\n * ```typescript\n * import { init, track } from 'autotel';\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * init({\n * service: 'checkout',\n * subscribers: [new PostHogSubscriber({ apiKey: 'phc_...' })]\n * });\n *\n * track('purchase.completed', { amount: 99.99 });\n * ```\n *\n * @example Inherit subscribers from init()\n * ```typescript\n * // Uses subscribers configured in init()\n * const event = new Event('checkout');\n * event.trackEvent('purchase.completed', { amount: 99.99 });\n * ```\n *\n * @example Override subscribers for this instance\n * ```typescript\n * import { Event } from 'autotel/event';\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * // Override: use different subscribers for this instance only\n * const event = new Event('checkout', {\n * subscribers: [new PostHogSubscriber({ apiKey: 'phc_different_project' })]\n * });\n * ```\n */\n constructor(serviceName: string, options: EventsOptions = {}) {\n this.serviceName = serviceName;\n this.logger = options.logger;\n this.collector = options.collector;\n\n // Subscriber resolution: instance-level overrides global init() config\n // If subscribers provided to constructor, use those\n // Otherwise, fall back to subscribers from init()\n this.subscribers =\n options.subscribers === undefined\n ? getConfig()?.subscribers || []\n : options.subscribers;\n\n this.hasSubscribers = this.subscribers.length > 0; // Cache for hot path\n\n // Create circuit breaker for each subscriber\n this.circuitBreakers = new Map();\n for (const subscriber of this.subscribers) {\n const subscriberName = subscriber.name || 'Unknown';\n this.circuitBreakers.set(\n subscriber,\n new CircuitBreaker(subscriberName, {\n failureThreshold: 5,\n resetTimeout: 30_000, // 30s\n windowSize: 60_000, // 1min\n }),\n );\n }\n }\n\n /**\n * Automatically enrich attributes with all available telemetry context\n *\n * Auto-captures:\n * - Resource attributes: service.version, deployment.environment\n * - Trace context: traceId, spanId, correlationId\n * - Operation context: operation.name\n */\n private enrichWithTelemetryContext(\n attributes: EventAttributes = {},\n ): EventAttributes {\n const enriched: EventAttributes = {\n service: this.serviceName,\n ...attributes,\n };\n\n // 1. Resource attributes (service-level context)\n const config = getConfig();\n if (config) {\n if (config.version) {\n enriched['service.version'] = config.version;\n }\n if (config.environment) {\n enriched['deployment.environment'] = config.environment;\n }\n }\n\n // 2. Trace context (if inside a traced operation)\n const span = trace.getActiveSpan();\n const spanContext = span?.spanContext();\n if (spanContext) {\n enriched.traceId = spanContext.traceId;\n enriched.spanId = spanContext.spanId;\n // Add correlation ID (first 16 chars of trace ID) for easier log grouping\n enriched.correlationId = spanContext.traceId.slice(0, 16);\n }\n\n // 3. Operation context (if inside a trace/span)\n const operationContext = getOperationContext();\n if (operationContext) {\n enriched['operation.name'] = operationContext.name;\n }\n\n return enriched;\n }\n\n /**\n * Build autotel event context for trace correlation\n *\n * Works in 4 contexts:\n * 1. Inside a span → use current span's trace_id + span_id\n * 2. Outside span but in AsyncLocalStorage context → use trace_id + correlation_id\n * 3. Totally standalone → use correlation_id + service/env/version\n * 4. Batch/fan-in (multiple linked parents) → use count + hash or full array\n *\n * @returns AutotelEventContext or undefined if trace context is disabled\n */\n private buildAutotelContext(): AutotelEventContext | undefined {\n const eventsConfig = getEventsConfig();\n\n // Return undefined if trace context is not enabled\n if (!eventsConfig?.includeTraceContext) {\n // Still generate correlation_id even without full trace context\n // This provides a stable join key across events/logs/spans\n return {\n correlation_id: getOrCreateCorrelationId(),\n };\n }\n\n const config = getConfig();\n const span = trace.getActiveSpan();\n const spanContext = span?.spanContext();\n\n // Always generate a correlation_id\n const correlationId = getOrCreateCorrelationId();\n\n // Build base context\n const autotelContext: AutotelEventContext = {\n correlation_id: correlationId,\n };\n\n // Add trace context if inside a span\n if (spanContext) {\n autotelContext.trace_id = spanContext.traceId;\n autotelContext.span_id = spanContext.spanId;\n\n // Trace flags as 2-char hex string (canonical format)\n autotelContext.trace_flags = spanContext.traceFlags\n .toString(16)\n .padStart(2, '0');\n\n // Tracestate if present\n const traceState = spanContext.traceState;\n if (traceState) {\n // Convert TraceState to string representation safely\n let traceStateStr = '';\n try {\n if (typeof traceState.serialize === 'function') {\n traceStateStr = traceState.serialize();\n }\n } catch {\n // Silently ignore serialization errors - traceState is optional metadata\n }\n if (traceStateStr) {\n autotelContext.trace_state = traceStateStr;\n }\n }\n\n // Generate trace URL if configured\n if (eventsConfig.traceUrl) {\n const traceUrl = eventsConfig.traceUrl({\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n correlationId,\n serviceName: config?.service || this.serviceName,\n environment: config?.environment,\n });\n if (traceUrl) {\n autotelContext.trace_url = traceUrl;\n }\n }\n\n // Handle linked spans (batch/fan-in scenarios)\n // Note: This would require access to span links which are not easily accessible\n // from the public OpenTelemetry API. For now, we skip this unless we have\n // explicit linked trace IDs passed in.\n } else {\n // Outside span but may still have trace URL generator\n if (eventsConfig.traceUrl && config) {\n const traceUrl = eventsConfig.traceUrl({\n correlationId,\n serviceName: config.service,\n environment: config.environment,\n });\n if (traceUrl) {\n autotelContext.trace_url = traceUrl;\n }\n }\n }\n\n return autotelContext;\n }\n\n /**\n * Enrich event attributes from baggage with guardrails\n *\n * @param attributes - Current event attributes\n * @returns Enriched attributes with baggage values\n */\n private enrichFromBaggage(attributes: EventAttributes): EventAttributes {\n const eventsConfig = getEventsConfig();\n const enrichConfig = eventsConfig?.enrichFromBaggage;\n\n if (!enrichConfig) {\n return attributes;\n }\n\n const enriched = { ...attributes };\n const activeContext = context.active();\n const baggage = propagation.getBaggage(activeContext);\n\n if (!baggage) {\n return enriched;\n }\n\n let keyCount = 0;\n let byteCount = 0;\n const maxKeys = enrichConfig.maxKeys ?? 10;\n const maxBytes = enrichConfig.maxBytes ?? 1024;\n const prefix = enrichConfig.prefix ?? '';\n\n // Get all baggage entries\n for (const [key, entry] of baggage.getAllEntries()) {\n // Check if key is allowed\n if (!this.isBaggageKeyAllowed(key, enrichConfig)) {\n continue;\n }\n\n // Check limits\n if (keyCount >= maxKeys) {\n break;\n }\n\n const value = entry.value;\n\n // Apply transform first so maxBytes is checked against transformed size (e.g. hash output)\n const transform = enrichConfig.transform?.[key];\n let transformedValue: string;\n\n if (transform === 'hash') {\n transformedValue = hashValue(value);\n } else if (transform === 'plain' || !transform) {\n transformedValue = value;\n } else if (typeof transform === 'function') {\n transformedValue = transform(value);\n } else {\n transformedValue = value;\n }\n\n const valueBytes = new TextEncoder().encode(transformedValue).length;\n\n if (byteCount + valueBytes > maxBytes) {\n continue; // Skip this entry if transformed value would exceed byte limit\n }\n\n // Add to enriched attributes with prefix\n const enrichedKey = `${prefix}${key}`;\n enriched[enrichedKey] = transformedValue;\n\n keyCount++;\n byteCount += valueBytes;\n }\n\n return enriched;\n }\n\n /**\n * Check if a baggage key is allowed based on config\n */\n private isBaggageKeyAllowed(\n key: string,\n config: EnrichFromBaggageConfig,\n ): boolean {\n // Check deny list first (takes precedence)\n if (config.deny) {\n for (const pattern of config.deny) {\n if (this.matchesBaggagePattern(key, pattern)) {\n return false;\n }\n }\n }\n\n // Check allow list\n for (const pattern of config.allow) {\n if (this.matchesBaggagePattern(key, pattern)) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if a key matches a baggage pattern\n * Supports exact matches and wildcard patterns (e.g., 'tenant.*')\n */\n private matchesBaggagePattern(key: string, pattern: string): boolean {\n if (pattern.endsWith('.*')) {\n const prefix = pattern.slice(0, -2);\n return key.startsWith(prefix + '.');\n }\n return key === pattern;\n }\n\n /**\n * Track a business event\n *\n * Use this for tracking user actions, business events, product usage:\n * - \"user.signup\"\n * - \"order.completed\"\n * - \"feature.used\"\n *\n * Events are sent to configured subscribers (PostHog, Mixpanel, etc.).\n *\n * @example\n * ```typescript\n * // Track user signup\n * events.trackEvent('user.signup', {\n * userId: '123',\n * plan: 'pro'\n * })\n *\n * // Track order\n * events.trackEvent('order.completed', {\n * orderId: 'ord_123',\n * amount: 99.99\n * })\n * ```\n */\n trackEvent(eventName: string, attributes?: EventAttributes): void {\n // Validate and sanitize input (with custom config if provided)\n const validationConfig = getValidationConfig();\n const validated = validateEvent(\n eventName,\n attributes,\n validationConfig || undefined,\n );\n\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext(\n validated.attributes,\n );\n\n this.logger?.info(\n {\n event: validated.eventName,\n attributes: enrichedAttributes,\n },\n 'Event tracked',\n );\n\n // Record for testing\n this.collector?.recordEvent({\n event: validated.eventName,\n attributes: enrichedAttributes,\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers (zero overhead if no subscribers)\n // Run in background - don't block event recording\n if (this.hasSubscribers) {\n // Build autotel context for trace correlation\n const autotelContext = this.buildAutotelContext();\n\n // Enrich from baggage if configured\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers((subscriber) =>\n subscriber.trackEvent(validated.eventName, finalAttributes, {\n autotel: autotelContext,\n }),\n );\n }\n }\n\n /**\n * Notify all subscribers concurrently without blocking\n * Uses circuit breakers to protect against failing subscribers\n * Uses Promise.allSettled to prevent subscriber errors from affecting other subscribers\n */\n private async notifySubscribers(\n fn: (subscriber: EventSubscriber) => Promise<void>,\n ): Promise<void> {\n const promises = this.subscribers.map(async (subscriber) => {\n const circuitBreaker = this.circuitBreakers.get(subscriber);\n if (!circuitBreaker) return; // Should never happen\n\n try {\n // Execute with circuit breaker protection\n await circuitBreaker.execute(() => fn(subscriber));\n } catch (error) {\n // Handle circuit open errors (expected behavior when subscriber is down)\n if (error instanceof CircuitOpenError) {\n // Circuit is open - subscriber is down, log at warn level for visibility (same behavior in all environments)\n getLogger().warn(\n {\n subscriberName: subscriber.name || 'Unknown',\n },\n `[Events] ${error.message}`,\n );\n return;\n }\n\n // Log other subscriber errors but don't throw - event failures shouldn't break business logic\n getLogger().error(\n {\n err: error instanceof Error ? error : undefined,\n subscriberName: subscriber.name || 'Unknown',\n },\n `[Events] Subscriber ${subscriber.name || 'Unknown'} failed`,\n );\n }\n });\n\n // Wait for all subscribers (success or failure)\n await Promise.allSettled(promises);\n }\n\n /**\n * Track conversion funnel steps\n *\n * Monitor where users drop off in multi-step processes.\n *\n * @example\n * ```typescript\n * // Track signup funnel\n * events.trackFunnelStep('signup', 'started', { userId: '123' })\n * events.trackFunnelStep('signup', 'email_verified', { userId: '123' })\n * events.trackFunnelStep('signup', 'completed', { userId: '123' })\n *\n * // Track checkout flow\n * events.trackFunnelStep('checkout', 'started', { cartValue: 99.99 })\n * events.trackFunnelStep('checkout', 'payment_info', { cartValue: 99.99 })\n * events.trackFunnelStep('checkout', 'completed', { cartValue: 99.99 })\n * ```\n */\n trackFunnelStep(\n funnelName: string,\n status: FunnelStatus,\n attributes?: EventAttributes,\n ): void {\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext(attributes);\n\n this.logger?.info(\n {\n funnel: funnelName,\n status,\n attributes: enrichedAttributes,\n },\n 'Funnel step tracked',\n );\n\n // Record for testing\n this.collector?.recordFunnelStep({\n funnel: funnelName,\n status,\n attributes: enrichedAttributes,\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers\n if (this.hasSubscribers) {\n const autotelContext = this.buildAutotelContext();\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers((subscriber) =>\n subscriber.trackFunnelStep(funnelName, status, finalAttributes, {\n autotel: autotelContext,\n }),\n );\n }\n }\n\n /**\n * Track outcomes (success/failure/partial)\n *\n * Monitor success rates of critical operations.\n *\n * @example\n * ```typescript\n * // Track email delivery\n * events.trackOutcome('email.delivery', 'success', {\n * recipientType: 'user',\n * emailType: 'welcome'\n * })\n *\n * events.trackOutcome('email.delivery', 'failure', {\n * recipientType: 'user',\n * errorCode: 'invalid_email'\n * })\n *\n * // Track payment processing\n * events.trackOutcome('payment.process', 'success', { amount: 99.99 })\n * events.trackOutcome('payment.process', 'failure', { error: 'insufficient_funds' })\n * ```\n */\n trackOutcome(\n operationName: string,\n status: OutcomeStatus,\n attributes?: EventAttributes,\n ): void {\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext(attributes);\n\n this.logger?.info(\n {\n operation: operationName,\n status,\n attributes: enrichedAttributes,\n },\n 'Outcome tracked',\n );\n\n // Record for testing\n this.collector?.recordOutcome({\n operation: operationName,\n status,\n attributes: enrichedAttributes,\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers\n if (this.hasSubscribers) {\n const autotelContext = this.buildAutotelContext();\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers((subscriber) =>\n subscriber.trackOutcome(operationName, status, finalAttributes, {\n autotel: autotelContext,\n }),\n );\n }\n }\n\n /**\n * Track value metrics\n *\n * Record numerical values like revenue, transaction amounts,\n * item counts, processing times, engagement scores, etc.\n *\n * @example\n * ```typescript\n * // Track revenue\n * events.trackValue('order.revenue', 149.99, {\n * currency: 'USD',\n * productCategory: 'electronics'\n * })\n *\n * // Track items per cart\n * events.trackValue('cart.item_count', 5, {\n * userId: '123'\n * })\n *\n * // Track processing time\n * events.trackValue('api.response_time', 250, {\n * unit: 'ms',\n * endpoint: '/api/checkout'\n * })\n * ```\n */\n trackValue(\n metricName: string,\n value: number,\n attributes?: EventAttributes,\n ): void {\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext({\n metric: metricName,\n ...attributes,\n });\n\n this.logger?.debug(\n {\n metric: metricName,\n value,\n attributes: enrichedAttributes,\n },\n 'Value tracked',\n );\n\n // Record for testing\n this.collector?.recordValue({\n metric: metricName,\n value,\n attributes: enrichedAttributes,\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers\n if (this.hasSubscribers) {\n const autotelContext = this.buildAutotelContext();\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers((subscriber) =>\n subscriber.trackValue(metricName, value, finalAttributes, {\n autotel: autotelContext,\n }),\n );\n }\n }\n\n /**\n * Flush all subscribers and wait for pending events\n *\n * Call this before shutdown to ensure all events are delivered.\n *\n * @example\n * ```typescript\n * const event =new Event('app', { subscribers: [...] });\n *\n * // Before shutdown\n * await events.flush();\n * ```\n */\n async flush(): Promise<void> {\n if (!this.hasSubscribers) return;\n\n const shutdownPromises = this.subscribers.map(async (subscriber) => {\n if (subscriber.shutdown) {\n try {\n await subscriber.shutdown();\n } catch (error) {\n getLogger().error(\n {\n err: error instanceof Error ? error : undefined,\n subscriberName: subscriber.name || 'Unknown',\n },\n `[Events] Failed to shutdown subscriber ${subscriber.name || 'Unknown'}`,\n );\n }\n }\n });\n\n await Promise.allSettled(shutdownPromises);\n }\n\n /**\n * Shutdown the Event instance and all subscribers\n *\n * Unlike `flush()`, this method:\n * - Shuts down all subscribers\n * - Prevents further event tracking (hasSubscribers becomes false)\n * - Should only be called once at application shutdown\n *\n * @example\n * ```typescript\n * // In Next.js API route with after()\n * import { after } from 'next/server';\n *\n * export async function POST(req: Request) {\n * const event = new Event('checkout', { subscribers: [...] });\n * event.trackEvent('order.completed', { orderId: '123' });\n *\n * after(async () => {\n * await event.shutdown();\n * });\n *\n * return Response.json({ success: true });\n * }\n * ```\n */\n async shutdown(): Promise<void> {\n if (!this.hasSubscribers) return;\n\n await Promise.allSettled(\n this.subscribers.map(async (subscriber) => {\n if (subscriber.shutdown) {\n try {\n await subscriber.shutdown();\n } catch (error) {\n getLogger().error(\n {\n err: error instanceof Error ? error : undefined,\n subscriberName: subscriber.name || 'Unknown',\n },\n `[Events] Failed to shutdown subscriber ${subscriber.name || 'Unknown'}`,\n );\n }\n }\n }),\n );\n\n // Prevent further tracking after shutdown\n this.hasSubscribers = false;\n }\n\n /**\n * Track funnel progression with custom step names\n *\n * Unlike trackFunnelStep which uses FunnelStatus enum values,\n * this method allows any string as the step name for flexible funnel tracking.\n *\n * @param funnelName - Name of the funnel (e.g., \"checkout\", \"onboarding\")\n * @param stepName - Custom step name (e.g., \"cart_viewed\", \"payment_entered\")\n * @param stepNumber - Optional numeric position in the funnel\n * @param attributes - Optional event attributes\n *\n * @example\n * ```typescript\n * // Track custom checkout steps\n * event.trackFunnelProgression('checkout', 'cart_viewed', 1);\n * event.trackFunnelProgression('checkout', 'shipping_selected', 2);\n * event.trackFunnelProgression('checkout', 'payment_entered', 3);\n * event.trackFunnelProgression('checkout', 'order_confirmed', 4);\n * ```\n */\n trackFunnelProgression(\n funnelName: string,\n stepName: string,\n stepNumber?: number,\n attributes?: EventAttributes,\n ): void {\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext(attributes);\n\n this.logger?.info(\n {\n funnel: funnelName,\n stepName,\n stepNumber,\n attributes: enrichedAttributes,\n },\n 'Funnel progression tracked',\n );\n\n // Record for testing (as funnel step with custom name)\n this.collector?.recordFunnelStep({\n funnel: funnelName,\n status: stepName as FunnelStatus, // Cast for testing collector\n attributes: {\n ...enrichedAttributes,\n step_name: stepName,\n ...(stepNumber === undefined ? {} : { step_number: stepNumber }),\n },\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers that support trackFunnelProgression\n if (this.hasSubscribers) {\n const autotelContext = this.buildAutotelContext();\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers(async (subscriber) => {\n await (subscriber.trackFunnelProgression\n ? subscriber.trackFunnelProgression(\n funnelName,\n stepName,\n stepNumber,\n finalAttributes,\n { autotel: autotelContext },\n )\n : // Fall back to trackFunnelStep with step as custom name (cast)\n subscriber.trackFunnelStep(\n funnelName,\n stepName as FunnelStatus,\n {\n ...finalAttributes,\n step_name: stepName,\n ...(stepNumber === undefined\n ? {}\n : { step_number: stepNumber }),\n },\n { autotel: autotelContext },\n ));\n });\n }\n }\n\n /**\n * Track multiple events in a batch\n *\n * Useful for bulk event tracking with consistent timestamps.\n * Events are sent to subscribers individually but processed together.\n *\n * @param events - Array of events to track\n *\n * @example\n * ```typescript\n * event.trackBatch([\n * { name: 'item.viewed', attributes: { itemId: '1' } },\n * { name: 'item.viewed', attributes: { itemId: '2' } },\n * { name: 'cart.updated', attributes: { itemCount: 2 } },\n * ]);\n * ```\n */\n trackBatch(\n events: Array<{ name: string; attributes?: EventAttributesInput }>,\n ): void {\n // Filter attributes and track each event\n for (const event of events) {\n // Filter undefined/null values from attributes\n const filteredAttributes = event.attributes\n ? (Object.fromEntries(\n Object.entries(event.attributes).filter(\n ([, v]) => v !== undefined && v !== null,\n ),\n ) as EventAttributes)\n : undefined;\n\n this.trackEvent(event.name, filteredAttributes);\n }\n }\n}\n\n/**\n * Global events instances (singleton pattern)\n */\nconst eventsInstances = new Map<string, Event>();\n\n/**\n * Get or create an Events instance for a service\n *\n * @param serviceName - Service name for identifying events\n * @param logger - Optional logger\n * @returns Events instance\n *\n * @example\n * ```typescript\n * const event =getEvents('job-application')\n * events.trackEvent('application.submitted', { jobId: '123' })\n * ```\n */\nexport function getEvents(serviceName: string, logger?: Logger): Event {\n if (!eventsInstances.has(serviceName)) {\n eventsInstances.set(serviceName, new Event(serviceName, { logger }));\n }\n return eventsInstances.get(serviceName)!;\n}\n\n/**\n * Reset all events instances (mainly for testing)\n */\nexport function resetEvents(): void {\n eventsInstances.clear();\n}\n"]}
1
+ {"version":3,"sources":["../src/circuit-breaker.ts","../src/events-config.ts","../src/event.ts"],"names":[],"mappings":"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","file":"chunk-MAITXZFR.js","sourcesContent":["/**\n * Circuit breaker for event subscribers\n *\n * Prevents cascading failures by fast-failing when an (subscriber) is unhealthy.\n * Uses the circuit breaker pattern with three states:\n * - CLOSED: Normal operation ((subscriber) working)\n * - OPEN: Fast-fail mode ((subscriber) down)\n * - HALF_OPEN: Testing if (subscriber) recovered\n */\n\nexport interface CircuitBreakerConfig {\n /** Number of failures before opening circuit (default: 5) */\n failureThreshold: number;\n /** Time to wait before trying again in ms (default: 30000 = 30s) */\n resetTimeout: number;\n /** Time window for counting failures in ms (default: 60000 = 1min) */\n windowSize: number;\n}\n\nconst DEFAULT_CONFIG: CircuitBreakerConfig = {\n failureThreshold: 5,\n resetTimeout: 30_000, // 30 seconds\n windowSize: 60_000, // 1 minute\n};\n\nexport type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';\n\nexport const CircuitState = {\n CLOSED: 'CLOSED' as const, // Normal operation\n OPEN: 'OPEN' as const, // Fast-fail mode\n HALF_OPEN: 'HALF_OPEN' as const, // Testing recovery\n} as const;\n\ninterface FailureRecord {\n timestamp: number;\n error: string;\n}\n\n/**\n * Circuit breaker implementation\n *\n * Tracks failures and automatically opens the circuit to prevent\n * overwhelming failing subscribers.\n */\nexport class CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failures: FailureRecord[] = [];\n private lastFailureTime: number = 0;\n private readonly config: CircuitBreakerConfig;\n private readonly name: string;\n\n constructor(name: string, config?: Partial<CircuitBreakerConfig>) {\n this.name = name;\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Execute a function with circuit breaker protection\n * Throws CircuitOpenError if circuit is open\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n // Check if circuit is open\n if (this.state === CircuitState.OPEN) {\n // Check if we should transition to half-open\n const now = Date.now();\n if (now - this.lastFailureTime >= this.config.resetTimeout) {\n this.state = CircuitState.HALF_OPEN;\n } else {\n throw new CircuitOpenError(\n `Circuit breaker is OPEN for ${this.name}. ` +\n `Will retry in ${Math.ceil((this.config.resetTimeout - (now - this.lastFailureTime)) / 1000)}s`,\n );\n }\n }\n\n try {\n const result = await fn();\n\n // Success! Close circuit if it was half-open\n if (this.state === CircuitState.HALF_OPEN) {\n this.reset();\n }\n\n return result;\n } catch (error) {\n this.recordFailure(error);\n throw error;\n }\n }\n\n /**\n * Record a failure and potentially open the circuit\n */\n private recordFailure(error: unknown): void {\n const now = Date.now();\n\n // Remove old failures outside the time window\n this.failures = this.failures.filter(\n (f) => now - f.timestamp < this.config.windowSize,\n );\n\n // Record new failure\n this.failures.push({\n timestamp: now,\n error: error instanceof Error ? error.message : String(error),\n });\n\n this.lastFailureTime = now;\n\n // Check if we should open the circuit\n if (this.failures.length >= this.config.failureThreshold) {\n if (this.state === CircuitState.HALF_OPEN) {\n // Failed during test - reopen circuit\n this.state = CircuitState.OPEN;\n } else if (this.state === CircuitState.CLOSED) {\n // Too many failures - open circuit\n this.state = CircuitState.OPEN;\n }\n }\n }\n\n /**\n * Reset the circuit breaker (on success)\n */\n private reset(): void {\n this.state = CircuitState.CLOSED;\n this.failures = [];\n this.lastFailureTime = 0;\n }\n\n /**\n * Get current state (for monitoring)\n */\n getState(): CircuitState {\n return this.state;\n }\n\n /**\n * Get failure count in current window\n */\n getFailureCount(): number {\n const now = Date.now();\n // Clean up old failures\n this.failures = this.failures.filter(\n (f) => now - f.timestamp < this.config.windowSize,\n );\n return this.failures.length;\n }\n\n /**\n * Get recent failures (for debugging)\n */\n getRecentFailures(): FailureRecord[] {\n const now = Date.now();\n return this.failures.filter(\n (f) => now - f.timestamp < this.config.windowSize,\n );\n }\n\n /**\n * Manually reset the circuit breaker (for testing or manual intervention)\n */\n forceReset(): void {\n this.reset();\n }\n\n /**\n * Manually open the circuit (for testing or manual intervention)\n */\n forceOpen(): void {\n this.state = CircuitState.OPEN;\n this.lastFailureTime = Date.now();\n }\n}\n\n/**\n * Error thrown when circuit is open\n */\nexport class CircuitOpenError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CircuitOpenError';\n }\n}\n","/**\n * Events configuration types for trace context, correlation IDs, and enrichment\n *\n * @example Basic usage\n * ```typescript\n * import { init } from 'autotel';\n *\n * init({\n * service: 'my-app',\n * events: {\n * includeTraceContext: true,\n * traceUrl: (ctx) => `https://grafana.internal/explore?traceId=${ctx.traceId}`\n * }\n * });\n * ```\n */\n\n/**\n * Context passed to the traceUrl function for generating clickable trace URLs\n */\nexport interface TraceUrlContext {\n /** Trace ID (32 hex chars) - may be undefined outside a trace */\n traceId?: string;\n /** Span ID (16 hex chars) - may be undefined outside a trace */\n spanId?: string;\n /** Correlation ID (always present, 16 hex chars) */\n correlationId: string;\n /** Service name from init config */\n serviceName: string;\n /** Environment from init config */\n environment?: string;\n}\n\n/**\n * Per-key transform options for baggage enrichment\n */\nexport type BaggageTransform = 'plain' | 'hash' | ((value: string) => string);\n\n/**\n * Baggage enrichment configuration with guardrails\n */\nexport interface EnrichFromBaggageConfig {\n /**\n * Allowlist of baggage keys to include in events\n * Supports exact matches and patterns (e.g., 'tenant.*')\n */\n allow: string[];\n\n /**\n * Optional denylist of baggage keys to exclude\n * Takes precedence over allow list\n */\n deny?: string[];\n\n /**\n * Optional prefix to add to all enriched keys\n * @example 'ctx.' results in 'ctx.tenant.id'\n */\n prefix?: string;\n\n /**\n * Maximum number of keys to include (default: 10)\n * Prevents payload bloat from excessive baggage\n */\n maxKeys?: number;\n\n /**\n * Maximum total bytes for enriched values (default: 1024)\n * Prevents payload bloat from large baggage values\n */\n maxBytes?: number;\n\n /**\n * Per-key transform options\n * - 'plain': Include value as-is\n * - 'hash': Hash the value (for PII protection)\n * - function: Custom transform function\n *\n * @example\n * ```typescript\n * transform: {\n * 'user.id': 'hash', // Hash user ID for privacy\n * 'tenant.id': 'plain', // Include tenant ID as-is\n * 'session.id': (v) => v.slice(0, 8) // Custom truncation\n * }\n * ```\n */\n transform?: Record<string, BaggageTransform>;\n}\n\n/**\n * Events configuration for trace context and enrichment\n */\nexport interface EventsConfig {\n /**\n * Include trace context in events (default: false)\n *\n * When enabled, events automatically include:\n * - autotel.trace_id (32 hex chars)\n * - autotel.span_id (16 hex chars)\n * - autotel.trace_flags (2 hex chars)\n * - autotel.trace_state (raw tracestate string, if present)\n * - autotel.correlation_id (always present, 16 hex chars)\n *\n * Subscribers map these to platform-specific names:\n * - PostHog: $trace_id, $span_id\n * - Mixpanel: trace_id, span_id\n */\n includeTraceContext?: boolean;\n\n /**\n * Include full array of linked trace IDs for batch/fan-in scenarios (default: false)\n *\n * When false (default), batch/fan-in events include:\n * - autotel.linked_trace_id_count: Number of linked parents\n * - autotel.linked_trace_id_hash: Stable hash of sorted IDs (keeps payload lean)\n *\n * When true, events also include:\n * - autotel.linked_trace_ids: Full array of linked trace IDs\n */\n includeLinkedTraceIds?: boolean;\n\n /**\n * Generate clickable trace URL from context\n *\n * @param ctx - Trace context with traceId, spanId, correlationId, serviceName, environment\n * @returns URL string or undefined to skip\n *\n * @example Grafana Tempo\n * ```typescript\n * traceUrl: (ctx) => ctx.traceId\n * ? `https://grafana.internal/explore?traceId=${ctx.traceId}`\n * : undefined\n * ```\n *\n * @example Datadog\n * ```typescript\n * traceUrl: (ctx) => ctx.traceId\n * ? `https://app.datadoghq.com/apm/traces?traceId=${ctx.traceId}`\n * : undefined\n * ```\n *\n * @example Jaeger\n * ```typescript\n * traceUrl: (ctx) => ctx.traceId\n * ? `https://jaeger.internal/trace/${ctx.traceId}`\n * : undefined\n * ```\n */\n traceUrl?: (ctx: TraceUrlContext) => string | undefined;\n\n /**\n * Auto-enrich events from baggage with guardrails\n *\n * Automatically includes baggage entries in events without manual code.\n * Apply allow/deny lists and per-key transforms for PII protection.\n *\n * @example Basic allowlist\n * ```typescript\n * enrichFromBaggage: {\n * allow: ['tenant.id', 'user.id', 'request.id']\n * }\n * // Events include: tenant.id, user.id, request.id from baggage\n * ```\n *\n * @example With prefix and transforms\n * ```typescript\n * enrichFromBaggage: {\n * allow: ['tenant.id', 'user.id', 'user.email'],\n * deny: ['user.ssn'],\n * prefix: 'ctx.',\n * transform: {\n * 'user.id': 'hash',\n * 'user.email': 'hash'\n * }\n * }\n * // Events include: ctx.tenant.id, ctx.user.id (hashed), ctx.user.email (hashed)\n * ```\n */\n enrichFromBaggage?: EnrichFromBaggageConfig;\n}\n\n/**\n * Autotel context object attached to event envelopes\n *\n * This structured object is attached to events and subscribers\n * decide how to map/flatten for their platform.\n */\nexport interface AutotelEventContext {\n /** Trace ID (32 hex chars) - present when inside a trace */\n trace_id?: string;\n /** Span ID (16 hex chars) - present when inside a span */\n span_id?: string;\n /** Trace flags (2 hex chars, e.g., '01' for sampled) */\n trace_flags?: string;\n /** Raw tracestate string - present if tracestate exists */\n trace_state?: string;\n /** Clickable trace URL - present if traceUrl config is set */\n trace_url?: string;\n /** Correlation ID (always present, 16 hex chars) */\n correlation_id: string;\n /** Number of linked parent traces (batch/fan-in scenarios) */\n linked_trace_id_count?: number;\n /** Stable hash of linked trace IDs (default for batch/fan-in) */\n linked_trace_id_hash?: string;\n /** Full array of linked trace IDs (only if includeLinkedTraceIds: true) */\n linked_trace_ids?: string[];\n}\n\n/**\n * Hash a string value for PII protection\n *\n * Uses a simple, fast hash function suitable for correlation.\n * NOT cryptographically secure - use for PII masking, not security.\n */\nexport function hashValue(value: string): string {\n let hash = 0;\n for (let i = 0; i < value.length; i++) {\n const char = value.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n // Convert to positive hex string\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\n/**\n * Create a stable hash of an array of trace IDs\n *\n * Sorts the array first to ensure deterministic output regardless of order.\n */\nexport function hashLinkedTraceIds(traceIds: string[]): string {\n const sorted = [...traceIds].sort();\n return hashValue(sorted.join(','));\n}\n","/**\n * Events API for product events platforms\n *\n * Track user behavior, business events, and critical actions.\n * Sends to product events platforms (PostHog, Mixpanel, Amplitude) via subscribers.\n * For business people who think in events/funnels.\n *\n * For OpenTelemetry metrics (Prometheus/Grafana), use the Metrics class instead.\n *\n * @example Recommended: Configure subscribers in init(), use track() function\n * ```typescript\n * import { init, track } from 'autotel';\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * init({\n * service: 'my-app',\n * subscribers: [new PostHogSubscriber({ apiKey: 'phc_...' })]\n * });\n *\n * // Track events - uses subscribers from init()\n * track('application.submitted', { jobId: '123', userId: '456' });\n * ```\n *\n * @example Create Event instance (inherits subscribers from init)\n * ```typescript\n * import { Event } from 'autotel/event';\n *\n * // Uses subscribers configured in init()\n * const event = new Event('job-application');\n * event.trackEvent('application.submitted', { jobId: '123' });\n * ```\n *\n * @example Override subscribers for specific Event instance\n * ```typescript\n * import { Event } from 'autotel/event';\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * // Override: use different subscribers for this instance\n * const event = new Event('job-application', {\n * subscribers: [new PostHogSubscriber({ apiKey: 'phc_different_project' })]\n * });\n *\n * event.trackEvent('application.submitted', { jobId: '123' });\n * ```\n */\n\nimport { trace, propagation, context, TraceFlags } from '@opentelemetry/api';\nimport { type Logger } from './logger';\nimport {\n getLogger,\n getValidationConfig,\n getConfig,\n getEventsConfig,\n} from './init';\nimport {\n type EventSubscriber,\n type EventAttributes,\n type EventAttributesInput,\n type FunnelStatus,\n type OutcomeStatus,\n type AutotelEventContext,\n} from './event-subscriber';\nimport { type EventCollector } from './event-testing';\nimport { CircuitBreaker, CircuitOpenError } from './circuit-breaker';\nimport { validateEvent } from './validation';\nimport { getOperationContext } from './operation-context';\nimport {\n type EnrichFromBaggageConfig,\n hashValue,\n hashLinkedTraceIds,\n} from './events-config';\nimport { getOrCreateCorrelationId } from './correlation-id';\n\n// Re-export types for convenience\nexport type {\n EventAttributes,\n EventAttributesInput,\n FunnelStatus,\n OutcomeStatus,\n} from './event-subscriber';\n\n/**\n * Events class for tracking user behavior and product events\n *\n * Track critical indicators such as:\n * - User events (signups, purchases, feature usage)\n * - Conversion funnels (signup → activation → purchase)\n * - Business outcomes (success/failure rates)\n * - Product metrics (revenue, engagement, retention)\n *\n * All events are sent to events platforms via subscribers (PostHog, Mixpanel, etc.).\n * For OpenTelemetry metrics, use the Metrics class instead.\n */\n/**\n * Events options\n */\nexport interface EventsOptions {\n /** Optional logger for audit trail */\n logger?: Logger;\n /** Optional collector for testing (captures events in memory) */\n collector?: EventCollector;\n /**\n * Optional subscribers to send events to other platforms\n * (e.g., PostHog, Mixpanel, Amplitude)\n *\n * **Subscriber Resolution**:\n * - If provided → uses these subscribers (instance override)\n * - If not provided → falls back to subscribers from `init()` (global config)\n * - If neither → no subscribers (events logged only)\n *\n * Install `autotel-subscribers` package for ready-made subscribers\n */\n subscribers?: EventSubscriber[];\n}\n\nexport class Event {\n private serviceName: string;\n private logger?: Logger;\n private collector?: EventCollector;\n private subscribers: EventSubscriber[];\n private hasSubscribers: boolean; // Cached for performance\n private circuitBreakers: Map<EventSubscriber, CircuitBreaker>; // One per subscriber\n\n /**\n * Create a new Event instance\n *\n * **Note**: Most users should use `init()` + `track()` instead of creating Event instances directly.\n *\n * **Subscriber Resolution**:\n * - If `subscribers` provided in options → uses those (instance override)\n * - If `subscribers` not provided → falls back to subscribers from `init()` (global config)\n * - If neither → no subscribers (events logged only)\n *\n * @param serviceName - Service name for identifying events\n * @param options - Optional configuration (logger, collector, subscribers)\n *\n * @example Recommended: Use track() with init()\n * ```typescript\n * import { init, track } from 'autotel';\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * init({\n * service: 'checkout',\n * subscribers: [new PostHogSubscriber({ apiKey: 'phc_...' })]\n * });\n *\n * track('purchase.completed', { amount: 99.99 });\n * ```\n *\n * @example Inherit subscribers from init()\n * ```typescript\n * // Uses subscribers configured in init()\n * const event = new Event('checkout');\n * event.trackEvent('purchase.completed', { amount: 99.99 });\n * ```\n *\n * @example Override subscribers for this instance\n * ```typescript\n * import { Event } from 'autotel/event';\n * import { PostHogSubscriber } from 'autotel-subscribers/posthog';\n *\n * // Override: use different subscribers for this instance only\n * const event = new Event('checkout', {\n * subscribers: [new PostHogSubscriber({ apiKey: 'phc_different_project' })]\n * });\n * ```\n */\n constructor(serviceName: string, options: EventsOptions = {}) {\n this.serviceName = serviceName;\n this.logger = options.logger;\n this.collector = options.collector;\n\n // Subscriber resolution: instance-level overrides global init() config\n // If subscribers provided to constructor, use those\n // Otherwise, fall back to subscribers from init()\n this.subscribers =\n options.subscribers === undefined\n ? getConfig()?.subscribers || []\n : options.subscribers;\n\n this.hasSubscribers = this.subscribers.length > 0; // Cache for hot path\n\n // Create circuit breaker for each subscriber\n this.circuitBreakers = new Map();\n for (const subscriber of this.subscribers) {\n const subscriberName = subscriber.name || 'Unknown';\n this.circuitBreakers.set(\n subscriber,\n new CircuitBreaker(subscriberName, {\n failureThreshold: 5,\n resetTimeout: 30_000, // 30s\n windowSize: 60_000, // 1min\n }),\n );\n }\n }\n\n /**\n * Automatically enrich attributes with all available telemetry context\n *\n * Auto-captures:\n * - Resource attributes: service.version, deployment.environment\n * - Trace context: traceId, spanId, correlationId\n * - Operation context: operation.name\n */\n private enrichWithTelemetryContext(\n attributes: EventAttributes = {},\n ): EventAttributes {\n const enriched: EventAttributes = {\n service: this.serviceName,\n ...attributes,\n };\n\n // 1. Resource attributes (service-level context)\n const config = getConfig();\n if (config) {\n if (config.version) {\n enriched['service.version'] = config.version;\n }\n if (config.environment) {\n enriched['deployment.environment'] = config.environment;\n }\n }\n\n // 2. Trace context (if inside a traced operation)\n const span = trace.getActiveSpan();\n const spanContext = span?.spanContext();\n if (spanContext) {\n enriched.traceId = spanContext.traceId;\n enriched.spanId = spanContext.spanId;\n // Add correlation ID (first 16 chars of trace ID) for easier log grouping\n enriched.correlationId = spanContext.traceId.slice(0, 16);\n }\n\n // 3. Operation context (if inside a trace/span)\n const operationContext = getOperationContext();\n if (operationContext) {\n enriched['operation.name'] = operationContext.name;\n }\n\n return enriched;\n }\n\n /**\n * Build autotel event context for trace correlation\n *\n * Works in 4 contexts:\n * 1. Inside a span → use current span's trace_id + span_id\n * 2. Outside span but in AsyncLocalStorage context → use trace_id + correlation_id\n * 3. Totally standalone → use correlation_id + service/env/version\n * 4. Batch/fan-in (multiple linked parents) → use count + hash or full array\n *\n * @returns AutotelEventContext or undefined if trace context is disabled\n */\n private buildAutotelContext(): AutotelEventContext | undefined {\n const eventsConfig = getEventsConfig();\n\n // Return undefined if trace context is not enabled\n if (!eventsConfig?.includeTraceContext) {\n // Still generate correlation_id even without full trace context\n // This provides a stable join key across events/logs/spans\n return {\n correlation_id: getOrCreateCorrelationId(),\n };\n }\n\n const config = getConfig();\n const span = trace.getActiveSpan();\n const spanContext = span?.spanContext();\n\n // Always generate a correlation_id\n const correlationId = getOrCreateCorrelationId();\n\n // Build base context\n const autotelContext: AutotelEventContext = {\n correlation_id: correlationId,\n };\n\n // Add trace context if inside a span\n if (spanContext) {\n autotelContext.trace_id = spanContext.traceId;\n autotelContext.span_id = spanContext.spanId;\n\n // Trace flags as 2-char hex string (canonical format)\n autotelContext.trace_flags = spanContext.traceFlags\n .toString(16)\n .padStart(2, '0');\n\n // Tracestate if present\n const traceState = spanContext.traceState;\n if (traceState) {\n // Convert TraceState to string representation safely\n let traceStateStr = '';\n try {\n if (typeof traceState.serialize === 'function') {\n traceStateStr = traceState.serialize();\n }\n } catch {\n // Silently ignore serialization errors - traceState is optional metadata\n }\n if (traceStateStr) {\n autotelContext.trace_state = traceStateStr;\n }\n }\n\n // Generate trace URL if configured\n if (eventsConfig.traceUrl) {\n const traceUrl = eventsConfig.traceUrl({\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n correlationId,\n serviceName: config?.service || this.serviceName,\n environment: config?.environment,\n });\n if (traceUrl) {\n autotelContext.trace_url = traceUrl;\n }\n }\n\n // Handle linked spans (batch/fan-in scenarios)\n // Note: This would require access to span links which are not easily accessible\n // from the public OpenTelemetry API. For now, we skip this unless we have\n // explicit linked trace IDs passed in.\n } else {\n // Outside span but may still have trace URL generator\n if (eventsConfig.traceUrl && config) {\n const traceUrl = eventsConfig.traceUrl({\n correlationId,\n serviceName: config.service,\n environment: config.environment,\n });\n if (traceUrl) {\n autotelContext.trace_url = traceUrl;\n }\n }\n }\n\n return autotelContext;\n }\n\n /**\n * Enrich event attributes from baggage with guardrails\n *\n * @param attributes - Current event attributes\n * @returns Enriched attributes with baggage values\n */\n private enrichFromBaggage(attributes: EventAttributes): EventAttributes {\n const eventsConfig = getEventsConfig();\n const enrichConfig = eventsConfig?.enrichFromBaggage;\n\n if (!enrichConfig) {\n return attributes;\n }\n\n const enriched = { ...attributes };\n const activeContext = context.active();\n const baggage = propagation.getBaggage(activeContext);\n\n if (!baggage) {\n return enriched;\n }\n\n let keyCount = 0;\n let byteCount = 0;\n const maxKeys = enrichConfig.maxKeys ?? 10;\n const maxBytes = enrichConfig.maxBytes ?? 1024;\n const prefix = enrichConfig.prefix ?? '';\n\n // Get all baggage entries\n for (const [key, entry] of baggage.getAllEntries()) {\n // Check if key is allowed\n if (!this.isBaggageKeyAllowed(key, enrichConfig)) {\n continue;\n }\n\n // Check limits\n if (keyCount >= maxKeys) {\n break;\n }\n\n const value = entry.value;\n\n // Apply transform first so maxBytes is checked against transformed size (e.g. hash output)\n const transform = enrichConfig.transform?.[key];\n let transformedValue: string;\n\n if (transform === 'hash') {\n transformedValue = hashValue(value);\n } else if (transform === 'plain' || !transform) {\n transformedValue = value;\n } else if (typeof transform === 'function') {\n transformedValue = transform(value);\n } else {\n transformedValue = value;\n }\n\n const valueBytes = new TextEncoder().encode(transformedValue).length;\n\n if (byteCount + valueBytes > maxBytes) {\n continue; // Skip this entry if transformed value would exceed byte limit\n }\n\n // Add to enriched attributes with prefix\n const enrichedKey = `${prefix}${key}`;\n enriched[enrichedKey] = transformedValue;\n\n keyCount++;\n byteCount += valueBytes;\n }\n\n return enriched;\n }\n\n /**\n * Check if a baggage key is allowed based on config\n */\n private isBaggageKeyAllowed(\n key: string,\n config: EnrichFromBaggageConfig,\n ): boolean {\n // Check deny list first (takes precedence)\n if (config.deny) {\n for (const pattern of config.deny) {\n if (this.matchesBaggagePattern(key, pattern)) {\n return false;\n }\n }\n }\n\n // Check allow list\n for (const pattern of config.allow) {\n if (this.matchesBaggagePattern(key, pattern)) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Check if a key matches a baggage pattern\n * Supports exact matches and wildcard patterns (e.g., 'tenant.*')\n */\n private matchesBaggagePattern(key: string, pattern: string): boolean {\n if (pattern.endsWith('.*')) {\n const prefix = pattern.slice(0, -2);\n return key.startsWith(prefix + '.');\n }\n return key === pattern;\n }\n\n /**\n * Track a business event\n *\n * Use this for tracking user actions, business events, product usage:\n * - \"user.signup\"\n * - \"order.completed\"\n * - \"feature.used\"\n *\n * Events are sent to configured subscribers (PostHog, Mixpanel, etc.).\n *\n * @example\n * ```typescript\n * // Track user signup\n * events.trackEvent('user.signup', {\n * userId: '123',\n * plan: 'pro'\n * })\n *\n * // Track order\n * events.trackEvent('order.completed', {\n * orderId: 'ord_123',\n * amount: 99.99\n * })\n * ```\n */\n trackEvent(eventName: string, attributes?: EventAttributes): void {\n // Validate and sanitize input (with custom config if provided)\n const validationConfig = getValidationConfig();\n const validated = validateEvent(\n eventName,\n attributes,\n validationConfig || undefined,\n );\n\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext(\n validated.attributes,\n );\n\n this.logger?.info(\n {\n event: validated.eventName,\n attributes: enrichedAttributes,\n },\n 'Event tracked',\n );\n\n // Record for testing\n this.collector?.recordEvent({\n event: validated.eventName,\n attributes: enrichedAttributes,\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers (zero overhead if no subscribers)\n // Run in background - don't block event recording\n if (this.hasSubscribers) {\n // Build autotel context for trace correlation\n const autotelContext = this.buildAutotelContext();\n\n // Enrich from baggage if configured\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers((subscriber) =>\n subscriber.trackEvent(validated.eventName, finalAttributes, {\n autotel: autotelContext,\n }),\n );\n }\n }\n\n /**\n * Notify all subscribers concurrently without blocking\n * Uses circuit breakers to protect against failing subscribers\n * Uses Promise.allSettled to prevent subscriber errors from affecting other subscribers\n */\n private async notifySubscribers(\n fn: (subscriber: EventSubscriber) => Promise<void>,\n ): Promise<void> {\n const promises = this.subscribers.map(async (subscriber) => {\n const circuitBreaker = this.circuitBreakers.get(subscriber);\n if (!circuitBreaker) return; // Should never happen\n\n try {\n // Execute with circuit breaker protection\n await circuitBreaker.execute(() => fn(subscriber));\n } catch (error) {\n // Handle circuit open errors (expected behavior when subscriber is down)\n if (error instanceof CircuitOpenError) {\n // Circuit is open - subscriber is down, log at warn level for visibility (same behavior in all environments)\n getLogger().warn(\n {\n subscriberName: subscriber.name || 'Unknown',\n },\n `[Events] ${error.message}`,\n );\n return;\n }\n\n // Log other subscriber errors but don't throw - event failures shouldn't break business logic\n getLogger().error(\n {\n err: error instanceof Error ? error : undefined,\n subscriberName: subscriber.name || 'Unknown',\n },\n `[Events] Subscriber ${subscriber.name || 'Unknown'} failed`,\n );\n }\n });\n\n // Wait for all subscribers (success or failure)\n await Promise.allSettled(promises);\n }\n\n /**\n * Track conversion funnel steps\n *\n * Monitor where users drop off in multi-step processes.\n *\n * @example\n * ```typescript\n * // Track signup funnel\n * events.trackFunnelStep('signup', 'started', { userId: '123' })\n * events.trackFunnelStep('signup', 'email_verified', { userId: '123' })\n * events.trackFunnelStep('signup', 'completed', { userId: '123' })\n *\n * // Track checkout flow\n * events.trackFunnelStep('checkout', 'started', { cartValue: 99.99 })\n * events.trackFunnelStep('checkout', 'payment_info', { cartValue: 99.99 })\n * events.trackFunnelStep('checkout', 'completed', { cartValue: 99.99 })\n * ```\n */\n trackFunnelStep(\n funnelName: string,\n status: FunnelStatus,\n attributes?: EventAttributes,\n ): void {\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext(attributes);\n\n this.logger?.info(\n {\n funnel: funnelName,\n status,\n attributes: enrichedAttributes,\n },\n 'Funnel step tracked',\n );\n\n // Record for testing\n this.collector?.recordFunnelStep({\n funnel: funnelName,\n status,\n attributes: enrichedAttributes,\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers\n if (this.hasSubscribers) {\n const autotelContext = this.buildAutotelContext();\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers((subscriber) =>\n subscriber.trackFunnelStep(funnelName, status, finalAttributes, {\n autotel: autotelContext,\n }),\n );\n }\n }\n\n /**\n * Track outcomes (success/failure/partial)\n *\n * Monitor success rates of critical operations.\n *\n * @example\n * ```typescript\n * // Track email delivery\n * events.trackOutcome('email.delivery', 'success', {\n * recipientType: 'user',\n * emailType: 'welcome'\n * })\n *\n * events.trackOutcome('email.delivery', 'failure', {\n * recipientType: 'user',\n * errorCode: 'invalid_email'\n * })\n *\n * // Track payment processing\n * events.trackOutcome('payment.process', 'success', { amount: 99.99 })\n * events.trackOutcome('payment.process', 'failure', { error: 'insufficient_funds' })\n * ```\n */\n trackOutcome(\n operationName: string,\n status: OutcomeStatus,\n attributes?: EventAttributes,\n ): void {\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext(attributes);\n\n this.logger?.info(\n {\n operation: operationName,\n status,\n attributes: enrichedAttributes,\n },\n 'Outcome tracked',\n );\n\n // Record for testing\n this.collector?.recordOutcome({\n operation: operationName,\n status,\n attributes: enrichedAttributes,\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers\n if (this.hasSubscribers) {\n const autotelContext = this.buildAutotelContext();\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers((subscriber) =>\n subscriber.trackOutcome(operationName, status, finalAttributes, {\n autotel: autotelContext,\n }),\n );\n }\n }\n\n /**\n * Track value metrics\n *\n * Record numerical values like revenue, transaction amounts,\n * item counts, processing times, engagement scores, etc.\n *\n * @example\n * ```typescript\n * // Track revenue\n * events.trackValue('order.revenue', 149.99, {\n * currency: 'USD',\n * productCategory: 'electronics'\n * })\n *\n * // Track items per cart\n * events.trackValue('cart.item_count', 5, {\n * userId: '123'\n * })\n *\n * // Track processing time\n * events.trackValue('api.response_time', 250, {\n * unit: 'ms',\n * endpoint: '/api/checkout'\n * })\n * ```\n */\n trackValue(\n metricName: string,\n value: number,\n attributes?: EventAttributes,\n ): void {\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext({\n metric: metricName,\n ...attributes,\n });\n\n this.logger?.debug(\n {\n metric: metricName,\n value,\n attributes: enrichedAttributes,\n },\n 'Value tracked',\n );\n\n // Record for testing\n this.collector?.recordValue({\n metric: metricName,\n value,\n attributes: enrichedAttributes,\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers\n if (this.hasSubscribers) {\n const autotelContext = this.buildAutotelContext();\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers((subscriber) =>\n subscriber.trackValue(metricName, value, finalAttributes, {\n autotel: autotelContext,\n }),\n );\n }\n }\n\n /**\n * Flush all subscribers and wait for pending events\n *\n * Call this before shutdown to ensure all events are delivered.\n *\n * @example\n * ```typescript\n * const event =new Event('app', { subscribers: [...] });\n *\n * // Before shutdown\n * await events.flush();\n * ```\n */\n async flush(): Promise<void> {\n if (!this.hasSubscribers) return;\n\n const shutdownPromises = this.subscribers.map(async (subscriber) => {\n if (subscriber.shutdown) {\n try {\n await subscriber.shutdown();\n } catch (error) {\n getLogger().error(\n {\n err: error instanceof Error ? error : undefined,\n subscriberName: subscriber.name || 'Unknown',\n },\n `[Events] Failed to shutdown subscriber ${subscriber.name || 'Unknown'}`,\n );\n }\n }\n });\n\n await Promise.allSettled(shutdownPromises);\n }\n\n /**\n * Shutdown the Event instance and all subscribers\n *\n * Unlike `flush()`, this method:\n * - Shuts down all subscribers\n * - Prevents further event tracking (hasSubscribers becomes false)\n * - Should only be called once at application shutdown\n *\n * @example\n * ```typescript\n * // In Next.js API route with after()\n * import { after } from 'next/server';\n *\n * export async function POST(req: Request) {\n * const event = new Event('checkout', { subscribers: [...] });\n * event.trackEvent('order.completed', { orderId: '123' });\n *\n * after(async () => {\n * await event.shutdown();\n * });\n *\n * return Response.json({ success: true });\n * }\n * ```\n */\n async shutdown(): Promise<void> {\n if (!this.hasSubscribers) return;\n\n await Promise.allSettled(\n this.subscribers.map(async (subscriber) => {\n if (subscriber.shutdown) {\n try {\n await subscriber.shutdown();\n } catch (error) {\n getLogger().error(\n {\n err: error instanceof Error ? error : undefined,\n subscriberName: subscriber.name || 'Unknown',\n },\n `[Events] Failed to shutdown subscriber ${subscriber.name || 'Unknown'}`,\n );\n }\n }\n }),\n );\n\n // Prevent further tracking after shutdown\n this.hasSubscribers = false;\n }\n\n /**\n * Track funnel progression with custom step names\n *\n * Unlike trackFunnelStep which uses FunnelStatus enum values,\n * this method allows any string as the step name for flexible funnel tracking.\n *\n * @param funnelName - Name of the funnel (e.g., \"checkout\", \"onboarding\")\n * @param stepName - Custom step name (e.g., \"cart_viewed\", \"payment_entered\")\n * @param stepNumber - Optional numeric position in the funnel\n * @param attributes - Optional event attributes\n *\n * @example\n * ```typescript\n * // Track custom checkout steps\n * event.trackFunnelProgression('checkout', 'cart_viewed', 1);\n * event.trackFunnelProgression('checkout', 'shipping_selected', 2);\n * event.trackFunnelProgression('checkout', 'payment_entered', 3);\n * event.trackFunnelProgression('checkout', 'order_confirmed', 4);\n * ```\n */\n trackFunnelProgression(\n funnelName: string,\n stepName: string,\n stepNumber?: number,\n attributes?: EventAttributes,\n ): void {\n // Auto-attach all available telemetry context\n const enrichedAttributes = this.enrichWithTelemetryContext(attributes);\n\n this.logger?.info(\n {\n funnel: funnelName,\n stepName,\n stepNumber,\n attributes: enrichedAttributes,\n },\n 'Funnel progression tracked',\n );\n\n // Record for testing (as funnel step with custom name)\n this.collector?.recordFunnelStep({\n funnel: funnelName,\n status: stepName as FunnelStatus, // Cast for testing collector\n attributes: {\n ...enrichedAttributes,\n step_name: stepName,\n ...(stepNumber === undefined ? {} : { step_number: stepNumber }),\n },\n service: this.serviceName,\n timestamp: Date.now(),\n });\n\n // Notify subscribers that support trackFunnelProgression\n if (this.hasSubscribers) {\n const autotelContext = this.buildAutotelContext();\n const finalAttributes = this.enrichFromBaggage(enrichedAttributes);\n\n void this.notifySubscribers(async (subscriber) => {\n await (subscriber.trackFunnelProgression\n ? subscriber.trackFunnelProgression(\n funnelName,\n stepName,\n stepNumber,\n finalAttributes,\n { autotel: autotelContext },\n )\n : // Fall back to trackFunnelStep with step as custom name (cast)\n subscriber.trackFunnelStep(\n funnelName,\n stepName as FunnelStatus,\n {\n ...finalAttributes,\n step_name: stepName,\n ...(stepNumber === undefined\n ? {}\n : { step_number: stepNumber }),\n },\n { autotel: autotelContext },\n ));\n });\n }\n }\n\n /**\n * Track multiple events in a batch\n *\n * Useful for bulk event tracking with consistent timestamps.\n * Events are sent to subscribers individually but processed together.\n *\n * @param events - Array of events to track\n *\n * @example\n * ```typescript\n * event.trackBatch([\n * { name: 'item.viewed', attributes: { itemId: '1' } },\n * { name: 'item.viewed', attributes: { itemId: '2' } },\n * { name: 'cart.updated', attributes: { itemCount: 2 } },\n * ]);\n * ```\n */\n trackBatch(\n events: Array<{ name: string; attributes?: EventAttributesInput }>,\n ): void {\n // Filter attributes and track each event\n for (const event of events) {\n // Filter undefined/null values from attributes\n const filteredAttributes = event.attributes\n ? (Object.fromEntries(\n Object.entries(event.attributes).filter(\n ([, v]) => v !== undefined && v !== null,\n ),\n ) as EventAttributes)\n : undefined;\n\n this.trackEvent(event.name, filteredAttributes);\n }\n }\n}\n\n/**\n * Global events instances (singleton pattern)\n */\nconst eventsInstances = new Map<string, Event>();\n\n/**\n * Get or create an Events instance for a service\n *\n * @param serviceName - Service name for identifying events\n * @param logger - Optional logger\n * @returns Events instance\n *\n * @example\n * ```typescript\n * const event =getEvents('job-application')\n * events.trackEvent('application.submitted', { jobId: '123' })\n * ```\n */\nexport function getEvents(serviceName: string, logger?: Logger): Event {\n if (!eventsInstances.has(serviceName)) {\n eventsInstances.set(serviceName, new Event(serviceName, { logger }));\n }\n return eventsInstances.get(serviceName)!;\n}\n\n/**\n * Reset all events instances (mainly for testing)\n */\nexport function resetEvents(): void {\n eventsInstances.clear();\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { requireModule } from './chunk-33WTKH7X.js';
1
+ import { requireModule } from './chunk-KPNV2GPW.js';
2
2
  import { trace, context, SpanStatusCode } from '@opentelemetry/api';
3
3
 
4
4
  var spanNameMap = /* @__PURE__ */ new WeakMap();
@@ -114,5 +114,5 @@ function flattenMetadata(metadata, prefix = "metadata") {
114
114
  }
115
115
 
116
116
  export { createDeterministicTraceId, enrichWithTraceContext, finalizeSpan, flattenMetadata, getActiveContext, getActiveSpan, getTraceContext, getTracer, isTracing, resolveTraceUrl, runWithSpan, setSpanName };
117
- //# sourceMappingURL=chunk-DSMSIVTG.js.map
118
- //# sourceMappingURL=chunk-DSMSIVTG.js.map
117
+ //# sourceMappingURL=chunk-MBEHEGQE.js.map
118
+ //# sourceMappingURL=chunk-MBEHEGQE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/trace-helpers.ts"],"names":["context"],"mappings":"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","file":"chunk-DSMSIVTG.js","sourcesContent":["/**\n * Trace context helpers - Core primitives for trace correlation\n *\n * These are the building blocks that allow users to bring their own logger\n * (bunyan, log4js, custom, etc.) and add trace correlation.\n *\n * @example Using with bunyan\n * ```typescript\n * import bunyan from 'bunyan';\n * import { enrichWithTraceContext } from 'autotel/trace-helpers';\n *\n * const bunyanLogger = bunyan.createLogger({ name: 'myapp' });\n *\n * const logger = {\n * info: (msg: string, extra?: object) => {\n * bunyanLogger.info(enrichWithTraceContext(extra || {}), msg);\n * }\n * };\n * ```\n *\n * @example Using with log4js\n * ```typescript\n * import log4js from 'log4js';\n * import { getTraceContext } from 'autotel/trace-helpers';\n *\n * const log4jsLogger = log4js.getLogger();\n *\n * function logWithTrace(level: string, msg: string, extra?: object) {\n * const context = getTraceContext();\n * log4jsLogger[level](msg, { ...extra, ...context });\n * }\n * ```\n */\n\nimport { trace, context, SpanStatusCode } from '@opentelemetry/api';\nimport type { Span, Tracer, Context } from '@opentelemetry/api';\nimport { requireModule } from './node-require';\n\n/**\n * WeakMap to store span names for active spans\n * This allows us to retrieve the span name even though OpenTelemetry\n * doesn't expose it through the public API\n */\nconst spanNameMap = new WeakMap<Span, string>();\n\n/**\n * Store span name for a given span\n * Called internally when spans are created\n */\nexport function setSpanName(span: Span, name: string): void {\n spanNameMap.set(span, name);\n}\n\n/**\n * Trace context extracted from active span\n */\nexport interface TraceContext {\n /** Full 32-character hex trace ID */\n traceId: string;\n /** 16-character hex span ID */\n spanId: string;\n /** First 16 characters of trace ID (for log grouping/correlation) */\n correlationId: string;\n /** Function/operation name (OpenTelemetry semantic convention: code.function) */\n 'code.function'?: string;\n /** Datadog trace ID in decimal format (lower 64 bits) for log-trace correlation */\n 'dd.trace_id'?: string;\n /** Datadog span ID in decimal format for log-trace correlation */\n 'dd.span_id'?: string;\n}\n\n/**\n * Convert hex string to decimal string representation\n * Handles 64-bit unsigned integers for Datadog correlation\n *\n * @param hex - Hex string (up to 16 characters for 64-bit)\n * @returns Decimal string representation\n */\nfunction hexToDecimal(hex: string): string {\n // For 64-bit values, use BigInt to avoid precision loss\n return BigInt('0x' + hex).toString(10);\n}\n\n/**\n * Get current trace context from active span\n *\n * Returns null if no span is active (e.g., outside of trace operation)\n *\n * Includes both OpenTelemetry standard fields (hex) and Datadog-specific\n * fields (decimal) for maximum compatibility.\n *\n * @returns Trace context with traceId, spanId, correlationId, and Datadog decimal IDs, or null\n *\n * @example\n * ```typescript\n * import { getTraceContext } from 'autotel/trace-helpers';\n *\n * const context = getTraceContext();\n * if (context) {\n * console.log('Current trace:', context.traceId);\n * // Current trace: 4bf92f3577b34da6a3ce929d0e0e4736\n * console.log('Datadog trace ID:', context['dd.trace_id']);\n * // Datadog trace ID: 12007117331170166582 (decimal for log correlation)\n * }\n * ```\n */\nexport function getTraceContext(): TraceContext | null {\n const span = trace.getActiveSpan();\n if (!span) return null;\n\n const spanContext = span.spanContext();\n const traceId = spanContext.traceId;\n const spanId = spanContext.spanId;\n\n // Get span name from WeakMap (set when span is created)\n // Map to OpenTelemetry semantic convention: code.function\n const spanName = spanNameMap.get(span);\n\n // Datadog uses the lower 64 bits of the 128-bit OpenTelemetry trace ID\n // Convert from hex to decimal for Datadog's log-trace correlation\n const traceIdLower64 = traceId.slice(-16); // Last 16 hex chars = lower 64 bits\n const ddTraceId = hexToDecimal(traceIdLower64);\n const ddSpanId = hexToDecimal(spanId);\n\n return {\n traceId,\n spanId,\n correlationId: traceId.slice(0, 16),\n ...(spanName && { 'code.function': spanName }),\n // Datadog-specific fields for log-trace correlation\n 'dd.trace_id': ddTraceId,\n 'dd.span_id': ddSpanId,\n };\n}\n\n/**\n * Enrich object with trace context (traceId, spanId, correlationId, and Datadog fields)\n *\n * If no span is active, returns the object unchanged.\n * This prevents \"undefined\" or \"null\" values in logs.\n *\n * Automatically adds both OpenTelemetry standard fields (hex) and Datadog-specific\n * fields (decimal) for maximum compatibility with observability backends.\n *\n * @param obj - Object to enrich (e.g., log metadata)\n * @returns Object with trace context merged in, or unchanged if no active span\n *\n * @example\n * ```typescript\n * import { enrichWithTraceContext } from 'autotel/trace-helpers';\n *\n * // Inside a trace operation:\n * const enriched = enrichWithTraceContext({ userId: '123' });\n * // {\n * // userId: '123',\n * // traceId: '4bf92f3577b34da6a3ce929d0e0e4736',\n * // spanId: '00f067aa0ba902b7',\n * // correlationId: '4bf92f3577b34da6',\n * // 'dd.trace_id': '12007117331170166582', // Datadog decimal format\n * // 'dd.span_id': '67667974448284583' // Datadog decimal format\n * // }\n *\n * // Outside trace operation:\n * const unchanged = enrichWithTraceContext({ userId: '123' });\n * // { userId: '123' } - no trace fields added\n * ```\n */\nexport function enrichWithTraceContext<T extends Record<string, unknown>>(\n obj: T,\n): T {\n const context = getTraceContext();\n return context ? ({ ...obj, ...context } as T) : obj;\n}\n\n/**\n * Check if currently in a trace context\n *\n * Useful for conditional logic based on trace presence\n *\n * @returns true if active span exists, false otherwise\n *\n * @example\n * ```typescript\n * import { isTracing } from 'autotel/trace-helpers';\n *\n * if (isTracing()) {\n * // Add expensive debug metadata only when tracing\n * logger.debug('Detailed context', expensiveDebugData());\n * }\n * ```\n */\nexport function isTracing(): boolean {\n return trace.getActiveSpan() !== undefined;\n}\n\n/**\n * Get a tracer instance for creating custom spans\n *\n * Use this when you need low-level control over span lifecycle.\n * For most use cases, prefer trace(), span(), or instrument() instead.\n *\n * @param name - Tracer name (usually your service or module name)\n * @param version - Optional version string\n * @returns OpenTelemetry Tracer instance\n *\n * @example Basic usage\n * ```typescript\n * import { getTracer } from 'autotel';\n *\n * const tracer = getTracer('my-service');\n * const span = tracer.startSpan('custom.operation');\n * try {\n * // Your logic\n * span.setAttribute('key', 'value');\n * } finally {\n * span.end();\n * }\n * ```\n *\n * @example With AI SDK\n * ```typescript\n * import { getTracer } from 'autotel';\n * import { generateText } from 'ai';\n *\n * const tracer = getTracer('ai-agent');\n * const result = await generateText({\n * model: myModel,\n * prompt: 'Hello',\n * experimental_telemetry: {\n * isEnabled: true,\n * tracer,\n * },\n * });\n * ```\n */\nexport function getTracer(name: string, version?: string): Tracer {\n return trace.getTracer(name, version);\n}\n\n/**\n * Get the currently active span\n *\n * Returns undefined if no span is currently active.\n * Useful for adding attributes to the current span.\n *\n * @returns Active span or undefined\n *\n * @example Adding attributes to active span\n * ```typescript\n * import { getActiveSpan } from 'autotel';\n *\n * const span = getActiveSpan();\n * if (span) {\n * span.setAttribute('user.id', userId);\n * span.setAttribute('user.action', 'click');\n * }\n * ```\n *\n * @example Checking span status\n * ```typescript\n * import { getActiveSpan, SpanStatusCode } from 'autotel';\n *\n * const span = getActiveSpan();\n * if (span?.isRecording()) {\n * span.setStatus({ code: SpanStatusCode.OK });\n * }\n * ```\n */\nexport function getActiveSpan(): Span | undefined {\n return trace.getActiveSpan();\n}\n\n/**\n * Get the currently active OpenTelemetry context\n *\n * The context contains the active span and any baggage.\n * Useful for context propagation and custom instrumentation.\n *\n * @returns Current active context\n *\n * @example Propagating context\n * ```typescript\n * import { getActiveContext } from 'autotel';\n *\n * const currentContext = getActiveContext();\n * // Pass context to another function or service\n * ```\n *\n * @example With context injection\n * ```typescript\n * import { getActiveContext, injectTraceContext } from 'autotel';\n *\n * const headers = {};\n * injectTraceContext(headers);\n * // Headers now contain trace propagation data\n * ```\n */\nexport function getActiveContext(): Context {\n // Check stored context first (from baggage setters), then fall back to active context\n // This ensures ctx.setBaggage() changes are visible to OpenTelemetry operations\n try {\n const { getActiveContextWithBaggage } = requireModule<{\n getActiveContextWithBaggage: () => Context;\n }>('./trace-context');\n return getActiveContextWithBaggage();\n } catch {\n // Fallback if trace-context isn't available\n return context.active();\n }\n}\n\n/**\n * Run a function with a specific span set as active\n *\n * This is a convenience wrapper around the two-step process of\n * setting a span in context and running code within that context.\n *\n * @param span - The span to set as active\n * @param fn - Function to execute with the span active\n * @returns The return value of the function\n *\n * @example Running code with a custom span\n * ```typescript\n * import { getTracer, runWithSpan } from 'autotel';\n *\n * const tracer = getTracer('my-service');\n * const span = tracer.startSpan('background.job');\n *\n * try {\n * const result = await runWithSpan(span, async () => {\n * // Any spans created here will be children of 'background.job'\n * await processData();\n * return { success: true };\n * });\n * console.log(result);\n * } finally {\n * span.end();\n * }\n * ```\n *\n * @example Testing with custom spans\n * ```typescript\n * import { runWithSpan, otelTrace } from 'autotel';\n *\n * const tracer = otelTrace.getTracer('test');\n * const span = tracer.startSpan('test.operation');\n *\n * const result = runWithSpan(span, () => {\n * // Code under test runs with this span as active\n * return myFunction();\n * });\n *\n * span.end();\n * ```\n */\nexport function runWithSpan<T>(span: Span, fn: () => T): T {\n const ctx = trace.setSpan(context.active(), span);\n return context.with(ctx, fn);\n}\n\n/**\n * Finalize a span with appropriate status and optional error recording\n *\n * This is a convenience function that:\n * - Records exceptions if an error is provided\n * - Sets span status to ERROR if error exists, OK otherwise\n * - Ends the span\n *\n * @param span - The span to finalize\n * @param error - Optional error to record\n *\n * @example Without error (success case)\n * ```typescript\n * import { getTracer, finalizeSpan } from 'autotel';\n *\n * const tracer = getTracer('my-service');\n * const span = tracer.startSpan('operation');\n *\n * try {\n * await doWork();\n * finalizeSpan(span);\n * } catch (error) {\n * finalizeSpan(span, error);\n * throw error;\n * }\n * ```\n *\n * @example With error\n * ```typescript\n * import { getTracer, finalizeSpan } from 'autotel';\n *\n * const tracer = getTracer('my-service');\n * const span = tracer.startSpan('operation');\n *\n * try {\n * await riskyOperation();\n * finalizeSpan(span);\n * } catch (error) {\n * finalizeSpan(span, error); // Records exception and sets ERROR status\n * throw error;\n * }\n * ```\n *\n * @example In instrumentation\n * ```typescript\n * import { getTracer, runWithSpan, finalizeSpan } from 'autotel';\n *\n * function instrumentedQuery(query: string) {\n * const tracer = getTracer('db');\n * const span = tracer.startSpan('db.query');\n *\n * return runWithSpan(span, () => {\n * try {\n * const result = executeQuery(query);\n * finalizeSpan(span);\n * return result;\n * } catch (error) {\n * finalizeSpan(span, error);\n * throw error;\n * }\n * });\n * }\n * ```\n */\nexport function finalizeSpan(span: Span, error?: unknown): void {\n if (error) {\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.setStatus({ code: SpanStatusCode.ERROR });\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n span.end();\n}\n\n/**\n * Creates a deterministic trace ID from a seed string.\n *\n * Generates a consistent 128-bit trace ID (32 hex characters) from an input seed\n * using SHA-256 hashing. Useful for correlating external system IDs (request IDs,\n * order IDs, session IDs) with OpenTelemetry trace IDs.\n *\n * **Use Cases:**\n * - Correlate external request IDs with traces\n * - Link customer support tickets to trace data\n * - Associate business entities (orders, sessions) with observability data\n * - Debug specific user flows by deterministic trace lookup\n *\n * **Important:** Only use this when you need deterministic trace IDs for correlation.\n * For normal tracing, let OpenTelemetry generate random trace IDs automatically.\n *\n * **Runtime Support:**\n * - Node.js 15+ (native crypto.subtle)\n * - All modern browsers\n * - Edge runtimes (Cloudflare Workers, Deno, etc.)\n *\n * @param seed - Input string to generate trace ID from (e.g., request ID, order ID)\n * @returns Promise resolving to a 32-character hex trace ID (128 bits)\n *\n * @example Correlate external request ID with trace\n * ```typescript\n * import { createDeterministicTraceId } from 'autotel/trace-helpers'\n * import { trace, context } from '@opentelemetry/api'\n *\n * // In middleware or request handler\n * const requestId = req.headers['x-request-id']\n * const traceId = await createDeterministicTraceId(requestId)\n *\n * // Use with manual span creation (advanced - not needed with trace/span functions)\n * const tracer = trace.getTracer('my-service')\n * const spanContext = {\n * traceId,\n * spanId: '0123456789abcdef', // Still random\n * traceFlags: 1\n * }\n * ```\n *\n * @example Link customer support tickets to traces\n * ```typescript\n * import { createDeterministicTraceId } from 'autotel/trace-helpers'\n *\n * // Support dashboard integration\n * const ticketId = 'TICKET-12345'\n * const traceId = await createDeterministicTraceId(ticketId)\n *\n * // Generate direct link to traces in observability backend\n * const traceUrl = `https://your-otel-backend.com/traces/${traceId}`\n * console.log(`View related traces: ${traceUrl}`)\n * ```\n *\n * @example Session-based correlation\n * ```typescript\n * import { createDeterministicTraceId } from 'autotel/trace-helpers'\n *\n * // Track all operations for a user session\n * const sessionId = req.session.id\n * const traceId = await createDeterministicTraceId(sessionId)\n *\n * // All operations in this session share the same trace ID\n * // Makes it easy to find all activity for a specific session\n * ```\n *\n * @public\n */\nexport async function createDeterministicTraceId(\n seed: string,\n): Promise<string> {\n // Encode seed string to bytes\n const encoder = new TextEncoder();\n const data = encoder.encode(seed);\n\n // Generate SHA-256 hash (256 bits)\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n\n // Convert to hex string and truncate to 32 characters (128 bits)\n // OpenTelemetry trace IDs are 128 bits (16 bytes, 32 hex characters)\n const hashArray = new Uint8Array(hashBuffer);\n return [...hashArray]\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n .slice(0, 32);\n}\n\n/**\n * Flattens nested metadata objects into dot-notation span attributes.\n *\n * Converts complex nested objects into flat key-value pairs suitable for\n * OpenTelemetry span attributes. Non-string values are JSON serialized.\n * Handles serialization failures gracefully with a fallback value.\n *\n * **Use Cases:**\n * - Structured metadata with nested objects\n * - User context with multiple properties\n * - Request/response metadata\n * - Business entity attributes\n *\n * **Note:** Filters out null/undefined values automatically to keep spans clean.\n *\n * @param metadata - Nested metadata object to flatten\n * @param prefix - Prefix for all attribute keys (default: 'metadata')\n * @returns Flattened attributes as { [key: string]: string }\n *\n * @example Basic metadata flattening\n * ```typescript\n * import { flattenMetadata } from 'autotel/trace-helpers'\n * import { trace } from 'autotel'\n *\n * export const processOrder = trace(ctx => async (orderId: string) => {\n * const order = await getOrder(orderId)\n *\n * // Flatten complex order metadata\n * const flattened = flattenMetadata({\n * user: { id: order.userId, tier: 'premium' },\n * payment: { method: 'card', processor: 'stripe' },\n * items: order.items.length\n * })\n *\n * ctx.setAttributes(flattened)\n * // Results in:\n * // {\n * // 'metadata.user.id': 'user-123',\n * // 'metadata.user.tier': 'premium',\n * // 'metadata.payment.method': 'card',\n * // 'metadata.payment.processor': 'stripe',\n * // 'metadata.items': '5'\n * // }\n * })\n * ```\n *\n * @example Custom prefix for semantic conventions\n * ```typescript\n * import { flattenMetadata } from 'autotel/trace-helpers'\n * import { trace } from 'autotel'\n *\n * export const fetchUser = trace(ctx => async (userId: string) => {\n * const user = await db.users.findOne({ id: userId })\n *\n * // Use semantic convention prefix\n * const userAttrs = flattenMetadata(\n * {\n * id: user.id,\n * email: user.email,\n * plan: user.subscription.plan\n * },\n * 'user' // Custom prefix\n * )\n *\n * ctx.setAttributes(userAttrs)\n * // Results in:\n * // {\n * // 'user.id': 'user-123',\n * // 'user.email': 'user@example.com',\n * // 'user.plan': 'enterprise'\n * // }\n * })\n * ```\n *\n * @example With complex objects (auto-serialized)\n * ```typescript\n * import { flattenMetadata } from 'autotel/trace-helpers'\n * import { trace } from 'autotel'\n *\n * export const analyzeRequest = trace(ctx => async (req: Request) => {\n * const metadata = flattenMetadata({\n * headers: req.headers, // Object - will be JSON serialized\n * query: req.query, // Object - will be JSON serialized\n * timestamp: new Date() // Non-string - will be JSON serialized\n * })\n *\n * ctx.setAttributes(metadata)\n * // Results in:\n * // {\n * // 'metadata.headers': '{\"accept\":\"application/json\",...}',\n * // 'metadata.query': '{\"page\":\"1\",\"limit\":\"10\"}',\n * // 'metadata.timestamp': '\"2024-01-15T12:00:00.000Z\"'\n * // }\n * })\n * ```\n *\n * @example Error handling\n * ```typescript\n * import { flattenMetadata } from 'autotel/trace-helpers'\n *\n * // Objects with circular references are handled gracefully\n * const circular: any = { a: 1 }\n * circular.self = circular\n *\n * const flattened = flattenMetadata({ data: circular })\n * // Results in:\n * // { 'metadata.data': '<serialization-failed>' }\n * ```\n *\n * @public\n */\n/**\n * Resolve a trace URL from a template string and trace ID.\n *\n * Templates use `{traceId}` as placeholder. Falls back to `OTEL_TRACE_URL_TEMPLATE` env var.\n *\n * @example\n * resolveTraceUrl('https://grafana.example.com/explore?traceId={traceId}', 'abc123')\n * // => 'https://grafana.example.com/explore?traceId=abc123'\n */\nexport function resolveTraceUrl(\n template: string | undefined,\n traceId: string,\n): string | undefined {\n const t = template ?? process.env.OTEL_TRACE_URL_TEMPLATE;\n if (!t) return undefined;\n return t.replace(/\\{traceId\\}/g, traceId);\n}\n\nexport function flattenMetadata(\n metadata: Record<string, unknown>,\n prefix = 'metadata',\n): Record<string, string> {\n const flattened: Record<string, string> = {};\n const seen = new WeakSet<object>(); // Track visited objects to detect cycles\n\n function flatten(obj: Record<string, unknown>, currentPrefix: string): void {\n for (const [key, value] of Object.entries(obj)) {\n // Skip null/undefined values\n if (value == null) continue;\n\n const attributeKey = `${currentPrefix}.${key}`;\n\n // Handle primitives directly (string, number, boolean)\n if (typeof value === 'string') {\n flattened[attributeKey] = value;\n continue;\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n flattened[attributeKey] = String(value);\n continue;\n }\n\n // Recursively flatten plain objects (with cycle detection)\n if (\n typeof value === 'object' &&\n value !== null &&\n value.constructor === Object\n ) {\n // Detect circular references\n if (seen.has(value)) {\n flattened[attributeKey] = '<circular-reference>';\n continue;\n }\n\n // Mark as visited and recursively flatten\n seen.add(value);\n flatten(value as Record<string, unknown>, attributeKey);\n continue;\n }\n\n // Serialize arrays and other non-plain objects to JSON\n try {\n flattened[attributeKey] = JSON.stringify(value);\n } catch {\n // Handle circular references or non-serializable objects\n flattened[attributeKey] = '<serialization-failed>';\n }\n }\n }\n\n flatten(metadata, prefix);\n return flattened;\n}\n"]}
1
+ {"version":3,"sources":["../src/trace-helpers.ts"],"names":["context"],"mappings":"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","file":"chunk-MBEHEGQE.js","sourcesContent":["/**\n * Trace context helpers - Core primitives for trace correlation\n *\n * These are the building blocks that allow users to bring their own logger\n * (bunyan, log4js, custom, etc.) and add trace correlation.\n *\n * @example Using with bunyan\n * ```typescript\n * import bunyan from 'bunyan';\n * import { enrichWithTraceContext } from 'autotel/trace-helpers';\n *\n * const bunyanLogger = bunyan.createLogger({ name: 'myapp' });\n *\n * const logger = {\n * info: (msg: string, extra?: object) => {\n * bunyanLogger.info(enrichWithTraceContext(extra || {}), msg);\n * }\n * };\n * ```\n *\n * @example Using with log4js\n * ```typescript\n * import log4js from 'log4js';\n * import { getTraceContext } from 'autotel/trace-helpers';\n *\n * const log4jsLogger = log4js.getLogger();\n *\n * function logWithTrace(level: string, msg: string, extra?: object) {\n * const context = getTraceContext();\n * log4jsLogger[level](msg, { ...extra, ...context });\n * }\n * ```\n */\n\nimport { trace, context, SpanStatusCode } from '@opentelemetry/api';\nimport type { Span, Tracer, Context } from '@opentelemetry/api';\nimport { requireModule } from './node-require';\n\n/**\n * WeakMap to store span names for active spans\n * This allows us to retrieve the span name even though OpenTelemetry\n * doesn't expose it through the public API\n */\nconst spanNameMap = new WeakMap<Span, string>();\n\n/**\n * Store span name for a given span\n * Called internally when spans are created\n */\nexport function setSpanName(span: Span, name: string): void {\n spanNameMap.set(span, name);\n}\n\n/**\n * Trace context extracted from active span\n */\nexport interface TraceContext {\n /** Full 32-character hex trace ID */\n traceId: string;\n /** 16-character hex span ID */\n spanId: string;\n /** First 16 characters of trace ID (for log grouping/correlation) */\n correlationId: string;\n /** Function/operation name (OpenTelemetry semantic convention: code.function) */\n 'code.function'?: string;\n /** Datadog trace ID in decimal format (lower 64 bits) for log-trace correlation */\n 'dd.trace_id'?: string;\n /** Datadog span ID in decimal format for log-trace correlation */\n 'dd.span_id'?: string;\n}\n\n/**\n * Convert hex string to decimal string representation\n * Handles 64-bit unsigned integers for Datadog correlation\n *\n * @param hex - Hex string (up to 16 characters for 64-bit)\n * @returns Decimal string representation\n */\nfunction hexToDecimal(hex: string): string {\n // For 64-bit values, use BigInt to avoid precision loss\n return BigInt('0x' + hex).toString(10);\n}\n\n/**\n * Get current trace context from active span\n *\n * Returns null if no span is active (e.g., outside of trace operation)\n *\n * Includes both OpenTelemetry standard fields (hex) and Datadog-specific\n * fields (decimal) for maximum compatibility.\n *\n * @returns Trace context with traceId, spanId, correlationId, and Datadog decimal IDs, or null\n *\n * @example\n * ```typescript\n * import { getTraceContext } from 'autotel/trace-helpers';\n *\n * const context = getTraceContext();\n * if (context) {\n * console.log('Current trace:', context.traceId);\n * // Current trace: 4bf92f3577b34da6a3ce929d0e0e4736\n * console.log('Datadog trace ID:', context['dd.trace_id']);\n * // Datadog trace ID: 12007117331170166582 (decimal for log correlation)\n * }\n * ```\n */\nexport function getTraceContext(): TraceContext | null {\n const span = trace.getActiveSpan();\n if (!span) return null;\n\n const spanContext = span.spanContext();\n const traceId = spanContext.traceId;\n const spanId = spanContext.spanId;\n\n // Get span name from WeakMap (set when span is created)\n // Map to OpenTelemetry semantic convention: code.function\n const spanName = spanNameMap.get(span);\n\n // Datadog uses the lower 64 bits of the 128-bit OpenTelemetry trace ID\n // Convert from hex to decimal for Datadog's log-trace correlation\n const traceIdLower64 = traceId.slice(-16); // Last 16 hex chars = lower 64 bits\n const ddTraceId = hexToDecimal(traceIdLower64);\n const ddSpanId = hexToDecimal(spanId);\n\n return {\n traceId,\n spanId,\n correlationId: traceId.slice(0, 16),\n ...(spanName && { 'code.function': spanName }),\n // Datadog-specific fields for log-trace correlation\n 'dd.trace_id': ddTraceId,\n 'dd.span_id': ddSpanId,\n };\n}\n\n/**\n * Enrich object with trace context (traceId, spanId, correlationId, and Datadog fields)\n *\n * If no span is active, returns the object unchanged.\n * This prevents \"undefined\" or \"null\" values in logs.\n *\n * Automatically adds both OpenTelemetry standard fields (hex) and Datadog-specific\n * fields (decimal) for maximum compatibility with observability backends.\n *\n * @param obj - Object to enrich (e.g., log metadata)\n * @returns Object with trace context merged in, or unchanged if no active span\n *\n * @example\n * ```typescript\n * import { enrichWithTraceContext } from 'autotel/trace-helpers';\n *\n * // Inside a trace operation:\n * const enriched = enrichWithTraceContext({ userId: '123' });\n * // {\n * // userId: '123',\n * // traceId: '4bf92f3577b34da6a3ce929d0e0e4736',\n * // spanId: '00f067aa0ba902b7',\n * // correlationId: '4bf92f3577b34da6',\n * // 'dd.trace_id': '12007117331170166582', // Datadog decimal format\n * // 'dd.span_id': '67667974448284583' // Datadog decimal format\n * // }\n *\n * // Outside trace operation:\n * const unchanged = enrichWithTraceContext({ userId: '123' });\n * // { userId: '123' } - no trace fields added\n * ```\n */\nexport function enrichWithTraceContext<T extends Record<string, unknown>>(\n obj: T,\n): T {\n const context = getTraceContext();\n return context ? ({ ...obj, ...context } as T) : obj;\n}\n\n/**\n * Check if currently in a trace context\n *\n * Useful for conditional logic based on trace presence\n *\n * @returns true if active span exists, false otherwise\n *\n * @example\n * ```typescript\n * import { isTracing } from 'autotel/trace-helpers';\n *\n * if (isTracing()) {\n * // Add expensive debug metadata only when tracing\n * logger.debug('Detailed context', expensiveDebugData());\n * }\n * ```\n */\nexport function isTracing(): boolean {\n return trace.getActiveSpan() !== undefined;\n}\n\n/**\n * Get a tracer instance for creating custom spans\n *\n * Use this when you need low-level control over span lifecycle.\n * For most use cases, prefer trace(), span(), or instrument() instead.\n *\n * @param name - Tracer name (usually your service or module name)\n * @param version - Optional version string\n * @returns OpenTelemetry Tracer instance\n *\n * @example Basic usage\n * ```typescript\n * import { getTracer } from 'autotel';\n *\n * const tracer = getTracer('my-service');\n * const span = tracer.startSpan('custom.operation');\n * try {\n * // Your logic\n * span.setAttribute('key', 'value');\n * } finally {\n * span.end();\n * }\n * ```\n *\n * @example With AI SDK\n * ```typescript\n * import { getTracer } from 'autotel';\n * import { generateText } from 'ai';\n *\n * const tracer = getTracer('ai-agent');\n * const result = await generateText({\n * model: myModel,\n * prompt: 'Hello',\n * experimental_telemetry: {\n * isEnabled: true,\n * tracer,\n * },\n * });\n * ```\n */\nexport function getTracer(name: string, version?: string): Tracer {\n return trace.getTracer(name, version);\n}\n\n/**\n * Get the currently active span\n *\n * Returns undefined if no span is currently active.\n * Useful for adding attributes to the current span.\n *\n * @returns Active span or undefined\n *\n * @example Adding attributes to active span\n * ```typescript\n * import { getActiveSpan } from 'autotel';\n *\n * const span = getActiveSpan();\n * if (span) {\n * span.setAttribute('user.id', userId);\n * span.setAttribute('user.action', 'click');\n * }\n * ```\n *\n * @example Checking span status\n * ```typescript\n * import { getActiveSpan, SpanStatusCode } from 'autotel';\n *\n * const span = getActiveSpan();\n * if (span?.isRecording()) {\n * span.setStatus({ code: SpanStatusCode.OK });\n * }\n * ```\n */\nexport function getActiveSpan(): Span | undefined {\n return trace.getActiveSpan();\n}\n\n/**\n * Get the currently active OpenTelemetry context\n *\n * The context contains the active span and any baggage.\n * Useful for context propagation and custom instrumentation.\n *\n * @returns Current active context\n *\n * @example Propagating context\n * ```typescript\n * import { getActiveContext } from 'autotel';\n *\n * const currentContext = getActiveContext();\n * // Pass context to another function or service\n * ```\n *\n * @example With context injection\n * ```typescript\n * import { getActiveContext, injectTraceContext } from 'autotel';\n *\n * const headers = {};\n * injectTraceContext(headers);\n * // Headers now contain trace propagation data\n * ```\n */\nexport function getActiveContext(): Context {\n // Check stored context first (from baggage setters), then fall back to active context\n // This ensures ctx.setBaggage() changes are visible to OpenTelemetry operations\n try {\n const { getActiveContextWithBaggage } = requireModule<{\n getActiveContextWithBaggage: () => Context;\n }>('./trace-context');\n return getActiveContextWithBaggage();\n } catch {\n // Fallback if trace-context isn't available\n return context.active();\n }\n}\n\n/**\n * Run a function with a specific span set as active\n *\n * This is a convenience wrapper around the two-step process of\n * setting a span in context and running code within that context.\n *\n * @param span - The span to set as active\n * @param fn - Function to execute with the span active\n * @returns The return value of the function\n *\n * @example Running code with a custom span\n * ```typescript\n * import { getTracer, runWithSpan } from 'autotel';\n *\n * const tracer = getTracer('my-service');\n * const span = tracer.startSpan('background.job');\n *\n * try {\n * const result = await runWithSpan(span, async () => {\n * // Any spans created here will be children of 'background.job'\n * await processData();\n * return { success: true };\n * });\n * console.log(result);\n * } finally {\n * span.end();\n * }\n * ```\n *\n * @example Testing with custom spans\n * ```typescript\n * import { runWithSpan, otelTrace } from 'autotel';\n *\n * const tracer = otelTrace.getTracer('test');\n * const span = tracer.startSpan('test.operation');\n *\n * const result = runWithSpan(span, () => {\n * // Code under test runs with this span as active\n * return myFunction();\n * });\n *\n * span.end();\n * ```\n */\nexport function runWithSpan<T>(span: Span, fn: () => T): T {\n const ctx = trace.setSpan(context.active(), span);\n return context.with(ctx, fn);\n}\n\n/**\n * Finalize a span with appropriate status and optional error recording\n *\n * This is a convenience function that:\n * - Records exceptions if an error is provided\n * - Sets span status to ERROR if error exists, OK otherwise\n * - Ends the span\n *\n * @param span - The span to finalize\n * @param error - Optional error to record\n *\n * @example Without error (success case)\n * ```typescript\n * import { getTracer, finalizeSpan } from 'autotel';\n *\n * const tracer = getTracer('my-service');\n * const span = tracer.startSpan('operation');\n *\n * try {\n * await doWork();\n * finalizeSpan(span);\n * } catch (error) {\n * finalizeSpan(span, error);\n * throw error;\n * }\n * ```\n *\n * @example With error\n * ```typescript\n * import { getTracer, finalizeSpan } from 'autotel';\n *\n * const tracer = getTracer('my-service');\n * const span = tracer.startSpan('operation');\n *\n * try {\n * await riskyOperation();\n * finalizeSpan(span);\n * } catch (error) {\n * finalizeSpan(span, error); // Records exception and sets ERROR status\n * throw error;\n * }\n * ```\n *\n * @example In instrumentation\n * ```typescript\n * import { getTracer, runWithSpan, finalizeSpan } from 'autotel';\n *\n * function instrumentedQuery(query: string) {\n * const tracer = getTracer('db');\n * const span = tracer.startSpan('db.query');\n *\n * return runWithSpan(span, () => {\n * try {\n * const result = executeQuery(query);\n * finalizeSpan(span);\n * return result;\n * } catch (error) {\n * finalizeSpan(span, error);\n * throw error;\n * }\n * });\n * }\n * ```\n */\nexport function finalizeSpan(span: Span, error?: unknown): void {\n if (error) {\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.setStatus({ code: SpanStatusCode.ERROR });\n } else {\n span.setStatus({ code: SpanStatusCode.OK });\n }\n span.end();\n}\n\n/**\n * Creates a deterministic trace ID from a seed string.\n *\n * Generates a consistent 128-bit trace ID (32 hex characters) from an input seed\n * using SHA-256 hashing. Useful for correlating external system IDs (request IDs,\n * order IDs, session IDs) with OpenTelemetry trace IDs.\n *\n * **Use Cases:**\n * - Correlate external request IDs with traces\n * - Link customer support tickets to trace data\n * - Associate business entities (orders, sessions) with observability data\n * - Debug specific user flows by deterministic trace lookup\n *\n * **Important:** Only use this when you need deterministic trace IDs for correlation.\n * For normal tracing, let OpenTelemetry generate random trace IDs automatically.\n *\n * **Runtime Support:**\n * - Node.js 15+ (native crypto.subtle)\n * - All modern browsers\n * - Edge runtimes (Cloudflare Workers, Deno, etc.)\n *\n * @param seed - Input string to generate trace ID from (e.g., request ID, order ID)\n * @returns Promise resolving to a 32-character hex trace ID (128 bits)\n *\n * @example Correlate external request ID with trace\n * ```typescript\n * import { createDeterministicTraceId } from 'autotel/trace-helpers'\n * import { trace, context } from '@opentelemetry/api'\n *\n * // In middleware or request handler\n * const requestId = req.headers['x-request-id']\n * const traceId = await createDeterministicTraceId(requestId)\n *\n * // Use with manual span creation (advanced - not needed with trace/span functions)\n * const tracer = trace.getTracer('my-service')\n * const spanContext = {\n * traceId,\n * spanId: '0123456789abcdef', // Still random\n * traceFlags: 1\n * }\n * ```\n *\n * @example Link customer support tickets to traces\n * ```typescript\n * import { createDeterministicTraceId } from 'autotel/trace-helpers'\n *\n * // Support dashboard integration\n * const ticketId = 'TICKET-12345'\n * const traceId = await createDeterministicTraceId(ticketId)\n *\n * // Generate direct link to traces in observability backend\n * const traceUrl = `https://your-otel-backend.com/traces/${traceId}`\n * console.log(`View related traces: ${traceUrl}`)\n * ```\n *\n * @example Session-based correlation\n * ```typescript\n * import { createDeterministicTraceId } from 'autotel/trace-helpers'\n *\n * // Track all operations for a user session\n * const sessionId = req.session.id\n * const traceId = await createDeterministicTraceId(sessionId)\n *\n * // All operations in this session share the same trace ID\n * // Makes it easy to find all activity for a specific session\n * ```\n *\n * @public\n */\nexport async function createDeterministicTraceId(\n seed: string,\n): Promise<string> {\n // Encode seed string to bytes\n const encoder = new TextEncoder();\n const data = encoder.encode(seed);\n\n // Generate SHA-256 hash (256 bits)\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n\n // Convert to hex string and truncate to 32 characters (128 bits)\n // OpenTelemetry trace IDs are 128 bits (16 bytes, 32 hex characters)\n const hashArray = new Uint8Array(hashBuffer);\n return [...hashArray]\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n .slice(0, 32);\n}\n\n/**\n * Flattens nested metadata objects into dot-notation span attributes.\n *\n * Converts complex nested objects into flat key-value pairs suitable for\n * OpenTelemetry span attributes. Non-string values are JSON serialized.\n * Handles serialization failures gracefully with a fallback value.\n *\n * **Use Cases:**\n * - Structured metadata with nested objects\n * - User context with multiple properties\n * - Request/response metadata\n * - Business entity attributes\n *\n * **Note:** Filters out null/undefined values automatically to keep spans clean.\n *\n * @param metadata - Nested metadata object to flatten\n * @param prefix - Prefix for all attribute keys (default: 'metadata')\n * @returns Flattened attributes as { [key: string]: string }\n *\n * @example Basic metadata flattening\n * ```typescript\n * import { flattenMetadata } from 'autotel/trace-helpers'\n * import { trace } from 'autotel'\n *\n * export const processOrder = trace(ctx => async (orderId: string) => {\n * const order = await getOrder(orderId)\n *\n * // Flatten complex order metadata\n * const flattened = flattenMetadata({\n * user: { id: order.userId, tier: 'premium' },\n * payment: { method: 'card', processor: 'stripe' },\n * items: order.items.length\n * })\n *\n * ctx.setAttributes(flattened)\n * // Results in:\n * // {\n * // 'metadata.user.id': 'user-123',\n * // 'metadata.user.tier': 'premium',\n * // 'metadata.payment.method': 'card',\n * // 'metadata.payment.processor': 'stripe',\n * // 'metadata.items': '5'\n * // }\n * })\n * ```\n *\n * @example Custom prefix for semantic conventions\n * ```typescript\n * import { flattenMetadata } from 'autotel/trace-helpers'\n * import { trace } from 'autotel'\n *\n * export const fetchUser = trace(ctx => async (userId: string) => {\n * const user = await db.users.findOne({ id: userId })\n *\n * // Use semantic convention prefix\n * const userAttrs = flattenMetadata(\n * {\n * id: user.id,\n * email: user.email,\n * plan: user.subscription.plan\n * },\n * 'user' // Custom prefix\n * )\n *\n * ctx.setAttributes(userAttrs)\n * // Results in:\n * // {\n * // 'user.id': 'user-123',\n * // 'user.email': 'user@example.com',\n * // 'user.plan': 'enterprise'\n * // }\n * })\n * ```\n *\n * @example With complex objects (auto-serialized)\n * ```typescript\n * import { flattenMetadata } from 'autotel/trace-helpers'\n * import { trace } from 'autotel'\n *\n * export const analyzeRequest = trace(ctx => async (req: Request) => {\n * const metadata = flattenMetadata({\n * headers: req.headers, // Object - will be JSON serialized\n * query: req.query, // Object - will be JSON serialized\n * timestamp: new Date() // Non-string - will be JSON serialized\n * })\n *\n * ctx.setAttributes(metadata)\n * // Results in:\n * // {\n * // 'metadata.headers': '{\"accept\":\"application/json\",...}',\n * // 'metadata.query': '{\"page\":\"1\",\"limit\":\"10\"}',\n * // 'metadata.timestamp': '\"2024-01-15T12:00:00.000Z\"'\n * // }\n * })\n * ```\n *\n * @example Error handling\n * ```typescript\n * import { flattenMetadata } from 'autotel/trace-helpers'\n *\n * // Objects with circular references are handled gracefully\n * const circular: any = { a: 1 }\n * circular.self = circular\n *\n * const flattened = flattenMetadata({ data: circular })\n * // Results in:\n * // { 'metadata.data': '<serialization-failed>' }\n * ```\n *\n * @public\n */\n/**\n * Resolve a trace URL from a template string and trace ID.\n *\n * Templates use `{traceId}` as placeholder. Falls back to `OTEL_TRACE_URL_TEMPLATE` env var.\n *\n * @example\n * resolveTraceUrl('https://grafana.example.com/explore?traceId={traceId}', 'abc123')\n * // => 'https://grafana.example.com/explore?traceId=abc123'\n */\nexport function resolveTraceUrl(\n template: string | undefined,\n traceId: string,\n): string | undefined {\n const t = template ?? process.env.OTEL_TRACE_URL_TEMPLATE;\n if (!t) return undefined;\n return t.replace(/\\{traceId\\}/g, traceId);\n}\n\nexport function flattenMetadata(\n metadata: Record<string, unknown>,\n prefix = 'metadata',\n): Record<string, string> {\n const flattened: Record<string, string> = {};\n const seen = new WeakSet<object>(); // Track visited objects to detect cycles\n\n function flatten(obj: Record<string, unknown>, currentPrefix: string): void {\n for (const [key, value] of Object.entries(obj)) {\n // Skip null/undefined values\n if (value == null) continue;\n\n const attributeKey = `${currentPrefix}.${key}`;\n\n // Handle primitives directly (string, number, boolean)\n if (typeof value === 'string') {\n flattened[attributeKey] = value;\n continue;\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n flattened[attributeKey] = String(value);\n continue;\n }\n\n // Recursively flatten plain objects (with cycle detection)\n if (\n typeof value === 'object' &&\n value !== null &&\n value.constructor === Object\n ) {\n // Detect circular references\n if (seen.has(value)) {\n flattened[attributeKey] = '<circular-reference>';\n continue;\n }\n\n // Mark as visited and recursively flatten\n seen.add(value);\n flatten(value as Record<string, unknown>, attributeKey);\n continue;\n }\n\n // Serialize arrays and other non-plain objects to JSON\n try {\n flattened[attributeKey] = JSON.stringify(value);\n } catch {\n // Handle circular references or non-serializable objects\n flattened[attributeKey] = '<serialization-failed>';\n }\n }\n }\n\n flatten(metadata, prefix);\n return flattened;\n}\n"]}
@@ -1,11 +1,11 @@
1
- import { loadYamlConfig } from './chunk-3SDILILG.js';
1
+ import { loadYamlConfig } from './chunk-7NDHLHZK.js';
2
2
  import { TailSamplingSpanProcessor } from './chunk-A4E5AQFK.js';
3
3
  import { FilteringSpanProcessor } from './chunk-WGWSHJ2N.js';
4
4
  import { SpanNameNormalizingProcessor } from './chunk-GYR5K654.js';
5
5
  import { REDACTOR_PRESETS, normalizeAttributeRedactorConfig, AttributeRedactingProcessor } from './chunk-JVWJDHDB.js';
6
6
  import { PrettyConsoleExporter } from './chunk-6UQRVUN3.js';
7
7
  import { CanonicalLogLineProcessor } from './chunk-3QXBFGKP.js';
8
- import { requireModule, safeRequire } from './chunk-33WTKH7X.js';
8
+ import { requireModule, safeRequire } from './chunk-KPNV2GPW.js';
9
9
  import { resolveSamplingPreset, samplingPresets } from './chunk-DPSA4QLA.js';
10
10
  import { propagation, context } from '@opentelemetry/api';
11
11
  import { NodeSDK } from '@opentelemetry/sdk-node';
@@ -643,11 +643,15 @@ function init(cfg) {
643
643
  );
644
644
  }
645
645
  const protocol = resolveProtocol(mergedConfig.protocol);
646
+ const configuredSpanProcessors = mergedConfig.spanProcessors && mergedConfig.spanProcessors.length > 0 ? mergedConfig.spanProcessors : mergedConfig.spanProcessor ? [mergedConfig.spanProcessor] : void 0;
647
+ const configuredSpanExporters = mergedConfig.spanExporters && mergedConfig.spanExporters.length > 0 ? mergedConfig.spanExporters : mergedConfig.spanExporter ? [mergedConfig.spanExporter] : void 0;
648
+ const configuredMetricReaders = mergedConfig.metricReaders && mergedConfig.metricReaders.length > 0 ? mergedConfig.metricReaders : mergedConfig.metricReader ? [mergedConfig.metricReader] : void 0;
649
+ const configuredLogRecordProcessors = mergedConfig.logRecordProcessors && mergedConfig.logRecordProcessors.length > 0 ? mergedConfig.logRecordProcessors : mergedConfig.logRecordProcessor ? [mergedConfig.logRecordProcessor] : void 0;
646
650
  let spanProcessors = [];
647
- if (mergedConfig.spanProcessors && mergedConfig.spanProcessors.length > 0) {
648
- spanProcessors.push(...mergedConfig.spanProcessors);
649
- } else if (mergedConfig.spanExporters && mergedConfig.spanExporters.length > 0) {
650
- for (const exporter of mergedConfig.spanExporters) {
651
+ if (configuredSpanProcessors && configuredSpanProcessors.length > 0) {
652
+ spanProcessors.push(...configuredSpanProcessors);
653
+ } else if (configuredSpanExporters && configuredSpanExporters.length > 0) {
654
+ for (const exporter of configuredSpanExporters) {
651
655
  spanProcessors.push(
652
656
  new TailSamplingSpanProcessor(new BatchSpanProcessor(exporter))
653
657
  );
@@ -718,8 +722,8 @@ function init(cfg) {
718
722
  );
719
723
  }
720
724
  const metricReaders = [];
721
- if (mergedConfig.metricReaders && mergedConfig.metricReaders.length > 0) {
722
- metricReaders.push(...mergedConfig.metricReaders);
725
+ if (configuredMetricReaders && configuredMetricReaders.length > 0) {
726
+ metricReaders.push(...configuredMetricReaders);
723
727
  } else if (metricsEnabled && endpoint) {
724
728
  const metricExporter = createMetricExporter(protocol, {
725
729
  url: formatEndpointUrl(endpoint, "metrics", protocol),
@@ -732,8 +736,8 @@ function init(cfg) {
732
736
  );
733
737
  }
734
738
  let logRecordProcessors;
735
- if (mergedConfig.logRecordProcessors && mergedConfig.logRecordProcessors.length > 0) {
736
- logRecordProcessors = [...mergedConfig.logRecordProcessors];
739
+ if (configuredLogRecordProcessors && configuredLogRecordProcessors.length > 0) {
740
+ logRecordProcessors = [...configuredLogRecordProcessors];
737
741
  }
738
742
  if (logsEnabled && endpoint) {
739
743
  const logExporter = createLogExporter(protocol, {
@@ -835,8 +839,8 @@ function init(cfg) {
835
839
  initOptions.tracerProvider = tracerProvider;
836
840
  } catch {
837
841
  }
838
- if (mergedConfig.spanExporters?.[0]) {
839
- initOptions.exporter = mergedConfig.spanExporters[0];
842
+ if (configuredSpanExporters?.[0]) {
843
+ initOptions.exporter = configuredSpanExporters[0];
840
844
  }
841
845
  if (typeof traceloop.initialize === "function") {
842
846
  traceloop.initialize(initOptions);
@@ -1031,5 +1035,5 @@ function getSdk() {
1031
1035
  }
1032
1036
 
1033
1037
  export { BaggageSpanProcessor, _closeEmbeddedDevtools, createStringRedactor, getConfig, getEventsConfig, getLogger, getSdk, getValidationConfig, init, isInitialized, isLoggerLocked, lockLogger, warnIfNotInitialized };
1034
- //# sourceMappingURL=chunk-ZDPIWKWD.js.map
1035
- //# sourceMappingURL=chunk-ZDPIWKWD.js.map
1038
+ //# sourceMappingURL=chunk-SIMG4IGE.js.map
1039
+ //# sourceMappingURL=chunk-SIMG4IGE.js.map