perf(fast-browser): compute scoped origin policy without worker dispatch

This commit is contained in:
jb
2026-09-21 13:11:16 -04:00
parent 3c321b3033
commit c0c18a5191
2 changed files with 128 additions and 17 deletions
+29 -5
View File
@@ -449,6 +449,30 @@ export function createBrowserRuntime(
return run;
};
// Policy narrowing is a runtime concern, not a worker operation. Keep it
// on the same lane so it observes the same lifecycle and serialization
// boundaries without starting a transport or emitting JSONL.
const invokeLocal = <T>(
operation: BrowserRuntimeOperationName,
signal: AbortSignal,
action: () => T,
): Promise<T> => {
const run = lane.then(() => {
if (closed && operation !== "close") throw operationError(operation, "lifecycle", "browser_closed", "browser session is closed", "not_attempted");
if (parentSignal.aborted && operation !== "close") throw operationError(operation, "lifecycle", "browser_closed", "browser session is unavailable", "not_attempted");
// Match invoke(): a pre-aborted operation signal is rejected before
// dispatch/error shaping, while lifecycle failures remain typed.
throwIfAborted(signal);
try {
return action();
} catch (error) {
throw asOperationError(error, operation, "dispatch", false);
}
});
lane = run.catch(() => undefined);
return run;
};
const captureAfterFailure = async (operation: BrowserRuntimeOperationName, context?: RuntimeOperationContext): Promise<FailureCaptureSummary> => {
if (parentSignal.aborted) return { status: "unavailable", reason: "browser session is unavailable" };
if (operation === "captureEvidence" || operation === "close" || operation === "narrowOriginPolicy") {
@@ -500,6 +524,10 @@ export function createBrowserRuntime(
const controller = new AbortController();
const timed = timedSignal(controller.signal, OPERATION_BUDGETS.close);
try {
// Wait for local-only operations too. A narrow policy must not race
// session teardown, and waiting here still keeps an unused transport
// unstarted.
await lane;
if (transport) {
await invoke("close", { op: "close" }, timed.signal, undefined, () => undefined).catch(() => undefined);
await transport.close().catch(() => {});
@@ -612,11 +640,7 @@ export function createBrowserRuntime(
const allowedOrigins = normalizePolicy(request.allowedOrigins);
if (basePolicy !== "*" && (allowedOrigins === "*" || allowedOrigins.some((origin) => !basePolicy.includes(origin)))) throw operationError("narrowOriginPolicy", "policy", "policy_denied", "origin policy cannot be broadened", "not_attempted");
const context = { allowedOrigins };
const result = await invoke("narrowOriginPolicy", { op: "narrowOriginPolicy", request: { allowedOrigins } }, signal, { allowedOrigins: basePolicy }, (raw) => {
if (!raw || typeof raw !== "object" || !("allowedOrigins" in raw)) throw new Error("worker returned invalid origin policy");
return context;
});
return result;
return invokeLocal("narrowOriginPolicy", signal, () => context);
},
close,
};