SERVICE_WORKER

Constant SERVICE_WORKER 

Source
pub const SERVICE_WORKER: &str = "// The service worker: the shell, so that a cold start with no network is a page rather than an\n// error.\n//\n// `docs/94` \u{a7}94.13 is why this exists. A Mode B client keeps its state in the browser and queues\n// what it cannot send, so it survives a *reconnect* \u{2014} but a **reload** with nothing listening never\n// gets that far, because the document, the scripts and the kernel all come from the server. The\n// local copy is fine and unreachable. A worker is the only thing a browser will run before the\n// network is consulted, so it is the only place that can answer.\n//\n// Network first, cache second. A live server always wins, which is what keeps a deploy from being\n// hostage to a cache: the only requests answered from the cache are the ones that *failed*.\n//\n// `%WIRE%` is substituted by the server from the program\'s content-derived wire id (\u{a7}4.3), so a\n// deployment that changes the command channel\'s types gets a new cache and the old one is deleted\n// on activate. That is the same key `beck-mode-b.js` stores its local copy under, and for the same\n// reason: two programs must not share one browser\'s idea of either.\nconst CACHE = \"beck-shell-%WIRE%\";\n\n// Everything a Mode B tab needs before it can render anything at all. The document is `/` \u{2014} and it\n// is the document for **every** route, not only that one: a Mode B client renders from the state it\n// holds and reads its route off `location`, so the shell it hydrates into is the same shell\n// whatever the address bar says (`docs/94` \u{a7}94.3). Caching one document per route would be caching\n// the same file under different names, and would still miss the route nobody had visited.\n// The bundle and the kernel are the component and its backend.\nconst SHELL = [\n  \"/\",\n  \"/beck.css\",\n  \"/beck-patch.js\",\n  \"/beck-mode-b.js\",\n  \"/beck-bundle.bpk\",\n  \"/beck-kernel.wasm\",\n];\n\nself.addEventListener(\"install\", (event) => {\n  // `skipWaiting` so a tab that reloads onto a new deployment gets the new worker rather than the\n  // one the previous page installed. The cache name changed with the wire id, so there is nothing\n  // of the old program left to serve.\n  event.waitUntil(\n    caches.open(CACHE).then((c) => c.addAll(SHELL)).then(() => self.skipWaiting()),\n  );\n});\n\nself.addEventListener(\"activate\", (event) => {\n  event.waitUntil(\n    caches\n      .keys()\n      .then((names) =>\n        Promise.all(\n          names.filter((n) => n.startsWith(\"beck-shell-\") && n !== CACHE).map((n) => caches.delete(n)),\n        ),\n      )\n      .then(() => self.clients.claim()),\n  );\n});\n\nself.addEventListener(\"fetch\", (event) => {\n  const url = new URL(event.request.url);\n  // Only this origin, only GETs, and never the socket: a command must reach the server or be\n  // queued by the client, and a cached answer to one would be a lie about the log.\n  if (url.origin !== self.location.origin) return;\n  if (event.request.method !== \"GET\") return;\n  if (url.pathname === \"/socket\") return;\n\n  event.respondWith(\n    fetch(event.request)\n      .then((response) => {\n        // Keep the shell current. A copy is taken because a Response body is read once.\n        if (response.ok && SHELL.includes(url.pathname)) {\n          const copy = response.clone();\n          caches.open(CACHE).then((c) => c.put(event.request, copy));\n        }\n        return response;\n      })\n      .catch(async () => {\n        const hit = await caches.match(event.request);\n        if (hit) return hit;\n        // A route this tab has never asked for while offline. The shell answers for it, because in\n        // Mode B the route is the *client\'s* to render \u{2014} it reads `location` and renders from the\n        // state it holds \u{2014} so one cached document serves every route. Without this, a tab that had\n        // navigated and then reloaded with no network got an error page for a route it could have\n        // rendered (`docs/94` \u{a7}94.3).\n        if (event.request.mode === \"navigate\") {\n          const shell = await caches.match(\"/\", { ignoreSearch: true });\n          if (shell) return shell;\n        }\n        // Nothing cached at all: say so as a page rather than as a browser error, because \"the\n        // server is unreachable and this tab has never been here before\" is a different thing from\n        // \"this site is broken\".\n        return new Response(\"this application has not been loaded on this device before\", {\n          status: 503,\n          headers: { \"content-type\": \"text/plain\" },\n        });\n      }),\n  );\n});\n";
Expand description

Mode B’s service worker: the shell, cached, so a cold start with no network is a page.

Served with the program’s wire id substituted for %WIRE%, which is what keys the cache to the program and what deletes the previous one on a deploy.