/ concept-collection / stan-web-ide
Sign in
concept-collection / stan-web-ide
stan-web-ide / public / coi-serviceworker.js
72 lines · 2.6 KBCodeBlameHistory
2 * Cross-Origin Isolation Service Worker
3 *
4 * Adds COOP/COEP headers to responses so that SharedArrayBuffer is available
5 * on hosts that don't allow custom response headers (e.g. GitHub Pages).
6 *
7 * Based on https://github.com/niccokunzmann/coi-serviceworker (MIT).
8 */
10/* global self, caches, fetch, Response, clients */
12if (typeof window === "undefined") {
13 // --- Service Worker scope ---
14 self.addEventListener("install", () => self.skipWaiting());
15 self.addEventListener("activate", event =>
16 event.waitUntil(self.clients.claim())
17 );
19 self.addEventListener("fetch", event => {
20 const request = event.request;
21 if (request.cache === "only-if-cached" && request.mode !== "same-origin") {
22 return; // Chrome bug workaround
23 }
25 // Only add isolation headers to same-origin responses.
26 // Wrapping cross-origin responses in a new Response strips CORS
27 // internal flags, which breaks cross-origin fetch requests.
28 if (new URL(request.url).origin !== self.location.origin) {
29 return; // let the browser handle cross-origin requests normally
30 }
32 event.respondWith(
33 fetch(request).then(response => {
34 if (response.status === 0) return response; // opaque response
36 const headers = new Headers(response.headers);
37 // must match the value the dev/preview servers send — a document and
38 // its dedicated workers with mismatched COEP values fail to load
39 headers.set("Cross-Origin-Embedder-Policy", "require-corp");
40 headers.set("Cross-Origin-Opener-Policy", "same-origin");
42 return new Response(response.body, {
43 status: response.status,
44 statusText: response.statusText,
45 headers,
46 });
47 })
48 );
49 });
50} else {
51 // --- Window scope (registration) ---
53 // Capture currentScript synchronously — it becomes null after script runs.
54 const scriptUrl = document.currentScript && document.currentScript.src;
56 if (!window.crossOriginIsolated && navigator.serviceWorker) {
57 navigator.serviceWorker.register(scriptUrl || "/coi-serviceworker.js").then(
58 reg => {
59 if (reg.installing || reg.waiting) {
60 const sw = reg.installing || reg.waiting;
61 sw.addEventListener("statechange", () => {
62 if (sw.state === "activated") window.location.reload();
63 });
64 } else if (reg.active && !navigator.serviceWorker.controller) {
65 // Active but not yet controlling — reload to let it intercept.
66 window.location.reload();
67 }
68 },
69 err => console.error("COI service worker registration failed:", err)
70 );
71 }
moveopenescclose