@event-nest/mongodb 4.0.2 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event-nest/mongodb",
3
- "version": "4.0.2",
3
+ "version": "6.0.0",
4
4
  "license": "MIT",
5
5
  "description": "Event sourcing module for NestJS using MongoDB. It uses MongoDB collections and transactions to store events and object information",
6
6
  "author": "Nick Tsitlakidis",
@@ -9,7 +9,7 @@
9
9
  "url": "https://github.com/NickTsitlakidis/event-nest.git"
10
10
  },
11
11
  "engines": {
12
- "node": ">= 20"
12
+ "node": ">= 22"
13
13
  },
14
14
  "type": "commonjs",
15
15
  "keywords": [
@@ -24,15 +24,28 @@
24
24
  "peerDependencies": {
25
25
  "@nestjs/common": "^10.0.0 || ^11.0.0",
26
26
  "@nestjs/core": "^10.0.0 || ^11.0.0",
27
- "mongodb": "^6.15.0",
27
+ "mongodb": "^7.0.0",
28
28
  "reflect-metadata": "^0.1.12 || ^0.2.0",
29
29
  "rxjs": "^7.2.0"
30
30
  },
31
31
  "dependencies": {
32
32
  "class-transformer": "^0.5.1",
33
- "es-toolkit": "^1.32.0",
33
+ "es-toolkit": "^1.45.1",
34
34
  "tslib": "^2.3.0",
35
- "@event-nest/core": "4.0.2"
35
+ "@event-nest/core": "6.0.0"
36
+ },
37
+ "packageManager": "pnpm@10.33.4",
38
+ "pnpm": {
39
+ "onlyBuiltDependencies": [
40
+ "@nestjs/core",
41
+ "cpu-features",
42
+ "less",
43
+ "mongodb-memory-server",
44
+ "nx",
45
+ "protobufjs",
46
+ "ssh2",
47
+ "unrs-resolver"
48
+ ]
36
49
  },
37
50
  "types": "./src/index.d.ts",
38
51
  "main": "./src/index.js"
@@ -4,6 +4,7 @@ exports.ModuleProviders = void 0;
4
4
  const core_1 = require("@event-nest/core");
5
5
  const mongodb_1 = require("mongodb");
6
6
  const mongo_event_store_1 = require("./storage/mongo-event-store");
7
+ const mongo_snapshot_store_1 = require("./storage/mongo-snapshot-store");
7
8
  class ModuleProviders {
8
9
  static create(options) {
9
10
  return [
@@ -14,15 +15,56 @@ class ModuleProviders {
14
15
  }
15
16
  },
16
17
  {
17
- inject: [core_1.DomainEventEmitter],
18
+ provide: "EVENT_NEST_MONGO_CLIENT",
19
+ useFactory: () => {
20
+ return new mongodb_1.MongoClient(options.connectionUri, options.mongoClientConfiguration);
21
+ }
22
+ },
23
+ {
24
+ inject: ["EVENT_NEST_MONGO_CLIENT"],
25
+ provide: core_1.SNAPSHOT_STORE,
26
+ useFactory: (mongoClient) => {
27
+ const { snapshotCollection, snapshotStrategy } = options;
28
+ if (Boolean(snapshotStrategy) !== Boolean(snapshotCollection)) {
29
+ throw new Error("To use snapshots, both 'snapshotStrategy' and 'snapshotCollection' must be provided.");
30
+ }
31
+ if (!snapshotCollection || !snapshotStrategy) {
32
+ return new core_1.NoOpSnapshotStore();
33
+ }
34
+ return new mongo_snapshot_store_1.MongoSnapshotStore(snapshotStrategy, mongoClient, snapshotCollection);
35
+ }
36
+ },
37
+ {
38
+ inject: [core_1.DomainEventEmitter, "EVENT_NEST_MONGO_CLIENT", core_1.SNAPSHOT_STORE],
18
39
  provide: core_1.EVENT_STORE,
19
- useFactory: (eventEmitter) => {
20
- return new mongo_event_store_1.MongoEventStore(eventEmitter, new mongodb_1.MongoClient(options.connectionUri, options.mongoClientConfiguration), options.aggregatesCollection, options.eventsCollection);
40
+ useFactory: (eventEmitter, mongoClient, snapshotStore) => {
41
+ return new mongo_event_store_1.MongoEventStore(eventEmitter, snapshotStore, mongoClient, options.aggregatesCollection, options.eventsCollection);
21
42
  }
22
43
  }
23
44
  ];
24
45
  }
25
46
  static createAsync(options) {
47
+ const mongoClientProvider = {
48
+ inject: ["EVENT_NEST_OPTIONS"],
49
+ provide: "EVENT_NEST_MONGO_CLIENT",
50
+ useFactory: (options) => {
51
+ return new mongodb_1.MongoClient(options.connectionUri, options.mongoClientConfiguration);
52
+ }
53
+ };
54
+ const snapshotStoreProvider = {
55
+ inject: ["EVENT_NEST_MONGO_CLIENT", "EVENT_NEST_OPTIONS"],
56
+ provide: core_1.SNAPSHOT_STORE,
57
+ useFactory: (mongoClient, options) => {
58
+ const { snapshotCollection, snapshotStrategy } = options;
59
+ if (Boolean(snapshotStrategy) !== Boolean(snapshotCollection)) {
60
+ throw new Error("To use snapshots, both 'snapshotStrategy' and 'snapshotCollection' must be provided.");
61
+ }
62
+ if (!snapshotCollection || !snapshotStrategy) {
63
+ return new core_1.NoOpSnapshotStore();
64
+ }
65
+ return new mongo_snapshot_store_1.MongoSnapshotStore(snapshotStrategy, mongoClient, snapshotCollection);
66
+ }
67
+ };
26
68
  const optionsProvider = {
27
69
  inject: options.inject,
28
70
  provide: "EVENT_NEST_OPTIONS",
@@ -38,14 +80,13 @@ class ModuleProviders {
38
80
  }
39
81
  };
40
82
  const eventStoreProvider = {
41
- inject: ["EVENT_NEST_OPTIONS", core_1.DomainEventEmitter],
83
+ inject: ["EVENT_NEST_OPTIONS", core_1.DomainEventEmitter, "EVENT_NEST_MONGO_CLIENT", core_1.SNAPSHOT_STORE],
42
84
  provide: core_1.EVENT_STORE,
43
- useFactory: (options, eventBus) => {
44
- const mongoClient = new mongodb_1.MongoClient(options.connectionUri, options.mongoClientConfiguration);
45
- return new mongo_event_store_1.MongoEventStore(eventBus, mongoClient, options.aggregatesCollection, options.eventsCollection);
85
+ useFactory: (options, eventBus, mongoClient, snapshotStore) => {
86
+ return new mongo_event_store_1.MongoEventStore(eventBus, snapshotStore, mongoClient, options.aggregatesCollection, options.eventsCollection);
46
87
  }
47
88
  };
48
- return [optionsProvider, eventBusProvider, eventStoreProvider];
89
+ return [optionsProvider, eventBusProvider, eventStoreProvider, snapshotStoreProvider, mongoClientProvider];
49
90
  }
50
91
  }
51
92
  exports.ModuleProviders = ModuleProviders;
@@ -1 +1 @@
1
- {"version":3,"file":"module-providers.js","sourceRoot":"","sources":["../../../../../libs/mongodb/src/lib/module-providers.ts"],"names":[],"mappings":";;;AAAA,2CAAmE;AAEnE,qCAAsC;AAItC,mEAA8D;AAE9D,MAAa,eAAe;IACxB,MAAM,CAAC,MAAM,CAAC,OAA6B;QACvC,OAAO;YACH;gBACI,OAAO,EAAE,yBAAkB;gBAC3B,UAAU,EAAE,GAAG,EAAE;oBACb,OAAO,IAAI,yBAAkB,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;gBACnE,CAAC;aACJ;YACD;gBACI,MAAM,EAAE,CAAC,yBAAkB,CAAC;gBAC5B,OAAO,EAAE,kBAAW;gBACpB,UAAU,EAAE,CAAC,YAAgC,EAAE,EAAE;oBAC7C,OAAO,IAAI,mCAAe,CACtB,YAAY,EACZ,IAAI,qBAAW,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,wBAAwB,CAAC,EACxE,OAAO,CAAC,oBAAoB,EAC5B,OAAO,CAAC,gBAAgB,CAC3B,CAAC;gBACN,CAAC;aACJ;SACJ,CAAC;IACN,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,OAAkC;QACjD,MAAM,eAAe,GAAG;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,oBAAoB;YAC7B,UAAU,EAAE,KAAK,EAAE,GAAG,UAAqB,EAAE,EAAE;gBAC3C,OAAO,MAAM,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,CAAC;YACnD,CAAC;SACJ,CAAC;QAEF,MAAM,gBAAgB,GAAG;YACrB,MAAM,EAAE,CAAC,oBAAoB,CAAC;YAC9B,OAAO,EAAE,yBAAkB;YAC3B,UAAU,EAAE,CAAC,OAA6B,EAAE,EAAE;gBAC1C,OAAO,IAAI,yBAAkB,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;YACnE,CAAC;SACJ,CAAC;QAEF,MAAM,kBAAkB,GAAG;YACvB,MAAM,EAAE,CAAC,oBAAoB,EAAE,yBAAkB,CAAC;YAClD,OAAO,EAAE,kBAAW;YACpB,UAAU,EAAE,CAAC,OAA6B,EAAE,QAA4B,EAAE,EAAE;gBACxE,MAAM,WAAW,GAAG,IAAI,qBAAW,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,wBAAwB,CAAC,CAAC;gBAC7F,OAAO,IAAI,mCAAe,CACtB,QAAQ,EACR,WAAW,EACX,OAAO,CAAC,oBAAoB,EAC5B,OAAO,CAAC,gBAAgB,CAC3B,CAAC;YACN,CAAC;SACJ,CAAC;QAEF,OAAO,CAAC,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IACnE,CAAC;CACJ;AAzDD,0CAyDC"}
1
+ {"version":3,"file":"module-providers.js","sourceRoot":"","sources":["../../../../../libs/mongodb/src/lib/module-providers.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import { CoreModuleOptions } from "@event-nest/core";
1
+ import { CoreModuleOptions, SnapshotStrategy } from "@event-nest/core";
2
2
  import { MongoClientOptions } from "mongodb";
3
3
  export interface MongoDbModuleAsyncOptions {
4
4
  inject?: any[];
5
5
  useFactory: (...parameters: any[]) => MongodbModuleOptions | Promise<MongodbModuleOptions>;
6
6
  }
7
- export interface MongodbModuleOptions extends CoreModuleOptions {
7
+ export type MongodbModuleOptions = CoreModuleOptions & (SnapshotsDisabled | SnapshotsEnabled) & {
8
8
  /**
9
9
  * The name of the collection which will be used to store the aggregate root objects.
10
10
  */
@@ -23,4 +23,21 @@ export interface MongodbModuleOptions extends CoreModuleOptions {
23
23
  * be passed to the MongoClient constructor.
24
24
  */
25
25
  mongoClientConfiguration?: MongoClientOptions;
26
- }
26
+ };
27
+ type SnapshotsDisabled = {
28
+ snapshotCollection?: undefined;
29
+ snapshotStrategy?: undefined;
30
+ };
31
+ type SnapshotsEnabled = {
32
+ /**
33
+ * The name of the collection which will be used to store the aggregate snapshots
34
+ * You can omit this option if you do not want to use snapshots optimization.
35
+ */
36
+ snapshotCollection: string;
37
+ /**
38
+ * The snapshot strategy to use for determining when snapshots should be created for aggregate roots.
39
+ * See {@link SnapshotStrategy} for more information.
40
+ */
41
+ snapshotStrategy: SnapshotStrategy;
42
+ };
43
+ export {};
@@ -1,16 +1,21 @@
1
- import { AbstractEventStore, AggregateRoot, AggregateRootClass, DomainEventEmitter, StoredAggregateRoot, StoredEvent } from "@event-nest/core";
1
+ import { AbstractEventStore, AbstractSnapshotStore, AggregateRoot, AggregateRootClass, AggregateRootSnapshot, DomainEventEmitter, StoredAggregateRoot, StoredEvent } from "@event-nest/core";
2
2
  import { MongoClient } from "mongodb";
3
3
  export declare class MongoEventStore extends AbstractEventStore {
4
4
  private readonly _mongoClient;
5
5
  private readonly _aggregatesCollectionName;
6
6
  private readonly _eventsCollectionName;
7
7
  private readonly _logger;
8
- constructor(eventEmitter: DomainEventEmitter, _mongoClient: MongoClient, _aggregatesCollectionName: string, _eventsCollectionName: string);
8
+ constructor(eventEmitter: DomainEventEmitter, snapshotStore: AbstractSnapshotStore, _mongoClient: MongoClient, _aggregatesCollectionName: string, _eventsCollectionName: string);
9
9
  get aggregatesCollectionName(): string;
10
10
  get eventsCollectionName(): string;
11
11
  findAggregateRootVersion(id: string): Promise<number>;
12
12
  findByAggregateRootId<T extends AggregateRoot>(aggregateRootClass: AggregateRootClass<T>, id: string): Promise<Array<StoredEvent>>;
13
13
  findByAggregateRootIds<T extends AggregateRoot>(aggregateRootClass: AggregateRootClass<T>, ids: string[]): Promise<Record<string, Array<StoredEvent>>>;
14
+ findWithSnapshot<T extends AggregateRoot>(aggregateRootClass: AggregateRootClass<T>, id: string): Promise<{
15
+ events: Array<StoredEvent>;
16
+ snapshot?: AggregateRootSnapshot<T>;
17
+ }>;
14
18
  generateEntityId(): Promise<string>;
19
+ purgeAggregate(id: string): Promise<void>;
15
20
  save(events: Array<StoredEvent>, aggregate: StoredAggregateRoot): Promise<Array<StoredEvent>>;
16
21
  }
@@ -6,8 +6,8 @@ const common_1 = require("@nestjs/common");
6
6
  const es_toolkit_1 = require("es-toolkit");
7
7
  const mongodb_1 = require("mongodb");
8
8
  class MongoEventStore extends core_1.AbstractEventStore {
9
- constructor(eventEmitter, _mongoClient, _aggregatesCollectionName, _eventsCollectionName) {
10
- super(eventEmitter);
9
+ constructor(eventEmitter, snapshotStore, _mongoClient, _aggregatesCollectionName, _eventsCollectionName) {
10
+ super(eventEmitter, snapshotStore);
11
11
  this._mongoClient = _mongoClient;
12
12
  this._aggregatesCollectionName = _aggregatesCollectionName;
13
13
  this._eventsCollectionName = _eventsCollectionName;
@@ -70,66 +70,124 @@ class MongoEventStore extends core_1.AbstractEventStore {
70
70
  }
71
71
  return grouped;
72
72
  }
73
+ async findWithSnapshot(aggregateRootClass, id) {
74
+ const aggregateRootName = (0, core_1.getAggregateRootName)(aggregateRootClass);
75
+ if ((0, es_toolkit_1.isNil)(aggregateRootName)) {
76
+ this._logger.error(`Missing aggregate root name for class: ${aggregateRootClass.name}. Use the @AggregateRootName decorator.`);
77
+ throw new core_1.MissingAggregateRootNameException(aggregateRootClass.name);
78
+ }
79
+ const snapshotRevision = (0, core_1.getAggregateRootSnapshotRevision)(aggregateRootClass);
80
+ if ((0, es_toolkit_1.isNil)(snapshotRevision)) {
81
+ this._logger.error(`Missing snapshot revision for class: ${aggregateRootClass.name}. Use the @AggregateRootConfig decorator to set the snapshotRevision.`);
82
+ throw new core_1.AggregateClassNotSnapshotAwareException(aggregateRootName);
83
+ }
84
+ const snapshot = await this._snapshotStore.findLatestSnapshotByAggregateId(id);
85
+ if (!snapshot) {
86
+ return { events: await this.findByAggregateRootId(aggregateRootClass, id), snapshot: undefined };
87
+ }
88
+ if (snapshot.revision != snapshotRevision) {
89
+ throw new core_1.SnapshotRevisionMismatchException(aggregateRootName);
90
+ }
91
+ const documents = await this._mongoClient
92
+ .db()
93
+ .collection(this._eventsCollectionName)
94
+ .find({
95
+ aggregateRootId: id,
96
+ aggregateRootName: aggregateRootName,
97
+ aggregateRootVersion: { $gt: snapshot.aggregateRootVersion }
98
+ })
99
+ .toArray();
100
+ const events = documents.map((document) => {
101
+ return core_1.StoredEvent.fromStorage(document._id.toHexString(), document["aggregateRootId"], document["eventName"], document["createdAt"], document["aggregateRootVersion"], document["aggregateRootName"], document["payload"]);
102
+ });
103
+ return {
104
+ events,
105
+ snapshot: snapshot.payload
106
+ };
107
+ }
73
108
  generateEntityId() {
74
109
  return Promise.resolve(new mongodb_1.ObjectId().toHexString());
75
110
  }
111
+ async purgeAggregate(id) {
112
+ const startedAt = Date.now();
113
+ const session = this._mongoClient.startSession();
114
+ try {
115
+ await session.withTransaction(async () => {
116
+ await this._snapshotStore.deleteByAggregateId(id, session);
117
+ await this._mongoClient
118
+ .db()
119
+ .collection(this._eventsCollectionName)
120
+ .deleteMany({ aggregateRootId: id }, { session });
121
+ await this._mongoClient
122
+ .db()
123
+ .collection(this._aggregatesCollectionName)
124
+ .deleteOne({ _id: new mongodb_1.ObjectId(id) }, { session });
125
+ });
126
+ }
127
+ finally {
128
+ await session.endSession();
129
+ }
130
+ const duration = Date.now() - startedAt;
131
+ this._logger.debug(`Purging aggregate ${id} took ${duration}ms`);
132
+ }
76
133
  async save(events, aggregate) {
77
134
  const startedAt = Date.now();
78
135
  if (events.length === 0) {
79
136
  return events;
80
137
  }
81
- let incrementedVersion = 0;
82
- let finalAggregate;
83
- const foundAggregateDocument = await this._mongoClient
84
- .db()
85
- .collection(this._aggregatesCollectionName)
86
- .findOne({
87
- _id: new mongodb_1.ObjectId(aggregate.id)
88
- });
89
- let foundAggregate = (0, es_toolkit_1.isNil)(foundAggregateDocument)
90
- ? undefined
91
- : new core_1.StoredAggregateRoot(foundAggregateDocument._id.toHexString(), foundAggregateDocument["version"]);
138
+ const expectedVersion = aggregate.version;
139
+ let committedVersion = expectedVersion;
92
140
  const session = this._mongoClient.startSession();
93
- await session.withTransaction(async () => {
94
- if ((0, es_toolkit_1.isNil)(foundAggregate)) {
95
- aggregate.version = 0;
96
- this._logger.debug(`Aggregate ${aggregate.id} does not exist. Will save it`);
97
- const mapped = { _id: new mongodb_1.ObjectId(aggregate.id), version: aggregate.version };
98
- await this._mongoClient.db().collection(this._aggregatesCollectionName).insertOne(mapped);
99
- foundAggregate = aggregate;
100
- }
101
- if (aggregate.isOutdated(foundAggregate)) {
102
- this._logger.error(`Version conflict detected for aggregate ${aggregate.id}. Expected ${aggregate.version}. Stored ${foundAggregate.version}`);
103
- throw new core_1.EventConcurrencyException(aggregate.id, foundAggregate.version, aggregate.version);
104
- }
105
- for (const [index, storedEvent] of events.entries()) {
106
- incrementedVersion = aggregate.version + index + 1;
107
- storedEvent.aggregateRootVersion = incrementedVersion;
108
- }
109
- aggregate.version = incrementedVersion;
110
- finalAggregate = aggregate;
111
- this._logger.debug(`Saving ${events.length} events for aggregate ${aggregate.id}`);
112
- const mapped = events.map((event) => {
113
- return {
114
- _id: new mongodb_1.ObjectId(event.id),
115
- aggregateRootId: event.aggregateRootId,
116
- aggregateRootName: event.aggregateRootName,
117
- aggregateRootVersion: event.aggregateRootVersion,
118
- createdAt: event.createdAt,
119
- eventName: event.eventName,
120
- payload: event.payload
121
- };
122
- });
123
- await this._mongoClient.db().collection(this._eventsCollectionName).insertMany(mapped);
124
- await this._mongoClient
125
- .db()
126
- .collection(this._aggregatesCollectionName)
127
- .findOneAndUpdate({
128
- _id: new mongodb_1.ObjectId(finalAggregate.id)
129
- }, {
130
- $set: { version: finalAggregate.version }
141
+ try {
142
+ await session.withTransaction(async () => {
143
+ const foundAggregateDocument = await this._mongoClient
144
+ .db()
145
+ .collection(this._aggregatesCollectionName)
146
+ .findOne({ _id: new mongodb_1.ObjectId(aggregate.id) }, { session });
147
+ let currentVersion;
148
+ if ((0, es_toolkit_1.isNil)(foundAggregateDocument)) {
149
+ this._logger.debug(`Aggregate ${aggregate.id} does not exist. Will save it`);
150
+ await this._mongoClient
151
+ .db()
152
+ .collection(this._aggregatesCollectionName)
153
+ .insertOne({ _id: new mongodb_1.ObjectId(aggregate.id), version: 0 }, { session });
154
+ currentVersion = 0;
155
+ }
156
+ else {
157
+ currentVersion = foundAggregateDocument["version"];
158
+ if (expectedVersion !== currentVersion) {
159
+ this._logger.error(`Version conflict detected for aggregate ${aggregate.id}. Expected ${expectedVersion}. Stored ${currentVersion}`);
160
+ throw new core_1.EventConcurrencyException(aggregate.id, currentVersion, expectedVersion);
161
+ }
162
+ }
163
+ for (const [index, storedEvent] of events.entries()) {
164
+ storedEvent.aggregateRootVersion = currentVersion + index + 1;
165
+ }
166
+ const newVersion = currentVersion + events.length;
167
+ this._logger.debug(`Saving ${events.length} events for aggregate ${aggregate.id}`);
168
+ const mapped = events.map((event) => {
169
+ return {
170
+ _id: new mongodb_1.ObjectId(event.id),
171
+ aggregateRootId: event.aggregateRootId,
172
+ aggregateRootName: event.aggregateRootName,
173
+ aggregateRootVersion: event.aggregateRootVersion,
174
+ createdAt: event.createdAt,
175
+ eventName: event.eventName,
176
+ payload: event.payload
177
+ };
178
+ });
179
+ await this._mongoClient.db().collection(this._eventsCollectionName).insertMany(mapped, { session });
180
+ await this._mongoClient
181
+ .db()
182
+ .collection(this._aggregatesCollectionName)
183
+ .findOneAndUpdate({ _id: new mongodb_1.ObjectId(aggregate.id) }, { $set: { version: newVersion } }, { session });
184
+ committedVersion = newVersion;
131
185
  });
132
- });
186
+ }
187
+ finally {
188
+ await session.endSession();
189
+ }
190
+ aggregate.version = committedVersion;
133
191
  const duration = Date.now() - startedAt;
134
192
  this._logger.debug(`Saving events for aggregate ${aggregate.id} took ${duration}ms`);
135
193
  return events;
@@ -1 +1 @@
1
- {"version":3,"file":"mongo-event-store.js","sourceRoot":"","sources":["../../../../../../libs/mongodb/src/lib/storage/mongo-event-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mongo-event-store.js","sourceRoot":"","sources":["../../../../../../libs/mongodb/src/lib/storage/mongo-event-store.ts"],"names":[],"mappings":";;;AAAA,2CAe0B;AAC1B,2CAAwC;AACxC,2CAAmC;AACnC,qCAAgD;AAEhD,MAAa,eAAgB,SAAQ,yBAAkB;IAGnD,YACI,YAAgC,EAChC,aAAoC,EACnB,YAAyB,EACzB,yBAAiC,EACjC,qBAA6B;QAE9C,KAAK,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QAJlB,iBAAY,GAAZ,YAAY,CAAa;QACzB,8BAAyB,GAAzB,yBAAyB,CAAQ;QACjC,0BAAqB,GAArB,qBAAqB,CAAQ;QAG9C,IAAI,CAAC,OAAO,GAAG,IAAI,eAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,wBAAwB;QACxB,OAAO,IAAI,CAAC,yBAAyB,CAAC;IAC1C,CAAC;IAED,IAAI,oBAAoB;QACpB,OAAO,IAAI,CAAC,qBAAqB,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,EAAU;QACrC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY;aAChC,EAAE,EAAE;aACJ,UAAU,CAAC,IAAI,CAAC,yBAAyB,CAAC;aAC1C,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,kBAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAExC,IAAI,IAAA,kBAAK,EAAC,KAAK,CAAC,IAAI,IAAA,kBAAK,EAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,CAAC,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,qBAAqB,CACvB,kBAAyC,EACzC,EAAU;QAEV,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,iBAAiB,GAAG,IAAA,2BAAoB,EAAC,kBAAkB,CAAC,CAAC;QACnE,IAAI,IAAA,kBAAK,EAAC,iBAAiB,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,KAAK,CACd,0CAA0C,kBAAkB,CAAC,IAAI,yCAAyC,CAC7G,CAAC;YACF,MAAM,IAAI,wCAAiC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY;aACpC,EAAE,EAAE;aACJ,UAAU,CAAC,IAAI,CAAC,qBAAqB,CAAC;aACtC,IAAI,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,CAAC;aACnE,OAAO,EAAE,CAAC;QACf,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,SAAS,QAAQ,IAAI,CAAC,CAAC;QAC5E,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAC9B,OAAO,kBAAW,CAAC,WAAW,CAC1B,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,EAC1B,QAAQ,CAAC,iBAAiB,CAAC,EAC3B,QAAQ,CAAC,WAAW,CAAC,EACrB,QAAQ,CAAC,WAAW,CAAC,EACrB,QAAQ,CAAC,sBAAsB,CAAC,EAChC,QAAQ,CAAC,mBAAmB,CAAC,EAC7B,QAAQ,CAAC,SAAS,CAAC,CACtB,CAAC;YACN,CAAC,CAAC,CAAC;QACP,CAAC;QAED,OAAO,EAAE,CAAC;IACd,CAAC;IAED,KAAK,CAAC,sBAAsB,CACxB,kBAAyC,EACzC,GAAa;QAEb,MAAM,iBAAiB,GAAG,IAAA,2BAAoB,EAAC,kBAAkB,CAAC,CAAC;QACnE,IAAI,IAAA,kBAAK,EAAC,iBAAiB,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,KAAK,CACd,0CAA0C,kBAAkB,CAAC,IAAI,yCAAyC,CAC7G,CAAC;YACF,MAAM,IAAI,wCAAiC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY;aACpC,EAAE,EAAE;aACJ,UAAU,CAAC,IAAI,CAAC,qBAAqB,CAAC;aACtC,IAAI,CAAC,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,CAAC;aAC7E,OAAO,EAAE,CAAC;QAEf,MAAM,OAAO,GAAuC,EAAE,CAAC;QAEvD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAC/B,IAAI,IAAA,kBAAK,EAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,GAAG,EAAE,CAAC;YAC9C,CAAC;YACD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CACrC,kBAAW,CAAC,WAAW,CACnB,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,EAC1B,QAAQ,CAAC,iBAAiB,CAAC,EAC3B,QAAQ,CAAC,WAAW,CAAC,EACrB,QAAQ,CAAC,WAAW,CAAC,EACrB,QAAQ,CAAC,sBAAsB,CAAC,EAChC,QAAQ,CAAC,mBAAmB,CAAC,EAC7B,QAAQ,CAAC,SAAS,CAAC,CACtB,CACJ,CAAC;QACN,CAAC;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAClB,kBAAyC,EACzC,EAAU;QAEV,MAAM,iBAAiB,GAAG,IAAA,2BAAoB,EAAC,kBAAkB,CAAC,CAAC;QACnE,IAAI,IAAA,kBAAK,EAAC,iBAAiB,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,KAAK,CACd,0CAA0C,kBAAkB,CAAC,IAAI,yCAAyC,CAC7G,CAAC;YACF,MAAM,IAAI,wCAAiC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAA,uCAAgC,EAAC,kBAAkB,CAAC,CAAC;QAC9E,IAAI,IAAA,kBAAK,EAAC,gBAAgB,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,CAAC,KAAK,CACd,wCAAwC,kBAAkB,CAAC,IAAI,uEAAuE,CACzI,CAAC;YACF,MAAM,IAAI,8CAAuC,CAAC,iBAAiB,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,+BAA+B,CAAC,EAAE,CAAC,CAAC;QAC/E,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QACrG,CAAC;QAED,IAAI,QAAQ,CAAC,QAAQ,IAAI,gBAAgB,EAAE,CAAC;YACxC,MAAM,IAAI,wCAAiC,CAAC,iBAAiB,CAAC,CAAC;QACnE,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY;aACpC,EAAE,EAAE;aACJ,UAAU,CAAC,IAAI,CAAC,qBAAqB,CAAC;aACtC,IAAI,CAAC;YACF,eAAe,EAAE,EAAE;YACnB,iBAAiB,EAAE,iBAAiB;YACpC,oBAAoB,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,oBAAoB,EAAE;SAC/D,CAAC;aACD,OAAO,EAAE,CAAC;QAEf,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YACtC,OAAO,kBAAW,CAAC,WAAW,CAC1B,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,EAC1B,QAAQ,CAAC,iBAAiB,CAAC,EAC3B,QAAQ,CAAC,WAAW,CAAC,EACrB,QAAQ,CAAC,WAAW,CAAC,EACrB,QAAQ,CAAC,sBAAsB,CAAC,EAChC,QAAQ,CAAC,mBAAmB,CAAC,EAC7B,QAAQ,CAAC,SAAS,CAAC,CACtB,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,OAAO;YACH,MAAM;YACN,QAAQ,EAAE,QAAQ,CAAC,OAAmC;SACzD,CAAC;IACN,CAAC;IAED,gBAAgB;QACZ,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,kBAAQ,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,EAAU;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QACjD,IAAI,CAAC;YACD,MAAM,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE;gBACrC,MAAM,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC3D,MAAM,IAAI,CAAC,YAAY;qBAClB,EAAE,EAAE;qBACJ,UAAU,CAAC,IAAI,CAAC,qBAAqB,CAAC;qBACtC,UAAU,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;gBACtD,MAAM,IAAI,CAAC,YAAY;qBAClB,EAAE,EAAE;qBACJ,UAAU,CAAC,IAAI,CAAC,yBAAyB,CAAC;qBAC1C,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,kBAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;QACP,CAAC;gBAAS,CAAC;YACP,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAC/B,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,SAAS,QAAQ,IAAI,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAA0B,EAAE,SAA8B;QACjE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAC;QAC1C,IAAI,gBAAgB,GAAG,eAAe,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QACjD,IAAI,CAAC;YACD,MAAM,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE;gBACrC,MAAM,sBAAsB,GAAG,MAAM,IAAI,CAAC,YAAY;qBACjD,EAAE,EAAE;qBACJ,UAAU,CAAC,IAAI,CAAC,yBAAyB,CAAC;qBAC1C,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,kBAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;gBAE/D,IAAI,cAAsB,CAAC;gBAC3B,IAAI,IAAA,kBAAK,EAAC,sBAAsB,CAAC,EAAE,CAAC;oBAChC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,SAAS,CAAC,EAAE,+BAA+B,CAAC,CAAC;oBAC7E,MAAM,IAAI,CAAC,YAAY;yBAClB,EAAE,EAAE;yBACJ,UAAU,CAAC,IAAI,CAAC,yBAAyB,CAAC;yBAC1C,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,kBAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC7E,cAAc,GAAG,CAAC,CAAC;gBACvB,CAAC;qBAAM,CAAC;oBACJ,cAAc,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;oBACnD,IAAI,eAAe,KAAK,cAAc,EAAE,CAAC;wBACrC,IAAI,CAAC,OAAO,CAAC,KAAK,CACd,2CAA2C,SAAS,CAAC,EAAE,cAAc,eAAe,YAAY,cAAc,EAAE,CACnH,CAAC;wBACF,MAAM,IAAI,gCAAyB,CAAC,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;oBACvF,CAAC;gBACL,CAAC;gBAED,KAAK,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;oBAClD,WAAW,CAAC,oBAAoB,GAAG,cAAc,GAAG,KAAK,GAAG,CAAC,CAAC;gBAClE,CAAC;gBACD,MAAM,UAAU,GAAG,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;gBAElD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,MAAM,yBAAyB,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;gBAEnF,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;oBAChC,OAAO;wBACH,GAAG,EAAE,IAAI,kBAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC3B,eAAe,EAAE,KAAK,CAAC,eAAe;wBACtC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;wBAC1C,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;wBAChD,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;wBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;qBACzB,CAAC;gBACN,CAAC,CAAC,CAAC;gBAEH,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;gBACpG,MAAM,IAAI,CAAC,YAAY;qBAClB,EAAE,EAAE;qBACJ,UAAU,CAAC,IAAI,CAAC,yBAAyB,CAAC;qBAC1C,gBAAgB,CACb,EAAE,GAAG,EAAE,IAAI,kBAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,EACnC,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EACjC,EAAE,OAAO,EAAE,CACd,CAAC;gBAEN,gBAAgB,GAAG,UAAU,CAAC;YAClC,CAAC,CAAC,CAAC;QACP,CAAC;gBAAS,CAAC;YACP,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAC/B,CAAC;QACD,SAAS,CAAC,OAAO,GAAG,gBAAgB,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,+BAA+B,SAAS,CAAC,EAAE,SAAS,QAAQ,IAAI,CAAC,CAAC;QACrF,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AA7QD,0CA6QC"}
@@ -0,0 +1,12 @@
1
+ import { AbstractSnapshotStore, SnapshotStrategy, StoredSnapshot } from "@event-nest/core";
2
+ import { ClientSession, MongoClient } from "mongodb";
3
+ export declare class MongoSnapshotStore extends AbstractSnapshotStore {
4
+ private readonly _mongoClient;
5
+ private readonly _snapshotsCollectionName;
6
+ private readonly _logger;
7
+ constructor(snapshotStrategy: SnapshotStrategy, _mongoClient: MongoClient, _snapshotsCollectionName: string);
8
+ deleteByAggregateId(id: string, session?: ClientSession): Promise<void>;
9
+ findLatestSnapshotByAggregateId(id: string): Promise<StoredSnapshot | undefined>;
10
+ generateEntityId(): Promise<string>;
11
+ save(snapshot: StoredSnapshot): Promise<StoredSnapshot | undefined>;
12
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var MongoSnapshotStore_1;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.MongoSnapshotStore = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const core_1 = require("@event-nest/core");
7
+ const common_1 = require("@nestjs/common");
8
+ const es_toolkit_1 = require("es-toolkit");
9
+ const mongodb_1 = require("mongodb");
10
+ let MongoSnapshotStore = MongoSnapshotStore_1 = class MongoSnapshotStore extends core_1.AbstractSnapshotStore {
11
+ constructor(snapshotStrategy, _mongoClient, _snapshotsCollectionName) {
12
+ super(snapshotStrategy);
13
+ this._mongoClient = _mongoClient;
14
+ this._snapshotsCollectionName = _snapshotsCollectionName;
15
+ this._logger = new common_1.Logger(MongoSnapshotStore_1.name);
16
+ }
17
+ async deleteByAggregateId(id, session) {
18
+ const startedAt = Date.now();
19
+ await this._mongoClient
20
+ .db()
21
+ .collection(this._snapshotsCollectionName)
22
+ .deleteMany({ aggregateRootId: id }, { session });
23
+ const duration = Date.now() - startedAt;
24
+ this._logger.debug(`Deleting snapshots for aggregate ${id} took ${duration}ms`);
25
+ }
26
+ async findLatestSnapshotByAggregateId(id) {
27
+ const startedAt = Date.now();
28
+ const document = await this._mongoClient
29
+ .db()
30
+ .collection(this._snapshotsCollectionName)
31
+ .findOne({ aggregateRootId: id }, { sort: { aggregateRootVersion: -1 } });
32
+ if ((0, es_toolkit_1.isNil)(document)) {
33
+ return undefined;
34
+ }
35
+ const duration = Date.now() - startedAt;
36
+ this._logger.debug(`Finding latest snapshot for aggregate ${id} took ${duration}ms`);
37
+ return core_1.StoredSnapshot.create(document._id.toHexString(), document["aggregateRootVersion"], document["revision"], document["payload"], document["aggregateRootId"]);
38
+ }
39
+ generateEntityId() {
40
+ return Promise.resolve(new mongodb_1.ObjectId().toHexString());
41
+ }
42
+ async save(snapshot) {
43
+ const snapshotDocument = {
44
+ _id: new mongodb_1.ObjectId(snapshot.id),
45
+ aggregateRootId: snapshot.aggregateRootId,
46
+ aggregateRootVersion: snapshot.aggregateRootVersion,
47
+ payload: snapshot.payload,
48
+ revision: snapshot.revision
49
+ };
50
+ const startedAt = Date.now();
51
+ await this._mongoClient
52
+ .db()
53
+ .collection(this._snapshotsCollectionName)
54
+ .insertOne(snapshotDocument);
55
+ const duration = Date.now() - startedAt;
56
+ this._logger.debug(`Saving snapshot for aggregate ${snapshot.id} took ${duration}ms`);
57
+ return snapshot;
58
+ }
59
+ };
60
+ exports.MongoSnapshotStore = MongoSnapshotStore;
61
+ exports.MongoSnapshotStore = MongoSnapshotStore = MongoSnapshotStore_1 = tslib_1.__decorate([
62
+ (0, common_1.Injectable)(),
63
+ tslib_1.__metadata("design:paramtypes", [core_1.SnapshotStrategy,
64
+ mongodb_1.MongoClient, String])
65
+ ], MongoSnapshotStore);
66
+ //# sourceMappingURL=mongo-snapshot-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo-snapshot-store.js","sourceRoot":"","sources":["../../../../../../libs/mongodb/src/lib/storage/mongo-snapshot-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { ObjectId } from "mongodb";
2
+ export interface SnapshotDocument {
3
+ _id: ObjectId;
4
+ aggregateRootId: string;
5
+ aggregateRootVersion: number;
6
+ payload: unknown;
7
+ revision: number;
8
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=snapshot-document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-document.js","sourceRoot":"","sources":["../../../../../../libs/mongodb/src/lib/storage/snapshot-document.ts"],"names":[],"mappings":""}