Files
rea/src/browser/WebBundleAnalysisWorkerCapacity.test.ts
T
morluto 9aca543f46 fix(browser): isolate web bundle analysis with bounded partial results
Run inert captured-script analysis in owned children with per-script and aggregate deadlines, bounded source/result transfer and explicit per-script coverage. Preserve completed facts and exact cleanup authority across cancellation, mixed descriptor/process failures and cross-consumer retry.

Share aggregate source admission across page and Electron capture, expose CLI/MCP resource controls and retain selected parameters in Evidence. Verified with controlled CDP public workflows, real owned Node failure controls and the reporter-matching ReactDOM UMD artifact; real Chrome/Electron and Windows/Bun remain unqualified.
2026-10-19 13:22:54 +08:00

83 lines
2.6 KiB
TypeScript

import { createHash } from "node:crypto";
import { expect, it, vi } from "vitest";
const heapLimit = vi.hoisted(() => ({ override: null as number | null }));
vi.mock("node:v8", async (importOriginal) => {
const actual = await importOriginal<typeof import("node:v8")>();
return {
...actual,
getHeapStatistics: () => {
const statistics = actual.getHeapStatistics();
return heapLimit.override === null
? statistics
: { ...statistics, heap_size_limit: heapLimit.override };
},
};
});
import { AnalysisResourceConstraintError } from "../domain/analysisErrorCore.js";
import { createWebTextArtifact } from "../domain/webContentArtifact.js";
import type { IncludedScript } from "../domain/webBundleAnalyzerInspection.js";
import { WebBundleAnalysisWorker } from "./WebBundleAnalysisWorker.js";
it("refuses before spawning or reading source when no host result capacity remains", async () => {
const text = "fetch('/never-serialized');";
const base = makeScript(text);
let sourceReads = 0;
let launches = 0;
const artifact = { ...base.source.artifact };
Object.defineProperty(artifact, "text", {
configurable: true,
get: () => {
sourceReads += 1;
return text;
},
});
const script: IncludedScript = {
...base,
source: { included: true, artifact },
};
const worker = new WebBundleAnalysisWorker(1024, async () => {
launches += 1;
throw new Error(
"The worker must not launch when the host has no result capacity",
);
});
heapLimit.override = 0;
try {
const result = await worker.analyze(script, 10_000);
expect(result.ok).toBe(false);
if (result.ok) throw new Error("Expected result-capacity refusal");
expect(result.error.error).toBeInstanceOf(AnalysisResourceConstraintError);
expect(result.error.continuation).toBe("result_capacity_exhausted");
expect(result.error.completed).toBeNull();
expect(sourceReads).toBe(0);
expect(launches).toBe(0);
} finally {
heapLimit.override = null;
await worker.close();
}
});
const makeScript = (text: string): IncludedScript => ({
script_key: `scr_${createHash("sha256").update(text).digest("hex")}`,
frame_id: "frame-1",
url: "https://app.example.test/app.js",
origin: "https://app.example.test",
cdp_hash: null,
length: Buffer.byteLength(text),
is_module: false,
language: "JavaScript",
source_map_url: null,
resource_reconciliation: {
status: "unmatched",
reason: "no_exact_sanitized_url",
},
source: {
included: true,
artifact: createWebTextArtifact(text, "application/javascript"),
},
});