@zdavison/matador 4.0.3 → 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 (71) hide show
  1. package/dist/core/matador.d.ts.map +1 -1
  2. package/dist/core/matador.js +4 -1
  3. package/dist/index.cjs +156 -16
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/pipeline/pipeline.d.ts +30 -2
  7. package/dist/pipeline/pipeline.d.ts.map +1 -1
  8. package/dist/pipeline/pipeline.js +65 -9
  9. package/dist/retry/index.d.ts +1 -1
  10. package/dist/retry/index.d.ts.map +1 -1
  11. package/dist/retry/policy.d.ts +27 -0
  12. package/dist/retry/policy.d.ts.map +1 -1
  13. package/dist/retry/standard-policy.d.ts +33 -2
  14. package/dist/retry/standard-policy.d.ts.map +1 -1
  15. package/dist/retry/standard-policy.js +73 -9
  16. package/dist/topology/types.d.ts +14 -0
  17. package/dist/topology/types.d.ts.map +1 -1
  18. package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -1
  19. package/dist/transport/rabbitmq/rabbitmq-transport.js +3 -0
  20. package/package.json +1 -1
  21. package/dist/checkpoint/context.test.d.ts +0 -2
  22. package/dist/checkpoint/context.test.d.ts.map +0 -1
  23. package/dist/checkpoint/context.test.js +0 -428
  24. package/dist/checkpoint/stores/stores.test.d.ts +0 -2
  25. package/dist/checkpoint/stores/stores.test.d.ts.map +0 -1
  26. package/dist/checkpoint/stores/stores.test.js +0 -146
  27. package/dist/codec/rabbitmq-codec.test.d.ts +0 -2
  28. package/dist/codec/rabbitmq-codec.test.d.ts.map +0 -1
  29. package/dist/codec/rabbitmq-codec.test.js +0 -428
  30. package/dist/core/fanout.test.d.ts +0 -2
  31. package/dist/core/fanout.test.d.ts.map +0 -1
  32. package/dist/core/fanout.test.js +0 -1970
  33. package/dist/core/matador.test.d.ts +0 -2
  34. package/dist/core/matador.test.d.ts.map +0 -1
  35. package/dist/core/matador.test.js +0 -813
  36. package/dist/core/shutdown.test.d.ts +0 -2
  37. package/dist/core/shutdown.test.d.ts.map +0 -1
  38. package/dist/core/shutdown.test.js +0 -599
  39. package/dist/errors/retry-errors.test.d.ts +0 -2
  40. package/dist/errors/retry-errors.test.d.ts.map +0 -1
  41. package/dist/errors/retry-errors.test.js +0 -136
  42. package/dist/pipeline/pipeline.test.d.ts +0 -2
  43. package/dist/pipeline/pipeline.test.d.ts.map +0 -1
  44. package/dist/pipeline/pipeline.test.js +0 -1124
  45. package/dist/retry/standard-policy.test.d.ts +0 -2
  46. package/dist/retry/standard-policy.test.d.ts.map +0 -1
  47. package/dist/retry/standard-policy.test.js +0 -196
  48. package/dist/schema/registry.test.d.ts +0 -2
  49. package/dist/schema/registry.test.d.ts.map +0 -1
  50. package/dist/schema/registry.test.js +0 -278
  51. package/dist/schema/types.test.d.ts +0 -2
  52. package/dist/schema/types.test.d.ts.map +0 -1
  53. package/dist/schema/types.test.js +0 -246
  54. package/dist/topology/builder.test.d.ts +0 -2
  55. package/dist/topology/builder.test.d.ts.map +0 -1
  56. package/dist/topology/builder.test.js +0 -547
  57. package/dist/transport/local/local-transport.test.d.ts +0 -2
  58. package/dist/transport/local/local-transport.test.d.ts.map +0 -1
  59. package/dist/transport/local/local-transport.test.js +0 -232
  60. package/dist/transport/multi/multi-transport.test.d.ts +0 -2
  61. package/dist/transport/multi/multi-transport.test.d.ts.map +0 -1
  62. package/dist/transport/multi/multi-transport.test.js +0 -322
  63. package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.d.ts +0 -2
  64. package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.d.ts.map +0 -1
  65. package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.js +0 -149
  66. package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts +0 -2
  67. package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts.map +0 -1
  68. package/dist/transport/rabbitmq/rabbitmq-transport.test.js +0 -230
  69. package/dist/types/event.test.d.ts +0 -2
  70. package/dist/types/event.test.d.ts.map +0 -1
  71. package/dist/types/event.test.js +0 -130
@@ -1,428 +0,0 @@
1
- import { describe, expect, it } from 'bun:test';
2
- import { RabbitMQCodec } from './rabbitmq-codec.js';
3
- /**
4
- * Add your v1 message examples here.
5
- * Each fixture describes:
6
- * - name: A descriptive name for the test case
7
- * - body: The v1 message body (what goes in the RabbitMQ message content)
8
- * - headers: Optional RabbitMQ headers that accompany the message
9
- * - expected: The expected v2 envelope fields after translation
10
- */
11
- const V1_MESSAGE_FIXTURES = [
12
- // === BASIC EXAMPLES ===
13
- {
14
- name: 'minimal v1 message with only required fields',
15
- body: {
16
- key: 'user.created',
17
- data: { userId: '123' },
18
- targetSubscriber: 'email-service',
19
- },
20
- expected: {
21
- eventKey: 'user.created',
22
- targetSubscriber: 'email-service',
23
- data: { userId: '123' },
24
- attempts: 1,
25
- importance: 'should-investigate',
26
- },
27
- },
28
- {
29
- name: 'v1 message with metadata',
30
- body: {
31
- key: 'order.placed',
32
- data: { orderId: 'ORD-456', amount: 99.99 },
33
- metadata: { source: 'web', region: 'us-east' },
34
- targetSubscriber: 'fulfillment-service',
35
- },
36
- expected: {
37
- eventKey: 'order.placed',
38
- targetSubscriber: 'fulfillment-service',
39
- data: { orderId: 'ORD-456', amount: 99.99 },
40
- metadata: { source: 'web', region: 'us-east' },
41
- },
42
- },
43
- // === UNIVERSAL METADATA EXAMPLES ===
44
- {
45
- name: 'v1 message with universal.event_id',
46
- body: {
47
- key: 'payment.processed',
48
- data: { paymentId: 'PAY-789' },
49
- universal: {
50
- event_id: 'evt-abc-123',
51
- },
52
- targetSubscriber: 'notification-service',
53
- },
54
- expected: {
55
- id: 'evt-abc-123',
56
- eventKey: 'payment.processed',
57
- targetSubscriber: 'notification-service',
58
- data: { paymentId: 'PAY-789' },
59
- },
60
- },
61
- {
62
- name: 'v1 message with universal.user_id (merged into metadata)',
63
- body: {
64
- key: 'profile.updated',
65
- data: { field: 'email' },
66
- universal: {
67
- user_id: 'user-456',
68
- },
69
- targetSubscriber: 'audit-service',
70
- },
71
- expected: {
72
- eventKey: 'profile.updated',
73
- targetSubscriber: 'audit-service',
74
- data: { field: 'email' },
75
- metadata: { user_id: 'user-456' },
76
- },
77
- },
78
- {
79
- name: 'v1 message with universal.correlation_id',
80
- body: {
81
- key: 'request.received',
82
- data: { requestId: 'req-001' },
83
- universal: {
84
- correlation_id: 'corr-xyz-789',
85
- },
86
- targetSubscriber: 'logger-service',
87
- },
88
- expected: {
89
- eventKey: 'request.received',
90
- targetSubscriber: 'logger-service',
91
- data: { requestId: 'req-001' },
92
- correlationId: 'corr-xyz-789',
93
- },
94
- },
95
- {
96
- name: 'v1 message with all universal fields',
97
- body: {
98
- key: 'checkout.completed',
99
- data: { cartId: 'cart-999' },
100
- universal: {
101
- event_id: 'evt-full-123',
102
- user_id: 'user-777',
103
- correlation_id: 'corr-full-456',
104
- custom_field: 'custom_value',
105
- },
106
- targetSubscriber: 'analytics-service',
107
- },
108
- expected: {
109
- id: 'evt-full-123',
110
- eventKey: 'checkout.completed',
111
- targetSubscriber: 'analytics-service',
112
- data: { cartId: 'cart-999' },
113
- correlationId: 'corr-full-456',
114
- metadata: {
115
- user_id: 'user-777',
116
- custom_field: 'custom_value',
117
- },
118
- },
119
- },
120
- // === METADATA MERGING EXAMPLES ===
121
- {
122
- name: 'v1 message with both metadata and universal (merged)',
123
- body: {
124
- key: 'item.added',
125
- data: { itemId: 'item-123' },
126
- metadata: { category: 'electronics', priority: 'high' },
127
- universal: {
128
- user_id: 'user-888',
129
- tenant_id: 'tenant-001',
130
- },
131
- targetSubscriber: 'inventory-service',
132
- },
133
- expected: {
134
- eventKey: 'item.added',
135
- targetSubscriber: 'inventory-service',
136
- data: { itemId: 'item-123' },
137
- metadata: {
138
- category: 'electronics',
139
- priority: 'high',
140
- user_id: 'user-888',
141
- tenant_id: 'tenant-001',
142
- },
143
- },
144
- },
145
- // === HEADER-BASED EXAMPLES ===
146
- {
147
- name: 'v1 message with attempt count from header',
148
- body: {
149
- key: 'task.retry',
150
- data: { taskId: 'task-555' },
151
- targetSubscriber: 'worker-service',
152
- },
153
- headers: {
154
- 'x-matador-attempts': 3,
155
- },
156
- expected: {
157
- eventKey: 'task.retry',
158
- targetSubscriber: 'worker-service',
159
- data: { taskId: 'task-555' },
160
- attempts: 3,
161
- },
162
- },
163
- {
164
- name: 'v1 message with importance from header',
165
- body: {
166
- key: 'alert.triggered',
167
- data: { alertId: 'alert-111' },
168
- targetSubscriber: 'pager-service',
169
- },
170
- headers: {
171
- 'x-matador-importance': 'must-investigate',
172
- },
173
- expected: {
174
- eventKey: 'alert.triggered',
175
- targetSubscriber: 'pager-service',
176
- data: { alertId: 'alert-111' },
177
- importance: 'must-investigate',
178
- },
179
- },
180
- {
181
- name: 'v1 message with correlation_id from v1 header',
182
- body: {
183
- key: 'trace.event',
184
- data: { traceId: 'trace-222' },
185
- targetSubscriber: 'tracing-service',
186
- },
187
- headers: {
188
- 'x-correlation-id': 'header-corr-id',
189
- },
190
- expected: {
191
- eventKey: 'trace.event',
192
- targetSubscriber: 'tracing-service',
193
- data: { traceId: 'trace-222' },
194
- correlationId: 'header-corr-id',
195
- },
196
- },
197
- {
198
- name: 'v1 message with event_id from v1 header',
199
- body: {
200
- key: 'legacy.event',
201
- data: { legacyId: 'leg-333' },
202
- targetSubscriber: 'legacy-handler',
203
- },
204
- headers: {
205
- 'x-event-id': 'header-event-id-456',
206
- },
207
- expected: {
208
- id: 'header-event-id-456',
209
- eventKey: 'legacy.event',
210
- targetSubscriber: 'legacy-handler',
211
- data: { legacyId: 'leg-333' },
212
- },
213
- },
214
- // === EDGE CASES ===
215
- {
216
- name: 'v1 message with null universal fields (ignored)',
217
- body: {
218
- key: 'null.test',
219
- data: { test: true },
220
- universal: {
221
- event_id: null,
222
- user_id: null,
223
- correlation_id: null,
224
- },
225
- targetSubscriber: 'null-handler',
226
- },
227
- expected: {
228
- eventKey: 'null.test',
229
- targetSubscriber: 'null-handler',
230
- data: { test: true },
231
- },
232
- },
233
- {
234
- name: 'v1 message with empty metadata object',
235
- body: {
236
- key: 'empty.metadata',
237
- data: { value: 42 },
238
- metadata: {},
239
- targetSubscriber: 'empty-handler',
240
- },
241
- expected: {
242
- eventKey: 'empty.metadata',
243
- targetSubscriber: 'empty-handler',
244
- data: { value: 42 },
245
- },
246
- },
247
- {
248
- name: 'v1 message with complex nested data',
249
- body: {
250
- key: 'complex.event',
251
- data: {
252
- nested: {
253
- deeply: {
254
- value: [1, 2, { three: 'four' }],
255
- },
256
- },
257
- array: ['a', 'b', 'c'],
258
- },
259
- targetSubscriber: 'complex-handler',
260
- },
261
- expected: {
262
- eventKey: 'complex.event',
263
- targetSubscriber: 'complex-handler',
264
- data: {
265
- nested: {
266
- deeply: {
267
- value: [1, 2, { three: 'four' }],
268
- },
269
- },
270
- array: ['a', 'b', 'c'],
271
- },
272
- },
273
- },
274
- {
275
- name: 'v1 message with before field (ignored in v2)',
276
- body: {
277
- key: 'update.event',
278
- data: { newValue: 'after' },
279
- before: { oldValue: 'before' },
280
- targetSubscriber: 'update-handler',
281
- },
282
- expected: {
283
- eventKey: 'update.event',
284
- targetSubscriber: 'update-handler',
285
- data: { newValue: 'after' },
286
- },
287
- },
288
- // === ADD YOUR EXAMPLES BELOW ===
289
- // Copy this template and fill in your v1 message data:
290
- //
291
- // {
292
- // name: 'descriptive name for your test case',
293
- // body: {
294
- // key: 'your.event.key',
295
- // data: { /* your event data */ },
296
- // metadata: { /* optional metadata */ },
297
- // universal: {
298
- // event_id: 'optional-event-id',
299
- // user_id: 'optional-user-id',
300
- // correlation_id: 'optional-correlation-id',
301
- // // any other custom fields
302
- // },
303
- // before: { /* optional, will be ignored */ },
304
- // options: { delayMs: 1000 }, // optional
305
- // targetSubscriber: 'your-subscriber-name',
306
- // },
307
- // headers: {
308
- // // optional headers
309
- // 'x-matador-attempts': 1,
310
- // 'x-matador-importance': 'should-investigate',
311
- // 'x-event-id': 'header-event-id',
312
- // 'x-correlation-id': 'header-correlation-id',
313
- // },
314
- // expected: {
315
- // id: 'expected-id', // optional, will be generated if not in body/headers
316
- // eventKey: 'your.event.key',
317
- // targetSubscriber: 'your-subscriber-name',
318
- // data: { /* expected data */ },
319
- // metadata: { /* expected merged metadata */ },
320
- // correlationId: 'expected-correlation-id',
321
- // attempts: 1,
322
- // importance: 'should-investigate',
323
- // },
324
- // },
325
- ];
326
- const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
327
- const ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/;
328
- function assertV1Id(envelope, expectedId) {
329
- if (expectedId !== undefined) {
330
- expect(envelope.id).toBe(expectedId);
331
- }
332
- else {
333
- expect(envelope.id).toMatch(UUID_PATTERN);
334
- }
335
- }
336
- function assertV1Metadata(metadata, expected) {
337
- if (expected !== undefined) {
338
- expect(metadata).toEqual(expected);
339
- }
340
- else {
341
- expect(metadata === undefined || Object.keys(metadata).length === 0).toBe(true);
342
- }
343
- }
344
- function assertV1Translation(envelope, expected) {
345
- expect(envelope.docket.eventKey).toBe(expected.eventKey);
346
- expect(envelope.docket.targetSubscriber).toBe(expected.targetSubscriber);
347
- expect(envelope.data).toEqual(expected.data);
348
- assertV1Id(envelope, expected.id);
349
- assertV1Metadata(envelope.docket.metadata, expected.metadata);
350
- if (expected.correlationId !== undefined) {
351
- expect(envelope.docket.correlationId).toBe(expected.correlationId);
352
- }
353
- expect(envelope.docket.attempts).toBe(expected.attempts ?? 1);
354
- expect(envelope.docket.importance).toBe(expected.importance ?? 'should-investigate');
355
- expect(envelope.docket.createdAt).toMatch(ISO_DATE_PATTERN);
356
- }
357
- describe('RabbitMQCodec', () => {
358
- const codec = new RabbitMQCodec();
359
- describe('v1 to v2 translation', () => {
360
- for (const fixture of V1_MESSAGE_FIXTURES) {
361
- it(`should translate: ${fixture.name}`, () => {
362
- const body = new TextEncoder().encode(JSON.stringify(fixture.body));
363
- const headers = fixture.headers ?? {};
364
- const envelope = codec.decode(body, headers);
365
- assertV1Translation(envelope, fixture.expected);
366
- });
367
- }
368
- });
369
- describe('v1 edge cases', () => {
370
- it('should handle options.delayMs by setting scheduledFor', () => {
371
- const body = {
372
- key: 'delayed.event',
373
- data: { test: true },
374
- options: { delayMs: 5000 },
375
- targetSubscriber: 'delay-handler',
376
- };
377
- const encoded = new TextEncoder().encode(JSON.stringify(body));
378
- const before = Date.now();
379
- const envelope = codec.decode(encoded, {});
380
- const after = Date.now();
381
- const { scheduledFor } = envelope.docket;
382
- if (!scheduledFor)
383
- throw new Error('expected scheduledFor to be set');
384
- const scheduledTime = new Date(scheduledFor).getTime();
385
- expect(scheduledTime).toBeGreaterThanOrEqual(before + 5000);
386
- expect(scheduledTime).toBeLessThanOrEqual(after + 5000);
387
- });
388
- it('should prefer header event_id over body universal.event_id', () => {
389
- const body = {
390
- key: 'priority.test',
391
- data: {},
392
- universal: { event_id: 'body-event-id' },
393
- targetSubscriber: 'test-handler',
394
- };
395
- const encoded = new TextEncoder().encode(JSON.stringify(body));
396
- const envelope = codec.decode(encoded, {
397
- 'x-event-id': 'header-event-id',
398
- });
399
- expect(envelope.id).toBe('header-event-id');
400
- });
401
- it('should prefer v2 correlation header over v1 header', () => {
402
- const body = {
403
- key: 'corr.priority',
404
- data: {},
405
- targetSubscriber: 'test-handler',
406
- };
407
- const encoded = new TextEncoder().encode(JSON.stringify(body));
408
- const envelope = codec.decode(encoded, {
409
- 'x-matador-correlation-id': 'v2-corr-id',
410
- 'x-correlation-id': 'v1-corr-id',
411
- });
412
- expect(envelope.docket.correlationId).toBe('v2-corr-id');
413
- });
414
- it('should prefer header correlation_id over body universal.correlation_id', () => {
415
- const body = {
416
- key: 'corr.priority',
417
- data: {},
418
- universal: { correlation_id: 'body-corr-id' },
419
- targetSubscriber: 'test-handler',
420
- };
421
- const encoded = new TextEncoder().encode(JSON.stringify(body));
422
- const envelope = codec.decode(encoded, {
423
- 'x-correlation-id': 'header-corr-id',
424
- });
425
- expect(envelope.docket.correlationId).toBe('header-corr-id');
426
- });
427
- });
428
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=fanout.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fanout.test.d.ts","sourceRoot":"","sources":["../../src/core/fanout.test.ts"],"names":[],"mappings":""}