@event-driven-io/emmett-esdb 0.20.2-alpha.1 → 0.20.2-alpha2
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 +406 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +406 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,2 +1,407 @@
|
|
|
1
|
-
|
|
1
|
+
// ../emmett/dist/chunk-AEEEXE2R.js
|
|
2
|
+
var isNumber = (val) => typeof val === "number" && val === val;
|
|
3
|
+
var isString = (val) => typeof val === "string";
|
|
4
|
+
var EmmettError = class _EmmettError extends Error {
|
|
5
|
+
errorCode;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
const errorCode = options && typeof options === "object" && "errorCode" in options ? options.errorCode : isNumber(options) ? options : 500;
|
|
8
|
+
const message = options && typeof options === "object" && "message" in options ? options.message : isString(options) ? options : `Error with status code '${errorCode}' ocurred during Emmett processing`;
|
|
9
|
+
super(message);
|
|
10
|
+
this.errorCode = errorCode;
|
|
11
|
+
Object.setPrototypeOf(this, _EmmettError.prototype);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var ConcurrencyError = class _ConcurrencyError extends EmmettError {
|
|
15
|
+
constructor(current, expected, message) {
|
|
16
|
+
super({
|
|
17
|
+
errorCode: 412,
|
|
18
|
+
message: message ?? `Expected version ${expected.toString()} does not match current ${current?.toString()}`
|
|
19
|
+
});
|
|
20
|
+
this.current = current;
|
|
21
|
+
this.expected = expected;
|
|
22
|
+
Object.setPrototypeOf(this, _ConcurrencyError.prototype);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// ../emmett/dist/index.js
|
|
27
|
+
import { v4 as uuid3 } from "uuid";
|
|
28
|
+
import { TransformStream } from "web-streams-polyfill";
|
|
29
|
+
import { v4 as uuid2 } from "uuid";
|
|
30
|
+
import { v4 as uuid } from "uuid";
|
|
31
|
+
import { TransformStream as TransformStream2 } from "web-streams-polyfill";
|
|
32
|
+
import retry from "async-retry";
|
|
33
|
+
import { ReadableStream } from "web-streams-polyfill";
|
|
34
|
+
import "web-streams-polyfill";
|
|
35
|
+
import { TransformStream as TransformStream3 } from "web-streams-polyfill";
|
|
36
|
+
import { TransformStream as TransformStream4 } from "web-streams-polyfill";
|
|
37
|
+
import { TransformStream as TransformStream5 } from "web-streams-polyfill";
|
|
38
|
+
import {
|
|
39
|
+
TransformStream as TransformStream6
|
|
40
|
+
} from "web-streams-polyfill";
|
|
41
|
+
import { TransformStream as TransformStream7 } from "web-streams-polyfill";
|
|
42
|
+
import { TransformStream as TransformStream8 } from "web-streams-polyfill";
|
|
43
|
+
import { TransformStream as TransformStream9 } from "web-streams-polyfill";
|
|
44
|
+
import { TransformStream as TransformStream10 } from "web-streams-polyfill";
|
|
45
|
+
import { TransformStream as TransformStream11 } from "web-streams-polyfill";
|
|
46
|
+
var STREAM_EXISTS = "STREAM_EXISTS";
|
|
47
|
+
var STREAM_DOES_NOT_EXIST = "STREAM_DOES_NOT_EXIST";
|
|
48
|
+
var NO_CONCURRENCY_CHECK = "NO_CONCURRENCY_CHECK";
|
|
49
|
+
var matchesExpectedVersion = (current, expected, defaultVersion) => {
|
|
50
|
+
if (expected === NO_CONCURRENCY_CHECK) return true;
|
|
51
|
+
if (expected == STREAM_DOES_NOT_EXIST) return current === defaultVersion;
|
|
52
|
+
if (expected == STREAM_EXISTS) return current !== defaultVersion;
|
|
53
|
+
return current === expected;
|
|
54
|
+
};
|
|
55
|
+
var assertExpectedVersionMatchesCurrent = (current, expected, defaultVersion) => {
|
|
56
|
+
expected ??= NO_CONCURRENCY_CHECK;
|
|
57
|
+
if (!matchesExpectedVersion(current, expected, defaultVersion))
|
|
58
|
+
throw new ExpectedVersionConflictError(current, expected);
|
|
59
|
+
};
|
|
60
|
+
var ExpectedVersionConflictError = class _ExpectedVersionConflictError extends ConcurrencyError {
|
|
61
|
+
constructor(current, expected) {
|
|
62
|
+
super(current?.toString(), expected?.toString());
|
|
63
|
+
Object.setPrototypeOf(this, _ExpectedVersionConflictError.prototype);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var notifyAboutNoActiveReadersStream = (onNoActiveReaderCallback, options = {}) => new NotifyAboutNoActiveReadersStream(onNoActiveReaderCallback, options);
|
|
67
|
+
var NotifyAboutNoActiveReadersStream = class extends TransformStream2 {
|
|
68
|
+
constructor(onNoActiveReaderCallback, options = {}) {
|
|
69
|
+
super({
|
|
70
|
+
cancel: (reason) => {
|
|
71
|
+
console.log("Stream was canceled. Reason:", reason);
|
|
72
|
+
this.stopChecking();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
this.onNoActiveReaderCallback = onNoActiveReaderCallback;
|
|
76
|
+
this.streamId = options?.streamId ?? uuid();
|
|
77
|
+
this.onNoActiveReaderCallback = onNoActiveReaderCallback;
|
|
78
|
+
this.startChecking(options?.intervalCheckInMs ?? 20);
|
|
79
|
+
}
|
|
80
|
+
checkInterval = null;
|
|
81
|
+
streamId;
|
|
82
|
+
_isStopped = false;
|
|
83
|
+
get hasActiveSubscribers() {
|
|
84
|
+
return !this._isStopped;
|
|
85
|
+
}
|
|
86
|
+
startChecking(interval) {
|
|
87
|
+
this.checkInterval = setInterval(() => {
|
|
88
|
+
this.checkNoActiveReader();
|
|
89
|
+
}, interval);
|
|
90
|
+
}
|
|
91
|
+
stopChecking() {
|
|
92
|
+
if (!this.checkInterval) return;
|
|
93
|
+
clearInterval(this.checkInterval);
|
|
94
|
+
this.checkInterval = null;
|
|
95
|
+
this._isStopped = true;
|
|
96
|
+
this.onNoActiveReaderCallback(this);
|
|
97
|
+
}
|
|
98
|
+
checkNoActiveReader() {
|
|
99
|
+
if (!this.readable.locked && !this._isStopped) {
|
|
100
|
+
this.stopChecking();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
var asyncRetry = async (fn, opts) => {
|
|
105
|
+
if (opts === void 0 || opts.retries === 0) return fn();
|
|
106
|
+
return retry(
|
|
107
|
+
async (bail) => {
|
|
108
|
+
try {
|
|
109
|
+
return await fn();
|
|
110
|
+
} catch (error2) {
|
|
111
|
+
if (opts?.shouldRetryError && !opts.shouldRetryError(error2)) {
|
|
112
|
+
bail(error2);
|
|
113
|
+
}
|
|
114
|
+
throw error2;
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
opts ?? { retries: 0 }
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
var filter = (filter2) => new TransformStream3({
|
|
121
|
+
transform(chunk, controller) {
|
|
122
|
+
if (filter2(chunk)) {
|
|
123
|
+
controller.enqueue(chunk);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
var map = (map22) => new TransformStream4({
|
|
128
|
+
transform(chunk, controller) {
|
|
129
|
+
controller.enqueue(map22(chunk));
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
var reduce = (reducer, initialValue) => new ReduceTransformStream(reducer, initialValue);
|
|
133
|
+
var ReduceTransformStream = class extends TransformStream5 {
|
|
134
|
+
accumulator;
|
|
135
|
+
reducer;
|
|
136
|
+
constructor(reducer, initialValue) {
|
|
137
|
+
super({
|
|
138
|
+
transform: (chunk) => {
|
|
139
|
+
this.accumulator = this.reducer(this.accumulator, chunk);
|
|
140
|
+
},
|
|
141
|
+
flush: (controller) => {
|
|
142
|
+
controller.enqueue(this.accumulator);
|
|
143
|
+
controller.terminate();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
this.accumulator = initialValue;
|
|
147
|
+
this.reducer = reducer;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var retryStream = (createSourceStream, handleChunk2, retryOptions = { forever: true, minTimeout: 25 }) => new TransformStream6({
|
|
151
|
+
start(controller) {
|
|
152
|
+
asyncRetry(
|
|
153
|
+
() => onRestream(createSourceStream, handleChunk2, controller),
|
|
154
|
+
retryOptions
|
|
155
|
+
).catch((error2) => {
|
|
156
|
+
controller.error(error2);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
var onRestream = async (createSourceStream, handleChunk2, controller) => {
|
|
161
|
+
const sourceStream = createSourceStream();
|
|
162
|
+
const reader = sourceStream.getReader();
|
|
163
|
+
try {
|
|
164
|
+
let done;
|
|
165
|
+
do {
|
|
166
|
+
const result = await reader.read();
|
|
167
|
+
done = result.done;
|
|
168
|
+
await handleChunk2(result, controller);
|
|
169
|
+
if (done) {
|
|
170
|
+
controller.terminate();
|
|
171
|
+
}
|
|
172
|
+
} while (!done);
|
|
173
|
+
} finally {
|
|
174
|
+
reader.releaseLock();
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
var skip = (limit) => new SkipTransformStream(limit);
|
|
178
|
+
var SkipTransformStream = class extends TransformStream7 {
|
|
179
|
+
count = 0;
|
|
180
|
+
skip;
|
|
181
|
+
constructor(skip2) {
|
|
182
|
+
super({
|
|
183
|
+
transform: (chunk, controller) => {
|
|
184
|
+
this.count++;
|
|
185
|
+
if (this.count > this.skip) {
|
|
186
|
+
controller.enqueue(chunk);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
this.skip = skip2;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
var stopAfter = (stopCondition) => new TransformStream8({
|
|
194
|
+
transform(chunk, controller) {
|
|
195
|
+
controller.enqueue(chunk);
|
|
196
|
+
if (stopCondition(chunk)) {
|
|
197
|
+
controller.terminate();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
var stopOn = (stopCondition) => new TransformStream9({
|
|
202
|
+
async transform(chunk, controller) {
|
|
203
|
+
if (!stopCondition(chunk)) {
|
|
204
|
+
controller.enqueue(chunk);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
await Promise.resolve();
|
|
208
|
+
controller.terminate();
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
var take = (limit) => new TakeTransformStream(limit);
|
|
212
|
+
var TakeTransformStream = class extends TransformStream10 {
|
|
213
|
+
count = 0;
|
|
214
|
+
limit;
|
|
215
|
+
constructor(limit) {
|
|
216
|
+
super({
|
|
217
|
+
transform: (chunk, controller) => {
|
|
218
|
+
if (this.count < this.limit) {
|
|
219
|
+
this.count++;
|
|
220
|
+
controller.enqueue(chunk);
|
|
221
|
+
} else {
|
|
222
|
+
controller.terminate();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
this.limit = limit;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
var waitAtMost = (waitTimeInMs) => new TransformStream11({
|
|
230
|
+
start(controller) {
|
|
231
|
+
const timeoutId = setTimeout(() => {
|
|
232
|
+
controller.terminate();
|
|
233
|
+
}, waitTimeInMs);
|
|
234
|
+
const originalTerminate = controller.terminate.bind(controller);
|
|
235
|
+
controller.terminate = () => {
|
|
236
|
+
clearTimeout(timeoutId);
|
|
237
|
+
originalTerminate();
|
|
238
|
+
};
|
|
239
|
+
},
|
|
240
|
+
transform(chunk, controller) {
|
|
241
|
+
controller.enqueue(chunk);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
var streamTransformations = {
|
|
245
|
+
filter,
|
|
246
|
+
take,
|
|
247
|
+
TakeTransformStream,
|
|
248
|
+
skip,
|
|
249
|
+
SkipTransformStream,
|
|
250
|
+
map,
|
|
251
|
+
notifyAboutNoActiveReadersStream,
|
|
252
|
+
NotifyAboutNoActiveReadersStream,
|
|
253
|
+
reduce,
|
|
254
|
+
ReduceTransformStream,
|
|
255
|
+
retry: retryStream,
|
|
256
|
+
stopAfter,
|
|
257
|
+
stopOn,
|
|
258
|
+
waitAtMost
|
|
259
|
+
};
|
|
260
|
+
var { retry: retry2 } = streamTransformations;
|
|
261
|
+
|
|
262
|
+
// src/eventStore/eventstoreDBEventStore.ts
|
|
263
|
+
import {
|
|
264
|
+
ANY,
|
|
265
|
+
STREAM_EXISTS as ESDB_STREAM_EXISTS,
|
|
266
|
+
NO_STREAM,
|
|
267
|
+
StreamNotFoundError,
|
|
268
|
+
WrongExpectedVersionError,
|
|
269
|
+
jsonEvent
|
|
270
|
+
} from "@eventstore/db-client";
|
|
271
|
+
import { WritableStream } from "node:stream/web";
|
|
272
|
+
import { Readable } from "stream";
|
|
273
|
+
var { map: map2 } = streamTransformations;
|
|
274
|
+
var toEventStoreDBReadOptions = (options) => {
|
|
275
|
+
return options ? {
|
|
276
|
+
fromRevision: "from" in options ? options.from : void 0,
|
|
277
|
+
maxCount: "maxCount" in options ? options.maxCount : "to" in options ? options.to : void 0
|
|
278
|
+
} : void 0;
|
|
279
|
+
};
|
|
280
|
+
var EventStoreDBEventStoreDefaultStreamVersion = -1n;
|
|
281
|
+
var getEventStoreDBEventStore = (eventStore) => {
|
|
282
|
+
return {
|
|
283
|
+
async aggregateStream(streamName, options) {
|
|
284
|
+
const { evolve, initialState, read } = options;
|
|
285
|
+
const expectedStreamVersion = read?.expectedStreamVersion;
|
|
286
|
+
let state = initialState();
|
|
287
|
+
let currentStreamVersion = EventStoreDBEventStoreDefaultStreamVersion;
|
|
288
|
+
try {
|
|
289
|
+
for await (const { event } of eventStore.readStream(
|
|
290
|
+
streamName,
|
|
291
|
+
toEventStoreDBReadOptions(options.read)
|
|
292
|
+
)) {
|
|
293
|
+
if (!event) continue;
|
|
294
|
+
state = evolve(state, mapFromESDBEvent(event));
|
|
295
|
+
currentStreamVersion = event.revision;
|
|
296
|
+
}
|
|
297
|
+
assertExpectedVersionMatchesCurrent(
|
|
298
|
+
currentStreamVersion,
|
|
299
|
+
expectedStreamVersion,
|
|
300
|
+
EventStoreDBEventStoreDefaultStreamVersion
|
|
301
|
+
);
|
|
302
|
+
return {
|
|
303
|
+
currentStreamVersion,
|
|
304
|
+
state,
|
|
305
|
+
streamExists: true
|
|
306
|
+
};
|
|
307
|
+
} catch (error) {
|
|
308
|
+
if (error instanceof StreamNotFoundError) {
|
|
309
|
+
return {
|
|
310
|
+
currentStreamVersion,
|
|
311
|
+
state,
|
|
312
|
+
streamExists: false
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
throw error;
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
readStream: async (streamName, options) => {
|
|
319
|
+
const events = [];
|
|
320
|
+
let currentStreamVersion = EventStoreDBEventStoreDefaultStreamVersion;
|
|
321
|
+
try {
|
|
322
|
+
for await (const { event } of eventStore.readStream(
|
|
323
|
+
streamName,
|
|
324
|
+
toEventStoreDBReadOptions(options)
|
|
325
|
+
)) {
|
|
326
|
+
if (!event) continue;
|
|
327
|
+
events.push(mapFromESDBEvent(event));
|
|
328
|
+
currentStreamVersion = event.revision;
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
currentStreamVersion,
|
|
332
|
+
events,
|
|
333
|
+
streamExists: true
|
|
334
|
+
};
|
|
335
|
+
} catch (error) {
|
|
336
|
+
if (error instanceof StreamNotFoundError) {
|
|
337
|
+
return {
|
|
338
|
+
currentStreamVersion,
|
|
339
|
+
events: [],
|
|
340
|
+
streamExists: false
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
throw error;
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
appendToStream: async (streamName, events, options) => {
|
|
347
|
+
try {
|
|
348
|
+
const serializedEvents = events.map(jsonEvent);
|
|
349
|
+
const expectedRevision = toExpectedRevision(
|
|
350
|
+
options?.expectedStreamVersion
|
|
351
|
+
);
|
|
352
|
+
const appendResult = await eventStore.appendToStream(
|
|
353
|
+
streamName,
|
|
354
|
+
serializedEvents,
|
|
355
|
+
{
|
|
356
|
+
expectedRevision
|
|
357
|
+
}
|
|
358
|
+
);
|
|
359
|
+
return {
|
|
360
|
+
nextExpectedStreamVersion: appendResult.nextExpectedRevision,
|
|
361
|
+
createdNewStream: appendResult.nextExpectedRevision >= BigInt(serializedEvents.length)
|
|
362
|
+
};
|
|
363
|
+
} catch (error) {
|
|
364
|
+
if (error instanceof WrongExpectedVersionError) {
|
|
365
|
+
throw new ExpectedVersionConflictError(
|
|
366
|
+
error.actualVersion,
|
|
367
|
+
toExpectedVersion(error.expectedVersion)
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
throw error;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
//streamEvents: streamEvents(eventStore),
|
|
374
|
+
};
|
|
375
|
+
};
|
|
376
|
+
var mapFromESDBEvent = (event) => {
|
|
377
|
+
return {
|
|
378
|
+
type: event.type,
|
|
379
|
+
data: event.data,
|
|
380
|
+
metadata: {
|
|
381
|
+
...event.metadata ?? {},
|
|
382
|
+
eventId: event.id,
|
|
383
|
+
streamName: event.streamId,
|
|
384
|
+
streamPosition: event.revision,
|
|
385
|
+
globalPosition: event.position.commit
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
};
|
|
389
|
+
var toExpectedRevision = (expected) => {
|
|
390
|
+
if (expected === void 0) return ANY;
|
|
391
|
+
if (expected === NO_CONCURRENCY_CHECK) return ANY;
|
|
392
|
+
if (expected == STREAM_DOES_NOT_EXIST) return NO_STREAM;
|
|
393
|
+
if (expected == STREAM_EXISTS) return ESDB_STREAM_EXISTS;
|
|
394
|
+
return expected;
|
|
395
|
+
};
|
|
396
|
+
var toExpectedVersion = (expected) => {
|
|
397
|
+
if (expected === void 0) return NO_CONCURRENCY_CHECK;
|
|
398
|
+
if (expected === ANY) return NO_CONCURRENCY_CHECK;
|
|
399
|
+
if (expected == NO_STREAM) return STREAM_DOES_NOT_EXIST;
|
|
400
|
+
if (expected == ESDB_STREAM_EXISTS) return STREAM_EXISTS;
|
|
401
|
+
return expected;
|
|
402
|
+
};
|
|
403
|
+
export {
|
|
404
|
+
EventStoreDBEventStoreDefaultStreamVersion,
|
|
405
|
+
getEventStoreDBEventStore
|
|
406
|
+
};
|
|
2
407
|
//# sourceMappingURL=index.js.map
|