@noy-db/test-mesh-conformance 0.8.0 → 0.9.0-pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -28
- package/dist/index.js +1 -121
- package/dist/index.js.map +1 -1
- package/package.json +9 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,28 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Parameterized conformance suite for the `by-*` family port.
|
|
5
|
-
*
|
|
6
|
-
* `NoydbMesh` is what a session-share transport implements so a schema-fence
|
|
7
|
-
* cutover can drain: who else is live, and what generation are they on.
|
|
8
|
-
*
|
|
9
|
-
* ⚠️ THE FIXTURE IS A PAIR, NOT AN INSTANCE — and that is the whole point.
|
|
10
|
-
* A mesh's defining property is that two participants see each other; a suite
|
|
11
|
-
* built around one instance would pass on an implementation that shares
|
|
12
|
-
* nothing, which is precisely the implementation that breaks a cutover. Same
|
|
13
|
-
* reasoning as the sealer kit requiring a second, differently-identified
|
|
14
|
-
* provider.
|
|
15
|
-
*
|
|
16
|
-
* `channelMesh` (by-peer, by-tabs) is push-based and `StoreMesh` polls,
|
|
17
|
-
* so every observation here is written against `waitFor` rather than assuming
|
|
18
|
-
* synchronous delivery. An implementation that only ever delivers on the next
|
|
19
|
-
* poll is conformant — slow, but conformant.
|
|
20
|
-
*/
|
|
21
|
-
declare function runMeshConformanceTests(name: string, fixture: {
|
|
22
|
-
/** Two meshes that share coordination state. */
|
|
23
|
-
readonly pair: () => Promise<readonly [NoydbMesh, NoydbMesh]> | readonly [NoydbMesh, NoydbMesh];
|
|
24
|
-
/** Tear down a pair, if the transport needs it. */
|
|
25
|
-
readonly cleanup?: (pair: readonly [NoydbMesh, NoydbMesh]) => void | Promise<void>;
|
|
26
|
-
}): void;
|
|
27
|
-
|
|
28
|
-
export { runMeshConformanceTests };
|
|
1
|
+
export * from '@noy-db/ports/by';
|
package/dist/index.js
CHANGED
|
@@ -1,123 +1,3 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
|
|
3
|
-
async function waitFor(fn, ms = 3e3) {
|
|
4
|
-
const deadline = Date.now() + ms;
|
|
5
|
-
for (; ; ) {
|
|
6
|
-
const v = await fn();
|
|
7
|
-
if (v) return v;
|
|
8
|
-
if (Date.now() > deadline) throw new Error("waitFor: timed out");
|
|
9
|
-
await new Promise((r) => setTimeout(r, 10));
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
var writer = (id, lastSeen) => ({
|
|
13
|
-
writerId: id,
|
|
14
|
-
sessionId: `${id}-s`,
|
|
15
|
-
lastSeen,
|
|
16
|
-
quiescedAtVersion: null
|
|
17
|
-
});
|
|
18
|
-
function runMeshConformanceTests(name, fixture) {
|
|
19
|
-
const VAULT = "conformance-vault";
|
|
20
|
-
describe(`NoydbMesh conformance: ${name}`, () => {
|
|
21
|
-
const withPair = async (fn) => {
|
|
22
|
-
const pair = await fixture.pair();
|
|
23
|
-
try {
|
|
24
|
-
await fn(pair[0], pair[1]);
|
|
25
|
-
} finally {
|
|
26
|
-
await fixture.cleanup?.(pair);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
it("readFence returns a usable default before anything is written", async () => {
|
|
30
|
-
await withPair(async (a) => {
|
|
31
|
-
const f = await a.readFence(VAULT);
|
|
32
|
-
expect(f).toBeDefined();
|
|
33
|
-
expect(typeof f.currentSchemaVersion).toBe("number");
|
|
34
|
-
expect(["normal", "draining", "migrating", "complete"]).toContain(f.fenceState);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
it("setFence \u2192 readFence round-trips on the SAME participant", async () => {
|
|
38
|
-
await withPair(async (a) => {
|
|
39
|
-
await a.setFence(VAULT, { currentSchemaVersion: 7, fenceState: "draining" });
|
|
40
|
-
expect(await a.readFence(VAULT)).toMatchObject({ currentSchemaVersion: 7, fenceState: "draining" });
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
it("setFence on one participant is VISIBLE to the other", async () => {
|
|
44
|
-
await withPair(async (a, b) => {
|
|
45
|
-
await a.setFence(VAULT, { currentSchemaVersion: 9, fenceState: "migrating" });
|
|
46
|
-
const f = await waitFor(async () => {
|
|
47
|
-
const cur = await b.readFence(VAULT);
|
|
48
|
-
return cur.fenceState === "migrating" ? cur : null;
|
|
49
|
-
});
|
|
50
|
-
expect(f.currentSchemaVersion).toBe(9);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
it("observeFence fires on the other participant when the fence moves", async () => {
|
|
54
|
-
await withPair(async (a, b) => {
|
|
55
|
-
const seen = [];
|
|
56
|
-
const un = b.observeFence(VAULT, (f) => {
|
|
57
|
-
seen.push(f.fenceState);
|
|
58
|
-
});
|
|
59
|
-
await a.setFence(VAULT, { currentSchemaVersion: 3, fenceState: "draining" });
|
|
60
|
-
await waitFor(() => seen.includes("draining"));
|
|
61
|
-
un();
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
it("observeFence stops delivering after unsubscribe", async () => {
|
|
65
|
-
await withPair(async (a, b) => {
|
|
66
|
-
const seen = [];
|
|
67
|
-
const un = b.observeFence(VAULT, (f) => {
|
|
68
|
-
seen.push(f.fenceState);
|
|
69
|
-
});
|
|
70
|
-
await a.setFence(VAULT, { currentSchemaVersion: 1, fenceState: "draining" });
|
|
71
|
-
await waitFor(() => seen.includes("draining"));
|
|
72
|
-
un();
|
|
73
|
-
const after = seen.length;
|
|
74
|
-
await a.setFence(VAULT, { currentSchemaVersion: 2, fenceState: "complete" });
|
|
75
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
76
|
-
expect(seen.length, "callback fired after unsubscribe").toBe(after);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
it("reportPresence on one participant is REACHABLE from the other", async () => {
|
|
80
|
-
await withPair(async (a, b) => {
|
|
81
|
-
const now = Date.now();
|
|
82
|
-
await a.reportPresence(VAULT, writer("w-a", now));
|
|
83
|
-
const found = await waitFor(async () => {
|
|
84
|
-
const ws = await b.reachableWriters(VAULT, { staleMs: 6e4, now: Date.now() });
|
|
85
|
-
return ws.some((w) => w.writerId === "w-a") ? ws : null;
|
|
86
|
-
}, 3e3);
|
|
87
|
-
expect(found.map((w) => w.writerId)).toContain("w-a");
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
it("reachableWriters EXCLUDES a writer older than staleMs", async () => {
|
|
91
|
-
await withPair(async (a, b) => {
|
|
92
|
-
const now = Date.now();
|
|
93
|
-
await a.reportPresence(VAULT, writer("w-stale", now - 12e4));
|
|
94
|
-
await new Promise((r) => setTimeout(r, 100));
|
|
95
|
-
const ws = await b.reachableWriters(VAULT, { staleMs: 3e4, now });
|
|
96
|
-
expect(ws.map((w) => w.writerId)).not.toContain("w-stale");
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
it("observePresence fires on the other participant", async () => {
|
|
100
|
-
await withPair(async (a, b) => {
|
|
101
|
-
let seen = [];
|
|
102
|
-
const un = b.observePresence(VAULT, (ws) => {
|
|
103
|
-
seen = ws;
|
|
104
|
-
});
|
|
105
|
-
await a.reportPresence(VAULT, writer("w-obs", Date.now()));
|
|
106
|
-
await waitFor(() => seen.some((w) => w.writerId === "w-obs"));
|
|
107
|
-
un();
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
it("keeps vaults isolated \u2014 presence in one is not reachable from another", async () => {
|
|
111
|
-
await withPair(async (a, b) => {
|
|
112
|
-
await a.reportPresence(VAULT, writer("w-iso", Date.now()));
|
|
113
|
-
await new Promise((r) => setTimeout(r, 150));
|
|
114
|
-
const other = await b.reachableWriters("a-different-vault", { staleMs: 6e4, now: Date.now() });
|
|
115
|
-
expect(other.map((w) => w.writerId)).not.toContain("w-iso");
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
export {
|
|
121
|
-
runMeshConformanceTests
|
|
122
|
-
};
|
|
2
|
+
export * from "@noy-db/ports/by";
|
|
123
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { describe, it, expect } from 'vitest'\nimport type { NoydbMesh, WriterPresence } from '@noy-db/hub/by'\n\n/**\n * Poll until `fn` yields something truthy, or the budget runs out. Delivery is\n * asynchronous on every transport — push-based ones deliver on a microtask,\n * `StoreMesh` on its next poll — so no observation here may assume it has\n * already happened.\n *\n * ⚠️ It MUST await the predicate. An earlier version did not, so an `async`\n * predicate returned a Promise, a Promise is always truthy, and every test\n * using one passed without observing anything at all.\n */\nasync function waitFor<T>(\n fn: () => Promise<T | null | undefined | false> | T | null | undefined | false,\n ms = 3000,\n): Promise<T> {\n const deadline = Date.now() + ms\n for (;;) {\n const v = await fn()\n if (v) return v\n if (Date.now() > deadline) throw new Error('waitFor: timed out')\n await new Promise((r) => setTimeout(r, 10))\n }\n}\n\nconst writer = (id: string, lastSeen: number): WriterPresence => ({\n writerId: id, sessionId: `${id}-s`, lastSeen, quiescedAtVersion: null,\n})\n\n/**\n * Parameterized conformance suite for the `by-*` family port.\n *\n * `NoydbMesh` is what a session-share transport implements so a schema-fence\n * cutover can drain: who else is live, and what generation are they on.\n *\n * ⚠️ THE FIXTURE IS A PAIR, NOT AN INSTANCE — and that is the whole point.\n * A mesh's defining property is that two participants see each other; a suite\n * built around one instance would pass on an implementation that shares\n * nothing, which is precisely the implementation that breaks a cutover. Same\n * reasoning as the sealer kit requiring a second, differently-identified\n * provider.\n *\n * `channelMesh` (by-peer, by-tabs) is push-based and `StoreMesh` polls,\n * so every observation here is written against `waitFor` rather than assuming\n * synchronous delivery. An implementation that only ever delivers on the next\n * poll is conformant — slow, but conformant.\n */\nexport function runMeshConformanceTests(\n name: string,\n fixture: {\n /** Two meshes that share coordination state. */\n readonly pair: () => Promise<readonly [NoydbMesh, NoydbMesh]> | readonly [NoydbMesh, NoydbMesh]\n /** Tear down a pair, if the transport needs it. */\n readonly cleanup?: (pair: readonly [NoydbMesh, NoydbMesh]) => void | Promise<void>\n },\n): void {\n const VAULT = 'conformance-vault'\n\n describe(`NoydbMesh conformance: ${name}`, () => {\n const withPair = async (fn: (a: NoydbMesh, b: NoydbMesh) => Promise<void>) => {\n const pair = await fixture.pair()\n try { await fn(pair[0], pair[1]) } finally { await fixture.cleanup?.(pair) }\n }\n\n it('readFence returns a usable default before anything is written', async () => {\n // A cutover asks the fence before anyone sets one. Throwing here, or\n // returning undefined, breaks the first migration on a fresh vault.\n await withPair(async (a) => {\n const f = await a.readFence(VAULT)\n expect(f).toBeDefined()\n expect(typeof f.currentSchemaVersion).toBe('number')\n expect(['normal', 'draining', 'migrating', 'complete']).toContain(f.fenceState)\n })\n })\n\n it('setFence → readFence round-trips on the SAME participant', async () => {\n await withPair(async (a) => {\n await a.setFence(VAULT, { currentSchemaVersion: 7, fenceState: 'draining' })\n expect(await a.readFence(VAULT)).toMatchObject({ currentSchemaVersion: 7, fenceState: 'draining' })\n })\n })\n\n it('setFence on one participant is VISIBLE to the other', async () => {\n // The load-bearing one. A mesh that keeps fence state per-instance\n // passes every single-instance test and still lets a migration proceed\n // while another writer believes the vault is normal.\n await withPair(async (a, b) => {\n await a.setFence(VAULT, { currentSchemaVersion: 9, fenceState: 'migrating' })\n const f = await waitFor(async () => {\n const cur = await b.readFence(VAULT)\n return cur.fenceState === 'migrating' ? cur : null\n })\n expect(f.currentSchemaVersion).toBe(9)\n })\n })\n\n it('observeFence fires on the other participant when the fence moves', async () => {\n await withPair(async (a, b) => {\n const seen: string[] = []\n const un = b.observeFence(VAULT, (f) => { seen.push(f.fenceState) })\n await a.setFence(VAULT, { currentSchemaVersion: 3, fenceState: 'draining' })\n await waitFor(() => seen.includes('draining'))\n un()\n })\n })\n\n it('observeFence stops delivering after unsubscribe', async () => {\n await withPair(async (a, b) => {\n const seen: string[] = []\n const un = b.observeFence(VAULT, (f) => { seen.push(f.fenceState) })\n await a.setFence(VAULT, { currentSchemaVersion: 1, fenceState: 'draining' })\n await waitFor(() => seen.includes('draining'))\n un()\n const after = seen.length\n await a.setFence(VAULT, { currentSchemaVersion: 2, fenceState: 'complete' })\n await new Promise((r) => setTimeout(r, 200))\n expect(seen.length, 'callback fired after unsubscribe').toBe(after)\n })\n })\n\n it('reportPresence on one participant is REACHABLE from the other', async () => {\n await withPair(async (a, b) => {\n const now = Date.now()\n await a.reportPresence(VAULT, writer('w-a', now))\n const found = await waitFor(async () => {\n const ws = await b.reachableWriters(VAULT, { staleMs: 60_000, now: Date.now() })\n return ws.some((w) => w.writerId === 'w-a') ? ws : null\n }, 3000)\n expect(found.map((w) => w.writerId)).toContain('w-a')\n })\n })\n\n it('reachableWriters EXCLUDES a writer older than staleMs', async () => {\n // The drain barrier waits for reachable writers to quiesce. Counting a\n // dead writer as reachable hangs the cutover until the timeout — the\n // failure this filter exists to prevent.\n await withPair(async (a, b) => {\n const now = Date.now()\n await a.reportPresence(VAULT, writer('w-stale', now - 120_000))\n await new Promise((r) => setTimeout(r, 100))\n const ws = await b.reachableWriters(VAULT, { staleMs: 30_000, now })\n expect(ws.map((w) => w.writerId)).not.toContain('w-stale')\n })\n })\n\n it('observePresence fires on the other participant', async () => {\n await withPair(async (a, b) => {\n let seen: readonly WriterPresence[] = []\n const un = b.observePresence(VAULT, (ws) => { seen = ws })\n await a.reportPresence(VAULT, writer('w-obs', Date.now()))\n await waitFor(() => seen.some((w) => w.writerId === 'w-obs'))\n un()\n })\n })\n\n it('keeps vaults isolated — presence in one is not reachable from another', async () => {\n await withPair(async (a, b) => {\n await a.reportPresence(VAULT, writer('w-iso', Date.now()))\n await new Promise((r) => setTimeout(r, 150))\n const other = await b.reachableWriters('a-different-vault', { staleMs: 60_000, now: Date.now() })\n expect(other.map((w) => w.writerId)).not.toContain('w-iso')\n })\n })\n })\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@noy-db/test-mesh-conformance` is now a re-export of `@noy-db/ports/by` — the six\n * conformance kits were consolidated into one package with one subpath per\n * hub port (2026-09-21). Function names are unchanged; only the specifier\n * moved. This name stays published for consumers still pinning it and is\n * deprecated in favour of `@noy-db/ports/by`.\n */\nexport * from '@noy-db/ports/by'\n"],"mappings":";AAOA,cAAc;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noy-db/test-mesh-conformance",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Parameterized contract tests for noy-db by-* transports — the conformance suite every NoydbMesh implementation must pass",
|
|
3
|
+
"version": "0.9.0-pre.1",
|
|
4
|
+
"description": "Parameterized contract tests for noy-db by-* transports — the conformance suite every NoydbMesh implementation must pass — now a re-export of @noy-db/ports/by; deprecated in favour of it",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "vLannaAi <vicio@lanna.ai>",
|
|
7
7
|
"homepage": "https://github.com/noy-db/core/tree/main/packages/test-mesh-conformance#readme",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"vitest": "^3.0.0",
|
|
37
|
-
"@noy-db/hub": "^0.
|
|
37
|
+
"@noy-db/hub": "^0.9.0-pre.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"vitest": "^3.0.0",
|
|
41
|
-
"@noy-db/hub": "0.
|
|
41
|
+
"@noy-db/hub": "0.9.0-pre.1"
|
|
42
42
|
},
|
|
43
43
|
"keywords": [
|
|
44
44
|
"noy-db",
|
|
@@ -50,9 +50,12 @@
|
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"access": "public"
|
|
52
52
|
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@noy-db/ports": "^0.9.0-pre.1"
|
|
55
|
+
},
|
|
53
56
|
"scripts": {
|
|
54
57
|
"build": "tsup",
|
|
55
|
-
"test": "vitest run
|
|
56
|
-
"typecheck": "tsc --noEmit"
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.tests.json"
|
|
57
60
|
}
|
|
58
61
|
}
|