@event-driven-io/emmett-sqlite 0.43.0-beta.12 → 0.43.0-beta.13

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.js CHANGED
@@ -1,130 +1,3 @@
1
- // src/eventStore/projections/pongo/pongoProjections.ts
2
- import {
3
- pongoClient
4
- } from "@event-driven-io/pongo";
5
- var pongoProjection = ({
6
- name,
7
- kind,
8
- version,
9
- truncate,
10
- handle,
11
- canHandle,
12
- eventsOptions
13
- }) => sqliteProjection({
14
- name,
15
- version,
16
- kind: kind ?? "emt:projections:postgresql:pongo:generic",
17
- canHandle,
18
- eventsOptions,
19
- handle: async (events, context) => {
20
- const { connection } = context;
21
- const driver = await pongoDriverRegistry.tryResolve(
22
- context.driverType
23
- );
24
- const pongo = pongoClient({
25
- driver,
26
- connectionOptions: { connection }
27
- });
28
- try {
29
- await handle(events, {
30
- ...context,
31
- pongo
32
- });
33
- } finally {
34
- await pongo.close();
35
- }
36
- },
37
- truncate: truncate ? async (context) => {
38
- const { connection } = context;
39
- const driver = await pongoDriverRegistry.tryResolve(
40
- context.driverType
41
- );
42
- const pongo = pongoClient({
43
- driver,
44
- connectionOptions: { connection }
45
- });
46
- try {
47
- await truncate({
48
- ...context,
49
- pongo
50
- });
51
- } finally {
52
- await pongo.close();
53
- }
54
- } : void 0
55
- });
56
- var pongoMultiStreamProjection = (options) => {
57
- const { collectionName, getDocumentId, canHandle } = options;
58
- const collectionNameWithVersion = options.version && options.version > 0 ? `${collectionName}_v${options.version}` : collectionName;
59
- return pongoProjection({
60
- name: collectionNameWithVersion,
61
- version: options.version,
62
- kind: options.kind ?? "emt:projections:postgresql:pongo:multi_stream",
63
- eventsOptions: options.eventsOptions,
64
- handle: async (events, { pongo }) => {
65
- const collection = pongo.db().collection(
66
- collectionNameWithVersion,
67
- options.collectionOptions
68
- );
69
- for (const event of events) {
70
- await collection.handle(getDocumentId(event), async (document) => {
71
- return "initialState" in options ? await options.evolve(
72
- document ?? options.initialState(),
73
- event
74
- ) : await options.evolve(
75
- document,
76
- event
77
- );
78
- });
79
- }
80
- },
81
- canHandle,
82
- truncate: async (context) => {
83
- const { connection } = context;
84
- const driver = await pongoDriverRegistry.tryResolve(
85
- context.driverType
86
- );
87
- const pongo = pongoClient({
88
- driver,
89
- connectionOptions: { connection }
90
- });
91
- try {
92
- await pongo.db().collection(
93
- collectionNameWithVersion,
94
- options.collectionOptions
95
- ).deleteMany();
96
- } finally {
97
- await pongo.close();
98
- }
99
- },
100
- init: async (context) => {
101
- const { connection } = context;
102
- const driver = await pongoDriverRegistry.tryResolve(
103
- context.driverType
104
- );
105
- const pongo = pongoClient({
106
- connectionOptions: { connection },
107
- driver
108
- });
109
- try {
110
- await pongo.db().collection(
111
- collectionNameWithVersion,
112
- options.collectionOptions
113
- ).schema.migrate();
114
- } finally {
115
- await pongo.close();
116
- }
117
- }
118
- });
119
- };
120
- var pongoSingleStreamProjection = (options) => {
121
- return pongoMultiStreamProjection({
122
- ...options,
123
- kind: "emt:projections:postgresql:pongo:single_stream",
124
- getDocumentId: options.getDocumentId ?? ((event) => event.metadata.streamName)
125
- });
126
- };
127
-
128
1
  // ../emmett/dist/chunk-AZDDB5SF.js
129
2
  var isNumber = (val) => typeof val === "number" && val === val;
130
3
  var isString = (val) => typeof val === "string";
@@ -218,6 +91,13 @@ var isExpectedVersionConflictError = (error) => error instanceof ExpectedVersion
218
91
  error,
219
92
  ExpectedVersionConflictError.Codes.ConcurrencyError
220
93
  );
94
+ async function reduceAsync(items, fn, initial) {
95
+ let accumulator = initial;
96
+ for (let i = 0; i < items.length; i++) {
97
+ accumulator = await fn(accumulator, items[i], i);
98
+ }
99
+ return accumulator;
100
+ }
221
101
  var isPrimitive = (value) => {
222
102
  const type = typeof value;
223
103
  return value === null || value === void 0 || type === "boolean" || type === "number" || type === "string" || type === "symbol" || type === "bigint";
@@ -609,7 +489,40 @@ var reactor = (options) => {
609
489
  canHandle,
610
490
  stopAfter
611
491
  } = options;
612
- const eachMessage = "eachMessage" in options && options.eachMessage ? options.eachMessage : () => Promise.resolve();
492
+ const isCustomBatch = "eachBatch" in options && !!options.eachBatch;
493
+ const eachBatch = isCustomBatch ? options.eachBatch : async (messages, context) => {
494
+ let result = void 0;
495
+ for (let i = 0; i < messages.length; i++) {
496
+ const message2 = messages[i];
497
+ const messageProcessingResult = await options.eachMessage(
498
+ message2,
499
+ context
500
+ );
501
+ if (messageProcessingResult && messageProcessingResult.type === "STOP") {
502
+ result = {
503
+ ...messageProcessingResult,
504
+ lastSuccessfulMessage: messageProcessingResult.error ? messages[i - 1] : message2
505
+ };
506
+ break;
507
+ }
508
+ if (stopAfter && stopAfter(message2)) {
509
+ result = {
510
+ type: "STOP",
511
+ reason: "Stop condition reached",
512
+ lastSuccessfulMessage: message2
513
+ };
514
+ break;
515
+ }
516
+ if (messageProcessingResult && messageProcessingResult.type === "SKIP") {
517
+ result = {
518
+ ...messageProcessingResult,
519
+ lastSuccessfulMessage: message2
520
+ };
521
+ continue;
522
+ }
523
+ }
524
+ return result;
525
+ };
613
526
  let isInitiated = false;
614
527
  let isActive = false;
615
528
  let lastCheckpoint = null;
@@ -647,10 +560,11 @@ var reactor = (options) => {
647
560
  await init(startOptions);
648
561
  isActive = true;
649
562
  closeSignal = onShutdown(() => close(startOptions));
650
- if (lastCheckpoint !== null)
563
+ if (lastCheckpoint !== null) {
651
564
  return {
652
565
  lastCheckpoint
653
566
  };
567
+ }
654
568
  return await processingScope(async (context) => {
655
569
  if (hooks.onStart) {
656
570
  await hooks.onStart(context);
@@ -679,46 +593,48 @@ var reactor = (options) => {
679
593
  handle: async (messages, partialContext) => {
680
594
  if (!isActive) return Promise.resolve();
681
595
  return await processingScope(async (context) => {
682
- let result = void 0;
683
- for (const message2 of messages) {
684
- if (wasMessageHandled(message2, lastCheckpoint)) continue;
685
- const upcasted = upcastRecordedMessage(
596
+ const messagesAboveCheckpoint = messages.filter(
597
+ (message2) => !wasMessageHandled(message2, lastCheckpoint)
598
+ );
599
+ const upcastedMessages = messagesAboveCheckpoint.map(
600
+ (message2) => upcastRecordedMessage(
686
601
  // TODO: Make it smarter
687
602
  message2,
688
603
  options.messageOptions?.schema?.versioning
604
+ )
605
+ ).filter(
606
+ (upcasted) => !canHandle || canHandle.includes(upcasted.type)
607
+ );
608
+ const stopMessageIndex = isCustomBatch && stopAfter ? upcastedMessages.findIndex(stopAfter) : -1;
609
+ const unhandledMessages = stopMessageIndex !== -1 ? upcastedMessages.slice(0, stopMessageIndex + 1) : upcastedMessages;
610
+ const batchResult = await eachBatch(unhandledMessages, context);
611
+ const messageProcessingResult = batchResult?.type === "STOP" ? batchResult : stopMessageIndex !== -1 ? {
612
+ type: "STOP",
613
+ reason: "Stop condition reached",
614
+ lastSuccessfulMessage: unhandledMessages[stopMessageIndex]
615
+ } : batchResult;
616
+ const isStop = messageProcessingResult && messageProcessingResult.type === "STOP";
617
+ const checkpointMessage = messageProcessingResult?.type === "STOP" ? messageProcessingResult.lastSuccessfulMessage : messagesAboveCheckpoint[messagesAboveCheckpoint.length - 1];
618
+ if (checkpointMessage && checkpoints) {
619
+ const storeCheckpointResult = await checkpoints.store(
620
+ {
621
+ processorId,
622
+ version,
623
+ message: checkpointMessage,
624
+ lastCheckpoint,
625
+ partition
626
+ },
627
+ context
689
628
  );
690
- if (canHandle !== void 0 && !canHandle.includes(upcasted.type))
691
- continue;
692
- const messageProcessingResult = await eachMessage(upcasted, context);
693
- if (checkpoints) {
694
- const storeCheckpointResult = await checkpoints.store(
695
- {
696
- processorId,
697
- version,
698
- message: upcasted,
699
- lastCheckpoint,
700
- partition
701
- },
702
- context
703
- );
704
- if (storeCheckpointResult.success) {
705
- lastCheckpoint = storeCheckpointResult.newCheckpoint;
706
- }
707
- }
708
- if (messageProcessingResult && messageProcessingResult.type === "STOP") {
709
- isActive = false;
710
- result = messageProcessingResult;
711
- break;
629
+ if (storeCheckpointResult.success) {
630
+ lastCheckpoint = storeCheckpointResult.newCheckpoint;
712
631
  }
713
- if (stopAfter && stopAfter(upcasted)) {
714
- isActive = false;
715
- result = { type: "STOP", reason: "Stop condition reached" };
716
- break;
717
- }
718
- if (messageProcessingResult && messageProcessingResult.type === "SKIP")
719
- continue;
720
632
  }
721
- return result;
633
+ if (isStop) {
634
+ isActive = false;
635
+ return messageProcessingResult;
636
+ }
637
+ return void 0;
722
638
  }, partialContext);
723
639
  }
724
640
  };
@@ -746,7 +662,7 @@ var projector = (options) => {
746
662
  } : void 0,
747
663
  onClose: options.hooks?.onClose
748
664
  },
749
- eachMessage: async (event2, context) => projection2.handle([event2], context)
665
+ eachBatch: async (events, context) => projection2.handle(events, context)
750
666
  });
751
667
  };
752
668
  var AssertionError = class extends Error {
@@ -1185,6 +1101,146 @@ var workflowProcessor = (options) => {
1185
1101
  });
1186
1102
  };
1187
1103
 
1104
+ // src/eventStore/projections/pongo/pongoProjections.ts
1105
+ import {
1106
+ pongoClient
1107
+ } from "@event-driven-io/pongo";
1108
+ var pongoProjection = ({
1109
+ name,
1110
+ kind,
1111
+ version,
1112
+ truncate,
1113
+ handle,
1114
+ canHandle,
1115
+ eventsOptions
1116
+ }) => sqliteProjection({
1117
+ name,
1118
+ version,
1119
+ kind: kind ?? "emt:projections:postgresql:pongo:generic",
1120
+ canHandle,
1121
+ eventsOptions,
1122
+ handle: async (events, context) => {
1123
+ const { connection } = context;
1124
+ const driver = await pongoDriverRegistry.tryResolve(
1125
+ context.driverType
1126
+ );
1127
+ const pongo = pongoClient({
1128
+ driver,
1129
+ connectionOptions: { connection }
1130
+ });
1131
+ try {
1132
+ await handle(events, {
1133
+ ...context,
1134
+ pongo
1135
+ });
1136
+ } finally {
1137
+ await pongo.close();
1138
+ }
1139
+ },
1140
+ truncate: truncate ? async (context) => {
1141
+ const { connection } = context;
1142
+ const driver = await pongoDriverRegistry.tryResolve(
1143
+ context.driverType
1144
+ );
1145
+ const pongo = pongoClient({
1146
+ driver,
1147
+ connectionOptions: { connection }
1148
+ });
1149
+ try {
1150
+ await truncate({
1151
+ ...context,
1152
+ pongo
1153
+ });
1154
+ } finally {
1155
+ await pongo.close();
1156
+ }
1157
+ } : void 0
1158
+ });
1159
+ var pongoMultiStreamProjection = (options) => {
1160
+ const { collectionName, getDocumentId, canHandle } = options;
1161
+ const collectionNameWithVersion = options.version && options.version > 0 ? `${collectionName}_v${options.version}` : collectionName;
1162
+ return pongoProjection({
1163
+ name: collectionNameWithVersion,
1164
+ version: options.version,
1165
+ kind: options.kind ?? "emt:projections:postgresql:pongo:multi_stream",
1166
+ eventsOptions: options.eventsOptions,
1167
+ handle: async (events, { pongo }) => {
1168
+ const collection = pongo.db().collection(
1169
+ collectionNameWithVersion,
1170
+ options.collectionOptions
1171
+ );
1172
+ const eventsByDocumentId = events.map((event) => {
1173
+ const documentId = getDocumentId(event);
1174
+ return {
1175
+ documentId,
1176
+ event
1177
+ };
1178
+ }).reduce((acc, { documentId, event }) => {
1179
+ if (!acc.has(documentId)) {
1180
+ acc.set(documentId, []);
1181
+ }
1182
+ acc.get(documentId).push(event);
1183
+ return acc;
1184
+ }, /* @__PURE__ */ new Map());
1185
+ await collection.handle(
1186
+ [...eventsByDocumentId.keys()],
1187
+ (document, id) => {
1188
+ const events2 = eventsByDocumentId.get(id);
1189
+ return reduceAsync(
1190
+ events2,
1191
+ async (acc, event) => await options.evolve(acc, event),
1192
+ document ?? ("initialState" in options ? options.initialState() : null)
1193
+ );
1194
+ }
1195
+ );
1196
+ },
1197
+ canHandle,
1198
+ truncate: async (context) => {
1199
+ const { connection } = context;
1200
+ const driver = await pongoDriverRegistry.tryResolve(
1201
+ context.driverType
1202
+ );
1203
+ const pongo = pongoClient({
1204
+ driver,
1205
+ connectionOptions: { connection }
1206
+ });
1207
+ try {
1208
+ await pongo.db().collection(
1209
+ collectionNameWithVersion,
1210
+ options.collectionOptions
1211
+ ).deleteMany();
1212
+ } finally {
1213
+ await pongo.close();
1214
+ }
1215
+ },
1216
+ init: async (context) => {
1217
+ const { connection } = context;
1218
+ const driver = await pongoDriverRegistry.tryResolve(
1219
+ context.driverType
1220
+ );
1221
+ const pongo = pongoClient({
1222
+ connectionOptions: { connection },
1223
+ driver
1224
+ });
1225
+ try {
1226
+ await pongo.db().collection(
1227
+ collectionNameWithVersion,
1228
+ options.collectionOptions
1229
+ ).schema.migrate();
1230
+ } finally {
1231
+ await pongo.close();
1232
+ }
1233
+ }
1234
+ });
1235
+ };
1236
+ var pongoSingleStreamProjection = (options) => {
1237
+ return pongoMultiStreamProjection({
1238
+ ...options,
1239
+ kind: "emt:projections:postgresql:pongo:single_stream",
1240
+ getDocumentId: options.getDocumentId ?? ((event) => event.metadata.streamName)
1241
+ });
1242
+ };
1243
+
1188
1244
  // src/eventStore/projections/pongo/pongoProjectionSpec.ts
1189
1245
  import {
1190
1246
  pongoClient as pongoClient2