@event-driven-io/emmett-postgresql 0.43.0-beta.1 → 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
@@ -39,7 +39,7 @@ var ConcurrencyError = class _ConcurrencyError extends EmmettError {
39
39
  constructor(current, expected, message) {
40
40
  super({
41
41
  errorCode: EmmettError.Codes.ConcurrencyError,
42
- message: _nullishCoalesce(message, () => ( `Expected version ${expected.toString()} does not match current ${_optionalChain([current, 'optionalAccess', _2 => _2.toString, 'call', _3 => _3()])}`))
42
+ message: _nullishCoalesce(message, () => ( `Expected version ${expected.toString()} does not match current ${_optionalChain([current, 'optionalAccess', _ => _.toString, 'call', _2 => _2()])}`))
43
43
  });
44
44
  this.current = current;
45
45
  this.expected = expected;
@@ -50,12 +50,24 @@ var ConcurrencyError = class _ConcurrencyError extends EmmettError {
50
50
  // ../emmett/dist/index.js
51
51
  var _uuid = require('uuid');
52
52
 
53
+
53
54
  var _asyncretry = require('async-retry'); var _asyncretry2 = _interopRequireDefault(_asyncretry);
54
55
 
55
56
 
57
+
56
58
  var emmettPrefix = "emt";
57
59
  var defaultTag = `${emmettPrefix}:default`;
58
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
+ });
59
71
  var STREAM_EXISTS = "STREAM_EXISTS";
60
72
  var STREAM_DOES_NOT_EXIST = "STREAM_DOES_NOT_EXIST";
61
73
  var NO_CONCURRENCY_CHECK = "NO_CONCURRENCY_CHECK";
@@ -72,10 +84,14 @@ var assertExpectedVersionMatchesCurrent = (current, expected, defaultVersion) =>
72
84
  };
73
85
  var ExpectedVersionConflictError = class _ExpectedVersionConflictError extends ConcurrencyError {
74
86
  constructor(current, expected) {
75
- super(_optionalChain([current, 'optionalAccess', _4 => _4.toString, 'call', _5 => _5()]), _optionalChain([expected, 'optionalAccess', _6 => _6.toString, 'call', _7 => _7()]));
87
+ super(_optionalChain([current, 'optionalAccess', _3 => _3.toString, 'call', _4 => _4()]), _optionalChain([expected, 'optionalAccess', _5 => _5.toString, 'call', _6 => _6()]));
76
88
  Object.setPrototypeOf(this, _ExpectedVersionConflictError.prototype);
77
89
  }
78
90
  };
91
+ var isExpectedVersionConflictError = (error) => error instanceof ExpectedVersionConflictError || EmmettError.isInstanceOf(
92
+ error,
93
+ ExpectedVersionConflictError.Codes.ConcurrencyError
94
+ );
79
95
  var isPrimitive = (value) => {
80
96
  const type = typeof value;
81
97
  return value === null || value === void 0 || type === "boolean" || type === "number" || type === "string" || type === "symbol" || type === "bigint";
@@ -281,45 +297,128 @@ var toNormalizedString = (value) => value.toString().padStart(19, "0");
281
297
  var bigInt = {
282
298
  toNormalizedString
283
299
  };
284
- var ParseError = class extends Error {
285
- constructor(text) {
286
- 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
+ }
332
+ }
333
+ return value;
334
+ };
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
+ }
287
341
  }
342
+ return value;
288
343
  };
289
- var JSONParser = {
290
- stringify: (value, options) => {
291
- return JSON.stringify(
292
- _optionalChain([options, 'optionalAccess', _8 => _8.map]) ? options.map(value) : value,
293
- //TODO: Consider adding support to DateTime and adding specific format to mark that's a bigint
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(
294
350
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
295
- (_, v) => typeof v === "bigint" ? v.toString() : v
296
- );
297
- },
298
- parse: (text, options) => {
299
- const parsed = JSON.parse(text, _optionalChain([options, 'optionalAccess', _9 => _9.reviver]));
300
- if (_optionalChain([options, 'optionalAccess', _10 => _10.typeCheck]) && !_optionalChain([options, 'optionalAccess', _11 => _11.typeCheck, 'call', _12 => _12(parsed)]))
301
- throw new ParseError(text);
302
- return _optionalChain([options, 'optionalAccess', _13 => _13.map]) ? options.map(parsed) : parsed;
303
- }
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
304
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
+ };
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 };
305
404
  var asyncRetry = async (fn, opts) => {
306
405
  if (opts === void 0 || opts.retries === 0) return fn();
307
406
  return _asyncretry2.default.call(void 0,
308
407
  async (bail) => {
309
408
  try {
310
409
  const result = await fn();
311
- if (_optionalChain([opts, 'optionalAccess', _14 => _14.shouldRetryResult]) && opts.shouldRetryResult(result)) {
410
+ if (_optionalChain([opts, 'optionalAccess', _20 => _20.shouldRetryResult]) && opts.shouldRetryResult(result)) {
312
411
  throw new EmmettError(
313
- `Retrying because of result: ${JSONParser.stringify(result)}`
412
+ `Retrying because of result: ${JSONSerializer.serialize(result)}`
314
413
  );
315
414
  }
316
415
  return result;
317
- } catch (error2) {
318
- if (_optionalChain([opts, 'optionalAccess', _15 => _15.shouldRetryError]) && !opts.shouldRetryError(error2)) {
319
- bail(error2);
416
+ } catch (error) {
417
+ if (_optionalChain([opts, 'optionalAccess', _21 => _21.shouldRetryError]) && !opts.shouldRetryError(error)) {
418
+ bail(error);
320
419
  return void 0;
321
420
  }
322
- throw error2;
421
+ throw error;
323
422
  }
324
423
  },
325
424
  _nullishCoalesce(opts, () => ( { retries: 0 }))
@@ -423,12 +522,13 @@ var reactor = (options) => {
423
522
  id: processorId,
424
523
  instanceId,
425
524
  type,
525
+ canHandle,
426
526
  init,
427
527
  start: async (startOptions) => {
428
528
  if (isActive) return;
429
529
  await init(startOptions);
430
530
  isActive = true;
431
- closeSignal = onShutdown(() => close({}));
531
+ closeSignal = onShutdown(() => close(startOptions));
432
532
  if (lastCheckpoint !== null)
433
533
  return {
434
534
  lastCheckpoint
@@ -439,7 +539,7 @@ var reactor = (options) => {
439
539
  }
440
540
  if (startFrom && startFrom !== "CURRENT") return startFrom;
441
541
  if (checkpoints) {
442
- const readResult = await _optionalChain([checkpoints, 'optionalAccess', _16 => _16.read, 'call', _17 => _17(
542
+ const readResult = await _optionalChain([checkpoints, 'optionalAccess', _22 => _22.read, 'call', _23 => _23(
443
543
  {
444
544
  processorId,
445
545
  partition
@@ -467,7 +567,7 @@ var reactor = (options) => {
467
567
  const upcasted = upcastRecordedMessage(
468
568
  // TODO: Make it smarter
469
569
  message2,
470
- _optionalChain([options, 'access', _18 => _18.messageOptions, 'optionalAccess', _19 => _19.schema, 'optionalAccess', _20 => _20.versioning])
570
+ _optionalChain([options, 'access', _24 => _24.messageOptions, 'optionalAccess', _25 => _25.schema, 'optionalAccess', _26 => _26.versioning])
471
571
  );
472
572
  if (canHandle !== void 0 && !canHandle.includes(upcasted.type))
473
573
  continue;
@@ -520,13 +620,13 @@ var projector = (options) => {
520
620
  processorId,
521
621
  messageOptions: options.projection.eventsOptions,
522
622
  hooks: {
523
- onInit: _optionalChain([options, 'access', _21 => _21.hooks, 'optionalAccess', _22 => _22.onInit]),
524
- onStart: options.truncateOnStart && options.projection.truncate || _optionalChain([options, 'access', _23 => _23.hooks, 'optionalAccess', _24 => _24.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) => {
525
625
  if (options.truncateOnStart && options.projection.truncate)
526
626
  await options.projection.truncate(context);
527
- if (_optionalChain([options, 'access', _25 => _25.hooks, 'optionalAccess', _26 => _26.onStart])) await _optionalChain([options, 'access', _27 => _27.hooks, 'optionalAccess', _28 => _28.onStart, 'call', _29 => _29(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)]);
528
628
  } : void 0,
529
- onClose: _optionalChain([options, 'access', _30 => _30.hooks, 'optionalAccess', _31 => _31.onClose])
629
+ onClose: _optionalChain([options, 'access', _36 => _36.hooks, 'optionalAccess', _37 => _37.onClose])
530
630
  },
531
631
  eachMessage: async (event2, context) => projection2.handle([event2], context)
532
632
  });
@@ -555,9 +655,9 @@ var assertDeepEqual = (actual, expected, message2) => {
555
655
  if (!deepEquals(actual, expected))
556
656
  throw new AssertionError(
557
657
  _nullishCoalesce(message2, () => ( `subObj:
558
- ${JSONParser.stringify(expected)}
658
+ ${JSONSerializer.serialize(expected)}
559
659
  is not equal to
560
- ${JSONParser.stringify(actual)}`))
660
+ ${JSONSerializer.serialize(actual)}`))
561
661
  );
562
662
  };
563
663
  function assertTrue(condition, message2) {
@@ -571,26 +671,29 @@ function assertEqual(expected, actual, message2) {
571
671
  if (expected !== actual)
572
672
  throw new AssertionError(
573
673
  `${_nullishCoalesce(message2, () => ( "Objects are not equal"))}:
574
- Expected: ${JSONParser.stringify(expected)}
575
- Actual: ${JSONParser.stringify(actual)}`
674
+ Expected: ${JSONSerializer.serialize(expected)}
675
+ Actual: ${JSONSerializer.serialize(actual)}`
576
676
  );
577
677
  }
578
678
  function assertNotEqual(obj, other, message2) {
579
679
  if (obj === other)
580
680
  throw new AssertionError(
581
- _nullishCoalesce(message2, () => ( `Objects are equal: ${JSONParser.stringify(obj)}`))
681
+ _nullishCoalesce(message2, () => ( `Objects are equal: ${JSONSerializer.serialize(obj)}`))
582
682
  );
583
683
  }
584
684
  function assertIsNotNull(result) {
585
685
  assertNotEqual(result, null);
586
686
  assertOk(result);
587
687
  }
688
+ function assertIsNull(result) {
689
+ assertEqual(result, null);
690
+ }
588
691
  var assertThatArray = (array) => {
589
692
  return {
590
693
  isEmpty: () => assertEqual(
591
694
  array.length,
592
695
  0,
593
- `Array is not empty ${JSONParser.stringify(array)}`
696
+ `Array is not empty ${JSONSerializer.serialize(array)}`
594
697
  ),
595
698
  isNotEmpty: () => assertNotEqual(array.length, 0, `Array is empty`),
596
699
  hasSize: (length) => assertEqual(array.length, length),
@@ -647,7 +750,7 @@ var assertThatArray = (array) => {
647
750
  };
648
751
  };
649
752
  var downcastRecordedMessage = (recordedMessage, options) => {
650
- if (!_optionalChain([options, 'optionalAccess', _32 => _32.downcast]))
753
+ if (!_optionalChain([options, 'optionalAccess', _38 => _38.downcast]))
651
754
  return recordedMessage;
652
755
  const downcasted = options.downcast(
653
756
  recordedMessage
@@ -665,14 +768,14 @@ var downcastRecordedMessage = (recordedMessage, options) => {
665
768
  };
666
769
  };
667
770
  var downcastRecordedMessages = (recordedMessages, options) => {
668
- if (!_optionalChain([options, 'optionalAccess', _33 => _33.downcast]))
771
+ if (!_optionalChain([options, 'optionalAccess', _39 => _39.downcast]))
669
772
  return recordedMessages;
670
773
  return recordedMessages.map(
671
774
  (recordedMessage) => downcastRecordedMessage(recordedMessage, options)
672
775
  );
673
776
  };
674
777
  var upcastRecordedMessage = (recordedMessage, options) => {
675
- if (!_optionalChain([options, 'optionalAccess', _34 => _34.upcast]))
778
+ if (!_optionalChain([options, 'optionalAccess', _40 => _40.upcast]))
676
779
  return recordedMessage;
677
780
  const upcasted = options.upcast(
678
781
  recordedMessage
@@ -690,6 +793,281 @@ var upcastRecordedMessage = (recordedMessage, options) => {
690
793
  };
691
794
  };
692
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 : {};
828
+ return {
829
+ ...msg,
830
+ metadata: {
831
+ ...existingMetadata,
832
+ action
833
+ }
834
+ };
835
+ };
836
+ var createWrappedInitialState = (initialState) => {
837
+ return () => ({
838
+ userState: initialState(),
839
+ processedInputIds: /* @__PURE__ */ new Set()
840
+ });
841
+ };
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
+ )
992
+ );
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
+ };
693
1071
 
694
1072
  // src/eventStore/schema/readLastMessageGlobalPosition.ts
695
1073
  var _dumbo = require('@event-driven-io/dumbo');
@@ -736,7 +1114,7 @@ var readLastMessageGlobalPosition = async (execute, options) => {
736
1114
  execute.query(
737
1115
  _dumbo.SQL`SELECT global_position
738
1116
  FROM ${_dumbo.SQL.identifier(messagesTable.name)}
739
- WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _35 => _35.partition]), () => ( defaultTag2))} AND is_archived = FALSE AND transaction_id < pg_snapshot_xmin(pg_current_snapshot())
1117
+ WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _56 => _56.partition]), () => ( defaultTag2))} AND is_archived = FALSE AND transaction_id < pg_snapshot_xmin(pg_current_snapshot())
740
1118
  ORDER BY transaction_id, global_position
741
1119
  LIMIT 1`
742
1120
  )
@@ -760,7 +1138,7 @@ var readMessagesBatch = async (execute, options) => {
760
1138
  _dumbo.SQL`
761
1139
  SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
762
1140
  FROM ${_dumbo.SQL.identifier(messagesTable.name)}
763
- WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _36 => _36.partition]), () => ( defaultTag2))} AND is_archived = FALSE AND transaction_id < pg_snapshot_xmin(pg_current_snapshot()) ${fromCondition} ${toCondition}
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}
764
1142
  ORDER BY transaction_id, global_position
765
1143
  ${limitCondition}`
766
1144
  ),
@@ -816,7 +1194,7 @@ var postgreSQLEventStoreMessageBatchPuller = ({
816
1194
  batchSize
817
1195
  };
818
1196
  let waitTime = 100;
819
- while (isRunning && !_optionalChain([signal, 'optionalAccess', _37 => _37.aborted])) {
1197
+ while (isRunning && !_optionalChain([signal, 'optionalAccess', _58 => _58.aborted])) {
820
1198
  const { messages, currentGlobalPosition, areMessagesLeft } = await readMessagesBatch(executor, readMessagesOptions);
821
1199
  if (messages.length > 0) {
822
1200
  const result = await eachBatch(messages);
@@ -827,7 +1205,7 @@ var postgreSQLEventStoreMessageBatchPuller = ({
827
1205
  }
828
1206
  readMessagesOptions.after = currentGlobalPosition;
829
1207
  await new Promise((resolve) => setTimeout(resolve, waitTime));
830
- if (_optionalChain([stopWhen, 'optionalAccess', _38 => _38.noMessagesLeft]) === true && !areMessagesLeft) {
1208
+ if (_optionalChain([stopWhen, 'optionalAccess', _59 => _59.noMessagesLeft]) === true && !areMessagesLeft) {
831
1209
  isRunning = false;
832
1210
  break;
833
1211
  }
@@ -871,6 +1249,14 @@ var zipPostgreSQLEventStoreMessageBatchPullerStartFrom = (options) => {
871
1249
  // src/eventStore/consumers/postgreSQLProcessor.ts
872
1250
 
873
1251
 
1252
+ // src/eventStore/postgreSQLEventStore.ts
1253
+
1254
+
1255
+
1256
+
1257
+
1258
+
1259
+
874
1260
  // src/eventStore/projections/locks/tryAcquireProjectionLock.ts
875
1261
 
876
1262
 
@@ -1121,9 +1507,9 @@ var tryAcquireProcessorLock = async (execute, options) => {
1121
1507
  version: options.version,
1122
1508
  partition: options.partition,
1123
1509
  processorInstanceId: options.processorInstanceId,
1124
- projectionName: _nullishCoalesce(_optionalChain([options, 'access', _39 => _39.projection, 'optionalAccess', _40 => _40.name]), () => ( null)),
1125
- projectionType: _optionalChain([options, 'access', _41 => _41.projection, 'optionalAccess', _42 => _42.handlingType]) ? options.projection.handlingType === "inline" ? "i" : "a" : null,
1126
- projectionKind: _nullishCoalesce(_optionalChain([options, 'access', _43 => _43.projection, 'optionalAccess', _44 => _44.kind]), () => ( null)),
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)),
1127
1513
  lockTimeoutSeconds: _nullishCoalesce(options.lockTimeoutSeconds, () => ( PROCESSOR_LOCK_DEFAULT_TIMEOUT_SECONDS))
1128
1514
  })
1129
1515
  )
@@ -1175,7 +1561,7 @@ var postgreSQLProcessorLock = (options) => {
1175
1561
  ...options,
1176
1562
  lockKey
1177
1563
  });
1178
- if (!result.acquired && _optionalChain([options, 'access', _45 => _45.lockAcquisitionPolicy, 'optionalAccess', _46 => _46.type]) !== "skip") {
1564
+ if (!result.acquired && _optionalChain([options, 'access', _66 => _66.lockAcquisitionPolicy, 'optionalAccess', _67 => _67.type]) !== "skip") {
1179
1565
  throw new EmmettError(
1180
1566
  `Failed to acquire lock for processor '${options.processorId}'`
1181
1567
  );
@@ -1189,7 +1575,7 @@ var postgreSQLProcessorLock = (options) => {
1189
1575
  await releaseProcessorLock(context.execute, {
1190
1576
  ...releaseOptions,
1191
1577
  lockKey,
1192
- projectionName: _optionalChain([projection2, 'optionalAccess', _47 => _47.name])
1578
+ projectionName: _optionalChain([projection2, 'optionalAccess', _68 => _68.name])
1193
1579
  });
1194
1580
  acquired = false;
1195
1581
  }
@@ -1650,7 +2036,7 @@ var documentDoesNotExist = (options) => (assertOptions) => withCollection(
1650
2036
  const result = await collection.findOne(
1651
2037
  "withId" in options ? { _id: options.withId } : options.matchingFilter
1652
2038
  );
1653
- assertIsNotNull(result);
2039
+ assertIsNull(result);
1654
2040
  },
1655
2041
  { ...options, ...assertOptions }
1656
2042
  );
@@ -1702,143 +2088,385 @@ var expectPongoDocuments = {
1702
2088
 
1703
2089
 
1704
2090
 
1705
-
1706
- // src/eventStore/postgreSQLEventStore.ts
1707
-
1708
-
1709
-
1710
-
1711
-
1712
-
1713
-
1714
- // src/eventStore/schema/index.ts
1715
-
1716
-
1717
-
1718
-
1719
-
1720
-
1721
- // src/eventStore/schema/appendToStream.ts
1722
-
1723
-
1724
-
1725
-
1726
-
1727
-
1728
-
1729
- var appendToStreamSQL = createFunctionIfDoesNotExistSQL(
1730
- "emt_append_to_stream",
1731
- _dumbo.SQL`CREATE OR REPLACE FUNCTION emt_append_to_stream(
1732
- v_message_ids text[],
1733
- v_messages_data jsonb[],
1734
- v_messages_metadata jsonb[],
1735
- v_message_schema_versions text[],
1736
- v_message_types text[],
1737
- v_message_kinds text[],
1738
- v_stream_id text,
1739
- v_stream_type text,
1740
- v_expected_stream_position bigint DEFAULT NULL,
1741
- v_partition text DEFAULT emt_sanitize_name('default_partition')
1742
- ) RETURNS TABLE (
1743
- success boolean,
1744
- next_stream_position bigint,
1745
- global_positions bigint[],
1746
- transaction_id xid8
1747
- ) LANGUAGE plpgsql
1748
- AS $emt_append_to_stream$
1749
- DECLARE
1750
- v_next_stream_position bigint;
1751
- v_position bigint;
1752
- v_updated_rows int;
1753
- v_transaction_id xid8;
1754
- v_global_positions bigint[];
1755
- BEGIN
1756
- v_transaction_id := pg_current_xact_id();
1757
-
1758
- IF v_expected_stream_position IS NULL THEN
1759
- SELECT COALESCE(
1760
- (SELECT stream_position
1761
- FROM ${_dumbo.SQL.identifier(streamsTable.name)}
1762
- WHERE stream_id = v_stream_id
1763
- AND partition = v_partition
1764
- AND is_archived = FALSE
1765
- LIMIT 1),
1766
- 0
1767
- ) INTO v_expected_stream_position;
1768
- END IF;
1769
-
1770
- v_next_stream_position := v_expected_stream_position + array_upper(v_messages_data, 1);
1771
-
1772
- IF v_expected_stream_position = 0 THEN
1773
- INSERT INTO ${_dumbo.SQL.identifier(streamsTable.name)}
1774
- (stream_id, stream_position, partition, stream_type, stream_metadata, is_archived)
1775
- VALUES
1776
- (v_stream_id, v_next_stream_position, v_partition, v_stream_type, '{}', FALSE);
1777
- ELSE
1778
- UPDATE ${_dumbo.SQL.identifier(streamsTable.name)} as s
1779
- SET stream_position = v_next_stream_position
1780
- WHERE stream_id = v_stream_id AND stream_position = v_expected_stream_position AND partition = v_partition AND is_archived = FALSE;
1781
-
1782
- get diagnostics v_updated_rows = row_count;
1783
-
1784
- IF v_updated_rows = 0 THEN
1785
- RETURN QUERY SELECT FALSE, NULL::bigint, NULL::bigint[], NULL::xid8;
1786
- RETURN;
1787
- END IF;
1788
- END IF;
1789
-
1790
- WITH ev AS (
1791
- SELECT row_number() OVER () + v_expected_stream_position AS stream_position,
1792
- message_data,
1793
- message_metadata,
1794
- schema_version,
1795
- message_id,
1796
- message_type,
1797
- message_kind
1798
- FROM (
1799
- SELECT *
1800
- FROM
1801
- unnest(v_message_ids, v_messages_data, v_messages_metadata, v_message_schema_versions, v_message_types, v_message_kinds)
1802
- AS message(message_id, message_data, message_metadata, schema_version, message_type, message_kind)
1803
- ) AS message
1804
- ),
1805
- all_messages_insert AS (
1806
- INSERT INTO ${_dumbo.SQL.identifier(messagesTable.name)}
1807
- (stream_id, stream_position, partition, message_data, message_metadata, message_schema_version, message_type, message_kind, message_id, transaction_id)
1808
- SELECT
1809
- v_stream_id, ev.stream_position, v_partition, ev.message_data, ev.message_metadata, ev.schema_version, ev.message_type, ev.message_kind, ev.message_id, v_transaction_id
1810
- FROM ev
1811
- RETURNING global_position
1812
- )
1813
- SELECT
1814
- array_agg(global_position ORDER BY global_position) INTO v_global_positions
1815
- FROM
1816
- all_messages_insert;
1817
-
1818
- RETURN QUERY SELECT TRUE, v_next_stream_position, v_global_positions, v_transaction_id;
1819
- END;
1820
- $emt_append_to_stream$;
1821
- `
1822
- );
1823
- var callAppendToStream = (params) => _dumbo.SQL`SELECT * FROM emt_append_to_stream(
1824
- ${params.messageIds},
1825
- ${params.messagesData},
1826
- ${params.messagesMetadata},
1827
- ${params.schemaVersions},
1828
- ${params.messageTypes},
1829
- ${params.messageKinds},
1830
- ${params.streamId}::text,
1831
- ${params.streamType}::text,
1832
- ${params.expectedStreamPosition},
1833
- ${params.partition}::text
1834
- )`;
1835
- var appendToStream = (pool, streamName, streamType, messages, options) => pool.withTransaction(async (transaction) => {
1836
- const { execute } = transaction;
1837
- if (messages.length === 0)
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
+
2357
+ var appendToStreamSQL = createFunctionIfDoesNotExistSQL(
2358
+ "emt_append_to_stream",
2359
+ _dumbo.SQL`CREATE OR REPLACE FUNCTION emt_append_to_stream(
2360
+ v_message_ids text[],
2361
+ v_messages_data jsonb[],
2362
+ v_messages_metadata jsonb[],
2363
+ v_message_schema_versions text[],
2364
+ v_message_types text[],
2365
+ v_message_kinds text[],
2366
+ v_stream_id text,
2367
+ v_stream_type text,
2368
+ v_expected_stream_position bigint DEFAULT NULL,
2369
+ v_partition text DEFAULT emt_sanitize_name('default_partition')
2370
+ ) RETURNS TABLE (
2371
+ success boolean,
2372
+ next_stream_position bigint,
2373
+ global_positions bigint[],
2374
+ transaction_id xid8
2375
+ ) LANGUAGE plpgsql
2376
+ AS $emt_append_to_stream$
2377
+ DECLARE
2378
+ v_next_stream_position bigint;
2379
+ v_position bigint;
2380
+ v_updated_rows int;
2381
+ v_transaction_id xid8;
2382
+ v_global_positions bigint[];
2383
+ BEGIN
2384
+ v_transaction_id := pg_current_xact_id();
2385
+
2386
+ IF v_expected_stream_position IS NULL THEN
2387
+ SELECT COALESCE(
2388
+ (SELECT stream_position
2389
+ FROM ${_dumbo.SQL.identifier(streamsTable.name)}
2390
+ WHERE stream_id = v_stream_id
2391
+ AND partition = v_partition
2392
+ AND is_archived = FALSE
2393
+ LIMIT 1),
2394
+ 0
2395
+ ) INTO v_expected_stream_position;
2396
+ END IF;
2397
+
2398
+ v_next_stream_position := v_expected_stream_position + array_upper(v_messages_data, 1);
2399
+
2400
+ IF v_expected_stream_position = 0 THEN
2401
+ INSERT INTO ${_dumbo.SQL.identifier(streamsTable.name)}
2402
+ (stream_id, stream_position, partition, stream_type, stream_metadata, is_archived)
2403
+ VALUES
2404
+ (v_stream_id, v_next_stream_position, v_partition, v_stream_type, '{}', FALSE);
2405
+ ELSE
2406
+ UPDATE ${_dumbo.SQL.identifier(streamsTable.name)} as s
2407
+ SET stream_position = v_next_stream_position
2408
+ WHERE stream_id = v_stream_id AND stream_position = v_expected_stream_position AND partition = v_partition AND is_archived = FALSE;
2409
+
2410
+ get diagnostics v_updated_rows = row_count;
2411
+
2412
+ IF v_updated_rows = 0 THEN
2413
+ RETURN QUERY SELECT FALSE, NULL::bigint, NULL::bigint[], NULL::xid8;
2414
+ RETURN;
2415
+ END IF;
2416
+ END IF;
2417
+
2418
+ WITH ev AS (
2419
+ SELECT row_number() OVER () + v_expected_stream_position AS stream_position,
2420
+ message_data,
2421
+ message_metadata,
2422
+ schema_version,
2423
+ message_id,
2424
+ message_type,
2425
+ message_kind
2426
+ FROM (
2427
+ SELECT *
2428
+ FROM
2429
+ unnest(v_message_ids, v_messages_data, v_messages_metadata, v_message_schema_versions, v_message_types, v_message_kinds)
2430
+ AS message(message_id, message_data, message_metadata, schema_version, message_type, message_kind)
2431
+ ) AS message
2432
+ ),
2433
+ all_messages_insert AS (
2434
+ INSERT INTO ${_dumbo.SQL.identifier(messagesTable.name)}
2435
+ (stream_id, stream_position, partition, message_data, message_metadata, message_schema_version, message_type, message_kind, message_id, transaction_id)
2436
+ SELECT
2437
+ v_stream_id, ev.stream_position, v_partition, ev.message_data, ev.message_metadata, ev.schema_version, ev.message_type, ev.message_kind, ev.message_id, v_transaction_id
2438
+ FROM ev
2439
+ RETURNING global_position
2440
+ )
2441
+ SELECT
2442
+ array_agg(global_position ORDER BY global_position) INTO v_global_positions
2443
+ FROM
2444
+ all_messages_insert;
2445
+
2446
+ RETURN QUERY SELECT TRUE, v_next_stream_position, v_global_positions, v_transaction_id;
2447
+ END;
2448
+ $emt_append_to_stream$;
2449
+ `
2450
+ );
2451
+ var callAppendToStream = (params) => _dumbo.SQL`SELECT * FROM emt_append_to_stream(
2452
+ ${params.messageIds},
2453
+ ${params.messagesData},
2454
+ ${params.messagesMetadata},
2455
+ ${params.schemaVersions},
2456
+ ${params.messageTypes},
2457
+ ${params.messageKinds},
2458
+ ${params.streamId}::text,
2459
+ ${params.streamType}::text,
2460
+ ${params.expectedStreamPosition},
2461
+ ${params.partition}::text
2462
+ )`;
2463
+ var appendToStream = (pool, streamName, streamType, messages, options) => pool.withTransaction(async (transaction) => {
2464
+ const { execute } = transaction;
2465
+ if (messages.length === 0)
1838
2466
  return { success: false, result: { success: false } };
1839
2467
  try {
1840
2468
  const expectedStreamVersion = toExpectedVersion(
1841
- _optionalChain([options, 'optionalAccess', _48 => _48.expectedStreamVersion])
2469
+ _optionalChain([options, 'optionalAccess', _78 => _78.expectedStreamVersion])
1842
2470
  );
1843
2471
  const messagesToAppend = messages.map((e) => ({
1844
2472
  ...e,
@@ -1878,7 +2506,7 @@ var appendToStream = (pool, streamName, streamType, messages, options) => pool.w
1878
2506
  globalPosition
1879
2507
  };
1880
2508
  });
1881
- if (_optionalChain([options, 'optionalAccess', _49 => _49.beforeCommitHook]))
2509
+ if (_optionalChain([options, 'optionalAccess', _79 => _79.beforeCommitHook]))
1882
2510
  await options.beforeCommitHook(messagesToAppend, { transaction });
1883
2511
  return {
1884
2512
  success: true,
@@ -1921,8 +2549,8 @@ var appendEventsRaw = (execute, streamId, streamType, messages, options) => _dum
1921
2549
  messageKinds: messages.map((e) => e.kind === "Event" ? "E" : "C"),
1922
2550
  streamId,
1923
2551
  streamType,
1924
- expectedStreamPosition: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _50 => _50.expectedStreamVersion]), () => ( null)),
1925
- partition: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _51 => _51.partition]), () => ( defaultTag2))
2552
+ expectedStreamPosition: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _80 => _80.expectedStreamVersion]), () => ( null)),
2553
+ partition: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _81 => _81.partition]), () => ( defaultTag2))
1926
2554
  })
1927
2555
  )
1928
2556
  );
@@ -3938,632 +4566,387 @@ var addTenantForAllModulesSQL = _dumbo.SQL`
3938
4566
  EXECUTE format('
3939
4567
  CREATE TABLE IF NOT EXISTS %I PARTITION OF %I
3940
4568
  FOR VALUES IN (emt_sanitize_name(''%s__%s'')) PARTITION BY LIST (is_archived);',
3941
- emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant), '${_dumbo.SQL.plain(messagesTable.name)}', module_record.partitionname, new_tenant
3942
- );
3943
-
3944
- EXECUTE format('
3945
- CREATE TABLE IF NOT EXISTS %I_active PARTITION OF %I
3946
- FOR VALUES IN (FALSE);',
3947
- emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant || '_active'), emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant)
3948
- );
3949
-
3950
- EXECUTE format('
3951
- CREATE TABLE IF NOT EXISTS %I_archived PARTITION OF %I
3952
- FOR VALUES IN (TRUE);',
3953
- emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant || '_archived'), emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant)
3954
- );
3955
-
3956
- -- For ${_dumbo.SQL.plain(streamsTable.name)} table
3957
- EXECUTE format('
3958
- CREATE TABLE IF NOT EXISTS %I PARTITION OF %I
3959
- FOR VALUES IN (emt_sanitize_name(''%s__%s'')) PARTITION BY LIST (is_archived);',
3960
- emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant), '${_dumbo.SQL.plain(streamsTable.name)}', module_record.partitionname, new_tenant
3961
- );
3962
-
3963
- EXECUTE format('
3964
- CREATE TABLE IF NOT EXISTS %I_active PARTITION OF %I
3965
- FOR VALUES IN (FALSE);',
3966
- emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant || '_active'), emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant)
3967
- );
3968
-
3969
- EXECUTE format('
3970
- CREATE TABLE IF NOT EXISTS %I_archived PARTITION OF %I
3971
- FOR VALUES IN (TRUE);',
3972
- emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant || '_archived'), emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant)
3973
- );
3974
- END LOOP;
3975
- END;
3976
- $$ LANGUAGE plpgsql;
3977
- `;
3978
- var addDefaultPartitionSQL = _dumbo.SQL`SELECT emt_add_partition('${_dumbo.SQL.plain(defaultTag2)}');`;
3979
-
3980
- // src/eventStore/schema/readProcessorCheckpoint.ts
3981
-
3982
- var readProcessorCheckpoint = async (execute, options) => {
3983
- const result = await _dumbo.singleOrNull.call(void 0,
3984
- execute.query(
3985
- _dumbo.SQL`SELECT last_processed_checkpoint
3986
- FROM ${_dumbo.SQL.identifier(processorsTable.name)}
3987
- WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _52 => _52.partition]), () => ( defaultTag2))} AND processor_id = ${options.processorId} AND version = ${_nullishCoalesce(options.version, () => ( 1))}
3988
- LIMIT 1`
3989
- )
3990
- );
3991
- return {
3992
- lastProcessedCheckpoint: result !== null ? result.last_processed_checkpoint : null
3993
- };
3994
- };
3995
-
3996
- // src/eventStore/schema/readStream.ts
3997
-
3998
- var readStream = async (execute, streamId, options) => {
3999
- const fromCondition = _optionalChain([options, 'optionalAccess', _53 => _53.from]) ? `AND stream_position >= ${options.from}` : "";
4000
- const to = Number(
4001
- _nullishCoalesce(_optionalChain([options, 'optionalAccess', _54 => _54.to]), () => ( (_optionalChain([options, 'optionalAccess', _55 => _55.maxCount]) ? (_nullishCoalesce(options.from, () => ( 0n))) + options.maxCount : NaN)))
4002
- );
4003
- const toCondition = !isNaN(to) ? `AND stream_position <= ${to}` : "";
4004
- const events = await _dumbo.mapRows.call(void 0,
4005
- execute.query(
4006
- _dumbo.SQL`SELECT stream_id, stream_position, global_position, message_data, message_metadata, message_schema_version, message_type, message_id
4007
- FROM ${_dumbo.SQL.identifier(messagesTable.name)}
4008
- WHERE stream_id = ${streamId} AND partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _56 => _56.partition]), () => ( defaultTag2))} AND is_archived = FALSE ${_dumbo.SQL.plain(fromCondition)} ${_dumbo.SQL.plain(toCondition)}
4009
- ORDER BY stream_position ASC`
4010
- ),
4011
- (row) => {
4012
- const rawEvent = {
4013
- type: row.message_type,
4014
- data: row.message_data,
4015
- metadata: row.message_metadata
4016
- };
4017
- const metadata = {
4018
- ..."metadata" in rawEvent ? _nullishCoalesce(rawEvent.metadata, () => ( {})) : {},
4019
- messageId: row.message_id,
4020
- streamName: streamId,
4021
- streamPosition: BigInt(row.stream_position),
4022
- globalPosition: BigInt(row.global_position),
4023
- checkpoint: bigIntProcessorCheckpoint(BigInt(row.global_position))
4024
- };
4025
- const event = {
4026
- ...rawEvent,
4027
- kind: "Event",
4028
- metadata
4029
- };
4030
- return upcastRecordedMessage(event, _optionalChain([options, 'optionalAccess', _57 => _57.schema, 'optionalAccess', _58 => _58.versioning]));
4031
- }
4032
- );
4033
- return events.length > 0 ? {
4034
- currentStreamVersion: events[events.length - 1].metadata.streamPosition,
4035
- events,
4036
- streamExists: true
4037
- } : {
4038
- currentStreamVersion: PostgreSQLEventStoreDefaultStreamVersion,
4039
- events: [],
4040
- streamExists: false
4041
- };
4042
- };
4043
-
4044
- // src/eventStore/schema/streamExists.ts
4045
-
4046
- var streamExists = async (execute, streamId, options) => {
4047
- const queryResult = await execute.query(
4048
- _dumbo.SQL`SELECT EXISTS (
4049
- SELECT 1
4050
- from ${_dumbo.SQL.identifier(streamsTable.name)}
4051
- WHERE stream_id = ${streamId} AND partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _59 => _59.partition]), () => ( defaultTag2))} AND is_archived = FALSE)
4052
- `
4053
- );
4054
- return _nullishCoalesce(_optionalChain([queryResult, 'access', _60 => _60.rows, 'access', _61 => _61[0], 'optionalAccess', _62 => _62.exists]), () => ( false));
4055
- };
4056
-
4057
- // src/eventStore/schema/index.ts
4058
- var schemaSQL = [
4059
- streamsTableSQL,
4060
- messagesTableSQL,
4061
- projectionsTableSQL,
4062
- processorsTableSQL,
4063
- sanitizeNameSQL,
4064
- addTablePartitions,
4065
- addPartitionSQL,
4066
- appendToStreamSQL,
4067
- addDefaultPartitionSQL,
4068
- storeSubscriptionCheckpointSQL,
4069
- tryAcquireProcessorLockSQL,
4070
- releaseProcessorLockSQL,
4071
- registerProjectionSQL,
4072
- activateProjectionSQL,
4073
- deactivateProjectionSQL
4074
- ];
4075
- var schemaMigration = _dumbo.sqlMigration.call(void 0,
4076
- "emt:postgresql:eventstore:initial",
4077
- schemaSQL
4078
- );
4079
- var eventStoreSchemaMigrations = [
4080
- migration_0_38_7_and_older,
4081
- migration_0_42_0_FromSubscriptionsToProcessors,
4082
- migration_0_42_0_2_AddProcessorProjectionFunctions,
4083
- schemaMigration
4084
- ];
4085
- var createEventStoreSchema = (connectionString, pool, hooks, options) => {
4086
- return pool.withTransaction(async (tx) => {
4087
- const context = await transactionToPostgreSQLProjectionHandlerContext(
4088
- connectionString,
4089
- pool,
4090
- tx
4091
- );
4092
- const nestedPool = _dumbo.dumbo.call(void 0, { connectionString, connection: tx.connection });
4093
- try {
4094
- if (_optionalChain([hooks, 'optionalAccess', _63 => _63.onBeforeSchemaCreated])) {
4095
- await hooks.onBeforeSchemaCreated(context);
4096
- }
4097
- const result = await _dumbo.runSQLMigrations.call(void 0,
4098
- nestedPool,
4099
- eventStoreSchemaMigrations,
4100
- options
4101
- );
4102
- if (_optionalChain([hooks, 'optionalAccess', _64 => _64.onAfterSchemaCreated])) {
4103
- await hooks.onAfterSchemaCreated(context);
4104
- }
4105
- return result;
4106
- } finally {
4107
- await nestedPool.close();
4108
- }
4109
- });
4110
- };
4111
-
4112
- // src/eventStore/schema/truncateTables.ts
4569
+ emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant), '${_dumbo.SQL.plain(messagesTable.name)}', module_record.partitionname, new_tenant
4570
+ );
4571
+
4572
+ EXECUTE format('
4573
+ CREATE TABLE IF NOT EXISTS %I_active PARTITION OF %I
4574
+ FOR VALUES IN (FALSE);',
4575
+ emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant || '_active'), emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant)
4576
+ );
4577
+
4578
+ EXECUTE format('
4579
+ CREATE TABLE IF NOT EXISTS %I_archived PARTITION OF %I
4580
+ FOR VALUES IN (TRUE);',
4581
+ emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant || '_archived'), emt_sanitize_name('${_dumbo.SQL.plain(messagesTable.name)}_' || module_record.partitionname || '__' || new_tenant)
4582
+ );
4583
+
4584
+ -- For ${_dumbo.SQL.plain(streamsTable.name)} table
4585
+ EXECUTE format('
4586
+ CREATE TABLE IF NOT EXISTS %I PARTITION OF %I
4587
+ FOR VALUES IN (emt_sanitize_name(''%s__%s'')) PARTITION BY LIST (is_archived);',
4588
+ emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant), '${_dumbo.SQL.plain(streamsTable.name)}', module_record.partitionname, new_tenant
4589
+ );
4590
+
4591
+ EXECUTE format('
4592
+ CREATE TABLE IF NOT EXISTS %I_active PARTITION OF %I
4593
+ FOR VALUES IN (FALSE);',
4594
+ emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant || '_active'), emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant)
4595
+ );
4596
+
4597
+ EXECUTE format('
4598
+ CREATE TABLE IF NOT EXISTS %I_archived PARTITION OF %I
4599
+ FOR VALUES IN (TRUE);',
4600
+ emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant || '_archived'), emt_sanitize_name('${_dumbo.SQL.plain(streamsTable.name)}_' || module_record.partitionname || '__' || new_tenant)
4601
+ );
4602
+ END LOOP;
4603
+ END;
4604
+ $$ LANGUAGE plpgsql;
4605
+ `;
4606
+ var addDefaultPartitionSQL = _dumbo.SQL`SELECT emt_add_partition('${_dumbo.SQL.plain(defaultTag2)}');`;
4113
4607
 
4114
- var truncateTables = async (execute, options) => {
4115
- await execute.command(
4116
- _dumbo.SQL`TRUNCATE TABLE
4117
- ${_dumbo.SQL.identifier(streamsTable.name)},
4118
- ${_dumbo.SQL.identifier(messagesTable.name)},
4119
- ${_dumbo.SQL.identifier(processorsTable.name)},
4120
- ${_dumbo.SQL.identifier(projectionsTable.name)}
4121
- CASCADE${_dumbo.SQL.plain(_optionalChain([options, 'optionalAccess', _65 => _65.resetSequences]) ? "; ALTER SEQUENCE emt_global_message_position RESTART WITH 1" : "")};`
4122
- );
4123
- };
4608
+ // src/eventStore/schema/readProcessorCheckpoint.ts
4124
4609
 
4125
- // src/eventStore/postgreSQLEventStore.ts
4126
- var defaultPostgreSQLOptions = {
4127
- projections: [],
4128
- schema: { autoMigration: "CreateOrUpdate" }
4129
- };
4130
- var PostgreSQLEventStoreDefaultStreamVersion = 0n;
4131
- var getPostgreSQLEventStore = (connectionString, options = defaultPostgreSQLOptions) => {
4132
- const poolOptions = {
4133
- connectionString,
4134
- ...options.connectionOptions ? options.connectionOptions : {}
4135
- };
4136
- const pool = "dumbo" in poolOptions ? poolOptions.dumbo : _dumbo.dumbo.call(void 0, poolOptions);
4137
- let migrateSchema = void 0;
4138
- 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";
4139
- const inlineProjections = (_nullishCoalesce(options.projections, () => ( []))).filter(({ type }) => type === "inline").map(({ projection: projection2 }) => projection2);
4140
- const migrate = async (migrationOptions) => {
4141
- if (!migrateSchema) {
4142
- migrateSchema = createEventStoreSchema(
4143
- connectionString,
4144
- pool,
4145
- {
4146
- onBeforeSchemaCreated: async (context) => {
4147
- if (_optionalChain([options, 'access', _70 => _70.hooks, 'optionalAccess', _71 => _71.onBeforeSchemaCreated])) {
4148
- await options.hooks.onBeforeSchemaCreated(context);
4149
- }
4150
- },
4151
- onAfterSchemaCreated: async (context) => {
4152
- for (const projection2 of inlineProjections) {
4153
- if (projection2.init) {
4154
- await projection2.init({
4155
- version: _nullishCoalesce(projection2.version, () => ( 1)),
4156
- status: "active",
4157
- registrationType: "inline",
4158
- context: { ...context, migrationOptions }
4159
- });
4160
- }
4161
- }
4162
- if (_optionalChain([options, 'access', _72 => _72.hooks, 'optionalAccess', _73 => _73.onAfterSchemaCreated])) {
4163
- await options.hooks.onAfterSchemaCreated(context);
4164
- }
4165
- }
4166
- },
4167
- migrationOptions
4168
- );
4169
- }
4170
- return migrateSchema;
4171
- };
4172
- const ensureSchemaExists = () => {
4173
- if (!autoGenerateSchema) return Promise.resolve();
4174
- return migrate();
4175
- };
4176
- const beforeCommitHook = inlineProjections.length > 0 ? async (events, { transaction }) => handleProjections({
4177
- projections: inlineProjections,
4178
- // TODO: Add proper handling of global data
4179
- // Currently it's not available as append doesn't return array of global position but just the last one
4180
- events,
4181
- ...await transactionToPostgreSQLProjectionHandlerContext(
4182
- connectionString,
4183
- pool,
4184
- transaction
4610
+ var readProcessorCheckpoint = async (execute, options) => {
4611
+ const result = await _dumbo.singleOrNull.call(void 0,
4612
+ execute.query(
4613
+ _dumbo.SQL`SELECT last_processed_checkpoint
4614
+ FROM ${_dumbo.SQL.identifier(processorsTable.name)}
4615
+ WHERE partition = ${_nullishCoalesce(_optionalChain([options, 'optionalAccess', _82 => _82.partition]), () => ( defaultTag2))} AND processor_id = ${options.processorId} AND version = ${_nullishCoalesce(options.version, () => ( 1))}
4616
+ LIMIT 1`
4185
4617
  )
4186
- }) : void 0;
4618
+ );
4187
4619
  return {
4188
- schema: {
4189
- sql: () => _dumbo.SQL.describe(
4190
- schemaSQL,
4191
- _dumbo.getFormatter.call(void 0, _dumbo.fromDatabaseDriverType.call(void 0, pool.driverType).databaseType)
4192
- ),
4193
- print: () => console.log(
4194
- _dumbo.SQL.describe(
4195
- schemaSQL,
4196
- _dumbo.getFormatter.call(void 0, _dumbo.fromDatabaseDriverType.call(void 0, pool.driverType).databaseType)
4197
- )
4198
- ),
4199
- migrate,
4200
- dangerous: {
4201
- truncate: (truncateOptions) => pool.withTransaction(async (transaction) => {
4202
- await ensureSchemaExists();
4203
- await truncateTables(transaction.execute, truncateOptions);
4204
- if (_optionalChain([truncateOptions, 'optionalAccess', _74 => _74.truncateProjections])) {
4205
- const projectionContext = await transactionToPostgreSQLProjectionHandlerContext(
4206
- connectionString,
4207
- pool,
4208
- transaction
4209
- );
4210
- for (const projection2 of _nullishCoalesce(_optionalChain([options, 'optionalAccess', _75 => _75.projections]), () => ( []))) {
4211
- if (projection2.projection.truncate)
4212
- await projection2.projection.truncate(projectionContext);
4213
- }
4214
- }
4215
- })
4216
- }
4217
- },
4218
- async aggregateStream(streamName, options2) {
4219
- const { evolve, initialState, read } = options2;
4220
- const expectedStreamVersion = _optionalChain([read, 'optionalAccess', _76 => _76.expectedStreamVersion]);
4221
- let state = initialState();
4222
- const result = await this.readStream(
4223
- streamName,
4224
- read
4225
- );
4226
- const currentStreamVersion = result.currentStreamVersion;
4227
- assertExpectedVersionMatchesCurrent(
4228
- currentStreamVersion,
4229
- expectedStreamVersion,
4230
- PostgreSQLEventStoreDefaultStreamVersion
4231
- );
4232
- for (const event of result.events) {
4233
- if (!event) continue;
4234
- state = evolve(state, event);
4235
- }
4236
- return {
4237
- currentStreamVersion,
4238
- state,
4239
- streamExists: result.streamExists
4240
- };
4241
- },
4242
- readStream: async (streamName, options2) => {
4243
- await ensureSchemaExists();
4244
- return readStream(
4245
- pool.execute,
4246
- streamName,
4247
- options2
4248
- );
4249
- },
4250
- appendToStream: async (streamName, events, options2) => {
4251
- await ensureSchemaExists();
4252
- const [firstPart, ...rest] = streamName.split("-");
4253
- const streamType = firstPart && rest.length > 0 ? firstPart : unknownTag2;
4254
- const appendResult = await appendToStream(
4255
- // TODO: Fix this when introducing more drivers
4256
- pool,
4257
- streamName,
4258
- streamType,
4259
- downcastRecordedMessages(events, _optionalChain([options2, 'optionalAccess', _77 => _77.schema, 'optionalAccess', _78 => _78.versioning])),
4260
- {
4261
- ...options2,
4262
- beforeCommitHook
4263
- }
4264
- );
4265
- if (!appendResult.success)
4266
- throw new ExpectedVersionConflictError(
4267
- -1n,
4268
- //TODO: Return actual version in case of error
4269
- _nullishCoalesce(_optionalChain([options2, 'optionalAccess', _79 => _79.expectedStreamVersion]), () => ( NO_CONCURRENCY_CHECK))
4270
- );
4271
- return {
4272
- nextExpectedStreamVersion: appendResult.nextStreamPosition,
4273
- lastEventGlobalPosition: appendResult.globalPositions[appendResult.globalPositions.length - 1],
4274
- createdNewStream: appendResult.nextStreamPosition >= BigInt(events.length)
4275
- };
4276
- },
4277
- streamExists: async (streamName, options2) => {
4278
- await ensureSchemaExists();
4279
- return streamExists(pool.execute, streamName, options2);
4280
- },
4281
- consumer: (options2) => postgreSQLEventStoreConsumer({
4282
- ..._nullishCoalesce(options2, () => ( {})),
4283
- pool,
4284
- connectionString
4285
- }),
4286
- close: () => pool.close(),
4287
- async withSession(callback) {
4288
- return await pool.withConnection(async (connection) => {
4289
- const storeOptions = {
4290
- ...options,
4291
- connectionOptions: {
4292
- connection
4293
- },
4294
- schema: {
4295
- ..._nullishCoalesce(options.schema, () => ( {})),
4296
- autoMigration: "None"
4297
- }
4298
- };
4299
- const eventStore = getPostgreSQLEventStore(
4300
- connectionString,
4301
- storeOptions
4302
- );
4303
- return ensureSchemaExists().then(
4304
- () => callback({
4305
- eventStore,
4306
- close: () => Promise.resolve()
4307
- })
4308
- );
4309
- });
4310
- }
4620
+ lastProcessedCheckpoint: result !== null ? result.last_processed_checkpoint : null
4311
4621
  };
4312
4622
  };
4313
4623
 
4314
- // src/eventStore/projections/postgresProjectionSpec.ts
4315
- var PostgreSQLProjectionSpec = {
4316
- for: (options) => {
4317
- {
4318
- const { projection: projection2, ...dumoOptions } = options;
4319
- const { connectionString } = dumoOptions;
4320
- let wasInitialised = false;
4321
- const initialize = async (pool) => {
4322
- const eventStore = getPostgreSQLEventStore(connectionString, {
4323
- // TODO: This will need to change when we support other drivers
4324
- connectionOptions: { dumbo: pool }
4325
- });
4326
- if (wasInitialised) return;
4327
- wasInitialised = true;
4328
- await eventStore.schema.migrate();
4329
- if (projection2.init)
4330
- await pool.withTransaction(async (transaction) => {
4331
- await projection2.init({
4332
- registrationType: "async",
4333
- version: _nullishCoalesce(projection2.version, () => ( 1)),
4334
- status: "active",
4335
- context: await transactionToPostgreSQLProjectionHandlerContext(
4336
- connectionString,
4337
- pool,
4338
- transaction
4339
- )
4340
- });
4341
- });
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
4342
4644
  };
4343
- return (givenEvents) => {
4344
- return {
4345
- when: (events, options2) => {
4346
- const allEvents = [];
4347
- const run = async (pool) => {
4348
- let globalPosition = 0n;
4349
- const numberOfTimes = _nullishCoalesce(_optionalChain([options2, 'optionalAccess', _80 => _80.numberOfTimes]), () => ( 1));
4350
- for (const event of [
4351
- ...givenEvents,
4352
- ...Array.from({ length: numberOfTimes }).flatMap(() => events)
4353
- ]) {
4354
- const metadata = {
4355
- checkpoint: bigIntProcessorCheckpoint(++globalPosition),
4356
- globalPosition,
4357
- streamPosition: globalPosition,
4358
- streamName: `test-${_uuid.v4.call(void 0, )}`,
4359
- messageId: _uuid.v4.call(void 0, )
4360
- };
4361
- allEvents.push({
4362
- ...event,
4363
- kind: "Event",
4364
- metadata: {
4365
- ...metadata,
4366
- ..."metadata" in event ? _nullishCoalesce(event.metadata, () => ( {})) : {}
4367
- }
4368
- });
4369
- }
4370
- await initialize(pool);
4371
- await pool.withTransaction(async (transaction) => {
4372
- await handleProjections({
4373
- events: allEvents,
4374
- projections: [projection2],
4375
- ...await transactionToPostgreSQLProjectionHandlerContext(
4376
- connectionString,
4377
- pool,
4378
- transaction
4379
- )
4380
- });
4381
- });
4382
- };
4383
- return {
4384
- then: async (assert, message) => {
4385
- const pool = _dumbo.dumbo.call(void 0, dumoOptions);
4386
- try {
4387
- await run(pool);
4388
- const succeeded = await assert({ pool, connectionString });
4389
- if (succeeded !== void 0 && succeeded === false)
4390
- assertFails(
4391
- _nullishCoalesce(message, () => ( "Projection specification didn't match the criteria"))
4392
- );
4393
- } finally {
4394
- await pool.close();
4395
- }
4396
- },
4397
- thenThrows: async (...args) => {
4398
- const pool = _dumbo.dumbo.call(void 0, dumoOptions);
4399
- try {
4400
- await run(pool);
4401
- throw new AssertionError("Handler did not fail as expected");
4402
- } catch (error) {
4403
- if (error instanceof AssertionError) throw error;
4404
- if (args.length === 0) return;
4405
- if (!isErrorConstructor(args[0])) {
4406
- assertTrue(
4407
- args[0](error),
4408
- `Error didn't match the error condition: ${_optionalChain([error, 'optionalAccess', _81 => _81.toString, 'call', _82 => _82()])}`
4409
- );
4410
- return;
4411
- }
4412
- assertTrue(
4413
- error instanceof args[0],
4414
- `Caught error is not an instance of the expected type: ${_optionalChain([error, 'optionalAccess', _83 => _83.toString, 'call', _84 => _84()])}`
4415
- );
4416
- if (args[1]) {
4417
- assertTrue(
4418
- args[1](error),
4419
- `Error didn't match the error condition: ${_optionalChain([error, 'optionalAccess', _85 => _85.toString, 'call', _86 => _86()])}`
4420
- );
4421
- }
4422
- } finally {
4423
- await pool.close();
4424
- }
4425
- }
4426
- };
4427
- }
4428
- };
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))
4429
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]));
4430
4659
  }
4431
- }
4432
- };
4433
- var eventInStream = (streamName, event) => {
4434
- return {
4435
- ...event,
4436
- metadata: {
4437
- ..._nullishCoalesce(event.metadata, () => ( {})),
4438
- streamName: _nullishCoalesce(_optionalChain([event, 'access', _87 => _87.metadata, 'optionalAccess', _88 => _88.streamName]), () => ( streamName))
4439
- }
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
4440
4669
  };
4441
4670
  };
4442
- var eventsInStream = (streamName, events) => {
4443
- return events.map((e) => eventInStream(streamName, e));
4444
- };
4445
- var newEventsInStream = eventsInStream;
4446
- var assertSQLQueryResultMatches = (sql, rows) => async ({ pool: { execute } }) => {
4447
- const result = await execute.query(sql);
4448
- 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));
4449
4683
  };
4450
- var expectSQL = {
4451
- query: (sql) => ({
4452
- resultRows: {
4453
- 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();
4454
4740
  }
4455
- })
4741
+ });
4456
4742
  };
4457
4743
 
4458
- // src/eventStore/projections/postgreSQLProjection.ts
4459
- var transactionToPostgreSQLProjectionHandlerContext = async (connectionString, pool, transaction) => ({
4460
- execute: transaction.execute,
4461
- connection: {
4462
- connectionString,
4463
- client: await transaction.connection.open(),
4464
- transaction,
4465
- pool
4466
- }
4467
- });
4468
- var handleProjections = async (options) => {
4469
- const {
4470
- projections: allProjections,
4471
- events,
4472
- connection: { pool, transaction, connectionString },
4473
- partition = defaultTag2
4474
- } = options;
4475
- const eventTypes = events.map((e) => e.type);
4476
- const projections = allProjections.filter(
4477
- (p) => p.canHandle.some((type) => eventTypes.includes(type))
4744
+ // src/eventStore/schema/truncateTables.ts
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" : "")};`
4478
4754
  );
4479
- const client = await transaction.connection.open();
4480
- for (const projection2 of projections) {
4481
- if (projection2.name) {
4482
- const lockAcquired = await postgreSQLProjectionLock({
4483
- projectionName: projection2.name,
4484
- partition,
4485
- version: _nullishCoalesce(projection2.version, () => ( 1))
4486
- }).tryAcquire({ execute: transaction.execute });
4487
- if (!lockAcquired) {
4488
- continue;
4489
- }
4490
- }
4491
- await projection2.handle(events, {
4492
- connection: {
4755
+ };
4756
+
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 = {
4765
+ connectionString,
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(
4493
4775
  connectionString,
4494
4776
  pool,
4495
- client,
4496
- transaction
4497
- },
4498
- execute: transaction.execute
4499
- });
4500
- }
4501
- };
4502
- var postgreSQLProjection = (definition) => projection({
4503
- ...definition,
4504
- init: async (options) => {
4505
- await registerProjection(options.context.execute, {
4506
- // TODO: pass partition from options
4507
- partition: defaultTag2,
4508
- status: "active",
4509
- registration: {
4510
- type: "async",
4511
- // TODO: fix this
4512
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
4513
- projection: definition
4514
- }
4515
- });
4516
- if (definition.init) {
4517
- 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
+ );
4518
4801
  }
4519
- }
4520
- });
4521
- var postgreSQLRawBatchSQLProjection = (options) => postgreSQLProjection({
4522
- name: options.name,
4523
- kind: _nullishCoalesce(options.kind, () => ( "emt:projections:postgresql:raw_sql:batch")),
4524
- version: options.version,
4525
- canHandle: options.canHandle,
4526
- eventsOptions: options.eventsOptions,
4527
- handle: async (events, context) => {
4528
- const sqls = await options.evolve(events, context);
4529
- await context.execute.batchCommand(sqls);
4530
- },
4531
- init: async (initOptions) => {
4532
- const initSQL = options.init ? await options.init(initOptions) : void 0;
4533
- if (initSQL) {
4534
- if (Array.isArray(initSQL)) {
4535
- await initOptions.context.execute.batchCommand(initSQL);
4536
- } else {
4537
- 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
+ })
4538
4848
  }
4539
- }
4540
- }
4541
- });
4542
- var postgreSQLRawSQLProjection = (options) => {
4543
- const { evolve, kind, ...rest } = options;
4544
- return postgreSQLRawBatchSQLProjection({
4545
- kind: _nullishCoalesce(kind, () => ( "emt:projections:postgresql:raw:_sql:single")),
4546
- ...rest,
4547
- evolve: async (events, context) => {
4548
- const sqls = [];
4549
- for (const event of events) {
4550
- const pendingSqls = await evolve(event, context);
4551
- if (Array.isArray(pendingSqls)) {
4552
- sqls.push(...pendingSqls);
4553
- } else {
4554
- sqls.push(pendingSqls);
4555
- }
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);
4556
4867
  }
4557
- 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
+ });
4558
4941
  }
4559
- });
4942
+ };
4560
4943
  };
4561
4944
 
4562
4945
  // src/eventStore/consumers/postgreSQLProcessor.ts
4563
4946
  var postgreSQLCheckpointer = () => ({
4564
4947
  read: async (options, context) => {
4565
4948
  const result = await readProcessorCheckpoint(context.execute, options);
4566
- return { lastCheckpoint: _optionalChain([result, 'optionalAccess', _89 => _89.lastProcessedCheckpoint]) };
4949
+ return { lastCheckpoint: _optionalChain([result, 'optionalAccess', _112 => _112.lastProcessedCheckpoint]) };
4567
4950
  },
4568
4951
  store: async (options, context) => {
4569
4952
  const newCheckpoint = getCheckpoint(options.message);
@@ -4581,13 +4964,13 @@ var postgreSQLProcessingScope = (options) => {
4581
4964
  const processorConnectionString = options.connectionString;
4582
4965
  const processorPool = options.pool;
4583
4966
  const processingScope = async (handler, partialContext) => {
4584
- const connection = _optionalChain([partialContext, 'optionalAccess', _90 => _90.connection]);
4585
- 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])));
4586
4969
  if (!connectionString)
4587
4970
  throw new EmmettError(
4588
4971
  `PostgreSQL processor '${options.processorId}' is missing connection string. Ensure that you passed it through options`
4589
4972
  );
4590
- 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));
4591
4974
  if (!pool)
4592
4975
  throw new EmmettError(
4593
4976
  `PostgreSQL processor '${options.processorId}' is missing connection string. Ensure that you passed it through options`
@@ -4602,7 +4985,10 @@ var postgreSQLProcessingScope = (options) => {
4602
4985
  connectionString,
4603
4986
  pool,
4604
4987
  client,
4605
- transaction
4988
+ transaction,
4989
+ messageStore: getPostgreSQLEventStore(connectionString, {
4990
+ connectionOptions: { client }
4991
+ })
4606
4992
  }
4607
4993
  });
4608
4994
  });
@@ -4616,7 +5002,8 @@ var getProcessorPool = (options) => {
4616
5002
  const processorConnectionString = "connectionString" in poolOptions ? _nullishCoalesce(poolOptions.connectionString, () => ( null)) : null;
4617
5003
  const processorPool = "dumbo" in poolOptions ? poolOptions.dumbo : processorConnectionString ? _dumbo.dumbo.call(void 0, {
4618
5004
  connectionString: processorConnectionString,
4619
- ...poolOptions
5005
+ ...poolOptions,
5006
+ serialization: options.serialization
4620
5007
  }) : null;
4621
5008
  return {
4622
5009
  pool: processorPool,
@@ -4628,11 +5015,11 @@ var wrapHooksWithProcessorLocks = (hooks, processorLock) => ({
4628
5015
  ..._nullishCoalesce(hooks, () => ( {})),
4629
5016
  onStart: async (context) => {
4630
5017
  await processorLock.tryAcquire({ execute: context.execute });
4631
- if (_optionalChain([hooks, 'optionalAccess', _93 => _93.onStart])) await hooks.onStart(context);
5018
+ if (_optionalChain([hooks, 'optionalAccess', _116 => _116.onStart])) await hooks.onStart(context);
4632
5019
  },
4633
- onClose: _optionalChain([hooks, 'optionalAccess', _94 => _94.onClose]) || processorLock ? async (context) => {
5020
+ onClose: _optionalChain([hooks, 'optionalAccess', _117 => _117.onClose]) || processorLock ? async (context) => {
4634
5021
  await processorLock.release({ execute: context.execute });
4635
- if (_optionalChain([hooks, 'optionalAccess', _95 => _95.onClose])) await hooks.onClose(context);
5022
+ if (_optionalChain([hooks, 'optionalAccess', _118 => _118.onClose])) await hooks.onClose(context);
4636
5023
  } : void 0
4637
5024
  });
4638
5025
  var postgreSQLProjector = (options) => {
@@ -4657,13 +5044,13 @@ var postgreSQLProjector = (options) => {
4657
5044
  version: _nullishCoalesce(options.projection.version, () => ( version)),
4658
5045
  handlingType: "async"
4659
5046
  } : void 0,
4660
- lockAcquisitionPolicy: _nullishCoalesce(_optionalChain([lock, 'optionalAccess', _96 => _96.acquisitionPolicy]), () => ( DefaultPostgreSQLProcessorLockPolicy)),
4661
- lockTimeoutSeconds: _optionalChain([lock, 'optionalAccess', _97 => _97.timeoutSeconds])
5047
+ lockAcquisitionPolicy: _nullishCoalesce(_optionalChain([lock, 'optionalAccess', _119 => _119.acquisitionPolicy]), () => ( DefaultPostgreSQLProcessorLockPolicy)),
5048
+ lockTimeoutSeconds: _optionalChain([lock, 'optionalAccess', _120 => _120.timeoutSeconds])
4662
5049
  });
4663
5050
  const hooks = wrapHooksWithProcessorLocks(
4664
5051
  {
4665
5052
  ..._nullishCoalesce(options.hooks, () => ( {})),
4666
- onInit: options.projection.init !== void 0 || _optionalChain([options, 'access', _98 => _98.hooks, 'optionalAccess', _99 => _99.onInit]) ? async (context) => {
5053
+ onInit: options.projection.init !== void 0 || _optionalChain([options, 'access', _121 => _121.hooks, 'optionalAccess', _122 => _122.onInit]) ? async (context) => {
4667
5054
  if (options.projection.init)
4668
5055
  await options.projection.init({
4669
5056
  version: _nullishCoalesce(options.projection.version, () => ( version)),
@@ -4674,16 +5061,16 @@ var postgreSQLProjector = (options) => {
4674
5061
  migrationOptions: options.migrationOptions
4675
5062
  }
4676
5063
  });
4677
- if (_optionalChain([options, 'access', _100 => _100.hooks, 'optionalAccess', _101 => _101.onInit]))
5064
+ if (_optionalChain([options, 'access', _123 => _123.hooks, 'optionalAccess', _124 => _124.onInit]))
4678
5065
  await options.hooks.onInit({
4679
5066
  ...context,
4680
5067
  migrationOptions: options.migrationOptions
4681
5068
  });
4682
- } : _optionalChain([options, 'access', _102 => _102.hooks, 'optionalAccess', _103 => _103.onInit]),
5069
+ } : _optionalChain([options, 'access', _125 => _125.hooks, 'optionalAccess', _126 => _126.onInit]),
4683
5070
  onClose: close ? async (context) => {
4684
- if (_optionalChain([options, 'access', _104 => _104.hooks, 'optionalAccess', _105 => _105.onClose])) await _optionalChain([options, 'access', _106 => _106.hooks, 'optionalAccess', _107 => _107.onClose, 'call', _108 => _108(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)]);
4685
5072
  if (close) await close();
4686
- } : _optionalChain([options, 'access', _109 => _109.hooks, 'optionalAccess', _110 => _110.onClose])
5073
+ } : _optionalChain([options, 'access', _132 => _132.hooks, 'optionalAccess', _133 => _133.onClose])
4687
5074
  },
4688
5075
  processorLock
4689
5076
  );
@@ -4704,6 +5091,53 @@ var postgreSQLProjector = (options) => {
4704
5091
  });
4705
5092
  return processor;
4706
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
+ };
4707
5141
  var postgreSQLReactor = (options) => {
4708
5142
  const {
4709
5143
  processorId = options.processorId,
@@ -4719,16 +5153,16 @@ var postgreSQLReactor = (options) => {
4719
5153
  partition,
4720
5154
  processorInstanceId,
4721
5155
  projection: void 0,
4722
- lockAcquisitionPolicy: _nullishCoalesce(_optionalChain([lock, 'optionalAccess', _111 => _111.acquisitionPolicy]), () => ( DefaultPostgreSQLProcessorLockPolicy)),
4723
- lockTimeoutSeconds: _optionalChain([lock, 'optionalAccess', _112 => _112.timeoutSeconds])
5156
+ lockAcquisitionPolicy: _nullishCoalesce(_optionalChain([lock, 'optionalAccess', _143 => _143.acquisitionPolicy]), () => ( DefaultPostgreSQLProcessorLockPolicy)),
5157
+ lockTimeoutSeconds: _optionalChain([lock, 'optionalAccess', _144 => _144.timeoutSeconds])
4724
5158
  });
4725
5159
  const hooks = wrapHooksWithProcessorLocks(
4726
5160
  {
4727
5161
  ..._nullishCoalesce(options.hooks, () => ( {})),
4728
5162
  onClose: close ? async (context) => {
4729
- if (_optionalChain([options, 'access', _113 => _113.hooks, 'optionalAccess', _114 => _114.onClose])) await _optionalChain([options, 'access', _115 => _115.hooks, 'optionalAccess', _116 => _116.onClose, 'call', _117 => _117(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)]);
4730
5164
  if (close) await close();
4731
- } : _optionalChain([options, 'access', _118 => _118.hooks, 'optionalAccess', _119 => _119.onClose])
5165
+ } : _optionalChain([options, 'access', _150 => _150.hooks, 'optionalAccess', _151 => _151.onClose])
4732
5166
  },
4733
5167
  processorLock
4734
5168
  );
@@ -4758,7 +5192,10 @@ var postgreSQLEventStoreConsumer = (options) => {
4758
5192
  let abortController = null;
4759
5193
  let start;
4760
5194
  let messagePuller;
4761
- 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
+ });
4762
5199
  const eachBatch = async (messagesBatch) => {
4763
5200
  const activeProcessors = processors.filter((s) => s.isActive);
4764
5201
  if (activeProcessors.length === 0)
@@ -4777,7 +5214,7 @@ var postgreSQLEventStoreConsumer = (options) => {
4777
5214
  })
4778
5215
  );
4779
5216
  return result.some(
4780
- (r) => r.status === "fulfilled" && _optionalChain([r, 'access', _120 => _120.value, 'optionalAccess', _121 => _121.type]) !== "STOP"
5217
+ (r) => r.status === "fulfilled" && _optionalChain([r, 'access', _152 => _152.value, 'optionalAccess', _153 => _153.type]) !== "STOP"
4781
5218
  ) ? void 0 : {
4782
5219
  type: "STOP"
4783
5220
  };
@@ -4788,7 +5225,8 @@ var postgreSQLEventStoreConsumer = (options) => {
4788
5225
  connectionString: options.connectionString,
4789
5226
  pool,
4790
5227
  client: void 0,
4791
- transaction: void 0
5228
+ transaction: void 0,
5229
+ messageStore: void 0
4792
5230
  }
4793
5231
  };
4794
5232
  const stopProcessors = () => Promise.all(processors.map((p) => p.close(processorContext)));
@@ -4796,12 +5234,12 @@ var postgreSQLEventStoreConsumer = (options) => {
4796
5234
  if (!isRunning) return;
4797
5235
  isRunning = false;
4798
5236
  if (messagePuller) {
4799
- _optionalChain([abortController, 'optionalAccess', _122 => _122.abort, 'call', _123 => _123()]);
5237
+ _optionalChain([abortController, 'optionalAccess', _154 => _154.abort, 'call', _155 => _155()]);
4800
5238
  await messagePuller.stop();
4801
- messagePuller = void 0;
4802
- abortController = null;
4803
5239
  }
4804
5240
  await start;
5241
+ messagePuller = void 0;
5242
+ abortController = null;
4805
5243
  await stopProcessors();
4806
5244
  };
4807
5245
  const init = async () => {
@@ -4837,6 +5275,14 @@ var postgreSQLEventStoreConsumer = (options) => {
4837
5275
  );
4838
5276
  return processor;
4839
5277
  },
5278
+ workflowProcessor: (options2) => {
5279
+ const processor = postgreSQLWorkflowProcessor(options2);
5280
+ processors.push(
5281
+ // TODO: change that
5282
+ processor
5283
+ );
5284
+ return processor;
5285
+ },
4840
5286
  start: () => {
4841
5287
  if (isRunning) return start;
4842
5288
  if (processors.length === 0)
@@ -4849,8 +5295,8 @@ var postgreSQLEventStoreConsumer = (options) => {
4849
5295
  stopWhen: options.stopWhen,
4850
5296
  executor: pool.execute,
4851
5297
  eachBatch,
4852
- batchSize: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess', _124 => _124.batchSize]), () => ( DefaultPostgreSQLEventStoreProcessorBatchSize)),
4853
- pullingFrequencyInMs: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess', _125 => _125.pullingFrequencyInMs]), () => ( DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs)),
5298
+ batchSize: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess', _156 => _156.batchSize]), () => ( DefaultPostgreSQLEventStoreProcessorBatchSize)),
5299
+ pullingFrequencyInMs: _nullishCoalesce(_optionalChain([pulling, 'optionalAccess', _157 => _157.pullingFrequencyInMs]), () => ( DefaultPostgreSQLEventStoreProcessorPullingFrequencyInMs)),
4854
5300
  signal: abortController.signal
4855
5301
  });
4856
5302
  start = (async () => {
@@ -5014,5 +5460,6 @@ var rebuildPostgreSQLProjections = (options) => {
5014
5460
 
5015
5461
 
5016
5462
 
5017
- 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.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;
5463
+
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;
5018
5465
  //# sourceMappingURL=index.cjs.map