Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
import { describe, expect, it } from "@suaveplan/testing/runner";
describe("network-plugin-relay dep-graph", () => {
it("loads index.js (acyclic static imports)", async () => {
const mod = await import("../src/index.js");
expect(mod.RelayManager).toBeDefined();
expect(mod.RelayRouter).toBeDefined();
expect(mod.MeshDirectory).toBeDefined();
expect(mod.LoopGuard).toBeDefined();
expect(mod.HostBackboneTransport).toBeDefined();
expect(mod.createCrossMeshEnvelope).toBeDefined();
});
});

View File

@@ -0,0 +1,137 @@
import { describe, expect, it } from "@suaveplan/testing/runner";
import {
type BackboneWire,
createCrossMeshEnvelope,
HostBackboneTransport,
LoopGuard,
MeshDirectory,
RelayManager,
RelayRouter,
} from "../../src/index.js";
/**
* End-to-end two-mesh test: alice in mesh-A sends a message to bob in
* mesh-B; host-A relays via host-B over a shared backbone wire.
*/
describe("relay end-to-end", () => {
it("routes alice@A → bob@B via host backbone", async () => {
// Single shared in-memory wire that both backbones use to talk
// to each other. Each backbone is configured to address the
// *other* host id.
const aliceQueue: Array<{ hostId: string; payload: Uint8Array }> = [];
const bobQueue: Array<{ hostId: string; payload: Uint8Array }> = [];
let aliceHandler:
| ((hostId: string, payload: Uint8Array) => void)
| null = null;
let bobHandler: ((hostId: string, payload: Uint8Array) => void) | null =
null;
const aliceConnections = new Set<string>();
const bobConnections = new Set<string>();
const aliceWire: BackboneWire = {
async open(h) {
aliceConnections.add(h);
},
async close(h) {
aliceConnections.delete(h);
},
async write(hostId, payload) {
aliceQueue.push({ hostId, payload });
bobHandler?.("host-A", payload);
},
onPayload(h) {
aliceHandler = h;
return () => {
aliceHandler = null;
};
},
isConnected(h) {
return aliceConnections.has(h);
},
};
const bobWire: BackboneWire = {
async open(h) {
bobConnections.add(h);
},
async close(h) {
bobConnections.delete(h);
},
async write(hostId, payload) {
bobQueue.push({ hostId, payload });
aliceHandler?.("host-B", payload);
},
onPayload(h) {
bobHandler = h;
return () => {
bobHandler = null;
};
},
isConnected(h) {
return bobConnections.has(h);
},
};
const aliceBackbone = new HostBackboneTransport({ wire: aliceWire });
const bobBackbone = new HostBackboneTransport({ wire: bobWire });
aliceBackbone.start();
bobBackbone.start();
const aliceRouter = new RelayRouter();
aliceRouter.addRoute("mesh-B", "bob", "host-B");
const bobRouter = new RelayRouter();
const aliceDelivered: unknown[] = [];
const bobDelivered: unknown[] = [];
const aliceManager = new RelayManager({
localMeshId: "mesh-A",
localHostId: "host-A",
router: aliceRouter,
backbone: aliceBackbone,
directory: new MeshDirectory(),
loopGuard: new LoopGuard({ localHostId: "host-A" }),
deliverLocally: async (env) => {
aliceDelivered.push(env);
},
});
const bobManager = new RelayManager({
localMeshId: "mesh-B",
localHostId: "host-B",
router: bobRouter,
backbone: bobBackbone,
directory: new MeshDirectory(),
loopGuard: new LoopGuard({ localHostId: "host-B" }),
deliverLocally: async (env) => {
bobDelivered.push(env);
},
});
const offA = aliceManager.attachToBackbone();
const offB = bobManager.attachToBackbone();
await aliceBackbone.connect("host-B", "wss://b");
await bobBackbone.connect("host-A", "wss://a");
const envelope = createCrossMeshEnvelope({
id: "msg-1",
type: "chat",
senderId: "alice",
senderMeshId: "mesh-A",
targetId: "bob",
targetMeshId: "mesh-B",
payload: { text: "hi bob" },
timestamp: 0,
});
await aliceManager.route(envelope);
await Promise.resolve();
await Promise.resolve();
expect(bobDelivered).toHaveLength(1);
expect(aliceDelivered).toHaveLength(0);
offA();
offB();
});
});

View File

@@ -0,0 +1,8 @@
// Ensure `globalThis.crypto` is available in bare-Node vitest runs.
import { webcrypto } from "node:crypto";
type WritableGlobal = { crypto?: Crypto };
const g = globalThis as WritableGlobal;
if (g.crypto === undefined) {
g.crypto = webcrypto as unknown as Crypto;
}