@rolandsall24/nest-mediator 0.5.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +597 -40
  2. package/dist/lib/decorators/event-criticality.decorator.d.ts +61 -0
  3. package/dist/lib/decorators/event-criticality.decorator.d.ts.map +1 -0
  4. package/dist/lib/decorators/event-criticality.decorator.js +71 -0
  5. package/dist/lib/decorators/event-criticality.decorator.js.map +1 -0
  6. package/dist/lib/decorators/event-handler.decorator.d.ts +21 -0
  7. package/dist/lib/decorators/event-handler.decorator.d.ts.map +1 -0
  8. package/dist/lib/decorators/event-handler.decorator.js +27 -0
  9. package/dist/lib/decorators/event-handler.decorator.js.map +1 -0
  10. package/dist/lib/decorators/index.d.ts +2 -0
  11. package/dist/lib/decorators/index.d.ts.map +1 -1
  12. package/dist/lib/decorators/index.js +2 -0
  13. package/dist/lib/decorators/index.js.map +1 -1
  14. package/dist/lib/decorators/pipeline-behavior.decorator.d.ts +49 -0
  15. package/dist/lib/decorators/pipeline-behavior.decorator.d.ts.map +1 -1
  16. package/dist/lib/decorators/pipeline-behavior.decorator.js +56 -1
  17. package/dist/lib/decorators/pipeline-behavior.decorator.js.map +1 -1
  18. package/dist/lib/interfaces/command-bus.interface.d.ts +25 -0
  19. package/dist/lib/interfaces/command-bus.interface.d.ts.map +1 -0
  20. package/dist/lib/interfaces/command-bus.interface.js +3 -0
  21. package/dist/lib/interfaces/command-bus.interface.js.map +1 -0
  22. package/dist/lib/interfaces/event-bus.interface.d.ts +35 -0
  23. package/dist/lib/interfaces/event-bus.interface.d.ts.map +1 -0
  24. package/dist/lib/interfaces/event-bus.interface.js +3 -0
  25. package/dist/lib/interfaces/event-bus.interface.js.map +1 -0
  26. package/dist/lib/interfaces/event-consumer.interface.d.ts +64 -0
  27. package/dist/lib/interfaces/event-consumer.interface.d.ts.map +1 -0
  28. package/dist/lib/interfaces/event-consumer.interface.js +3 -0
  29. package/dist/lib/interfaces/event-consumer.interface.js.map +1 -0
  30. package/dist/lib/interfaces/event-criticality.interface.d.ts +28 -0
  31. package/dist/lib/interfaces/event-criticality.interface.d.ts.map +1 -0
  32. package/dist/lib/interfaces/event-criticality.interface.js +25 -0
  33. package/dist/lib/interfaces/event-criticality.interface.js.map +1 -0
  34. package/dist/lib/interfaces/event-handler.interface.d.ts +24 -0
  35. package/dist/lib/interfaces/event-handler.interface.d.ts.map +1 -0
  36. package/dist/lib/interfaces/event-handler.interface.js +3 -0
  37. package/dist/lib/interfaces/event-handler.interface.js.map +1 -0
  38. package/dist/lib/interfaces/event.interface.d.ts +30 -0
  39. package/dist/lib/interfaces/event.interface.d.ts.map +1 -0
  40. package/dist/lib/interfaces/event.interface.js +3 -0
  41. package/dist/lib/interfaces/event.interface.js.map +1 -0
  42. package/dist/lib/interfaces/index.d.ts +7 -0
  43. package/dist/lib/interfaces/index.d.ts.map +1 -1
  44. package/dist/lib/interfaces/index.js +7 -0
  45. package/dist/lib/interfaces/index.js.map +1 -1
  46. package/dist/lib/interfaces/mediator.interface.d.ts +14 -0
  47. package/dist/lib/interfaces/mediator.interface.d.ts.map +1 -0
  48. package/dist/lib/interfaces/mediator.interface.js +3 -0
  49. package/dist/lib/interfaces/mediator.interface.js.map +1 -0
  50. package/dist/lib/interfaces/query-bus.interface.d.ts +26 -0
  51. package/dist/lib/interfaces/query-bus.interface.d.ts.map +1 -0
  52. package/dist/lib/interfaces/query-bus.interface.js +3 -0
  53. package/dist/lib/interfaces/query-bus.interface.js.map +1 -0
  54. package/dist/lib/nest-mediator.module.d.ts.map +1 -1
  55. package/dist/lib/nest-mediator.module.js +37 -2
  56. package/dist/lib/nest-mediator.module.js.map +1 -1
  57. package/dist/lib/services/command.bus.d.ts +30 -0
  58. package/dist/lib/services/command.bus.d.ts.map +1 -0
  59. package/dist/lib/services/command.bus.js +69 -0
  60. package/dist/lib/services/command.bus.js.map +1 -0
  61. package/dist/lib/services/event.bus.d.ts +61 -0
  62. package/dist/lib/services/event.bus.d.ts.map +1 -0
  63. package/dist/lib/services/event.bus.js +176 -0
  64. package/dist/lib/services/event.bus.js.map +1 -0
  65. package/dist/lib/services/mediator.bus.d.ts +50 -31
  66. package/dist/lib/services/mediator.bus.d.ts.map +1 -1
  67. package/dist/lib/services/mediator.bus.js +60 -97
  68. package/dist/lib/services/mediator.bus.js.map +1 -1
  69. package/dist/lib/services/pipeline.orchestrator.d.ts +46 -0
  70. package/dist/lib/services/pipeline.orchestrator.d.ts.map +1 -0
  71. package/dist/lib/services/pipeline.orchestrator.js +87 -0
  72. package/dist/lib/services/pipeline.orchestrator.js.map +1 -0
  73. package/dist/lib/services/query.bus.d.ts +31 -0
  74. package/dist/lib/services/query.bus.d.ts.map +1 -0
  75. package/dist/lib/services/query.bus.js +68 -0
  76. package/dist/lib/services/query.bus.js.map +1 -0
  77. package/package.json +1 -1
@@ -0,0 +1,61 @@
1
+ export { EventCriticality, EventCriticalityMetadata } from '../interfaces/event-criticality.interface.js';
2
+ export declare const EVENT_CRITICALITY_METADATA = "EVENT_CRITICALITY_METADATA";
3
+ /**
4
+ * Options for critical event handlers
5
+ */
6
+ export interface CriticalOptions {
7
+ /**
8
+ * Execution order within critical handlers.
9
+ * Lower numbers execute first.
10
+ * Default: 0
11
+ */
12
+ order?: number;
13
+ }
14
+ /**
15
+ * Decorator to mark an event handler as critical.
16
+ * Critical handlers:
17
+ * - Run sequentially in the order specified
18
+ * - Must complete before non-critical handlers start
19
+ * - If one fails, the publish operation fails (remaining critical handlers are skipped)
20
+ * - Are awaited by the caller
21
+ *
22
+ * @param options - Optional configuration (order)
23
+ * @returns Class decorator
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * @EventHandler(OrderPlacedEvent)
28
+ * @Critical({ order: 1 })
29
+ * export class ReserveInventoryHandler implements IEventConsumer<OrderPlacedEvent> {
30
+ * async handle(event: OrderPlacedEvent): Promise<void> {
31
+ * await this.inventoryService.reserve(event.items);
32
+ * }
33
+ * }
34
+ * ```
35
+ */
36
+ export declare const Critical: (options?: CriticalOptions) => ClassDecorator;
37
+ /**
38
+ * Decorator to explicitly mark an event handler as non-critical.
39
+ * Non-critical handlers:
40
+ * - Run in parallel after all critical handlers complete
41
+ * - Fire and forget (not awaited by the caller)
42
+ * - Failures are logged but don't affect the publish result
43
+ * - Don't block the caller
44
+ *
45
+ * Note: Handlers without @Critical or @NonCritical are non-critical by default.
46
+ *
47
+ * @returns Class decorator
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * @EventHandler(OrderPlacedEvent)
52
+ * @NonCritical()
53
+ * export class SendOrderConfirmationEmail implements IEventConsumer<OrderPlacedEvent> {
54
+ * async handle(event: OrderPlacedEvent): Promise<void> {
55
+ * await this.emailService.send(event.customerEmail, 'order_confirmed');
56
+ * }
57
+ * }
58
+ * ```
59
+ */
60
+ export declare const NonCritical: () => ClassDecorator;
61
+ //# sourceMappingURL=event-criticality.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-criticality.decorator.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/event-criticality.decorator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,8CAA8C,CAAC;AAE1G,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ,GAAI,UAAS,eAAoB,KAAG,cAMxD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,WAAW,QAAO,cAM9B,CAAC"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NonCritical = exports.Critical = exports.EVENT_CRITICALITY_METADATA = exports.EventCriticality = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const event_criticality_interface_js_1 = require("../interfaces/event-criticality.interface.js");
6
+ // Re-export types for backward compatibility
7
+ var event_criticality_interface_js_2 = require("../interfaces/event-criticality.interface.js");
8
+ Object.defineProperty(exports, "EventCriticality", { enumerable: true, get: function () { return event_criticality_interface_js_2.EventCriticality; } });
9
+ exports.EVENT_CRITICALITY_METADATA = 'EVENT_CRITICALITY_METADATA';
10
+ /**
11
+ * Decorator to mark an event handler as critical.
12
+ * Critical handlers:
13
+ * - Run sequentially in the order specified
14
+ * - Must complete before non-critical handlers start
15
+ * - If one fails, the publish operation fails (remaining critical handlers are skipped)
16
+ * - Are awaited by the caller
17
+ *
18
+ * @param options - Optional configuration (order)
19
+ * @returns Class decorator
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * @EventHandler(OrderPlacedEvent)
24
+ * @Critical({ order: 1 })
25
+ * export class ReserveInventoryHandler implements IEventConsumer<OrderPlacedEvent> {
26
+ * async handle(event: OrderPlacedEvent): Promise<void> {
27
+ * await this.inventoryService.reserve(event.items);
28
+ * }
29
+ * }
30
+ * ```
31
+ */
32
+ const Critical = (options = {}) => {
33
+ const metadata = {
34
+ criticality: event_criticality_interface_js_1.EventCriticality.CRITICAL,
35
+ order: options.order ?? 0,
36
+ };
37
+ return (0, common_1.SetMetadata)(exports.EVENT_CRITICALITY_METADATA, metadata);
38
+ };
39
+ exports.Critical = Critical;
40
+ /**
41
+ * Decorator to explicitly mark an event handler as non-critical.
42
+ * Non-critical handlers:
43
+ * - Run in parallel after all critical handlers complete
44
+ * - Fire and forget (not awaited by the caller)
45
+ * - Failures are logged but don't affect the publish result
46
+ * - Don't block the caller
47
+ *
48
+ * Note: Handlers without @Critical or @NonCritical are non-critical by default.
49
+ *
50
+ * @returns Class decorator
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * @EventHandler(OrderPlacedEvent)
55
+ * @NonCritical()
56
+ * export class SendOrderConfirmationEmail implements IEventConsumer<OrderPlacedEvent> {
57
+ * async handle(event: OrderPlacedEvent): Promise<void> {
58
+ * await this.emailService.send(event.customerEmail, 'order_confirmed');
59
+ * }
60
+ * }
61
+ * ```
62
+ */
63
+ const NonCritical = () => {
64
+ const metadata = {
65
+ criticality: event_criticality_interface_js_1.EventCriticality.NON_CRITICAL,
66
+ order: 0,
67
+ };
68
+ return (0, common_1.SetMetadata)(exports.EVENT_CRITICALITY_METADATA, metadata);
69
+ };
70
+ exports.NonCritical = NonCritical;
71
+ //# sourceMappingURL=event-criticality.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-criticality.decorator.js","sourceRoot":"","sources":["../../../src/lib/decorators/event-criticality.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAC7C,iGAGsD;AAEtD,6CAA6C;AAC7C,+FAA0G;AAAjG,kIAAA,gBAAgB,OAAA;AAEZ,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAcvE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACI,MAAM,QAAQ,GAAG,CAAC,UAA2B,EAAE,EAAkB,EAAE;IACxE,MAAM,QAAQ,GAA6B;QACzC,WAAW,EAAE,iDAAgB,CAAC,QAAQ;QACtC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;KAC1B,CAAC;IACF,OAAO,IAAA,oBAAW,EAAC,kCAA0B,EAAE,QAAQ,CAAC,CAAC;AAC3D,CAAC,CAAC;AANW,QAAA,QAAQ,YAMnB;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACI,MAAM,WAAW,GAAG,GAAmB,EAAE;IAC9C,MAAM,QAAQ,GAA6B;QACzC,WAAW,EAAE,iDAAgB,CAAC,YAAY;QAC1C,KAAK,EAAE,CAAC;KACT,CAAC;IACF,OAAO,IAAA,oBAAW,EAAC,kCAA0B,EAAE,QAAQ,CAAC,CAAC;AAC3D,CAAC,CAAC;AANW,QAAA,WAAW,eAMtB"}
@@ -0,0 +1,21 @@
1
+ import { IEvent } from '../interfaces/index.js';
2
+ export declare const EVENT_HANDLER_METADATA = "EVENT_HANDLER_METADATA";
3
+ /**
4
+ * Decorator to mark a class as an event consumer.
5
+ * Multiple consumers can subscribe to the same event.
6
+ *
7
+ * @param event - The event class that this consumer handles
8
+ * @returns Class decorator
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * @EventHandler(UserCreatedEvent)
13
+ * export class SendWelcomeEmailConsumer implements IEventConsumer<UserCreatedEvent> {
14
+ * async handle(event: UserCreatedEvent): Promise<void> {
15
+ * await this.emailService.sendWelcome(event.userEmail);
16
+ * }
17
+ * }
18
+ * ```
19
+ */
20
+ export declare const EventHandler: (event: new (...args: any[]) => IEvent) => ClassDecorator;
21
+ //# sourceMappingURL=event-handler.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-handler.decorator.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/event-handler.decorator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAE/D;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY,GACvB,OAAO,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,KACpC,cAEF,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventHandler = exports.EVENT_HANDLER_METADATA = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.EVENT_HANDLER_METADATA = 'EVENT_HANDLER_METADATA';
6
+ /**
7
+ * Decorator to mark a class as an event consumer.
8
+ * Multiple consumers can subscribe to the same event.
9
+ *
10
+ * @param event - The event class that this consumer handles
11
+ * @returns Class decorator
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * @EventHandler(UserCreatedEvent)
16
+ * export class SendWelcomeEmailConsumer implements IEventConsumer<UserCreatedEvent> {
17
+ * async handle(event: UserCreatedEvent): Promise<void> {
18
+ * await this.emailService.sendWelcome(event.userEmail);
19
+ * }
20
+ * }
21
+ * ```
22
+ */
23
+ const EventHandler = (event) => {
24
+ return (0, common_1.SetMetadata)(exports.EVENT_HANDLER_METADATA, event);
25
+ };
26
+ exports.EventHandler = EventHandler;
27
+ //# sourceMappingURL=event-handler.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-handler.decorator.js","sourceRoot":"","sources":["../../../src/lib/decorators/event-handler.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAGhC,QAAA,sBAAsB,GAAG,wBAAwB,CAAC;AAE/D;;;;;;;;;;;;;;;;GAgBG;AACI,MAAM,YAAY,GAAG,CAC1B,KAAqC,EACrB,EAAE;IAClB,OAAO,IAAA,oBAAW,EAAC,8BAAsB,EAAE,KAAK,CAAC,CAAC;AACpD,CAAC,CAAC;AAJW,QAAA,YAAY,gBAIvB"}
@@ -2,4 +2,6 @@ export * from './command-handler.decorator.js';
2
2
  export * from './query-handler.decorator.js';
3
3
  export * from './pipeline-behavior.decorator.js';
4
4
  export * from './skip-behavior.decorator.js';
5
+ export * from './event-handler.decorator.js';
6
+ export * from './event-criticality.decorator.js';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC"}
@@ -18,4 +18,6 @@ __exportStar(require("./command-handler.decorator.js"), exports);
18
18
  __exportStar(require("./query-handler.decorator.js"), exports);
19
19
  __exportStar(require("./pipeline-behavior.decorator.js"), exports);
20
20
  __exportStar(require("./skip-behavior.decorator.js"), exports);
21
+ __exportStar(require("./event-handler.decorator.js"), exports);
22
+ __exportStar(require("./event-criticality.decorator.js"), exports);
21
23
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA+C;AAC/C,+DAA6C;AAC7C,mEAAiD;AACjD,+DAA6C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA+C;AAC/C,+DAA6C;AAC7C,mEAAiD;AACjD,+DAA6C;AAC7C,+DAA6C;AAC7C,mEAAiD"}
@@ -3,6 +3,11 @@ import { PipelineBehaviorOptions } from '../interfaces/pipeline-behavior.interfa
3
3
  * Metadata key for pipeline behavior registration
4
4
  */
5
5
  export declare const PIPELINE_BEHAVIOR_METADATA = "PIPELINE_BEHAVIOR_METADATA";
6
+ /**
7
+ * Metadata key to mark that the handle method has the decorator applied
8
+ * (used to trigger design:paramtypes emission for type inference)
9
+ */
10
+ export declare const PIPELINE_BEHAVIOR_HANDLE_METADATA = "PIPELINE_BEHAVIOR_HANDLE_METADATA";
6
11
  /**
7
12
  * Decorator that marks a class as a pipeline behavior.
8
13
  * Pipeline behaviors execute around request handlers, enabling cross-cutting concerns.
@@ -45,7 +50,51 @@ export declare const PIPELINE_BEHAVIOR_METADATA = "PIPELINE_BEHAVIOR_METADATA";
45
50
  * return next();
46
51
  * }
47
52
  * }
53
+ *
54
+ * // Type-specific behavior - only applies to CreateUserCommand
55
+ * // Use @Handle() on the method to enable automatic type inference
56
+ * @Injectable()
57
+ * @PipelineBehavior({ priority: 100, scope: 'command' })
58
+ * export class CreateUserValidationBehavior implements IPipelineBehavior<CreateUserCommand, any> {
59
+ * @Handle() // Enables type inference from method signature
60
+ * async handle(request: CreateUserCommand, next: () => Promise<any>): Promise<any> {
61
+ * // This behavior only runs for CreateUserCommand - no instanceof check needed!
62
+ * await this.validate(request);
63
+ * return next();
64
+ * }
65
+ * }
48
66
  * ```
49
67
  */
50
68
  export declare const PipelineBehavior: (options?: PipelineBehaviorOptions) => ClassDecorator;
69
+ /**
70
+ * Method decorator that enables automatic request type inference for pipeline behaviors.
71
+ *
72
+ * When applied to the `handle` method of a pipeline behavior, TypeScript emits
73
+ * `design:paramtypes` metadata that the library reads to determine which request
74
+ * type the behavior should apply to.
75
+ *
76
+ * @returns Method decorator
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * @Injectable()
81
+ * @PipelineBehavior({ priority: 100, scope: 'command' })
82
+ * export class CreateUserValidationBehavior
83
+ * implements IPipelineBehavior<CreateUserCommand, void>
84
+ * {
85
+ * @Handle() // Enables type inference - behavior only runs for CreateUserCommand
86
+ * async handle(
87
+ * request: CreateUserCommand,
88
+ * next: () => Promise<void>,
89
+ * ): Promise<void> {
90
+ * // No instanceof check needed - this only runs for CreateUserCommand
91
+ * if (!request.email.includes('@')) {
92
+ * throw new Error('Invalid email');
93
+ * }
94
+ * return next();
95
+ * }
96
+ * }
97
+ * ```
98
+ */
99
+ export declare const Handle: () => MethodDecorator;
51
100
  //# sourceMappingURL=pipeline-behavior.decorator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-behavior.decorator.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/pipeline-behavior.decorator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAEvF;;GAEG;AACH,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAUvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,uBAAuB,KAChC,cAMF,CAAC"}
1
+ {"version":3,"file":"pipeline-behavior.decorator.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/pipeline-behavior.decorator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAEvF;;GAEG;AACH,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,iCAAiC,sCAAsC,CAAC;AAUrF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,uBAAuB,KAChC,cAMF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,MAAM,QAAO,eASzB,CAAC"}
@@ -1,11 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PipelineBehavior = exports.PIPELINE_BEHAVIOR_METADATA = void 0;
3
+ exports.Handle = exports.PipelineBehavior = exports.PIPELINE_BEHAVIOR_HANDLE_METADATA = exports.PIPELINE_BEHAVIOR_METADATA = void 0;
4
4
  const common_1 = require("@nestjs/common");
5
5
  /**
6
6
  * Metadata key for pipeline behavior registration
7
7
  */
8
8
  exports.PIPELINE_BEHAVIOR_METADATA = 'PIPELINE_BEHAVIOR_METADATA';
9
+ /**
10
+ * Metadata key to mark that the handle method has the decorator applied
11
+ * (used to trigger design:paramtypes emission for type inference)
12
+ */
13
+ exports.PIPELINE_BEHAVIOR_HANDLE_METADATA = 'PIPELINE_BEHAVIOR_HANDLE_METADATA';
9
14
  /**
10
15
  * Default options for pipeline behaviors
11
16
  */
@@ -55,6 +60,19 @@ const DEFAULT_OPTIONS = {
55
60
  * return next();
56
61
  * }
57
62
  * }
63
+ *
64
+ * // Type-specific behavior - only applies to CreateUserCommand
65
+ * // Use @Handle() on the method to enable automatic type inference
66
+ * @Injectable()
67
+ * @PipelineBehavior({ priority: 100, scope: 'command' })
68
+ * export class CreateUserValidationBehavior implements IPipelineBehavior<CreateUserCommand, any> {
69
+ * @Handle() // Enables type inference from method signature
70
+ * async handle(request: CreateUserCommand, next: () => Promise<any>): Promise<any> {
71
+ * // This behavior only runs for CreateUserCommand - no instanceof check needed!
72
+ * await this.validate(request);
73
+ * return next();
74
+ * }
75
+ * }
58
76
  * ```
59
77
  */
60
78
  const PipelineBehavior = (options) => {
@@ -65,4 +83,41 @@ const PipelineBehavior = (options) => {
65
83
  return (0, common_1.SetMetadata)(exports.PIPELINE_BEHAVIOR_METADATA, mergedOptions);
66
84
  };
67
85
  exports.PipelineBehavior = PipelineBehavior;
86
+ /**
87
+ * Method decorator that enables automatic request type inference for pipeline behaviors.
88
+ *
89
+ * When applied to the `handle` method of a pipeline behavior, TypeScript emits
90
+ * `design:paramtypes` metadata that the library reads to determine which request
91
+ * type the behavior should apply to.
92
+ *
93
+ * @returns Method decorator
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * @Injectable()
98
+ * @PipelineBehavior({ priority: 100, scope: 'command' })
99
+ * export class CreateUserValidationBehavior
100
+ * implements IPipelineBehavior<CreateUserCommand, void>
101
+ * {
102
+ * @Handle() // Enables type inference - behavior only runs for CreateUserCommand
103
+ * async handle(
104
+ * request: CreateUserCommand,
105
+ * next: () => Promise<void>,
106
+ * ): Promise<void> {
107
+ * // No instanceof check needed - this only runs for CreateUserCommand
108
+ * if (!request.email.includes('@')) {
109
+ * throw new Error('Invalid email');
110
+ * }
111
+ * return next();
112
+ * }
113
+ * }
114
+ * ```
115
+ */
116
+ const Handle = () => {
117
+ return (target, propertyKey, descriptor) => {
118
+ Reflect.defineMetadata(exports.PIPELINE_BEHAVIOR_HANDLE_METADATA, true, target, propertyKey);
119
+ return descriptor;
120
+ };
121
+ };
122
+ exports.Handle = Handle;
68
123
  //# sourceMappingURL=pipeline-behavior.decorator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-behavior.decorator.js","sourceRoot":"","sources":["../../../src/lib/decorators/pipeline-behavior.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAG7C;;GAEG;AACU,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAEvE;;GAEG;AACH,MAAM,eAAe,GAA4B;IAC/C,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,KAAK;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACI,MAAM,gBAAgB,GAAG,CAC9B,OAAiC,EACjB,EAAE;IAClB,MAAM,aAAa,GAA4B;QAC7C,GAAG,eAAe;QAClB,GAAG,OAAO;KACX,CAAC;IACF,OAAO,IAAA,oBAAW,EAAC,kCAA0B,EAAE,aAAa,CAAC,CAAC;AAChE,CAAC,CAAC;AARW,QAAA,gBAAgB,oBAQ3B"}
1
+ {"version":3,"file":"pipeline-behavior.decorator.js","sourceRoot":"","sources":["../../../src/lib/decorators/pipeline-behavior.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAG7C;;GAEG;AACU,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAEvE;;;GAGG;AACU,QAAA,iCAAiC,GAAG,mCAAmC,CAAC;AAErF;;GAEG;AACH,MAAM,eAAe,GAA4B;IAC/C,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,KAAK;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACI,MAAM,gBAAgB,GAAG,CAC9B,OAAiC,EACjB,EAAE;IAClB,MAAM,aAAa,GAA4B;QAC7C,GAAG,eAAe;QAClB,GAAG,OAAO;KACX,CAAC;IACF,OAAO,IAAA,oBAAW,EAAC,kCAA0B,EAAE,aAAa,CAAC,CAAC;AAChE,CAAC,CAAC;AARW,QAAA,gBAAgB,oBAQ3B;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACI,MAAM,MAAM,GAAG,GAAoB,EAAE;IAC1C,OAAO,CACL,MAAc,EACd,WAA4B,EAC5B,UAA8B,EACV,EAAE;QACtB,OAAO,CAAC,cAAc,CAAC,yCAAiC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACrF,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC,CAAC;AATW,QAAA,MAAM,UASjB"}
@@ -0,0 +1,25 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { ICommand } from './command.interface.js';
3
+ import { ICommandHandler } from './command-handler.interface.js';
4
+ /**
5
+ * Interface for the command bus.
6
+ * Responsible for dispatching commands to their handlers.
7
+ */
8
+ export interface ICommandBus {
9
+ /**
10
+ * Send a command to its handler
11
+ * @param command - The command instance
12
+ */
13
+ send<TCommand extends ICommand>(command: TCommand): Promise<void>;
14
+ /**
15
+ * Register a command handler
16
+ * @param command - The command class
17
+ * @param handler - The handler class
18
+ */
19
+ registerCommandHandler(command: Type<ICommand>, handler: Type<ICommandHandler<any>>): void;
20
+ /**
21
+ * Get registered command names (for debugging)
22
+ */
23
+ getRegisteredCommands(): string[];
24
+ }
25
+ //# sourceMappingURL=command-bus.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-bus.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/command-bus.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,IAAI,CAAC,QAAQ,SAAS,QAAQ,EAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE;;;;OAIG;IACH,sBAAsB,CACpB,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,EACvB,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,GAClC,IAAI,CAAC;IAER;;OAEG;IACH,qBAAqB,IAAI,MAAM,EAAE,CAAC;CACnC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=command-bus.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-bus.interface.js","sourceRoot":"","sources":["../../../src/lib/interfaces/command-bus.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { IEvent, EventPublishResult } from './event.interface.js';
3
+ import { IEventConsumer } from './event-consumer.interface.js';
4
+ import { EventCriticalityMetadata } from './event-criticality.interface.js';
5
+ /**
6
+ * Interface for the event bus.
7
+ * Responsible for publishing events to their consumers.
8
+ */
9
+ export interface IEventBus {
10
+ /**
11
+ * Publish an event to all its consumers
12
+ * @param event - The event instance
13
+ * @returns Promise with the publish result
14
+ */
15
+ publish<TEvent extends IEvent>(event: TEvent): Promise<EventPublishResult>;
16
+ /**
17
+ * Register an event consumer
18
+ * @param event - The event class
19
+ * @param handler - The consumer class
20
+ * @param criticalityMetadata - Criticality metadata
21
+ */
22
+ registerEventHandler(event: Type<IEvent>, handler: Type<IEventConsumer<any>>, criticalityMetadata?: EventCriticalityMetadata): void;
23
+ /**
24
+ * Get registered events and their consumers (for debugging)
25
+ */
26
+ getRegisteredEvents(): {
27
+ event: string;
28
+ handlers: {
29
+ name: string;
30
+ criticality: string;
31
+ order: number;
32
+ }[];
33
+ }[];
34
+ }
35
+ //# sourceMappingURL=event-bus.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/event-bus.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAE5E;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,OAAO,CAAC,MAAM,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE3E;;;;;OAKG;IACH,oBAAoB,CAClB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EACnB,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,EAClC,mBAAmB,CAAC,EAAE,wBAAwB,GAC7C,IAAI,CAAC;IAER;;OAEG;IACH,mBAAmB,IAAI;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAClE,EAAE,CAAC;CACL"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=event-bus.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.interface.js","sourceRoot":"","sources":["../../../src/lib/interfaces/event-bus.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,64 @@
1
+ import { IEvent } from './event.interface.js';
2
+ /**
3
+ * Interface for event consumers.
4
+ * Event consumers subscribe to events and react to them.
5
+ * Multiple consumers can subscribe to the same event.
6
+ *
7
+ * Use this interface for non-critical consumers (fire-and-forget).
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * @EventHandler(UserCreatedEvent)
12
+ * @NonCritical()
13
+ * export class SendWelcomeEmailConsumer implements IEventConsumer<UserCreatedEvent> {
14
+ * async handle(event: UserCreatedEvent): Promise<void> {
15
+ * await this.emailService.sendWelcome(event.userEmail);
16
+ * }
17
+ * }
18
+ * ```
19
+ */
20
+ export interface IEventConsumer<TEvent extends IEvent> {
21
+ /**
22
+ * Handle the event
23
+ * @param event - The event instance
24
+ */
25
+ handle(event: TEvent): Promise<void>;
26
+ }
27
+ /**
28
+ * Interface for critical event consumers with optional compensation.
29
+ * Critical consumers run sequentially and can define a compensate method
30
+ * that will be called if a subsequent critical consumer fails.
31
+ *
32
+ * Compensation is called in reverse order (last succeeded -> first succeeded)
33
+ * when a critical consumer in the chain fails.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * @EventHandler(OrderPlacedEvent)
38
+ * @Critical({ order: 2 })
39
+ * export class ReserveInventoryConsumer implements ICriticalEventConsumer<OrderPlacedEvent> {
40
+ * async handle(event: OrderPlacedEvent): Promise<void> {
41
+ * await this.inventoryService.reserve(event.orderId, event.items);
42
+ * }
43
+ *
44
+ * async compensate(event: OrderPlacedEvent): Promise<void> {
45
+ * await this.inventoryService.releaseByOrderId(event.orderId);
46
+ * }
47
+ * }
48
+ * ```
49
+ */
50
+ export interface ICriticalEventConsumer<TEvent extends IEvent> extends IEventConsumer<TEvent> {
51
+ /**
52
+ * Compensate/rollback the work done by handle().
53
+ * Called when a subsequent critical consumer fails.
54
+ * Should be idempotent and derive state from the event.
55
+ *
56
+ * @param event - The same event instance passed to handle()
57
+ */
58
+ compensate?(event: TEvent): Promise<void>;
59
+ }
60
+ /**
61
+ * @deprecated Use IEventConsumer instead
62
+ */
63
+ export type IEventHandler<TEvent extends IEvent> = IEventConsumer<TEvent>;
64
+ //# sourceMappingURL=event-consumer.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-consumer.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/event-consumer.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,cAAc,CAAC,MAAM,SAAS,MAAM;IACnD;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,sBAAsB,CAAC,MAAM,SAAS,MAAM,CAAE,SAAQ,cAAc,CAAC,MAAM,CAAC;IAC3F;;;;;;OAMG;IACH,UAAU,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,SAAS,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=event-consumer.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-consumer.interface.js","sourceRoot":"","sources":["../../../src/lib/interfaces/event-consumer.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Criticality level for event consumers.
3
+ * Determines how the consumer is executed when an event is published.
4
+ */
5
+ export declare enum EventCriticality {
6
+ /**
7
+ * Critical consumers run sequentially in order.
8
+ * - Must complete before non-critical consumers start
9
+ * - If one fails, the publish operation fails
10
+ * - Are awaited by the caller
11
+ */
12
+ CRITICAL = "critical",
13
+ /**
14
+ * Non-critical consumers run in parallel after critical consumers complete.
15
+ * - Fire and forget (not awaited by the caller)
16
+ * - Failures are logged but don't affect the publish result
17
+ * - Don't block the caller
18
+ */
19
+ NON_CRITICAL = "non-critical"
20
+ }
21
+ /**
22
+ * Metadata stored for event consumer criticality
23
+ */
24
+ export interface EventCriticalityMetadata {
25
+ criticality: EventCriticality;
26
+ order: number;
27
+ }
28
+ //# sourceMappingURL=event-criticality.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-criticality.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/event-criticality.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,oBAAY,gBAAgB;IAC1B;;;;;OAKG;IACH,QAAQ,aAAa;IAErB;;;;;OAKG;IACH,YAAY,iBAAiB;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventCriticality = void 0;
4
+ /**
5
+ * Criticality level for event consumers.
6
+ * Determines how the consumer is executed when an event is published.
7
+ */
8
+ var EventCriticality;
9
+ (function (EventCriticality) {
10
+ /**
11
+ * Critical consumers run sequentially in order.
12
+ * - Must complete before non-critical consumers start
13
+ * - If one fails, the publish operation fails
14
+ * - Are awaited by the caller
15
+ */
16
+ EventCriticality["CRITICAL"] = "critical";
17
+ /**
18
+ * Non-critical consumers run in parallel after critical consumers complete.
19
+ * - Fire and forget (not awaited by the caller)
20
+ * - Failures are logged but don't affect the publish result
21
+ * - Don't block the caller
22
+ */
23
+ EventCriticality["NON_CRITICAL"] = "non-critical";
24
+ })(EventCriticality || (exports.EventCriticality = EventCriticality = {}));
25
+ //# sourceMappingURL=event-criticality.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-criticality.interface.js","sourceRoot":"","sources":["../../../src/lib/interfaces/event-criticality.interface.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,IAAY,gBAgBX;AAhBD,WAAY,gBAAgB;IAC1B;;;;;OAKG;IACH,yCAAqB,CAAA;IAErB;;;;;OAKG;IACH,iDAA6B,CAAA;AAC/B,CAAC,EAhBW,gBAAgB,gCAAhB,gBAAgB,QAgB3B"}
@@ -0,0 +1,24 @@
1
+ import { IEvent } from './event.interface.js';
2
+ /**
3
+ * Interface for event handlers
4
+ * Event handlers subscribe to events and react to them.
5
+ * Multiple handlers can subscribe to the same event.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * @EventHandler(UserCreatedEvent)
10
+ * export class SendWelcomeEmailHandler implements IEventHandler<UserCreatedEvent> {
11
+ * async handle(event: UserCreatedEvent): Promise<void> {
12
+ * await this.emailService.sendWelcome(event.userEmail);
13
+ * }
14
+ * }
15
+ * ```
16
+ */
17
+ export interface IEventHandler<TEvent extends IEvent> {
18
+ /**
19
+ * Handle the event
20
+ * @param event - The event instance
21
+ */
22
+ handle(event: TEvent): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=event-handler.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-handler.interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interfaces/event-handler.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,aAAa,CAAC,MAAM,SAAS,MAAM;IAClD;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=event-handler.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-handler.interface.js","sourceRoot":"","sources":["../../../src/lib/interfaces/event-handler.interface.ts"],"names":[],"mappings":""}