Migrate P2P UI and CLI transfers to service views

This commit is contained in:
vorotamoroz
2026-08-31 15:06:39 +00:00
parent 1d2077d3fc
commit 3f76ad796e
8 changed files with 125 additions and 47 deletions
+7
View File
@@ -17,6 +17,7 @@ function delay(ms: number): Promise<void> {
return new Promise((resolve) => compatGlobal.setTimeout(resolve, ms));
}
/** Parse a CLI timeout expressed as a finite, non-negative number of seconds. */
export function parseTimeoutSeconds(value: string, commandName: string): number {
const timeoutSec = Number(value);
if (!Number.isFinite(timeoutSec) || timeoutSec < 0) {
@@ -54,6 +55,7 @@ function getSortedPeers(service: Pick<P2PServiceViews, "peerDirectory">): CLIP2P
.sort((a, b) => a.peerId.localeCompare(b.peerId));
}
/** Connect for a bounded discovery interval, return a stable peer ordering, and disconnect. */
export async function collectPeers(
core: LiveSyncBaseCore<ServiceContext, never>,
p2pService: CLIP2PService | undefined,
@@ -137,6 +139,7 @@ export function createPeerConnectionStatsPayload(
return payload;
}
/** Resolve one peer token, complete pull then push, and disconnect on every settlement. */
export async function syncWithPeer(
core: LiveSyncBaseCore<ServiceContext, never>,
p2pService: CLIP2PService | undefined,
@@ -167,6 +170,9 @@ export async function syncWithPeer(
if (pullResult && "error" in pullResult && pullResult.error) {
throw pullResult.error instanceof Error ? pullResult.error : LiveSyncError.fromError(pullResult.error);
}
if (!pullResult || pullResult.status !== "completed") {
throw LiveSyncError.fromError("P2P sync failed while pulling from peer");
}
const pushResult = await service.targetedTransfer.requestPushToPeer(targetPeer.peerId);
if (!pushResult || pushResult.ok !== true) {
const err: unknown = pushResult && "error" in pushResult ? pushResult.error : undefined;
@@ -182,6 +188,7 @@ export async function syncWithPeer(
}
}
/** Connect the headless P2P host and transfer transport ownership to the caller. */
export async function openP2PHost(
core: LiveSyncBaseCore<ServiceContext, never>,
p2pService: CLIP2PService | undefined
+12 -2
View File
@@ -14,8 +14,8 @@ function createCore() {
function createP2PService() {
const connect = vi.fn(async () => undefined);
const disconnect = vi.fn(async () => undefined);
const pullFromPeer = vi.fn(async () => ({ ok: true }));
const requestPushToPeer = vi.fn(async () => ({ ok: true }));
const pullFromPeer = vi.fn(async () => ({ status: "completed" as const, ok: true as const }));
const requestPushToPeer = vi.fn(async () => ({ status: "completed" as const, ok: true as const }));
return {
service: {
transportLifecycle: { isConnected: false, connect, disconnect },
@@ -72,6 +72,16 @@ describe("p2p command helpers", () => {
expect(requestPushToPeer).toHaveBeenCalledWith("peer-a");
});
it("rejects a cancelled pull without requesting a peer push", async () => {
const { service, disconnect, pullFromPeer, requestPushToPeer } = createP2PService();
pullFromPeer.mockResolvedValue({ status: "cancelled" } as never);
await expect(syncWithPeer(createCore(), service as never, "peer-a", 0)).rejects.toBeDefined();
expect(requestPushToPeer).not.toHaveBeenCalled();
expect(disconnect).toHaveBeenCalledOnce();
});
it("preserves the benchmark diagnostics JSONL contract", () => {
expect(
createPeerConnectionStatsPayload(