const originalFetch = globalThis.fetch; globalThis.fetch = async (input, init) => { const url = input instanceof Request ? input.url : input.toString(); self.postMessage({ type: "LOG", message: `FETCH: ${url}` }); if (url.includes("webp.wasm")) { self.postMessage({ type: "LOG", message: `INTERCEPTED → /workers/webp.wasm`, }); const res = await originalFetch("/workers/webp.wasm", init); self.postMessage({ type: "LOG", message: `WASM response status: ${res.status}`, }); return res; } return originalFetch(input, init); }; // Intercept XMLHttpRequest (Emscripten uses this in Workers) if (typeof XMLHttpRequest !== "undefined") { const originalOpen = XMLHttpRequest.prototype.open; // @ts-ignore XMLHttpRequest.prototype.open = function ( method: string, url: string | URL, ...rest: any[] ) { if (typeof url === "string" && url.includes("webp.wasm")) { url = "/workers/webp.wasm"; } return originalOpen.apply(this, [method, url, ...rest] as any); }; } self.onmessage = async (e: MessageEvent) => { const { type, filesData, mainLccName, fileName } = e.data; if (type === "START_CONVERSION") { try { self.postMessage({ type: "LOG", message: "Initialisiere..." }); // Fetch the WASM binary ourselves and inject it const wasmResponse = await fetch("/workers/webp.wasm"); const wasmBinary = await wasmResponse.arrayBuffer(); // Inject before the module loads // @ts-ignore globalThis.Module = { wasmBinary }; const { readFile, writeFile, MemoryReadFileSystem, MemoryFileSystem, getInputFormat, getOutputFormat, } = await import("@playcanvas/splat-transform"); const readFs = new MemoryReadFileSystem(); self.postMessage({ type: "LOG", message: "Lade Dateien in den virtuellen Speicher...", }); for (const file of filesData) { readFs.set(file.name, new Uint8Array(file.buffer)); } const fullOptions = { iterations: 0, lodSelect: [0], unbundled: false, lodChunkCount: 0, lodChunkExtent: 0, }; self.postMessage({ type: "LOG", message: "Lese LCC und Binärdaten..." }); const tables = await readFile({ filename: mainLccName, fileSystem: readFs, inputFormat: getInputFormat(mainLccName), params: [], options: fullOptions, }); const mainTable = tables[0]; if (!mainTable) throw new Error("Keine Splat-Daten gefunden."); self.postMessage({ type: "LOG", message: "Kompiliere SOG..." }); const writeFs = new MemoryFileSystem(); const outputName = `${fileName}.sog`; await writeFile( { filename: outputName, outputFormat: getOutputFormat(outputName, fullOptions), dataTable: mainTable, options: { ...fullOptions, iterations: 8 }, }, writeFs, ); const sogData = writeFs.results.get(outputName); if (!sogData) throw new Error("SOG-Erstellung fehlgeschlagen."); self.postMessage({ type: "DONE", data: { sog: new Blob([new Uint8Array(sogData).slice().buffer], { type: "application/octet-stream", }), fileName, }, }); } catch (err: any) { self.postMessage({ type: "LOG", message: `Fehler: ${err.message}` }); console.error(err); } } };