generated at
ServiceWorker
web browserのネットワーク通信の間に割り込んでいろんなことが出来るDOM API
demoはこっちに移動された
WebWorkerの一種でもある

proxyっぽく間に挟まる感じ
何でも出来てしまうが、基本的にはネットワークから取得したデータをcacheする用途がメイン
あとはoffline対応


ServiceWorker.register()で、Service Workerをブラウザに登録・起動してもらう
registerServiceWorker.ts
/// <reference no-default-lib="true" /> /// <reference lib="esnext" /> /// <reference lib="dom" /> await (async () => {   if (!("serviceWorker" in navigator)) return;      try {     const registration = await navigator.serviceWorker.register(       "sw.js",       { scope: "/" } ,     );     if (registration.installing) {       console.log("Service worker installing");     } else if (registration.waiting) {       console.log("Service worker installed");     } else if (registration.active) {       console.log("Service worker active");     }   } catch (error: unknown) {     console.error(`Registration failed with ${error}`);   } })();

sw.ts
/// <reference no-default-lib="true" /> /// <reference lib="esnext" /> /// <reference types="https://cdn.jsdelivr.net/npm/@types/serviceworker@0.0.57/index.d.ts" /> const cache = await globalThis.caches.open("v1");

workerのintall process
ExtendableEvent.waitUntil()内で作業することで、作業が終わるまでworkerのinstallをpendingできる
sw.ts
globalThis.addEventListener("install", (event) => {   event.waitUntil(     cache.addAll([       '/index.html',       '/style.css',       '/app.js',       '/image-list.js',       '/star-wars-logo.jpg',       '/gallery/bountyHunters.jpg',       '/gallery/myLittleVader.jpg',       '/gallery/snowTroopers.jpg',     ]),  ); });
sw.ts
globalThis.addEventListener("activate", (event) => {   event.waitUntil(    globalThis.registration.navigationPreload?.enable?.()   ); });
sw.ts
globalThis.addEventListener("fetch", (event) => {   event.respondWith(     (async () => {   // First try to get the resource from the cache      const request = event.request;   const responseFromCache = await cache.match(request);   if (responseFromCache) return responseFromCache;   // Next try to use the preloaded response, if it's there      const preloadResponse = await event.preloadResponse;   if (preloadResponse) {     console.info("using preload response", preloadResponse);     await cache.put(request, preloadResponse.clone());     return preloadResponse;   }   // Next try to get the resource from the network   try {     const responseFromNetwork = await fetch(request);          // response may be used only once     // we need to save clone to put one copy in cache     // and serve second one     await cache.put(request, responseFromNetwork.clone());     return responseFromNetwork;   } catch (error: unknown) {    const fallbackUrl = "/gallery/myLittleVader.jpg";     const fallbackResponse = await caches.match(fallbackUrl);     if (fallbackResponse) return fallbackResponse;          // when even the fallback response is not available,     // there is nothing we can do, but we must always     // return a Response object     return new Response("Network error happened", {       status: 408,       headers: { "Content-Type": "text/plain" },     });   } })()   ); });

#2023-04-13 20:17:08
#2022-12-03 19:54:24
#2021-10-31 22:18:29