@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
@@ -4,7 +4,7 @@ import type { SafeHooks } from '../hooks/index.js';
4
4
  import type { RetryDecision, RetryPolicy } from '../retry/index.js';
5
5
  import type { SchemaRegistry } from '../schema/index.js';
6
6
  import type { MessageReceipt, Transport } from '../transport/index.js';
7
- import type { Envelope, SubscriberDefinition } from '../types/index.js';
7
+ import type { Dispatcher, Envelope, SubscriberDefinition } from '../types/index.js';
8
8
  /**
9
9
  * Configuration for the processing pipeline.
10
10
  */
@@ -16,6 +16,8 @@ export interface PipelineConfig {
16
16
  readonly hooks: SafeHooks;
17
17
  /** Optional checkpoint store for resumable subscribers */
18
18
  readonly checkpointStore?: CheckpointStore | undefined;
19
+ /** Dispatcher (matador) for sending events from subscriber callbacks */
20
+ readonly dispatcher: Dispatcher;
19
21
  }
20
22
  /**
21
23
  * Result of pipeline processing.
@@ -44,6 +46,7 @@ export declare class ProcessingPipeline {
44
46
  private readonly retryPolicy;
45
47
  private readonly hooks;
46
48
  private readonly checkpointStore;
49
+ private readonly dispatcher;
47
50
  constructor(config: PipelineConfig);
48
51
  /**
49
52
  * Processes a raw message from the transport.
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/pipeline/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE1E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAM/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGxE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;gBAEtC,MAAM,EAAE,cAAc;IASlC;;OAEG;IACG,OAAO,CACX,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC;YAgNX,mBAAmB;YAqCnB,gBAAgB;IAkB9B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;CA+BlC"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/pipeline/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE1E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAM/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAEV,UAAU,EACV,QAAQ,EAER,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAG3B;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACvD,wEAAwE;IACxE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;gBAE5B,MAAM,EAAE,cAAc;IAUlC;;OAEG;IACG,OAAO,CACX,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC;YA4NX,mBAAmB;YAqCnB,gBAAgB;IAkB9B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;CA+BlC"}
@@ -18,6 +18,7 @@ export class ProcessingPipeline {
18
18
  retryPolicy;
19
19
  hooks;
20
20
  checkpointStore;
21
+ dispatcher;
21
22
  constructor(config) {
22
23
  this.transport = config.transport;
23
24
  this.schema = config.schema;
@@ -25,6 +26,7 @@ export class ProcessingPipeline {
25
26
  this.retryPolicy = config.retryPolicy;
26
27
  this.hooks = config.hooks;
27
28
  this.checkpointStore = config.checkpointStore ?? new NoOpCheckpointStore();
29
+ this.dispatcher = config.dispatcher;
28
30
  }
29
31
  /**
30
32
  * Processes a raw message from the transport.
@@ -113,19 +115,29 @@ export class ProcessingPipeline {
113
115
  },
114
116
  });
115
117
  }
118
+ // Create base callback context with matador dispatcher
119
+ const callbackContext = { matador: this.dispatcher };
116
120
  await this.hooks.onWorkerWrap(envelope, subscriberDef, async () => {
117
121
  await this.hooks.onWorkerBeforeProcess(envelope, subscriberDef);
118
122
  try {
119
123
  if (isResumable && context) {
120
- // Resumable subscriber: pass context as second argument
124
+ // Resumable subscriber: pass combined context (checkpoint + matador)
121
125
  // Cast needed because TypeScript can't narrow the union type based on isResumable
122
126
  const resumableCallback = subscriber.callback;
123
- result = await resumableCallback(envelope, context);
127
+ // Create combined context by binding class methods and adding matador
128
+ const fullContext = {
129
+ io: context.io.bind(context),
130
+ all: context.all.bind(context),
131
+ attempt: context.attempt,
132
+ isRetry: context.isRetry,
133
+ matador: this.dispatcher,
134
+ };
135
+ result = await resumableCallback(envelope, fullContext);
124
136
  }
125
137
  else {
126
- // Standard subscriber: just pass envelope
138
+ // Standard subscriber: pass envelope and callback context
127
139
  const standardCallback = subscriber.callback;
128
- result = await standardCallback(envelope);
140
+ result = await standardCallback(envelope, callbackContext);
129
141
  }
130
142
  }
131
143
  catch (e) {
@@ -255,7 +255,11 @@ describe('ProcessingPipeline', () => {
255
255
  const receipt = createReceipt();
256
256
  const result = await pipeline.process(new Uint8Array(), receipt);
257
257
  expect(result.success).toBe(true);
258
- expect(callbackMock).toHaveBeenCalledWith(envelope);
258
+ expect(callbackMock).toHaveBeenCalledTimes(1);
259
+ // Callback receives envelope as first argument and context (with matador) as second
260
+ const calls = callbackMock.mock.calls;
261
+ expect(calls[0][0]).toEqual(envelope);
262
+ expect(calls[0][1]).toHaveProperty('matador');
259
263
  });
260
264
  it('should handle callback throwing error', async () => {
261
265
  const envelope = createTestEnvelope();
@@ -422,6 +426,39 @@ describe('ProcessingPipeline', () => {
422
426
  transport: 'mock',
423
427
  });
424
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
+ });
425
462
  it('should call onWorkerError after failed callback', async () => {
426
463
  const envelope = createTestEnvelope();
427
464
  const subscriberDef = createSubscriberDefinition();
@@ -1027,12 +1064,22 @@ function createMockConfig(overrides = {}) {
1027
1064
  onDecodeError: async () => { },
1028
1065
  ...overrides.hooks,
1029
1066
  };
1067
+ const defaultDispatcher = {
1068
+ send: mock(async () => ({
1069
+ eventKey: 'test.event',
1070
+ subscribersSent: 0,
1071
+ subscribersSkipped: 0,
1072
+ errors: [],
1073
+ })),
1074
+ ...overrides.dispatcher,
1075
+ };
1030
1076
  return {
1031
1077
  transport: defaultTransport,
1032
1078
  schema: { ...defaultSchema, ...overrides.schema },
1033
1079
  codec: defaultCodec,
1034
1080
  retryPolicy: defaultRetryPolicy,
1035
1081
  hooks: defaultHooks,
1082
+ dispatcher: defaultDispatcher,
1036
1083
  };
1037
1084
  }
1038
1085
  function createTestEnvelope() {
@@ -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 = {
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/topology/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;AAWzD;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,KAAM,YAAW,cAAc;aASxD,MAAM,EAAE,SAAS,MAAM,EAAE;IAR3C,QAAQ,CAAC,WAAW,SAIuC;gBAGzD,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,SAAS,MAAM,EAAE;CAK5C;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,eAAe;IAIhC,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,UAAU,CAGhB;IACF,OAAO,CAAC,KAAK,CAIX;IAEF;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKtC;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAapD;;;OAGG;IACH,KAAK,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IACxC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAWjD;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAQvD;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAS7C;;OAEG;IACH,YAAY,IAAI,IAAI;IAKpB;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAQzB;;OAEG;IACH,QAAQ,IAAI,SAAS,MAAM,EAAE;IAsD7B;;;OAGG;IACH,KAAK,IAAI,QAAQ;CAgBlB"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/topology/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;AAWzD;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,KAAM,YAAW,cAAc;aASxD,MAAM,EAAE,SAAS,MAAM,EAAE;IAR3C,QAAQ,CAAC,WAAW,SAIuC;gBAGzD,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,SAAS,MAAM,EAAE;CAK5C;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,eAAe;IAIhC,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,UAAU,CAGhB;IACF,OAAO,CAAC,KAAK,CAIX;IAEF;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKtC;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAapD;;;OAGG;IACH,KAAK,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IACxC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI;IAWjD;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAQvD;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAS7C;;OAEG;IACH,YAAY,IAAI,IAAI;IAKpB;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAQzB;;OAEG;IACH,QAAQ,IAAI,SAAS,MAAM,EAAE;IAuD7B;;;OAGG;IACH,KAAK,IAAI,QAAQ;CAgBlB"}
@@ -119,7 +119,8 @@ export class TopologyBuilder {
119
119
  if (!queue.name || queue.name.trim() === '') {
120
120
  issues.push('Queue name cannot be empty');
121
121
  }
122
- else if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(queue.name)) {
122
+ else if (!queue.exact && !/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(queue.name)) {
123
+ // Skip pattern validation for exact queues (allows names like 'matador.shared.id-platform')
123
124
  issues.push(`Queue name "${queue.name}" must start with a letter and contain only alphanumeric characters, underscores, and hyphens`);
124
125
  }
125
126
  else if (queueNames.has(queue.name)) {
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, it } from 'bun:test';
2
2
  import { TopologyBuilder, TopologyValidationError } from './builder.js';
3
+ import { resolveQueueName } from './types.js';
3
4
  describe('TopologyBuilder', () => {
4
5
  describe('withNamespace', () => {
5
6
  it('should set the namespace', () => {
@@ -218,6 +219,44 @@ describe('TopologyBuilder', () => {
218
219
  .build();
219
220
  expect(topology.queues[0]?.exact).toBe(true);
220
221
  });
222
+ it('should allow dots in queue name when exact: true', () => {
223
+ const topology = TopologyBuilder.create()
224
+ .withNamespace('test')
225
+ .addQueue('matador.shared.id-platform', { exact: true })
226
+ .build();
227
+ expect(topology.queues[0]?.name).toBe('matador.shared.id-platform');
228
+ expect(topology.queues[0]?.exact).toBe(true);
229
+ });
230
+ it('should reject dots in queue name when exact: false', () => {
231
+ const builder = TopologyBuilder.create()
232
+ .withNamespace('test')
233
+ .addQueue('invalid.queue.name');
234
+ expect(() => builder.build()).toThrow('must start with a letter');
235
+ });
236
+ it('should allow transport-specific RabbitMQ options with exact queue', () => {
237
+ const topology = TopologyBuilder.create()
238
+ .withNamespace('test')
239
+ .addQueue('matador.shared.id-platform', {
240
+ exact: true,
241
+ transport: {
242
+ rabbitmq: {
243
+ options: {
244
+ durable: true,
245
+ deadLetterExchange: 'matador.shared.dlx-undeliverable',
246
+ arguments: {
247
+ 'x-queue-type': 'quorum',
248
+ },
249
+ },
250
+ },
251
+ },
252
+ })
253
+ .build();
254
+ expect(topology.queues[0]?.name).toBe('matador.shared.id-platform');
255
+ expect(topology.queues[0]?.exact).toBe(true);
256
+ expect(topology.queues[0]?.transport?.rabbitmq?.options?.durable).toBe(true);
257
+ expect(topology.queues[0]?.transport?.rabbitmq?.options?.deadLetterExchange).toBe('matador.shared.dlx-undeliverable');
258
+ expect(topology.queues[0]?.transport?.rabbitmq?.options?.arguments?.['x-queue-type']).toBe('quorum');
259
+ });
221
260
  });
222
261
  describe('addQueue with QueueDefinition object', () => {
223
262
  it('should accept a QueueDefinition object', () => {
@@ -290,3 +329,32 @@ describe('TopologyBuilder', () => {
290
329
  });
291
330
  });
292
331
  });
332
+ describe('resolveQueueName', () => {
333
+ it('should return namespace.name for regular queues', () => {
334
+ const queueDef = { name: 'events' };
335
+ expect(resolveQueueName('myapp', queueDef)).toBe('myapp.events');
336
+ });
337
+ it('should return name as-is when exact: true', () => {
338
+ const queueDef = { name: 'matador.shared.id-platform', exact: true };
339
+ expect(resolveQueueName('myapp', queueDef)).toBe('matador.shared.id-platform');
340
+ });
341
+ it('should return namespace.name when exact: false', () => {
342
+ const queueDef = { name: 'events', exact: false };
343
+ expect(resolveQueueName('myapp', queueDef)).toBe('myapp.events');
344
+ });
345
+ it('should work with full QueueDefinition including transport options', () => {
346
+ const queueDef = {
347
+ name: 'matador.shared.id-platform',
348
+ exact: true,
349
+ transport: {
350
+ rabbitmq: {
351
+ options: {
352
+ durable: true,
353
+ deadLetterExchange: 'matador.shared.dlx-undeliverable',
354
+ },
355
+ },
356
+ },
357
+ };
358
+ expect(resolveQueueName('myapp', queueDef)).toBe('matador.shared.id-platform');
359
+ });
360
+ });
@@ -1,5 +1,5 @@
1
- export type { DeadLetterConfig, DeadLetterQueueConfig, QueueDefinition, RetryConfig, Topology, } from './types.js';
2
- export { getDeadLetterQueueName, getQualifiedQueueName, getRetryQueueName, } from './types.js';
1
+ export type { DeadLetterConfig, DeadLetterQueueConfig, QueueDefinition, RabbitMQQueueDefinition, RabbitMQQueueOptions, RetryConfig, Topology, TransportQueueOptions, } from './types.js';
2
+ export { getDeadLetterQueueName, getQualifiedQueueName, getRetryQueueName, resolveQueueName, } from './types.js';
3
3
  export type { QueueOptions } from './builder.js';
4
4
  export { TopologyBuilder, TopologyValidationError } from './builder.js';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/topology/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,QAAQ,GACT,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/topology/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,WAAW,EACX,QAAQ,EACR,qBAAqB,GACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
@@ -1,2 +1,2 @@
1
- export { getDeadLetterQueueName, getQualifiedQueueName, getRetryQueueName, } from './types.js';
1
+ export { getDeadLetterQueueName, getQualifiedQueueName, getRetryQueueName, resolveQueueName, } from './types.js';
2
2
  export { TopologyBuilder, TopologyValidationError } from './builder.js';
@@ -16,7 +16,7 @@ export interface Topology {
16
16
  * Individual queue definition.
17
17
  */
18
18
  export interface QueueDefinition {
19
- /** Queue name (will be prefixed with namespace) */
19
+ /** Queue name (will be prefixed with namespace unless exact: true) */
20
20
  readonly name: string;
21
21
  /** Concurrency for this queue */
22
22
  readonly concurrency?: number | undefined;
@@ -31,6 +31,53 @@ export interface QueueDefinition {
31
31
  * queues that are not managed by Matador.
32
32
  */
33
33
  readonly exact?: boolean | undefined;
34
+ /** Transport-specific queue options */
35
+ readonly transport?: TransportQueueOptions | undefined;
36
+ }
37
+ /**
38
+ * Transport-specific queue options.
39
+ * Each transport can define its own options under its transport name key.
40
+ */
41
+ export interface TransportQueueOptions {
42
+ /** RabbitMQ-specific queue options */
43
+ readonly rabbitmq?: RabbitMQQueueDefinition | undefined;
44
+ }
45
+ /**
46
+ * RabbitMQ-specific queue definition options.
47
+ */
48
+ export interface RabbitMQQueueDefinition {
49
+ /**
50
+ * Exact RabbitMQ queue assertion options.
51
+ * When provided, these options completely replace all auto-computed defaults
52
+ * (durable, x-queue-type, x-dead-letter-exchange, etc.).
53
+ */
54
+ readonly options?: RabbitMQQueueOptions | undefined;
55
+ }
56
+ /**
57
+ * RabbitMQ queue assertion options.
58
+ * Maps to amqplib's Options.AssertQueue.
59
+ */
60
+ export interface RabbitMQQueueOptions {
61
+ /** Queue survives broker restart */
62
+ readonly durable?: boolean | undefined;
63
+ /** Queue is deleted when last consumer unsubscribes */
64
+ readonly autoDelete?: boolean | undefined;
65
+ /** Queue can only be used by the declaring connection */
66
+ readonly exclusive?: boolean | undefined;
67
+ /** Exchange to which dead-lettered messages are sent */
68
+ readonly deadLetterExchange?: string | undefined;
69
+ /** Routing key for dead-lettered messages */
70
+ readonly deadLetterRoutingKey?: string | undefined;
71
+ /** Message TTL in milliseconds */
72
+ readonly messageTtl?: number | undefined;
73
+ /** Queue expires after this many milliseconds of non-use */
74
+ readonly expires?: number | undefined;
75
+ /** Maximum number of messages in the queue */
76
+ readonly maxLength?: number | undefined;
77
+ /** Maximum priority level (0-255) */
78
+ readonly maxPriority?: number | undefined;
79
+ /** Additional x-* arguments for RabbitMQ */
80
+ readonly arguments?: Record<string, unknown> | undefined;
34
81
  }
35
82
  /**
36
83
  * Dead-letter queue configuration.
@@ -73,4 +120,9 @@ export declare function getDeadLetterQueueName(namespace: string, queueName: str
73
120
  * Gets the retry queue name for a given queue.
74
121
  */
75
122
  export declare function getRetryQueueName(namespace: string, queueName: string): string;
123
+ /**
124
+ * Resolves the actual queue name for a given queue definition.
125
+ * When exact: true, returns name as-is. Otherwise, returns namespace.name.
126
+ */
127
+ export declare function resolveQueueName(namespace: string, queueDef: QueueDefinition): string;
76
128
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/topology/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,sCAAsC;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAE5C,sCAAsC;IACtC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEtC,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,iCAAiC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE1C,uCAAuC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE9C,kDAAkD;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAE1C;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,qBAAqB,CAAC;IAE1C,sDAAsD;IACtD,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,kCAAkC;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,0CAA0C;IAC1C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,0CAA0C;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,WAAW,GAAG,eAAe,GACrC,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/topology/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,sCAAsC;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAE5C,sCAAsC;IACtC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IAEtC,gCAAgC;IAChC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,iCAAiC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE1C,uCAAuC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE9C,kDAAkD;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAE1C;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAErC,uCAAuC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;CACxD;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;CACzD;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;CACrD;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,oCAAoC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAEvC,uDAAuD;IACvD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAE1C,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAEzC,wDAAwD;IACxD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjD,6CAA6C;IAC7C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnD,kCAAkC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEzC,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAExC,qCAAqC;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE1C,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC1D;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,qBAAqB,CAAC;IAE1C,sDAAsD;IACtD,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,kCAAkC;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,0CAA0C;IAC1C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,0CAA0C;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,WAAW,GAAG,eAAe,GACrC,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GACxB,MAAM,CAKR"}
@@ -16,3 +16,13 @@ export function getDeadLetterQueueName(namespace, queueName, dlqType) {
16
16
  export function getRetryQueueName(namespace, queueName) {
17
17
  return `${namespace}.${queueName}.retry`;
18
18
  }
19
+ /**
20
+ * Resolves the actual queue name for a given queue definition.
21
+ * When exact: true, returns name as-is. Otherwise, returns namespace.name.
22
+ */
23
+ export function resolveQueueName(namespace, queueDef) {
24
+ if (queueDef.exact) {
25
+ return queueDef.name;
26
+ }
27
+ return `${namespace}.${queueDef.name}`;
28
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"rabbitmq-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/rabbitmq/rabbitmq-transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rabbitmq-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/rabbitmq/rabbitmq-transport.ts"],"names":[],"mappings":"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"}
@@ -407,29 +407,37 @@ export class RabbitMQTransport {
407
407
  const queueName = queueDef.exact
408
408
  ? queueDef.name
409
409
  : `${topology.namespace}.${queueDef.name}`;
410
- const queueOptions = {
411
- durable: true,
412
- arguments: {},
413
- };
414
- // Use quorum queues for durability
415
- if (this.config.quorumQueues && !queueDef.exact) {
416
- queueOptions.arguments['x-queue-type'] = 'quorum';
417
- }
418
- // Set up dead-letter exchange routing
419
- const dlxExchange = this.getDLXExchangeName(topology.namespace);
420
- if (topology.deadLetter.unhandled.enabled ||
421
- topology.deadLetter.undeliverable.enabled) {
422
- queueOptions.arguments['x-dead-letter-exchange'] = dlxExchange;
423
- }
424
- // Enable priority if requested
425
- if (queueDef.priorities) {
426
- queueOptions.arguments['x-max-priority'] = 10;
427
- }
428
- // Set consumer timeout if specified
429
- if (queueDef.consumerTimeout) {
430
- queueOptions.arguments['x-consumer-timeout'] = queueDef.consumerTimeout;
410
+ const rabbitmqOptions = queueDef.transport?.rabbitmq?.options;
411
+ // If user provided exact RabbitMQ options, use them directly (replaces all defaults)
412
+ if (rabbitmqOptions) {
413
+ await channel.assertQueue(queueName, rabbitmqOptions);
414
+ }
415
+ else {
416
+ // Use computed defaults
417
+ const queueOptions = {
418
+ durable: true,
419
+ arguments: {},
420
+ };
421
+ // Use quorum queues for durability
422
+ if (this.config.quorumQueues && !queueDef.exact) {
423
+ queueOptions.arguments['x-queue-type'] = 'quorum';
424
+ }
425
+ // Set up dead-letter exchange routing
426
+ const dlxExchange = this.getDLXExchangeName(topology.namespace);
427
+ if (topology.deadLetter.unhandled.enabled ||
428
+ topology.deadLetter.undeliverable.enabled) {
429
+ queueOptions.arguments['x-dead-letter-exchange'] = dlxExchange;
430
+ }
431
+ // Enable priority if requested
432
+ if (queueDef.priorities) {
433
+ queueOptions.arguments['x-max-priority'] = 10;
434
+ }
435
+ // Set consumer timeout if specified
436
+ if (queueDef.consumerTimeout) {
437
+ queueOptions.arguments['x-consumer-timeout'] = queueDef.consumerTimeout;
438
+ }
439
+ await channel.assertQueue(queueName, queueOptions);
431
440
  }
432
- await channel.assertQueue(queueName, queueOptions);
433
441
  // Bind queue to main exchange
434
442
  const mainExchange = this.getMainExchangeName(topology.namespace);
435
443
  await channel.bindQueue(queueName, mainExchange, queueName);
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it, mock } from 'bun:test';
2
- import { redactAmqpUrl, RabbitMQTransport } from './rabbitmq-transport.js';
2
+ import { RabbitMQTransport, redactAmqpUrl } from './rabbitmq-transport.js';
3
3
  describe('redactAmqpUrl', () => {
4
4
  it('should redact username and password with 4 asterisks', () => {
5
5
  const url = 'amqp://myuser:mypassword@localhost:5672';
@@ -0,0 +1,14 @@
1
+ import type { SendResult } from '../core/fanout.js';
2
+ import type { Event, EventClass, EventOptions } from './event.js';
3
+ /**
4
+ * Interface for dispatching events.
5
+ * Implemented by Matador to allow subscribers to send events.
6
+ */
7
+ export interface Dispatcher {
8
+ /**
9
+ * Sends an event to all registered subscribers.
10
+ */
11
+ send<T>(eventClass: EventClass<T>, data: T, options?: EventOptions): Promise<SendResult>;
12
+ send<T>(event: Event<T>, options?: EventOptions): Promise<SendResult>;
13
+ }
14
+ //# sourceMappingURL=dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/types/dispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,CAAC,CAAC,EACJ,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,UAAU,CAAC,CAAC;IACvB,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACvE"}
@@ -0,0 +1 @@
1
+ export {};
@@ -78,5 +78,22 @@ 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>(event: {
93
+ data: T;
94
+ constructor: {
95
+ key: string;
96
+ };
97
+ }): Envelope<T>;
81
98
  export {};
82
99
  //# 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,KAAK,EAAE;IAC5C,IAAI,EAAE,CAAC,CAAC;IACR,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9B,GAAG,QAAQ,CAAC,CAAC,CAAC,CAOd"}
@@ -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(event) {
49
+ return createEnvelope({
50
+ data: event.data,
51
+ eventKey: event.constructor.key,
52
+ targetSubscriber: 'dummy-subscriber',
53
+ importance: 'can-ignore',
54
+ });
55
+ }
@@ -1,9 +1,10 @@
1
1
  export type { DeliveryMode, Idempotency, Importance, ValidationError, ValidationResult, } from './common.js';
2
2
  export { invalidResult, validResult } from './common.js';
3
+ export type { Dispatcher } from './dispatcher.js';
3
4
  export type { CreateEnvelopeOptions, Docket, Envelope } from './envelope.js';
4
- export { createEnvelope } from './envelope.js';
5
+ export { createDummyEnvelope, createEnvelope } from './envelope.js';
5
6
  export type { Event, EventClass, EventData, EventKey, EventOptions, EventStatic, JsonPrimitive, JsonRecord, JsonValue, } from './event.js';
6
7
  export { MatadorEvent } from './event.js';
7
- export type { AnySubscriber, BaseSubscriberOptions, CreateResumableSubscriberInput, CreateStandardSubscriberInput, CreateSubscriberInput, EnvelopeOf, ResumableCallback, ResumableSubscriber, ResumableSubscriberOptions, StandardCallback, StandardSubscriber, StandardSubscriberOptions, Subscriber, SubscriberCallback, SubscriberDefinition, SubscriberOptions, SubscriberStub, } from './subscriber.js';
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';
8
9
  export { createSubscriber, createSubscriberStub, isResumableSubscriber, isStandardSubscriber, isSubscriber, isSubscriberStub, } from './subscriber.js';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -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,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,8BAA8B,EAC9B,6BAA6B,EAC7B,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,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';