@haskou/ddd-kernel 0.1.1 → 1.0.1

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 (120) hide show
  1. package/README.md +5 -10
  2. package/dist/DomainEventConsumer-Bg-bOwmh.d.cts +11 -0
  3. package/dist/DomainEventConsumer-BroJmVty.d.ts +11 -0
  4. package/dist/DomainMessageBus-3jYk7TPw.d.ts +13 -0
  5. package/dist/DomainMessageBus-OyliPu3Z.d.cts +13 -0
  6. package/dist/MessageBus-BtUXnd0Y.d.cts +10 -0
  7. package/dist/MessageBus-oQ9BnW84.d.ts +10 -0
  8. package/dist/{NoFailedMessagesError-0YJKRWPF.d.ts → NoFailedMessagesError-BLpGI-G4.d.ts} +6 -1
  9. package/dist/{NoFailedMessagesError-Kz7CYWpT.d.cts → NoFailedMessagesError-BjxYoKTR.d.cts} +6 -1
  10. package/dist/PublisherHookErrorPolicy-CjouTcSR.d.cts +8 -0
  11. package/dist/PublisherHookErrorPolicy-DSsCNE6O.d.ts +8 -0
  12. package/dist/RetryPredicate-U7dYnQ4N.d.ts +15 -0
  13. package/dist/RetryPredicate-yT_z9zk1.d.cts +15 -0
  14. package/dist/{Scheduler-oigqNOUJ.d.ts → Scheduler-BW-U5Ccg.d.cts} +1 -1
  15. package/dist/{Scheduler-oigqNOUJ.d.cts → Scheduler-BW-U5Ccg.d.ts} +1 -1
  16. package/dist/ServiceClass-BkEHcXDi.d.cts +72 -0
  17. package/dist/ServiceClass-Bq_fBC5R.d.ts +72 -0
  18. package/dist/{Kernel-BWUOUWWI.d.cts → ShutdownHook-BjbnCKzr.d.cts} +49 -7
  19. package/dist/{Kernel-CUaqHa1s.d.ts → ShutdownHook-CMWLsfu-.d.ts} +49 -7
  20. package/dist/Subscription-4vuAAxax.d.cts +23 -0
  21. package/dist/Subscription-vtF0lEHP.d.ts +23 -0
  22. package/dist/adapters/index.cjs +665 -37
  23. package/dist/adapters/index.cjs.map +1 -1
  24. package/dist/adapters/index.d.cts +15 -13
  25. package/dist/adapters/index.d.ts +15 -13
  26. package/dist/adapters/index.js +659 -37
  27. package/dist/adapters/index.js.map +1 -1
  28. package/dist/adapters/pubsub/amqp/index.cjs +241 -16
  29. package/dist/adapters/pubsub/amqp/index.cjs.map +1 -1
  30. package/dist/adapters/pubsub/amqp/index.d.cts +16 -8
  31. package/dist/adapters/pubsub/amqp/index.d.ts +16 -8
  32. package/dist/adapters/pubsub/amqp/index.js +241 -16
  33. package/dist/adapters/pubsub/amqp/index.js.map +1 -1
  34. package/dist/adapters/pubsub/in-memory/index.cjs +96 -8
  35. package/dist/adapters/pubsub/in-memory/index.cjs.map +1 -1
  36. package/dist/adapters/pubsub/in-memory/index.d.cts +9 -3
  37. package/dist/adapters/pubsub/in-memory/index.d.ts +9 -3
  38. package/dist/adapters/pubsub/in-memory/index.js +96 -8
  39. package/dist/adapters/pubsub/in-memory/index.js.map +1 -1
  40. package/dist/adapters/pubsub/index.cjs +397 -27
  41. package/dist/adapters/pubsub/index.cjs.map +1 -1
  42. package/dist/adapters/pubsub/index.d.cts +89 -7
  43. package/dist/adapters/pubsub/index.d.ts +89 -7
  44. package/dist/adapters/pubsub/index.js +389 -26
  45. package/dist/adapters/pubsub/index.js.map +1 -1
  46. package/dist/adapters/ui/express/index.cjs +279 -11
  47. package/dist/adapters/ui/express/index.cjs.map +1 -1
  48. package/dist/adapters/ui/express/index.d.cts +127 -12
  49. package/dist/adapters/ui/express/index.d.ts +127 -12
  50. package/dist/adapters/ui/express/index.js +270 -11
  51. package/dist/adapters/ui/express/index.js.map +1 -1
  52. package/dist/adapters/ui/index.cjs +412 -27
  53. package/dist/adapters/ui/index.cjs.map +1 -1
  54. package/dist/adapters/ui/index.d.cts +7 -8
  55. package/dist/adapters/ui/index.d.ts +7 -8
  56. package/dist/adapters/ui/index.js +413 -27
  57. package/dist/adapters/ui/index.js.map +1 -1
  58. package/dist/adapters/ui/routes/index.cjs +136 -9
  59. package/dist/adapters/ui/routes/index.cjs.map +1 -1
  60. package/dist/adapters/ui/routes/index.js +136 -9
  61. package/dist/adapters/ui/routes/index.js.map +1 -1
  62. package/dist/contracts/index.cjs +16 -17
  63. package/dist/contracts/index.cjs.map +1 -1
  64. package/dist/contracts/index.d.cts +10 -2
  65. package/dist/contracts/index.d.ts +10 -2
  66. package/dist/contracts/index.js +16 -17
  67. package/dist/contracts/index.js.map +1 -1
  68. package/dist/contracts/kernel/index.cjs.map +1 -1
  69. package/dist/contracts/kernel/index.d.cts +7 -1
  70. package/dist/contracts/kernel/index.d.ts +7 -1
  71. package/dist/contracts/pubsub/index.cjs.map +1 -1
  72. package/dist/contracts/pubsub/index.d.cts +5 -1
  73. package/dist/contracts/pubsub/index.d.ts +5 -1
  74. package/dist/contracts/ui/index.cjs +16 -17
  75. package/dist/contracts/ui/index.cjs.map +1 -1
  76. package/dist/contracts/ui/index.d.cts +16 -16
  77. package/dist/contracts/ui/index.d.ts +16 -16
  78. package/dist/contracts/ui/index.js +16 -17
  79. package/dist/contracts/ui/index.js.map +1 -1
  80. package/dist/domain/index.cjs.map +1 -1
  81. package/dist/domain/index.d.cts +6 -2
  82. package/dist/domain/index.d.ts +6 -2
  83. package/dist/domain/index.js.map +1 -1
  84. package/dist/index.cjs +152 -26
  85. package/dist/index.cjs.map +1 -1
  86. package/dist/index.d.cts +8 -7
  87. package/dist/index.d.ts +8 -7
  88. package/dist/index.js +152 -26
  89. package/dist/index.js.map +1 -1
  90. package/dist/infrastructure/dependency-injection/index.cjs +119 -3
  91. package/dist/infrastructure/dependency-injection/index.cjs.map +1 -1
  92. package/dist/infrastructure/dependency-injection/index.d.cts +4 -1
  93. package/dist/infrastructure/dependency-injection/index.d.ts +4 -1
  94. package/dist/infrastructure/dependency-injection/index.js +119 -3
  95. package/dist/infrastructure/dependency-injection/index.js.map +1 -1
  96. package/dist/infrastructure/express/index.cjs +279 -11
  97. package/dist/infrastructure/express/index.cjs.map +1 -1
  98. package/dist/infrastructure/express/index.d.cts +7 -8
  99. package/dist/infrastructure/express/index.d.ts +7 -8
  100. package/dist/infrastructure/express/index.js +270 -11
  101. package/dist/infrastructure/express/index.js.map +1 -1
  102. package/dist/infrastructure/scheduler/index.cjs +136 -9
  103. package/dist/infrastructure/scheduler/index.cjs.map +1 -1
  104. package/dist/infrastructure/scheduler/index.d.cts +2 -2
  105. package/dist/infrastructure/scheduler/index.d.ts +2 -2
  106. package/dist/infrastructure/scheduler/index.js +136 -9
  107. package/dist/infrastructure/scheduler/index.js.map +1 -1
  108. package/package.json +92 -17
  109. package/dist/Consumer-CC8ZRCsd.d.cts +0 -17
  110. package/dist/Consumer-CeT0Wbxb.d.ts +0 -17
  111. package/dist/DomainEventConsumer-3WBMSSr2.d.cts +0 -7
  112. package/dist/DomainEventConsumer-B4hkIUmP.d.ts +0 -7
  113. package/dist/DomainEventPublisher-8G0lvmdy.d.cts +0 -7
  114. package/dist/DomainEventPublisher-DhGgM3f2.d.ts +0 -7
  115. package/dist/ServiceClass-BmNw8fJj.d.cts +0 -37
  116. package/dist/ServiceClass-C7NCKdSS.d.ts +0 -37
  117. package/dist/ShutdownHook-BGskq2-q.d.ts +0 -9
  118. package/dist/ShutdownHook-Dib5uNKB.d.cts +0 -9
  119. package/dist/Subscription-Bwkb_did.d.ts +0 -9
  120. package/dist/Subscription-P9WROD_6.d.cts +0 -9
@@ -45,6 +45,7 @@ var DependencyInjection = class _DependencyInjection {
45
45
  autowire;
46
46
  loader;
47
47
  container;
48
+ overrideTokenIds = /* @__PURE__ */ new Map();
48
49
  static configure(options) {
49
50
  _DependencyInjection.configuredInstance = new _DependencyInjection(options);
50
51
  return _DependencyInjection.configuredInstance;
@@ -69,6 +70,16 @@ var DependencyInjection = class _DependencyInjection {
69
70
  getServiceClassName(serviceName) {
70
71
  return typeof serviceName === "function" ? serviceName.name : void 0;
71
72
  }
73
+ getOverrideId(prefix, token) {
74
+ const tokenName = this.getServiceClassName(token) ?? String(token);
75
+ return `ddd-kernel.override.${prefix}.${tokenName}`;
76
+ }
77
+ ensureSyntheticService(id, value) {
78
+ const definition = this.container.register(id);
79
+ definition.public = true;
80
+ definition.synthetic = true;
81
+ this.container.set(id, value);
82
+ }
72
83
  parentMatchesService(parentId, serviceClassName) {
73
84
  if (!parentId) {
74
85
  return false;
@@ -80,6 +91,26 @@ var DependencyInjection = class _DependencyInjection {
80
91
  const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
81
92
  return serviceName.endsWith(`__${serviceClassName}__${serviceClassName}`);
82
93
  }
94
+ serviceIdReferencesService(serviceId, serviceClassName) {
95
+ const serviceName = Buffer.from(serviceId, "base64").toString("utf8");
96
+ return serviceName.endsWith(`__${serviceClassName}`);
97
+ }
98
+ getReferenceId(value) {
99
+ if (typeof value === "object" && value !== null && "id" in value && typeof value.id === "string") {
100
+ return value.id;
101
+ }
102
+ return void 0;
103
+ }
104
+ getDefinitionArgumentReferences(definition) {
105
+ return [
106
+ ...definition._args ?? [],
107
+ ...definition._appendArgs ?? [],
108
+ ...definition._overrideArgs ?? []
109
+ ].flatMap((argument) => {
110
+ const referenceId = this.getReferenceId(argument);
111
+ return referenceId ? [referenceId] : [];
112
+ });
113
+ }
83
114
  findConcreteChildServiceId(serviceName) {
84
115
  const serviceClassName = this.getServiceClassName(serviceName);
85
116
  if (!serviceClassName) {
@@ -110,6 +141,86 @@ var DependencyInjection = class _DependencyInjection {
110
141
  );
111
142
  return matches[matches.length - 1];
112
143
  }
144
+ findReferencedServiceIds(serviceName) {
145
+ const serviceClassName = this.getServiceClassName(serviceName);
146
+ if (!serviceClassName) {
147
+ return [];
148
+ }
149
+ return [
150
+ ...new Set(
151
+ [...this.definitions.values()].flatMap(
152
+ (definition) => this.getDefinitionArgumentReferences(definition)
153
+ ).filter(
154
+ (id) => this.serviceIdReferencesService(id, serviceClassName)
155
+ )
156
+ )
157
+ ];
158
+ }
159
+ getOverrideTokenIds(token) {
160
+ const tokenIds = [
161
+ this.findRegisteredServiceId(token),
162
+ this.findAliasServiceId(token),
163
+ ...this.findReferencedServiceIds(token)
164
+ ].filter((id) => id !== void 0);
165
+ const existingTokenIds = [...new Set(tokenIds)];
166
+ if (existingTokenIds.length > 0) {
167
+ return existingTokenIds;
168
+ }
169
+ const overrideTokenId = this.getOverrideId("token", token);
170
+ this.ensureSyntheticService(overrideTokenId, void 0);
171
+ return [overrideTokenId];
172
+ }
173
+ getOverrideClassServiceId(ClassDefinition) {
174
+ const registeredServiceId = this.findRegisteredServiceId(ClassDefinition);
175
+ if (registeredServiceId) {
176
+ return registeredServiceId;
177
+ }
178
+ const overrideClassId = this.getOverrideId("class", ClassDefinition);
179
+ this.container.register(overrideClassId, ClassDefinition);
180
+ return overrideClassId;
181
+ }
182
+ applyClassOverride(override) {
183
+ if (!("useClass" in override)) {
184
+ return;
185
+ }
186
+ const tokenIds = this.getOverrideTokenIds(override.token);
187
+ const classId = this.getOverrideClassServiceId(override.useClass);
188
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
189
+ for (const tokenId of tokenIds) {
190
+ this.container.setAlias(tokenId, classId);
191
+ }
192
+ }
193
+ applyFactoryOverride(override) {
194
+ if (!("useFactory" in override)) {
195
+ return;
196
+ }
197
+ const tokenIds = this.getOverrideTokenIds(override.token);
198
+ const factoryId = this.getOverrideId("factory", override.token);
199
+ this.ensureSyntheticService(factoryId, override.useFactory(this));
200
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
201
+ for (const tokenId of tokenIds) {
202
+ this.container.setAlias(tokenId, factoryId);
203
+ }
204
+ }
205
+ applyValueOverride(override) {
206
+ if (!("useValue" in override)) {
207
+ return;
208
+ }
209
+ const tokenIds = this.getOverrideTokenIds(override.token);
210
+ const valueId = this.getOverrideId("value", override.token);
211
+ this.ensureSyntheticService(valueId, override.useValue);
212
+ this.overrideTokenIds.set(override.token, tokenIds[0]);
213
+ for (const tokenId of tokenIds) {
214
+ this.container.setAlias(tokenId, valueId);
215
+ }
216
+ }
217
+ applyOverrides() {
218
+ for (const override of this.options.overrides ?? []) {
219
+ this.applyClassOverride(override);
220
+ this.applyFactoryOverride(override);
221
+ this.applyValueOverride(override);
222
+ }
223
+ }
113
224
  registerParentAliases() {
114
225
  for (const [id, definition] of this.definitions.entries()) {
115
226
  if (definition._abstract === true || !definition._parent) {
@@ -132,17 +243,22 @@ var DependencyInjection = class _DependencyInjection {
132
243
  await this.loader.load(this.options.servicesYamlPath);
133
244
  }
134
245
  this.registerParentAliases();
246
+ this.applyOverrides();
135
247
  await this.container.compile();
136
248
  }
137
249
  getService(serviceName) {
138
- const childServiceId = this.findConcreteChildServiceId(serviceName);
139
- if (childServiceId) {
140
- return this.container.get(childServiceId);
250
+ const overrideTokenId = this.overrideTokenIds.get(serviceName);
251
+ if (overrideTokenId) {
252
+ return this.container.get(overrideTokenId);
141
253
  }
142
254
  const aliasServiceId = this.findAliasServiceId(serviceName);
143
255
  if (aliasServiceId) {
144
256
  return this.container.get(aliasServiceId);
145
257
  }
258
+ const childServiceId = this.findConcreteChildServiceId(serviceName);
259
+ if (childServiceId) {
260
+ return this.container.get(childServiceId);
261
+ }
146
262
  const registeredServiceId = this.findRegisteredServiceId(serviceName);
147
263
  if (registeredServiceId) {
148
264
  return this.container.get(registeredServiceId);
@@ -190,6 +306,9 @@ var Kernel = class _Kernel {
190
306
  static get logger() {
191
307
  return _Kernel.getActiveKernel().logger;
192
308
  }
309
+ static get active() {
310
+ return _Kernel.getActiveKernel();
311
+ }
193
312
  static get rootDirectory() {
194
313
  return process.cwd();
195
314
  }
@@ -258,13 +377,21 @@ var Kernel = class _Kernel {
258
377
  get schedulers() {
259
378
  return this.schedulersList;
260
379
  }
261
- async dependencyInjection() {
262
- this.dependencyInjectionInstance = this.dependencyInjectionInstance ?? DependencyInjection.configure({
263
- containerBuild: process.env.CONTAINER_BUILD === "true",
264
- servicesYamlPath: this.options.servicesYamlPath ?? path2.resolve(_Kernel.configDirectory, "container", "services.yaml"),
265
- sourceDirectory: this.options.sourceDirectory ?? _Kernel.sourceDirectory
266
- });
380
+ getDependencyInjectionOptions(options = {}) {
381
+ return {
382
+ containerBuild: options.containerBuild ?? process.env.CONTAINER_BUILD === "true",
383
+ overrides: options.overrides ?? [],
384
+ servicesYamlPath: options.servicesYamlPath ?? this.options.servicesYamlPath ?? path2.resolve(_Kernel.configDirectory, "container", "services.yaml"),
385
+ sourceDirectory: options.sourceDirectory ?? this.options.sourceDirectory ?? _Kernel.sourceDirectory
386
+ };
387
+ }
388
+ async dependencyInjection(options = {}) {
389
+ _Kernel.state.activeKernel = this;
390
+ this.dependencyInjectionInstance = this.dependencyInjectionInstance ?? DependencyInjection.configure(
391
+ this.getDependencyInjectionOptions(options)
392
+ );
267
393
  await this.dependencyInjectionInstance.compile();
394
+ _Kernel.state.activeKernel = this;
268
395
  }
269
396
  getRoutes() {
270
397
  return this.routes;
@@ -347,21 +474,52 @@ var Kernel = class _Kernel {
347
474
  }
348
475
  };
349
476
 
477
+ // src/adapters/pubsub/ConsumerMiddlewarePipeline.ts
478
+ var ConsumerMiddlewarePipeline = class {
479
+ constructor(middlewares) {
480
+ this.middlewares = middlewares;
481
+ }
482
+ middlewares;
483
+ async run(event, context, handler, index) {
484
+ const middleware = this.middlewares[index];
485
+ if (!middleware) {
486
+ await handler();
487
+ return;
488
+ }
489
+ await middleware.handle(
490
+ event,
491
+ () => this.run(event, context, handler, index + 1),
492
+ context
493
+ );
494
+ }
495
+ async execute(event, context, handler) {
496
+ await this.run(event, context, handler, 0);
497
+ }
498
+ };
499
+
350
500
  // src/adapters/pubsub/Consumer.ts
351
501
  var Consumer = class {
352
502
  constructor(consumer) {
353
503
  this.consumer = consumer;
354
504
  }
355
505
  consumer;
356
- async runMiddleware(event, middlewares, index) {
357
- const middleware = middlewares[index];
358
- if (!middleware) {
359
- await this.handler(event);
360
- return;
361
- }
362
- await middleware.handle(
506
+ async runMiddleware(event, consumerContext) {
507
+ const pipeline = new ConsumerMiddlewarePipeline(Kernel.consumerMiddleware);
508
+ const metadata = consumerContext?.metadata ?? {};
509
+ await pipeline.execute(
363
510
  event,
364
- () => this.runMiddleware(event, middlewares, index + 1)
511
+ {
512
+ causationId: event.getCausationId(),
513
+ correlationId: event.getCorrelationId(),
514
+ eventId: event.eventId,
515
+ eventName: this.eventName,
516
+ exchange: this.exchange,
517
+ kernel: Kernel.active,
518
+ metadata,
519
+ queueName: this.queueName,
520
+ rawMessage: metadata.rawMessage
521
+ },
522
+ () => this.handler(event)
365
523
  );
366
524
  }
367
525
  async init() {
@@ -370,7 +528,7 @@ var Consumer = class {
370
528
  this.eventName,
371
529
  this.domainEvent,
372
530
  this.exchange,
373
- (event) => this.runMiddleware(event, Kernel.consumerMiddleware, 0)
531
+ (event, context) => this.runMiddleware(event, context)
374
532
  );
375
533
  }
376
534
  get(service) {
@@ -379,6 +537,178 @@ var Consumer = class {
379
537
  };
380
538
  var Consumer_default = Consumer;
381
539
 
540
+ // src/adapters/pubsub/CorrelationConsumerMiddleware.ts
541
+ var CorrelationConsumerMiddleware = class {
542
+ constructor(options = {}) {
543
+ this.options = options;
544
+ }
545
+ options;
546
+ async handle(event, next, context) {
547
+ const correlationId = this.options.correlationId?.(event, context) ?? context.correlationId;
548
+ const causationId = this.options.causationId?.(event, context) ?? context.causationId;
549
+ if (correlationId) {
550
+ event.withCorrelationId(correlationId);
551
+ }
552
+ if (causationId) {
553
+ event.withCausationId(causationId);
554
+ }
555
+ await next();
556
+ }
557
+ };
558
+
559
+ // src/adapters/pubsub/DefaultPublisherHookErrorPolicy.ts
560
+ var DefaultPublisherHookErrorPolicy = class {
561
+ handleAfterPublishError(error, context) {
562
+ void error;
563
+ void context;
564
+ }
565
+ shouldFailAfterPublish(error, context) {
566
+ void error;
567
+ void context;
568
+ return false;
569
+ }
570
+ };
571
+
572
+ // src/adapters/pubsub/IdempotencyConsumerMiddleware.ts
573
+ var IdempotencyConsumerMiddleware = class {
574
+ constructor(options) {
575
+ this.options = options;
576
+ }
577
+ options;
578
+ async handleClaimedKey(key, next) {
579
+ const claimed = await this.options.store.claim?.(key);
580
+ if (!claimed) {
581
+ return;
582
+ }
583
+ try {
584
+ await next();
585
+ await (this.options.store.commit?.(key) ?? this.options.store.mark(key));
586
+ } catch (error) {
587
+ await this.options.store.release?.(key);
588
+ throw error;
589
+ }
590
+ }
591
+ async handleLegacyKey(key, next) {
592
+ if (await this.options.store.has(key)) {
593
+ return;
594
+ }
595
+ await next();
596
+ await this.options.store.mark(key);
597
+ }
598
+ async handle(event, next, context) {
599
+ const key = this.options.key?.(event, context) ?? context.eventId;
600
+ if (this.options.store.claim) {
601
+ await this.handleClaimedKey(key, next);
602
+ } else {
603
+ await this.handleLegacyKey(key, next);
604
+ }
605
+ }
606
+ };
607
+
608
+ // src/adapters/pubsub/InMemoryIdempotencyStore.ts
609
+ var InMemoryIdempotencyStore = class {
610
+ claimedKeys = /* @__PURE__ */ new Set();
611
+ handledKeys = /* @__PURE__ */ new Set();
612
+ claim(key) {
613
+ if (this.handledKeys.has(key) || this.claimedKeys.has(key)) {
614
+ return false;
615
+ }
616
+ this.claimedKeys.add(key);
617
+ return true;
618
+ }
619
+ commit(key) {
620
+ this.claimedKeys.delete(key);
621
+ this.handledKeys.add(key);
622
+ }
623
+ release(key) {
624
+ this.claimedKeys.delete(key);
625
+ }
626
+ has(key) {
627
+ return this.handledKeys.has(key);
628
+ }
629
+ mark(key) {
630
+ this.handledKeys.add(key);
631
+ }
632
+ };
633
+
634
+ // src/adapters/pubsub/PublisherHookPipeline.ts
635
+ var PublisherHookPipeline = class {
636
+ constructor(hooks = [], errorPolicy = new DefaultPublisherHookErrorPolicy()) {
637
+ this.errorPolicy = errorPolicy;
638
+ this.hooks.push(...hooks);
639
+ }
640
+ errorPolicy;
641
+ hooks = [];
642
+ async runAfterPublishHooks(context) {
643
+ for (const hook of this.hooks) {
644
+ await this.runAfterPublishHook(hook, context);
645
+ }
646
+ }
647
+ async runAfterPublishHook(hook, context) {
648
+ try {
649
+ await hook.afterPublish?.(context);
650
+ } catch (error) {
651
+ await this.errorPolicy.handleAfterPublishError(error, context);
652
+ if (this.errorPolicy.shouldFailAfterPublish(error, context)) {
653
+ throw error;
654
+ }
655
+ }
656
+ }
657
+ async runBeforePublishHooks(context) {
658
+ for (const hook of this.hooks) {
659
+ await hook.beforePublish?.(context);
660
+ }
661
+ }
662
+ async runPublishErrorHooks(error, context) {
663
+ for (const hook of this.hooks) {
664
+ await hook.onPublishError?.(error, context);
665
+ }
666
+ }
667
+ register(...hooks) {
668
+ this.hooks.push(...hooks);
669
+ }
670
+ async run(context, publish) {
671
+ await this.runBeforePublishHooks(context);
672
+ try {
673
+ const result = await publish();
674
+ await this.runAfterPublishHooks(context);
675
+ return result;
676
+ } catch (error) {
677
+ await this.runPublishErrorHooks(error, context);
678
+ throw error;
679
+ }
680
+ }
681
+ };
682
+
683
+ // src/adapters/pubsub/RetryConsumerMiddleware.ts
684
+ var RetryConsumerMiddleware = class {
685
+ constructor(options) {
686
+ this.options = options;
687
+ }
688
+ options;
689
+ async delay(attempt, error, context) {
690
+ const delayInMilliseconds = typeof this.options.delay === "function" ? await this.options.delay(attempt, error, context) : this.options.delay ?? 0;
691
+ if (delayInMilliseconds > 0) {
692
+ await new Promise((resolve) => setTimeout(resolve, delayInMilliseconds));
693
+ }
694
+ }
695
+ async handle(event, next, context) {
696
+ for (let attempt = 1; attempt <= this.options.maxAttempts; attempt++) {
697
+ try {
698
+ await next();
699
+ return;
700
+ } catch (error) {
701
+ const canRetry = attempt < this.options.maxAttempts && await (this.options.shouldRetry?.(error, attempt, context) ?? true);
702
+ if (!canRetry) {
703
+ throw error;
704
+ }
705
+ await this.options.onRetry?.(error, attempt, context);
706
+ await this.delay(attempt, error, context);
707
+ }
708
+ }
709
+ }
710
+ };
711
+
382
712
  // src/adapters/pubsub/amqp/AmqpMessageBusAdapter.ts
383
713
  import amqplib from "amqplib";
384
714
  import { randomUUID } from "crypto";
@@ -401,11 +731,16 @@ var NoFailedMessagesError = class extends Error {
401
731
 
402
732
  // src/adapters/pubsub/in-memory/InMemoryEventBus.ts
403
733
  var InMemoryEventBus = class {
404
- constructor(context) {
734
+ constructor(context, publisherHooks = [], publisherHookErrorPolicy) {
405
735
  this.context = context;
736
+ this.publisherHookPipeline = new PublisherHookPipeline(
737
+ publisherHooks,
738
+ publisherHookErrorPolicy
739
+ );
406
740
  }
407
741
  context;
408
742
  handlers = /* @__PURE__ */ new Map();
743
+ publisherHookPipeline;
409
744
  subscribe(name, handler) {
410
745
  const handlers = this.handlers.get(name) ?? [];
411
746
  handlers.push(handler);
@@ -413,24 +748,42 @@ var InMemoryEventBus = class {
413
748
  }
414
749
  async publish(event) {
415
750
  const handlers = this.handlers.get(event.name) ?? [];
416
- for (const handler of handlers) {
417
- await handler(event, this.context);
418
- }
751
+ await this.publisherHookPipeline.run(
752
+ { message: event, metadata: event.metadata ?? {}, topic: event.name },
753
+ async () => {
754
+ for (const handler of handlers) {
755
+ await handler(event, this.context);
756
+ }
757
+ }
758
+ );
759
+ }
760
+ registerPublisherHooks(...hooks) {
761
+ this.publisherHookPipeline.register(...hooks);
419
762
  }
420
763
  };
421
764
 
422
765
  // src/adapters/pubsub/in-memory/InMemoryPubSub.ts
423
766
  var InMemoryPubSub = class {
424
- constructor(context) {
767
+ constructor(context, publisherHooks = [], publisherHookErrorPolicy) {
425
768
  this.context = context;
769
+ this.publisherHookPipeline = new PublisherHookPipeline(
770
+ publisherHooks,
771
+ publisherHookErrorPolicy
772
+ );
426
773
  }
427
774
  context;
428
775
  consumers = /* @__PURE__ */ new Map();
776
+ publisherHookPipeline;
429
777
  async publish(topic, message) {
430
778
  const consumers = this.consumers.get(topic) ?? /* @__PURE__ */ new Set();
431
- for (const consumer of consumers) {
432
- await consumer(message, this.context);
433
- }
779
+ await this.publisherHookPipeline.run(
780
+ { message, metadata: message.metadata ?? {}, topic },
781
+ async () => {
782
+ for (const consumer of consumers) {
783
+ await consumer(message, this.context);
784
+ }
785
+ }
786
+ );
434
787
  }
435
788
  subscribe(topic, consumer) {
436
789
  const consumers = this.consumers.get(topic) ?? /* @__PURE__ */ new Set();
@@ -444,13 +797,23 @@ var InMemoryPubSub = class {
444
797
  }
445
798
  });
446
799
  }
800
+ registerPublisherHooks(...hooks) {
801
+ this.publisherHookPipeline.register(...hooks);
802
+ }
447
803
  };
448
804
  export {
449
805
  Consumer,
806
+ ConsumerMiddlewarePipeline,
807
+ CorrelationConsumerMiddleware,
808
+ DefaultPublisherHookErrorPolicy,
809
+ IdempotencyConsumerMiddleware,
450
810
  InMemoryEventBus,
811
+ InMemoryIdempotencyStore,
451
812
  InMemoryPubSub,
452
813
  InvalidDomainEventError,
453
814
  NoFailedMessagesError,
815
+ PublisherHookPipeline,
816
+ RetryConsumerMiddleware,
454
817
  Consumer_default as default
455
818
  };
456
819
  //# sourceMappingURL=index.js.map