Files
i-want-to-heal/scripts/generate-service-worker.mjs
T
2026-06-17 20:04:36 -04:00

64 lines
1.8 KiB
JavaScript

import { readdirSync, writeFileSync } from 'node:fs'
import { relative, resolve } from 'node:path'
const distDirectory = resolve('dist')
function listFiles(directory) {
return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
const path = resolve(directory, entry.name)
return entry.isDirectory() ? listFiles(path) : [path]
})
}
const assets = listFiles(distDirectory)
.map((path) => `/${relative(distDirectory, path).replaceAll('\\', '/')}`)
.filter((path) => path !== '/service-worker.js')
.sort()
const cacheName = `chronicle-${Date.now()}`
const source = `const CACHE_NAME = ${JSON.stringify(cacheName)}
const APP_ASSETS = ${JSON.stringify(assets, null, 2)}
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.addAll(APP_ASSETS))
.then(() => self.skipWaiting()),
)
})
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys()
.then((keys) => Promise.all(
keys.filter((key) => key !== CACHE_NAME).map((key) => caches.delete(key)),
))
.then(() => self.clients.claim()),
)
})
self.addEventListener('fetch', (event) => {
const requestUrl = new URL(event.request.url)
if (
event.request.method !== 'GET'
|| requestUrl.origin !== self.location.origin
|| requestUrl.pathname.startsWith('/api/')
) {
return
}
event.respondWith(
caches.match(event.request).then((cached) => {
if (cached) return cached
return fetch(event.request).catch(() => (
event.request.mode === 'navigate'
? caches.match('/index.html')
: Response.error()
))
}),
)
})
`
writeFileSync(resolve(distDirectory, 'service-worker.js'), source)
console.log(`Offline app shell generated with ${assets.length} files.`)