diff --git a/frontend/src/components/UpdateBanner.tsx b/frontend/src/components/UpdateBanner.tsx index e7da185..c481d16 100644 --- a/frontend/src/components/UpdateBanner.tsx +++ b/frontend/src/components/UpdateBanner.tsx @@ -1,3 +1,4 @@ +import { useEffect } from 'react' import { useRegisterSW } from 'virtual:pwa-register/react' import { checkForUpdate, setSwRegistration } from '../lib/swUpdate' import './UpdateBanner.css' @@ -26,6 +27,21 @@ export function UpdateBanner() { }, }) + useEffect(() => { + // #58: a third trigger, alongside WS-reconnect and the hourly interval + // above -- a tab backgrounded across a deploy gets checked the moment + // someone actually looks at it again, rather than waiting on whichever + // of those two happens to land first. Cheap insurance against either + // one missing its moment (e.g. the reconnect-triggered check landing + // during the same network blip that caused the reconnect, and failing + // -- see checkForUpdate's own comment). + function handleVisibilityChange() { + if (document.visibilityState === 'visible') checkForUpdate() + } + document.addEventListener('visibilitychange', handleVisibilityChange) + return () => document.removeEventListener('visibilitychange', handleVisibilityChange) + }, []) + if (!needRefresh) return null return ( diff --git a/frontend/src/lib/swUpdate.ts b/frontend/src/lib/swUpdate.ts index 29219c4..6501fa7 100644 --- a/frontend/src/lib/swUpdate.ts +++ b/frontend/src/lib/swUpdate.ts @@ -10,5 +10,15 @@ export function setSwRegistration(reg: ServiceWorkerRegistration): void { } export function checkForUpdate(): void { - void registration?.update() + // #58: this used to be a bare `void registration?.update()` -- if the + // fetch failed (most plausible right when it's triggered by a WS + // reconnect, i.e. the network just flapped from a backend restart), the + // rejection vanished with nothing to catch it and nothing logged. The + // only other trigger was an hourly interval, so a client that hit this + // at the wrong moment could sit stale for up to an hour with zero trace + // of why. This doesn't fix a bad network, but it stops the failure from + // being silent, and callers still don't need to handle anything. + registration?.update().catch((err: unknown) => { + console.error('Service worker update check failed', err) + }) }