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,187 @@
/**
* Deterministic in-memory PeerJS substitute used by the test suites. Models a
* single shared broker — every `FakePeer` constructed against the same
* `FakeBroker` can `connect` to every other peer. No mocks: this is a real
* implementation of the structural contract.
*/
import type {
DataConnectionLike,
PeerFactory,
PeerJSMessage,
PeerJSPeerOptions,
PeerLike,
} from "../../src/types/types.js";
type Handler = (arg?: unknown) => void;
/** Shared broker state — wires `FakePeer`s together by id. */
export class FakeBroker {
public readonly peers = new Map<string, FakePeer>();
public nextId = 0;
/** When `true`, peer-open is rejected with `Error('broker down')`. */
public broken = false;
public register(peer: FakePeer): string {
this.nextId += 1;
const id = peer.configuredPeerId || `fake-peer-${this.nextId}`;
this.peers.set(id, peer);
return id;
}
public unregister(id: string): void {
this.peers.delete(id);
}
public find(id: string): FakePeer | undefined {
return this.peers.get(id);
}
}
/** Implementation of `DataConnectionLike` shared by both ends of a channel. */
export class FakeDataConnection implements DataConnectionLike {
public open = false;
private readonly handlers = new Map<string, Set<Handler>>();
public partner: FakeDataConnection | undefined;
public constructor(public readonly peer: string) {}
public send(message: PeerJSMessage): void {
if (!this.open) throw new Error("connection closed");
const partner = this.partner;
if (partner === undefined) return;
queueMicrotask(() => {
partner.emit("data", message);
});
}
public on(event: "open", h: () => void): void;
public on(event: "data", h: (data: unknown) => void): void;
public on(event: "error", h: (error: Error) => void): void;
public on(event: "close", h: () => void): void;
public on(event: string, h: Handler): void {
let set = this.handlers.get(event);
if (set === undefined) {
set = new Set();
this.handlers.set(event, set);
}
set.add(h);
}
public close(): void {
if (!this.open && this.handlers.size === 0) return;
this.open = false;
this.emit("close");
this.partner?.fireClose();
}
public fireOpen(): void {
this.open = true;
this.emit("open");
}
public fireError(error: Error): void {
this.emit("error", error);
}
private fireClose(): void {
if (!this.open) return;
this.open = false;
this.emit("close");
}
public emit(event: string, arg?: unknown): void {
const set = this.handlers.get(event);
if (set === undefined) return;
for (const handler of set) {
handler(arg);
}
}
}
/** Implementation of `PeerLike`. */
export class FakePeer implements PeerLike {
public readonly handlers = new Map<string, Set<Handler>>();
public id: string | undefined;
public destroyed = false;
public outboundFailure: Error | undefined;
public constructor(
public readonly broker: FakeBroker,
public readonly configuredPeerId: string,
public readonly options: PeerJSPeerOptions
) {
queueMicrotask(() => {
if (this.destroyed) return;
if (broker.broken) {
this.emit("error", new Error("broker down"));
return;
}
this.id = broker.register(this);
this.emit("open", this.id);
});
}
public connect(peerId: string): DataConnectionLike {
if (this.outboundFailure !== undefined) {
throw this.outboundFailure;
}
const remote = this.broker.find(peerId);
const local = new FakeDataConnection(peerId);
const partner = new FakeDataConnection(this.id ?? "");
local.partner = partner;
partner.partner = local;
if (remote !== undefined) {
queueMicrotask(() => {
remote.emit("connection", partner);
partner.fireOpen();
local.fireOpen();
});
} else {
queueMicrotask(() => {
local.fireError(new Error(`peer ${peerId} not found`));
});
}
return local;
}
public on(event: "open", h: (id: string) => void): void;
public on(event: "connection", h: (c: DataConnectionLike) => void): void;
public on(event: "error", h: (e: Error) => void): void;
public on(event: "disconnected", h: () => void): void;
public on(event: "close", h: () => void): void;
public on(event: string, h: Handler): void {
let set = this.handlers.get(event);
if (set === undefined) {
set = new Set();
this.handlers.set(event, set);
}
set.add(h);
}
public destroy(): void {
if (this.destroyed) return;
this.destroyed = true;
if (this.id !== undefined) this.broker.unregister(this.id);
this.emit("close");
}
public emit(event: string, arg?: unknown): void {
const set = this.handlers.get(event);
if (set === undefined) return;
for (const handler of set) {
handler(arg);
}
}
}
/** Build a `PeerFactory` bound to a shared broker. */
export function fakePeerFactory(broker: FakeBroker): PeerFactory {
return (peerId, options) => new FakePeer(broker, peerId, options);
}
/** Yield control until pending microtasks have drained. */
export async function flushMicrotasks(): Promise<void> {
for (let i = 0; i < 4; i += 1) {
await Promise.resolve();
}
}

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;
}