@rotorsoft/act-tck 1.5.0 → 1.5.2
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/README.md +21 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/fixtures/helpers.d.ts +2 -2
- package/dist/@types/fixtures/helpers.d.ts.map +1 -1
- package/dist/@types/index.d.ts +3 -1
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/@types/stability-tck.d.ts +52 -0
- package/dist/@types/stability-tck.d.ts.map +1 -0
- package/dist/@types/store-tck.d.ts.map +1 -1
- package/dist/index.cjs +686 -506
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +673 -502
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -29,12 +39,11 @@ __export(index_exports, {
|
|
|
29
39
|
collect: () => collect,
|
|
30
40
|
dec: () => dec,
|
|
31
41
|
inc: () => inc,
|
|
32
|
-
makeMeta: () => makeMeta,
|
|
33
42
|
reset: () => reset,
|
|
34
43
|
runCacheTck: () => runCacheTck,
|
|
35
44
|
runLoggerTck: () => runLoggerTck,
|
|
45
|
+
runStabilityTck: () => runStabilityTck,
|
|
36
46
|
runStoreTck: () => runStoreTck,
|
|
37
|
-
seedStream: () => seedStream,
|
|
38
47
|
uid: () => uid
|
|
39
48
|
});
|
|
40
49
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -130,7 +139,7 @@ var COUNTER_EVENT_NAMES = [
|
|
|
130
139
|
var import_node_crypto = require("crypto");
|
|
131
140
|
var uid = () => (0, import_node_crypto.randomUUID)().slice(0, 8);
|
|
132
141
|
var actor = (name = "tester") => ({ id: (0, import_node_crypto.randomUUID)(), name });
|
|
133
|
-
var
|
|
142
|
+
var make_meta = (opts = {}) => ({
|
|
134
143
|
correlation: opts.correlation ?? (0, import_node_crypto.randomUUID)(),
|
|
135
144
|
causation: opts.stream ? {
|
|
136
145
|
action: {
|
|
@@ -149,13 +158,13 @@ var dec = (amount = 1) => ({
|
|
|
149
158
|
data: { amount }
|
|
150
159
|
});
|
|
151
160
|
var reset = () => ({ name: "Reset", data: {} });
|
|
152
|
-
var
|
|
161
|
+
var seed_stream = async (store, stream, count, correlation) => {
|
|
153
162
|
const out = [];
|
|
154
163
|
for (let i = 0; i < count; i++) {
|
|
155
164
|
const committed = await store.commit(
|
|
156
165
|
stream,
|
|
157
166
|
[inc(1)],
|
|
158
|
-
|
|
167
|
+
make_meta({ correlation, stream })
|
|
159
168
|
);
|
|
160
169
|
out.push(...committed);
|
|
161
170
|
}
|
|
@@ -175,14 +184,14 @@ var LEVELS = ["fatal", "error", "warn", "info", "debug", "trace"];
|
|
|
175
184
|
var runLoggerTck = (options) => {
|
|
176
185
|
(0, import_vitest2.describe)(`TCK / Logger / ${options.name}`, () => {
|
|
177
186
|
let logger;
|
|
178
|
-
let
|
|
187
|
+
let original_stdout;
|
|
179
188
|
(0, import_vitest2.beforeEach)(() => {
|
|
180
189
|
logger = options.factory();
|
|
181
|
-
|
|
190
|
+
original_stdout = process.stdout.write.bind(process.stdout);
|
|
182
191
|
process.stdout.write = (() => true);
|
|
183
192
|
});
|
|
184
193
|
(0, import_vitest2.afterEach)(async () => {
|
|
185
|
-
process.stdout.write =
|
|
194
|
+
process.stdout.write = original_stdout;
|
|
186
195
|
await logger.dispose();
|
|
187
196
|
});
|
|
188
197
|
(0, import_vitest2.it)("exposes a non-empty `level` string", () => {
|
|
@@ -209,7 +218,7 @@ var runLoggerTck = (options) => {
|
|
|
209
218
|
(0, import_vitest2.expect)(() => logger.info(cyclic, "cycle")).not.toThrow();
|
|
210
219
|
});
|
|
211
220
|
(0, import_vitest2.it)("child(bindings) returns a Logger satisfying the same contract", () => {
|
|
212
|
-
const child = logger.child({
|
|
221
|
+
const child = logger.child({ request_id: "abc" });
|
|
213
222
|
(0, import_vitest2.expect)(typeof child.level).toBe("string");
|
|
214
223
|
for (const level of LEVELS) {
|
|
215
224
|
(0, import_vitest2.expect)(typeof child[level]).toBe("function");
|
|
@@ -229,118 +238,162 @@ var runLoggerTck = (options) => {
|
|
|
229
238
|
});
|
|
230
239
|
};
|
|
231
240
|
|
|
241
|
+
// src/stability-tck.ts
|
|
242
|
+
var import_node_fs = require("fs");
|
|
243
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
244
|
+
var import_vitest3 = require("vitest");
|
|
245
|
+
function runStabilityTck(options) {
|
|
246
|
+
(0, import_vitest3.describe)(`${options.name} \u2014 public API stability`, () => {
|
|
247
|
+
for (const [subpath, entry2] of Object.entries(options.entryPoints)) {
|
|
248
|
+
const label = subpath || "(root)";
|
|
249
|
+
(0, import_vitest3.it)(`stable public surface for ${label}`, async () => {
|
|
250
|
+
const surface = await load_surface(entry2);
|
|
251
|
+
(0, import_vitest3.expect)(surface).toMatchSnapshot();
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
async function load_surface(entry2) {
|
|
257
|
+
const visited = /* @__PURE__ */ new Map();
|
|
258
|
+
async function walk(file) {
|
|
259
|
+
const abs = import_node_path.default.resolve(file);
|
|
260
|
+
if (visited.has(abs)) return;
|
|
261
|
+
const content = await import_node_fs.promises.readFile(abs, "utf8");
|
|
262
|
+
visited.set(abs, content);
|
|
263
|
+
const re_export = /^\s*(?:import|export)\b[^"';]*\bfrom\s+["'](\.[^"']+)["']/gm;
|
|
264
|
+
for (const m of content.matchAll(re_export)) {
|
|
265
|
+
const rel = m[1].replace(/\.js$/, ".ts");
|
|
266
|
+
const target = import_node_path.default.resolve(import_node_path.default.dirname(abs), rel);
|
|
267
|
+
await walk(target);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
await walk(entry2);
|
|
271
|
+
const sorted = [...visited.entries()].sort(
|
|
272
|
+
([a], [b]) => import_node_path.default.basename(a).localeCompare(import_node_path.default.basename(b))
|
|
273
|
+
);
|
|
274
|
+
return sorted.map(([abs, content]) => {
|
|
275
|
+
const rel = import_node_path.default.basename(abs);
|
|
276
|
+
return `// === ${rel} ===
|
|
277
|
+
${content}`;
|
|
278
|
+
}).join("\n");
|
|
279
|
+
}
|
|
280
|
+
|
|
232
281
|
// src/store-tck.ts
|
|
233
282
|
var import_act = require("@rotorsoft/act");
|
|
234
|
-
var
|
|
283
|
+
var import_vitest4 = require("vitest");
|
|
235
284
|
var runStoreTck = (options) => {
|
|
236
|
-
(0,
|
|
285
|
+
(0, import_vitest4.describe)(`TCK / Store / ${options.name}`, () => {
|
|
237
286
|
let store;
|
|
238
287
|
const caps = { ...options.capabilities };
|
|
239
|
-
(0,
|
|
288
|
+
(0, import_vitest4.beforeAll)(async () => {
|
|
240
289
|
store = await options.factory();
|
|
241
290
|
await store.drop();
|
|
242
291
|
await store.seed();
|
|
243
292
|
});
|
|
244
|
-
(0,
|
|
293
|
+
(0, import_vitest4.afterAll)(async () => {
|
|
245
294
|
await store.dispose();
|
|
246
295
|
});
|
|
247
|
-
(0,
|
|
248
|
-
(0,
|
|
296
|
+
(0, import_vitest4.describe)("commit", () => {
|
|
297
|
+
(0, import_vitest4.it)("returns committed events with sequenced ids and versions", async () => {
|
|
249
298
|
const s = `commit-seq-${uid()}`;
|
|
250
299
|
const committed = await store.commit(
|
|
251
300
|
s,
|
|
252
301
|
[inc(1), inc(2), dec(3)],
|
|
253
|
-
|
|
254
|
-
);
|
|
255
|
-
(0,
|
|
256
|
-
(0,
|
|
257
|
-
(0,
|
|
258
|
-
(0,
|
|
259
|
-
(0,
|
|
260
|
-
(0,
|
|
302
|
+
make_meta({ stream: s })
|
|
303
|
+
);
|
|
304
|
+
(0, import_vitest4.expect)(committed).toHaveLength(3);
|
|
305
|
+
(0, import_vitest4.expect)(committed[0].version).toBe(0);
|
|
306
|
+
(0, import_vitest4.expect)(committed[1].version).toBe(1);
|
|
307
|
+
(0, import_vitest4.expect)(committed[2].version).toBe(2);
|
|
308
|
+
(0, import_vitest4.expect)(committed[0].name).toBe("Incremented");
|
|
309
|
+
(0, import_vitest4.expect)(committed[2].data).toEqual({ amount: 3 });
|
|
261
310
|
for (let i = 1; i < committed.length; i++) {
|
|
262
|
-
(0,
|
|
311
|
+
(0, import_vitest4.expect)(committed[i].id).toBeGreaterThan(committed[i - 1].id);
|
|
263
312
|
}
|
|
264
313
|
});
|
|
265
|
-
(0,
|
|
314
|
+
(0, import_vitest4.it)("attaches correlation and stream metadata", async () => {
|
|
266
315
|
const s = `commit-meta-${uid()}`;
|
|
267
316
|
const correlation = `cor-${uid()}`;
|
|
268
317
|
const committed = await store.commit(
|
|
269
318
|
s,
|
|
270
319
|
[inc(1)],
|
|
271
|
-
|
|
320
|
+
make_meta({ stream: s, correlation })
|
|
272
321
|
);
|
|
273
|
-
(0,
|
|
274
|
-
(0,
|
|
322
|
+
(0, import_vitest4.expect)(committed[0].stream).toBe(s);
|
|
323
|
+
(0, import_vitest4.expect)(committed[0].meta.correlation).toBe(correlation);
|
|
275
324
|
});
|
|
276
|
-
(0,
|
|
325
|
+
(0, import_vitest4.it)("throws ConcurrencyError when expectedVersion is wrong", async () => {
|
|
277
326
|
const s = `commit-cc-${uid()}`;
|
|
278
|
-
await store.commit(s, [inc(1)], makeMeta({ stream: s }));
|
|
279
327
|
await store.commit(
|
|
280
328
|
s,
|
|
281
329
|
[inc(1)],
|
|
282
|
-
|
|
330
|
+
make_meta({ stream: s })
|
|
331
|
+
);
|
|
332
|
+
await store.commit(
|
|
333
|
+
s,
|
|
334
|
+
[inc(1)],
|
|
335
|
+
make_meta({ stream: s }),
|
|
283
336
|
0
|
|
284
337
|
);
|
|
285
|
-
await (0,
|
|
286
|
-
store.commit(s, [inc(1)],
|
|
338
|
+
await (0, import_vitest4.expect)(
|
|
339
|
+
store.commit(s, [inc(1)], make_meta({ stream: s }), 0)
|
|
287
340
|
).rejects.toBeInstanceOf(import_act.ConcurrencyError);
|
|
288
341
|
});
|
|
289
|
-
(0,
|
|
342
|
+
(0, import_vitest4.it)("preserves prior events when a concurrent commit is rejected", async () => {
|
|
290
343
|
const s = `commit-cc-preserve-${uid()}`;
|
|
291
344
|
await store.commit(
|
|
292
345
|
s,
|
|
293
346
|
[inc(1), inc(2)],
|
|
294
|
-
|
|
347
|
+
make_meta({ stream: s })
|
|
295
348
|
);
|
|
296
|
-
await (0,
|
|
297
|
-
store.commit(s, [inc(3)],
|
|
349
|
+
await (0, import_vitest4.expect)(
|
|
350
|
+
store.commit(s, [inc(3)], make_meta({ stream: s }), 0)
|
|
298
351
|
).rejects.toBeInstanceOf(import_act.ConcurrencyError);
|
|
299
352
|
const found = await collect(store, { stream: s, stream_exact: true });
|
|
300
|
-
(0,
|
|
353
|
+
(0, import_vitest4.expect)(found).toHaveLength(2);
|
|
301
354
|
});
|
|
302
355
|
});
|
|
303
|
-
(0,
|
|
304
|
-
(0,
|
|
356
|
+
(0, import_vitest4.describe)("query", () => {
|
|
357
|
+
(0, import_vitest4.it)("filters by stream, names, correlation, limit, with_snaps", async () => {
|
|
305
358
|
const s1 = `q-s1-${uid()}`;
|
|
306
359
|
const s2 = `q-s2-${uid()}`;
|
|
307
360
|
const cor = `q-cor-${uid()}`;
|
|
308
361
|
await store.commit(
|
|
309
362
|
s1,
|
|
310
363
|
[inc(1), dec(1)],
|
|
311
|
-
|
|
364
|
+
make_meta({ stream: s1, correlation: cor })
|
|
312
365
|
);
|
|
313
366
|
await store.commit(
|
|
314
367
|
s2,
|
|
315
368
|
[inc(2), dec(2), reset()],
|
|
316
|
-
|
|
369
|
+
make_meta({ stream: s2, correlation: cor })
|
|
317
370
|
);
|
|
318
|
-
const
|
|
371
|
+
const by_stream = await collect(store, {
|
|
319
372
|
stream: s1,
|
|
320
373
|
stream_exact: true
|
|
321
374
|
});
|
|
322
|
-
(0,
|
|
323
|
-
const
|
|
375
|
+
(0, import_vitest4.expect)(by_stream).toHaveLength(2);
|
|
376
|
+
const by_name = await collect(store, {
|
|
324
377
|
stream: s2,
|
|
325
378
|
stream_exact: true,
|
|
326
379
|
names: ["Reset"]
|
|
327
380
|
});
|
|
328
|
-
(0,
|
|
329
|
-
(0,
|
|
330
|
-
const
|
|
331
|
-
(0,
|
|
381
|
+
(0, import_vitest4.expect)(by_name).toHaveLength(1);
|
|
382
|
+
(0, import_vitest4.expect)(by_name[0].name).toBe("Reset");
|
|
383
|
+
const by_correlation = await collect(store, { correlation: cor });
|
|
384
|
+
(0, import_vitest4.expect)(by_correlation).toHaveLength(5);
|
|
332
385
|
const limited = await collect(store, {
|
|
333
386
|
correlation: cor,
|
|
334
387
|
limit: 2
|
|
335
388
|
});
|
|
336
|
-
(0,
|
|
389
|
+
(0, import_vitest4.expect)(limited).toHaveLength(2);
|
|
337
390
|
});
|
|
338
|
-
(0,
|
|
391
|
+
(0, import_vitest4.it)("supports backward traversal", async () => {
|
|
339
392
|
const s = `q-back-${uid()}`;
|
|
340
393
|
const committed = await store.commit(
|
|
341
394
|
s,
|
|
342
395
|
[inc(1), inc(2), inc(3)],
|
|
343
|
-
|
|
396
|
+
make_meta({ stream: s })
|
|
344
397
|
);
|
|
345
398
|
const forward = await collect(store, { stream: s, stream_exact: true });
|
|
346
399
|
const backward = await collect(store, {
|
|
@@ -348,8 +401,8 @@ var runStoreTck = (options) => {
|
|
|
348
401
|
stream_exact: true,
|
|
349
402
|
backward: true
|
|
350
403
|
});
|
|
351
|
-
(0,
|
|
352
|
-
(0,
|
|
404
|
+
(0, import_vitest4.expect)(forward.map((e) => e.id)).toEqual(committed.map((c) => c.id));
|
|
405
|
+
(0, import_vitest4.expect)(backward.map((e) => e.id)).toEqual(
|
|
353
406
|
[...committed].reverse().map((c) => c.id)
|
|
354
407
|
);
|
|
355
408
|
const latest = await collect(store, {
|
|
@@ -358,58 +411,62 @@ var runStoreTck = (options) => {
|
|
|
358
411
|
backward: true,
|
|
359
412
|
limit: 1
|
|
360
413
|
});
|
|
361
|
-
(0,
|
|
362
|
-
(0,
|
|
414
|
+
(0, import_vitest4.expect)(latest).toHaveLength(1);
|
|
415
|
+
(0, import_vitest4.expect)(latest[0].id).toBe(committed.at(-1).id);
|
|
363
416
|
});
|
|
364
|
-
(0,
|
|
417
|
+
(0, import_vitest4.it)("after/before bound the id range", async () => {
|
|
365
418
|
const s = `q-bounds-${uid()}`;
|
|
366
419
|
const committed = await store.commit(
|
|
367
420
|
s,
|
|
368
421
|
[inc(1), inc(2), inc(3), inc(4)],
|
|
369
|
-
|
|
422
|
+
make_meta({ stream: s })
|
|
370
423
|
);
|
|
371
|
-
const
|
|
424
|
+
const after_first = await collect(store, {
|
|
372
425
|
stream: s,
|
|
373
426
|
stream_exact: true,
|
|
374
427
|
after: committed[0].id
|
|
375
428
|
});
|
|
376
|
-
(0,
|
|
429
|
+
(0, import_vitest4.expect)(after_first.map((e) => e.id)).toEqual(
|
|
377
430
|
committed.slice(1).map((c) => c.id)
|
|
378
431
|
);
|
|
379
|
-
const
|
|
432
|
+
const before_last = await collect(store, {
|
|
380
433
|
stream: s,
|
|
381
434
|
stream_exact: true,
|
|
382
435
|
before: committed[committed.length - 1].id
|
|
383
436
|
});
|
|
384
|
-
(0,
|
|
437
|
+
(0, import_vitest4.expect)(before_last.map((e) => e.id)).toEqual(
|
|
385
438
|
committed.slice(0, -1).map((c) => c.id)
|
|
386
439
|
);
|
|
387
440
|
});
|
|
388
|
-
(0,
|
|
441
|
+
(0, import_vitest4.it)("created_after/created_before filter by timestamp", async () => {
|
|
389
442
|
const s = `q-ts-${uid()}`;
|
|
390
443
|
const before = new Date(Date.now() - 6e4);
|
|
391
444
|
const future = new Date(Date.now() + 6e4);
|
|
392
|
-
await store.commit(
|
|
393
|
-
|
|
445
|
+
await store.commit(
|
|
446
|
+
s,
|
|
447
|
+
[inc(1)],
|
|
448
|
+
make_meta({ stream: s })
|
|
449
|
+
);
|
|
450
|
+
const in_window = await collect(store, {
|
|
394
451
|
stream: s,
|
|
395
452
|
stream_exact: true,
|
|
396
453
|
created_after: before,
|
|
397
454
|
created_before: future
|
|
398
455
|
});
|
|
399
|
-
(0,
|
|
400
|
-
const
|
|
456
|
+
(0, import_vitest4.expect)(in_window.length).toBe(1);
|
|
457
|
+
const out_of_window = await collect(store, {
|
|
401
458
|
stream: s,
|
|
402
459
|
stream_exact: true,
|
|
403
460
|
created_after: future
|
|
404
461
|
});
|
|
405
|
-
(0,
|
|
462
|
+
(0, import_vitest4.expect)(out_of_window.length).toBe(0);
|
|
406
463
|
});
|
|
407
|
-
(0,
|
|
464
|
+
(0, import_vitest4.it)("backward traversal short-circuits at `after` id boundary", async () => {
|
|
408
465
|
const s = `q-back-after-${uid()}`;
|
|
409
466
|
const committed = await store.commit(
|
|
410
467
|
s,
|
|
411
468
|
[inc(1), inc(2), inc(3)],
|
|
412
|
-
|
|
469
|
+
make_meta({ stream: s })
|
|
413
470
|
);
|
|
414
471
|
const got = await collect(store, {
|
|
415
472
|
stream: s,
|
|
@@ -417,14 +474,18 @@ var runStoreTck = (options) => {
|
|
|
417
474
|
backward: true,
|
|
418
475
|
after: committed[0].id
|
|
419
476
|
});
|
|
420
|
-
(0,
|
|
477
|
+
(0, import_vitest4.expect)(got.map((e) => e.id)).toEqual([
|
|
421
478
|
committed[2].id,
|
|
422
479
|
committed[1].id
|
|
423
480
|
]);
|
|
424
481
|
});
|
|
425
|
-
(0,
|
|
482
|
+
(0, import_vitest4.it)("backward traversal short-circuits at `created_after` boundary", async () => {
|
|
426
483
|
const s = `q-back-cafter-${uid()}`;
|
|
427
|
-
await store.commit(
|
|
484
|
+
await store.commit(
|
|
485
|
+
s,
|
|
486
|
+
[inc(1)],
|
|
487
|
+
make_meta({ stream: s })
|
|
488
|
+
);
|
|
428
489
|
const future = new Date(Date.now() + 6e4);
|
|
429
490
|
const got = await collect(store, {
|
|
430
491
|
stream: s,
|
|
@@ -432,11 +493,11 @@ var runStoreTck = (options) => {
|
|
|
432
493
|
backward: true,
|
|
433
494
|
created_after: future
|
|
434
495
|
});
|
|
435
|
-
(0,
|
|
496
|
+
(0, import_vitest4.expect)(got).toHaveLength(0);
|
|
436
497
|
});
|
|
437
|
-
(0,
|
|
498
|
+
(0, import_vitest4.it)("backward traversal honors created_before by skipping newer events", async () => {
|
|
438
499
|
const s = `q-back-ts-${uid()}`;
|
|
439
|
-
await store.commit(s, [inc(1)],
|
|
500
|
+
await store.commit(s, [inc(1)], make_meta());
|
|
440
501
|
const past = new Date(Date.now() - 6e4);
|
|
441
502
|
const got = await collect(store, {
|
|
442
503
|
stream: s,
|
|
@@ -444,302 +505,362 @@ var runStoreTck = (options) => {
|
|
|
444
505
|
backward: true,
|
|
445
506
|
created_before: past
|
|
446
507
|
});
|
|
447
|
-
(0,
|
|
508
|
+
(0, import_vitest4.expect)(got).toHaveLength(0);
|
|
448
509
|
});
|
|
449
|
-
(0,
|
|
510
|
+
(0, import_vitest4.it)("stream_exact disables regex matching", async () => {
|
|
450
511
|
const tag = uid();
|
|
451
512
|
const a = `q-exact-${tag}`;
|
|
452
513
|
const b = `q-exact-${tag}-extra`;
|
|
453
|
-
await store.commit(
|
|
454
|
-
|
|
514
|
+
await store.commit(
|
|
515
|
+
a,
|
|
516
|
+
[inc(1)],
|
|
517
|
+
make_meta({ stream: a })
|
|
518
|
+
);
|
|
519
|
+
await store.commit(
|
|
520
|
+
b,
|
|
521
|
+
[inc(2)],
|
|
522
|
+
make_meta({ stream: b })
|
|
523
|
+
);
|
|
455
524
|
const exact = await collect(store, { stream: a, stream_exact: true });
|
|
456
|
-
(0,
|
|
457
|
-
(0,
|
|
525
|
+
(0, import_vitest4.expect)(exact).toHaveLength(1);
|
|
526
|
+
(0, import_vitest4.expect)(exact[0].data).toEqual({ amount: 1 });
|
|
458
527
|
});
|
|
459
|
-
(0,
|
|
528
|
+
(0, import_vitest4.it)("plain regex without anchors is a substring match", async () => {
|
|
460
529
|
const tag = uid();
|
|
461
530
|
const inner = `qr-${tag}-inner`;
|
|
462
531
|
const longer = `qr-${tag}-inner-extra`;
|
|
463
532
|
await store.commit(
|
|
464
533
|
inner,
|
|
465
534
|
[inc(1)],
|
|
466
|
-
|
|
535
|
+
make_meta({ stream: inner })
|
|
467
536
|
);
|
|
468
537
|
await store.commit(
|
|
469
538
|
longer,
|
|
470
539
|
[inc(2)],
|
|
471
|
-
|
|
540
|
+
make_meta({ stream: longer })
|
|
472
541
|
);
|
|
473
542
|
const got = await collect(store, { stream: `qr-${tag}-inner` });
|
|
474
|
-
(0,
|
|
543
|
+
(0, import_vitest4.expect)(got.map((e) => e.stream).sort()).toEqual([inner, longer].sort());
|
|
475
544
|
});
|
|
476
|
-
(0,
|
|
545
|
+
(0, import_vitest4.it)("caller-anchored `^name$` matches only the whole string", async () => {
|
|
477
546
|
const tag = uid();
|
|
478
547
|
const inner = `qr-${tag}-anchor`;
|
|
479
548
|
const longer = `qr-${tag}-anchor-extra`;
|
|
480
549
|
await store.commit(
|
|
481
550
|
inner,
|
|
482
551
|
[inc(1)],
|
|
483
|
-
|
|
552
|
+
make_meta({ stream: inner })
|
|
484
553
|
);
|
|
485
554
|
await store.commit(
|
|
486
555
|
longer,
|
|
487
556
|
[inc(2)],
|
|
488
|
-
|
|
557
|
+
make_meta({ stream: longer })
|
|
489
558
|
);
|
|
490
559
|
const got = await collect(store, { stream: `^qr-${tag}-anchor$` });
|
|
491
|
-
(0,
|
|
492
|
-
(0,
|
|
560
|
+
(0, import_vitest4.expect)(got).toHaveLength(1);
|
|
561
|
+
(0, import_vitest4.expect)(got[0].stream).toBe(inner);
|
|
493
562
|
});
|
|
494
|
-
(0,
|
|
563
|
+
(0, import_vitest4.it)("caller-anchored `^prefix` matches by prefix", async () => {
|
|
495
564
|
const tag = uid();
|
|
496
565
|
const a = `qr-${tag}-pfx-a`;
|
|
497
566
|
const b = `qr-${tag}-pfx-b`;
|
|
498
567
|
const other = `zz-${tag}-other`;
|
|
499
|
-
await store.commit(
|
|
500
|
-
|
|
568
|
+
await store.commit(
|
|
569
|
+
a,
|
|
570
|
+
[inc(1)],
|
|
571
|
+
make_meta({ stream: a })
|
|
572
|
+
);
|
|
573
|
+
await store.commit(
|
|
574
|
+
b,
|
|
575
|
+
[inc(2)],
|
|
576
|
+
make_meta({ stream: b })
|
|
577
|
+
);
|
|
501
578
|
await store.commit(
|
|
502
579
|
other,
|
|
503
580
|
[inc(3)],
|
|
504
|
-
|
|
581
|
+
make_meta({ stream: other })
|
|
505
582
|
);
|
|
506
583
|
const got = await collect(store, { stream: `^qr-${tag}-pfx-` });
|
|
507
|
-
(0,
|
|
584
|
+
(0, import_vitest4.expect)(got.map((e) => e.stream).sort()).toEqual([a, b].sort());
|
|
508
585
|
});
|
|
509
586
|
});
|
|
510
|
-
(0,
|
|
511
|
-
(0,
|
|
587
|
+
(0, import_vitest4.describe)("subscribe + claim + ack", () => {
|
|
588
|
+
(0, import_vitest4.it)("subscribes new streams and is idempotent on repeat", async () => {
|
|
512
589
|
const s = `sub-${uid()}`;
|
|
513
590
|
const first = await store.subscribe([{ stream: s }]);
|
|
514
|
-
(0,
|
|
591
|
+
(0, import_vitest4.expect)(first.subscribed).toBe(1);
|
|
515
592
|
const second = await store.subscribe([{ stream: s }]);
|
|
516
|
-
(0,
|
|
593
|
+
(0, import_vitest4.expect)(second.subscribed).toBe(0);
|
|
517
594
|
});
|
|
518
|
-
(0,
|
|
595
|
+
(0, import_vitest4.it)("claims a subscribed stream and ack releases the lease", async () => {
|
|
519
596
|
const s = `claim-${uid()}`;
|
|
520
597
|
await store.subscribe([{ stream: s }]);
|
|
521
|
-
await store.commit(
|
|
598
|
+
await store.commit(
|
|
599
|
+
s,
|
|
600
|
+
[inc(1)],
|
|
601
|
+
make_meta({ stream: s })
|
|
602
|
+
);
|
|
522
603
|
const by = `worker-${uid()}`;
|
|
523
604
|
const leased = await store.claim(100, 0, by, 1e4);
|
|
524
605
|
const mine = leased.find((l) => l.stream === s);
|
|
525
|
-
(0,
|
|
526
|
-
(0,
|
|
606
|
+
(0, import_vitest4.expect)(mine).toBeDefined();
|
|
607
|
+
(0, import_vitest4.expect)(mine.by).toBe(by);
|
|
527
608
|
await store.ack([{ ...mine, at: mine.at + 1 }]);
|
|
528
609
|
});
|
|
529
|
-
(0,
|
|
610
|
+
(0, import_vitest4.it)("does not double-claim a held lease", async () => {
|
|
530
611
|
const s = `claim-held-${uid()}`;
|
|
531
612
|
const other = `claim-other-${uid()}`;
|
|
532
613
|
await store.subscribe([{ stream: s }]);
|
|
533
|
-
await store.commit(
|
|
614
|
+
await store.commit(
|
|
615
|
+
s,
|
|
616
|
+
[inc(1)],
|
|
617
|
+
make_meta({ stream: s })
|
|
618
|
+
);
|
|
534
619
|
const leasedA = await store.claim(100, 0, `wA-${uid()}`, 1e5);
|
|
535
620
|
const targetA = leasedA.find((l) => l.stream === s);
|
|
536
|
-
(0,
|
|
621
|
+
(0, import_vitest4.expect)(targetA).toBeDefined();
|
|
537
622
|
await store.subscribe([{ stream: other }]);
|
|
538
623
|
await store.commit(
|
|
539
624
|
other,
|
|
540
625
|
[inc(2)],
|
|
541
|
-
|
|
626
|
+
make_meta({ stream: other })
|
|
542
627
|
);
|
|
543
628
|
const leasedB = await store.claim(100, 0, `wB-${uid()}`, 1e5);
|
|
544
|
-
(0,
|
|
545
|
-
(0,
|
|
546
|
-
(0,
|
|
629
|
+
(0, import_vitest4.expect)(leasedB.length).toBeGreaterThan(0);
|
|
630
|
+
(0, import_vitest4.expect)(leasedB.find((l) => l.stream === s)).toBeUndefined();
|
|
631
|
+
(0, import_vitest4.expect)(leasedB.find((l) => l.stream === other)).toBeDefined();
|
|
547
632
|
});
|
|
548
|
-
(0,
|
|
633
|
+
(0, import_vitest4.it)("supports dual frontiers (lagging + leading)", async () => {
|
|
549
634
|
const s = `claim-dual-${uid()}`;
|
|
550
635
|
await store.subscribe([{ stream: s }]);
|
|
551
636
|
await store.commit(
|
|
552
637
|
s,
|
|
553
638
|
[inc(1), inc(2)],
|
|
554
|
-
|
|
639
|
+
make_meta({ stream: s })
|
|
555
640
|
);
|
|
556
641
|
const first = await store.claim(100, 0, `w-${uid()}`, 1);
|
|
557
642
|
const mine = first.find((l) => l.stream === s);
|
|
558
|
-
(0,
|
|
643
|
+
(0, import_vitest4.expect)(mine).toBeDefined();
|
|
559
644
|
await store.ack([{ ...mine, at: mine.at + 1 }]);
|
|
560
645
|
const second = await store.claim(0, 100, `w-${uid()}`, 1);
|
|
561
|
-
(0,
|
|
646
|
+
(0, import_vitest4.expect)(second.find((l) => l.stream === s)).toBeDefined();
|
|
562
647
|
});
|
|
563
|
-
(0,
|
|
648
|
+
(0, import_vitest4.it)("dedupes when both frontiers would return the same stream", async () => {
|
|
564
649
|
const s = `claim-dedup-${uid()}`;
|
|
565
650
|
await store.subscribe([{ stream: s }]);
|
|
566
|
-
await store.commit(
|
|
651
|
+
await store.commit(
|
|
652
|
+
s,
|
|
653
|
+
[inc(1)],
|
|
654
|
+
make_meta({ stream: s })
|
|
655
|
+
);
|
|
567
656
|
const claimed = await store.claim(100, 100, `w-${uid()}`, 1e5);
|
|
568
657
|
const matches = claimed.filter((l) => l.stream === s);
|
|
569
|
-
(0,
|
|
658
|
+
(0, import_vitest4.expect)(matches).toHaveLength(1);
|
|
570
659
|
});
|
|
571
|
-
(0,
|
|
660
|
+
(0, import_vitest4.it)("silently ignores ack from the wrong holder", async () => {
|
|
572
661
|
const s = `ack-wrong-${uid()}`;
|
|
573
662
|
const sibling = `ack-sibling-${uid()}`;
|
|
574
663
|
await store.subscribe([{ stream: s }, { stream: sibling }]);
|
|
575
|
-
await store.commit(
|
|
664
|
+
await store.commit(
|
|
665
|
+
s,
|
|
666
|
+
[inc(1)],
|
|
667
|
+
make_meta({ stream: s })
|
|
668
|
+
);
|
|
576
669
|
await store.commit(
|
|
577
670
|
sibling,
|
|
578
671
|
[inc(2)],
|
|
579
|
-
|
|
672
|
+
make_meta({ stream: sibling })
|
|
580
673
|
);
|
|
581
674
|
const leased = await store.claim(100, 0, `right-${uid()}`, 1e5);
|
|
582
675
|
const mine = leased.find((l) => l.stream === s);
|
|
583
|
-
const
|
|
584
|
-
(0,
|
|
585
|
-
(0,
|
|
676
|
+
const sibling_lease = leased.find((l) => l.stream === sibling);
|
|
677
|
+
(0, import_vitest4.expect)(mine).toBeDefined();
|
|
678
|
+
(0, import_vitest4.expect)(sibling_lease).toBeDefined();
|
|
586
679
|
const acked = await store.ack([
|
|
587
680
|
{ ...mine, by: "imposter" },
|
|
588
|
-
|
|
681
|
+
sibling_lease
|
|
589
682
|
]);
|
|
590
|
-
(0,
|
|
591
|
-
(0,
|
|
683
|
+
(0, import_vitest4.expect)(acked.length).toBeGreaterThan(0);
|
|
684
|
+
(0, import_vitest4.expect)(acked.find((l) => l.stream === s)).toBeUndefined();
|
|
592
685
|
});
|
|
593
|
-
(0,
|
|
686
|
+
(0, import_vitest4.it)("ack with a stale (lower) watermark does not throw", async () => {
|
|
594
687
|
const s = `ack-stale-${uid()}`;
|
|
595
688
|
await store.subscribe([{ stream: s }]);
|
|
596
689
|
const by = `w-${uid()}`;
|
|
597
690
|
const leased = await store.claim(100, 0, by, 1e5);
|
|
598
691
|
const mine = leased.find((l) => l.stream === s);
|
|
599
|
-
(0,
|
|
600
|
-
await (0,
|
|
692
|
+
(0, import_vitest4.expect)(mine).toBeDefined();
|
|
693
|
+
await (0, import_vitest4.expect)(
|
|
601
694
|
store.ack([{ ...mine, at: -5 }])
|
|
602
695
|
).resolves.toBeDefined();
|
|
603
696
|
});
|
|
604
|
-
(0,
|
|
697
|
+
(0, import_vitest4.it)("claim with no subscribed streams returns an empty array", async () => {
|
|
605
698
|
const fresh = await options.factory();
|
|
606
699
|
try {
|
|
607
700
|
await fresh.drop();
|
|
608
701
|
await fresh.seed();
|
|
609
702
|
const claimed = await fresh.claim(1, 1, `w-${uid()}`, 1e3);
|
|
610
|
-
(0,
|
|
703
|
+
(0, import_vitest4.expect)(claimed).toEqual([]);
|
|
611
704
|
} finally {
|
|
612
705
|
await fresh.dispose();
|
|
613
706
|
}
|
|
614
707
|
});
|
|
615
708
|
});
|
|
616
|
-
(0,
|
|
617
|
-
(0,
|
|
709
|
+
(0, import_vitest4.describe)("block", () => {
|
|
710
|
+
(0, import_vitest4.it)("hides blocked streams from claim", async () => {
|
|
618
711
|
const s = `block-${uid()}`;
|
|
619
712
|
await store.subscribe([{ stream: s }]);
|
|
620
|
-
await store.commit(
|
|
713
|
+
await store.commit(
|
|
714
|
+
s,
|
|
715
|
+
[inc(1)],
|
|
716
|
+
make_meta({ stream: s })
|
|
717
|
+
);
|
|
621
718
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
622
719
|
const mine = leased.find((l) => l.stream === s);
|
|
623
|
-
(0,
|
|
720
|
+
(0, import_vitest4.expect)(mine).toBeDefined();
|
|
624
721
|
const others = leased.filter((l) => l.stream !== s);
|
|
625
722
|
await store.ack(others);
|
|
626
723
|
const blocked = await store.block([
|
|
627
724
|
{ ...mine, error: "boom" }
|
|
628
725
|
]);
|
|
629
|
-
(0,
|
|
630
|
-
(0,
|
|
726
|
+
(0, import_vitest4.expect)(blocked).toHaveLength(1);
|
|
727
|
+
(0, import_vitest4.expect)(blocked[0].error).toBe("boom");
|
|
631
728
|
const again = await store.claim(100, 100, `w2-${uid()}`, 1e5);
|
|
632
|
-
(0,
|
|
729
|
+
(0, import_vitest4.expect)(again.find((l) => l.stream === s)).toBeUndefined();
|
|
633
730
|
});
|
|
634
|
-
(0,
|
|
731
|
+
(0, import_vitest4.it)("rejects block calls from a different holder", async () => {
|
|
635
732
|
const s = `block-wrong-${uid()}`;
|
|
636
733
|
await store.subscribe([{ stream: s }]);
|
|
637
|
-
await store.commit(
|
|
734
|
+
await store.commit(
|
|
735
|
+
s,
|
|
736
|
+
[inc(1)],
|
|
737
|
+
make_meta({ stream: s })
|
|
738
|
+
);
|
|
638
739
|
const leased = await store.claim(100, 0, `right-${uid()}`, 1e5);
|
|
639
740
|
const mine = leased.find((l) => l.stream === s);
|
|
640
|
-
(0,
|
|
741
|
+
(0, import_vitest4.expect)(mine).toBeDefined();
|
|
641
742
|
const others = leased.filter((l) => l.stream !== s);
|
|
642
743
|
await store.ack(others);
|
|
643
744
|
const blocked = await store.block([
|
|
644
745
|
{ ...mine, by: "imposter", error: "no" }
|
|
645
746
|
]);
|
|
646
|
-
(0,
|
|
747
|
+
(0, import_vitest4.expect)(blocked).toHaveLength(0);
|
|
647
748
|
});
|
|
648
749
|
});
|
|
649
|
-
(0,
|
|
650
|
-
(0,
|
|
750
|
+
(0, import_vitest4.describe)("reset", () => {
|
|
751
|
+
(0, import_vitest4.it)("rewinds a stream watermark to -1", async () => {
|
|
651
752
|
const s = `reset-${uid()}`;
|
|
652
753
|
await store.subscribe([{ stream: s }]);
|
|
653
|
-
await store.commit(
|
|
754
|
+
await store.commit(
|
|
755
|
+
s,
|
|
756
|
+
[inc(1)],
|
|
757
|
+
make_meta({ stream: s })
|
|
758
|
+
);
|
|
654
759
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
655
760
|
const mine = leased.find((l) => l.stream === s);
|
|
656
|
-
(0,
|
|
761
|
+
(0, import_vitest4.expect)(mine).toBeDefined();
|
|
657
762
|
await store.ack([{ ...mine, at: 99 }]);
|
|
658
|
-
(0,
|
|
763
|
+
(0, import_vitest4.expect)(await store.reset([s])).toBe(1);
|
|
659
764
|
const after = await store.claim(100, 0, `w2-${uid()}`, 1e5);
|
|
660
765
|
const back = after.find((l) => l.stream === s);
|
|
661
|
-
(0,
|
|
662
|
-
(0,
|
|
766
|
+
(0, import_vitest4.expect)(back).toBeDefined();
|
|
767
|
+
(0, import_vitest4.expect)(back.at).toBe(-1);
|
|
663
768
|
});
|
|
664
|
-
(0,
|
|
769
|
+
(0, import_vitest4.it)("clears blocked status when resetting", async () => {
|
|
665
770
|
const s = `reset-blk-${uid()}`;
|
|
666
771
|
await store.subscribe([{ stream: s }]);
|
|
667
|
-
await store.commit(
|
|
772
|
+
await store.commit(
|
|
773
|
+
s,
|
|
774
|
+
[inc(1)],
|
|
775
|
+
make_meta({ stream: s })
|
|
776
|
+
);
|
|
668
777
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
669
778
|
const mine = leased.find((l) => l.stream === s);
|
|
670
779
|
const others = leased.filter((l) => l.stream !== s);
|
|
671
780
|
await store.ack(others);
|
|
672
781
|
await store.block([{ ...mine, error: "boom" }]);
|
|
673
|
-
(0,
|
|
782
|
+
(0, import_vitest4.expect)(await store.reset([s])).toBe(1);
|
|
674
783
|
const after = await store.claim(100, 0, `w2-${uid()}`, 1e5);
|
|
675
|
-
(0,
|
|
784
|
+
(0, import_vitest4.expect)(after.find((l) => l.stream === s)).toBeDefined();
|
|
676
785
|
});
|
|
677
|
-
(0,
|
|
678
|
-
(0,
|
|
679
|
-
(0,
|
|
786
|
+
(0, import_vitest4.it)("returns 0 for unknown streams and empty input", async () => {
|
|
787
|
+
(0, import_vitest4.expect)(await store.reset([`missing-${uid()}`])).toBe(0);
|
|
788
|
+
(0, import_vitest4.expect)(await store.reset([])).toBe(0);
|
|
680
789
|
});
|
|
681
790
|
});
|
|
682
|
-
(0,
|
|
683
|
-
(0,
|
|
791
|
+
(0, import_vitest4.describe)("unblock", () => {
|
|
792
|
+
(0, import_vitest4.it)("clears blocked flag and preserves the watermark", async () => {
|
|
684
793
|
const s = `unblock-${uid()}`;
|
|
685
794
|
await store.subscribe([{ stream: s }]);
|
|
686
|
-
await store.commit(
|
|
687
|
-
|
|
795
|
+
await store.commit(
|
|
796
|
+
s,
|
|
797
|
+
[inc(1)],
|
|
798
|
+
make_meta({ stream: s })
|
|
799
|
+
);
|
|
800
|
+
await store.commit(
|
|
801
|
+
s,
|
|
802
|
+
[inc(2)],
|
|
803
|
+
make_meta({ stream: s })
|
|
804
|
+
);
|
|
688
805
|
const first = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
689
806
|
const m1 = first.find((l) => l.stream === s);
|
|
690
807
|
await store.ack([{ ...m1, at: m1.at }]);
|
|
691
|
-
const
|
|
692
|
-
const m2 =
|
|
693
|
-
(0,
|
|
694
|
-
const
|
|
808
|
+
const before_block = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
809
|
+
const m2 = before_block.find((l) => l.stream === s);
|
|
810
|
+
(0, import_vitest4.expect)(m2).toBeDefined();
|
|
811
|
+
const watermark_before = m2.at;
|
|
695
812
|
await store.block([{ ...m2, error: "permanent" }]);
|
|
696
|
-
let
|
|
813
|
+
let blocked_flag;
|
|
697
814
|
await store.query_streams(
|
|
698
815
|
(p) => {
|
|
699
|
-
|
|
816
|
+
blocked_flag = p.blocked;
|
|
700
817
|
},
|
|
701
818
|
{ stream: s, stream_exact: true, limit: 1 }
|
|
702
819
|
);
|
|
703
|
-
(0,
|
|
704
|
-
(0,
|
|
820
|
+
(0, import_vitest4.expect)(blocked_flag).toBe(true);
|
|
821
|
+
(0, import_vitest4.expect)(await store.unblock([s])).toBe(1);
|
|
705
822
|
const after = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
706
823
|
const back = after.find((l) => l.stream === s);
|
|
707
|
-
(0,
|
|
708
|
-
(0,
|
|
709
|
-
(0,
|
|
824
|
+
(0, import_vitest4.expect)(back).toBeDefined();
|
|
825
|
+
(0, import_vitest4.expect)(back.at).toBe(watermark_before);
|
|
826
|
+
(0, import_vitest4.expect)(back.retry).toBe(0);
|
|
710
827
|
});
|
|
711
|
-
(0,
|
|
828
|
+
(0, import_vitest4.it)("returns 0 when the stream is not blocked", async () => {
|
|
712
829
|
const s = `unblock-noop-${uid()}`;
|
|
713
830
|
await store.subscribe([{ stream: s }]);
|
|
714
|
-
await store.commit(
|
|
715
|
-
|
|
831
|
+
await store.commit(
|
|
832
|
+
s,
|
|
833
|
+
[inc(1)],
|
|
834
|
+
make_meta({ stream: s })
|
|
835
|
+
);
|
|
836
|
+
(0, import_vitest4.expect)(await store.unblock([s])).toBe(0);
|
|
716
837
|
});
|
|
717
|
-
(0,
|
|
718
|
-
(0,
|
|
719
|
-
(0,
|
|
838
|
+
(0, import_vitest4.it)("returns 0 for unknown streams and empty input", async () => {
|
|
839
|
+
(0, import_vitest4.expect)(await store.unblock([`missing-${uid()}`])).toBe(0);
|
|
840
|
+
(0, import_vitest4.expect)(await store.unblock([])).toBe(0);
|
|
720
841
|
});
|
|
721
|
-
(0,
|
|
842
|
+
(0, import_vitest4.it)("only counts streams that were actually blocked", async () => {
|
|
722
843
|
const s1 = `unblock-mix-a-${uid()}`;
|
|
723
844
|
const s2 = `unblock-mix-b-${uid()}`;
|
|
724
845
|
await store.subscribe([{ stream: s1 }, { stream: s2 }]);
|
|
725
846
|
await store.commit(
|
|
726
847
|
s1,
|
|
727
848
|
[inc(1)],
|
|
728
|
-
|
|
849
|
+
make_meta({ stream: s1 })
|
|
729
850
|
);
|
|
730
851
|
await store.commit(
|
|
731
852
|
s2,
|
|
732
853
|
[inc(1)],
|
|
733
|
-
|
|
854
|
+
make_meta({ stream: s2 })
|
|
734
855
|
);
|
|
735
856
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
736
857
|
const m1 = leased.find((l) => l.stream === s1);
|
|
737
858
|
const others = leased.filter((l) => l.stream !== s1);
|
|
738
859
|
await store.ack(others);
|
|
739
860
|
await store.block([{ ...m1, error: "boom" }]);
|
|
740
|
-
(0,
|
|
861
|
+
(0, import_vitest4.expect)(await store.unblock([s1, s2])).toBe(1);
|
|
741
862
|
});
|
|
742
|
-
(0,
|
|
863
|
+
(0, import_vitest4.it)("filter form: unblocks by stream pattern", async () => {
|
|
743
864
|
const tag = uid();
|
|
744
865
|
const s1 = `unblock-filter-${tag}-a`;
|
|
745
866
|
const s2 = `unblock-filter-${tag}-b`;
|
|
@@ -748,17 +869,17 @@ var runStoreTck = (options) => {
|
|
|
748
869
|
await store.commit(
|
|
749
870
|
s1,
|
|
750
871
|
[inc(1)],
|
|
751
|
-
|
|
872
|
+
make_meta({ stream: s1 })
|
|
752
873
|
);
|
|
753
874
|
await store.commit(
|
|
754
875
|
s2,
|
|
755
876
|
[inc(1)],
|
|
756
|
-
|
|
877
|
+
make_meta({ stream: s2 })
|
|
757
878
|
);
|
|
758
879
|
await store.commit(
|
|
759
880
|
s3,
|
|
760
881
|
[inc(1)],
|
|
761
|
-
|
|
882
|
+
make_meta({ stream: s3 })
|
|
762
883
|
);
|
|
763
884
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
764
885
|
const blockable = leased.filter((l) => l.stream === s1 || l.stream === s2 || l.stream === s3).map((l) => ({ ...l, error: "boom" }));
|
|
@@ -771,13 +892,13 @@ var runStoreTck = (options) => {
|
|
|
771
892
|
const count = await store.unblock({
|
|
772
893
|
stream: `^unblock-filter-${tag}-`
|
|
773
894
|
});
|
|
774
|
-
(0,
|
|
895
|
+
(0, import_vitest4.expect)(count).toBe(2);
|
|
775
896
|
const after = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
776
|
-
(0,
|
|
777
|
-
(0,
|
|
778
|
-
(0,
|
|
897
|
+
(0, import_vitest4.expect)(after.find((l) => l.stream === s3)).toBeUndefined();
|
|
898
|
+
(0, import_vitest4.expect)(after.find((l) => l.stream === s1)).toBeDefined();
|
|
899
|
+
(0, import_vitest4.expect)(after.find((l) => l.stream === s2)).toBeDefined();
|
|
779
900
|
});
|
|
780
|
-
(0,
|
|
901
|
+
(0, import_vitest4.it)("filter form: empty filter unblocks every blocked stream", async () => {
|
|
781
902
|
const tag = uid();
|
|
782
903
|
const s1 = `unblock-empty-${tag}-a`;
|
|
783
904
|
const s2 = `unblock-empty-${tag}-b`;
|
|
@@ -785,12 +906,12 @@ var runStoreTck = (options) => {
|
|
|
785
906
|
await store.commit(
|
|
786
907
|
s1,
|
|
787
908
|
[inc(1)],
|
|
788
|
-
|
|
909
|
+
make_meta({ stream: s1 })
|
|
789
910
|
);
|
|
790
911
|
await store.commit(
|
|
791
912
|
s2,
|
|
792
913
|
[inc(1)],
|
|
793
|
-
|
|
914
|
+
make_meta({ stream: s2 })
|
|
794
915
|
);
|
|
795
916
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
796
917
|
const mine = leased.filter((l) => l.stream === s1 || l.stream === s2);
|
|
@@ -801,14 +922,18 @@ var runStoreTck = (options) => {
|
|
|
801
922
|
const count = await store.unblock({
|
|
802
923
|
stream: `^unblock-empty-${tag}-`
|
|
803
924
|
});
|
|
804
|
-
(0,
|
|
925
|
+
(0, import_vitest4.expect)(count).toBe(2);
|
|
805
926
|
});
|
|
806
|
-
(0,
|
|
927
|
+
(0, import_vitest4.it)("filter form: explicit blocked:false matches nothing", async () => {
|
|
807
928
|
const tag = uid();
|
|
808
929
|
const s = `unblock-blocked-false-${tag}`;
|
|
809
930
|
await store.subscribe([{ stream: s }]);
|
|
810
|
-
await store.commit(
|
|
811
|
-
|
|
931
|
+
await store.commit(
|
|
932
|
+
s,
|
|
933
|
+
[inc(1)],
|
|
934
|
+
make_meta({ stream: s })
|
|
935
|
+
);
|
|
936
|
+
(0, import_vitest4.expect)(
|
|
812
937
|
await store.unblock({
|
|
813
938
|
stream: `^unblock-blocked-false-${tag}`,
|
|
814
939
|
blocked: false
|
|
@@ -816,8 +941,8 @@ var runStoreTck = (options) => {
|
|
|
816
941
|
).toBe(0);
|
|
817
942
|
});
|
|
818
943
|
});
|
|
819
|
-
(0,
|
|
820
|
-
(0,
|
|
944
|
+
(0, import_vitest4.describe)("reset filter form", () => {
|
|
945
|
+
(0, import_vitest4.it)("resets streams matching a stream pattern", async () => {
|
|
821
946
|
const tag = uid();
|
|
822
947
|
const s1 = `reset-filter-${tag}-a`;
|
|
823
948
|
const s2 = `reset-filter-${tag}-b`;
|
|
@@ -830,17 +955,17 @@ var runStoreTck = (options) => {
|
|
|
830
955
|
await store.commit(
|
|
831
956
|
s1,
|
|
832
957
|
[inc(1)],
|
|
833
|
-
|
|
958
|
+
make_meta({ stream: s1 })
|
|
834
959
|
);
|
|
835
960
|
await store.commit(
|
|
836
961
|
s2,
|
|
837
962
|
[inc(1)],
|
|
838
|
-
|
|
963
|
+
make_meta({ stream: s2 })
|
|
839
964
|
);
|
|
840
965
|
await store.commit(
|
|
841
966
|
other,
|
|
842
967
|
[inc(1)],
|
|
843
|
-
|
|
968
|
+
make_meta({ stream: other })
|
|
844
969
|
);
|
|
845
970
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
846
971
|
const mine = leased.filter(
|
|
@@ -848,8 +973,8 @@ var runStoreTck = (options) => {
|
|
|
848
973
|
);
|
|
849
974
|
await store.ack(mine.map((l) => ({ ...l, at: l.at + 100 })));
|
|
850
975
|
const count = await store.reset({ stream: `^reset-filter-${tag}-` });
|
|
851
|
-
(0,
|
|
852
|
-
const
|
|
976
|
+
(0, import_vitest4.expect)(count).toBe(2);
|
|
977
|
+
const position_for = async (name) => {
|
|
853
978
|
let at = null;
|
|
854
979
|
await store.query_streams(
|
|
855
980
|
(p) => {
|
|
@@ -859,11 +984,11 @@ var runStoreTck = (options) => {
|
|
|
859
984
|
);
|
|
860
985
|
return at;
|
|
861
986
|
};
|
|
862
|
-
(0,
|
|
863
|
-
(0,
|
|
864
|
-
(0,
|
|
987
|
+
(0, import_vitest4.expect)(await position_for(s1)).toBe(-1);
|
|
988
|
+
(0, import_vitest4.expect)(await position_for(s2)).toBe(-1);
|
|
989
|
+
(0, import_vitest4.expect)(await position_for(other)).toBeGreaterThan(-1);
|
|
865
990
|
});
|
|
866
|
-
(0,
|
|
991
|
+
(0, import_vitest4.it)("filter form: resets only blocked streams when blocked:true", async () => {
|
|
867
992
|
const tag = uid();
|
|
868
993
|
const s1 = `reset-blocked-${tag}-blocked`;
|
|
869
994
|
const s2 = `reset-blocked-${tag}-fine`;
|
|
@@ -871,12 +996,12 @@ var runStoreTck = (options) => {
|
|
|
871
996
|
await store.commit(
|
|
872
997
|
s1,
|
|
873
998
|
[inc(1)],
|
|
874
|
-
|
|
999
|
+
make_meta({ stream: s1 })
|
|
875
1000
|
);
|
|
876
1001
|
await store.commit(
|
|
877
1002
|
s2,
|
|
878
1003
|
[inc(1)],
|
|
879
|
-
|
|
1004
|
+
make_meta({ stream: s2 })
|
|
880
1005
|
);
|
|
881
1006
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
882
1007
|
const m1 = leased.find((l) => l.stream === s1);
|
|
@@ -886,11 +1011,11 @@ var runStoreTck = (options) => {
|
|
|
886
1011
|
stream: `^reset-blocked-${tag}-`,
|
|
887
1012
|
blocked: true
|
|
888
1013
|
});
|
|
889
|
-
(0,
|
|
1014
|
+
(0, import_vitest4.expect)(count).toBe(1);
|
|
890
1015
|
});
|
|
891
1016
|
});
|
|
892
|
-
(0,
|
|
893
|
-
(0,
|
|
1017
|
+
(0, import_vitest4.describe)("prioritize", () => {
|
|
1018
|
+
(0, import_vitest4.it)("sets priority directly, overriding subscribe's max() rule", async () => {
|
|
894
1019
|
const tag = uid();
|
|
895
1020
|
const s1 = `pri-${tag}-a`;
|
|
896
1021
|
const s2 = `pri-${tag}-b`;
|
|
@@ -902,7 +1027,7 @@ var runStoreTck = (options) => {
|
|
|
902
1027
|
{ stream: s1, stream_exact: true },
|
|
903
1028
|
3
|
|
904
1029
|
);
|
|
905
|
-
(0,
|
|
1030
|
+
(0, import_vitest4.expect)(updated).toBe(1);
|
|
906
1031
|
const got1 = {};
|
|
907
1032
|
const got2 = {};
|
|
908
1033
|
await store.query_streams(
|
|
@@ -912,12 +1037,12 @@ var runStoreTck = (options) => {
|
|
|
912
1037
|
},
|
|
913
1038
|
{ stream: `pri-${tag}-.*`, limit: 100 }
|
|
914
1039
|
);
|
|
915
|
-
(0,
|
|
916
|
-
(0,
|
|
1040
|
+
(0, import_vitest4.expect)(got1.priority).toBe(3);
|
|
1041
|
+
(0, import_vitest4.expect)(got2.priority).toBe(5);
|
|
917
1042
|
});
|
|
918
1043
|
});
|
|
919
|
-
(0,
|
|
920
|
-
(0,
|
|
1044
|
+
(0, import_vitest4.describe)("lanes", () => {
|
|
1045
|
+
(0, import_vitest4.it)("subscribe defaults lane to 'default' when omitted", async () => {
|
|
921
1046
|
const s = `lane-default-${uid()}`;
|
|
922
1047
|
await store.subscribe([{ stream: s }]);
|
|
923
1048
|
const seen = [];
|
|
@@ -925,9 +1050,9 @@ var runStoreTck = (options) => {
|
|
|
925
1050
|
stream: s,
|
|
926
1051
|
stream_exact: true
|
|
927
1052
|
});
|
|
928
|
-
(0,
|
|
1053
|
+
(0, import_vitest4.expect)(seen).toEqual(["default"]);
|
|
929
1054
|
});
|
|
930
|
-
(0,
|
|
1055
|
+
(0, import_vitest4.it)("subscribe records the lane passed in", async () => {
|
|
931
1056
|
const s = `lane-set-${uid()}`;
|
|
932
1057
|
await store.subscribe([{ stream: s, lane: "slow" }]);
|
|
933
1058
|
const seen = [];
|
|
@@ -935,9 +1060,9 @@ var runStoreTck = (options) => {
|
|
|
935
1060
|
stream: s,
|
|
936
1061
|
stream_exact: true
|
|
937
1062
|
});
|
|
938
|
-
(0,
|
|
1063
|
+
(0, import_vitest4.expect)(seen).toEqual(["slow"]);
|
|
939
1064
|
});
|
|
940
|
-
(0,
|
|
1065
|
+
(0, import_vitest4.it)("subscribe re-lanes existing streams on subsequent calls", async () => {
|
|
941
1066
|
const s = `lane-upsert-${uid()}`;
|
|
942
1067
|
await store.subscribe([{ stream: s, lane: "slow" }]);
|
|
943
1068
|
await store.subscribe([{ stream: s, lane: "fast" }]);
|
|
@@ -946,45 +1071,45 @@ var runStoreTck = (options) => {
|
|
|
946
1071
|
stream: s,
|
|
947
1072
|
stream_exact: true
|
|
948
1073
|
});
|
|
949
|
-
(0,
|
|
1074
|
+
(0, import_vitest4.expect)(seen).toEqual(["fast"]);
|
|
950
1075
|
});
|
|
951
|
-
(0,
|
|
1076
|
+
(0, import_vitest4.it)("claim() filters by lane when supplied and returns lane on the Lease", async () => {
|
|
952
1077
|
const tag = uid();
|
|
953
1078
|
const src1 = `lane-claim-src1-${tag}`;
|
|
954
1079
|
const src2 = `lane-claim-src2-${tag}`;
|
|
955
|
-
const
|
|
956
|
-
const
|
|
1080
|
+
const sub_default = `lane-claim-def-${tag}`;
|
|
1081
|
+
const sub_slow = `lane-claim-slow-${tag}`;
|
|
957
1082
|
await store.commit(
|
|
958
1083
|
src1,
|
|
959
1084
|
[inc(1)],
|
|
960
|
-
|
|
1085
|
+
make_meta({ stream: src1 })
|
|
961
1086
|
);
|
|
962
1087
|
await store.commit(
|
|
963
1088
|
src2,
|
|
964
1089
|
[inc(1)],
|
|
965
|
-
|
|
1090
|
+
make_meta({ stream: src2 })
|
|
966
1091
|
);
|
|
967
1092
|
await store.subscribe([
|
|
968
|
-
{ stream:
|
|
969
|
-
{ stream:
|
|
1093
|
+
{ stream: sub_default, source: src1 },
|
|
1094
|
+
{ stream: sub_slow, source: src2, lane: "slow" }
|
|
970
1095
|
]);
|
|
971
1096
|
const slow = await store.claim(50, 0, `w-slow-${tag}`, 1e3, "slow");
|
|
972
|
-
const
|
|
973
|
-
(l) => l.stream ===
|
|
1097
|
+
const slow_mine = slow.filter(
|
|
1098
|
+
(l) => l.stream === sub_default || l.stream === sub_slow
|
|
974
1099
|
);
|
|
975
|
-
(0,
|
|
976
|
-
(0,
|
|
977
|
-
await store.ack(
|
|
1100
|
+
(0, import_vitest4.expect)(slow_mine.map((l) => l.stream)).toEqual([sub_slow]);
|
|
1101
|
+
(0, import_vitest4.expect)(slow_mine[0]?.lane).toBe("slow");
|
|
1102
|
+
await store.ack(slow_mine.map((l) => ({ ...l, at: l.at + 1 })));
|
|
978
1103
|
const all = await store.claim(50, 0, `w-all-${tag}`, 1e3);
|
|
979
|
-
const
|
|
980
|
-
(0,
|
|
981
|
-
|
|
982
|
-
{ stream:
|
|
983
|
-
{ stream:
|
|
1104
|
+
const all_mine = all.filter((l) => l.stream === sub_default || l.stream === sub_slow).map((l) => ({ stream: l.stream, lane: l.lane }));
|
|
1105
|
+
(0, import_vitest4.expect)(all_mine).toEqual(
|
|
1106
|
+
import_vitest4.expect.arrayContaining([
|
|
1107
|
+
{ stream: sub_default, lane: "default" },
|
|
1108
|
+
{ stream: sub_slow, lane: "slow" }
|
|
984
1109
|
])
|
|
985
1110
|
);
|
|
986
1111
|
});
|
|
987
|
-
(0,
|
|
1112
|
+
(0, import_vitest4.it)("query_streams filters by lane", async () => {
|
|
988
1113
|
const tag = uid();
|
|
989
1114
|
const a = `lane-q-a-${tag}`;
|
|
990
1115
|
const b = `lane-q-b-${tag}`;
|
|
@@ -1000,9 +1125,9 @@ var runStoreTck = (options) => {
|
|
|
1000
1125
|
stream: `lane-q-.*-${tag}`,
|
|
1001
1126
|
limit: 100
|
|
1002
1127
|
});
|
|
1003
|
-
(0,
|
|
1128
|
+
(0, import_vitest4.expect)(seen.sort()).toEqual([a, c]);
|
|
1004
1129
|
});
|
|
1005
|
-
(0,
|
|
1130
|
+
(0, import_vitest4.it)("prioritize filters by lane", async () => {
|
|
1006
1131
|
const tag = uid();
|
|
1007
1132
|
const a = `lane-pri-a-${tag}`;
|
|
1008
1133
|
const b = `lane-pri-b-${tag}`;
|
|
@@ -1011,16 +1136,16 @@ var runStoreTck = (options) => {
|
|
|
1011
1136
|
{ stream: b, lane: `pfast-${tag}` }
|
|
1012
1137
|
]);
|
|
1013
1138
|
const updated = await store.prioritize({ lane: `pslow-${tag}` }, 7);
|
|
1014
|
-
(0,
|
|
1139
|
+
(0, import_vitest4.expect)(updated).toBe(1);
|
|
1015
1140
|
const seen = /* @__PURE__ */ new Map();
|
|
1016
1141
|
await store.query_streams((p) => seen.set(p.stream, p.priority), {
|
|
1017
1142
|
stream: `lane-pri-.*-${tag}`,
|
|
1018
1143
|
limit: 100
|
|
1019
1144
|
});
|
|
1020
|
-
(0,
|
|
1021
|
-
(0,
|
|
1145
|
+
(0, import_vitest4.expect)(seen.get(a)).toBe(7);
|
|
1146
|
+
(0, import_vitest4.expect)(seen.get(b)).toBe(0);
|
|
1022
1147
|
});
|
|
1023
|
-
(0,
|
|
1148
|
+
(0, import_vitest4.it)("reset filters by lane", async () => {
|
|
1024
1149
|
const tag = uid();
|
|
1025
1150
|
const src = `lane-reset-src-${tag}`;
|
|
1026
1151
|
const a = `lane-reset-a-${tag}`;
|
|
@@ -1028,7 +1153,7 @@ var runStoreTck = (options) => {
|
|
|
1028
1153
|
await store.commit(
|
|
1029
1154
|
src,
|
|
1030
1155
|
[inc(1)],
|
|
1031
|
-
|
|
1156
|
+
make_meta({ stream: src })
|
|
1032
1157
|
);
|
|
1033
1158
|
await store.subscribe([
|
|
1034
1159
|
{ stream: a, source: src, lane: `rslow-${tag}` },
|
|
@@ -1038,7 +1163,7 @@ var runStoreTck = (options) => {
|
|
|
1038
1163
|
const mine = leases.filter((l) => l.stream === a || l.stream === b);
|
|
1039
1164
|
await store.ack(mine.map((l) => ({ ...l, at: l.at + 1 })));
|
|
1040
1165
|
const count = await store.reset({ lane: `rslow-${tag}` });
|
|
1041
|
-
(0,
|
|
1166
|
+
(0, import_vitest4.expect)(count).toBe(1);
|
|
1042
1167
|
const ats = /* @__PURE__ */ new Map();
|
|
1043
1168
|
for (const name of [a, b]) {
|
|
1044
1169
|
await store.query_streams((p) => ats.set(p.stream, p.at), {
|
|
@@ -1046,10 +1171,10 @@ var runStoreTck = (options) => {
|
|
|
1046
1171
|
stream_exact: true
|
|
1047
1172
|
});
|
|
1048
1173
|
}
|
|
1049
|
-
(0,
|
|
1050
|
-
(0,
|
|
1174
|
+
(0, import_vitest4.expect)(ats.get(a)).toBe(-1);
|
|
1175
|
+
(0, import_vitest4.expect)(ats.get(b)).toBeGreaterThanOrEqual(0);
|
|
1051
1176
|
});
|
|
1052
|
-
(0,
|
|
1177
|
+
(0, import_vitest4.it)("unblock filters by lane", async () => {
|
|
1053
1178
|
const tag = uid();
|
|
1054
1179
|
const src = `lane-ub-src-${tag}`;
|
|
1055
1180
|
const a = `lane-ub-a-${tag}`;
|
|
@@ -1057,7 +1182,7 @@ var runStoreTck = (options) => {
|
|
|
1057
1182
|
await store.commit(
|
|
1058
1183
|
src,
|
|
1059
1184
|
[inc(1)],
|
|
1060
|
-
|
|
1185
|
+
make_meta({ stream: src })
|
|
1061
1186
|
);
|
|
1062
1187
|
await store.subscribe([
|
|
1063
1188
|
{ stream: a, source: src, lane: `uslow-${tag}` },
|
|
@@ -1067,7 +1192,7 @@ var runStoreTck = (options) => {
|
|
|
1067
1192
|
const mine = leases.filter((l) => l.stream === a || l.stream === b);
|
|
1068
1193
|
await store.block(mine.map((l) => ({ ...l, error: "boom" })));
|
|
1069
1194
|
const count = await store.unblock({ lane: `uslow-${tag}` });
|
|
1070
|
-
(0,
|
|
1195
|
+
(0, import_vitest4.expect)(count).toBe(1);
|
|
1071
1196
|
const blocked = /* @__PURE__ */ new Map();
|
|
1072
1197
|
for (const name of [a, b]) {
|
|
1073
1198
|
await store.query_streams((p) => blocked.set(p.stream, p.blocked), {
|
|
@@ -1075,20 +1200,20 @@ var runStoreTck = (options) => {
|
|
|
1075
1200
|
stream_exact: true
|
|
1076
1201
|
});
|
|
1077
1202
|
}
|
|
1078
|
-
(0,
|
|
1079
|
-
(0,
|
|
1203
|
+
(0, import_vitest4.expect)(blocked.get(a)).toBe(false);
|
|
1204
|
+
(0, import_vitest4.expect)(blocked.get(b)).toBe(true);
|
|
1080
1205
|
});
|
|
1081
1206
|
});
|
|
1082
|
-
(0,
|
|
1083
|
-
(0,
|
|
1207
|
+
(0, import_vitest4.describe)("truncate", () => {
|
|
1208
|
+
(0, import_vitest4.it)("seeds a tombstone when no snapshot is provided", async () => {
|
|
1084
1209
|
const s = `trunc-tomb-${uid()}`;
|
|
1085
1210
|
await store.commit(
|
|
1086
1211
|
s,
|
|
1087
1212
|
[inc(1), inc(2)],
|
|
1088
|
-
|
|
1213
|
+
make_meta({ stream: s })
|
|
1089
1214
|
);
|
|
1090
1215
|
const result = await store.truncate([{ stream: s }]);
|
|
1091
|
-
(0,
|
|
1216
|
+
(0, import_vitest4.expect)(result.get(s)?.deleted).toBe(2);
|
|
1092
1217
|
const remaining = [];
|
|
1093
1218
|
await store.query(
|
|
1094
1219
|
(e) => {
|
|
@@ -1096,18 +1221,22 @@ var runStoreTck = (options) => {
|
|
|
1096
1221
|
},
|
|
1097
1222
|
{ stream: s, stream_exact: true }
|
|
1098
1223
|
);
|
|
1099
|
-
(0,
|
|
1100
|
-
(0,
|
|
1224
|
+
(0, import_vitest4.expect)(remaining).toHaveLength(1);
|
|
1225
|
+
(0, import_vitest4.expect)(remaining[0].name).toBe(
|
|
1101
1226
|
"__tombstone__"
|
|
1102
1227
|
);
|
|
1103
1228
|
});
|
|
1104
|
-
(0,
|
|
1229
|
+
(0, import_vitest4.it)("seeds a snapshot when one is provided", async () => {
|
|
1105
1230
|
const s = `trunc-snap-${uid()}`;
|
|
1106
|
-
await store.commit(
|
|
1231
|
+
await store.commit(
|
|
1232
|
+
s,
|
|
1233
|
+
[inc(1)],
|
|
1234
|
+
make_meta({ stream: s })
|
|
1235
|
+
);
|
|
1107
1236
|
const result = await store.truncate([
|
|
1108
1237
|
{ stream: s, snapshot: { count: 7 } }
|
|
1109
1238
|
]);
|
|
1110
|
-
(0,
|
|
1239
|
+
(0, import_vitest4.expect)(result.get(s)?.deleted).toBe(1);
|
|
1111
1240
|
const remaining = [];
|
|
1112
1241
|
await store.query(
|
|
1113
1242
|
(e) => {
|
|
@@ -1115,24 +1244,24 @@ var runStoreTck = (options) => {
|
|
|
1115
1244
|
},
|
|
1116
1245
|
{ stream: s, stream_exact: true, with_snaps: true }
|
|
1117
1246
|
);
|
|
1118
|
-
(0,
|
|
1119
|
-
(0,
|
|
1247
|
+
(0, import_vitest4.expect)(remaining).toHaveLength(1);
|
|
1248
|
+
(0, import_vitest4.expect)(remaining[0].name).toBe(
|
|
1120
1249
|
"__snapshot__"
|
|
1121
1250
|
);
|
|
1122
|
-
(0,
|
|
1251
|
+
(0, import_vitest4.expect)(remaining[0].data).toEqual({ count: 7 });
|
|
1123
1252
|
});
|
|
1124
|
-
(0,
|
|
1253
|
+
(0, import_vitest4.it)("returns an empty map for empty input", async () => {
|
|
1125
1254
|
const result = await store.truncate([]);
|
|
1126
|
-
(0,
|
|
1255
|
+
(0, import_vitest4.expect)(result.size).toBe(0);
|
|
1127
1256
|
});
|
|
1128
|
-
(0,
|
|
1257
|
+
(0, import_vitest4.it)("returns 0 deleted for streams that don't exist", async () => {
|
|
1129
1258
|
const s = `trunc-missing-${uid()}`;
|
|
1130
1259
|
const result = await store.truncate([{ stream: s }]);
|
|
1131
|
-
(0,
|
|
1260
|
+
(0, import_vitest4.expect)(result.get(s)?.deleted).toBe(0);
|
|
1132
1261
|
});
|
|
1133
1262
|
});
|
|
1134
|
-
(0,
|
|
1135
|
-
(0,
|
|
1263
|
+
(0, import_vitest4.describe)("query_streams", () => {
|
|
1264
|
+
(0, import_vitest4.it)("returns positions filtered by stream regex, exact, source, and source_exact", async () => {
|
|
1136
1265
|
const tag = uid();
|
|
1137
1266
|
const proj1 = `qs-${tag}-projection-tickets`;
|
|
1138
1267
|
const proj2 = `qs-${tag}-projection-users`;
|
|
@@ -1147,41 +1276,41 @@ var runStoreTck = (options) => {
|
|
|
1147
1276
|
{ stream: dyn2, source: src2 }
|
|
1148
1277
|
]);
|
|
1149
1278
|
const all = [];
|
|
1150
|
-
const
|
|
1279
|
+
const all_result = await store.query_streams(
|
|
1151
1280
|
(p) => all.push({ stream: p.stream, source: p.source }),
|
|
1152
1281
|
{ stream: `qs-${tag}-.*` }
|
|
1153
1282
|
);
|
|
1154
|
-
(0,
|
|
1155
|
-
(0,
|
|
1156
|
-
(0,
|
|
1283
|
+
(0, import_vitest4.expect)(all_result.count).toBe(4);
|
|
1284
|
+
(0, import_vitest4.expect)(all_result.maxEventId).toBeGreaterThanOrEqual(-1);
|
|
1285
|
+
(0, import_vitest4.expect)(all.map((p) => p.stream).sort()).toEqual(
|
|
1157
1286
|
[proj1, proj2, dyn1, dyn2].sort()
|
|
1158
1287
|
);
|
|
1159
1288
|
const projections = [];
|
|
1160
1289
|
await store.query_streams((p) => projections.push(p.stream), {
|
|
1161
1290
|
stream: `qs-${tag}-projection-.*`
|
|
1162
1291
|
});
|
|
1163
|
-
(0,
|
|
1292
|
+
(0, import_vitest4.expect)(projections.sort()).toEqual([proj1, proj2].sort());
|
|
1164
1293
|
const exact = [];
|
|
1165
1294
|
await store.query_streams((p) => exact.push(p.stream), {
|
|
1166
1295
|
stream: dyn1,
|
|
1167
1296
|
stream_exact: true
|
|
1168
1297
|
});
|
|
1169
|
-
(0,
|
|
1170
|
-
const
|
|
1171
|
-
await store.query_streams((p) =>
|
|
1298
|
+
(0, import_vitest4.expect)(exact).toEqual([dyn1]);
|
|
1299
|
+
const by_source = [];
|
|
1300
|
+
await store.query_streams((p) => by_source.push(p.stream), {
|
|
1172
1301
|
stream: `qs-${tag}-.*`,
|
|
1173
1302
|
source: `qs-${tag}-src-.*`
|
|
1174
1303
|
});
|
|
1175
|
-
(0,
|
|
1176
|
-
const
|
|
1177
|
-
await store.query_streams((p) =>
|
|
1304
|
+
(0, import_vitest4.expect)(by_source.sort()).toEqual([dyn1, dyn2].sort());
|
|
1305
|
+
const exact_source = [];
|
|
1306
|
+
await store.query_streams((p) => exact_source.push(p.stream), {
|
|
1178
1307
|
stream: `qs-${tag}-.*`,
|
|
1179
1308
|
source: src2,
|
|
1180
1309
|
source_exact: true
|
|
1181
1310
|
});
|
|
1182
|
-
(0,
|
|
1311
|
+
(0, import_vitest4.expect)(exact_source).toEqual([dyn2]);
|
|
1183
1312
|
});
|
|
1184
|
-
(0,
|
|
1313
|
+
(0, import_vitest4.it)("paginates with limit + after (keyset)", async () => {
|
|
1185
1314
|
const tag = uid();
|
|
1186
1315
|
const streams = [
|
|
1187
1316
|
`qp-${tag}-a`,
|
|
@@ -1195,22 +1324,26 @@ var runStoreTck = (options) => {
|
|
|
1195
1324
|
stream: `qp-${tag}-.*`,
|
|
1196
1325
|
limit: 2
|
|
1197
1326
|
});
|
|
1198
|
-
(0,
|
|
1327
|
+
(0, import_vitest4.expect)(page1).toHaveLength(2);
|
|
1199
1328
|
const page2 = [];
|
|
1200
1329
|
await store.query_streams((p) => page2.push(p.stream), {
|
|
1201
1330
|
stream: `qp-${tag}-.*`,
|
|
1202
1331
|
limit: 2,
|
|
1203
1332
|
after: page1.at(-1)
|
|
1204
1333
|
});
|
|
1205
|
-
(0,
|
|
1206
|
-
(0,
|
|
1334
|
+
(0, import_vitest4.expect)(page2).toHaveLength(2);
|
|
1335
|
+
(0, import_vitest4.expect)([...page1, ...page2].sort()).toEqual([...streams].sort());
|
|
1207
1336
|
});
|
|
1208
|
-
(0,
|
|
1337
|
+
(0, import_vitest4.it)("filters by blocked status", async () => {
|
|
1209
1338
|
const tag = uid();
|
|
1210
1339
|
const s = `qb-${tag}`;
|
|
1211
1340
|
const sibling = `qb-${tag}-other`;
|
|
1212
1341
|
await store.subscribe([{ stream: s }, { stream: sibling }]);
|
|
1213
|
-
await store.commit(
|
|
1342
|
+
await store.commit(
|
|
1343
|
+
s,
|
|
1344
|
+
[inc(1)],
|
|
1345
|
+
make_meta({ stream: s })
|
|
1346
|
+
);
|
|
1214
1347
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
1215
1348
|
const mine = leased.find((l) => l.stream === s);
|
|
1216
1349
|
const others = leased.filter((l) => l.stream !== s);
|
|
@@ -1221,18 +1354,18 @@ var runStoreTck = (options) => {
|
|
|
1221
1354
|
(p) => blocked.push({ stream: p.stream, error: p.error }),
|
|
1222
1355
|
{ stream: `qb-${tag}.*`, blocked: true }
|
|
1223
1356
|
);
|
|
1224
|
-
(0,
|
|
1225
|
-
(0,
|
|
1357
|
+
(0, import_vitest4.expect)(blocked).toHaveLength(1);
|
|
1358
|
+
(0, import_vitest4.expect)(blocked[0].error).toBe("boom");
|
|
1226
1359
|
const unblocked = [];
|
|
1227
1360
|
await store.query_streams((p) => unblocked.push(p.stream), {
|
|
1228
1361
|
stream: `qb-${tag}.*`,
|
|
1229
1362
|
blocked: false
|
|
1230
1363
|
});
|
|
1231
|
-
(0,
|
|
1364
|
+
(0, import_vitest4.expect)(unblocked).toEqual([sibling]);
|
|
1232
1365
|
});
|
|
1233
1366
|
});
|
|
1234
|
-
(0,
|
|
1235
|
-
(0,
|
|
1367
|
+
(0, import_vitest4.describe)("query_stats", () => {
|
|
1368
|
+
(0, import_vitest4.it)("array input \u2014 returns head per stream, absent when not in input", async () => {
|
|
1236
1369
|
const tag = uid();
|
|
1237
1370
|
const sA = `qst-${tag}-a`;
|
|
1238
1371
|
const sB = `qst-${tag}-b`;
|
|
@@ -1240,111 +1373,131 @@ var runStoreTck = (options) => {
|
|
|
1240
1373
|
await store.commit(
|
|
1241
1374
|
sA,
|
|
1242
1375
|
[inc(1), inc(2)],
|
|
1243
|
-
|
|
1376
|
+
make_meta({ stream: sA })
|
|
1244
1377
|
);
|
|
1245
1378
|
await store.commit(
|
|
1246
1379
|
sB,
|
|
1247
1380
|
[dec(5)],
|
|
1248
|
-
|
|
1381
|
+
make_meta({ stream: sB })
|
|
1249
1382
|
);
|
|
1250
1383
|
await store.commit(
|
|
1251
1384
|
sUnasked,
|
|
1252
1385
|
[inc(99)],
|
|
1253
|
-
|
|
1386
|
+
make_meta({ stream: sUnasked })
|
|
1254
1387
|
);
|
|
1255
1388
|
const stats = await store.query_stats([sA, sB]);
|
|
1256
|
-
(0,
|
|
1257
|
-
(0,
|
|
1258
|
-
(0,
|
|
1259
|
-
(0,
|
|
1260
|
-
(0,
|
|
1261
|
-
(0,
|
|
1389
|
+
(0, import_vitest4.expect)(stats.size).toBe(2);
|
|
1390
|
+
(0, import_vitest4.expect)(stats.get(sA)?.head.name).toBe("Incremented");
|
|
1391
|
+
(0, import_vitest4.expect)((stats.get(sA)?.head.data).amount).toBe(2);
|
|
1392
|
+
(0, import_vitest4.expect)(stats.get(sB)?.head.name).toBe("Decremented");
|
|
1393
|
+
(0, import_vitest4.expect)((stats.get(sB)?.head.data).amount).toBe(5);
|
|
1394
|
+
(0, import_vitest4.expect)(stats.has(sUnasked)).toBe(false);
|
|
1262
1395
|
const empty = await store.query_stats([]);
|
|
1263
|
-
(0,
|
|
1396
|
+
(0, import_vitest4.expect)(empty.size).toBe(0);
|
|
1264
1397
|
const unknown = await store.query_stats([`qst-${tag}-missing`]);
|
|
1265
|
-
(0,
|
|
1398
|
+
(0, import_vitest4.expect)(unknown.size).toBe(0);
|
|
1266
1399
|
});
|
|
1267
|
-
(0,
|
|
1400
|
+
(0, import_vitest4.it)("tail returns the earliest event per stream", async () => {
|
|
1268
1401
|
const tag = uid();
|
|
1269
1402
|
const s = `qst-tail-${tag}`;
|
|
1270
|
-
await store.commit(
|
|
1271
|
-
|
|
1272
|
-
|
|
1403
|
+
await store.commit(
|
|
1404
|
+
s,
|
|
1405
|
+
[inc(1)],
|
|
1406
|
+
make_meta({ stream: s })
|
|
1407
|
+
);
|
|
1408
|
+
await store.commit(
|
|
1409
|
+
s,
|
|
1410
|
+
[inc(2)],
|
|
1411
|
+
make_meta({ stream: s })
|
|
1412
|
+
);
|
|
1413
|
+
await store.commit(
|
|
1414
|
+
s,
|
|
1415
|
+
[inc(3)],
|
|
1416
|
+
make_meta({ stream: s })
|
|
1417
|
+
);
|
|
1273
1418
|
const stats = await store.query_stats([s], {
|
|
1274
1419
|
tail: true
|
|
1275
1420
|
});
|
|
1276
1421
|
const r = stats.get(s);
|
|
1277
|
-
(0,
|
|
1278
|
-
(0,
|
|
1279
|
-
(0,
|
|
1280
|
-
(0,
|
|
1422
|
+
(0, import_vitest4.expect)(r?.head.name).toBe("Incremented");
|
|
1423
|
+
(0, import_vitest4.expect)((r?.head.data).amount).toBe(3);
|
|
1424
|
+
(0, import_vitest4.expect)(r?.tail?.name).toBe("Incremented");
|
|
1425
|
+
(0, import_vitest4.expect)((r?.tail?.data).amount).toBe(1);
|
|
1281
1426
|
});
|
|
1282
|
-
(0,
|
|
1427
|
+
(0, import_vitest4.it)("count + names \u2014 full aggregates including framework markers", async () => {
|
|
1283
1428
|
const tag = uid();
|
|
1284
1429
|
const s = `qst-cn-${tag}`;
|
|
1285
|
-
await store.commit(
|
|
1430
|
+
await store.commit(
|
|
1431
|
+
s,
|
|
1432
|
+
[inc(1)],
|
|
1433
|
+
make_meta({ stream: s })
|
|
1434
|
+
);
|
|
1286
1435
|
await store.truncate([{ stream: s, snapshot: { count: 99 } }]);
|
|
1287
1436
|
await store.commit(
|
|
1288
1437
|
s,
|
|
1289
1438
|
[inc(2), inc(3), dec(1)],
|
|
1290
|
-
|
|
1439
|
+
make_meta({ stream: s })
|
|
1291
1440
|
);
|
|
1292
1441
|
const stats = await store.query_stats([s], {
|
|
1293
1442
|
count: true,
|
|
1294
1443
|
names: true
|
|
1295
1444
|
});
|
|
1296
1445
|
const r = stats.get(s);
|
|
1297
|
-
(0,
|
|
1298
|
-
(0,
|
|
1299
|
-
(0,
|
|
1300
|
-
(0,
|
|
1301
|
-
(0,
|
|
1446
|
+
(0, import_vitest4.expect)(r?.count).toBe(4);
|
|
1447
|
+
(0, import_vitest4.expect)(r?.names?.[import_act.SNAP_EVENT]).toBe(1);
|
|
1448
|
+
(0, import_vitest4.expect)(r?.names?.Incremented).toBe(2);
|
|
1449
|
+
(0, import_vitest4.expect)(r?.names?.Decremented).toBe(1);
|
|
1450
|
+
(0, import_vitest4.expect)(r?.names?.[import_act.SNAP_EVENT]).toBe(1);
|
|
1302
1451
|
});
|
|
1303
|
-
(0,
|
|
1452
|
+
(0, import_vitest4.it)("exclude shifts head past filtered events; stream absent when all filtered", async () => {
|
|
1304
1453
|
const tag = uid();
|
|
1305
1454
|
const s = `qst-excl-${tag}`;
|
|
1306
1455
|
const sAllOut = `qst-allout-${tag}`;
|
|
1307
1456
|
await store.commit(
|
|
1308
1457
|
s,
|
|
1309
1458
|
[inc(1), dec(2), inc(3)],
|
|
1310
|
-
|
|
1459
|
+
make_meta({ stream: s })
|
|
1311
1460
|
);
|
|
1312
1461
|
await store.commit(
|
|
1313
1462
|
sAllOut,
|
|
1314
1463
|
[inc(7)],
|
|
1315
|
-
|
|
1464
|
+
make_meta({ stream: sAllOut })
|
|
1316
1465
|
);
|
|
1317
1466
|
const all = await store.query_stats([s]);
|
|
1318
|
-
(0,
|
|
1319
|
-
(0,
|
|
1467
|
+
(0, import_vitest4.expect)(all.get(s)?.head.name).toBe("Incremented");
|
|
1468
|
+
(0, import_vitest4.expect)((all.get(s)?.head.data).amount).toBe(3);
|
|
1320
1469
|
const excl = await store.query_stats([s], {
|
|
1321
1470
|
exclude: ["Incremented"]
|
|
1322
1471
|
});
|
|
1323
|
-
(0,
|
|
1324
|
-
(0,
|
|
1472
|
+
(0, import_vitest4.expect)(excl.get(s)?.head.name).toBe("Decremented");
|
|
1473
|
+
(0, import_vitest4.expect)((excl.get(s)?.head.data).amount).toBe(2);
|
|
1325
1474
|
const wipe = await store.query_stats([sAllOut], {
|
|
1326
1475
|
exclude: ["Incremented", "Decremented", "Reset"]
|
|
1327
1476
|
});
|
|
1328
|
-
(0,
|
|
1329
|
-
const
|
|
1477
|
+
(0, import_vitest4.expect)(wipe.has(sAllOut)).toBe(false);
|
|
1478
|
+
const no_tomb = await store.query_stats([s], {
|
|
1330
1479
|
exclude: [import_act.TOMBSTONE_EVENT]
|
|
1331
1480
|
});
|
|
1332
|
-
(0,
|
|
1481
|
+
(0, import_vitest4.expect)(no_tomb.get(s)?.head.name).toBe("Incremented");
|
|
1333
1482
|
});
|
|
1334
|
-
(0,
|
|
1483
|
+
(0, import_vitest4.it)("before \u2014 time travel narrows head/tail/count", async () => {
|
|
1335
1484
|
const tag = uid();
|
|
1336
1485
|
const s = `qst-tt-${tag}`;
|
|
1337
1486
|
const c1 = await store.commit(
|
|
1338
1487
|
s,
|
|
1339
1488
|
[inc(1)],
|
|
1340
|
-
|
|
1489
|
+
make_meta({ stream: s })
|
|
1341
1490
|
);
|
|
1342
1491
|
const c2 = await store.commit(
|
|
1343
1492
|
s,
|
|
1344
1493
|
[inc(2)],
|
|
1345
|
-
|
|
1494
|
+
make_meta({ stream: s })
|
|
1495
|
+
);
|
|
1496
|
+
await store.commit(
|
|
1497
|
+
s,
|
|
1498
|
+
[inc(3)],
|
|
1499
|
+
make_meta({ stream: s })
|
|
1346
1500
|
);
|
|
1347
|
-
await store.commit(s, [inc(3)], makeMeta({ stream: s }));
|
|
1348
1501
|
const before = c2[0].id;
|
|
1349
1502
|
const stats = await store.query_stats([s], {
|
|
1350
1503
|
tail: true,
|
|
@@ -1352,15 +1505,15 @@ var runStoreTck = (options) => {
|
|
|
1352
1505
|
before
|
|
1353
1506
|
});
|
|
1354
1507
|
const r = stats.get(s);
|
|
1355
|
-
(0,
|
|
1356
|
-
(0,
|
|
1357
|
-
(0,
|
|
1508
|
+
(0, import_vitest4.expect)(r?.count).toBe(1);
|
|
1509
|
+
(0, import_vitest4.expect)(r?.head.id).toBe(c1[0].id);
|
|
1510
|
+
(0, import_vitest4.expect)(r?.tail?.id).toBe(c1[0].id);
|
|
1358
1511
|
const empty = await store.query_stats([s], {
|
|
1359
1512
|
before: 0
|
|
1360
1513
|
});
|
|
1361
|
-
(0,
|
|
1514
|
+
(0, import_vitest4.expect)(empty.has(s)).toBe(false);
|
|
1362
1515
|
});
|
|
1363
|
-
(0,
|
|
1516
|
+
(0, import_vitest4.it)("filter form \u2014 stream regex, stream_exact, empty {} match", async () => {
|
|
1364
1517
|
const tag = uid();
|
|
1365
1518
|
const sA = `qsf-${tag}-orders-1`;
|
|
1366
1519
|
const sB = `qsf-${tag}-orders-2`;
|
|
@@ -1368,94 +1521,110 @@ var runStoreTck = (options) => {
|
|
|
1368
1521
|
await store.commit(
|
|
1369
1522
|
sA,
|
|
1370
1523
|
[inc(1)],
|
|
1371
|
-
|
|
1524
|
+
make_meta({ stream: sA })
|
|
1372
1525
|
);
|
|
1373
1526
|
await store.commit(
|
|
1374
1527
|
sB,
|
|
1375
1528
|
[inc(2)],
|
|
1376
|
-
|
|
1529
|
+
make_meta({ stream: sB })
|
|
1377
1530
|
);
|
|
1378
1531
|
await store.commit(
|
|
1379
1532
|
sOther,
|
|
1380
1533
|
[inc(3)],
|
|
1381
|
-
|
|
1534
|
+
make_meta({ stream: sOther })
|
|
1382
1535
|
);
|
|
1383
1536
|
const orders = await store.query_stats({
|
|
1384
1537
|
stream: `^qsf-${tag}-orders-`
|
|
1385
1538
|
});
|
|
1386
|
-
(0,
|
|
1539
|
+
(0, import_vitest4.expect)([...orders.keys()].sort()).toEqual([sA, sB].sort());
|
|
1387
1540
|
const exact = await store.query_stats({
|
|
1388
1541
|
stream: sA,
|
|
1389
1542
|
stream_exact: true
|
|
1390
1543
|
});
|
|
1391
|
-
(0,
|
|
1544
|
+
(0, import_vitest4.expect)([...exact.keys()]).toEqual([sA]);
|
|
1392
1545
|
const all = await store.query_stats({
|
|
1393
1546
|
stream: `^qsf-${tag}-`
|
|
1394
1547
|
});
|
|
1395
|
-
(0,
|
|
1548
|
+
(0, import_vitest4.expect)([...all.keys()].sort()).toEqual([sA, sB, sOther].sort());
|
|
1396
1549
|
});
|
|
1397
|
-
(0,
|
|
1550
|
+
(0, import_vitest4.it)("compose with query_streams for subscription-level filters", async () => {
|
|
1398
1551
|
const tag = uid();
|
|
1399
1552
|
const a = `qsc-${tag}-a`;
|
|
1400
1553
|
const b = `qsc-${tag}-b`;
|
|
1401
1554
|
await store.subscribe([{ stream: a }, { stream: b }]);
|
|
1402
|
-
await store.commit(
|
|
1403
|
-
|
|
1555
|
+
await store.commit(
|
|
1556
|
+
a,
|
|
1557
|
+
[inc(1)],
|
|
1558
|
+
make_meta({ stream: a })
|
|
1559
|
+
);
|
|
1560
|
+
await store.commit(
|
|
1561
|
+
b,
|
|
1562
|
+
[inc(2)],
|
|
1563
|
+
make_meta({ stream: b })
|
|
1564
|
+
);
|
|
1404
1565
|
const leased = await store.claim(100, 0, `w-${uid()}`, 1e5);
|
|
1405
1566
|
const mine = leased.find((l) => l.stream === a);
|
|
1406
|
-
(0,
|
|
1567
|
+
(0, import_vitest4.expect)(mine).toBeDefined();
|
|
1407
1568
|
const others = leased.filter((l) => l.stream !== a);
|
|
1408
1569
|
await store.ack(others);
|
|
1409
1570
|
await store.block([{ ...mine, error: "boom" }]);
|
|
1410
|
-
const
|
|
1411
|
-
await store.query_streams((p) =>
|
|
1571
|
+
const blocked_names = [];
|
|
1572
|
+
await store.query_streams((p) => blocked_names.push(p.stream), {
|
|
1412
1573
|
stream: `^qsc-${tag}-`,
|
|
1413
1574
|
blocked: true
|
|
1414
1575
|
});
|
|
1415
|
-
(0,
|
|
1416
|
-
const stats = await store.query_stats(
|
|
1417
|
-
(0,
|
|
1418
|
-
(0,
|
|
1576
|
+
(0, import_vitest4.expect)(blocked_names).toEqual([a]);
|
|
1577
|
+
const stats = await store.query_stats(blocked_names);
|
|
1578
|
+
(0, import_vitest4.expect)(stats.get(a)?.head.name).toBe("Incremented");
|
|
1579
|
+
(0, import_vitest4.expect)(stats.has(b)).toBe(false);
|
|
1419
1580
|
});
|
|
1420
|
-
(0,
|
|
1581
|
+
(0, import_vitest4.it)("empty filter {} \u2014 matches every event-bearing stream", async () => {
|
|
1421
1582
|
const tag = uid();
|
|
1422
1583
|
const a = `qse-${tag}-a`;
|
|
1423
1584
|
const b = `qse-${tag}-b`;
|
|
1424
|
-
await store.commit(
|
|
1425
|
-
|
|
1585
|
+
await store.commit(
|
|
1586
|
+
a,
|
|
1587
|
+
[inc(1)],
|
|
1588
|
+
make_meta({ stream: a })
|
|
1589
|
+
);
|
|
1590
|
+
await store.commit(
|
|
1591
|
+
b,
|
|
1592
|
+
[dec(2)],
|
|
1593
|
+
make_meta({ stream: b })
|
|
1594
|
+
);
|
|
1426
1595
|
const all = await store.query_stats({});
|
|
1427
|
-
(0,
|
|
1428
|
-
(0,
|
|
1596
|
+
(0, import_vitest4.expect)(all.has(a)).toBe(true);
|
|
1597
|
+
(0, import_vitest4.expect)(all.has(b)).toBe(true);
|
|
1429
1598
|
});
|
|
1430
|
-
(0,
|
|
1599
|
+
(0, import_vitest4.it)("stat-flag combinations \u2014 count-only, names-only, tail-only", async () => {
|
|
1431
1600
|
const tag = uid();
|
|
1432
1601
|
const s = `qsfl-${tag}`;
|
|
1433
1602
|
await store.commit(
|
|
1434
1603
|
s,
|
|
1435
1604
|
[inc(1), inc(2), dec(3)],
|
|
1436
|
-
|
|
1605
|
+
make_meta({ stream: s })
|
|
1437
1606
|
);
|
|
1438
1607
|
const c = await store.query_stats([s], {
|
|
1439
1608
|
count: true
|
|
1440
1609
|
});
|
|
1441
|
-
(0,
|
|
1442
|
-
(0,
|
|
1443
|
-
(0,
|
|
1610
|
+
(0, import_vitest4.expect)(c.get(s)?.count).toBe(3);
|
|
1611
|
+
(0, import_vitest4.expect)(c.get(s)?.names).toBeUndefined();
|
|
1612
|
+
(0, import_vitest4.expect)(c.get(s)?.tail).toBeUndefined();
|
|
1444
1613
|
const n = await store.query_stats([s], {
|
|
1445
1614
|
names: true
|
|
1446
1615
|
});
|
|
1447
|
-
(0,
|
|
1448
|
-
(0,
|
|
1449
|
-
(0,
|
|
1616
|
+
(0, import_vitest4.expect)(n.get(s)?.names).toEqual({ Incremented: 2, Decremented: 1 });
|
|
1617
|
+
(0, import_vitest4.expect)(n.get(s)?.count).toBeUndefined();
|
|
1618
|
+
(0, import_vitest4.expect)(n.get(s)?.tail).toBeUndefined();
|
|
1450
1619
|
const t = await store.query_stats([s], { tail: true });
|
|
1451
|
-
(0,
|
|
1452
|
-
(0,
|
|
1453
|
-
(0,
|
|
1454
|
-
(0,
|
|
1620
|
+
(0, import_vitest4.expect)(t.get(s)?.tail?.name).toBe("Incremented");
|
|
1621
|
+
(0, import_vitest4.expect)((t.get(s)?.tail?.data).amount).toBe(1);
|
|
1622
|
+
(0, import_vitest4.expect)(t.get(s)?.count).toBeUndefined();
|
|
1623
|
+
(0, import_vitest4.expect)(t.get(s)?.names).toBeUndefined();
|
|
1455
1624
|
});
|
|
1456
1625
|
});
|
|
1457
|
-
(0,
|
|
1458
|
-
(0,
|
|
1626
|
+
(0, import_vitest4.describe)("query_streams anchor contract", () => {
|
|
1627
|
+
(0, import_vitest4.it)("plain regex without anchors is a substring match", async () => {
|
|
1459
1628
|
const tag = uid();
|
|
1460
1629
|
const inner = `qsr-${tag}-inner`;
|
|
1461
1630
|
const longer = `qsr-${tag}-inner-extra`;
|
|
@@ -1469,9 +1638,9 @@ var runStoreTck = (options) => {
|
|
|
1469
1638
|
await store.query_streams((p) => seen.push(p.stream), {
|
|
1470
1639
|
stream: `qsr-${tag}-inner`
|
|
1471
1640
|
});
|
|
1472
|
-
(0,
|
|
1641
|
+
(0, import_vitest4.expect)(seen.sort()).toEqual([inner, longer].sort());
|
|
1473
1642
|
});
|
|
1474
|
-
(0,
|
|
1643
|
+
(0, import_vitest4.it)("caller-anchored `^name$` matches only the whole string", async () => {
|
|
1475
1644
|
const tag = uid();
|
|
1476
1645
|
const inner = `qsr-${tag}-anchor`;
|
|
1477
1646
|
const longer = `qsr-${tag}-anchor-extra`;
|
|
@@ -1480,9 +1649,9 @@ var runStoreTck = (options) => {
|
|
|
1480
1649
|
await store.query_streams((p) => seen.push(p.stream), {
|
|
1481
1650
|
stream: `^qsr-${tag}-anchor$`
|
|
1482
1651
|
});
|
|
1483
|
-
(0,
|
|
1652
|
+
(0, import_vitest4.expect)(seen).toEqual([inner]);
|
|
1484
1653
|
});
|
|
1485
|
-
(0,
|
|
1654
|
+
(0, import_vitest4.it)("caller-anchored `^prefix` matches by prefix", async () => {
|
|
1486
1655
|
const tag = uid();
|
|
1487
1656
|
const a = `qsr-${tag}-pfx-a`;
|
|
1488
1657
|
const b = `qsr-${tag}-pfx-b`;
|
|
@@ -1496,11 +1665,11 @@ var runStoreTck = (options) => {
|
|
|
1496
1665
|
await store.query_streams((p) => seen.push(p.stream), {
|
|
1497
1666
|
stream: `^qsr-${tag}-pfx-`
|
|
1498
1667
|
});
|
|
1499
|
-
(0,
|
|
1668
|
+
(0, import_vitest4.expect)(seen.sort()).toEqual([a, b].sort());
|
|
1500
1669
|
});
|
|
1501
1670
|
});
|
|
1502
|
-
(0,
|
|
1503
|
-
(0,
|
|
1671
|
+
(0, import_vitest4.describe)("prioritize anchor contract", () => {
|
|
1672
|
+
(0, import_vitest4.it)("caller-anchored `^name$` filter matches only the whole string", async () => {
|
|
1504
1673
|
const tag = uid();
|
|
1505
1674
|
const inner = `pr-${tag}-anchor`;
|
|
1506
1675
|
const longer = `pr-${tag}-anchor-extra`;
|
|
@@ -1512,45 +1681,49 @@ var runStoreTck = (options) => {
|
|
|
1512
1681
|
{ stream: `^pr-${tag}-anchor$` },
|
|
1513
1682
|
7
|
|
1514
1683
|
);
|
|
1515
|
-
(0,
|
|
1684
|
+
(0, import_vitest4.expect)(updated).toBe(1);
|
|
1516
1685
|
const seen = /* @__PURE__ */ new Map();
|
|
1517
1686
|
await store.query_streams((p) => seen.set(p.stream, p.priority), {
|
|
1518
1687
|
stream: `pr-${tag}-anchor`
|
|
1519
1688
|
});
|
|
1520
|
-
(0,
|
|
1521
|
-
(0,
|
|
1689
|
+
(0, import_vitest4.expect)(seen.get(inner)).toBe(7);
|
|
1690
|
+
(0, import_vitest4.expect)(seen.get(longer)).toBe(0);
|
|
1522
1691
|
});
|
|
1523
1692
|
});
|
|
1524
|
-
(0,
|
|
1525
|
-
(0,
|
|
1693
|
+
(0, import_vitest4.describe)("query_streams head", () => {
|
|
1694
|
+
(0, import_vitest4.it)("maxEventId tracks the highest committed id", async () => {
|
|
1526
1695
|
const s = `head-${uid()}`;
|
|
1527
1696
|
await store.subscribe([{ stream: s }]);
|
|
1528
|
-
await store.commit(
|
|
1697
|
+
await store.commit(
|
|
1698
|
+
s,
|
|
1699
|
+
[inc(1)],
|
|
1700
|
+
make_meta({ stream: s })
|
|
1701
|
+
);
|
|
1529
1702
|
const positions = [];
|
|
1530
1703
|
const { maxEventId } = await store.query_streams(
|
|
1531
1704
|
(p) => positions.push(p.stream),
|
|
1532
1705
|
{ stream: s, stream_exact: true, limit: 1 }
|
|
1533
1706
|
);
|
|
1534
|
-
(0,
|
|
1535
|
-
(0,
|
|
1707
|
+
(0, import_vitest4.expect)(maxEventId).toBeGreaterThanOrEqual(0);
|
|
1708
|
+
(0, import_vitest4.expect)(positions).toEqual([s]);
|
|
1536
1709
|
});
|
|
1537
1710
|
});
|
|
1538
|
-
(0,
|
|
1539
|
-
(0,
|
|
1711
|
+
(0, import_vitest4.describe)("seed_stream helper coverage", () => {
|
|
1712
|
+
(0, import_vitest4.it)("commits N events with monotonically increasing ids", async () => {
|
|
1540
1713
|
const s = `seed-${uid()}`;
|
|
1541
|
-
const committed = await
|
|
1542
|
-
(0,
|
|
1714
|
+
const committed = await seed_stream(store, s, 3);
|
|
1715
|
+
(0, import_vitest4.expect)(committed).toHaveLength(3);
|
|
1543
1716
|
for (let i = 1; i < committed.length; i++) {
|
|
1544
|
-
(0,
|
|
1717
|
+
(0, import_vitest4.expect)(committed[i].id).toBeGreaterThan(committed[i - 1].id);
|
|
1545
1718
|
}
|
|
1546
1719
|
});
|
|
1547
1720
|
});
|
|
1548
|
-
|
|
1721
|
+
import_vitest4.describe.skipIf(!caps.restore)("restore (capability)", () => {
|
|
1549
1722
|
beforeEach(async () => {
|
|
1550
1723
|
await store.drop();
|
|
1551
1724
|
await store.seed();
|
|
1552
1725
|
});
|
|
1553
|
-
const
|
|
1726
|
+
const as_source = (events) => ({
|
|
1554
1727
|
async query(callback) {
|
|
1555
1728
|
for (const e of events)
|
|
1556
1729
|
await Promise.resolve(
|
|
@@ -1563,8 +1736,8 @@ var runStoreTck = (options) => {
|
|
|
1563
1736
|
async dispose() {
|
|
1564
1737
|
}
|
|
1565
1738
|
});
|
|
1566
|
-
const event = (
|
|
1567
|
-
id:
|
|
1739
|
+
const event = (original_id, stream, version, name, created, data = {}) => ({
|
|
1740
|
+
id: original_id,
|
|
1568
1741
|
name,
|
|
1569
1742
|
data,
|
|
1570
1743
|
stream,
|
|
@@ -1582,18 +1755,18 @@ var runStoreTck = (options) => {
|
|
|
1582
1755
|
await cache.dispose();
|
|
1583
1756
|
}
|
|
1584
1757
|
};
|
|
1585
|
-
(0,
|
|
1586
|
-
const result = await restore(
|
|
1587
|
-
(0,
|
|
1588
|
-
(0,
|
|
1589
|
-
(0,
|
|
1758
|
+
(0, import_vitest4.it)("returns kept=0 on an empty source", async () => {
|
|
1759
|
+
const result = await restore(as_source([]));
|
|
1760
|
+
(0, import_vitest4.expect)(result.kept).toBe(0);
|
|
1761
|
+
(0, import_vitest4.expect)(result.duration_ms).toBeGreaterThanOrEqual(0);
|
|
1762
|
+
(0, import_vitest4.expect)(result.dropped).toEqual({
|
|
1590
1763
|
closed_streams: 0,
|
|
1591
1764
|
snapshots: 0
|
|
1592
1765
|
});
|
|
1593
1766
|
const events = await collect(store, { limit: 10 });
|
|
1594
|
-
(0,
|
|
1767
|
+
(0, import_vitest4.expect)(events).toHaveLength(0);
|
|
1595
1768
|
});
|
|
1596
|
-
(0,
|
|
1769
|
+
(0, import_vitest4.it)("rebuilds a single stream and preserves `created` verbatim", async () => {
|
|
1597
1770
|
const s = `restore-single-${uid()}`;
|
|
1598
1771
|
const t0 = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
|
|
1599
1772
|
const t1 = /* @__PURE__ */ new Date("2020-01-02T00:00:00.000Z");
|
|
@@ -1603,8 +1776,8 @@ var runStoreTck = (options) => {
|
|
|
1603
1776
|
event(2, s, 1, "Incremented", t1, { amount: 2 }),
|
|
1604
1777
|
event(3, s, 2, "Decremented", t2, { amount: 1 })
|
|
1605
1778
|
];
|
|
1606
|
-
const result = await restore(
|
|
1607
|
-
(0,
|
|
1779
|
+
const result = await restore(as_source(events));
|
|
1780
|
+
(0, import_vitest4.expect)(result.kept).toBe(3);
|
|
1608
1781
|
const back = [];
|
|
1609
1782
|
await store.query(
|
|
1610
1783
|
(e) => {
|
|
@@ -1612,8 +1785,8 @@ var runStoreTck = (options) => {
|
|
|
1612
1785
|
},
|
|
1613
1786
|
{ stream: s, stream_exact: true }
|
|
1614
1787
|
);
|
|
1615
|
-
(0,
|
|
1616
|
-
(0,
|
|
1788
|
+
(0, import_vitest4.expect)(back).toHaveLength(3);
|
|
1789
|
+
(0, import_vitest4.expect)(
|
|
1617
1790
|
back.map((e) => ({
|
|
1618
1791
|
stream: e.stream,
|
|
1619
1792
|
version: e.version,
|
|
@@ -1645,7 +1818,7 @@ var runStoreTck = (options) => {
|
|
|
1645
1818
|
}
|
|
1646
1819
|
]);
|
|
1647
1820
|
});
|
|
1648
|
-
(0,
|
|
1821
|
+
(0, import_vitest4.it)("rebuilds multiple streams interleaved", async () => {
|
|
1649
1822
|
const a = `restore-multi-a-${uid()}`;
|
|
1650
1823
|
const b = `restore-multi-b-${uid()}`;
|
|
1651
1824
|
const t = /* @__PURE__ */ new Date("2020-06-01T00:00:00.000Z");
|
|
@@ -1655,8 +1828,8 @@ var runStoreTck = (options) => {
|
|
|
1655
1828
|
event(3, a, 1, "Decremented", t, { amount: 5 }),
|
|
1656
1829
|
event(4, b, 1, "Incremented", t, { amount: 30 })
|
|
1657
1830
|
];
|
|
1658
|
-
const result = await restore(
|
|
1659
|
-
(0,
|
|
1831
|
+
const result = await restore(as_source(events));
|
|
1832
|
+
(0, import_vitest4.expect)(result.kept).toBe(4);
|
|
1660
1833
|
const aBack = [];
|
|
1661
1834
|
const bBack = [];
|
|
1662
1835
|
await store.query(
|
|
@@ -1671,14 +1844,14 @@ var runStoreTck = (options) => {
|
|
|
1671
1844
|
},
|
|
1672
1845
|
{ stream: b, stream_exact: true }
|
|
1673
1846
|
);
|
|
1674
|
-
(0,
|
|
1675
|
-
(0,
|
|
1847
|
+
(0, import_vitest4.expect)(aBack.map((e) => e.version)).toEqual([0, 1]);
|
|
1848
|
+
(0, import_vitest4.expect)(bBack.map((e) => e.version)).toEqual([0, 1]);
|
|
1676
1849
|
});
|
|
1677
|
-
(0,
|
|
1850
|
+
(0, import_vitest4.it)("preserves Date `created` verbatim", async () => {
|
|
1678
1851
|
const s = `restore-isoc-${uid()}`;
|
|
1679
1852
|
const iso = "2021-07-15T12:34:56.789Z";
|
|
1680
1853
|
await restore(
|
|
1681
|
-
|
|
1854
|
+
as_source([
|
|
1682
1855
|
{
|
|
1683
1856
|
id: 1,
|
|
1684
1857
|
stream: s,
|
|
@@ -1697,53 +1870,53 @@ var runStoreTck = (options) => {
|
|
|
1697
1870
|
},
|
|
1698
1871
|
{ stream: s, stream_exact: true }
|
|
1699
1872
|
);
|
|
1700
|
-
(0,
|
|
1701
|
-
(0,
|
|
1873
|
+
(0, import_vitest4.expect)(back).toHaveLength(1);
|
|
1874
|
+
(0, import_vitest4.expect)(back[0].created.toISOString()).toBe(iso);
|
|
1702
1875
|
});
|
|
1703
|
-
(0,
|
|
1876
|
+
(0, import_vitest4.it)("wipes pre-existing events before inserting", async () => {
|
|
1704
1877
|
const old = `restore-old-${uid()}`;
|
|
1705
1878
|
await store.commit(
|
|
1706
1879
|
old,
|
|
1707
1880
|
[inc(1), inc(2)],
|
|
1708
|
-
|
|
1881
|
+
make_meta({ stream: old })
|
|
1709
1882
|
);
|
|
1710
1883
|
const fresh = `restore-fresh-${uid()}`;
|
|
1711
1884
|
const t = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
|
|
1712
1885
|
await restore(
|
|
1713
|
-
|
|
1886
|
+
as_source([event(1, fresh, 0, "Incremented", t, { amount: 99 })])
|
|
1714
1887
|
);
|
|
1715
|
-
const
|
|
1888
|
+
const old_back = await collect(store, {
|
|
1716
1889
|
stream: old,
|
|
1717
1890
|
stream_exact: true
|
|
1718
1891
|
});
|
|
1719
|
-
(0,
|
|
1720
|
-
const
|
|
1892
|
+
(0, import_vitest4.expect)(old_back).toHaveLength(0);
|
|
1893
|
+
const fresh_back = await collect(store, {
|
|
1721
1894
|
stream: fresh,
|
|
1722
1895
|
stream_exact: true
|
|
1723
1896
|
});
|
|
1724
|
-
(0,
|
|
1897
|
+
(0, import_vitest4.expect)(fresh_back).toHaveLength(1);
|
|
1725
1898
|
});
|
|
1726
|
-
(0,
|
|
1899
|
+
(0, import_vitest4.it)("clears subscription/stream-position metadata", async () => {
|
|
1727
1900
|
const sub = `restore-sub-${uid()}`;
|
|
1728
1901
|
await store.subscribe([{ stream: sub, source: "anything" }]);
|
|
1729
|
-
const
|
|
1902
|
+
const collect_streams = async () => {
|
|
1730
1903
|
const out = [];
|
|
1731
1904
|
await store.query_streams((p) => {
|
|
1732
1905
|
out.push(p.stream);
|
|
1733
1906
|
});
|
|
1734
1907
|
return out;
|
|
1735
1908
|
};
|
|
1736
|
-
const before = await
|
|
1737
|
-
(0,
|
|
1738
|
-
await restore(
|
|
1739
|
-
const after = await
|
|
1740
|
-
(0,
|
|
1909
|
+
const before = await collect_streams();
|
|
1910
|
+
(0, import_vitest4.expect)(before.includes(sub)).toBe(true);
|
|
1911
|
+
await restore(as_source([]));
|
|
1912
|
+
const after = await collect_streams();
|
|
1913
|
+
(0, import_vitest4.expect)(after.includes(sub)).toBe(false);
|
|
1741
1914
|
});
|
|
1742
|
-
(0,
|
|
1915
|
+
(0, import_vitest4.it)("preserves snapshot events through restore", async () => {
|
|
1743
1916
|
const s = `restore-snap-${uid()}`;
|
|
1744
1917
|
const t = /* @__PURE__ */ new Date("2020-04-01T00:00:00.000Z");
|
|
1745
1918
|
await restore(
|
|
1746
|
-
|
|
1919
|
+
as_source([
|
|
1747
1920
|
{
|
|
1748
1921
|
id: 1,
|
|
1749
1922
|
stream: s,
|
|
@@ -1760,10 +1933,10 @@ var runStoreTck = (options) => {
|
|
|
1760
1933
|
stream_exact: true,
|
|
1761
1934
|
with_snaps: true
|
|
1762
1935
|
});
|
|
1763
|
-
(0,
|
|
1764
|
-
(0,
|
|
1936
|
+
(0, import_vitest4.expect)(back).toHaveLength(1);
|
|
1937
|
+
(0, import_vitest4.expect)(back[0].name).toBe(import_act.SNAP_EVENT);
|
|
1765
1938
|
});
|
|
1766
|
-
(0,
|
|
1939
|
+
(0, import_vitest4.it)("rewrites causation refs through the old\u2192new id map", async () => {
|
|
1767
1940
|
const s = `restore-caus-${uid()}`;
|
|
1768
1941
|
const t = /* @__PURE__ */ new Date("2020-08-01T00:00:00.000Z");
|
|
1769
1942
|
const events = [
|
|
@@ -1805,7 +1978,7 @@ var runStoreTck = (options) => {
|
|
|
1805
1978
|
}
|
|
1806
1979
|
}
|
|
1807
1980
|
];
|
|
1808
|
-
await restore(
|
|
1981
|
+
await restore(as_source(events));
|
|
1809
1982
|
const back = [];
|
|
1810
1983
|
await store.query(
|
|
1811
1984
|
(e) => {
|
|
@@ -1813,16 +1986,16 @@ var runStoreTck = (options) => {
|
|
|
1813
1986
|
},
|
|
1814
1987
|
{ stream: s, stream_exact: true }
|
|
1815
1988
|
);
|
|
1816
|
-
(0,
|
|
1817
|
-
(0,
|
|
1818
|
-
(0,
|
|
1819
|
-
(0,
|
|
1989
|
+
(0, import_vitest4.expect)(back).toHaveLength(3);
|
|
1990
|
+
(0, import_vitest4.expect)(back[0].meta.causation.event).toBeUndefined();
|
|
1991
|
+
(0, import_vitest4.expect)(back[1].meta.causation.event?.id).toBe(back[0].id);
|
|
1992
|
+
(0, import_vitest4.expect)(back[2].meta.causation.event?.id).toBe(back[1].id);
|
|
1820
1993
|
});
|
|
1821
|
-
(0,
|
|
1994
|
+
(0, import_vitest4.it)("leaves causation refs unmapped when the target isn't in the source", async () => {
|
|
1822
1995
|
const s = `restore-orphan-${uid()}`;
|
|
1823
1996
|
const t = /* @__PURE__ */ new Date("2020-09-01T00:00:00.000Z");
|
|
1824
1997
|
await restore(
|
|
1825
|
-
|
|
1998
|
+
as_source([
|
|
1826
1999
|
{
|
|
1827
2000
|
id: 1,
|
|
1828
2001
|
stream: s,
|
|
@@ -1846,14 +2019,14 @@ var runStoreTck = (options) => {
|
|
|
1846
2019
|
},
|
|
1847
2020
|
{ stream: s, stream_exact: true }
|
|
1848
2021
|
);
|
|
1849
|
-
(0,
|
|
2022
|
+
(0, import_vitest4.expect)(back[0].meta.causation.event?.id).toBe(999);
|
|
1850
2023
|
});
|
|
1851
|
-
(0,
|
|
2024
|
+
(0, import_vitest4.it)("rolls back atomically when the source throws mid-iteration", async () => {
|
|
1852
2025
|
const original = `restore-pre-${uid()}`;
|
|
1853
2026
|
const committed = await store.commit(
|
|
1854
2027
|
original,
|
|
1855
2028
|
[inc(1), inc(2), inc(3)],
|
|
1856
|
-
|
|
2029
|
+
make_meta({ stream: original })
|
|
1857
2030
|
);
|
|
1858
2031
|
const explosive = {
|
|
1859
2032
|
async query(callback) {
|
|
@@ -1874,7 +2047,7 @@ var runStoreTck = (options) => {
|
|
|
1874
2047
|
async dispose() {
|
|
1875
2048
|
}
|
|
1876
2049
|
};
|
|
1877
|
-
await (0,
|
|
2050
|
+
await (0, import_vitest4.expect)(restore(explosive)).rejects.toThrow("boom");
|
|
1878
2051
|
const back = [];
|
|
1879
2052
|
await store.query(
|
|
1880
2053
|
(e) => {
|
|
@@ -1882,14 +2055,14 @@ var runStoreTck = (options) => {
|
|
|
1882
2055
|
},
|
|
1883
2056
|
{ stream: original, stream_exact: true }
|
|
1884
2057
|
);
|
|
1885
|
-
(0,
|
|
1886
|
-
(0,
|
|
2058
|
+
(0, import_vitest4.expect)(back).toHaveLength(3);
|
|
2059
|
+
(0, import_vitest4.expect)(back.map((e) => e.id)).toEqual(committed.map((c) => c.id));
|
|
1887
2060
|
});
|
|
1888
|
-
(0,
|
|
2061
|
+
(0, import_vitest4.it)("drop_snapshots: skips SNAP_EVENT rows and counts them", async () => {
|
|
1889
2062
|
const s = `restore-drop-snap-${uid()}`;
|
|
1890
2063
|
const t = /* @__PURE__ */ new Date("2020-10-01T00:00:00.000Z");
|
|
1891
2064
|
const result = await restore(
|
|
1892
|
-
|
|
2065
|
+
as_source([
|
|
1893
2066
|
event(1, s, 0, "Incremented", t, { amount: 1 }),
|
|
1894
2067
|
{
|
|
1895
2068
|
id: 2,
|
|
@@ -1904,34 +2077,34 @@ var runStoreTck = (options) => {
|
|
|
1904
2077
|
]),
|
|
1905
2078
|
{ drop_snapshots: true }
|
|
1906
2079
|
);
|
|
1907
|
-
(0,
|
|
1908
|
-
(0,
|
|
2080
|
+
(0, import_vitest4.expect)(result.kept).toBe(2);
|
|
2081
|
+
(0, import_vitest4.expect)(result.dropped.snapshots).toBe(1);
|
|
1909
2082
|
const back = await collect(store, {
|
|
1910
2083
|
stream: s,
|
|
1911
2084
|
stream_exact: true,
|
|
1912
2085
|
with_snaps: true
|
|
1913
2086
|
});
|
|
1914
|
-
(0,
|
|
1915
|
-
(0,
|
|
2087
|
+
(0, import_vitest4.expect)(back).toHaveLength(2);
|
|
2088
|
+
(0, import_vitest4.expect)(
|
|
1916
2089
|
back.every((e) => e.name !== import_act.SNAP_EVENT)
|
|
1917
2090
|
).toBe(true);
|
|
1918
2091
|
});
|
|
1919
|
-
(0,
|
|
2092
|
+
(0, import_vitest4.it)("on_progress fires once per event (caller throttles)", async () => {
|
|
1920
2093
|
const calls = [];
|
|
1921
2094
|
const s = `restore-progress-${uid()}`;
|
|
1922
2095
|
const t = /* @__PURE__ */ new Date("2021-02-01T00:00:00.000Z");
|
|
1923
2096
|
await restore(
|
|
1924
|
-
|
|
2097
|
+
as_source([
|
|
1925
2098
|
event(1, s, 0, "Incremented", t, { amount: 1 }),
|
|
1926
2099
|
event(2, s, 1, "Incremented", t, { amount: 2 })
|
|
1927
2100
|
]),
|
|
1928
2101
|
{ on_progress: (p) => calls.push(p.processed) }
|
|
1929
2102
|
);
|
|
1930
|
-
(0,
|
|
2103
|
+
(0, import_vitest4.expect)(calls).toEqual([1, 2]);
|
|
1931
2104
|
});
|
|
1932
2105
|
});
|
|
1933
|
-
|
|
1934
|
-
(0,
|
|
2106
|
+
import_vitest4.describe.skipIf(!caps.pii_isolation)("pii_isolation (capability)", () => {
|
|
2107
|
+
(0, import_vitest4.it)("commits and loads pii alongside data", async () => {
|
|
1935
2108
|
const s = `pii-roundtrip-${uid()}`;
|
|
1936
2109
|
const committed = await store.commit(
|
|
1937
2110
|
s,
|
|
@@ -1942,10 +2115,10 @@ var runStoreTck = (options) => {
|
|
|
1942
2115
|
pii: { email: "u@example.com", name: "Ursula" }
|
|
1943
2116
|
}
|
|
1944
2117
|
],
|
|
1945
|
-
|
|
2118
|
+
make_meta({ stream: s })
|
|
1946
2119
|
);
|
|
1947
|
-
(0,
|
|
1948
|
-
(0,
|
|
2120
|
+
(0, import_vitest4.expect)(committed).toHaveLength(1);
|
|
2121
|
+
(0, import_vitest4.expect)(committed[0].pii).toEqual({
|
|
1949
2122
|
email: "u@example.com",
|
|
1950
2123
|
name: "Ursula"
|
|
1951
2124
|
});
|
|
@@ -1956,13 +2129,17 @@ var runStoreTck = (options) => {
|
|
|
1956
2129
|
},
|
|
1957
2130
|
{ stream: s, stream_exact: true }
|
|
1958
2131
|
);
|
|
1959
|
-
(0,
|
|
1960
|
-
(0,
|
|
1961
|
-
(0,
|
|
2132
|
+
(0, import_vitest4.expect)(seen).toHaveLength(1);
|
|
2133
|
+
(0, import_vitest4.expect)(seen[0].pii).toEqual({ email: "u@example.com", name: "Ursula" });
|
|
2134
|
+
(0, import_vitest4.expect)(seen[0].data).toEqual({ amount: 1 });
|
|
1962
2135
|
});
|
|
1963
|
-
(0,
|
|
2136
|
+
(0, import_vitest4.it)("passes through events without pii (pii is null or undefined on load)", async () => {
|
|
1964
2137
|
const s = `pii-none-${uid()}`;
|
|
1965
|
-
await store.commit(
|
|
2138
|
+
await store.commit(
|
|
2139
|
+
s,
|
|
2140
|
+
[inc(1)],
|
|
2141
|
+
make_meta({ stream: s })
|
|
2142
|
+
);
|
|
1966
2143
|
const seen = [];
|
|
1967
2144
|
await store.query(
|
|
1968
2145
|
(e) => {
|
|
@@ -1970,10 +2147,10 @@ var runStoreTck = (options) => {
|
|
|
1970
2147
|
},
|
|
1971
2148
|
{ stream: s, stream_exact: true }
|
|
1972
2149
|
);
|
|
1973
|
-
(0,
|
|
1974
|
-
(0,
|
|
2150
|
+
(0, import_vitest4.expect)(seen).toHaveLength(1);
|
|
2151
|
+
(0, import_vitest4.expect)(seen[0].pii == null).toBe(true);
|
|
1975
2152
|
});
|
|
1976
|
-
(0,
|
|
2153
|
+
(0, import_vitest4.it)("wipes pii for every event on the stream via forget_pii", async () => {
|
|
1977
2154
|
const s = `pii-forget-${uid()}`;
|
|
1978
2155
|
await store.commit(
|
|
1979
2156
|
s,
|
|
@@ -1989,12 +2166,12 @@ var runStoreTck = (options) => {
|
|
|
1989
2166
|
pii: { email: "b@example.com" }
|
|
1990
2167
|
}
|
|
1991
2168
|
],
|
|
1992
|
-
|
|
2169
|
+
make_meta({ stream: s })
|
|
1993
2170
|
);
|
|
1994
2171
|
const forget = store.forget_pii;
|
|
1995
|
-
(0,
|
|
2172
|
+
(0, import_vitest4.expect)(forget).toBeDefined();
|
|
1996
2173
|
const wiped = await forget.call(store, s);
|
|
1997
|
-
(0,
|
|
2174
|
+
(0, import_vitest4.expect)(wiped).toBe(2);
|
|
1998
2175
|
const seen = [];
|
|
1999
2176
|
await store.query(
|
|
2000
2177
|
(e) => {
|
|
@@ -2002,13 +2179,13 @@ var runStoreTck = (options) => {
|
|
|
2002
2179
|
},
|
|
2003
2180
|
{ stream: s, stream_exact: true }
|
|
2004
2181
|
);
|
|
2005
|
-
(0,
|
|
2182
|
+
(0, import_vitest4.expect)(seen).toHaveLength(2);
|
|
2006
2183
|
for (const e of seen) {
|
|
2007
|
-
(0,
|
|
2008
|
-
(0,
|
|
2184
|
+
(0, import_vitest4.expect)(e.pii == null).toBe(true);
|
|
2185
|
+
(0, import_vitest4.expect)(e.data).toBeDefined();
|
|
2009
2186
|
}
|
|
2010
2187
|
});
|
|
2011
|
-
(0,
|
|
2188
|
+
(0, import_vitest4.it)("is idempotent \u2014 second forget_pii returns 0, no error", async () => {
|
|
2012
2189
|
const s = `pii-forget-idem-${uid()}`;
|
|
2013
2190
|
await store.commit(
|
|
2014
2191
|
s,
|
|
@@ -2019,15 +2196,15 @@ var runStoreTck = (options) => {
|
|
|
2019
2196
|
pii: { email: "u@example.com" }
|
|
2020
2197
|
}
|
|
2021
2198
|
],
|
|
2022
|
-
|
|
2199
|
+
make_meta({ stream: s })
|
|
2023
2200
|
);
|
|
2024
2201
|
const forget = store.forget_pii;
|
|
2025
2202
|
const first = await forget.call(store, s);
|
|
2026
|
-
(0,
|
|
2203
|
+
(0, import_vitest4.expect)(first).toBe(1);
|
|
2027
2204
|
const second = await forget.call(store, s);
|
|
2028
|
-
(0,
|
|
2205
|
+
(0, import_vitest4.expect)(second).toBe(0);
|
|
2029
2206
|
});
|
|
2030
|
-
(0,
|
|
2207
|
+
(0, import_vitest4.it)("only wipes the targeted stream \u2014 siblings untouched", async () => {
|
|
2031
2208
|
const sA = `pii-iso-a-${uid()}`;
|
|
2032
2209
|
const sB = `pii-iso-b-${uid()}`;
|
|
2033
2210
|
await store.commit(
|
|
@@ -2039,7 +2216,7 @@ var runStoreTck = (options) => {
|
|
|
2039
2216
|
pii: { email: "alice@example.com" }
|
|
2040
2217
|
}
|
|
2041
2218
|
],
|
|
2042
|
-
|
|
2219
|
+
make_meta({ stream: sA })
|
|
2043
2220
|
);
|
|
2044
2221
|
await store.commit(
|
|
2045
2222
|
sB,
|
|
@@ -2050,7 +2227,7 @@ var runStoreTck = (options) => {
|
|
|
2050
2227
|
pii: { email: "bob@example.com" }
|
|
2051
2228
|
}
|
|
2052
2229
|
],
|
|
2053
|
-
|
|
2230
|
+
make_meta({ stream: sB })
|
|
2054
2231
|
);
|
|
2055
2232
|
await store.forget_pii.call(store, sA);
|
|
2056
2233
|
const a = [];
|
|
@@ -2060,7 +2237,7 @@ var runStoreTck = (options) => {
|
|
|
2060
2237
|
},
|
|
2061
2238
|
{ stream: sA, stream_exact: true }
|
|
2062
2239
|
);
|
|
2063
|
-
(0,
|
|
2240
|
+
(0, import_vitest4.expect)(a[0].pii == null).toBe(true);
|
|
2064
2241
|
const b = [];
|
|
2065
2242
|
await store.query(
|
|
2066
2243
|
(e) => {
|
|
@@ -2068,28 +2245,32 @@ var runStoreTck = (options) => {
|
|
|
2068
2245
|
},
|
|
2069
2246
|
{ stream: sB, stream_exact: true }
|
|
2070
2247
|
);
|
|
2071
|
-
(0,
|
|
2248
|
+
(0, import_vitest4.expect)(b[0].pii).toEqual({ email: "bob@example.com" });
|
|
2072
2249
|
});
|
|
2073
|
-
(0,
|
|
2250
|
+
(0, import_vitest4.it)("forget_pii on a stream with no pii events returns 0", async () => {
|
|
2074
2251
|
const s = `pii-forget-empty-${uid()}`;
|
|
2075
|
-
await store.commit(
|
|
2252
|
+
await store.commit(
|
|
2253
|
+
s,
|
|
2254
|
+
[inc(1)],
|
|
2255
|
+
make_meta({ stream: s })
|
|
2256
|
+
);
|
|
2076
2257
|
const wiped = await store.forget_pii.call(store, s);
|
|
2077
|
-
(0,
|
|
2258
|
+
(0, import_vitest4.expect)(wiped).toBe(0);
|
|
2078
2259
|
});
|
|
2079
2260
|
});
|
|
2080
2261
|
if (caps.notify) {
|
|
2081
|
-
(0,
|
|
2082
|
-
(0,
|
|
2262
|
+
(0, import_vitest4.describe)("notify (capability)", () => {
|
|
2263
|
+
(0, import_vitest4.it)("delivers a notification when a different instance commits", async () => {
|
|
2083
2264
|
const notify = store.notify;
|
|
2084
|
-
(0,
|
|
2265
|
+
(0, import_vitest4.expect)(notify).toBeDefined();
|
|
2085
2266
|
const received = [];
|
|
2086
|
-
let
|
|
2267
|
+
let resolve_arrived;
|
|
2087
2268
|
const arrived = new Promise((res) => {
|
|
2088
|
-
|
|
2269
|
+
resolve_arrived = res;
|
|
2089
2270
|
});
|
|
2090
2271
|
const disposer = await notify.call(store, (n) => {
|
|
2091
2272
|
received.push(n);
|
|
2092
|
-
|
|
2273
|
+
resolve_arrived();
|
|
2093
2274
|
});
|
|
2094
2275
|
const writer = await options.factory();
|
|
2095
2276
|
try {
|
|
@@ -2097,12 +2278,12 @@ var runStoreTck = (options) => {
|
|
|
2097
2278
|
await writer.commit(
|
|
2098
2279
|
stream,
|
|
2099
2280
|
[inc(1)],
|
|
2100
|
-
|
|
2281
|
+
make_meta({ stream })
|
|
2101
2282
|
);
|
|
2102
2283
|
await arrived;
|
|
2103
|
-
(0,
|
|
2104
|
-
(0,
|
|
2105
|
-
(0,
|
|
2284
|
+
(0, import_vitest4.expect)(received.length).toBeGreaterThanOrEqual(1);
|
|
2285
|
+
(0, import_vitest4.expect)(received[0].stream).toBe(stream);
|
|
2286
|
+
(0, import_vitest4.expect)(received[0].events.length).toBeGreaterThanOrEqual(1);
|
|
2106
2287
|
} finally {
|
|
2107
2288
|
await writer.dispose();
|
|
2108
2289
|
await Promise.resolve(disposer());
|
|
@@ -2123,12 +2304,11 @@ var runStoreTck = (options) => {
|
|
|
2123
2304
|
collect,
|
|
2124
2305
|
dec,
|
|
2125
2306
|
inc,
|
|
2126
|
-
makeMeta,
|
|
2127
2307
|
reset,
|
|
2128
2308
|
runCacheTck,
|
|
2129
2309
|
runLoggerTck,
|
|
2310
|
+
runStabilityTck,
|
|
2130
2311
|
runStoreTck,
|
|
2131
|
-
seedStream,
|
|
2132
2312
|
uid
|
|
2133
2313
|
});
|
|
2134
2314
|
//# sourceMappingURL=index.cjs.map
|