@nestjs-transactional/cqrs 1.0.0-alpha.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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +431 -0
  3. package/dist/decorators/integration-events-handler.decorator.d.ts +125 -0
  4. package/dist/decorators/integration-events-handler.decorator.js +57 -0
  5. package/dist/decorators/integration-events-handler.decorator.js.map +1 -0
  6. package/dist/decorators/transactional-events-handler.decorator.d.ts +138 -0
  7. package/dist/decorators/transactional-events-handler.decorator.js +65 -0
  8. package/dist/decorators/transactional-events-handler.decorator.js.map +1 -0
  9. package/dist/event-dispatcher/event-dispatcher.d.ts +100 -0
  10. package/dist/event-dispatcher/event-dispatcher.js +229 -0
  11. package/dist/event-dispatcher/event-dispatcher.js.map +1 -0
  12. package/dist/event-publisher/hybrid-event-publisher.d.ts +76 -0
  13. package/dist/event-publisher/hybrid-event-publisher.js +86 -0
  14. package/dist/event-publisher/hybrid-event-publisher.js.map +1 -0
  15. package/dist/event-publisher/transactional-event-publisher-adapter.d.ts +32 -0
  16. package/dist/event-publisher/transactional-event-publisher-adapter.js +72 -0
  17. package/dist/event-publisher/transactional-event-publisher-adapter.js.map +1 -0
  18. package/dist/event-publisher/transactional-event-publisher.d.ts +33 -0
  19. package/dist/event-publisher/transactional-event-publisher.js +58 -0
  20. package/dist/event-publisher/transactional-event-publisher.js.map +1 -0
  21. package/dist/handlers/bootstrap.d.ts +18 -0
  22. package/dist/handlers/bootstrap.js +39 -0
  23. package/dist/handlers/bootstrap.js.map +1 -0
  24. package/dist/handlers/handler-wrapper.d.ts +77 -0
  25. package/dist/handlers/handler-wrapper.js +183 -0
  26. package/dist/handlers/handler-wrapper.js.map +1 -0
  27. package/dist/handlers/integration-events-handler-scanner.d.ts +37 -0
  28. package/dist/handlers/integration-events-handler-scanner.js +144 -0
  29. package/dist/handlers/integration-events-handler-scanner.js.map +1 -0
  30. package/dist/handlers/listener-scanner.d.ts +33 -0
  31. package/dist/handlers/listener-scanner.js +86 -0
  32. package/dist/handlers/listener-scanner.js.map +1 -0
  33. package/dist/handlers/outbox-listener-registrar.d.ts +49 -0
  34. package/dist/handlers/outbox-listener-registrar.js +17 -0
  35. package/dist/handlers/outbox-listener-registrar.js.map +1 -0
  36. package/dist/index.d.ts +16 -0
  37. package/dist/index.js +37 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/interfaces/integration-event-handler.interface.d.ts +35 -0
  40. package/dist/interfaces/integration-event-handler.interface.js +3 -0
  41. package/dist/interfaces/integration-event-handler.interface.js.map +1 -0
  42. package/dist/interfaces/transactional-event-handler.interface.d.ts +31 -0
  43. package/dist/interfaces/transactional-event-handler.interface.js +3 -0
  44. package/dist/interfaces/transactional-event-handler.interface.js.map +1 -0
  45. package/dist/module/cqrs-transactional.module.d.ts +92 -0
  46. package/dist/module/cqrs-transactional.module.js +137 -0
  47. package/dist/module/cqrs-transactional.module.js.map +1 -0
  48. package/dist/types/transactional-listener.types.d.ts +21 -0
  49. package/dist/types/transactional-listener.types.js +25 -0
  50. package/dist/types/transactional-listener.types.js.map +1 -0
  51. package/package.json +73 -0
@@ -0,0 +1,137 @@
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 CqrsTransactionalModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.CqrsTransactionalModule = exports.CQRS_TRANSACTIONAL_OPTIONS = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const core_1 = require("@nestjs/core");
13
+ const cqrs_1 = require("@nestjs/cqrs");
14
+ const core_2 = require("@nestjs-transactional/core");
15
+ const event_dispatcher_1 = require("../event-dispatcher/event-dispatcher");
16
+ const hybrid_event_publisher_1 = require("../event-publisher/hybrid-event-publisher");
17
+ const transactional_event_publisher_1 = require("../event-publisher/transactional-event-publisher");
18
+ const transactional_event_publisher_adapter_1 = require("../event-publisher/transactional-event-publisher-adapter");
19
+ const bootstrap_1 = require("../handlers/bootstrap");
20
+ const handler_wrapper_1 = require("../handlers/handler-wrapper");
21
+ const integration_events_handler_scanner_1 = require("../handlers/integration-events-handler-scanner");
22
+ const listener_scanner_1 = require("../handlers/listener-scanner");
23
+ /**
24
+ * DI token for the resolved {@link CqrsTransactionalOptions} object.
25
+ * Consumers normally do not inject this directly — it is used by the
26
+ * module's internal factory to pass options to {@link CqrsHandlerWrapper}.
27
+ */
28
+ exports.CQRS_TRANSACTIONAL_OPTIONS = 'CQRS_TRANSACTIONAL_OPTIONS';
29
+ /**
30
+ * NestJS module that wires the `@nestjs-transactional/cqrs` runtime:
31
+ *
32
+ * - {@link TransactionalEventDispatcher} for phase-aware event
33
+ * routing.
34
+ * - {@link TransactionalListenerScanner} for auto-registration of
35
+ * `@TransactionalEventsHandler`-decorated classes at module init.
36
+ * - {@link IntegrationEventsHandlerScanner} for
37
+ * `@IntegrationEventsHandler`-decorated classes, with smart routing
38
+ * to the outbox (when bound) or the dispatcher (otherwise).
39
+ * - {@link CqrsHandlerWrapper} + {@link CqrsTransactionalBootstrap}
40
+ * to wrap `@CommandHandler` / `@QueryHandler` / `@EventsHandler`
41
+ * execute/handle methods at application bootstrap.
42
+ * - {@link TransactionalEventPublisher} +
43
+ * {@link TransactionalEventPublisherAdapter} as the `EventPublisher`
44
+ * DI override so `AggregateRoot.commit()` flows through the
45
+ * dispatcher.
46
+ *
47
+ * Pair with `TransactionalModule.forRoot({ isGlobal: true })` at the
48
+ * application root. For TypeORM-backed applications, also register
49
+ * adapters with `TypeOrmTransactionalModule.forFeature(...)`.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * @Module({
54
+ * imports: [
55
+ * TransactionalModule.forRoot({ isGlobal: true }),
56
+ * TypeOrmTransactionalModule.forFeature({ dataSource: myDs }),
57
+ * CqrsModule,
58
+ * CqrsTransactionalModule.forRoot(),
59
+ * ],
60
+ * })
61
+ * export class AppModule {}
62
+ * ```
63
+ *
64
+ * **Multi-dataSource setups** (Phase 14.7): the cqrs runtime is
65
+ * dataSource-agnostic by design. There is exactly one
66
+ * `CqrsTransactionalModule.forRoot()` per application regardless of
67
+ * how many dataSources are configured — multi-DS routing emerges
68
+ * from the structural-port wiring, not from a per-DS module instance.
69
+ *
70
+ * Wire {@link OUTBOX_PUBLICATION_SCHEDULER} and
71
+ * {@link OUTBOX_LISTENER_REGISTRAR} to the outbox stack you want
72
+ * cqrs to delegate to (`useExisting: OutboxEventPublisher` /
73
+ * `useExisting: OutboxListenerRegistry`). Apps with multiple outbox
74
+ * stacks (one `OutboxModule.forRoot()` per dataSource — ADR-019)
75
+ * choose which one cqrs bridges to via the `useExisting` target.
76
+ *
77
+ * Known limitation in multi-DS deployments: the in-memory
78
+ * dispatcher's hook-attachment goes through
79
+ * `TransactionManager.registerBeforeCommit` / `registerAfterCommit`,
80
+ * which target the first-active transaction on the current async
81
+ * context (non-deterministic across simultaneously-active
82
+ * cross-dataSource transactions). For cross-DS event handling
83
+ * prefer the outbox path — see `docs/known-limitations.md`.
84
+ */
85
+ let CqrsTransactionalModule = CqrsTransactionalModule_1 = class CqrsTransactionalModule {
86
+ static forRoot(options = {}) {
87
+ const resolved = {
88
+ wrapCommandHandlers: options.wrapCommandHandlers ?? true,
89
+ wrapQueryHandlers: options.wrapQueryHandlers ?? true,
90
+ wrapEventHandlers: options.wrapEventHandlers ?? true,
91
+ useTransactionalEventPublisher: options.useTransactionalEventPublisher ?? true,
92
+ defaultQueryOptions: options.defaultQueryOptions ?? { readOnly: true },
93
+ defaultCommandOptions: options.defaultCommandOptions,
94
+ };
95
+ const providers = [
96
+ {
97
+ provide: exports.CQRS_TRANSACTIONAL_OPTIONS,
98
+ useValue: resolved,
99
+ },
100
+ event_dispatcher_1.TransactionalEventDispatcher,
101
+ listener_scanner_1.TransactionalListenerScanner,
102
+ integration_events_handler_scanner_1.IntegrationEventsHandlerScanner,
103
+ {
104
+ provide: handler_wrapper_1.CqrsHandlerWrapper,
105
+ useFactory: (discovery, manager, opts) => new handler_wrapper_1.CqrsHandlerWrapper(discovery, manager, opts),
106
+ inject: [core_1.DiscoveryService, core_2.TransactionManager, exports.CQRS_TRANSACTIONAL_OPTIONS],
107
+ },
108
+ bootstrap_1.CqrsTransactionalBootstrap,
109
+ ];
110
+ const exportTokens = [event_dispatcher_1.TransactionalEventDispatcher];
111
+ if (resolved.useTransactionalEventPublisher) {
112
+ // Keep TransactionalEventPublisher as a standalone provider for
113
+ // consumers that want the in-memory-only strategy. The adapter
114
+ // itself now routes through HybridEventPublisher, which picks
115
+ // up the optional outbox scheduler via @Optional injection.
116
+ providers.push(transactional_event_publisher_1.TransactionalEventPublisher);
117
+ providers.push(hybrid_event_publisher_1.HybridEventPublisher);
118
+ providers.push({
119
+ provide: cqrs_1.EventPublisher,
120
+ useFactory: (strategy, eventBus) => new transactional_event_publisher_adapter_1.TransactionalEventPublisherAdapter(strategy, eventBus),
121
+ inject: [hybrid_event_publisher_1.HybridEventPublisher, cqrs_1.EventBus],
122
+ });
123
+ exportTokens.push(transactional_event_publisher_1.TransactionalEventPublisher, hybrid_event_publisher_1.HybridEventPublisher, cqrs_1.EventPublisher);
124
+ }
125
+ return {
126
+ module: CqrsTransactionalModule_1,
127
+ imports: [core_1.DiscoveryModule, cqrs_1.CqrsModule],
128
+ providers,
129
+ exports: exportTokens,
130
+ };
131
+ }
132
+ };
133
+ exports.CqrsTransactionalModule = CqrsTransactionalModule;
134
+ exports.CqrsTransactionalModule = CqrsTransactionalModule = CqrsTransactionalModule_1 = __decorate([
135
+ (0, common_1.Module)({})
136
+ ], CqrsTransactionalModule);
137
+ //# sourceMappingURL=cqrs-transactional.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cqrs-transactional.module.js","sourceRoot":"","sources":["../../src/module/cqrs-transactional.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA2E;AAC3E,uCAAiE;AACjE,uCAAoE;AACpE,qDAAgE;AAEhE,2EAAoF;AACpF,sFAAiF;AACjF,oGAA+F;AAC/F,oHAA8G;AAC9G,qDAAmE;AACnE,iEAA6F;AAC7F,uGAAiG;AACjG,mEAA4E;AAE5E;;;;GAIG;AACU,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AA2BvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEI,IAAM,uBAAuB,+BAA7B,MAAM,uBAAuB;IAClC,MAAM,CAAC,OAAO,CAAC,UAAoC,EAAE;QACnD,MAAM,QAAQ,GASsE;YAClF,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,IAAI,IAAI;YACxD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,IAAI;YACpD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,IAAI;YACpD,8BAA8B,EAAE,OAAO,CAAC,8BAA8B,IAAI,IAAI;YAC9E,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;YACtE,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;SACrD,CAAC;QAEF,MAAM,SAAS,GAAe;YAC5B;gBACE,OAAO,EAAE,kCAA0B;gBACnC,QAAQ,EAAE,QAAQ;aACnB;YACD,+CAA4B;YAC5B,+CAA4B;YAC5B,oEAA+B;YAC/B;gBACE,OAAO,EAAE,oCAAkB;gBAC3B,UAAU,EAAE,CACV,SAA2B,EAC3B,OAA2B,EAC3B,IAA2B,EACP,EAAE,CAAC,IAAI,oCAAkB,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC;gBACzE,MAAM,EAAE,CAAC,uBAAgB,EAAE,yBAAkB,EAAE,kCAA0B,CAAC;aAC3E;YACD,sCAA0B;SAC3B,CAAC;QAEF,MAAM,YAAY,GAAc,CAAC,+CAA4B,CAAC,CAAC;QAE/D,IAAI,QAAQ,CAAC,8BAA8B,EAAE,CAAC;YAC5C,gEAAgE;YAChE,+DAA+D;YAC/D,8DAA8D;YAC9D,4DAA4D;YAC5D,SAAS,CAAC,IAAI,CAAC,2DAA2B,CAAC,CAAC;YAC5C,SAAS,CAAC,IAAI,CAAC,6CAAoB,CAAC,CAAC;YACrC,SAAS,CAAC,IAAI,CAAC;gBACb,OAAO,EAAE,qBAAc;gBACvB,UAAU,EAAE,CACV,QAA8B,EAC9B,QAAkB,EACkB,EAAE,CACtC,IAAI,0EAAkC,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBAC5D,MAAM,EAAE,CAAC,6CAAoB,EAAE,eAAQ,CAAC;aACzC,CAAC,CAAC;YACH,YAAY,CAAC,IAAI,CAAC,2DAA2B,EAAE,6CAAoB,EAAE,qBAAc,CAAC,CAAC;QACvF,CAAC;QAED,OAAO;YACL,MAAM,EAAE,yBAAuB;YAC/B,OAAO,EAAE,CAAC,sBAAe,EAAE,iBAAU,CAAC;YACtC,SAAS;YACT,OAAO,EAAE,YAAuB;SACjC,CAAC;IACJ,CAAC;CACF,CAAA;AApEY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,uBAAuB,CAoEnC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Transaction lifecycle phase at which a `@TransactionalEventsHandler`
3
+ * runs. Mirrors Spring's `TransactionPhase` — see the package README
4
+ * for semantics.
5
+ *
6
+ * - {@link BEFORE_COMMIT}: handler runs before commit; a thrown error
7
+ * causes the transaction to roll back (unless `async: true`).
8
+ * - {@link AFTER_COMMIT}: default. Handler runs only after the
9
+ * transaction has successfully committed. The canonical "publish
10
+ * domain event" phase.
11
+ * - {@link AFTER_ROLLBACK}: handler runs after a rollback.
12
+ * - {@link AFTER_COMPLETION}: handler runs on any completion (commit
13
+ * or rollback).
14
+ */
15
+ export declare enum TransactionPhase {
16
+ BEFORE_COMMIT = "BEFORE_COMMIT",
17
+ AFTER_COMMIT = "AFTER_COMMIT",
18
+ AFTER_ROLLBACK = "AFTER_ROLLBACK",
19
+ AFTER_COMPLETION = "AFTER_COMPLETION"
20
+ }
21
+ //# sourceMappingURL=transactional-listener.types.d.ts.map
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransactionPhase = void 0;
4
+ /**
5
+ * Transaction lifecycle phase at which a `@TransactionalEventsHandler`
6
+ * runs. Mirrors Spring's `TransactionPhase` — see the package README
7
+ * for semantics.
8
+ *
9
+ * - {@link BEFORE_COMMIT}: handler runs before commit; a thrown error
10
+ * causes the transaction to roll back (unless `async: true`).
11
+ * - {@link AFTER_COMMIT}: default. Handler runs only after the
12
+ * transaction has successfully committed. The canonical "publish
13
+ * domain event" phase.
14
+ * - {@link AFTER_ROLLBACK}: handler runs after a rollback.
15
+ * - {@link AFTER_COMPLETION}: handler runs on any completion (commit
16
+ * or rollback).
17
+ */
18
+ var TransactionPhase;
19
+ (function (TransactionPhase) {
20
+ TransactionPhase["BEFORE_COMMIT"] = "BEFORE_COMMIT";
21
+ TransactionPhase["AFTER_COMMIT"] = "AFTER_COMMIT";
22
+ TransactionPhase["AFTER_ROLLBACK"] = "AFTER_ROLLBACK";
23
+ TransactionPhase["AFTER_COMPLETION"] = "AFTER_COMPLETION";
24
+ })(TransactionPhase || (exports.TransactionPhase = TransactionPhase = {}));
25
+ //# sourceMappingURL=transactional-listener.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactional-listener.types.js","sourceRoot":"","sources":["../../src/types/transactional-listener.types.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;GAaG;AACH,IAAY,gBAKX;AALD,WAAY,gBAAgB;IAC1B,mDAA+B,CAAA;IAC/B,iDAA6B,CAAA;IAC7B,qDAAiC,CAAA;IACjC,yDAAqC,CAAA;AACvC,CAAC,EALW,gBAAgB,gCAAhB,gBAAgB,QAK3B"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@nestjs-transactional/cqrs",
3
+ "version": "1.0.0-alpha.0",
4
+ "description": "@nestjs/cqrs integration for @nestjs-transactional/core — transactional event listeners with phases, handler wrapping, AggregateRoot integration",
5
+ "license": "MIT",
6
+ "author": "Igor Golovanov",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/igorgolovanov/nestjs-transactional.git",
10
+ "directory": "packages/cqrs"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/igorgolovanov/nestjs-transactional/issues"
14
+ },
15
+ "homepage": "https://github.com/igorgolovanov/nestjs-transactional/tree/main/packages/cqrs#readme",
16
+ "keywords": [
17
+ "nestjs",
18
+ "cqrs",
19
+ "transaction",
20
+ "transactional",
21
+ "spring",
22
+ "event-listener",
23
+ "aggregate-root",
24
+ "after-commit"
25
+ ],
26
+ "engines": {
27
+ "node": ">=22.11.0"
28
+ },
29
+ "main": "dist/index.js",
30
+ "types": "dist/index.d.ts",
31
+ "files": [
32
+ "dist/**/*.js",
33
+ "dist/**/*.d.ts",
34
+ "dist/**/*.js.map",
35
+ "!dist/**/*.spec.*"
36
+ ],
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/index.d.ts",
40
+ "default": "./dist/index.js"
41
+ }
42
+ },
43
+ "publishConfig": {
44
+ "access": "public",
45
+ "provenance": true
46
+ },
47
+ "peerDependencies": {
48
+ "@nestjs/common": "^10.0.0 || ^11.0.0",
49
+ "@nestjs/core": "^10.0.0 || ^11.0.0",
50
+ "@nestjs/cqrs": "^11.0.0",
51
+ "reflect-metadata": "^0.1.13 || ^0.2.0",
52
+ "rxjs": "^7.0.0",
53
+ "@nestjs-transactional/core": "^1.0.0-alpha.0"
54
+ },
55
+ "devDependencies": {
56
+ "@nestjs/common": "^11.0.0",
57
+ "@nestjs/core": "^11.0.0",
58
+ "@nestjs/cqrs": "^11.0.0",
59
+ "reflect-metadata": "^0.2.2",
60
+ "rxjs": "^7.8.1",
61
+ "@nestjs-transactional/core": "1.0.0-alpha.0",
62
+ "@nestjs-transactional/outbox": "1.0.0-alpha.0"
63
+ },
64
+ "scripts": {
65
+ "build": "tsc -p tsconfig.build.json",
66
+ "clean": "rimraf dist *.tsbuildinfo coverage",
67
+ "test": "jest",
68
+ "test:watch": "jest --watch",
69
+ "test:cov": "jest --coverage",
70
+ "type-check": "tsc --noEmit",
71
+ "lint": "eslint \"src/**/*.ts\""
72
+ }
73
+ }