autotel 4.0.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/README.md +26 -1
  2. package/dist/auto.cjs +2 -2
  3. package/dist/auto.js +1 -1
  4. package/dist/correlation-id.cjs +1 -1
  5. package/dist/correlation-id.js +1 -1
  6. package/dist/decorators.cjs +1 -1
  7. package/dist/decorators.js +1 -1
  8. package/dist/{event-Dlqr4ZNL.cjs → event-BhHREDJk.cjs} +3 -3
  9. package/dist/{event-Dlqr4ZNL.cjs.map → event-BhHREDJk.cjs.map} +1 -1
  10. package/dist/{event-_58ryBjh.js → event-ByBTV9M2.js} +3 -3
  11. package/dist/{event-_58ryBjh.js.map → event-ByBTV9M2.js.map} +1 -1
  12. package/dist/event.cjs +1 -1
  13. package/dist/event.js +1 -1
  14. package/dist/{functional-BGkT8J-h.js → functional-DtI0u4vx.js} +19 -19
  15. package/dist/functional-DtI0u4vx.js.map +1 -0
  16. package/dist/{functional-C4CzoVrX.cjs → functional-zpzNLhky.cjs} +4 -4
  17. package/dist/{functional-C4CzoVrX.cjs.map → functional-zpzNLhky.cjs.map} +1 -1
  18. package/dist/functional.cjs +1 -1
  19. package/dist/functional.js +1 -1
  20. package/dist/http.cjs +1 -1
  21. package/dist/http.js +1 -1
  22. package/dist/index.cjs +5 -5
  23. package/dist/index.d.cts +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.js +5 -5
  26. package/dist/{init-DJQOdVlN.d.ts → init-B7u-DjxM.d.ts} +57 -2
  27. package/dist/init-B7u-DjxM.d.ts.map +1 -0
  28. package/dist/{init-DvapOXCc.cjs → init-BX7AmFRl.cjs} +40 -21
  29. package/dist/init-BX7AmFRl.cjs.map +1 -0
  30. package/dist/{init-Ch6t7MNI.js → init-D-jnNMix.js} +39 -20
  31. package/dist/init-D-jnNMix.js.map +1 -0
  32. package/dist/{init-CNp-ee80.d.cts → init-DSrRmVnz.d.cts} +57 -2
  33. package/dist/init-DSrRmVnz.d.cts.map +1 -0
  34. package/dist/instrumentation.cjs +1 -1
  35. package/dist/instrumentation.js +1 -1
  36. package/dist/logger-D3Ej3DII.js +446 -0
  37. package/dist/logger-D3Ej3DII.js.map +1 -0
  38. package/dist/logger-thMPLpOG.cjs +487 -0
  39. package/dist/logger-thMPLpOG.cjs.map +1 -0
  40. package/dist/logger.cjs +8 -236
  41. package/dist/logger.js +2 -204
  42. package/dist/messaging.cjs +1 -1
  43. package/dist/messaging.js +1 -1
  44. package/dist/semantic-helpers.cjs +1 -1
  45. package/dist/semantic-helpers.js +1 -1
  46. package/dist/{track-3HY4NGV-.cjs → track-D59FfpL0.cjs} +2 -2
  47. package/dist/{track-3HY4NGV-.cjs.map → track-D59FfpL0.cjs.map} +1 -1
  48. package/dist/{track-nsKVy-pj.js → track-wc0HafS_.js} +6 -6
  49. package/dist/track-wc0HafS_.js.map +1 -0
  50. package/dist/webhook.cjs +1 -1
  51. package/dist/webhook.js +1 -1
  52. package/dist/workflow-distributed.cjs +1 -1
  53. package/dist/workflow-distributed.js +1 -1
  54. package/dist/workflow.cjs +1 -1
  55. package/dist/workflow.js +1 -1
  56. package/dist/{yaml-config-B3dQ82GR.cjs → yaml-config-Ck2uB0Dp.cjs} +2 -1
  57. package/dist/yaml-config-Ck2uB0Dp.cjs.map +1 -0
  58. package/dist/yaml-config.cjs +1 -1
  59. package/dist/yaml-config.d.cts +7 -1
  60. package/dist/yaml-config.d.cts.map +1 -1
  61. package/dist/yaml-config.d.ts +7 -1
  62. package/dist/yaml-config.d.ts.map +1 -1
  63. package/dist/yaml-config.js +1 -0
  64. package/dist/yaml-config.js.map +1 -1
  65. package/package.json +1 -2
  66. package/skills/autotel-core/SKILL.md +2 -0
  67. package/skills/autotel-instrumentation/SKILL.md +25 -0
  68. package/skills/debug-missing-spans/SKILL.md +3 -1
  69. package/skills/migrate-to-autotel/SKILL.md +24 -23
  70. package/skills/review-otel-patterns/SKILL.md +5 -4
  71. package/dist/functional-BGkT8J-h.js.map +0 -1
  72. package/dist/init-CNp-ee80.d.cts.map +0 -1
  73. package/dist/init-Ch6t7MNI.js.map +0 -1
  74. package/dist/init-DJQOdVlN.d.ts.map +0 -1
  75. package/dist/init-DvapOXCc.cjs.map +0 -1
  76. package/dist/logger.cjs.map +0 -1
  77. package/dist/logger.js.map +0 -1
  78. package/dist/track-nsKVy-pj.js.map +0 -1
  79. package/dist/yaml-config-B3dQ82GR.cjs.map +0 -1
  80. package/src/attribute-redacting-processor.test.ts +0 -763
  81. package/src/attribute-redacting-processor.ts +0 -621
  82. package/src/attributes/attachers.ts +0 -161
  83. package/src/attributes/builders.ts +0 -529
  84. package/src/attributes/domains.ts +0 -42
  85. package/src/attributes/index.ts +0 -81
  86. package/src/attributes/registry.ts +0 -323
  87. package/src/attributes/types.ts +0 -211
  88. package/src/attributes/utils.ts +0 -64
  89. package/src/attributes/validators.ts +0 -266
  90. package/src/attributes.test.ts +0 -292
  91. package/src/auto.ts +0 -67
  92. package/src/autotel-logger.test.ts +0 -548
  93. package/src/autotel-logger.ts +0 -364
  94. package/src/baggage-span-processor.test.ts +0 -202
  95. package/src/baggage-span-processor.ts +0 -100
  96. package/src/business-baggage.test.ts +0 -500
  97. package/src/business-baggage.ts +0 -669
  98. package/src/circuit-breaker.test.ts +0 -341
  99. package/src/circuit-breaker.ts +0 -184
  100. package/src/config.test.ts +0 -94
  101. package/src/config.ts +0 -172
  102. package/src/correlated-events.test.ts +0 -151
  103. package/src/correlated-events.ts +0 -47
  104. package/src/correlation-id.test.ts +0 -163
  105. package/src/correlation-id.ts +0 -206
  106. package/src/db.test.ts +0 -252
  107. package/src/db.ts +0 -447
  108. package/src/decorators.test.ts +0 -153
  109. package/src/decorators.ts +0 -188
  110. package/src/define-event.test.ts +0 -41
  111. package/src/define-event.ts +0 -58
  112. package/src/devtools.ts +0 -60
  113. package/src/drain-pipeline.test.ts +0 -68
  114. package/src/drain-pipeline.ts +0 -199
  115. package/src/drain-toolkit.test.ts +0 -113
  116. package/src/drain-toolkit.ts +0 -129
  117. package/src/enricher-toolkit.test.ts +0 -67
  118. package/src/enricher-toolkit.ts +0 -79
  119. package/src/enrichers.test.ts +0 -150
  120. package/src/enrichers.ts +0 -145
  121. package/src/env-config.test.ts +0 -323
  122. package/src/env-config.ts +0 -309
  123. package/src/error-catalog.test.ts +0 -133
  124. package/src/error-catalog.ts +0 -262
  125. package/src/event-queue.test.ts +0 -864
  126. package/src/event-queue.ts +0 -699
  127. package/src/event-subscriber.ts +0 -262
  128. package/src/event-testing.ts +0 -197
  129. package/src/event.test.ts +0 -1104
  130. package/src/event.ts +0 -988
  131. package/src/events-config.ts +0 -235
  132. package/src/exporters.ts +0 -165
  133. package/src/filtering-span-processor.test.ts +0 -281
  134. package/src/filtering-span-processor.ts +0 -111
  135. package/src/flatten-attributes.test.ts +0 -76
  136. package/src/flatten-attributes.ts +0 -80
  137. package/src/functional.strict-types.typecheck.ts +0 -53
  138. package/src/functional.test.ts +0 -1464
  139. package/src/functional.ts +0 -2539
  140. package/src/functional.types.test.ts +0 -135
  141. package/src/hook.mjs +0 -15
  142. package/src/http.test.ts +0 -485
  143. package/src/http.ts +0 -424
  144. package/src/index.ts +0 -433
  145. package/src/init-auto-redactor.test.ts +0 -53
  146. package/src/init-redactor.test.ts +0 -8
  147. package/src/init.customization.test.ts +0 -594
  148. package/src/init.integrations.test.ts +0 -399
  149. package/src/init.openllmetry.test.ts +0 -194
  150. package/src/init.protocol.test.ts +0 -215
  151. package/src/init.ts +0 -2312
  152. package/src/instrumentation.test.ts +0 -108
  153. package/src/instrumentation.ts +0 -319
  154. package/src/logger.test.ts +0 -125
  155. package/src/logger.ts +0 -341
  156. package/src/messaging-adapters.test.ts +0 -595
  157. package/src/messaging-adapters.ts +0 -583
  158. package/src/messaging-testing.test.ts +0 -573
  159. package/src/messaging-testing.ts +0 -935
  160. package/src/messaging.test.ts +0 -1646
  161. package/src/messaging.ts +0 -2245
  162. package/src/metric-helpers.ts +0 -47
  163. package/src/metric-testing.ts +0 -197
  164. package/src/metric.ts +0 -446
  165. package/src/metrics.test.ts +0 -241
  166. package/src/node-require.ts +0 -123
  167. package/src/operation-context.ts +0 -93
  168. package/src/parse-error.test.ts +0 -73
  169. package/src/parse-error.ts +0 -112
  170. package/src/posthog-logs.test.ts +0 -115
  171. package/src/posthog-logs.ts +0 -77
  172. package/src/pretty-console-exporter.test.ts +0 -545
  173. package/src/pretty-console-exporter.ts +0 -413
  174. package/src/pretty-log-formatter.test.ts +0 -123
  175. package/src/pretty-log-formatter.ts +0 -210
  176. package/src/processors/canonical-log-line-processor.test.ts +0 -523
  177. package/src/processors/canonical-log-line-processor.ts +0 -396
  178. package/src/processors.ts +0 -152
  179. package/src/rate-limiter.test.ts +0 -199
  180. package/src/rate-limiter.ts +0 -98
  181. package/src/redact-values.test.ts +0 -90
  182. package/src/redact-values.ts +0 -34
  183. package/src/register.ts +0 -37
  184. package/src/request-logger.test.ts +0 -545
  185. package/src/request-logger.ts +0 -342
  186. package/src/sampling.test.ts +0 -1060
  187. package/src/sampling.ts +0 -737
  188. package/src/security-schema.test.ts +0 -45
  189. package/src/security-schema.ts +0 -107
  190. package/src/semantic-conventions.ts +0 -15
  191. package/src/semantic-helpers.test.ts +0 -226
  192. package/src/semantic-helpers.ts +0 -438
  193. package/src/shutdown.test.ts +0 -364
  194. package/src/shutdown.ts +0 -246
  195. package/src/span-name-normalizer.test.ts +0 -377
  196. package/src/span-name-normalizer.ts +0 -213
  197. package/src/stable-hash.ts +0 -27
  198. package/src/structured-error.test.ts +0 -191
  199. package/src/structured-error.ts +0 -157
  200. package/src/stub.integration.test.ts +0 -361
  201. package/src/tail-sampling-processor.test.ts +0 -230
  202. package/src/tail-sampling-processor.ts +0 -55
  203. package/src/test-span-collector.test.ts +0 -234
  204. package/src/test-span-collector.ts +0 -150
  205. package/src/testing.ts +0 -705
  206. package/src/trace-context.test.ts +0 -73
  207. package/src/trace-context.ts +0 -567
  208. package/src/trace-helpers.new.test.ts +0 -278
  209. package/src/trace-helpers.test.ts +0 -290
  210. package/src/trace-helpers.ts +0 -710
  211. package/src/trace-hybrid.test.ts +0 -42
  212. package/src/trace-hybrid.ts +0 -37
  213. package/src/tracer-provider.test.ts +0 -183
  214. package/src/tracer-provider.ts +0 -266
  215. package/src/track.test.ts +0 -154
  216. package/src/track.ts +0 -216
  217. package/src/validate.test.ts +0 -287
  218. package/src/validate.ts +0 -307
  219. package/src/validation-attributes.ts +0 -43
  220. package/src/validation.test.ts +0 -330
  221. package/src/validation.ts +0 -246
  222. package/src/variable-name-inference.test.ts +0 -178
  223. package/src/variable-name-inference.ts +0 -242
  224. package/src/webhook.test.ts +0 -649
  225. package/src/webhook.ts +0 -637
  226. package/src/workflow-distributed.test.ts +0 -786
  227. package/src/workflow-distributed.ts +0 -916
  228. package/src/workflow.async-safety.integration.test.ts +0 -345
  229. package/src/workflow.test.ts +0 -647
  230. package/src/workflow.ts +0 -810
  231. package/src/yaml-config.test.ts +0 -337
  232. package/src/yaml-config.ts +0 -342
@@ -1,262 +0,0 @@
1
- /**
2
- * Event Subscriber Interface (Type-only)
3
- *
4
- * Import this interface to create custom subscribers without importing implementations.
5
- * Keeps core package focused on OpenTelemetry with zero extra dependencies.
6
- *
7
- * For ready-made subscribers (PostHog, Mixpanel, Amplitude, Segment),
8
- * see the separate `autotel-subscribers` package.
9
- *
10
- * @example Custom subscriber
11
- * ```typescript
12
- * import { EventSubscriber } from 'autotel/event-subscriber';
13
- *
14
- * class MyCustomSubscriber implements EventSubscriber {
15
- * trackEvent(name: string, attributes?: Record<string, any>): void {
16
- * // Send to your events platform
17
- * }
18
- * // ... implement other methods
19
- * }
20
- * ```
21
- *
22
- * @example Use pre-built subscribers
23
- * ```typescript
24
- * import { Events } from 'autotel/events';
25
- * import { PostHogSubscriber } from 'autotel-subscribers/posthog';
26
- * import { MixpanelSubscriber } from 'autotel-subscribers/mixpanel';
27
- *
28
- * const event =new Event('checkout', {
29
- * subscribers: [
30
- * new PostHogSubscriber({ apiKey: 'phc_...' }),
31
- * new MixpanelSubscriber({ token: '...' })
32
- * ]
33
- * });
34
- * ```
35
- */
36
-
37
- /**
38
- * Event attributes (supports any JSON-serializable values)
39
- *
40
- * Allows primitive types for flat attributes and unknown for flexibility
41
- * with nested objects when using subscribers that support JSON payloads
42
- * (e.g., WebhookSubscriber).
43
- */
44
- export type EventAttributes = Record<string, unknown>;
45
-
46
- /**
47
- * Permissive input type for event attributes
48
- *
49
- * Accepts undefined/null values which will be filtered out before sending.
50
- * This improves DX when working with optional properties from objects.
51
- *
52
- * @example
53
- * ```typescript
54
- * // No need to filter out undefined values manually
55
- * event.trackEvent('user.action', {
56
- * userId: user.id,
57
- * email: user.email, // might be undefined
58
- * plan: user.subscription, // might be null
59
- * });
60
- * ```
61
- */
62
- export type EventAttributesInput = Record<
63
- string,
64
- string | number | boolean | undefined | null
65
- >;
66
-
67
- /**
68
- * Funnel step status
69
- */
70
- export type FunnelStatus = 'started' | 'completed' | 'abandoned' | 'failed';
71
-
72
- /**
73
- * Outcome status
74
- */
75
- export type OutcomeStatus = 'success' | 'failure' | 'partial';
76
-
77
- /**
78
- * Autotel event context for trace correlation
79
- *
80
- * This structured object contains trace context and correlation IDs.
81
- * Subscribers decide how to map/flatten these for their platform.
82
- */
83
- export interface AutotelEventContext {
84
- /** Trace ID (32 hex chars) - present when inside a trace */
85
- trace_id?: string;
86
- /** Span ID (16 hex chars) - present when inside a span */
87
- span_id?: string;
88
- /** Trace flags (2 hex chars, e.g., '01' for sampled) */
89
- trace_flags?: string;
90
- /** Raw tracestate string - present if tracestate exists */
91
- trace_state?: string;
92
- /** Clickable trace URL - present if traceUrl config is set */
93
- trace_url?: string;
94
- /** Correlation ID (always present, 16 hex chars) */
95
- correlation_id: string;
96
- /** Number of linked parent traces (batch/fan-in scenarios) */
97
- linked_trace_id_count?: number;
98
- /** Stable hash of linked trace IDs (default for batch/fan-in) */
99
- linked_trace_id_hash?: string;
100
- /** Full array of linked trace IDs (only if includeLinkedTraceIds: true) */
101
- linked_trace_ids?: string[];
102
- }
103
-
104
- /**
105
- * Optional machine-readable schema metadata attached to an event payload.
106
- * Intended for contract-aware subscribers (e.g. architecture snapshot capture).
107
- */
108
- export interface EventSchemaMetadata {
109
- /** Schema source format used at the call site. */
110
- source: 'zod';
111
- /** JSON Schema representation of the payload contract. */
112
- jsonSchema: unknown;
113
- /** Stable schema hash for change detection and cache keys. */
114
- hash: string;
115
- }
116
-
117
- /**
118
- * Options for event tracking methods
119
- */
120
- export interface EventTrackingOptions {
121
- /** Autotel trace context to include in the event */
122
- autotel?: AutotelEventContext;
123
- /** Optional event payload schema metadata */
124
- schema?: EventSchemaMetadata;
125
- }
126
-
127
- /**
128
- * Event subscriber interface
129
- *
130
- * Implement this to send events to any platform.
131
- * Zero runtime dependencies - just types.
132
- *
133
- * All tracking methods are async to support:
134
- * - Backpressure signaling (buffer full)
135
- * - Streaming platforms (Kafka, Kinesis, Pub/Sub)
136
- * - Await delivery confirmation
137
- * - Proper error propagation
138
- */
139
- export interface EventSubscriber {
140
- /**
141
- * Track an event (e.g., "user.registered", "order.created")
142
- *
143
- * @param name - Event name
144
- * @param attributes - Optional event attributes
145
- * @param options - Optional tracking options including autotel context
146
- * @returns Promise that resolves when event is sent (or buffered)
147
- */
148
- trackEvent(
149
- name: string,
150
- attributes?: EventAttributes,
151
- options?: EventTrackingOptions,
152
- ): Promise<void>;
153
-
154
- /**
155
- * Track a funnel step (e.g., checkout: started → completed)
156
- *
157
- * @param funnelName - Funnel name
158
- * @param step - Funnel step status
159
- * @param attributes - Optional event attributes
160
- * @param options - Optional tracking options including autotel context
161
- * @returns Promise that resolves when event is sent (or buffered)
162
- */
163
- trackFunnelStep(
164
- funnelName: string,
165
- step: FunnelStatus,
166
- attributes?: EventAttributes,
167
- options?: EventTrackingOptions,
168
- ): Promise<void>;
169
-
170
- /**
171
- * Track an outcome (e.g., "payment.processing" → success/failure)
172
- *
173
- * @param operationName - Operation name
174
- * @param outcome - Outcome status
175
- * @param attributes - Optional event attributes
176
- * @param options - Optional tracking options including autotel context
177
- * @returns Promise that resolves when event is sent (or buffered)
178
- */
179
- trackOutcome(
180
- operationName: string,
181
- outcome: OutcomeStatus,
182
- attributes?: EventAttributes,
183
- options?: EventTrackingOptions,
184
- ): Promise<void>;
185
-
186
- /**
187
- * Track a value/metric (e.g., revenue, cart value)
188
- *
189
- * @param name - Metric name
190
- * @param value - Numeric value
191
- * @param attributes - Optional event attributes
192
- * @param options - Optional tracking options including autotel context
193
- * @returns Promise that resolves when event is sent (or buffered)
194
- */
195
- trackValue(
196
- name: string,
197
- value: number,
198
- attributes?: EventAttributes,
199
- options?: EventTrackingOptions,
200
- ): Promise<void>;
201
-
202
- /**
203
- * Track funnel progression with custom step names
204
- *
205
- * Unlike trackFunnelStep which uses FunnelStatus enum values,
206
- * this method allows any string as the step name for flexible funnel tracking.
207
- *
208
- * @param funnelName - Name of the funnel (e.g., "checkout", "onboarding")
209
- * @param stepName - Custom step name (e.g., "cart_viewed", "payment_entered")
210
- * @param stepNumber - Optional numeric position in the funnel
211
- * @param attributes - Optional event attributes
212
- * @param options - Optional tracking options including autotel context
213
- *
214
- * @example
215
- * ```typescript
216
- * // Track custom checkout steps
217
- * await subscriber.trackFunnelProgression('checkout', 'cart_viewed', 1);
218
- * await subscriber.trackFunnelProgression('checkout', 'shipping_selected', 2);
219
- * await subscriber.trackFunnelProgression('checkout', 'payment_entered', 3);
220
- * await subscriber.trackFunnelProgression('checkout', 'order_confirmed', 4);
221
- * ```
222
- */
223
- trackFunnelProgression?(
224
- funnelName: string,
225
- stepName: string,
226
- stepNumber?: number,
227
- attributes?: EventAttributes,
228
- options?: EventTrackingOptions,
229
- ): Promise<void>;
230
-
231
- /**
232
- * Optional: Flush pending events and clean up resources
233
- *
234
- * Implement this if your subscriber buffers events, maintains connections,
235
- * or needs cleanup before shutdown. Called during graceful shutdown.
236
- *
237
- * @example
238
- * ```typescript
239
- * class MySubscriber implements EventSubscriber {
240
- * async shutdown(): Promise<void> {
241
- * await this.flushBuffer();
242
- * await this.closeConnections();
243
- * }
244
- * }
245
- * ```
246
- */
247
- shutdown?(): Promise<void>;
248
-
249
- /**
250
- * Optional: Subscriber name for debugging and error reporting
251
- *
252
- * @example "PostHogSubscriber", "SnowflakeSubscriber", "CustomWebhookSubscriber"
253
- */
254
- readonly name?: string;
255
-
256
- /**
257
- * Optional: Subscriber version for debugging
258
- *
259
- * @example "1.0.0"
260
- */
261
- readonly version?: string;
262
- }
@@ -1,197 +0,0 @@
1
- /**
2
- * Testing utilities for Events
3
- *
4
- * Provides in-memory collection of events for testing purposes.
5
- */
6
-
7
- import type {
8
- EventAttributes,
9
- FunnelStatus,
10
- OutcomeStatus,
11
- } from './event-subscriber';
12
-
13
- export interface EventData {
14
- event: string;
15
- attributes?: EventAttributes;
16
- service: string;
17
- timestamp: number;
18
- }
19
-
20
- export interface EventsFunnelStep {
21
- funnel: string;
22
- status: FunnelStatus;
23
- attributes?: EventAttributes;
24
- service: string;
25
- timestamp: number;
26
- }
27
-
28
- export interface EventsOutcome {
29
- operation: string;
30
- status: OutcomeStatus;
31
- attributes?: EventAttributes;
32
- service: string;
33
- timestamp: number;
34
- }
35
-
36
- export interface EventsValue {
37
- metric: string;
38
- value: number;
39
- attributes?: EventAttributes;
40
- service: string;
41
- timestamp: number;
42
- }
43
-
44
- /**
45
- * In-memory events collector for testing
46
- */
47
- export interface EventCollector {
48
- /** Get all collected events */
49
- getEvents(): EventData[];
50
- /** Get all collected funnel steps */
51
- getFunnelSteps(): EventsFunnelStep[];
52
- /** Get all collected outcomes */
53
- getOutcomes(): EventsOutcome[];
54
- /** Get all collected values */
55
- getValues(): EventsValue[];
56
- /** Clear all collected events */
57
- clear(): void;
58
- /** Record an event (internal use) */
59
- recordEvent(event: EventData): void;
60
- /** Record a funnel step (internal use) */
61
- recordFunnelStep(step: EventsFunnelStep): void;
62
- /** Record an outcome (internal use) */
63
- recordOutcome(outcome: EventsOutcome): void;
64
- /** Record a value (internal use) */
65
- recordValue(value: EventsValue): void;
66
- }
67
-
68
- /**
69
- * Create an in-memory events collector for testing
70
- *
71
- * @example
72
- * ```typescript
73
- * const collector = createEventCollector()
74
- *
75
- * const events = new Event('test-service', { collector })
76
- * events.trackEvent('application.submitted', { jobId: '123' })
77
- *
78
- * const event =collector.getEvents()
79
- * expect(events).toHaveLength(1)
80
- * expect(events[0].event).toBe('application.submitted')
81
- * ```
82
- */
83
- export function createEventCollector(): EventCollector {
84
- const events: EventData[] = [];
85
- const funnelSteps: EventsFunnelStep[] = [];
86
- const outcomes: EventsOutcome[] = [];
87
- const values: EventsValue[] = [];
88
-
89
- return {
90
- getEvents(): EventData[] {
91
- return [...events];
92
- },
93
-
94
- getFunnelSteps(): EventsFunnelStep[] {
95
- return [...funnelSteps];
96
- },
97
-
98
- getOutcomes(): EventsOutcome[] {
99
- return [...outcomes];
100
- },
101
-
102
- getValues(): EventsValue[] {
103
- return [...values];
104
- },
105
-
106
- clear(): void {
107
- events.length = 0;
108
- funnelSteps.length = 0;
109
- outcomes.length = 0;
110
- values.length = 0;
111
- },
112
-
113
- recordEvent(event: EventData): void {
114
- events.push(event);
115
- },
116
-
117
- recordFunnelStep(step: EventsFunnelStep): void {
118
- funnelSteps.push(step);
119
- },
120
-
121
- recordOutcome(outcome: EventsOutcome): void {
122
- outcomes.push(outcome);
123
- },
124
-
125
- recordValue(value: EventsValue): void {
126
- values.push(value);
127
- },
128
- };
129
- }
130
-
131
- /**
132
- * Assert that an events event was tracked
133
- *
134
- * @example
135
- * ```typescript
136
- * assertEventTracked({
137
- * collector,
138
- * eventName: 'application.submitted',
139
- * attributes: { jobId: '123' }
140
- * })
141
- * ```
142
- */
143
- export function assertEventTracked(options: {
144
- collector: EventCollector;
145
- eventName: string;
146
- attributes?: Record<string, unknown>;
147
- }): void {
148
- const events = options.collector.getEvents();
149
- const matching = events.filter((e) => e.event === options.eventName);
150
-
151
- if (matching.length === 0) {
152
- throw new Error(`No events found with name: ${options.eventName}`);
153
- }
154
-
155
- if (options.attributes) {
156
- const matchingWithAttrs = matching.filter((e) =>
157
- Object.entries(options.attributes!).every(
158
- ([key, value]) => e.attributes && e.attributes[key] === value,
159
- ),
160
- );
161
-
162
- if (matchingWithAttrs.length === 0) {
163
- throw new Error(
164
- `Event ${options.eventName} found but attributes don't match: ${JSON.stringify(options.attributes)}`,
165
- );
166
- }
167
- }
168
- }
169
-
170
- /**
171
- * Assert that an outcome was tracked
172
- *
173
- * @example
174
- * ```typescript
175
- * assertOutcomeTracked({
176
- * collector,
177
- * operation: 'email.delivery',
178
- * status: 'success'
179
- * })
180
- * ```
181
- */
182
- export function assertOutcomeTracked(options: {
183
- collector: EventCollector;
184
- operation: string;
185
- status: 'success' | 'failure' | 'partial';
186
- }): void {
187
- const outcomes = options.collector.getOutcomes();
188
- const matching = outcomes.filter(
189
- (o) => o.operation === options.operation && o.status === options.status,
190
- );
191
-
192
- if (matching.length === 0) {
193
- throw new Error(
194
- `No outcomes found with operation: ${options.operation} and status: ${options.status}`,
195
- );
196
- }
197
- }