in fusion-plugin-service-worker/src/handlers.js [12:112]
export default function getHandlers(assetInfo: AssetInfo) {
const {
precachePaths,
cacheableResourcePaths,
cacheableRoutePatternStrings,
cacheBustingPatternStrings,
cacheDuration = defaultMaxCacheDuration,
} = assetInfo;
const cacheableRoutePatterns = mapToRegex(cacheableRoutePatternStrings);
const cacheBustingPatterns = mapToRegex(cacheBustingPatternStrings);
return {
onInstall: (event: InstallEvent) => {
self.skipWaiting();
event.waitUntil(
// remove old caches, then precache
caches.delete(cacheName).then(() =>
caches
.open(cacheName)
.then(cache => {
return cache.addAll(precachePaths);
})
.catch(e => {
// Don't throw an error because we expect CORS (CDN) requests to not be precacheable
// (`addAll` expects a 200 response, but CORS returns an opaque response)
// CORS resources will be lazily cached on first fetch instead
debug.log(`[sw debug] unable to pre-cache some resources: ${e}`);
})
)
);
},
onActivate: (event: InstallEvent) => {
// let all existing clients claim this new worker instance
event.waitUntil(clients.claim());
self.clients.matchAll().then(all =>
all.map(client =>
client.postMessage({
type: 'upgrade-available',
text: '*** from sw: reload for updates',
})
)
);
},
onFetch: (event: FetchEvent) => {
try {
const expectsHtml = requestExpectsHtml(event.request);
if (shouldInvalidateCache(event, cacheBustingPatterns)) {
// clear cache then bypass service worker, use network
return caches
.delete(cacheName)
.then(() =>
debug.log(
`[debug] navigation to ${event.request.url}, invalidated cache`
)
);
}
if (
!requestIsCacheable(
expectsHtml,
cacheableResourcePaths,
cacheableRoutePatterns,
event
)
) {
// bypass service worker, use network
return;
}
const p = caches.match(event.request).then(cachedResponse => {
if (cachedResponse) {
if (expectsHtml) {
if (cacheHasExpired(cachedResponse, cacheDuration)) {
// if html cache has expired, clear all caches and refetch
return caches
.delete(cacheName)
.then(() =>
self.clients.matchAll().then(all =>
all.map(client =>
client.postMessage({
type: 'cache-expired',
text: '*** from sw: cache expired',
})
)
)
)
.then(() => fetchAndCache(event.request, expectsHtml));
}
}
fetchAndCache(event.request, expectsHtml); // async update cache for next time
return cachedResponse; // return cache now
}
return fetchAndCache(event.request, expectsHtml); // fetch, then cache and return
});
event.respondWith(p);
event.waitUntil(p);
} catch (e) {
caches
.delete(cacheName)
.then(() => debug.log(`*** sw fetch failed with`, e));
}
},
};
}