feat(pwa): ✨ add precached files
This commit is contained in:
parent
2ded36b38b
commit
f2b39d0288
4
dev.ts
4
dev.ts
|
@ -17,8 +17,8 @@ await dev(import.meta.url, './main.ts', {
|
||||||
`\n\t%c Server started %c %chttps://${hostname}:${port}\n`,
|
`\n\t%c Server started %c %chttps://${hostname}:${port}\n`,
|
||||||
'font-weight: bold; background-color: blue',
|
'font-weight: bold; background-color: blue',
|
||||||
'',
|
'',
|
||||||
'color: blue; text-decoration: underline'
|
'color: blue; text-decoration: underline',
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { requestApi } from ':src/utils.ts'
|
||||||
|
|
||||||
export default function RegisterServiceWorker() {
|
export default function RegisterServiceWorker() {
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
import('./StartServiceWorker.tsx').then(async (mod) => {
|
import(':islands/StartServiceWorker.tsx').then(async (mod) => {
|
||||||
const href = mod.default()
|
const href = mod.default()
|
||||||
const registration = await navigator.serviceWorker.register(href, {
|
const registration = await navigator.serviceWorker.register(href, {
|
||||||
scope: '/',
|
scope: '/',
|
||||||
|
|
|
@ -4,7 +4,7 @@ const IS_SW = 'onpushsubscriptionchange' in self
|
||||||
|
|
||||||
export default function StartServiceWorker() {
|
export default function StartServiceWorker() {
|
||||||
if (IS_SW) {
|
if (IS_SW) {
|
||||||
main()
|
main(location.origin)
|
||||||
}
|
}
|
||||||
return new URL(import.meta.url).pathname
|
return new URL(import.meta.url).pathname
|
||||||
}
|
}
|
||||||
|
|
54
routes/api/serviceworker/precache.tsx
Normal file
54
routes/api/serviceworker/precache.tsx
Normal file
|
@ -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('*', ''),
|
||||||
|
'/',
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,17 +1,21 @@
|
||||||
/// <reference no-default-lib="true"/>
|
/// <reference no-default-lib="true"/>
|
||||||
/// <reference lib="webworker" />
|
/// <reference lib="webworker" />
|
||||||
|
|
||||||
|
import type { PrecacheResponse } from '../../routes/api/serviceworker/precache.tsx'
|
||||||
|
|
||||||
// Force load service worker types
|
// Force load service worker types
|
||||||
const self = globalThis as unknown as ServiceWorkerGlobalScope
|
const self = globalThis as unknown as ServiceWorkerGlobalScope
|
||||||
|
|
||||||
const cacheName = 'v1' //TODO dynamique cache key
|
export async function main(origin: string) {
|
||||||
const _preCachedPaths = ['/', '/css/*', '/assets/*'] //TODO pre-cache these paths
|
const cacheConfig = await fetch(
|
||||||
|
new URL('/api/serviceworker/precache', origin),
|
||||||
|
).then((response) => response.json() as Promise<PrecacheResponse>)
|
||||||
|
const cacheName = cacheConfig.version
|
||||||
|
|
||||||
export function main() {
|
|
||||||
self.addEventListener('install', (event) => {
|
self.addEventListener('install', (event) => {
|
||||||
//TODO handle installation
|
|
||||||
event.waitUntil(
|
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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue