@event-driven-io/emmett-mongodb 0.43.0-beta.2 → 0.43.0-beta.21
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/README.md +484 -0
- package/dist/index.cjs +514 -1097
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +144 -139
- package/dist/index.d.ts +144 -139
- package/dist/index.js +490 -1090
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,1121 +1,521 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var isErrorConstructor = (expect) => {
|
|
5
|
-
return typeof expect === "function" && expect.prototype && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
6
|
-
expect.prototype.constructor === expect;
|
|
7
|
-
};
|
|
8
|
-
var EmmettError = class _EmmettError extends Error {
|
|
9
|
-
static Codes = {
|
|
10
|
-
ValidationError: 400,
|
|
11
|
-
IllegalStateError: 403,
|
|
12
|
-
NotFoundError: 404,
|
|
13
|
-
ConcurrencyError: 412,
|
|
14
|
-
InternalServerError: 500
|
|
15
|
-
};
|
|
16
|
-
errorCode;
|
|
17
|
-
constructor(options) {
|
|
18
|
-
const errorCode = options && typeof options === "object" && "errorCode" in options ? options.errorCode : isNumber(options) ? options : _EmmettError.Codes.InternalServerError;
|
|
19
|
-
const message = options && typeof options === "object" && "message" in options ? options.message : isString(options) ? options : `Error with status code '${errorCode}' ocurred during Emmett processing`;
|
|
20
|
-
super(message);
|
|
21
|
-
this.errorCode = errorCode;
|
|
22
|
-
Object.setPrototypeOf(this, _EmmettError.prototype);
|
|
23
|
-
}
|
|
24
|
-
static mapFrom(error) {
|
|
25
|
-
if (_EmmettError.isInstanceOf(error)) {
|
|
26
|
-
return error;
|
|
27
|
-
}
|
|
28
|
-
return new _EmmettError({
|
|
29
|
-
errorCode: "errorCode" in error && error.errorCode !== void 0 && error.errorCode !== null ? error.errorCode : _EmmettError.Codes.InternalServerError,
|
|
30
|
-
message: error.message ?? "An unknown error occurred"
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
static isInstanceOf(error, errorCode) {
|
|
34
|
-
return typeof error === "object" && error !== null && "errorCode" in error && isNumber(error.errorCode) && (errorCode === void 0 || error.errorCode === errorCode);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
var ConcurrencyError = class _ConcurrencyError extends EmmettError {
|
|
38
|
-
constructor(current, expected, message) {
|
|
39
|
-
super({
|
|
40
|
-
errorCode: EmmettError.Codes.ConcurrencyError,
|
|
41
|
-
message: message ?? `Expected version ${expected.toString()} does not match current ${current?.toString()}`
|
|
42
|
-
});
|
|
43
|
-
this.current = current;
|
|
44
|
-
this.expected = expected;
|
|
45
|
-
Object.setPrototypeOf(this, _ConcurrencyError.prototype);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// ../emmett/dist/index.js
|
|
50
|
-
import { v4 as uuid4 } from "uuid";
|
|
51
|
-
import { v7 as uuid } from "uuid";
|
|
52
|
-
import retry from "async-retry";
|
|
53
|
-
import { v7 as uuid2 } from "uuid";
|
|
54
|
-
import { v4 as uuid3 } from "uuid";
|
|
55
|
-
import { v7 as uuid5 } from "uuid";
|
|
56
|
-
async function tryPublishMessagesAfterCommit(messages, options, context) {
|
|
57
|
-
if (options?.onAfterCommit === void 0) return false;
|
|
58
|
-
try {
|
|
59
|
-
await options?.onAfterCommit(messages, context);
|
|
60
|
-
return true;
|
|
61
|
-
} catch (error) {
|
|
62
|
-
console.error(`Error in on after commit hook`, error);
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
var emmettPrefix = "emt";
|
|
67
|
-
var defaultTag = `${emmettPrefix}:default`;
|
|
68
|
-
var unknownTag = `${emmettPrefix}:unknown`;
|
|
69
|
-
var STREAM_EXISTS = "STREAM_EXISTS";
|
|
70
|
-
var STREAM_DOES_NOT_EXIST = "STREAM_DOES_NOT_EXIST";
|
|
71
|
-
var NO_CONCURRENCY_CHECK = "NO_CONCURRENCY_CHECK";
|
|
72
|
-
var matchesExpectedVersion = (current, expected, defaultVersion) => {
|
|
73
|
-
if (expected === NO_CONCURRENCY_CHECK) return true;
|
|
74
|
-
if (expected == STREAM_DOES_NOT_EXIST) return current === defaultVersion;
|
|
75
|
-
if (expected == STREAM_EXISTS) return current !== defaultVersion;
|
|
76
|
-
return current === expected;
|
|
77
|
-
};
|
|
78
|
-
var assertExpectedVersionMatchesCurrent = (current, expected, defaultVersion) => {
|
|
79
|
-
expected ??= NO_CONCURRENCY_CHECK;
|
|
80
|
-
if (!matchesExpectedVersion(current, expected, defaultVersion))
|
|
81
|
-
throw new ExpectedVersionConflictError(current, expected);
|
|
82
|
-
};
|
|
83
|
-
var ExpectedVersionConflictError = class _ExpectedVersionConflictError extends ConcurrencyError {
|
|
84
|
-
constructor(current, expected) {
|
|
85
|
-
super(current?.toString(), expected?.toString());
|
|
86
|
-
Object.setPrototypeOf(this, _ExpectedVersionConflictError.prototype);
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
var hasDuplicates = (array, predicate) => {
|
|
90
|
-
const mapped = array.map(predicate);
|
|
91
|
-
const uniqueValues = new Set(mapped);
|
|
92
|
-
return uniqueValues.size < mapped.length;
|
|
93
|
-
};
|
|
94
|
-
var getDuplicates = (array, predicate) => {
|
|
95
|
-
const map = /* @__PURE__ */ new Map();
|
|
96
|
-
for (let i = 0; i < array.length; i++) {
|
|
97
|
-
const item = array[i];
|
|
98
|
-
const key = predicate(item, i, array);
|
|
99
|
-
if (!map.has(key)) {
|
|
100
|
-
map.set(key, []);
|
|
101
|
-
}
|
|
102
|
-
map.get(key).push(item);
|
|
103
|
-
}
|
|
104
|
-
return Array.from(map.values()).filter((group) => group.length > 1).flat();
|
|
105
|
-
};
|
|
106
|
-
var merge = (array, item, where, onExisting, onNotFound = () => void 0) => {
|
|
107
|
-
let wasFound = false;
|
|
108
|
-
const result = array.map((p) => {
|
|
109
|
-
if (!where(p)) return p;
|
|
110
|
-
wasFound = true;
|
|
111
|
-
return onExisting(p);
|
|
112
|
-
}).filter((p) => p !== void 0).map((p) => {
|
|
113
|
-
if (!p) throw Error("That should not happen");
|
|
114
|
-
return p;
|
|
115
|
-
});
|
|
116
|
-
if (!wasFound) {
|
|
117
|
-
const result2 = onNotFound();
|
|
118
|
-
if (result2 !== void 0) return [...array, item];
|
|
119
|
-
}
|
|
120
|
-
return result;
|
|
121
|
-
};
|
|
122
|
-
var arrayUtils = {
|
|
123
|
-
merge,
|
|
124
|
-
hasDuplicates,
|
|
125
|
-
getDuplicates
|
|
126
|
-
};
|
|
127
|
-
var isPrimitive = (value) => {
|
|
128
|
-
const type = typeof value;
|
|
129
|
-
return value === null || value === void 0 || type === "boolean" || type === "number" || type === "string" || type === "symbol" || type === "bigint";
|
|
130
|
-
};
|
|
131
|
-
var compareArrays = (left, right) => {
|
|
132
|
-
if (left.length !== right.length) {
|
|
133
|
-
return false;
|
|
134
|
-
}
|
|
135
|
-
for (let i = 0; i < left.length; i++) {
|
|
136
|
-
const leftHas = i in left;
|
|
137
|
-
const rightHas = i in right;
|
|
138
|
-
if (leftHas !== rightHas) return false;
|
|
139
|
-
if (leftHas && !deepEquals(left[i], right[i])) return false;
|
|
140
|
-
}
|
|
141
|
-
return true;
|
|
142
|
-
};
|
|
143
|
-
var compareDates = (left, right) => {
|
|
144
|
-
return left.getTime() === right.getTime();
|
|
145
|
-
};
|
|
146
|
-
var compareRegExps = (left, right) => {
|
|
147
|
-
return left.toString() === right.toString();
|
|
148
|
-
};
|
|
149
|
-
var compareErrors = (left, right) => {
|
|
150
|
-
if (left.message !== right.message || left.name !== right.name) {
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
|
-
const leftKeys = Object.keys(left);
|
|
154
|
-
const rightKeys = Object.keys(right);
|
|
155
|
-
if (leftKeys.length !== rightKeys.length) return false;
|
|
156
|
-
const rightKeySet = new Set(rightKeys);
|
|
157
|
-
for (const key of leftKeys) {
|
|
158
|
-
if (!rightKeySet.has(key)) return false;
|
|
159
|
-
if (!deepEquals(left[key], right[key])) return false;
|
|
160
|
-
}
|
|
161
|
-
return true;
|
|
162
|
-
};
|
|
163
|
-
var compareMaps = (left, right) => {
|
|
164
|
-
if (left.size !== right.size) return false;
|
|
165
|
-
for (const [key, value] of left) {
|
|
166
|
-
if (isPrimitive(key)) {
|
|
167
|
-
if (!right.has(key) || !deepEquals(value, right.get(key))) {
|
|
168
|
-
return false;
|
|
169
|
-
}
|
|
170
|
-
} else {
|
|
171
|
-
let found = false;
|
|
172
|
-
for (const [rightKey, rightValue] of right) {
|
|
173
|
-
if (deepEquals(key, rightKey) && deepEquals(value, rightValue)) {
|
|
174
|
-
found = true;
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (!found) return false;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return true;
|
|
182
|
-
};
|
|
183
|
-
var compareSets = (left, right) => {
|
|
184
|
-
if (left.size !== right.size) return false;
|
|
185
|
-
for (const leftItem of left) {
|
|
186
|
-
if (isPrimitive(leftItem)) {
|
|
187
|
-
if (!right.has(leftItem)) return false;
|
|
188
|
-
} else {
|
|
189
|
-
let found = false;
|
|
190
|
-
for (const rightItem of right) {
|
|
191
|
-
if (deepEquals(leftItem, rightItem)) {
|
|
192
|
-
found = true;
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
if (!found) return false;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return true;
|
|
200
|
-
};
|
|
201
|
-
var compareArrayBuffers = (left, right) => {
|
|
202
|
-
if (left.byteLength !== right.byteLength) return false;
|
|
203
|
-
const leftView = new Uint8Array(left);
|
|
204
|
-
const rightView = new Uint8Array(right);
|
|
205
|
-
for (let i = 0; i < leftView.length; i++) {
|
|
206
|
-
if (leftView[i] !== rightView[i]) return false;
|
|
207
|
-
}
|
|
208
|
-
return true;
|
|
209
|
-
};
|
|
210
|
-
var compareTypedArrays = (left, right) => {
|
|
211
|
-
if (left.constructor !== right.constructor) return false;
|
|
212
|
-
if (left.byteLength !== right.byteLength) return false;
|
|
213
|
-
const leftArray = new Uint8Array(
|
|
214
|
-
left.buffer,
|
|
215
|
-
left.byteOffset,
|
|
216
|
-
left.byteLength
|
|
217
|
-
);
|
|
218
|
-
const rightArray = new Uint8Array(
|
|
219
|
-
right.buffer,
|
|
220
|
-
right.byteOffset,
|
|
221
|
-
right.byteLength
|
|
222
|
-
);
|
|
223
|
-
for (let i = 0; i < leftArray.length; i++) {
|
|
224
|
-
if (leftArray[i] !== rightArray[i]) return false;
|
|
225
|
-
}
|
|
226
|
-
return true;
|
|
227
|
-
};
|
|
228
|
-
var compareObjects = (left, right) => {
|
|
229
|
-
const keys1 = Object.keys(left);
|
|
230
|
-
const keys2 = Object.keys(right);
|
|
231
|
-
if (keys1.length !== keys2.length) {
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
for (const key of keys1) {
|
|
235
|
-
if (left[key] instanceof Function && right[key] instanceof Function) {
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
const isEqual = deepEquals(left[key], right[key]);
|
|
239
|
-
if (!isEqual) {
|
|
240
|
-
return false;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
return true;
|
|
244
|
-
};
|
|
245
|
-
var getType = (value) => {
|
|
246
|
-
if (value === null) return "null";
|
|
247
|
-
if (value === void 0) return "undefined";
|
|
248
|
-
const primitiveType = typeof value;
|
|
249
|
-
if (primitiveType !== "object") return primitiveType;
|
|
250
|
-
if (Array.isArray(value)) return "array";
|
|
251
|
-
if (value instanceof Boolean) return "boxed-boolean";
|
|
252
|
-
if (value instanceof Number) return "boxed-number";
|
|
253
|
-
if (value instanceof String) return "boxed-string";
|
|
254
|
-
if (value instanceof Date) return "date";
|
|
255
|
-
if (value instanceof RegExp) return "regexp";
|
|
256
|
-
if (value instanceof Error) return "error";
|
|
257
|
-
if (value instanceof Map) return "map";
|
|
258
|
-
if (value instanceof Set) return "set";
|
|
259
|
-
if (value instanceof ArrayBuffer) return "arraybuffer";
|
|
260
|
-
if (value instanceof DataView) return "dataview";
|
|
261
|
-
if (value instanceof WeakMap) return "weakmap";
|
|
262
|
-
if (value instanceof WeakSet) return "weakset";
|
|
263
|
-
if (ArrayBuffer.isView(value)) return "typedarray";
|
|
264
|
-
return "object";
|
|
265
|
-
};
|
|
266
|
-
var deepEquals = (left, right) => {
|
|
267
|
-
if (left === right) return true;
|
|
268
|
-
if (isEquatable(left)) {
|
|
269
|
-
return left.equals(right);
|
|
270
|
-
}
|
|
271
|
-
const leftType = getType(left);
|
|
272
|
-
const rightType = getType(right);
|
|
273
|
-
if (leftType !== rightType) return false;
|
|
274
|
-
switch (leftType) {
|
|
275
|
-
case "null":
|
|
276
|
-
case "undefined":
|
|
277
|
-
case "boolean":
|
|
278
|
-
case "number":
|
|
279
|
-
case "bigint":
|
|
280
|
-
case "string":
|
|
281
|
-
case "symbol":
|
|
282
|
-
case "function":
|
|
283
|
-
return left === right;
|
|
284
|
-
case "array":
|
|
285
|
-
return compareArrays(left, right);
|
|
286
|
-
case "date":
|
|
287
|
-
return compareDates(left, right);
|
|
288
|
-
case "regexp":
|
|
289
|
-
return compareRegExps(left, right);
|
|
290
|
-
case "error":
|
|
291
|
-
return compareErrors(left, right);
|
|
292
|
-
case "map":
|
|
293
|
-
return compareMaps(
|
|
294
|
-
left,
|
|
295
|
-
right
|
|
296
|
-
);
|
|
297
|
-
case "set":
|
|
298
|
-
return compareSets(left, right);
|
|
299
|
-
case "arraybuffer":
|
|
300
|
-
return compareArrayBuffers(left, right);
|
|
301
|
-
case "dataview":
|
|
302
|
-
case "weakmap":
|
|
303
|
-
case "weakset":
|
|
304
|
-
return false;
|
|
305
|
-
case "typedarray":
|
|
306
|
-
return compareTypedArrays(
|
|
307
|
-
left,
|
|
308
|
-
right
|
|
309
|
-
);
|
|
310
|
-
case "boxed-boolean":
|
|
311
|
-
return left.valueOf() === right.valueOf();
|
|
312
|
-
case "boxed-number":
|
|
313
|
-
return left.valueOf() === right.valueOf();
|
|
314
|
-
case "boxed-string":
|
|
315
|
-
return left.valueOf() === right.valueOf();
|
|
316
|
-
case "object":
|
|
317
|
-
return compareObjects(
|
|
318
|
-
left,
|
|
319
|
-
right
|
|
320
|
-
);
|
|
321
|
-
default:
|
|
322
|
-
return false;
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
var isEquatable = (left) => {
|
|
326
|
-
return left !== null && left !== void 0 && typeof left === "object" && "equals" in left && typeof left["equals"] === "function";
|
|
327
|
-
};
|
|
328
|
-
var ParseError = class extends Error {
|
|
329
|
-
constructor(text) {
|
|
330
|
-
super(`Cannot parse! ${text}`);
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
var JSONParser = {
|
|
334
|
-
stringify: (value, options) => {
|
|
335
|
-
return JSON.stringify(
|
|
336
|
-
options?.map ? options.map(value) : value,
|
|
337
|
-
//TODO: Consider adding support to DateTime and adding specific format to mark that's a bigint
|
|
338
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
339
|
-
(_, v) => typeof v === "bigint" ? v.toString() : v
|
|
340
|
-
);
|
|
341
|
-
},
|
|
342
|
-
parse: (text, options) => {
|
|
343
|
-
const parsed = JSON.parse(text, options?.reviver);
|
|
344
|
-
if (options?.typeCheck && !options?.typeCheck(parsed))
|
|
345
|
-
throw new ParseError(text);
|
|
346
|
-
return options?.map ? options.map(parsed) : parsed;
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
var textEncoder = new TextEncoder();
|
|
350
|
-
var AssertionError = class extends Error {
|
|
351
|
-
constructor(message2) {
|
|
352
|
-
super(message2);
|
|
353
|
-
}
|
|
354
|
-
};
|
|
355
|
-
var isSubset = (superObj, subObj) => {
|
|
356
|
-
const sup = superObj;
|
|
357
|
-
const sub = subObj;
|
|
358
|
-
assertOk(sup);
|
|
359
|
-
assertOk(sub);
|
|
360
|
-
return Object.keys(sub).every((ele) => {
|
|
361
|
-
if (sub[ele] !== null && typeof sub[ele] == "object") {
|
|
362
|
-
return isSubset(sup[ele], sub[ele]);
|
|
363
|
-
}
|
|
364
|
-
return sub[ele] === sup[ele];
|
|
365
|
-
});
|
|
366
|
-
};
|
|
367
|
-
var assertFails = (message2) => {
|
|
368
|
-
throw new AssertionError(message2 ?? "That should not ever happened, right?");
|
|
369
|
-
};
|
|
370
|
-
function assertTrue(condition, message2) {
|
|
371
|
-
if (condition !== true)
|
|
372
|
-
throw new AssertionError(message2 ?? `Condition is false`);
|
|
373
|
-
}
|
|
374
|
-
function assertOk(obj, message2) {
|
|
375
|
-
if (!obj) throw new AssertionError(message2 ?? `Condition is not truthy`);
|
|
376
|
-
}
|
|
377
|
-
var downcastRecordedMessage = (recordedMessage, options) => {
|
|
378
|
-
if (!options?.downcast)
|
|
379
|
-
return recordedMessage;
|
|
380
|
-
const downcasted = options.downcast(
|
|
381
|
-
recordedMessage
|
|
382
|
-
);
|
|
383
|
-
return {
|
|
384
|
-
...recordedMessage,
|
|
385
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
386
|
-
data: downcasted.data,
|
|
387
|
-
..."metadata" in recordedMessage || "metadata" in downcasted ? {
|
|
388
|
-
metadata: {
|
|
389
|
-
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
390
|
-
..."metadata" in downcasted ? downcasted.metadata : {}
|
|
391
|
-
}
|
|
392
|
-
} : {}
|
|
393
|
-
};
|
|
394
|
-
};
|
|
395
|
-
var upcastRecordedMessage = (recordedMessage, options) => {
|
|
396
|
-
if (!options?.upcast)
|
|
397
|
-
return recordedMessage;
|
|
398
|
-
const upcasted = options.upcast(
|
|
399
|
-
recordedMessage
|
|
400
|
-
);
|
|
401
|
-
return {
|
|
402
|
-
...recordedMessage,
|
|
403
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
404
|
-
data: upcasted.data,
|
|
405
|
-
..."metadata" in recordedMessage || "metadata" in upcasted ? {
|
|
406
|
-
metadata: {
|
|
407
|
-
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
408
|
-
..."metadata" in upcasted ? upcasted.metadata : {}
|
|
409
|
-
}
|
|
410
|
-
} : {}
|
|
411
|
-
};
|
|
412
|
-
};
|
|
413
|
-
var upcastRecordedMessages = (recordedMessages, options) => {
|
|
414
|
-
if (!options?.upcast)
|
|
415
|
-
return recordedMessages;
|
|
416
|
-
return recordedMessages.map(
|
|
417
|
-
(recordedMessage) => upcastRecordedMessage(recordedMessage, options)
|
|
418
|
-
);
|
|
419
|
-
};
|
|
420
|
-
var filterProjections = (type, projections2) => {
|
|
421
|
-
const inlineProjections2 = projections2.filter((projection2) => projection2.type === type).map(({ projection: projection2 }) => projection2);
|
|
422
|
-
const duplicateRegistrations = arrayUtils.getDuplicates(
|
|
423
|
-
inlineProjections2,
|
|
424
|
-
(proj) => proj.name
|
|
425
|
-
);
|
|
426
|
-
if (duplicateRegistrations.length > 0) {
|
|
427
|
-
throw new EmmettError(`You cannot register multiple projections with the same name (or without the name).
|
|
428
|
-
Ensure that:
|
|
429
|
-
${JSONParser.stringify(duplicateRegistrations)}
|
|
430
|
-
have different names`);
|
|
431
|
-
}
|
|
432
|
-
return inlineProjections2;
|
|
433
|
-
};
|
|
434
|
-
var inlineProjections = (definitions) => definitions.map((definition) => ({
|
|
435
|
-
type: "inline",
|
|
436
|
-
projection: definition
|
|
437
|
-
}));
|
|
438
|
-
var asyncProjections = (definitions) => definitions.map((definition) => ({
|
|
439
|
-
type: "inline",
|
|
440
|
-
projection: definition
|
|
441
|
-
}));
|
|
442
|
-
var projections = {
|
|
443
|
-
inline: inlineProjections,
|
|
444
|
-
async: asyncProjections
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
// src/eventStore/mongoDBEventStore.ts
|
|
448
|
-
import {
|
|
449
|
-
MongoClient as MongoClient2
|
|
450
|
-
} from "mongodb";
|
|
451
|
-
import { v4 as uuid6 } from "uuid";
|
|
1
|
+
import { AssertionError, ExpectedVersionConflictError, assertExpectedVersionMatchesCurrent, assertFails, assertTrue, deepEquals, downcastRecordedMessage, filterProjections, isErrorConstructor, isSubset, noopScope, projections, tryPublishMessagesAfterCommit, upcastRecordedMessages } from "@event-driven-io/emmett";
|
|
2
|
+
import { MongoClient } from "mongodb";
|
|
3
|
+
import { v4 } from "uuid";
|
|
452
4
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
event
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
const metadata = {
|
|
493
|
-
streamId,
|
|
494
|
-
name: projectionName,
|
|
495
|
-
schemaVersion,
|
|
496
|
-
streamPosition: events[events.length - 1].metadata.streamPosition
|
|
497
|
-
};
|
|
498
|
-
updates.$set[`projections.${projectionName}`] = state !== null ? {
|
|
499
|
-
...state,
|
|
500
|
-
_metadata: metadata
|
|
501
|
-
} : null;
|
|
502
|
-
}
|
|
503
|
-
};
|
|
5
|
+
//#region src/eventStore/projections/mongoDBInlineProjection.ts
|
|
6
|
+
const MongoDBDefaultInlineProjectionName = "_default";
|
|
7
|
+
const handleInlineProjections = async (options) => {
|
|
8
|
+
const { events, projections: allProjections, updates: update, streamId, collection, readModels } = options;
|
|
9
|
+
const eventTypes = events.map((e) => e.type);
|
|
10
|
+
const projections = allProjections.filter((p) => p.canHandle.some((type) => eventTypes.includes(type)));
|
|
11
|
+
for (const projection of projections) await projection.handle(events, {
|
|
12
|
+
document: readModels[projection.name] ?? null,
|
|
13
|
+
streamId,
|
|
14
|
+
collection,
|
|
15
|
+
updates: update,
|
|
16
|
+
observabilityScope: noopScope
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
const mongoDBInlineProjection = (options) => {
|
|
20
|
+
const projectionName = options.name ?? "_default";
|
|
21
|
+
const schemaVersion = options.schemaVersion ?? 1;
|
|
22
|
+
return {
|
|
23
|
+
name: projectionName,
|
|
24
|
+
canHandle: options.canHandle,
|
|
25
|
+
handle: async (events, { document, updates, streamId }) => {
|
|
26
|
+
if (events.length === 0) return;
|
|
27
|
+
let state = "initialState" in options ? document ?? options.initialState() : document;
|
|
28
|
+
for (const event of events) state = await options.evolve(state, event);
|
|
29
|
+
const metadata = {
|
|
30
|
+
streamId,
|
|
31
|
+
name: projectionName,
|
|
32
|
+
schemaVersion,
|
|
33
|
+
streamPosition: events[events.length - 1].metadata.streamPosition
|
|
34
|
+
};
|
|
35
|
+
updates.$set[`projections.${projectionName}`] = state !== null ? {
|
|
36
|
+
...state,
|
|
37
|
+
_metadata: metadata
|
|
38
|
+
} : null;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
504
41
|
};
|
|
505
42
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
);
|
|
565
|
-
if (args[1]) {
|
|
566
|
-
assertTrue(
|
|
567
|
-
args[1](error),
|
|
568
|
-
`Error didn't match the error condition: ${error?.toString()}`
|
|
569
|
-
);
|
|
570
|
-
}
|
|
571
|
-
} finally {
|
|
572
|
-
await client.close();
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
};
|
|
576
|
-
}
|
|
577
|
-
};
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
};
|
|
582
|
-
var eventInStream = (streamName, event) => ({
|
|
583
|
-
streamName,
|
|
584
|
-
events: [event]
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/eventStore/projections/mongoDBInlineProjectionSpec.ts
|
|
45
|
+
const MongoDBInlineProjectionSpec = { for: (options) => {
|
|
46
|
+
{
|
|
47
|
+
const { projection, ...connectionOptions } = options;
|
|
48
|
+
return (givenStream) => {
|
|
49
|
+
const { streamName, events: givenEvents } = givenStream;
|
|
50
|
+
return { when: (events) => {
|
|
51
|
+
const allEvents = [...givenEvents, ...events];
|
|
52
|
+
const run = (eventStore) => eventStore.appendToStream(streamName, allEvents);
|
|
53
|
+
return {
|
|
54
|
+
then: async (assert, message) => {
|
|
55
|
+
const client = "client" in connectionOptions && connectionOptions.client ? connectionOptions.client : new MongoClient(connectionOptions.connectionString, connectionOptions.clientOptions);
|
|
56
|
+
const eventStore = getMongoDBEventStore({
|
|
57
|
+
projections: projections.inline([projection]),
|
|
58
|
+
client
|
|
59
|
+
});
|
|
60
|
+
try {
|
|
61
|
+
await run(eventStore);
|
|
62
|
+
const succeeded = await assert({
|
|
63
|
+
eventStore,
|
|
64
|
+
streamName
|
|
65
|
+
});
|
|
66
|
+
if (succeeded !== void 0 && succeeded === false) assertFails(message ?? "Projection specification didn't match the criteria");
|
|
67
|
+
} finally {
|
|
68
|
+
await client.close();
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
thenThrows: async (...args) => {
|
|
72
|
+
const client = "client" in connectionOptions && connectionOptions.client ? connectionOptions.client : new MongoClient(connectionOptions.connectionString, connectionOptions.clientOptions);
|
|
73
|
+
const eventStore = getMongoDBEventStore({
|
|
74
|
+
projections: projections.inline([projection]),
|
|
75
|
+
client
|
|
76
|
+
});
|
|
77
|
+
try {
|
|
78
|
+
await run(eventStore);
|
|
79
|
+
throw new AssertionError("Handler did not fail as expected");
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (error instanceof AssertionError) throw error;
|
|
82
|
+
if (args.length === 0) return;
|
|
83
|
+
if (!isErrorConstructor(args[0])) {
|
|
84
|
+
assertTrue(args[0](error), `Error didn't match the error condition: ${error?.toString()}`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
assertTrue(error instanceof args[0], `Caught error is not an instance of the expected type: ${error?.toString()}`);
|
|
88
|
+
if (args[1]) assertTrue(args[1](error), `Error didn't match the error condition: ${error?.toString()}`);
|
|
89
|
+
} finally {
|
|
90
|
+
await client.close();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
} };
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
} };
|
|
98
|
+
const eventInStream = (streamName, event) => ({
|
|
99
|
+
streamName,
|
|
100
|
+
events: [event]
|
|
585
101
|
});
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
102
|
+
const eventsInStream = (streamName, events) => ({
|
|
103
|
+
streamName,
|
|
104
|
+
events
|
|
589
105
|
});
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
})
|
|
106
|
+
const expectReadModelToMatch = async (options) => {
|
|
107
|
+
const { streamName, projectionName, eventStore, match } = options;
|
|
108
|
+
return match(await eventStore.projections.inline.findOne({
|
|
109
|
+
streamName,
|
|
110
|
+
projectionName
|
|
111
|
+
}));
|
|
112
|
+
};
|
|
113
|
+
const expectInlineReadModelWithName = (projectionName) => ({
|
|
114
|
+
toHave: (expected) => ({ eventStore, streamName }) => expectReadModelToMatch({
|
|
115
|
+
eventStore,
|
|
116
|
+
streamName,
|
|
117
|
+
projectionName,
|
|
118
|
+
match: (readModel) => isSubset(readModel, expected)
|
|
119
|
+
}),
|
|
120
|
+
toDeepEquals: (expected) => ({ eventStore, streamName }) => expectReadModelToMatch({
|
|
121
|
+
eventStore,
|
|
122
|
+
streamName,
|
|
123
|
+
projectionName,
|
|
124
|
+
match: (readModel) => deepEquals(readModel, expected)
|
|
125
|
+
}),
|
|
126
|
+
toMatch: (match) => ({ eventStore, streamName }) => expectReadModelToMatch({
|
|
127
|
+
eventStore,
|
|
128
|
+
streamName,
|
|
129
|
+
projectionName,
|
|
130
|
+
match
|
|
131
|
+
}),
|
|
132
|
+
notToExist: () => ({ eventStore, streamName }) => expectReadModelToMatch({
|
|
133
|
+
eventStore,
|
|
134
|
+
streamName,
|
|
135
|
+
projectionName,
|
|
136
|
+
match: (readModel) => readModel === null
|
|
137
|
+
}),
|
|
138
|
+
toExist: () => ({ eventStore, streamName }) => expectReadModelToMatch({
|
|
139
|
+
eventStore,
|
|
140
|
+
streamName,
|
|
141
|
+
projectionName,
|
|
142
|
+
match: (readModel) => readModel !== null
|
|
143
|
+
})
|
|
629
144
|
});
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
145
|
+
const expectInlineReadModel = {
|
|
146
|
+
withName: (name) => expectInlineReadModelWithName(name),
|
|
147
|
+
...expectInlineReadModelWithName(MongoDBDefaultInlineProjectionName)
|
|
633
148
|
};
|
|
634
149
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
};
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
};
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
collection = await collectionFor({
|
|
696
|
-
collectionName,
|
|
697
|
-
streamCollections,
|
|
698
|
-
db
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
|
-
return collection;
|
|
702
|
-
}
|
|
703
|
-
};
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region src/eventStore/storage/mongoDBEventStoreStorage.ts
|
|
152
|
+
const DefaultMongoDBEventStoreStorageOptions = "COLLECTION_PER_STREAM_TYPE";
|
|
153
|
+
const DefaultMongoDBEventStoreCollectionName = "emt:streams";
|
|
154
|
+
const resolveCollectionAndDatabase = (streamType, options) => {
|
|
155
|
+
if (options === "SINGLE_COLLECTION" || typeof options === "object" && options.type === "SINGLE_COLLECTION") return {
|
|
156
|
+
collectionName: typeof options === "object" ? options.collectionName ?? "emt:streams" : DefaultMongoDBEventStoreCollectionName,
|
|
157
|
+
databaseName: typeof options === "object" ? options.databaseName : void 0
|
|
158
|
+
};
|
|
159
|
+
else if (options === "COLLECTION_PER_STREAM_TYPE" || typeof options === "object" && options.type === "COLLECTION_PER_STREAM_TYPE") return {
|
|
160
|
+
collectionName: toStreamCollectionName(streamType),
|
|
161
|
+
databaseName: typeof options === "object" ? options.databaseName : void 0
|
|
162
|
+
};
|
|
163
|
+
else {
|
|
164
|
+
const result = options.collectionFor(streamType);
|
|
165
|
+
return {
|
|
166
|
+
collectionName: typeof result === "object" ? result.collectionName : result,
|
|
167
|
+
databaseName: typeof result === "object" ? result.databaseName ?? options.databaseName : options.databaseName
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const getDB = async (options) => {
|
|
172
|
+
const { dbsCache, databaseName, getConnectedClient } = options;
|
|
173
|
+
const safeDbName = databaseName ?? "___default";
|
|
174
|
+
let db = dbsCache.get(safeDbName);
|
|
175
|
+
if (!db) {
|
|
176
|
+
db = (await getConnectedClient()).db(databaseName);
|
|
177
|
+
dbsCache.set(safeDbName, db);
|
|
178
|
+
}
|
|
179
|
+
return db;
|
|
180
|
+
};
|
|
181
|
+
const collectionFor = async (options) => {
|
|
182
|
+
const { collectionName, db, streamCollections } = options;
|
|
183
|
+
let collection = streamCollections.get(collectionName);
|
|
184
|
+
if (!collection) {
|
|
185
|
+
collection = db.collection(collectionName);
|
|
186
|
+
await collection.createIndex({ streamName: 1 }, { unique: true });
|
|
187
|
+
streamCollections.set(collectionName, collection);
|
|
188
|
+
}
|
|
189
|
+
return collection;
|
|
190
|
+
};
|
|
191
|
+
const mongoDBEventStoreStorage = (options) => {
|
|
192
|
+
const dbsCache = /* @__PURE__ */ new Map();
|
|
193
|
+
const streamCollections = /* @__PURE__ */ new Map();
|
|
194
|
+
const storageOptions = options.storage ?? "COLLECTION_PER_STREAM_TYPE";
|
|
195
|
+
const { getConnectedClient } = options;
|
|
196
|
+
return { collectionFor: async (streamType) => {
|
|
197
|
+
const { collectionName, databaseName } = resolveCollectionAndDatabase(streamType, storageOptions);
|
|
198
|
+
let collection = streamCollections.get(collectionName);
|
|
199
|
+
if (!collection) collection = await collectionFor({
|
|
200
|
+
collectionName,
|
|
201
|
+
streamCollections,
|
|
202
|
+
db: await getDB({
|
|
203
|
+
databaseName,
|
|
204
|
+
dbsCache,
|
|
205
|
+
getConnectedClient
|
|
206
|
+
})
|
|
207
|
+
});
|
|
208
|
+
return collection;
|
|
209
|
+
} };
|
|
704
210
|
};
|
|
705
211
|
|
|
706
|
-
|
|
707
|
-
|
|
212
|
+
//#endregion
|
|
213
|
+
//#region src/eventStore/mongoDBEventStore.ts
|
|
214
|
+
const MongoDBEventStoreDefaultStreamVersion = 0n;
|
|
708
215
|
var MongoDBEventStoreImplementation = class {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
this.isClosed = true;
|
|
910
|
-
if (!this.shouldManageClientLifetime) return Promise.resolve();
|
|
911
|
-
return this.client.close();
|
|
912
|
-
};
|
|
913
|
-
async findOneInlineProjection(streamFilter, projectionQuery) {
|
|
914
|
-
const { projectionName, streamName, streamType } = parseSingleProjectionQueryStreamFilter(streamFilter);
|
|
915
|
-
const collection = await this.storage.collectionFor(streamType);
|
|
916
|
-
const query = prependMongoFilterWithProjectionPrefix(projectionQuery, `projections.${projectionName}`);
|
|
917
|
-
const filters = [
|
|
918
|
-
{ [`projections.${projectionName}`]: { $exists: true } }
|
|
919
|
-
];
|
|
920
|
-
if (query) {
|
|
921
|
-
filters.push(query);
|
|
922
|
-
}
|
|
923
|
-
if (streamName) {
|
|
924
|
-
filters.push({ streamName: { $eq: streamName } });
|
|
925
|
-
}
|
|
926
|
-
const result = await collection.findOne(
|
|
927
|
-
{ $and: filters },
|
|
928
|
-
{
|
|
929
|
-
useBigInt64: true,
|
|
930
|
-
projection: { [`projections.${projectionName}`]: 1 }
|
|
931
|
-
}
|
|
932
|
-
);
|
|
933
|
-
return result?.projections?.[projectionName] ?? null;
|
|
934
|
-
}
|
|
935
|
-
async findInlineProjection(streamFilter, projectionQuery, queryOptions) {
|
|
936
|
-
const parsedStreamFilter = parseMultiProjectionQueryStreamFilter(streamFilter);
|
|
937
|
-
if (!parsedStreamFilter) return [];
|
|
938
|
-
const { projectionName, streamNames, streamType } = parsedStreamFilter;
|
|
939
|
-
const collection = await this.storage.collectionFor(streamType);
|
|
940
|
-
const prefix = `projections.${projectionName}`;
|
|
941
|
-
const projectionFilter = prependMongoFilterWithProjectionPrefix(projectionQuery, prefix);
|
|
942
|
-
const filters = [
|
|
943
|
-
{ [`projections.${projectionName}`]: { $ne: null } }
|
|
944
|
-
];
|
|
945
|
-
if (projectionFilter) {
|
|
946
|
-
filters.push(projectionFilter);
|
|
947
|
-
}
|
|
948
|
-
if (streamNames) {
|
|
949
|
-
filters.push({ streamName: { $in: streamNames } });
|
|
950
|
-
}
|
|
951
|
-
let query = collection.find(
|
|
952
|
-
{ $and: filters },
|
|
953
|
-
{
|
|
954
|
-
useBigInt64: true,
|
|
955
|
-
projection: { [`projections.${projectionName}`]: 1 }
|
|
956
|
-
}
|
|
957
|
-
);
|
|
958
|
-
if (queryOptions?.skip) {
|
|
959
|
-
query = query.skip(queryOptions.skip);
|
|
960
|
-
}
|
|
961
|
-
if (queryOptions?.limit) {
|
|
962
|
-
query = query.limit(queryOptions.limit);
|
|
963
|
-
}
|
|
964
|
-
if (queryOptions?.sort) {
|
|
965
|
-
const sort = prependMongoFilterWithProjectionPrefix(
|
|
966
|
-
queryOptions.sort,
|
|
967
|
-
prefix
|
|
968
|
-
);
|
|
969
|
-
query = query.sort(sort);
|
|
970
|
-
}
|
|
971
|
-
const streams = await query.toArray();
|
|
972
|
-
return streams.map((s) => s.projections[projectionName]).filter((p) => !!p);
|
|
973
|
-
}
|
|
974
|
-
async countInlineProjection(streamFilter, projectionQuery) {
|
|
975
|
-
const parsedStreamFilter = parseMultiProjectionQueryStreamFilter(streamFilter);
|
|
976
|
-
if (!parsedStreamFilter) return 0;
|
|
977
|
-
const { projectionName, streamNames, streamType } = parsedStreamFilter;
|
|
978
|
-
const collection = await this.storage.collectionFor(streamType);
|
|
979
|
-
const prefix = `projections.${projectionName}`;
|
|
980
|
-
const projectionFilter = prependMongoFilterWithProjectionPrefix(projectionQuery, prefix);
|
|
981
|
-
const filters = [
|
|
982
|
-
{ [`projections.${projectionName}`]: { $ne: null } }
|
|
983
|
-
];
|
|
984
|
-
if (projectionFilter) {
|
|
985
|
-
filters.push(projectionFilter);
|
|
986
|
-
}
|
|
987
|
-
if (streamNames) {
|
|
988
|
-
filters.push({ streamName: { $in: streamNames } });
|
|
989
|
-
}
|
|
990
|
-
const total = await collection.countDocuments({ $and: filters });
|
|
991
|
-
return total;
|
|
992
|
-
}
|
|
993
|
-
getConnectedClient = async () => {
|
|
994
|
-
if (!this.isClosed) await this.client.connect();
|
|
995
|
-
return this.client;
|
|
996
|
-
};
|
|
216
|
+
client;
|
|
217
|
+
inlineProjections;
|
|
218
|
+
shouldManageClientLifetime;
|
|
219
|
+
isClosed = false;
|
|
220
|
+
storage;
|
|
221
|
+
options;
|
|
222
|
+
projections;
|
|
223
|
+
constructor(options) {
|
|
224
|
+
this.options = options;
|
|
225
|
+
this.client = "client" in options && options.client ? options.client : new MongoClient(options.connectionString, options.clientOptions);
|
|
226
|
+
this.shouldManageClientLifetime = !("client" in options);
|
|
227
|
+
this.storage = mongoDBEventStoreStorage({
|
|
228
|
+
storage: options.storage,
|
|
229
|
+
getConnectedClient: () => this.getConnectedClient()
|
|
230
|
+
});
|
|
231
|
+
this.inlineProjections = filterProjections("inline", options.projections ?? []);
|
|
232
|
+
this.projections = { inline: {
|
|
233
|
+
findOne: this.findOneInlineProjection.bind(this),
|
|
234
|
+
find: this.findInlineProjection.bind(this),
|
|
235
|
+
count: this.countInlineProjection.bind(this)
|
|
236
|
+
} };
|
|
237
|
+
}
|
|
238
|
+
async readStream(streamName, options) {
|
|
239
|
+
const { streamType } = fromStreamName(streamName);
|
|
240
|
+
const expectedStreamVersion = options?.expectedStreamVersion;
|
|
241
|
+
const collection = await this.storage.collectionFor(streamType);
|
|
242
|
+
const filter = { streamName: { $eq: streamName } };
|
|
243
|
+
const eventsSliceArr = [];
|
|
244
|
+
if (options && "from" in options) eventsSliceArr.push(Number(options.from));
|
|
245
|
+
else eventsSliceArr.push(0);
|
|
246
|
+
if (options && "to" in options) eventsSliceArr.push(Number(options.to));
|
|
247
|
+
const eventsSlice = eventsSliceArr.length > 1 ? { $slice: eventsSliceArr } : 1;
|
|
248
|
+
const stream = await collection.findOne(filter, {
|
|
249
|
+
useBigInt64: true,
|
|
250
|
+
projection: {
|
|
251
|
+
metadata: 1,
|
|
252
|
+
messages: eventsSlice
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
if (!stream) return {
|
|
256
|
+
events: [],
|
|
257
|
+
currentStreamVersion: MongoDBEventStoreDefaultStreamVersion,
|
|
258
|
+
streamExists: false
|
|
259
|
+
};
|
|
260
|
+
assertExpectedVersionMatchesCurrent(stream.metadata.streamPosition, expectedStreamVersion, MongoDBEventStoreDefaultStreamVersion);
|
|
261
|
+
return {
|
|
262
|
+
events: upcastRecordedMessages(stream.messages, options?.schema?.versioning),
|
|
263
|
+
currentStreamVersion: stream.metadata.streamPosition,
|
|
264
|
+
streamExists: true
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
async aggregateStream(streamName, options) {
|
|
268
|
+
const stream = await this.readStream(streamName, options?.read);
|
|
269
|
+
const { evolve, initialState } = options;
|
|
270
|
+
return {
|
|
271
|
+
state: stream.events.reduce(evolve, initialState()),
|
|
272
|
+
currentStreamVersion: stream.currentStreamVersion,
|
|
273
|
+
streamExists: stream.streamExists
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
async appendToStream(streamName, events, options) {
|
|
277
|
+
const { streamId, streamType } = fromStreamName(streamName);
|
|
278
|
+
const expectedStreamVersion = options?.expectedStreamVersion;
|
|
279
|
+
const collection = await this.storage.collectionFor(streamType);
|
|
280
|
+
const stream = await collection.findOne({ streamName: { $eq: streamName } }, {
|
|
281
|
+
useBigInt64: true,
|
|
282
|
+
projection: {
|
|
283
|
+
"metadata.streamPosition": 1,
|
|
284
|
+
projections: 1
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
const currentStreamVersion = stream?.metadata.streamPosition ?? 0n;
|
|
288
|
+
assertExpectedVersionMatchesCurrent(currentStreamVersion, expectedStreamVersion, MongoDBEventStoreDefaultStreamVersion);
|
|
289
|
+
let streamOffset = currentStreamVersion;
|
|
290
|
+
const eventsToAppend = events.map((event) => {
|
|
291
|
+
const metadata = {
|
|
292
|
+
messageId: v4(),
|
|
293
|
+
streamName,
|
|
294
|
+
streamPosition: ++streamOffset
|
|
295
|
+
};
|
|
296
|
+
return downcastRecordedMessage({
|
|
297
|
+
type: event.type,
|
|
298
|
+
data: event.data,
|
|
299
|
+
metadata: {
|
|
300
|
+
...metadata,
|
|
301
|
+
..."metadata" in event ? event.metadata ?? {} : {}
|
|
302
|
+
}
|
|
303
|
+
}, options?.schema?.versioning);
|
|
304
|
+
});
|
|
305
|
+
const now = /* @__PURE__ */ new Date();
|
|
306
|
+
const updates = {
|
|
307
|
+
$push: { messages: { $each: eventsToAppend } },
|
|
308
|
+
$set: {
|
|
309
|
+
"metadata.updatedAt": now,
|
|
310
|
+
"metadata.streamPosition": currentStreamVersion + BigInt(events.length)
|
|
311
|
+
},
|
|
312
|
+
$setOnInsert: {
|
|
313
|
+
streamName,
|
|
314
|
+
"metadata.streamId": streamId,
|
|
315
|
+
"metadata.streamType": streamType,
|
|
316
|
+
"metadata.createdAt": now
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
if (this.inlineProjections) await handleInlineProjections({
|
|
320
|
+
readModels: stream?.projections ?? {},
|
|
321
|
+
streamId,
|
|
322
|
+
events: eventsToAppend,
|
|
323
|
+
projections: this.inlineProjections,
|
|
324
|
+
collection,
|
|
325
|
+
updates,
|
|
326
|
+
client: {}
|
|
327
|
+
});
|
|
328
|
+
if (!await collection.updateOne({
|
|
329
|
+
streamName: { $eq: streamName },
|
|
330
|
+
"metadata.streamPosition": currentStreamVersion
|
|
331
|
+
}, updates, {
|
|
332
|
+
useBigInt64: true,
|
|
333
|
+
upsert: true
|
|
334
|
+
})) throw new ExpectedVersionConflictError(currentStreamVersion, options?.expectedStreamVersion ?? 0n);
|
|
335
|
+
await tryPublishMessagesAfterCommit(eventsToAppend, this.options.hooks);
|
|
336
|
+
return {
|
|
337
|
+
nextExpectedStreamVersion: currentStreamVersion + BigInt(eventsToAppend.length),
|
|
338
|
+
createdNewStream: currentStreamVersion === MongoDBEventStoreDefaultStreamVersion
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
async streamExists(streamName) {
|
|
342
|
+
const { streamType } = fromStreamName(streamName);
|
|
343
|
+
const collection = await this.storage.collectionFor(streamType);
|
|
344
|
+
const filter = { streamName: { $eq: streamName } };
|
|
345
|
+
const count = await collection.countDocuments(filter, {
|
|
346
|
+
useBigInt64: true,
|
|
347
|
+
limit: 1
|
|
348
|
+
});
|
|
349
|
+
return Boolean(count > 0);
|
|
350
|
+
}
|
|
351
|
+
collectionFor = async (streamType) => {
|
|
352
|
+
return this.storage.collectionFor(streamType);
|
|
353
|
+
};
|
|
354
|
+
/**
|
|
355
|
+
* Gracefully cleans up managed resources by the MongoDBEventStore.
|
|
356
|
+
* It closes MongoDB client created for the provided connection string
|
|
357
|
+
* through event store options.
|
|
358
|
+
*
|
|
359
|
+
* @memberof Closeable
|
|
360
|
+
*/
|
|
361
|
+
close = () => {
|
|
362
|
+
if (this.isClosed) return Promise.resolve();
|
|
363
|
+
this.isClosed = true;
|
|
364
|
+
if (!this.shouldManageClientLifetime) return Promise.resolve();
|
|
365
|
+
return this.client.close();
|
|
366
|
+
};
|
|
367
|
+
async findOneInlineProjection(streamFilter, projectionQuery) {
|
|
368
|
+
const { projectionName, streamName, streamType } = parseSingleProjectionQueryStreamFilter(streamFilter);
|
|
369
|
+
const collection = await this.storage.collectionFor(streamType);
|
|
370
|
+
const query = prependMongoFilterWithProjectionPrefix(projectionQuery, `projections.${projectionName}`);
|
|
371
|
+
const filters = [{ [`projections.${projectionName}`]: { $exists: true } }];
|
|
372
|
+
if (query) filters.push(query);
|
|
373
|
+
if (streamName) filters.push({ streamName: { $eq: streamName } });
|
|
374
|
+
return (await collection.findOne({ $and: filters }, {
|
|
375
|
+
useBigInt64: true,
|
|
376
|
+
projection: { [`projections.${projectionName}`]: 1 }
|
|
377
|
+
}))?.projections?.[projectionName] ?? null;
|
|
378
|
+
}
|
|
379
|
+
async findInlineProjection(streamFilter, projectionQuery, queryOptions) {
|
|
380
|
+
const parsedStreamFilter = parseMultiProjectionQueryStreamFilter(streamFilter);
|
|
381
|
+
if (!parsedStreamFilter) return [];
|
|
382
|
+
const { projectionName, streamNames, streamType } = parsedStreamFilter;
|
|
383
|
+
const collection = await this.storage.collectionFor(streamType);
|
|
384
|
+
const prefix = `projections.${projectionName}`;
|
|
385
|
+
const projectionFilter = prependMongoFilterWithProjectionPrefix(projectionQuery, prefix);
|
|
386
|
+
const filters = [{ [`projections.${projectionName}`]: { $ne: null } }];
|
|
387
|
+
if (projectionFilter) filters.push(projectionFilter);
|
|
388
|
+
if (streamNames) filters.push({ streamName: { $in: streamNames } });
|
|
389
|
+
let query = collection.find({ $and: filters }, {
|
|
390
|
+
useBigInt64: true,
|
|
391
|
+
projection: { [`projections.${projectionName}`]: 1 }
|
|
392
|
+
});
|
|
393
|
+
if (queryOptions?.skip) query = query.skip(queryOptions.skip);
|
|
394
|
+
if (queryOptions?.limit) query = query.limit(queryOptions.limit);
|
|
395
|
+
if (queryOptions?.sort) {
|
|
396
|
+
const sort = prependMongoFilterWithProjectionPrefix(queryOptions.sort, prefix);
|
|
397
|
+
query = query.sort(sort);
|
|
398
|
+
}
|
|
399
|
+
return (await query.toArray()).map((s) => s.projections[projectionName]).filter((p) => !!p);
|
|
400
|
+
}
|
|
401
|
+
async countInlineProjection(streamFilter, projectionQuery) {
|
|
402
|
+
const parsedStreamFilter = parseMultiProjectionQueryStreamFilter(streamFilter);
|
|
403
|
+
if (!parsedStreamFilter) return 0;
|
|
404
|
+
const { projectionName, streamNames, streamType } = parsedStreamFilter;
|
|
405
|
+
const collection = await this.storage.collectionFor(streamType);
|
|
406
|
+
const projectionFilter = prependMongoFilterWithProjectionPrefix(projectionQuery, `projections.${projectionName}`);
|
|
407
|
+
const filters = [{ [`projections.${projectionName}`]: { $ne: null } }];
|
|
408
|
+
if (projectionFilter) filters.push(projectionFilter);
|
|
409
|
+
if (streamNames) filters.push({ streamName: { $in: streamNames } });
|
|
410
|
+
return await collection.countDocuments({ $and: filters });
|
|
411
|
+
}
|
|
412
|
+
getConnectedClient = async () => {
|
|
413
|
+
if (!this.isClosed) await this.client.connect();
|
|
414
|
+
return this.client;
|
|
415
|
+
};
|
|
997
416
|
};
|
|
998
417
|
function parseSingleProjectionQueryStreamFilter(streamFilter) {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
};
|
|
1018
|
-
}
|
|
1019
|
-
return {
|
|
1020
|
-
projectionName,
|
|
1021
|
-
streamType: streamFilter.streamType
|
|
1022
|
-
};
|
|
418
|
+
const projectionName = streamFilter.projectionName ?? "_default";
|
|
419
|
+
if ("streamName" in streamFilter) {
|
|
420
|
+
const { streamType } = fromStreamName(streamFilter.streamName);
|
|
421
|
+
return {
|
|
422
|
+
projectionName,
|
|
423
|
+
streamName: streamFilter.streamName,
|
|
424
|
+
streamType
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
if (streamFilter.streamId) return {
|
|
428
|
+
projectionName,
|
|
429
|
+
streamName: toStreamName(streamFilter.streamType, streamFilter.streamId),
|
|
430
|
+
streamType: streamFilter.streamType
|
|
431
|
+
};
|
|
432
|
+
return {
|
|
433
|
+
projectionName,
|
|
434
|
+
streamType: streamFilter.streamType
|
|
435
|
+
};
|
|
1023
436
|
}
|
|
1024
437
|
function parseMultiProjectionQueryStreamFilter(streamFilter) {
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
}
|
|
1045
|
-
return {
|
|
1046
|
-
projectionName,
|
|
1047
|
-
streamType: streamFilter.streamType
|
|
1048
|
-
};
|
|
438
|
+
const projectionName = streamFilter.projectionName ?? "_default";
|
|
439
|
+
if ("streamNames" in streamFilter) {
|
|
440
|
+
if (streamFilter.streamNames.length == 0) return null;
|
|
441
|
+
const { streamType } = fromStreamName(streamFilter.streamNames[0]);
|
|
442
|
+
return {
|
|
443
|
+
projectionName,
|
|
444
|
+
streamNames: streamFilter.streamNames,
|
|
445
|
+
streamType
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
if (streamFilter.streamIds && streamFilter.streamIds.length > 0) return {
|
|
449
|
+
projectionName,
|
|
450
|
+
streamNames: streamFilter.streamIds.map((id) => toStreamName(streamFilter.streamType, id)),
|
|
451
|
+
streamType: streamFilter.streamType
|
|
452
|
+
};
|
|
453
|
+
return {
|
|
454
|
+
projectionName,
|
|
455
|
+
streamType: streamFilter.streamType
|
|
456
|
+
};
|
|
1049
457
|
}
|
|
458
|
+
/**
|
|
459
|
+
* Prepends `prefix` to all object keys that don't start with a '$'
|
|
460
|
+
*/
|
|
1050
461
|
function prependMongoFilterWithProjectionPrefix(obj, prefix) {
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
}
|
|
1066
|
-
obj[k] = prependMongoFilterWithProjectionPrefix(obj[k], prefix);
|
|
1067
|
-
}
|
|
1068
|
-
return obj;
|
|
462
|
+
if (typeof obj !== "object" || obj === null || obj === void 0) return obj;
|
|
463
|
+
if (Array.isArray(obj)) {
|
|
464
|
+
for (let i = 0; i < obj.length; i++) obj[i] = prependMongoFilterWithProjectionPrefix(obj[i], prefix);
|
|
465
|
+
return obj;
|
|
466
|
+
}
|
|
467
|
+
for (const key in obj) {
|
|
468
|
+
const k = addProjectionPrefixToMongoKey(key, prefix);
|
|
469
|
+
if (k !== key) {
|
|
470
|
+
obj[k] = obj[key];
|
|
471
|
+
delete obj[key];
|
|
472
|
+
}
|
|
473
|
+
obj[k] = prependMongoFilterWithProjectionPrefix(obj[k], prefix);
|
|
474
|
+
}
|
|
475
|
+
return obj;
|
|
1069
476
|
}
|
|
1070
477
|
function addProjectionPrefixToMongoKey(key, prefix) {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
}
|
|
1074
|
-
return `${prefix}${key.length > 0 ? "." : ""}${key}`;
|
|
478
|
+
if (key[0] === "$") return key;
|
|
479
|
+
return `${prefix}${key.length > 0 ? "." : ""}${key}`;
|
|
1075
480
|
}
|
|
1076
481
|
function getMongoDBEventStore(options) {
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
}
|
|
1081
|
-
return impl;
|
|
482
|
+
const impl = new MongoDBEventStoreImplementation(options);
|
|
483
|
+
if ("client" in options && "close" in impl) delete impl.close;
|
|
484
|
+
return impl;
|
|
1082
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Accepts a `streamType` (the type/category of the event stream) and an `streamId`
|
|
488
|
+
* (the individual entity/object or aggregate ID) and combines them to a singular
|
|
489
|
+
* `streamName` which can be used in `EventStore`.
|
|
490
|
+
*/
|
|
1083
491
|
function toStreamName(streamType, streamId) {
|
|
1084
|
-
|
|
492
|
+
return `${streamType}:${streamId}`;
|
|
1085
493
|
}
|
|
494
|
+
/**
|
|
495
|
+
* Accepts a fully formatted `streamName` and returns the broken down
|
|
496
|
+
* `streamType` and `streamId`.
|
|
497
|
+
*/
|
|
1086
498
|
function fromStreamName(streamName) {
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
499
|
+
const parts = streamName.split(":");
|
|
500
|
+
return {
|
|
501
|
+
streamType: parts[0],
|
|
502
|
+
streamId: parts[1]
|
|
503
|
+
};
|
|
1092
504
|
}
|
|
505
|
+
/**
|
|
506
|
+
* Accepts a `streamType` (the type/category of the event stream)
|
|
507
|
+
* and combines them to a `collectionName` which can be used in `EventStore`.
|
|
508
|
+
*/
|
|
1093
509
|
function toStreamCollectionName(streamType) {
|
|
1094
|
-
|
|
510
|
+
return `emt:${streamType}`;
|
|
1095
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* Accepts a fully formatted `streamCollectionName` and returns the parsed `streamType`.
|
|
514
|
+
*/
|
|
1096
515
|
function fromStreamCollectionName(streamCollectionName) {
|
|
1097
|
-
|
|
1098
|
-
return {
|
|
1099
|
-
streamType: parts[1]
|
|
1100
|
-
};
|
|
516
|
+
return { streamType: streamCollectionName.split(":")[1] };
|
|
1101
517
|
}
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
MongoDBDefaultInlineProjectionName,
|
|
1106
|
-
MongoDBEventStoreDefaultStreamVersion,
|
|
1107
|
-
MongoDBInlineProjectionSpec,
|
|
1108
|
-
eventInStream,
|
|
1109
|
-
eventsInStream,
|
|
1110
|
-
expectInlineReadModel,
|
|
1111
|
-
fromStreamCollectionName,
|
|
1112
|
-
fromStreamName,
|
|
1113
|
-
getMongoDBEventStore,
|
|
1114
|
-
handleInlineProjections,
|
|
1115
|
-
mongoDBEventStoreStorage,
|
|
1116
|
-
mongoDBInlineProjection,
|
|
1117
|
-
prependMongoFilterWithProjectionPrefix,
|
|
1118
|
-
toStreamCollectionName,
|
|
1119
|
-
toStreamName
|
|
1120
|
-
};
|
|
518
|
+
|
|
519
|
+
//#endregion
|
|
520
|
+
export { DefaultMongoDBEventStoreCollectionName, DefaultMongoDBEventStoreStorageOptions, MongoDBDefaultInlineProjectionName, MongoDBEventStoreDefaultStreamVersion, MongoDBInlineProjectionSpec, eventInStream, eventsInStream, expectInlineReadModel, fromStreamCollectionName, fromStreamName, getMongoDBEventStore, handleInlineProjections, mongoDBEventStoreStorage, mongoDBInlineProjection, prependMongoFilterWithProjectionPrefix, toStreamCollectionName, toStreamName };
|
|
1121
521
|
//# sourceMappingURL=index.js.map
|