Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/firefox-bidi/__bench__/baseline.ts

Raw
// Verbatim copy of the pre-optimization hot path (index.ts runBatch loop +
// execute payload build), used as the benchmark baseline and diff-checked
// against the optimized implementation. Do not "improve" this file.

import { mkdtemp, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { interpolate } from "../lib.ts";

const MAX_INLINE = 256 * 1024;

interface BidiResponse {
	id: number;
	method?: string;
	type?: string;
	result?: unknown;
	error?: string;
	message?: string;
	skipped?: boolean;
}

interface BatchCtx {
	pending: Map<number, (r: BidiResponse) => void>;
	ledger: {
		subscriptions: string[];
		intercepts: string[];
		preloadScripts: string[];
	};
	spoolDir: string;
}

function ledgerUpdate(
	b: BatchCtx,
	method: string,
	params: Record<string, unknown>,
	res: BidiResponse,
): void {
	const ok = res.type === "success";
	const result = (res.result ?? {}) as Record<string, unknown>;
	if (method === "session.subscribe" && ok) {
		for (const e of (params.events as string[]) ?? [])
			if (!b.ledger.subscriptions.includes(e)) b.ledger.subscriptions.push(e);
	} else if (method === "session.unsubscribe") {
		const gone = new Set((params.events as string[]) ?? []);
		b.ledger.subscriptions = b.ledger.subscriptions.filter((x) => !gone.has(x));
	} else if (
		method === "network.addIntercept" &&
		ok &&
		typeof result.intercept === "string"
	) {
		b.ledger.intercepts.push(result.intercept);
	} else if (method === "network.removeIntercept") {
		const ids = new Set(
			((params.intercepts as string[]) ?? []).concat(
				(params.intercept as string[]) ?? [],
			),
		);
		b.ledger.intercepts = b.ledger.intercepts.filter((x) => !ids.has(x));
	} else if (
		method === "script.addPreloadScript" &&
		ok &&
		typeof result.id === "string"
	) {
		b.ledger.preloadScripts.push(result.id);
	} else if (
		method === "script.removePreloadScript" &&
		typeof params.id === "string"
	) {
		b.ledger.preloadScripts = b.ledger.preloadScripts.filter(
			(x) => x !== params.id,
		);
	}
}

export async function runBatchBaseline(
	ws: { send: (s: string) => void },
	b: BatchCtx,
	frames: { id: number; method: string; params?: Record<string, unknown> }[],
	byId: Map<number, BidiResponse>,
	timeoutMs: number,
): Promise<BidiResponse[]> {
	const responses: BidiResponse[] = [];
	let aborted = false;
	for (const frame of frames) {
		if (aborted) {
			responses.push({ id: frame.id, method: frame.method, skipped: true });
			continue;
		}
		let wire: unknown;
		try {
			wire = {
				id: frame.id,
				method: frame.method,
				params: interpolate(frame.params ?? {}, byId),
			};
		} catch (e) {
			responses.push({
				id: frame.id,
				method: frame.method,
				type: "error",
				error: "pi interpolation",
				message: e instanceof Error ? e.message : String(e),
			});
			aborted = true;
			continue;
		}
		const res = await new Promise<BidiResponse>((resolve) => {
			const t = setTimeout(
				() =>
					resolve({
						id: frame.id,
						type: "timeout",
						message: `no response within ${timeoutMs}ms; side effects may have applied`,
					}),
				timeoutMs,
			);
			b.pending.set(frame.id, (r) => {
				clearTimeout(t);
				resolve(r);
			});
			ws.send(JSON.stringify(wire));
		});
		ledgerUpdate(
			b,
			frame.method,
			(frame.params ?? {}) as Record<string, unknown>,
			res,
		);
		byId.set(frame.id, res);
		const out: BidiResponse = { ...res, id: frame.id, method: frame.method };
		const size = JSON.stringify(out).length;
		if (size > MAX_INLINE && res.type === "success") {
			const file = join(
				b.spoolDir,
				`${frame.method.replace(/[^\w.-]/g, "_")}-${frame.id}.json`,
			);
			await writeFile(file, JSON.stringify(out.result ?? null));
			out.result = {
				spooled: file,
				size,
				note: "full result written to file; read selectively",
			} as unknown;
		}
		responses.push(out);
	}
	return responses;
}

export function payloadBaseline(
	session: unknown,
	responses: BidiResponse[],
	events: unknown[],
	wait: unknown,
	eventCap: number,
): string {
	const payload = {
		session,
		responses,
		events,
		...(events.length === eventCap
			? { note: `event buffer capped at ${eventCap}` }
			: {}),
		...(wait ? { wait } : {}),
	};
	return JSON.stringify(payload);
}

// ── fixture ───────────────────────────────────────────────────────────────

export interface Fixture {
	ws: { send: (s: string) => void };
	ctx: BatchCtx;
	frames: { id: number; method: string; params?: Record<string, unknown> }[];
	byId: Map<number, BidiResponse>;
}

// Batch shape a real agent call produces: many small frames, a few huge
// (screenshot/print-like) results, some params with {{N.result.*}} refs.
export async function makeFixture(
	_smallKb = 2,
	bigKb = 512,
	small = 22,
	big = 3,
): Promise<Fixture> {
	const pending = new Map<number, (r: BidiResponse) => void>();
	const frames: Fixture["frames"] = [];
	const resultsById = new Map<number, unknown>();
	let id = 1;
	frames.push({
		id: id,
		method: "session.subscribe",
		params: { events: ["network"] },
	});
	resultsById.set(id, {});
	id++;
	frames.push({ id: id, method: "browsingContext.create", params: {} });
	const ctxId = `ctx-${id}-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee`;
	resultsById.set(id, { context: ctxId, userContext: "default" });
	id++;
	frames.push({
		id: id,
		method: "browsingContext.navigate",
		params: {
			context: `{{2.result.context}}`,
			url: "https://example.com/",
			wait: "complete",
		},
	});
	resultsById.set(id, { context: ctxId, url: "https://example.com/" });
	id++;
	for (let i = 0; i < small; i++) {
		frames.push({
			id: id,
			method: "script.evaluate",
			params: {
				expression: `1+${i}`,
				awaitPromise: false,
				target: { context: "{{2.result.context}}" },
			},
		});
		resultsById.set(id, { type: "number", value: i });
		id++;
	}
	for (let i = 0; i < big; i++) {
		frames.push({
			id: id,
			method: "browsingContext.captureScreenshot",
			params: { context: "{{2.result.context}}" },
		});
		resultsById.set(id, {
			data: "iVBORw0KGgoAAAANSUhEUg".padEnd(bigKb * 1024, "A"),
		});
		id++;
	}
	const ws = {
		send: (s: string) => {
			const f = JSON.parse(s);
			queueMicrotask(() =>
				pending.get(f.id)?.({
					id: f.id,
					type: "success",
					result: resultsById.get(f.id),
				}),
			);
		},
	};
	const spoolDir = await mkdtemp(join(tmpdir(), "pi-firefox-bench-"));
	return {
		ws,
		ctx: {
			pending,
			ledger: { subscriptions: [], intercepts: [], preloadScripts: [] },
			spoolDir,
		},
		frames,
		byId: new Map(),
	};
}

export async function makeSpoolCtx(): Promise<BatchCtx> {
	const dir = await mkdtemp(join(tmpdir(), "pi-firefox-bench-"));
	return {
		pending: new Map(),
		ledger: { subscriptions: [], intercepts: [], preloadScripts: [] },
		spoolDir: dir,
	};
}