···11+import { DiffuseElement } from "~/common/element.js";
22+33+////////////////////////////////////////////
44+// ELEMENT
55+////////////////////////////////////////////
66+77+/**
88+ * Registers a service worker that makes the page available offline.
99+ *
1010+ * All resources fetched by the page are cached as they load.
1111+ * While online, requests always go to the network (the cache is bypassed),
1212+ * and successful responses are stored for later. While offline, the cache
1313+ * is used as a fallback.
1414+ *
1515+ * Attributes:
1616+ * cache-name Name of the cache to use (default: "diffuse-offline")
1717+ * scope Service worker scope (default: document.baseURI ?? "./")
1818+ * src URL of the service worker script (default: built-in service-worker.js)
1919+ * Must be served from a path within the requested scope, or the server
2020+ * must include a `Service-Worker-Allowed: /` response header.
2121+ */
2222+class OfflineOrchestrator extends DiffuseElement {
2323+ static NAME = "diffuse/orchestrator/offline";
2424+2525+ // LIFECYCLE
2626+2727+ /** @override */
2828+ async connectedCallback() {
2929+ super.connectedCallback();
3030+3131+ if (!("serviceWorker" in navigator)) return;
3232+3333+ const cacheName = this.getAttribute("cache-name") ?? "diffuse-offline";
3434+ const scope = this.getAttribute("scope") ?? document.baseURI ?? "./";
3535+ const src = this.getAttribute("src");
3636+3737+ const swUrl = new URL(
3838+ src ?? import.meta.resolve("../../../service-worker-offline.js"),
3939+ );
4040+4141+ swUrl.searchParams.set("cache-name", cacheName);
4242+4343+ try {
4444+ await navigator.serviceWorker.register(swUrl.href, {
4545+ type: "module",
4646+ scope,
4747+ });
4848+ } catch (error) {
4949+ console.warn("[do-offline] Failed to register service worker:", error);
5050+ }
5151+ }
5252+}
5353+5454+export default OfflineOrchestrator;
5555+5656+////////////////////////////////////////////
5757+// REGISTER
5858+////////////////////////////////////////////
5959+6060+export const CLASS = OfflineOrchestrator;
6161+export const NAME = "do-offline";
6262+6363+customElements.define(NAME, OfflineOrchestrator);