mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
fix(pwa): keep the new worker's precache when loading a new version
The reload cleared every HealthLog cache after asking the worker to update, but the update resolves as soon as the new worker starts installing. Its fresh precache of logos and favicon was deleted with the old ones, so the installed app lacked them offline. Leave the target release's caches in place.
This commit is contained in:
1 parent
58592e4822
commit
ad620bcf80
2 files changed
+51
-4
No files matched your search
@@ -15,7 +15,7 @@
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { resolveVersionPollDecision } from "../version-poller";
|
||||
import { cachesToEvict, resolveVersionPollDecision } from "../version-poller";
|
||||
|
||||
describe("resolveVersionPollDecision", () => {
|
||||
it("is up-to-date when live matches the shell", () => {
|
||||
@@ -144,3 +144,31 @@ describe("evictAndReload", () => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("cachesToEvict", () => {
|
||||
const keys = [
|
||||
"healthlog-static-v1.41.2",
|
||||
"healthlog-pages-v1.41.2",
|
||||
"healthlog-data-v1.41.2",
|
||||
"healthlog-static-v1.42.0",
|
||||
"another-app-cache",
|
||||
];
|
||||
|
||||
it("keeps the target release's caches the new worker just filled", () => {
|
||||
expect(cachesToEvict(keys, "1.42.0")).toEqual([
|
||||
"healthlog-static-v1.41.2",
|
||||
"healthlog-pages-v1.41.2",
|
||||
"healthlog-data-v1.41.2",
|
||||
]);
|
||||
});
|
||||
|
||||
it("reads the target with or without its v", () => {
|
||||
expect(cachesToEvict(keys, "v1.42.0")).not.toContain(
|
||||
"healthlog-static-v1.42.0",
|
||||
);
|
||||
});
|
||||
|
||||
it("never touches another app's caches", () => {
|
||||
expect(cachesToEvict(keys, "1.43.0")).not.toContain("another-app-cache");
|
||||
});
|
||||
});
|
||||
@@ -101,6 +101,27 @@ async function fetchLiveVersion(signal: AbortSignal): Promise<string | null> {
|
||||
// to break the loop within one document lifetime.
|
||||
let inMemoryReloadGuard: string | null = null;
|
||||
|
||||
/**
|
||||
* The worker caches the "new version" reload clears: every HealthLog cache
|
||||
* except the target release's own. `registration.update()` resolves as soon
|
||||
* as the new worker starts installing, so its freshly precached logos and
|
||||
* favicon (`healthlog-static-v<target>`) may already exist by then; deleting
|
||||
* them left the installed app without them offline until they were fetched
|
||||
* again. Cache names carry the version with a `v`, the version endpoint may
|
||||
* answer without one.
|
||||
*/
|
||||
export function cachesToEvict(
|
||||
keys: readonly string[],
|
||||
targetVersion: string,
|
||||
): string[] {
|
||||
const target = targetVersion.replace(/^v/, "");
|
||||
return keys.filter((key) => {
|
||||
if (!HEALTHLOG_CACHE_NAME_RE.test(key)) return false;
|
||||
const version = key.replace(HEALTHLOG_CACHE_NAME_RE, "").replace(/^v/, "");
|
||||
return version !== target;
|
||||
});
|
||||
}
|
||||
|
||||
export async function evictAndReload(targetVersion: string): Promise<void> {
|
||||
inMemoryReloadGuard = targetVersion;
|
||||
try {
|
||||
@@ -123,9 +144,7 @@ export async function evictAndReload(targetVersion: string): Promise<void> {
|
||||
try {
|
||||
const keys = await caches.keys();
|
||||
await Promise.all(
|
||||
keys
|
||||
.filter((k) => HEALTHLOG_CACHE_NAME_RE.test(k))
|
||||
.map((k) => caches.delete(k)),
|
||||
cachesToEvict(keys, targetVersion).map((k) => caches.delete(k)),
|
||||
);
|
||||
} catch {
|
||||
/* best effort */
|
||||
|
||||
Reference in new issue
Block a user