@event-nest/core 3.3.2 → 3.4.1

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 (37) hide show
  1. package/README.md +81 -65
  2. package/package.json +3 -2
  3. package/src/index.d.ts +1 -0
  4. package/src/index.js +1 -0
  5. package/src/index.js.map +1 -1
  6. package/src/lib/aggregate-root/aggregate-root.d.ts +2 -0
  7. package/src/lib/aggregate-root/aggregate-root.js +13 -2
  8. package/src/lib/aggregate-root/aggregate-root.js.map +1 -1
  9. package/src/lib/domain-event-emitter.d.ts +7 -3
  10. package/src/lib/domain-event-emitter.js +108 -35
  11. package/src/lib/domain-event-emitter.js.map +1 -1
  12. package/src/lib/domain-event-subscription.d.ts +15 -1
  13. package/src/lib/domain-event-subscription.js +18 -6
  14. package/src/lib/domain-event-subscription.js.map +1 -1
  15. package/src/lib/exceptions/event-concurrency-exception.d.ts +8 -0
  16. package/src/lib/exceptions/event-concurrency-exception.js +8 -0
  17. package/src/lib/exceptions/event-concurrency-exception.js.map +1 -1
  18. package/src/lib/exceptions/event-name-conflict-exception.d.ts +3 -0
  19. package/src/lib/exceptions/event-name-conflict-exception.js +3 -0
  20. package/src/lib/exceptions/event-name-conflict-exception.js.map +1 -1
  21. package/src/lib/exceptions/id-generation-exception.d.ts +4 -0
  22. package/src/lib/exceptions/id-generation-exception.js +4 -0
  23. package/src/lib/exceptions/id-generation-exception.js.map +1 -1
  24. package/src/lib/exceptions/missing-aggregate-root-name-exception.d.ts +3 -0
  25. package/src/lib/exceptions/missing-aggregate-root-name-exception.js +3 -0
  26. package/src/lib/exceptions/missing-aggregate-root-name-exception.js.map +1 -1
  27. package/src/lib/exceptions/subscription-exception.d.ts +13 -0
  28. package/src/lib/exceptions/subscription-exception.js +26 -0
  29. package/src/lib/exceptions/subscription-exception.js.map +1 -0
  30. package/src/lib/exceptions/unknown-event-exception.d.ts +3 -0
  31. package/src/lib/exceptions/unknown-event-exception.js +3 -0
  32. package/src/lib/exceptions/unknown-event-exception.js.map +1 -1
  33. package/src/lib/exceptions/unregistered-event-exception.d.ts +3 -0
  34. package/src/lib/exceptions/unregistered-event-exception.js +3 -0
  35. package/src/lib/exceptions/unregistered-event-exception.js.map +1 -1
  36. package/src/lib/storage/abstract-event-store.js +1 -1
  37. package/src/lib/storage/abstract-event-store.js.map +1 -1
package/README.md CHANGED
@@ -1,23 +1,20 @@
1
1
  # Event Nest
2
- A collection of [nest.js](https://nestjs.com/) libraries to help you build applications based on event sourcing architecture.
2
+ A collection of [NestJS](https://nestjs.com/) libraries to help you build applications based on event-sourcing architecture.
3
3
 
4
4
  ![build status](https://github.com/NickTsitlakidis/event-nest/actions/workflows/checks.yml/badge.svg)
5
5
  [![npm version](https://badge.fury.io/js/@event-nest%2Fcore.svg)](https://badge.fury.io/js/@event-nest%2Fcore)
6
6
  [![Coverage Status](https://coveralls.io/repos/github/NickTsitlakidis/event-nest/badge.svg?branch=master)](https://coveralls.io/github/NickTsitlakidis/event-nest?branch=master)
7
7
 
8
8
  ## Description
9
- Event Nest is a collection of libraries based on nest.js that assists in implementing the core concepts of event sourcing:
10
- * Saving events in a persistent storage
11
- * Utilizing the saved events to trigger side effects, such as updating your read model
12
- * Replaying events to reconstruct the state of your application
9
+ Event Nest simplifies the implementation of event-sourcing patterns in NestJS applications by providing tools to manage events, aggregates, and domain subscriptions. It helps developers focus on business logic by addressing common challenges in event sourcing, such as event persistence, replay, and projection updates.
13
10
 
14
- Given that event sourcing is commonly used in conjunction with [CQRS](https://martinfowler.com/bliki/CQRS.html) and [Domain Driven Design](https://en.wikipedia.org/wiki/Domain-driven_design), these libraries adopt principles from these architectural patterns.
11
+ Event sourcing is commonly used alongside [CQRS](https://martinfowler.com/bliki/CQRS.html) and [Domain Driven Design](https://en.wikipedia.org/wiki/Domain-driven_design). Event Nest incorporates principles from these architectural patterns to provide robust support for scalable application development.
15
12
 
16
- It would also probably help to make some distinctions about what Event Nest is not :
17
- * It is not a framework, it is a set of libraries which are designed to be used with nest.js.
18
- * It is not an ORM, if you want an ORM to define simple models, there are far better solutions out there.
19
- * It is not a library for establishing event-based communication between services.
20
- * **Although the code is covered by tests, the library is not widely tested in production. Use it at your own risk.**
13
+ What Event Nest is Not:
14
+ * **Not a framework**: It is a set of libraries which are designed to be used with NestJS.
15
+ * **Not an ORM**: If your primary goal is managing simple database models, more appropriate solutions exist.
16
+ * **Not for event-based communication**: It is not a library for establishing event-based communication between services.
17
+ * **Not widely tested in production**: While the code is covered by tests, extensive production testing has not yet been conducted. Use it at your own risk.
21
18
 
22
19
  ## Table of contents
23
20
  - [Why?](#why)
@@ -29,30 +26,34 @@ It would also probably help to make some distinctions about what Event Nest is n
29
26
  - [Event](#event)
30
27
  - [Aggregate Root](#aggregate-root)
31
28
  - [Domain Event Subscription](#domain-event-subscription)
29
+ - [Order of execution in subscriptions](#order-of-execution-in-subscriptions)
30
+ - [Waiting for subscriptions to complete](#waiting-for-subscriptions-to-complete)
32
31
 
33
32
 
34
33
  ## Why?
35
- Implementing event sourcing in an application can be challenging, particularly when combined with CQRS and DDD.
34
+ Implementing event sourcing in an application can be challenging, particularly when combined with CQRS and Domain-Driven Design.
36
35
 
37
- Nest.js provides a [fantastic module](https://github.com/nestjs/cqrs) for CQRS but after using it for a while I thought that maybe some things could be improved.
38
- Furthermore, these improvements can't be added to the official module due to its lightweight and abstract nature.
39
- For instance, the official module lacks a specific way of persisting the events to a storage.
36
+ While NestJS provides a [fantastic module](https://github.com/nestjs/cqrs) for CQRS, its lightweight and abstract design leaves gaps in areas such as event persistence.
40
37
 
41
- This is where Event Nest comes into play. In fact, a significant portion of the code in Event Nest is influenced by how things are implemented in the official module.
38
+ Event Nest bridges these gaps by providing:
39
+ * A structured way to persist events.
40
+ * Seamless integration with NestJS.
41
+ * Tools to manage aggregates and replay events.
42
+
43
+ The library emerged from using the official CQRS module in various projects, where practical enhancements and improvements were made to address real-world challenges.
44
+ A significant portion of the code in Event Nest is inspired by the patterns implemented in the official NestJS module.
42
45
 
43
- This project evolved into a library after I used the official module with my improvements in a few projects and I thought that it could be useful to other people. To make things
44
- simpler, the library is not depending on the official module, so you can use it without having to worry about conflicts.
45
46
 
46
47
  ## Getting Started
47
48
  Depending on the storage solution you intend to use, you will need to install the corresponding packages.
48
- At the moment, the supported storage solutions are MongoDB and PostgreSQL.
49
+ Currently supported options are MongoDB and PostgreSQL.
49
50
 
50
51
  ### MongoDB setup
51
52
 
52
53
  ```bash
53
54
  npm install --save @event-nest/core @event-nest/mongodb
54
55
  ```
55
- After installation, import the `EventNestMongoDbModule` to your nest.js application :
56
+ After installation, import the `EventNestMongoDbModule` to your NestJS application :
56
57
  ```typescript
57
58
  import { EventNestMongoDbModule } from "@event-nest/mongodb";
58
59
  import { Module } from "@nestjs/common";
@@ -68,7 +69,7 @@ import { Module } from "@nestjs/common";
68
69
  })
69
70
  export class AppModule {}
70
71
  ```
71
- The collection settings define which MongoDB collections will be used to store the aggregates and the events.
72
+ The collections specified in the configuration will store the aggregates and events.
72
73
 
73
74
 
74
75
  ### PostgreSQL setup
@@ -77,7 +78,7 @@ The collection settings define which MongoDB collections will be used to store t
77
78
  npm install --save @event-nest/core @event-nest/postgresql
78
79
  ```
79
80
 
80
- After installation, import the `EventNestPostgreSQLModule` to your nest.js application :
81
+ After installation, import the `EventNestPostgreSQLModule` to your NestJS application :
81
82
  ```typescript
82
83
  import { EventNestPostgreSQLModule } from "@event-nest/postgresql";
83
84
  import { Module } from "@nestjs/common";
@@ -96,9 +97,7 @@ import { Module } from "@nestjs/common";
96
97
  export class AppModule {}
97
98
  ```
98
99
 
99
- If the database user has privileges to create tables, you can set the `ensureTablesExist` option to `true`. This will create the necessary tables in your database during application bootstrap.
100
- By default, this option is disabled to avoid requiring a user with elevated privileges.
101
-
100
+ If the database user has privileges to create tables, set the `ensureTablesExist` option to true to automatically create the necessary tables during bootstrap. Otherwise, refer to the manual table creation instructions below.
102
101
 
103
102
 
104
103
  #### Manual creation of PostgreSQL tables
@@ -129,9 +128,9 @@ If you prefer to create the tables manually, the following guidelines describe t
129
128
  An event is a representation of something that has happened in the past. It is identified by a unique name, and it may contain additional data that will be persisted with the event.
130
129
 
131
130
  Each event serves three purposes :
132
- * It will be persisted so that it can be used to reconstruct the state of an aggregate root
133
- * It will be passed to any internal subscribers that need to react to this event (e.g. updating the read model)
134
- * When it's time to recreate the aggregate root, the event will be applied by the correct method in the aggregate root
131
+ * It will be saved to the database because it represents a change in the state of the system
132
+ * It will be passed to any internal subscriptions that need to react to this event (e.g. updating the read model)
133
+ * When it's time to reconstruct the state of an aggregate root, the events will be replayed in the order they were created.
135
134
 
136
135
  There is no specific requirement for the structure of an event, but it is recommended to keep it simple and immutable. The [class-transformer](https://github.com/typestack/class-transformer) library is utilized under the hood to save and read the events from the database. Therefore, your event classes should adhere to the rules of class-transformer to be properly serialized and deserialized.
137
136
 
@@ -141,27 +140,26 @@ To register a class as an event, use the `@DomainEvent` decorator. The decorator
141
140
  ### Aggregate Root
142
141
  An [aggregate root](https://stackoverflow.com/questions/1958621/whats-an-aggregate-root) is a fundamental concept in Domain-Driven Design (DDD).
143
142
  It represents a cluster of domain objects that are treated as a single unit. The aggregate root is responsible for maintaining the consistency and enforcing business rules within the aggregate.
144
- While explaining the concept of an aggregate root in depth is beyond the scope of this documentation, it's important to understand how such an object interacts with the event sourcing system.
145
143
 
146
144
  In the context of event sourcing, the aggregate root plays a crucial role. Each aggregate root maintains its own set of events, forming an event stream.
147
145
  These events capture the changes or actions that have occurred within the aggregate. The event stream serves as the historical record of what has happened to the aggregate over time.
148
146
 
149
147
  Let's consider an example to illustrate the concept of an aggregate root. Suppose we have a user management system where we need to create new users and update existing users. In this case, the `User` entity serves as the aggregate root.
150
148
 
151
- The `User` class encapsulates the user-specific behavior and maintains the internal state of a user. It provides methods for creating a new user, updating user details, and performing any other operations relevant to the user domain. These methods are called from Nest.js services or other parts of the application responsible for user-related operations.
149
+ The `User` class encapsulates the user-specific behavior and maintains the internal state of a user. It provides methods for creating a new user, updating user details, and performing any other operations relevant to the user domain. These methods are called from NestJS services or other parts of the application responsible for user-related operations.
152
150
 
153
151
  Each instance of the `User` class has its own event stream, which records the events specific to that user. For example, when a new user is created, an event called `UserCreatedEvent` is appended to the event stream. Similarly, when a user's details are updated, an event called `UserUpdatedEvent` is appended.
154
152
 
155
153
  When loading a user from the event store, the event stream is replayed, and each event is processed by the corresponding method in the `User` class. This allows the user object to be reconstructed and updated to its most recent state based on the events.
156
154
 
157
- To ensure that all modifications to the user's state are properly recorded, any method that changes the state should also append the corresponding event to the event stream. By doing so, the event is persisted and can be used for reconstructing the state in the future.
158
- If an event is not appended, the changes will not be saved in the database, and the consistency of the user object will be compromised.
159
-
155
+ To ensure that all modifications to the user's state are properly recorded, any method that changes the state should also append the corresponding event to the event stream.
160
156
 
161
- Enough with the theory, let's see an example that includes all of the above.
162
157
 
163
158
  #### Example
164
159
 
160
+ We'll start with this example by defining two simple events for a user: a creation event and an update event. Each one has its own data, and they are identified by a unique name which is set with the `@DomainEvent` decorator.
161
+
162
+
165
163
  ```typescript
166
164
  import { DomainEvent } from "@event-nest/core";
167
165
 
@@ -180,7 +178,24 @@ export class UserUpdatedEvent {
180
178
  }
181
179
  ```
182
180
 
183
- We start this example by defining two simple events for a user: a creation event and an update event. Each one has its own data, and they are identified by a unique name which is set with the `@DomainEvent` decorator.
181
+ Next, we will define the aggregate root for the user. Let's break down what this class should do and how.
182
+
183
+ First of all, the class has to extend the `AggregateRoot` class, and it has to be decorated with the `@AggregateRootName` decorator.
184
+ The name is required to associate persisted events with the correct aggregate root when retrieving them from storage.
185
+
186
+ Now let's talk about constructors. TypeScript doesn't allow us to define multiple constructors. Therefore, if we have two ways of creating an object, we could use static methods as factories.
187
+ In our case, we have the following creation cases :
188
+ * The user is new, and we need to create it from scratch. In that case, we create a new `UserCreatedEvent` event, and we `append` it to the aggregate root's event stream.
189
+ * The user already exists. In that case we need to recreate the aggregate root from the events that have been persisted. We do that by calling the `reconstitute` method.
190
+
191
+ The `reconstitute` method will use the provided events to find and call the appropriate method that updates the state for each specific event.
192
+ These methods should be decorated with the `@ApplyEvent` decorator, which takes the event class as a parameter.
193
+
194
+
195
+ Finally, we will define an `update` method which is the place to run any business logic we need and append the corresponding event (`UserUpdatedEvent`) to the event stream.
196
+
197
+ It's important to note that the append method will not save the event. All the appended events can be saved by calling the `commit` method on the aggregate root.
198
+
184
199
 
185
200
  ```typescript
186
201
  import { AggregateRoot, AggregateRootName, ApplyEvent, StoredEvent } from "@event-nest/core";
@@ -228,25 +243,14 @@ export class User extends AggregateRoot {
228
243
  }
229
244
  ```
230
245
 
231
- Next, we define the aggregate root for the user. There's a lot going on here so let's break it down.
232
-
233
- First of all, the class has to extend the `AggregateRoot` class, and it has to be decorated with the `@AggregateRootName` decorator.
234
- The name is required to associate persisted events with the correct aggregate root when retrieving them from storage.
235
-
236
- Now let's talk about the constructor. TypeScript doesn't allow us to define multiple constructors. So if we have two ways of creating an object, we could use static methods as factories.
237
- In our case, we have the following creation cases :
238
- * The user is new, and we need to create it from scratch. In that case, we create a new `UserCreatedEvent` event, and we `append` it to the aggregate root's event stream.
239
- * The user already exists. In that case we need to recreate the aggregate root from the events that have been persisted. We do that by calling the `reconstitute` method.
240
-
241
- The `reconstitute` method will initiate the event processing based on the events order.
242
-
243
- To apply each event, we have defined two private methods which are decorated with the `@ApplyEvent` decorator. Each method will be called when the corresponding event is retrieved, and it's ready to be processed.
244
- This is the place to update the object's internal state based on the event's data.
246
+ The final piece of the puzzle is a NestJS service that will orchestrate the process.
245
247
 
248
+ We start by injecting the `EventStore`, which will be used to retrieve persisted events.
246
249
 
247
- Finally, we define an `update` method which is the place to run any business logic we need and append the corresponding event (`UserUpdatedEvent`) to the event stream.
250
+ The next step would be to make the aggregate root be aware of the event store. This is required because aggregate root classes are not managed by the NestJS dependency injection system.
251
+ The `EventStore` includes a method called `addPublisher` that takes an aggregate root and updates it by connecting it to the event store.
248
252
 
249
- It's important to note that the append method is not saving the event. All the appended events can be saved by calling the `commit` method on the aggregate root.
253
+ Finally, we will call the `commit` method on the aggregate root to save the appended events to the storage.
250
254
 
251
255
  ```typescript
252
256
  import { EVENT_STORE, EventStore } from "@event-nest/core";
@@ -256,7 +260,7 @@ export class UserService {
256
260
  constructor(@Inject(EVENT_STORE) private eventStore: EventStore) {}
257
261
 
258
262
  async createUser(name: string, email: string) {
259
- const user = User.createNew(new ObjectId().toHexString(), name, email);
263
+ const user = User.createNew('a-unique-id', name, email);
260
264
  const userWithPublisher = this.eventStore.addPublisher(user);
261
265
  await userWithPublisher.commit();
262
266
  return user.id;
@@ -272,15 +276,8 @@ export class UserService {
272
276
  }
273
277
  ```
274
278
 
275
- The final piece of the puzzle is a nest.js service that will manage the process.
276
-
277
- We start by injecting the `EventStore`, which will be used to retrieve persisted events.
278
-
279
- Additionally, since the aggregate root classes are not managed by the nest.js dependency injection system, we need to connect them to the event store by calling the `addPublisher` method. This will allow the
280
- `commit` method to work as expected.
281
-
282
279
  ### Domain Event Subscription
283
- When working with event sourcing, you will likely need a way of updating other parts of your system when an event is persisted. For example, you may have a read model for users that needs to be updated when a user is created or updated.
280
+ When working with event sourcing, you will often need to update other parts of your system after an event has been persisted. For example, you may have a read model for users that needs to be updated when a user is created or updated. Or, perhaps you need to send an email notification when a specific event occurs.
284
281
 
285
282
  To achieve this, you can implement a service decorated with the `@DomainEventSubscription` decorator. This decorator takes a list of events that the service is interested in, and it automatically subscribes to them when the service is initialized.
286
283
 
@@ -295,15 +292,16 @@ import { PublishedDomainEvent, DomainEventSubscription, OnDomainEvent } from "@e
295
292
  @DomainEventSubscription(UserCreatedEvent, UserUpdatedEvent)
296
293
  export class UserEventSubscription implements OnDomainEvent<UserCreatedEvent | UserUpdatedEvent> {
297
294
 
298
- onDomainEvent(event: PublishedDomainEvent<UserCreatedEvent | UserUpdatedEvent>): Promise<unknown> {
299
- //Here you can create/update your read model based on the event and your custom logic.
300
- return Promise.resolve(undefined);
301
- }
295
+ onDomainEvent(event: PublishedDomainEvent<UserCreatedEvent | UserUpdatedEvent>): Promise<unknown> {
296
+ //Here you can create/update your read model based on the event and your custom logic.
297
+ return Promise.resolve(undefined);
298
+ }
302
299
 
303
300
  }
304
301
  ```
302
+ #### Order of execution in subscriptions
305
303
 
306
- If there are multiple subscription services for the same event, they will be executed concurrently.
304
+ If there are multiple subscriptions for the same event, they will be executed concurrently.
307
305
  However, if there are multiple events that the service is subscribed to, they will be executed sequentially based on the order they were emitted.
308
306
 
309
307
  This is the default behaviour because there are cases where the logic may depend on the completion of the previous event. If you want better performance
@@ -323,6 +321,24 @@ and your logic doesn't depend on the order of the events, you can change this se
323
321
  export class AppModule {}
324
322
  ```
325
323
 
324
+ #### Waiting for subscriptions to complete
325
+
326
+ By default, the `commit` method on the aggregate root will return a promise that resolves when the events are saved to the storage. It will not wait for the subscriptions to complete.
327
+ This is the most common requirement in event-sourcing systems, as the subscriptions are usually used for updating the read model and are not critical for the operation of the system.
328
+
329
+ However, there are use cases that require the subscriptions to complete before the `commit` method returns a result.
330
+
331
+ The `DomainEventSubscription` decorator supports an alternative syntax for those cases :
332
+
333
+ ```typescript
334
+
335
+ @DomainEventSubscription({ eventClasses: [UserCreatedEvent, UserUpdatedEvent], isAsync: false })
336
+
337
+ ```
338
+ When your subscription is defined like this, the `commit` method will not return until the `onDomainEvent` method is completed for all the events that the service is subscribed to.
339
+
340
+ If your subscription throws an exception, the exception will be wrapped in a `SubscriptionException` which will be thrown by the `commit` method.
341
+ It's important to note that when the `commit` method throws such an exception, it doesn't mean that the events were not saved to the storage. Since the subscriptions run after the events are saved, an exception from a subscription doesn't roll back the events.
326
342
 
327
343
 
328
344
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event-nest/core",
3
- "version": "3.3.2",
3
+ "version": "3.4.1",
4
4
  "license": "MIT",
5
5
  "author": "Nick Tsitlakidis",
6
6
  "description": "Event sourcing module for NestJS. It provides a set of decorators and classes to build an application based on event sourcing.",
@@ -29,7 +29,8 @@
29
29
  "tslib": "^2.3.0"
30
30
  },
31
31
  "dependencies": {
32
- "class-transformer": "^0.5.1"
32
+ "class-transformer": "^0.5.1",
33
+ "radash": "^12.1.0"
33
34
  },
34
35
  "types": "./src/index.d.ts",
35
36
  "main": "./src/index.js"
package/src/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export * from "./lib/domain-event-subscription";
8
8
  export * from "./lib/exceptions/event-concurrency-exception";
9
9
  export * from "./lib/exceptions/event-name-conflict-exception";
10
10
  export * from "./lib/exceptions/missing-aggregate-root-name-exception";
11
+ export * from "./lib/exceptions/subscription-exception";
11
12
  export * from "./lib/exceptions/unknown-event-exception";
12
13
  export * from "./lib/on-domain-event";
13
14
  export * from "./lib/published-domain-event";
package/src/index.js CHANGED
@@ -11,6 +11,7 @@ tslib_1.__exportStar(require("./lib/domain-event-subscription"), exports);
11
11
  tslib_1.__exportStar(require("./lib/exceptions/event-concurrency-exception"), exports);
12
12
  tslib_1.__exportStar(require("./lib/exceptions/event-name-conflict-exception"), exports);
13
13
  tslib_1.__exportStar(require("./lib/exceptions/missing-aggregate-root-name-exception"), exports);
14
+ tslib_1.__exportStar(require("./lib/exceptions/subscription-exception"), exports);
14
15
  tslib_1.__exportStar(require("./lib/exceptions/unknown-event-exception"), exports);
15
16
  tslib_1.__exportStar(require("./lib/on-domain-event"), exports);
16
17
  tslib_1.__exportStar(require("./lib/published-domain-event"), exports);
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/core/src/index.ts"],"names":[],"mappings":";;;AAAA,8EAAoD;AACpD,mFAAyD;AACzD,qFAA2D;AAE3D,oEAA0C;AAC1C,6DAAmC;AACnC,qEAA2C;AAC3C,0EAAgD;AAEhD,uFAA6D;AAC7D,yFAA+D;AAC/D,iGAAuE;AAEvE,mFAAyD;AACzD,gEAAsC;AACtC,uEAA6C;AAE7C,6EAAmD;AACnD,oEAA0C;AAC1C,8EAAoD;AACpD,qEAA2C;AAE3C,iEAAuC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/core/src/index.ts"],"names":[],"mappings":";;;AAAA,8EAAoD;AACpD,mFAAyD;AACzD,qFAA2D;AAE3D,oEAA0C;AAC1C,6DAAmC;AACnC,qEAA2C;AAC3C,0EAAgD;AAEhD,uFAA6D;AAC7D,yFAA+D;AAC/D,iGAAuE;AACvE,kFAAwD;AAExD,mFAAyD;AACzD,gEAAsC;AACtC,uEAA6C;AAE7C,6EAAmD;AACnD,oEAA0C;AAC1C,8EAAoD;AACpD,qEAA2C;AAE3C,iEAAuC"}
@@ -22,6 +22,7 @@ export declare abstract class AggregateRoot {
22
22
  * Adds an event to the currently existing events of the entity. This will not publish the event. Use the {@link commit}
23
23
  * method once all the events you want are appended.
24
24
  * @param event The event to be appended
25
+ * @throws UnregisteredEventException if the event is not registered
25
26
  */
26
27
  append(event: object): void;
27
28
  /**
@@ -46,6 +47,7 @@ export declare abstract class AggregateRoot {
46
47
  * method will trigger all the matching {@link ApplyEvent} functions of the entity to populate the object based on
47
48
  * application logic.
48
49
  * @param events The events that will be sent to {@link ApplyEvent} functions
50
+ * @throws UnknownEventException if an event is not known
49
51
  */
50
52
  reconstitute(events: Array<StoredEvent>): void;
51
53
  resolveVersion(events: Array<StoredEvent>): void;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AggregateRoot = void 0;
4
4
  const common_1 = require("@nestjs/common");
5
5
  const domain_event_registrations_1 = require("../domain-event-registrations");
6
+ const subscription_exception_1 = require("../exceptions/subscription-exception");
6
7
  const unknown_event_exception_1 = require("../exceptions/unknown-event-exception");
7
8
  const unregistered_event_exception_1 = require("../exceptions/unregistered-event-exception");
8
9
  const type_utils_1 = require("../utils/type-utils");
@@ -37,6 +38,7 @@ class AggregateRoot {
37
38
  * Adds an event to the currently existing events of the entity. This will not publish the event. Use the {@link commit}
38
39
  * method once all the events you want are appended.
39
40
  * @param event The event to be appended
41
+ * @throws UnregisteredEventException if the event is not registered
40
42
  */
41
43
  append(event) {
42
44
  if (!(0, domain_event_registrations_1.isRegistered)(event)) {
@@ -58,12 +60,20 @@ class AggregateRoot {
58
60
  */
59
61
  async commit() {
60
62
  const toPublish = [...this._appendedEvents];
61
- if (toPublish.length > 0) {
63
+ if (toPublish.length === 0) {
64
+ return this;
65
+ }
66
+ try {
62
67
  await this.publish(toPublish);
63
68
  this._appendedEvents = [];
64
69
  return this;
65
70
  }
66
- return this;
71
+ catch (error) {
72
+ if (error instanceof subscription_exception_1.SubscriptionException) {
73
+ this._appendedEvents = [];
74
+ }
75
+ throw error;
76
+ }
67
77
  }
68
78
  /**
69
79
  * Publishes all the provided events using a connected event publisher. To connect a publisher, use the
@@ -82,6 +92,7 @@ class AggregateRoot {
82
92
  * method will trigger all the matching {@link ApplyEvent} functions of the entity to populate the object based on
83
93
  * application logic.
84
94
  * @param events The events that will be sent to {@link ApplyEvent} functions
95
+ * @throws UnknownEventException if an event is not known
85
96
  */
86
97
  reconstitute(events) {
87
98
  const startedAt = Date.now();
@@ -1 +1 @@
1
- {"version":3,"file":"aggregate-root.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/aggregate-root/aggregate-root.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"aggregate-root.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/aggregate-root/aggregate-root.ts"],"names":[],"mappings":"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"}
@@ -3,12 +3,16 @@ import { Module } from "@nestjs/core/injector/module";
3
3
  import { PublishedDomainEvent } from "./published-domain-event";
4
4
  export declare class DomainEventEmitter implements OnModuleDestroy {
5
5
  private readonly _concurrentSubscriptions;
6
- private readonly _handlers;
6
+ private readonly _asyncHandlers;
7
7
  private readonly _logger;
8
+ private readonly _syncHandlers;
8
9
  constructor(_concurrentSubscriptions?: boolean);
9
10
  get concurrentSubscriptions(): boolean;
10
11
  bindSubscriptions(injectorModules: Map<string, Module>): void;
11
- emit(withAggregate: PublishedDomainEvent<object>): Promise<unknown>;
12
- emitMultiple(withAggregate: PublishedDomainEvent<object>[]): Promise<unknown>;
12
+ emitMultiple(publishedEvents: PublishedDomainEvent<object>[]): Promise<unknown>;
13
13
  onModuleDestroy(): void;
14
+ private catchError;
15
+ private emitConcurrently;
16
+ private emitSequentially;
17
+ private splitEventsBySubscriptionType;
14
18
  }
@@ -4,11 +4,13 @@ exports.DomainEventEmitter = void 0;
4
4
  const common_1 = require("@nestjs/common");
5
5
  const rxjs_1 = require("rxjs");
6
6
  const domain_event_subscription_1 = require("./domain-event-subscription");
7
+ const subscription_exception_1 = require("./exceptions/subscription-exception");
7
8
  const type_utils_1 = require("./utils/type-utils");
8
9
  class DomainEventEmitter {
9
10
  constructor(_concurrentSubscriptions = false) {
10
11
  this._concurrentSubscriptions = _concurrentSubscriptions;
11
- this._handlers = new Map();
12
+ this._asyncHandlers = new Map();
13
+ this._syncHandlers = new Map();
12
14
  this._logger = new common_1.Logger(DomainEventEmitter.name);
13
15
  }
14
16
  get concurrentSubscriptions() {
@@ -22,52 +24,123 @@ class DomainEventEmitter {
22
24
  }
23
25
  if ((0, domain_event_subscription_1.isDomainEventSubscription)(provider.instance)) {
24
26
  const events = (0, domain_event_subscription_1.getEventsFromDomainEventSubscription)(provider.instance);
25
- events.forEach((event) => {
26
- const eventId = (0, domain_event_subscription_1.getEventId)(event);
27
- if (!this._handlers.has(eventId)) {
28
- this._handlers.set(eventId, []);
29
- }
30
- this._logger.debug(`Binding ${provider.instance?.constructor.name} to event ${eventId}`);
31
- this._handlers.get(eventId)?.push(provider.instance);
32
- });
27
+ const isAsync = (0, domain_event_subscription_1.getSubscriptionAsyncType)(provider.instance);
28
+ if (isAsync) {
29
+ events.forEach((event) => {
30
+ const eventId = (0, domain_event_subscription_1.getEventId)(event);
31
+ if (!this._asyncHandlers.has(eventId)) {
32
+ this._asyncHandlers.set(eventId, []);
33
+ }
34
+ this._logger.debug(`Binding ${provider.instance?.constructor.name} to event ${eventId}`);
35
+ this._asyncHandlers.get(eventId)?.push(provider.instance);
36
+ });
37
+ }
38
+ else {
39
+ events.forEach((event) => {
40
+ const eventId = (0, domain_event_subscription_1.getEventId)(event);
41
+ if (!this._syncHandlers.has(eventId)) {
42
+ this._syncHandlers.set(eventId, []);
43
+ }
44
+ this._logger.debug(`Binding ${provider.instance?.constructor.name} to event ${eventId}`);
45
+ this._syncHandlers.get(eventId)?.push(provider.instance);
46
+ });
47
+ }
33
48
  }
34
49
  });
35
50
  });
36
51
  }
37
- emit(withAggregate) {
38
- if (this._handlers.size === 0) {
39
- this._logger.warn(`Event ${withAggregate.payload.constructor.name} can't be passed to subscriptions. Make sure you use the @DomainEventSubscription decorator`);
52
+ emitMultiple(publishedEvents) {
53
+ if (this._asyncHandlers.size === 0 && this._syncHandlers.size === 0) {
54
+ this._logger.warn(`No event subscriptions have been discovered. Make sure you use the @DomainEventSubscription decorator`);
40
55
  return Promise.resolve();
41
56
  }
42
- const eventId = (0, domain_event_subscription_1.getEventId)(withAggregate.payload.constructor);
43
- if ((0, type_utils_1.isNil)(eventId) || !this._handlers.has(eventId)) {
44
- this._logger.warn(`Event ${withAggregate.payload.constructor.name} can't be passed to subscriptions. Make sure you use the @DomainEventSubscription decorator`);
45
- return Promise.resolve();
57
+ return this._concurrentSubscriptions
58
+ ? this.emitConcurrently(publishedEvents)
59
+ : this.emitSequentially(publishedEvents);
60
+ }
61
+ onModuleDestroy() {
62
+ this._asyncHandlers.clear();
63
+ this._syncHandlers.clear();
64
+ }
65
+ catchError(handler, rethrow = false) {
66
+ return (event) => {
67
+ return handler.onDomainEvent(event).catch((error) => {
68
+ this._logger.error(`Error while emitting event ${event.payload.constructor.name} : ${error.message}`);
69
+ return rethrow
70
+ ? Promise.reject(new subscription_exception_1.SubscriptionException(error, event.payload.constructor.name, event.eventId))
71
+ : Promise.resolve();
72
+ });
73
+ };
74
+ }
75
+ emitConcurrently(publishedEvents) {
76
+ const [eventsWithSyncSubscriptions, eventsWithAsyncSubscriptions] = this.splitEventsBySubscriptionType(publishedEvents);
77
+ if (eventsWithAsyncSubscriptions.length > 0) {
78
+ const promises = eventsWithAsyncSubscriptions.flatMap((event) => {
79
+ const eventId = (0, domain_event_subscription_1.getEventId)(event.payload.constructor);
80
+ const handlers = this._asyncHandlers.get(eventId);
81
+ return handlers.map((handler) => this.catchError(handler)(event));
82
+ });
83
+ Promise.all(promises);
46
84
  }
47
- const handlers = this._handlers.get(eventId);
48
- const withErrorHandling = handlers.map((handler) => {
49
- return async () => {
50
- try {
51
- return await handler.onDomainEvent(withAggregate);
52
- }
53
- catch (error) {
54
- this._logger.error(`Error while emitting event ${withAggregate.payload.constructor.name} : ${error.message}`);
55
- throw error;
85
+ if (eventsWithSyncSubscriptions.length > 0) {
86
+ const promises = eventsWithSyncSubscriptions.flatMap((event) => {
87
+ const eventId = (0, domain_event_subscription_1.getEventId)(event.payload.constructor);
88
+ const handlers = this._syncHandlers.get(eventId);
89
+ return handlers.map((handler) => this.catchError(handler, true)(event));
90
+ });
91
+ return Promise.all(promises);
92
+ }
93
+ return Promise.resolve();
94
+ }
95
+ emitSequentially(publishedEvents) {
96
+ const [eventsWithSyncSubscriptions] = this.splitEventsBySubscriptionType(publishedEvents);
97
+ //if there is even one event with a sync subscription, we should wait for all events to be emitted
98
+ const shouldWait = eventsWithSyncSubscriptions.length > 0;
99
+ const promisesPerEvent = publishedEvents
100
+ .filter((event) => {
101
+ const eventId = (0, domain_event_subscription_1.getEventId)(event.payload.constructor);
102
+ const hasSubscriptions = this._syncHandlers.has(eventId) || this._asyncHandlers.has(eventId);
103
+ if (!hasSubscriptions) {
104
+ this._logger.warn(`Event ${event.payload.constructor.name} can't be passed to subscriptions. Make sure you use the @DomainEventSubscription decorator`);
105
+ }
106
+ return hasSubscriptions;
107
+ })
108
+ .map((event) => {
109
+ const eventId = (0, domain_event_subscription_1.getEventId)(event.payload.constructor);
110
+ const syncHandlers = this._syncHandlers.get(eventId) ?? [];
111
+ const asyncHandlers = this._asyncHandlers.get(eventId) ?? [];
112
+ const all = [...syncHandlers, ...asyncHandlers].map((handler) => this.catchError(handler, true));
113
+ return {
114
+ event,
115
+ promise: () => {
116
+ return Promise.all(all.map((handler) => handler(event)));
56
117
  }
57
118
  };
58
119
  });
59
- return Promise.all(withErrorHandling.map((f) => f()));
60
- }
61
- emitMultiple(withAggregate) {
62
- if (this._concurrentSubscriptions) {
63
- return Promise.all(withAggregate.map((aggregate) => this.emit(aggregate)));
120
+ if (shouldWait) {
121
+ return (0, rxjs_1.lastValueFrom)((0, rxjs_1.from)(promisesPerEvent).pipe((0, rxjs_1.concatMap)((perEvent) => (0, rxjs_1.from)(perEvent.promise())), (0, rxjs_1.toArray)()));
122
+ }
123
+ else {
124
+ (0, rxjs_1.from)(promisesPerEvent)
125
+ .pipe((0, rxjs_1.concatMap)((perEvent) => (0, rxjs_1.from)(perEvent.promise())), (0, rxjs_1.toArray)())
126
+ .subscribe({});
127
+ return Promise.resolve();
64
128
  }
65
- return (0, rxjs_1.lastValueFrom)((0, rxjs_1.from)(withAggregate).pipe((0, rxjs_1.concatMap)((event) => (0, rxjs_1.from)(this.emit(event))), (0, rxjs_1.toArray)())).catch((error) => {
66
- this._logger.debug(`Error while emitting events sequentially: ${error.message}`);
67
- });
68
129
  }
69
- onModuleDestroy() {
70
- this._handlers.clear();
130
+ splitEventsBySubscriptionType(publishedEvents) {
131
+ const withValidMetadata = publishedEvents.filter((event) => {
132
+ const eventId = (0, domain_event_subscription_1.getEventId)(event.payload.constructor);
133
+ return !(0, type_utils_1.isNil)(eventId);
134
+ });
135
+ const eventsWithSyncSubscriptions = withValidMetadata.filter((event) => {
136
+ const eventId = (0, domain_event_subscription_1.getEventId)(event.payload.constructor);
137
+ return this._syncHandlers.has(eventId);
138
+ });
139
+ const eventsWithAsyncSubscriptions = withValidMetadata.filter((event) => {
140
+ const eventId = (0, domain_event_subscription_1.getEventId)(event.payload.constructor);
141
+ return this._asyncHandlers.has(eventId);
142
+ });
143
+ return [eventsWithSyncSubscriptions, eventsWithAsyncSubscriptions];
71
144
  }
72
145
  }
73
146
  exports.DomainEventEmitter = DomainEventEmitter;
@@ -1 +1 @@
1
- {"version":3,"file":"domain-event-emitter.js","sourceRoot":"","sources":["../../../../../libs/core/src/lib/domain-event-emitter.ts"],"names":[],"mappings":";;;AAAA,2CAAyD;AAEzD,+BAA+D;AAE/D,2EAIqC;AAGrC,mDAA2C;AAE3C,MAAa,kBAAkB;IAI3B,YAA6B,2BAA2B,KAAK;QAAhC,6BAAwB,GAAxB,wBAAwB,CAAQ;QACzD,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAwC,CAAC;QACjE,IAAI,CAAC,OAAO,GAAG,IAAI,eAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,uBAAuB;QACvB,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACzC,CAAC;IAED,iBAAiB,CAAC,eAAoC;QAClD,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC/B,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAClC,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;oBACvD,OAAO;gBACX,CAAC;gBAED,IAAI,IAAA,qDAAyB,EAAC,QAAQ,CAAC,QAAkB,CAAC,EAAE,CAAC;oBACzD,MAAM,MAAM,GAAG,IAAA,gEAAoC,EAAC,QAAQ,CAAC,QAAkC,CAAC,CAAC;oBACjG,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;wBACrB,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAW,CAAC;wBAC5C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;4BAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;wBACpC,CAAC;wBAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,aAAa,OAAO,EAAE,CAAC,CAAC;wBACzF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAiC,CAAC,CAAC;oBAClF,CAAC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED,IAAI,CAAC,aAA2C;QAC5C,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,IAAI,CACb,SAAS,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,6FAA6F,CAC/I,CAAC;YACF,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC;QACD,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC9D,IAAI,IAAA,kBAAK,EAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,OAAO,CAAC,IAAI,CACb,SAAS,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,6FAA6F,CAC/I,CAAC;YACF,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAiC,CAAC;QAC7E,MAAM,iBAAiB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YAC/C,OAAO,KAAK,IAAI,EAAE;gBACd,IAAI,CAAC;oBACD,OAAO,MAAM,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;gBACtD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,IAAI,CAAC,OAAO,CAAC,KAAK,CACd,8BAA8B,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,MAC/D,KAAa,CAAC,OACnB,EAAE,CACL,CAAC;oBACF,MAAM,KAAK,CAAC;gBAChB,CAAC;YACL,CAAC,CAAC;QACN,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,YAAY,CAAC,aAA6C;QACtD,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAChC,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC;QAED,OAAO,IAAA,oBAAa,EAChB,IAAA,WAAI,EAAC,aAAa,CAAC,CAAC,IAAI,CACpB,IAAA,gBAAS,EAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,WAAI,EAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAC5C,IAAA,cAAO,GAAE,CACZ,CACJ,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACd,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,6CAA8C,KAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9F,CAAC,CAAC,CAAC;IACP,CAAC;IAED,eAAe;QACX,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACJ;AAvFD,gDAuFC"}
1
+ {"version":3,"file":"domain-event-emitter.js","sourceRoot":"","sources":["../../../../../libs/core/src/lib/domain-event-emitter.ts"],"names":[],"mappings":";;;AAAA,2CAAyD;AAEzD,+BAA+D;AAE/D,2EAKqC;AACrC,gFAA4E;AAG5E,mDAA2C;AAE3C,MAAa,kBAAkB;IAK3B,YAA6B,2BAA2B,KAAK;QAAhC,6BAAwB,GAAxB,wBAAwB,CAAQ;QACzD,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,EAAwC,CAAC;QACtE,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAwC,CAAC;QACrE,IAAI,CAAC,OAAO,GAAG,IAAI,eAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,uBAAuB;QACvB,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACzC,CAAC;IAED,iBAAiB,CAAC,eAAoC;QAClD,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC/B,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAClC,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;oBACvD,OAAO;gBACX,CAAC;gBAED,IAAI,IAAA,qDAAyB,EAAC,QAAQ,CAAC,QAAkB,CAAC,EAAE,CAAC;oBACzD,MAAM,MAAM,GAAG,IAAA,gEAAoC,EAAC,QAAQ,CAAC,QAAkC,CAAC,CAAC;oBACjG,MAAM,OAAO,GAAG,IAAA,oDAAwB,EAAC,QAAQ,CAAC,QAAkC,CAAC,CAAC;oBACtF,IAAI,OAAO,EAAE,CAAC;wBACV,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;4BACrB,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAW,CAAC;4BAC5C,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gCACpC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;4BACzC,CAAC;4BAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,aAAa,OAAO,EAAE,CAAC,CAAC;4BACzF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAiC,CAAC,CAAC;wBACvF,CAAC,CAAC,CAAC;oBACP,CAAC;yBAAM,CAAC;wBACJ,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;4BACrB,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAW,CAAC;4BAC5C,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gCACnC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;4BACxC,CAAC;4BAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,aAAa,OAAO,EAAE,CAAC,CAAC;4BACzF,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAiC,CAAC,CAAC;wBACtF,CAAC,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED,YAAY,CAAC,eAA+C;QACxD,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAClE,IAAI,CAAC,OAAO,CAAC,IAAI,CACb,uGAAuG,CAC1G,CAAC;YACF,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC;QAED,OAAO,IAAI,CAAC,wBAAwB;YAChC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC;YACxC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;IACjD,CAAC;IAED,eAAe;QACX,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAEO,UAAU,CACd,OAA8B,EAC9B,OAAO,GAAG,KAAK;QAEf,OAAO,CAAC,KAAmC,EAAE,EAAE;YAC3C,OAAO,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBAChD,IAAI,CAAC,OAAO,CAAC,KAAK,CACd,8BAA8B,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,MAAO,KAAa,CAAC,OAAO,EAAE,CAC7F,CAAC;gBACF,OAAO,OAAO;oBACV,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,8CAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;oBACjG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC5B,CAAC,CAAC,CAAC;QACP,CAAC,CAAC;IACN,CAAC;IAEO,gBAAgB,CAAC,eAA+C;QACpE,MAAM,CAAC,2BAA2B,EAAE,4BAA4B,CAAC,GAC7D,IAAI,CAAC,6BAA6B,CAAC,eAAe,CAAC,CAAC;QAExD,IAAI,4BAA4B,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC5D,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAW,CAAC;gBAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAiC,CAAC;gBAClF,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAED,IAAI,2BAA2B,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC3D,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAW,CAAC;gBAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAiC,CAAC;gBACjF,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5E,CAAC,CAAC,CAAC;YAEH,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAEO,gBAAgB,CAAC,eAA+C;QACpE,MAAM,CAAC,2BAA2B,CAAC,GAAG,IAAI,CAAC,6BAA6B,CAAC,eAAe,CAAC,CAAC;QAE1F,kGAAkG;QAClG,MAAM,UAAU,GAAG,2BAA2B,CAAC,MAAM,GAAG,CAAC,CAAC;QAE1D,MAAM,gBAAgB,GAGjB,eAAe;aACf,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACd,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAW,CAAC;YAChE,MAAM,gBAAgB,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC7F,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CACb,SAAS,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,6FAA6F,CACvI,CAAC;YACN,CAAC;YACD,OAAO,gBAAgB,CAAC;QAC5B,CAAC,CAAC;aACD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACX,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAW,CAAC;YAChE,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC3D,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC7D,MAAM,GAAG,GAAG,CAAC,GAAG,YAAY,EAAE,GAAG,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YACjG,OAAO;gBACH,KAAK;gBACL,OAAO,EAAE,GAAG,EAAE;oBACV,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC7D,CAAC;aACJ,CAAC;QACN,CAAC,CAAC,CAAC;QAEP,IAAI,UAAU,EAAE,CAAC;YACb,OAAO,IAAA,oBAAa,EAChB,IAAA,WAAI,EAAC,gBAAgB,CAAC,CAAC,IAAI,CACvB,IAAA,gBAAS,EAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAA,WAAI,EAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,EACjD,IAAA,cAAO,GAAE,CACZ,CACJ,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,IAAA,WAAI,EAAC,gBAAgB,CAAC;iBACjB,IAAI,CACD,IAAA,gBAAS,EAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAA,WAAI,EAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,EACjD,IAAA,cAAO,GAAE,CACZ;iBACA,SAAS,CAAC,EAAE,CAAC,CAAC;YACnB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAEO,6BAA6B,CACjC,eAA+C;QAE/C,MAAM,iBAAiB,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACvD,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YACtD,OAAO,CAAC,IAAA,kBAAK,EAAC,OAAO,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,MAAM,2BAA2B,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACnE,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAW,CAAC;YAChE,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,MAAM,4BAA4B,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpE,MAAM,OAAO,GAAG,IAAA,sCAAU,EAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAW,CAAC;YAChE,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,2BAA2B,EAAE,4BAA4B,CAAC,CAAC;IACvE,CAAC;CACJ;AAvLD,gDAuLC"}
@@ -1,6 +1,20 @@
1
1
  import { Class } from "type-fest";
2
2
  import { OnDomainEvent } from "./on-domain-event";
3
- export declare const DomainEventSubscription: (...eventClasses: Class<unknown>[]) => ClassDecorator;
3
+ type SubscriptionConfiguration = {
4
+ /**
5
+ * The event classes that the subscription listens to.
6
+ */
7
+ eventClasses: Class<unknown>[];
8
+ /**
9
+ * Setting isAsync to false will make the rest of the commit process to wait for the subscription to finish.
10
+ * Default is true.
11
+ */
12
+ isAsync?: boolean;
13
+ };
14
+ export declare function DomainEventSubscription(...eventClasses: Class<unknown>[]): ClassDecorator;
15
+ export declare function DomainEventSubscription(config: SubscriptionConfiguration): ClassDecorator;
4
16
  export declare function getEventId(eventConstructor: Function): string | undefined;
5
17
  export declare function getEventsFromDomainEventSubscription(subscriptionInstance: OnDomainEvent<unknown>): any[];
18
+ export declare function getSubscriptionAsyncType(subscriptionInstance: OnDomainEvent<unknown>): boolean;
6
19
  export declare function isDomainEventSubscription(targetInstance: object): boolean;
20
+ export {};
@@ -1,23 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DomainEventSubscription = void 0;
3
+ exports.DomainEventSubscription = DomainEventSubscription;
4
4
  exports.getEventId = getEventId;
5
5
  exports.getEventsFromDomainEventSubscription = getEventsFromDomainEventSubscription;
6
+ exports.getSubscriptionAsyncType = getSubscriptionAsyncType;
6
7
  exports.isDomainEventSubscription = isDomainEventSubscription;
7
8
  const node_crypto_1 = require("node:crypto");
9
+ const radash_1 = require("radash");
8
10
  const metadata_keys_1 = require("./metadata-keys");
9
11
  const type_utils_1 = require("./utils/type-utils");
10
- const DomainEventSubscription = (...eventClasses) => {
12
+ function DomainEventSubscription(configOrEventClass, ...eventClasses) {
13
+ const actualEventClasses = (0, radash_1.isObject)(configOrEventClass)
14
+ ? configOrEventClass.eventClasses
15
+ : [configOrEventClass, ...eventClasses];
16
+ let isAsync = true;
17
+ if ((0, radash_1.isObject)(configOrEventClass)) {
18
+ isAsync = configOrEventClass.isAsync ?? true;
19
+ }
11
20
  return (target) => {
12
- for (const event of eventClasses) {
21
+ for (const event of actualEventClasses) {
13
22
  if (!Reflect.hasOwnMetadata(metadata_keys_1.DOMAIN_EVENT_KEY, event)) {
14
23
  Reflect.defineMetadata(metadata_keys_1.DOMAIN_EVENT_KEY, { eventSubscriptionId: `${event.name}-${(0, node_crypto_1.randomUUID)()}` }, event);
15
24
  }
16
25
  }
17
- Reflect.defineMetadata(metadata_keys_1.DOMAIN_EVENT_SUBSCRIPTION_KEY, { events: eventClasses }, target);
26
+ Reflect.defineMetadata(metadata_keys_1.DOMAIN_EVENT_SUBSCRIPTION_KEY, { events: actualEventClasses, isAsync }, target);
18
27
  };
19
- };
20
- exports.DomainEventSubscription = DomainEventSubscription;
28
+ }
21
29
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
22
30
  function getEventId(eventConstructor) {
23
31
  return Reflect.getMetadata(metadata_keys_1.DOMAIN_EVENT_KEY, eventConstructor)?.eventSubscriptionId;
@@ -26,6 +34,10 @@ function getEventsFromDomainEventSubscription(subscriptionInstance) {
26
34
  const metadata = Reflect.getMetadata(metadata_keys_1.DOMAIN_EVENT_SUBSCRIPTION_KEY, subscriptionInstance.constructor);
27
35
  return (0, type_utils_1.isNil)(metadata) ? [] : metadata.events;
28
36
  }
37
+ function getSubscriptionAsyncType(subscriptionInstance) {
38
+ const metadata = Reflect.getMetadata(metadata_keys_1.DOMAIN_EVENT_SUBSCRIPTION_KEY, subscriptionInstance.constructor);
39
+ return (0, type_utils_1.isNil)(metadata) ? true : metadata.isAsync;
40
+ }
29
41
  function isDomainEventSubscription(targetInstance) {
30
42
  const hasMetadata = Reflect.hasOwnMetadata(metadata_keys_1.DOMAIN_EVENT_SUBSCRIPTION_KEY, targetInstance.constructor);
31
43
  return hasMetadata && typeof targetInstance.onDomainEvent === "function";
@@ -1 +1 @@
1
- {"version":3,"file":"domain-event-subscription.js","sourceRoot":"","sources":["../../../../../libs/core/src/lib/domain-event-subscription.ts"],"names":[],"mappings":";;;AAwBA,gCAEC;AAED,oFAGC;AAED,8DAGC;AApCD,6CAAyC;AAGzC,mDAAkF;AAElF,mDAA2C;AAEpC,MAAM,uBAAuB,GAAG,CAAC,GAAG,YAA8B,EAAkB,EAAE;IACzF,OAAO,CAAC,MAAc,EAAE,EAAE;QACtB,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,gCAAgB,EAAE,KAAK,CAAC,EAAE,CAAC;gBACnD,OAAO,CAAC,cAAc,CAClB,gCAAgB,EAChB,EAAE,mBAAmB,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,IAAA,wBAAU,GAAE,EAAE,EAAE,EACxD,KAAK,CACR,CAAC;YACN,CAAC;QACL,CAAC;QAED,OAAO,CAAC,cAAc,CAAC,6CAA6B,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,MAAM,CAAC,CAAC;IAC5F,CAAC,CAAC;AACN,CAAC,CAAC;AAdW,QAAA,uBAAuB,2BAclC;AAEF,sEAAsE;AACtE,SAAgB,UAAU,CAAC,gBAA0B;IACjD,OAAO,OAAO,CAAC,WAAW,CAAC,gCAAgB,EAAE,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;AACxF,CAAC;AAED,SAAgB,oCAAoC,CAAC,oBAA4C;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,6CAA6B,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACtG,OAAO,IAAA,kBAAK,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;AAClD,CAAC;AAED,SAAgB,yBAAyB,CAAC,cAAsB;IAC5D,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,6CAA6B,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;IACtG,OAAO,WAAW,IAAI,OAAQ,cAAyC,CAAC,aAAa,KAAK,UAAU,CAAC;AACzG,CAAC"}
1
+ {"version":3,"file":"domain-event-subscription.js","sourceRoot":"","sources":["../../../../../libs/core/src/lib/domain-event-subscription.ts"],"names":[],"mappings":";;AAsBA,0DA0BC;AAGD,gCAEC;AAED,oFAGC;AAED,4DAGC;AAED,8DAGC;AApED,6CAAyC;AACzC,mCAAkC;AAGlC,mDAAkF;AAElF,mDAA2C;AAgB3C,SAAgB,uBAAuB,CACnC,kBAA8D,EAC9D,GAAG,YAA8B;IAEjC,MAAM,kBAAkB,GAAG,IAAA,iBAAQ,EAAC,kBAAkB,CAAC;QACnD,CAAC,CAAE,kBAAgD,CAAC,YAAY;QAChE,CAAC,CAAC,CAAC,kBAAkB,EAAE,GAAG,YAAY,CAAC,CAAC;IAE5C,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,IAAA,iBAAQ,EAAC,kBAAkB,CAAC,EAAE,CAAC;QAC/B,OAAO,GAAI,kBAAgD,CAAC,OAAO,IAAI,IAAI,CAAC;IAChF,CAAC;IAED,OAAO,CAAC,MAAc,EAAE,EAAE;QACtB,KAAK,MAAM,KAAK,IAAI,kBAAkB,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,gCAAgB,EAAE,KAAK,CAAC,EAAE,CAAC;gBACnD,OAAO,CAAC,cAAc,CAClB,gCAAgB,EAChB,EAAE,mBAAmB,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,IAAA,wBAAU,GAAE,EAAE,EAAE,EACxD,KAAK,CACR,CAAC;YACN,CAAC;QACL,CAAC;QAED,OAAO,CAAC,cAAc,CAAC,6CAA6B,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;IAC3G,CAAC,CAAC;AACN,CAAC;AAED,sEAAsE;AACtE,SAAgB,UAAU,CAAC,gBAA0B;IACjD,OAAO,OAAO,CAAC,WAAW,CAAC,gCAAgB,EAAE,gBAAgB,CAAC,EAAE,mBAAmB,CAAC;AACxF,CAAC;AAED,SAAgB,oCAAoC,CAAC,oBAA4C;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,6CAA6B,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACtG,OAAO,IAAA,kBAAK,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;AAClD,CAAC;AAED,SAAgB,wBAAwB,CAAC,oBAA4C;IACjF,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,6CAA6B,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACtG,OAAO,IAAA,kBAAK,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;AACrD,CAAC;AAED,SAAgB,yBAAyB,CAAC,cAAsB;IAC5D,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,6CAA6B,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;IACtG,OAAO,WAAW,IAAI,OAAQ,cAAyC,CAAC,aAAa,KAAK,UAAU,CAAC;AACzG,CAAC"}
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Thrown during event persistence if there's a concurrency issue.
3
+ * Concurrency issues are detected if the expected version of an aggregate root is different from the version stored in the database.
4
+ *
5
+ * Typically, this could only happen if some other process in your system has updated the aggregate root in the meantime.
6
+ *
7
+ * By catching this exception, you can decide how to handle the situation.
8
+ */
1
9
  export declare class EventConcurrencyException extends Error {
2
10
  constructor(aggregateRootId: string, databaseVersion: number, version: number);
3
11
  }
@@ -1,6 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventConcurrencyException = void 0;
4
+ /**
5
+ * Thrown during event persistence if there's a concurrency issue.
6
+ * Concurrency issues are detected if the expected version of an aggregate root is different from the version stored in the database.
7
+ *
8
+ * Typically, this could only happen if some other process in your system has updated the aggregate root in the meantime.
9
+ *
10
+ * By catching this exception, you can decide how to handle the situation.
11
+ */
4
12
  class EventConcurrencyException extends Error {
5
13
  constructor(aggregateRootId, databaseVersion, version) {
6
14
  super(`Concurrency issue for aggregate ${aggregateRootId}. Expected ${version}. Stored ${databaseVersion}`);
@@ -1 +1 @@
1
- {"version":3,"file":"event-concurrency-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/event-concurrency-exception.ts"],"names":[],"mappings":";;;AAAA,MAAa,yBAA0B,SAAQ,KAAK;IAChD,YAAY,eAAuB,EAAE,eAAuB,EAAE,OAAe;QACzE,KAAK,CAAC,mCAAmC,eAAe,cAAc,OAAO,YAAY,eAAe,EAAE,CAAC,CAAC;IAChH,CAAC;CACJ;AAJD,8DAIC"}
1
+ {"version":3,"file":"event-concurrency-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/event-concurrency-exception.ts"],"names":[],"mappings":";;;AAAA;;;;;;;GAOG;AACH,MAAa,yBAA0B,SAAQ,KAAK;IAChD,YAAY,eAAuB,EAAE,eAAuB,EAAE,OAAe;QACzE,KAAK,CAAC,mCAAmC,eAAe,cAAc,OAAO,YAAY,eAAe,EAAE,CAAC,CAAC;IAChH,CAAC;CACJ;AAJD,8DAIC"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Thrown when the name of an event is already used for another event.
3
+ */
1
4
  export declare class EventNameConflictException extends Error {
2
5
  constructor(name: string);
3
6
  }
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventNameConflictException = void 0;
4
+ /**
5
+ * Thrown when the name of an event is already used for another event.
6
+ */
4
7
  class EventNameConflictException extends Error {
5
8
  constructor(name) {
6
9
  super(`${name} is already registered as RegisteredEvent. Use another name`);
@@ -1 +1 @@
1
- {"version":3,"file":"event-name-conflict-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/event-name-conflict-exception.ts"],"names":[],"mappings":";;;AAAA,MAAa,0BAA2B,SAAQ,KAAK;IACjD,YAAY,IAAY;QACpB,KAAK,CAAC,GAAG,IAAI,6DAA6D,CAAC,CAAC;IAChF,CAAC;CACJ;AAJD,gEAIC"}
1
+ {"version":3,"file":"event-name-conflict-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/event-name-conflict-exception.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,0BAA2B,SAAQ,KAAK;IACjD,YAAY,IAAY;QACpB,KAAK,CAAC,GAAG,IAAI,6DAA6D,CAAC,CAAC;IAChF,CAAC;CACJ;AAJD,gEAIC"}
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Thrown during event persistence. Each database technology is using its own id format. This exception is thrown
3
+ * when event-nest tries to generate multiple ids and the number of generated ids does not match the expected number.
4
+ */
1
5
  export declare class IdGenerationException extends Error {
2
6
  constructor(idsLength: number, expectedLength: number);
3
7
  }
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IdGenerationException = void 0;
4
+ /**
5
+ * Thrown during event persistence. Each database technology is using its own id format. This exception is thrown
6
+ * when event-nest tries to generate multiple ids and the number of generated ids does not match the expected number.
7
+ */
4
8
  class IdGenerationException extends Error {
5
9
  constructor(idsLength, expectedLength) {
6
10
  super(`Unexpected mismatch of required ids. Generated: ${idsLength}, expected: ${expectedLength}`);
@@ -1 +1 @@
1
- {"version":3,"file":"id-generation-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/id-generation-exception.ts"],"names":[],"mappings":";;;AAAA,MAAa,qBAAsB,SAAQ,KAAK;IAC5C,YAAY,SAAiB,EAAE,cAAsB;QACjD,KAAK,CAAC,mDAAmD,SAAS,eAAe,cAAc,EAAE,CAAC,CAAC;IACvG,CAAC;CACJ;AAJD,sDAIC"}
1
+ {"version":3,"file":"id-generation-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/id-generation-exception.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,MAAa,qBAAsB,SAAQ,KAAK;IAC5C,YAAY,SAAiB,EAAE,cAAsB;QACjD,KAAK,CAAC,mDAAmD,SAAS,eAAe,cAAc,EAAE,CAAC,CAAC;IACvG,CAAC;CACJ;AAJD,sDAIC"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Exception thrown when an aggregate root is missing the @AggregateRootName decorator
3
+ */
1
4
  export declare class MissingAggregateRootNameException extends Error {
2
5
  constructor(aggregateRootClassName: string);
3
6
  }
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MissingAggregateRootNameException = void 0;
4
+ /**
5
+ * Exception thrown when an aggregate root is missing the @AggregateRootName decorator
6
+ */
4
7
  class MissingAggregateRootNameException extends Error {
5
8
  constructor(aggregateRootClassName) {
6
9
  super(`${aggregateRootClassName} is not decorated with @AggregateRootName. Use the decorator to set the name of the aggregate root`);
@@ -1 +1 @@
1
- {"version":3,"file":"missing-aggregate-root-name-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/missing-aggregate-root-name-exception.ts"],"names":[],"mappings":";;;AAAA,MAAa,iCAAkC,SAAQ,KAAK;IACxD,YAAY,sBAA8B;QACtC,KAAK,CACD,GAAG,sBAAsB,oGAAoG,CAChI,CAAC;IACN,CAAC;CACJ;AAND,8EAMC"}
1
+ {"version":3,"file":"missing-aggregate-root-name-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/missing-aggregate-root-name-exception.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,iCAAkC,SAAQ,KAAK;IACxD,YAAY,sBAA8B;QACtC,KAAK,CACD,GAAG,sBAAsB,oGAAoG,CAChI,CAAC;IACN,CAAC;CACJ;AAND,8EAMC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Exception thrown when an error occurs while running subscriptions for an event.
3
+ * The caught error, the event class name and the event id are stored in the exception.
4
+ */
5
+ export declare class SubscriptionException extends Error {
6
+ private readonly _caughtError;
7
+ private readonly _eventClassName;
8
+ private readonly _eventId;
9
+ constructor(caughtError: Error, eventClassName: string, eventId: string);
10
+ get caughtError(): Error;
11
+ get eventClassName(): string;
12
+ get eventId(): string;
13
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubscriptionException = void 0;
4
+ /**
5
+ * Exception thrown when an error occurs while running subscriptions for an event.
6
+ * The caught error, the event class name and the event id are stored in the exception.
7
+ */
8
+ class SubscriptionException extends Error {
9
+ constructor(caughtError, eventClassName, eventId) {
10
+ super(`Error while running subscriptions for event ${eventClassName} with id ${eventId}`);
11
+ this._caughtError = caughtError;
12
+ this._eventClassName = eventClassName;
13
+ this._eventId = eventId;
14
+ }
15
+ get caughtError() {
16
+ return this._caughtError;
17
+ }
18
+ get eventClassName() {
19
+ return this._eventClassName;
20
+ }
21
+ get eventId() {
22
+ return this._eventId;
23
+ }
24
+ }
25
+ exports.SubscriptionException = SubscriptionException;
26
+ //# sourceMappingURL=subscription-exception.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/subscription-exception.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,MAAa,qBAAsB,SAAQ,KAAK;IAK5C,YAAY,WAAkB,EAAE,cAAsB,EAAE,OAAe;QACnE,KAAK,CAAC,+CAA+C,cAAc,YAAY,OAAO,EAAE,CAAC,CAAC;QAC1F,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;QACtC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC5B,CAAC;IAED,IAAI,WAAW;QACX,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAED,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,eAAe,CAAC;IAChC,CAAC;IAED,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;CACJ;AAvBD,sDAuBC"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Thrown during reconstitution of an aggregate root if the event is not registered using the @DomainEvent decorator.
3
+ */
1
4
  export declare class UnknownEventException extends Error {
2
5
  constructor(unregisteredEventNames: Array<string>, missingApplyEventNames: Array<string>, aggregateRootId: string);
3
6
  }
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UnknownEventException = void 0;
4
+ /**
5
+ * Thrown during reconstitution of an aggregate root if the event is not registered using the @DomainEvent decorator.
6
+ */
4
7
  class UnknownEventException extends Error {
5
8
  constructor(unregisteredEventNames, missingApplyEventNames, aggregateRootId) {
6
9
  super(`Found unknown events for aggregate root ${aggregateRootId}. Unregistered : ${unregisteredEventNames.join(", ")}. Missing apply method: ${missingApplyEventNames.join(", ")}`);
@@ -1 +1 @@
1
- {"version":3,"file":"unknown-event-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/unknown-event-exception.ts"],"names":[],"mappings":";;;AAAA,MAAa,qBAAsB,SAAQ,KAAK;IAC5C,YAAY,sBAAqC,EAAE,sBAAqC,EAAE,eAAuB;QAC7G,KAAK,CACD,2CAA2C,eAAe,oBAAoB,sBAAsB,CAAC,IAAI,CACrG,IAAI,CACP,2BAA2B,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClE,CAAC;IACN,CAAC;CACJ;AARD,sDAQC"}
1
+ {"version":3,"file":"unknown-event-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/unknown-event-exception.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,qBAAsB,SAAQ,KAAK;IAC5C,YAAY,sBAAqC,EAAE,sBAAqC,EAAE,eAAuB;QAC7G,KAAK,CACD,2CAA2C,eAAe,oBAAoB,sBAAsB,CAAC,IAAI,CACrG,IAAI,CACP,2BAA2B,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClE,CAAC;IACN,CAAC;CACJ;AARD,sDAQC"}
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Thrown if an event is passed to the aggregate root's append method but it's not registered using the @DomainEvent decorator.
3
+ */
1
4
  export declare class UnregisteredEventException extends Error {
2
5
  constructor(eventClassName: string);
3
6
  }
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UnregisteredEventException = void 0;
4
+ /**
5
+ * Thrown if an event is passed to the aggregate root's append method but it's not registered using the @DomainEvent decorator.
6
+ */
4
7
  class UnregisteredEventException extends Error {
5
8
  constructor(eventClassName) {
6
9
  super(`${eventClassName} is not registered to be processed. Use the @DomainEvent decorator to register it.`);
@@ -1 +1 @@
1
- {"version":3,"file":"unregistered-event-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/unregistered-event-exception.ts"],"names":[],"mappings":";;;AAAA,MAAa,0BAA2B,SAAQ,KAAK;IACjD,YAAY,cAAsB;QAC9B,KAAK,CAAC,GAAG,cAAc,oFAAoF,CAAC,CAAC;IACjH,CAAC;CACJ;AAJD,gEAIC"}
1
+ {"version":3,"file":"unregistered-event-exception.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/exceptions/unregistered-event-exception.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,0BAA2B,SAAQ,KAAK;IACjD,YAAY,cAAsB;QAC9B,KAAK,CAAC,GAAG,cAAc,oFAAoF,CAAC,CAAC;IACjH,CAAC;CACJ;AAJD,gEAIC"}
@@ -50,8 +50,8 @@ class AbstractEventStore {
50
50
  }
51
51
  publishedEvent.version = found.aggregateRootVersion;
52
52
  }
53
- this._eventEmitter.emitMultiple(published);
54
53
  aggregateRoot.resolveVersion(saved);
54
+ await this._eventEmitter.emitMultiple(published);
55
55
  return saved;
56
56
  };
57
57
  return aggregateRoot;
@@ -1 +1 @@
1
- {"version":3,"file":"abstract-event-store.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/storage/abstract-event-store.ts"],"names":[],"mappings":";;;AAEA,+EAA6E;AAE7E,mFAA8E;AAC9E,+GAAwG;AACxG,mGAA6F;AAE7F,oDAA0D;AAE1D,mEAA8D;AAC9D,iDAA6C;AAE7C;;;;GAIG;AACH,MAAsB,kBAAkB;IACpC,YAA8B,aAAiC;QAAjC,kBAAa,GAAb,aAAa,CAAoB;IAAG,CAAC;IAEnE,YAAY,CAA0B,aAAgB;QAClD,aAAa,CAAC,OAAO,GAAG,KAAK,EAAE,MAAyC,EAAE,EAAE;YACxE,MAAM,iBAAiB,GAAG,IAAA,0CAAoB,EAAC,aAAa,CAAC,WAAW,CAAC,CAAC;YAC1E,IAAI,IAAA,kBAAK,EAAC,iBAAiB,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,yEAAiC,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAChF,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;YACzE,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,CAAC,IAAA,yBAAY,EAAC,GAAG,CAAC,EAAE,CAAC;gBACrD,MAAM,IAAI,+CAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAC/D,CAAC;YACD,MAAM,SAAS,GAAwC,EAAE,CAAC;YAC1D,MAAM,YAAY,GAAuB,EAAE,CAAC;YAE5C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,EAAY,CAAC;gBAC/B,YAAY,CAAC,IAAI,CACb,0BAAW,CAAC,kBAAkB,CAC1B,EAAE,EACF,aAAa,CAAC,EAAE,EAChB,iBAAiB,EACjB,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,UAAU,CACnB,CACJ,CAAC;gBACF,SAAS,CAAC,IAAI,CAAC;oBACX,GAAG,KAAK;oBACR,OAAO,EAAE,EAAE;oBACX,OAAO,EAAE,aAAa,CAAC,OAAO;iBACjC,CAAC,CAAC;YACP,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,2CAAmB,CAAC,aAAa,CAAC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;YACjF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACrD,KAAK,MAAM,cAAc,IAAI,SAAS,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC,OAAO,CAAC,CAAC;gBACjE,IAAI,IAAA,kBAAK,EAAC,KAAK,CAAC,EAAE,CAAC;oBACf,MAAM,IAAI,8DAA4B,CAAC,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;gBACnG,CAAC;gBAED,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC,oBAAoB,CAAC;YACxD,CAAC;YAED,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAC3C,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YACpC,OAAO,KAAK,CAAC;QACjB,CAAC,CAAC;QACF,OAAO,aAAa,CAAC;IACzB,CAAC;CAiBJ;AAxED,gDAwEC"}
1
+ {"version":3,"file":"abstract-event-store.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/storage/abstract-event-store.ts"],"names":[],"mappings":";;;AAEA,+EAA6E;AAE7E,mFAA8E;AAC9E,+GAAwG;AACxG,mGAA6F;AAE7F,oDAA0D;AAE1D,mEAA8D;AAC9D,iDAA6C;AAE7C;;;;GAIG;AACH,MAAsB,kBAAkB;IACpC,YAA8B,aAAiC;QAAjC,kBAAa,GAAb,aAAa,CAAoB;IAAG,CAAC;IAEnE,YAAY,CAA0B,aAAgB;QAClD,aAAa,CAAC,OAAO,GAAG,KAAK,EAAE,MAAyC,EAAE,EAAE;YACxE,MAAM,iBAAiB,GAAG,IAAA,0CAAoB,EAAC,aAAa,CAAC,WAAW,CAAC,CAAC;YAC1E,IAAI,IAAA,kBAAK,EAAC,iBAAiB,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,yEAAiC,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAChF,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;YACzE,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,CAAC,IAAA,yBAAY,EAAC,GAAG,CAAC,EAAE,CAAC;gBACrD,MAAM,IAAI,+CAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAC/D,CAAC;YACD,MAAM,SAAS,GAAwC,EAAE,CAAC;YAC1D,MAAM,YAAY,GAAuB,EAAE,CAAC;YAE5C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,EAAY,CAAC;gBAC/B,YAAY,CAAC,IAAI,CACb,0BAAW,CAAC,kBAAkB,CAC1B,EAAE,EACF,aAAa,CAAC,EAAE,EAChB,iBAAiB,EACjB,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,UAAU,CACnB,CACJ,CAAC;gBACF,SAAS,CAAC,IAAI,CAAC;oBACX,GAAG,KAAK;oBACR,OAAO,EAAE,EAAE;oBACX,OAAO,EAAE,aAAa,CAAC,OAAO;iBACjC,CAAC,CAAC;YACP,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,2CAAmB,CAAC,aAAa,CAAC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;YACjF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACrD,KAAK,MAAM,cAAc,IAAI,SAAS,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC,OAAO,CAAC,CAAC;gBACjE,IAAI,IAAA,kBAAK,EAAC,KAAK,CAAC,EAAE,CAAC;oBACf,MAAM,IAAI,8DAA4B,CAAC,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;gBACnG,CAAC;gBAED,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC,oBAAoB,CAAC;YACxD,CAAC;YAED,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YACjD,OAAO,KAAK,CAAC;QACjB,CAAC,CAAC;QACF,OAAO,aAAa,CAAC;IACzB,CAAC;CAiBJ;AAxED,gDAwEC"}