@nestjs/cqrs 10.2.8 → 11.0.0-next.2
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 +29 -1
- package/.husky/commit-msg +0 -3
- package/.husky/pre-commit +0 -3
- package/dist/classes/command.d.ts +9 -0
- package/dist/classes/command.js +7 -0
- package/dist/classes/constants.d.ts +1 -0
- package/dist/classes/constants.js +4 -0
- package/dist/classes/index.d.ts +2 -0
- package/dist/classes/index.js +18 -0
- package/dist/classes/query.d.ts +9 -0
- package/dist/classes/query.js +7 -0
- package/dist/command-bus.d.ts +26 -7
- package/dist/command-bus.js +57 -21
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -0
- package/dist/cqrs.module.d.ts +5 -4
- package/dist/cqrs.module.js +21 -11
- package/dist/decorators/command-handler.decorator.d.ts +3 -1
- package/dist/decorators/command-handler.decorator.js +8 -3
- package/dist/decorators/events-handler.decorator.d.ts +3 -1
- package/dist/decorators/events-handler.decorator.js +9 -2
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +6 -1
- package/dist/decorators/publishable.decorator.d.ts +5 -0
- package/dist/decorators/publishable.decorator.js +13 -0
- package/dist/decorators/query-handler.decorator.d.ts +3 -1
- package/dist/decorators/query-handler.decorator.js +8 -3
- package/dist/event-bus.d.ts +51 -10
- package/dist/event-bus.js +108 -31
- package/dist/event-publisher.d.ts +5 -2
- package/dist/event-publisher.js +10 -8
- package/dist/exceptions/command-not-found.exception.js +1 -1
- package/dist/exceptions/index.d.ts +1 -0
- package/dist/exceptions/index.js +6 -1
- package/dist/exceptions/invalid-command-handler.exception.js +1 -1
- package/dist/exceptions/invalid-events-handler.exception.js +1 -1
- package/dist/exceptions/invalid-query-handler.exception.js +1 -1
- package/dist/exceptions/invalid-saga.exception.js +1 -1
- package/dist/exceptions/query-not-found.exception.js +1 -1
- package/dist/exceptions/unsupported-saga-scope.exception.d.ts +3 -0
- package/dist/exceptions/unsupported-saga-scope.exception.js +9 -0
- package/dist/helpers/default-event-id-provider.d.ts +7 -0
- package/dist/helpers/default-event-id-provider.js +10 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -1
- package/dist/interfaces/commands/command-bus.interface.d.ts +18 -1
- package/dist/interfaces/commands/command-handler.interface.d.ts +9 -2
- package/dist/interfaces/cqrs-module-options.interface.d.ts +38 -8
- package/dist/interfaces/events/event-bus.interface.d.ts +41 -4
- package/dist/interfaces/events/event-id-provider.interface.d.ts +12 -0
- package/dist/interfaces/events/event-id-provider.interface.js +2 -0
- package/dist/interfaces/events/event-publisher.interface.d.ts +7 -4
- package/dist/interfaces/index.d.ts +2 -0
- package/dist/interfaces/index.js +7 -1
- package/dist/interfaces/providers-introspection-result.interface.d.ts +10 -0
- package/dist/interfaces/providers-introspection-result.interface.js +2 -0
- package/dist/interfaces/queries/query-bus.interface.d.ts +18 -1
- package/dist/interfaces/queries/query-handler.interface.d.ts +9 -2
- package/dist/interfaces/saga.type.d.ts +1 -1
- package/dist/operators/index.js +5 -1
- package/dist/operators/of-type.d.ts +1 -1
- package/dist/operators/of-type.js +1 -2
- package/dist/query-bus.d.ts +26 -6
- package/dist/query-bus.js +49 -20
- package/dist/scopes/async.context.d.ts +30 -0
- package/dist/scopes/async.context.js +58 -0
- package/dist/scopes/index.d.ts +1 -0
- package/dist/scopes/index.js +17 -0
- package/dist/services/explorer.service.d.ts +4 -6
- package/dist/services/explorer.service.js +14 -14
- package/dist/storages/aggregate-root.storage.d.ts +8 -0
- package/dist/storages/aggregate-root.storage.js +21 -0
- package/dist/unhandled-exception-bus.d.ts +4 -3
- package/dist/unhandled-exception-bus.js +18 -5
- package/dist/utils/index.js +5 -1
- package/jest.config.js +5 -0
- package/package.json +29 -17
- package/renovate.json +8 -7
- package/test/e2e/basic-flows.spec.ts +106 -0
- package/test/e2e/generics.spec.ts +198 -0
- package/test/e2e/request-scope.spec.ts +141 -0
- package/test/e2e/unhandled-exceptions.spec.ts +73 -0
- package/test/jest-e2e.json +9 -0
- package/test/utils/wait-immediate.ts +2 -0
- package/tsconfig.build.json +10 -0
package/dist/event-bus.d.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import { OnModuleDestroy, Type } from '@nestjs/common';
|
|
2
2
|
import { ModuleRef } from '@nestjs/core';
|
|
3
|
+
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
|
3
4
|
import { Observable, Subscription } from 'rxjs';
|
|
4
5
|
import { CommandBus } from './command-bus';
|
|
5
|
-
import { IEvent, IEventBus, IEventHandler, IEventPublisher, ISaga } from './interfaces';
|
|
6
|
+
import { CqrsModuleOptions, EventIdProvider, IEvent, IEventBus, IEventHandler, IEventPublisher, ISaga } from './interfaces';
|
|
7
|
+
import { AsyncContext } from './scopes';
|
|
6
8
|
import { UnhandledExceptionBus } from './unhandled-exception-bus';
|
|
7
9
|
import { ObservableBus } from './utils';
|
|
8
|
-
export
|
|
10
|
+
export type EventHandlerType<EventBase extends IEvent = IEvent> = Type<IEventHandler<EventBase>>;
|
|
9
11
|
export declare class EventBus<EventBase extends IEvent = IEvent> extends ObservableBus<EventBase> implements IEventBus<EventBase>, OnModuleDestroy {
|
|
10
12
|
private readonly commandBus;
|
|
11
13
|
private readonly moduleRef;
|
|
12
14
|
private readonly unhandledExceptionBus;
|
|
13
|
-
|
|
15
|
+
private readonly options?;
|
|
16
|
+
protected eventIdProvider: EventIdProvider<EventBase>;
|
|
14
17
|
protected readonly subscriptions: Subscription[];
|
|
15
18
|
private _publisher;
|
|
16
19
|
private readonly _logger;
|
|
17
|
-
constructor(commandBus: CommandBus, moduleRef: ModuleRef, unhandledExceptionBus: UnhandledExceptionBus);
|
|
20
|
+
constructor(commandBus: CommandBus, moduleRef: ModuleRef, unhandledExceptionBus: UnhandledExceptionBus, options?: CqrsModuleOptions | undefined);
|
|
18
21
|
/**
|
|
19
22
|
* Returns the publisher.
|
|
20
23
|
* Default publisher is `DefaultPubSub` (in memory).
|
|
@@ -31,16 +34,54 @@ export declare class EventBus<EventBase extends IEvent = IEvent> extends Observa
|
|
|
31
34
|
* Publishes an event.
|
|
32
35
|
* @param event The event to publish.
|
|
33
36
|
*/
|
|
34
|
-
publish<TEvent extends EventBase
|
|
37
|
+
publish<TEvent extends EventBase>(event: TEvent): any;
|
|
38
|
+
/**
|
|
39
|
+
* Publishes an event.
|
|
40
|
+
* @param event The event to publish.
|
|
41
|
+
* @param asyncContext Async context
|
|
42
|
+
*/
|
|
43
|
+
publish<TEvent extends EventBase>(event: TEvent, asyncContext: AsyncContext): any;
|
|
44
|
+
/**
|
|
45
|
+
* Publishes an event.
|
|
46
|
+
* @param event The event to publish.
|
|
47
|
+
* @param dispatcherContext Dispatcher context
|
|
48
|
+
*/
|
|
49
|
+
publish<TEvent extends EventBase, TContext = unknown>(event: TEvent, dispatcherContext: TContext): any;
|
|
50
|
+
/**
|
|
51
|
+
* Publishes an event.
|
|
52
|
+
* @param event The event to publish.
|
|
53
|
+
* @param dispatcherContext Dispatcher context
|
|
54
|
+
* @param asyncContext Async context
|
|
55
|
+
*/
|
|
56
|
+
publish<TEvent extends EventBase, TContext = unknown>(event: TEvent, dispatcherContext: TContext, asyncContext: AsyncContext): any;
|
|
57
|
+
/**
|
|
58
|
+
* Publishes multiple events.
|
|
59
|
+
* @param events The events to publish.
|
|
60
|
+
*/
|
|
61
|
+
publishAll<TEvent extends EventBase>(events: TEvent[]): any;
|
|
62
|
+
/**
|
|
63
|
+
* Publishes multiple events.
|
|
64
|
+
* @param events The events to publish.
|
|
65
|
+
* @param asyncContext Async context
|
|
66
|
+
*/
|
|
67
|
+
publishAll<TEvent extends EventBase>(events: TEvent[], asyncContext: AsyncContext): any;
|
|
68
|
+
/**
|
|
69
|
+
* Publishes multiple events.
|
|
70
|
+
* @param events The events to publish.
|
|
71
|
+
* @param dispatcherContext Dispatcher context
|
|
72
|
+
*/
|
|
73
|
+
publishAll<TEvent extends EventBase, TContext = unknown>(events: TEvent[], dispatcherContext: TContext): any;
|
|
35
74
|
/**
|
|
36
75
|
* Publishes multiple events.
|
|
37
76
|
* @param events The events to publish.
|
|
77
|
+
* @param dispatcherContext Dispatcher context
|
|
78
|
+
* @param asyncContext Async context
|
|
38
79
|
*/
|
|
39
|
-
publishAll<TEvent extends EventBase, TContext = unknown>(events: TEvent[],
|
|
40
|
-
bind(handler: IEventHandler<EventBase
|
|
41
|
-
registerSagas(
|
|
42
|
-
register(handlers?:
|
|
43
|
-
protected registerHandler(handler:
|
|
80
|
+
publishAll<TEvent extends EventBase, TContext = unknown>(events: TEvent[], dispatcherContext: TContext, asyncContext: AsyncContext): any;
|
|
81
|
+
bind(handler: InstanceWrapper<IEventHandler<EventBase>>, id: string): void;
|
|
82
|
+
registerSagas(wrappers?: InstanceWrapper<object>[]): void;
|
|
83
|
+
register(handlers?: InstanceWrapper<IEventHandler<EventBase>>[]): void;
|
|
84
|
+
protected registerHandler(handler: InstanceWrapper<IEventHandler<EventBase>>): void;
|
|
44
85
|
protected ofEventId(id: string): Observable<EventBase>;
|
|
45
86
|
protected registerSaga(saga: ISaga<EventBase>): void;
|
|
46
87
|
private reflectEvents;
|
package/dist/event-bus.js
CHANGED
|
@@ -8,6 +8,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
11
14
|
var EventBus_1;
|
|
12
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
16
|
exports.EventBus = void 0;
|
|
@@ -16,22 +19,31 @@ const core_1 = require("@nestjs/core");
|
|
|
16
19
|
const rxjs_1 = require("rxjs");
|
|
17
20
|
const operators_1 = require("rxjs/operators");
|
|
18
21
|
const command_bus_1 = require("./command-bus");
|
|
19
|
-
const constants_1 = require("./
|
|
22
|
+
const constants_1 = require("./constants");
|
|
23
|
+
const constants_2 = require("./decorators/constants");
|
|
20
24
|
const exceptions_1 = require("./exceptions");
|
|
21
|
-
const
|
|
25
|
+
const default_event_id_provider_1 = require("./helpers/default-event-id-provider");
|
|
22
26
|
const default_pubsub_1 = require("./helpers/default-pubsub");
|
|
27
|
+
const scopes_1 = require("./scopes");
|
|
23
28
|
const unhandled_exception_bus_1 = require("./unhandled-exception-bus");
|
|
24
29
|
const utils_1 = require("./utils");
|
|
25
30
|
let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
26
|
-
constructor(commandBus, moduleRef, unhandledExceptionBus) {
|
|
31
|
+
constructor(commandBus, moduleRef, unhandledExceptionBus, options) {
|
|
27
32
|
super();
|
|
28
33
|
this.commandBus = commandBus;
|
|
29
34
|
this.moduleRef = moduleRef;
|
|
30
35
|
this.unhandledExceptionBus = unhandledExceptionBus;
|
|
36
|
+
this.options = options;
|
|
31
37
|
this._logger = new common_1.Logger(EventBus_1.name);
|
|
32
38
|
this.subscriptions = [];
|
|
33
|
-
this.
|
|
34
|
-
|
|
39
|
+
this.eventIdProvider =
|
|
40
|
+
this.options?.eventIdProvider ?? default_event_id_provider_1.defaultEventIdProvider;
|
|
41
|
+
if (this.options?.eventPublisher) {
|
|
42
|
+
this._publisher = this.options.eventPublisher;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.useDefaultPublisher();
|
|
46
|
+
}
|
|
35
47
|
}
|
|
36
48
|
/**
|
|
37
49
|
* Returns the publisher.
|
|
@@ -54,24 +66,61 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
54
66
|
/**
|
|
55
67
|
* Publishes an event.
|
|
56
68
|
* @param event The event to publish.
|
|
69
|
+
* @param dispatcherOrAsyncContext Dispatcher context or async context
|
|
70
|
+
* @param asyncContext Async context
|
|
57
71
|
*/
|
|
58
|
-
publish(event,
|
|
59
|
-
|
|
72
|
+
publish(event, dispatcherOrAsyncContext, asyncContext) {
|
|
73
|
+
if (!asyncContext && dispatcherOrAsyncContext instanceof scopes_1.AsyncContext) {
|
|
74
|
+
asyncContext = dispatcherOrAsyncContext;
|
|
75
|
+
dispatcherOrAsyncContext = undefined;
|
|
76
|
+
}
|
|
77
|
+
if (asyncContext) {
|
|
78
|
+
asyncContext.attachTo(event);
|
|
79
|
+
}
|
|
80
|
+
return this._publisher.publish(event, dispatcherOrAsyncContext, asyncContext);
|
|
60
81
|
}
|
|
61
82
|
/**
|
|
62
83
|
* Publishes multiple events.
|
|
63
84
|
* @param events The events to publish.
|
|
85
|
+
* @param dispatcherOrAsyncContext Dispatcher context or async context
|
|
86
|
+
* @param asyncContext Async context
|
|
64
87
|
*/
|
|
65
|
-
publishAll(events,
|
|
88
|
+
publishAll(events, dispatcherOrAsyncContext, asyncContext) {
|
|
89
|
+
if (!asyncContext && dispatcherOrAsyncContext instanceof scopes_1.AsyncContext) {
|
|
90
|
+
asyncContext = dispatcherOrAsyncContext;
|
|
91
|
+
dispatcherOrAsyncContext = undefined;
|
|
92
|
+
}
|
|
93
|
+
if (asyncContext) {
|
|
94
|
+
events.forEach((event) => {
|
|
95
|
+
if (scopes_1.AsyncContext.isAttached(event)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
asyncContext.attachTo(event);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
66
101
|
if (this._publisher.publishAll) {
|
|
67
|
-
return this._publisher.publishAll(events,
|
|
102
|
+
return this._publisher.publishAll(events, dispatcherOrAsyncContext, asyncContext);
|
|
68
103
|
}
|
|
69
|
-
return (events || []).map((event) => this._publisher.publish(event,
|
|
104
|
+
return (events || []).map((event) => this._publisher.publish(event, dispatcherOrAsyncContext, asyncContext));
|
|
70
105
|
}
|
|
71
106
|
bind(handler, id) {
|
|
72
107
|
const stream$ = id ? this.ofEventId(id) : this.subject$;
|
|
108
|
+
const deferred = handler.isDependencyTreeStatic()
|
|
109
|
+
? (event) => () => {
|
|
110
|
+
return Promise.resolve(handler.instance.handle(event));
|
|
111
|
+
}
|
|
112
|
+
: (event) => async () => {
|
|
113
|
+
const asyncContext = scopes_1.AsyncContext.of(event) ?? new scopes_1.AsyncContext();
|
|
114
|
+
const instance = await this.moduleRef.resolve(handler.metatype, asyncContext.id, {
|
|
115
|
+
strict: false,
|
|
116
|
+
});
|
|
117
|
+
return instance.handle(event);
|
|
118
|
+
};
|
|
73
119
|
const subscription = stream$
|
|
74
|
-
.pipe((0, operators_1.mergeMap)((event) => (0, rxjs_1.defer)((
|
|
120
|
+
.pipe((0, operators_1.mergeMap)((event) => (0, rxjs_1.defer)(deferred(event)).pipe((0, operators_1.catchError)((error) => {
|
|
121
|
+
if (this.options?.rethrowUnhandled) {
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
75
124
|
const unhandledError = this.mapToUnhandledErrorInfo(event, error);
|
|
76
125
|
this.unhandledExceptionBus.publish(unhandledError);
|
|
77
126
|
this._logger.error(`"${handler.constructor.name}" has thrown an unhandled exception.`, error);
|
|
@@ -80,15 +129,24 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
80
129
|
.subscribe();
|
|
81
130
|
this.subscriptions.push(subscription);
|
|
82
131
|
}
|
|
83
|
-
registerSagas(
|
|
84
|
-
const sagas =
|
|
85
|
-
.map((
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
if (!
|
|
89
|
-
throw new exceptions_1.
|
|
132
|
+
registerSagas(wrappers = []) {
|
|
133
|
+
const sagas = wrappers
|
|
134
|
+
.map((wrapper) => {
|
|
135
|
+
const { metatype: target } = wrapper;
|
|
136
|
+
const metadata = Reflect.getMetadata(constants_2.SAGA_METADATA, target) ?? [];
|
|
137
|
+
if (!wrapper.isDependencyTreeStatic()) {
|
|
138
|
+
throw new exceptions_1.UnsupportedSagaScopeException();
|
|
90
139
|
}
|
|
91
|
-
|
|
140
|
+
const instance = wrapper.instance;
|
|
141
|
+
return metadata.map((key) => {
|
|
142
|
+
const sagaFn = instance[key].bind(instance);
|
|
143
|
+
Object.defineProperty(sagaFn, 'name', {
|
|
144
|
+
value: key,
|
|
145
|
+
writable: false,
|
|
146
|
+
configurable: false,
|
|
147
|
+
});
|
|
148
|
+
return sagaFn;
|
|
149
|
+
});
|
|
92
150
|
})
|
|
93
151
|
.reduce((a, b) => a.concat(b), []);
|
|
94
152
|
sagas.forEach((saga) => this.registerSaga(saga));
|
|
@@ -97,15 +155,21 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
97
155
|
handlers.forEach((handler) => this.registerHandler(handler));
|
|
98
156
|
}
|
|
99
157
|
registerHandler(handler) {
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
158
|
+
const typeRef = handler.metatype;
|
|
159
|
+
const events = this.reflectEvents(typeRef);
|
|
160
|
+
events.forEach((event) => {
|
|
161
|
+
const eventId = this.eventIdProvider.getEventId(event);
|
|
162
|
+
this.bind(handler, eventId);
|
|
163
|
+
});
|
|
106
164
|
}
|
|
107
165
|
ofEventId(id) {
|
|
108
|
-
return this.subject$.pipe((0, operators_1.filter)((event) =>
|
|
166
|
+
return this.subject$.pipe((0, operators_1.filter)((event) => {
|
|
167
|
+
const { constructor } = Object.getPrototypeOf(event);
|
|
168
|
+
if (!constructor) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
return this.eventIdProvider.getEventId(constructor) === id;
|
|
172
|
+
}));
|
|
109
173
|
}
|
|
110
174
|
registerSaga(saga) {
|
|
111
175
|
if (typeof saga !== 'function') {
|
|
@@ -116,7 +180,18 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
116
180
|
throw new exceptions_1.InvalidSagaException();
|
|
117
181
|
}
|
|
118
182
|
const subscription = stream$
|
|
119
|
-
.pipe((0, operators_1.filter)((e) => !!e), (0, operators_1.
|
|
183
|
+
.pipe((0, operators_1.filter)((e) => !!e), (0, operators_1.catchError)((error) => {
|
|
184
|
+
if (this.options?.rethrowUnhandled) {
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
const unhandledError = this.mapToUnhandledErrorInfo(saga.name, error);
|
|
188
|
+
this.unhandledExceptionBus.publish(unhandledError);
|
|
189
|
+
this._logger.error(`Saga "${saga.name}" has thrown an unhandled exception.`, error);
|
|
190
|
+
return (0, rxjs_1.of)();
|
|
191
|
+
}), (0, operators_1.mergeMap)((command) => (0, rxjs_1.defer)(() => this.commandBus.execute(command)).pipe((0, operators_1.catchError)((error) => {
|
|
192
|
+
if (this.options?.rethrowUnhandled) {
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
120
195
|
const unhandledError = this.mapToUnhandledErrorInfo(command, error);
|
|
121
196
|
this.unhandledExceptionBus.publish(unhandledError);
|
|
122
197
|
this._logger.error(`Command handler which execution was triggered by Saga has thrown an unhandled exception.`, error);
|
|
@@ -126,7 +201,7 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
126
201
|
this.subscriptions.push(subscription);
|
|
127
202
|
}
|
|
128
203
|
reflectEvents(handler) {
|
|
129
|
-
return Reflect.getMetadata(
|
|
204
|
+
return Reflect.getMetadata(constants_2.EVENTS_HANDLER_METADATA, handler);
|
|
130
205
|
}
|
|
131
206
|
useDefaultPublisher() {
|
|
132
207
|
this._publisher = new default_pubsub_1.DefaultPubSub(this.subject$);
|
|
@@ -138,10 +213,12 @@ let EventBus = EventBus_1 = class EventBus extends utils_1.ObservableBus {
|
|
|
138
213
|
};
|
|
139
214
|
}
|
|
140
215
|
};
|
|
141
|
-
EventBus =
|
|
216
|
+
exports.EventBus = EventBus;
|
|
217
|
+
exports.EventBus = EventBus = EventBus_1 = __decorate([
|
|
142
218
|
(0, common_1.Injectable)(),
|
|
219
|
+
__param(3, (0, common_1.Optional)()),
|
|
220
|
+
__param(3, (0, common_1.Inject)(constants_1.CQRS_MODULE_OPTIONS)),
|
|
143
221
|
__metadata("design:paramtypes", [command_bus_1.CommandBus,
|
|
144
222
|
core_1.ModuleRef,
|
|
145
|
-
unhandled_exception_bus_1.UnhandledExceptionBus])
|
|
223
|
+
unhandled_exception_bus_1.UnhandledExceptionBus, Object])
|
|
146
224
|
], EventBus);
|
|
147
|
-
exports.EventBus = EventBus;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AggregateRoot } from './aggregate-root';
|
|
2
2
|
import { EventBus } from './event-bus';
|
|
3
3
|
import { IEvent } from './interfaces';
|
|
4
|
+
import { AsyncContext } from './scopes';
|
|
4
5
|
export interface Constructor<T> {
|
|
5
6
|
new (...args: any[]): T;
|
|
6
7
|
}
|
|
@@ -11,12 +12,14 @@ export declare class EventPublisher<EventBase extends IEvent = IEvent> {
|
|
|
11
12
|
* Merge the event publisher into the provided class.
|
|
12
13
|
* This is required to make `publish` and `publishAll` available on the `AgreggateRoot` class.
|
|
13
14
|
* @param metatype The class to merge into.
|
|
15
|
+
* @param asyncContext The async context (if scoped).
|
|
14
16
|
*/
|
|
15
|
-
mergeClassContext<T extends Constructor<AggregateRoot<EventBase>>>(metatype: T): T;
|
|
17
|
+
mergeClassContext<T extends Constructor<AggregateRoot<EventBase>>>(metatype: T, asyncContext?: AsyncContext): T;
|
|
16
18
|
/**
|
|
17
19
|
* Merge the event publisher into the provided object.
|
|
18
20
|
* This is required to make `publish` and `publishAll` available on the `AgreggateRoot` class instance.
|
|
19
21
|
* @param object The object to merge into.
|
|
22
|
+
* @param asyncContext The async context (if scoped).
|
|
20
23
|
*/
|
|
21
|
-
mergeObjectContext<T extends AggregateRoot<EventBase>>(object: T): T;
|
|
24
|
+
mergeObjectContext<T extends AggregateRoot<EventBase>>(object: T, asyncContext?: AsyncContext): T;
|
|
22
25
|
}
|
package/dist/event-publisher.js
CHANGED
|
@@ -20,15 +20,16 @@ let EventPublisher = class EventPublisher {
|
|
|
20
20
|
* Merge the event publisher into the provided class.
|
|
21
21
|
* This is required to make `publish` and `publishAll` available on the `AgreggateRoot` class.
|
|
22
22
|
* @param metatype The class to merge into.
|
|
23
|
+
* @param asyncContext The async context (if scoped).
|
|
23
24
|
*/
|
|
24
|
-
mergeClassContext(metatype) {
|
|
25
|
+
mergeClassContext(metatype, asyncContext) {
|
|
25
26
|
const eventBus = this.eventBus;
|
|
26
27
|
return class extends metatype {
|
|
27
28
|
publish(event) {
|
|
28
|
-
eventBus.publish(event, this);
|
|
29
|
+
eventBus.publish(event, this, asyncContext);
|
|
29
30
|
}
|
|
30
31
|
publishAll(events) {
|
|
31
|
-
eventBus.publishAll(events, this);
|
|
32
|
+
eventBus.publishAll(events, this, asyncContext);
|
|
32
33
|
}
|
|
33
34
|
};
|
|
34
35
|
}
|
|
@@ -36,20 +37,21 @@ let EventPublisher = class EventPublisher {
|
|
|
36
37
|
* Merge the event publisher into the provided object.
|
|
37
38
|
* This is required to make `publish` and `publishAll` available on the `AgreggateRoot` class instance.
|
|
38
39
|
* @param object The object to merge into.
|
|
40
|
+
* @param asyncContext The async context (if scoped).
|
|
39
41
|
*/
|
|
40
|
-
mergeObjectContext(object) {
|
|
42
|
+
mergeObjectContext(object, asyncContext) {
|
|
41
43
|
const eventBus = this.eventBus;
|
|
42
44
|
object.publish = (event) => {
|
|
43
|
-
eventBus.publish(event, object);
|
|
45
|
+
eventBus.publish(event, object, asyncContext);
|
|
44
46
|
};
|
|
45
47
|
object.publishAll = (events) => {
|
|
46
|
-
eventBus.publishAll(events, object);
|
|
48
|
+
eventBus.publishAll(events, object, asyncContext);
|
|
47
49
|
};
|
|
48
50
|
return object;
|
|
49
51
|
}
|
|
50
52
|
};
|
|
51
|
-
EventPublisher =
|
|
53
|
+
exports.EventPublisher = EventPublisher;
|
|
54
|
+
exports.EventPublisher = EventPublisher = __decorate([
|
|
52
55
|
(0, common_1.Injectable)(),
|
|
53
56
|
__metadata("design:paramtypes", [event_bus_1.EventBus])
|
|
54
57
|
], EventPublisher);
|
|
55
|
-
exports.EventPublisher = EventPublisher;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CommandHandlerNotFoundException = void 0;
|
|
4
4
|
class CommandHandlerNotFoundException extends Error {
|
|
5
5
|
constructor(commandName) {
|
|
6
|
-
super(`
|
|
6
|
+
super(`No handler found for the command: "${commandName}".`);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
exports.CommandHandlerNotFoundException = CommandHandlerNotFoundException;
|
package/dist/exceptions/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -16,3 +20,4 @@ __exportStar(require("./invalid-events-handler.exception"), exports);
|
|
|
16
20
|
__exportStar(require("./invalid-query-handler.exception"), exports);
|
|
17
21
|
__exportStar(require("./invalid-saga.exception"), exports);
|
|
18
22
|
__exportStar(require("./query-not-found.exception"), exports);
|
|
23
|
+
__exportStar(require("./unsupported-saga-scope.exception"), exports);
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.InvalidCommandHandlerException = void 0;
|
|
4
4
|
class InvalidCommandHandlerException extends Error {
|
|
5
5
|
constructor() {
|
|
6
|
-
super(`
|
|
6
|
+
super(`An invalid command handler has been provided. Please ensure that the provided handler is a class annotated with @CommandHandler and contains an 'execute' method.`);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
exports.InvalidCommandHandlerException = InvalidCommandHandlerException;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.InvalidEventsHandlerException = void 0;
|
|
4
4
|
class InvalidEventsHandlerException extends Error {
|
|
5
5
|
constructor() {
|
|
6
|
-
super(`
|
|
6
|
+
super(`An invalid events handler has been provided. Please ensure that the provided handler is a class annotated with @EventsHandler and contains a 'handle' method.`);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
exports.InvalidEventsHandlerException = InvalidEventsHandlerException;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.InvalidQueryHandlerException = void 0;
|
|
4
4
|
class InvalidQueryHandlerException extends Error {
|
|
5
5
|
constructor() {
|
|
6
|
-
super(`
|
|
6
|
+
super(`An invalid query handler has been provided. Please ensure that the provided handler is a class annotated with @QueryHandler and contains an 'execute' method.`);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
exports.InvalidQueryHandlerException = InvalidQueryHandlerException;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.InvalidSagaException = void 0;
|
|
4
4
|
class InvalidSagaException extends Error {
|
|
5
5
|
constructor() {
|
|
6
|
-
super(`Invalid saga
|
|
6
|
+
super(`Invalid saga. Each saga should return Observable stream.`);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
exports.InvalidSagaException = InvalidSagaException;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.QueryHandlerNotFoundException = void 0;
|
|
4
4
|
class QueryHandlerNotFoundException extends Error {
|
|
5
5
|
constructor(queryName) {
|
|
6
|
-
super(`
|
|
6
|
+
super(`No handler found for the query: "${queryName}"`);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
exports.QueryHandlerNotFoundException = QueryHandlerNotFoundException;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnsupportedSagaScopeException = void 0;
|
|
4
|
+
class UnsupportedSagaScopeException extends Error {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(`Request-scoped saga hosts are not supported. Instead, you should retrieve async-context-specific instances within the saga itself, using the "ModuleRef" provider.`);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.UnsupportedSagaScopeException = UnsupportedSagaScopeException;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Type } from '@nestjs/common';
|
|
2
|
+
import { EventIdProvider, IEvent } from '../interfaces';
|
|
3
|
+
declare class DefaultEventIdProvider<EventBase extends IEvent = IEvent> implements EventIdProvider<EventBase> {
|
|
4
|
+
getEventId(event: Type<EventBase>): string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare const defaultEventIdProvider: DefaultEventIdProvider<IEvent>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultEventIdProvider = void 0;
|
|
4
|
+
const constants_1 = require("../decorators/constants");
|
|
5
|
+
class DefaultEventIdProvider {
|
|
6
|
+
getEventId(event) {
|
|
7
|
+
return Reflect.getMetadata(constants_1.EVENT_METADATA, event)?.id ?? null;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.defaultEventIdProvider = new DefaultEventIdProvider();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './aggregate-root';
|
|
2
|
+
export * from './classes';
|
|
2
3
|
export * from './command-bus';
|
|
3
4
|
export * from './cqrs.module';
|
|
4
5
|
export * from './decorators';
|
|
@@ -8,5 +9,6 @@ export * from './exceptions';
|
|
|
8
9
|
export * from './interfaces';
|
|
9
10
|
export * from './operators';
|
|
10
11
|
export * from './query-bus';
|
|
12
|
+
export * from './scopes';
|
|
11
13
|
export * from './unhandled-exception-bus';
|
|
12
14
|
export * from './utils';
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
9
|
if (k2 === undefined) k2 = k;
|
|
10
|
-
Object.
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
11
15
|
}) : (function(o, m, k, k2) {
|
|
12
16
|
if (k2 === undefined) k2 = k;
|
|
13
17
|
o[k2] = m[k];
|
|
@@ -17,6 +21,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
17
21
|
};
|
|
18
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
23
|
__exportStar(require("./aggregate-root"), exports);
|
|
24
|
+
__exportStar(require("./classes"), exports);
|
|
20
25
|
__exportStar(require("./command-bus"), exports);
|
|
21
26
|
__exportStar(require("./cqrs.module"), exports);
|
|
22
27
|
__exportStar(require("./decorators"), exports);
|
|
@@ -26,5 +31,6 @@ __exportStar(require("./exceptions"), exports);
|
|
|
26
31
|
__exportStar(require("./interfaces"), exports);
|
|
27
32
|
__exportStar(require("./operators"), exports);
|
|
28
33
|
__exportStar(require("./query-bus"), exports);
|
|
34
|
+
__exportStar(require("./scopes"), exports);
|
|
29
35
|
__exportStar(require("./unhandled-exception-bus"), exports);
|
|
30
36
|
__exportStar(require("./utils"), exports);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Command } from '../../classes';
|
|
2
|
+
import { AsyncContext } from '../../scopes/async.context';
|
|
1
3
|
import { ICommand } from './command.interface';
|
|
2
4
|
/**
|
|
3
5
|
* Represents a command bus.
|
|
@@ -6,6 +8,21 @@ export interface ICommandBus<CommandBase extends ICommand = ICommand> {
|
|
|
6
8
|
/**
|
|
7
9
|
* Executes a command.
|
|
8
10
|
* @param command The command to execute.
|
|
11
|
+
* @returns A promise that, when resolved, will contain the result returned by the command's handler.
|
|
9
12
|
*/
|
|
10
|
-
execute<
|
|
13
|
+
execute<R = void>(command: Command<R>): Promise<R>;
|
|
14
|
+
/**
|
|
15
|
+
* Executes a command.
|
|
16
|
+
* @param command The command to execute.
|
|
17
|
+
* @param context The context to use. Optional.
|
|
18
|
+
* @returns A promise that, when resolved, will contain the result returned by the command's handler.
|
|
19
|
+
*/
|
|
20
|
+
execute<R = void>(command: Command<R>, context?: AsyncContext): Promise<R>;
|
|
21
|
+
/**
|
|
22
|
+
* Executes a command.
|
|
23
|
+
* @param command The command to execute.
|
|
24
|
+
* @param context The context to use. Optional.
|
|
25
|
+
* @returns A promise that, when resolved, will contain the result returned by the command's handler.
|
|
26
|
+
*/
|
|
27
|
+
execute<T extends CommandBase, R = any>(command: T, context?: AsyncContext): Promise<R>;
|
|
11
28
|
}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
import { Command } from '../../classes';
|
|
1
2
|
import { ICommand } from './command.interface';
|
|
2
3
|
/**
|
|
3
4
|
* Represents a command handler.
|
|
4
5
|
* Command handlers are used to execute commands.
|
|
5
6
|
*/
|
|
6
|
-
export
|
|
7
|
+
export type ICommandHandler<TCommand extends ICommand = any, TResult = any> = TCommand extends Command<infer InferredCommandResult> ? {
|
|
8
|
+
/**
|
|
9
|
+
* Executes a command.
|
|
10
|
+
* @param command The command to execute.
|
|
11
|
+
*/
|
|
12
|
+
execute(command: TCommand): Promise<InferredCommandResult>;
|
|
13
|
+
} : {
|
|
7
14
|
/**
|
|
8
15
|
* Executes a command.
|
|
9
16
|
* @param command The command to execute.
|
|
10
17
|
*/
|
|
11
18
|
execute(command: TCommand): Promise<TResult>;
|
|
12
|
-
}
|
|
19
|
+
};
|
|
@@ -1,10 +1,40 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { ICommandPublisher } from './commands/command-publisher.interface';
|
|
2
|
+
import { EventIdProvider } from './events/event-id-provider.interface';
|
|
3
|
+
import { IEventPublisher } from './events/event-publisher.interface';
|
|
4
|
+
import { IUnhandledExceptionPublisher } from './exceptions/unhandled-exception-publisher.interface';
|
|
5
|
+
import { IQueryPublisher } from './queries/query-publisher.interface';
|
|
6
|
+
/**
|
|
7
|
+
* Options for the CqrsModule.
|
|
8
|
+
*/
|
|
5
9
|
export interface CqrsModuleOptions {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Command publisher to use for publishing commands.
|
|
12
|
+
* @default DefaultCommandPubSub
|
|
13
|
+
*/
|
|
14
|
+
commandPublisher?: ICommandPublisher;
|
|
15
|
+
/**
|
|
16
|
+
* Event publisher to use for publishing events.
|
|
17
|
+
* @default DefaultPubSub
|
|
18
|
+
*/
|
|
19
|
+
eventPublisher?: IEventPublisher;
|
|
20
|
+
/**
|
|
21
|
+
* Query publisher to use for publishing queries.
|
|
22
|
+
* @default DefaultQueryPubSub
|
|
23
|
+
*/
|
|
24
|
+
queryPublisher?: IQueryPublisher;
|
|
25
|
+
/**
|
|
26
|
+
* Unhandled exception publisher to use for publishing unhandled exceptions.
|
|
27
|
+
* @default DefaultUnhandledExceptionPubSub
|
|
28
|
+
*/
|
|
29
|
+
unhandledExceptionPublisher?: IUnhandledExceptionPublisher;
|
|
30
|
+
/**
|
|
31
|
+
* Event ID provider to use for retrieving event IDs by event instances.
|
|
32
|
+
* @default DefaultEventIdProvider
|
|
33
|
+
*/
|
|
34
|
+
eventIdProvider?: EventIdProvider;
|
|
35
|
+
/**
|
|
36
|
+
* Whether to rethrow unhandled exceptions.
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
rethrowUnhandled?: boolean;
|
|
10
40
|
}
|