1e9b7a8aa2
* remove cross-env * append build hash to service worker cache names for easy purge
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import type { AssetsManifest } from "@remix-run/react/entry";
|
|
|
|
declare const ASSET_CACHE: string;
|
|
declare const self: ServiceWorkerGlobalScope;
|
|
|
|
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;
|
|
const routes = [...Object.values(manifest.routes), manifest.entry];
|
|
const assetsToCache: string[] = [];
|
|
for (const route of routes) {
|
|
assetsToCache.push(route.module);
|
|
|
|
if (route.imports) {
|
|
assetsToCache.push(...route.imports);
|
|
}
|
|
}
|
|
|
|
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)));
|
|
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
|
|
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)));
|
|
}
|