diff --git a/dev.ts b/dev.ts index 9124c79..20efcb8 100644 --- a/dev.ts +++ b/dev.ts @@ -11,14 +11,14 @@ await dev(import.meta.url, './main.ts', { server: { cert: await Deno.readTextFile('./cert/cohabit.localhost.pem'), key: await Deno.readTextFile('./cert/cohabit.localhost-key.pem'), - hostname, - onListen: (({ port }) => { - console.log( - `\n\t%c Server started %c %chttps://${hostname}:${port}\n`, - 'font-weight: bold; background-color: blue', - '', - 'color: blue; text-decoration: underline' - ) - }) + hostname, + onListen: (({ port }) => { + console.log( + `\n\t%c Server started %c %chttps://${hostname}:${port}\n`, + 'font-weight: bold; background-color: blue', + '', + 'color: blue; text-decoration: underline', + ) + }), }, }) diff --git a/islands/RegisterServiceWorker.tsx b/islands/RegisterServiceWorker.tsx index b9a6026..c4b237c 100644 --- a/islands/RegisterServiceWorker.tsx +++ b/islands/RegisterServiceWorker.tsx @@ -2,7 +2,7 @@ import { requestApi } from ':src/utils.ts' export default function RegisterServiceWorker() { if ('serviceWorker' in navigator) { - import('./StartServiceWorker.tsx').then(async (mod) => { + import(':islands/StartServiceWorker.tsx').then(async (mod) => { const href = mod.default() const registration = await navigator.serviceWorker.register(href, { scope: '/', diff --git a/islands/StartServiceWorker.tsx b/islands/StartServiceWorker.tsx index ffcf7c2..764f88f 100644 --- a/islands/StartServiceWorker.tsx +++ b/islands/StartServiceWorker.tsx @@ -4,7 +4,7 @@ const IS_SW = 'onpushsubscriptionchange' in self export default function StartServiceWorker() { if (IS_SW) { - main() + main(location.origin) } return new URL(import.meta.url).pathname } diff --git a/routes/api/serviceworker/precache.tsx b/routes/api/serviceworker/precache.tsx new file mode 100644 index 0000000..5eb2927 --- /dev/null +++ b/routes/api/serviceworker/precache.tsx @@ -0,0 +1,54 @@ +import { SessionHandlers } from ':src/session/mod.ts' +import { respondApi } from ':src/utils.ts' +import { expandGlob } from '$std/fs/mod.ts' + +export type PrecacheResponse = { version: string; files: string[] } + +// Updated only at server start +const version = crypto.randomUUID() + +export const handler: SessionHandlers = { + async GET() { + try { + const files: string[] = ['/', '/imports/markdown_css'] + const paths = ['/static/**', '/_fresh/static/**'] + const routes = '/routes/*' + + //Pre-cache routes + for await (const route of expandGlob(routes, { root: '.' })) { + if (!route.isDirectory) continue + if (route.name === 'api') continue + if (route.name === 'imports') continue + + files.push(strip(routes, route)) + } + + // Pre-cache files + for (const path of paths) { + for await (const entry of expandGlob(path, { root: '.' })) { + if (entry.isFile) { + files.push(strip(path, entry)) + } + } + } + + return respondApi<'success', PrecacheResponse>('success', { + version, + files, + }) + } catch (error) { + return respondApi('error', error) + } + }, +} + +function strip(root: string, { path }: { path: string }) { + return path + // Force unix/web separator + .replaceAll('\\', '/') + .replace( + // Remove root slash and glob * + root.slice(1).replaceAll('*', ''), + '/', + ) +} diff --git a/src/serviceworker/mod.ts b/src/serviceworker/mod.ts index 66837de..307b726 100644 --- a/src/serviceworker/mod.ts +++ b/src/serviceworker/mod.ts @@ -1,17 +1,21 @@ /// /// +import type { PrecacheResponse } from '../../routes/api/serviceworker/precache.tsx' + // Force load service worker types const self = globalThis as unknown as ServiceWorkerGlobalScope -const cacheName = 'v1' //TODO dynamique cache key -const _preCachedPaths = ['/', '/css/*', '/assets/*'] //TODO pre-cache these paths +export async function main(origin: string) { + const cacheConfig = await fetch( + new URL('/api/serviceworker/precache', origin), + ).then((response) => response.json() as Promise) + const cacheName = cacheConfig.version -export function main() { self.addEventListener('install', (event) => { - //TODO handle installation event.waitUntil( - addToCache([]), + //precache static files and routes index + addToCache(cacheName, cacheConfig.files) ) }) @@ -35,9 +39,8 @@ export function main() { } }) } -async function addToCache(ressources: string[]) { - const cache = await caches.open(cacheName) //TODO dynamique cache key - await cache.addAll(ressources) - //TODO list statics +async function addToCache(cacheName: string, ressources: string[]) { + const cache = await caches.open(cacheName) + await cache.addAll(ressources) }