const V = "2"; const send = (m) => self.clients.matchAll({ type: "window", includeUncontrolled: true }).then((cs) => cs.forEach((c) => c.postMessage(m))); self.addEventListener("install", (e) => { self.skipWaiting(); }); self.addEventListener("activate", (e) => { e.waitUntil(self.clients.claim().then(() => send({ type: "SW_ACTIVE", v: V, ts: Date.now() }))); }); const ORIGINS = ["openrouter.ai"]; const isTarget = (req) => { const u = new URL(req.url); return ORIGINS.some((h) => u.hostname.endsWith(h)) && req.method === "POST"; }; const wantsStream = async (req) => { try { return /"stream"\s*:\s*true/i.test(await req.clone().text()); } catch { return false; } }; self.addEventListener("fetch", (e) => { const req = e.request; const nav = req.mode === "navigate"; if (nav) return; if (!isTarget(req)) return; e.respondWith((async () => { if (!await wantsStream(req)) return fetch(req); const netRes = await fetch(req); const reader = netRes.body?.getReader(); if (!reader) return netRes; send({ type: "SW_STREAM_START", url: req.url, ts: Date.now() }); let done = false, bytes = 0, buf = [], bufBytes = 0, notify = null; const MAX = 2 * 1024 * 1024, LOW = 1 * 1024 * 1024; const pump = (async () => { for (; ; ) { const r = await reader.read(); if (r.done) { done = true; break; } const chunk = r.value; buf.push(chunk); bufBytes += chunk.byteLength || chunk.length; bytes += chunk.byteLength || chunk.length; send({ type: "SW_STREAM_BYTES", n: bytes }); if (bufBytes > MAX) await new Promise((r2) => { notify = r2; }); } })(); e.waitUntil(pump); const stream = new ReadableStream({ start(c) { const loop = async () => { for (; ; ) { if (buf.length) { const x = buf.shift(); bufBytes -= x.byteLength || x.length; c.enqueue(x); if (notify && bufBytes <= LOW) { const n = notify; notify = null; n(); } } else if (done) { c.close(); send({ type: "SW_STREAM_END", bytes }); break; } else await new Promise((r) => setTimeout(r, 30)); } }; loop(); }, cancel() { try { reader.cancel(); } catch { } } }); const h = new Headers(netRes.headers); h.delete("content-length"); return new Response(stream, { status: netRes.status, statusText: netRes.statusText, headers: h }); })()); }); self.addEventListener("message", (e) => { const m = e.data || {}; if (m && m.type === "PING") { (e.source || null)?.postMessage({ type: "PONG", v: V, ts: Date.now() }) || send({ type: "PONG", v: V, ts: Date.now() }); } });