@zdavison/matador 2.0.3 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/core/fanout.test.js +0 -1
  2. package/dist/core/matador.d.ts +2 -2
  3. package/dist/core/matador.d.ts.map +1 -1
  4. package/dist/core/matador.js +1 -0
  5. package/dist/errors/index.d.ts +1 -1
  6. package/dist/errors/index.d.ts.map +1 -1
  7. package/dist/errors/index.js +1 -1
  8. package/dist/errors/retry-errors.d.ts +40 -5
  9. package/dist/errors/retry-errors.d.ts.map +1 -1
  10. package/dist/errors/retry-errors.js +56 -9
  11. package/dist/errors/retry-errors.test.d.ts +2 -0
  12. package/dist/errors/retry-errors.test.d.ts.map +1 -0
  13. package/dist/errors/retry-errors.test.js +136 -0
  14. package/dist/index.cjs +73 -28
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +5 -5
  17. package/dist/index.d.ts +5 -5
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +3 -3
  20. package/dist/index.js.map +1 -1
  21. package/dist/pipeline/pipeline.d.ts +4 -1
  22. package/dist/pipeline/pipeline.d.ts.map +1 -1
  23. package/dist/pipeline/pipeline.js +16 -4
  24. package/dist/pipeline/pipeline.test.js +48 -1
  25. package/dist/retry/standard-policy.test.js +7 -1
  26. package/dist/schema/registry.d.ts.map +1 -1
  27. package/dist/schema/registry.js +4 -1
  28. package/dist/schema/types.test.js +0 -1
  29. package/dist/topology/builder.d.ts.map +1 -1
  30. package/dist/topology/builder.js +2 -1
  31. package/dist/topology/builder.test.js +68 -0
  32. package/dist/topology/index.d.ts +2 -2
  33. package/dist/topology/index.d.ts.map +1 -1
  34. package/dist/topology/index.js +1 -1
  35. package/dist/topology/types.d.ts +53 -1
  36. package/dist/topology/types.d.ts.map +1 -1
  37. package/dist/topology/types.js +10 -0
  38. package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -1
  39. package/dist/transport/rabbitmq/rabbitmq-transport.js +30 -22
  40. package/dist/transport/rabbitmq/rabbitmq-transport.test.js +1 -1
  41. package/dist/types/dispatcher.d.ts +14 -0
  42. package/dist/types/dispatcher.d.ts.map +1 -0
  43. package/dist/types/dispatcher.js +1 -0
  44. package/dist/types/envelope.d.ts +17 -0
  45. package/dist/types/envelope.d.ts.map +1 -1
  46. package/dist/types/envelope.js +19 -0
  47. package/dist/types/index.d.ts +3 -2
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/dist/types/index.js +1 -1
  50. package/dist/types/subscriber.d.ts +28 -8
  51. package/dist/types/subscriber.d.ts.map +1 -1
  52. package/dist/types/subscriber.js +0 -2
  53. package/package.json +1 -1
  54. package/src/core/fanout.test.ts +0 -1
  55. package/src/core/matador.ts +3 -1
  56. package/src/errors/index.ts +1 -0
  57. package/src/errors/retry-errors.test.ts +175 -0
  58. package/src/errors/retry-errors.ts +63 -9
  59. package/src/index.ts +11 -0
  60. package/src/pipeline/pipeline.test.ts +62 -2
  61. package/src/pipeline/pipeline.ts +28 -6
  62. package/src/retry/standard-policy.test.ts +9 -1
  63. package/src/schema/registry.ts +4 -1
  64. package/src/schema/types.test.ts +0 -1
  65. package/src/topology/builder.test.ts +90 -0
  66. package/src/topology/builder.ts +2 -1
  67. package/src/topology/index.ts +4 -0
  68. package/src/topology/types.ts +75 -1
  69. package/src/transport/rabbitmq/rabbitmq-transport.test.ts +1 -1
  70. package/src/transport/rabbitmq/rabbitmq-transport.ts +33 -25
  71. package/src/types/dispatcher.ts +18 -0
  72. package/src/types/envelope.ts +23 -0
  73. package/src/types/index.ts +5 -1
  74. package/src/types/subscriber.ts +33 -10
  75. package/test/e2e/rabbitmq-transport.e2e.test.ts +287 -0
  76. package/tsconfig.tsbuildinfo +1 -1
@@ -489,7 +489,6 @@ describe('FanoutEngine', () => {
489
489
  it('should work with subscriber stubs', async () => {
490
490
  const stub = createSubscriberStub({
491
491
  name: 'remote-subscriber',
492
- description: 'Remote subscriber stub',
493
492
  enabled: () => false,
494
493
  });
495
494
  schema.register(UserCreatedEvent, [stub]);
@@ -5,7 +5,7 @@ import type { RetryPolicy } from '../retry/index.js';
5
5
  import type { MatadorSchema } from '../schema/index.js';
6
6
  import type { Topology } from '../topology/index.js';
7
7
  import type { Transport } from '../transport/index.js';
8
- import type { AnySubscriber, Event, EventClass, EventOptions } from '../types/index.js';
8
+ import type { AnySubscriber, Dispatcher, Event, EventClass, EventOptions } from '../types/index.js';
9
9
  import type { SendResult } from './fanout.js';
10
10
  import type { HandlersState, ShutdownConfig } from './shutdown.js';
11
11
  /**
@@ -44,7 +44,7 @@ export interface MatadorConfig {
44
44
  * - Fanout: Event sending
45
45
  * - Shutdown: Graceful termination
46
46
  */
47
- export declare class Matador {
47
+ export declare class Matador implements Dispatcher {
48
48
  private readonly transport;
49
49
  private readonly topology;
50
50
  private readonly schema;
@@ -1 +1 @@
1
- {"version":3,"file":"matador.d.ts","sourceRoot":"","sources":["../../src/core/matador.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"matador.d.ts","sourceRoot":"","sources":["../../src/core/matador.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAO/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,KAAK,EACL,UAAU,EACV,YAAY,EACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGnE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B,6BAA6B;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAE/B,sDAAsD;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAErD,sCAAsC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAEnC,0BAA0B;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAE/C,6BAA6B;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAE9D;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;CACxD;AAED;;;;;;;;;GASG;AACH,qBAAa,OAAQ,YAAW,UAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAsB;IACpD,OAAO,CAAC,OAAO,CAAS;IAExB;;;;;;OAMG;gBACS,MAAM,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,YAAY;IA4CvD;;OAEG;IACH,QAAQ,CAAC,CAAC,EACR,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,WAAW,EAAE,SAAS,aAAa,EAAE,GACpC,IAAI;IAKP;;;;;;;;;;;;;;;;;OAiBG;IACH,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAc3C;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+D5B;;;;;;;;;;;;OAYG;IACG,IAAI,CAAC,CAAC,EACV,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,UAAU,CAAC;IAChB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IAkC3E;;OAEG;IACH,gBAAgB,IAAI,aAAa;IAIjC;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACG,WAAW,CAAC,SAAS,SAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAatD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B;;OAEG;IACH,WAAW,IAAI,OAAO;YAIR,aAAa;CAM5B"}
@@ -56,6 +56,7 @@ export class Matador {
56
56
  retryPolicy: this.retryPolicy,
57
57
  hooks: this.hooks,
58
58
  checkpointStore: config.checkpointStore,
59
+ dispatcher: this,
59
60
  });
60
61
  // Create fanout engine
61
62
  const defaultQueue = this.topology.queues[0]?.name ?? 'default';
@@ -1,6 +1,6 @@
1
1
  export type { HasDescription } from './has-description.js';
2
2
  export { hasDescription } from './has-description.js';
3
- export { DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, RetryControlError, } from './retry-errors.js';
3
+ export { assertEvent, DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, RetryControlError, } from './retry-errors.js';
4
4
  export { MatadorError, isMatadorError, NotStartedError, isNotStartedError, ShutdownInProgressError, TransportNotConnectedError, isTransportNotConnectedError, TransportClosedError, TransportSendError, AllTransportsFailedError, DelayedMessagesNotSupportedError, EventNotRegisteredError, isEventNotRegisteredError, SubscriberNotRegisteredError, isSubscriberNotRegisteredError, NoSubscribersExistError, InvalidSchemaError, SubscriberIsStubError, LocalTransportCannotProcessStubError, QueueNotFoundError, InvalidEventError, MessageMaybePoisonedError, isMessageMaybePoisonedError, IdempotentMessageCannotRetryError, isIdempotentMessageCannotRetryError, TimeoutError, } from './matador-errors.js';
5
5
  export { CheckpointStoreError, DuplicateIoKeyError, isCheckpointStoreError, isDuplicateIoKeyError, } from './checkpoint-errors.js';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EACL,SAAS,EACT,OAAO,EACP,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEL,YAAY,EACZ,cAAc,EAEd,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EAEvB,0BAA0B,EAC1B,4BAA4B,EAC5B,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,gCAAgC,EAEhC,uBAAuB,EACvB,yBAAyB,EACzB,4BAA4B,EAC5B,8BAA8B,EAC9B,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,oCAAoC,EAEpC,kBAAkB,EAElB,iBAAiB,EAEjB,yBAAyB,EACzB,2BAA2B,EAC3B,iCAAiC,EACjC,mCAAmC,EAEnC,YAAY,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EACL,WAAW,EACX,SAAS,EACT,OAAO,EACP,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEL,YAAY,EACZ,cAAc,EAEd,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EAEvB,0BAA0B,EAC1B,4BAA4B,EAC5B,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,gCAAgC,EAEhC,uBAAuB,EACvB,yBAAyB,EACzB,4BAA4B,EAC5B,8BAA8B,EAC9B,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,oCAAoC,EAEpC,kBAAkB,EAElB,iBAAiB,EAEjB,yBAAyB,EACzB,2BAA2B,EAC3B,iCAAiC,EACjC,mCAAmC,EAEnC,YAAY,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  export { hasDescription } from './has-description.js';
2
- export { DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, RetryControlError, } from './retry-errors.js';
2
+ export { assertEvent, DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, RetryControlError, } from './retry-errors.js';
3
3
  export {
4
4
  // Base class
5
5
  MatadorError, isMatadorError,
@@ -1,3 +1,4 @@
1
+ import type { Envelope } from '../types/envelope.js';
1
2
  /**
2
3
  * Base class for retry control errors.
3
4
  * These errors control the retry behavior of message processing.
@@ -40,16 +41,24 @@ export declare class DontRetry extends RetryControlError {
40
41
  constructor(message?: string);
41
42
  }
42
43
  /**
43
- * Assertion error that should never be retried.
44
- * Use for programming errors and invariant violations.
44
+ * Thrown by `assertEvent` in the event of a failed assertion.
45
45
  *
46
- * ACTION: Review the assertion failure message to identify the bug
47
- * in the event payload or subscriber logic.
46
+ * This error indicates that an event was in an unexpected state when it reached the subscriber.
47
+ * Throwing this error will indicate to Matador NOT to retry the event - it will be sent
48
+ * directly to the undeliverable dead-letter queue.
49
+ *
50
+ * Use `assertEvent` in your subscribers to assert properties about an event payload.
51
+ * This is useful in scenarios where you would expect an event payload to contain a field
52
+ * based on the types, but something unexpected caused it to not be present.
53
+ *
54
+ * @see assertEvent
48
55
  */
49
56
  export declare class EventAssertionError extends Error {
50
57
  readonly name: string;
51
58
  readonly description: string;
52
- constructor(message: string);
59
+ /** The envelope that failed the assertion */
60
+ readonly envelope: Envelope<unknown>;
61
+ constructor(envelope: Envelope<unknown>, message: string);
53
62
  toJSON(): Record<string, unknown>;
54
63
  }
55
64
  /**
@@ -64,4 +73,30 @@ export declare function isDontRetry(error: unknown): error is DontRetry;
64
73
  * Checks if an error is an assertion error (never retry).
65
74
  */
66
75
  export declare function isAssertionError(error: unknown): error is EventAssertionError;
76
+ /**
77
+ * Same as Node.js `assert`, but throws an `EventAssertionError` if the assertion fails.
78
+ *
79
+ * `EventAssertionError`s thrown within a subscriber do not cause the subscriber to be retried.
80
+ * The event will be delivered to the undeliverable dead-letter queue instead.
81
+ *
82
+ * @see https://nodejs.org/api/assert.html#assertvalue-message
83
+ * @param envelope - The envelope this assertion relates to.
84
+ * @param value - The value to assert. If falsy, the assertion fails.
85
+ * @param message - The message to include in the error if the assertion fails.
86
+ * @throws {EventAssertionError} If the assertion fails.
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * const subscriber = createSubscriber<MyEvent>({
91
+ * name: 'my-subscriber',
92
+ * description: 'Processes MyEvent',
93
+ * callback: async (envelope) => {
94
+ * // Assert that userId exists - if not, event goes to DLQ without retry
95
+ * assertEvent(envelope, envelope.data.userId, 'userId is required');
96
+ * // ... rest of processing
97
+ * },
98
+ * });
99
+ * ```
100
+ */
101
+ export declare function assertEvent(envelope: Envelope<unknown>, value: unknown, message: string): asserts value;
67
102
  //# sourceMappingURL=retry-errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry-errors.d.ts","sourceRoot":"","sources":["../../src/errors/retry-errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,8BAAsB,iBAAkB,SAAQ,KAAK;IACnD;;OAEG;IACH,SAAiB,IAAI,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAE1B,OAAO,EAAE,MAAM;IAY3B;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQlC;AAED;;;;;;GAMG;AACH,qBAAa,OAAQ,SAAQ,iBAAiB;IAC5C,QAAQ,CAAC,WAAW,SAGyD;gBAEjE,OAAO,SAA2B;CAG/C;AAED;;;;;;GAMG;AACH,qBAAa,SAAU,SAAQ,iBAAiB;IAC9C,QAAQ,CAAC,WAAW,SAIqD;gBAE7D,OAAO,SAA8B;CAGlD;AAED;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,SAAiB,IAAI,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,WAAW,SAImB;gBAE3B,OAAO,EAAE,MAAM;IAW3B,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQlC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAE7E"}
1
+ {"version":3,"file":"retry-errors.d.ts","sourceRoot":"","sources":["../../src/errors/retry-errors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;GAGG;AACH,8BAAsB,iBAAkB,SAAQ,KAAK;IACnD;;OAEG;IACH,SAAiB,IAAI,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAE1B,OAAO,EAAE,MAAM;IAY3B;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAQlC;AAED;;;;;;GAMG;AACH,qBAAa,OAAQ,SAAQ,iBAAiB;IAC5C,QAAQ,CAAC,WAAW,SAGyD;gBAEjE,OAAO,SAA2B;CAG/C;AAED;;;;;;GAMG;AACH,qBAAa,SAAU,SAAQ,iBAAiB;IAC9C,QAAQ,CAAC,WAAW,SAIqD;gBAE7D,OAAO,SAA8B;CAGlD;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,SAAiB,IAAI,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,WAAW,SAO0E;IAE9F,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAEzB,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM;IAYxD,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CASlC;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAE7E;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,EAC3B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAMf"}
@@ -1,3 +1,4 @@
1
+ import assert from 'node:assert';
1
2
  /**
2
3
  * Base class for retry control errors.
3
4
  * These errors control the retry behavior of message processing.
@@ -58,20 +59,32 @@ export class DontRetry extends RetryControlError {
58
59
  }
59
60
  }
60
61
  /**
61
- * Assertion error that should never be retried.
62
- * Use for programming errors and invariant violations.
62
+ * Thrown by `assertEvent` in the event of a failed assertion.
63
63
  *
64
- * ACTION: Review the assertion failure message to identify the bug
65
- * in the event payload or subscriber logic.
64
+ * This error indicates that an event was in an unexpected state when it reached the subscriber.
65
+ * Throwing this error will indicate to Matador NOT to retry the event - it will be sent
66
+ * directly to the undeliverable dead-letter queue.
67
+ *
68
+ * Use `assertEvent` in your subscribers to assert properties about an event payload.
69
+ * This is useful in scenarios where you would expect an event payload to contain a field
70
+ * based on the types, but something unexpected caused it to not be present.
71
+ *
72
+ * @see assertEvent
66
73
  */
67
74
  export class EventAssertionError extends Error {
68
- description = 'An event assertion failed, indicating a programming error or invariant violation. ' +
69
- 'ACTION: Review the assertion failure message to identify the bug in the ' +
70
- 'event payload or subscriber logic. These errors are never retried and go ' +
71
- 'directly to the dead-letter queue.';
72
- constructor(message) {
75
+ description = 'Thrown to indicate that an event was in an unexpected state when it reached the subscriber. ' +
76
+ 'Throwing this error will indicate to Matador NOT to retry the event. ' +
77
+ 'Matador does not throw this error directly - it is thrown by assertEvent, which you can ' +
78
+ 'use in your subscribers to assert properties about an event. ' +
79
+ 'This can be useful in scenarios where you would expect an event payload to contain a field ' +
80
+ 'based on the types, but something unexpected caused it to not be present. ' +
81
+ 'Using this instead of the NodeJS assert allows Matador to not retry the event subscriber.';
82
+ /** The envelope that failed the assertion */
83
+ envelope;
84
+ constructor(envelope, message) {
73
85
  super(message);
74
86
  this.name = 'EventAssertionError';
87
+ this.envelope = envelope;
75
88
  Object.defineProperty(this, 'name', {
76
89
  value: 'EventAssertionError',
77
90
  enumerable: true,
@@ -84,6 +97,7 @@ export class EventAssertionError extends Error {
84
97
  name: this.name,
85
98
  message: this.message,
86
99
  description: this.description,
100
+ envelope: this.envelope,
87
101
  stack: this.stack,
88
102
  };
89
103
  }
@@ -106,3 +120,36 @@ export function isDontRetry(error) {
106
120
  export function isAssertionError(error) {
107
121
  return error instanceof EventAssertionError;
108
122
  }
123
+ /**
124
+ * Same as Node.js `assert`, but throws an `EventAssertionError` if the assertion fails.
125
+ *
126
+ * `EventAssertionError`s thrown within a subscriber do not cause the subscriber to be retried.
127
+ * The event will be delivered to the undeliverable dead-letter queue instead.
128
+ *
129
+ * @see https://nodejs.org/api/assert.html#assertvalue-message
130
+ * @param envelope - The envelope this assertion relates to.
131
+ * @param value - The value to assert. If falsy, the assertion fails.
132
+ * @param message - The message to include in the error if the assertion fails.
133
+ * @throws {EventAssertionError} If the assertion fails.
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const subscriber = createSubscriber<MyEvent>({
138
+ * name: 'my-subscriber',
139
+ * description: 'Processes MyEvent',
140
+ * callback: async (envelope) => {
141
+ * // Assert that userId exists - if not, event goes to DLQ without retry
142
+ * assertEvent(envelope, envelope.data.userId, 'userId is required');
143
+ * // ... rest of processing
144
+ * },
145
+ * });
146
+ * ```
147
+ */
148
+ export function assertEvent(envelope, value, message) {
149
+ try {
150
+ assert(value, message);
151
+ }
152
+ catch {
153
+ throw new EventAssertionError(envelope, message);
154
+ }
155
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=retry-errors.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-errors.test.d.ts","sourceRoot":"","sources":["../../src/errors/retry-errors.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,136 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+ import { createEnvelope } from '../types/envelope.js';
3
+ import { assertEvent, DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, } from './retry-errors.js';
4
+ function createTestEnvelope(data = { foo: 'bar' }) {
5
+ return createEnvelope({
6
+ data,
7
+ eventKey: 'test.event',
8
+ targetSubscriber: 'test-subscriber',
9
+ importance: 'can-ignore',
10
+ });
11
+ }
12
+ describe('retry-errors', () => {
13
+ describe('DoRetry', () => {
14
+ it('should have correct name', () => {
15
+ const error = new DoRetry('test message');
16
+ expect(error.name).toBe('DoRetry');
17
+ });
18
+ it('should have description', () => {
19
+ const error = new DoRetry('test message');
20
+ expect(error.description).toBeDefined();
21
+ });
22
+ it('should serialize to JSON', () => {
23
+ const error = new DoRetry('test message');
24
+ const json = error.toJSON();
25
+ expect(json.name).toBe('DoRetry');
26
+ expect(json.message).toBe('test message');
27
+ expect(json.description).toBeDefined();
28
+ });
29
+ });
30
+ describe('DontRetry', () => {
31
+ it('should have correct name', () => {
32
+ const error = new DontRetry('test message');
33
+ expect(error.name).toBe('DontRetry');
34
+ });
35
+ it('should have description', () => {
36
+ const error = new DontRetry('test message');
37
+ expect(error.description).toBeDefined();
38
+ });
39
+ it('should serialize to JSON', () => {
40
+ const error = new DontRetry('test message');
41
+ const json = error.toJSON();
42
+ expect(json.name).toBe('DontRetry');
43
+ expect(json.message).toBe('test message');
44
+ expect(json.description).toBeDefined();
45
+ });
46
+ });
47
+ describe('EventAssertionError', () => {
48
+ it('should have correct name', () => {
49
+ const envelope = createTestEnvelope();
50
+ const error = new EventAssertionError(envelope, 'assertion failed');
51
+ expect(error.name).toBe('EventAssertionError');
52
+ });
53
+ it('should store the envelope', () => {
54
+ const envelope = createTestEnvelope();
55
+ const error = new EventAssertionError(envelope, 'assertion failed');
56
+ expect(error.envelope).toBe(envelope);
57
+ });
58
+ it('should have description', () => {
59
+ const envelope = createTestEnvelope();
60
+ const error = new EventAssertionError(envelope, 'assertion failed');
61
+ expect(error.description).toBeDefined();
62
+ expect(error.description).toContain('NOT to retry');
63
+ });
64
+ it('should serialize to JSON with envelope', () => {
65
+ const envelope = createTestEnvelope();
66
+ const error = new EventAssertionError(envelope, 'assertion failed');
67
+ const json = error.toJSON();
68
+ expect(json.name).toBe('EventAssertionError');
69
+ expect(json.message).toBe('assertion failed');
70
+ expect(json.envelope).toBe(envelope);
71
+ expect(json.description).toBeDefined();
72
+ });
73
+ });
74
+ describe('assertEvent', () => {
75
+ it('should not throw when value is truthy', () => {
76
+ const envelope = createTestEnvelope();
77
+ expect(() => assertEvent(envelope, true, 'should be true')).not.toThrow();
78
+ expect(() => assertEvent(envelope, 'string', 'should be string')).not.toThrow();
79
+ expect(() => assertEvent(envelope, 1, 'should be number')).not.toThrow();
80
+ expect(() => assertEvent(envelope, {}, 'should be object')).not.toThrow();
81
+ expect(() => assertEvent(envelope, [], 'should be array')).not.toThrow();
82
+ });
83
+ it('should throw EventAssertionError when value is falsy', () => {
84
+ const envelope = createTestEnvelope();
85
+ expect(() => assertEvent(envelope, false, 'value was false')).toThrow(EventAssertionError);
86
+ expect(() => assertEvent(envelope, null, 'value was null')).toThrow(EventAssertionError);
87
+ expect(() => assertEvent(envelope, undefined, 'value was undefined')).toThrow(EventAssertionError);
88
+ expect(() => assertEvent(envelope, 0, 'value was zero')).toThrow(EventAssertionError);
89
+ expect(() => assertEvent(envelope, '', 'value was empty string')).toThrow(EventAssertionError);
90
+ });
91
+ it('should include envelope in thrown error', () => {
92
+ const envelope = createTestEnvelope();
93
+ try {
94
+ assertEvent(envelope, false, 'assertion failed');
95
+ expect.unreachable('should have thrown');
96
+ }
97
+ catch (error) {
98
+ expect(error).toBeInstanceOf(EventAssertionError);
99
+ expect(error.envelope).toBe(envelope);
100
+ expect(error.message).toBe('assertion failed');
101
+ }
102
+ });
103
+ it('should include message in thrown error', () => {
104
+ const envelope = createTestEnvelope();
105
+ try {
106
+ assertEvent(envelope, null, 'userId is required');
107
+ expect.unreachable('should have thrown');
108
+ }
109
+ catch (error) {
110
+ expect(error).toBeInstanceOf(EventAssertionError);
111
+ expect(error.message).toBe('userId is required');
112
+ }
113
+ });
114
+ });
115
+ describe('type guards', () => {
116
+ it('isDoRetry should identify DoRetry errors', () => {
117
+ expect(isDoRetry(new DoRetry('test'))).toBe(true);
118
+ expect(isDoRetry(new DontRetry('test'))).toBe(false);
119
+ expect(isDoRetry(new Error('test'))).toBe(false);
120
+ expect(isDoRetry(null)).toBe(false);
121
+ });
122
+ it('isDontRetry should identify DontRetry errors', () => {
123
+ expect(isDontRetry(new DontRetry('test'))).toBe(true);
124
+ expect(isDontRetry(new DoRetry('test'))).toBe(false);
125
+ expect(isDontRetry(new Error('test'))).toBe(false);
126
+ expect(isDontRetry(null)).toBe(false);
127
+ });
128
+ it('isAssertionError should identify EventAssertionError', () => {
129
+ const envelope = createTestEnvelope();
130
+ expect(isAssertionError(new EventAssertionError(envelope, 'test'))).toBe(true);
131
+ expect(isAssertionError(new DoRetry('test'))).toBe(false);
132
+ expect(isAssertionError(new Error('test'))).toBe(false);
133
+ expect(isAssertionError(null)).toBe(false);
134
+ });
135
+ });
136
+ });
package/dist/index.cjs CHANGED
@@ -1,17 +1,17 @@
1
1
  'use strict';
2
2
 
3
+ var assert = require('assert');
3
4
  var amqplib = require('amqplib');
4
5
 
5
6
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
7
 
8
+ var assert__default = /*#__PURE__*/_interopDefault(assert);
7
9
  var amqplib__default = /*#__PURE__*/_interopDefault(amqplib);
8
10
 
9
11
  // src/errors/has-description.ts
10
12
  function hasDescription(error) {
11
13
  return typeof error === "object" && error !== null && "description" in error && typeof error.description === "string";
12
14
  }
13
-
14
- // src/errors/retry-errors.ts
15
15
  var RetryControlError = class extends Error {
16
16
  constructor(message) {
17
17
  super(message);
@@ -48,10 +48,13 @@ var DontRetry = class extends RetryControlError {
48
48
  }
49
49
  };
50
50
  var EventAssertionError = class extends Error {
51
- description = "An event assertion failed, indicating a programming error or invariant violation. ACTION: Review the assertion failure message to identify the bug in the event payload or subscriber logic. These errors are never retried and go directly to the dead-letter queue.";
52
- constructor(message) {
51
+ description = "Thrown to indicate that an event was in an unexpected state when it reached the subscriber. Throwing this error will indicate to Matador NOT to retry the event. Matador does not throw this error directly - it is thrown by assertEvent, which you can use in your subscribers to assert properties about an event. This can be useful in scenarios where you would expect an event payload to contain a field based on the types, but something unexpected caused it to not be present. Using this instead of the NodeJS assert allows Matador to not retry the event subscriber.";
52
+ /** The envelope that failed the assertion */
53
+ envelope;
54
+ constructor(envelope, message) {
53
55
  super(message);
54
56
  this.name = "EventAssertionError";
57
+ this.envelope = envelope;
55
58
  Object.defineProperty(this, "name", {
56
59
  value: "EventAssertionError",
57
60
  enumerable: true,
@@ -64,6 +67,7 @@ var EventAssertionError = class extends Error {
64
67
  name: this.name,
65
68
  message: this.message,
66
69
  description: this.description,
70
+ envelope: this.envelope,
67
71
  stack: this.stack
68
72
  };
69
73
  }
@@ -77,6 +81,13 @@ function isDontRetry(error) {
77
81
  function isAssertionError(error) {
78
82
  return error instanceof EventAssertionError;
79
83
  }
84
+ function assertEvent(envelope, value, message) {
85
+ try {
86
+ assert__default.default(value, message);
87
+ } catch {
88
+ throw new EventAssertionError(envelope, message);
89
+ }
90
+ }
80
91
 
81
92
  // src/errors/matador-errors.ts
82
93
  var MatadorError = class extends Error {
@@ -330,6 +341,12 @@ function getDeadLetterQueueName(namespace, queueName, dlqType) {
330
341
  function getRetryQueueName(namespace, queueName) {
331
342
  return `${namespace}.${queueName}.retry`;
332
343
  }
344
+ function resolveQueueName(namespace, queueDef) {
345
+ if (queueDef.exact) {
346
+ return queueDef.name;
347
+ }
348
+ return `${namespace}.${queueDef.name}`;
349
+ }
333
350
 
334
351
  // src/topology/builder.ts
335
352
  function isQueueDefinition(arg) {
@@ -440,7 +457,7 @@ var TopologyBuilder = class _TopologyBuilder {
440
457
  for (const queue of this.queues) {
441
458
  if (!queue.name || queue.name.trim() === "") {
442
459
  issues.push("Queue name cannot be empty");
443
- } else if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(queue.name)) {
460
+ } else if (!queue.exact && !/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(queue.name)) {
444
461
  issues.push(
445
462
  `Queue name "${queue.name}" must start with a letter and contain only alphanumeric characters, underscores, and hyphens`
446
463
  );
@@ -528,6 +545,14 @@ function createEnvelope(options) {
528
545
  }
529
546
  };
530
547
  }
548
+ function createDummyEnvelope(event) {
549
+ return createEnvelope({
550
+ data: event.data,
551
+ eventKey: event.constructor.key,
552
+ targetSubscriber: "dummy-subscriber",
553
+ importance: "can-ignore"
554
+ });
555
+ }
531
556
 
532
557
  // src/types/event.ts
533
558
  var MatadorEvent = class {
@@ -575,7 +600,6 @@ function createSubscriber(input) {
575
600
  function createSubscriberStub(input) {
576
601
  return {
577
602
  name: input.name,
578
- description: input.description,
579
603
  isStub: true,
580
604
  idempotent: input.idempotent ?? "unknown",
581
605
  importance: input.importance ?? "should-investigate",
@@ -1406,6 +1430,7 @@ var ProcessingPipeline = class {
1406
1430
  retryPolicy;
1407
1431
  hooks;
1408
1432
  checkpointStore;
1433
+ dispatcher;
1409
1434
  constructor(config) {
1410
1435
  this.transport = config.transport;
1411
1436
  this.schema = config.schema;
@@ -1413,6 +1438,7 @@ var ProcessingPipeline = class {
1413
1438
  this.retryPolicy = config.retryPolicy;
1414
1439
  this.hooks = config.hooks;
1415
1440
  this.checkpointStore = config.checkpointStore ?? new NoOpCheckpointStore();
1441
+ this.dispatcher = config.dispatcher;
1416
1442
  }
1417
1443
  /**
1418
1444
  * Processes a raw message from the transport.
@@ -1499,15 +1525,23 @@ var ProcessingPipeline = class {
1499
1525
  }
1500
1526
  });
1501
1527
  }
1528
+ const callbackContext = { matador: this.dispatcher };
1502
1529
  await this.hooks.onWorkerWrap(envelope, subscriberDef, async () => {
1503
1530
  await this.hooks.onWorkerBeforeProcess(envelope, subscriberDef);
1504
1531
  try {
1505
1532
  if (isResumable && context) {
1506
1533
  const resumableCallback = subscriber.callback;
1507
- result = await resumableCallback(envelope, context);
1534
+ const fullContext = {
1535
+ io: context.io.bind(context),
1536
+ all: context.all.bind(context),
1537
+ attempt: context.attempt,
1538
+ isRetry: context.isRetry,
1539
+ matador: this.dispatcher
1540
+ };
1541
+ result = await resumableCallback(envelope, fullContext);
1508
1542
  } else {
1509
1543
  const standardCallback = subscriber.callback;
1510
- result = await standardCallback(envelope);
1544
+ result = await standardCallback(envelope, callbackContext);
1511
1545
  }
1512
1546
  } catch (e) {
1513
1547
  error = e instanceof Error ? e : new Error(String(e));
@@ -1818,9 +1852,11 @@ var SchemaRegistry = class {
1818
1852
  if (!subscriber) return void 0;
1819
1853
  const def = {
1820
1854
  name: subscriber.name,
1821
- description: subscriber.description,
1822
1855
  idempotent: subscriber.idempotent ?? "unknown",
1823
- importance: subscriber.importance ?? "should-investigate"
1856
+ importance: subscriber.importance ?? "should-investigate",
1857
+ ..."description" in subscriber && subscriber.description !== void 0 && {
1858
+ description: subscriber.description
1859
+ }
1824
1860
  };
1825
1861
  if (subscriber.targetQueue !== void 0) {
1826
1862
  def.targetQueue = subscriber.targetQueue;
@@ -1940,7 +1976,8 @@ var Matador = class {
1940
1976
  codec: this.codec,
1941
1977
  retryPolicy: this.retryPolicy,
1942
1978
  hooks: this.hooks,
1943
- checkpointStore: config.checkpointStore
1979
+ checkpointStore: config.checkpointStore,
1980
+ dispatcher: this
1944
1981
  });
1945
1982
  const defaultQueue = this.topology.queues[0]?.name ?? "default";
1946
1983
  this.fanout = new FanoutEngine({
@@ -2986,24 +3023,29 @@ var RabbitMQTransport = class {
2986
3023
  }
2987
3024
  async assertWorkQueue(channel, topology, queueDef) {
2988
3025
  const queueName = queueDef.exact ? queueDef.name : `${topology.namespace}.${queueDef.name}`;
2989
- const queueOptions = {
2990
- durable: true,
2991
- arguments: {}
2992
- };
2993
- if (this.config.quorumQueues && !queueDef.exact) {
2994
- queueOptions.arguments["x-queue-type"] = "quorum";
2995
- }
2996
- const dlxExchange = this.getDLXExchangeName(topology.namespace);
2997
- if (topology.deadLetter.unhandled.enabled || topology.deadLetter.undeliverable.enabled) {
2998
- queueOptions.arguments["x-dead-letter-exchange"] = dlxExchange;
2999
- }
3000
- if (queueDef.priorities) {
3001
- queueOptions.arguments["x-max-priority"] = 10;
3002
- }
3003
- if (queueDef.consumerTimeout) {
3004
- queueOptions.arguments["x-consumer-timeout"] = queueDef.consumerTimeout;
3026
+ const rabbitmqOptions = queueDef.transport?.rabbitmq?.options;
3027
+ if (rabbitmqOptions) {
3028
+ await channel.assertQueue(queueName, rabbitmqOptions);
3029
+ } else {
3030
+ const queueOptions = {
3031
+ durable: true,
3032
+ arguments: {}
3033
+ };
3034
+ if (this.config.quorumQueues && !queueDef.exact) {
3035
+ queueOptions.arguments["x-queue-type"] = "quorum";
3036
+ }
3037
+ const dlxExchange = this.getDLXExchangeName(topology.namespace);
3038
+ if (topology.deadLetter.unhandled.enabled || topology.deadLetter.undeliverable.enabled) {
3039
+ queueOptions.arguments["x-dead-letter-exchange"] = dlxExchange;
3040
+ }
3041
+ if (queueDef.priorities) {
3042
+ queueOptions.arguments["x-max-priority"] = 10;
3043
+ }
3044
+ if (queueDef.consumerTimeout) {
3045
+ queueOptions.arguments["x-consumer-timeout"] = queueDef.consumerTimeout;
3046
+ }
3047
+ await channel.assertQueue(queueName, queueOptions);
3005
3048
  }
3006
- await channel.assertQueue(queueName, queueOptions);
3007
3049
  const mainExchange = this.getMainExchangeName(topology.namespace);
3008
3050
  await channel.bindQueue(queueName, mainExchange, queueName);
3009
3051
  if (this.delayedExchangeAvailable) {
@@ -3144,8 +3186,10 @@ exports.TopologyValidationError = TopologyValidationError;
3144
3186
  exports.TransportClosedError = TransportClosedError;
3145
3187
  exports.TransportNotConnectedError = TransportNotConnectedError;
3146
3188
  exports.TransportSendError = TransportSendError;
3189
+ exports.assertEvent = assertEvent;
3147
3190
  exports.bind = bind;
3148
3191
  exports.consoleLogger = consoleLogger;
3192
+ exports.createDummyEnvelope = createDummyEnvelope;
3149
3193
  exports.createEnvelope = createEnvelope;
3150
3194
  exports.createSubscriber = createSubscriber;
3151
3195
  exports.createSubscriberStub = createSubscriberStub;
@@ -3174,6 +3218,7 @@ exports.isSubscriber = isSubscriber;
3174
3218
  exports.isSubscriberNotRegisteredError = isSubscriberNotRegisteredError;
3175
3219
  exports.isSubscriberStub = isSubscriberStub;
3176
3220
  exports.isTransportNotConnectedError = isTransportNotConnectedError;
3221
+ exports.resolveQueueName = resolveQueueName;
3177
3222
  exports.supportsDelayedMessages = supportsDelayedMessages;
3178
3223
  exports.supportsDeliveryMode = supportsDeliveryMode;
3179
3224
  exports.validResult = validResult;