From 6f6c77c7d2ea6de092fec97e8cd0d3c3d9dbdd39 Mon Sep 17 00:00:00 2001 From: Cory Dransfeldt Date: Mon, 12 May 2025 15:48:49 -0700 Subject: [PATCH] chore(sw.js): add lightweight service worker --- package-lock.json | 4 +- package.json | 2 +- src/assets/scripts/index.js | 3 + src/assets/scripts/sw.js | 57 +++++++++++++++++++ .../{opml.liquid => blogroll.opml.liquid} | 0 src/feeds/manifest.json.liquid | 21 +++++++ 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 src/assets/scripts/sw.js rename src/feeds/{opml.liquid => blogroll.opml.liquid} (100%) create mode 100644 src/feeds/manifest.json.liquid diff --git a/package-lock.json b/package-lock.json index 79dcd7e..a67b08e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "coryd.dev", - "version": "4.0.6", + "version": "4.1.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "coryd.dev", - "version": "4.0.6", + "version": "4.1.6", "license": "MIT", "dependencies": { "html-minifier-terser": "7.2.0", diff --git a/package.json b/package.json index b711843..21f4269 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "coryd.dev", - "version": "4.0.6", + "version": "4.1.6", "description": "The source for my personal site. Built using 11ty (and other tools).", "type": "module", "engines": { diff --git a/src/assets/scripts/index.js b/src/assets/scripts/index.js index 89054ba..356aa65 100644 --- a/src/assets/scripts/index.js +++ b/src/assets/scripts/index.js @@ -1,4 +1,7 @@ window.addEventListener("load", () => { + // service worker + if ('serviceWorker' in navigator) navigator.serviceWorker.register('/assets/scripts/sw.js'); + // dialog controls (() => { const dialogButtons = document.querySelectorAll(".dialog-open"); diff --git a/src/assets/scripts/sw.js b/src/assets/scripts/sw.js new file mode 100644 index 0000000..e64c3f7 --- /dev/null +++ b/src/assets/scripts/sw.js @@ -0,0 +1,57 @@ +const cacheName = 'coryd.dev-static-assets'; +const staticAssets = [ + '/assets/styles/index.css', + '/assets/styles/noscript.css', + '/assets/fonts/sg.woff2', + '/assets/fonts/dm.woff2', + '/assets/fonts/dmi.woff2', + '/assets/fonts/ml.woff2', + '/assets/scripts/index.js', +]; + +self.addEventListener('install', event => { + event.waitUntil( + caches.open(cacheName) + .then(cache => cache.addAll(staticAssets)) + .then(() => self.skipWaiting()) + ); +}); + +self.addEventListener('activate', event => { + event.waitUntil( + (async () => { + const keys = await caches.keys(); + await Promise.all( + keys.filter(key => key !== cacheName).map(key => caches.delete(key)) + ); + + if (self.registration.navigationPreload) await self.registration.navigationPreload.enable(); + + await self.clients.claim(); + })() + ); +}); + +self.addEventListener('fetch', event => { + const request = event.request; + + if (request.method !== 'GET') return; + if (request.headers.get('Accept').includes('text/html')) { + event.respondWith( + (async () => { + try { + const preloadResponse = await event.preloadResponse; + if (preloadResponse) return preloadResponse; + + return await fetch(request); + } catch (err) { + return Response.error(); + } + })() + ); + return; + } + + event.respondWith(caches.match(request).then(response => response || fetch(request)) + ); +}); diff --git a/src/feeds/opml.liquid b/src/feeds/blogroll.opml.liquid similarity index 100% rename from src/feeds/opml.liquid rename to src/feeds/blogroll.opml.liquid diff --git a/src/feeds/manifest.json.liquid b/src/feeds/manifest.json.liquid new file mode 100644 index 0000000..b6623d7 --- /dev/null +++ b/src/feeds/manifest.json.liquid @@ -0,0 +1,21 @@ +--- +permalink: "/manifest.json" +layout: null +eleventyExcludeFromCollections: true +excludeFromSitemap: true +--- +{ + "lang": "{{ globals.lang }}", + "name": "{{ globals.site_name }}", + "description": "{{ globals.site_description }}", + "background_color": "#f9fafb", + "theme_color": "#f9fafb" + "display": "minimal-ui", + "dir": "ltr", + "icons": [ + { "src": "{{ globals.url }}/og/w200/{% appVersion %}{{ globals.avatar }}", "type": "image/png", "sizes": "192x192" }, + { "src": "{{ globals.url }}/og/w800/{% appVersion %}{{ globals.avatar }}", "type": "image/png", "sizes": "512x512" }, + { "src": "{{ globals.url }}/og/w800/{% appVersion %}{{ globals.avatar }}", "type": "image/png", "sizes": "512x512", "purpose": "maskable" } + ], + "start_url": "/", +}