@zdavison/matador 2.0.4 → 2.0.6

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 (45) hide show
  1. package/dist/core/fanout.test.js +0 -1
  2. package/dist/errors/index.d.ts +1 -1
  3. package/dist/errors/index.d.ts.map +1 -1
  4. package/dist/errors/index.js +1 -1
  5. package/dist/errors/retry-errors.d.ts +40 -5
  6. package/dist/errors/retry-errors.d.ts.map +1 -1
  7. package/dist/errors/retry-errors.js +56 -9
  8. package/dist/errors/retry-errors.test.d.ts +2 -0
  9. package/dist/errors/retry-errors.test.d.ts.map +1 -0
  10. package/dist/errors/retry-errors.test.js +136 -0
  11. package/dist/index.cjs +29 -7
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +2 -2
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/pipeline/pipeline.test.js +33 -0
  19. package/dist/retry/standard-policy.test.js +7 -1
  20. package/dist/schema/registry.d.ts.map +1 -1
  21. package/dist/schema/registry.js +4 -1
  22. package/dist/schema/types.test.js +0 -1
  23. package/dist/types/envelope.d.ts +12 -0
  24. package/dist/types/envelope.d.ts.map +1 -1
  25. package/dist/types/envelope.js +19 -0
  26. package/dist/types/index.d.ts +1 -1
  27. package/dist/types/index.d.ts.map +1 -1
  28. package/dist/types/index.js +1 -1
  29. package/dist/types/subscriber.d.ts +10 -6
  30. package/dist/types/subscriber.d.ts.map +1 -1
  31. package/dist/types/subscriber.js +0 -2
  32. package/package.json +1 -1
  33. package/src/core/fanout.test.ts +0 -1
  34. package/src/errors/index.ts +1 -0
  35. package/src/errors/retry-errors.test.ts +175 -0
  36. package/src/errors/retry-errors.ts +63 -9
  37. package/src/index.ts +2 -0
  38. package/src/pipeline/pipeline.test.ts +38 -0
  39. package/src/retry/standard-policy.test.ts +9 -1
  40. package/src/schema/registry.ts +4 -1
  41. package/src/schema/types.test.ts +0 -1
  42. package/src/types/envelope.ts +20 -0
  43. package/src/types/index.ts +1 -1
  44. package/src/types/subscriber.ts +11 -7
  45. package/tsconfig.tsbuildinfo +1 -1
@@ -426,6 +426,39 @@ describe('ProcessingPipeline', () => {
426
426
  transport: 'mock',
427
427
  });
428
428
  });
429
+ it('should pass subscriber return value to onWorkerSuccess', async () => {
430
+ const envelope = createTestEnvelope();
431
+ const subscriberDef = createSubscriberDefinition();
432
+ const onWorkerSuccessMock = mock(async () => { });
433
+ const returnValue = { processed: true, count: 42 };
434
+ const config = createMockConfig({
435
+ codec: {
436
+ decode: mock(() => envelope),
437
+ },
438
+ schema: {
439
+ getSubscriberDefinition: mock(() => subscriberDef),
440
+ getExecutableSubscriber: mock(() => ({
441
+ name: 'test-subscriber',
442
+ description: 'Test subscriber',
443
+ idempotent: 'unknown',
444
+ callback: mock(async () => returnValue),
445
+ })),
446
+ },
447
+ hooks: {
448
+ onWorkerSuccess: onWorkerSuccessMock,
449
+ },
450
+ });
451
+ const pipeline = new ProcessingPipeline(config);
452
+ const receipt = createReceipt();
453
+ await pipeline.process(new Uint8Array(), receipt);
454
+ expect(onWorkerSuccessMock).toHaveBeenCalledWith({
455
+ envelope,
456
+ subscriber: subscriberDef,
457
+ result: returnValue,
458
+ durationMs: expect.any(Number),
459
+ transport: 'mock',
460
+ });
461
+ });
429
462
  it('should call onWorkerError after failed callback', async () => {
430
463
  const envelope = createTestEnvelope();
431
464
  const subscriberDef = createSubscriberDefinition();
@@ -6,7 +6,13 @@ describe('StandardRetryPolicy', () => {
6
6
  describe('shouldRetry', () => {
7
7
  it('should dead-letter on EventAssertionError', () => {
8
8
  const policy = new StandardRetryPolicy();
9
- const context = createContext(new EventAssertionError('Invalid event'));
9
+ const envelope = createEnvelope({
10
+ eventKey: 'test.event',
11
+ targetSubscriber: 'test-subscriber',
12
+ data: { test: 'data' },
13
+ importance: 'should-investigate',
14
+ });
15
+ const context = createContext(new EventAssertionError(envelope, 'Invalid event'));
10
16
  const decision = policy.shouldRetry(context);
11
17
  expect(decision.action).toBe('dead-letter');
12
18
  assertDeadLetter(decision);
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/schema/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,UAAU,EACV,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EACV,eAAe,EAGf,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAM,YAAW,cAAc;IAC9D,QAAQ,CAAC,WAAW,SAIM;gBAEd,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAErD;;OAEG;IACH,QAAQ,CAAC,CAAC,EACR,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,OAAO,GAAE,eAAoB,GAC5B,IAAI;IA6BP;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAalD;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,aAAa,EAAE;IAK1D;;OAEG;IACH,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,aAAa,GAAG,SAAS;IAK5B;;OAEG;IACH,uBAAuB,CACrB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,oBAAoB,GAAG,SAAS;IAkBnC;;OAEG;IACH,uBAAuB,CACrB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS;IAMhD;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAMtD;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI9B;;OAEG;IACH,YAAY,IAAI,SAAS,MAAM,EAAE;IAIjC;;OAEG;IACH,QAAQ,IAAI,sBAAsB;IAkClC;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,QAAQ;CAWjB"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/schema/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,UAAU,EACV,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EACV,eAAe,EAGf,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAM,YAAW,cAAc;IAC9D,QAAQ,CAAC,WAAW,SAIM;gBAEd,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAErD;;OAEG;IACH,QAAQ,CAAC,CAAC,EACR,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,WAAW,EAAE,SAAS,aAAa,EAAE,EACrC,OAAO,GAAE,eAAoB,GAC5B,IAAI;IA6BP;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAalD;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,aAAa,EAAE;IAK1D;;OAEG;IACH,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,aAAa,GAAG,SAAS;IAK5B;;OAEG;IACH,uBAAuB,CACrB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,oBAAoB,GAAG,SAAS;IAqBnC;;OAEG;IACH,uBAAuB,CACrB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS;IAMhD;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAMtD;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI9B;;OAEG;IACH,YAAY,IAAI,SAAS,MAAM,EAAE;IAIjC;;OAEG;IACH,QAAQ,IAAI,sBAAsB;IAkClC;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,QAAQ;CAWjB"}
@@ -79,9 +79,12 @@ export class SchemaRegistry {
79
79
  return undefined;
80
80
  const def = {
81
81
  name: subscriber.name,
82
- description: subscriber.description,
83
82
  idempotent: subscriber.idempotent ?? 'unknown',
84
83
  importance: subscriber.importance ?? 'should-investigate',
84
+ ...('description' in subscriber &&
85
+ subscriber.description !== undefined && {
86
+ description: subscriber.description,
87
+ }),
85
88
  };
86
89
  if (subscriber.targetQueue !== undefined) {
87
90
  def.targetQueue = subscriber.targetQueue;
@@ -196,7 +196,6 @@ describe('installPlugins', () => {
196
196
  });
197
197
  const stubSub = createSubscriberStub({
198
198
  name: 'remote-analytics',
199
- description: 'Remote analytics stub',
200
199
  targetQueue: 'analytics-worker',
201
200
  });
202
201
  const baseSchema = {
@@ -78,5 +78,17 @@ export interface CreateEnvelopeOptions<T> extends DocketCreateFields {
78
78
  * Creates a new envelope with the provided options.
79
79
  */
80
80
  export declare function createEnvelope<T>(options: CreateEnvelopeOptions<T>): Envelope<T>;
81
+ /**
82
+ * Helper to create a test envelope for a given event instance.
83
+ * Useful for unit testing subscriber callbacks directly.
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const event = new UserCreatedEvent({ userId: '123', email: 'test@example.com' });
88
+ * const envelope = createDummyEnvelope(event);
89
+ * await mySubscriber.callback(envelope, event);
90
+ * ```
91
+ */
92
+ export declare function createDummyEnvelope<T>(data: T): Envelope<T>;
81
93
  export {};
82
94
  //# sourceMappingURL=envelope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/types/envelope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,kCAAkC;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAEjB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IAGrB,4BAA4B;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,0EAA0E;IAC1E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE/C,6CAA6C;IAC7C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAElC,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnC,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAIlC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEhC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAI/B,sCAAsC;IACtC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAEhC,yCAAyC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE5C;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CACzD;AAED;;GAEG;AACH,KAAK,kBAAkB,GAAG,IAAI,CAC5B,MAAM,EACJ,UAAU,GACV,kBAAkB,GAClB,kBAAkB,GAClB,YAAY,GACZ,eAAe,CAClB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC,CAAE,SAAQ,kBAAkB;IAClE,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAEjB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAExD;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAEjE,iDAAiD;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAChC,QAAQ,CAAC,CAAC,CAAC,CAmCb"}
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/types/envelope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,kCAAkC;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAEjB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IAGrB,4BAA4B;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,0EAA0E;IAC1E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE/C,6CAA6C;IAC7C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAElC,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnC,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAIlC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEhC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAI/B,sCAAsC;IACtC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAEhC,yCAAyC;IACzC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE5C;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CACzD;AAED;;GAEG;AACH,KAAK,kBAAkB,GAAG,IAAI,CAC5B,MAAM,EACJ,UAAU,GACV,kBAAkB,GAClB,kBAAkB,GAClB,YAAY,GACZ,eAAe,CAClB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC,CAAE,SAAQ,kBAAkB;IAClE,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAEjB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAExD;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAEjE,iDAAiD;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAChC,QAAQ,CAAC,CAAC,CAAC,CAmCb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAO3D"}
@@ -34,3 +34,22 @@ export function createEnvelope(options) {
34
34
  },
35
35
  };
36
36
  }
37
+ /**
38
+ * Helper to create a test envelope for a given event instance.
39
+ * Useful for unit testing subscriber callbacks directly.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const event = new UserCreatedEvent({ userId: '123', email: 'test@example.com' });
44
+ * const envelope = createDummyEnvelope(event);
45
+ * await mySubscriber.callback(envelope, event);
46
+ * ```
47
+ */
48
+ export function createDummyEnvelope(data) {
49
+ return createEnvelope({
50
+ data,
51
+ eventKey: 'dummy.event.key',
52
+ targetSubscriber: 'dummy-subscriber',
53
+ importance: 'can-ignore',
54
+ });
55
+ }
@@ -2,7 +2,7 @@ export type { DeliveryMode, Idempotency, Importance, ValidationError, Validation
2
2
  export { invalidResult, validResult } from './common.js';
3
3
  export type { Dispatcher } from './dispatcher.js';
4
4
  export type { CreateEnvelopeOptions, Docket, Envelope } from './envelope.js';
5
- export { createEnvelope } from './envelope.js';
5
+ export { createDummyEnvelope, createEnvelope } from './envelope.js';
6
6
  export type { Event, EventClass, EventData, EventKey, EventOptions, EventStatic, JsonPrimitive, JsonRecord, JsonValue, } from './event.js';
7
7
  export { MatadorEvent } from './event.js';
8
8
  export type { AnySubscriber, BaseSubscriberOptions, CallbackContext, CreateResumableSubscriberInput, CreateStandardSubscriberInput, CreateSubscriberInput, EnvelopeOf, ResumableCallback, ResumableCallbackContext, ResumableSubscriber, ResumableSubscriberOptions, StandardCallback, StandardSubscriber, StandardSubscriberOptions, Subscriber, SubscriberCallback, SubscriberDefinition, SubscriberOptions, SubscriberStub, } from './subscriber.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,YAAY,EAAE,qBAAqB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,YAAY,EACV,KAAK,EACL,UAAU,EACV,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,UAAU,EACV,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,YAAY,EACV,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,8BAA8B,EAC9B,6BAA6B,EAC7B,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,EACzB,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,GACjB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,YAAY,EAAE,qBAAqB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpE,YAAY,EACV,KAAK,EACL,UAAU,EACV,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,UAAU,EACV,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,YAAY,EACV,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,8BAA8B,EAC9B,6BAA6B,EAC7B,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,EAC1B,gBAAgB,EAChB,kBAAkB,EAClB,yBAAyB,EACzB,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,GACjB,MAAM,iBAAiB,CAAC"}
@@ -1,4 +1,4 @@
1
1
  export { invalidResult, validResult } from './common.js';
2
- export { createEnvelope } from './envelope.js';
2
+ export { createDummyEnvelope, createEnvelope } from './envelope.js';
3
3
  export { MatadorEvent } from './event.js';
4
4
  export { createSubscriber, createSubscriberStub, isResumableSubscriber, isStandardSubscriber, isSubscriber, isSubscriberStub, } from './subscriber.js';
@@ -25,8 +25,11 @@ export type EnvelopeOf<T extends MatadorEvent> = Envelope<T['data']>;
25
25
  * Callback function executed when an event is received (standard subscribers).
26
26
  * Receives the full envelope containing id, data, and docket, plus a context
27
27
  * with access to the matador instance for sending additional events.
28
+ *
29
+ * The callback may optionally return a value, which will be included in the
30
+ * onWorkerSuccess hook context for logging or observability purposes.
28
31
  */
29
- export type StandardCallback<T = unknown> = (envelope: Envelope<T>, context: CallbackContext) => Promise<void> | void;
32
+ export type StandardCallback<T = unknown> = (envelope: Envelope<T>, context: CallbackContext) => Promise<unknown> | unknown | void;
30
33
  /**
31
34
  * Context for resumable subscriber callbacks.
32
35
  * Combines checkpoint operations (io, all) with matador access.
@@ -36,8 +39,11 @@ export type ResumableCallbackContext = SubscriberContext & CallbackContext;
36
39
  * Callback function for resumable subscribers.
37
40
  * Receives the envelope and a context with io() for checkpointed operations
38
41
  * and matador for sending additional events.
42
+ *
43
+ * The callback may optionally return a value, which will be included in the
44
+ * onWorkerSuccess hook context for logging or observability purposes.
39
45
  */
40
- export type ResumableCallback<T = unknown> = (envelope: Envelope<T>, context: ResumableCallbackContext) => Promise<void> | void;
46
+ export type ResumableCallback<T = unknown> = (envelope: Envelope<T>, context: ResumableCallbackContext) => Promise<unknown> | unknown | void;
41
47
  /**
42
48
  * Callback function executed when an event is received.
43
49
  * @deprecated Use StandardCallback or ResumableCallback instead.
@@ -102,7 +108,7 @@ export type Subscriber<T extends MatadorEvent> = StandardSubscriber<T> | Resumab
102
108
  * is in a remote service. Declares the subscriber contract without providing
103
109
  * the callback.
104
110
  */
105
- export interface SubscriberStub extends StandardSubscriberOptions {
111
+ export interface SubscriberStub extends Omit<StandardSubscriberOptions, 'description'> {
106
112
  /** Human-readable name for the subscriber */
107
113
  readonly name: string;
108
114
  /** Indicates this is a stub without implementation */
@@ -191,7 +197,6 @@ export declare function createSubscriber<T extends MatadorEvent>(input: CreateSu
191
197
  */
192
198
  export interface CreateSubscriberStubInput {
193
199
  readonly name: string;
194
- readonly description: string;
195
200
  readonly idempotent?: 'yes' | 'no' | 'unknown' | undefined;
196
201
  readonly importance?: Importance | undefined;
197
202
  readonly targetQueue?: string | undefined;
@@ -204,7 +209,6 @@ export interface CreateSubscriberStubInput {
204
209
  * ```typescript
205
210
  * const stub = createSubscriberStub({
206
211
  * name: 'remote-analytics',
207
- * description: 'Sends events to remote analytics service',
208
212
  * targetQueue: 'analytics-worker',
209
213
  * });
210
214
  * ```
@@ -215,7 +219,7 @@ export declare function createSubscriberStub(input: CreateSubscriberStubInput):
215
219
  */
216
220
  export interface SubscriberDefinition {
217
221
  readonly name: string;
218
- readonly description: string;
222
+ readonly description?: string | undefined;
219
223
  readonly idempotent: Idempotency;
220
224
  readonly importance: Importance;
221
225
  readonly targetQueue?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"subscriber.d.ts","sourceRoot":"","sources":["../../src/types/subscriber.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subscriber.d.ts","sourceRoot":"","sources":["../../src/types/subscriber.ts"],"names":[],"mappings":"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"}
@@ -79,7 +79,6 @@ export function createSubscriber(input) {
79
79
  * ```typescript
80
80
  * const stub = createSubscriberStub({
81
81
  * name: 'remote-analytics',
82
- * description: 'Sends events to remote analytics service',
83
82
  * targetQueue: 'analytics-worker',
84
83
  * });
85
84
  * ```
@@ -87,7 +86,6 @@ export function createSubscriber(input) {
87
86
  export function createSubscriberStub(input) {
88
87
  return {
89
88
  name: input.name,
90
- description: input.description,
91
89
  isStub: true,
92
90
  idempotent: input.idempotent ?? 'unknown',
93
91
  importance: input.importance ?? 'should-investigate',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zdavison/matador",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "A batteries-included event system.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -630,7 +630,6 @@ describe('FanoutEngine', () => {
630
630
  it('should work with subscriber stubs', async () => {
631
631
  const stub = createSubscriberStub({
632
632
  name: 'remote-subscriber',
633
- description: 'Remote subscriber stub',
634
633
  enabled: () => false,
635
634
  });
636
635
 
@@ -2,6 +2,7 @@ export type { HasDescription } from './has-description.js';
2
2
  export { hasDescription } from './has-description.js';
3
3
 
4
4
  export {
5
+ assertEvent,
5
6
  DontRetry,
6
7
  DoRetry,
7
8
  EventAssertionError,
@@ -0,0 +1,175 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+ import { createEnvelope } from '../types/envelope.js';
3
+ import {
4
+ assertEvent,
5
+ DontRetry,
6
+ DoRetry,
7
+ EventAssertionError,
8
+ isAssertionError,
9
+ isDontRetry,
10
+ isDoRetry,
11
+ } from './retry-errors.js';
12
+
13
+ function createTestEnvelope(data: unknown = { foo: 'bar' }) {
14
+ return createEnvelope({
15
+ data,
16
+ eventKey: 'test.event',
17
+ targetSubscriber: 'test-subscriber',
18
+ importance: 'can-ignore',
19
+ });
20
+ }
21
+
22
+ describe('retry-errors', () => {
23
+ describe('DoRetry', () => {
24
+ it('should have correct name', () => {
25
+ const error = new DoRetry('test message');
26
+ expect(error.name).toBe('DoRetry');
27
+ });
28
+
29
+ it('should have description', () => {
30
+ const error = new DoRetry('test message');
31
+ expect(error.description).toBeDefined();
32
+ });
33
+
34
+ it('should serialize to JSON', () => {
35
+ const error = new DoRetry('test message');
36
+ const json = error.toJSON();
37
+ expect(json.name).toBe('DoRetry');
38
+ expect(json.message).toBe('test message');
39
+ expect(json.description).toBeDefined();
40
+ });
41
+ });
42
+
43
+ describe('DontRetry', () => {
44
+ it('should have correct name', () => {
45
+ const error = new DontRetry('test message');
46
+ expect(error.name).toBe('DontRetry');
47
+ });
48
+
49
+ it('should have description', () => {
50
+ const error = new DontRetry('test message');
51
+ expect(error.description).toBeDefined();
52
+ });
53
+
54
+ it('should serialize to JSON', () => {
55
+ const error = new DontRetry('test message');
56
+ const json = error.toJSON();
57
+ expect(json.name).toBe('DontRetry');
58
+ expect(json.message).toBe('test message');
59
+ expect(json.description).toBeDefined();
60
+ });
61
+ });
62
+
63
+ describe('EventAssertionError', () => {
64
+ it('should have correct name', () => {
65
+ const envelope = createTestEnvelope();
66
+ const error = new EventAssertionError(envelope, 'assertion failed');
67
+ expect(error.name).toBe('EventAssertionError');
68
+ });
69
+
70
+ it('should store the envelope', () => {
71
+ const envelope = createTestEnvelope();
72
+ const error = new EventAssertionError(envelope, 'assertion failed');
73
+ expect(error.envelope).toBe(envelope);
74
+ });
75
+
76
+ it('should have description', () => {
77
+ const envelope = createTestEnvelope();
78
+ const error = new EventAssertionError(envelope, 'assertion failed');
79
+ expect(error.description).toBeDefined();
80
+ expect(error.description).toContain('NOT to retry');
81
+ });
82
+
83
+ it('should serialize to JSON with envelope', () => {
84
+ const envelope = createTestEnvelope();
85
+ const error = new EventAssertionError(envelope, 'assertion failed');
86
+ const json = error.toJSON();
87
+ expect(json.name).toBe('EventAssertionError');
88
+ expect(json.message).toBe('assertion failed');
89
+ expect(json.envelope).toBe(envelope);
90
+ expect(json.description).toBeDefined();
91
+ });
92
+ });
93
+
94
+ describe('assertEvent', () => {
95
+ it('should not throw when value is truthy', () => {
96
+ const envelope = createTestEnvelope();
97
+ expect(() => assertEvent(envelope, true, 'should be true')).not.toThrow();
98
+ expect(() =>
99
+ assertEvent(envelope, 'string', 'should be string'),
100
+ ).not.toThrow();
101
+ expect(() => assertEvent(envelope, 1, 'should be number')).not.toThrow();
102
+ expect(() => assertEvent(envelope, {}, 'should be object')).not.toThrow();
103
+ expect(() => assertEvent(envelope, [], 'should be array')).not.toThrow();
104
+ });
105
+
106
+ it('should throw EventAssertionError when value is falsy', () => {
107
+ const envelope = createTestEnvelope();
108
+
109
+ expect(() => assertEvent(envelope, false, 'value was false')).toThrow(
110
+ EventAssertionError,
111
+ );
112
+ expect(() => assertEvent(envelope, null, 'value was null')).toThrow(
113
+ EventAssertionError,
114
+ );
115
+ expect(() =>
116
+ assertEvent(envelope, undefined, 'value was undefined'),
117
+ ).toThrow(EventAssertionError);
118
+ expect(() => assertEvent(envelope, 0, 'value was zero')).toThrow(
119
+ EventAssertionError,
120
+ );
121
+ expect(() => assertEvent(envelope, '', 'value was empty string')).toThrow(
122
+ EventAssertionError,
123
+ );
124
+ });
125
+
126
+ it('should include envelope in thrown error', () => {
127
+ const envelope = createTestEnvelope();
128
+ try {
129
+ assertEvent(envelope, false, 'assertion failed');
130
+ expect.unreachable('should have thrown');
131
+ } catch (error) {
132
+ expect(error).toBeInstanceOf(EventAssertionError);
133
+ expect((error as EventAssertionError).envelope).toBe(envelope);
134
+ expect((error as EventAssertionError).message).toBe('assertion failed');
135
+ }
136
+ });
137
+
138
+ it('should include message in thrown error', () => {
139
+ const envelope = createTestEnvelope();
140
+ try {
141
+ assertEvent(envelope, null, 'userId is required');
142
+ expect.unreachable('should have thrown');
143
+ } catch (error) {
144
+ expect(error).toBeInstanceOf(EventAssertionError);
145
+ expect((error as EventAssertionError).message).toBe('userId is required');
146
+ }
147
+ });
148
+ });
149
+
150
+ describe('type guards', () => {
151
+ it('isDoRetry should identify DoRetry errors', () => {
152
+ expect(isDoRetry(new DoRetry('test'))).toBe(true);
153
+ expect(isDoRetry(new DontRetry('test'))).toBe(false);
154
+ expect(isDoRetry(new Error('test'))).toBe(false);
155
+ expect(isDoRetry(null)).toBe(false);
156
+ });
157
+
158
+ it('isDontRetry should identify DontRetry errors', () => {
159
+ expect(isDontRetry(new DontRetry('test'))).toBe(true);
160
+ expect(isDontRetry(new DoRetry('test'))).toBe(false);
161
+ expect(isDontRetry(new Error('test'))).toBe(false);
162
+ expect(isDontRetry(null)).toBe(false);
163
+ });
164
+
165
+ it('isAssertionError should identify EventAssertionError', () => {
166
+ const envelope = createTestEnvelope();
167
+ expect(isAssertionError(new EventAssertionError(envelope, 'test'))).toBe(
168
+ true,
169
+ );
170
+ expect(isAssertionError(new DoRetry('test'))).toBe(false);
171
+ expect(isAssertionError(new Error('test'))).toBe(false);
172
+ expect(isAssertionError(null)).toBe(false);
173
+ });
174
+ });
175
+ });
@@ -1,3 +1,6 @@
1
+ import assert from 'node:assert';
2
+ import type { Envelope } from '../types/envelope.js';
3
+
1
4
  /**
2
5
  * Base class for retry control errors.
3
6
  * These errors control the retry behavior of message processing.
@@ -76,24 +79,37 @@ export class DontRetry extends RetryControlError {
76
79
  }
77
80
 
78
81
  /**
79
- * Assertion error that should never be retried.
80
- * Use for programming errors and invariant violations.
82
+ * Thrown by `assertEvent` in the event of a failed assertion.
83
+ *
84
+ * This error indicates that an event was in an unexpected state when it reached the subscriber.
85
+ * Throwing this error will indicate to Matador NOT to retry the event - it will be sent
86
+ * directly to the undeliverable dead-letter queue.
81
87
  *
82
- * ACTION: Review the assertion failure message to identify the bug
83
- * in the event payload or subscriber logic.
88
+ * Use `assertEvent` in your subscribers to assert properties about an event payload.
89
+ * This is useful in scenarios where you would expect an event payload to contain a field
90
+ * based on the types, but something unexpected caused it to not be present.
91
+ *
92
+ * @see assertEvent
84
93
  */
85
94
  export class EventAssertionError extends Error {
86
95
  declare readonly name: string;
87
96
 
88
97
  readonly description =
89
- 'An event assertion failed, indicating a programming error or invariant violation. ' +
90
- 'ACTION: Review the assertion failure message to identify the bug in the ' +
91
- 'event payload or subscriber logic. These errors are never retried and go ' +
92
- 'directly to the dead-letter queue.';
98
+ 'Thrown to indicate that an event was in an unexpected state when it reached the subscriber. ' +
99
+ 'Throwing this error will indicate to Matador NOT to retry the event. ' +
100
+ 'Matador does not throw this error directly - it is thrown by assertEvent, which you can ' +
101
+ 'use in your subscribers to assert properties about an event. ' +
102
+ 'This can be useful in scenarios where you would expect an event payload to contain a field ' +
103
+ 'based on the types, but something unexpected caused it to not be present. ' +
104
+ 'Using this instead of the NodeJS assert allows Matador to not retry the event subscriber.';
93
105
 
94
- constructor(message: string) {
106
+ /** The envelope that failed the assertion */
107
+ readonly envelope: Envelope<unknown>;
108
+
109
+ constructor(envelope: Envelope<unknown>, message: string) {
95
110
  super(message);
96
111
  this.name = 'EventAssertionError';
112
+ this.envelope = envelope;
97
113
  Object.defineProperty(this, 'name', {
98
114
  value: 'EventAssertionError',
99
115
  enumerable: true,
@@ -107,6 +123,7 @@ export class EventAssertionError extends Error {
107
123
  name: this.name,
108
124
  message: this.message,
109
125
  description: this.description,
126
+ envelope: this.envelope,
110
127
  stack: this.stack,
111
128
  };
112
129
  }
@@ -132,3 +149,40 @@ export function isDontRetry(error: unknown): error is DontRetry {
132
149
  export function isAssertionError(error: unknown): error is EventAssertionError {
133
150
  return error instanceof EventAssertionError;
134
151
  }
152
+
153
+ /**
154
+ * Same as Node.js `assert`, but throws an `EventAssertionError` if the assertion fails.
155
+ *
156
+ * `EventAssertionError`s thrown within a subscriber do not cause the subscriber to be retried.
157
+ * The event will be delivered to the undeliverable dead-letter queue instead.
158
+ *
159
+ * @see https://nodejs.org/api/assert.html#assertvalue-message
160
+ * @param envelope - The envelope this assertion relates to.
161
+ * @param value - The value to assert. If falsy, the assertion fails.
162
+ * @param message - The message to include in the error if the assertion fails.
163
+ * @throws {EventAssertionError} If the assertion fails.
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * const subscriber = createSubscriber<MyEvent>({
168
+ * name: 'my-subscriber',
169
+ * description: 'Processes MyEvent',
170
+ * callback: async (envelope) => {
171
+ * // Assert that userId exists - if not, event goes to DLQ without retry
172
+ * assertEvent(envelope, envelope.data.userId, 'userId is required');
173
+ * // ... rest of processing
174
+ * },
175
+ * });
176
+ * ```
177
+ */
178
+ export function assertEvent(
179
+ envelope: Envelope<unknown>,
180
+ value: unknown,
181
+ message: string,
182
+ ): asserts value {
183
+ try {
184
+ assert(value, message);
185
+ } catch {
186
+ throw new EventAssertionError(envelope, message);
187
+ }
188
+ }
package/src/index.ts CHANGED
@@ -48,6 +48,7 @@ export type {
48
48
  } from './types/index.js';
49
49
  export {
50
50
  MatadorEvent,
51
+ createDummyEnvelope,
51
52
  createEnvelope,
52
53
  createSubscriber,
53
54
  createSubscriberStub,
@@ -171,6 +172,7 @@ export { ProcessingPipeline } from './pipeline/index.js';
171
172
  export type { HasDescription } from './errors/index.js';
172
173
  export {
173
174
  // Retry control errors
175
+ assertEvent,
174
176
  DontRetry,
175
177
  DoRetry,
176
178
  EventAssertionError,
@@ -542,6 +542,44 @@ describe('ProcessingPipeline', () => {
542
542
  });
543
543
  });
544
544
 
545
+ it('should pass subscriber return value to onWorkerSuccess', async () => {
546
+ const envelope = createTestEnvelope();
547
+ const subscriberDef = createSubscriberDefinition();
548
+ const onWorkerSuccessMock = mock(async () => {});
549
+ const returnValue = { processed: true, count: 42 };
550
+
551
+ const config = createMockConfig({
552
+ codec: {
553
+ decode: mock(() => envelope),
554
+ },
555
+ schema: {
556
+ getSubscriberDefinition: mock(() => subscriberDef),
557
+ getExecutableSubscriber: mock(() => ({
558
+ name: 'test-subscriber',
559
+ description: 'Test subscriber',
560
+ idempotent: 'unknown' as const,
561
+ callback: mock(async () => returnValue),
562
+ })),
563
+ },
564
+ hooks: {
565
+ onWorkerSuccess: onWorkerSuccessMock,
566
+ },
567
+ });
568
+
569
+ const pipeline = new ProcessingPipeline(config);
570
+ const receipt = createReceipt();
571
+
572
+ await pipeline.process(new Uint8Array(), receipt);
573
+
574
+ expect(onWorkerSuccessMock).toHaveBeenCalledWith({
575
+ envelope,
576
+ subscriber: subscriberDef,
577
+ result: returnValue,
578
+ durationMs: expect.any(Number),
579
+ transport: 'mock',
580
+ });
581
+ });
582
+
545
583
  it('should call onWorkerError after failed callback', async () => {
546
584
  const envelope = createTestEnvelope();
547
585
  const subscriberDef = createSubscriberDefinition();
@@ -14,7 +14,15 @@ describe('StandardRetryPolicy', () => {
14
14
  describe('shouldRetry', () => {
15
15
  it('should dead-letter on EventAssertionError', () => {
16
16
  const policy = new StandardRetryPolicy();
17
- const context = createContext(new EventAssertionError('Invalid event'));
17
+ const envelope = createEnvelope({
18
+ eventKey: 'test.event',
19
+ targetSubscriber: 'test-subscriber',
20
+ data: { test: 'data' },
21
+ importance: 'should-investigate',
22
+ });
23
+ const context = createContext(
24
+ new EventAssertionError(envelope, 'Invalid event'),
25
+ );
18
26
 
19
27
  const decision = policy.shouldRetry(context);
20
28