@rotorsoft/act-tck 1.38.20 → 1.38.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/store-tck.d.ts.map +1 -1
- package/dist/index.cjs +187 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +188 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-tck.d.ts","sourceRoot":"","sources":["../../src/store-tck.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store-tck.d.ts","sourceRoot":"","sources":["../../src/store-tck.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAQV,KAAK,EAIN,MAAM,sBAAsB,CAAC;AAe9B;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;;;;OASG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC;;;;;;;;OAQG;IACH,QAAQ,CAAC,gCAAgC,CAAC,EAAE,OAAO,CAAC;IACpD;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACxD;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,WAAW,YAAa,eAAe,KAAG,IAmgLtD,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -189,9 +189,9 @@ var runCacheDifferentialTck = (options) => {
|
|
|
189
189
|
|
|
190
190
|
// src/cache-tck.ts
|
|
191
191
|
var import_vitest2 = require("vitest");
|
|
192
|
-
var entry = (event_id,
|
|
192
|
+
var entry = (event_id, state2 = {}, stream = `s-${event_id}`) => ({
|
|
193
193
|
stream,
|
|
194
|
-
state,
|
|
194
|
+
state: state2,
|
|
195
195
|
version: event_id,
|
|
196
196
|
event_id,
|
|
197
197
|
patches: 1,
|
|
@@ -417,7 +417,7 @@ async function load_surface(entry2) {
|
|
|
417
417
|
if (visited.has(abs)) return;
|
|
418
418
|
const content = await import_node_fs.promises.readFile(abs, "utf8");
|
|
419
419
|
visited.set(abs, content);
|
|
420
|
-
const re_export = /^\s*
|
|
420
|
+
const re_export = /^\s*export\b[^"';]*\bfrom\s+["'](\.[^"']+)["']/gm;
|
|
421
421
|
for (const m of content.matchAll(re_export)) {
|
|
422
422
|
const rel = m[1].replace(/\.js$/, ".ts");
|
|
423
423
|
const target = import_node_path.default.resolve(import_node_path.default.dirname(abs), rel);
|
|
@@ -1163,6 +1163,7 @@ var runStorePropertyTck = (options) => {
|
|
|
1163
1163
|
// src/store-tck.ts
|
|
1164
1164
|
var import_act2 = require("@rotorsoft/act");
|
|
1165
1165
|
var import_vitest9 = require("vitest");
|
|
1166
|
+
var import_zod2 = require("zod");
|
|
1166
1167
|
var runStoreTck = (options) => {
|
|
1167
1168
|
(0, import_vitest9.describe)(`TCK / Store / ${options.name}`, () => {
|
|
1168
1169
|
let store;
|
|
@@ -3264,6 +3265,106 @@ var runStoreTck = (options) => {
|
|
|
3264
3265
|
(0, import_vitest9.expect)(got1.priority).toBe(3);
|
|
3265
3266
|
(0, import_vitest9.expect)(got2.priority).toBe(5);
|
|
3266
3267
|
});
|
|
3268
|
+
(0, import_vitest9.it)("matches a stream pattern", async () => {
|
|
3269
|
+
const tag = uid();
|
|
3270
|
+
await store.subscribe([
|
|
3271
|
+
{ stream: `pri-${tag}-proj-a` },
|
|
3272
|
+
{ stream: `pri-${tag}-proj-b` },
|
|
3273
|
+
{ stream: `pri-${tag}-audit-x` }
|
|
3274
|
+
]);
|
|
3275
|
+
(0, import_vitest9.expect)(
|
|
3276
|
+
await store.prioritize({ stream: `^pri-${tag}-proj-.*$` }, 3)
|
|
3277
|
+
).toBe(2);
|
|
3278
|
+
});
|
|
3279
|
+
(0, import_vitest9.it)("matches by source, skipping rows that have none", async () => {
|
|
3280
|
+
const tag = uid();
|
|
3281
|
+
await store.subscribe([
|
|
3282
|
+
{ stream: `pri-${tag}-t1`, source: `pri-src-${tag}-users` },
|
|
3283
|
+
{ stream: `pri-${tag}-t2`, source: `pri-src-${tag}-audit` },
|
|
3284
|
+
{ stream: `pri-${tag}-t3` }
|
|
3285
|
+
]);
|
|
3286
|
+
(0, import_vitest9.expect)(
|
|
3287
|
+
await store.prioritize(
|
|
3288
|
+
{ source: `pri-src-${tag}-users`, source_exact: true },
|
|
3289
|
+
4
|
|
3290
|
+
)
|
|
3291
|
+
).toBe(1);
|
|
3292
|
+
(0, import_vitest9.expect)(
|
|
3293
|
+
await store.prioritize({ source: `^pri-src-${tag}-.*$` }, 6)
|
|
3294
|
+
).toBe(2);
|
|
3295
|
+
});
|
|
3296
|
+
(0, import_vitest9.it)("matches by blocked state, both ways", async () => {
|
|
3297
|
+
const fresh = await options.factory();
|
|
3298
|
+
try {
|
|
3299
|
+
await fresh.drop();
|
|
3300
|
+
await fresh.seed();
|
|
3301
|
+
const tag = uid();
|
|
3302
|
+
const src = `pri-src-${tag}`;
|
|
3303
|
+
const ok = `pri-${tag}-ok`;
|
|
3304
|
+
const bad = `pri-${tag}-bad`;
|
|
3305
|
+
await fresh.commit(
|
|
3306
|
+
src,
|
|
3307
|
+
[inc(1)],
|
|
3308
|
+
make_meta({ stream: src })
|
|
3309
|
+
);
|
|
3310
|
+
await fresh.subscribe([
|
|
3311
|
+
{ stream: ok, source: src },
|
|
3312
|
+
{ stream: bad, source: src }
|
|
3313
|
+
]);
|
|
3314
|
+
await correlate(fresh);
|
|
3315
|
+
const leases = await fresh.claim(2, 0, `w-${uid()}`, 5e3);
|
|
3316
|
+
const lease = leases.find((l) => l.stream === bad);
|
|
3317
|
+
await fresh.block([{ ...lease, error: "boom" }]);
|
|
3318
|
+
const scope = `^pri-${tag}-.*$`;
|
|
3319
|
+
(0, import_vitest9.expect)(
|
|
3320
|
+
await fresh.prioritize({ stream: scope, blocked: true }, 9)
|
|
3321
|
+
).toBe(1);
|
|
3322
|
+
(0, import_vitest9.expect)(
|
|
3323
|
+
await fresh.prioritize({ stream: scope, blocked: false }, 9)
|
|
3324
|
+
).toBe(1);
|
|
3325
|
+
} finally {
|
|
3326
|
+
await fresh.dispose();
|
|
3327
|
+
}
|
|
3328
|
+
});
|
|
3329
|
+
(0, import_vitest9.it)("an empty filter updates every row, and skips rows already at the value", async () => {
|
|
3330
|
+
const fresh = await options.factory();
|
|
3331
|
+
try {
|
|
3332
|
+
await fresh.drop();
|
|
3333
|
+
await fresh.seed();
|
|
3334
|
+
const tag = uid();
|
|
3335
|
+
await fresh.subscribe([
|
|
3336
|
+
{ stream: `pri-${tag}-a` },
|
|
3337
|
+
{ stream: `pri-${tag}-b`, priority: 5 }
|
|
3338
|
+
]);
|
|
3339
|
+
(0, import_vitest9.expect)(await fresh.prioritize({}, 5)).toBe(1);
|
|
3340
|
+
(0, import_vitest9.expect)(await fresh.prioritize({}, 5)).toBe(0);
|
|
3341
|
+
} finally {
|
|
3342
|
+
await fresh.dispose();
|
|
3343
|
+
}
|
|
3344
|
+
});
|
|
3345
|
+
(0, import_vitest9.it)("claim returns higher-priority streams first under tied watermarks", async () => {
|
|
3346
|
+
const fresh = await options.factory();
|
|
3347
|
+
try {
|
|
3348
|
+
await fresh.drop();
|
|
3349
|
+
await fresh.seed();
|
|
3350
|
+
const tag = uid();
|
|
3351
|
+
const src = `pri-src-${tag}`;
|
|
3352
|
+
await fresh.commit(
|
|
3353
|
+
src,
|
|
3354
|
+
[inc(1), inc(2)],
|
|
3355
|
+
make_meta({ stream: src })
|
|
3356
|
+
);
|
|
3357
|
+
await fresh.subscribe([
|
|
3358
|
+
{ stream: `pri-${tag}-low`, source: src, priority: 0 },
|
|
3359
|
+
{ stream: `pri-${tag}-high`, source: src, priority: 5 }
|
|
3360
|
+
]);
|
|
3361
|
+
await correlate(fresh);
|
|
3362
|
+
const leases = await fresh.claim(1, 0, `w-${uid()}`, 5e3);
|
|
3363
|
+
(0, import_vitest9.expect)(leases.map((l) => l.stream)).toEqual([`pri-${tag}-high`]);
|
|
3364
|
+
} finally {
|
|
3365
|
+
await fresh.dispose();
|
|
3366
|
+
}
|
|
3367
|
+
});
|
|
3267
3368
|
});
|
|
3268
3369
|
(0, import_vitest9.describe)("lanes", () => {
|
|
3269
3370
|
(0, import_vitest9.it)("subscribe defaults lane to 'default' when omitted", async () => {
|
|
@@ -4304,6 +4405,43 @@ var runStoreTck = (options) => {
|
|
|
4304
4405
|
});
|
|
4305
4406
|
(0, import_vitest9.expect)([...all.keys()].sort()).toEqual([...streams].sort());
|
|
4306
4407
|
});
|
|
4408
|
+
(0, import_vitest9.it)("pages the count and tail paths by limit + after too", async () => {
|
|
4409
|
+
const tag = uid();
|
|
4410
|
+
for (const s of [`qsc-${tag}-c`, `qsc-${tag}-a`, `qsc-${tag}-b`])
|
|
4411
|
+
await store.commit(
|
|
4412
|
+
s,
|
|
4413
|
+
[inc(1), inc(2)],
|
|
4414
|
+
make_meta({ stream: s })
|
|
4415
|
+
);
|
|
4416
|
+
const pattern = { stream: `qsc-${tag}-.*` };
|
|
4417
|
+
const counted = await store.query_stats(pattern, {
|
|
4418
|
+
count: true,
|
|
4419
|
+
names: true,
|
|
4420
|
+
limit: 2
|
|
4421
|
+
});
|
|
4422
|
+
(0, import_vitest9.expect)([...counted.keys()]).toEqual([`qsc-${tag}-a`, `qsc-${tag}-b`]);
|
|
4423
|
+
(0, import_vitest9.expect)(counted.get(`qsc-${tag}-a`)?.count).toBe(2);
|
|
4424
|
+
(0, import_vitest9.expect)(counted.get(`qsc-${tag}-a`)?.names).toEqual({ Incremented: 2 });
|
|
4425
|
+
const counted2 = await store.query_stats(pattern, {
|
|
4426
|
+
count: true,
|
|
4427
|
+
limit: 2,
|
|
4428
|
+
after: `qsc-${tag}-b`
|
|
4429
|
+
});
|
|
4430
|
+
(0, import_vitest9.expect)([...counted2.keys()]).toEqual([`qsc-${tag}-c`]);
|
|
4431
|
+
const tailed = await store.query_stats(pattern, {
|
|
4432
|
+
tail: true,
|
|
4433
|
+
limit: 2
|
|
4434
|
+
});
|
|
4435
|
+
(0, import_vitest9.expect)([...tailed.keys()]).toEqual([`qsc-${tag}-a`, `qsc-${tag}-b`]);
|
|
4436
|
+
(0, import_vitest9.expect)(tailed.get(`qsc-${tag}-a`)?.head.version).toBe(1);
|
|
4437
|
+
(0, import_vitest9.expect)(tailed.get(`qsc-${tag}-a`)?.tail?.version).toBe(0);
|
|
4438
|
+
const tailed2 = await store.query_stats(pattern, {
|
|
4439
|
+
tail: true,
|
|
4440
|
+
limit: 2,
|
|
4441
|
+
after: `qsc-${tag}-b`
|
|
4442
|
+
});
|
|
4443
|
+
(0, import_vitest9.expect)([...tailed2.keys()]).toEqual([`qsc-${tag}-c`]);
|
|
4444
|
+
});
|
|
4307
4445
|
});
|
|
4308
4446
|
import_vitest9.describe.skipIf(!caps.source_matches)(
|
|
4309
4447
|
"query_streams source_matches (capability)",
|
|
@@ -4434,6 +4572,52 @@ var runStoreTck = (options) => {
|
|
|
4434
4572
|
(0, import_vitest9.expect)(positions).toEqual([s]);
|
|
4435
4573
|
});
|
|
4436
4574
|
});
|
|
4575
|
+
(0, import_vitest9.describe)("autoclose end-to-end", () => {
|
|
4576
|
+
const Ticket = (0, import_act2.state)({ TckTicket: import_zod2.z.object({ open: import_zod2.z.boolean() }) }).init(() => ({ open: false })).emits({
|
|
4577
|
+
TckTicketOpened: import_zod2.z.object({ title: import_zod2.z.string() }),
|
|
4578
|
+
TckTicketResolved: import_zod2.z.object({})
|
|
4579
|
+
}).patch({
|
|
4580
|
+
TckTicketOpened: () => ({ open: true }),
|
|
4581
|
+
TckTicketResolved: () => ({ open: false })
|
|
4582
|
+
}).on({ OpenTckTicket: import_zod2.z.object({ title: import_zod2.z.string() }) }).emit((a) => ["TckTicketOpened", { title: a.title }]).on({ ResolveTckTicket: import_zod2.z.object({}) }).emit(() => ["TckTicketResolved", {}]).autocloses({ is: "TckTicketResolved" }).build();
|
|
4583
|
+
const actor2 = { id: "tck", name: "tck" };
|
|
4584
|
+
const run = async (resolve) => {
|
|
4585
|
+
const fresh = await options.factory();
|
|
4586
|
+
await fresh.drop();
|
|
4587
|
+
await fresh.seed();
|
|
4588
|
+
const cache = new import_act2.InMemoryCache();
|
|
4589
|
+
const app = (0, import_act2.act)().withState(Ticket).build({ scoped: { store: fresh, cache } });
|
|
4590
|
+
const truncated = [];
|
|
4591
|
+
app.on("closed", (r) => truncated.push(...r.truncated.keys()));
|
|
4592
|
+
const stream = `ac-${uid()}`;
|
|
4593
|
+
try {
|
|
4594
|
+
await app.do("OpenTckTicket", { stream, actor: actor2 }, { title: "a" });
|
|
4595
|
+
if (resolve) await app.do("ResolveTckTicket", { stream, actor: actor2 }, {});
|
|
4596
|
+
await app.correlate();
|
|
4597
|
+
await app.drain();
|
|
4598
|
+
const surviving = [];
|
|
4599
|
+
await fresh.query((e) => surviving.push(String(e.name)), {
|
|
4600
|
+
stream,
|
|
4601
|
+
stream_exact: true
|
|
4602
|
+
});
|
|
4603
|
+
return { stream, truncated, surviving };
|
|
4604
|
+
} finally {
|
|
4605
|
+
await app.shutdown();
|
|
4606
|
+
await cache.dispose();
|
|
4607
|
+
await fresh.dispose();
|
|
4608
|
+
}
|
|
4609
|
+
};
|
|
4610
|
+
(0, import_vitest9.it)("closes a stream whose head is the terminal event, leaving a tombstone", async () => {
|
|
4611
|
+
const { stream, truncated, surviving } = await run(true);
|
|
4612
|
+
(0, import_vitest9.expect)(truncated).toContain(stream);
|
|
4613
|
+
(0, import_vitest9.expect)(surviving).toEqual([import_act2.TOMBSTONE_EVENT]);
|
|
4614
|
+
});
|
|
4615
|
+
(0, import_vitest9.it)("leaves a stream whose head is not the terminal event", async () => {
|
|
4616
|
+
const { stream, truncated, surviving } = await run(false);
|
|
4617
|
+
(0, import_vitest9.expect)(truncated).not.toContain(stream);
|
|
4618
|
+
(0, import_vitest9.expect)(surviving).toEqual(["TckTicketOpened"]);
|
|
4619
|
+
});
|
|
4620
|
+
});
|
|
4437
4621
|
(0, import_vitest9.describe)("seed_stream helper coverage", () => {
|
|
4438
4622
|
(0, import_vitest9.it)("commits N events with monotonically increasing ids", async () => {
|
|
4439
4623
|
const s = `seed-${uid()}`;
|