Initial Commit
This commit is contained in:
@@ -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();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user