@event-driven-io/emmett-postgresql 0.43.0-apha.2 → 0.43.0-beta.10
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/index.cjs +1723 -1305
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +199 -198
- package/dist/index.d.ts +199 -198
- package/dist/index.js +2086 -1668
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.cjs
CHANGED
|
@@ -1,65 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;//
|
|
2
|
-
var _dumbo = require('@event-driven-io/dumbo');
|
|
3
|
-
|
|
4
|
-
// src/eventStore/schema/readLastMessageGlobalPosition.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// src/eventStore/schema/typing.ts
|
|
8
|
-
var emmettPrefix = "emt";
|
|
9
|
-
var globalTag = "global";
|
|
10
|
-
var defaultTag = `${emmettPrefix}:default`;
|
|
11
|
-
var unknownTag = `${emmettPrefix}:unknown`;
|
|
12
|
-
var globalNames = {
|
|
13
|
-
module: `${emmettPrefix}:module:${globalTag}`,
|
|
14
|
-
tenant: `${emmettPrefix}:tenant:${globalTag}`
|
|
15
|
-
};
|
|
16
|
-
var columns = {
|
|
17
|
-
partition: {
|
|
18
|
-
name: "partition"
|
|
19
|
-
},
|
|
20
|
-
isArchived: { name: "is_archived" }
|
|
21
|
-
};
|
|
22
|
-
var streamsTable = {
|
|
23
|
-
name: `${emmettPrefix}_streams`,
|
|
24
|
-
columns: {
|
|
25
|
-
partition: columns.partition,
|
|
26
|
-
isArchived: columns.isArchived
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var messagesTable = {
|
|
30
|
-
name: `${emmettPrefix}_messages`,
|
|
31
|
-
columns: {
|
|
32
|
-
partition: columns.partition,
|
|
33
|
-
isArchived: columns.isArchived
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
var processorsTable = {
|
|
37
|
-
name: `${emmettPrefix}_processors`
|
|
38
|
-
};
|
|
39
|
-
var projectionsTable = {
|
|
40
|
-
name: `${emmettPrefix}_projections`
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// src/eventStore/schema/readLastMessageGlobalPosition.ts
|
|
44
|
-
var readLastMessageGlobalPosition = async (execute, options) => {
|
|
45
|
-
const result = await _dumbo.singleOrNull.call(void 0,
|
|
46
|
-
execute.query(
|
|
47
|
-
_dumbo.SQL`SELECT global_position
|
|
48
|
-
FROM ${_dumbo.SQL.identifier(messagesTable.name)}
|
|
49
|
-
WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _2 => _2.partition]), () => ( defaultTag))} AND is_archived = FALSE AND transaction_id < pg_snapshot_xmin(pg_current_snapshot())
|
|
50
|
-
ORDER BY transaction_id, global_position
|
|
51
|
-
LIMIT 1`
|
|
52
|
-
)
|
|
53
|
-
);
|
|
54
|
-
return {
|
|
55
|
-
currentGlobalPosition: result !== null ? BigInt(result.global_position) : null
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// src/eventStore/schema/readMessagesBatch.ts
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// ../emmett/dist/chunk-AZDDB5SF.js
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;// ../emmett/dist/chunk-AZDDB5SF.js
|
|
63
2
|
var isNumber = (val) => typeof val === "number" && val === val;
|
|
64
3
|
var isBigint = (val) => typeof val === "bigint" && val === val;
|
|
65
4
|
var isString = (val) => typeof val === "string";
|
|
@@ -100,7 +39,7 @@ var ConcurrencyError = class _ConcurrencyError extends EmmettError {
|
|
|
100
39
|
constructor(current, expected, message) {
|
|
101
40
|
super({
|
|
102
41
|
errorCode: EmmettError.Codes.ConcurrencyError,
|
|
103
|
-
message: _nullishCoalesce(message, () => ( `Expected version ${expected.toString()} does not match current ${_optionalChain([current, 'optionalAccess',
|
|
42
|
+
message: _nullishCoalesce(message, () => ( `Expected version ${expected.toString()} does not match current ${_optionalChain([current, 'optionalAccess', _ => _.toString, 'call', _2 => _2()])}`))
|
|
104
43
|
});
|
|
105
44
|
this.current = current;
|
|
106
45
|
this.expected = expected;
|
|
@@ -111,12 +50,24 @@ var ConcurrencyError = class _ConcurrencyError extends EmmettError {
|
|
|
111
50
|
// ../emmett/dist/index.js
|
|
112
51
|
var _uuid = require('uuid');
|
|
113
52
|
|
|
53
|
+
|
|
114
54
|
var _asyncretry = require('async-retry'); var _asyncretry2 = _interopRequireDefault(_asyncretry);
|
|
115
55
|
|
|
116
56
|
|
|
117
|
-
|
|
118
|
-
var
|
|
119
|
-
var
|
|
57
|
+
|
|
58
|
+
var emmettPrefix = "emt";
|
|
59
|
+
var defaultTag = `${emmettPrefix}:default`;
|
|
60
|
+
var unknownTag = `${emmettPrefix}:unknown`;
|
|
61
|
+
var canCreateEventStoreSession = (eventStore) => "withSession" in eventStore;
|
|
62
|
+
var nulloSessionFactory = (eventStore) => ({
|
|
63
|
+
withSession: (callback) => {
|
|
64
|
+
const nulloSession = {
|
|
65
|
+
eventStore,
|
|
66
|
+
close: () => Promise.resolve()
|
|
67
|
+
};
|
|
68
|
+
return callback(nulloSession);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
120
71
|
var STREAM_EXISTS = "STREAM_EXISTS";
|
|
121
72
|
var STREAM_DOES_NOT_EXIST = "STREAM_DOES_NOT_EXIST";
|
|
122
73
|
var NO_CONCURRENCY_CHECK = "NO_CONCURRENCY_CHECK";
|
|
@@ -133,10 +84,14 @@ var assertExpectedVersionMatchesCurrent = (current, expected, defaultVersion) =>
|
|
|
133
84
|
};
|
|
134
85
|
var ExpectedVersionConflictError = class _ExpectedVersionConflictError extends ConcurrencyError {
|
|
135
86
|
constructor(current, expected) {
|
|
136
|
-
super(_optionalChain([current, 'optionalAccess',
|
|
87
|
+
super(_optionalChain([current, 'optionalAccess', _3 => _3.toString, 'call', _4 => _4()]), _optionalChain([expected, 'optionalAccess', _5 => _5.toString, 'call', _6 => _6()]));
|
|
137
88
|
Object.setPrototypeOf(this, _ExpectedVersionConflictError.prototype);
|
|
138
89
|
}
|
|
139
90
|
};
|
|
91
|
+
var isExpectedVersionConflictError = (error) => error instanceof ExpectedVersionConflictError || EmmettError.isInstanceOf(
|
|
92
|
+
error,
|
|
93
|
+
ExpectedVersionConflictError.Codes.ConcurrencyError
|
|
94
|
+
);
|
|
140
95
|
var isPrimitive = (value) => {
|
|
141
96
|
const type = typeof value;
|
|
142
97
|
return value === null || value === void 0 || type === "boolean" || type === "number" || type === "string" || type === "symbol" || type === "bigint";
|
|
@@ -342,45 +297,128 @@ var toNormalizedString = (value) => value.toString().padStart(19, "0");
|
|
|
342
297
|
var bigInt = {
|
|
343
298
|
toNormalizedString
|
|
344
299
|
};
|
|
345
|
-
var
|
|
346
|
-
|
|
347
|
-
|
|
300
|
+
var bigIntReplacer = (_key, value) => {
|
|
301
|
+
return typeof value === "bigint" ? value.toString() : value;
|
|
302
|
+
};
|
|
303
|
+
var dateReplacer = (_key, value) => {
|
|
304
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
305
|
+
};
|
|
306
|
+
var isFirstLetterNumeric = (str) => {
|
|
307
|
+
const c = str.charCodeAt(0);
|
|
308
|
+
return c >= 48 && c <= 57;
|
|
309
|
+
};
|
|
310
|
+
var isFirstLetterNumericOrMinus = (str) => {
|
|
311
|
+
const c = str.charCodeAt(0);
|
|
312
|
+
return c >= 48 && c <= 57 || c === 45;
|
|
313
|
+
};
|
|
314
|
+
var bigIntReviver = (_key, value, context) => {
|
|
315
|
+
if (typeof value === "number" && Number.isInteger(value) && !Number.isSafeInteger(value)) {
|
|
316
|
+
try {
|
|
317
|
+
return BigInt(_nullishCoalesce(_optionalChain([context, 'optionalAccess', _7 => _7.source]), () => ( value.toString())));
|
|
318
|
+
} catch (e2) {
|
|
319
|
+
return value;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (typeof value === "string" && value.length > 15) {
|
|
323
|
+
if (isFirstLetterNumericOrMinus(value)) {
|
|
324
|
+
const num = Number(value);
|
|
325
|
+
if (Number.isFinite(num) && !Number.isSafeInteger(num)) {
|
|
326
|
+
try {
|
|
327
|
+
return BigInt(value);
|
|
328
|
+
} catch (e3) {
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
348
332
|
}
|
|
333
|
+
return value;
|
|
349
334
|
};
|
|
350
|
-
var
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
(_, v) => typeof v === "bigint" ? v.toString() : v
|
|
357
|
-
);
|
|
358
|
-
},
|
|
359
|
-
parse: (text, options) => {
|
|
360
|
-
const parsed = JSON.parse(text, _optionalChain([options, 'optionalAccess', _10 => _10.reviver]));
|
|
361
|
-
if (_optionalChain([options, 'optionalAccess', _11 => _11.typeCheck]) && !_optionalChain([options, 'optionalAccess', _12 => _12.typeCheck, 'call', _13 => _13(parsed)]))
|
|
362
|
-
throw new ParseError(text);
|
|
363
|
-
return _optionalChain([options, 'optionalAccess', _14 => _14.map]) ? options.map(parsed) : parsed;
|
|
335
|
+
var dateReviver = (_key, value) => {
|
|
336
|
+
if (typeof value === "string" && value.length === 24 && isFirstLetterNumeric(value) && value[10] === "T" && value[23] === "Z") {
|
|
337
|
+
const date = new Date(value);
|
|
338
|
+
if (!isNaN(date.getTime())) {
|
|
339
|
+
return date;
|
|
340
|
+
}
|
|
364
341
|
}
|
|
342
|
+
return value;
|
|
343
|
+
};
|
|
344
|
+
var composeJSONReplacers = (...replacers) => {
|
|
345
|
+
const filteredReplacers = replacers.filter((r) => r !== void 0);
|
|
346
|
+
if (filteredReplacers.length === 0) return void 0;
|
|
347
|
+
return (key, value) => (
|
|
348
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
349
|
+
filteredReplacers.reduce(
|
|
350
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
351
|
+
(accValue, replacer) => replacer(key, accValue),
|
|
352
|
+
value
|
|
353
|
+
)
|
|
354
|
+
);
|
|
355
|
+
};
|
|
356
|
+
var composeJSONRevivers = (...revivers) => {
|
|
357
|
+
const filteredRevivers = revivers.filter((r) => r !== void 0);
|
|
358
|
+
if (filteredRevivers.length === 0) return void 0;
|
|
359
|
+
return (key, value, context) => (
|
|
360
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
361
|
+
filteredRevivers.reduce(
|
|
362
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
363
|
+
(accValue, reviver) => reviver(key, accValue, context),
|
|
364
|
+
value
|
|
365
|
+
)
|
|
366
|
+
);
|
|
367
|
+
};
|
|
368
|
+
var JSONReplacer = (opts) => composeJSONReplacers(
|
|
369
|
+
_optionalChain([opts, 'optionalAccess', _8 => _8.replacer]),
|
|
370
|
+
_optionalChain([opts, 'optionalAccess', _9 => _9.failOnBigIntSerialization]) !== true ? JSONReplacers.bigInt : void 0,
|
|
371
|
+
_optionalChain([opts, 'optionalAccess', _10 => _10.useDefaultDateSerialization]) !== true ? JSONReplacers.date : void 0
|
|
372
|
+
);
|
|
373
|
+
var JSONReviver = (opts) => composeJSONRevivers(
|
|
374
|
+
_optionalChain([opts, 'optionalAccess', _11 => _11.reviver]),
|
|
375
|
+
_optionalChain([opts, 'optionalAccess', _12 => _12.parseBigInts]) === true ? JSONRevivers.bigInt : void 0,
|
|
376
|
+
_optionalChain([opts, 'optionalAccess', _13 => _13.parseDates]) === true ? JSONRevivers.date : void 0
|
|
377
|
+
);
|
|
378
|
+
var JSONReplacers = {
|
|
379
|
+
bigInt: bigIntReplacer,
|
|
380
|
+
date: dateReplacer
|
|
381
|
+
};
|
|
382
|
+
var JSONRevivers = {
|
|
383
|
+
bigInt: bigIntReviver,
|
|
384
|
+
date: dateReviver
|
|
385
|
+
};
|
|
386
|
+
var jsonSerializer = (options) => {
|
|
387
|
+
const defaultReplacer = JSONReplacer(options);
|
|
388
|
+
const defaultReviver = JSONReviver(options);
|
|
389
|
+
return {
|
|
390
|
+
serialize: (object, serializerOptions) => JSON.stringify(
|
|
391
|
+
object,
|
|
392
|
+
serializerOptions ? JSONReplacer(serializerOptions) : defaultReplacer
|
|
393
|
+
),
|
|
394
|
+
deserialize: (payload, deserializerOptions) => JSON.parse(
|
|
395
|
+
payload,
|
|
396
|
+
deserializerOptions ? JSONReviver(deserializerOptions) : defaultReviver
|
|
397
|
+
)
|
|
398
|
+
};
|
|
365
399
|
};
|
|
400
|
+
var JSONSerializer = Object.assign(jsonSerializer(), {
|
|
401
|
+
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)))
|
|
402
|
+
});
|
|
403
|
+
var NoRetries = { retries: 0 };
|
|
366
404
|
var asyncRetry = async (fn, opts) => {
|
|
367
405
|
if (opts === void 0 || opts.retries === 0) return fn();
|
|
368
406
|
return _asyncretry2.default.call(void 0,
|
|
369
407
|
async (bail) => {
|
|
370
408
|
try {
|
|
371
409
|
const result = await fn();
|
|
372
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
410
|
+
if (_optionalChain([opts, 'optionalAccess', _20 => _20.shouldRetryResult]) && opts.shouldRetryResult(result)) {
|
|
373
411
|
throw new EmmettError(
|
|
374
|
-
`Retrying because of result: ${
|
|
412
|
+
`Retrying because of result: ${JSONSerializer.serialize(result)}`
|
|
375
413
|
);
|
|
376
414
|
}
|
|
377
415
|
return result;
|
|
378
|
-
} catch (
|
|
379
|
-
if (_optionalChain([opts, 'optionalAccess',
|
|
380
|
-
bail(
|
|
416
|
+
} catch (error) {
|
|
417
|
+
if (_optionalChain([opts, 'optionalAccess', _21 => _21.shouldRetryError]) && !opts.shouldRetryError(error)) {
|
|
418
|
+
bail(error);
|
|
381
419
|
return void 0;
|
|
382
420
|
}
|
|
383
|
-
throw
|
|
421
|
+
throw error;
|
|
384
422
|
}
|
|
385
423
|
},
|
|
386
424
|
_nullishCoalesce(opts, () => ( { retries: 0 }))
|
|
@@ -421,190 +459,22 @@ var hashText = async (text) => {
|
|
|
421
459
|
const view = new BigInt64Array(hashBuffer, 0, 1);
|
|
422
460
|
return view[0];
|
|
423
461
|
};
|
|
424
|
-
var AssertionError = class extends Error {
|
|
425
|
-
constructor(message2) {
|
|
426
|
-
super(message2);
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
var isSubset = (superObj, subObj) => {
|
|
430
|
-
const sup = superObj;
|
|
431
|
-
const sub = subObj;
|
|
432
|
-
assertOk(sup);
|
|
433
|
-
assertOk(sub);
|
|
434
|
-
return Object.keys(sub).every((ele) => {
|
|
435
|
-
if (typeof sub[ele] == "object") {
|
|
436
|
-
return isSubset(sup[ele], sub[ele]);
|
|
437
|
-
}
|
|
438
|
-
return sub[ele] === sup[ele];
|
|
439
|
-
});
|
|
440
|
-
};
|
|
441
|
-
var assertFails = (message2) => {
|
|
442
|
-
throw new AssertionError(_nullishCoalesce(message2, () => ( "That should not ever happened, right?")));
|
|
443
|
-
};
|
|
444
|
-
var assertDeepEqual = (actual, expected, message2) => {
|
|
445
|
-
if (!deepEquals(actual, expected))
|
|
446
|
-
throw new AssertionError(
|
|
447
|
-
_nullishCoalesce(message2, () => ( `subObj:
|
|
448
|
-
${JSONParser.stringify(expected)}
|
|
449
|
-
is not equal to
|
|
450
|
-
${JSONParser.stringify(actual)}`))
|
|
451
|
-
);
|
|
452
|
-
};
|
|
453
|
-
function assertTrue(condition, message2) {
|
|
454
|
-
if (condition !== true)
|
|
455
|
-
throw new AssertionError(_nullishCoalesce(message2, () => ( `Condition is false`)));
|
|
456
|
-
}
|
|
457
|
-
function assertOk(obj, message2) {
|
|
458
|
-
if (!obj) throw new AssertionError(_nullishCoalesce(message2, () => ( `Condition is not truthy`)));
|
|
459
|
-
}
|
|
460
|
-
function assertEqual(expected, actual, message2) {
|
|
461
|
-
if (expected !== actual)
|
|
462
|
-
throw new AssertionError(
|
|
463
|
-
`${_nullishCoalesce(message2, () => ( "Objects are not equal"))}:
|
|
464
|
-
Expected: ${JSONParser.stringify(expected)}
|
|
465
|
-
Actual: ${JSONParser.stringify(actual)}`
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
function assertNotEqual(obj, other, message2) {
|
|
469
|
-
if (obj === other)
|
|
470
|
-
throw new AssertionError(
|
|
471
|
-
_nullishCoalesce(message2, () => ( `Objects are equal: ${JSONParser.stringify(obj)}`))
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
function assertIsNotNull(result) {
|
|
475
|
-
assertNotEqual(result, null);
|
|
476
|
-
assertOk(result);
|
|
477
|
-
}
|
|
478
|
-
var assertThatArray = (array) => {
|
|
479
|
-
return {
|
|
480
|
-
isEmpty: () => assertEqual(
|
|
481
|
-
array.length,
|
|
482
|
-
0,
|
|
483
|
-
`Array is not empty ${JSONParser.stringify(array)}`
|
|
484
|
-
),
|
|
485
|
-
isNotEmpty: () => assertNotEqual(array.length, 0, `Array is empty`),
|
|
486
|
-
hasSize: (length) => assertEqual(array.length, length),
|
|
487
|
-
containsElements: (other) => {
|
|
488
|
-
assertTrue(other.every((ts) => array.some((o) => deepEquals(ts, o))));
|
|
489
|
-
},
|
|
490
|
-
containsElementsMatching: (other) => {
|
|
491
|
-
assertTrue(other.every((ts) => array.some((o) => isSubset(o, ts))));
|
|
492
|
-
},
|
|
493
|
-
containsOnlyElementsMatching: (other) => {
|
|
494
|
-
assertEqual(array.length, other.length, `Arrays lengths don't match`);
|
|
495
|
-
assertTrue(other.every((ts) => array.some((o) => isSubset(o, ts))));
|
|
496
|
-
},
|
|
497
|
-
containsExactlyInAnyOrder: (other) => {
|
|
498
|
-
assertEqual(array.length, other.length);
|
|
499
|
-
assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));
|
|
500
|
-
},
|
|
501
|
-
containsExactlyInAnyOrderElementsOf: (other) => {
|
|
502
|
-
assertEqual(array.length, other.length);
|
|
503
|
-
assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));
|
|
504
|
-
},
|
|
505
|
-
containsExactlyElementsOf: (other) => {
|
|
506
|
-
assertEqual(array.length, other.length);
|
|
507
|
-
for (let i = 0; i < array.length; i++) {
|
|
508
|
-
assertTrue(deepEquals(array[i], other[i]));
|
|
509
|
-
}
|
|
510
|
-
},
|
|
511
|
-
containsExactly: (elem) => {
|
|
512
|
-
assertEqual(array.length, 1);
|
|
513
|
-
assertTrue(deepEquals(array[0], elem));
|
|
514
|
-
},
|
|
515
|
-
contains: (elem) => {
|
|
516
|
-
assertTrue(array.some((a) => deepEquals(a, elem)));
|
|
517
|
-
},
|
|
518
|
-
containsOnlyOnceElementsOf: (other) => {
|
|
519
|
-
assertTrue(
|
|
520
|
-
other.map((o) => array.filter((a) => deepEquals(a, o)).length).filter((a) => a === 1).length === other.length
|
|
521
|
-
);
|
|
522
|
-
},
|
|
523
|
-
containsAnyOf: (other) => {
|
|
524
|
-
assertTrue(array.some((a) => other.some((o) => deepEquals(a, o))));
|
|
525
|
-
},
|
|
526
|
-
allMatch: (matches) => {
|
|
527
|
-
assertTrue(array.every(matches));
|
|
528
|
-
},
|
|
529
|
-
anyMatches: (matches) => {
|
|
530
|
-
assertTrue(array.some(matches));
|
|
531
|
-
},
|
|
532
|
-
allMatchAsync: async (matches) => {
|
|
533
|
-
for (const item of array) {
|
|
534
|
-
assertTrue(await matches(item));
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
};
|
|
538
|
-
};
|
|
539
|
-
var downcastRecordedMessage = (recordedMessage, options) => {
|
|
540
|
-
if (!_optionalChain([options, 'optionalAccess', _17 => _17.downcast]))
|
|
541
|
-
return recordedMessage;
|
|
542
|
-
const downcasted = options.downcast(
|
|
543
|
-
recordedMessage
|
|
544
|
-
);
|
|
545
|
-
return {
|
|
546
|
-
...recordedMessage,
|
|
547
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
548
|
-
data: downcasted.data,
|
|
549
|
-
..."metadata" in recordedMessage || "metadata" in downcasted ? {
|
|
550
|
-
metadata: {
|
|
551
|
-
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
552
|
-
..."metadata" in downcasted ? downcasted.metadata : {}
|
|
553
|
-
}
|
|
554
|
-
} : {}
|
|
555
|
-
};
|
|
556
|
-
};
|
|
557
|
-
var downcastRecordedMessages = (recordedMessages, options) => {
|
|
558
|
-
if (!_optionalChain([options, 'optionalAccess', _18 => _18.downcast]))
|
|
559
|
-
return recordedMessages;
|
|
560
|
-
return recordedMessages.map(
|
|
561
|
-
(recordedMessage) => downcastRecordedMessage(recordedMessage, options)
|
|
562
|
-
);
|
|
563
|
-
};
|
|
564
|
-
var upcastRecordedMessage = (recordedMessage, options) => {
|
|
565
|
-
if (!_optionalChain([options, 'optionalAccess', _19 => _19.upcast]))
|
|
566
|
-
return recordedMessage;
|
|
567
|
-
const upcasted = options.upcast(
|
|
568
|
-
recordedMessage
|
|
569
|
-
);
|
|
570
|
-
return {
|
|
571
|
-
...recordedMessage,
|
|
572
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
573
|
-
data: upcasted.data,
|
|
574
|
-
..."metadata" in recordedMessage || "metadata" in upcasted ? {
|
|
575
|
-
metadata: {
|
|
576
|
-
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
577
|
-
..."metadata" in upcasted ? upcasted.metadata : {}
|
|
578
|
-
}
|
|
579
|
-
} : {}
|
|
580
|
-
};
|
|
581
|
-
};
|
|
582
462
|
var getCheckpoint = (message2) => {
|
|
583
|
-
return
|
|
584
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
585
|
-
message2.metadata.checkpoint
|
|
586
|
-
) : "globalPosition" in message2.metadata && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
587
|
-
isBigint(message2.metadata.globalPosition) ? (
|
|
588
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
589
|
-
message2.metadata.globalPosition
|
|
590
|
-
) : "streamPosition" in message2.metadata && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
591
|
-
isBigint(message2.metadata.streamPosition) ? (
|
|
592
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
593
|
-
message2.metadata.streamPosition
|
|
594
|
-
) : null;
|
|
463
|
+
return message2.metadata.checkpoint;
|
|
595
464
|
};
|
|
596
465
|
var wasMessageHandled = (message2, checkpoint) => {
|
|
597
466
|
const messageCheckpoint = getCheckpoint(message2);
|
|
598
|
-
|
|
599
|
-
return messageCheckpoint !== null && messageCheckpoint !== void 0 && checkpointBigint !== null && checkpointBigint !== void 0 && messageCheckpoint <= checkpointBigint;
|
|
467
|
+
return messageCheckpoint !== null && messageCheckpoint !== void 0 && checkpoint !== null && checkpoint !== void 0 && messageCheckpoint <= checkpoint;
|
|
600
468
|
};
|
|
601
469
|
var MessageProcessorType = {
|
|
602
470
|
PROJECTOR: "projector",
|
|
603
471
|
REACTOR: "reactor"
|
|
604
472
|
};
|
|
605
473
|
var defaultProcessingMessageProcessingScope = (handler, partialContext) => handler(partialContext);
|
|
474
|
+
var bigIntProcessorCheckpoint = (value) => bigInt.toNormalizedString(value);
|
|
475
|
+
var parseBigIntProcessorCheckpoint = (value) => BigInt(value);
|
|
606
476
|
var defaultProcessorVersion = 1;
|
|
607
|
-
var defaultProcessorPartition =
|
|
477
|
+
var defaultProcessorPartition = defaultTag;
|
|
608
478
|
var getProcessorInstanceId = (processorId) => `${processorId}:${_uuid.v7.call(void 0, )}`;
|
|
609
479
|
var getProjectorId = (options) => `emt:processor:projector:${options.projectionName}`;
|
|
610
480
|
var reactor = (options) => {
|
|
@@ -652,12 +522,13 @@ var reactor = (options) => {
|
|
|
652
522
|
id: processorId,
|
|
653
523
|
instanceId,
|
|
654
524
|
type,
|
|
525
|
+
canHandle,
|
|
655
526
|
init,
|
|
656
527
|
start: async (startOptions) => {
|
|
657
528
|
if (isActive) return;
|
|
658
529
|
await init(startOptions);
|
|
659
530
|
isActive = true;
|
|
660
|
-
closeSignal = onShutdown(() => close(
|
|
531
|
+
closeSignal = onShutdown(() => close(startOptions));
|
|
661
532
|
if (lastCheckpoint !== null)
|
|
662
533
|
return {
|
|
663
534
|
lastCheckpoint
|
|
@@ -668,7 +539,7 @@ var reactor = (options) => {
|
|
|
668
539
|
}
|
|
669
540
|
if (startFrom && startFrom !== "CURRENT") return startFrom;
|
|
670
541
|
if (checkpoints) {
|
|
671
|
-
const readResult = await _optionalChain([checkpoints, 'optionalAccess',
|
|
542
|
+
const readResult = await _optionalChain([checkpoints, 'optionalAccess', _22 => _22.read, 'call', _23 => _23(
|
|
672
543
|
{
|
|
673
544
|
processorId,
|
|
674
545
|
partition
|
|
@@ -696,7 +567,7 @@ var reactor = (options) => {
|
|
|
696
567
|
const upcasted = upcastRecordedMessage(
|
|
697
568
|
// TODO: Make it smarter
|
|
698
569
|
message2,
|
|
699
|
-
_optionalChain([options, 'access',
|
|
570
|
+
_optionalChain([options, 'access', _24 => _24.messageOptions, 'optionalAccess', _25 => _25.schema, 'optionalAccess', _26 => _26.versioning])
|
|
700
571
|
);
|
|
701
572
|
if (canHandle !== void 0 && !canHandle.includes(upcasted.type))
|
|
702
573
|
continue;
|
|
@@ -749,352 +620,661 @@ var projector = (options) => {
|
|
|
749
620
|
processorId,
|
|
750
621
|
messageOptions: options.projection.eventsOptions,
|
|
751
622
|
hooks: {
|
|
752
|
-
onInit: _optionalChain([options, 'access',
|
|
753
|
-
onStart: options.truncateOnStart && options.projection.truncate || _optionalChain([options, 'access',
|
|
623
|
+
onInit: _optionalChain([options, 'access', _27 => _27.hooks, 'optionalAccess', _28 => _28.onInit]),
|
|
624
|
+
onStart: options.truncateOnStart && options.projection.truncate || _optionalChain([options, 'access', _29 => _29.hooks, 'optionalAccess', _30 => _30.onStart]) ? async (context) => {
|
|
754
625
|
if (options.truncateOnStart && options.projection.truncate)
|
|
755
626
|
await options.projection.truncate(context);
|
|
756
|
-
if (_optionalChain([options, 'access',
|
|
627
|
+
if (_optionalChain([options, 'access', _31 => _31.hooks, 'optionalAccess', _32 => _32.onStart])) await _optionalChain([options, 'access', _33 => _33.hooks, 'optionalAccess', _34 => _34.onStart, 'call', _35 => _35(context)]);
|
|
757
628
|
} : void 0,
|
|
758
|
-
onClose: _optionalChain([options, 'access',
|
|
629
|
+
onClose: _optionalChain([options, 'access', _36 => _36.hooks, 'optionalAccess', _37 => _37.onClose])
|
|
759
630
|
},
|
|
760
631
|
eachMessage: async (event2, context) => projection2.handle([event2], context)
|
|
761
632
|
});
|
|
762
633
|
};
|
|
763
|
-
var
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
const
|
|
770
|
-
const
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
634
|
+
var AssertionError = class extends Error {
|
|
635
|
+
constructor(message2) {
|
|
636
|
+
super(message2);
|
|
637
|
+
}
|
|
638
|
+
};
|
|
639
|
+
var isSubset = (superObj, subObj) => {
|
|
640
|
+
const sup = superObj;
|
|
641
|
+
const sub = subObj;
|
|
642
|
+
assertOk(sup);
|
|
643
|
+
assertOk(sub);
|
|
644
|
+
return Object.keys(sub).every((ele) => {
|
|
645
|
+
if (sub[ele] !== null && typeof sub[ele] == "object") {
|
|
646
|
+
return isSubset(sup[ele], sub[ele]);
|
|
647
|
+
}
|
|
648
|
+
return sub[ele] === sup[ele];
|
|
649
|
+
});
|
|
650
|
+
};
|
|
651
|
+
var assertFails = (message2) => {
|
|
652
|
+
throw new AssertionError(_nullishCoalesce(message2, () => ( "That should not ever happened, right?")));
|
|
653
|
+
};
|
|
654
|
+
var assertDeepEqual = (actual, expected, message2) => {
|
|
655
|
+
if (!deepEquals(actual, expected))
|
|
656
|
+
throw new AssertionError(
|
|
657
|
+
_nullishCoalesce(message2, () => ( `subObj:
|
|
658
|
+
${JSONSerializer.serialize(expected)}
|
|
659
|
+
is not equal to
|
|
660
|
+
${JSONSerializer.serialize(actual)}`))
|
|
661
|
+
);
|
|
662
|
+
};
|
|
663
|
+
function assertTrue(condition, message2) {
|
|
664
|
+
if (condition !== true)
|
|
665
|
+
throw new AssertionError(_nullishCoalesce(message2, () => ( `Condition is false`)));
|
|
666
|
+
}
|
|
667
|
+
function assertOk(obj, message2) {
|
|
668
|
+
if (!obj) throw new AssertionError(_nullishCoalesce(message2, () => ( `Condition is not truthy`)));
|
|
669
|
+
}
|
|
670
|
+
function assertEqual(expected, actual, message2) {
|
|
671
|
+
if (expected !== actual)
|
|
672
|
+
throw new AssertionError(
|
|
673
|
+
`${_nullishCoalesce(message2, () => ( "Objects are not equal"))}:
|
|
674
|
+
Expected: ${JSONSerializer.serialize(expected)}
|
|
675
|
+
Actual: ${JSONSerializer.serialize(actual)}`
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
function assertNotEqual(obj, other, message2) {
|
|
679
|
+
if (obj === other)
|
|
680
|
+
throw new AssertionError(
|
|
681
|
+
_nullishCoalesce(message2, () => ( `Objects are equal: ${JSONSerializer.serialize(obj)}`))
|
|
682
|
+
);
|
|
683
|
+
}
|
|
684
|
+
function assertIsNotNull(result) {
|
|
685
|
+
assertNotEqual(result, null);
|
|
686
|
+
assertOk(result);
|
|
687
|
+
}
|
|
688
|
+
function assertIsNull(result) {
|
|
689
|
+
assertEqual(result, null);
|
|
690
|
+
}
|
|
691
|
+
var assertThatArray = (array) => {
|
|
692
|
+
return {
|
|
693
|
+
isEmpty: () => assertEqual(
|
|
694
|
+
array.length,
|
|
695
|
+
0,
|
|
696
|
+
`Array is not empty ${JSONSerializer.serialize(array)}`
|
|
780
697
|
),
|
|
781
|
-
(
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
698
|
+
isNotEmpty: () => assertNotEqual(array.length, 0, `Array is empty`),
|
|
699
|
+
hasSize: (length) => assertEqual(array.length, length),
|
|
700
|
+
containsElements: (other) => {
|
|
701
|
+
assertTrue(other.every((ts) => array.some((o) => deepEquals(ts, o))));
|
|
702
|
+
},
|
|
703
|
+
containsElementsMatching: (other) => {
|
|
704
|
+
assertTrue(other.every((ts) => array.some((o) => isSubset(o, ts))));
|
|
705
|
+
},
|
|
706
|
+
containsOnlyElementsMatching: (other) => {
|
|
707
|
+
assertEqual(array.length, other.length, `Arrays lengths don't match`);
|
|
708
|
+
assertTrue(other.every((ts) => array.some((o) => isSubset(o, ts))));
|
|
709
|
+
},
|
|
710
|
+
containsExactlyInAnyOrder: (other) => {
|
|
711
|
+
assertEqual(array.length, other.length);
|
|
712
|
+
assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));
|
|
713
|
+
},
|
|
714
|
+
containsExactlyInAnyOrderElementsOf: (other) => {
|
|
715
|
+
assertEqual(array.length, other.length);
|
|
716
|
+
assertTrue(array.every((ts) => other.some((o) => deepEquals(ts, o))));
|
|
717
|
+
},
|
|
718
|
+
containsExactlyElementsOf: (other) => {
|
|
719
|
+
assertEqual(array.length, other.length);
|
|
720
|
+
for (let i = 0; i < array.length; i++) {
|
|
721
|
+
assertTrue(deepEquals(array[i], other[i]));
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
containsExactly: (elem) => {
|
|
725
|
+
assertEqual(array.length, 1);
|
|
726
|
+
assertTrue(deepEquals(array[0], elem));
|
|
727
|
+
},
|
|
728
|
+
contains: (elem) => {
|
|
729
|
+
assertTrue(array.some((a) => deepEquals(a, elem)));
|
|
730
|
+
},
|
|
731
|
+
containsOnlyOnceElementsOf: (other) => {
|
|
732
|
+
assertTrue(
|
|
733
|
+
other.map((o) => array.filter((a) => deepEquals(a, o)).length).filter((a) => a === 1).length === other.length
|
|
734
|
+
);
|
|
735
|
+
},
|
|
736
|
+
containsAnyOf: (other) => {
|
|
737
|
+
assertTrue(array.some((a) => other.some((o) => deepEquals(a, o))));
|
|
738
|
+
},
|
|
739
|
+
allMatch: (matches) => {
|
|
740
|
+
assertTrue(array.every(matches));
|
|
741
|
+
},
|
|
742
|
+
anyMatches: (matches) => {
|
|
743
|
+
assertTrue(array.some(matches));
|
|
744
|
+
},
|
|
745
|
+
allMatchAsync: async (matches) => {
|
|
746
|
+
for (const item of array) {
|
|
747
|
+
assertTrue(await matches(item));
|
|
748
|
+
}
|
|
799
749
|
}
|
|
800
|
-
);
|
|
801
|
-
return messages.length > 0 ? {
|
|
802
|
-
currentGlobalPosition: messages[messages.length - 1].metadata.globalPosition,
|
|
803
|
-
messages,
|
|
804
|
-
areMessagesLeft: messages.length === batchSize
|
|
805
|
-
} : {
|
|
806
|
-
currentGlobalPosition: "from" in options ? options.from : "after" in options ? options.after : 0n,
|
|
807
|
-
messages: [],
|
|
808
|
-
areMessagesLeft: false
|
|
809
750
|
};
|
|
810
751
|
};
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
const pullMessages = async (options) => {
|
|
826
|
-
const after = options.startFrom === "BEGINNING" ? 0n : options.startFrom === "END" ? await _asyncNullishCoalesce((await readLastMessageGlobalPosition(executor)).currentGlobalPosition, async () => ( 0n)) : options.startFrom.lastCheckpoint;
|
|
827
|
-
const readMessagesOptions = {
|
|
828
|
-
after,
|
|
829
|
-
batchSize
|
|
830
|
-
};
|
|
831
|
-
let waitTime = 100;
|
|
832
|
-
while (isRunning && !_optionalChain([signal, 'optionalAccess', _37 => _37.aborted])) {
|
|
833
|
-
const { messages, currentGlobalPosition, areMessagesLeft } = await readMessagesBatch(executor, readMessagesOptions);
|
|
834
|
-
if (messages.length > 0) {
|
|
835
|
-
const result = await eachBatch(messages);
|
|
836
|
-
if (result && result.type === "STOP") {
|
|
837
|
-
isRunning = false;
|
|
838
|
-
break;
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
readMessagesOptions.after = currentGlobalPosition;
|
|
842
|
-
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
843
|
-
if (_optionalChain([stopWhen, 'optionalAccess', _38 => _38.noMessagesLeft]) === true && !areMessagesLeft) {
|
|
844
|
-
isRunning = false;
|
|
845
|
-
break;
|
|
752
|
+
var downcastRecordedMessage = (recordedMessage, options) => {
|
|
753
|
+
if (!_optionalChain([options, 'optionalAccess', _38 => _38.downcast]))
|
|
754
|
+
return recordedMessage;
|
|
755
|
+
const downcasted = options.downcast(
|
|
756
|
+
recordedMessage
|
|
757
|
+
);
|
|
758
|
+
return {
|
|
759
|
+
...recordedMessage,
|
|
760
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
761
|
+
data: downcasted.data,
|
|
762
|
+
..."metadata" in recordedMessage || "metadata" in downcasted ? {
|
|
763
|
+
metadata: {
|
|
764
|
+
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
765
|
+
..."metadata" in downcasted ? downcasted.metadata : {}
|
|
846
766
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
767
|
+
} : {}
|
|
768
|
+
};
|
|
769
|
+
};
|
|
770
|
+
var downcastRecordedMessages = (recordedMessages, options) => {
|
|
771
|
+
if (!_optionalChain([options, 'optionalAccess', _39 => _39.downcast]))
|
|
772
|
+
return recordedMessages;
|
|
773
|
+
return recordedMessages.map(
|
|
774
|
+
(recordedMessage) => downcastRecordedMessage(recordedMessage, options)
|
|
775
|
+
);
|
|
776
|
+
};
|
|
777
|
+
var upcastRecordedMessage = (recordedMessage, options) => {
|
|
778
|
+
if (!_optionalChain([options, 'optionalAccess', _40 => _40.upcast]))
|
|
779
|
+
return recordedMessage;
|
|
780
|
+
const upcasted = options.upcast(
|
|
781
|
+
recordedMessage
|
|
782
|
+
);
|
|
783
|
+
return {
|
|
784
|
+
...recordedMessage,
|
|
785
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
786
|
+
data: upcasted.data,
|
|
787
|
+
..."metadata" in recordedMessage || "metadata" in upcasted ? {
|
|
788
|
+
metadata: {
|
|
789
|
+
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
790
|
+
..."metadata" in upcasted ? upcasted.metadata : {}
|
|
851
791
|
}
|
|
852
|
-
}
|
|
792
|
+
} : {}
|
|
853
793
|
};
|
|
794
|
+
};
|
|
795
|
+
var projection = (definition) => definition;
|
|
796
|
+
var WorkflowHandlerStreamVersionConflictRetryOptions = {
|
|
797
|
+
retries: 3,
|
|
798
|
+
minTimeout: 100,
|
|
799
|
+
factor: 1.5,
|
|
800
|
+
shouldRetryError: isExpectedVersionConflictError
|
|
801
|
+
};
|
|
802
|
+
var fromWorkflowHandlerRetryOptions = (retryOptions) => {
|
|
803
|
+
if (retryOptions === void 0) return NoRetries;
|
|
804
|
+
if ("onVersionConflict" in retryOptions) {
|
|
805
|
+
if (typeof retryOptions.onVersionConflict === "boolean")
|
|
806
|
+
return WorkflowHandlerStreamVersionConflictRetryOptions;
|
|
807
|
+
else if (typeof retryOptions.onVersionConflict === "number")
|
|
808
|
+
return {
|
|
809
|
+
...WorkflowHandlerStreamVersionConflictRetryOptions,
|
|
810
|
+
retries: retryOptions.onVersionConflict
|
|
811
|
+
};
|
|
812
|
+
else return retryOptions.onVersionConflict;
|
|
813
|
+
}
|
|
814
|
+
return retryOptions;
|
|
815
|
+
};
|
|
816
|
+
var emptyHandlerResult = (nextExpectedStreamVersion = 0n) => ({
|
|
817
|
+
newMessages: [],
|
|
818
|
+
createdNewStream: false,
|
|
819
|
+
nextExpectedStreamVersion
|
|
820
|
+
});
|
|
821
|
+
var createInputMetadata = (originalMessageId, action) => ({
|
|
822
|
+
originalMessageId,
|
|
823
|
+
input: true,
|
|
824
|
+
action
|
|
825
|
+
});
|
|
826
|
+
var tagOutputMessage = (msg, action) => {
|
|
827
|
+
const existingMetadata = "metadata" in msg && msg.metadata ? msg.metadata : {};
|
|
854
828
|
return {
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
if (isRunning) return start;
|
|
860
|
-
isRunning = true;
|
|
861
|
-
start = (async () => {
|
|
862
|
-
return pullMessages(options);
|
|
863
|
-
})();
|
|
864
|
-
return start;
|
|
865
|
-
},
|
|
866
|
-
stop: async () => {
|
|
867
|
-
if (!isRunning) return;
|
|
868
|
-
isRunning = false;
|
|
869
|
-
await start;
|
|
829
|
+
...msg,
|
|
830
|
+
metadata: {
|
|
831
|
+
...existingMetadata,
|
|
832
|
+
action
|
|
870
833
|
}
|
|
871
834
|
};
|
|
872
835
|
};
|
|
873
|
-
var
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
836
|
+
var createWrappedInitialState = (initialState) => {
|
|
837
|
+
return () => ({
|
|
838
|
+
userState: initialState(),
|
|
839
|
+
processedInputIds: /* @__PURE__ */ new Set()
|
|
840
|
+
});
|
|
878
841
|
};
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
)
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
842
|
+
var createWrappedEvolve = (evolve, workflowName, separateInputInboxFromProcessing) => {
|
|
843
|
+
return (state, event2) => {
|
|
844
|
+
const metadata = event2.metadata;
|
|
845
|
+
let processedInputIds = state.processedInputIds;
|
|
846
|
+
if (_optionalChain([metadata, 'optionalAccess', _41 => _41.input]) === true && typeof _optionalChain([metadata, 'optionalAccess', _42 => _42.originalMessageId]) === "string") {
|
|
847
|
+
processedInputIds = new Set(state.processedInputIds);
|
|
848
|
+
processedInputIds.add(metadata.originalMessageId);
|
|
849
|
+
}
|
|
850
|
+
if (separateInputInboxFromProcessing && _optionalChain([metadata, 'optionalAccess', _43 => _43.input]) === true) {
|
|
851
|
+
return {
|
|
852
|
+
userState: state.userState,
|
|
853
|
+
processedInputIds
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
const eventType = event2.type;
|
|
857
|
+
const eventForEvolve = eventType.startsWith(`${workflowName}:`) ? {
|
|
858
|
+
...event2,
|
|
859
|
+
type: eventType.replace(`${workflowName}:`, "")
|
|
860
|
+
} : event2;
|
|
861
|
+
return {
|
|
862
|
+
userState: evolve(state.userState, eventForEvolve),
|
|
863
|
+
processedInputIds
|
|
864
|
+
};
|
|
865
|
+
};
|
|
866
|
+
};
|
|
867
|
+
var workflowStreamName = ({
|
|
868
|
+
workflowName,
|
|
869
|
+
workflowId
|
|
870
|
+
}) => `emt:workflow:${workflowName}:${workflowId}`;
|
|
871
|
+
var WorkflowHandler = (options) => async (store, message2, handleOptions) => asyncRetry(
|
|
872
|
+
async () => {
|
|
873
|
+
const result = await withSession2(store, async ({ eventStore }) => {
|
|
874
|
+
const {
|
|
875
|
+
workflow: { evolve, initialState, decide, name: workflowName },
|
|
876
|
+
getWorkflowId: getWorkflowId2
|
|
877
|
+
} = options;
|
|
878
|
+
const inputMessageId = (
|
|
879
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
880
|
+
_nullishCoalesce(("metadata" in message2 && _optionalChain([message2, 'access', _44 => _44.metadata, 'optionalAccess', _45 => _45.messageId]) ? (
|
|
881
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
882
|
+
message2.metadata.messageId
|
|
883
|
+
) : void 0), () => ( _uuid.v7.call(void 0, )))
|
|
884
|
+
);
|
|
885
|
+
const messageWithMetadata = {
|
|
886
|
+
...message2,
|
|
887
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
888
|
+
metadata: {
|
|
889
|
+
messageId: inputMessageId,
|
|
890
|
+
...message2.metadata
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
const workflowId = getWorkflowId2(messageWithMetadata);
|
|
894
|
+
if (!workflowId) {
|
|
895
|
+
return emptyHandlerResult();
|
|
896
|
+
}
|
|
897
|
+
const streamName = options.mapWorkflowId ? options.mapWorkflowId(workflowId) : workflowStreamName({ workflowName, workflowId });
|
|
898
|
+
const messageType = messageWithMetadata.type;
|
|
899
|
+
const hasWorkflowPrefix = messageType.startsWith(`${workflowName}:`);
|
|
900
|
+
if (options.separateInputInboxFromProcessing && !hasWorkflowPrefix) {
|
|
901
|
+
const inputMetadata2 = createInputMetadata(
|
|
902
|
+
inputMessageId,
|
|
903
|
+
"InitiatedBy"
|
|
904
|
+
);
|
|
905
|
+
const inputToStore2 = {
|
|
906
|
+
type: `${workflowName}:${messageWithMetadata.type}`,
|
|
907
|
+
data: messageWithMetadata.data,
|
|
908
|
+
kind: messageWithMetadata.kind,
|
|
909
|
+
metadata: inputMetadata2
|
|
910
|
+
};
|
|
911
|
+
const appendResult2 = await eventStore.appendToStream(
|
|
912
|
+
streamName,
|
|
913
|
+
[inputToStore2],
|
|
914
|
+
{
|
|
915
|
+
...handleOptions,
|
|
916
|
+
expectedStreamVersion: _nullishCoalesce(_optionalChain([handleOptions, 'optionalAccess', _46 => _46.expectedStreamVersion]), () => ( NO_CONCURRENCY_CHECK))
|
|
917
|
+
}
|
|
918
|
+
);
|
|
919
|
+
return {
|
|
920
|
+
...appendResult2,
|
|
921
|
+
newMessages: []
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
const wrappedInitialState = createWrappedInitialState(initialState);
|
|
925
|
+
const wrappedEvolve = createWrappedEvolve(
|
|
926
|
+
evolve,
|
|
927
|
+
workflowName,
|
|
928
|
+
_nullishCoalesce(options.separateInputInboxFromProcessing, () => ( false))
|
|
929
|
+
);
|
|
930
|
+
const aggregationResult = await eventStore.aggregateStream(streamName, {
|
|
931
|
+
evolve: wrappedEvolve,
|
|
932
|
+
initialState: wrappedInitialState,
|
|
933
|
+
read: {
|
|
934
|
+
...handleOptions,
|
|
935
|
+
// expected stream version is passed to fail fast
|
|
936
|
+
// if stream is in the wrong state
|
|
937
|
+
expectedStreamVersion: _nullishCoalesce(_optionalChain([handleOptions, 'optionalAccess', _47 => _47.expectedStreamVersion]), () => ( NO_CONCURRENCY_CHECK))
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
const { currentStreamVersion } = aggregationResult;
|
|
941
|
+
const { userState: state, processedInputIds } = aggregationResult.state;
|
|
942
|
+
if (processedInputIds.has(inputMessageId)) {
|
|
943
|
+
return emptyHandlerResult(currentStreamVersion);
|
|
944
|
+
}
|
|
945
|
+
const messageForDecide = hasWorkflowPrefix ? {
|
|
946
|
+
...messageWithMetadata,
|
|
947
|
+
type: messageType.replace(`${workflowName}:`, "")
|
|
948
|
+
} : messageWithMetadata;
|
|
949
|
+
const result2 = decide(messageForDecide, state);
|
|
950
|
+
const inputMetadata = createInputMetadata(
|
|
951
|
+
inputMessageId,
|
|
952
|
+
aggregationResult.streamExists ? "Received" : "InitiatedBy"
|
|
953
|
+
);
|
|
954
|
+
const inputToStore = {
|
|
955
|
+
type: `${workflowName}:${messageWithMetadata.type}`,
|
|
956
|
+
data: messageWithMetadata.data,
|
|
957
|
+
kind: messageWithMetadata.kind,
|
|
958
|
+
metadata: inputMetadata
|
|
959
|
+
};
|
|
960
|
+
const outputMessages = (Array.isArray(result2) ? result2 : [result2]).filter((msg) => msg !== void 0 && msg !== null);
|
|
961
|
+
const outputCommandTypes = _nullishCoalesce(_optionalChain([options, 'access', _48 => _48.outputs, 'optionalAccess', _49 => _49.commands]), () => ( []));
|
|
962
|
+
const taggedOutputMessages = outputMessages.map((msg) => {
|
|
963
|
+
const action = outputCommandTypes.includes(
|
|
964
|
+
msg.type
|
|
965
|
+
) ? "Sent" : "Published";
|
|
966
|
+
return tagOutputMessage(msg, action);
|
|
967
|
+
});
|
|
968
|
+
const messagesToAppend = options.separateInputInboxFromProcessing && hasWorkflowPrefix ? [...taggedOutputMessages] : [inputToStore, ...taggedOutputMessages];
|
|
969
|
+
if (messagesToAppend.length === 0) {
|
|
970
|
+
return emptyHandlerResult(currentStreamVersion);
|
|
971
|
+
}
|
|
972
|
+
const expectedStreamVersion = _nullishCoalesce(_optionalChain([handleOptions, 'optionalAccess', _50 => _50.expectedStreamVersion]), () => ( (aggregationResult.streamExists ? currentStreamVersion : STREAM_DOES_NOT_EXIST)));
|
|
973
|
+
const appendResult = await eventStore.appendToStream(
|
|
974
|
+
streamName,
|
|
975
|
+
// TODO: Fix this cast
|
|
976
|
+
messagesToAppend,
|
|
977
|
+
{
|
|
978
|
+
...handleOptions,
|
|
979
|
+
expectedStreamVersion
|
|
980
|
+
}
|
|
981
|
+
);
|
|
982
|
+
return {
|
|
983
|
+
...appendResult,
|
|
984
|
+
newMessages: outputMessages
|
|
985
|
+
};
|
|
986
|
+
});
|
|
987
|
+
return result;
|
|
988
|
+
},
|
|
989
|
+
fromWorkflowHandlerRetryOptions(
|
|
990
|
+
handleOptions && "retry" in handleOptions ? handleOptions.retry : options.retry
|
|
991
|
+
)
|
|
976
992
|
);
|
|
977
|
-
var
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
993
|
+
var withSession2 = (eventStore, callback) => {
|
|
994
|
+
const sessionFactory = canCreateEventStoreSession(eventStore) ? eventStore : nulloSessionFactory(eventStore);
|
|
995
|
+
return sessionFactory.withSession(callback);
|
|
996
|
+
};
|
|
997
|
+
var getWorkflowId = (options) => `emt:processor:workflow:${options.workflowName}`;
|
|
998
|
+
var workflowProcessor = (options) => {
|
|
999
|
+
const { workflow, ...rest } = options;
|
|
1000
|
+
const inputs = [...options.inputs.commands, ...options.inputs.events];
|
|
1001
|
+
let canHandle = inputs;
|
|
1002
|
+
if (options.separateInputInboxFromProcessing)
|
|
1003
|
+
canHandle = [
|
|
1004
|
+
...canHandle,
|
|
1005
|
+
...options.inputs.commands.map((t) => `${workflow.name}:${t}`),
|
|
1006
|
+
...options.inputs.events.map((t) => `${workflow.name}:${t}`)
|
|
1007
|
+
];
|
|
1008
|
+
if (options.outputHandler)
|
|
1009
|
+
canHandle = [...canHandle, ...options.outputHandler.canHandle];
|
|
1010
|
+
const handle = WorkflowHandler(options);
|
|
1011
|
+
return reactor({
|
|
1012
|
+
...rest,
|
|
1013
|
+
processorId: _nullishCoalesce(options.processorId, () => ( getWorkflowId({ workflowName: workflow.name }))),
|
|
1014
|
+
canHandle,
|
|
1015
|
+
type: MessageProcessorType.PROJECTOR,
|
|
1016
|
+
eachMessage: async (message2, context) => {
|
|
1017
|
+
const messageType = message2.type;
|
|
1018
|
+
const metadata = message2.metadata;
|
|
1019
|
+
const isInput = _optionalChain([metadata, 'optionalAccess', _51 => _51.input]) === true;
|
|
1020
|
+
if (isInput || inputs.includes(messageType)) {
|
|
1021
|
+
const result = await handle(
|
|
1022
|
+
context.connection.messageStore,
|
|
1023
|
+
message2,
|
|
1024
|
+
context
|
|
1025
|
+
);
|
|
1026
|
+
if (options.stopAfter && result.newMessages.length > 0) {
|
|
1027
|
+
for (const outputMessage of result.newMessages) {
|
|
1028
|
+
if (options.stopAfter(
|
|
1029
|
+
outputMessage
|
|
1030
|
+
)) {
|
|
1031
|
+
return { type: "STOP", reason: "Stop condition reached" };
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
if (_optionalChain([options, 'access', _52 => _52.outputHandler, 'optionalAccess', _53 => _53.canHandle, 'access', _54 => _54.includes, 'call', _55 => _55(messageType)]) === true) {
|
|
1038
|
+
const handledOutputMessages = await options.outputHandler.handle(
|
|
1039
|
+
message2,
|
|
1040
|
+
context
|
|
1041
|
+
);
|
|
1042
|
+
if (handledOutputMessages instanceof EmmettError) {
|
|
1043
|
+
return {
|
|
1044
|
+
type: "STOP",
|
|
1045
|
+
reason: "Routing error",
|
|
1046
|
+
error: handledOutputMessages
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
const messagesToAppend = Array.isArray(handledOutputMessages) ? handledOutputMessages : handledOutputMessages ? [handledOutputMessages] : [];
|
|
1050
|
+
if (messagesToAppend.length === 0) {
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
const workflowId = options.getWorkflowId(
|
|
1054
|
+
message2
|
|
1055
|
+
);
|
|
1056
|
+
if (!workflowId) return;
|
|
1057
|
+
const streamName = options.mapWorkflowId ? options.mapWorkflowId(workflowId) : workflowStreamName({
|
|
1058
|
+
workflowName: workflow.name,
|
|
1059
|
+
workflowId
|
|
1060
|
+
});
|
|
1061
|
+
await context.connection.messageStore.appendToStream(
|
|
1062
|
+
streamName,
|
|
1063
|
+
messagesToAppend
|
|
1064
|
+
);
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
};
|
|
1015
1071
|
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
$emt_release_processor_lock$;
|
|
1019
|
-
`
|
|
1020
|
-
);
|
|
1021
|
-
var callTryAcquireProcessorLock = (params) => _dumbo.SQL`
|
|
1022
|
-
SELECT * FROM emt_try_acquire_processor_lock(
|
|
1023
|
-
${params.lockKey},
|
|
1024
|
-
${params.processorId},
|
|
1025
|
-
${params.version},
|
|
1026
|
-
${params.partition},
|
|
1027
|
-
${params.processorInstanceId},
|
|
1028
|
-
${params.projectionName},
|
|
1029
|
-
${params.projectionType},
|
|
1030
|
-
${params.projectionKind},
|
|
1031
|
-
${params.lockTimeoutSeconds}
|
|
1032
|
-
);
|
|
1033
|
-
`;
|
|
1034
|
-
var callReleaseProcessorLock = (params) => _dumbo.SQL`SELECT emt_release_processor_lock(
|
|
1035
|
-
${params.lockKey},
|
|
1036
|
-
${params.processorId},
|
|
1037
|
-
${params.partition},
|
|
1038
|
-
${params.version},
|
|
1039
|
-
${params.processorInstanceId},
|
|
1040
|
-
${params.projectionName}
|
|
1041
|
-
) as result;`;
|
|
1072
|
+
// src/eventStore/schema/readLastMessageGlobalPosition.ts
|
|
1073
|
+
var _dumbo = require('@event-driven-io/dumbo');
|
|
1042
1074
|
|
|
1043
|
-
// src/eventStore/
|
|
1044
|
-
var
|
|
1045
|
-
var
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
processorId: options.processorId,
|
|
1052
|
-
version: options.version,
|
|
1053
|
-
partition: options.partition,
|
|
1054
|
-
processorInstanceId: options.processorInstanceId,
|
|
1055
|
-
projectionName: _nullishCoalesce(_optionalChain([options, 'access', _39 => _39.projection, 'optionalAccess', _40 => _40.name]), () => ( null)),
|
|
1056
|
-
projectionType: _optionalChain([options, 'access', _41 => _41.projection, 'optionalAccess', _42 => _42.handlingType]) ? options.projection.handlingType === "inline" ? "i" : "a" : null,
|
|
1057
|
-
projectionKind: _nullishCoalesce(_optionalChain([options, 'access', _43 => _43.projection, 'optionalAccess', _44 => _44.kind]), () => ( null)),
|
|
1058
|
-
lockTimeoutSeconds: _nullishCoalesce(options.lockTimeoutSeconds, () => ( PROCESSOR_LOCK_DEFAULT_TIMEOUT_SECONDS))
|
|
1059
|
-
})
|
|
1060
|
-
)
|
|
1061
|
-
);
|
|
1062
|
-
return acquired ? { acquired: true, checkpoint } : { acquired: false };
|
|
1075
|
+
// src/eventStore/schema/typing.ts
|
|
1076
|
+
var emmettPrefix2 = "emt";
|
|
1077
|
+
var globalTag = "global";
|
|
1078
|
+
var defaultTag2 = `${emmettPrefix2}:default`;
|
|
1079
|
+
var unknownTag2 = `${emmettPrefix2}:unknown`;
|
|
1080
|
+
var globalNames = {
|
|
1081
|
+
module: `${emmettPrefix2}:module:${globalTag}`,
|
|
1082
|
+
tenant: `${emmettPrefix2}:tenant:${globalTag}`
|
|
1063
1083
|
};
|
|
1064
|
-
var
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1084
|
+
var columns = {
|
|
1085
|
+
partition: {
|
|
1086
|
+
name: "partition"
|
|
1087
|
+
},
|
|
1088
|
+
isArchived: { name: "is_archived" }
|
|
1089
|
+
};
|
|
1090
|
+
var streamsTable = {
|
|
1091
|
+
name: `${emmettPrefix2}_streams`,
|
|
1092
|
+
columns: {
|
|
1093
|
+
partition: columns.partition,
|
|
1094
|
+
isArchived: columns.isArchived
|
|
1073
1095
|
}
|
|
1074
|
-
return tryAcquireProcessorLock(execute, options);
|
|
1075
1096
|
};
|
|
1076
|
-
var
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
processorId: options.processorId,
|
|
1083
|
-
partition: options.partition,
|
|
1084
|
-
version: options.version,
|
|
1085
|
-
processorInstanceId: options.processorInstanceId,
|
|
1086
|
-
projectionName: _nullishCoalesce(options.projectionName, () => ( null))
|
|
1087
|
-
})
|
|
1088
|
-
)
|
|
1089
|
-
);
|
|
1090
|
-
return result;
|
|
1097
|
+
var messagesTable = {
|
|
1098
|
+
name: `${emmettPrefix2}_messages`,
|
|
1099
|
+
columns: {
|
|
1100
|
+
partition: columns.partition,
|
|
1101
|
+
isArchived: columns.isArchived
|
|
1102
|
+
}
|
|
1091
1103
|
};
|
|
1104
|
+
var processorsTable = {
|
|
1105
|
+
name: `${emmettPrefix2}_processors`
|
|
1106
|
+
};
|
|
1107
|
+
var projectionsTable = {
|
|
1108
|
+
name: `${emmettPrefix2}_projections`
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
// src/eventStore/schema/readLastMessageGlobalPosition.ts
|
|
1112
|
+
var readLastMessageGlobalPosition = async (execute, options) => {
|
|
1113
|
+
const result = await _dumbo.singleOrNull.call(void 0,
|
|
1114
|
+
execute.query(
|
|
1115
|
+
_dumbo.SQL`SELECT global_position
|
|
1116
|
+
FROM ${_dumbo.SQL.identifier(messagesTable.name)}
|
|
1117
|
+
WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _56 => _56.partition]), () => ( defaultTag2))} AND is_archived = FALSE AND transaction_id < pg_snapshot_xmin(pg_current_snapshot())
|
|
1118
|
+
ORDER BY transaction_id, global_position
|
|
1119
|
+
LIMIT 1`
|
|
1120
|
+
)
|
|
1121
|
+
);
|
|
1122
|
+
return {
|
|
1123
|
+
currentGlobalPosition: result !== null ? BigInt(result.global_position) : null
|
|
1124
|
+
};
|
|
1125
|
+
};
|
|
1126
|
+
|
|
1127
|
+
// src/eventStore/schema/readMessagesBatch.ts
|
|
1128
|
+
|
|
1129
|
+
var readMessagesBatch = async (execute, options) => {
|
|
1130
|
+
const from = "from" in options ? options.from : void 0;
|
|
1131
|
+
const after = "after" in options ? options.after : void 0;
|
|
1132
|
+
const batchSize = "batchSize" in options ? options.batchSize : options.to - options.from;
|
|
1133
|
+
const fromCondition = from !== void 0 ? _dumbo.SQL`AND global_position >= ${from}` : after !== void 0 ? _dumbo.SQL`AND global_position > ${after}` : _dumbo.SQL.EMPTY;
|
|
1134
|
+
const toCondition = "to" in options ? _dumbo.SQL`AND global_position <= ${options.to}` : _dumbo.SQL.EMPTY;
|
|
1135
|
+
const limitCondition = "batchSize" in options ? _dumbo.SQL`LIMIT ${options.batchSize}` : _dumbo.SQL.EMPTY;
|
|
1136
|
+
const messages = await _dumbo.mapRows.call(void 0,
|
|
1137
|
+
execute.query(
|
|
1138
|
+
_dumbo.SQL`
|
|
1139
|
+
SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
|
|
1140
|
+
FROM ${_dumbo.SQL.identifier(messagesTable.name)}
|
|
1141
|
+
WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _57 => _57.partition]), () => ( defaultTag2))} AND is_archived = FALSE AND transaction_id < pg_snapshot_xmin(pg_current_snapshot()) ${fromCondition} ${toCondition}
|
|
1142
|
+
ORDER BY transaction_id, global_position
|
|
1143
|
+
${limitCondition}`
|
|
1144
|
+
),
|
|
1145
|
+
(row) => {
|
|
1146
|
+
const rawEvent = {
|
|
1147
|
+
type: row.message_type,
|
|
1148
|
+
data: row.message_data,
|
|
1149
|
+
metadata: row.message_metadata
|
|
1150
|
+
};
|
|
1151
|
+
const metadata = {
|
|
1152
|
+
..."metadata" in rawEvent ? _nullishCoalesce(rawEvent.metadata, () => ( {})) : {},
|
|
1153
|
+
messageId: row.message_id,
|
|
1154
|
+
streamName: row.stream_id,
|
|
1155
|
+
streamPosition: BigInt(row.stream_position),
|
|
1156
|
+
globalPosition: BigInt(row.global_position),
|
|
1157
|
+
checkpoint: bigIntProcessorCheckpoint(BigInt(row.global_position))
|
|
1158
|
+
};
|
|
1159
|
+
return {
|
|
1160
|
+
...rawEvent,
|
|
1161
|
+
kind: "Event",
|
|
1162
|
+
metadata
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
);
|
|
1166
|
+
return messages.length > 0 ? {
|
|
1167
|
+
currentGlobalPosition: messages[messages.length - 1].metadata.globalPosition,
|
|
1168
|
+
messages,
|
|
1169
|
+
areMessagesLeft: messages.length === batchSize
|
|
1170
|
+
} : {
|
|
1171
|
+
currentGlobalPosition: "from" in options ? options.from : "after" in options ? options.after : 0n,
|
|
1172
|
+
messages: [],
|
|
1173
|
+
areMessagesLeft: false
|
|
1174
|
+
};
|
|
1175
|
+
};
|
|
1176
|
+
|
|
1177
|
+
// src/eventStore/consumers/messageBatchProcessing/index.ts
|
|
1178
|
+
var DefaultPostgreSQLEventStoreProcessorBatchSize = 100;
|
|
1179
|
+
var DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs = 50;
|
|
1180
|
+
var postgreSQLEventStoreMessageBatchPuller = ({
|
|
1181
|
+
executor,
|
|
1182
|
+
batchSize,
|
|
1183
|
+
eachBatch,
|
|
1184
|
+
pullingFrequencyInMs,
|
|
1185
|
+
stopWhen,
|
|
1186
|
+
signal
|
|
1187
|
+
}) => {
|
|
1188
|
+
let isRunning = false;
|
|
1189
|
+
let start;
|
|
1190
|
+
const pullMessages = async (options) => {
|
|
1191
|
+
const after = options.startFrom === "BEGINNING" ? 0n : options.startFrom === "END" ? await _asyncNullishCoalesce((await readLastMessageGlobalPosition(executor)).currentGlobalPosition, async () => ( 0n)) : parseBigIntProcessorCheckpoint(options.startFrom.lastCheckpoint);
|
|
1192
|
+
const readMessagesOptions = {
|
|
1193
|
+
after,
|
|
1194
|
+
batchSize
|
|
1195
|
+
};
|
|
1196
|
+
let waitTime = 100;
|
|
1197
|
+
while (isRunning && !_optionalChain([signal, 'optionalAccess', _58 => _58.aborted])) {
|
|
1198
|
+
const { messages, currentGlobalPosition, areMessagesLeft } = await readMessagesBatch(executor, readMessagesOptions);
|
|
1199
|
+
if (messages.length > 0) {
|
|
1200
|
+
const result = await eachBatch(messages);
|
|
1201
|
+
if (result && result.type === "STOP") {
|
|
1202
|
+
isRunning = false;
|
|
1203
|
+
break;
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
readMessagesOptions.after = currentGlobalPosition;
|
|
1207
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
1208
|
+
if (_optionalChain([stopWhen, 'optionalAccess', _59 => _59.noMessagesLeft]) === true && !areMessagesLeft) {
|
|
1209
|
+
isRunning = false;
|
|
1210
|
+
break;
|
|
1211
|
+
}
|
|
1212
|
+
if (!areMessagesLeft) {
|
|
1213
|
+
waitTime = Math.min(waitTime * 2, 1e3);
|
|
1214
|
+
} else {
|
|
1215
|
+
waitTime = pullingFrequencyInMs;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
return {
|
|
1220
|
+
get isRunning() {
|
|
1221
|
+
return isRunning;
|
|
1222
|
+
},
|
|
1223
|
+
start: (options) => {
|
|
1224
|
+
if (isRunning) return start;
|
|
1225
|
+
isRunning = true;
|
|
1226
|
+
start = (async () => {
|
|
1227
|
+
return pullMessages(options);
|
|
1228
|
+
})();
|
|
1229
|
+
return start;
|
|
1230
|
+
},
|
|
1231
|
+
stop: async () => {
|
|
1232
|
+
if (!isRunning) return;
|
|
1233
|
+
isRunning = false;
|
|
1234
|
+
await start;
|
|
1235
|
+
}
|
|
1236
|
+
};
|
|
1237
|
+
};
|
|
1238
|
+
var zipPostgreSQLEventStoreMessageBatchPullerStartFrom = (options) => {
|
|
1239
|
+
if (options.length === 0 || options.some((o) => o === void 0 || o === "BEGINNING"))
|
|
1240
|
+
return "BEGINNING";
|
|
1241
|
+
if (options.every((o) => o === "END")) return "END";
|
|
1242
|
+
return options.filter((o) => o !== void 0 && o !== "BEGINNING" && o !== "END").sort((a, b) => a > b ? 1 : -1)[0];
|
|
1243
|
+
};
|
|
1244
|
+
|
|
1245
|
+
// src/eventStore/consumers/postgreSQLEventStoreConsumer.ts
|
|
1246
|
+
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
// src/eventStore/consumers/postgreSQLProcessor.ts
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
// src/eventStore/postgreSQLEventStore.ts
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
|
|
1092
1259
|
|
|
1093
1260
|
// src/eventStore/projections/locks/tryAcquireProjectionLock.ts
|
|
1094
1261
|
|
|
1095
1262
|
|
|
1096
1263
|
// src/eventStore/schema/projections/projectionsLocks.ts
|
|
1097
1264
|
|
|
1265
|
+
|
|
1266
|
+
// src/eventStore/schema/createFunctionIfDoesNotExist.ts
|
|
1267
|
+
|
|
1268
|
+
var createFunctionIfDoesNotExistSQL = (functionName, functionDefinition) => _dumbo.SQL`
|
|
1269
|
+
DO $$
|
|
1270
|
+
BEGIN
|
|
1271
|
+
IF NOT EXISTS (SELECT 1 FROM pg_proc WHERE proname = '${_dumbo.SQL.plain(functionName)}') THEN
|
|
1272
|
+
${functionDefinition}
|
|
1273
|
+
END IF;
|
|
1274
|
+
END $$;
|
|
1275
|
+
`;
|
|
1276
|
+
|
|
1277
|
+
// src/eventStore/schema/projections/projectionsLocks.ts
|
|
1098
1278
|
var tryAcquireProjectionLockSQL = createFunctionIfDoesNotExistSQL(
|
|
1099
1279
|
"emt_try_acquire_projection_lock",
|
|
1100
1280
|
_dumbo.SQL`
|
|
@@ -1174,95 +1354,286 @@ var toProjectionLockKey = ({
|
|
|
1174
1354
|
version
|
|
1175
1355
|
}) => `${partition}:${projectionName}:${version}`;
|
|
1176
1356
|
|
|
1177
|
-
// src/eventStore/projections/locks/
|
|
1178
|
-
var DefaultPostgreSQLProcessorLockPolicy = {
|
|
1179
|
-
type: "fail"
|
|
1180
|
-
};
|
|
1181
|
-
var postgreSQLProcessorLock = (options) => {
|
|
1182
|
-
let acquired = false;
|
|
1183
|
-
const lockKey = _nullishCoalesce(options.lockKey, () => ( toProcessorLockKey(options)));
|
|
1184
|
-
return {
|
|
1185
|
-
tryAcquire: async (context) => {
|
|
1186
|
-
if (acquired) {
|
|
1187
|
-
return true;
|
|
1188
|
-
}
|
|
1189
|
-
const result = await tryAcquireProcessorLockWithRetry(context.execute, {
|
|
1190
|
-
...options,
|
|
1191
|
-
lockKey
|
|
1192
|
-
});
|
|
1193
|
-
if (!result.acquired && _optionalChain([options, 'access', _45 => _45.lockPolicy, 'optionalAccess', _46 => _46.type]) !== "skip") {
|
|
1194
|
-
throw new EmmettError(
|
|
1195
|
-
`Failed to acquire lock for processor '${options.processorId}'`
|
|
1196
|
-
);
|
|
1197
|
-
}
|
|
1198
|
-
acquired = result.acquired;
|
|
1199
|
-
return acquired;
|
|
1200
|
-
},
|
|
1201
|
-
release: async (context) => {
|
|
1202
|
-
if (!acquired) return;
|
|
1203
|
-
const { projection: projection2, ...releaseOptions } = options;
|
|
1204
|
-
await releaseProcessorLock(context.execute, {
|
|
1205
|
-
...releaseOptions,
|
|
1206
|
-
lockKey,
|
|
1207
|
-
projectionName: _optionalChain([projection2, 'optionalAccess', _47 => _47.name])
|
|
1208
|
-
});
|
|
1209
|
-
acquired = false;
|
|
1210
|
-
}
|
|
1211
|
-
};
|
|
1212
|
-
};
|
|
1213
|
-
var toProcessorLockKey = ({
|
|
1214
|
-
projection: projection2,
|
|
1215
|
-
processorId,
|
|
1216
|
-
partition,
|
|
1217
|
-
version
|
|
1218
|
-
}) => projection2 ? toProjectionLockKey({
|
|
1219
|
-
projectionName: projection2.name,
|
|
1220
|
-
partition,
|
|
1221
|
-
version: projection2.version
|
|
1222
|
-
}) : `${partition}:${processorId}:${version}`;
|
|
1223
|
-
|
|
1224
|
-
// src/eventStore/projections/management/projectionManagement.ts
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1357
|
+
// src/eventStore/projections/locks/tryAcquireProcessorLock.ts
|
|
1230
1358
|
|
|
1231
1359
|
|
|
1232
|
-
// src/eventStore/schema/
|
|
1360
|
+
// src/eventStore/schema/processors/processorsLocks.ts
|
|
1233
1361
|
|
|
1234
|
-
var
|
|
1235
|
-
"
|
|
1362
|
+
var tryAcquireProcessorLockSQL = createFunctionIfDoesNotExistSQL(
|
|
1363
|
+
"emt_try_acquire_processor_lock",
|
|
1236
1364
|
_dumbo.SQL`
|
|
1237
|
-
CREATE OR REPLACE FUNCTION
|
|
1238
|
-
p_lock_key
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1365
|
+
CREATE OR REPLACE FUNCTION emt_try_acquire_processor_lock(
|
|
1366
|
+
p_lock_key BIGINT,
|
|
1367
|
+
p_processor_id TEXT,
|
|
1368
|
+
p_version INT,
|
|
1369
|
+
p_partition TEXT DEFAULT '${_dumbo.SQL.plain(defaultTag2)}',
|
|
1370
|
+
p_processor_instance_id TEXT DEFAULT '${_dumbo.SQL.plain(unknownTag2)}',
|
|
1371
|
+
p_projection_name TEXT DEFAULT NULL,
|
|
1372
|
+
p_projection_type VARCHAR(1) DEFAULT NULL,
|
|
1373
|
+
p_projection_kind TEXT DEFAULT NULL,
|
|
1374
|
+
p_lock_timeout_seconds INT DEFAULT 300
|
|
1246
1375
|
)
|
|
1247
|
-
RETURNS BOOLEAN
|
|
1376
|
+
RETURNS TABLE (acquired BOOLEAN, checkpoint TEXT)
|
|
1248
1377
|
LANGUAGE plpgsql
|
|
1249
|
-
AS $
|
|
1250
|
-
DECLARE
|
|
1251
|
-
v_result BOOLEAN;
|
|
1378
|
+
AS $emt_try_acquire_processor_lock$
|
|
1252
1379
|
BEGIN
|
|
1380
|
+
RETURN QUERY
|
|
1253
1381
|
WITH lock_check AS (
|
|
1254
1382
|
SELECT pg_try_advisory_xact_lock(p_lock_key) AS lock_acquired
|
|
1255
1383
|
),
|
|
1256
|
-
|
|
1257
|
-
INSERT INTO ${_dumbo.SQL.
|
|
1258
|
-
|
|
1384
|
+
ownership_check AS (
|
|
1385
|
+
INSERT INTO ${_dumbo.SQL.plain(processorsTable.name)} (
|
|
1386
|
+
processor_id,
|
|
1387
|
+
partition,
|
|
1388
|
+
version,
|
|
1389
|
+
processor_instance_id,
|
|
1390
|
+
status,
|
|
1391
|
+
last_processed_checkpoint,
|
|
1392
|
+
last_processed_transaction_id,
|
|
1393
|
+
created_at,
|
|
1394
|
+
last_updated
|
|
1259
1395
|
)
|
|
1260
|
-
SELECT
|
|
1396
|
+
SELECT p_processor_id, p_partition, p_version, p_processor_instance_id, 'running', '${_dumbo.SQL.plain(bigInt.toNormalizedString(0n))}', '0'::xid8, now(), now()
|
|
1261
1397
|
WHERE (SELECT lock_acquired FROM lock_check) = true
|
|
1262
|
-
ON CONFLICT (
|
|
1263
|
-
SET
|
|
1398
|
+
ON CONFLICT (processor_id, partition, version) DO UPDATE
|
|
1399
|
+
SET processor_instance_id = p_processor_instance_id,
|
|
1400
|
+
status = 'running',
|
|
1264
1401
|
last_updated = now()
|
|
1265
|
-
|
|
1402
|
+
WHERE ${_dumbo.SQL.plain(processorsTable.name)}.processor_instance_id = p_processor_instance_id
|
|
1403
|
+
OR ${_dumbo.SQL.plain(processorsTable.name)}.processor_instance_id = '${_dumbo.SQL.plain(unknownTag2)}'
|
|
1404
|
+
OR ${_dumbo.SQL.plain(processorsTable.name)}.status = 'stopped'
|
|
1405
|
+
OR ${_dumbo.SQL.plain(processorsTable.name)}.last_updated < now() - (p_lock_timeout_seconds || ' seconds')::interval
|
|
1406
|
+
RETURNING last_processed_checkpoint
|
|
1407
|
+
),
|
|
1408
|
+
projection_status AS (
|
|
1409
|
+
INSERT INTO ${_dumbo.SQL.plain(projectionsTable.name)} (
|
|
1410
|
+
name,
|
|
1411
|
+
partition,
|
|
1412
|
+
version,
|
|
1413
|
+
type,
|
|
1414
|
+
kind,
|
|
1415
|
+
status,
|
|
1416
|
+
definition
|
|
1417
|
+
)
|
|
1418
|
+
SELECT p_projection_name, p_partition, p_version, p_projection_type, p_projection_kind, 'async_processing', '{}'::jsonb
|
|
1419
|
+
WHERE p_projection_name IS NOT NULL
|
|
1420
|
+
AND (SELECT last_processed_checkpoint FROM ownership_check) IS NOT NULL
|
|
1421
|
+
ON CONFLICT (name, partition, version) DO UPDATE
|
|
1422
|
+
SET status = 'async_processing'
|
|
1423
|
+
RETURNING name
|
|
1424
|
+
)
|
|
1425
|
+
SELECT
|
|
1426
|
+
(SELECT COUNT(*) > 0 FROM ownership_check),
|
|
1427
|
+
(SELECT oc.last_processed_checkpoint FROM ownership_check oc);
|
|
1428
|
+
END;
|
|
1429
|
+
$emt_try_acquire_processor_lock$;
|
|
1430
|
+
`
|
|
1431
|
+
);
|
|
1432
|
+
var releaseProcessorLockSQL = createFunctionIfDoesNotExistSQL(
|
|
1433
|
+
"emt_release_processor_lock",
|
|
1434
|
+
_dumbo.SQL`
|
|
1435
|
+
CREATE OR REPLACE FUNCTION emt_release_processor_lock(
|
|
1436
|
+
p_lock_key BIGINT,
|
|
1437
|
+
p_processor_id TEXT,
|
|
1438
|
+
p_partition TEXT,
|
|
1439
|
+
p_version INT,
|
|
1440
|
+
p_processor_instance_id TEXT DEFAULT '${_dumbo.SQL.plain(unknownTag2)}',
|
|
1441
|
+
p_projection_name TEXT DEFAULT NULL
|
|
1442
|
+
)
|
|
1443
|
+
RETURNS BOOLEAN
|
|
1444
|
+
LANGUAGE plpgsql
|
|
1445
|
+
AS $emt_release_processor_lock$
|
|
1446
|
+
DECLARE
|
|
1447
|
+
v_rows_updated INT;
|
|
1448
|
+
BEGIN
|
|
1449
|
+
IF p_projection_name IS NOT NULL THEN
|
|
1450
|
+
UPDATE ${_dumbo.SQL.plain(projectionsTable.name)}
|
|
1451
|
+
SET status = 'active',
|
|
1452
|
+
last_updated = now()
|
|
1453
|
+
WHERE partition = p_partition
|
|
1454
|
+
AND name = p_projection_name
|
|
1455
|
+
AND version = p_version;
|
|
1456
|
+
END IF;
|
|
1457
|
+
|
|
1458
|
+
UPDATE ${_dumbo.SQL.plain(processorsTable.name)}
|
|
1459
|
+
SET status = 'stopped',
|
|
1460
|
+
processor_instance_id = '${_dumbo.SQL.plain(unknownTag2)}',
|
|
1461
|
+
last_updated = now()
|
|
1462
|
+
WHERE processor_id = p_processor_id
|
|
1463
|
+
AND partition = p_partition
|
|
1464
|
+
AND version = p_version
|
|
1465
|
+
AND processor_instance_id = p_processor_instance_id;
|
|
1466
|
+
|
|
1467
|
+
GET DIAGNOSTICS v_rows_updated = ROW_COUNT;
|
|
1468
|
+
|
|
1469
|
+
PERFORM pg_advisory_unlock(p_lock_key);
|
|
1470
|
+
|
|
1471
|
+
RETURN v_rows_updated > 0;
|
|
1472
|
+
END;
|
|
1473
|
+
$emt_release_processor_lock$;
|
|
1474
|
+
`
|
|
1475
|
+
);
|
|
1476
|
+
var callTryAcquireProcessorLock = (params) => _dumbo.SQL`
|
|
1477
|
+
SELECT * FROM emt_try_acquire_processor_lock(
|
|
1478
|
+
${params.lockKey},
|
|
1479
|
+
${params.processorId},
|
|
1480
|
+
${params.version},
|
|
1481
|
+
${params.partition},
|
|
1482
|
+
${params.processorInstanceId},
|
|
1483
|
+
${params.projectionName},
|
|
1484
|
+
${params.projectionType},
|
|
1485
|
+
${params.projectionKind},
|
|
1486
|
+
${params.lockTimeoutSeconds}
|
|
1487
|
+
);
|
|
1488
|
+
`;
|
|
1489
|
+
var callReleaseProcessorLock = (params) => _dumbo.SQL`SELECT emt_release_processor_lock(
|
|
1490
|
+
${params.lockKey},
|
|
1491
|
+
${params.processorId},
|
|
1492
|
+
${params.partition},
|
|
1493
|
+
${params.version},
|
|
1494
|
+
${params.processorInstanceId},
|
|
1495
|
+
${params.projectionName}
|
|
1496
|
+
) as result;`;
|
|
1497
|
+
|
|
1498
|
+
// src/eventStore/projections/locks/tryAcquireProcessorLock.ts
|
|
1499
|
+
var PROCESSOR_LOCK_DEFAULT_TIMEOUT_SECONDS = 300;
|
|
1500
|
+
var tryAcquireProcessorLock = async (execute, options) => {
|
|
1501
|
+
const lockKeyBigInt = isBigint(options.lockKey) ? options.lockKey : await hashText(options.lockKey);
|
|
1502
|
+
const { acquired, checkpoint } = await _dumbo.single.call(void 0,
|
|
1503
|
+
execute.command(
|
|
1504
|
+
callTryAcquireProcessorLock({
|
|
1505
|
+
lockKey: lockKeyBigInt.toString(),
|
|
1506
|
+
processorId: options.processorId,
|
|
1507
|
+
version: options.version,
|
|
1508
|
+
partition: options.partition,
|
|
1509
|
+
processorInstanceId: options.processorInstanceId,
|
|
1510
|
+
projectionName: _nullishCoalesce(_optionalChain([options, 'access', _60 => _60.projection, 'optionalAccess', _61 => _61.name]), () => ( null)),
|
|
1511
|
+
projectionType: _optionalChain([options, 'access', _62 => _62.projection, 'optionalAccess', _63 => _63.handlingType]) ? options.projection.handlingType === "inline" ? "i" : "a" : null,
|
|
1512
|
+
projectionKind: _nullishCoalesce(_optionalChain([options, 'access', _64 => _64.projection, 'optionalAccess', _65 => _65.kind]), () => ( null)),
|
|
1513
|
+
lockTimeoutSeconds: _nullishCoalesce(options.lockTimeoutSeconds, () => ( PROCESSOR_LOCK_DEFAULT_TIMEOUT_SECONDS))
|
|
1514
|
+
})
|
|
1515
|
+
)
|
|
1516
|
+
);
|
|
1517
|
+
return acquired ? { acquired: true, checkpoint } : { acquired: false };
|
|
1518
|
+
};
|
|
1519
|
+
var tryAcquireProcessorLockWithRetry = async (execute, options) => {
|
|
1520
|
+
const policy = _nullishCoalesce(options.lockAcquisitionPolicy, () => ( DefaultPostgreSQLProcessorLockPolicy));
|
|
1521
|
+
if (policy.type === "retry") {
|
|
1522
|
+
return asyncRetry(() => tryAcquireProcessorLock(execute, options), {
|
|
1523
|
+
retries: policy.retries - 1,
|
|
1524
|
+
minTimeout: policy.minTimeout,
|
|
1525
|
+
maxTimeout: policy.maxTimeout,
|
|
1526
|
+
shouldRetryResult: (r) => !r.acquired
|
|
1527
|
+
});
|
|
1528
|
+
}
|
|
1529
|
+
return tryAcquireProcessorLock(execute, options);
|
|
1530
|
+
};
|
|
1531
|
+
var releaseProcessorLock = async (execute, options) => {
|
|
1532
|
+
const lockKeyBigInt = isBigint(options.lockKey) ? options.lockKey : await hashText(options.lockKey);
|
|
1533
|
+
const { result } = await _dumbo.single.call(void 0,
|
|
1534
|
+
execute.command(
|
|
1535
|
+
callReleaseProcessorLock({
|
|
1536
|
+
lockKey: lockKeyBigInt.toString(),
|
|
1537
|
+
processorId: options.processorId,
|
|
1538
|
+
partition: options.partition,
|
|
1539
|
+
version: options.version,
|
|
1540
|
+
processorInstanceId: options.processorInstanceId,
|
|
1541
|
+
projectionName: _nullishCoalesce(options.projectionName, () => ( null))
|
|
1542
|
+
})
|
|
1543
|
+
)
|
|
1544
|
+
);
|
|
1545
|
+
return result;
|
|
1546
|
+
};
|
|
1547
|
+
|
|
1548
|
+
// src/eventStore/projections/locks/postgreSQLProcessorLock.ts
|
|
1549
|
+
var DefaultPostgreSQLProcessorLockPolicy = {
|
|
1550
|
+
type: "fail"
|
|
1551
|
+
};
|
|
1552
|
+
var postgreSQLProcessorLock = (options) => {
|
|
1553
|
+
let acquired = false;
|
|
1554
|
+
const lockKey = _nullishCoalesce(options.lockKey, () => ( toProcessorLockKey(options)));
|
|
1555
|
+
return {
|
|
1556
|
+
tryAcquire: async (context) => {
|
|
1557
|
+
if (acquired) {
|
|
1558
|
+
return true;
|
|
1559
|
+
}
|
|
1560
|
+
const result = await tryAcquireProcessorLockWithRetry(context.execute, {
|
|
1561
|
+
...options,
|
|
1562
|
+
lockKey
|
|
1563
|
+
});
|
|
1564
|
+
if (!result.acquired && _optionalChain([options, 'access', _66 => _66.lockAcquisitionPolicy, 'optionalAccess', _67 => _67.type]) !== "skip") {
|
|
1565
|
+
throw new EmmettError(
|
|
1566
|
+
`Failed to acquire lock for processor '${options.processorId}'`
|
|
1567
|
+
);
|
|
1568
|
+
}
|
|
1569
|
+
acquired = result.acquired;
|
|
1570
|
+
return acquired;
|
|
1571
|
+
},
|
|
1572
|
+
release: async (context) => {
|
|
1573
|
+
if (!acquired) return;
|
|
1574
|
+
const { projection: projection2, ...releaseOptions } = options;
|
|
1575
|
+
await releaseProcessorLock(context.execute, {
|
|
1576
|
+
...releaseOptions,
|
|
1577
|
+
lockKey,
|
|
1578
|
+
projectionName: _optionalChain([projection2, 'optionalAccess', _68 => _68.name])
|
|
1579
|
+
});
|
|
1580
|
+
acquired = false;
|
|
1581
|
+
}
|
|
1582
|
+
};
|
|
1583
|
+
};
|
|
1584
|
+
var toProcessorLockKey = ({
|
|
1585
|
+
projection: projection2,
|
|
1586
|
+
processorId,
|
|
1587
|
+
partition,
|
|
1588
|
+
version
|
|
1589
|
+
}) => projection2 ? toProjectionLockKey({
|
|
1590
|
+
projectionName: projection2.name,
|
|
1591
|
+
partition,
|
|
1592
|
+
version: projection2.version
|
|
1593
|
+
}) : `${partition}:${processorId}:${version}`;
|
|
1594
|
+
|
|
1595
|
+
// src/eventStore/projections/management/projectionManagement.ts
|
|
1596
|
+
|
|
1597
|
+
|
|
1598
|
+
|
|
1599
|
+
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
|
|
1603
|
+
// src/eventStore/schema/projections/registerProjection.ts
|
|
1604
|
+
|
|
1605
|
+
var registerProjectionSQL = createFunctionIfDoesNotExistSQL(
|
|
1606
|
+
"emt_register_projection",
|
|
1607
|
+
_dumbo.SQL`
|
|
1608
|
+
CREATE OR REPLACE FUNCTION emt_register_projection(
|
|
1609
|
+
p_lock_key BIGINT,
|
|
1610
|
+
p_name TEXT,
|
|
1611
|
+
p_partition TEXT,
|
|
1612
|
+
p_version INT,
|
|
1613
|
+
p_type VARCHAR(1),
|
|
1614
|
+
p_kind TEXT,
|
|
1615
|
+
p_status TEXT,
|
|
1616
|
+
p_definition JSONB
|
|
1617
|
+
)
|
|
1618
|
+
RETURNS BOOLEAN
|
|
1619
|
+
LANGUAGE plpgsql
|
|
1620
|
+
AS $emt_register_projection$
|
|
1621
|
+
DECLARE
|
|
1622
|
+
v_result BOOLEAN;
|
|
1623
|
+
BEGIN
|
|
1624
|
+
WITH lock_check AS (
|
|
1625
|
+
SELECT pg_try_advisory_xact_lock(p_lock_key) AS lock_acquired
|
|
1626
|
+
),
|
|
1627
|
+
upsert_result AS (
|
|
1628
|
+
INSERT INTO ${_dumbo.SQL.identifier(projectionsTable.name)} (
|
|
1629
|
+
name, partition, version, type, kind, status, definition, created_at, last_updated
|
|
1630
|
+
)
|
|
1631
|
+
SELECT p_name, p_partition, p_version, p_type, p_kind, p_status, p_definition, now(), now()
|
|
1632
|
+
WHERE (SELECT lock_acquired FROM lock_check) = true
|
|
1633
|
+
ON CONFLICT (name, partition, version) DO UPDATE
|
|
1634
|
+
SET definition = EXCLUDED.definition,
|
|
1635
|
+
last_updated = now()
|
|
1636
|
+
RETURNING name
|
|
1266
1637
|
)
|
|
1267
1638
|
SELECT COUNT(*) > 0 INTO v_result FROM upsert_result;
|
|
1268
1639
|
|
|
@@ -1579,7 +1950,6 @@ var pongoSingleStreamProjection = (options) => {
|
|
|
1579
1950
|
|
|
1580
1951
|
|
|
1581
1952
|
|
|
1582
|
-
|
|
1583
1953
|
var withCollection = (handle, options) => {
|
|
1584
1954
|
const { pool, connectionString, inDatabase, inCollection } = options;
|
|
1585
1955
|
return pool.withConnection(async (connection) => {
|
|
@@ -1666,7 +2036,7 @@ var documentDoesNotExist = (options) => (assertOptions) => withCollection(
|
|
|
1666
2036
|
const result = await collection.findOne(
|
|
1667
2037
|
"withId" in options ? { _id: options.withId } : options.matchingFilter
|
|
1668
2038
|
);
|
|
1669
|
-
|
|
2039
|
+
assertIsNull(result);
|
|
1670
2040
|
},
|
|
1671
2041
|
{ ...options, ...assertOptions }
|
|
1672
2042
|
);
|
|
@@ -1718,34 +2088,272 @@ var expectPongoDocuments = {
|
|
|
1718
2088
|
|
|
1719
2089
|
|
|
1720
2090
|
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
//
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
2091
|
+
var PostgreSQLProjectionSpec = {
|
|
2092
|
+
for: (options) => {
|
|
2093
|
+
{
|
|
2094
|
+
const { projection: projection2, ...restOptions } = options;
|
|
2095
|
+
const dumboOptions = {
|
|
2096
|
+
...restOptions,
|
|
2097
|
+
serialization: projection2.serialization
|
|
2098
|
+
};
|
|
2099
|
+
const { connectionString } = dumboOptions;
|
|
2100
|
+
let wasInitialised = false;
|
|
2101
|
+
const initialize = async (pool) => {
|
|
2102
|
+
const eventStore = getPostgreSQLEventStore(connectionString, {
|
|
2103
|
+
// TODO: This will need to change when we support other drivers
|
|
2104
|
+
connectionOptions: { dumbo: pool }
|
|
2105
|
+
});
|
|
2106
|
+
if (wasInitialised) return;
|
|
2107
|
+
wasInitialised = true;
|
|
2108
|
+
await eventStore.schema.migrate();
|
|
2109
|
+
if (projection2.init)
|
|
2110
|
+
await pool.withTransaction(async (transaction) => {
|
|
2111
|
+
await projection2.init({
|
|
2112
|
+
registrationType: "async",
|
|
2113
|
+
version: _nullishCoalesce(projection2.version, () => ( 1)),
|
|
2114
|
+
status: "active",
|
|
2115
|
+
context: await transactionToPostgreSQLProjectionHandlerContext(
|
|
2116
|
+
connectionString,
|
|
2117
|
+
pool,
|
|
2118
|
+
transaction
|
|
2119
|
+
)
|
|
2120
|
+
});
|
|
2121
|
+
});
|
|
2122
|
+
};
|
|
2123
|
+
return (givenEvents) => {
|
|
2124
|
+
return {
|
|
2125
|
+
when: (events, options2) => {
|
|
2126
|
+
const allEvents = [];
|
|
2127
|
+
const run = async (pool) => {
|
|
2128
|
+
let globalPosition = 0n;
|
|
2129
|
+
const numberOfTimes = _nullishCoalesce(_optionalChain([options2, 'optionalAccess', _69 => _69.numberOfTimes]), () => ( 1));
|
|
2130
|
+
for (const event of [
|
|
2131
|
+
...givenEvents,
|
|
2132
|
+
...Array.from({ length: numberOfTimes }).flatMap(() => events)
|
|
2133
|
+
]) {
|
|
2134
|
+
const metadata = {
|
|
2135
|
+
checkpoint: bigIntProcessorCheckpoint(++globalPosition),
|
|
2136
|
+
globalPosition,
|
|
2137
|
+
streamPosition: globalPosition,
|
|
2138
|
+
streamName: `test-${_uuid.v4.call(void 0, )}`,
|
|
2139
|
+
messageId: _uuid.v4.call(void 0, )
|
|
2140
|
+
};
|
|
2141
|
+
allEvents.push({
|
|
2142
|
+
...event,
|
|
2143
|
+
kind: "Event",
|
|
2144
|
+
metadata: {
|
|
2145
|
+
...metadata,
|
|
2146
|
+
..."metadata" in event ? _nullishCoalesce(event.metadata, () => ( {})) : {}
|
|
2147
|
+
}
|
|
2148
|
+
});
|
|
2149
|
+
}
|
|
2150
|
+
await initialize(pool);
|
|
2151
|
+
await pool.withTransaction(async (transaction) => {
|
|
2152
|
+
await handleProjections({
|
|
2153
|
+
events: allEvents,
|
|
2154
|
+
projections: [projection2],
|
|
2155
|
+
...await transactionToPostgreSQLProjectionHandlerContext(
|
|
2156
|
+
connectionString,
|
|
2157
|
+
pool,
|
|
2158
|
+
transaction
|
|
2159
|
+
)
|
|
2160
|
+
});
|
|
2161
|
+
});
|
|
2162
|
+
};
|
|
2163
|
+
return {
|
|
2164
|
+
then: async (assert, message) => {
|
|
2165
|
+
const pool = _dumbo.dumbo.call(void 0, dumboOptions);
|
|
2166
|
+
try {
|
|
2167
|
+
await run(pool);
|
|
2168
|
+
const succeeded = await assert({ pool, connectionString });
|
|
2169
|
+
if (succeeded !== void 0 && succeeded === false)
|
|
2170
|
+
assertFails(
|
|
2171
|
+
_nullishCoalesce(message, () => ( "Projection specification didn't match the criteria"))
|
|
2172
|
+
);
|
|
2173
|
+
} finally {
|
|
2174
|
+
await pool.close();
|
|
2175
|
+
}
|
|
2176
|
+
},
|
|
2177
|
+
thenThrows: async (...args) => {
|
|
2178
|
+
const pool = _dumbo.dumbo.call(void 0, dumboOptions);
|
|
2179
|
+
try {
|
|
2180
|
+
await run(pool);
|
|
2181
|
+
throw new AssertionError("Handler did not fail as expected");
|
|
2182
|
+
} catch (error) {
|
|
2183
|
+
if (error instanceof AssertionError) throw error;
|
|
2184
|
+
if (args.length === 0) return;
|
|
2185
|
+
if (!isErrorConstructor(args[0])) {
|
|
2186
|
+
assertTrue(
|
|
2187
|
+
args[0](error),
|
|
2188
|
+
`Error didn't match the error condition: ${_optionalChain([error, 'optionalAccess', _70 => _70.toString, 'call', _71 => _71()])}`
|
|
2189
|
+
);
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
2192
|
+
assertTrue(
|
|
2193
|
+
error instanceof args[0],
|
|
2194
|
+
`Caught error is not an instance of the expected type: ${_optionalChain([error, 'optionalAccess', _72 => _72.toString, 'call', _73 => _73()])}`
|
|
2195
|
+
);
|
|
2196
|
+
if (args[1]) {
|
|
2197
|
+
assertTrue(
|
|
2198
|
+
args[1](error),
|
|
2199
|
+
`Error didn't match the error condition: ${_optionalChain([error, 'optionalAccess', _74 => _74.toString, 'call', _75 => _75()])}`
|
|
2200
|
+
);
|
|
2201
|
+
}
|
|
2202
|
+
} finally {
|
|
2203
|
+
await pool.close();
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
};
|
|
2207
|
+
}
|
|
2208
|
+
};
|
|
2209
|
+
};
|
|
2210
|
+
}
|
|
2211
|
+
}
|
|
2212
|
+
};
|
|
2213
|
+
var eventInStream = (streamName, event) => {
|
|
2214
|
+
return {
|
|
2215
|
+
...event,
|
|
2216
|
+
metadata: {
|
|
2217
|
+
..._nullishCoalesce(event.metadata, () => ( {})),
|
|
2218
|
+
streamName: _nullishCoalesce(_optionalChain([event, 'access', _76 => _76.metadata, 'optionalAccess', _77 => _77.streamName]), () => ( streamName))
|
|
2219
|
+
}
|
|
2220
|
+
};
|
|
2221
|
+
};
|
|
2222
|
+
var eventsInStream = (streamName, events) => {
|
|
2223
|
+
return events.map((e) => eventInStream(streamName, e));
|
|
2224
|
+
};
|
|
2225
|
+
var newEventsInStream = eventsInStream;
|
|
2226
|
+
var assertSQLQueryResultMatches = (sql, rows) => async ({ pool: { execute } }) => {
|
|
2227
|
+
const result = await execute.query(sql);
|
|
2228
|
+
assertThatArray(rows).containsExactlyInAnyOrder(result.rows);
|
|
2229
|
+
};
|
|
2230
|
+
var expectSQL = {
|
|
2231
|
+
query: (sql) => ({
|
|
2232
|
+
resultRows: {
|
|
2233
|
+
toBeTheSame: (rows) => assertSQLQueryResultMatches(sql, rows)
|
|
2234
|
+
}
|
|
2235
|
+
})
|
|
2236
|
+
};
|
|
2237
|
+
|
|
2238
|
+
// src/eventStore/projections/postgreSQLProjection.ts
|
|
2239
|
+
var transactionToPostgreSQLProjectionHandlerContext = async (connectionString, pool, transaction) => ({
|
|
2240
|
+
execute: transaction.execute,
|
|
2241
|
+
connection: {
|
|
2242
|
+
connectionString,
|
|
2243
|
+
client: await transaction.connection.open(),
|
|
2244
|
+
transaction,
|
|
2245
|
+
pool
|
|
2246
|
+
}
|
|
2247
|
+
});
|
|
2248
|
+
var handleProjections = async (options) => {
|
|
2249
|
+
const {
|
|
2250
|
+
projections: allProjections,
|
|
2251
|
+
events,
|
|
2252
|
+
connection: { pool, transaction, connectionString },
|
|
2253
|
+
partition = defaultTag2
|
|
2254
|
+
} = options;
|
|
2255
|
+
const eventTypes = events.map((e) => e.type);
|
|
2256
|
+
const projections = allProjections.filter(
|
|
2257
|
+
(p) => p.canHandle.some((type) => eventTypes.includes(type))
|
|
2258
|
+
);
|
|
2259
|
+
const client = await transaction.connection.open();
|
|
2260
|
+
for (const projection2 of projections) {
|
|
2261
|
+
if (projection2.name) {
|
|
2262
|
+
const lockAcquired = await postgreSQLProjectionLock({
|
|
2263
|
+
projectionName: projection2.name,
|
|
2264
|
+
partition,
|
|
2265
|
+
version: _nullishCoalesce(projection2.version, () => ( 1))
|
|
2266
|
+
}).tryAcquire({ execute: transaction.execute });
|
|
2267
|
+
if (!lockAcquired) {
|
|
2268
|
+
continue;
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
await projection2.handle(events, {
|
|
2272
|
+
connection: {
|
|
2273
|
+
connectionString,
|
|
2274
|
+
pool,
|
|
2275
|
+
client,
|
|
2276
|
+
transaction
|
|
2277
|
+
},
|
|
2278
|
+
execute: transaction.execute
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2281
|
+
};
|
|
2282
|
+
var postgreSQLProjection = (definition) => projection({
|
|
2283
|
+
...definition,
|
|
2284
|
+
init: async (options) => {
|
|
2285
|
+
await registerProjection(options.context.execute, {
|
|
2286
|
+
// TODO: pass partition from options
|
|
2287
|
+
partition: defaultTag2,
|
|
2288
|
+
status: "active",
|
|
2289
|
+
registration: {
|
|
2290
|
+
type: "async",
|
|
2291
|
+
// TODO: fix this
|
|
2292
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
|
|
2293
|
+
projection: definition
|
|
2294
|
+
}
|
|
2295
|
+
});
|
|
2296
|
+
if (definition.init) {
|
|
2297
|
+
await definition.init(options);
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
});
|
|
2301
|
+
var postgreSQLRawBatchSQLProjection = (options) => postgreSQLProjection({
|
|
2302
|
+
name: options.name,
|
|
2303
|
+
kind: _nullishCoalesce(options.kind, () => ( "emt:projections:postgresql:raw_sql:batch")),
|
|
2304
|
+
version: options.version,
|
|
2305
|
+
canHandle: options.canHandle,
|
|
2306
|
+
eventsOptions: options.eventsOptions,
|
|
2307
|
+
handle: async (events, context) => {
|
|
2308
|
+
const sqls = await options.evolve(events, context);
|
|
2309
|
+
await context.execute.batchCommand(sqls);
|
|
2310
|
+
},
|
|
2311
|
+
init: async (initOptions) => {
|
|
2312
|
+
const initSQL = options.init ? await options.init(initOptions) : void 0;
|
|
2313
|
+
if (initSQL) {
|
|
2314
|
+
if (Array.isArray(initSQL)) {
|
|
2315
|
+
await initOptions.context.execute.batchCommand(initSQL);
|
|
2316
|
+
} else {
|
|
2317
|
+
await initOptions.context.execute.command(initSQL);
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
});
|
|
2322
|
+
var postgreSQLRawSQLProjection = (options) => {
|
|
2323
|
+
const { evolve, kind, ...rest } = options;
|
|
2324
|
+
return postgreSQLRawBatchSQLProjection({
|
|
2325
|
+
kind: _nullishCoalesce(kind, () => ( "emt:projections:postgresql:raw:_sql:single")),
|
|
2326
|
+
...rest,
|
|
2327
|
+
evolve: async (events, context) => {
|
|
2328
|
+
const sqls = [];
|
|
2329
|
+
for (const event of events) {
|
|
2330
|
+
const pendingSqls = await evolve(event, context);
|
|
2331
|
+
if (Array.isArray(pendingSqls)) {
|
|
2332
|
+
sqls.push(...pendingSqls);
|
|
2333
|
+
} else {
|
|
2334
|
+
sqls.push(pendingSqls);
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
return sqls;
|
|
2338
|
+
}
|
|
2339
|
+
});
|
|
2340
|
+
};
|
|
2341
|
+
|
|
2342
|
+
// src/eventStore/schema/index.ts
|
|
2343
|
+
|
|
2344
|
+
|
|
2345
|
+
|
|
2346
|
+
|
|
2347
|
+
|
|
2348
|
+
|
|
2349
|
+
// src/eventStore/schema/appendToStream.ts
|
|
2350
|
+
|
|
2351
|
+
|
|
2352
|
+
|
|
2353
|
+
|
|
2354
|
+
|
|
2355
|
+
|
|
2356
|
+
|
|
1749
2357
|
var appendToStreamSQL = createFunctionIfDoesNotExistSQL(
|
|
1750
2358
|
"emt_append_to_stream",
|
|
1751
2359
|
_dumbo.SQL`CREATE OR REPLACE FUNCTION emt_append_to_stream(
|
|
@@ -1858,7 +2466,7 @@ var appendToStream = (pool, streamName, streamType, messages, options) => pool.w
|
|
|
1858
2466
|
return { success: false, result: { success: false } };
|
|
1859
2467
|
try {
|
|
1860
2468
|
const expectedStreamVersion = toExpectedVersion(
|
|
1861
|
-
_optionalChain([options, 'optionalAccess',
|
|
2469
|
+
_optionalChain([options, 'optionalAccess', _78 => _78.expectedStreamVersion])
|
|
1862
2470
|
);
|
|
1863
2471
|
const messagesToAppend = messages.map((e) => ({
|
|
1864
2472
|
...e,
|
|
@@ -1898,7 +2506,7 @@ var appendToStream = (pool, streamName, streamType, messages, options) => pool.w
|
|
|
1898
2506
|
globalPosition
|
|
1899
2507
|
};
|
|
1900
2508
|
});
|
|
1901
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
2509
|
+
if (_optionalChain([options, 'optionalAccess', _79 => _79.beforeCommitHook]))
|
|
1902
2510
|
await options.beforeCommitHook(messagesToAppend, { transaction });
|
|
1903
2511
|
return {
|
|
1904
2512
|
success: true,
|
|
@@ -1941,8 +2549,8 @@ var appendEventsRaw = (execute, streamId, streamType, messages, options) => _dum
|
|
|
1941
2549
|
messageKinds: messages.map((e) => e.kind === "Event" ? "E" : "C"),
|
|
1942
2550
|
streamId,
|
|
1943
2551
|
streamType,
|
|
1944
|
-
expectedStreamPosition: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
1945
|
-
partition: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2552
|
+
expectedStreamPosition: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _80 => _80.expectedStreamVersion]), () => ( null)),
|
|
2553
|
+
partition: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _81 => _81.partition]), () => ( defaultTag2))
|
|
1946
2554
|
})
|
|
1947
2555
|
)
|
|
1948
2556
|
);
|
|
@@ -2437,7 +3045,7 @@ BEGIN
|
|
|
2437
3045
|
END;
|
|
2438
3046
|
$fnpar$ LANGUAGE plpgsql;
|
|
2439
3047
|
|
|
2440
|
-
PERFORM emt_add_partition('${_dumbo.SQL.plain(
|
|
3048
|
+
PERFORM emt_add_partition('${_dumbo.SQL.plain(defaultTag2)}');
|
|
2441
3049
|
|
|
2442
3050
|
-- 3. Copy data from old table to new table
|
|
2443
3051
|
INSERT INTO "emt_processors"
|
|
@@ -2553,7 +3161,7 @@ BEGIN
|
|
|
2553
3161
|
p_position TEXT,
|
|
2554
3162
|
p_check_position TEXT,
|
|
2555
3163
|
p_transaction_id xid8,
|
|
2556
|
-
p_partition TEXT DEFAULT '${_dumbo.SQL.plain(
|
|
3164
|
+
p_partition TEXT DEFAULT '${_dumbo.SQL.plain(defaultTag2)}',
|
|
2557
3165
|
p_processor_instance_id TEXT DEFAULT 'emt:unknown'
|
|
2558
3166
|
) RETURNS INT AS $fn2$
|
|
2559
3167
|
DECLARE
|
|
@@ -2688,7 +3296,7 @@ CREATE OR REPLACE FUNCTION emt_try_acquire_processor_lock(
|
|
|
2688
3296
|
p_lock_key BIGINT,
|
|
2689
3297
|
p_processor_id TEXT,
|
|
2690
3298
|
p_version INT,
|
|
2691
|
-
p_partition TEXT DEFAULT '${_dumbo.SQL.plain(
|
|
3299
|
+
p_partition TEXT DEFAULT '${_dumbo.SQL.plain(defaultTag2)}',
|
|
2692
3300
|
p_processor_instance_id TEXT DEFAULT 'emt:unknown',
|
|
2693
3301
|
p_projection_name TEXT DEFAULT NULL,
|
|
2694
3302
|
p_projection_type VARCHAR(1) DEFAULT NULL,
|
|
@@ -3467,8 +4075,8 @@ CREATE OR REPLACE FUNCTION store_processor_checkpoint(
|
|
|
3467
4075
|
p_position TEXT,
|
|
3468
4076
|
p_check_position TEXT,
|
|
3469
4077
|
p_transaction_id xid8,
|
|
3470
|
-
p_partition TEXT DEFAULT '${_dumbo.SQL.plain(
|
|
3471
|
-
p_processor_instance_id TEXT DEFAULT '${_dumbo.SQL.plain(
|
|
4078
|
+
p_partition TEXT DEFAULT '${_dumbo.SQL.plain(defaultTag2)}',
|
|
4079
|
+
p_processor_instance_id TEXT DEFAULT '${_dumbo.SQL.plain(unknownTag2)}'
|
|
3472
4080
|
) RETURNS INT AS $spc$
|
|
3473
4081
|
DECLARE
|
|
3474
4082
|
current_position TEXT;
|
|
@@ -3549,10 +4157,10 @@ var storeProcessorCheckpoint = async (execute, options) => {
|
|
|
3549
4157
|
callStoreProcessorCheckpoint({
|
|
3550
4158
|
processorId: options.processorId,
|
|
3551
4159
|
version: _nullishCoalesce(options.version, () => ( 1)),
|
|
3552
|
-
position: options.newCheckpoint !== null ?
|
|
3553
|
-
checkPosition: options.lastProcessedCheckpoint !== null ?
|
|
3554
|
-
partition: _nullishCoalesce(options.partition, () => (
|
|
3555
|
-
processorInstanceId: _nullishCoalesce(options.processorInstanceId, () => (
|
|
4160
|
+
position: options.newCheckpoint !== null ? options.newCheckpoint : null,
|
|
4161
|
+
checkPosition: options.lastProcessedCheckpoint !== null ? options.lastProcessedCheckpoint : null,
|
|
4162
|
+
partition: _nullishCoalesce(options.partition, () => ( defaultTag2)),
|
|
4163
|
+
processorInstanceId: _nullishCoalesce(options.processorInstanceId, () => ( unknownTag2))
|
|
3556
4164
|
})
|
|
3557
4165
|
)
|
|
3558
4166
|
);
|
|
@@ -3612,7 +4220,7 @@ IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'emt_subscriptions') THEN
|
|
|
3612
4220
|
p_position TEXT,
|
|
3613
4221
|
p_check_position TEXT,
|
|
3614
4222
|
p_transaction_id xid8,
|
|
3615
|
-
p_partition TEXT DEFAULT '${_dumbo.SQL.plain(
|
|
4223
|
+
p_partition TEXT DEFAULT '${_dumbo.SQL.plain(defaultTag2)}',
|
|
3616
4224
|
p_processor_instance_id TEXT DEFAULT 'emt:unknown'
|
|
3617
4225
|
) RETURNS INT AS $fn$
|
|
3618
4226
|
DECLARE
|
|
@@ -3689,7 +4297,7 @@ var streamsTableSQL = _dumbo.SQL`
|
|
|
3689
4297
|
CREATE TABLE IF NOT EXISTS ${_dumbo.SQL.identifier(streamsTable.name)}(
|
|
3690
4298
|
stream_id TEXT NOT NULL,
|
|
3691
4299
|
stream_position BIGINT NOT NULL,
|
|
3692
|
-
partition TEXT NOT NULL DEFAULT '${_dumbo.SQL.plain(
|
|
4300
|
+
partition TEXT NOT NULL DEFAULT '${_dumbo.SQL.plain(defaultTag2)}',
|
|
3693
4301
|
stream_type TEXT NOT NULL,
|
|
3694
4302
|
stream_metadata JSONB NOT NULL,
|
|
3695
4303
|
is_archived BOOLEAN NOT NULL DEFAULT FALSE,
|
|
@@ -3710,7 +4318,7 @@ var messagesTableSQL = _dumbo.SQL`
|
|
|
3710
4318
|
is_archived BOOLEAN NOT NULL DEFAULT FALSE,
|
|
3711
4319
|
message_kind VARCHAR(1) NOT NULL DEFAULT 'E',
|
|
3712
4320
|
stream_id TEXT NOT NULL,
|
|
3713
|
-
partition TEXT NOT NULL DEFAULT '${_dumbo.SQL.plain(
|
|
4321
|
+
partition TEXT NOT NULL DEFAULT '${_dumbo.SQL.plain(defaultTag2)}',
|
|
3714
4322
|
message_schema_version TEXT NOT NULL,
|
|
3715
4323
|
message_id TEXT NOT NULL,
|
|
3716
4324
|
message_type TEXT NOT NULL,
|
|
@@ -3723,10 +4331,10 @@ var processorsTableSQL = _dumbo.SQL`
|
|
|
3723
4331
|
last_processed_transaction_id XID8 NOT NULL,
|
|
3724
4332
|
version INT NOT NULL DEFAULT 1,
|
|
3725
4333
|
processor_id TEXT NOT NULL,
|
|
3726
|
-
partition TEXT NOT NULL DEFAULT '${_dumbo.SQL.plain(
|
|
4334
|
+
partition TEXT NOT NULL DEFAULT '${_dumbo.SQL.plain(defaultTag2)}',
|
|
3727
4335
|
status TEXT NOT NULL DEFAULT 'stopped',
|
|
3728
4336
|
last_processed_checkpoint TEXT NOT NULL,
|
|
3729
|
-
processor_instance_id TEXT DEFAULT '${_dumbo.SQL.plain(
|
|
4337
|
+
processor_instance_id TEXT DEFAULT '${_dumbo.SQL.plain(unknownTag2)}',
|
|
3730
4338
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
3731
4339
|
last_updated TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
3732
4340
|
PRIMARY KEY (processor_id, partition, version)
|
|
@@ -3737,7 +4345,7 @@ var projectionsTableSQL = _dumbo.SQL`
|
|
|
3737
4345
|
version INT NOT NULL DEFAULT 1,
|
|
3738
4346
|
type VARCHAR(1) NOT NULL,
|
|
3739
4347
|
name TEXT NOT NULL,
|
|
3740
|
-
partition TEXT NOT NULL DEFAULT '${_dumbo.SQL.plain(
|
|
4348
|
+
partition TEXT NOT NULL DEFAULT '${_dumbo.SQL.plain(defaultTag2)}',
|
|
3741
4349
|
kind TEXT NOT NULL,
|
|
3742
4350
|
status TEXT NOT NULL,
|
|
3743
4351
|
definition JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
@@ -3995,7 +4603,7 @@ var addTenantForAllModulesSQL = _dumbo.SQL`
|
|
|
3995
4603
|
END;
|
|
3996
4604
|
$$ LANGUAGE plpgsql;
|
|
3997
4605
|
`;
|
|
3998
|
-
var addDefaultPartitionSQL = _dumbo.SQL`SELECT emt_add_partition('${_dumbo.SQL.plain(
|
|
4606
|
+
var addDefaultPartitionSQL = _dumbo.SQL`SELECT emt_add_partition('${_dumbo.SQL.plain(defaultTag2)}');`;
|
|
3999
4607
|
|
|
4000
4608
|
// src/eventStore/schema/readProcessorCheckpoint.ts
|
|
4001
4609
|
|
|
@@ -4004,592 +4612,347 @@ var readProcessorCheckpoint = async (execute, options) => {
|
|
|
4004
4612
|
execute.query(
|
|
4005
4613
|
_dumbo.SQL`SELECT last_processed_checkpoint
|
|
4006
4614
|
FROM ${_dumbo.SQL.identifier(processorsTable.name)}
|
|
4007
|
-
WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
4615
|
+
WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _82 => _82.partition]), () => ( defaultTag2))} AND processor_id = ${options.processorId} AND version = ${_nullishCoalesce(options.version, () => ( 1))}
|
|
4008
4616
|
LIMIT 1`
|
|
4009
4617
|
)
|
|
4010
4618
|
);
|
|
4011
4619
|
return {
|
|
4012
|
-
lastProcessedCheckpoint: result !== null ?
|
|
4620
|
+
lastProcessedCheckpoint: result !== null ? result.last_processed_checkpoint : null
|
|
4013
4621
|
};
|
|
4014
|
-
};
|
|
4015
|
-
|
|
4016
|
-
// src/eventStore/schema/readStream.ts
|
|
4017
|
-
|
|
4018
|
-
var readStream = async (execute, streamId, options) => {
|
|
4019
|
-
const fromCondition = _optionalChain([options, 'optionalAccess',
|
|
4020
|
-
const to = Number(
|
|
4021
|
-
_nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
4022
|
-
);
|
|
4023
|
-
const toCondition = !isNaN(to) ? `AND stream_position <= ${to}` : "";
|
|
4024
|
-
const events = await _dumbo.mapRows.call(void 0,
|
|
4025
|
-
execute.query(
|
|
4026
|
-
_dumbo.SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
|
|
4027
|
-
FROM ${_dumbo.SQL.identifier(messagesTable.name)}
|
|
4028
|
-
WHERE stream_id = ${streamId} AND partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
4029
|
-
ORDER BY stream_position ASC`
|
|
4030
|
-
),
|
|
4031
|
-
(row) => {
|
|
4032
|
-
const rawEvent = {
|
|
4033
|
-
type: row.message_type,
|
|
4034
|
-
data: row.message_data,
|
|
4035
|
-
metadata: row.message_metadata
|
|
4036
|
-
};
|
|
4037
|
-
const metadata = {
|
|
4038
|
-
..."metadata" in rawEvent ? _nullishCoalesce(rawEvent.metadata, () => ( {})) : {},
|
|
4039
|
-
messageId: row.message_id,
|
|
4040
|
-
streamName: streamId,
|
|
4041
|
-
streamPosition: BigInt(row.stream_position),
|
|
4042
|
-
globalPosition: BigInt(row.global_position)
|
|
4043
|
-
};
|
|
4044
|
-
const event = {
|
|
4045
|
-
...rawEvent,
|
|
4046
|
-
kind: "Event",
|
|
4047
|
-
metadata
|
|
4048
|
-
};
|
|
4049
|
-
return upcastRecordedMessage(event, _optionalChain([options, 'optionalAccess', _57 => _57.schema, 'optionalAccess', _58 => _58.versioning]));
|
|
4050
|
-
}
|
|
4051
|
-
);
|
|
4052
|
-
return events.length > 0 ? {
|
|
4053
|
-
currentStreamVersion: events[events.length - 1].metadata.streamPosition,
|
|
4054
|
-
events,
|
|
4055
|
-
streamExists: true
|
|
4056
|
-
} : {
|
|
4057
|
-
currentStreamVersion: PostgreSQLEventStoreDefaultStreamVersion,
|
|
4058
|
-
events: [],
|
|
4059
|
-
streamExists: false
|
|
4060
|
-
};
|
|
4061
|
-
};
|
|
4062
|
-
|
|
4063
|
-
// src/eventStore/schema/streamExists.ts
|
|
4064
|
-
|
|
4065
|
-
var streamExists = async (execute, streamId, options) => {
|
|
4066
|
-
const queryResult = await execute.query(
|
|
4067
|
-
_dumbo.SQL`SELECT EXISTS (
|
|
4068
|
-
SELECT 1
|
|
4069
|
-
from ${_dumbo.SQL.identifier(streamsTable.name)}
|
|
4070
|
-
WHERE stream_id = ${streamId} AND partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _59 => _59.partition]), () => ( defaultTag))} AND is_archived = FALSE)
|
|
4071
|
-
`
|
|
4072
|
-
);
|
|
4073
|
-
return _nullishCoalesce(_optionalChain([queryResult, 'access', _60 => _60.rows, 'access', _61 => _61[0], 'optionalAccess', _62 => _62.exists]), () => ( false));
|
|
4074
|
-
};
|
|
4075
|
-
|
|
4076
|
-
// src/eventStore/schema/index.ts
|
|
4077
|
-
var schemaSQL = [
|
|
4078
|
-
streamsTableSQL,
|
|
4079
|
-
messagesTableSQL,
|
|
4080
|
-
projectionsTableSQL,
|
|
4081
|
-
processorsTableSQL,
|
|
4082
|
-
sanitizeNameSQL,
|
|
4083
|
-
addTablePartitions,
|
|
4084
|
-
addPartitionSQL,
|
|
4085
|
-
appendToStreamSQL,
|
|
4086
|
-
addDefaultPartitionSQL,
|
|
4087
|
-
storeSubscriptionCheckpointSQL,
|
|
4088
|
-
tryAcquireProcessorLockSQL,
|
|
4089
|
-
releaseProcessorLockSQL,
|
|
4090
|
-
registerProjectionSQL,
|
|
4091
|
-
activateProjectionSQL,
|
|
4092
|
-
deactivateProjectionSQL
|
|
4093
|
-
];
|
|
4094
|
-
var schemaMigration = _dumbo.sqlMigration.call(void 0,
|
|
4095
|
-
"emt:postgresql:eventstore:initial",
|
|
4096
|
-
schemaSQL
|
|
4097
|
-
);
|
|
4098
|
-
var eventStoreSchemaMigrations = [
|
|
4099
|
-
migration_0_38_7_and_older,
|
|
4100
|
-
migration_0_42_0_FromSubscriptionsToProcessors,
|
|
4101
|
-
migration_0_42_0_2_AddProcessorProjectionFunctions,
|
|
4102
|
-
schemaMigration
|
|
4103
|
-
];
|
|
4104
|
-
var createEventStoreSchema = (connectionString, pool, hooks, options) => {
|
|
4105
|
-
return pool.withTransaction(async (tx) => {
|
|
4106
|
-
const context = await transactionToPostgreSQLProjectionHandlerContext(
|
|
4107
|
-
connectionString,
|
|
4108
|
-
pool,
|
|
4109
|
-
tx
|
|
4110
|
-
);
|
|
4111
|
-
const nestedPool = _dumbo.dumbo.call(void 0, { connectionString, connection: tx.connection });
|
|
4112
|
-
try {
|
|
4113
|
-
if (_optionalChain([hooks, 'optionalAccess', _63 => _63.onBeforeSchemaCreated])) {
|
|
4114
|
-
await hooks.onBeforeSchemaCreated(context);
|
|
4115
|
-
}
|
|
4116
|
-
const result = await _dumbo.runSQLMigrations.call(void 0,
|
|
4117
|
-
nestedPool,
|
|
4118
|
-
eventStoreSchemaMigrations,
|
|
4119
|
-
options
|
|
4120
|
-
);
|
|
4121
|
-
if (_optionalChain([hooks, 'optionalAccess', _64 => _64.onAfterSchemaCreated])) {
|
|
4122
|
-
await hooks.onAfterSchemaCreated(context);
|
|
4123
|
-
}
|
|
4124
|
-
return result;
|
|
4125
|
-
} finally {
|
|
4126
|
-
await nestedPool.close();
|
|
4127
|
-
}
|
|
4128
|
-
});
|
|
4129
|
-
};
|
|
4130
|
-
|
|
4131
|
-
// src/eventStore/schema/truncateTables.ts
|
|
4132
|
-
|
|
4133
|
-
var truncateTables = async (execute, options) => {
|
|
4134
|
-
await execute.command(
|
|
4135
|
-
_dumbo.SQL`TRUNCATE TABLE
|
|
4136
|
-
${_dumbo.SQL.identifier(streamsTable.name)},
|
|
4137
|
-
${_dumbo.SQL.identifier(messagesTable.name)},
|
|
4138
|
-
${_dumbo.SQL.identifier(processorsTable.name)},
|
|
4139
|
-
${_dumbo.SQL.identifier(projectionsTable.name)}
|
|
4140
|
-
CASCADE${_dumbo.SQL.plain(_optionalChain([options, 'optionalAccess', _65 => _65.resetSequences]) ? "; ALTER SEQUENCE emt_global_message_position RESTART WITH 1" : "")};`
|
|
4141
|
-
);
|
|
4142
|
-
};
|
|
4143
|
-
|
|
4144
|
-
// src/eventStore/postgreSQLEventStore.ts
|
|
4145
|
-
var defaultPostgreSQLOptions = {
|
|
4146
|
-
projections: [],
|
|
4147
|
-
schema: { autoMigration: "CreateOrUpdate" }
|
|
4148
|
-
};
|
|
4149
|
-
var PostgreSQLEventStoreDefaultStreamVersion = 0n;
|
|
4150
|
-
var getPostgreSQLEventStore = (connectionString, options = defaultPostgreSQLOptions) => {
|
|
4151
|
-
const poolOptions = {
|
|
4152
|
-
connectionString,
|
|
4153
|
-
...options.connectionOptions ? options.connectionOptions : {}
|
|
4154
|
-
};
|
|
4155
|
-
const pool = "dumbo" in poolOptions ? poolOptions.dumbo : _dumbo.dumbo.call(void 0, poolOptions);
|
|
4156
|
-
let migrateSchema = void 0;
|
|
4157
|
-
const autoGenerateSchema = _optionalChain([options, 'access', _66 => _66.schema, 'optionalAccess', _67 => _67.autoMigration]) === void 0 || _optionalChain([options, 'access', _68 => _68.schema, 'optionalAccess', _69 => _69.autoMigration]) !== "None";
|
|
4158
|
-
const inlineProjections = (_nullishCoalesce(options.projections, () => ( []))).filter(({ type }) => type === "inline").map(({ projection: projection2 }) => projection2);
|
|
4159
|
-
const migrate = async (migrationOptions) => {
|
|
4160
|
-
if (!migrateSchema) {
|
|
4161
|
-
migrateSchema = createEventStoreSchema(
|
|
4162
|
-
connectionString,
|
|
4163
|
-
pool,
|
|
4164
|
-
{
|
|
4165
|
-
onBeforeSchemaCreated: async (context) => {
|
|
4166
|
-
if (_optionalChain([options, 'access', _70 => _70.hooks, 'optionalAccess', _71 => _71.onBeforeSchemaCreated])) {
|
|
4167
|
-
await options.hooks.onBeforeSchemaCreated(context);
|
|
4168
|
-
}
|
|
4169
|
-
},
|
|
4170
|
-
onAfterSchemaCreated: async (context) => {
|
|
4171
|
-
for (const projection2 of inlineProjections) {
|
|
4172
|
-
if (projection2.init) {
|
|
4173
|
-
await projection2.init({
|
|
4174
|
-
version: _nullishCoalesce(projection2.version, () => ( 1)),
|
|
4175
|
-
status: "active",
|
|
4176
|
-
registrationType: "inline",
|
|
4177
|
-
context: { ...context, migrationOptions }
|
|
4178
|
-
});
|
|
4179
|
-
}
|
|
4180
|
-
}
|
|
4181
|
-
if (_optionalChain([options, 'access', _72 => _72.hooks, 'optionalAccess', _73 => _73.onAfterSchemaCreated])) {
|
|
4182
|
-
await options.hooks.onAfterSchemaCreated(context);
|
|
4183
|
-
}
|
|
4184
|
-
}
|
|
4185
|
-
},
|
|
4186
|
-
migrationOptions
|
|
4187
|
-
);
|
|
4188
|
-
}
|
|
4189
|
-
return migrateSchema;
|
|
4190
|
-
};
|
|
4191
|
-
const ensureSchemaExists = () => {
|
|
4192
|
-
if (!autoGenerateSchema) return Promise.resolve();
|
|
4193
|
-
return migrate();
|
|
4194
|
-
};
|
|
4195
|
-
const beforeCommitHook = inlineProjections.length > 0 ? async (events, { transaction }) => handleProjections({
|
|
4196
|
-
projections: inlineProjections,
|
|
4197
|
-
// TODO: Add proper handling of global data
|
|
4198
|
-
// Currently it's not available as append doesn't return array of global position but just the last one
|
|
4199
|
-
events,
|
|
4200
|
-
...await transactionToPostgreSQLProjectionHandlerContext(
|
|
4201
|
-
connectionString,
|
|
4202
|
-
pool,
|
|
4203
|
-
transaction
|
|
4204
|
-
)
|
|
4205
|
-
}) : void 0;
|
|
4206
|
-
return {
|
|
4207
|
-
schema: {
|
|
4208
|
-
sql: () => _dumbo.SQL.describe(
|
|
4209
|
-
schemaSQL,
|
|
4210
|
-
_dumbo.getFormatter.call(void 0, _dumbo.fromDatabaseDriverType.call(void 0, pool.driverType).databaseType)
|
|
4211
|
-
),
|
|
4212
|
-
print: () => console.log(
|
|
4213
|
-
_dumbo.SQL.describe(
|
|
4214
|
-
schemaSQL,
|
|
4215
|
-
_dumbo.getFormatter.call(void 0, _dumbo.fromDatabaseDriverType.call(void 0, pool.driverType).databaseType)
|
|
4216
|
-
)
|
|
4217
|
-
),
|
|
4218
|
-
migrate,
|
|
4219
|
-
dangerous: {
|
|
4220
|
-
truncate: (truncateOptions) => pool.withTransaction(async (transaction) => {
|
|
4221
|
-
await ensureSchemaExists();
|
|
4222
|
-
await truncateTables(transaction.execute, truncateOptions);
|
|
4223
|
-
if (_optionalChain([truncateOptions, 'optionalAccess', _74 => _74.truncateProjections])) {
|
|
4224
|
-
const projectionContext = await transactionToPostgreSQLProjectionHandlerContext(
|
|
4225
|
-
connectionString,
|
|
4226
|
-
pool,
|
|
4227
|
-
transaction
|
|
4228
|
-
);
|
|
4229
|
-
for (const projection2 of _nullishCoalesce(_optionalChain([options, 'optionalAccess', _75 => _75.projections]), () => ( []))) {
|
|
4230
|
-
if (projection2.projection.truncate)
|
|
4231
|
-
await projection2.projection.truncate(projectionContext);
|
|
4232
|
-
}
|
|
4233
|
-
}
|
|
4234
|
-
})
|
|
4235
|
-
}
|
|
4236
|
-
},
|
|
4237
|
-
async aggregateStream(streamName, options2) {
|
|
4238
|
-
const { evolve, initialState, read } = options2;
|
|
4239
|
-
const expectedStreamVersion = _optionalChain([read, 'optionalAccess', _76 => _76.expectedStreamVersion]);
|
|
4240
|
-
let state = initialState();
|
|
4241
|
-
const result = await this.readStream(
|
|
4242
|
-
streamName,
|
|
4243
|
-
read
|
|
4244
|
-
);
|
|
4245
|
-
const currentStreamVersion = result.currentStreamVersion;
|
|
4246
|
-
assertExpectedVersionMatchesCurrent(
|
|
4247
|
-
currentStreamVersion,
|
|
4248
|
-
expectedStreamVersion,
|
|
4249
|
-
PostgreSQLEventStoreDefaultStreamVersion
|
|
4250
|
-
);
|
|
4251
|
-
for (const event of result.events) {
|
|
4252
|
-
if (!event) continue;
|
|
4253
|
-
state = evolve(state, event);
|
|
4254
|
-
}
|
|
4255
|
-
return {
|
|
4256
|
-
currentStreamVersion,
|
|
4257
|
-
state,
|
|
4258
|
-
streamExists: result.streamExists
|
|
4259
|
-
};
|
|
4260
|
-
},
|
|
4261
|
-
readStream: async (streamName, options2) => {
|
|
4262
|
-
await ensureSchemaExists();
|
|
4263
|
-
return readStream(
|
|
4264
|
-
pool.execute,
|
|
4265
|
-
streamName,
|
|
4266
|
-
options2
|
|
4267
|
-
);
|
|
4268
|
-
},
|
|
4269
|
-
appendToStream: async (streamName, events, options2) => {
|
|
4270
|
-
await ensureSchemaExists();
|
|
4271
|
-
const [firstPart, ...rest] = streamName.split("-");
|
|
4272
|
-
const streamType = firstPart && rest.length > 0 ? firstPart : unknownTag;
|
|
4273
|
-
const appendResult = await appendToStream(
|
|
4274
|
-
// TODO: Fix this when introducing more drivers
|
|
4275
|
-
pool,
|
|
4276
|
-
streamName,
|
|
4277
|
-
streamType,
|
|
4278
|
-
downcastRecordedMessages(events, _optionalChain([options2, 'optionalAccess', _77 => _77.schema, 'optionalAccess', _78 => _78.versioning])),
|
|
4279
|
-
{
|
|
4280
|
-
...options2,
|
|
4281
|
-
beforeCommitHook
|
|
4282
|
-
}
|
|
4283
|
-
);
|
|
4284
|
-
if (!appendResult.success)
|
|
4285
|
-
throw new ExpectedVersionConflictError(
|
|
4286
|
-
-1n,
|
|
4287
|
-
//TODO: Return actual version in case of error
|
|
4288
|
-
_nullishCoalesce(_optionalChain([options2, 'optionalAccess', _79 => _79.expectedStreamVersion]), () => ( NO_CONCURRENCY_CHECK))
|
|
4289
|
-
);
|
|
4290
|
-
return {
|
|
4291
|
-
nextExpectedStreamVersion: appendResult.nextStreamPosition,
|
|
4292
|
-
lastEventGlobalPosition: appendResult.globalPositions[appendResult.globalPositions.length - 1],
|
|
4293
|
-
createdNewStream: appendResult.nextStreamPosition >= BigInt(events.length)
|
|
4294
|
-
};
|
|
4295
|
-
},
|
|
4296
|
-
streamExists: async (streamName, options2) => {
|
|
4297
|
-
await ensureSchemaExists();
|
|
4298
|
-
return streamExists(pool.execute, streamName, options2);
|
|
4299
|
-
},
|
|
4300
|
-
consumer: (options2) => postgreSQLEventStoreConsumer({
|
|
4301
|
-
..._nullishCoalesce(options2, () => ( {})),
|
|
4302
|
-
pool,
|
|
4303
|
-
connectionString
|
|
4304
|
-
}),
|
|
4305
|
-
close: () => pool.close(),
|
|
4306
|
-
async withSession(callback) {
|
|
4307
|
-
return await pool.withConnection(async (connection) => {
|
|
4308
|
-
const storeOptions = {
|
|
4309
|
-
...options,
|
|
4310
|
-
connectionOptions: {
|
|
4311
|
-
connection
|
|
4312
|
-
},
|
|
4313
|
-
schema: {
|
|
4314
|
-
..._nullishCoalesce(options.schema, () => ( {})),
|
|
4315
|
-
autoMigration: "None"
|
|
4316
|
-
}
|
|
4317
|
-
};
|
|
4318
|
-
const eventStore = getPostgreSQLEventStore(
|
|
4319
|
-
connectionString,
|
|
4320
|
-
storeOptions
|
|
4321
|
-
);
|
|
4322
|
-
return ensureSchemaExists().then(
|
|
4323
|
-
() => callback({
|
|
4324
|
-
eventStore,
|
|
4325
|
-
close: () => Promise.resolve()
|
|
4326
|
-
})
|
|
4327
|
-
);
|
|
4328
|
-
});
|
|
4329
|
-
}
|
|
4330
|
-
};
|
|
4331
|
-
};
|
|
4332
|
-
|
|
4333
|
-
// src/eventStore/projections/postgresProjectionSpec.ts
|
|
4334
|
-
var PostgreSQLProjectionSpec = {
|
|
4335
|
-
for: (options) => {
|
|
4336
|
-
{
|
|
4337
|
-
const { projection: projection2, ...dumoOptions } = options;
|
|
4338
|
-
const { connectionString } = dumoOptions;
|
|
4339
|
-
let wasInitialised = false;
|
|
4340
|
-
const initialize = async (pool) => {
|
|
4341
|
-
const eventStore = getPostgreSQLEventStore(connectionString, {
|
|
4342
|
-
// TODO: This will need to change when we support other drivers
|
|
4343
|
-
connectionOptions: { dumbo: pool }
|
|
4344
|
-
});
|
|
4345
|
-
if (wasInitialised) return;
|
|
4346
|
-
wasInitialised = true;
|
|
4347
|
-
await eventStore.schema.migrate();
|
|
4348
|
-
if (projection2.init)
|
|
4349
|
-
await pool.withTransaction(async (transaction) => {
|
|
4350
|
-
await projection2.init({
|
|
4351
|
-
registrationType: "async",
|
|
4352
|
-
version: _nullishCoalesce(projection2.version, () => ( 1)),
|
|
4353
|
-
status: "active",
|
|
4354
|
-
context: await transactionToPostgreSQLProjectionHandlerContext(
|
|
4355
|
-
connectionString,
|
|
4356
|
-
pool,
|
|
4357
|
-
transaction
|
|
4358
|
-
)
|
|
4359
|
-
});
|
|
4360
|
-
});
|
|
4622
|
+
};
|
|
4623
|
+
|
|
4624
|
+
// src/eventStore/schema/readStream.ts
|
|
4625
|
+
|
|
4626
|
+
var readStream = async (execute, streamId, options) => {
|
|
4627
|
+
const fromCondition = _optionalChain([options, 'optionalAccess', _83 => _83.from]) ? `AND stream_position >= ${options.from}` : "";
|
|
4628
|
+
const to = Number(
|
|
4629
|
+
_nullishCoalesce(_optionalChain([options, 'optionalAccess', _84 => _84.to]), () => ( (_optionalChain([options, 'optionalAccess', _85 => _85.maxCount]) ? (_nullishCoalesce(options.from, () => ( 0n))) + options.maxCount : NaN)))
|
|
4630
|
+
);
|
|
4631
|
+
const toCondition = !isNaN(to) ? `AND stream_position <= ${to}` : "";
|
|
4632
|
+
const events = await _dumbo.mapRows.call(void 0,
|
|
4633
|
+
execute.query(
|
|
4634
|
+
_dumbo.SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
|
|
4635
|
+
FROM ${_dumbo.SQL.identifier(messagesTable.name)}
|
|
4636
|
+
WHERE stream_id = ${streamId} AND partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _86 => _86.partition]), () => ( defaultTag2))} AND is_archived = FALSE ${_dumbo.SQL.plain(fromCondition)} ${_dumbo.SQL.plain(toCondition)}
|
|
4637
|
+
ORDER BY stream_position ASC`
|
|
4638
|
+
),
|
|
4639
|
+
(row) => {
|
|
4640
|
+
const rawEvent = {
|
|
4641
|
+
type: row.message_type,
|
|
4642
|
+
data: row.message_data,
|
|
4643
|
+
metadata: row.message_metadata
|
|
4361
4644
|
};
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
for (const event of [
|
|
4370
|
-
...givenEvents,
|
|
4371
|
-
...Array.from({ length: numberOfTimes }).flatMap(() => events)
|
|
4372
|
-
]) {
|
|
4373
|
-
const metadata = {
|
|
4374
|
-
globalPosition: ++globalPosition,
|
|
4375
|
-
streamPosition: globalPosition,
|
|
4376
|
-
streamName: `test-${_uuid.v4.call(void 0, )}`,
|
|
4377
|
-
messageId: _uuid.v4.call(void 0, )
|
|
4378
|
-
};
|
|
4379
|
-
allEvents.push({
|
|
4380
|
-
...event,
|
|
4381
|
-
kind: "Event",
|
|
4382
|
-
metadata: {
|
|
4383
|
-
...metadata,
|
|
4384
|
-
..."metadata" in event ? _nullishCoalesce(event.metadata, () => ( {})) : {}
|
|
4385
|
-
}
|
|
4386
|
-
});
|
|
4387
|
-
}
|
|
4388
|
-
await initialize(pool);
|
|
4389
|
-
await pool.withTransaction(async (transaction) => {
|
|
4390
|
-
await handleProjections({
|
|
4391
|
-
events: allEvents,
|
|
4392
|
-
projections: [projection2],
|
|
4393
|
-
...await transactionToPostgreSQLProjectionHandlerContext(
|
|
4394
|
-
connectionString,
|
|
4395
|
-
pool,
|
|
4396
|
-
transaction
|
|
4397
|
-
)
|
|
4398
|
-
});
|
|
4399
|
-
});
|
|
4400
|
-
};
|
|
4401
|
-
return {
|
|
4402
|
-
then: async (assert, message) => {
|
|
4403
|
-
const pool = _dumbo.dumbo.call(void 0, dumoOptions);
|
|
4404
|
-
try {
|
|
4405
|
-
await run(pool);
|
|
4406
|
-
const succeeded = await assert({ pool, connectionString });
|
|
4407
|
-
if (succeeded !== void 0 && succeeded === false)
|
|
4408
|
-
assertFails(
|
|
4409
|
-
_nullishCoalesce(message, () => ( "Projection specification didn't match the criteria"))
|
|
4410
|
-
);
|
|
4411
|
-
} finally {
|
|
4412
|
-
await pool.close();
|
|
4413
|
-
}
|
|
4414
|
-
},
|
|
4415
|
-
thenThrows: async (...args) => {
|
|
4416
|
-
const pool = _dumbo.dumbo.call(void 0, dumoOptions);
|
|
4417
|
-
try {
|
|
4418
|
-
await run(pool);
|
|
4419
|
-
throw new AssertionError("Handler did not fail as expected");
|
|
4420
|
-
} catch (error) {
|
|
4421
|
-
if (error instanceof AssertionError) throw error;
|
|
4422
|
-
if (args.length === 0) return;
|
|
4423
|
-
if (!isErrorConstructor(args[0])) {
|
|
4424
|
-
assertTrue(
|
|
4425
|
-
args[0](error),
|
|
4426
|
-
`Error didn't match the error condition: ${_optionalChain([error, 'optionalAccess', _81 => _81.toString, 'call', _82 => _82()])}`
|
|
4427
|
-
);
|
|
4428
|
-
return;
|
|
4429
|
-
}
|
|
4430
|
-
assertTrue(
|
|
4431
|
-
error instanceof args[0],
|
|
4432
|
-
`Caught error is not an instance of the expected type: ${_optionalChain([error, 'optionalAccess', _83 => _83.toString, 'call', _84 => _84()])}`
|
|
4433
|
-
);
|
|
4434
|
-
if (args[1]) {
|
|
4435
|
-
assertTrue(
|
|
4436
|
-
args[1](error),
|
|
4437
|
-
`Error didn't match the error condition: ${_optionalChain([error, 'optionalAccess', _85 => _85.toString, 'call', _86 => _86()])}`
|
|
4438
|
-
);
|
|
4439
|
-
}
|
|
4440
|
-
} finally {
|
|
4441
|
-
await pool.close();
|
|
4442
|
-
}
|
|
4443
|
-
}
|
|
4444
|
-
};
|
|
4445
|
-
}
|
|
4446
|
-
};
|
|
4645
|
+
const metadata = {
|
|
4646
|
+
..."metadata" in rawEvent ? _nullishCoalesce(rawEvent.metadata, () => ( {})) : {},
|
|
4647
|
+
messageId: row.message_id,
|
|
4648
|
+
streamName: streamId,
|
|
4649
|
+
streamPosition: BigInt(row.stream_position),
|
|
4650
|
+
globalPosition: BigInt(row.global_position),
|
|
4651
|
+
checkpoint: bigIntProcessorCheckpoint(BigInt(row.global_position))
|
|
4447
4652
|
};
|
|
4653
|
+
const event = {
|
|
4654
|
+
...rawEvent,
|
|
4655
|
+
kind: "Event",
|
|
4656
|
+
metadata
|
|
4657
|
+
};
|
|
4658
|
+
return upcastRecordedMessage(event, _optionalChain([options, 'optionalAccess', _87 => _87.schema, 'optionalAccess', _88 => _88.versioning]));
|
|
4448
4659
|
}
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4660
|
+
);
|
|
4661
|
+
return events.length > 0 ? {
|
|
4662
|
+
currentStreamVersion: events[events.length - 1].metadata.streamPosition,
|
|
4663
|
+
events,
|
|
4664
|
+
streamExists: true
|
|
4665
|
+
} : {
|
|
4666
|
+
currentStreamVersion: PostgreSQLEventStoreDefaultStreamVersion,
|
|
4667
|
+
events: [],
|
|
4668
|
+
streamExists: false
|
|
4458
4669
|
};
|
|
4459
4670
|
};
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
var
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4671
|
+
|
|
4672
|
+
// src/eventStore/schema/streamExists.ts
|
|
4673
|
+
|
|
4674
|
+
var streamExists = async (execute, streamId, options) => {
|
|
4675
|
+
const queryResult = await execute.query(
|
|
4676
|
+
_dumbo.SQL`SELECT EXISTS (
|
|
4677
|
+
SELECT 1
|
|
4678
|
+
from ${_dumbo.SQL.identifier(streamsTable.name)}
|
|
4679
|
+
WHERE stream_id = ${streamId} AND partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _89 => _89.partition]), () => ( defaultTag2))} AND is_archived = FALSE)
|
|
4680
|
+
`
|
|
4681
|
+
);
|
|
4682
|
+
return _nullishCoalesce(_optionalChain([queryResult, 'access', _90 => _90.rows, 'access', _91 => _91[0], 'optionalAccess', _92 => _92.exists]), () => ( false));
|
|
4467
4683
|
};
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4684
|
+
|
|
4685
|
+
// src/eventStore/schema/index.ts
|
|
4686
|
+
var schemaSQL = [
|
|
4687
|
+
streamsTableSQL,
|
|
4688
|
+
messagesTableSQL,
|
|
4689
|
+
projectionsTableSQL,
|
|
4690
|
+
processorsTableSQL,
|
|
4691
|
+
sanitizeNameSQL,
|
|
4692
|
+
addTablePartitions,
|
|
4693
|
+
addPartitionSQL,
|
|
4694
|
+
appendToStreamSQL,
|
|
4695
|
+
addDefaultPartitionSQL,
|
|
4696
|
+
storeSubscriptionCheckpointSQL,
|
|
4697
|
+
tryAcquireProcessorLockSQL,
|
|
4698
|
+
releaseProcessorLockSQL,
|
|
4699
|
+
registerProjectionSQL,
|
|
4700
|
+
activateProjectionSQL,
|
|
4701
|
+
deactivateProjectionSQL
|
|
4702
|
+
];
|
|
4703
|
+
var schemaMigration = _dumbo.sqlMigration.call(void 0,
|
|
4704
|
+
"emt:postgresql:eventstore:initial",
|
|
4705
|
+
schemaSQL
|
|
4706
|
+
);
|
|
4707
|
+
var eventStoreSchemaMigrations = [
|
|
4708
|
+
migration_0_38_7_and_older,
|
|
4709
|
+
migration_0_42_0_FromSubscriptionsToProcessors,
|
|
4710
|
+
migration_0_42_0_2_AddProcessorProjectionFunctions,
|
|
4711
|
+
schemaMigration
|
|
4712
|
+
];
|
|
4713
|
+
var createEventStoreSchema = (connectionString, pool, hooks, options) => {
|
|
4714
|
+
return pool.withTransaction(async (tx) => {
|
|
4715
|
+
const context = await transactionToPostgreSQLProjectionHandlerContext(
|
|
4716
|
+
connectionString,
|
|
4717
|
+
pool,
|
|
4718
|
+
tx
|
|
4719
|
+
);
|
|
4720
|
+
const nestedPool = _dumbo.dumbo.call(void 0, {
|
|
4721
|
+
connectionString,
|
|
4722
|
+
connection: tx.connection,
|
|
4723
|
+
serialization: _optionalChain([options, 'optionalAccess', _93 => _93.serialization])
|
|
4724
|
+
});
|
|
4725
|
+
try {
|
|
4726
|
+
if (_optionalChain([hooks, 'optionalAccess', _94 => _94.onBeforeSchemaCreated])) {
|
|
4727
|
+
await hooks.onBeforeSchemaCreated(context);
|
|
4728
|
+
}
|
|
4729
|
+
const result = await _dumbo.runSQLMigrations.call(void 0,
|
|
4730
|
+
nestedPool,
|
|
4731
|
+
eventStoreSchemaMigrations,
|
|
4732
|
+
options
|
|
4733
|
+
);
|
|
4734
|
+
if (_optionalChain([hooks, 'optionalAccess', _95 => _95.onAfterSchemaCreated])) {
|
|
4735
|
+
await hooks.onAfterSchemaCreated(context);
|
|
4736
|
+
}
|
|
4737
|
+
return result;
|
|
4738
|
+
} finally {
|
|
4739
|
+
await nestedPool.close();
|
|
4472
4740
|
}
|
|
4473
|
-
})
|
|
4741
|
+
});
|
|
4474
4742
|
};
|
|
4475
4743
|
|
|
4476
|
-
// src/eventStore/
|
|
4744
|
+
// src/eventStore/schema/truncateTables.ts
|
|
4477
4745
|
|
|
4746
|
+
var truncateTables = async (execute, options) => {
|
|
4747
|
+
await execute.command(
|
|
4748
|
+
_dumbo.SQL`TRUNCATE TABLE
|
|
4749
|
+
${_dumbo.SQL.identifier(streamsTable.name)},
|
|
4750
|
+
${_dumbo.SQL.identifier(messagesTable.name)},
|
|
4751
|
+
${_dumbo.SQL.identifier(processorsTable.name)},
|
|
4752
|
+
${_dumbo.SQL.identifier(projectionsTable.name)}
|
|
4753
|
+
CASCADE${_dumbo.SQL.plain(_optionalChain([options, 'optionalAccess', _96 => _96.resetSequences]) ? "; ALTER SEQUENCE emt_global_message_position RESTART WITH 1" : "")};`
|
|
4754
|
+
);
|
|
4755
|
+
};
|
|
4478
4756
|
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4757
|
+
// src/eventStore/postgreSQLEventStore.ts
|
|
4758
|
+
var defaultPostgreSQLOptions = {
|
|
4759
|
+
projections: [],
|
|
4760
|
+
schema: { autoMigration: "CreateOrUpdate" }
|
|
4761
|
+
};
|
|
4762
|
+
var PostgreSQLEventStoreDefaultStreamVersion = 0n;
|
|
4763
|
+
var getPostgreSQLEventStore = (connectionString, options = defaultPostgreSQLOptions) => {
|
|
4764
|
+
const poolOptions = {
|
|
4482
4765
|
connectionString,
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
const {
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
connection: { pool, transaction, connectionString },
|
|
4493
|
-
partition = defaultTag
|
|
4494
|
-
} = options;
|
|
4495
|
-
const eventTypes = events.map((e) => e.type);
|
|
4496
|
-
const projections = allProjections.filter(
|
|
4497
|
-
(p) => p.canHandle.some((type) => eventTypes.includes(type))
|
|
4498
|
-
);
|
|
4499
|
-
const client = await transaction.connection.open();
|
|
4500
|
-
for (const projection2 of projections) {
|
|
4501
|
-
if (projection2.name) {
|
|
4502
|
-
const lockAcquired = await postgreSQLProjectionLock({
|
|
4503
|
-
projectionName: projection2.name,
|
|
4504
|
-
partition,
|
|
4505
|
-
version: _nullishCoalesce(projection2.version, () => ( 1))
|
|
4506
|
-
}).tryAcquire({ execute: transaction.execute });
|
|
4507
|
-
if (!lockAcquired) {
|
|
4508
|
-
continue;
|
|
4509
|
-
}
|
|
4510
|
-
}
|
|
4511
|
-
await projection2.handle(events, {
|
|
4512
|
-
connection: {
|
|
4766
|
+
...options.connectionOptions ? options.connectionOptions : {}
|
|
4767
|
+
};
|
|
4768
|
+
const pool = "dumbo" in poolOptions ? poolOptions.dumbo : _dumbo.dumbo.call(void 0, { ...poolOptions, serialization: options.serialization });
|
|
4769
|
+
let migrateSchema = void 0;
|
|
4770
|
+
const autoGenerateSchema = _optionalChain([options, 'access', _97 => _97.schema, 'optionalAccess', _98 => _98.autoMigration]) === void 0 || _optionalChain([options, 'access', _99 => _99.schema, 'optionalAccess', _100 => _100.autoMigration]) !== "None";
|
|
4771
|
+
const inlineProjections = (_nullishCoalesce(options.projections, () => ( []))).filter(({ type }) => type === "inline").map(({ projection: projection2 }) => projection2);
|
|
4772
|
+
const migrate = async (migrationOptions) => {
|
|
4773
|
+
if (!migrateSchema) {
|
|
4774
|
+
migrateSchema = createEventStoreSchema(
|
|
4513
4775
|
connectionString,
|
|
4514
4776
|
pool,
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4777
|
+
{
|
|
4778
|
+
onBeforeSchemaCreated: async (context) => {
|
|
4779
|
+
if (_optionalChain([options, 'access', _101 => _101.hooks, 'optionalAccess', _102 => _102.onBeforeSchemaCreated])) {
|
|
4780
|
+
await options.hooks.onBeforeSchemaCreated(context);
|
|
4781
|
+
}
|
|
4782
|
+
},
|
|
4783
|
+
onAfterSchemaCreated: async (context) => {
|
|
4784
|
+
for (const projection2 of inlineProjections) {
|
|
4785
|
+
if (projection2.init) {
|
|
4786
|
+
await projection2.init({
|
|
4787
|
+
version: _nullishCoalesce(projection2.version, () => ( 1)),
|
|
4788
|
+
status: "active",
|
|
4789
|
+
registrationType: "inline",
|
|
4790
|
+
context: { ...context, migrationOptions }
|
|
4791
|
+
});
|
|
4792
|
+
}
|
|
4793
|
+
}
|
|
4794
|
+
if (_optionalChain([options, 'access', _103 => _103.hooks, 'optionalAccess', _104 => _104.onAfterSchemaCreated])) {
|
|
4795
|
+
await options.hooks.onAfterSchemaCreated(context);
|
|
4796
|
+
}
|
|
4797
|
+
}
|
|
4798
|
+
},
|
|
4799
|
+
migrationOptions
|
|
4800
|
+
);
|
|
4538
4801
|
}
|
|
4539
|
-
|
|
4540
|
-
}
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4802
|
+
return migrateSchema;
|
|
4803
|
+
};
|
|
4804
|
+
const ensureSchemaExists = () => {
|
|
4805
|
+
if (!autoGenerateSchema) return Promise.resolve();
|
|
4806
|
+
return migrate();
|
|
4807
|
+
};
|
|
4808
|
+
const beforeCommitHook = inlineProjections.length > 0 ? async (events, { transaction }) => handleProjections({
|
|
4809
|
+
projections: inlineProjections,
|
|
4810
|
+
// TODO: Add proper handling of global data
|
|
4811
|
+
// Currently it's not available as append doesn't return array of global position but just the last one
|
|
4812
|
+
events,
|
|
4813
|
+
...await transactionToPostgreSQLProjectionHandlerContext(
|
|
4814
|
+
connectionString,
|
|
4815
|
+
pool,
|
|
4816
|
+
transaction
|
|
4817
|
+
)
|
|
4818
|
+
}) : void 0;
|
|
4819
|
+
return {
|
|
4820
|
+
schema: {
|
|
4821
|
+
sql: () => _dumbo.SQL.describe(
|
|
4822
|
+
schemaSQL,
|
|
4823
|
+
_dumbo.getFormatter.call(void 0, _dumbo.fromDatabaseDriverType.call(void 0, pool.driverType).databaseType)
|
|
4824
|
+
),
|
|
4825
|
+
print: () => console.log(
|
|
4826
|
+
_dumbo.SQL.describe(
|
|
4827
|
+
schemaSQL,
|
|
4828
|
+
_dumbo.getFormatter.call(void 0, _dumbo.fromDatabaseDriverType.call(void 0, pool.driverType).databaseType)
|
|
4829
|
+
)
|
|
4830
|
+
),
|
|
4831
|
+
migrate,
|
|
4832
|
+
dangerous: {
|
|
4833
|
+
truncate: (truncateOptions) => pool.withTransaction(async (transaction) => {
|
|
4834
|
+
await ensureSchemaExists();
|
|
4835
|
+
await truncateTables(transaction.execute, truncateOptions);
|
|
4836
|
+
if (_optionalChain([truncateOptions, 'optionalAccess', _105 => _105.truncateProjections])) {
|
|
4837
|
+
const projectionContext = await transactionToPostgreSQLProjectionHandlerContext(
|
|
4838
|
+
connectionString,
|
|
4839
|
+
pool,
|
|
4840
|
+
transaction
|
|
4841
|
+
);
|
|
4842
|
+
for (const projection2 of _nullishCoalesce(_optionalChain([options, 'optionalAccess', _106 => _106.projections]), () => ( []))) {
|
|
4843
|
+
if (projection2.projection.truncate)
|
|
4844
|
+
await projection2.projection.truncate(projectionContext);
|
|
4845
|
+
}
|
|
4846
|
+
}
|
|
4847
|
+
})
|
|
4558
4848
|
}
|
|
4559
|
-
}
|
|
4560
|
-
|
|
4561
|
-
}
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
const
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4849
|
+
},
|
|
4850
|
+
async aggregateStream(streamName, options2) {
|
|
4851
|
+
const { evolve, initialState, read } = options2;
|
|
4852
|
+
const expectedStreamVersion = _optionalChain([read, 'optionalAccess', _107 => _107.expectedStreamVersion]);
|
|
4853
|
+
let state = initialState();
|
|
4854
|
+
const result = await this.readStream(
|
|
4855
|
+
streamName,
|
|
4856
|
+
read
|
|
4857
|
+
);
|
|
4858
|
+
const currentStreamVersion = result.currentStreamVersion;
|
|
4859
|
+
assertExpectedVersionMatchesCurrent(
|
|
4860
|
+
currentStreamVersion,
|
|
4861
|
+
expectedStreamVersion,
|
|
4862
|
+
PostgreSQLEventStoreDefaultStreamVersion
|
|
4863
|
+
);
|
|
4864
|
+
for (const event of result.events) {
|
|
4865
|
+
if (!event) continue;
|
|
4866
|
+
state = evolve(state, event);
|
|
4576
4867
|
}
|
|
4577
|
-
return
|
|
4868
|
+
return {
|
|
4869
|
+
currentStreamVersion,
|
|
4870
|
+
state,
|
|
4871
|
+
streamExists: result.streamExists
|
|
4872
|
+
};
|
|
4873
|
+
},
|
|
4874
|
+
readStream: async (streamName, readOptions) => {
|
|
4875
|
+
await ensureSchemaExists();
|
|
4876
|
+
return readStream(pool.execute, streamName, {
|
|
4877
|
+
...readOptions,
|
|
4878
|
+
serialization: _nullishCoalesce(options.serialization, () => ( _optionalChain([readOptions, 'optionalAccess', _108 => _108.serialization])))
|
|
4879
|
+
});
|
|
4880
|
+
},
|
|
4881
|
+
appendToStream: async (streamName, events, appendOptions) => {
|
|
4882
|
+
await ensureSchemaExists();
|
|
4883
|
+
const [firstPart, ...rest] = streamName.split("-");
|
|
4884
|
+
const streamType = firstPart && rest.length > 0 ? firstPart : unknownTag2;
|
|
4885
|
+
const appendResult = await appendToStream(
|
|
4886
|
+
// TODO: Fix this when introducing more drivers
|
|
4887
|
+
pool,
|
|
4888
|
+
streamName,
|
|
4889
|
+
streamType,
|
|
4890
|
+
downcastRecordedMessages(events, _optionalChain([appendOptions, 'optionalAccess', _109 => _109.schema, 'optionalAccess', _110 => _110.versioning])),
|
|
4891
|
+
{
|
|
4892
|
+
...appendOptions,
|
|
4893
|
+
beforeCommitHook
|
|
4894
|
+
}
|
|
4895
|
+
);
|
|
4896
|
+
if (!appendResult.success)
|
|
4897
|
+
throw new ExpectedVersionConflictError(
|
|
4898
|
+
-1n,
|
|
4899
|
+
//TODO: Return actual version in case of error
|
|
4900
|
+
_nullishCoalesce(_optionalChain([appendOptions, 'optionalAccess', _111 => _111.expectedStreamVersion]), () => ( NO_CONCURRENCY_CHECK))
|
|
4901
|
+
);
|
|
4902
|
+
return {
|
|
4903
|
+
nextExpectedStreamVersion: appendResult.nextStreamPosition,
|
|
4904
|
+
lastEventGlobalPosition: appendResult.globalPositions[appendResult.globalPositions.length - 1],
|
|
4905
|
+
createdNewStream: appendResult.nextStreamPosition >= BigInt(events.length)
|
|
4906
|
+
};
|
|
4907
|
+
},
|
|
4908
|
+
streamExists: async (streamName, options2) => {
|
|
4909
|
+
await ensureSchemaExists();
|
|
4910
|
+
return streamExists(pool.execute, streamName, options2);
|
|
4911
|
+
},
|
|
4912
|
+
consumer: (options2) => postgreSQLEventStoreConsumer({
|
|
4913
|
+
..._nullishCoalesce(options2, () => ( {})),
|
|
4914
|
+
pool,
|
|
4915
|
+
connectionString
|
|
4916
|
+
}),
|
|
4917
|
+
close: () => pool.close(),
|
|
4918
|
+
async withSession(callback) {
|
|
4919
|
+
return await pool.withConnection(async (connection) => {
|
|
4920
|
+
const storeOptions = {
|
|
4921
|
+
...options,
|
|
4922
|
+
connectionOptions: {
|
|
4923
|
+
connection
|
|
4924
|
+
},
|
|
4925
|
+
schema: {
|
|
4926
|
+
..._nullishCoalesce(options.schema, () => ( {})),
|
|
4927
|
+
autoMigration: "None"
|
|
4928
|
+
}
|
|
4929
|
+
};
|
|
4930
|
+
const eventStore = getPostgreSQLEventStore(
|
|
4931
|
+
connectionString,
|
|
4932
|
+
storeOptions
|
|
4933
|
+
);
|
|
4934
|
+
return ensureSchemaExists().then(
|
|
4935
|
+
() => callback({
|
|
4936
|
+
eventStore,
|
|
4937
|
+
close: () => Promise.resolve()
|
|
4938
|
+
})
|
|
4939
|
+
);
|
|
4940
|
+
});
|
|
4578
4941
|
}
|
|
4579
|
-
}
|
|
4942
|
+
};
|
|
4580
4943
|
};
|
|
4581
4944
|
|
|
4582
4945
|
// src/eventStore/consumers/postgreSQLProcessor.ts
|
|
4583
4946
|
var postgreSQLCheckpointer = () => ({
|
|
4584
4947
|
read: async (options, context) => {
|
|
4585
4948
|
const result = await readProcessorCheckpoint(context.execute, options);
|
|
4586
|
-
return { lastCheckpoint: _optionalChain([result, 'optionalAccess',
|
|
4949
|
+
return { lastCheckpoint: _optionalChain([result, 'optionalAccess', _112 => _112.lastProcessedCheckpoint]) };
|
|
4587
4950
|
},
|
|
4588
4951
|
store: async (options, context) => {
|
|
4589
|
-
const
|
|
4952
|
+
const newCheckpoint = getCheckpoint(options.message);
|
|
4590
4953
|
const result = await storeProcessorCheckpoint(context.execute, {
|
|
4591
4954
|
lastProcessedCheckpoint: options.lastCheckpoint,
|
|
4592
|
-
newCheckpoint
|
|
4955
|
+
newCheckpoint,
|
|
4593
4956
|
processorId: options.processorId,
|
|
4594
4957
|
partition: options.partition,
|
|
4595
4958
|
version: options.version
|
|
@@ -4601,13 +4964,13 @@ var postgreSQLProcessingScope = (options) => {
|
|
|
4601
4964
|
const processorConnectionString = options.connectionString;
|
|
4602
4965
|
const processorPool = options.pool;
|
|
4603
4966
|
const processingScope = async (handler, partialContext) => {
|
|
4604
|
-
const connection = _optionalChain([partialContext, 'optionalAccess',
|
|
4605
|
-
const connectionString = _nullishCoalesce(processorConnectionString, () => ( _optionalChain([connection, 'optionalAccess',
|
|
4967
|
+
const connection = _optionalChain([partialContext, 'optionalAccess', _113 => _113.connection]);
|
|
4968
|
+
const connectionString = _nullishCoalesce(processorConnectionString, () => ( _optionalChain([connection, 'optionalAccess', _114 => _114.connectionString])));
|
|
4606
4969
|
if (!connectionString)
|
|
4607
4970
|
throw new EmmettError(
|
|
4608
4971
|
`PostgreSQL processor '${options.processorId}' is missing connection string. Ensure that you passed it through options`
|
|
4609
4972
|
);
|
|
4610
|
-
const pool = _nullishCoalesce((!processorConnectionString || connectionString == processorConnectionString ? _optionalChain([connection, 'optionalAccess',
|
|
4973
|
+
const pool = _nullishCoalesce((!processorConnectionString || connectionString == processorConnectionString ? _optionalChain([connection, 'optionalAccess', _115 => _115.pool]) : processorPool), () => ( processorPool));
|
|
4611
4974
|
if (!pool)
|
|
4612
4975
|
throw new EmmettError(
|
|
4613
4976
|
`PostgreSQL processor '${options.processorId}' is missing connection string. Ensure that you passed it through options`
|
|
@@ -4622,7 +4985,10 @@ var postgreSQLProcessingScope = (options) => {
|
|
|
4622
4985
|
connectionString,
|
|
4623
4986
|
pool,
|
|
4624
4987
|
client,
|
|
4625
|
-
transaction
|
|
4988
|
+
transaction,
|
|
4989
|
+
messageStore: getPostgreSQLEventStore(connectionString, {
|
|
4990
|
+
connectionOptions: { client }
|
|
4991
|
+
})
|
|
4626
4992
|
}
|
|
4627
4993
|
});
|
|
4628
4994
|
});
|
|
@@ -4636,7 +5002,8 @@ var getProcessorPool = (options) => {
|
|
|
4636
5002
|
const processorConnectionString = "connectionString" in poolOptions ? _nullishCoalesce(poolOptions.connectionString, () => ( null)) : null;
|
|
4637
5003
|
const processorPool = "dumbo" in poolOptions ? poolOptions.dumbo : processorConnectionString ? _dumbo.dumbo.call(void 0, {
|
|
4638
5004
|
connectionString: processorConnectionString,
|
|
4639
|
-
...poolOptions
|
|
5005
|
+
...poolOptions,
|
|
5006
|
+
serialization: options.serialization
|
|
4640
5007
|
}) : null;
|
|
4641
5008
|
return {
|
|
4642
5009
|
pool: processorPool,
|
|
@@ -4648,11 +5015,11 @@ var wrapHooksWithProcessorLocks = (hooks, processorLock) => ({
|
|
|
4648
5015
|
..._nullishCoalesce(hooks, () => ( {})),
|
|
4649
5016
|
onStart: async (context) => {
|
|
4650
5017
|
await processorLock.tryAcquire({ execute: context.execute });
|
|
4651
|
-
if (_optionalChain([hooks, 'optionalAccess',
|
|
5018
|
+
if (_optionalChain([hooks, 'optionalAccess', _116 => _116.onStart])) await hooks.onStart(context);
|
|
4652
5019
|
},
|
|
4653
|
-
onClose: _optionalChain([hooks, 'optionalAccess',
|
|
5020
|
+
onClose: _optionalChain([hooks, 'optionalAccess', _117 => _117.onClose]) || processorLock ? async (context) => {
|
|
4654
5021
|
await processorLock.release({ execute: context.execute });
|
|
4655
|
-
if (_optionalChain([hooks, 'optionalAccess',
|
|
5022
|
+
if (_optionalChain([hooks, 'optionalAccess', _118 => _118.onClose])) await hooks.onClose(context);
|
|
4656
5023
|
} : void 0
|
|
4657
5024
|
});
|
|
4658
5025
|
var postgreSQLProjector = (options) => {
|
|
@@ -4663,8 +5030,7 @@ var postgreSQLProjector = (options) => {
|
|
|
4663
5030
|
processorInstanceId = getProcessorInstanceId(processorId),
|
|
4664
5031
|
version = defaultProcessorVersion,
|
|
4665
5032
|
partition = defaultProcessorPartition,
|
|
4666
|
-
|
|
4667
|
-
lockTimeoutSeconds
|
|
5033
|
+
lock
|
|
4668
5034
|
} = options;
|
|
4669
5035
|
const { pool, connectionString, close } = getProcessorPool(options);
|
|
4670
5036
|
const processorLock = postgreSQLProcessorLock({
|
|
@@ -4673,18 +5039,18 @@ var postgreSQLProjector = (options) => {
|
|
|
4673
5039
|
partition,
|
|
4674
5040
|
processorInstanceId,
|
|
4675
5041
|
projection: options.projection ? {
|
|
4676
|
-
name: _nullishCoalesce(options.projection.name, () => (
|
|
4677
|
-
kind: _nullishCoalesce(options.projection.kind, () => (
|
|
5042
|
+
name: _nullishCoalesce(options.projection.name, () => ( unknownTag)),
|
|
5043
|
+
kind: _nullishCoalesce(options.projection.kind, () => ( unknownTag)),
|
|
4678
5044
|
version: _nullishCoalesce(options.projection.version, () => ( version)),
|
|
4679
5045
|
handlingType: "async"
|
|
4680
5046
|
} : void 0,
|
|
4681
|
-
|
|
4682
|
-
lockTimeoutSeconds
|
|
5047
|
+
lockAcquisitionPolicy: _nullishCoalesce(_optionalChain([lock, 'optionalAccess', _119 => _119.acquisitionPolicy]), () => ( DefaultPostgreSQLProcessorLockPolicy)),
|
|
5048
|
+
lockTimeoutSeconds: _optionalChain([lock, 'optionalAccess', _120 => _120.timeoutSeconds])
|
|
4683
5049
|
});
|
|
4684
5050
|
const hooks = wrapHooksWithProcessorLocks(
|
|
4685
5051
|
{
|
|
4686
5052
|
..._nullishCoalesce(options.hooks, () => ( {})),
|
|
4687
|
-
onInit: options.projection.init !== void 0 || _optionalChain([options, 'access',
|
|
5053
|
+
onInit: options.projection.init !== void 0 || _optionalChain([options, 'access', _121 => _121.hooks, 'optionalAccess', _122 => _122.onInit]) ? async (context) => {
|
|
4688
5054
|
if (options.projection.init)
|
|
4689
5055
|
await options.projection.init({
|
|
4690
5056
|
version: _nullishCoalesce(options.projection.version, () => ( version)),
|
|
@@ -4695,16 +5061,16 @@ var postgreSQLProjector = (options) => {
|
|
|
4695
5061
|
migrationOptions: options.migrationOptions
|
|
4696
5062
|
}
|
|
4697
5063
|
});
|
|
4698
|
-
if (_optionalChain([options, 'access',
|
|
5064
|
+
if (_optionalChain([options, 'access', _123 => _123.hooks, 'optionalAccess', _124 => _124.onInit]))
|
|
4699
5065
|
await options.hooks.onInit({
|
|
4700
5066
|
...context,
|
|
4701
5067
|
migrationOptions: options.migrationOptions
|
|
4702
5068
|
});
|
|
4703
|
-
} : _optionalChain([options, 'access',
|
|
5069
|
+
} : _optionalChain([options, 'access', _125 => _125.hooks, 'optionalAccess', _126 => _126.onInit]),
|
|
4704
5070
|
onClose: close ? async (context) => {
|
|
4705
|
-
if (_optionalChain([options, 'access',
|
|
5071
|
+
if (_optionalChain([options, 'access', _127 => _127.hooks, 'optionalAccess', _128 => _128.onClose])) await _optionalChain([options, 'access', _129 => _129.hooks, 'optionalAccess', _130 => _130.onClose, 'call', _131 => _131(context)]);
|
|
4706
5072
|
if (close) await close();
|
|
4707
|
-
} : _optionalChain([options, 'access',
|
|
5073
|
+
} : _optionalChain([options, 'access', _132 => _132.hooks, 'optionalAccess', _133 => _133.onClose])
|
|
4708
5074
|
},
|
|
4709
5075
|
processorLock
|
|
4710
5076
|
);
|
|
@@ -4725,13 +5091,60 @@ var postgreSQLProjector = (options) => {
|
|
|
4725
5091
|
});
|
|
4726
5092
|
return processor;
|
|
4727
5093
|
};
|
|
5094
|
+
var postgreSQLWorkflowProcessor = (options) => {
|
|
5095
|
+
const {
|
|
5096
|
+
processorId = _nullishCoalesce(options.processorId, () => ( getWorkflowId({
|
|
5097
|
+
workflowName: _nullishCoalesce(options.workflow.name, () => ( "unknown"))
|
|
5098
|
+
}))),
|
|
5099
|
+
processorInstanceId = getProcessorInstanceId(processorId),
|
|
5100
|
+
version = defaultProcessorVersion,
|
|
5101
|
+
partition = defaultProcessorPartition,
|
|
5102
|
+
lock
|
|
5103
|
+
} = options;
|
|
5104
|
+
const { pool, connectionString, close } = getProcessorPool(options);
|
|
5105
|
+
const processorLock = postgreSQLProcessorLock({
|
|
5106
|
+
processorId,
|
|
5107
|
+
version,
|
|
5108
|
+
partition,
|
|
5109
|
+
processorInstanceId,
|
|
5110
|
+
projection: void 0,
|
|
5111
|
+
lockAcquisitionPolicy: _nullishCoalesce(_optionalChain([lock, 'optionalAccess', _134 => _134.acquisitionPolicy]), () => ( DefaultPostgreSQLProcessorLockPolicy)),
|
|
5112
|
+
lockTimeoutSeconds: _optionalChain([lock, 'optionalAccess', _135 => _135.timeoutSeconds])
|
|
5113
|
+
});
|
|
5114
|
+
const hooks = wrapHooksWithProcessorLocks(
|
|
5115
|
+
{
|
|
5116
|
+
..._nullishCoalesce(options.hooks, () => ( {})),
|
|
5117
|
+
onClose: close ? async (context) => {
|
|
5118
|
+
if (_optionalChain([options, 'access', _136 => _136.hooks, 'optionalAccess', _137 => _137.onClose]))
|
|
5119
|
+
await _optionalChain([options, 'access', _138 => _138.hooks, 'optionalAccess', _139 => _139.onClose, 'call', _140 => _140(context)]);
|
|
5120
|
+
if (close) await close();
|
|
5121
|
+
} : _optionalChain([options, 'access', _141 => _141.hooks, 'optionalAccess', _142 => _142.onClose])
|
|
5122
|
+
},
|
|
5123
|
+
processorLock
|
|
5124
|
+
);
|
|
5125
|
+
return workflowProcessor({
|
|
5126
|
+
...options,
|
|
5127
|
+
processorId,
|
|
5128
|
+
processorInstanceId,
|
|
5129
|
+
version,
|
|
5130
|
+
partition,
|
|
5131
|
+
hooks,
|
|
5132
|
+
processingScope: postgreSQLProcessingScope({
|
|
5133
|
+
pool,
|
|
5134
|
+
connectionString,
|
|
5135
|
+
processorId,
|
|
5136
|
+
partition
|
|
5137
|
+
}),
|
|
5138
|
+
checkpoints: postgreSQLCheckpointer()
|
|
5139
|
+
});
|
|
5140
|
+
};
|
|
4728
5141
|
var postgreSQLReactor = (options) => {
|
|
4729
5142
|
const {
|
|
4730
5143
|
processorId = options.processorId,
|
|
4731
5144
|
processorInstanceId = getProcessorInstanceId(processorId),
|
|
4732
5145
|
version = defaultProcessorVersion,
|
|
4733
5146
|
partition = defaultProcessorPartition,
|
|
4734
|
-
|
|
5147
|
+
lock
|
|
4735
5148
|
} = options;
|
|
4736
5149
|
const { pool, connectionString, close } = getProcessorPool(options);
|
|
4737
5150
|
const processorLock = postgreSQLProcessorLock({
|
|
@@ -4740,15 +5153,16 @@ var postgreSQLReactor = (options) => {
|
|
|
4740
5153
|
partition,
|
|
4741
5154
|
processorInstanceId,
|
|
4742
5155
|
projection: void 0,
|
|
4743
|
-
|
|
5156
|
+
lockAcquisitionPolicy: _nullishCoalesce(_optionalChain([lock, 'optionalAccess', _143 => _143.acquisitionPolicy]), () => ( DefaultPostgreSQLProcessorLockPolicy)),
|
|
5157
|
+
lockTimeoutSeconds: _optionalChain([lock, 'optionalAccess', _144 => _144.timeoutSeconds])
|
|
4744
5158
|
});
|
|
4745
5159
|
const hooks = wrapHooksWithProcessorLocks(
|
|
4746
5160
|
{
|
|
4747
5161
|
..._nullishCoalesce(options.hooks, () => ( {})),
|
|
4748
5162
|
onClose: close ? async (context) => {
|
|
4749
|
-
if (_optionalChain([options, 'access',
|
|
5163
|
+
if (_optionalChain([options, 'access', _145 => _145.hooks, 'optionalAccess', _146 => _146.onClose])) await _optionalChain([options, 'access', _147 => _147.hooks, 'optionalAccess', _148 => _148.onClose, 'call', _149 => _149(context)]);
|
|
4750
5164
|
if (close) await close();
|
|
4751
|
-
} : _optionalChain([options, 'access',
|
|
5165
|
+
} : _optionalChain([options, 'access', _150 => _150.hooks, 'optionalAccess', _151 => _151.onClose])
|
|
4752
5166
|
},
|
|
4753
5167
|
processorLock
|
|
4754
5168
|
);
|
|
@@ -4768,14 +5182,6 @@ var postgreSQLReactor = (options) => {
|
|
|
4768
5182
|
checkpoints: postgreSQLCheckpointer()
|
|
4769
5183
|
});
|
|
4770
5184
|
};
|
|
4771
|
-
var postgreSQLMessageProcessor = (options) => {
|
|
4772
|
-
if ("projection" in options) {
|
|
4773
|
-
return postgreSQLProjector(
|
|
4774
|
-
options
|
|
4775
|
-
);
|
|
4776
|
-
}
|
|
4777
|
-
return postgreSQLReactor(options);
|
|
4778
|
-
};
|
|
4779
5185
|
|
|
4780
5186
|
// src/eventStore/consumers/postgreSQLEventStoreConsumer.ts
|
|
4781
5187
|
var postgreSQLEventStoreConsumer = (options) => {
|
|
@@ -4786,7 +5192,10 @@ var postgreSQLEventStoreConsumer = (options) => {
|
|
|
4786
5192
|
let abortController = null;
|
|
4787
5193
|
let start;
|
|
4788
5194
|
let messagePuller;
|
|
4789
|
-
const pool = options.pool ? options.pool : _dumbo.dumbo.call(void 0, {
|
|
5195
|
+
const pool = options.pool ? options.pool : _dumbo.dumbo.call(void 0, {
|
|
5196
|
+
connectionString: options.connectionString,
|
|
5197
|
+
serialization: options.serialization
|
|
5198
|
+
});
|
|
4790
5199
|
const eachBatch = async (messagesBatch) => {
|
|
4791
5200
|
const activeProcessors = processors.filter((s) => s.isActive);
|
|
4792
5201
|
if (activeProcessors.length === 0)
|
|
@@ -4805,7 +5214,7 @@ var postgreSQLEventStoreConsumer = (options) => {
|
|
|
4805
5214
|
})
|
|
4806
5215
|
);
|
|
4807
5216
|
return result.some(
|
|
4808
|
-
(r) => r.status === "fulfilled" && _optionalChain([r, 'access',
|
|
5217
|
+
(r) => r.status === "fulfilled" && _optionalChain([r, 'access', _152 => _152.value, 'optionalAccess', _153 => _153.type]) !== "STOP"
|
|
4809
5218
|
) ? void 0 : {
|
|
4810
5219
|
type: "STOP"
|
|
4811
5220
|
};
|
|
@@ -4816,7 +5225,8 @@ var postgreSQLEventStoreConsumer = (options) => {
|
|
|
4816
5225
|
connectionString: options.connectionString,
|
|
4817
5226
|
pool,
|
|
4818
5227
|
client: void 0,
|
|
4819
|
-
transaction: void 0
|
|
5228
|
+
transaction: void 0,
|
|
5229
|
+
messageStore: void 0
|
|
4820
5230
|
}
|
|
4821
5231
|
};
|
|
4822
5232
|
const stopProcessors = () => Promise.all(processors.map((p) => p.close(processorContext)));
|
|
@@ -4824,12 +5234,12 @@ var postgreSQLEventStoreConsumer = (options) => {
|
|
|
4824
5234
|
if (!isRunning) return;
|
|
4825
5235
|
isRunning = false;
|
|
4826
5236
|
if (messagePuller) {
|
|
4827
|
-
_optionalChain([abortController, 'optionalAccess',
|
|
5237
|
+
_optionalChain([abortController, 'optionalAccess', _154 => _154.abort, 'call', _155 => _155()]);
|
|
4828
5238
|
await messagePuller.stop();
|
|
4829
|
-
messagePuller = void 0;
|
|
4830
|
-
abortController = null;
|
|
4831
5239
|
}
|
|
4832
5240
|
await start;
|
|
5241
|
+
messagePuller = void 0;
|
|
5242
|
+
abortController = null;
|
|
4833
5243
|
await stopProcessors();
|
|
4834
5244
|
};
|
|
4835
5245
|
const init = async () => {
|
|
@@ -4865,6 +5275,14 @@ var postgreSQLEventStoreConsumer = (options) => {
|
|
|
4865
5275
|
);
|
|
4866
5276
|
return processor;
|
|
4867
5277
|
},
|
|
5278
|
+
workflowProcessor: (options2) => {
|
|
5279
|
+
const processor = postgreSQLWorkflowProcessor(options2);
|
|
5280
|
+
processors.push(
|
|
5281
|
+
// TODO: change that
|
|
5282
|
+
processor
|
|
5283
|
+
);
|
|
5284
|
+
return processor;
|
|
5285
|
+
},
|
|
4868
5286
|
start: () => {
|
|
4869
5287
|
if (isRunning) return start;
|
|
4870
5288
|
if (processors.length === 0)
|
|
@@ -4877,8 +5295,8 @@ var postgreSQLEventStoreConsumer = (options) => {
|
|
|
4877
5295
|
stopWhen: options.stopWhen,
|
|
4878
5296
|
executor: pool.execute,
|
|
4879
5297
|
eachBatch,
|
|
4880
|
-
batchSize: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess',
|
|
4881
|
-
pullingFrequencyInMs: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess',
|
|
5298
|
+
batchSize: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess', _156 => _156.batchSize]), () => ( DefaultPostgreSQLEventStoreProcessorBatchSize)),
|
|
5299
|
+
pullingFrequencyInMs: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess', _157 => _157.pullingFrequencyInMs]), () => ( DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs)),
|
|
4882
5300
|
signal: abortController.signal
|
|
4883
5301
|
});
|
|
4884
5302
|
start = (async () => {
|
|
@@ -4926,27 +5344,27 @@ var rebuildPostgreSQLProjections = (options) => {
|
|
|
4926
5344
|
...options,
|
|
4927
5345
|
stopWhen: { noMessagesLeft: true }
|
|
4928
5346
|
});
|
|
5347
|
+
const lock = { acquisitionPolicy: defaultRebuildLockPolicy, ...options.lock };
|
|
4929
5348
|
const projections = "projections" in options ? options.projections.map(
|
|
4930
5349
|
(p) => "projection" in p ? {
|
|
4931
|
-
lockPolicy: defaultRebuildLockPolicy,
|
|
4932
5350
|
truncateOnStart: true,
|
|
4933
5351
|
processorId: getProjectorId({
|
|
4934
|
-
projectionName: _nullishCoalesce(p.projection.name, () => (
|
|
5352
|
+
projectionName: _nullishCoalesce(p.projection.name, () => ( unknownTag))
|
|
4935
5353
|
}),
|
|
4936
5354
|
...p
|
|
4937
5355
|
} : {
|
|
4938
5356
|
projection: p,
|
|
4939
5357
|
processorId: getProjectorId({
|
|
4940
|
-
projectionName: _nullishCoalesce(p.name, () => (
|
|
5358
|
+
projectionName: _nullishCoalesce(p.name, () => ( unknownTag))
|
|
4941
5359
|
}),
|
|
4942
|
-
truncateOnStart: true
|
|
4943
|
-
lockPolicy: defaultRebuildLockPolicy
|
|
5360
|
+
truncateOnStart: true
|
|
4944
5361
|
}
|
|
4945
5362
|
) : [options];
|
|
4946
5363
|
for (const projectionDefinition of projections) {
|
|
4947
5364
|
consumer.projector({
|
|
4948
5365
|
...projectionDefinition,
|
|
4949
|
-
truncateOnStart: _nullishCoalesce(projectionDefinition.truncateOnStart, () => ( true))
|
|
5366
|
+
truncateOnStart: _nullishCoalesce(projectionDefinition.truncateOnStart, () => ( true)),
|
|
5367
|
+
lock
|
|
4950
5368
|
});
|
|
4951
5369
|
}
|
|
4952
5370
|
return consumer;
|
|
@@ -5043,5 +5461,5 @@ var rebuildPostgreSQLProjections = (options) => {
|
|
|
5043
5461
|
|
|
5044
5462
|
|
|
5045
5463
|
|
|
5046
|
-
exports.DefaultPostgreSQLEventStoreProcessorBatchSize = DefaultPostgreSQLEventStoreProcessorBatchSize; exports.DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs = DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs; exports.DefaultPostgreSQLProcessorLockPolicy = DefaultPostgreSQLProcessorLockPolicy; exports.PostgreSQLEventStoreDefaultStreamVersion = PostgreSQLEventStoreDefaultStreamVersion; exports.PostgreSQLProjectionSpec = PostgreSQLProjectionSpec; exports.activateProjection = activateProjection; exports.activateProjectionSQL = activateProjectionSQL; exports.addDefaultPartitionSQL = addDefaultPartitionSQL; exports.addModuleForAllTenantsSQL = addModuleForAllTenantsSQL; exports.addModuleSQL = addModuleSQL; exports.addPartitionSQL = addPartitionSQL; exports.addTablePartitions = addTablePartitions; exports.addTenantForAllModulesSQL = addTenantForAllModulesSQL; exports.addTenantSQL = addTenantSQL; exports.appendToStream = appendToStream; exports.appendToStreamSQL = appendToStreamSQL; exports.assertSQLQueryResultMatches = assertSQLQueryResultMatches; exports.callActivateProjection = callActivateProjection; exports.callAppendToStream = callAppendToStream; exports.callDeactivateProjection = callDeactivateProjection; exports.callRegisterProjection = callRegisterProjection; exports.callReleaseProcessorLock = callReleaseProcessorLock; exports.callStoreProcessorCheckpoint = callStoreProcessorCheckpoint; exports.callTryAcquireProcessorLock = callTryAcquireProcessorLock; exports.callTryAcquireProjectionLock = callTryAcquireProjectionLock; exports.cleanupLegacySubscriptionTables = cleanupLegacySubscriptionTables; exports.createEventStoreSchema = createEventStoreSchema; exports.deactivateProjection = deactivateProjection; exports.deactivateProjectionSQL = deactivateProjectionSQL; exports.defaultPostgreSQLOptions = defaultPostgreSQLOptions; exports.defaultTag =
|
|
5464
|
+
exports.DefaultPostgreSQLEventStoreProcessorBatchSize = DefaultPostgreSQLEventStoreProcessorBatchSize; exports.DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs = DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs; exports.DefaultPostgreSQLProcessorLockPolicy = DefaultPostgreSQLProcessorLockPolicy; exports.PostgreSQLEventStoreDefaultStreamVersion = PostgreSQLEventStoreDefaultStreamVersion; exports.PostgreSQLProjectionSpec = PostgreSQLProjectionSpec; exports.activateProjection = activateProjection; exports.activateProjectionSQL = activateProjectionSQL; exports.addDefaultPartitionSQL = addDefaultPartitionSQL; exports.addModuleForAllTenantsSQL = addModuleForAllTenantsSQL; exports.addModuleSQL = addModuleSQL; exports.addPartitionSQL = addPartitionSQL; exports.addTablePartitions = addTablePartitions; exports.addTenantForAllModulesSQL = addTenantForAllModulesSQL; exports.addTenantSQL = addTenantSQL; exports.appendToStream = appendToStream; exports.appendToStreamSQL = appendToStreamSQL; exports.assertSQLQueryResultMatches = assertSQLQueryResultMatches; exports.callActivateProjection = callActivateProjection; exports.callAppendToStream = callAppendToStream; exports.callDeactivateProjection = callDeactivateProjection; exports.callRegisterProjection = callRegisterProjection; exports.callReleaseProcessorLock = callReleaseProcessorLock; exports.callStoreProcessorCheckpoint = callStoreProcessorCheckpoint; exports.callTryAcquireProcessorLock = callTryAcquireProcessorLock; exports.callTryAcquireProjectionLock = callTryAcquireProjectionLock; exports.cleanupLegacySubscriptionTables = cleanupLegacySubscriptionTables; exports.createEventStoreSchema = createEventStoreSchema; exports.deactivateProjection = deactivateProjection; exports.deactivateProjectionSQL = deactivateProjectionSQL; exports.defaultPostgreSQLOptions = defaultPostgreSQLOptions; 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.eventStoreSchemaMigrations = eventStoreSchemaMigrations; exports.eventsInStream = eventsInStream; exports.expectPongoDocuments = expectPongoDocuments; exports.expectSQL = expectSQL; exports.getPostgreSQLEventStore = getPostgreSQLEventStore; exports.globalNames = globalNames; exports.globalTag = globalTag; exports.handleProjections = handleProjections; exports.messagesTable = messagesTable; exports.messagesTableSQL = messagesTableSQL; exports.newEventsInStream = newEventsInStream; exports.pongoMultiStreamProjection = pongoMultiStreamProjection; exports.pongoProjection = pongoProjection; exports.pongoSingleStreamProjection = pongoSingleStreamProjection; exports.postgreSQLCheckpointer = postgreSQLCheckpointer; exports.postgreSQLEventStoreConsumer = postgreSQLEventStoreConsumer; exports.postgreSQLEventStoreMessageBatchPuller = postgreSQLEventStoreMessageBatchPuller; exports.postgreSQLProcessorLock = postgreSQLProcessorLock; exports.postgreSQLProjection = postgreSQLProjection; exports.postgreSQLProjectionLock = postgreSQLProjectionLock; exports.postgreSQLProjector = postgreSQLProjector; exports.postgreSQLRawBatchSQLProjection = postgreSQLRawBatchSQLProjection; exports.postgreSQLRawSQLProjection = postgreSQLRawSQLProjection; exports.postgreSQLReactor = postgreSQLReactor; exports.postgreSQLWorkflowProcessor = postgreSQLWorkflowProcessor; exports.processorsTable = processorsTable; exports.processorsTableSQL = processorsTableSQL; exports.projectionsTable = projectionsTable; exports.projectionsTableSQL = projectionsTableSQL; exports.readLastMessageGlobalPosition = readLastMessageGlobalPosition; exports.readMessagesBatch = readMessagesBatch; exports.readProcessorCheckpoint = readProcessorCheckpoint; exports.readProjectionInfo = readProjectionInfo; exports.readStream = readStream; exports.rebuildPostgreSQLProjections = rebuildPostgreSQLProjections; exports.registerProjection = registerProjection; exports.registerProjectionSQL = registerProjectionSQL; exports.releaseProcessorLockSQL = releaseProcessorLockSQL; exports.sanitizeNameSQL = sanitizeNameSQL; exports.schemaMigration = schemaMigration; exports.schemaSQL = schemaSQL; exports.storeProcessorCheckpoint = storeProcessorCheckpoint; exports.storeSubscriptionCheckpointSQL = storeSubscriptionCheckpointSQL; exports.streamExists = streamExists; exports.streamsTable = streamsTable; exports.streamsTableSQL = streamsTableSQL; exports.toProcessorLockKey = toProcessorLockKey; exports.toProjectionLockKey = toProjectionLockKey; exports.transactionToPostgreSQLProjectionHandlerContext = transactionToPostgreSQLProjectionHandlerContext; exports.tryAcquireProcessorLockSQL = tryAcquireProcessorLockSQL; exports.tryAcquireProjectionLockSQL = tryAcquireProjectionLockSQL; exports.unknownTag = unknownTag2; exports.zipPostgreSQLEventStoreMessageBatchPullerStartFrom = zipPostgreSQLEventStoreMessageBatchPullerStartFrom;
|
|
5047
5465
|
//# sourceMappingURL=index.cjs.map
|