@event-driven-io/emmett-sqlite 0.43.0-beta.13 → 0.43.0-beta.14
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/dist/cli.cjs +0 -1
- package/dist/cli.d.cts +1 -2
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +1 -1
- package/dist/cloudflare.cjs +16 -16
- package/dist/cloudflare.cjs.map +1 -1
- package/dist/cloudflare.d.cts +9 -10
- package/dist/cloudflare.d.ts +9 -10
- package/dist/cloudflare.js +18 -19
- package/dist/cloudflare.js.map +1 -1
- package/dist/index-2i8q-ZKl.d.ts +415 -0
- package/dist/index-CqxXzmd1.d.cts +415 -0
- package/dist/index.cjs +1164 -2613
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -243
- package/dist/index.d.ts +2 -243
- package/dist/index.js +1090 -2586
- package/dist/index.js.map +1 -1
- package/dist/sqlite3.cjs +14 -14
- package/dist/sqlite3.cjs.map +1 -1
- package/dist/sqlite3.d.cts +8 -9
- package/dist/sqlite3.d.ts +8 -9
- package/dist/sqlite3.js +14 -15
- package/dist/sqlite3.js.map +1 -1
- package/package.json +10 -10
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/sqliteProjection-BrbKryzB.d.cts +0 -150
- package/dist/sqliteProjection-BrbKryzB.d.ts +0 -150
package/dist/index.cjs
CHANGED
|
@@ -1,1763 +1,471 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.expected = expected;
|
|
45
|
-
Object.setPrototypeOf(this, _ConcurrencyError.prototype);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// ../emmett/dist/index.js
|
|
50
|
-
var _uuid = require('uuid');
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
var _asyncretry = require('async-retry'); var _asyncretry2 = _interopRequireDefault(_asyncretry);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
var emmettPrefix = "emt";
|
|
58
|
-
var defaultTag = `${emmettPrefix}:default`;
|
|
59
|
-
var unknownTag = `${emmettPrefix}:unknown`;
|
|
60
|
-
var canCreateEventStoreSession = (eventStore) => "withSession" in eventStore;
|
|
61
|
-
var nulloSessionFactory = (eventStore) => ({
|
|
62
|
-
withSession: (callback) => {
|
|
63
|
-
const nulloSession = {
|
|
64
|
-
eventStore,
|
|
65
|
-
close: () => Promise.resolve()
|
|
66
|
-
};
|
|
67
|
-
return callback(nulloSession);
|
|
68
|
-
}
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
let _event_driven_io_emmett = require("@event-driven-io/emmett");
|
|
3
|
+
let _event_driven_io_pongo = require("@event-driven-io/pongo");
|
|
4
|
+
let _event_driven_io_dumbo = require("@event-driven-io/dumbo");
|
|
5
|
+
let uuid = require("uuid");
|
|
6
|
+
|
|
7
|
+
//#region src/eventStore/projections/pongo/pongoProjections.ts
|
|
8
|
+
const pongoProjection = ({ name, kind, version, truncate, handle, canHandle, eventsOptions }) => sqliteProjection({
|
|
9
|
+
name,
|
|
10
|
+
version,
|
|
11
|
+
kind: kind ?? "emt:projections:postgresql:pongo:generic",
|
|
12
|
+
canHandle,
|
|
13
|
+
eventsOptions,
|
|
14
|
+
handle: async (events, context) => {
|
|
15
|
+
const { connection } = context;
|
|
16
|
+
const pongo = (0, _event_driven_io_pongo.pongoClient)({
|
|
17
|
+
driver: await pongoDriverRegistry.tryResolve(context.driverType),
|
|
18
|
+
connectionOptions: { connection }
|
|
19
|
+
});
|
|
20
|
+
try {
|
|
21
|
+
await handle(events, {
|
|
22
|
+
...context,
|
|
23
|
+
pongo
|
|
24
|
+
});
|
|
25
|
+
} finally {
|
|
26
|
+
await pongo.close();
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
truncate: truncate ? async (context) => {
|
|
30
|
+
const { connection } = context;
|
|
31
|
+
const pongo = (0, _event_driven_io_pongo.pongoClient)({
|
|
32
|
+
driver: await pongoDriverRegistry.tryResolve(context.driverType),
|
|
33
|
+
connectionOptions: { connection }
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
await truncate({
|
|
37
|
+
...context,
|
|
38
|
+
pongo
|
|
39
|
+
});
|
|
40
|
+
} finally {
|
|
41
|
+
await pongo.close();
|
|
42
|
+
}
|
|
43
|
+
} : void 0
|
|
69
44
|
});
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if (isPrimitive(leftItem)) {
|
|
161
|
-
if (!right.has(leftItem)) return false;
|
|
162
|
-
} else {
|
|
163
|
-
let found = false;
|
|
164
|
-
for (const rightItem of right) {
|
|
165
|
-
if (deepEquals(leftItem, rightItem)) {
|
|
166
|
-
found = true;
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
if (!found) return false;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
return true;
|
|
174
|
-
};
|
|
175
|
-
var compareArrayBuffers = (left, right) => {
|
|
176
|
-
if (left.byteLength !== right.byteLength) return false;
|
|
177
|
-
const leftView = new Uint8Array(left);
|
|
178
|
-
const rightView = new Uint8Array(right);
|
|
179
|
-
for (let i = 0; i < leftView.length; i++) {
|
|
180
|
-
if (leftView[i] !== rightView[i]) return false;
|
|
181
|
-
}
|
|
182
|
-
return true;
|
|
183
|
-
};
|
|
184
|
-
var compareTypedArrays = (left, right) => {
|
|
185
|
-
if (left.constructor !== right.constructor) return false;
|
|
186
|
-
if (left.byteLength !== right.byteLength) return false;
|
|
187
|
-
const leftArray = new Uint8Array(
|
|
188
|
-
left.buffer,
|
|
189
|
-
left.byteOffset,
|
|
190
|
-
left.byteLength
|
|
191
|
-
);
|
|
192
|
-
const rightArray = new Uint8Array(
|
|
193
|
-
right.buffer,
|
|
194
|
-
right.byteOffset,
|
|
195
|
-
right.byteLength
|
|
196
|
-
);
|
|
197
|
-
for (let i = 0; i < leftArray.length; i++) {
|
|
198
|
-
if (leftArray[i] !== rightArray[i]) return false;
|
|
199
|
-
}
|
|
200
|
-
return true;
|
|
201
|
-
};
|
|
202
|
-
var compareObjects = (left, right) => {
|
|
203
|
-
const keys1 = Object.keys(left);
|
|
204
|
-
const keys2 = Object.keys(right);
|
|
205
|
-
if (keys1.length !== keys2.length) {
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
for (const key of keys1) {
|
|
209
|
-
if (left[key] instanceof Function && right[key] instanceof Function) {
|
|
210
|
-
continue;
|
|
211
|
-
}
|
|
212
|
-
const isEqual = deepEquals(left[key], right[key]);
|
|
213
|
-
if (!isEqual) {
|
|
214
|
-
return false;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return true;
|
|
218
|
-
};
|
|
219
|
-
var getType = (value) => {
|
|
220
|
-
if (value === null) return "null";
|
|
221
|
-
if (value === void 0) return "undefined";
|
|
222
|
-
const primitiveType = typeof value;
|
|
223
|
-
if (primitiveType !== "object") return primitiveType;
|
|
224
|
-
if (Array.isArray(value)) return "array";
|
|
225
|
-
if (value instanceof Boolean) return "boxed-boolean";
|
|
226
|
-
if (value instanceof Number) return "boxed-number";
|
|
227
|
-
if (value instanceof String) return "boxed-string";
|
|
228
|
-
if (value instanceof Date) return "date";
|
|
229
|
-
if (value instanceof RegExp) return "regexp";
|
|
230
|
-
if (value instanceof Error) return "error";
|
|
231
|
-
if (value instanceof Map) return "map";
|
|
232
|
-
if (value instanceof Set) return "set";
|
|
233
|
-
if (value instanceof ArrayBuffer) return "arraybuffer";
|
|
234
|
-
if (value instanceof DataView) return "dataview";
|
|
235
|
-
if (value instanceof WeakMap) return "weakmap";
|
|
236
|
-
if (value instanceof WeakSet) return "weakset";
|
|
237
|
-
if (ArrayBuffer.isView(value)) return "typedarray";
|
|
238
|
-
return "object";
|
|
239
|
-
};
|
|
240
|
-
var deepEquals = (left, right) => {
|
|
241
|
-
if (left === right) return true;
|
|
242
|
-
if (isEquatable(left)) {
|
|
243
|
-
return left.equals(right);
|
|
244
|
-
}
|
|
245
|
-
const leftType = getType(left);
|
|
246
|
-
const rightType = getType(right);
|
|
247
|
-
if (leftType !== rightType) return false;
|
|
248
|
-
switch (leftType) {
|
|
249
|
-
case "null":
|
|
250
|
-
case "undefined":
|
|
251
|
-
case "boolean":
|
|
252
|
-
case "number":
|
|
253
|
-
case "bigint":
|
|
254
|
-
case "string":
|
|
255
|
-
case "symbol":
|
|
256
|
-
case "function":
|
|
257
|
-
return left === right;
|
|
258
|
-
case "array":
|
|
259
|
-
return compareArrays(left, right);
|
|
260
|
-
case "date":
|
|
261
|
-
return compareDates(left, right);
|
|
262
|
-
case "regexp":
|
|
263
|
-
return compareRegExps(left, right);
|
|
264
|
-
case "error":
|
|
265
|
-
return compareErrors(left, right);
|
|
266
|
-
case "map":
|
|
267
|
-
return compareMaps(
|
|
268
|
-
left,
|
|
269
|
-
right
|
|
270
|
-
);
|
|
271
|
-
case "set":
|
|
272
|
-
return compareSets(left, right);
|
|
273
|
-
case "arraybuffer":
|
|
274
|
-
return compareArrayBuffers(left, right);
|
|
275
|
-
case "dataview":
|
|
276
|
-
case "weakmap":
|
|
277
|
-
case "weakset":
|
|
278
|
-
return false;
|
|
279
|
-
case "typedarray":
|
|
280
|
-
return compareTypedArrays(
|
|
281
|
-
left,
|
|
282
|
-
right
|
|
283
|
-
);
|
|
284
|
-
case "boxed-boolean":
|
|
285
|
-
return left.valueOf() === right.valueOf();
|
|
286
|
-
case "boxed-number":
|
|
287
|
-
return left.valueOf() === right.valueOf();
|
|
288
|
-
case "boxed-string":
|
|
289
|
-
return left.valueOf() === right.valueOf();
|
|
290
|
-
case "object":
|
|
291
|
-
return compareObjects(
|
|
292
|
-
left,
|
|
293
|
-
right
|
|
294
|
-
);
|
|
295
|
-
default:
|
|
296
|
-
return false;
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
var isEquatable = (left) => {
|
|
300
|
-
return left !== null && left !== void 0 && typeof left === "object" && "equals" in left && typeof left["equals"] === "function";
|
|
301
|
-
};
|
|
302
|
-
var toNormalizedString = (value) => value.toString().padStart(19, "0");
|
|
303
|
-
var bigInt = {
|
|
304
|
-
toNormalizedString
|
|
305
|
-
};
|
|
306
|
-
var bigIntReplacer = (_key, value) => {
|
|
307
|
-
return typeof value === "bigint" ? value.toString() : value;
|
|
308
|
-
};
|
|
309
|
-
var dateReplacer = (_key, value) => {
|
|
310
|
-
return value instanceof Date ? value.toISOString() : value;
|
|
311
|
-
};
|
|
312
|
-
var isFirstLetterNumeric = (str) => {
|
|
313
|
-
const c = str.charCodeAt(0);
|
|
314
|
-
return c >= 48 && c <= 57;
|
|
315
|
-
};
|
|
316
|
-
var isFirstLetterNumericOrMinus = (str) => {
|
|
317
|
-
const c = str.charCodeAt(0);
|
|
318
|
-
return c >= 48 && c <= 57 || c === 45;
|
|
319
|
-
};
|
|
320
|
-
var bigIntReviver = (_key, value, context) => {
|
|
321
|
-
if (typeof value === "number" && Number.isInteger(value) && !Number.isSafeInteger(value)) {
|
|
322
|
-
try {
|
|
323
|
-
return BigInt(_nullishCoalesce(_optionalChain([context, 'optionalAccess', _7 => _7.source]), () => ( value.toString())));
|
|
324
|
-
} catch (e2) {
|
|
325
|
-
return value;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
if (typeof value === "string" && value.length > 15) {
|
|
329
|
-
if (isFirstLetterNumericOrMinus(value)) {
|
|
330
|
-
const num = Number(value);
|
|
331
|
-
if (Number.isFinite(num) && !Number.isSafeInteger(num)) {
|
|
332
|
-
try {
|
|
333
|
-
return BigInt(value);
|
|
334
|
-
} catch (e3) {
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
return value;
|
|
340
|
-
};
|
|
341
|
-
var dateReviver = (_key, value) => {
|
|
342
|
-
if (typeof value === "string" && value.length === 24 && isFirstLetterNumeric(value) && value[10] === "T" && value[23] === "Z") {
|
|
343
|
-
const date = new Date(value);
|
|
344
|
-
if (!isNaN(date.getTime())) {
|
|
345
|
-
return date;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
return value;
|
|
349
|
-
};
|
|
350
|
-
var composeJSONReplacers = (...replacers) => {
|
|
351
|
-
const filteredReplacers = replacers.filter((r) => r !== void 0);
|
|
352
|
-
if (filteredReplacers.length === 0) return void 0;
|
|
353
|
-
return (key, value) => (
|
|
354
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
355
|
-
filteredReplacers.reduce(
|
|
356
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
357
|
-
(accValue, replacer) => replacer(key, accValue),
|
|
358
|
-
value
|
|
359
|
-
)
|
|
360
|
-
);
|
|
361
|
-
};
|
|
362
|
-
var composeJSONRevivers = (...revivers) => {
|
|
363
|
-
const filteredRevivers = revivers.filter((r) => r !== void 0);
|
|
364
|
-
if (filteredRevivers.length === 0) return void 0;
|
|
365
|
-
return (key, value, context) => (
|
|
366
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
367
|
-
filteredRevivers.reduce(
|
|
368
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
369
|
-
(accValue, reviver) => reviver(key, accValue, context),
|
|
370
|
-
value
|
|
371
|
-
)
|
|
372
|
-
);
|
|
373
|
-
};
|
|
374
|
-
var JSONReplacer = (opts) => composeJSONReplacers(
|
|
375
|
-
_optionalChain([opts, 'optionalAccess', _8 => _8.replacer]),
|
|
376
|
-
_optionalChain([opts, 'optionalAccess', _9 => _9.failOnBigIntSerialization]) !== true ? JSONReplacers.bigInt : void 0,
|
|
377
|
-
_optionalChain([opts, 'optionalAccess', _10 => _10.useDefaultDateSerialization]) !== true ? JSONReplacers.date : void 0
|
|
378
|
-
);
|
|
379
|
-
var JSONReviver = (opts) => composeJSONRevivers(
|
|
380
|
-
_optionalChain([opts, 'optionalAccess', _11 => _11.reviver]),
|
|
381
|
-
_optionalChain([opts, 'optionalAccess', _12 => _12.parseBigInts]) === true ? JSONRevivers.bigInt : void 0,
|
|
382
|
-
_optionalChain([opts, 'optionalAccess', _13 => _13.parseDates]) === true ? JSONRevivers.date : void 0
|
|
383
|
-
);
|
|
384
|
-
var JSONReplacers = {
|
|
385
|
-
bigInt: bigIntReplacer,
|
|
386
|
-
date: dateReplacer
|
|
387
|
-
};
|
|
388
|
-
var JSONRevivers = {
|
|
389
|
-
bigInt: bigIntReviver,
|
|
390
|
-
date: dateReviver
|
|
391
|
-
};
|
|
392
|
-
var jsonSerializer = (options) => {
|
|
393
|
-
const defaultReplacer = JSONReplacer(options);
|
|
394
|
-
const defaultReviver = JSONReviver(options);
|
|
395
|
-
return {
|
|
396
|
-
serialize: (object, serializerOptions) => JSON.stringify(
|
|
397
|
-
object,
|
|
398
|
-
serializerOptions ? JSONReplacer(serializerOptions) : defaultReplacer
|
|
399
|
-
),
|
|
400
|
-
deserialize: (payload, deserializerOptions) => JSON.parse(
|
|
401
|
-
payload,
|
|
402
|
-
deserializerOptions ? JSONReviver(deserializerOptions) : defaultReviver
|
|
403
|
-
)
|
|
404
|
-
};
|
|
405
|
-
};
|
|
406
|
-
var JSONSerializer = Object.assign(jsonSerializer(), {
|
|
407
|
-
from: (options) => _nullishCoalesce(_optionalChain([options, 'optionalAccess', _14 => _14.serialization, 'optionalAccess', _15 => _15.serializer]), () => ( (_optionalChain([options, 'optionalAccess', _16 => _16.serialization, 'optionalAccess', _17 => _17.options]) ? jsonSerializer(_optionalChain([options, 'optionalAccess', _18 => _18.serialization, 'optionalAccess', _19 => _19.options])) : JSONSerializer)))
|
|
45
|
+
const pongoMultiStreamProjection = (options) => {
|
|
46
|
+
const { collectionName, getDocumentId, canHandle } = options;
|
|
47
|
+
const collectionNameWithVersion = options.version && options.version > 0 ? `${collectionName}_v${options.version}` : collectionName;
|
|
48
|
+
return pongoProjection({
|
|
49
|
+
name: collectionNameWithVersion,
|
|
50
|
+
version: options.version,
|
|
51
|
+
kind: options.kind ?? "emt:projections:postgresql:pongo:multi_stream",
|
|
52
|
+
eventsOptions: options.eventsOptions,
|
|
53
|
+
handle: async (events, { pongo }) => {
|
|
54
|
+
const collection = pongo.db().collection(collectionNameWithVersion, options.collectionOptions);
|
|
55
|
+
const eventsByDocumentId = events.map((event) => {
|
|
56
|
+
return {
|
|
57
|
+
documentId: getDocumentId(event),
|
|
58
|
+
event
|
|
59
|
+
};
|
|
60
|
+
}).reduce((acc, { documentId, event }) => {
|
|
61
|
+
if (!acc.has(documentId)) acc.set(documentId, []);
|
|
62
|
+
acc.get(documentId).push(event);
|
|
63
|
+
return acc;
|
|
64
|
+
}, /* @__PURE__ */ new Map());
|
|
65
|
+
await collection.handle([...eventsByDocumentId.keys()], (document, id) => {
|
|
66
|
+
return (0, _event_driven_io_emmett.reduceAsync)(eventsByDocumentId.get(id), async (acc, event) => await options.evolve(acc, event), document ?? ("initialState" in options ? options.initialState() : null));
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
canHandle,
|
|
70
|
+
truncate: async (context) => {
|
|
71
|
+
const { connection } = context;
|
|
72
|
+
const pongo = (0, _event_driven_io_pongo.pongoClient)({
|
|
73
|
+
driver: await pongoDriverRegistry.tryResolve(context.driverType),
|
|
74
|
+
connectionOptions: { connection }
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
await pongo.db().collection(collectionNameWithVersion, options.collectionOptions).deleteMany();
|
|
78
|
+
} finally {
|
|
79
|
+
await pongo.close();
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
init: async (context) => {
|
|
83
|
+
const { connection } = context;
|
|
84
|
+
const driver = await pongoDriverRegistry.tryResolve(context.driverType);
|
|
85
|
+
const pongo = (0, _event_driven_io_pongo.pongoClient)({
|
|
86
|
+
connectionOptions: { connection },
|
|
87
|
+
driver
|
|
88
|
+
});
|
|
89
|
+
try {
|
|
90
|
+
await pongo.db().collection(collectionNameWithVersion, options.collectionOptions).schema.migrate();
|
|
91
|
+
} finally {
|
|
92
|
+
await pongo.close();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
const pongoSingleStreamProjection = (options) => {
|
|
98
|
+
return pongoMultiStreamProjection({
|
|
99
|
+
...options,
|
|
100
|
+
kind: "emt:projections:postgresql:pongo:single_stream",
|
|
101
|
+
getDocumentId: options.getDocumentId ?? ((event) => event.metadata.streamName)
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/eventStore/projections/pongo/pongoProjectionSpec.ts
|
|
107
|
+
const withCollection = async (handle, options) => {
|
|
108
|
+
const { connection, inDatabase, inCollection } = options;
|
|
109
|
+
const driver = await pongoDriverRegistry.tryResolve(connection.driverType);
|
|
110
|
+
const pongo = (0, _event_driven_io_pongo.pongoClient)({
|
|
111
|
+
connectionOptions: { connection },
|
|
112
|
+
driver
|
|
113
|
+
});
|
|
114
|
+
try {
|
|
115
|
+
return handle(pongo.db(inDatabase).collection(inCollection));
|
|
116
|
+
} finally {
|
|
117
|
+
await pongo.close();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const withoutIdAndVersion = (doc) => {
|
|
121
|
+
const { _id, _version, ...without } = doc;
|
|
122
|
+
return without;
|
|
123
|
+
};
|
|
124
|
+
const assertDocumentsEqual = (actual, expected) => {
|
|
125
|
+
if ("_id" in expected) (0, _event_driven_io_emmett.assertEqual)(expected._id, actual._id, `Document ids are not matching! Expected: ${expected._id}, Actual: ${actual._id}`);
|
|
126
|
+
return (0, _event_driven_io_emmett.assertDeepEqual)(withoutIdAndVersion(actual), withoutIdAndVersion(expected));
|
|
127
|
+
};
|
|
128
|
+
const documentExists = (document, options) => (assertOptions) => withCollection(async (collection) => {
|
|
129
|
+
const result = await collection.findOne("withId" in options ? { _id: options.withId } : options.matchingFilter);
|
|
130
|
+
(0, _event_driven_io_emmett.assertIsNotNull)(result);
|
|
131
|
+
assertDocumentsEqual(result, document);
|
|
132
|
+
}, {
|
|
133
|
+
...options,
|
|
134
|
+
...assertOptions
|
|
408
135
|
});
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
if (_optionalChain([opts, 'optionalAccess', _20 => _20.shouldRetryResult]) && opts.shouldRetryResult(result)) {
|
|
417
|
-
throw new EmmettError(
|
|
418
|
-
`Retrying because of result: ${JSONSerializer.serialize(result)}`
|
|
419
|
-
);
|
|
420
|
-
}
|
|
421
|
-
return result;
|
|
422
|
-
} catch (error) {
|
|
423
|
-
if (_optionalChain([opts, 'optionalAccess', _21 => _21.shouldRetryError]) && !opts.shouldRetryError(error)) {
|
|
424
|
-
bail(error);
|
|
425
|
-
return void 0;
|
|
426
|
-
}
|
|
427
|
-
throw error;
|
|
428
|
-
}
|
|
429
|
-
},
|
|
430
|
-
_nullishCoalesce(opts, () => ( { retries: 0 }))
|
|
431
|
-
);
|
|
432
|
-
};
|
|
433
|
-
var onShutdown = (handler) => {
|
|
434
|
-
const signals = ["SIGTERM", "SIGINT"];
|
|
435
|
-
if (typeof process !== "undefined" && typeof process.on === "function") {
|
|
436
|
-
for (const signal of signals) {
|
|
437
|
-
process.on(signal, handler);
|
|
438
|
-
}
|
|
439
|
-
return () => {
|
|
440
|
-
for (const signal of signals) {
|
|
441
|
-
process.off(signal, handler);
|
|
442
|
-
}
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
const deno = globalThis.Deno;
|
|
446
|
-
if (deno && typeof deno.addSignalListener === "function") {
|
|
447
|
-
for (const signal of signals) {
|
|
448
|
-
deno.addSignalListener(signal, handler);
|
|
449
|
-
}
|
|
450
|
-
return () => {
|
|
451
|
-
for (const signal of signals) {
|
|
452
|
-
deno.removeSignalListener(signal, handler);
|
|
453
|
-
}
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
return () => {
|
|
457
|
-
};
|
|
458
|
-
};
|
|
459
|
-
var textEncoder = new TextEncoder();
|
|
460
|
-
var getCheckpoint = (message2) => {
|
|
461
|
-
return message2.metadata.checkpoint;
|
|
462
|
-
};
|
|
463
|
-
var wasMessageHandled = (message2, checkpoint) => {
|
|
464
|
-
const messageCheckpoint = getCheckpoint(message2);
|
|
465
|
-
return messageCheckpoint !== null && messageCheckpoint !== void 0 && checkpoint !== null && checkpoint !== void 0 && messageCheckpoint <= checkpoint;
|
|
466
|
-
};
|
|
467
|
-
var MessageProcessorType = {
|
|
468
|
-
PROJECTOR: "projector",
|
|
469
|
-
REACTOR: "reactor"
|
|
470
|
-
};
|
|
471
|
-
var defaultProcessingMessageProcessingScope = (handler, partialContext) => handler(partialContext);
|
|
472
|
-
var bigIntProcessorCheckpoint = (value) => bigInt.toNormalizedString(value);
|
|
473
|
-
var parseBigIntProcessorCheckpoint = (value) => BigInt(value);
|
|
474
|
-
var defaultProcessorVersion = 1;
|
|
475
|
-
var defaultProcessorPartition = defaultTag;
|
|
476
|
-
var getProcessorInstanceId = (processorId) => `${processorId}:${_uuid.v7.call(void 0, )}`;
|
|
477
|
-
var getProjectorId = (options) => `emt:processor:projector:${options.projectionName}`;
|
|
478
|
-
var reactor = (options) => {
|
|
479
|
-
const {
|
|
480
|
-
checkpoints,
|
|
481
|
-
processorId,
|
|
482
|
-
processorInstanceId: instanceId = getProcessorInstanceId(processorId),
|
|
483
|
-
type = MessageProcessorType.REACTOR,
|
|
484
|
-
version = defaultProcessorVersion,
|
|
485
|
-
partition = defaultProcessorPartition,
|
|
486
|
-
hooks = {},
|
|
487
|
-
processingScope = defaultProcessingMessageProcessingScope,
|
|
488
|
-
startFrom,
|
|
489
|
-
canHandle,
|
|
490
|
-
stopAfter
|
|
491
|
-
} = options;
|
|
492
|
-
const isCustomBatch = "eachBatch" in options && !!options.eachBatch;
|
|
493
|
-
const eachBatch = isCustomBatch ? options.eachBatch : async (messages, context) => {
|
|
494
|
-
let result = void 0;
|
|
495
|
-
for (let i = 0; i < messages.length; i++) {
|
|
496
|
-
const message2 = messages[i];
|
|
497
|
-
const messageProcessingResult = await options.eachMessage(
|
|
498
|
-
message2,
|
|
499
|
-
context
|
|
500
|
-
);
|
|
501
|
-
if (messageProcessingResult && messageProcessingResult.type === "STOP") {
|
|
502
|
-
result = {
|
|
503
|
-
...messageProcessingResult,
|
|
504
|
-
lastSuccessfulMessage: messageProcessingResult.error ? messages[i - 1] : message2
|
|
505
|
-
};
|
|
506
|
-
break;
|
|
507
|
-
}
|
|
508
|
-
if (stopAfter && stopAfter(message2)) {
|
|
509
|
-
result = {
|
|
510
|
-
type: "STOP",
|
|
511
|
-
reason: "Stop condition reached",
|
|
512
|
-
lastSuccessfulMessage: message2
|
|
513
|
-
};
|
|
514
|
-
break;
|
|
515
|
-
}
|
|
516
|
-
if (messageProcessingResult && messageProcessingResult.type === "SKIP") {
|
|
517
|
-
result = {
|
|
518
|
-
...messageProcessingResult,
|
|
519
|
-
lastSuccessfulMessage: message2
|
|
520
|
-
};
|
|
521
|
-
continue;
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
return result;
|
|
525
|
-
};
|
|
526
|
-
let isInitiated = false;
|
|
527
|
-
let isActive = false;
|
|
528
|
-
let lastCheckpoint = null;
|
|
529
|
-
let closeSignal = null;
|
|
530
|
-
const init = async (initOptions) => {
|
|
531
|
-
if (isInitiated) return;
|
|
532
|
-
if (hooks.onInit === void 0) {
|
|
533
|
-
isInitiated = true;
|
|
534
|
-
return;
|
|
535
|
-
}
|
|
536
|
-
return await processingScope(async (context) => {
|
|
537
|
-
await hooks.onInit(context);
|
|
538
|
-
isInitiated = true;
|
|
539
|
-
}, initOptions);
|
|
540
|
-
};
|
|
541
|
-
const close = async (closeOptions) => {
|
|
542
|
-
isActive = false;
|
|
543
|
-
if (closeSignal) {
|
|
544
|
-
closeSignal();
|
|
545
|
-
closeSignal = null;
|
|
546
|
-
}
|
|
547
|
-
if (hooks.onClose) {
|
|
548
|
-
await processingScope(hooks.onClose, closeOptions);
|
|
549
|
-
}
|
|
550
|
-
};
|
|
551
|
-
return {
|
|
552
|
-
// TODO: Consider whether not make it optional or add URN prefix
|
|
553
|
-
id: processorId,
|
|
554
|
-
instanceId,
|
|
555
|
-
type,
|
|
556
|
-
canHandle,
|
|
557
|
-
init,
|
|
558
|
-
start: async (startOptions) => {
|
|
559
|
-
if (isActive) return;
|
|
560
|
-
await init(startOptions);
|
|
561
|
-
isActive = true;
|
|
562
|
-
closeSignal = onShutdown(() => close(startOptions));
|
|
563
|
-
if (lastCheckpoint !== null) {
|
|
564
|
-
return {
|
|
565
|
-
lastCheckpoint
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
return await processingScope(async (context) => {
|
|
569
|
-
if (hooks.onStart) {
|
|
570
|
-
await hooks.onStart(context);
|
|
571
|
-
}
|
|
572
|
-
if (startFrom && startFrom !== "CURRENT") return startFrom;
|
|
573
|
-
if (checkpoints) {
|
|
574
|
-
const readResult = await _optionalChain([checkpoints, 'optionalAccess', _22 => _22.read, 'call', _23 => _23(
|
|
575
|
-
{
|
|
576
|
-
processorId,
|
|
577
|
-
partition
|
|
578
|
-
},
|
|
579
|
-
{ ...startOptions, ...context }
|
|
580
|
-
)]);
|
|
581
|
-
lastCheckpoint = readResult.lastCheckpoint;
|
|
582
|
-
}
|
|
583
|
-
if (lastCheckpoint === null) return "BEGINNING";
|
|
584
|
-
return {
|
|
585
|
-
lastCheckpoint
|
|
586
|
-
};
|
|
587
|
-
}, startOptions);
|
|
588
|
-
},
|
|
589
|
-
close,
|
|
590
|
-
get isActive() {
|
|
591
|
-
return isActive;
|
|
592
|
-
},
|
|
593
|
-
handle: async (messages, partialContext) => {
|
|
594
|
-
if (!isActive) return Promise.resolve();
|
|
595
|
-
return await processingScope(async (context) => {
|
|
596
|
-
const messagesAboveCheckpoint = messages.filter(
|
|
597
|
-
(message2) => !wasMessageHandled(message2, lastCheckpoint)
|
|
598
|
-
);
|
|
599
|
-
const upcastedMessages = messagesAboveCheckpoint.map(
|
|
600
|
-
(message2) => upcastRecordedMessage(
|
|
601
|
-
// TODO: Make it smarter
|
|
602
|
-
message2,
|
|
603
|
-
_optionalChain([options, 'access', _24 => _24.messageOptions, 'optionalAccess', _25 => _25.schema, 'optionalAccess', _26 => _26.versioning])
|
|
604
|
-
)
|
|
605
|
-
).filter(
|
|
606
|
-
(upcasted) => !canHandle || canHandle.includes(upcasted.type)
|
|
607
|
-
);
|
|
608
|
-
const stopMessageIndex = isCustomBatch && stopAfter ? upcastedMessages.findIndex(stopAfter) : -1;
|
|
609
|
-
const unhandledMessages = stopMessageIndex !== -1 ? upcastedMessages.slice(0, stopMessageIndex + 1) : upcastedMessages;
|
|
610
|
-
const batchResult = await eachBatch(unhandledMessages, context);
|
|
611
|
-
const messageProcessingResult = _optionalChain([batchResult, 'optionalAccess', _27 => _27.type]) === "STOP" ? batchResult : stopMessageIndex !== -1 ? {
|
|
612
|
-
type: "STOP",
|
|
613
|
-
reason: "Stop condition reached",
|
|
614
|
-
lastSuccessfulMessage: unhandledMessages[stopMessageIndex]
|
|
615
|
-
} : batchResult;
|
|
616
|
-
const isStop = messageProcessingResult && messageProcessingResult.type === "STOP";
|
|
617
|
-
const checkpointMessage = _optionalChain([messageProcessingResult, 'optionalAccess', _28 => _28.type]) === "STOP" ? messageProcessingResult.lastSuccessfulMessage : messagesAboveCheckpoint[messagesAboveCheckpoint.length - 1];
|
|
618
|
-
if (checkpointMessage && checkpoints) {
|
|
619
|
-
const storeCheckpointResult = await checkpoints.store(
|
|
620
|
-
{
|
|
621
|
-
processorId,
|
|
622
|
-
version,
|
|
623
|
-
message: checkpointMessage,
|
|
624
|
-
lastCheckpoint,
|
|
625
|
-
partition
|
|
626
|
-
},
|
|
627
|
-
context
|
|
628
|
-
);
|
|
629
|
-
if (storeCheckpointResult.success) {
|
|
630
|
-
lastCheckpoint = storeCheckpointResult.newCheckpoint;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
if (isStop) {
|
|
634
|
-
isActive = false;
|
|
635
|
-
return messageProcessingResult;
|
|
636
|
-
}
|
|
637
|
-
return void 0;
|
|
638
|
-
}, partialContext);
|
|
639
|
-
}
|
|
640
|
-
};
|
|
641
|
-
};
|
|
642
|
-
var projector = (options) => {
|
|
643
|
-
const {
|
|
644
|
-
projection: projection2,
|
|
645
|
-
processorId = getProjectorId({
|
|
646
|
-
projectionName: _nullishCoalesce(projection2.name, () => ( "unknown"))
|
|
647
|
-
}),
|
|
648
|
-
...rest
|
|
649
|
-
} = options;
|
|
650
|
-
return reactor({
|
|
651
|
-
...rest,
|
|
652
|
-
type: MessageProcessorType.PROJECTOR,
|
|
653
|
-
canHandle: projection2.canHandle,
|
|
654
|
-
processorId,
|
|
655
|
-
messageOptions: options.projection.eventsOptions,
|
|
656
|
-
hooks: {
|
|
657
|
-
onInit: _optionalChain([options, 'access', _29 => _29.hooks, 'optionalAccess', _30 => _30.onInit]),
|
|
658
|
-
onStart: options.truncateOnStart && options.projection.truncate || _optionalChain([options, 'access', _31 => _31.hooks, 'optionalAccess', _32 => _32.onStart]) ? async (context) => {
|
|
659
|
-
if (options.truncateOnStart && options.projection.truncate)
|
|
660
|
-
await options.projection.truncate(context);
|
|
661
|
-
if (_optionalChain([options, 'access', _33 => _33.hooks, 'optionalAccess', _34 => _34.onStart])) await _optionalChain([options, 'access', _35 => _35.hooks, 'optionalAccess', _36 => _36.onStart, 'call', _37 => _37(context)]);
|
|
662
|
-
} : void 0,
|
|
663
|
-
onClose: _optionalChain([options, 'access', _38 => _38.hooks, 'optionalAccess', _39 => _39.onClose])
|
|
664
|
-
},
|
|
665
|
-
eachBatch: async (events, context) => projection2.handle(events, context)
|
|
666
|
-
});
|
|
667
|
-
};
|
|
668
|
-
var AssertionError = class extends Error {
|
|
669
|
-
constructor(message2) {
|
|
670
|
-
super(message2);
|
|
671
|
-
}
|
|
672
|
-
};
|
|
673
|
-
var isSubset = (superObj, subObj) => {
|
|
674
|
-
const sup = superObj;
|
|
675
|
-
const sub = subObj;
|
|
676
|
-
assertOk(sup);
|
|
677
|
-
assertOk(sub);
|
|
678
|
-
return Object.keys(sub).every((ele) => {
|
|
679
|
-
if (sub[ele] !== null && typeof sub[ele] == "object") {
|
|
680
|
-
return isSubset(sup[ele], sub[ele]);
|
|
681
|
-
}
|
|
682
|
-
return sub[ele] === sup[ele];
|
|
683
|
-
});
|
|
684
|
-
};
|
|
685
|
-
var assertFails = (message2) => {
|
|
686
|
-
throw new AssertionError(_nullishCoalesce(message2, () => ( "That should not ever happened, right?")));
|
|
687
|
-
};
|
|
688
|
-
var assertDeepEqual = (actual, expected, message2) => {
|
|
689
|
-
if (!deepEquals(actual, expected))
|
|
690
|
-
throw new AssertionError(
|
|
691
|
-
_nullishCoalesce(message2, () => ( `subObj:
|
|
692
|
-
${JSONSerializer.serialize(expected)}
|
|
693
|
-
is not equal to
|
|
694
|
-
${JSONSerializer.serialize(actual)}`))
|
|
695
|
-
);
|
|
696
|
-
};
|
|
697
|
-
function assertTrue(condition, message2) {
|
|
698
|
-
if (condition !== true)
|
|
699
|
-
throw new AssertionError(_nullishCoalesce(message2, () => ( `Condition is false`)));
|
|
700
|
-
}
|
|
701
|
-
function assertOk(obj, message2) {
|
|
702
|
-
if (!obj) throw new AssertionError(_nullishCoalesce(message2, () => ( `Condition is not truthy`)));
|
|
703
|
-
}
|
|
704
|
-
function assertEqual(expected, actual, message2) {
|
|
705
|
-
if (expected !== actual)
|
|
706
|
-
throw new AssertionError(
|
|
707
|
-
`${_nullishCoalesce(message2, () => ( "Objects are not equal"))}:
|
|
708
|
-
Expected: ${JSONSerializer.serialize(expected)}
|
|
709
|
-
Actual: ${JSONSerializer.serialize(actual)}`
|
|
710
|
-
);
|
|
711
|
-
}
|
|
712
|
-
function assertNotEqual(obj, other, message2) {
|
|
713
|
-
if (obj === other)
|
|
714
|
-
throw new AssertionError(
|
|
715
|
-
_nullishCoalesce(message2, () => ( `Objects are equal: ${JSONSerializer.serialize(obj)}`))
|
|
716
|
-
);
|
|
717
|
-
}
|
|
718
|
-
function assertIsNotNull(result) {
|
|
719
|
-
assertNotEqual(result, null);
|
|
720
|
-
assertOk(result);
|
|
721
|
-
}
|
|
722
|
-
function assertIsNull(result) {
|
|
723
|
-
assertEqual(result, null);
|
|
724
|
-
}
|
|
725
|
-
var assertThatArray = (array) => {
|
|
726
|
-
return {
|
|
727
|
-
isEmpty: () => assertEqual(
|
|
728
|
-
array.length,
|
|
729
|
-
0,
|
|
730
|
-
`Array is not empty ${JSONSerializer.serialize(array)}`
|
|
731
|
-
),
|
|
732
|
-
isNotEmpty: () => assertNotEqual(array.length, 0, `Array is empty`),
|
|
733
|
-
hasSize: (length) => assertEqual(array.length, length),
|
|
734
|
-
containsElements: (other) => {
|
|
735
|
-
assertTrue(other.every((ts) => array.some((o) => deepEquals(ts, o))));
|
|
736
|
-
},
|
|
737
|
-
containsElementsMatching: (other) => {
|
|
738
|
-
assertTrue(other.every((ts) => array.some((o) => isSubset(o, ts))));
|
|
739
|
-
},
|
|
740
|
-
containsOnlyElementsMatching: (other) => {
|
|
741
|
-
assertEqual(array.length, other.length, `Arrays lengths don't match`);
|
|
742
|
-
assertTrue(other.every((ts) => array.some((o) => isSubset(o, ts))));
|
|
743
|
-
},
|
|
744
|
-
containsExactlyInAnyOrder: (other) => {
|
|
745
|
-
assertEqual(array.length, other.length);
|
|
746
|
-
assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));
|
|
747
|
-
},
|
|
748
|
-
containsExactlyInAnyOrderElementsOf: (other) => {
|
|
749
|
-
assertEqual(array.length, other.length);
|
|
750
|
-
assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));
|
|
751
|
-
},
|
|
752
|
-
containsExactlyElementsOf: (other) => {
|
|
753
|
-
assertEqual(array.length, other.length);
|
|
754
|
-
for (let i = 0; i < array.length; i++) {
|
|
755
|
-
assertTrue(deepEquals(array[i], other[i]));
|
|
756
|
-
}
|
|
757
|
-
},
|
|
758
|
-
containsExactly: (elem) => {
|
|
759
|
-
assertEqual(array.length, 1);
|
|
760
|
-
assertTrue(deepEquals(array[0], elem));
|
|
761
|
-
},
|
|
762
|
-
contains: (elem) => {
|
|
763
|
-
assertTrue(array.some((a) => deepEquals(a, elem)));
|
|
764
|
-
},
|
|
765
|
-
containsOnlyOnceElementsOf: (other) => {
|
|
766
|
-
assertTrue(
|
|
767
|
-
other.map((o) => array.filter((a) => deepEquals(a, o)).length).filter((a) => a === 1).length === other.length
|
|
768
|
-
);
|
|
769
|
-
},
|
|
770
|
-
containsAnyOf: (other) => {
|
|
771
|
-
assertTrue(array.some((a) => other.some((o) => deepEquals(a, o))));
|
|
772
|
-
},
|
|
773
|
-
allMatch: (matches) => {
|
|
774
|
-
assertTrue(array.every(matches));
|
|
775
|
-
},
|
|
776
|
-
anyMatches: (matches) => {
|
|
777
|
-
assertTrue(array.some(matches));
|
|
778
|
-
},
|
|
779
|
-
allMatchAsync: async (matches) => {
|
|
780
|
-
for (const item of array) {
|
|
781
|
-
assertTrue(await matches(item));
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
};
|
|
785
|
-
};
|
|
786
|
-
var downcastRecordedMessage = (recordedMessage, options) => {
|
|
787
|
-
if (!_optionalChain([options, 'optionalAccess', _40 => _40.downcast]))
|
|
788
|
-
return recordedMessage;
|
|
789
|
-
const downcasted = options.downcast(
|
|
790
|
-
recordedMessage
|
|
791
|
-
);
|
|
792
|
-
return {
|
|
793
|
-
...recordedMessage,
|
|
794
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
795
|
-
data: downcasted.data,
|
|
796
|
-
..."metadata" in recordedMessage || "metadata" in downcasted ? {
|
|
797
|
-
metadata: {
|
|
798
|
-
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
799
|
-
..."metadata" in downcasted ? downcasted.metadata : {}
|
|
800
|
-
}
|
|
801
|
-
} : {}
|
|
802
|
-
};
|
|
803
|
-
};
|
|
804
|
-
var downcastRecordedMessages = (recordedMessages, options) => {
|
|
805
|
-
if (!_optionalChain([options, 'optionalAccess', _41 => _41.downcast]))
|
|
806
|
-
return recordedMessages;
|
|
807
|
-
return recordedMessages.map(
|
|
808
|
-
(recordedMessage) => downcastRecordedMessage(recordedMessage, options)
|
|
809
|
-
);
|
|
810
|
-
};
|
|
811
|
-
var upcastRecordedMessage = (recordedMessage, options) => {
|
|
812
|
-
if (!_optionalChain([options, 'optionalAccess', _42 => _42.upcast]))
|
|
813
|
-
return recordedMessage;
|
|
814
|
-
const upcasted = options.upcast(
|
|
815
|
-
recordedMessage
|
|
816
|
-
);
|
|
817
|
-
return {
|
|
818
|
-
...recordedMessage,
|
|
819
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
820
|
-
data: upcasted.data,
|
|
821
|
-
..."metadata" in recordedMessage || "metadata" in upcasted ? {
|
|
822
|
-
metadata: {
|
|
823
|
-
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
824
|
-
..."metadata" in upcasted ? upcasted.metadata : {}
|
|
825
|
-
}
|
|
826
|
-
} : {}
|
|
827
|
-
};
|
|
828
|
-
};
|
|
829
|
-
var projection = (definition) => definition;
|
|
830
|
-
var WorkflowHandlerStreamVersionConflictRetryOptions = {
|
|
831
|
-
retries: 3,
|
|
832
|
-
minTimeout: 100,
|
|
833
|
-
factor: 1.5,
|
|
834
|
-
shouldRetryError: isExpectedVersionConflictError
|
|
835
|
-
};
|
|
836
|
-
var fromWorkflowHandlerRetryOptions = (retryOptions) => {
|
|
837
|
-
if (retryOptions === void 0) return NoRetries;
|
|
838
|
-
if ("onVersionConflict" in retryOptions) {
|
|
839
|
-
if (typeof retryOptions.onVersionConflict === "boolean")
|
|
840
|
-
return WorkflowHandlerStreamVersionConflictRetryOptions;
|
|
841
|
-
else if (typeof retryOptions.onVersionConflict === "number")
|
|
842
|
-
return {
|
|
843
|
-
...WorkflowHandlerStreamVersionConflictRetryOptions,
|
|
844
|
-
retries: retryOptions.onVersionConflict
|
|
845
|
-
};
|
|
846
|
-
else return retryOptions.onVersionConflict;
|
|
847
|
-
}
|
|
848
|
-
return retryOptions;
|
|
849
|
-
};
|
|
850
|
-
var emptyHandlerResult = (nextExpectedStreamVersion = 0n) => ({
|
|
851
|
-
newMessages: [],
|
|
852
|
-
createdNewStream: false,
|
|
853
|
-
nextExpectedStreamVersion
|
|
136
|
+
const documentsAreTheSame = (documents, options) => (assertOptions) => withCollection(async (collection) => {
|
|
137
|
+
const result = await collection.find("withId" in options ? { _id: options.withId } : options.matchingFilter);
|
|
138
|
+
(0, _event_driven_io_emmett.assertEqual)(documents.length, result.length, "Different Documents Count than expected");
|
|
139
|
+
for (let i = 0; i < documents.length; i++) (0, _event_driven_io_emmett.assertThatArray)(result).contains(documents[i]);
|
|
140
|
+
}, {
|
|
141
|
+
...options,
|
|
142
|
+
...assertOptions
|
|
854
143
|
});
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
144
|
+
const documentsMatchingHaveCount = (expectedCount, options) => (assertOptions) => withCollection(async (collection) => {
|
|
145
|
+
(0, _event_driven_io_emmett.assertEqual)(expectedCount, (await collection.find("withId" in options ? { _id: options.withId } : options.matchingFilter)).length, "Different Documents Count than expected");
|
|
146
|
+
}, {
|
|
147
|
+
...options,
|
|
148
|
+
...assertOptions
|
|
859
149
|
});
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
...existingMetadata,
|
|
866
|
-
action
|
|
867
|
-
}
|
|
868
|
-
};
|
|
869
|
-
};
|
|
870
|
-
var createWrappedInitialState = (initialState) => {
|
|
871
|
-
return () => ({
|
|
872
|
-
userState: initialState(),
|
|
873
|
-
processedInputIds: /* @__PURE__ */ new Set()
|
|
874
|
-
});
|
|
875
|
-
};
|
|
876
|
-
var createWrappedEvolve = (evolve, workflowName, separateInputInboxFromProcessing) => {
|
|
877
|
-
return (state, event2) => {
|
|
878
|
-
const metadata = event2.metadata;
|
|
879
|
-
let processedInputIds = state.processedInputIds;
|
|
880
|
-
if (_optionalChain([metadata, 'optionalAccess', _43 => _43.input]) === true && typeof _optionalChain([metadata, 'optionalAccess', _44 => _44.originalMessageId]) === "string") {
|
|
881
|
-
processedInputIds = new Set(state.processedInputIds);
|
|
882
|
-
processedInputIds.add(metadata.originalMessageId);
|
|
883
|
-
}
|
|
884
|
-
if (separateInputInboxFromProcessing && _optionalChain([metadata, 'optionalAccess', _45 => _45.input]) === true) {
|
|
885
|
-
return {
|
|
886
|
-
userState: state.userState,
|
|
887
|
-
processedInputIds
|
|
888
|
-
};
|
|
889
|
-
}
|
|
890
|
-
const eventType = event2.type;
|
|
891
|
-
const eventForEvolve = eventType.startsWith(`${workflowName}:`) ? {
|
|
892
|
-
...event2,
|
|
893
|
-
type: eventType.replace(`${workflowName}:`, "")
|
|
894
|
-
} : event2;
|
|
895
|
-
return {
|
|
896
|
-
userState: evolve(state.userState, eventForEvolve),
|
|
897
|
-
processedInputIds
|
|
898
|
-
};
|
|
899
|
-
};
|
|
900
|
-
};
|
|
901
|
-
var workflowStreamName = ({
|
|
902
|
-
workflowName,
|
|
903
|
-
workflowId
|
|
904
|
-
}) => `emt:workflow:${workflowName}:${workflowId}`;
|
|
905
|
-
var WorkflowHandler = (options) => async (store, message2, handleOptions) => asyncRetry(
|
|
906
|
-
async () => {
|
|
907
|
-
const result = await withSession2(store, async ({ eventStore }) => {
|
|
908
|
-
const {
|
|
909
|
-
workflow: { evolve, initialState, decide, name: workflowName },
|
|
910
|
-
getWorkflowId: getWorkflowId2
|
|
911
|
-
} = options;
|
|
912
|
-
const inputMessageId = (
|
|
913
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
914
|
-
_nullishCoalesce(("metadata" in message2 && _optionalChain([message2, 'access', _46 => _46.metadata, 'optionalAccess', _47 => _47.messageId]) ? (
|
|
915
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
916
|
-
message2.metadata.messageId
|
|
917
|
-
) : void 0), () => ( _uuid.v7.call(void 0, )))
|
|
918
|
-
);
|
|
919
|
-
const messageWithMetadata = {
|
|
920
|
-
...message2,
|
|
921
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
922
|
-
metadata: {
|
|
923
|
-
messageId: inputMessageId,
|
|
924
|
-
...message2.metadata
|
|
925
|
-
}
|
|
926
|
-
};
|
|
927
|
-
const workflowId = getWorkflowId2(messageWithMetadata);
|
|
928
|
-
if (!workflowId) {
|
|
929
|
-
return emptyHandlerResult();
|
|
930
|
-
}
|
|
931
|
-
const streamName = options.mapWorkflowId ? options.mapWorkflowId(workflowId) : workflowStreamName({ workflowName, workflowId });
|
|
932
|
-
const messageType = messageWithMetadata.type;
|
|
933
|
-
const hasWorkflowPrefix = messageType.startsWith(`${workflowName}:`);
|
|
934
|
-
if (options.separateInputInboxFromProcessing && !hasWorkflowPrefix) {
|
|
935
|
-
const inputMetadata2 = createInputMetadata(
|
|
936
|
-
inputMessageId,
|
|
937
|
-
"InitiatedBy"
|
|
938
|
-
);
|
|
939
|
-
const inputToStore2 = {
|
|
940
|
-
type: `${workflowName}:${messageWithMetadata.type}`,
|
|
941
|
-
data: messageWithMetadata.data,
|
|
942
|
-
kind: messageWithMetadata.kind,
|
|
943
|
-
metadata: inputMetadata2
|
|
944
|
-
};
|
|
945
|
-
const appendResult2 = await eventStore.appendToStream(
|
|
946
|
-
streamName,
|
|
947
|
-
[inputToStore2],
|
|
948
|
-
{
|
|
949
|
-
...handleOptions,
|
|
950
|
-
expectedStreamVersion: _nullishCoalesce(_optionalChain([handleOptions, 'optionalAccess', _48 => _48.expectedStreamVersion]), () => ( NO_CONCURRENCY_CHECK))
|
|
951
|
-
}
|
|
952
|
-
);
|
|
953
|
-
return {
|
|
954
|
-
...appendResult2,
|
|
955
|
-
newMessages: []
|
|
956
|
-
};
|
|
957
|
-
}
|
|
958
|
-
const wrappedInitialState = createWrappedInitialState(initialState);
|
|
959
|
-
const wrappedEvolve = createWrappedEvolve(
|
|
960
|
-
evolve,
|
|
961
|
-
workflowName,
|
|
962
|
-
_nullishCoalesce(options.separateInputInboxFromProcessing, () => ( false))
|
|
963
|
-
);
|
|
964
|
-
const aggregationResult = await eventStore.aggregateStream(streamName, {
|
|
965
|
-
evolve: wrappedEvolve,
|
|
966
|
-
initialState: wrappedInitialState,
|
|
967
|
-
read: {
|
|
968
|
-
...handleOptions,
|
|
969
|
-
// expected stream version is passed to fail fast
|
|
970
|
-
// if stream is in the wrong state
|
|
971
|
-
expectedStreamVersion: _nullishCoalesce(_optionalChain([handleOptions, 'optionalAccess', _49 => _49.expectedStreamVersion]), () => ( NO_CONCURRENCY_CHECK))
|
|
972
|
-
}
|
|
973
|
-
});
|
|
974
|
-
const { currentStreamVersion } = aggregationResult;
|
|
975
|
-
const { userState: state, processedInputIds } = aggregationResult.state;
|
|
976
|
-
if (processedInputIds.has(inputMessageId)) {
|
|
977
|
-
return emptyHandlerResult(currentStreamVersion);
|
|
978
|
-
}
|
|
979
|
-
const messageForDecide = hasWorkflowPrefix ? {
|
|
980
|
-
...messageWithMetadata,
|
|
981
|
-
type: messageType.replace(`${workflowName}:`, "")
|
|
982
|
-
} : messageWithMetadata;
|
|
983
|
-
const result2 = decide(messageForDecide, state);
|
|
984
|
-
const inputMetadata = createInputMetadata(
|
|
985
|
-
inputMessageId,
|
|
986
|
-
aggregationResult.streamExists ? "Received" : "InitiatedBy"
|
|
987
|
-
);
|
|
988
|
-
const inputToStore = {
|
|
989
|
-
type: `${workflowName}:${messageWithMetadata.type}`,
|
|
990
|
-
data: messageWithMetadata.data,
|
|
991
|
-
kind: messageWithMetadata.kind,
|
|
992
|
-
metadata: inputMetadata
|
|
993
|
-
};
|
|
994
|
-
const outputMessages = (Array.isArray(result2) ? result2 : [result2]).filter((msg) => msg !== void 0 && msg !== null);
|
|
995
|
-
const outputCommandTypes = _nullishCoalesce(_optionalChain([options, 'access', _50 => _50.outputs, 'optionalAccess', _51 => _51.commands]), () => ( []));
|
|
996
|
-
const taggedOutputMessages = outputMessages.map((msg) => {
|
|
997
|
-
const action = outputCommandTypes.includes(
|
|
998
|
-
msg.type
|
|
999
|
-
) ? "Sent" : "Published";
|
|
1000
|
-
return tagOutputMessage(msg, action);
|
|
1001
|
-
});
|
|
1002
|
-
const messagesToAppend = options.separateInputInboxFromProcessing && hasWorkflowPrefix ? [...taggedOutputMessages] : [inputToStore, ...taggedOutputMessages];
|
|
1003
|
-
if (messagesToAppend.length === 0) {
|
|
1004
|
-
return emptyHandlerResult(currentStreamVersion);
|
|
1005
|
-
}
|
|
1006
|
-
const expectedStreamVersion = _nullishCoalesce(_optionalChain([handleOptions, 'optionalAccess', _52 => _52.expectedStreamVersion]), () => ( (aggregationResult.streamExists ? currentStreamVersion : STREAM_DOES_NOT_EXIST)));
|
|
1007
|
-
const appendResult = await eventStore.appendToStream(
|
|
1008
|
-
streamName,
|
|
1009
|
-
// TODO: Fix this cast
|
|
1010
|
-
messagesToAppend,
|
|
1011
|
-
{
|
|
1012
|
-
...handleOptions,
|
|
1013
|
-
expectedStreamVersion
|
|
1014
|
-
}
|
|
1015
|
-
);
|
|
1016
|
-
return {
|
|
1017
|
-
...appendResult,
|
|
1018
|
-
newMessages: outputMessages
|
|
1019
|
-
};
|
|
1020
|
-
});
|
|
1021
|
-
return result;
|
|
1022
|
-
},
|
|
1023
|
-
fromWorkflowHandlerRetryOptions(
|
|
1024
|
-
handleOptions && "retry" in handleOptions ? handleOptions.retry : options.retry
|
|
1025
|
-
)
|
|
1026
|
-
);
|
|
1027
|
-
var withSession2 = (eventStore, callback) => {
|
|
1028
|
-
const sessionFactory = canCreateEventStoreSession(eventStore) ? eventStore : nulloSessionFactory(eventStore);
|
|
1029
|
-
return sessionFactory.withSession(callback);
|
|
1030
|
-
};
|
|
1031
|
-
var getWorkflowId = (options) => `emt:processor:workflow:${options.workflowName}`;
|
|
1032
|
-
var workflowProcessor = (options) => {
|
|
1033
|
-
const { workflow, ...rest } = options;
|
|
1034
|
-
const inputs = [...options.inputs.commands, ...options.inputs.events];
|
|
1035
|
-
let canHandle = inputs;
|
|
1036
|
-
if (options.separateInputInboxFromProcessing)
|
|
1037
|
-
canHandle = [
|
|
1038
|
-
...canHandle,
|
|
1039
|
-
...options.inputs.commands.map((t) => `${workflow.name}:${t}`),
|
|
1040
|
-
...options.inputs.events.map((t) => `${workflow.name}:${t}`)
|
|
1041
|
-
];
|
|
1042
|
-
if (options.outputHandler)
|
|
1043
|
-
canHandle = [...canHandle, ...options.outputHandler.canHandle];
|
|
1044
|
-
const handle = WorkflowHandler(options);
|
|
1045
|
-
return reactor({
|
|
1046
|
-
...rest,
|
|
1047
|
-
processorId: _nullishCoalesce(options.processorId, () => ( getWorkflowId({ workflowName: workflow.name }))),
|
|
1048
|
-
canHandle,
|
|
1049
|
-
type: MessageProcessorType.PROJECTOR,
|
|
1050
|
-
eachMessage: async (message2, context) => {
|
|
1051
|
-
const messageType = message2.type;
|
|
1052
|
-
const metadata = message2.metadata;
|
|
1053
|
-
const isInput = _optionalChain([metadata, 'optionalAccess', _53 => _53.input]) === true;
|
|
1054
|
-
if (isInput || inputs.includes(messageType)) {
|
|
1055
|
-
const result = await handle(
|
|
1056
|
-
context.connection.messageStore,
|
|
1057
|
-
message2,
|
|
1058
|
-
context
|
|
1059
|
-
);
|
|
1060
|
-
if (options.stopAfter && result.newMessages.length > 0) {
|
|
1061
|
-
for (const outputMessage of result.newMessages) {
|
|
1062
|
-
if (options.stopAfter(
|
|
1063
|
-
outputMessage
|
|
1064
|
-
)) {
|
|
1065
|
-
return { type: "STOP", reason: "Stop condition reached" };
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
return;
|
|
1070
|
-
}
|
|
1071
|
-
if (_optionalChain([options, 'access', _54 => _54.outputHandler, 'optionalAccess', _55 => _55.canHandle, 'access', _56 => _56.includes, 'call', _57 => _57(messageType)]) === true) {
|
|
1072
|
-
const recordedMessage = message2;
|
|
1073
|
-
const handledOutputMessages = options.outputHandler.eachBatch ? await options.outputHandler.eachBatch([recordedMessage], context) : await options.outputHandler.eachMessage(recordedMessage, context);
|
|
1074
|
-
if (handledOutputMessages instanceof EmmettError) {
|
|
1075
|
-
return {
|
|
1076
|
-
type: "STOP",
|
|
1077
|
-
reason: "Routing error",
|
|
1078
|
-
error: handledOutputMessages
|
|
1079
|
-
};
|
|
1080
|
-
}
|
|
1081
|
-
const messagesToAppend = Array.isArray(handledOutputMessages) ? handledOutputMessages : handledOutputMessages ? [handledOutputMessages] : [];
|
|
1082
|
-
if (messagesToAppend.length === 0) {
|
|
1083
|
-
return;
|
|
1084
|
-
}
|
|
1085
|
-
const workflowId = options.getWorkflowId(
|
|
1086
|
-
message2
|
|
1087
|
-
);
|
|
1088
|
-
if (!workflowId) return;
|
|
1089
|
-
const streamName = options.mapWorkflowId ? options.mapWorkflowId(workflowId) : workflowStreamName({
|
|
1090
|
-
workflowName: workflow.name,
|
|
1091
|
-
workflowId
|
|
1092
|
-
});
|
|
1093
|
-
await context.connection.messageStore.appendToStream(
|
|
1094
|
-
streamName,
|
|
1095
|
-
messagesToAppend
|
|
1096
|
-
);
|
|
1097
|
-
return;
|
|
1098
|
-
}
|
|
1099
|
-
return;
|
|
1100
|
-
}
|
|
1101
|
-
});
|
|
1102
|
-
};
|
|
1103
|
-
|
|
1104
|
-
// src/eventStore/projections/pongo/pongoProjections.ts
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
var _pongo = require('@event-driven-io/pongo');
|
|
1108
|
-
var pongoProjection = ({
|
|
1109
|
-
name,
|
|
1110
|
-
kind,
|
|
1111
|
-
version,
|
|
1112
|
-
truncate,
|
|
1113
|
-
handle,
|
|
1114
|
-
canHandle,
|
|
1115
|
-
eventsOptions
|
|
1116
|
-
}) => sqliteProjection({
|
|
1117
|
-
name,
|
|
1118
|
-
version,
|
|
1119
|
-
kind: _nullishCoalesce(kind, () => ( "emt:projections:postgresql:pongo:generic")),
|
|
1120
|
-
canHandle,
|
|
1121
|
-
eventsOptions,
|
|
1122
|
-
handle: async (events, context) => {
|
|
1123
|
-
const { connection } = context;
|
|
1124
|
-
const driver = await pongoDriverRegistry.tryResolve(
|
|
1125
|
-
context.driverType
|
|
1126
|
-
);
|
|
1127
|
-
const pongo = _pongo.pongoClient.call(void 0, {
|
|
1128
|
-
driver,
|
|
1129
|
-
connectionOptions: { connection }
|
|
1130
|
-
});
|
|
1131
|
-
try {
|
|
1132
|
-
await handle(events, {
|
|
1133
|
-
...context,
|
|
1134
|
-
pongo
|
|
1135
|
-
});
|
|
1136
|
-
} finally {
|
|
1137
|
-
await pongo.close();
|
|
1138
|
-
}
|
|
1139
|
-
},
|
|
1140
|
-
truncate: truncate ? async (context) => {
|
|
1141
|
-
const { connection } = context;
|
|
1142
|
-
const driver = await pongoDriverRegistry.tryResolve(
|
|
1143
|
-
context.driverType
|
|
1144
|
-
);
|
|
1145
|
-
const pongo = _pongo.pongoClient.call(void 0, {
|
|
1146
|
-
driver,
|
|
1147
|
-
connectionOptions: { connection }
|
|
1148
|
-
});
|
|
1149
|
-
try {
|
|
1150
|
-
await truncate({
|
|
1151
|
-
...context,
|
|
1152
|
-
pongo
|
|
1153
|
-
});
|
|
1154
|
-
} finally {
|
|
1155
|
-
await pongo.close();
|
|
1156
|
-
}
|
|
1157
|
-
} : void 0
|
|
150
|
+
const documentMatchingExists = (options) => (assertOptions) => withCollection(async (collection) => {
|
|
151
|
+
(0, _event_driven_io_emmett.assertThatArray)(await collection.find("withId" in options ? { _id: options.withId } : options.matchingFilter)).isNotEmpty();
|
|
152
|
+
}, {
|
|
153
|
+
...options,
|
|
154
|
+
...assertOptions
|
|
1158
155
|
});
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
version: options.version,
|
|
1165
|
-
kind: _nullishCoalesce(options.kind, () => ( "emt:projections:postgresql:pongo:multi_stream")),
|
|
1166
|
-
eventsOptions: options.eventsOptions,
|
|
1167
|
-
handle: async (events, { pongo }) => {
|
|
1168
|
-
const collection = pongo.db().collection(
|
|
1169
|
-
collectionNameWithVersion,
|
|
1170
|
-
options.collectionOptions
|
|
1171
|
-
);
|
|
1172
|
-
const eventsByDocumentId = events.map((event) => {
|
|
1173
|
-
const documentId = getDocumentId(event);
|
|
1174
|
-
return {
|
|
1175
|
-
documentId,
|
|
1176
|
-
event
|
|
1177
|
-
};
|
|
1178
|
-
}).reduce((acc, { documentId, event }) => {
|
|
1179
|
-
if (!acc.has(documentId)) {
|
|
1180
|
-
acc.set(documentId, []);
|
|
1181
|
-
}
|
|
1182
|
-
acc.get(documentId).push(event);
|
|
1183
|
-
return acc;
|
|
1184
|
-
}, /* @__PURE__ */ new Map());
|
|
1185
|
-
await collection.handle(
|
|
1186
|
-
[...eventsByDocumentId.keys()],
|
|
1187
|
-
(document, id) => {
|
|
1188
|
-
const events2 = eventsByDocumentId.get(id);
|
|
1189
|
-
return reduceAsync(
|
|
1190
|
-
events2,
|
|
1191
|
-
async (acc, event) => await options.evolve(acc, event),
|
|
1192
|
-
_nullishCoalesce(document, () => ( ("initialState" in options ? options.initialState() : null)))
|
|
1193
|
-
);
|
|
1194
|
-
}
|
|
1195
|
-
);
|
|
1196
|
-
},
|
|
1197
|
-
canHandle,
|
|
1198
|
-
truncate: async (context) => {
|
|
1199
|
-
const { connection } = context;
|
|
1200
|
-
const driver = await pongoDriverRegistry.tryResolve(
|
|
1201
|
-
context.driverType
|
|
1202
|
-
);
|
|
1203
|
-
const pongo = _pongo.pongoClient.call(void 0, {
|
|
1204
|
-
driver,
|
|
1205
|
-
connectionOptions: { connection }
|
|
1206
|
-
});
|
|
1207
|
-
try {
|
|
1208
|
-
await pongo.db().collection(
|
|
1209
|
-
collectionNameWithVersion,
|
|
1210
|
-
options.collectionOptions
|
|
1211
|
-
).deleteMany();
|
|
1212
|
-
} finally {
|
|
1213
|
-
await pongo.close();
|
|
1214
|
-
}
|
|
1215
|
-
},
|
|
1216
|
-
init: async (context) => {
|
|
1217
|
-
const { connection } = context;
|
|
1218
|
-
const driver = await pongoDriverRegistry.tryResolve(
|
|
1219
|
-
context.driverType
|
|
1220
|
-
);
|
|
1221
|
-
const pongo = _pongo.pongoClient.call(void 0, {
|
|
1222
|
-
connectionOptions: { connection },
|
|
1223
|
-
driver
|
|
1224
|
-
});
|
|
1225
|
-
try {
|
|
1226
|
-
await pongo.db().collection(
|
|
1227
|
-
collectionNameWithVersion,
|
|
1228
|
-
options.collectionOptions
|
|
1229
|
-
).schema.migrate();
|
|
1230
|
-
} finally {
|
|
1231
|
-
await pongo.close();
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
});
|
|
1235
|
-
};
|
|
1236
|
-
var pongoSingleStreamProjection = (options) => {
|
|
1237
|
-
return pongoMultiStreamProjection({
|
|
1238
|
-
...options,
|
|
1239
|
-
kind: "emt:projections:postgresql:pongo:single_stream",
|
|
1240
|
-
getDocumentId: _nullishCoalesce(options.getDocumentId, () => ( ((event) => event.metadata.streamName)))
|
|
1241
|
-
});
|
|
1242
|
-
};
|
|
1243
|
-
|
|
1244
|
-
// src/eventStore/projections/pongo/pongoProjectionSpec.ts
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
var withCollection = async (handle, options) => {
|
|
1249
|
-
const { connection, inDatabase, inCollection } = options;
|
|
1250
|
-
const driver = await pongoDriverRegistry.tryResolve(
|
|
1251
|
-
connection.driverType
|
|
1252
|
-
);
|
|
1253
|
-
const pongo = _pongo.pongoClient.call(void 0, {
|
|
1254
|
-
connectionOptions: { connection },
|
|
1255
|
-
driver
|
|
1256
|
-
});
|
|
1257
|
-
try {
|
|
1258
|
-
const collection = pongo.db(inDatabase).collection(inCollection);
|
|
1259
|
-
return handle(collection);
|
|
1260
|
-
} finally {
|
|
1261
|
-
await pongo.close();
|
|
1262
|
-
}
|
|
1263
|
-
};
|
|
1264
|
-
var withoutIdAndVersion = (doc) => {
|
|
1265
|
-
const { _id, _version, ...without } = doc;
|
|
1266
|
-
return without;
|
|
1267
|
-
};
|
|
1268
|
-
var assertDocumentsEqual = (actual, expected) => {
|
|
1269
|
-
if ("_id" in expected)
|
|
1270
|
-
assertEqual(
|
|
1271
|
-
expected._id,
|
|
1272
|
-
actual._id,
|
|
1273
|
-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
1274
|
-
`Document ids are not matching! Expected: ${expected._id}, Actual: ${actual._id}`
|
|
1275
|
-
);
|
|
1276
|
-
return assertDeepEqual(
|
|
1277
|
-
withoutIdAndVersion(actual),
|
|
1278
|
-
withoutIdAndVersion(expected)
|
|
1279
|
-
);
|
|
1280
|
-
};
|
|
1281
|
-
var documentExists = (document, options) => (assertOptions) => withCollection(
|
|
1282
|
-
async (collection) => {
|
|
1283
|
-
const result = await collection.findOne(
|
|
1284
|
-
"withId" in options ? { _id: options.withId } : options.matchingFilter
|
|
1285
|
-
);
|
|
1286
|
-
assertIsNotNull(result);
|
|
1287
|
-
assertDocumentsEqual(result, document);
|
|
1288
|
-
},
|
|
1289
|
-
{ ...options, ...assertOptions }
|
|
1290
|
-
);
|
|
1291
|
-
var documentsAreTheSame = (documents, options) => (assertOptions) => withCollection(
|
|
1292
|
-
async (collection) => {
|
|
1293
|
-
const result = await collection.find(
|
|
1294
|
-
"withId" in options ? { _id: options.withId } : options.matchingFilter
|
|
1295
|
-
);
|
|
1296
|
-
assertEqual(
|
|
1297
|
-
documents.length,
|
|
1298
|
-
result.length,
|
|
1299
|
-
"Different Documents Count than expected"
|
|
1300
|
-
);
|
|
1301
|
-
for (let i = 0; i < documents.length; i++) {
|
|
1302
|
-
assertThatArray(result).contains(documents[i]);
|
|
1303
|
-
}
|
|
1304
|
-
},
|
|
1305
|
-
{ ...options, ...assertOptions }
|
|
1306
|
-
);
|
|
1307
|
-
var documentsMatchingHaveCount = (expectedCount, options) => (assertOptions) => withCollection(
|
|
1308
|
-
async (collection) => {
|
|
1309
|
-
const result = await collection.find(
|
|
1310
|
-
"withId" in options ? { _id: options.withId } : options.matchingFilter
|
|
1311
|
-
);
|
|
1312
|
-
assertEqual(
|
|
1313
|
-
expectedCount,
|
|
1314
|
-
result.length,
|
|
1315
|
-
"Different Documents Count than expected"
|
|
1316
|
-
);
|
|
1317
|
-
},
|
|
1318
|
-
{ ...options, ...assertOptions }
|
|
1319
|
-
);
|
|
1320
|
-
var documentMatchingExists = (options) => (assertOptions) => withCollection(
|
|
1321
|
-
async (collection) => {
|
|
1322
|
-
const result = await collection.find(
|
|
1323
|
-
"withId" in options ? { _id: options.withId } : options.matchingFilter
|
|
1324
|
-
);
|
|
1325
|
-
assertThatArray(result).isNotEmpty();
|
|
1326
|
-
},
|
|
1327
|
-
{ ...options, ...assertOptions }
|
|
1328
|
-
);
|
|
1329
|
-
var documentDoesNotExist = (options) => (assertOptions) => withCollection(
|
|
1330
|
-
async (collection) => {
|
|
1331
|
-
const result = await collection.findOne(
|
|
1332
|
-
"withId" in options ? { _id: options.withId } : options.matchingFilter
|
|
1333
|
-
);
|
|
1334
|
-
assertIsNull(result);
|
|
1335
|
-
},
|
|
1336
|
-
{ ...options, ...assertOptions }
|
|
1337
|
-
);
|
|
1338
|
-
var expectPongoDocuments = {
|
|
1339
|
-
fromCollection: (collectionName) => {
|
|
1340
|
-
return {
|
|
1341
|
-
withId: (id) => {
|
|
1342
|
-
return {
|
|
1343
|
-
toBeEqual: (document) => documentExists(document, {
|
|
1344
|
-
withId: id,
|
|
1345
|
-
inCollection: collectionName
|
|
1346
|
-
}),
|
|
1347
|
-
toExist: () => documentMatchingExists({
|
|
1348
|
-
withId: id,
|
|
1349
|
-
inCollection: collectionName
|
|
1350
|
-
}),
|
|
1351
|
-
notToExist: () => documentDoesNotExist({
|
|
1352
|
-
withId: id,
|
|
1353
|
-
inCollection: collectionName
|
|
1354
|
-
})
|
|
1355
|
-
};
|
|
1356
|
-
},
|
|
1357
|
-
matching: (filter) => {
|
|
1358
|
-
return {
|
|
1359
|
-
toBeTheSame: (documents) => documentsAreTheSame(documents, {
|
|
1360
|
-
matchingFilter: filter,
|
|
1361
|
-
inCollection: collectionName
|
|
1362
|
-
}),
|
|
1363
|
-
toHaveCount: (expectedCount) => documentsMatchingHaveCount(expectedCount, {
|
|
1364
|
-
matchingFilter: filter,
|
|
1365
|
-
inCollection: collectionName
|
|
1366
|
-
}),
|
|
1367
|
-
toExist: () => documentMatchingExists({
|
|
1368
|
-
matchingFilter: filter,
|
|
1369
|
-
inCollection: collectionName
|
|
1370
|
-
}),
|
|
1371
|
-
notToExist: () => documentDoesNotExist({
|
|
1372
|
-
matchingFilter: filter,
|
|
1373
|
-
inCollection: collectionName
|
|
1374
|
-
})
|
|
1375
|
-
};
|
|
1376
|
-
}
|
|
1377
|
-
};
|
|
1378
|
-
}
|
|
1379
|
-
};
|
|
1380
|
-
|
|
1381
|
-
// src/eventStore/projections/sqliteProjection.ts
|
|
1382
|
-
var handleProjections = async (options) => {
|
|
1383
|
-
const {
|
|
1384
|
-
projections: allProjections,
|
|
1385
|
-
events,
|
|
1386
|
-
connection,
|
|
1387
|
-
execute,
|
|
1388
|
-
driverType
|
|
1389
|
-
} = options;
|
|
1390
|
-
const eventTypes = events.map((e) => e.type);
|
|
1391
|
-
for (const projection2 of allProjections) {
|
|
1392
|
-
if (!projection2.canHandle.some((type) => eventTypes.includes(type))) {
|
|
1393
|
-
continue;
|
|
1394
|
-
}
|
|
1395
|
-
await projection2.handle(events, {
|
|
1396
|
-
connection,
|
|
1397
|
-
execute,
|
|
1398
|
-
driverType
|
|
1399
|
-
});
|
|
1400
|
-
}
|
|
1401
|
-
};
|
|
1402
|
-
var sqliteProjection = (definition) => projection(definition);
|
|
1403
|
-
var sqliteRawBatchSQLProjection = (options) => sqliteProjection({
|
|
1404
|
-
name: options.name,
|
|
1405
|
-
kind: _nullishCoalesce(options.kind, () => ( "emt:projections:sqlite:raw_sql:batch")),
|
|
1406
|
-
version: options.version,
|
|
1407
|
-
canHandle: options.canHandle,
|
|
1408
|
-
eventsOptions: options.eventsOptions,
|
|
1409
|
-
handle: async (events, context) => {
|
|
1410
|
-
const sqls = await options.evolve(events, context);
|
|
1411
|
-
await context.execute.batchCommand(sqls);
|
|
1412
|
-
},
|
|
1413
|
-
init: async (initOptions) => {
|
|
1414
|
-
const initSQL = options.init ? await options.init(initOptions) : void 0;
|
|
1415
|
-
if (initSQL) {
|
|
1416
|
-
if (Array.isArray(initSQL)) {
|
|
1417
|
-
await initOptions.context.execute.batchCommand(initSQL);
|
|
1418
|
-
} else {
|
|
1419
|
-
await initOptions.context.execute.command(initSQL);
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
156
|
+
const documentDoesNotExist = (options) => (assertOptions) => withCollection(async (collection) => {
|
|
157
|
+
(0, _event_driven_io_emmett.assertIsNull)(await collection.findOne("withId" in options ? { _id: options.withId } : options.matchingFilter));
|
|
158
|
+
}, {
|
|
159
|
+
...options,
|
|
160
|
+
...assertOptions
|
|
1423
161
|
});
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
};
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
};
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
};
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
const currentStreamVersion = await getLastStreamPosition(
|
|
1689
|
-
execute,
|
|
1690
|
-
streamId,
|
|
1691
|
-
expectedStreamVersion
|
|
1692
|
-
);
|
|
1693
|
-
expectedStreamVersion ??= _nullishCoalesce(currentStreamVersion, () => ( 0n));
|
|
1694
|
-
if (expectedStreamVersion !== currentStreamVersion) {
|
|
1695
|
-
throw new ExpectedVersionConflictError(
|
|
1696
|
-
currentStreamVersion,
|
|
1697
|
-
expectedStreamVersion
|
|
1698
|
-
);
|
|
1699
|
-
}
|
|
1700
|
-
const streamSQL = expectedStreamVersion === 0n ? _dumbo.SQL`INSERT INTO ${identifier(streamsTable.name)}
|
|
162
|
+
const expectPongoDocuments = { fromCollection: (collectionName) => {
|
|
163
|
+
return {
|
|
164
|
+
withId: (id) => {
|
|
165
|
+
return {
|
|
166
|
+
toBeEqual: (document) => documentExists(document, {
|
|
167
|
+
withId: id,
|
|
168
|
+
inCollection: collectionName
|
|
169
|
+
}),
|
|
170
|
+
toExist: () => documentMatchingExists({
|
|
171
|
+
withId: id,
|
|
172
|
+
inCollection: collectionName
|
|
173
|
+
}),
|
|
174
|
+
notToExist: () => documentDoesNotExist({
|
|
175
|
+
withId: id,
|
|
176
|
+
inCollection: collectionName
|
|
177
|
+
})
|
|
178
|
+
};
|
|
179
|
+
},
|
|
180
|
+
matching: (filter) => {
|
|
181
|
+
return {
|
|
182
|
+
toBeTheSame: (documents) => documentsAreTheSame(documents, {
|
|
183
|
+
matchingFilter: filter,
|
|
184
|
+
inCollection: collectionName
|
|
185
|
+
}),
|
|
186
|
+
toHaveCount: (expectedCount) => documentsMatchingHaveCount(expectedCount, {
|
|
187
|
+
matchingFilter: filter,
|
|
188
|
+
inCollection: collectionName
|
|
189
|
+
}),
|
|
190
|
+
toExist: () => documentMatchingExists({
|
|
191
|
+
matchingFilter: filter,
|
|
192
|
+
inCollection: collectionName
|
|
193
|
+
}),
|
|
194
|
+
notToExist: () => documentDoesNotExist({
|
|
195
|
+
matchingFilter: filter,
|
|
196
|
+
inCollection: collectionName
|
|
197
|
+
})
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
} };
|
|
202
|
+
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region src/eventStore/projections/sqliteProjection.ts
|
|
205
|
+
const handleProjections = async (options) => {
|
|
206
|
+
const { projections: allProjections, events, connection, execute, driverType } = options;
|
|
207
|
+
const eventTypes = events.map((e) => e.type);
|
|
208
|
+
for (const projection of allProjections) {
|
|
209
|
+
if (!projection.canHandle.some((type) => eventTypes.includes(type))) continue;
|
|
210
|
+
await projection.handle(events, {
|
|
211
|
+
connection,
|
|
212
|
+
execute,
|
|
213
|
+
driverType
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
const sqliteProjection = (definition) => (0, _event_driven_io_emmett.projection)(definition);
|
|
218
|
+
const sqliteRawBatchSQLProjection = (options) => sqliteProjection({
|
|
219
|
+
name: options.name,
|
|
220
|
+
kind: options.kind ?? "emt:projections:sqlite:raw_sql:batch",
|
|
221
|
+
version: options.version,
|
|
222
|
+
canHandle: options.canHandle,
|
|
223
|
+
eventsOptions: options.eventsOptions,
|
|
224
|
+
handle: async (events, context) => {
|
|
225
|
+
const sqls = await options.evolve(events, context);
|
|
226
|
+
await context.execute.batchCommand(sqls);
|
|
227
|
+
},
|
|
228
|
+
init: async (initOptions) => {
|
|
229
|
+
const initSQL = options.init ? await options.init(initOptions) : void 0;
|
|
230
|
+
if (initSQL) if (Array.isArray(initSQL)) await initOptions.context.execute.batchCommand(initSQL);
|
|
231
|
+
else await initOptions.context.execute.command(initSQL);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
const sqliteRawSQLProjection = (options) => {
|
|
235
|
+
const { evolve, kind, ...rest } = options;
|
|
236
|
+
return sqliteRawBatchSQLProjection({
|
|
237
|
+
kind: kind ?? "emt:projections:sqlite:raw:_sql:single",
|
|
238
|
+
...rest,
|
|
239
|
+
evolve: async (events, context) => {
|
|
240
|
+
const sqls = [];
|
|
241
|
+
for (const event of events) {
|
|
242
|
+
const pendingSqls = await evolve(event, context);
|
|
243
|
+
if (Array.isArray(pendingSqls)) sqls.push(...pendingSqls);
|
|
244
|
+
else sqls.push(pendingSqls);
|
|
245
|
+
}
|
|
246
|
+
return sqls;
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region src/eventStore/projections/sqliteProjectionSpec.ts
|
|
253
|
+
const SQLiteProjectionSpec = { for: (options) => {
|
|
254
|
+
{
|
|
255
|
+
const driverType = options.driver.driverType;
|
|
256
|
+
const pool = options.pool ?? (0, _event_driven_io_dumbo.dumbo)({
|
|
257
|
+
serialization: options.serialization,
|
|
258
|
+
transactionOptions: {
|
|
259
|
+
allowNestedTransactions: true,
|
|
260
|
+
mode: "session_based"
|
|
261
|
+
},
|
|
262
|
+
...options.driver.mapToDumboOptions(options)
|
|
263
|
+
});
|
|
264
|
+
const projection = options.projection;
|
|
265
|
+
let wasInitialized = false;
|
|
266
|
+
return (givenEvents) => {
|
|
267
|
+
return { when: (events, options) => {
|
|
268
|
+
const allEvents = [];
|
|
269
|
+
const run = async (connection) => {
|
|
270
|
+
let globalPosition = 0n;
|
|
271
|
+
const numberOfTimes = options?.numberOfTimes ?? 1;
|
|
272
|
+
for (const event of [...givenEvents, ...Array.from({ length: numberOfTimes }).flatMap(() => events)]) {
|
|
273
|
+
const metadata = {
|
|
274
|
+
checkpoint: (0, _event_driven_io_emmett.bigIntProcessorCheckpoint)(++globalPosition),
|
|
275
|
+
globalPosition,
|
|
276
|
+
streamPosition: globalPosition,
|
|
277
|
+
streamName: `test-${(0, uuid.v4)()}`,
|
|
278
|
+
messageId: (0, uuid.v4)()
|
|
279
|
+
};
|
|
280
|
+
allEvents.push({
|
|
281
|
+
...event,
|
|
282
|
+
kind: "Event",
|
|
283
|
+
metadata: {
|
|
284
|
+
...metadata,
|
|
285
|
+
..."metadata" in event ? event.metadata ?? {} : {}
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
if (!wasInitialized && projection.init) {
|
|
290
|
+
await projection.init({
|
|
291
|
+
registrationType: "async",
|
|
292
|
+
status: "active",
|
|
293
|
+
context: {
|
|
294
|
+
execute: connection.execute,
|
|
295
|
+
connection,
|
|
296
|
+
driverType
|
|
297
|
+
},
|
|
298
|
+
version: projection.version ?? 1
|
|
299
|
+
});
|
|
300
|
+
wasInitialized = true;
|
|
301
|
+
}
|
|
302
|
+
await connection.withTransaction(() => handleProjections({
|
|
303
|
+
events: allEvents,
|
|
304
|
+
projections: [projection],
|
|
305
|
+
execute: connection.execute,
|
|
306
|
+
connection,
|
|
307
|
+
driverType
|
|
308
|
+
}));
|
|
309
|
+
};
|
|
310
|
+
return {
|
|
311
|
+
then: (assert, message) => pool.withConnection(async (connection) => {
|
|
312
|
+
await run(connection);
|
|
313
|
+
const succeeded = await assert({ connection });
|
|
314
|
+
if (succeeded !== void 0 && succeeded === false) (0, _event_driven_io_emmett.assertFails)(message ?? "Projection specification didn't match the criteria");
|
|
315
|
+
}),
|
|
316
|
+
thenThrows: (...args) => pool.withConnection(async (connection) => {
|
|
317
|
+
try {
|
|
318
|
+
await run(connection);
|
|
319
|
+
throw new _event_driven_io_emmett.AssertionError("Handler did not fail as expected");
|
|
320
|
+
} catch (error) {
|
|
321
|
+
if (error instanceof _event_driven_io_emmett.AssertionError) throw error;
|
|
322
|
+
if (args.length === 0) return;
|
|
323
|
+
if (!(0, _event_driven_io_emmett.isErrorConstructor)(args[0])) {
|
|
324
|
+
(0, _event_driven_io_emmett.assertTrue)(args[0](error), `Error didn't match the error condition: ${error?.toString()}`);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
(0, _event_driven_io_emmett.assertTrue)(error instanceof args[0], `Caught error is not an instance of the expected type: ${error?.toString()}`);
|
|
328
|
+
if (args[1]) (0, _event_driven_io_emmett.assertTrue)(args[1](error), `Error didn't match the error condition: ${error?.toString()}`);
|
|
329
|
+
}
|
|
330
|
+
})
|
|
331
|
+
};
|
|
332
|
+
} };
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
} };
|
|
336
|
+
const eventInStream = (streamName, event) => {
|
|
337
|
+
return {
|
|
338
|
+
...event,
|
|
339
|
+
metadata: {
|
|
340
|
+
...event.metadata ?? {},
|
|
341
|
+
streamName: event.metadata?.streamName ?? streamName
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
};
|
|
345
|
+
const eventsInStream = (streamName, events) => {
|
|
346
|
+
return events.map((e) => eventInStream(streamName, e));
|
|
347
|
+
};
|
|
348
|
+
const newEventsInStream = eventsInStream;
|
|
349
|
+
const assertSQLQueryResultMatches = (sql, rows) => async ({ connection }) => {
|
|
350
|
+
const result = await connection.execute.query(sql);
|
|
351
|
+
(0, _event_driven_io_emmett.assertThatArray)(rows).containsExactlyInAnyOrder(result.rows);
|
|
352
|
+
};
|
|
353
|
+
const expectSQL = { query: (sql) => ({ resultRows: { toBeTheSame: (rows) => assertSQLQueryResultMatches(sql, rows) } }) };
|
|
354
|
+
|
|
355
|
+
//#endregion
|
|
356
|
+
//#region src/eventStore/schema/typing.ts
|
|
357
|
+
const emmettPrefix = "emt";
|
|
358
|
+
const globalTag = "global";
|
|
359
|
+
const defaultTag = `${"emt"}:default`;
|
|
360
|
+
const unknownTag = `${"emt"}:unknown`;
|
|
361
|
+
const globalNames = { module: `${"emt"}:module:${globalTag}` };
|
|
362
|
+
const columns = {
|
|
363
|
+
partition: { name: "partition" },
|
|
364
|
+
isArchived: { name: "is_archived" }
|
|
365
|
+
};
|
|
366
|
+
const streamsTable = {
|
|
367
|
+
name: `${"emt"}_streams`,
|
|
368
|
+
columns: {
|
|
369
|
+
partition: columns.partition,
|
|
370
|
+
isArchived: columns.isArchived
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
const messagesTable = {
|
|
374
|
+
name: `${"emt"}_messages`,
|
|
375
|
+
columns: {
|
|
376
|
+
partition: columns.partition,
|
|
377
|
+
isArchived: columns.isArchived
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
const processorsTable = { name: `${"emt"}_processors` };
|
|
381
|
+
const projectionsTable = { name: `${"emt"}_projections` };
|
|
382
|
+
|
|
383
|
+
//#endregion
|
|
384
|
+
//#region src/eventStore/schema/appendToStream.ts
|
|
385
|
+
const { identifier: identifier$7, merge } = _event_driven_io_dumbo.SQL;
|
|
386
|
+
const appendToStream = async (connection, streamName, streamType, messages, options) => {
|
|
387
|
+
if (messages.length === 0) return { success: false };
|
|
388
|
+
const expectedStreamVersion = toExpectedVersion(options?.expectedStreamVersion);
|
|
389
|
+
const messagesToAppend = messages.map((m, i) => ({
|
|
390
|
+
...m,
|
|
391
|
+
kind: m.kind ?? "Event",
|
|
392
|
+
metadata: {
|
|
393
|
+
streamName,
|
|
394
|
+
messageId: (0, uuid.v4)(),
|
|
395
|
+
streamPosition: BigInt(i + 1),
|
|
396
|
+
..."metadata" in m ? m.metadata ?? {} : {}
|
|
397
|
+
}
|
|
398
|
+
}));
|
|
399
|
+
try {
|
|
400
|
+
return await connection.withTransaction(async (transaction) => {
|
|
401
|
+
const result = await appendToStreamRaw(transaction.execute, streamName, streamType, (0, _event_driven_io_emmett.downcastRecordedMessages)(messagesToAppend, options?.schema?.versioning), { expectedStreamVersion });
|
|
402
|
+
if (options?.onBeforeCommit) await options.onBeforeCommit(messagesToAppend, { connection });
|
|
403
|
+
return {
|
|
404
|
+
success: true,
|
|
405
|
+
result
|
|
406
|
+
};
|
|
407
|
+
});
|
|
408
|
+
} catch (err) {
|
|
409
|
+
if ((0, _event_driven_io_emmett.isExpectedVersionConflictError)(err) || _event_driven_io_dumbo.DumboError.isInstanceOf(err, { errorType: _event_driven_io_dumbo.UniqueConstraintError.ErrorType }) || _event_driven_io_dumbo.DumboError.isInstanceOf(err, { errorType: _event_driven_io_dumbo.BatchCommandNoChangesError.ErrorType })) return { success: false };
|
|
410
|
+
throw err;
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
const toExpectedVersion = (expected) => {
|
|
414
|
+
if (expected === void 0) return null;
|
|
415
|
+
if (expected === _event_driven_io_emmett.NO_CONCURRENCY_CHECK) return null;
|
|
416
|
+
if (expected == _event_driven_io_emmett.STREAM_DOES_NOT_EXIST) return null;
|
|
417
|
+
if (expected == _event_driven_io_emmett.STREAM_EXISTS) return null;
|
|
418
|
+
return expected;
|
|
419
|
+
};
|
|
420
|
+
const appendToStreamRaw = async (execute, streamId, streamType, messages, options) => {
|
|
421
|
+
let expectedStreamVersion = options?.expectedStreamVersion ?? null;
|
|
422
|
+
const currentStreamVersion = await getLastStreamPosition(execute, streamId, expectedStreamVersion);
|
|
423
|
+
expectedStreamVersion ??= currentStreamVersion ?? 0n;
|
|
424
|
+
if (expectedStreamVersion !== currentStreamVersion) throw new _event_driven_io_emmett.ExpectedVersionConflictError(currentStreamVersion, expectedStreamVersion);
|
|
425
|
+
const streamSQL = expectedStreamVersion === 0n ? _event_driven_io_dumbo.SQL`INSERT INTO ${identifier$7(streamsTable.name)}
|
|
1701
426
|
(stream_id, stream_position, partition, stream_type, stream_metadata, is_archived)
|
|
1702
427
|
VALUES (
|
|
1703
428
|
${streamId},
|
|
1704
429
|
${messages.length},
|
|
1705
|
-
${
|
|
430
|
+
${options?.partition ?? streamsTable.columns.partition},
|
|
1706
431
|
${streamType},
|
|
1707
432
|
'[]',
|
|
1708
433
|
false
|
|
1709
434
|
)
|
|
1710
435
|
RETURNING stream_position;
|
|
1711
|
-
` :
|
|
436
|
+
` : _event_driven_io_dumbo.SQL`UPDATE ${identifier$7(streamsTable.name)}
|
|
1712
437
|
SET stream_position = stream_position + ${messages.length}
|
|
1713
438
|
WHERE stream_id = ${streamId}
|
|
1714
439
|
AND stream_position = ${expectedStreamVersion}
|
|
1715
|
-
AND partition = ${
|
|
440
|
+
AND partition = ${options?.partition ?? streamsTable.columns.partition}
|
|
1716
441
|
AND is_archived = false
|
|
1717
442
|
RETURNING stream_position;
|
|
1718
443
|
`;
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
throw new ExpectedVersionConflictError(0n, _nullishCoalesce(expectedStreamVersion, () => ( 0n)));
|
|
1731
|
-
if (!globalPosition) throw new Error("Could not find global position");
|
|
1732
|
-
return {
|
|
1733
|
-
success: true,
|
|
1734
|
-
nextStreamPosition: BigInt(streamPosition),
|
|
1735
|
-
lastGlobalPosition: BigInt(globalPosition)
|
|
1736
|
-
};
|
|
444
|
+
const insertSQL = buildMessageInsertQuery(messages, expectedStreamVersion, streamId, options?.partition?.toString() ?? defaultTag);
|
|
445
|
+
const [streamResult, messagesResult] = await execute.batchCommand([streamSQL, insertSQL], { assertChanges: true });
|
|
446
|
+
const streamPosition = streamResult?.rows[0]?.stream_position;
|
|
447
|
+
const globalPosition = messagesResult?.rows.at(-1)?.global_position;
|
|
448
|
+
if (!streamPosition) throw new _event_driven_io_emmett.ExpectedVersionConflictError(0n, expectedStreamVersion ?? 0n);
|
|
449
|
+
if (!globalPosition) throw new Error("Could not find global position");
|
|
450
|
+
return {
|
|
451
|
+
success: true,
|
|
452
|
+
nextStreamPosition: BigInt(streamPosition),
|
|
453
|
+
lastGlobalPosition: BigInt(globalPosition)
|
|
454
|
+
};
|
|
1737
455
|
};
|
|
1738
456
|
async function getLastStreamPosition(execute, streamId, expectedStreamVersion) {
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
);
|
|
1744
|
-
if (_optionalChain([result, 'optionalAccess', _84 => _84.stream_position]) == null) {
|
|
1745
|
-
expectedStreamVersion = 0n;
|
|
1746
|
-
} else {
|
|
1747
|
-
expectedStreamVersion = BigInt(result.stream_position);
|
|
1748
|
-
}
|
|
1749
|
-
return expectedStreamVersion;
|
|
457
|
+
const result = await (0, _event_driven_io_dumbo.singleOrNull)(execute.query(_event_driven_io_dumbo.SQL`SELECT CAST(stream_position AS VARCHAR) AS stream_position FROM ${identifier$7(streamsTable.name)} WHERE stream_id = ${streamId}`));
|
|
458
|
+
if (result?.stream_position == null) expectedStreamVersion = 0n;
|
|
459
|
+
else expectedStreamVersion = BigInt(result.stream_position);
|
|
460
|
+
return expectedStreamVersion;
|
|
1750
461
|
}
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
});
|
|
1759
|
-
return _dumbo.SQL`
|
|
1760
|
-
INSERT INTO ${identifier(messagesTable.name)} (
|
|
462
|
+
const buildMessageInsertQuery = (messages, expectedStreamVersion, streamId, partition) => {
|
|
463
|
+
const values = messages.map((message) => {
|
|
464
|
+
if (message.metadata?.streamPosition == null || typeof message.metadata.streamPosition !== "bigint") throw new Error("Stream position is required");
|
|
465
|
+
return _event_driven_io_dumbo.SQL`(${streamId},${BigInt(message.metadata.streamPosition) + BigInt(expectedStreamVersion) ?? 0n},${partition ?? defaultTag},${message.kind === "Event" ? "E" : "C"},${message.data},${message.metadata},${expectedStreamVersion ?? 0n},${message.type},${message.metadata.messageId},${false})`;
|
|
466
|
+
});
|
|
467
|
+
return _event_driven_io_dumbo.SQL`
|
|
468
|
+
INSERT INTO ${identifier$7(messagesTable.name)} (
|
|
1761
469
|
stream_id,
|
|
1762
470
|
stream_position,
|
|
1763
471
|
partition,
|
|
@@ -1775,10 +483,10 @@ var buildMessageInsertQuery = (messages, expectedStreamVersion, streamId, partit
|
|
|
1775
483
|
`;
|
|
1776
484
|
};
|
|
1777
485
|
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
486
|
+
//#endregion
|
|
487
|
+
//#region src/eventStore/schema/migrations/0_41_0/0_41_0.snapshot.ts
|
|
488
|
+
const schema_0_41_0 = [
|
|
489
|
+
_event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS emt_streams(
|
|
1782
490
|
stream_id TEXT NOT NULL,
|
|
1783
491
|
stream_position BIGINT NOT NULL DEFAULT 0,
|
|
1784
492
|
partition TEXT NOT NULL DEFAULT 'global',
|
|
@@ -1788,7 +496,7 @@ var schema_0_41_0 = [
|
|
|
1788
496
|
PRIMARY KEY (stream_id, partition, is_archived),
|
|
1789
497
|
UNIQUE (stream_id, partition, is_archived)
|
|
1790
498
|
)`,
|
|
1791
|
-
|
|
499
|
+
_event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS emt_messages(
|
|
1792
500
|
stream_id TEXT NOT NULL,
|
|
1793
501
|
stream_position BIGINT NOT NULL,
|
|
1794
502
|
partition TEXT NOT NULL DEFAULT 'global',
|
|
@@ -1803,7 +511,7 @@ var schema_0_41_0 = [
|
|
|
1803
511
|
created DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
1804
512
|
UNIQUE (stream_id, stream_position, partition, is_archived)
|
|
1805
513
|
)`,
|
|
1806
|
-
|
|
514
|
+
_event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS emt_subscriptions(
|
|
1807
515
|
subscription_id TEXT NOT NULL,
|
|
1808
516
|
version INTEGER NOT NULL DEFAULT 1,
|
|
1809
517
|
partition TEXT NOT NULL DEFAULT 'global',
|
|
@@ -1812,30 +520,30 @@ var schema_0_41_0 = [
|
|
|
1812
520
|
)`
|
|
1813
521
|
];
|
|
1814
522
|
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
523
|
+
//#endregion
|
|
524
|
+
//#region src/eventStore/schema/migrations/0_42_0/0_42_0.migration.ts
|
|
525
|
+
const { identifier: identifier$6, plain: plain$1 } = _event_driven_io_dumbo.SQL;
|
|
526
|
+
const migration_0_42_0_SQLs = [
|
|
527
|
+
_event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS ${identifier$6(processorsTable.name)}(
|
|
1820
528
|
processor_id TEXT NOT NULL,
|
|
1821
529
|
version INTEGER NOT NULL DEFAULT 1,
|
|
1822
|
-
partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',
|
|
530
|
+
partition TEXT NOT NULL DEFAULT '${plain$1(globalTag)}',
|
|
1823
531
|
status TEXT NOT NULL DEFAULT 'stopped',
|
|
1824
532
|
last_processed_checkpoint TEXT NOT NULL,
|
|
1825
533
|
processor_instance_id TEXT DEFAULT 'emt:unknown',
|
|
1826
534
|
PRIMARY KEY (processor_id, partition, version)
|
|
1827
535
|
)`,
|
|
1828
|
-
|
|
536
|
+
_event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS ${identifier$6(projectionsTable.name)}(
|
|
1829
537
|
name TEXT NOT NULL,
|
|
1830
538
|
version INTEGER NOT NULL DEFAULT 1,
|
|
1831
|
-
partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',
|
|
539
|
+
partition TEXT NOT NULL DEFAULT '${plain$1(globalTag)}',
|
|
1832
540
|
type CHAR(1) NOT NULL,
|
|
1833
541
|
kind TEXT NOT NULL,
|
|
1834
542
|
status TEXT NOT NULL,
|
|
1835
543
|
definition JSONB NOT NULL DEFAULT '{}',
|
|
1836
544
|
PRIMARY KEY (name, partition, version)
|
|
1837
545
|
)`,
|
|
1838
|
-
|
|
546
|
+
_event_driven_io_dumbo.SQL`INSERT INTO ${identifier$6(processorsTable.name)}
|
|
1839
547
|
(processor_id, version, partition, status, last_processed_checkpoint, processor_instance_id)
|
|
1840
548
|
SELECT
|
|
1841
549
|
subscription_id,
|
|
@@ -1845,24 +553,17 @@ var migration_0_42_0_SQLs = [
|
|
|
1845
553
|
printf('%019d', last_processed_position),
|
|
1846
554
|
'emt:unknown'
|
|
1847
555
|
FROM emt_subscriptions`,
|
|
1848
|
-
|
|
556
|
+
_event_driven_io_dumbo.SQL`DROP TABLE emt_subscriptions`
|
|
1849
557
|
];
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
_dumbo.SQL`SELECT name FROM sqlite_master WHERE type='table' AND name='emt_subscriptions'`
|
|
1854
|
-
)
|
|
1855
|
-
);
|
|
1856
|
-
if (!tableExists) {
|
|
1857
|
-
return;
|
|
1858
|
-
}
|
|
1859
|
-
await execute.batchCommand(migration_0_42_0_SQLs);
|
|
558
|
+
const migration_0_42_0_FromSubscriptionsToProcessors = async (execute) => {
|
|
559
|
+
if (!await (0, _event_driven_io_dumbo.singleOrNull)(execute.query(_event_driven_io_dumbo.SQL`SELECT name FROM sqlite_master WHERE type='table' AND name='emt_subscriptions'`))) return;
|
|
560
|
+
await execute.batchCommand(migration_0_42_0_SQLs);
|
|
1860
561
|
};
|
|
1861
562
|
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
563
|
+
//#endregion
|
|
564
|
+
//#region src/eventStore/schema/migrations/0_42_0/0_42_0.snapshot.ts
|
|
565
|
+
const schema_0_42_0 = [
|
|
566
|
+
_event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS emt_streams(
|
|
1866
567
|
stream_id TEXT NOT NULL,
|
|
1867
568
|
stream_position BIGINT NOT NULL DEFAULT 0,
|
|
1868
569
|
partition TEXT NOT NULL DEFAULT 'global',
|
|
@@ -1872,7 +573,7 @@ var schema_0_42_0 = [
|
|
|
1872
573
|
PRIMARY KEY (stream_id, partition, is_archived),
|
|
1873
574
|
UNIQUE (stream_id, partition, is_archived)
|
|
1874
575
|
)`,
|
|
1875
|
-
|
|
576
|
+
_event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS emt_messages(
|
|
1876
577
|
stream_id TEXT NOT NULL,
|
|
1877
578
|
stream_position BIGINT NOT NULL,
|
|
1878
579
|
partition TEXT NOT NULL DEFAULT 'global',
|
|
@@ -1887,7 +588,7 @@ var schema_0_42_0 = [
|
|
|
1887
588
|
created DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
1888
589
|
UNIQUE (stream_id, stream_position, partition, is_archived)
|
|
1889
590
|
)`,
|
|
1890
|
-
|
|
591
|
+
_event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS emt_processors(
|
|
1891
592
|
processor_id TEXT NOT NULL,
|
|
1892
593
|
version INTEGER NOT NULL DEFAULT 1,
|
|
1893
594
|
partition TEXT NOT NULL DEFAULT 'global',
|
|
@@ -1896,7 +597,7 @@ var schema_0_42_0 = [
|
|
|
1896
597
|
processor_instance_id TEXT DEFAULT 'emt:unknown',
|
|
1897
598
|
PRIMARY KEY (processor_id, partition, version)
|
|
1898
599
|
)`,
|
|
1899
|
-
|
|
600
|
+
_event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS emt_projections(
|
|
1900
601
|
name TEXT NOT NULL,
|
|
1901
602
|
version INTEGER NOT NULL DEFAULT 1,
|
|
1902
603
|
partition TEXT NOT NULL DEFAULT 'global',
|
|
@@ -1908,801 +609,657 @@ var schema_0_42_0 = [
|
|
|
1908
609
|
)`
|
|
1909
610
|
];
|
|
1910
611
|
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
execute.query(
|
|
1917
|
-
_dumbo.SQL`
|
|
612
|
+
//#endregion
|
|
613
|
+
//#region src/eventStore/schema/readLastMessageGlobalPosition.ts
|
|
614
|
+
const { identifier: identifier$5 } = _event_driven_io_dumbo.SQL;
|
|
615
|
+
const readLastMessageGlobalPosition = async (execute, options) => {
|
|
616
|
+
const result = await (0, _event_driven_io_dumbo.singleOrNull)(execute.query(_event_driven_io_dumbo.SQL`
|
|
1918
617
|
SELECT global_position
|
|
1919
|
-
FROM ${
|
|
1920
|
-
WHERE partition = ${
|
|
1921
|
-
ORDER BY global_position
|
|
1922
|
-
LIMIT 1`
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
};
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
const limitCondition = "batchSize" in options ? _dumbo.SQL`LIMIT ${options.batchSize}` : _dumbo.SQL.EMPTY;
|
|
1941
|
-
const messages = await _dumbo.mapRows.call(void 0,
|
|
1942
|
-
execute.query(
|
|
1943
|
-
_dumbo.SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
|
|
1944
|
-
FROM ${identifier4(messagesTable.name)}
|
|
1945
|
-
WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _88 => _88.partition]), () => ( defaultTag2))} AND is_archived = FALSE ${fromCondition} ${toCondition}
|
|
618
|
+
FROM ${identifier$5(messagesTable.name)}
|
|
619
|
+
WHERE partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE
|
|
620
|
+
ORDER BY global_position DESC
|
|
621
|
+
LIMIT 1`));
|
|
622
|
+
return { currentGlobalPosition: result !== null ? BigInt(result.global_position) : null };
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
//#endregion
|
|
626
|
+
//#region src/eventStore/schema/readMessagesBatch.ts
|
|
627
|
+
const { identifier: identifier$4 } = _event_driven_io_dumbo.SQL;
|
|
628
|
+
const readMessagesBatch = async (execute, options) => {
|
|
629
|
+
const { serializer } = options;
|
|
630
|
+
const from = "from" in options ? options.from : void 0;
|
|
631
|
+
const after = "after" in options ? options.after : void 0;
|
|
632
|
+
const batchSize = "batchSize" in options ? options.batchSize : options.to - options.from;
|
|
633
|
+
const fromCondition = from !== void 0 ? _event_driven_io_dumbo.SQL`AND global_position >= ${from}` : after !== void 0 ? _event_driven_io_dumbo.SQL`AND global_position > ${after}` : _event_driven_io_dumbo.SQL.EMPTY;
|
|
634
|
+
const toCondition = "to" in options ? _event_driven_io_dumbo.SQL`AND global_position <= ${options.to}` : _event_driven_io_dumbo.SQL.EMPTY;
|
|
635
|
+
const limitCondition = "batchSize" in options ? _event_driven_io_dumbo.SQL`LIMIT ${options.batchSize}` : _event_driven_io_dumbo.SQL.EMPTY;
|
|
636
|
+
const messages = await (0, _event_driven_io_dumbo.mapRows)(execute.query(_event_driven_io_dumbo.SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
|
|
637
|
+
FROM ${identifier$4(messagesTable.name)}
|
|
638
|
+
WHERE partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE ${fromCondition} ${toCondition}
|
|
1946
639
|
ORDER BY global_position
|
|
1947
|
-
${limitCondition}`
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
}
|
|
2074
|
-
|
|
2075
|
-
// src/eventStore/consumers/sqliteEventStoreConsumer.ts
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
// src/eventStore/consumers/sqliteCheckpointer.ts
|
|
2080
|
-
var sqliteCheckpointer = () => ({
|
|
2081
|
-
read: async (options, context) => {
|
|
2082
|
-
const result = await readProcessorCheckpoint(context.execute, options);
|
|
2083
|
-
return { lastCheckpoint: _optionalChain([result, 'optionalAccess', _92 => _92.lastProcessedCheckpoint]) };
|
|
2084
|
-
},
|
|
2085
|
-
store: async (options, context) => {
|
|
2086
|
-
const newCheckpoint = getCheckpoint(options.message);
|
|
2087
|
-
const result = await storeProcessorCheckpoint(context.execute, {
|
|
2088
|
-
lastProcessedCheckpoint: options.lastCheckpoint,
|
|
2089
|
-
newCheckpoint,
|
|
2090
|
-
processorId: options.processorId,
|
|
2091
|
-
partition: options.partition,
|
|
2092
|
-
version: options.version
|
|
2093
|
-
});
|
|
2094
|
-
return result.success ? { success: true, newCheckpoint: result.newCheckpoint } : result;
|
|
2095
|
-
}
|
|
640
|
+
${limitCondition}`), (row) => {
|
|
641
|
+
const rawEvent = {
|
|
642
|
+
type: row.message_type,
|
|
643
|
+
data: serializer.deserialize(row.message_data),
|
|
644
|
+
metadata: serializer.deserialize(row.message_metadata)
|
|
645
|
+
};
|
|
646
|
+
const metadata = {
|
|
647
|
+
..."metadata" in rawEvent ? rawEvent.metadata ?? {} : {},
|
|
648
|
+
messageId: row.message_id,
|
|
649
|
+
streamName: row.stream_id,
|
|
650
|
+
streamPosition: BigInt(row.stream_position),
|
|
651
|
+
globalPosition: BigInt(row.global_position),
|
|
652
|
+
checkpoint: (0, _event_driven_io_emmett.bigIntProcessorCheckpoint)(BigInt(row.global_position))
|
|
653
|
+
};
|
|
654
|
+
return {
|
|
655
|
+
...rawEvent,
|
|
656
|
+
kind: "Event",
|
|
657
|
+
metadata
|
|
658
|
+
};
|
|
659
|
+
});
|
|
660
|
+
return messages.length > 0 ? {
|
|
661
|
+
currentGlobalPosition: messages[messages.length - 1].metadata.globalPosition,
|
|
662
|
+
messages,
|
|
663
|
+
areMessagesLeft: messages.length === batchSize
|
|
664
|
+
} : {
|
|
665
|
+
currentGlobalPosition: "from" in options ? options.from : "after" in options ? options.after : 0n,
|
|
666
|
+
messages: [],
|
|
667
|
+
areMessagesLeft: false
|
|
668
|
+
};
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
//#endregion
|
|
672
|
+
//#region src/eventStore/schema/readProcessorCheckpoint.ts
|
|
673
|
+
const { identifier: identifier$3 } = _event_driven_io_dumbo.SQL;
|
|
674
|
+
const readProcessorCheckpoint = async (execute, options) => {
|
|
675
|
+
const result = await (0, _event_driven_io_dumbo.singleOrNull)(execute.query(_event_driven_io_dumbo.SQL`SELECT last_processed_checkpoint
|
|
676
|
+
FROM ${identifier$3(processorsTable.name)}
|
|
677
|
+
WHERE partition = ${options?.partition ?? defaultTag} AND processor_id = ${options.processorId}
|
|
678
|
+
LIMIT 1`));
|
|
679
|
+
return { lastProcessedCheckpoint: result !== null ? result.last_processed_checkpoint : null };
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
//#endregion
|
|
683
|
+
//#region src/eventStore/consumers/messageBatchProcessing/index.ts
|
|
684
|
+
const sqliteEventStoreMessageBatchPuller = ({ executor, batchSize, eachBatch, pullingFrequencyInMs, stopWhen, signal, serialization }) => {
|
|
685
|
+
let isRunning = false;
|
|
686
|
+
let start;
|
|
687
|
+
const serializer = _event_driven_io_emmett.JSONSerializer.from({ serialization });
|
|
688
|
+
const pullMessages = async (options) => {
|
|
689
|
+
let after;
|
|
690
|
+
try {
|
|
691
|
+
after = options.startFrom === "BEGINNING" ? 0n : options.startFrom === "END" ? (await readLastMessageGlobalPosition(executor)).currentGlobalPosition ?? 0n : (0, _event_driven_io_emmett.parseBigIntProcessorCheckpoint)(options.startFrom.lastCheckpoint);
|
|
692
|
+
} catch (error) {
|
|
693
|
+
options.started?.reject(error);
|
|
694
|
+
throw error;
|
|
695
|
+
}
|
|
696
|
+
options.started?.resolve();
|
|
697
|
+
const readMessagesOptions = {
|
|
698
|
+
after,
|
|
699
|
+
batchSize,
|
|
700
|
+
serializer
|
|
701
|
+
};
|
|
702
|
+
let waitTime = 100;
|
|
703
|
+
while (isRunning && !signal?.aborted) {
|
|
704
|
+
const { messages, currentGlobalPosition, areMessagesLeft } = await readMessagesBatch(executor, readMessagesOptions);
|
|
705
|
+
if (messages.length > 0) {
|
|
706
|
+
const result = await eachBatch(messages);
|
|
707
|
+
if (result && result.type === "STOP") {
|
|
708
|
+
isRunning = false;
|
|
709
|
+
break;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
readMessagesOptions.after = currentGlobalPosition;
|
|
713
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
714
|
+
if (stopWhen?.noMessagesLeft === true && !areMessagesLeft) {
|
|
715
|
+
isRunning = false;
|
|
716
|
+
break;
|
|
717
|
+
}
|
|
718
|
+
if (!areMessagesLeft) waitTime = Math.min(waitTime * 2, 1e3);
|
|
719
|
+
else waitTime = pullingFrequencyInMs;
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
return {
|
|
723
|
+
get isRunning() {
|
|
724
|
+
return isRunning;
|
|
725
|
+
},
|
|
726
|
+
start: (options) => {
|
|
727
|
+
if (isRunning) return start;
|
|
728
|
+
isRunning = true;
|
|
729
|
+
start = (async () => {
|
|
730
|
+
return pullMessages(options);
|
|
731
|
+
})();
|
|
732
|
+
return start;
|
|
733
|
+
},
|
|
734
|
+
stop: async () => {
|
|
735
|
+
if (!isRunning) return;
|
|
736
|
+
isRunning = false;
|
|
737
|
+
await start;
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
};
|
|
741
|
+
const zipSQLiteEventStoreMessageBatchPullerStartFrom = (options) => {
|
|
742
|
+
if (options.length === 0 || options.some((o) => o === void 0 || o === "BEGINNING")) return "BEGINNING";
|
|
743
|
+
if (options.every((o) => o === "END")) return "END";
|
|
744
|
+
return options.filter((o) => o !== void 0 && o !== "BEGINNING" && o !== "END").sort((a, b) => a > b ? 1 : -1)[0];
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
//#endregion
|
|
748
|
+
//#region src/eventStore/consumers/sqliteCheckpointer.ts
|
|
749
|
+
const sqliteCheckpointer = () => ({
|
|
750
|
+
read: async (options, context) => {
|
|
751
|
+
return { lastCheckpoint: (await readProcessorCheckpoint(context.execute, options))?.lastProcessedCheckpoint };
|
|
752
|
+
},
|
|
753
|
+
store: async (options, context) => {
|
|
754
|
+
const newCheckpoint = (0, _event_driven_io_emmett.getCheckpoint)(options.message);
|
|
755
|
+
const result = await storeProcessorCheckpoint(context.execute, {
|
|
756
|
+
lastProcessedCheckpoint: options.lastCheckpoint,
|
|
757
|
+
newCheckpoint,
|
|
758
|
+
processorId: options.processorId,
|
|
759
|
+
partition: options.partition,
|
|
760
|
+
version: options.version
|
|
761
|
+
});
|
|
762
|
+
return result.success ? {
|
|
763
|
+
success: true,
|
|
764
|
+
newCheckpoint: result.newCheckpoint
|
|
765
|
+
} : result;
|
|
766
|
+
}
|
|
2096
767
|
});
|
|
2097
768
|
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
};
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
transactionOptions: {
|
|
2519
|
-
allowNestedTransactions: true,
|
|
2520
|
-
mode: "session_based"
|
|
2521
|
-
},
|
|
2522
|
-
schema: {
|
|
2523
|
-
...options.schema,
|
|
2524
|
-
autoMigration: "None"
|
|
2525
|
-
},
|
|
2526
|
-
serialization: options.serialization
|
|
2527
|
-
});
|
|
2528
|
-
await ensureSchemaExists();
|
|
2529
|
-
return callback({
|
|
2530
|
-
eventStore: sessionStore,
|
|
2531
|
-
close: () => Promise.resolve()
|
|
2532
|
-
});
|
|
2533
|
-
});
|
|
2534
|
-
},
|
|
2535
|
-
close: () => pool.close(),
|
|
2536
|
-
schema: {
|
|
2537
|
-
sql: () => schemaSQL.join(""),
|
|
2538
|
-
print: () => console.log(schemaSQL.join("")),
|
|
2539
|
-
migrate: () => pool.withConnection(migrate)
|
|
2540
|
-
}
|
|
2541
|
-
};
|
|
2542
|
-
};
|
|
2543
|
-
|
|
2544
|
-
// src/eventStore/schema/readStream.ts
|
|
2545
|
-
var { identifier: identifier6 } = _dumbo.SQL;
|
|
2546
|
-
var readStream = async (execute, streamId, options) => {
|
|
2547
|
-
const { serializer } = options;
|
|
2548
|
-
const fromCondition = options.from ? _dumbo.SQL`AND stream_position >= ${options.from}` : _dumbo.SQL.EMPTY;
|
|
2549
|
-
const to = Number(
|
|
2550
|
-
_nullishCoalesce(_optionalChain([options, 'optionalAccess', _127 => _127.to]), () => ( (_optionalChain([options, 'optionalAccess', _128 => _128.maxCount]) ? (_nullishCoalesce(options.from, () => ( 0n))) + options.maxCount : NaN)))
|
|
2551
|
-
);
|
|
2552
|
-
const toCondition = !isNaN(to) ? _dumbo.SQL`AND stream_position <= ${to}` : _dumbo.SQL.EMPTY;
|
|
2553
|
-
const { rows: results } = await execute.query(
|
|
2554
|
-
_dumbo.SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
|
|
2555
|
-
FROM ${identifier6(messagesTable.name)}
|
|
2556
|
-
WHERE stream_id = ${streamId} AND partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _129 => _129.partition]), () => ( defaultTag2))} AND is_archived = FALSE ${fromCondition} ${toCondition}
|
|
2557
|
-
ORDER BY stream_position ASC`
|
|
2558
|
-
);
|
|
2559
|
-
const messages = results.map((row) => {
|
|
2560
|
-
const rawEvent = {
|
|
2561
|
-
type: row.message_type,
|
|
2562
|
-
data: serializer.deserialize(row.message_data),
|
|
2563
|
-
metadata: serializer.deserialize(row.message_metadata)
|
|
2564
|
-
};
|
|
2565
|
-
const metadata = {
|
|
2566
|
-
..."metadata" in rawEvent ? _nullishCoalesce(rawEvent.metadata, () => ( {})) : {},
|
|
2567
|
-
messageId: row.message_id,
|
|
2568
|
-
streamName: streamId,
|
|
2569
|
-
streamPosition: BigInt(row.stream_position),
|
|
2570
|
-
globalPosition: BigInt(row.global_position),
|
|
2571
|
-
checkpoint: bigIntProcessorCheckpoint(BigInt(row.global_position))
|
|
2572
|
-
};
|
|
2573
|
-
const event = {
|
|
2574
|
-
...rawEvent,
|
|
2575
|
-
kind: "Event",
|
|
2576
|
-
metadata
|
|
2577
|
-
};
|
|
2578
|
-
return upcastRecordedMessage(event, _optionalChain([options, 'optionalAccess', _130 => _130.schema, 'optionalAccess', _131 => _131.versioning]));
|
|
2579
|
-
});
|
|
2580
|
-
return messages.length > 0 ? {
|
|
2581
|
-
currentStreamVersion: messages[messages.length - 1].metadata.streamPosition,
|
|
2582
|
-
events: messages,
|
|
2583
|
-
streamExists: true
|
|
2584
|
-
} : {
|
|
2585
|
-
currentStreamVersion: SQLiteEventStoreDefaultStreamVersion,
|
|
2586
|
-
events: [],
|
|
2587
|
-
streamExists: false
|
|
2588
|
-
};
|
|
2589
|
-
};
|
|
2590
|
-
|
|
2591
|
-
// src/eventStore/schema/storeProcessorCheckpoint.ts
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
var { identifier: identifier7 } = _dumbo.SQL;
|
|
769
|
+
//#endregion
|
|
770
|
+
//#region src/eventStore/consumers/sqliteProcessor.ts
|
|
771
|
+
const sqliteProcessingScope = () => {
|
|
772
|
+
const processingScope = async (handler, partialContext) => {
|
|
773
|
+
const connection = partialContext?.connection;
|
|
774
|
+
if (!connection) throw new _event_driven_io_emmett.EmmettError("Connection is required in context or options");
|
|
775
|
+
return connection.withTransaction(async (transaction) => {
|
|
776
|
+
return handler({
|
|
777
|
+
...partialContext,
|
|
778
|
+
connection,
|
|
779
|
+
execute: transaction.execute
|
|
780
|
+
});
|
|
781
|
+
});
|
|
782
|
+
};
|
|
783
|
+
return processingScope;
|
|
784
|
+
};
|
|
785
|
+
const sqliteWorkflowProcessingScope = (messageStore) => {
|
|
786
|
+
const processingScope = async (handler, partialContext) => {
|
|
787
|
+
const connection = partialContext?.connection;
|
|
788
|
+
if (!connection) throw new _event_driven_io_emmett.EmmettError("Connection is required in context or options");
|
|
789
|
+
return connection.withTransaction(async (transaction) => {
|
|
790
|
+
return handler({
|
|
791
|
+
...partialContext,
|
|
792
|
+
connection: Object.assign(connection, { messageStore }),
|
|
793
|
+
execute: transaction.execute
|
|
794
|
+
});
|
|
795
|
+
});
|
|
796
|
+
};
|
|
797
|
+
return processingScope;
|
|
798
|
+
};
|
|
799
|
+
const sqliteWorkflowProcessor = (options) => {
|
|
800
|
+
const { processorId = options.processorId ?? (0, _event_driven_io_emmett.getWorkflowId)({ workflowName: options.workflow.name ?? "unknown" }), processorInstanceId = (0, _event_driven_io_emmett.getProcessorInstanceId)(processorId), version = _event_driven_io_emmett.defaultProcessorVersion, partition = _event_driven_io_emmett.defaultProcessorPartition } = options;
|
|
801
|
+
const hooks = {
|
|
802
|
+
...options.hooks ?? {},
|
|
803
|
+
onClose: options.hooks?.onClose
|
|
804
|
+
};
|
|
805
|
+
return (0, _event_driven_io_emmett.workflowProcessor)({
|
|
806
|
+
...options,
|
|
807
|
+
processorId,
|
|
808
|
+
processorInstanceId,
|
|
809
|
+
version,
|
|
810
|
+
partition,
|
|
811
|
+
hooks,
|
|
812
|
+
processingScope: sqliteWorkflowProcessingScope(options.messageStore),
|
|
813
|
+
checkpoints: sqliteCheckpointer()
|
|
814
|
+
});
|
|
815
|
+
};
|
|
816
|
+
const sqliteReactor = (options) => {
|
|
817
|
+
const { processorId = options.processorId, processorInstanceId = (0, _event_driven_io_emmett.getProcessorInstanceId)(processorId), version = _event_driven_io_emmett.defaultProcessorVersion, partition = _event_driven_io_emmett.defaultProcessorPartition, hooks } = options;
|
|
818
|
+
return (0, _event_driven_io_emmett.reactor)({
|
|
819
|
+
...options,
|
|
820
|
+
processorId,
|
|
821
|
+
processorInstanceId,
|
|
822
|
+
version,
|
|
823
|
+
partition,
|
|
824
|
+
hooks,
|
|
825
|
+
processingScope: sqliteProcessingScope(),
|
|
826
|
+
checkpoints: sqliteCheckpointer()
|
|
827
|
+
});
|
|
828
|
+
};
|
|
829
|
+
const sqliteProjector = (options) => {
|
|
830
|
+
const { processorId = (0, _event_driven_io_emmett.getProjectorId)({ projectionName: options.projection.name ?? "unknown" }), processorInstanceId = (0, _event_driven_io_emmett.getProcessorInstanceId)(processorId), version = _event_driven_io_emmett.defaultProcessorVersion, partition = _event_driven_io_emmett.defaultProcessorPartition } = options;
|
|
831
|
+
const hooks = {
|
|
832
|
+
...options.hooks ?? {},
|
|
833
|
+
onInit: options.projection.init !== void 0 || options.hooks?.onInit ? async (context) => {
|
|
834
|
+
if (options.projection.init) await options.projection.init({
|
|
835
|
+
version: options.projection.version ?? version,
|
|
836
|
+
status: "active",
|
|
837
|
+
registrationType: "async",
|
|
838
|
+
context: {
|
|
839
|
+
...context,
|
|
840
|
+
migrationOptions: options.migrationOptions
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
if (options.hooks?.onInit) await options.hooks.onInit({
|
|
844
|
+
...context,
|
|
845
|
+
migrationOptions: options.migrationOptions
|
|
846
|
+
});
|
|
847
|
+
} : options.hooks?.onInit,
|
|
848
|
+
onClose: options.hooks?.onClose
|
|
849
|
+
};
|
|
850
|
+
return (0, _event_driven_io_emmett.projector)({
|
|
851
|
+
...options,
|
|
852
|
+
processorId,
|
|
853
|
+
processorInstanceId,
|
|
854
|
+
version,
|
|
855
|
+
partition,
|
|
856
|
+
hooks,
|
|
857
|
+
processingScope: sqliteProcessingScope(),
|
|
858
|
+
checkpoints: sqliteCheckpointer()
|
|
859
|
+
});
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
//#endregion
|
|
863
|
+
//#region src/eventStore/consumers/sqliteEventStoreConsumer.ts
|
|
864
|
+
const sqliteEventStoreConsumer = (options) => {
|
|
865
|
+
let isRunning = false;
|
|
866
|
+
let isInitialized = false;
|
|
867
|
+
const { pulling } = options;
|
|
868
|
+
const processors = options.processors ?? [];
|
|
869
|
+
let abortController = null;
|
|
870
|
+
let start;
|
|
871
|
+
let messagePuller;
|
|
872
|
+
const startedAwaiter = (0, _event_driven_io_emmett.asyncAwaiter)();
|
|
873
|
+
const pool = options.pool ?? (0, _event_driven_io_dumbo.dumbo)({
|
|
874
|
+
serialization: options.serialization,
|
|
875
|
+
transactionOptions: {
|
|
876
|
+
allowNestedTransactions: true,
|
|
877
|
+
mode: "session_based"
|
|
878
|
+
},
|
|
879
|
+
...options.driver.mapToDumboOptions(options)
|
|
880
|
+
});
|
|
881
|
+
const eachBatch = (messagesBatch) => pool.withConnection(async (connection) => {
|
|
882
|
+
const activeProcessors = processors.filter((s) => s.isActive);
|
|
883
|
+
if (activeProcessors.length === 0) return {
|
|
884
|
+
type: "STOP",
|
|
885
|
+
reason: "No active processors"
|
|
886
|
+
};
|
|
887
|
+
return (await Promise.allSettled(activeProcessors.map(async (s) => {
|
|
888
|
+
return await s.handle(messagesBatch, {
|
|
889
|
+
connection,
|
|
890
|
+
execute: connection.execute
|
|
891
|
+
});
|
|
892
|
+
}))).some((r) => r.status === "fulfilled" && r.value?.type !== "STOP") ? void 0 : { type: "STOP" };
|
|
893
|
+
});
|
|
894
|
+
const processorContext = {
|
|
895
|
+
execute: void 0,
|
|
896
|
+
connection: void 0
|
|
897
|
+
};
|
|
898
|
+
const stopProcessors = () => Promise.all(processors.map((p) => p.close(processorContext)));
|
|
899
|
+
const stop = async () => {
|
|
900
|
+
if (!isRunning) return;
|
|
901
|
+
isRunning = false;
|
|
902
|
+
if (messagePuller) {
|
|
903
|
+
abortController?.abort();
|
|
904
|
+
await messagePuller.stop();
|
|
905
|
+
}
|
|
906
|
+
await start;
|
|
907
|
+
messagePuller = void 0;
|
|
908
|
+
abortController = null;
|
|
909
|
+
await stopProcessors();
|
|
910
|
+
};
|
|
911
|
+
const init = async () => {
|
|
912
|
+
if (isInitialized) return;
|
|
913
|
+
const sqliteProcessors = processors;
|
|
914
|
+
await pool.withConnection(async (connection) => {
|
|
915
|
+
for (const processor of sqliteProcessors) if (processor.init) await processor.init({
|
|
916
|
+
...processorContext,
|
|
917
|
+
connection,
|
|
918
|
+
execute: connection.execute
|
|
919
|
+
});
|
|
920
|
+
});
|
|
921
|
+
isInitialized = true;
|
|
922
|
+
};
|
|
923
|
+
return {
|
|
924
|
+
consumerId: options.consumerId ?? (0, uuid.v7)(),
|
|
925
|
+
get isRunning() {
|
|
926
|
+
return isRunning;
|
|
927
|
+
},
|
|
928
|
+
whenStarted: () => startedAwaiter.wait,
|
|
929
|
+
processors,
|
|
930
|
+
init,
|
|
931
|
+
reactor: (options) => {
|
|
932
|
+
const processor = sqliteReactor(options);
|
|
933
|
+
processors.push(processor);
|
|
934
|
+
return processor;
|
|
935
|
+
},
|
|
936
|
+
projector: (options) => {
|
|
937
|
+
const processor = sqliteProjector(options);
|
|
938
|
+
processors.push(processor);
|
|
939
|
+
return processor;
|
|
940
|
+
},
|
|
941
|
+
workflowProcessor: (processorOptions) => {
|
|
942
|
+
const messageStore = getSQLiteEventStore({
|
|
943
|
+
...options,
|
|
944
|
+
pool,
|
|
945
|
+
schema: { autoMigration: "None" }
|
|
946
|
+
});
|
|
947
|
+
const processor = sqliteWorkflowProcessor({
|
|
948
|
+
...processorOptions,
|
|
949
|
+
messageStore
|
|
950
|
+
});
|
|
951
|
+
processors.push(processor);
|
|
952
|
+
return processor;
|
|
953
|
+
},
|
|
954
|
+
start: () => {
|
|
955
|
+
if (isRunning) return start;
|
|
956
|
+
startedAwaiter.reset();
|
|
957
|
+
if (processors.length === 0) {
|
|
958
|
+
const error = new _event_driven_io_emmett.EmmettError("Cannot start consumer without at least a single processor");
|
|
959
|
+
startedAwaiter.reject(error);
|
|
960
|
+
return Promise.reject(error);
|
|
961
|
+
}
|
|
962
|
+
isRunning = true;
|
|
963
|
+
abortController = new AbortController();
|
|
964
|
+
start = (async () => {
|
|
965
|
+
if (!isRunning) return;
|
|
966
|
+
try {
|
|
967
|
+
messagePuller = sqliteEventStoreMessageBatchPuller({
|
|
968
|
+
stopWhen: options.stopWhen,
|
|
969
|
+
executor: pool.execute,
|
|
970
|
+
eachBatch,
|
|
971
|
+
batchSize: pulling?.batchSize ?? 100,
|
|
972
|
+
pullingFrequencyInMs: pulling?.pullingFrequencyInMs ?? 50,
|
|
973
|
+
signal: abortController.signal
|
|
974
|
+
});
|
|
975
|
+
if (!isInitialized) await init();
|
|
976
|
+
const startFrom = await pool.withConnection(async (connection) => zipSQLiteEventStoreMessageBatchPullerStartFrom(await Promise.all(processors.map(async (o) => {
|
|
977
|
+
return await o.start({
|
|
978
|
+
execute: connection.execute,
|
|
979
|
+
connection
|
|
980
|
+
});
|
|
981
|
+
}))));
|
|
982
|
+
await messagePuller.start({
|
|
983
|
+
startFrom,
|
|
984
|
+
started: startedAwaiter
|
|
985
|
+
});
|
|
986
|
+
} catch (error) {
|
|
987
|
+
isRunning = false;
|
|
988
|
+
startedAwaiter.reject(error);
|
|
989
|
+
throw error;
|
|
990
|
+
} finally {
|
|
991
|
+
await stopProcessors();
|
|
992
|
+
}
|
|
993
|
+
})();
|
|
994
|
+
return start;
|
|
995
|
+
},
|
|
996
|
+
stop,
|
|
997
|
+
close: async () => {
|
|
998
|
+
await stop();
|
|
999
|
+
await pool.close();
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
};
|
|
1003
|
+
|
|
1004
|
+
//#endregion
|
|
1005
|
+
//#region src/eventStore/SQLiteEventStore.ts
|
|
1006
|
+
const SQLiteEventStoreDefaultStreamVersion = 0n;
|
|
1007
|
+
const getSQLiteEventStore = (options) => {
|
|
1008
|
+
let autoGenerateSchema = false;
|
|
1009
|
+
const serializer = _event_driven_io_emmett.JSONSerializer.from(options);
|
|
1010
|
+
const pool = options.pool ?? (0, _event_driven_io_dumbo.dumbo)({
|
|
1011
|
+
serialization: options.serialization,
|
|
1012
|
+
transactionOptions: {
|
|
1013
|
+
allowNestedTransactions: true,
|
|
1014
|
+
mode: "session_based"
|
|
1015
|
+
},
|
|
1016
|
+
...options.driver.mapToDumboOptions(options)
|
|
1017
|
+
});
|
|
1018
|
+
let migrateSchema = void 0;
|
|
1019
|
+
const inlineProjections = (options.projections ?? []).filter(({ type }) => type === "inline").map(({ projection }) => projection);
|
|
1020
|
+
const onBeforeCommitHook = options.hooks?.onBeforeCommit;
|
|
1021
|
+
if (options) autoGenerateSchema = options.schema?.autoMigration === void 0 || options.schema?.autoMigration !== "None";
|
|
1022
|
+
const migrate = (connection) => {
|
|
1023
|
+
if (!migrateSchema) migrateSchema = createEventStoreSchema(connection, {
|
|
1024
|
+
onBeforeSchemaCreated: async (context) => {
|
|
1025
|
+
for (const projection of inlineProjections) if (projection.init) await projection.init({
|
|
1026
|
+
version: projection.version ?? 1,
|
|
1027
|
+
registrationType: "async",
|
|
1028
|
+
status: "active",
|
|
1029
|
+
context: {
|
|
1030
|
+
execute: context.connection.execute,
|
|
1031
|
+
connection: context.connection,
|
|
1032
|
+
driverType: options.driver.driverType
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
if (options.hooks?.onBeforeSchemaCreated) await options.hooks.onBeforeSchemaCreated(context);
|
|
1036
|
+
},
|
|
1037
|
+
onAfterSchemaCreated: options.hooks?.onAfterSchemaCreated
|
|
1038
|
+
});
|
|
1039
|
+
return migrateSchema;
|
|
1040
|
+
};
|
|
1041
|
+
const ensureSchemaExists = () => {
|
|
1042
|
+
if (!autoGenerateSchema) return Promise.resolve();
|
|
1043
|
+
return pool.withConnection((connection) => migrate(connection));
|
|
1044
|
+
};
|
|
1045
|
+
return {
|
|
1046
|
+
async aggregateStream(streamName, options) {
|
|
1047
|
+
await ensureSchemaExists();
|
|
1048
|
+
const { evolve, initialState, read } = options;
|
|
1049
|
+
const expectedStreamVersion = read?.expectedStreamVersion;
|
|
1050
|
+
let state = initialState();
|
|
1051
|
+
if (typeof streamName !== "string") throw new Error("Stream name is not string");
|
|
1052
|
+
const result = await readStream(pool.execute, streamName, {
|
|
1053
|
+
...read,
|
|
1054
|
+
serializer: read?.serialization?.serializer ?? serializer
|
|
1055
|
+
});
|
|
1056
|
+
const currentStreamVersion = result.currentStreamVersion;
|
|
1057
|
+
(0, _event_driven_io_emmett.assertExpectedVersionMatchesCurrent)(currentStreamVersion, expectedStreamVersion, SQLiteEventStoreDefaultStreamVersion);
|
|
1058
|
+
for (const event of result.events) {
|
|
1059
|
+
if (!event) continue;
|
|
1060
|
+
state = evolve(state, event);
|
|
1061
|
+
}
|
|
1062
|
+
return {
|
|
1063
|
+
currentStreamVersion,
|
|
1064
|
+
state,
|
|
1065
|
+
streamExists: result.streamExists
|
|
1066
|
+
};
|
|
1067
|
+
},
|
|
1068
|
+
readStream: async (streamName, readOptions) => {
|
|
1069
|
+
await ensureSchemaExists();
|
|
1070
|
+
return readStream(pool.execute, streamName, {
|
|
1071
|
+
...readOptions,
|
|
1072
|
+
serializer: options.serialization?.serializer ?? serializer
|
|
1073
|
+
});
|
|
1074
|
+
},
|
|
1075
|
+
appendToStream: async (streamName, events, appendOptions) => {
|
|
1076
|
+
await ensureSchemaExists();
|
|
1077
|
+
const [firstPart, ...rest] = streamName.split("-");
|
|
1078
|
+
const streamType = firstPart && rest.length > 0 ? firstPart : unknownTag;
|
|
1079
|
+
const appendResult = await pool.withConnection((connection) => appendToStream(connection, streamName, streamType, events, {
|
|
1080
|
+
...appendOptions,
|
|
1081
|
+
onBeforeCommit: async (messages, context) => {
|
|
1082
|
+
if (inlineProjections.length > 0) await handleProjections({
|
|
1083
|
+
projections: inlineProjections,
|
|
1084
|
+
events: messages,
|
|
1085
|
+
execute: context.connection.execute,
|
|
1086
|
+
connection: context.connection,
|
|
1087
|
+
driverType: options.driver.driverType
|
|
1088
|
+
});
|
|
1089
|
+
if (onBeforeCommitHook) await onBeforeCommitHook(messages, context);
|
|
1090
|
+
}
|
|
1091
|
+
}), { readonly: false });
|
|
1092
|
+
if (!appendResult.success) throw new _event_driven_io_emmett.ExpectedVersionConflictError(-1n, appendOptions?.expectedStreamVersion ?? _event_driven_io_emmett.NO_CONCURRENCY_CHECK);
|
|
1093
|
+
return {
|
|
1094
|
+
nextExpectedStreamVersion: appendResult.nextStreamPosition,
|
|
1095
|
+
lastEventGlobalPosition: appendResult.lastGlobalPosition,
|
|
1096
|
+
createdNewStream: appendResult.nextStreamPosition >= BigInt(events.length)
|
|
1097
|
+
};
|
|
1098
|
+
},
|
|
1099
|
+
async streamExists(streamName, options) {
|
|
1100
|
+
await ensureSchemaExists();
|
|
1101
|
+
return streamExists(pool.execute, streamName, options);
|
|
1102
|
+
},
|
|
1103
|
+
consumer: (consumerOptions) => sqliteEventStoreConsumer({
|
|
1104
|
+
...options ?? {},
|
|
1105
|
+
...consumerOptions ?? {},
|
|
1106
|
+
pool
|
|
1107
|
+
}),
|
|
1108
|
+
async withSession(callback) {
|
|
1109
|
+
return await pool.withConnection(async (connection) => {
|
|
1110
|
+
const sessionStore = getSQLiteEventStore({
|
|
1111
|
+
...options,
|
|
1112
|
+
pool: (0, _event_driven_io_dumbo.dumbo)({
|
|
1113
|
+
...options.driver.mapToDumboOptions(options),
|
|
1114
|
+
connection,
|
|
1115
|
+
serialization: options.serialization
|
|
1116
|
+
}),
|
|
1117
|
+
transactionOptions: {
|
|
1118
|
+
allowNestedTransactions: true,
|
|
1119
|
+
mode: "session_based"
|
|
1120
|
+
},
|
|
1121
|
+
schema: {
|
|
1122
|
+
...options.schema,
|
|
1123
|
+
autoMigration: "None"
|
|
1124
|
+
},
|
|
1125
|
+
serialization: options.serialization
|
|
1126
|
+
});
|
|
1127
|
+
await ensureSchemaExists();
|
|
1128
|
+
return callback({
|
|
1129
|
+
eventStore: sessionStore,
|
|
1130
|
+
close: () => Promise.resolve()
|
|
1131
|
+
});
|
|
1132
|
+
});
|
|
1133
|
+
},
|
|
1134
|
+
close: () => pool.close(),
|
|
1135
|
+
schema: {
|
|
1136
|
+
sql: () => schemaSQL.join(""),
|
|
1137
|
+
print: () => console.log(schemaSQL.join("")),
|
|
1138
|
+
migrate: () => pool.withConnection(migrate)
|
|
1139
|
+
}
|
|
1140
|
+
};
|
|
1141
|
+
};
|
|
1142
|
+
|
|
1143
|
+
//#endregion
|
|
1144
|
+
//#region src/eventStore/schema/readStream.ts
|
|
1145
|
+
const { identifier: identifier$2 } = _event_driven_io_dumbo.SQL;
|
|
1146
|
+
const readStream = async (execute, streamId, options) => {
|
|
1147
|
+
const { serializer } = options;
|
|
1148
|
+
const fromCondition = options.from ? _event_driven_io_dumbo.SQL`AND stream_position >= ${options.from}` : _event_driven_io_dumbo.SQL.EMPTY;
|
|
1149
|
+
const to = Number(options?.to ?? (options?.maxCount ? (options.from ?? 0n) + options.maxCount : NaN));
|
|
1150
|
+
const toCondition = !isNaN(to) ? _event_driven_io_dumbo.SQL`AND stream_position <= ${to}` : _event_driven_io_dumbo.SQL.EMPTY;
|
|
1151
|
+
const { rows: results } = await execute.query(_event_driven_io_dumbo.SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
|
|
1152
|
+
FROM ${identifier$2(messagesTable.name)}
|
|
1153
|
+
WHERE stream_id = ${streamId} AND partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE ${fromCondition} ${toCondition}
|
|
1154
|
+
ORDER BY stream_position ASC`);
|
|
1155
|
+
const messages = results.map((row) => {
|
|
1156
|
+
const rawEvent = {
|
|
1157
|
+
type: row.message_type,
|
|
1158
|
+
data: serializer.deserialize(row.message_data),
|
|
1159
|
+
metadata: serializer.deserialize(row.message_metadata)
|
|
1160
|
+
};
|
|
1161
|
+
const metadata = {
|
|
1162
|
+
..."metadata" in rawEvent ? rawEvent.metadata ?? {} : {},
|
|
1163
|
+
messageId: row.message_id,
|
|
1164
|
+
streamName: streamId,
|
|
1165
|
+
streamPosition: BigInt(row.stream_position),
|
|
1166
|
+
globalPosition: BigInt(row.global_position),
|
|
1167
|
+
checkpoint: (0, _event_driven_io_emmett.bigIntProcessorCheckpoint)(BigInt(row.global_position))
|
|
1168
|
+
};
|
|
1169
|
+
return (0, _event_driven_io_emmett.upcastRecordedMessage)({
|
|
1170
|
+
...rawEvent,
|
|
1171
|
+
kind: "Event",
|
|
1172
|
+
metadata
|
|
1173
|
+
}, options?.schema?.versioning);
|
|
1174
|
+
});
|
|
1175
|
+
return messages.length > 0 ? {
|
|
1176
|
+
currentStreamVersion: messages[messages.length - 1].metadata.streamPosition,
|
|
1177
|
+
events: messages,
|
|
1178
|
+
streamExists: true
|
|
1179
|
+
} : {
|
|
1180
|
+
currentStreamVersion: SQLiteEventStoreDefaultStreamVersion,
|
|
1181
|
+
events: [],
|
|
1182
|
+
streamExists: false
|
|
1183
|
+
};
|
|
1184
|
+
};
|
|
1185
|
+
|
|
1186
|
+
//#endregion
|
|
1187
|
+
//#region src/eventStore/schema/storeProcessorCheckpoint.ts
|
|
1188
|
+
const { identifier: identifier$1 } = _event_driven_io_dumbo.SQL;
|
|
2599
1189
|
async function storeSubscriptionCheckpointSQLite(execute, processorId, version, position, checkPosition, partition, processorInstanceId) {
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
UPDATE ${identifier7(processorsTable.name)}
|
|
1190
|
+
processorInstanceId ??= unknownTag;
|
|
1191
|
+
if (checkPosition !== null) {
|
|
1192
|
+
const updateResult = await execute.command(_event_driven_io_dumbo.SQL`
|
|
1193
|
+
UPDATE ${identifier$1(processorsTable.name)}
|
|
2605
1194
|
SET
|
|
2606
1195
|
last_processed_checkpoint = ${position},
|
|
2607
1196
|
processor_instance_id = ${processorInstanceId}
|
|
2608
1197
|
WHERE processor_id = ${processorId}
|
|
2609
1198
|
AND last_processed_checkpoint = ${checkPosition}
|
|
2610
1199
|
AND partition = ${partition}
|
|
2611
|
-
`
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
try {
|
|
2633
|
-
await execute.command(
|
|
2634
|
-
_dumbo.SQL`INSERT INTO ${identifier7(processorsTable.name)} (processor_id, version, last_processed_checkpoint, partition, processor_instance_id)
|
|
2635
|
-
VALUES (${processorId}, ${version}, ${position}, ${partition}, ${processorInstanceId})`
|
|
2636
|
-
);
|
|
2637
|
-
return 1;
|
|
2638
|
-
} catch (err) {
|
|
2639
|
-
if (!_dumbo.DumboError.isInstanceOf(err, {
|
|
2640
|
-
errorType: _dumbo.UniqueConstraintError.ErrorType
|
|
2641
|
-
})) {
|
|
2642
|
-
throw err;
|
|
2643
|
-
}
|
|
2644
|
-
const current = await _dumbo.singleOrNull.call(void 0,
|
|
2645
|
-
execute.query(
|
|
2646
|
-
_dumbo.SQL`
|
|
2647
|
-
SELECT last_processed_checkpoint FROM ${identifier7(processorsTable.name)}
|
|
2648
|
-
WHERE processor_id = ${processorId} AND partition = ${partition}`
|
|
2649
|
-
)
|
|
2650
|
-
);
|
|
2651
|
-
const currentPosition = current && _optionalChain([current, 'optionalAccess', _133 => _133.last_processed_checkpoint]) !== null ? BigInt(current.last_processed_checkpoint) : null;
|
|
2652
|
-
if (currentPosition === position) {
|
|
2653
|
-
return 0;
|
|
2654
|
-
} else {
|
|
2655
|
-
return 2;
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
}
|
|
1200
|
+
`);
|
|
1201
|
+
if (updateResult.rowCount && updateResult.rowCount > 0) return 1;
|
|
1202
|
+
const current_position = await (0, _event_driven_io_dumbo.singleOrNull)(execute.query(_event_driven_io_dumbo.SQL`
|
|
1203
|
+
SELECT last_processed_checkpoint FROM ${identifier$1(processorsTable.name)}
|
|
1204
|
+
WHERE processor_id = ${processorId} AND partition = ${partition}`));
|
|
1205
|
+
const currentPosition = current_position && current_position?.last_processed_checkpoint !== null ? current_position.last_processed_checkpoint : null;
|
|
1206
|
+
if (currentPosition === position) return 0;
|
|
1207
|
+
else if (position !== null && currentPosition !== null && currentPosition > position) return 2;
|
|
1208
|
+
else return 2;
|
|
1209
|
+
} else try {
|
|
1210
|
+
await execute.command(_event_driven_io_dumbo.SQL`INSERT INTO ${identifier$1(processorsTable.name)} (processor_id, version, last_processed_checkpoint, partition, processor_instance_id)
|
|
1211
|
+
VALUES (${processorId}, ${version}, ${position}, ${partition}, ${processorInstanceId})`);
|
|
1212
|
+
return 1;
|
|
1213
|
+
} catch (err) {
|
|
1214
|
+
if (!_event_driven_io_dumbo.DumboError.isInstanceOf(err, { errorType: _event_driven_io_dumbo.UniqueConstraintError.ErrorType })) throw err;
|
|
1215
|
+
const current = await (0, _event_driven_io_dumbo.singleOrNull)(execute.query(_event_driven_io_dumbo.SQL`
|
|
1216
|
+
SELECT last_processed_checkpoint FROM ${identifier$1(processorsTable.name)}
|
|
1217
|
+
WHERE processor_id = ${processorId} AND partition = ${partition}`));
|
|
1218
|
+
if ((current && current?.last_processed_checkpoint !== null ? BigInt(current.last_processed_checkpoint) : null) === position) return 0;
|
|
1219
|
+
else return 2;
|
|
1220
|
+
}
|
|
2659
1221
|
}
|
|
2660
1222
|
async function storeProcessorCheckpoint(execute, options) {
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
}
|
|
1223
|
+
try {
|
|
1224
|
+
const result = await storeSubscriptionCheckpointSQLite(execute, options.processorId, options.version ?? 1, options.newCheckpoint, options.lastProcessedCheckpoint, options.partition ?? defaultTag);
|
|
1225
|
+
return result === 1 ? {
|
|
1226
|
+
success: true,
|
|
1227
|
+
newCheckpoint: options.newCheckpoint
|
|
1228
|
+
} : {
|
|
1229
|
+
success: false,
|
|
1230
|
+
reason: result === 0 ? "IGNORED" : "MISMATCH"
|
|
1231
|
+
};
|
|
1232
|
+
} catch (error) {
|
|
1233
|
+
console.log(error);
|
|
1234
|
+
throw error;
|
|
1235
|
+
}
|
|
2675
1236
|
}
|
|
2676
1237
|
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
execute.query(
|
|
2681
|
-
_dumbo.SQL`SELECT EXISTS (
|
|
1238
|
+
//#endregion
|
|
1239
|
+
//#region src/eventStore/schema/streamExists.ts
|
|
1240
|
+
const streamExists = (execute, streamId, options) => (0, _event_driven_io_dumbo.exists)(execute.query(_event_driven_io_dumbo.SQL`SELECT EXISTS (
|
|
2682
1241
|
SELECT 1
|
|
2683
|
-
from ${
|
|
2684
|
-
WHERE stream_id = ${streamId} AND partition = ${
|
|
2685
|
-
`
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
var { identifier: identifier8, plain: plain2 } = _dumbo.SQL;
|
|
2692
|
-
var streamsTableSQL = _dumbo.SQL`CREATE TABLE IF NOT EXISTS ${identifier8(streamsTable.name)}(
|
|
1242
|
+
from ${_event_driven_io_dumbo.SQL.identifier(streamsTable.name)}
|
|
1243
|
+
WHERE stream_id = ${streamId} AND partition = ${options?.partition ?? defaultTag} AND is_archived = FALSE) as exists
|
|
1244
|
+
`));
|
|
1245
|
+
|
|
1246
|
+
//#endregion
|
|
1247
|
+
//#region src/eventStore/schema/tables.ts
|
|
1248
|
+
const { identifier, plain } = _event_driven_io_dumbo.SQL;
|
|
1249
|
+
const streamsTableSQL = _event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS ${identifier(streamsTable.name)}(
|
|
2693
1250
|
stream_id TEXT NOT NULL,
|
|
2694
1251
|
stream_position BIGINT NOT NULL DEFAULT 0,
|
|
2695
|
-
partition TEXT NOT NULL DEFAULT '${
|
|
1252
|
+
partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',
|
|
2696
1253
|
stream_type TEXT NOT NULL,
|
|
2697
1254
|
stream_metadata JSONB NOT NULL,
|
|
2698
1255
|
is_archived BOOLEAN NOT NULL DEFAULT FALSE,
|
|
2699
1256
|
PRIMARY KEY (stream_id, partition, is_archived),
|
|
2700
1257
|
UNIQUE (stream_id, partition, is_archived)
|
|
2701
1258
|
);`;
|
|
2702
|
-
|
|
1259
|
+
const messagesTableSQL = _event_driven_io_dumbo.SQL`CREATE TABLE IF NOT EXISTS ${identifier(messagesTable.name)}(
|
|
2703
1260
|
stream_id TEXT NOT NULL,
|
|
2704
1261
|
stream_position BIGINT NOT NULL,
|
|
2705
|
-
partition TEXT NOT NULL DEFAULT '${
|
|
1262
|
+
partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',
|
|
2706
1263
|
message_kind CHAR(1) NOT NULL DEFAULT 'E',
|
|
2707
1264
|
message_data JSONB NOT NULL,
|
|
2708
1265
|
message_metadata JSONB NOT NULL,
|
|
@@ -2715,22 +1272,22 @@ var messagesTableSQL = _dumbo.SQL`CREATE TABLE IF NOT EXISTS ${identifier8(messa
|
|
|
2715
1272
|
UNIQUE (stream_id, stream_position, partition, is_archived)
|
|
2716
1273
|
);
|
|
2717
1274
|
`;
|
|
2718
|
-
|
|
2719
|
-
CREATE TABLE IF NOT EXISTS ${
|
|
1275
|
+
const processorsTableSQL = _event_driven_io_dumbo.SQL`
|
|
1276
|
+
CREATE TABLE IF NOT EXISTS ${_event_driven_io_dumbo.SQL.identifier(processorsTable.name)}(
|
|
2720
1277
|
processor_id TEXT NOT NULL,
|
|
2721
1278
|
version INTEGER NOT NULL DEFAULT 1,
|
|
2722
|
-
partition TEXT NOT NULL DEFAULT '${
|
|
1279
|
+
partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',
|
|
2723
1280
|
status TEXT NOT NULL DEFAULT 'stopped',
|
|
2724
1281
|
last_processed_checkpoint TEXT NOT NULL,
|
|
2725
|
-
processor_instance_id TEXT DEFAULT '${
|
|
1282
|
+
processor_instance_id TEXT DEFAULT '${plain(unknownTag)}',
|
|
2726
1283
|
PRIMARY KEY (processor_id, partition, version)
|
|
2727
1284
|
);
|
|
2728
1285
|
`;
|
|
2729
|
-
|
|
2730
|
-
CREATE TABLE IF NOT EXISTS ${
|
|
1286
|
+
const projectionsTableSQL = _event_driven_io_dumbo.SQL`
|
|
1287
|
+
CREATE TABLE IF NOT EXISTS ${_event_driven_io_dumbo.SQL.identifier(projectionsTable.name)}(
|
|
2731
1288
|
name TEXT NOT NULL,
|
|
2732
1289
|
version INTEGER NOT NULL DEFAULT 1,
|
|
2733
|
-
partition TEXT NOT NULL DEFAULT '${
|
|
1290
|
+
partition TEXT NOT NULL DEFAULT '${plain(globalTag)}',
|
|
2734
1291
|
type CHAR(1) NOT NULL,
|
|
2735
1292
|
kind TEXT NOT NULL,
|
|
2736
1293
|
status TEXT NOT NULL,
|
|
@@ -2738,73 +1295,67 @@ var projectionsTableSQL = _dumbo.SQL`
|
|
|
2738
1295
|
PRIMARY KEY (name, partition, version)
|
|
2739
1296
|
);
|
|
2740
1297
|
`;
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
1298
|
+
const schemaSQL = [
|
|
1299
|
+
streamsTableSQL,
|
|
1300
|
+
messagesTableSQL,
|
|
1301
|
+
processorsTableSQL,
|
|
1302
|
+
projectionsTableSQL
|
|
2746
1303
|
];
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
exports.SQLiteEventStoreDefaultStreamVersion = SQLiteEventStoreDefaultStreamVersion; exports.SQLiteProjectionSpec = SQLiteProjectionSpec; exports.appendToStream = appendToStream; exports.assertSQLQueryResultMatches = assertSQLQueryResultMatches; exports.createEventStoreSchema = createEventStoreSchema; exports.defaultTag = defaultTag2; exports.documentDoesNotExist = documentDoesNotExist; exports.documentExists = documentExists; exports.documentMatchingExists = documentMatchingExists; exports.documentsAreTheSame = documentsAreTheSame; exports.documentsMatchingHaveCount = documentsMatchingHaveCount; exports.emmettPrefix = emmettPrefix2; exports.eventInStream = eventInStream; exports.eventsInStream = eventsInStream; exports.expectPongoDocuments = expectPongoDocuments; exports.expectSQL = expectSQL; exports.getSQLiteEventStore = getSQLiteEventStore; exports.globalNames = globalNames; exports.globalTag = globalTag; exports.handleProjections = handleProjections; exports.messagesTable = messagesTable; exports.messagesTableSQL = messagesTableSQL; exports.migration_0_42_0_FromSubscriptionsToProcessors = migration_0_42_0_FromSubscriptionsToProcessors; exports.migration_0_42_0_SQLs = migration_0_42_0_SQLs; exports.newEventsInStream = newEventsInStream; exports.pongoMultiStreamProjection = pongoMultiStreamProjection; exports.pongoProjection = pongoProjection; exports.pongoSingleStreamProjection = pongoSingleStreamProjection; exports.processorsTable = processorsTable; exports.processorsTableSQL = processorsTableSQL; exports.projectionsTable = projectionsTable; exports.projectionsTableSQL = projectionsTableSQL; exports.readLastMessageGlobalPosition = readLastMessageGlobalPosition; exports.readMessagesBatch = readMessagesBatch; exports.readProcessorCheckpoint = readProcessorCheckpoint; exports.readStream = readStream; exports.schemaSQL = schemaSQL; exports.schema_0_41_0 = schema_0_41_0; exports.schema_0_42_0 = schema_0_42_0; exports.sqliteProjection = sqliteProjection; exports.sqliteRawBatchSQLProjection = sqliteRawBatchSQLProjection; exports.sqliteRawSQLProjection = sqliteRawSQLProjection; exports.storeProcessorCheckpoint = storeProcessorCheckpoint; exports.streamExists = streamExists; exports.streamsTable = streamsTable; exports.streamsTableSQL = streamsTableSQL; exports.unknownTag = unknownTag2;
|
|
1304
|
+
const createEventStoreSchema = async (pool, hooks) => {
|
|
1305
|
+
await pool.withTransaction(async (tx) => {
|
|
1306
|
+
await migration_0_42_0_FromSubscriptionsToProcessors(tx.execute);
|
|
1307
|
+
if (hooks?.onBeforeSchemaCreated) await hooks.onBeforeSchemaCreated({ connection: tx.connection });
|
|
1308
|
+
await tx.execute.batchCommand(schemaSQL);
|
|
1309
|
+
if (hooks?.onAfterSchemaCreated) await hooks.onAfterSchemaCreated();
|
|
1310
|
+
});
|
|
1311
|
+
};
|
|
1312
|
+
|
|
1313
|
+
//#endregion
|
|
1314
|
+
exports.SQLiteEventStoreDefaultStreamVersion = SQLiteEventStoreDefaultStreamVersion;
|
|
1315
|
+
exports.SQLiteProjectionSpec = SQLiteProjectionSpec;
|
|
1316
|
+
exports.appendToStream = appendToStream;
|
|
1317
|
+
exports.assertSQLQueryResultMatches = assertSQLQueryResultMatches;
|
|
1318
|
+
exports.createEventStoreSchema = createEventStoreSchema;
|
|
1319
|
+
exports.defaultTag = defaultTag;
|
|
1320
|
+
exports.documentDoesNotExist = documentDoesNotExist;
|
|
1321
|
+
exports.documentExists = documentExists;
|
|
1322
|
+
exports.documentMatchingExists = documentMatchingExists;
|
|
1323
|
+
exports.documentsAreTheSame = documentsAreTheSame;
|
|
1324
|
+
exports.documentsMatchingHaveCount = documentsMatchingHaveCount;
|
|
1325
|
+
exports.emmettPrefix = emmettPrefix;
|
|
1326
|
+
exports.eventInStream = eventInStream;
|
|
1327
|
+
exports.eventsInStream = eventsInStream;
|
|
1328
|
+
exports.expectPongoDocuments = expectPongoDocuments;
|
|
1329
|
+
exports.expectSQL = expectSQL;
|
|
1330
|
+
exports.getSQLiteEventStore = getSQLiteEventStore;
|
|
1331
|
+
exports.globalNames = globalNames;
|
|
1332
|
+
exports.globalTag = globalTag;
|
|
1333
|
+
exports.handleProjections = handleProjections;
|
|
1334
|
+
exports.messagesTable = messagesTable;
|
|
1335
|
+
exports.messagesTableSQL = messagesTableSQL;
|
|
1336
|
+
exports.migration_0_42_0_FromSubscriptionsToProcessors = migration_0_42_0_FromSubscriptionsToProcessors;
|
|
1337
|
+
exports.migration_0_42_0_SQLs = migration_0_42_0_SQLs;
|
|
1338
|
+
exports.newEventsInStream = newEventsInStream;
|
|
1339
|
+
exports.pongoMultiStreamProjection = pongoMultiStreamProjection;
|
|
1340
|
+
exports.pongoProjection = pongoProjection;
|
|
1341
|
+
exports.pongoSingleStreamProjection = pongoSingleStreamProjection;
|
|
1342
|
+
exports.processorsTable = processorsTable;
|
|
1343
|
+
exports.processorsTableSQL = processorsTableSQL;
|
|
1344
|
+
exports.projectionsTable = projectionsTable;
|
|
1345
|
+
exports.projectionsTableSQL = projectionsTableSQL;
|
|
1346
|
+
exports.readLastMessageGlobalPosition = readLastMessageGlobalPosition;
|
|
1347
|
+
exports.readMessagesBatch = readMessagesBatch;
|
|
1348
|
+
exports.readProcessorCheckpoint = readProcessorCheckpoint;
|
|
1349
|
+
exports.readStream = readStream;
|
|
1350
|
+
exports.schemaSQL = schemaSQL;
|
|
1351
|
+
exports.schema_0_41_0 = schema_0_41_0;
|
|
1352
|
+
exports.schema_0_42_0 = schema_0_42_0;
|
|
1353
|
+
exports.sqliteProjection = sqliteProjection;
|
|
1354
|
+
exports.sqliteRawBatchSQLProjection = sqliteRawBatchSQLProjection;
|
|
1355
|
+
exports.sqliteRawSQLProjection = sqliteRawSQLProjection;
|
|
1356
|
+
exports.storeProcessorCheckpoint = storeProcessorCheckpoint;
|
|
1357
|
+
exports.streamExists = streamExists;
|
|
1358
|
+
exports.streamsTable = streamsTable;
|
|
1359
|
+
exports.streamsTableSQL = streamsTableSQL;
|
|
1360
|
+
exports.unknownTag = unknownTag;
|
|
2810
1361
|
//# sourceMappingURL=index.cjs.map
|