shellphone.app/app/service-worker/message.ts

60 lines
1.9 KiB
TypeScript
Raw Normal View History

2022-06-05 22:01:33 +00:00
import type { AssetsManifest } from "@remix-run/react/entry";
declare const ASSET_CACHE: string;
declare const self: ServiceWorkerGlobalScope;
2022-06-05 22:01:33 +00:00
export default async function handleMessage(event: ExtendableMessageEvent) {
if (event.data.type === "SYNC_REMIX_MANIFEST") {
return handleSyncRemixManifest(event);
}
}
async function handleSyncRemixManifest(event: ExtendableMessageEvent) {
console.debug("Caching routes modules");
const manifest: AssetsManifest = event.data.manifest;
2022-06-05 22:01:33 +00:00
const routes = [...Object.values(manifest.routes), manifest.entry];
const assetsToCache: string[] = [];
2022-06-05 22:01:33 +00:00
for (const route of routes) {
assetsToCache.push(route.module);
2022-06-05 22:01:33 +00:00
if (route.imports) {
assetsToCache.push(...route.imports);
2022-06-05 22:01:33 +00:00
}
}
await purgeStaticAssets(assetsToCache);
await cacheStaticAssets(assetsToCache);
}
async function cacheStaticAssets(assetsToCache: string[]) {
const cachePromises: Map<string, Promise<void>> = new Map();
const assetCache = await caches.open(ASSET_CACHE);
assetsToCache.forEach((assetUrl) => cachePromises.set(assetUrl, cacheAsset(assetUrl)));
2022-06-05 22:01:33 +00:00
await Promise.all(cachePromises.values());
async function cacheAsset(assetUrl: string) {
if (await assetCache.match(assetUrl)) {
// no need to update the asset, it has a unique hash in its name
2022-06-05 22:01:33 +00:00
return;
}
console.debug("Caching asset", assetUrl);
return assetCache.add(assetUrl).catch((error) => {
console.debug(`Failed to cache asset ${assetUrl}:`, error);
});
}
}
async function purgeStaticAssets(assetsToCache: string[]) {
const assetCache = await caches.open(ASSET_CACHE);
const cachedAssets = await assetCache.keys();
const cachesToDelete = cachedAssets.filter((asset) => !assetsToCache.includes(new URL(asset.url).pathname));
console.log(
"cachesToDelete",
cachesToDelete.map((c) => new URL(c.url).pathname),
);
await Promise.all(cachesToDelete.map((asset) => assetCache.delete(asset)));
}