import type { Worker } from '@playwright/test'; export async function installNativeComputeCapture(worker: Worker) { await worker.evaluate(() => { const root = self as any, calls: any[] = []; root.__wbv2NativeComputeCapture = calls; for(const transport of ['Worker','MessagePort']){const proto = (globalThis as any)[transport].prototype, original = proto.postMessage; proto.postMessage = function(this: any, envelope: any, ...rest: any[]) { const message = envelope?.request ?? envelope; if(message?.job && message.control instanceof SharedArrayBuffer && message.data instanceof SharedArrayBuffer){calls.push({ transport, job: structuredClone(message.job), sizes: [...message.sizes], data: message.data.byteLength <= 2097152 ? Array.from(new Uint8Array(message.data)) : null, control: message.control, error: message.error });}else if(Array.isArray(message?.releaseOwners))calls.push({ transport, releaseOwners: [...message.releaseOwners] }); if(calls.length > 64){calls.shift(); root.__wbv2CaptureTruncated = true;} return Reflect.apply(original, this, [envelope, ...rest]); }; } }); } export async function readNativeComputeCapture(worker: Worker) { return worker.evaluate(() => { if((self as any).__wbv2CaptureTruncated)throw new Error('Native compute capture budget exceeded'); return ((self as any).__wbv2NativeComputeCapture ?? []).map(({ control, error, ...snapshot }: any) => { if(!control)return snapshot; const flags = new Int32Array(control), bytes = new Uint8Array(error), length = Math.min(bytes.length, Math.max(0, Atomics.load(flags, 1))); return { ...snapshot, state: Atomics.load(flags, 0), diagnostic: new TextDecoder().decode(bytes.slice(0, length)) }; }); }); }