@nestplatform/transactional 1.0.1 → 1.1.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 (45) hide show
  1. package/README.md +91 -0
  2. package/dist/decorators/index.d.ts +2 -0
  3. package/dist/decorators/index.js +2 -0
  4. package/dist/decorators/index.js.map +1 -1
  5. package/dist/decorators/transactional-event-listener.decorator.d.ts +2 -0
  6. package/dist/decorators/transactional-event-listener.decorator.js +13 -0
  7. package/dist/decorators/transactional-event-listener.decorator.js.map +1 -0
  8. package/dist/decorators/transactional-event.decorator.d.ts +2 -0
  9. package/dist/decorators/transactional-event.decorator.js +13 -0
  10. package/dist/decorators/transactional-event.decorator.js.map +1 -0
  11. package/dist/decorators/transactional.decorator.js +1 -0
  12. package/dist/decorators/transactional.decorator.js.map +1 -1
  13. package/dist/index.d.ts +4 -0
  14. package/dist/index.js +4 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/interfaces/index.d.ts +1 -0
  17. package/dist/interfaces/index.js +1 -0
  18. package/dist/interfaces/index.js.map +1 -1
  19. package/dist/interfaces/transaction-synchronization.interface.d.ts +6 -0
  20. package/dist/interfaces/transaction-synchronization.interface.js +3 -0
  21. package/dist/interfaces/transaction-synchronization.interface.js.map +1 -0
  22. package/dist/transaction-context.d.ts +13 -6
  23. package/dist/transaction-context.js +41 -0
  24. package/dist/transaction-context.js.map +1 -1
  25. package/dist/transactional-event.publisher.d.ts +14 -0
  26. package/dist/transactional-event.publisher.js +75 -0
  27. package/dist/transactional-event.publisher.js.map +1 -0
  28. package/dist/transactional-feature.decoration.js +1 -0
  29. package/dist/transactional-feature.decoration.js.map +1 -1
  30. package/dist/transactional-metadata.accessor.d.ts +11 -5
  31. package/dist/transactional-metadata.accessor.js +6 -0
  32. package/dist/transactional-metadata.accessor.js.map +1 -1
  33. package/dist/transactional-metadata.explorer.d.ts +12 -6
  34. package/dist/transactional-metadata.explorer.js +32 -5
  35. package/dist/transactional-metadata.explorer.js.map +1 -1
  36. package/dist/transactional.constant.d.ts +2 -0
  37. package/dist/transactional.constant.js +3 -1
  38. package/dist/transactional.constant.js.map +1 -1
  39. package/dist/transactional.module.js +11 -1
  40. package/dist/transactional.module.js.map +1 -1
  41. package/dist/types/transactional.type.d.ts +35 -13
  42. package/dist/types/transactional.type.js +8 -1
  43. package/dist/types/transactional.type.js.map +1 -1
  44. package/package.json +3 -3
  45. package/tsconfig.tsbuildinfo +1 -1
package/README.md CHANGED
@@ -72,6 +72,82 @@ export class OrderService {
72
72
  }
73
73
  ```
74
74
 
75
+ ## Transaction Events
76
+
77
+ Handle events based on the transaction lifecycle using `@TransactionalEventListener` and `TransactionalEventPublisher`.
78
+
79
+ ### 1. Publish an event
80
+ ```typescript
81
+ @Injectable()
82
+ export class OrderService {
83
+ constructor(private readonly publisher: TransactionalEventPublisher) {}
84
+
85
+ @Transactional()
86
+ async createOrder(data: any) {
87
+ const order = await this.orderRepo.save(data);
88
+ await this.publisher.publish('order.created', order); // Defer execution
89
+ return order;
90
+ }
91
+ }
92
+ ```
93
+
94
+ ### 2. Listen to events
95
+ ```typescript
96
+ @Injectable()
97
+ export class NotificationService {
98
+ @TransactionalEventListener('order.created', { phase: TransactionPhase.AFTER_COMMIT })
99
+ async sendEmail(order: Order) {
100
+ // Only runs if the transaction successfully commits
101
+ }
102
+
103
+ @TransactionalEventListener('order.created', { phase: TransactionPhase.AFTER_ROLLBACK })
104
+ async notifySupport(order: Order) {
105
+ // Runs only if the transaction rolls back
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### 3. Declarative Event Publishing
111
+ Use `@TransactionalEvent` to automatically publish the return value of a method as an event.
112
+
113
+ ```typescript
114
+ @Injectable()
115
+ export class OrderService {
116
+ @Transactional()
117
+ @TransactionalEvent('order.created')
118
+ async createOrder(data: any) {
119
+ // The saved order will be automatically published as 'order.created'
120
+ return this.orderRepo.save(data);
121
+ }
122
+
123
+ // Custom payload extractor
124
+ @TransactionalEvent('order.created', {
125
+ payload: (result) => ({ id: result.id, status: result.status })
126
+ })
127
+ async createOrderCustom(data: any) { ... }
128
+ }
129
+ ```
130
+
131
+ **Supported Phases**: `BEFORE_COMMIT`, `AFTER_COMMIT` (default), `AFTER_ROLLBACK`, `AFTER_COMPLETION`.
132
+
133
+ ## Rollback Control
134
+
135
+ Fine-tune which errors trigger a rollback using the `rollbackOnError` option.
136
+
137
+ ```typescript
138
+ // Rollback only on specific error classes or names
139
+ @Transactional({ rollbackOnError: [BusinessError, 'DatabaseError'] })
140
+ async process() { ... }
141
+
142
+ // Disable rollback entirely for this method
143
+ @Transactional({ rollbackOnError: false })
144
+ async logAndContinue() { ... }
145
+
146
+ // Custom predicate logic
147
+ @Transactional({ rollbackOnError: (err) => err.status >= 500 })
148
+ async apiCall() { ... }
149
+ ```
150
+
75
151
  ## Propagation Levels
76
152
 
77
153
  - **REQUIRED** (Default): Support a current transaction, create a new one if none exists.
@@ -89,6 +165,21 @@ const store = TransactionContext.getStore();
89
165
  const queryRunner = store?.transaction;
90
166
  ```
91
167
 
168
+ ## Changelog
169
+
170
+ ### 1.1.0
171
+ - Added `@TransactionalEventListener` for transaction lifecycle events.
172
+ - Added `TransactionalEventPublisher` for manual and declarative event publishing.
173
+ - Added `@TransactionalEvent` decorator for automatic event publishing.
174
+ - Refined `rollbackOnError` to support error names (strings) and single class instances.
175
+ - Added `beforeCommit`, `afterCommit`, `afterRollback`, and `afterCompletion` synchronization hooks.
176
+
177
+ ### 1.0.1
178
+ - Internal fixes and improvements.
179
+
180
+ ### 1.0.0
181
+ - Initial release with core transactional logic and propagation support.
182
+
92
183
  ## License
93
184
 
94
185
  MIT
@@ -1 +1,3 @@
1
1
  export * from "./transactional.decorator";
2
+ export * from "./transactional-event-listener.decorator";
3
+ export * from "./transactional-event.decorator";
@@ -15,4 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./transactional.decorator"), exports);
18
+ __exportStar(require("./transactional-event-listener.decorator"), exports);
19
+ __exportStar(require("./transactional-event.decorator"), exports);
18
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4DAA0C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4DAA0C;AAC1C,2EAAyD;AACzD,kEAAgD"}
@@ -0,0 +1,2 @@
1
+ import { TransactionalEventListenerOptions } from "../types";
2
+ export declare const TransactionalEventListener: (event: string, options?: TransactionalEventListenerOptions) => MethodDecorator;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransactionalEventListener = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const transactional_constant_1 = require("../transactional.constant");
6
+ const TransactionalEventListener = (event, options) => {
7
+ return (0, common_1.applyDecorators)((0, common_1.SetMetadata)(transactional_constant_1.TRANSACTIONAL_EVENT_LISTENER_METADATA, {
8
+ event,
9
+ ...options,
10
+ }));
11
+ };
12
+ exports.TransactionalEventListener = TransactionalEventListener;
13
+ //# sourceMappingURL=transactional-event-listener.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactional-event-listener.decorator.js","sourceRoot":"","sources":["../../src/decorators/transactional-event-listener.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA8D;AAC9D,sEAAkF;AAuB3E,MAAM,0BAA0B,GAAG,CAAC,KAAa,EAAE,OAA2C,EAAmB,EAAE;IACxH,OAAO,IAAA,wBAAe,EACpB,IAAA,oBAAW,EAAC,8DAAqC,EAAE;QACjD,KAAK;QACL,GAAG,OAAO;KACX,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,0BAA0B,8BAOrC"}
@@ -0,0 +1,2 @@
1
+ import { TransactionalEventOptions } from "../types";
2
+ export declare const TransactionalEvent: (event: string, options?: TransactionalEventOptions) => MethodDecorator;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransactionalEvent = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const transactional_constant_1 = require("../transactional.constant");
6
+ const TransactionalEvent = (event, options) => {
7
+ return (0, common_1.applyDecorators)((0, common_1.SetMetadata)(transactional_constant_1.TRANSACTIONAL_EVENT_METADATA, {
8
+ event,
9
+ ...options,
10
+ }));
11
+ };
12
+ exports.TransactionalEvent = TransactionalEvent;
13
+ //# sourceMappingURL=transactional-event.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactional-event.decorator.js","sourceRoot":"","sources":["../../src/decorators/transactional-event.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA8D;AAC9D,sEAAyE;AAsBlE,MAAM,kBAAkB,GAAG,CAAC,KAAa,EAAE,OAAmC,EAAmB,EAAE;IACxG,OAAO,IAAA,wBAAe,EACpB,IAAA,oBAAW,EAAC,qDAA4B,EAAE;QACxC,KAAK;QACL,GAAG,OAAO;KACX,CAAC,CACH,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,kBAAkB,sBAO7B"}
@@ -7,6 +7,7 @@ const types_1 = require("../types");
7
7
  const TRANSACTIONAL_DEFAULTS = {
8
8
  propagation: types_1.TransactionPropagation.REQUIRED,
9
9
  logging: false,
10
+ rollbackOnError: true,
10
11
  };
11
12
  const Transactional = (options) => {
12
13
  const mergedOptions = {
@@ -1 +1 @@
1
- {"version":3,"file":"transactional.decorator.js","sourceRoot":"","sources":["../../src/decorators/transactional.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA8D;AAE9D,sEAA8F;AAC9F,oCAAwE;AAExE,MAAM,sBAAsB,GAAkE;IAC5F,WAAW,EAAE,8BAAsB,CAAC,QAAQ;IAC5C,OAAO,EAAE,KAAK;CACf,CAAC;AAuBK,MAAM,aAAa,GAAG,CAAC,OAA8B,EAAoC,EAAE;IAChG,MAAM,aAAa,GAAyB;QAC1C,GAAG,sBAAsB;QACzB,GAAG,OAAO;KACX,CAAC;IAEF,OAAO,IAAA,wBAAe,EAAC,IAAA,oBAAW,EAAC,+CAAsB,EAAE,aAAa,CAAC,CAAC,CAAC;AAC7E,CAAC,CAAC;AAPW,QAAA,aAAa,iBAOxB;AAaK,MAAM,eAAe,GAAG,GAAoB,EAAE;IACnD,OAAO,IAAA,wBAAe,EAAC,IAAA,oBAAW,EAAC,kDAAyB,EAAE,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC;AAFW,QAAA,eAAe,mBAE1B"}
1
+ {"version":3,"file":"transactional.decorator.js","sourceRoot":"","sources":["../../src/decorators/transactional.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA8D;AAE9D,sEAA8F;AAC9F,oCAAwE;AAExE,MAAM,sBAAsB,GAAkE;IAC5F,WAAW,EAAE,8BAAsB,CAAC,QAAQ;IAC5C,OAAO,EAAE,KAAK;IACd,eAAe,EAAE,IAAI;CACtB,CAAC;AAuBK,MAAM,aAAa,GAAG,CAAC,OAA8B,EAAoC,EAAE;IAChG,MAAM,aAAa,GAAyB;QAC1C,GAAG,sBAAsB;QACzB,GAAG,OAAO;KACX,CAAC;IAEF,OAAO,IAAA,wBAAe,EAAC,IAAA,oBAAW,EAAC,+CAAsB,EAAE,aAAa,CAAC,CAAC,CAAC;AAC7E,CAAC,CAAC;AAPW,QAAA,aAAa,iBAOxB;AAaK,MAAM,eAAe,GAAG,GAAoB,EAAE;IACnD,OAAO,IAAA,wBAAe,EAAC,IAAA,oBAAW,EAAC,kDAAyB,EAAE,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC;AAFW,QAAA,eAAe,mBAE1B"}
package/dist/index.d.ts CHANGED
@@ -3,4 +3,8 @@ export * from "./decorators";
3
3
  export * from "./transactional.module";
4
4
  export * from "./transactional.constant";
5
5
  export * from "./transaction-context";
6
+ export * from "./transactional-feature.decoration";
7
+ export * from "./transactional-metadata.accessor";
8
+ export * from "./transactional-metadata.explorer";
9
+ export * from "./transactional-event.publisher";
6
10
  export * from "./types";
package/dist/index.js CHANGED
@@ -19,5 +19,9 @@ __exportStar(require("./decorators"), exports);
19
19
  __exportStar(require("./transactional.module"), exports);
20
20
  __exportStar(require("./transactional.constant"), exports);
21
21
  __exportStar(require("./transaction-context"), exports);
22
+ __exportStar(require("./transactional-feature.decoration"), exports);
23
+ __exportStar(require("./transactional-metadata.accessor"), exports);
24
+ __exportStar(require("./transactional-metadata.explorer"), exports);
25
+ __exportStar(require("./transactional-event.publisher"), exports);
22
26
  __exportStar(require("./types"), exports);
23
27
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,+CAA6B;AAC7B,yDAAuC;AACvC,2DAAyC;AACzC,wDAAsC;AACtC,0CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,+CAA6B;AAC7B,yDAAuC;AACvC,2DAAyC;AACzC,wDAAsC;AACtC,qEAAmD;AACnD,oEAAkD;AAClD,oEAAkD;AAClD,kEAAgD;AAChD,0CAAwB"}
@@ -1 +1,2 @@
1
1
  export * from "./transaction-adapter.interface";
2
+ export * from "./transaction-synchronization.interface";
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./transaction-adapter.interface"), exports);
18
+ __exportStar(require("./transaction-synchronization.interface"), exports);
18
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAgD"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAgD;AAChD,0EAAwD"}
@@ -0,0 +1,6 @@
1
+ export interface TransactionSynchronization {
2
+ beforeCommit?(): void | Promise<void>;
3
+ afterCommit?(): void | Promise<void>;
4
+ afterRollback?(error: any): void | Promise<void>;
5
+ afterCompletion?(status: "committed" | "rolled-back"): void | Promise<void>;
6
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=transaction-synchronization.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction-synchronization.interface.js","sourceRoot":"","sources":["../../src/interfaces/transaction-synchronization.interface.ts"],"names":[],"mappings":""}
@@ -1,10 +1,17 @@
1
+ import { TransactionSynchronization } from "./interfaces";
1
2
  export type TransactionStore = {
2
- transaction: any;
3
- adapterKey: string;
3
+ transaction: any;
4
+ adapterKey: string;
5
+ synchronizations?: TransactionSynchronization[];
4
6
  };
5
7
  export declare class TransactionContext {
6
- private static readonly storage;
7
- static run<T>(store: TransactionStore, fn: () => Promise<T>): Promise<T>;
8
- static getStore(): TransactionStore | undefined;
9
- static getTransaction<T = any>(): T | undefined;
8
+ private static readonly storage;
9
+ static run<T>(store: TransactionStore, fn: () => Promise<T>): Promise<T>;
10
+ static getStore(): TransactionStore | undefined;
11
+ static getTransaction<T = any>(): T | undefined;
12
+ static addSynchronization(synchronization: TransactionSynchronization): void;
13
+ static invokeBeforeCommit(): Promise<void>;
14
+ static invokeAfterCommit(): Promise<void>;
15
+ static invokeAfterRollback(error: any): Promise<void>;
16
+ static invokeAfterCompletion(status: "committed" | "rolled-back"): Promise<void>;
10
17
  }
@@ -12,6 +12,47 @@ class TransactionContext {
12
12
  static getTransaction() {
13
13
  return this.storage.getStore()?.transaction;
14
14
  }
15
+ static addSynchronization(synchronization) {
16
+ const store = this.getStore();
17
+ if (store) {
18
+ if (!store.synchronizations) {
19
+ store.synchronizations = [];
20
+ }
21
+ store.synchronizations.push(synchronization);
22
+ }
23
+ }
24
+ static async invokeBeforeCommit() {
25
+ const store = this.getStore();
26
+ if (store?.synchronizations) {
27
+ for (const sync of store.synchronizations) {
28
+ await sync.beforeCommit?.();
29
+ }
30
+ }
31
+ }
32
+ static async invokeAfterCommit() {
33
+ const store = this.getStore();
34
+ if (store?.synchronizations) {
35
+ for (const sync of store.synchronizations) {
36
+ await sync.afterCommit?.();
37
+ }
38
+ }
39
+ }
40
+ static async invokeAfterRollback(error) {
41
+ const store = this.getStore();
42
+ if (store?.synchronizations) {
43
+ for (const sync of store.synchronizations) {
44
+ await sync.afterRollback?.(error);
45
+ }
46
+ }
47
+ }
48
+ static async invokeAfterCompletion(status) {
49
+ const store = this.getStore();
50
+ if (store?.synchronizations) {
51
+ for (const sync of store.synchronizations) {
52
+ await sync.afterCompletion?.(status);
53
+ }
54
+ }
55
+ }
15
56
  }
16
57
  exports.TransactionContext = TransactionContext;
17
58
  TransactionContext.storage = new node_async_hooks_1.AsyncLocalStorage();
@@ -1 +1 @@
1
- {"version":3,"file":"transaction-context.js","sourceRoot":"","sources":["../src/transaction-context.ts"],"names":[],"mappings":";;;AAAA,uDAAqD;AAoBrD,MAAa,kBAAkB;IAO7B,MAAM,CAAC,GAAG,CAAI,KAAuB,EAAE,EAAoB;QACzD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrC,CAAC;IAMD,MAAM,CAAC,QAAQ;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IACjC,CAAC;IAMD,MAAM,CAAC,cAAc;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,WAAW,CAAC;IAC9C,CAAC;;AAzBH,gDA0BC;AAzByB,0BAAO,GAAG,IAAI,oCAAiB,EAAoB,CAAC"}
1
+ {"version":3,"file":"transaction-context.js","sourceRoot":"","sources":["../src/transaction-context.ts"],"names":[],"mappings":";;;AAAA,uDAAqD;AAwBrD,MAAa,kBAAkB;IAO7B,MAAM,CAAC,GAAG,CAAI,KAAuB,EAAE,EAAoB;QACzD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrC,CAAC;IAMD,MAAM,CAAC,QAAQ;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IACjC,CAAC;IAMD,MAAM,CAAC,cAAc;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,WAAW,CAAC;IAC9C,CAAC;IAQD,MAAM,CAAC,kBAAkB,CAAC,eAA2C;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC5B,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAC;YAC9B,CAAC;YACD,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAMD,MAAM,CAAC,KAAK,CAAC,kBAAkB;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,EAAE,gBAAgB,EAAE,CAAC;YAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC1C,MAAM,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAMD,MAAM,CAAC,KAAK,CAAC,iBAAiB;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,EAAE,gBAAgB,EAAE,CAAC;YAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC1C,MAAM,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAMD,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,KAAU;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,EAAE,gBAAgB,EAAE,CAAC;YAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC1C,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAMD,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAmC;QACpE,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,EAAE,gBAAgB,EAAE,CAAC;YAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC1C,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;;AA7FH,gDA8FC;AA7FyB,0BAAO,GAAG,IAAI,oCAAiB,EAAoB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { TransactionPhase } from "./types";
2
+ export type TransactionalListenerMetadata = {
3
+ event: string;
4
+ phase?: TransactionPhase;
5
+ fallbackExecution?: boolean;
6
+ callback: (payload: any) => Promise<void> | void;
7
+ };
8
+ export declare class TransactionalEventPublisher {
9
+ private readonly listeners;
10
+ private readonly logger;
11
+ registerListener(metadata: TransactionalListenerMetadata): void;
12
+ publish(event: string, payload: any): Promise<void>;
13
+ private executeListener;
14
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var TransactionalEventPublisher_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.TransactionalEventPublisher = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const transaction_context_1 = require("./transaction-context");
13
+ const types_1 = require("./types");
14
+ let TransactionalEventPublisher = TransactionalEventPublisher_1 = class TransactionalEventPublisher {
15
+ constructor() {
16
+ this.listeners = new Map();
17
+ this.logger = new common_1.Logger(TransactionalEventPublisher_1.name);
18
+ }
19
+ registerListener(metadata) {
20
+ const eventListeners = this.listeners.get(metadata.event) || [];
21
+ eventListeners.push(metadata);
22
+ this.listeners.set(metadata.event, eventListeners);
23
+ }
24
+ async publish(event, payload) {
25
+ const eventListeners = this.listeners.get(event);
26
+ if (!eventListeners)
27
+ return;
28
+ const store = transaction_context_1.TransactionContext.getStore();
29
+ for (const listener of eventListeners) {
30
+ if (!store) {
31
+ if (listener.fallbackExecution !== false) {
32
+ await this.executeListener(listener, payload);
33
+ }
34
+ continue;
35
+ }
36
+ const phase = listener.phase || types_1.TransactionPhase.AFTER_COMMIT;
37
+ const self = this;
38
+ transaction_context_1.TransactionContext.addSynchronization({
39
+ async beforeCommit() {
40
+ if (phase === types_1.TransactionPhase.BEFORE_COMMIT) {
41
+ await self.executeListener(listener, payload);
42
+ }
43
+ },
44
+ async afterCommit() {
45
+ if (phase === types_1.TransactionPhase.AFTER_COMMIT) {
46
+ await self.executeListener(listener, payload);
47
+ }
48
+ },
49
+ async afterRollback() {
50
+ if (phase === types_1.TransactionPhase.AFTER_ROLLBACK) {
51
+ await self.executeListener(listener, payload);
52
+ }
53
+ },
54
+ async afterCompletion() {
55
+ if (phase === types_1.TransactionPhase.AFTER_COMPLETION) {
56
+ await self.executeListener(listener, payload);
57
+ }
58
+ },
59
+ });
60
+ }
61
+ }
62
+ async executeListener(listener, payload) {
63
+ try {
64
+ await listener.callback(payload);
65
+ }
66
+ catch (error) {
67
+ this.logger.error(`Error in transactional event listener for event "${listener.event}": ${error}`);
68
+ }
69
+ }
70
+ };
71
+ exports.TransactionalEventPublisher = TransactionalEventPublisher;
72
+ exports.TransactionalEventPublisher = TransactionalEventPublisher = TransactionalEventPublisher_1 = __decorate([
73
+ (0, common_1.Injectable)()
74
+ ], TransactionalEventPublisher);
75
+ //# sourceMappingURL=transactional-event.publisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactional-event.publisher.js","sourceRoot":"","sources":["../src/transactional-event.publisher.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAoD;AACpD,+DAA2D;AAC3D,mCAA2C;AAgBpC,IAAM,2BAA2B,mCAAjC,MAAM,2BAA2B;IAAjC;QACY,cAAS,GAAG,IAAI,GAAG,EAA2C,CAAC;QAC/D,WAAM,GAAG,IAAI,eAAM,CAAC,6BAA2B,CAAC,IAAI,CAAC,CAAC;IAqEzE,CAAC;IA/DC,gBAAgB,CAAC,QAAuC;QACtD,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChE,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IACrD,CAAC;IAQD,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,OAAY;QACvC,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACjD,IAAI,CAAC,cAAc;YAAE,OAAO;QAE5B,MAAM,KAAK,GAAG,wCAAkB,CAAC,QAAQ,EAAE,CAAC;QAE5C,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;YACtC,IAAI,CAAC,KAAK,EAAE,CAAC;gBAEX,IAAI,QAAQ,CAAC,iBAAiB,KAAK,KAAK,EAAE,CAAC;oBACzC,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAChD,CAAC;gBACD,SAAS;YACX,CAAC;YAGD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,wBAAgB,CAAC,YAAY,CAAC;YAC9D,MAAM,IAAI,GAAG,IAAI,CAAC;YAElB,wCAAkB,CAAC,kBAAkB,CAAC;gBACpC,KAAK,CAAC,YAAY;oBAChB,IAAI,KAAK,KAAK,wBAAgB,CAAC,aAAa,EAAE,CAAC;wBAC7C,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC,WAAW;oBACf,IAAI,KAAK,KAAK,wBAAgB,CAAC,YAAY,EAAE,CAAC;wBAC5C,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC,aAAa;oBACjB,IAAI,KAAK,KAAK,wBAAgB,CAAC,cAAc,EAAE,CAAC;wBAC9C,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC,eAAe;oBACnB,IAAI,KAAK,KAAK,wBAAgB,CAAC,gBAAgB,EAAE,CAAC;wBAChD,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,QAAuC,EAAE,OAAY;QACjF,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oDAAoD,QAAQ,CAAC,KAAK,MAAM,KAAK,EAAE,CAAC,CAAC;QACrG,CAAC;IACH,CAAC;CACF,CAAA;AAvEY,kEAA2B;sCAA3B,2BAA2B;IADvC,IAAA,mBAAU,GAAE;GACA,2BAA2B,CAuEvC"}
@@ -43,6 +43,7 @@ let TransactionalFeatureDecoration = class TransactionalFeatureDecoration extend
43
43
  const result = await adapter.execute(() => originalMethod.apply(proxiedInstance || instance, args), {
44
44
  propagation: options.propagation || types_1.TransactionPropagation.REQUIRED,
45
45
  isolation: options.isolation,
46
+ rollbackOnError: options.rollbackOnError,
46
47
  });
47
48
  if (options.logging) {
48
49
  common_1.Logger.log(`Transaction committed for \`${methodString}\``, LOGGING_CONTEXT);
@@ -1 +1 @@
1
- {"version":3,"file":"transactional-feature.decoration.js","sourceRoot":"","sources":["../src/transactional-feature.decoration.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4D;AAE5D,iDAA0E;AAE1E,qEAA6F;AAE7F,mCAA4F;AAE5F,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAGvC,IAAM,8BAA8B,GAApC,MAAM,8BAA+B,SAAQ,0BAAiB;IACnE,YAA2D,QAA6B;QACtF,KAAK,EAAE,CAAC;QADiD,aAAQ,GAAR,QAAQ,CAAqB;IAExF,CAAC;IAOM,yBAAyB,CAAC,QAAa,EAAE,UAAkB,EAAE,cAAwB,EAAE,OAA6B;QACzH,MAAM,UAAU,GAAW,OAAO,CAAC,OAAO,IAAI,oDAA2B,CAAC;QAC1E,MAAM,eAAe,GAAoC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzF,MAAM,OAAO,GAAoC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,eAAe,CAAC;QAE9F,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,eAAM,CAAC,IAAI,CAAC,wBAAwB,UAAU,yCAAyC,UAAU,GAAG,EAAE,eAAe,CAAC,CAAC;YACzH,CAAC;YAED,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,EAAE,GAAG,IAAW,EAAgB,EAAE;YAC5D,MAAM,YAAY,GAAW,IAAA,wBAAe,EAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;YAElE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,eAAM,CAAC,GAAG,CAAC,8BAA8B,YAAY,OAAO,OAAO,CAAC,WAAW,IAAI,8BAAsB,CAAC,QAAQ,GAAG,EAAE,eAAe,CAAC,CAAC;YAC1I,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,CAAC;gBAC1D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,eAAe,IAAI,QAAQ,EAAE,IAAI,CAAC,EAAE;oBAClG,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,8BAAsB,CAAC,QAAQ;oBACnE,SAAS,EAAE,OAAO,CAAC,SAAS;iBAC7B,CAAC,CAAC;gBAEH,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBACpB,eAAM,CAAC,GAAG,CAAC,+BAA+B,YAAY,IAAI,EAAE,eAAe,CAAC,CAAC;gBAC/E,CAAC;gBAED,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBACpB,eAAM,CAAC,KAAK,CAAC,iCAAiC,YAAY,OAAO,KAAK,EAAE,EAAE,eAAe,CAAC,CAAC;gBAC7F,CAAC;gBAED,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;CACF,CAAA;AApDY,wEAA8B;yCAA9B,8BAA8B;IAD1C,IAAA,mBAAU,GAAE;IAEE,WAAA,IAAA,eAAM,EAAC,6CAAoB,CAAC,CAAA;;GAD9B,8BAA8B,CAoD1C"}
1
+ {"version":3,"file":"transactional-feature.decoration.js","sourceRoot":"","sources":["../src/transactional-feature.decoration.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4D;AAE5D,iDAA0E;AAE1E,qEAA6F;AAE7F,mCAA4F;AAE5F,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAGvC,IAAM,8BAA8B,GAApC,MAAM,8BAA+B,SAAQ,0BAAiB;IACnE,YAA2D,QAA6B;QACtF,KAAK,EAAE,CAAC;QADiD,aAAQ,GAAR,QAAQ,CAAqB;IAExF,CAAC;IAOM,yBAAyB,CAAC,QAAa,EAAE,UAAkB,EAAE,cAAwB,EAAE,OAA6B;QACzH,MAAM,UAAU,GAAW,OAAO,CAAC,OAAO,IAAI,oDAA2B,CAAC;QAC1E,MAAM,eAAe,GAAoC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzF,MAAM,OAAO,GAAoC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,eAAe,CAAC;QAE9F,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,eAAM,CAAC,IAAI,CAAC,wBAAwB,UAAU,yCAAyC,UAAU,GAAG,EAAE,eAAe,CAAC,CAAC;YACzH,CAAC;YAED,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,EAAE,GAAG,IAAW,EAAgB,EAAE;YAC5D,MAAM,YAAY,GAAW,IAAA,wBAAe,EAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;YAElE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,eAAM,CAAC,GAAG,CAAC,8BAA8B,YAAY,OAAO,OAAO,CAAC,WAAW,IAAI,8BAAsB,CAAC,QAAQ,GAAG,EAAE,eAAe,CAAC,CAAC;YAC1I,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,CAAC;gBAC1D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,eAAe,IAAI,QAAQ,EAAE,IAAI,CAAC,EAAE;oBAClG,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,8BAAsB,CAAC,QAAQ;oBACnE,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,eAAe,EAAE,OAAO,CAAC,eAAe;iBACzC,CAAC,CAAC;gBAEH,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBACpB,eAAM,CAAC,GAAG,CAAC,+BAA+B,YAAY,IAAI,EAAE,eAAe,CAAC,CAAC;gBAC/E,CAAC;gBAED,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBACpB,eAAM,CAAC,KAAK,CAAC,iCAAiC,YAAY,OAAO,KAAK,EAAE,EAAE,eAAe,CAAC,CAAC;gBAC7F,CAAC;gBAED,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;CACF,CAAA;AArDY,wEAA8B;yCAA9B,8BAA8B;IAD1C,IAAA,mBAAU,GAAE;IAEE,WAAA,IAAA,eAAM,EAAC,6CAAoB,CAAC,CAAA;;GAD9B,8BAA8B,CAqD1C"}
@@ -1,9 +1,15 @@
1
1
  import { Reflector } from "@nestjs/core";
2
2
  import { MetadataAccessor } from "@nestplatform/common";
3
- import { TransactionalOptions } from "./types";
3
+ import { TransactionalOptions, TransactionalEventOptions } from "./types";
4
4
  export declare class TransactionalMetadataAccessor extends MetadataAccessor {
5
- protected readonly reflector: Reflector;
6
- constructor(reflector: Reflector);
7
- getTransactionalMetadata(target: Function): TransactionalOptions | undefined;
8
- getNoTransactionalMetadata(target: Function): boolean | undefined;
5
+ protected readonly reflector: Reflector;
6
+ constructor(reflector: Reflector);
7
+ getTransactionalMetadata(target: Function): TransactionalOptions | undefined;
8
+ getNoTransactionalMetadata(target: Function): boolean | undefined;
9
+ getEventListenerMetadata(target: Function): any | undefined;
10
+ getTransactionalEventMetadata(target: Function):
11
+ | (TransactionalEventOptions & {
12
+ event: string;
13
+ })
14
+ | undefined;
9
15
  }
@@ -25,6 +25,12 @@ let TransactionalMetadataAccessor = class TransactionalMetadataAccessor extends
25
25
  getNoTransactionalMetadata(target) {
26
26
  return this.getMetadata(transactional_constant_1.NO_TRANSACTIONAL_METADATA, target);
27
27
  }
28
+ getEventListenerMetadata(target) {
29
+ return this.getMetadata(transactional_constant_1.TRANSACTIONAL_EVENT_LISTENER_METADATA, target);
30
+ }
31
+ getTransactionalEventMetadata(target) {
32
+ return this.getMetadata(transactional_constant_1.TRANSACTIONAL_EVENT_METADATA, target);
33
+ }
28
34
  };
29
35
  exports.TransactionalMetadataAccessor = TransactionalMetadataAccessor;
30
36
  exports.TransactionalMetadataAccessor = TransactionalMetadataAccessor = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"transactional-metadata.accessor.js","sourceRoot":"","sources":["../src/transactional-metadata.accessor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,uCAAyC;AAEzC,iDAAwD;AAExD,qEAA6F;AAItF,IAAM,6BAA6B,GAAnC,MAAM,6BAA8B,SAAQ,yBAAgB;IACjE,YAA+B,SAAoB;QACjD,KAAK,EAAE,CAAC;QADqB,cAAS,GAAT,SAAS,CAAW;IAEnD,CAAC;IAMM,wBAAwB,CAAC,MAAgB;QAC9C,OAAO,IAAI,CAAC,WAAW,CAAuB,+CAAsB,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC;IAMM,0BAA0B,CAAC,MAAgB;QAChD,OAAO,IAAI,CAAC,WAAW,CAAU,kDAAyB,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC;CACF,CAAA;AApBY,sEAA6B;wCAA7B,6BAA6B;IADzC,IAAA,mBAAU,GAAE;qCAE+B,gBAAS;GADxC,6BAA6B,CAoBzC"}
1
+ {"version":3,"file":"transactional-metadata.accessor.js","sourceRoot":"","sources":["../src/transactional-metadata.accessor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,uCAAyC;AAEzC,iDAAwD;AAExD,qEAKkC;AAI3B,IAAM,6BAA6B,GAAnC,MAAM,6BAA8B,SAAQ,yBAAgB;IACjE,YAA+B,SAAoB;QACjD,KAAK,EAAE,CAAC;QADqB,cAAS,GAAT,SAAS,CAAW;IAEnD,CAAC;IAMM,wBAAwB,CAAC,MAAgB;QAC9C,OAAO,IAAI,CAAC,WAAW,CAAuB,+CAAsB,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC;IAMM,0BAA0B,CAAC,MAAgB;QAChD,OAAO,IAAI,CAAC,WAAW,CAAU,kDAAyB,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC;IAMM,wBAAwB,CAAC,MAAgB;QAC9C,OAAO,IAAI,CAAC,WAAW,CAAM,8DAAqC,EAAE,MAAM,CAAC,CAAC;IAC9E,CAAC;IAMM,6BAA6B,CAAC,MAAgB;QACnD,OAAO,IAAI,CAAC,WAAW,CAAgD,qDAA4B,EAAE,MAAM,CAAC,CAAC;IAC/G,CAAC;CACF,CAAA;AApCY,sEAA6B;wCAA7B,6BAA6B;IADzC,IAAA,mBAAU,GAAE;qCAE+B,gBAAS;GADxC,6BAA6B,CAoCzC"}
@@ -1,11 +1,17 @@
1
1
  import { IFeatureExplorer, MethodContext, ProviderContext } from "@nestplatform/common";
2
2
  import { TransactionalFeatureDecoration } from "./transactional-feature.decoration";
3
3
  import { TransactionalMetadataAccessor } from "./transactional-metadata.accessor";
4
+ import { TransactionalEventPublisher } from "./transactional-event.publisher";
4
5
  export declare class TransactionalMetadataExplorer implements IFeatureExplorer {
5
- private readonly metadataAccessor;
6
- private readonly featureDecoration;
7
- private readonly classLevelOptions;
8
- constructor(metadataAccessor: TransactionalMetadataAccessor, featureDecoration: TransactionalFeatureDecoration);
9
- onProvider(ctx: ProviderContext): void;
10
- onMethod(ctx: MethodContext): void;
6
+ private readonly metadataAccessor;
7
+ private readonly featureDecoration;
8
+ private readonly eventPublisher;
9
+ private readonly classLevelOptions;
10
+ constructor(
11
+ metadataAccessor: TransactionalMetadataAccessor,
12
+ featureDecoration: TransactionalFeatureDecoration,
13
+ eventPublisher: TransactionalEventPublisher,
14
+ );
15
+ onProvider(ctx: ProviderContext): void;
16
+ onMethod(ctx: MethodContext): void;
11
17
  }
@@ -14,10 +14,12 @@ const common_1 = require("@nestjs/common");
14
14
  const common_2 = require("@nestplatform/common");
15
15
  const transactional_feature_decoration_1 = require("./transactional-feature.decoration");
16
16
  const transactional_metadata_accessor_1 = require("./transactional-metadata.accessor");
17
+ const transactional_event_publisher_1 = require("./transactional-event.publisher");
17
18
  let TransactionalMetadataExplorer = class TransactionalMetadataExplorer {
18
- constructor(metadataAccessor, featureDecoration) {
19
+ constructor(metadataAccessor, featureDecoration, eventPublisher) {
19
20
  this.metadataAccessor = metadataAccessor;
20
21
  this.featureDecoration = featureDecoration;
22
+ this.eventPublisher = eventPublisher;
21
23
  this.classLevelOptions = new Map();
22
24
  }
23
25
  onProvider(ctx) {
@@ -29,15 +31,39 @@ let TransactionalMetadataExplorer = class TransactionalMetadataExplorer {
29
31
  }
30
32
  onMethod(ctx) {
31
33
  const { instance, methodName, methodRef, metatype } = ctx;
34
+ const listenerMetadata = this.metadataAccessor.getEventListenerMetadata(methodRef);
35
+ if (listenerMetadata) {
36
+ this.eventPublisher.registerListener({
37
+ ...listenerMetadata,
38
+ callback: (payload) => methodRef.apply(instance, [payload]),
39
+ });
40
+ }
32
41
  const isExcluded = this.metadataAccessor.getNoTransactionalMetadata(methodRef);
33
42
  if (isExcluded)
34
43
  return;
35
44
  const methodOptions = this.metadataAccessor.getTransactionalMetadata(methodRef);
36
45
  const classOptions = this.classLevelOptions.get(metatype);
37
46
  const resolvedOptions = methodOptions ? { ...classOptions, ...methodOptions } : classOptions;
38
- if (!resolvedOptions)
39
- return;
40
- this.featureDecoration.wrapMethodWithTransaction(instance, methodName, methodRef, resolvedOptions);
47
+ const eventMetadata = this.metadataAccessor.getTransactionalEventMetadata(methodRef);
48
+ if (eventMetadata) {
49
+ const eventPublisher = this.eventPublisher;
50
+ const originalMethod = methodRef;
51
+ const wrappedWithEvent = async function (...args) {
52
+ const result = await originalMethod.apply(this, args);
53
+ const payload = eventMetadata.payload ? eventMetadata.payload(result) : result;
54
+ await eventPublisher.publish(eventMetadata.event, payload);
55
+ return result;
56
+ };
57
+ if (resolvedOptions) {
58
+ this.featureDecoration.wrapMethodWithTransaction(instance, methodName, wrappedWithEvent, resolvedOptions);
59
+ }
60
+ else {
61
+ instance[methodName] = wrappedWithEvent;
62
+ }
63
+ }
64
+ else if (resolvedOptions) {
65
+ this.featureDecoration.wrapMethodWithTransaction(instance, methodName, methodRef, resolvedOptions);
66
+ }
41
67
  }
42
68
  };
43
69
  exports.TransactionalMetadataExplorer = TransactionalMetadataExplorer;
@@ -45,6 +71,7 @@ exports.TransactionalMetadataExplorer = TransactionalMetadataExplorer = __decora
45
71
  (0, common_1.Injectable)(),
46
72
  (0, common_2.FeatureExplorer)(),
47
73
  __metadata("design:paramtypes", [transactional_metadata_accessor_1.TransactionalMetadataAccessor,
48
- transactional_feature_decoration_1.TransactionalFeatureDecoration])
74
+ transactional_feature_decoration_1.TransactionalFeatureDecoration,
75
+ transactional_event_publisher_1.TransactionalEventPublisher])
49
76
  ], TransactionalMetadataExplorer);
50
77
  //# sourceMappingURL=transactional-metadata.explorer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transactional-metadata.explorer.js","sourceRoot":"","sources":["../src/transactional-metadata.explorer.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAE5C,iDAAyG;AAEzG,yFAAoF;AACpF,uFAAkF;AAK3E,IAAM,6BAA6B,GAAnC,MAAM,6BAA6B;IAQxC,YACmB,gBAA+C,EAC/C,iBAAiD;QADjD,qBAAgB,GAAhB,gBAAgB,CAA+B;QAC/C,sBAAiB,GAAjB,iBAAiB,CAAgC;QAJnD,sBAAiB,GAAG,IAAI,GAAG,EAAkC,CAAC;IAK5E,CAAC;IAKJ,UAAU,CAAC,GAAoB;QAC7B,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;QAEzB,MAAM,YAAY,GAAqC,IAAI,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QAEhH,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAMD,QAAQ,CAAC,GAAkB;QACzB,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;QAG1D,MAAM,UAAU,GAAwB,IAAI,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,SAAS,CAAC,CAAC;QAEpG,IAAI,UAAU;YAAE,OAAO;QAGvB,MAAM,aAAa,GAAqC,IAAI,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;QAGlH,MAAM,YAAY,GAAqC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAG5F,MAAM,eAAe,GAAqC,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,YAAY,EAAE,GAAG,aAAa,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;QAE/H,IAAI,CAAC,eAAe;YAAE,OAAO;QAE7B,IAAI,CAAC,iBAAiB,CAAC,yBAAyB,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IACrG,CAAC;CACF,CAAA;AAnDY,sEAA6B;wCAA7B,6BAA6B;IAFzC,IAAA,mBAAU,GAAE;IACZ,IAAA,wBAAe,GAAE;qCAUqB,+DAA6B;QAC5B,iEAA8B;GAVzD,6BAA6B,CAmDzC"}
1
+ {"version":3,"file":"transactional-metadata.explorer.js","sourceRoot":"","sources":["../src/transactional-metadata.explorer.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  export declare const TRANSACTIONAL_METADATA: unique symbol;
2
2
  export declare const NO_TRANSACTIONAL_METADATA: unique symbol;
3
+ export declare const TRANSACTIONAL_EVENT_LISTENER_METADATA: unique symbol;
4
+ export declare const TRANSACTIONAL_EVENT_METADATA: unique symbol;
3
5
  export declare const TRANSACTION_ADAPTERS: unique symbol;
4
6
  export declare const DEFAULT_TRANSACTION_ADAPTER = "default";
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_TRANSACTION_ADAPTER = exports.TRANSACTION_ADAPTERS = exports.NO_TRANSACTIONAL_METADATA = exports.TRANSACTIONAL_METADATA = void 0;
3
+ exports.DEFAULT_TRANSACTION_ADAPTER = exports.TRANSACTION_ADAPTERS = exports.TRANSACTIONAL_EVENT_METADATA = exports.TRANSACTIONAL_EVENT_LISTENER_METADATA = exports.NO_TRANSACTIONAL_METADATA = exports.TRANSACTIONAL_METADATA = void 0;
4
4
  exports.TRANSACTIONAL_METADATA = Symbol.for("metadata:transactional");
5
5
  exports.NO_TRANSACTIONAL_METADATA = Symbol.for("metadata:no_transactional");
6
+ exports.TRANSACTIONAL_EVENT_LISTENER_METADATA = Symbol.for("metadata:transactional_event_listener");
7
+ exports.TRANSACTIONAL_EVENT_METADATA = Symbol.for("metadata:transactional_event");
6
8
  exports.TRANSACTION_ADAPTERS = Symbol.for("token:TRANSACTION_ADAPTERS");
7
9
  exports.DEFAULT_TRANSACTION_ADAPTER = "default";
8
10
  //# sourceMappingURL=transactional.constant.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transactional.constant.js","sourceRoot":"","sources":["../src/transactional.constant.ts"],"names":[],"mappings":";;;AAAa,QAAA,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AAC9D,QAAA,yBAAyB,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;AAEpE,QAAA,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;AAIhE,QAAA,2BAA2B,GAAG,SAAS,CAAC"}
1
+ {"version":3,"file":"transactional.constant.js","sourceRoot":"","sources":["../src/transactional.constant.ts"],"names":[],"mappings":";;;AAAa,QAAA,sBAAsB,GAAG,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AAC9D,QAAA,yBAAyB,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;AACpE,QAAA,qCAAqC,GAAG,MAAM,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;AAC5F,QAAA,4BAA4B,GAAG,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAE1E,QAAA,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;AAIhE,QAAA,2BAA2B,GAAG,SAAS,CAAC"}