@rotorsoft/act-tck 1.39.0 → 1.39.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 +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/cache-differential-tck.d.ts +1 -2
- package/dist/@types/cache-differential-tck.d.ts.map +1 -1
- package/dist/@types/logger-differential-tck.d.ts +1 -2
- package/dist/@types/logger-differential-tck.d.ts.map +1 -1
- package/dist/@types/store-differential-tck.d.ts +10 -10
- package/dist/@types/store-property-tck.d.ts +1 -1
- package/dist/@types/store-tck.d.ts +7 -7
- package/dist/@types/store-tck.d.ts.map +1 -1
- package/dist/index.cjs +33 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +33 -1
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
|
@@ -46,8 +46,7 @@ export type CacheDifferentialTckOptions = {
|
|
|
46
46
|
readonly runs?: number;
|
|
47
47
|
};
|
|
48
48
|
/**
|
|
49
|
-
* Cross-implementation differential contract for the {@link Cache} port
|
|
50
|
-
* (#1057).
|
|
49
|
+
* Cross-implementation differential contract for the {@link Cache} port.
|
|
51
50
|
*
|
|
52
51
|
* Where {@link runCacheTck} pins each method's contract against a single
|
|
53
52
|
* implementation, this harness drives a **family of randomized, seeded
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-differential-tck.d.ts","sourceRoot":"","sources":["../../src/cache-differential-tck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,sBAAsB,CAAC;AAI9D;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;CAChD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACxC,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAClD;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AA8FF
|
|
1
|
+
{"version":3,"file":"cache-differential-tck.d.ts","sourceRoot":"","sources":["../../src/cache-differential-tck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,sBAAsB,CAAC;AAI9D;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;CAChD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACxC,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAClD;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AA8FF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,uBAAuB,YACzB,2BAA2B,KACnC,IAsCF,CAAC"}
|
|
@@ -29,8 +29,7 @@ export type LoggerDifferentialTckOptions = {
|
|
|
29
29
|
readonly loggers: ReadonlyArray<DifferentialLogger>;
|
|
30
30
|
};
|
|
31
31
|
/**
|
|
32
|
-
* Cross-implementation differential contract for the {@link Logger} port
|
|
33
|
-
* (#1057).
|
|
32
|
+
* Cross-implementation differential contract for the {@link Logger} port.
|
|
34
33
|
*
|
|
35
34
|
* A logger has no portable return value to byte-compare — its output
|
|
36
35
|
* format is adapter-specific by design, which is exactly why
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger-differential-tck.d.ts","sourceRoot":"","sources":["../../src/logger-differential-tck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAC;CAChC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACrD,CAAC;AAwDF
|
|
1
|
+
{"version":3,"file":"logger-differential-tck.d.ts","sourceRoot":"","sources":["../../src/logger-differential-tck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAC;CAChC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACrD,CAAC;AAwDF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,wBAAwB,YAC1B,4BAA4B,KACpC,IA+BF,CAAC"}
|
|
@@ -24,19 +24,19 @@ export type DifferentialStore = {
|
|
|
24
24
|
*/
|
|
25
25
|
export type DifferentialSkips = {
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* SQLite `LIKE` is ASCII-case-insensitive, so a **mixed-case
|
|
28
28
|
* regex pattern** filter overmatches vs PG (`~`) / InMemory (`RegExp`),
|
|
29
29
|
* which are case-sensitive. Skips only the pattern-driven mixed-case
|
|
30
30
|
* assertions; exact-match (`stream_exact`) mixed-case still runs, since
|
|
31
|
-
* that path is case-exact on every adapter.
|
|
31
|
+
* that path is case-exact on every adapter. No in-tree adapter sets it.
|
|
32
32
|
*/
|
|
33
33
|
readonly caseInsensitivePatterns?: boolean;
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
35
|
+
* Skips the edge-input query assertions: `names: []` and the falsy-zero
|
|
36
|
+
* `before: 0` / `after: 0` bounds. The in-tree adapters agree on the
|
|
37
|
+
* guards, but `after: 0` is an absolute id bound and stores number events
|
|
38
|
+
* from different origins (InMemory from 0, Postgres from 1), so the
|
|
39
|
+
* Postgres differential still sets it.
|
|
40
40
|
*/
|
|
41
41
|
readonly queryEdgeInputs?: boolean;
|
|
42
42
|
};
|
|
@@ -90,8 +90,8 @@ export type StoreDifferentialTckOptions = {
|
|
|
90
90
|
readonly skip?: DifferentialSkips;
|
|
91
91
|
};
|
|
92
92
|
/**
|
|
93
|
-
* Cross-adapter differential contract
|
|
94
|
-
*
|
|
93
|
+
* Cross-adapter differential contract: seeded fuzz workloads over commits,
|
|
94
|
+
* leases, truncates, pii and queries.
|
|
95
95
|
*
|
|
96
96
|
* Adapters can drift in ways per-adapter cases don't catch — event
|
|
97
97
|
* ordering, the `with_snaps` snapshot floor, the exact shape of
|
|
@@ -116,7 +116,7 @@ export type StoreDifferentialTckOptions = {
|
|
|
116
116
|
* everything that defines correctness (stream, version, name, data,
|
|
117
117
|
* emission order, and the durable subscription state a lease op leaves
|
|
118
118
|
* behind: watermark, retry, blocked, error, priority, lane). Stream names
|
|
119
|
-
* carry mixed case so a case-insensitive pattern filter
|
|
119
|
+
* carry mixed case so a case-insensitive pattern filter surfaces as
|
|
120
120
|
* a diff.
|
|
121
121
|
*
|
|
122
122
|
* Wire it with the in-memory store as the reference and one or more
|
|
@@ -3,7 +3,7 @@ import type { Store } from "@rotorsoft/act/types";
|
|
|
3
3
|
* Property-based contract for the store-level invariants the drain pipeline
|
|
4
4
|
* depends on — commit version monotonicity, claim/lease no-leak, watermark
|
|
5
5
|
* monotonicity, and block exclusion. These ran only against `InMemoryStore`
|
|
6
|
-
*
|
|
6
|
+
* at first; running them against the durable adapters too is the only
|
|
7
7
|
* way to catch a divergence the example-based TCK cases miss.
|
|
8
8
|
*
|
|
9
9
|
* Each predicate resets the store (`drop` + `seed`) so randomized runs are
|
|
@@ -28,17 +28,17 @@ export type StoreCapabilities = {
|
|
|
28
28
|
readonly restore?: boolean;
|
|
29
29
|
/**
|
|
30
30
|
* Adapter honours `subscribe`'s optional `correlator` argument and answers
|
|
31
|
-
* `correlating
|
|
31
|
+
* `correlating`. When `true`, the TCK runs the correlation-lease
|
|
32
32
|
* suite — exclusive acquisition, renewal by the same holder, re-acquisition
|
|
33
33
|
* after expiry, per-key independence, and the keyed checkpoint.
|
|
34
34
|
*
|
|
35
35
|
* Optional because a store that ignores the argument simply lets every
|
|
36
|
-
* worker scan, which is
|
|
36
|
+
* worker scan, which is how every worker scanned before keyed checkpoints, and remains correct: the
|
|
37
37
|
* marks are idempotent, so the duplication is waste rather than error.
|
|
38
38
|
*/
|
|
39
39
|
readonly lease_correlation?: boolean;
|
|
40
40
|
/**
|
|
41
|
-
* Adapter supports sensitive-data isolation
|
|
41
|
+
* Adapter supports sensitive-data isolation: accepts the
|
|
42
42
|
* optional `pii` field on commit messages, returns it on load
|
|
43
43
|
* outputs, and implements {@link Store.forget_pii}. When `true`,
|
|
44
44
|
* the TCK runs the PII isolation suite — commit-with-pii
|
|
@@ -87,8 +87,8 @@ export type StoreCapabilities = {
|
|
|
87
87
|
*/
|
|
88
88
|
readonly rejects_nonportable_claim_source?: boolean;
|
|
89
89
|
/**
|
|
90
|
-
* Adapter honors the {@link SubscribeInput.correlated_at} **work mark
|
|
91
|
-
*
|
|
90
|
+
* Adapter honors the {@link SubscribeInput.correlated_at} **work mark**:
|
|
91
|
+
* `subscribe` applies it as `GREATEST(correlated_at, N)` and
|
|
92
92
|
* `claim` serves a marked stream from the subscription row alone
|
|
93
93
|
* (`at < correlated_at`) instead of probing the event log. When `true`,
|
|
94
94
|
* the TCK runs the work-set suite — mark-then-claim, monotonicity
|
|
@@ -97,7 +97,7 @@ export type StoreCapabilities = {
|
|
|
97
97
|
* surfaces (`reset`, `unblock`, `defer`, `prioritize`) leaving the mark
|
|
98
98
|
* intact.
|
|
99
99
|
*
|
|
100
|
-
* @deprecated Ignored
|
|
100
|
+
* @deprecated Ignored: the mark is the only eligibility
|
|
101
101
|
* rule, so this suite always runs. The field is kept so an adapter that
|
|
102
102
|
* still passes `work_set: true` keeps compiling.
|
|
103
103
|
*/
|
|
@@ -133,7 +133,7 @@ export type StoreTckOptions = {
|
|
|
133
133
|
* second commit that advances the version.
|
|
134
134
|
* 3. ~~Construction succeeds, `commit` reports success, and the data
|
|
135
135
|
* is not there.~~ This is the shape the suite exists to catch
|
|
136
|
-
* (
|
|
136
|
+
* (a zero-config SQLite store once defaulted to a per-connection
|
|
137
137
|
* private in-memory database, so `seed`'s DDL landed where later
|
|
138
138
|
* statements could not see it — every write was accepted and lost).
|
|
139
139
|
*
|
|
@@ -1 +1 @@
|
|
|
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;;;;;;;OAOG;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,
|
|
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;;;;;;;OAOG;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,IAmiLtD,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -601,7 +601,7 @@ var build_plan = (seed, stream_count, pii_isolation) => {
|
|
|
601
601
|
// gated falsy-zero cases below compare only the *guard* behavior
|
|
602
602
|
// (filter applied → subset, vs filter dropped → all), which stays a
|
|
603
603
|
// well-defined divergence regardless of the concrete id values.
|
|
604
|
-
//
|
|
604
|
+
// Edge inputs, gated behind `queryEdgeInputs`.
|
|
605
605
|
{
|
|
606
606
|
label: "empty names filter",
|
|
607
607
|
query: { stream: `^${event_prefix}`, names: [] },
|
|
@@ -1342,6 +1342,19 @@ var runStoreTck = (options) => {
|
|
|
1342
1342
|
});
|
|
1343
1343
|
(0, import_vitest9.expect)(limited).toHaveLength(2);
|
|
1344
1344
|
});
|
|
1345
|
+
(0, import_vitest9.it)("excludes snapshots when called with no query object", async () => {
|
|
1346
|
+
const s = `q-nofilter-${uid()}`;
|
|
1347
|
+
await store.commit(
|
|
1348
|
+
s,
|
|
1349
|
+
[{ name: import_act2.SNAP_EVENT, data: { count: 0 } }],
|
|
1350
|
+
make_meta({ stream: s })
|
|
1351
|
+
);
|
|
1352
|
+
const names = [];
|
|
1353
|
+
await store.query((e) => {
|
|
1354
|
+
names.push(e.name);
|
|
1355
|
+
});
|
|
1356
|
+
(0, import_vitest9.expect)(names).not.toContain(import_act2.SNAP_EVENT);
|
|
1357
|
+
});
|
|
1345
1358
|
(0, import_vitest9.it)("with_snaps resumes from the latest snapshot per stream", async () => {
|
|
1346
1359
|
const s = `q-snap-${uid()}`;
|
|
1347
1360
|
await store.commit(
|
|
@@ -3794,6 +3807,25 @@ var runStoreTck = (options) => {
|
|
|
3794
3807
|
]);
|
|
3795
3808
|
(0, import_vitest9.expect)(remaining[0].id).toBe(snap_b.id);
|
|
3796
3809
|
});
|
|
3810
|
+
(0, import_vitest9.it)("prunes two windowed targets for one stream in call order", async () => {
|
|
3811
|
+
const later = `trunc-win-twice-${uid()}`;
|
|
3812
|
+
const a1 = await seed_windowed(later);
|
|
3813
|
+
const before = new Date(Date.now() + 6e4);
|
|
3814
|
+
const first = await store.truncate([
|
|
3815
|
+
{ stream: later, before, max_id: a1.snap_b.id },
|
|
3816
|
+
{ stream: later, before, max_id: a1.snap_a.id }
|
|
3817
|
+
]);
|
|
3818
|
+
(0, import_vitest9.expect)(first.get(later)?.deleted).toBe(4);
|
|
3819
|
+
(0, import_vitest9.expect)(first.get(later)?.committed.id).toBe(a1.snap_b.id);
|
|
3820
|
+
const earlier = `trunc-win-twice-${uid()}`;
|
|
3821
|
+
const a2 = await seed_windowed(earlier);
|
|
3822
|
+
const second = await store.truncate([
|
|
3823
|
+
{ stream: earlier, before, max_id: a2.snap_a.id },
|
|
3824
|
+
{ stream: earlier, before, max_id: a2.snap_b.id }
|
|
3825
|
+
]);
|
|
3826
|
+
(0, import_vitest9.expect)(second.get(earlier)?.deleted).toBe(2);
|
|
3827
|
+
(0, import_vitest9.expect)(second.get(earlier)?.committed.id).toBe(a2.snap_b.id);
|
|
3828
|
+
});
|
|
3797
3829
|
(0, import_vitest9.it)("honors the max_id cap \u2014 boundary never rises past a lagging consumer", async () => {
|
|
3798
3830
|
const s = `trunc-win-cap-${uid()}`;
|
|
3799
3831
|
const { snap_a, snap_b } = await seed_windowed(s);
|