@event-nest/core 4.0.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +249 -4
  2. package/package.json +3 -2
  3. package/src/index.d.ts +16 -0
  4. package/src/index.js +16 -0
  5. package/src/index.js.map +1 -1
  6. package/src/lib/aggregate-root/aggregate-root-config.d.ts +37 -0
  7. package/src/lib/aggregate-root/aggregate-root-config.js +25 -0
  8. package/src/lib/aggregate-root/aggregate-root-config.js.map +1 -0
  9. package/src/lib/aggregate-root/aggregate-root-name.d.ts +1 -1
  10. package/src/lib/aggregate-root/aggregate-root-name.js +1 -5
  11. package/src/lib/aggregate-root/aggregate-root-name.js.map +1 -1
  12. package/src/lib/aggregate-root/aggregate-root.d.ts +3 -5
  13. package/src/lib/aggregate-root/aggregate-root.js +10 -9
  14. package/src/lib/aggregate-root/aggregate-root.js.map +1 -1
  15. package/src/lib/aggregate-root/apply-event.decorator.d.ts +1 -1
  16. package/src/lib/aggregate-root/apply-event.decorator.js.map +1 -1
  17. package/src/lib/aggregate-root/reflection.d.ts +1 -1
  18. package/src/lib/aggregate-root/snapshot-aware.d.ts +47 -0
  19. package/src/lib/aggregate-root/snapshot-aware.js +52 -0
  20. package/src/lib/aggregate-root/snapshot-aware.js.map +1 -0
  21. package/src/lib/domain-event-registrations.d.ts +1 -1
  22. package/src/lib/domain-event-registrations.js.map +1 -1
  23. package/src/lib/domain-event-subscription.d.ts +1 -1
  24. package/src/lib/domain-event-subscription.js.map +1 -1
  25. package/src/lib/exceptions/aggregate-class-not-snapshot-aware-exception.d.ts +6 -0
  26. package/src/lib/exceptions/aggregate-class-not-snapshot-aware-exception.js +13 -0
  27. package/src/lib/exceptions/aggregate-class-not-snapshot-aware-exception.js.map +1 -0
  28. package/src/lib/exceptions/aggregate-instance-not-snapshot-aware-exception.d.ts +6 -0
  29. package/src/lib/exceptions/aggregate-instance-not-snapshot-aware-exception.js +13 -0
  30. package/src/lib/exceptions/aggregate-instance-not-snapshot-aware-exception.js.map +1 -0
  31. package/src/lib/exceptions/snapshot-revision-mismatch-exception.d.ts +6 -0
  32. package/src/lib/exceptions/snapshot-revision-mismatch-exception.js +14 -0
  33. package/src/lib/exceptions/snapshot-revision-mismatch-exception.js.map +1 -0
  34. package/src/lib/metadata-keys.d.ts +1 -0
  35. package/src/lib/metadata-keys.js +2 -1
  36. package/src/lib/metadata-keys.js.map +1 -1
  37. package/src/lib/snapshot-strategy/all-of-snapshot-strategy.d.ts +29 -0
  38. package/src/lib/snapshot-strategy/all-of-snapshot-strategy.js +40 -0
  39. package/src/lib/snapshot-strategy/all-of-snapshot-strategy.js.map +1 -0
  40. package/src/lib/snapshot-strategy/any-of-snapshot-strategy.d.ts +30 -0
  41. package/src/lib/snapshot-strategy/any-of-snapshot-strategy.js +41 -0
  42. package/src/lib/snapshot-strategy/any-of-snapshot-strategy.js.map +1 -0
  43. package/src/lib/snapshot-strategy/for-aggregate-roots-strategy.d.ts +30 -0
  44. package/src/lib/snapshot-strategy/for-aggregate-roots-strategy.js +51 -0
  45. package/src/lib/snapshot-strategy/for-aggregate-roots-strategy.js.map +1 -0
  46. package/src/lib/snapshot-strategy/for-count-snapshot-strategy.d.ts +28 -0
  47. package/src/lib/snapshot-strategy/for-count-snapshot-strategy.js +41 -0
  48. package/src/lib/snapshot-strategy/for-count-snapshot-strategy.js.map +1 -0
  49. package/src/lib/snapshot-strategy/for-events-snapshot-strategy.d.ts +33 -0
  50. package/src/lib/snapshot-strategy/for-events-snapshot-strategy.js +37 -0
  51. package/src/lib/snapshot-strategy/for-events-snapshot-strategy.js.map +1 -0
  52. package/src/lib/snapshot-strategy/no-snapshot-strategy.d.ts +18 -0
  53. package/src/lib/snapshot-strategy/no-snapshot-strategy.js +25 -0
  54. package/src/lib/snapshot-strategy/no-snapshot-strategy.js.map +1 -0
  55. package/src/lib/snapshot-strategy/snapshot-strategy.d.ts +26 -0
  56. package/src/lib/snapshot-strategy/snapshot-strategy.js +20 -0
  57. package/src/lib/snapshot-strategy/snapshot-strategy.js.map +1 -0
  58. package/src/lib/storage/abstract-event-store.d.ts +8 -2
  59. package/src/lib/storage/abstract-event-store.js +8 -3
  60. package/src/lib/storage/abstract-event-store.js.map +1 -1
  61. package/src/lib/storage/event-store.d.ts +29 -0
  62. package/src/lib/storage/event-store.js.map +1 -1
  63. package/src/lib/storage/snapshot/abstract-snapshot-store.d.ts +14 -0
  64. package/src/lib/storage/snapshot/abstract-snapshot-store.js +26 -0
  65. package/src/lib/storage/snapshot/abstract-snapshot-store.js.map +1 -0
  66. package/src/lib/storage/snapshot/no-op-snapshot-store.d.ts +11 -0
  67. package/src/lib/storage/snapshot/no-op-snapshot-store.js +25 -0
  68. package/src/lib/storage/snapshot/no-op-snapshot-store.js.map +1 -0
  69. package/src/lib/storage/snapshot/snapshot-store.d.ts +38 -0
  70. package/src/lib/storage/snapshot/snapshot-store.js +5 -0
  71. package/src/lib/storage/snapshot/snapshot-store.js.map +1 -0
  72. package/src/lib/storage/snapshot/stored-snapshot.d.ts +17 -0
  73. package/src/lib/storage/snapshot/stored-snapshot.js +36 -0
  74. package/src/lib/storage/snapshot/stored-snapshot.js.map +1 -0
  75. package/src/lib/storage/stored-event.d.ts +1 -1
  76. package/src/lib/storage/stored-event.js.map +1 -1
  77. package/src/lib/utils/type-utils.d.ts +4 -0
  78. package/src/lib/utils/type-utils.js.map +1 -1
package/README.md CHANGED
@@ -25,6 +25,11 @@ What Event Nest is Not:
25
25
  - [Concepts](#concepts)
26
26
  - [Event](#event)
27
27
  - [Aggregate Root](#aggregate-root)
28
+ - [Snapshots](#snapshots)
29
+ - [Making an aggregate root snapshot-aware](#making-an-aggregate-root-snapshot-aware)
30
+ - [Snapshot strategies](#snapshot-strategies)
31
+ - [Loading an aggregate root with a snapshot](#loading-an-aggregate-root-with-a-snapshot)
32
+ - [Snapshot revision](#snapshot-revision)
28
33
  - [Domain Event Subscription](#domain-event-subscription)
29
34
  - [Order of execution in subscriptions](#order-of-execution-in-subscriptions)
30
35
  - [Waiting for subscriptions to complete](#waiting-for-subscriptions-to-complete)
@@ -71,6 +76,26 @@ export class AppModule {}
71
76
  ```
72
77
  The collections specified in the configuration will store the aggregates and events.
73
78
 
79
+ If you want to enable [snapshots](#snapshots), you will also need to provide a `snapshotCollection` and a `snapshotStrategy` :
80
+ ```typescript
81
+ import { ForCountSnapshotStrategy } from "@event-nest/core";
82
+ import { EventNestMongoDbModule } from "@event-nest/mongodb";
83
+ import { Module } from "@nestjs/common";
84
+
85
+ @Module({
86
+ imports: [
87
+ EventNestMongoDbModule.forRoot({
88
+ connectionUri: "mongodb://localhost:27017/example",
89
+ aggregatesCollection: "aggregates-collection",
90
+ eventsCollection: "events-collection",
91
+ snapshotCollection: "snapshots-collection",
92
+ snapshotStrategy: new ForCountSnapshotStrategy({ count: 10 })
93
+ }),
94
+ ],
95
+ })
96
+ export class AppModule {}
97
+ ```
98
+
74
99
 
75
100
  ### PostgreSQL setup
76
101
 
@@ -99,6 +124,28 @@ export class AppModule {}
99
124
 
100
125
  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.
101
126
 
127
+ If you want to enable [snapshots](#snapshots), you will also need to provide a `snapshotTableName` and a `snapshotStrategy` :
128
+ ```typescript
129
+ import { ForCountSnapshotStrategy } from "@event-nest/core";
130
+ import { EventNestPostgreSQLModule } from "@event-nest/postgresql";
131
+ import { Module } from "@nestjs/common";
132
+
133
+ @Module({
134
+ imports: [
135
+ EventNestPostgreSQLModule.forRoot({
136
+ aggregatesTableName: "aggregates",
137
+ connectionUri: "postgresql://postgres:password@localhost:5432/event_nest",
138
+ eventsTableName: "events",
139
+ schemaName: "event_nest_schema",
140
+ ensureTablesExist: true,
141
+ snapshotTableName: "snapshots",
142
+ snapshotStrategy: new ForCountSnapshotStrategy({ count: 10 })
143
+ })
144
+ ]
145
+ })
146
+ export class AppModule {}
147
+ ```
148
+
102
149
 
103
150
  #### Manual creation of PostgreSQL tables
104
151
  If you prefer to create the tables manually, the following guidelines describe the structure of the tables that need to be created.
@@ -122,6 +169,16 @@ If you prefer to create the tables manually, the following guidelines describe t
122
169
  | payload | jsonb | A JSON representation of the event's additional data. |
123
170
  | created_at | timestamp with time zone | The timestamp when the event was produced. <br/>Must be set as NOT NULL |
124
171
 
172
+ **Snapshots Table (optional) :**
173
+
174
+ | Column Name | Type | Description |
175
+ |------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------|
176
+ | id | uuid | The unique identifier of the snapshot. <br/>Must be set as NOT NULL and it is the table's primary key |
177
+ | aggregate_root_id | uuid | The id of the aggregate that the snapshot belongs to.<br/> Must be set as NOT NULL and it is a foreign key to the aggregates table |
178
+ | aggregate_root_version | integer | The version of the aggregate root when the snapshot was created. <br/>Must be set as NOT NULL |
179
+ | payload | jsonb | A JSON representation of the snapshot data. <br/>Must be set as NOT NULL |
180
+ | revision | integer | The snapshot revision number. <br/>Must be set as NOT NULL |
181
+
125
182
 
126
183
  ## Concepts
127
184
  ### Event
@@ -180,9 +237,11 @@ export class UserUpdatedEvent {
180
237
 
181
238
  Next, we will define the aggregate root for the user. Let's break down what this class should do and how.
182
239
 
183
- First of all, the class has to extend the `AggregateRoot` class, and it has to be decorated with the `@AggregateRootName` decorator.
240
+ First of all, the class has to extend the `AggregateRoot` class, and it has to be decorated with the `@AggregateRootConfig` decorator.
184
241
  The name is required to associate persisted events with the correct aggregate root when retrieving them from storage.
185
242
 
243
+ > **Note:** The `@AggregateRootName` decorator is deprecated and will be removed in version 7.x. Use `@AggregateRootConfig` instead.
244
+
186
245
  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
246
  In our case, we have the following creation cases :
188
247
  * 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.
@@ -198,9 +257,9 @@ It's important to note that the append method will not save the event. All the a
198
257
 
199
258
 
200
259
  ```typescript
201
- import { AggregateRoot, AggregateRootName, ApplyEvent, StoredEvent } from "@event-nest/core";
260
+ import { AggregateRoot, AggregateRootConfig, ApplyEvent, StoredEvent } from "@event-nest/core";
202
261
 
203
- @AggregateRootName("User")
262
+ @AggregateRootConfig({ name: "User" })
204
263
  export class User extends AggregateRoot {
205
264
  private name: string;
206
265
  private email: string;
@@ -276,6 +335,192 @@ export class UserService {
276
335
  }
277
336
  ```
278
337
 
338
+ ### Snapshots
339
+ As the number of events for an aggregate root grows, replaying the full event stream to reconstruct its state can become increasingly slow. Snapshots address this by periodically capturing the aggregate's state, so that reconstitution can start from a recent snapshot instead of replaying every event from the beginning.
340
+
341
+ Snapshots are entirely optional. When enabled, the library will automatically create snapshots based on a configurable strategy and use them during reconstitution. The complete event history is always preserved in storage regardless of whether snapshots are used.
342
+
343
+ To use snapshots, you need to :
344
+ * Configure a snapshot strategy and a snapshot storage location in your module setup (see [MongoDB setup](#mongodb-setup) or [PostgreSQL setup](#postgresql-setup))
345
+ * Have your aggregate root classes implement the `SnapshotAware` interface
346
+
347
+ #### Making an aggregate root snapshot-aware
348
+
349
+ An aggregate root needs two things to support snapshots :
350
+
351
+ 1. The `@AggregateRootConfig` decorator must include a `snapshotRevision` number.
352
+ 2. The class must implement the `SnapshotAware` interface, which requires two methods: `toSnapshot()` and `applySnapshot()`.
353
+
354
+ Let's extend the `User` example from above to support snapshots :
355
+
356
+ ```typescript
357
+ import { AggregateRoot, AggregateRootConfig, ApplyEvent, SnapshotAware, StoredEvent } from "@event-nest/core";
358
+
359
+ interface UserSnapshot {
360
+ name: string;
361
+ email: string;
362
+ }
363
+
364
+ @AggregateRootConfig({ name: "User", snapshotRevision: 1 })
365
+ export class User extends AggregateRoot implements SnapshotAware<UserSnapshot> {
366
+ private name: string;
367
+ private email: string;
368
+
369
+ private constructor(id: string) {
370
+ super(id);
371
+ }
372
+
373
+ public static createNew(id: string, name: string, email: string): User {
374
+ const user = new User(id);
375
+ const event = new UserCreatedEvent(name, email);
376
+ user.applyUserCreatedEvent(event);
377
+ user.append(event);
378
+ return user;
379
+ }
380
+
381
+ public static fromEvents(id: string, events: Array<StoredEvent>, snapshot?: UserSnapshot): User {
382
+ const user = new User(id);
383
+ user.reconstitute(events, snapshot);
384
+ return user;
385
+ }
386
+
387
+ toSnapshot(): UserSnapshot {
388
+ return { name: this.name, email: this.email };
389
+ }
390
+
391
+ applySnapshot(snapshot: UserSnapshot) {
392
+ this.name = snapshot.name;
393
+ this.email = snapshot.email;
394
+ }
395
+
396
+ public update(newName: string) {
397
+ const event = new UserUpdatedEvent(newName);
398
+ this.applyUserUpdatedEvent(event);
399
+ this.append(event);
400
+ }
401
+
402
+ @ApplyEvent(UserCreatedEvent)
403
+ private applyUserCreatedEvent(event: UserCreatedEvent) {
404
+ this.name = event.name;
405
+ this.email = event.email;
406
+ }
407
+
408
+ @ApplyEvent(UserUpdatedEvent)
409
+ private applyUserUpdatedEvent(event: UserUpdatedEvent) {
410
+ this.name = event.newName;
411
+ }
412
+ }
413
+ ```
414
+
415
+ The `toSnapshot()` method returns a plain representation of the aggregate's current state. The `applySnapshot()` method restores that state when a snapshot is loaded from storage. The `reconstitute` method accepts an optional snapshot parameter. When a snapshot is provided, it will be applied first, and then any remaining events will be replayed on top of it.
416
+
417
+ Note that when calling `commit`, the library will automatically evaluate the configured snapshot strategy to determine whether a new snapshot should be created. If the strategy says yes, it will call `toSnapshot()` and persist the result. You don't need to manage snapshot creation manually.
418
+
419
+
420
+ #### Snapshot strategies
421
+
422
+ Snapshot strategies determine when the library should create a snapshot for an aggregate root. You configure the strategy once in your module setup, and it applies globally. Several built-in strategies are available, and they can be composed to build more complex rules.
423
+
424
+ **ForCountSnapshotStrategy**
425
+
426
+ Creates a snapshot when the aggregate root crosses a version threshold. For example, with a count of 10, a snapshot will be created when the version goes from 9 to 10, from 19 to 20, and so on.
427
+
428
+ ```typescript
429
+ import { ForCountSnapshotStrategy } from "@event-nest/core";
430
+
431
+ new ForCountSnapshotStrategy({ count: 10 })
432
+ ```
433
+
434
+ **ForEventsSnapshotStrategy**
435
+
436
+ Creates a snapshot when specific event types are present in the uncommitted events. This is useful when certain events represent significant state changes that are worth snapshotting.
437
+
438
+ ```typescript
439
+ import { ForEventsSnapshotStrategy } from "@event-nest/core";
440
+
441
+ new ForEventsSnapshotStrategy({ eventClasses: [UserCreatedEvent, UserUpdatedEvent] })
442
+ ```
443
+
444
+ **ForAggregateRootsStrategy**
445
+
446
+ Creates snapshots only for specific aggregate root classes. This is useful when only some of your aggregates have enough events to benefit from snapshots.
447
+
448
+ ```typescript
449
+ import { ForAggregateRootsStrategy } from "@event-nest/core";
450
+
451
+ new ForAggregateRootsStrategy({ aggregates: [User, Order] })
452
+ ```
453
+
454
+ **AllOfSnapshotStrategy**
455
+
456
+ A composite strategy that creates a snapshot only when **all** of the provided strategies agree. This acts as a logical AND.
457
+
458
+ ```typescript
459
+ import { AllOfSnapshotStrategy, ForAggregateRootsStrategy, ForCountSnapshotStrategy } from "@event-nest/core";
460
+
461
+ new AllOfSnapshotStrategy([
462
+ new ForAggregateRootsStrategy({ aggregates: [User] }),
463
+ new ForCountSnapshotStrategy({ count: 10 })
464
+ ])
465
+ ```
466
+ In this example, snapshots will only be created for `User` aggregates and only when they cross a version threshold of 10.
467
+
468
+ **AnyOfSnapshotStrategy**
469
+
470
+ A composite strategy that creates a snapshot when **any** of the provided strategies agrees. This acts as a logical OR.
471
+
472
+ ```typescript
473
+ import { AnyOfSnapshotStrategy, ForCountSnapshotStrategy, ForEventsSnapshotStrategy } from "@event-nest/core";
474
+
475
+ new AnyOfSnapshotStrategy([
476
+ new ForCountSnapshotStrategy({ count: 10 }),
477
+ new ForEventsSnapshotStrategy({ eventClasses: [UserCreatedEvent] })
478
+ ])
479
+ ```
480
+ In this example, a snapshot will be created either when the version crosses a threshold of 10 or when a `UserCreatedEvent` is committed.
481
+
482
+ The composite strategies can be nested to express more complex rules. For example, you could use an `AnyOfSnapshotStrategy` that contains an `AllOfSnapshotStrategy` alongside a `ForEventsSnapshotStrategy`.
483
+
484
+
485
+ #### Loading an aggregate root with a snapshot
486
+
487
+ The `EventStore` provides a `findWithSnapshot` method that retrieves the latest snapshot for an aggregate root along with any events that occurred after that snapshot. If no snapshot is found, all events are returned.
488
+
489
+ ```typescript
490
+ import { EVENT_STORE, EventStore } from "@event-nest/core";
491
+
492
+ @Injectable()
493
+ export class UserService {
494
+ constructor(@Inject(EVENT_STORE) private eventStore: EventStore) {}
495
+
496
+ async updateUser(id: string, newName: string) {
497
+ const { events, snapshot } = await this.eventStore.findWithSnapshot(User, id);
498
+ const user = User.fromEvents(id, events, snapshot);
499
+ const userWithPublisher = this.eventStore.addPublisher(user);
500
+ user.update(newName);
501
+ await userWithPublisher.commit();
502
+ }
503
+ }
504
+ ```
505
+
506
+ If the snapshot cannot be loaded for any reason (for example, a revision mismatch), you can fall back to loading all events with `findByAggregateRootId` as shown in the [Aggregate Root](#aggregate-root) example.
507
+
508
+
509
+ #### Snapshot revision
510
+
511
+ The `snapshotRevision` number in `@AggregateRootConfig` is a compatibility version for the snapshot format. When loading a snapshot from storage, the library compares the stored revision with the one defined on the class. If they don't match, a `SnapshotRevisionMismatchException` is thrown.
512
+
513
+ This mechanism exists to protect against applying outdated snapshots when the structure of your snapshot changes. For example, if you add a new field to a `User` aggregate and update `toSnapshot()` to include it, the old snapshots in the database no longer match the new format. By incrementing the `snapshotRevision`, the library will reject old snapshots and the aggregate will be reconstituted from the full event stream instead. New snapshots created from that point on will use the updated format and revision number.
514
+
515
+ ```typescript
516
+ // Before: snapshot only includes name and email
517
+ @AggregateRootConfig({ name: "User", snapshotRevision: 1 })
518
+
519
+ // After: snapshot now includes name, email, and role
520
+ @AggregateRootConfig({ name: "User", snapshotRevision: 2 })
521
+ ```
522
+
523
+
279
524
  ### Domain Event Subscription
280
525
  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.
281
526
 
@@ -338,7 +583,7 @@ The `DomainEventSubscription` decorator supports an alternative syntax for those
338
583
  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
584
 
340
585
  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.
586
+ > **Note:** When the `commit` method throws such a `SubscriptionException`, 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.
342
587
 
343
588
 
344
589
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event-nest/core",
3
- "version": "4.0.1",
3
+ "version": "5.0.0",
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.",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "type": "commonjs",
24
24
  "peerDependencies": {
25
- "@nestjs/common": "^^10.0.0 || ^11.0.0",
25
+ "@nestjs/common": "^10.0.0 || ^11.0.0",
26
26
  "@nestjs/core": "^10.0.0 || ^11.0.0",
27
27
  "reflect-metadata": "^0.1.12 || ^0.2.0",
28
28
  "rxjs": "^7.2.0",
@@ -32,6 +32,7 @@
32
32
  "class-transformer": "^0.5.1",
33
33
  "es-toolkit": "^1.32.0"
34
34
  },
35
+ "packageManager": "pnpm@10.29.2",
35
36
  "types": "./src/index.d.ts",
36
37
  "main": "./src/index.js"
37
38
  }
package/src/index.d.ts CHANGED
@@ -1,19 +1,35 @@
1
1
  export * from "./lib/aggregate-root/aggregate-root";
2
+ export * from "./lib/aggregate-root/aggregate-root-config";
2
3
  export * from "./lib/aggregate-root/aggregate-root-name";
3
4
  export * from "./lib/aggregate-root/apply-event.decorator";
5
+ export * from "./lib/aggregate-root/snapshot-aware";
4
6
  export * from "./lib/core-module-options";
5
7
  export * from "./lib/domain-event";
6
8
  export * from "./lib/domain-event-emitter";
7
9
  export * from "./lib/domain-event-subscription";
10
+ export * from "./lib/exceptions/aggregate-class-not-snapshot-aware-exception";
11
+ export * from "./lib/exceptions/aggregate-instance-not-snapshot-aware-exception";
8
12
  export * from "./lib/exceptions/event-concurrency-exception";
9
13
  export * from "./lib/exceptions/event-name-conflict-exception";
10
14
  export * from "./lib/exceptions/missing-aggregate-root-name-exception";
15
+ export * from "./lib/exceptions/snapshot-revision-mismatch-exception";
11
16
  export * from "./lib/exceptions/subscription-exception";
12
17
  export * from "./lib/exceptions/unknown-event-exception";
13
18
  export * from "./lib/on-domain-event";
14
19
  export * from "./lib/published-domain-event";
20
+ export * from "./lib/snapshot-strategy/all-of-snapshot-strategy";
21
+ export * from "./lib/snapshot-strategy/any-of-snapshot-strategy";
22
+ export * from "./lib/snapshot-strategy/for-aggregate-roots-strategy";
23
+ export * from "./lib/snapshot-strategy/for-count-snapshot-strategy";
24
+ export * from "./lib/snapshot-strategy/for-events-snapshot-strategy";
25
+ export * from "./lib/snapshot-strategy/no-snapshot-strategy";
26
+ export * from "./lib/snapshot-strategy/snapshot-strategy";
15
27
  export * from "./lib/storage/abstract-event-store";
16
28
  export * from "./lib/storage/event-store";
29
+ export * from "./lib/storage/snapshot/abstract-snapshot-store";
30
+ export * from "./lib/storage/snapshot/no-op-snapshot-store";
31
+ export * from "./lib/storage/snapshot/snapshot-store";
32
+ export * from "./lib/storage/snapshot/stored-snapshot";
17
33
  export * from "./lib/storage/stored-aggregate-root";
18
34
  export * from "./lib/storage/stored-event";
19
35
  export * from "./lib/utils/type-utils";
package/src/index.js CHANGED
@@ -2,21 +2,37 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./lib/aggregate-root/aggregate-root"), exports);
5
+ tslib_1.__exportStar(require("./lib/aggregate-root/aggregate-root-config"), exports);
5
6
  tslib_1.__exportStar(require("./lib/aggregate-root/aggregate-root-name"), exports);
6
7
  tslib_1.__exportStar(require("./lib/aggregate-root/apply-event.decorator"), exports);
8
+ tslib_1.__exportStar(require("./lib/aggregate-root/snapshot-aware"), exports);
7
9
  tslib_1.__exportStar(require("./lib/core-module-options"), exports);
8
10
  tslib_1.__exportStar(require("./lib/domain-event"), exports);
9
11
  tslib_1.__exportStar(require("./lib/domain-event-emitter"), exports);
10
12
  tslib_1.__exportStar(require("./lib/domain-event-subscription"), exports);
13
+ tslib_1.__exportStar(require("./lib/exceptions/aggregate-class-not-snapshot-aware-exception"), exports);
14
+ tslib_1.__exportStar(require("./lib/exceptions/aggregate-instance-not-snapshot-aware-exception"), exports);
11
15
  tslib_1.__exportStar(require("./lib/exceptions/event-concurrency-exception"), exports);
12
16
  tslib_1.__exportStar(require("./lib/exceptions/event-name-conflict-exception"), exports);
13
17
  tslib_1.__exportStar(require("./lib/exceptions/missing-aggregate-root-name-exception"), exports);
18
+ tslib_1.__exportStar(require("./lib/exceptions/snapshot-revision-mismatch-exception"), exports);
14
19
  tslib_1.__exportStar(require("./lib/exceptions/subscription-exception"), exports);
15
20
  tslib_1.__exportStar(require("./lib/exceptions/unknown-event-exception"), exports);
16
21
  tslib_1.__exportStar(require("./lib/on-domain-event"), exports);
17
22
  tslib_1.__exportStar(require("./lib/published-domain-event"), exports);
23
+ tslib_1.__exportStar(require("./lib/snapshot-strategy/all-of-snapshot-strategy"), exports);
24
+ tslib_1.__exportStar(require("./lib/snapshot-strategy/any-of-snapshot-strategy"), exports);
25
+ tslib_1.__exportStar(require("./lib/snapshot-strategy/for-aggregate-roots-strategy"), exports);
26
+ tslib_1.__exportStar(require("./lib/snapshot-strategy/for-count-snapshot-strategy"), exports);
27
+ tslib_1.__exportStar(require("./lib/snapshot-strategy/for-events-snapshot-strategy"), exports);
28
+ tslib_1.__exportStar(require("./lib/snapshot-strategy/no-snapshot-strategy"), exports);
29
+ tslib_1.__exportStar(require("./lib/snapshot-strategy/snapshot-strategy"), exports);
18
30
  tslib_1.__exportStar(require("./lib/storage/abstract-event-store"), exports);
19
31
  tslib_1.__exportStar(require("./lib/storage/event-store"), exports);
32
+ tslib_1.__exportStar(require("./lib/storage/snapshot/abstract-snapshot-store"), exports);
33
+ tslib_1.__exportStar(require("./lib/storage/snapshot/no-op-snapshot-store"), exports);
34
+ tslib_1.__exportStar(require("./lib/storage/snapshot/snapshot-store"), exports);
35
+ tslib_1.__exportStar(require("./lib/storage/snapshot/stored-snapshot"), exports);
20
36
  tslib_1.__exportStar(require("./lib/storage/stored-aggregate-root"), exports);
21
37
  tslib_1.__exportStar(require("./lib/storage/stored-event"), exports);
22
38
  tslib_1.__exportStar(require("./lib/utils/type-utils"), 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;AACvE,kFAAwD;AAExD,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,qFAA2D;AAC3D,mFAAyD;AACzD,qFAA2D;AAC3D,8EAAoD;AAEpD,oEAA0C;AAC1C,6DAAmC;AACnC,qEAA2C;AAC3C,0EAAgD;AAEhD,wGAA8E;AAC9E,2GAAiF;AACjF,uFAA6D;AAC7D,yFAA+D;AAC/D,iGAAuE;AACvE,gGAAsE;AACtE,kFAAwD;AACxD,mFAAyD;AAEzD,gEAAsC;AAEtC,uEAA6C;AAE7C,2FAAiE;AACjE,2FAAiE;AACjE,+FAAqE;AACrE,8FAAoE;AACpE,+FAAqE;AACrE,uFAA6D;AAC7D,oFAA0D;AAE1D,6EAAmD;AACnD,oEAA0C;AAC1C,yFAA+D;AAC/D,sFAA4D;AAC5D,gFAAsD;AACtD,iFAAuD;AACvD,8EAAoD;AACpD,qEAA2C;AAE3C,iEAAuC"}
@@ -0,0 +1,37 @@
1
+ import { AggregateRootClass, SnapshotAwareAggregateRoot } from "../storage/event-store";
2
+ export interface AggregateRootConfigParameters {
3
+ /**
4
+ * Will be saved with each event in the database and used during event retrieval to ensure
5
+ * the correct events are retrieved
6
+ */
7
+ name: string;
8
+ /**
9
+ * Optinal snapshot revision number that's used for snapshot optimization.
10
+ */
11
+ snapshotRevision?: number;
12
+ }
13
+ /**
14
+ * A decorator to configure an aggregate root class with a unique name and optional snapshot revision.
15
+ *
16
+ * @param params - Configuration parameters including the aggregate root name and optional snapshot revision
17
+ */
18
+ export declare const AggregateRootConfig: ({ name, snapshotRevision }: AggregateRootConfigParameters) => ClassDecorator;
19
+ /**
20
+ * Used to obtain the name attached to AggregateRoot class by getting it's metadata
21
+ * Works with both @see {@link AggregateRootConfig} and @see {@link AggregateRootName}
22
+ * Uses function overloading, because it's already known that SnapshotAwareAggregateRoot has name defined
23
+ *
24
+ * @param targetClass - the AggregateRoot class
25
+ * @returns snapshotRevision from provided {@link AggregateRootConfigParameters} or undefined if not present
26
+ */
27
+ export declare function getAggregateRootName(targetClass: AggregateRootClass<SnapshotAwareAggregateRoot>): string;
28
+ export declare function getAggregateRootName(targetClass: AggregateRootClass<unknown>): string | undefined;
29
+ /**
30
+ * Used to obtain the snapshotRevision number attached to AggregateRoot class by getting it's metadata
31
+ * Uses function overloading, because it's already known that SnapshotAwareAggregateRoot has snasphotRevision defined
32
+ *
33
+ * @param aggregateRootClass - the AggregateRootClass
34
+ * @returns snapshotRevision from provided {@link AggregateRootConfigParameters} or undefined if not present
35
+ */
36
+ export declare function getAggregateRootSnapshotRevision(targetClass: AggregateRootClass<SnapshotAwareAggregateRoot>): number;
37
+ export declare function getAggregateRootSnapshotRevision(targetClass: AggregateRootClass<unknown>): number | undefined;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AggregateRootConfig = void 0;
4
+ exports.getAggregateRootName = getAggregateRootName;
5
+ exports.getAggregateRootSnapshotRevision = getAggregateRootSnapshotRevision;
6
+ const metadata_keys_1 = require("../metadata-keys");
7
+ /**
8
+ * A decorator to configure an aggregate root class with a unique name and optional snapshot revision.
9
+ *
10
+ * @param params - Configuration parameters including the aggregate root name and optional snapshot revision
11
+ */
12
+ const AggregateRootConfig = ({ name, snapshotRevision }) => {
13
+ return (target) => {
14
+ Reflect.defineMetadata(metadata_keys_1.AGGREGATE_ROOT_NAME_KEY, { aggregateRootName: name }, target);
15
+ Reflect.defineMetadata(metadata_keys_1.AGGREGATE_ROOT_SNAPSHOT_REVISION_KEY, { aggregateRootSnapshotRevision: snapshotRevision }, target);
16
+ };
17
+ };
18
+ exports.AggregateRootConfig = AggregateRootConfig;
19
+ function getAggregateRootName(targetClass) {
20
+ return Reflect.getMetadata(metadata_keys_1.AGGREGATE_ROOT_NAME_KEY, targetClass)?.aggregateRootName;
21
+ }
22
+ function getAggregateRootSnapshotRevision(targetClass) {
23
+ return Reflect.getMetadata(metadata_keys_1.AGGREGATE_ROOT_SNAPSHOT_REVISION_KEY, targetClass)?.aggregateRootSnapshotRevision;
24
+ }
25
+ //# sourceMappingURL=aggregate-root-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate-root-config.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/aggregate-root/aggregate-root-config.ts"],"names":[],"mappings":";;;AAyCA,oDAEC;AAWD,4EAEC;AAxDD,oDAAiG;AAejG;;;;GAIG;AACI,MAAM,mBAAmB,GAAG,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAiC,EAAkB,EAAE;IAC7G,OAAO,CAAC,MAAc,EAAE,EAAE;QACtB,OAAO,CAAC,cAAc,CAAC,uCAAuB,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;QACrF,OAAO,CAAC,cAAc,CAClB,oDAAoC,EACpC,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,EACnD,MAAM,CACT,CAAC;IACN,CAAC,CAAC;AACN,CAAC,CAAC;AATW,QAAA,mBAAmB,uBAS9B;AAYF,SAAgB,oBAAoB,CAAC,WAAwC;IACzE,OAAO,OAAO,CAAC,WAAW,CAAC,uCAAuB,EAAE,WAAW,CAAC,EAAE,iBAAiB,CAAC;AACxF,CAAC;AAWD,SAAgB,gCAAgC,CAAC,WAAwC;IACrF,OAAO,OAAO,CAAC,WAAW,CAAC,oDAAoC,EAAE,WAAW,CAAC,EAAE,6BAA6B,CAAC;AACjH,CAAC"}
@@ -5,8 +5,8 @@ import "reflect-metadata";
5
5
  *
6
6
  * It will also be used during the retrieval process of the events to make sure that
7
7
  * the correct events are retrieved.
8
+ * @deprecated Use {@link AggregateRootConfig} decorator instead. It will be removed in version 7.x
8
9
  * @param name The name of the aggregate root
9
10
  * @constructor
10
11
  */
11
12
  export declare const AggregateRootName: (name: string) => ClassDecorator;
12
- export declare function getAggregateRootName(targetClass: Function): string | undefined;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AggregateRootName = void 0;
4
- exports.getAggregateRootName = getAggregateRootName;
5
4
  require("reflect-metadata");
6
5
  const metadata_keys_1 = require("../metadata-keys");
7
6
  /**
@@ -10,6 +9,7 @@ const metadata_keys_1 = require("../metadata-keys");
10
9
  *
11
10
  * It will also be used during the retrieval process of the events to make sure that
12
11
  * the correct events are retrieved.
12
+ * @deprecated Use {@link AggregateRootConfig} decorator instead. It will be removed in version 7.x
13
13
  * @param name The name of the aggregate root
14
14
  * @constructor
15
15
  */
@@ -19,8 +19,4 @@ const AggregateRootName = (name) => {
19
19
  };
20
20
  };
21
21
  exports.AggregateRootName = AggregateRootName;
22
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
23
- function getAggregateRootName(targetClass) {
24
- return Reflect.getMetadata(metadata_keys_1.AGGREGATE_ROOT_NAME_KEY, targetClass)?.aggregateRootName;
25
- }
26
22
  //# sourceMappingURL=aggregate-root-name.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"aggregate-root-name.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/aggregate-root/aggregate-root-name.ts"],"names":[],"mappings":";;;AAoBA,oDAEC;AAtBD,4BAA0B;AAE1B,oDAA2D;AAE3D;;;;;;;;GAQG;AACI,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAkB,EAAE;IAC9D,OAAO,CAAC,MAAc,EAAE,EAAE;QACtB,OAAO,CAAC,cAAc,CAAC,uCAAuB,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;IACzF,CAAC,CAAC;AACN,CAAC,CAAC;AAJW,QAAA,iBAAiB,qBAI5B;AAEF,sEAAsE;AACtE,SAAgB,oBAAoB,CAAC,WAAqB;IACtD,OAAO,OAAO,CAAC,WAAW,CAAC,uCAAuB,EAAE,WAAW,CAAC,EAAE,iBAAiB,CAAC;AACxF,CAAC"}
1
+ {"version":3,"file":"aggregate-root-name.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/aggregate-root/aggregate-root-name.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAE1B,oDAA2D;AAE3D;;;;;;;;;GASG;AACI,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAkB,EAAE;IAC9D,OAAO,CAAC,MAAc,EAAE,EAAE;QACtB,OAAO,CAAC,cAAc,CAAC,uCAAuB,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;IACzF,CAAC,CAAC;AACN,CAAC,CAAC;AAJW,QAAA,iBAAiB,qBAI5B"}
@@ -7,10 +7,6 @@ export declare abstract class AggregateRoot {
7
7
  private _uncommittedEvents;
8
8
  private _version;
9
9
  protected constructor(_id: string, logger?: Logger);
10
- /**
11
- * @deprecated Use {@link uncommittedEvents} instead. It will be removed in version 5.x
12
- */
13
- get appendedEvents(): Array<AggregateRootEvent<object>>;
14
10
  get id(): string;
15
11
  get logger(): Logger;
16
12
  /**
@@ -51,9 +47,11 @@ export declare abstract class AggregateRoot {
51
47
  * method will trigger all the matching {@link ApplyEvent} functions of the entity to populate the object based on
52
48
  * application logic.
53
49
  * @param events The events that will be sent to {@link ApplyEvent} functions
50
+ * @param snapshot Optional snapshot to apply before replaying events
51
+ * @throws AggregateInstanceNotSnapshotAwareException if a snapshot is provided but the aggregate is not snapshot-aware
54
52
  * @throws UnknownEventException if an event is not known
55
53
  */
56
- reconstitute(events: Array<StoredEvent>): void;
54
+ reconstitute<Snapshot = unknown>(events: Array<StoredEvent>, snapshot?: Snapshot): void;
57
55
  resolveVersion(events: Array<StoredEvent>): void;
58
56
  protected sortEvents(events: Array<StoredEvent>): Array<StoredEvent>;
59
57
  private splitEvents;
@@ -8,6 +8,7 @@ const subscription_exception_1 = require("../exceptions/subscription-exception")
8
8
  const unknown_event_exception_1 = require("../exceptions/unknown-event-exception");
9
9
  const unregistered_event_exception_1 = require("../exceptions/unregistered-event-exception");
10
10
  const reflection_1 = require("./reflection");
11
+ const snapshot_aware_1 = require("./snapshot-aware");
11
12
  class AggregateRoot {
12
13
  constructor(_id, logger) {
13
14
  this._id = _id;
@@ -15,12 +16,6 @@ class AggregateRoot {
15
16
  this._version = 0;
16
17
  this._logger = (0, es_toolkit_1.isNil)(logger) ? new common_1.Logger(AggregateRoot.name) : logger;
17
18
  }
18
- /**
19
- * @deprecated Use {@link uncommittedEvents} instead. It will be removed in version 5.x
20
- */
21
- get appendedEvents() {
22
- return [...this._uncommittedEvents];
23
- }
24
19
  get id() {
25
20
  return this._id;
26
21
  }
@@ -98,10 +93,16 @@ class AggregateRoot {
98
93
  * method will trigger all the matching {@link ApplyEvent} functions of the entity to populate the object based on
99
94
  * application logic.
100
95
  * @param events The events that will be sent to {@link ApplyEvent} functions
96
+ * @param snapshot Optional snapshot to apply before replaying events
97
+ * @throws AggregateInstanceNotSnapshotAwareException if a snapshot is provided but the aggregate is not snapshot-aware
101
98
  * @throws UnknownEventException if an event is not known
102
99
  */
103
- reconstitute(events) {
100
+ reconstitute(events, snapshot) {
104
101
  const startedAt = Date.now();
102
+ if (!(0, es_toolkit_1.isNil)(snapshot)) {
103
+ (0, snapshot_aware_1.assertIsSnapshotAwareAggregateRoot)(this);
104
+ this.applySnapshot(snapshot);
105
+ }
105
106
  if (events.length > 0) {
106
107
  const [unregistered, missingProcessor, known] = this.splitEvents(this.sortEvents(events));
107
108
  if (unregistered.length > 0 || missingProcessor.length > 0) {
@@ -124,12 +125,12 @@ class AggregateRoot {
124
125
  this._logger.debug(`Reconstitution of ${this.constructor.name} took ${duration}ms`);
125
126
  }
126
127
  resolveVersion(events) {
127
- const sorted = events.sort((event1, event2) => event1.aggregateRootVersion - event2.aggregateRootVersion);
128
+ const sorted = events.toSorted((event1, event2) => event1.aggregateRootVersion - event2.aggregateRootVersion);
128
129
  const lastElement = sorted.at(-1);
129
130
  this._version = (0, es_toolkit_1.isNil)(lastElement) ? 0 : lastElement.aggregateRootVersion;
130
131
  }
131
132
  sortEvents(events) {
132
- return events.sort((event1, event2) => event1.aggregateRootVersion - event2.aggregateRootVersion);
133
+ return events.toSorted((event1, event2) => event1.aggregateRootVersion - event2.aggregateRootVersion);
133
134
  }
134
135
  splitEvents(events) {
135
136
  const known = [];
@@ -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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"}
@@ -1,5 +1,5 @@
1
1
  import "reflect-metadata";
2
- import { Class } from "type-fest";
2
+ import { Class } from "../utils/type-utils";
3
3
  /**
4
4
  * A decorator to mark that a method is used to apply a specific event to an aggregate root.
5
5
  * When an aggregate root has to be reconstituted based on persisted events, these methods
@@ -1 +1 @@
1
- {"version":3,"file":"apply-event.decorator.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/aggregate-root/apply-event.decorator.ts"],"names":[],"mappings":";;AAgBA,gCAWC;AA3BD,4BAA0B;AAC1B,2CAAmC;AAGnC,+FAAyF;AACzF,oDAA6D;AAE7D;;;;;;;;GAQG;AACH,SAAgB,UAAU,CAAC,UAA0B;IACjD,IAAI,IAAA,kBAAK,EAAC,UAAU,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,0DAA0B,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO,CAAC,cAAc,EAAE,WAAW,EAAE,EAAE;QACnC,OAAO,CAAC,cAAc,CAClB,yCAAyB,GAAG,GAAG,GAAG,WAAW,CAAC,QAAQ,EAAE,EACxD,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,EAC5C,cAAc,CACjB,CAAC;IACN,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"apply-event.decorator.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/aggregate-root/apply-event.decorator.ts"],"names":[],"mappings":";;AAgBA,gCAWC;AA3BD,4BAA0B;AAC1B,2CAAmC;AAEnC,+FAAyF;AACzF,oDAA6D;AAG7D;;;;;;;;GAQG;AACH,SAAgB,UAAU,CAAC,UAA0B;IACjD,IAAI,IAAA,kBAAK,EAAC,UAAU,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,0DAA0B,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO,CAAC,cAAc,EAAE,WAAW,EAAE,EAAE;QACnC,OAAO,CAAC,cAAc,CAClB,yCAAyB,GAAG,GAAG,GAAG,WAAW,CAAC,QAAQ,EAAE,EACxD,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,EAC5C,cAAc,CACjB,CAAC;IACN,CAAC,CAAC;AACN,CAAC"}