@nestjs/cqrs 11.0.2 → 12.0.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.
- package/.circleci/config.yml +3 -3
- package/.nvmrc +1 -0
- package/README.md +0 -1
- package/dist/aggregate-root.d.ts +3 -67
- package/dist/aggregate-root.js +6 -83
- package/dist/classes/command.d.ts +2 -2
- package/dist/classes/command.js +2 -6
- package/dist/classes/constants.js +1 -4
- package/dist/classes/index.d.ts +2 -2
- package/dist/classes/index.js +2 -18
- package/dist/classes/query.d.ts +2 -2
- package/dist/classes/query.js +2 -6
- package/dist/command-bus.d.ts +8 -5
- package/dist/command-bus.js +32 -32
- package/dist/constants.js +1 -4
- package/dist/cqrs.module.d.ts +8 -5
- package/dist/cqrs.module.js +37 -37
- package/dist/decorators/command-handler.decorator.d.ts +3 -1
- package/dist/decorators/command-handler.decorator.js +11 -13
- package/dist/decorators/constants.js +7 -10
- package/dist/decorators/events-handler.decorator.d.ts +3 -1
- package/dist/decorators/events-handler.decorator.js +12 -14
- package/dist/decorators/index.d.ts +5 -5
- package/dist/decorators/index.js +5 -21
- package/dist/decorators/publishable.decorator.d.ts +2 -0
- package/dist/decorators/publishable.decorator.js +5 -6
- package/dist/decorators/query-handler.decorator.d.ts +3 -1
- package/dist/decorators/query-handler.decorator.js +11 -13
- package/dist/decorators/saga.decorator.d.ts +2 -0
- package/dist/decorators/saga.decorator.js +7 -9
- package/dist/event-bus.d.ts +13 -8
- package/dist/event-bus.js +54 -51
- package/dist/event-publisher.d.ts +9 -7
- package/dist/event-publisher.js +10 -10
- package/dist/exceptions/command-not-found.exception.d.ts +3 -0
- package/dist/exceptions/command-not-found.exception.js +4 -5
- package/dist/exceptions/index.d.ts +7 -7
- package/dist/exceptions/index.js +7 -23
- package/dist/exceptions/invalid-command-handler.exception.d.ts +3 -0
- package/dist/exceptions/invalid-command-handler.exception.js +4 -5
- package/dist/exceptions/invalid-events-handler.exception.d.ts +3 -0
- package/dist/exceptions/invalid-events-handler.exception.js +4 -5
- package/dist/exceptions/invalid-query-handler.exception.js +1 -5
- package/dist/exceptions/invalid-saga.exception.d.ts +3 -0
- package/dist/exceptions/invalid-saga.exception.js +4 -5
- package/dist/exceptions/query-not-found.exception.d.ts +3 -0
- package/dist/exceptions/query-not-found.exception.js +4 -5
- package/dist/exceptions/unsupported-saga-scope.exception.d.ts +3 -0
- package/dist/exceptions/unsupported-saga-scope.exception.js +4 -5
- package/dist/helpers/default-command-pubsub.d.ts +1 -1
- package/dist/helpers/default-command-pubsub.js +1 -5
- package/dist/helpers/default-event-id-provider.d.ts +1 -1
- package/dist/helpers/default-event-id-provider.js +3 -6
- package/dist/helpers/default-pubsub.d.ts +1 -1
- package/dist/helpers/default-pubsub.js +1 -5
- package/dist/helpers/default-query-pubsub.d.ts +1 -1
- package/dist/helpers/default-query-pubsub.js +1 -5
- package/dist/helpers/default-unhandled-exception-pubsub.d.ts +1 -1
- package/dist/helpers/default-unhandled-exception-pubsub.js +1 -5
- package/dist/index.d.ts +15 -14
- package/dist/index.js +15 -30
- package/dist/interfaces/aggregate-root.interface.d.ts +53 -0
- package/dist/interfaces/aggregate-root.interface.js +1 -0
- package/dist/interfaces/commands/command-bus.interface.d.ts +5 -3
- package/dist/interfaces/commands/command-bus.interface.js +1 -2
- package/dist/interfaces/commands/command-handler.interface.d.ts +4 -2
- package/dist/interfaces/commands/command-handler.interface.js +1 -2
- package/dist/interfaces/commands/command-metadata.interface.js +1 -2
- package/dist/interfaces/commands/command-publisher.interface.d.ts +6 -1
- package/dist/interfaces/commands/command-publisher.interface.js +1 -2
- package/dist/interfaces/commands/command.interface.js +1 -2
- package/dist/interfaces/cqrs-module-options.interface.d.ts +17 -5
- package/dist/interfaces/cqrs-module-options.interface.js +1 -2
- package/dist/interfaces/events/event-bus.interface.d.ts +2 -2
- package/dist/interfaces/events/event-bus.interface.js +1 -2
- package/dist/interfaces/events/event-handler.interface.d.ts +1 -1
- package/dist/interfaces/events/event-handler.interface.js +1 -2
- package/dist/interfaces/events/event-id-provider.interface.d.ts +1 -1
- package/dist/interfaces/events/event-id-provider.interface.js +1 -2
- package/dist/interfaces/events/event-publisher.interface.d.ts +2 -2
- package/dist/interfaces/events/event-publisher.interface.js +1 -2
- package/dist/interfaces/events/event.interface.js +1 -2
- package/dist/interfaces/events/message-source.interface.d.ts +1 -1
- package/dist/interfaces/events/message-source.interface.js +1 -2
- package/dist/interfaces/exceptions/unhandled-exception-info.interface.d.ts +2 -2
- package/dist/interfaces/exceptions/unhandled-exception-info.interface.js +1 -2
- package/dist/interfaces/exceptions/unhandled-exception-publisher.interface.d.ts +3 -3
- package/dist/interfaces/exceptions/unhandled-exception-publisher.interface.js +1 -2
- package/dist/interfaces/index.d.ts +20 -19
- package/dist/interfaces/index.js +20 -35
- package/dist/interfaces/providers-introspection-result.interface.d.ts +4 -4
- package/dist/interfaces/providers-introspection-result.interface.js +1 -2
- package/dist/interfaces/queries/query-bus.interface.d.ts +5 -3
- package/dist/interfaces/queries/query-bus.interface.js +1 -2
- package/dist/interfaces/queries/query-handler.interface.d.ts +4 -2
- package/dist/interfaces/queries/query-handler.interface.js +1 -2
- package/dist/interfaces/queries/query-metadata.interface.js +1 -2
- package/dist/interfaces/queries/query-publisher.interface.d.ts +6 -1
- package/dist/interfaces/queries/query-publisher.interface.js +1 -2
- package/dist/interfaces/queries/query-result.interface.js +1 -2
- package/dist/interfaces/queries/query.interface.js +1 -2
- package/dist/interfaces/saga.type.d.ts +2 -2
- package/dist/interfaces/saga.type.js +1 -2
- package/dist/mixins/index.d.ts +1 -0
- package/dist/mixins/index.js +1 -0
- package/dist/mixins/with-aggregate-root.mixin.d.ts +11 -0
- package/dist/mixins/with-aggregate-root.mixin.js +67 -0
- package/dist/operators/index.d.ts +1 -1
- package/dist/operators/index.js +1 -17
- package/dist/operators/of-type.d.ts +1 -1
- package/dist/operators/of-type.js +3 -6
- package/dist/query-bus.d.ts +8 -5
- package/dist/query-bus.js +31 -31
- package/dist/scopes/async.context.js +9 -13
- package/dist/scopes/index.d.ts +1 -1
- package/dist/scopes/index.js +1 -17
- package/dist/services/explorer.service.d.ts +5 -5
- package/dist/services/explorer.service.js +14 -20
- package/dist/storages/aggregate-root.storage.d.ts +3 -3
- package/dist/storages/aggregate-root.storage.js +1 -5
- package/dist/unhandled-exception-bus.d.ts +2 -2
- package/dist/unhandled-exception-bus.js +14 -17
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -17
- package/dist/utils/observable-bus.js +3 -7
- package/package.json +35 -27
- package/test/e2e/basic-flows.spec.ts +46 -26
- package/test/e2e/generics.spec.ts +3 -3
- package/test/e2e/request-scope.spec.ts +23 -22
- package/test/e2e/sync-event-handlers-app.spec.ts +123 -0
- package/test/e2e/unhandled-exceptions.spec.ts +36 -20
- package/tsconfig.build.json +3 -2
- package/vitest.config.e2e.ts +13 -0
- package/vitest.config.ts +8 -0
- package/dist/exceptions/invalid-module-ref.exception.d.ts +0 -3
- package/dist/exceptions/invalid-module-ref.exception.js +0 -8
- package/dist/helpers/default-get-event-id.d.ts +0 -9
- package/dist/helpers/default-get-event-id.js +0 -18
- package/dist/helpers/default-get-event-name.d.ts +0 -2
- package/dist/helpers/default-get-event-name.js +0 -8
- package/dist/interfaces/cqrs-options.interface.d.ts +0 -10
- package/dist/interfaces/cqrs-options.interface.js +0 -2
- package/dist/interfaces/event-observable.interface.d.ts +0 -4
- package/dist/interfaces/event-observable.interface.js +0 -2
- package/dist/utils/command-handler.decorator.d.ts +0 -3
- package/dist/utils/command-handler.decorator.js +0 -9
- package/dist/utils/constants.d.ts +0 -2
- package/dist/utils/constants.js +0 -4
- package/dist/utils/default-pubsub.d.ts +0 -9
- package/dist/utils/default-pubsub.js +0 -14
- package/dist/utils/events-handler.decorator.d.ts +0 -3
- package/dist/utils/events-handler.decorator.js +0 -9
- package/eslint.config.mjs +0 -42
- package/index.d.ts +0 -1
- package/index.js +0 -6
- package/jest.config.js +0 -9
- package/test/jest-e2e.json +0 -9
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const crypto_1 = require("crypto");
|
|
6
|
-
require("reflect-metadata");
|
|
7
|
-
const constants_1 = require("./constants");
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
import 'reflect-metadata';
|
|
4
|
+
import { COMMAND_HANDLER_METADATA, COMMAND_METADATA } from './constants.js';
|
|
8
5
|
/**
|
|
9
6
|
* Decorator that marks a class as a Nest command handler. A command handler
|
|
10
7
|
* handles commands (actions) executed by your application code.
|
|
@@ -15,16 +12,17 @@ const constants_1 = require("./constants");
|
|
|
15
12
|
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
16
13
|
*
|
|
17
14
|
* @see https://docs.nestjs.com/recipes/cqrs#commands
|
|
15
|
+
*
|
|
16
|
+
* @publicApi
|
|
18
17
|
*/
|
|
19
|
-
const CommandHandler = (command, options) => {
|
|
18
|
+
export const CommandHandler = (command, options) => {
|
|
20
19
|
return (target) => {
|
|
21
|
-
if (!Reflect.hasOwnMetadata(
|
|
22
|
-
Reflect.defineMetadata(
|
|
20
|
+
if (!Reflect.hasOwnMetadata(COMMAND_METADATA, command)) {
|
|
21
|
+
Reflect.defineMetadata(COMMAND_METADATA, { id: randomUUID() }, command);
|
|
23
22
|
}
|
|
24
|
-
Reflect.defineMetadata(
|
|
23
|
+
Reflect.defineMetadata(COMMAND_HANDLER_METADATA, command, target);
|
|
25
24
|
if (options) {
|
|
26
|
-
|
|
25
|
+
Injectable(options)(target);
|
|
27
26
|
}
|
|
28
27
|
};
|
|
29
28
|
};
|
|
30
|
-
exports.CommandHandler = CommandHandler;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
exports.EVENT_METADATA = '__event__';
|
|
9
|
-
exports.EVENTS_HANDLER_METADATA = '__eventsHandler__';
|
|
10
|
-
exports.SAGA_METADATA = '__saga__';
|
|
1
|
+
export const COMMAND_METADATA = '__command__';
|
|
2
|
+
export const COMMAND_HANDLER_METADATA = '__commandHandler__';
|
|
3
|
+
export const QUERY_METADATA = '__query__';
|
|
4
|
+
export const QUERY_HANDLER_METADATA = '__queryHandler__';
|
|
5
|
+
export const EVENT_METADATA = '__event__';
|
|
6
|
+
export const EVENTS_HANDLER_METADATA = '__eventsHandler__';
|
|
7
|
+
export const SAGA_METADATA = '__saga__';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { InjectableOptions } from '@nestjs/common';
|
|
2
2
|
import 'reflect-metadata';
|
|
3
|
-
import { IEvent } from '../index';
|
|
3
|
+
import { IEvent } from '../index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Decorator that marks a class as a Nest event handler. An event handler
|
|
6
6
|
* handles events executed by your application code.
|
|
@@ -11,5 +11,7 @@ import { IEvent } from '../index';
|
|
|
11
11
|
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
12
12
|
*
|
|
13
13
|
* @see https://docs.nestjs.com/recipes/cqrs#events
|
|
14
|
+
*
|
|
15
|
+
* @publicApi
|
|
14
16
|
*/
|
|
15
17
|
export declare const EventsHandler: (...events: (IEvent | (new (...args: any[]) => IEvent) | InjectableOptions)[]) => ClassDecorator;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const crypto_1 = require("crypto");
|
|
6
|
-
require("reflect-metadata");
|
|
7
|
-
const constants_1 = require("./constants");
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
import 'reflect-metadata';
|
|
4
|
+
import { EVENT_METADATA, EVENTS_HANDLER_METADATA } from './constants.js';
|
|
8
5
|
/**
|
|
9
6
|
* Decorator that marks a class as a Nest event handler. An event handler
|
|
10
7
|
* handles events executed by your application code.
|
|
@@ -15,20 +12,21 @@ const constants_1 = require("./constants");
|
|
|
15
12
|
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
16
13
|
*
|
|
17
14
|
* @see https://docs.nestjs.com/recipes/cqrs#events
|
|
15
|
+
*
|
|
16
|
+
* @publicApi
|
|
18
17
|
*/
|
|
19
|
-
const EventsHandler = (...events) => {
|
|
18
|
+
export const EventsHandler = (...events) => {
|
|
20
19
|
return (target) => {
|
|
21
20
|
const last = events[events.length - 1];
|
|
22
|
-
if (typeof last !== 'function' && 'scope' in last) {
|
|
23
|
-
|
|
21
|
+
if (last && typeof last !== 'function' && 'scope' in last) {
|
|
22
|
+
Injectable(last)(target);
|
|
24
23
|
events.pop();
|
|
25
24
|
}
|
|
26
25
|
events.forEach((event) => {
|
|
27
|
-
if (!Reflect.hasOwnMetadata(
|
|
28
|
-
Reflect.defineMetadata(
|
|
26
|
+
if (!Reflect.hasOwnMetadata(EVENT_METADATA, event)) {
|
|
27
|
+
Reflect.defineMetadata(EVENT_METADATA, { id: randomUUID() }, event);
|
|
29
28
|
}
|
|
30
29
|
});
|
|
31
|
-
Reflect.defineMetadata(
|
|
30
|
+
Reflect.defineMetadata(EVENTS_HANDLER_METADATA, events, target);
|
|
32
31
|
};
|
|
33
32
|
};
|
|
34
|
-
exports.EventsHandler = EventsHandler;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './command-handler.decorator';
|
|
2
|
-
export * from './events-handler.decorator';
|
|
3
|
-
export * from './query-handler.decorator';
|
|
4
|
-
export * from './saga.decorator';
|
|
5
|
-
export * from './publishable.decorator';
|
|
1
|
+
export * from './command-handler.decorator.js';
|
|
2
|
+
export * from './events-handler.decorator.js';
|
|
3
|
+
export * from './query-handler.decorator.js';
|
|
4
|
+
export * from './saga.decorator.js';
|
|
5
|
+
export * from './publishable.decorator.js';
|
package/dist/decorators/index.js
CHANGED
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./command-handler.decorator"), exports);
|
|
18
|
-
__exportStar(require("./events-handler.decorator"), exports);
|
|
19
|
-
__exportStar(require("./query-handler.decorator"), exports);
|
|
20
|
-
__exportStar(require("./saga.decorator"), exports);
|
|
21
|
-
__exportStar(require("./publishable.decorator"), exports);
|
|
1
|
+
export * from './command-handler.decorator.js';
|
|
2
|
+
export * from './events-handler.decorator.js';
|
|
3
|
+
export * from './query-handler.decorator.js';
|
|
4
|
+
export * from './saga.decorator.js';
|
|
5
|
+
export * from './publishable.decorator.js';
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Publishable = Publishable;
|
|
4
|
-
const aggregate_root_storage_1 = require("../storages/aggregate-root.storage");
|
|
1
|
+
import { AggregateRootStorage } from '../storages/aggregate-root.storage.js';
|
|
5
2
|
/**
|
|
6
3
|
* Merges event publisher with the decorated class.
|
|
7
4
|
* Implements the `publish` and `publishAll` methods in a similar way to {@link EventPublisher#mergeClassContext}.
|
|
5
|
+
*
|
|
6
|
+
* @publicApi
|
|
8
7
|
*/
|
|
9
|
-
function Publishable() {
|
|
8
|
+
export function Publishable() {
|
|
10
9
|
return (target) => {
|
|
11
|
-
|
|
10
|
+
AggregateRootStorage.add(target);
|
|
12
11
|
};
|
|
13
12
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { InjectableOptions } from '@nestjs/common';
|
|
2
2
|
import 'reflect-metadata';
|
|
3
|
-
import { IQuery } from '../interfaces';
|
|
3
|
+
import { IQuery } from '../interfaces/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Decorator that marks a class as a Nest query handler. A query handler
|
|
6
6
|
* handles queries executed by your application code.
|
|
@@ -11,5 +11,7 @@ import { IQuery } from '../interfaces';
|
|
|
11
11
|
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
12
12
|
*
|
|
13
13
|
* @see https://docs.nestjs.com/recipes/cqrs#queries
|
|
14
|
+
*
|
|
15
|
+
* @publicApi
|
|
14
16
|
*/
|
|
15
17
|
export declare const QueryHandler: (query: IQuery, options?: InjectableOptions) => ClassDecorator;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const crypto_1 = require("crypto");
|
|
6
|
-
require("reflect-metadata");
|
|
7
|
-
const constants_1 = require("./constants");
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
import 'reflect-metadata';
|
|
4
|
+
import { QUERY_HANDLER_METADATA, QUERY_METADATA } from './constants.js';
|
|
8
5
|
/**
|
|
9
6
|
* Decorator that marks a class as a Nest query handler. A query handler
|
|
10
7
|
* handles queries executed by your application code.
|
|
@@ -15,16 +12,17 @@ const constants_1 = require("./constants");
|
|
|
15
12
|
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
16
13
|
*
|
|
17
14
|
* @see https://docs.nestjs.com/recipes/cqrs#queries
|
|
15
|
+
*
|
|
16
|
+
* @publicApi
|
|
18
17
|
*/
|
|
19
|
-
const QueryHandler = (query, options) => {
|
|
18
|
+
export const QueryHandler = (query, options) => {
|
|
20
19
|
return (target) => {
|
|
21
|
-
if (!Reflect.hasOwnMetadata(
|
|
22
|
-
Reflect.defineMetadata(
|
|
20
|
+
if (!Reflect.hasOwnMetadata(QUERY_METADATA, query)) {
|
|
21
|
+
Reflect.defineMetadata(QUERY_METADATA, { id: randomUUID() }, query);
|
|
23
22
|
}
|
|
24
|
-
Reflect.defineMetadata(
|
|
23
|
+
Reflect.defineMetadata(QUERY_HANDLER_METADATA, query, target);
|
|
25
24
|
if (options) {
|
|
26
|
-
|
|
25
|
+
Injectable(options)(target);
|
|
27
26
|
}
|
|
28
27
|
};
|
|
29
28
|
};
|
|
30
|
-
exports.QueryHandler = QueryHandler;
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.Saga = void 0;
|
|
4
|
-
require("reflect-metadata");
|
|
5
|
-
const constants_1 = require("./constants");
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { SAGA_METADATA } from './constants.js';
|
|
6
3
|
/**
|
|
7
4
|
* Decorator that marks a class as a Nest saga. Sagas may listen and react to 1..N events.
|
|
8
5
|
*
|
|
9
6
|
* @see https://docs.nestjs.com/recipes/cqrs#sagas
|
|
7
|
+
*
|
|
8
|
+
* @publicApi
|
|
10
9
|
*/
|
|
11
|
-
const Saga = () => {
|
|
10
|
+
export const Saga = () => {
|
|
12
11
|
return (target, propertyKey) => {
|
|
13
|
-
const properties = Reflect.getMetadata(
|
|
14
|
-
Reflect.defineMetadata(
|
|
12
|
+
const properties = Reflect.getMetadata(SAGA_METADATA, target.constructor) || [];
|
|
13
|
+
Reflect.defineMetadata(SAGA_METADATA, [...properties, propertyKey], target.constructor);
|
|
15
14
|
};
|
|
16
15
|
};
|
|
17
|
-
exports.Saga = Saga;
|
package/dist/event-bus.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { OnModuleDestroy, Type } from '@nestjs/common';
|
|
2
2
|
import { ModuleRef } from '@nestjs/core';
|
|
3
|
-
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
|
4
|
-
import { Observable, Subscription } from 'rxjs';
|
|
5
|
-
import { CommandBus } from './command-bus';
|
|
6
|
-
import { CqrsModuleOptions, EventIdProvider, IEvent, IEventBus, IEventHandler, IEventPublisher, ISaga } from './interfaces';
|
|
7
|
-
import { AsyncContext } from './scopes';
|
|
8
|
-
import { UnhandledExceptionBus } from './unhandled-exception-bus';
|
|
9
|
-
import { ObservableBus } from './utils';
|
|
3
|
+
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper.js';
|
|
4
|
+
import { Observable, Subscription, UnaryFunction } from 'rxjs';
|
|
5
|
+
import { CommandBus } from './command-bus.js';
|
|
6
|
+
import { CqrsModuleOptions, EventIdProvider, IEvent, IEventBus, IEventHandler, IEventPublisher, ISaga } from './interfaces/index.js';
|
|
7
|
+
import { AsyncContext } from './scopes/index.js';
|
|
8
|
+
import { UnhandledExceptionBus } from './unhandled-exception-bus.js';
|
|
9
|
+
import { ObservableBus } from './utils/index.js';
|
|
10
10
|
export type EventHandlerType<EventBase extends IEvent = IEvent> = Type<IEventHandler<EventBase>>;
|
|
11
|
+
export type EventOperator<EventBase extends IEvent = IEvent> = UnaryFunction<Observable<EventBase>, Observable<any>>;
|
|
12
|
+
/**
|
|
13
|
+
* @publicApi
|
|
14
|
+
*/
|
|
11
15
|
export declare class EventBus<EventBase extends IEvent = IEvent> extends ObservableBus<EventBase> implements IEventBus<EventBase>, OnModuleDestroy {
|
|
12
16
|
private readonly commandBus;
|
|
13
17
|
private readonly moduleRef;
|
|
@@ -15,6 +19,7 @@ export declare class EventBus<EventBase extends IEvent = IEvent> extends Observa
|
|
|
15
19
|
private readonly options?;
|
|
16
20
|
protected eventIdProvider: EventIdProvider<EventBase>;
|
|
17
21
|
protected readonly subscriptions: Subscription[];
|
|
22
|
+
readonly eventOperators: EventOperator<EventBase>[];
|
|
18
23
|
private _publisher;
|
|
19
24
|
private readonly _logger;
|
|
20
25
|
constructor(commandBus: CommandBus, moduleRef: ModuleRef, unhandledExceptionBus: UnhandledExceptionBus, options?: CqrsModuleOptions | undefined);
|
|
@@ -82,7 +87,7 @@ export declare class EventBus<EventBase extends IEvent = IEvent> extends Observa
|
|
|
82
87
|
registerSagas(wrappers?: InstanceWrapper<object>[]): void;
|
|
83
88
|
register(handlers?: InstanceWrapper<IEventHandler<EventBase>>[]): void;
|
|
84
89
|
protected registerHandler(handler: InstanceWrapper<IEventHandler<EventBase>>): void;
|
|
85
|
-
protected
|
|
90
|
+
protected filterEventWithId(id: string | null): import("rxjs").MonoTypeOperatorFunction<EventBase>;
|
|
86
91
|
protected registerSaga(saga: ISaga<EventBase>): void;
|
|
87
92
|
private reflectEvents;
|
|
88
93
|
private useDefaultPublisher;
|
package/dist/event-bus.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
2
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
3
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -12,32 +11,34 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
12
|
};
|
|
14
13
|
var EventBus_1;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
import { Inject, Injectable, Logger, Optional, } from '@nestjs/common';
|
|
15
|
+
import { ModuleRef } from '@nestjs/core';
|
|
16
|
+
import { Observable, defer, of, pipe } from 'rxjs';
|
|
17
|
+
import { catchError, filter, mergeMap, tap } from 'rxjs/operators';
|
|
18
|
+
import { CommandBus } from './command-bus.js';
|
|
19
|
+
import { CQRS_MODULE_OPTIONS } from './constants.js';
|
|
20
|
+
import { EVENTS_HANDLER_METADATA, SAGA_METADATA, } from './decorators/constants.js';
|
|
21
|
+
import { InvalidSagaException, UnsupportedSagaScopeException, } from './exceptions/index.js';
|
|
22
|
+
import { defaultEventIdProvider } from './helpers/default-event-id-provider.js';
|
|
23
|
+
import { DefaultPubSub } from './helpers/default-pubsub.js';
|
|
24
|
+
import { AsyncContext } from './scopes/index.js';
|
|
25
|
+
import { UnhandledExceptionBus } from './unhandled-exception-bus.js';
|
|
26
|
+
import { ObservableBus } from './utils/index.js';
|
|
27
|
+
/**
|
|
28
|
+
* @publicApi
|
|
29
|
+
*/
|
|
30
|
+
let EventBus = EventBus_1 = class EventBus extends ObservableBus {
|
|
31
31
|
constructor(commandBus, moduleRef, unhandledExceptionBus, options) {
|
|
32
32
|
super();
|
|
33
33
|
this.commandBus = commandBus;
|
|
34
34
|
this.moduleRef = moduleRef;
|
|
35
35
|
this.unhandledExceptionBus = unhandledExceptionBus;
|
|
36
36
|
this.options = options;
|
|
37
|
-
this.
|
|
37
|
+
this.eventOperators = [];
|
|
38
|
+
this._logger = new Logger(EventBus_1.name);
|
|
38
39
|
this.subscriptions = [];
|
|
39
40
|
this.eventIdProvider =
|
|
40
|
-
this.options?.eventIdProvider ??
|
|
41
|
+
this.options?.eventIdProvider ?? defaultEventIdProvider;
|
|
41
42
|
if (this.options?.eventPublisher) {
|
|
42
43
|
this._publisher = this.options.eventPublisher;
|
|
43
44
|
}
|
|
@@ -70,7 +71,7 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
70
71
|
* @param asyncContext Async context
|
|
71
72
|
*/
|
|
72
73
|
publish(event, dispatcherOrAsyncContext, asyncContext) {
|
|
73
|
-
if (!asyncContext && dispatcherOrAsyncContext instanceof
|
|
74
|
+
if (!asyncContext && dispatcherOrAsyncContext instanceof AsyncContext) {
|
|
74
75
|
asyncContext = dispatcherOrAsyncContext;
|
|
75
76
|
dispatcherOrAsyncContext = undefined;
|
|
76
77
|
}
|
|
@@ -86,13 +87,13 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
86
87
|
* @param asyncContext Async context
|
|
87
88
|
*/
|
|
88
89
|
publishAll(events, dispatcherOrAsyncContext, asyncContext) {
|
|
89
|
-
if (!asyncContext && dispatcherOrAsyncContext instanceof
|
|
90
|
+
if (!asyncContext && dispatcherOrAsyncContext instanceof AsyncContext) {
|
|
90
91
|
asyncContext = dispatcherOrAsyncContext;
|
|
91
92
|
dispatcherOrAsyncContext = undefined;
|
|
92
93
|
}
|
|
93
94
|
if (asyncContext) {
|
|
94
95
|
events.forEach((event) => {
|
|
95
|
-
if (
|
|
96
|
+
if (AsyncContext.isAttached(event)) {
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
98
99
|
asyncContext.attachTo(event);
|
|
@@ -104,38 +105,37 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
104
105
|
return (events || []).map((event) => this._publisher.publish(event, dispatcherOrAsyncContext, asyncContext));
|
|
105
106
|
}
|
|
106
107
|
bind(handler, id) {
|
|
107
|
-
const stream$ = id ? this.ofEventId(id) : this.subject$;
|
|
108
108
|
const deferred = handler.isDependencyTreeStatic()
|
|
109
109
|
? (event) => () => {
|
|
110
110
|
return Promise.resolve(handler.instance.handle(event));
|
|
111
111
|
}
|
|
112
112
|
: (event) => async () => {
|
|
113
|
-
const asyncContext =
|
|
113
|
+
const asyncContext = AsyncContext.of(event) ?? new AsyncContext();
|
|
114
114
|
const instance = await this.moduleRef.resolve(handler.metatype, asyncContext.id, {
|
|
115
115
|
strict: false,
|
|
116
116
|
});
|
|
117
117
|
return instance.handle(event);
|
|
118
118
|
};
|
|
119
|
-
const
|
|
120
|
-
.pipe((0, operators_1.mergeMap)((event) => (0, rxjs_1.defer)(deferred(event)).pipe((0, operators_1.catchError)((error) => {
|
|
119
|
+
const eventOperator = pipe(this.filterEventWithId(id), mergeMap((event) => defer(deferred(event)).pipe(catchError((error) => {
|
|
121
120
|
if (this.options?.rethrowUnhandled) {
|
|
122
121
|
throw error;
|
|
123
122
|
}
|
|
124
123
|
const unhandledError = this.mapToUnhandledErrorInfo(event, error);
|
|
125
124
|
this.unhandledExceptionBus.publish(unhandledError);
|
|
126
125
|
this._logger.error(`"${handler.constructor.name}" has thrown an unhandled exception.`, error);
|
|
127
|
-
return
|
|
128
|
-
}))))
|
|
129
|
-
|
|
126
|
+
return of();
|
|
127
|
+
}))));
|
|
128
|
+
this.eventOperators.push(eventOperator);
|
|
129
|
+
const subscription = this.subject$.pipe(eventOperator).subscribe();
|
|
130
130
|
this.subscriptions.push(subscription);
|
|
131
131
|
}
|
|
132
132
|
registerSagas(wrappers = []) {
|
|
133
133
|
const sagas = wrappers
|
|
134
134
|
.map((wrapper) => {
|
|
135
135
|
const { metatype: target } = wrapper;
|
|
136
|
-
const metadata = Reflect.getMetadata(
|
|
136
|
+
const metadata = Reflect.getMetadata(SAGA_METADATA, target) ?? [];
|
|
137
137
|
if (!wrapper.isDependencyTreeStatic()) {
|
|
138
|
-
throw new
|
|
138
|
+
throw new UnsupportedSagaScopeException();
|
|
139
139
|
}
|
|
140
140
|
const instance = wrapper.instance;
|
|
141
141
|
return metadata.map((key) => {
|
|
@@ -164,49 +164,52 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
164
164
|
this.bind(handler, eventId);
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
filterEventWithId(id) {
|
|
168
|
+
if (!id) {
|
|
169
|
+
return tap();
|
|
170
|
+
}
|
|
171
|
+
return filter((event) => {
|
|
169
172
|
const { constructor } = Object.getPrototypeOf(event);
|
|
170
173
|
if (!constructor) {
|
|
171
174
|
return false;
|
|
172
175
|
}
|
|
173
176
|
return this.eventIdProvider.getEventId(constructor) === id;
|
|
174
|
-
})
|
|
177
|
+
});
|
|
175
178
|
}
|
|
176
179
|
registerSaga(saga) {
|
|
177
180
|
if (typeof saga !== 'function') {
|
|
178
|
-
throw new
|
|
181
|
+
throw new InvalidSagaException();
|
|
179
182
|
}
|
|
180
183
|
const stream$ = saga(this);
|
|
181
|
-
if (!(stream$ instanceof
|
|
182
|
-
throw new
|
|
184
|
+
if (!(stream$ instanceof Observable)) {
|
|
185
|
+
throw new InvalidSagaException();
|
|
183
186
|
}
|
|
184
187
|
const subscription = stream$
|
|
185
|
-
.pipe(
|
|
188
|
+
.pipe(filter((e) => !!e), catchError((error) => {
|
|
186
189
|
if (this.options?.rethrowUnhandled) {
|
|
187
190
|
throw error;
|
|
188
191
|
}
|
|
189
192
|
const unhandledError = this.mapToUnhandledErrorInfo(saga.name, error);
|
|
190
193
|
this.unhandledExceptionBus.publish(unhandledError);
|
|
191
194
|
this._logger.error(`Saga "${saga.name}" has thrown an unhandled exception.`, error);
|
|
192
|
-
return
|
|
193
|
-
}),
|
|
195
|
+
return of();
|
|
196
|
+
}), mergeMap((command) => defer(() => this.commandBus.execute(command)).pipe(catchError((error) => {
|
|
194
197
|
if (this.options?.rethrowUnhandled) {
|
|
195
198
|
throw error;
|
|
196
199
|
}
|
|
197
200
|
const unhandledError = this.mapToUnhandledErrorInfo(command, error);
|
|
198
201
|
this.unhandledExceptionBus.publish(unhandledError);
|
|
199
202
|
this._logger.error(`Command handler which execution was triggered by Saga has thrown an unhandled exception.`, error);
|
|
200
|
-
return
|
|
203
|
+
return of();
|
|
201
204
|
}))))
|
|
202
205
|
.subscribe();
|
|
203
206
|
this.subscriptions.push(subscription);
|
|
204
207
|
}
|
|
205
208
|
reflectEvents(handler) {
|
|
206
|
-
return Reflect.getMetadata(
|
|
209
|
+
return Reflect.getMetadata(EVENTS_HANDLER_METADATA, handler);
|
|
207
210
|
}
|
|
208
211
|
useDefaultPublisher() {
|
|
209
|
-
this._publisher = new
|
|
212
|
+
this._publisher = new DefaultPubSub(this.subject$);
|
|
210
213
|
}
|
|
211
214
|
mapToUnhandledErrorInfo(eventOrCommand, exception) {
|
|
212
215
|
return {
|
|
@@ -215,12 +218,12 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
215
218
|
};
|
|
216
219
|
}
|
|
217
220
|
};
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
(
|
|
221
|
-
__param(3, (
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
unhandled_exception_bus_1.UnhandledExceptionBus, Object])
|
|
221
|
+
EventBus = EventBus_1 = __decorate([
|
|
222
|
+
Injectable(),
|
|
223
|
+
__param(3, Optional()),
|
|
224
|
+
__param(3, Inject(CQRS_MODULE_OPTIONS)),
|
|
225
|
+
__metadata("design:paramtypes", [CommandBus,
|
|
226
|
+
ModuleRef,
|
|
227
|
+
UnhandledExceptionBus, Object])
|
|
226
228
|
], EventBus);
|
|
229
|
+
export { EventBus };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { AsyncContext } from './scopes';
|
|
1
|
+
import { EventBus } from './event-bus.js';
|
|
2
|
+
import { IAggregateRoot, IEvent } from './interfaces/index.js';
|
|
3
|
+
import { AsyncContext } from './scopes/index.js';
|
|
5
4
|
export interface Constructor<T> {
|
|
6
5
|
new (...args: any[]): T;
|
|
7
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* @publicApi
|
|
9
|
+
*/
|
|
8
10
|
export declare class EventPublisher<EventBase extends IEvent = IEvent> {
|
|
9
11
|
private readonly eventBus;
|
|
10
12
|
constructor(eventBus: EventBus<EventBase>);
|
|
@@ -14,12 +16,12 @@ export declare class EventPublisher<EventBase extends IEvent = IEvent> {
|
|
|
14
16
|
* @param metatype The class to merge into.
|
|
15
17
|
* @param asyncContext The async context (if scoped).
|
|
16
18
|
*/
|
|
17
|
-
mergeClassContext<T extends Constructor<
|
|
19
|
+
mergeClassContext<T extends Constructor<IAggregateRoot<EventBase>>>(metatype: T, asyncContext?: AsyncContext): T;
|
|
18
20
|
/**
|
|
19
21
|
* Merge the event publisher into the provided object.
|
|
20
|
-
* This is required to make `publish` and `publishAll` available on the `
|
|
22
|
+
* This is required to make `publish` and `publishAll` available on the `IAggregateRoot` class instance.
|
|
21
23
|
* @param object The object to merge into.
|
|
22
24
|
* @param asyncContext The async context (if scoped).
|
|
23
25
|
*/
|
|
24
|
-
mergeObjectContext<T extends
|
|
26
|
+
mergeObjectContext<T extends IAggregateRoot<EventBase>>(object: T, asyncContext?: AsyncContext): T;
|
|
25
27
|
}
|
package/dist/event-publisher.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
2
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
3
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -8,10 +7,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
import { Injectable } from '@nestjs/common';
|
|
11
|
+
import { EventBus } from './event-bus.js';
|
|
12
|
+
/**
|
|
13
|
+
* @publicApi
|
|
14
|
+
*/
|
|
15
15
|
let EventPublisher = class EventPublisher {
|
|
16
16
|
constructor(eventBus) {
|
|
17
17
|
this.eventBus = eventBus;
|
|
@@ -35,7 +35,7 @@ let EventPublisher = class EventPublisher {
|
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Merge the event publisher into the provided object.
|
|
38
|
-
* This is required to make `publish` and `publishAll` available on the `
|
|
38
|
+
* This is required to make `publish` and `publishAll` available on the `IAggregateRoot` class instance.
|
|
39
39
|
* @param object The object to merge into.
|
|
40
40
|
* @param asyncContext The async context (if scoped).
|
|
41
41
|
*/
|
|
@@ -50,8 +50,8 @@ let EventPublisher = class EventPublisher {
|
|
|
50
50
|
return object;
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
(
|
|
56
|
-
__metadata("design:paramtypes", [event_bus_1.EventBus])
|
|
53
|
+
EventPublisher = __decorate([
|
|
54
|
+
Injectable(),
|
|
55
|
+
__metadata("design:paramtypes", [EventBus])
|
|
57
56
|
], EventPublisher);
|
|
57
|
+
export { EventPublisher };
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class CommandHandlerNotFoundException extends Error {
|
|
1
|
+
/**
|
|
2
|
+
* @publicApi
|
|
3
|
+
*/
|
|
4
|
+
export class CommandHandlerNotFoundException extends Error {
|
|
5
5
|
constructor(commandName) {
|
|
6
6
|
super(`No handler found for the command: "${commandName}".`);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
|
-
exports.CommandHandlerNotFoundException = CommandHandlerNotFoundException;
|