@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 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;// src/eventStore/consumers/messageBatchProcessing/index.ts
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', _3 => _3.toString, 'call', _4 => _4()])}`))
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
- var emmettPrefix2 = "emt";
118
- var defaultTag2 = `${emmettPrefix2}:default`;
119
- var unknownTag2 = `${emmettPrefix2}:unknown`;
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', _5 => _5.toString, 'call', _6 => _6()]), _optionalChain([expected, 'optionalAccess', _7 => _7.toString, 'call', _8 => _8()]));
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 ParseError = class extends Error {
346
- constructor(text) {
347
- super(`Cannot parse! ${text}`);
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 JSONParser = {
351
- stringify: (value, options) => {
352
- return JSON.stringify(
353
- _optionalChain([options, 'optionalAccess', _9 => _9.map]) ? options.map(value) : value,
354
- //TODO: Consider adding support to DateTime and adding specific format to mark that's a bigint
355
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
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', _15 => _15.shouldRetryResult]) && opts.shouldRetryResult(result)) {
410
+ if (_optionalChain([opts, 'optionalAccess', _20 => _20.shouldRetryResult]) && opts.shouldRetryResult(result)) {
373
411
  throw new EmmettError(
374
- `Retrying because of result: ${JSONParser.stringify(result)}`
412
+ `Retrying because of result: ${JSONSerializer.serialize(result)}`
375
413
  );
376
414
  }
377
415
  return result;
378
- } catch (error2) {
379
- if (_optionalChain([opts, 'optionalAccess', _16 => _16.shouldRetryError]) && !opts.shouldRetryError(error2)) {
380
- bail(error2);
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 error2;
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 "checkpoint" in message2.metadata ? (
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
- const checkpointBigint = checkpoint;
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 = defaultTag2;
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', _20 => _20.read, 'call', _21 => _21(
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', _22 => _22.messageOptions, 'optionalAccess', _23 => _23.schema, 'optionalAccess', _24 => _24.versioning])
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', _25 => _25.hooks, 'optionalAccess', _26 => _26.onInit]),
753
- onStart: options.truncateOnStart && options.projection.truncate || _optionalChain([options, 'access', _27 => _27.hooks, 'optionalAccess', _28 => _28.onStart]) ? async (context) => {
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', _29 => _29.hooks, 'optionalAccess', _30 => _30.onStart])) await _optionalChain([options, 'access', _31 => _31.hooks, 'optionalAccess', _32 => _32.onStart, 'call', _33 => _33(context)]);
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', _34 => _34.hooks, 'optionalAccess', _35 => _35.onClose])
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 projection = (definition) => definition;
764
-
765
- // src/eventStore/schema/readMessagesBatch.ts
766
- var readMessagesBatch = async (execute, options) => {
767
- const from = "from" in options ? options.from : "after" in options ? options.after + 1n : 0n;
768
- const batchSize = options && "batchSize" in options ? options.batchSize : options.to - options.from;
769
- const fromCondition = from !== -0n ? `AND global_position >= ${from}` : "";
770
- const toCondition = "to" in options ? `AND global_position <= ${options.to}` : "";
771
- const limitCondition = "batchSize" in options ? `LIMIT ${options.batchSize}` : "";
772
- const messages = await _dumbo.mapRows.call(void 0,
773
- execute.query(
774
- _dumbo.SQL`
775
- SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
776
- FROM ${_dumbo.SQL.identifier(messagesTable.name)}
777
- WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _36 => _36.partition]), () => ( defaultTag))} AND is_archived = FALSE AND transaction_id < pg_snapshot_xmin(pg_current_snapshot()) ${_dumbo.SQL.plain(fromCondition)} ${_dumbo.SQL.plain(toCondition)}
778
- ORDER BY transaction_id, global_position
779
- ${_dumbo.SQL.plain(limitCondition)}`
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
- (row) => {
782
- const rawEvent = {
783
- type: row.message_type,
784
- data: row.message_data,
785
- metadata: row.message_metadata
786
- };
787
- const metadata = {
788
- ..."metadata" in rawEvent ? _nullishCoalesce(rawEvent.metadata, () => ( {})) : {},
789
- messageId: row.message_id,
790
- streamName: row.stream_id,
791
- streamPosition: BigInt(row.stream_position),
792
- globalPosition: BigInt(row.global_position)
793
- };
794
- return {
795
- ...rawEvent,
796
- kind: "Event",
797
- metadata
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
- // src/eventStore/consumers/messageBatchProcessing/index.ts
813
- var DefaultPostgreSQLEventStoreProcessorBatchSize = 100;
814
- var DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs = 50;
815
- var postgreSQLEventStoreMessageBatchPuller = ({
816
- executor,
817
- batchSize,
818
- eachBatch,
819
- pullingFrequencyInMs,
820
- stopWhen,
821
- signal
822
- }) => {
823
- let isRunning = false;
824
- let start;
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
- if (!areMessagesLeft) {
848
- waitTime = Math.min(waitTime * 2, 1e3);
849
- } else {
850
- waitTime = pullingFrequencyInMs;
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
- get isRunning() {
856
- return isRunning;
857
- },
858
- start: (options) => {
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 zipPostgreSQLEventStoreMessageBatchPullerStartFrom = (options) => {
874
- if (options.length === 0 || options.some((o) => o === void 0 || o === "BEGINNING"))
875
- return "BEGINNING";
876
- if (options.every((o) => o === "END")) return "END";
877
- return options.filter((o) => o !== void 0 && o !== "BEGINNING" && o !== "END").sort((a, b) => a > b ? 1 : -1)[0];
836
+ var createWrappedInitialState = (initialState) => {
837
+ return () => ({
838
+ userState: initialState(),
839
+ processedInputIds: /* @__PURE__ */ new Set()
840
+ });
878
841
  };
879
-
880
- // src/eventStore/consumers/postgreSQLEventStoreConsumer.ts
881
-
882
-
883
-
884
- // src/eventStore/consumers/postgreSQLProcessor.ts
885
-
886
- require('@event-driven-io/dumbo/pg');
887
- require('pg');
888
-
889
- // src/eventStore/projections/locks/tryAcquireProcessorLock.ts
890
-
891
-
892
- // src/eventStore/schema/processors/processorsLocks.ts
893
-
894
-
895
- // src/eventStore/schema/createFunctionIfDoesNotExist.ts
896
-
897
- var createFunctionIfDoesNotExistSQL = (functionName, functionDefinition) => _dumbo.SQL`
898
- DO $$
899
- BEGIN
900
- IF NOT EXISTS (SELECT 1 FROM pg_proc WHERE proname = '${_dumbo.SQL.plain(functionName)}') THEN
901
- ${functionDefinition}
902
- END IF;
903
- END $$;
904
- `;
905
-
906
- // src/eventStore/schema/processors/processorsLocks.ts
907
- var tryAcquireProcessorLockSQL = createFunctionIfDoesNotExistSQL(
908
- "emt_try_acquire_processor_lock",
909
- _dumbo.SQL`
910
- CREATE OR REPLACE FUNCTION emt_try_acquire_processor_lock(
911
- p_lock_key BIGINT,
912
- p_processor_id TEXT,
913
- p_version INT,
914
- p_partition TEXT DEFAULT '${_dumbo.SQL.plain(defaultTag)}',
915
- p_processor_instance_id TEXT DEFAULT '${_dumbo.SQL.plain(unknownTag)}',
916
- p_projection_name TEXT DEFAULT NULL,
917
- p_projection_type VARCHAR(1) DEFAULT NULL,
918
- p_projection_kind TEXT DEFAULT NULL,
919
- p_lock_timeout_seconds INT DEFAULT 300
920
- )
921
- RETURNS TABLE (acquired BOOLEAN, checkpoint TEXT)
922
- LANGUAGE plpgsql
923
- AS $emt_try_acquire_processor_lock$
924
- BEGIN
925
- RETURN QUERY
926
- WITH lock_check AS (
927
- SELECT pg_try_advisory_xact_lock(p_lock_key) AS lock_acquired
928
- ),
929
- ownership_check AS (
930
- INSERT INTO ${_dumbo.SQL.plain(processorsTable.name)} (
931
- processor_id,
932
- partition,
933
- version,
934
- processor_instance_id,
935
- status,
936
- last_processed_checkpoint,
937
- last_processed_transaction_id,
938
- created_at,
939
- last_updated
940
- )
941
- SELECT p_processor_id, p_partition, p_version, p_processor_instance_id, 'running', '${_dumbo.SQL.plain(bigInt.toNormalizedString(0n))}', '0'::xid8, now(), now()
942
- WHERE (SELECT lock_acquired FROM lock_check) = true
943
- ON CONFLICT (processor_id, partition, version) DO UPDATE
944
- SET processor_instance_id = p_processor_instance_id,
945
- status = 'running',
946
- last_updated = now()
947
- WHERE ${_dumbo.SQL.plain(processorsTable.name)}.processor_instance_id = p_processor_instance_id
948
- OR ${_dumbo.SQL.plain(processorsTable.name)}.processor_instance_id = '${_dumbo.SQL.plain(unknownTag)}'
949
- OR ${_dumbo.SQL.plain(processorsTable.name)}.status = 'stopped'
950
- OR ${_dumbo.SQL.plain(processorsTable.name)}.last_updated < now() - (p_lock_timeout_seconds || ' seconds')::interval
951
- RETURNING last_processed_checkpoint
952
- ),
953
- projection_status AS (
954
- INSERT INTO ${_dumbo.SQL.plain(projectionsTable.name)} (
955
- name,
956
- partition,
957
- version,
958
- type,
959
- kind,
960
- status,
961
- definition
962
- )
963
- SELECT p_projection_name, p_partition, p_version, p_projection_type, p_projection_kind, 'async_processing', '{}'::jsonb
964
- WHERE p_projection_name IS NOT NULL
965
- AND (SELECT last_processed_checkpoint FROM ownership_check) IS NOT NULL
966
- ON CONFLICT (name, partition, version) DO UPDATE
967
- SET status = 'async_processing'
968
- RETURNING name
969
- )
970
- SELECT
971
- (SELECT COUNT(*) > 0 FROM ownership_check),
972
- (SELECT oc.last_processed_checkpoint FROM ownership_check oc);
973
- END;
974
- $emt_try_acquire_processor_lock$;
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 releaseProcessorLockSQL = createFunctionIfDoesNotExistSQL(
978
- "emt_release_processor_lock",
979
- _dumbo.SQL`
980
- CREATE OR REPLACE FUNCTION emt_release_processor_lock(
981
- p_lock_key BIGINT,
982
- p_processor_id TEXT,
983
- p_partition TEXT,
984
- p_version INT,
985
- p_processor_instance_id TEXT DEFAULT '${_dumbo.SQL.plain(unknownTag)}',
986
- p_projection_name TEXT DEFAULT NULL
987
- )
988
- RETURNS BOOLEAN
989
- LANGUAGE plpgsql
990
- AS $emt_release_processor_lock$
991
- DECLARE
992
- v_rows_updated INT;
993
- BEGIN
994
- IF p_projection_name IS NOT NULL THEN
995
- UPDATE ${_dumbo.SQL.plain(projectionsTable.name)}
996
- SET status = 'active',
997
- last_updated = now()
998
- WHERE partition = p_partition
999
- AND name = p_projection_name
1000
- AND version = p_version;
1001
- END IF;
1002
-
1003
- UPDATE ${_dumbo.SQL.plain(processorsTable.name)}
1004
- SET status = 'stopped',
1005
- processor_instance_id = '${_dumbo.SQL.plain(unknownTag)}',
1006
- last_updated = now()
1007
- WHERE processor_id = p_processor_id
1008
- AND partition = p_partition
1009
- AND version = p_version
1010
- AND processor_instance_id = p_processor_instance_id;
1011
-
1012
- GET DIAGNOSTICS v_rows_updated = ROW_COUNT;
1013
-
1014
- PERFORM pg_advisory_unlock(p_lock_key);
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
- RETURN v_rows_updated > 0;
1017
- END;
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/projections/locks/tryAcquireProcessorLock.ts
1044
- var PROCESSOR_LOCK_DEFAULT_TIMEOUT_SECONDS = 300;
1045
- var tryAcquireProcessorLock = async (execute, options) => {
1046
- const lockKeyBigInt = isBigint(options.lockKey) ? options.lockKey : await hashText(options.lockKey);
1047
- const { acquired, checkpoint } = await _dumbo.single.call(void 0,
1048
- execute.command(
1049
- callTryAcquireProcessorLock({
1050
- lockKey: lockKeyBigInt.toString(),
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 tryAcquireProcessorLockWithRetry = async (execute, options) => {
1065
- const policy = _nullishCoalesce(options.lockPolicy, () => ( DefaultPostgreSQLProcessorLockPolicy));
1066
- if (policy.type === "retry") {
1067
- return asyncRetry(() => tryAcquireProcessorLock(execute, options), {
1068
- retries: policy.retries - 1,
1069
- minTimeout: policy.minTimeout,
1070
- maxTimeout: policy.maxTimeout,
1071
- shouldRetryResult: (r) => !r.acquired
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 releaseProcessorLock = async (execute, options) => {
1077
- const lockKeyBigInt = isBigint(options.lockKey) ? options.lockKey : await hashText(options.lockKey);
1078
- const { result } = await _dumbo.single.call(void 0,
1079
- execute.command(
1080
- callReleaseProcessorLock({
1081
- lockKey: lockKeyBigInt.toString(),
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/postgreSQLProcessorLock.ts
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/projections/registerProjection.ts
1360
+ // src/eventStore/schema/processors/processorsLocks.ts
1233
1361
 
1234
- var registerProjectionSQL = createFunctionIfDoesNotExistSQL(
1235
- "emt_register_projection",
1362
+ var tryAcquireProcessorLockSQL = createFunctionIfDoesNotExistSQL(
1363
+ "emt_try_acquire_processor_lock",
1236
1364
  _dumbo.SQL`
1237
- CREATE OR REPLACE FUNCTION emt_register_projection(
1238
- p_lock_key BIGINT,
1239
- p_name TEXT,
1240
- p_partition TEXT,
1241
- p_version INT,
1242
- p_type VARCHAR(1),
1243
- p_kind TEXT,
1244
- p_status TEXT,
1245
- p_definition JSONB
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 $emt_register_projection$
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
- upsert_result AS (
1257
- INSERT INTO ${_dumbo.SQL.identifier(projectionsTable.name)} (
1258
- name, partition, version, type, kind, status, definition, created_at, last_updated
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 p_name, p_partition, p_version, p_type, p_kind, p_status, p_definition, now(), now()
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 (name, partition, version) DO UPDATE
1263
- SET definition = EXCLUDED.definition,
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
- RETURNING name
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
- assertIsNotNull(result);
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
- // src/eventStore/postgreSQLEventStore.ts
1724
-
1725
-
1726
-
1727
-
1728
-
1729
-
1730
-
1731
-
1732
-
1733
- // src/eventStore/schema/index.ts
1734
-
1735
-
1736
-
1737
-
1738
-
1739
-
1740
- // src/eventStore/schema/appendToStream.ts
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', _48 => _48.expectedStreamVersion])
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', _49 => _49.beforeCommitHook]))
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', _50 => _50.expectedStreamVersion]), () => ( null)),
1945
- partition: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _51 => _51.partition]), () => ( defaultTag))
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(defaultTag)}');
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(defaultTag)}',
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(defaultTag)}',
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(defaultTag)}',
3471
- p_processor_instance_id TEXT DEFAULT '${_dumbo.SQL.plain(unknownTag)}'
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 ? bigInt.toNormalizedString(options.newCheckpoint) : null,
3553
- checkPosition: options.lastProcessedCheckpoint !== null ? bigInt.toNormalizedString(options.lastProcessedCheckpoint) : null,
3554
- partition: _nullishCoalesce(options.partition, () => ( defaultTag)),
3555
- processorInstanceId: _nullishCoalesce(options.processorInstanceId, () => ( unknownTag))
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(defaultTag)}',
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(defaultTag)}',
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(defaultTag)}',
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(defaultTag)}',
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(unknownTag)}',
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(defaultTag)}',
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(defaultTag)}');`;
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', _52 => _52.partition]), () => ( defaultTag))} AND processor_id = ${options.processorId} AND version = ${_nullishCoalesce(options.version, () => ( 1))}
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 ? BigInt(result.last_processed_checkpoint) : 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', _53 => _53.from]) ? `AND stream_position >= ${options.from}` : "";
4020
- const to = Number(
4021
- _nullishCoalesce(_optionalChain([options, 'optionalAccess', _54 => _54.to]), () => ( (_optionalChain([options, 'optionalAccess', _55 => _55.maxCount]) ? (_nullishCoalesce(options.from, () => ( 0n))) + options.maxCount : NaN)))
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', _56 => _56.partition]), () => ( defaultTag))} AND is_archived = FALSE ${_dumbo.SQL.plain(fromCondition)} ${_dumbo.SQL.plain(toCondition)}
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
- return (givenEvents) => {
4363
- return {
4364
- when: (events, options2) => {
4365
- const allEvents = [];
4366
- const run = async (pool) => {
4367
- let globalPosition = 0n;
4368
- const numberOfTimes = _nullishCoalesce(_optionalChain([options2, 'optionalAccess', _80 => _80.numberOfTimes]), () => ( 1));
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
- var eventInStream = (streamName, event) => {
4452
- return {
4453
- ...event,
4454
- metadata: {
4455
- ..._nullishCoalesce(event.metadata, () => ( {})),
4456
- streamName: _nullishCoalesce(_optionalChain([event, 'access', _87 => _87.metadata, 'optionalAccess', _88 => _88.streamName]), () => ( streamName))
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
- var eventsInStream = (streamName, events) => {
4461
- return events.map((e) => eventInStream(streamName, e));
4462
- };
4463
- var newEventsInStream = eventsInStream;
4464
- var assertSQLQueryResultMatches = (sql, rows) => async ({ pool: { execute } }) => {
4465
- const result = await execute.query(sql);
4466
- assertThatArray(rows).containsExactlyInAnyOrder(result.rows);
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
- var expectSQL = {
4469
- query: (sql) => ({
4470
- resultRows: {
4471
- toBeTheSame: (rows) => assertSQLQueryResultMatches(sql, rows)
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/projections/postgreSQLProjection.ts
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
- var transactionToPostgreSQLProjectionHandlerContext = async (connectionString, pool, transaction) => ({
4480
- execute: transaction.execute,
4481
- connection: {
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
- client: await transaction.connection.open(),
4484
- transaction,
4485
- pool
4486
- }
4487
- });
4488
- var handleProjections = async (options) => {
4489
- const {
4490
- projections: allProjections,
4491
- events,
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
- client,
4516
- transaction
4517
- },
4518
- execute: transaction.execute
4519
- });
4520
- }
4521
- };
4522
- var postgreSQLProjection = (definition) => projection({
4523
- ...definition,
4524
- init: async (options) => {
4525
- await registerProjection(options.context.execute, {
4526
- // TODO: pass partition from options
4527
- partition: defaultTag,
4528
- status: "active",
4529
- registration: {
4530
- type: "async",
4531
- // TODO: fix this
4532
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
4533
- projection: definition
4534
- }
4535
- });
4536
- if (definition.init) {
4537
- await definition.init(options);
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
- var postgreSQLRawBatchSQLProjection = (options) => postgreSQLProjection({
4542
- name: options.name,
4543
- kind: _nullishCoalesce(options.kind, () => ( "emt:projections:postgresql:raw_sql:batch")),
4544
- version: options.version,
4545
- canHandle: options.canHandle,
4546
- eventsOptions: options.eventsOptions,
4547
- handle: async (events, context) => {
4548
- const sqls = await options.evolve(events, context);
4549
- await context.execute.batchCommand(sqls);
4550
- },
4551
- init: async (initOptions) => {
4552
- const initSQL = options.init ? await options.init(initOptions) : void 0;
4553
- if (initSQL) {
4554
- if (Array.isArray(initSQL)) {
4555
- await initOptions.context.execute.batchCommand(initSQL);
4556
- } else {
4557
- await initOptions.context.execute.command(initSQL);
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
- var postgreSQLRawSQLProjection = (options) => {
4563
- const { evolve, kind, ...rest } = options;
4564
- return postgreSQLRawBatchSQLProjection({
4565
- kind: _nullishCoalesce(kind, () => ( "emt:projections:postgresql:raw:_sql:single")),
4566
- ...rest,
4567
- evolve: async (events, context) => {
4568
- const sqls = [];
4569
- for (const event of events) {
4570
- const pendingSqls = await evolve(event, context);
4571
- if (Array.isArray(pendingSqls)) {
4572
- sqls.push(...pendingSqls);
4573
- } else {
4574
- sqls.push(pendingSqls);
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 sqls;
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', _89 => _89.lastProcessedCheckpoint]) };
4949
+ return { lastCheckpoint: _optionalChain([result, 'optionalAccess', _112 => _112.lastProcessedCheckpoint]) };
4587
4950
  },
4588
4951
  store: async (options, context) => {
4589
- const newPosition = getCheckpoint(options.message);
4952
+ const newCheckpoint = getCheckpoint(options.message);
4590
4953
  const result = await storeProcessorCheckpoint(context.execute, {
4591
4954
  lastProcessedCheckpoint: options.lastCheckpoint,
4592
- newCheckpoint: newPosition,
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', _90 => _90.connection]);
4605
- const connectionString = _nullishCoalesce(processorConnectionString, () => ( _optionalChain([connection, 'optionalAccess', _91 => _91.connectionString])));
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', _92 => _92.pool]) : processorPool), () => ( processorPool));
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', _93 => _93.onStart])) await hooks.onStart(context);
5018
+ if (_optionalChain([hooks, 'optionalAccess', _116 => _116.onStart])) await hooks.onStart(context);
4652
5019
  },
4653
- onClose: _optionalChain([hooks, 'optionalAccess', _94 => _94.onClose]) || processorLock ? async (context) => {
5020
+ onClose: _optionalChain([hooks, 'optionalAccess', _117 => _117.onClose]) || processorLock ? async (context) => {
4654
5021
  await processorLock.release({ execute: context.execute });
4655
- if (_optionalChain([hooks, 'optionalAccess', _95 => _95.onClose])) await hooks.onClose(context);
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
- lockPolicy = DefaultPostgreSQLProcessorLockPolicy,
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, () => ( unknownTag2)),
4677
- kind: _nullishCoalesce(options.projection.kind, () => ( unknownTag2)),
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
- lockPolicy,
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', _96 => _96.hooks, 'optionalAccess', _97 => _97.onInit]) ? async (context) => {
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', _98 => _98.hooks, 'optionalAccess', _99 => _99.onInit]))
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', _100 => _100.hooks, 'optionalAccess', _101 => _101.onInit]),
5069
+ } : _optionalChain([options, 'access', _125 => _125.hooks, 'optionalAccess', _126 => _126.onInit]),
4704
5070
  onClose: close ? async (context) => {
4705
- if (_optionalChain([options, 'access', _102 => _102.hooks, 'optionalAccess', _103 => _103.onClose])) await _optionalChain([options, 'access', _104 => _104.hooks, 'optionalAccess', _105 => _105.onClose, 'call', _106 => _106(context)]);
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', _107 => _107.hooks, 'optionalAccess', _108 => _108.onClose])
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
- lockPolicy = DefaultPostgreSQLProcessorLockPolicy
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
- lockPolicy
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', _109 => _109.hooks, 'optionalAccess', _110 => _110.onClose])) await _optionalChain([options, 'access', _111 => _111.hooks, 'optionalAccess', _112 => _112.onClose, 'call', _113 => _113(context)]);
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', _114 => _114.hooks, 'optionalAccess', _115 => _115.onClose])
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, { connectionString: options.connectionString });
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', _116 => _116.value, 'optionalAccess', _117 => _117.type]) !== "STOP"
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', _118 => _118.abort, 'call', _119 => _119()]);
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', _120 => _120.batchSize]), () => ( DefaultPostgreSQLEventStoreProcessorBatchSize)),
4881
- pullingFrequencyInMs: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess', _121 => _121.pullingFrequencyInMs]), () => ( DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs)),
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, () => ( unknownTag2))
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, () => ( unknownTag2))
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 = defaultTag; exports.documentDoesNotExist = documentDoesNotExist; exports.documentExists = documentExists; exports.documentMatchingExists = documentMatchingExists; exports.documentsAreTheSame = documentsAreTheSame; exports.documentsMatchingHaveCount = documentsMatchingHaveCount; exports.emmettPrefix = emmettPrefix; 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.postgreSQLMessageProcessor = postgreSQLMessageProcessor; exports.postgreSQLProcessorLock = postgreSQLProcessorLock; exports.postgreSQLProjection = postgreSQLProjection; exports.postgreSQLProjectionLock = postgreSQLProjectionLock; exports.postgreSQLProjector = postgreSQLProjector; exports.postgreSQLRawBatchSQLProjection = postgreSQLRawBatchSQLProjection; exports.postgreSQLRawSQLProjection = postgreSQLRawSQLProjection; exports.postgreSQLReactor = postgreSQLReactor; 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 = unknownTag; exports.zipPostgreSQLEventStoreMessageBatchPullerStartFrom = zipPostgreSQLEventStoreMessageBatchPullerStartFrom;
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