siegel
Version:
Web application development ecosystem
75 lines (56 loc) • 1.97 kB
text/typescript
/// <reference lib="WebWorker" />
declare const buildOutput: string[]
// declare const globalThis: ServiceWorkerGlobalScope
declare const skipWaiting: ServiceWorkerGlobalScope['skipWaiting']
declare const clients: Clients
// declare const addEventListener: ServiceWorkerGlobalScope['addEventListener']
type AddEvent = ServiceWorkerGlobalScope['addEventListener']
const assetsSet: Set<string> = new Set()
// generated by serviceworker-webpack-plugin
buildOutput.forEach(asset => {
assetsSet.add(`${origin}/${asset}`)
})
const cacheURLRegExp = /^http.*\.(woff2|png|jpg|ico|css|js|json)/
const cacheMethod = 'GET'
const isCachable = (req: Request) => {
const { url, method } = req
return method == cacheMethod && cacheURLRegExp.test(url)
}
async function processRequest(req: Request) {
const cachedResp = await caches.match(req)
if (cachedResp) return cachedResp
else try {
const res = await fetch(req)
if (res.ok) {
const clonedRes = res.clone()
caches.open(req.url)
.then(cache => cache.put(req, clonedRes))
return res
}
} catch (e) { console.error(e) }
}
(addEventListener as AddEvent)('fetch', e => {
const req = e.request
// @ts-ignore
isCachable(req) && e.respondWith( processRequest(req) )
})
;(addEventListener as AddEvent)('activate', e => {
async function preCache() {
const cachesKeys = await caches.keys()
cachesKeys.forEach(cacheName => {
assetsSet.has(cacheName) || caches.delete(cacheName)
})
const cachesKeysSet = new Set(cachesKeys)
assetsSet.forEach(async asset => {
if (!cachesKeysSet.has(asset)) {
const cache = await caches.open(asset)
cache.add(asset)
}
})
}
e.waitUntil(preCache())
e.waitUntil(clients.claim())
})
;(addEventListener as AddEvent)('install', () => {
skipWaiting()
})