fix(offline): gate SW precache on controller, not just registration

`navigator.serviceWorker.ready` resolves only when a SW is registered
and active. In `vite dev` no SW exists, so awaiting `ready` hangs the
sync forever. Gate on `navigator.serviceWorker.controller` first to
short-circuit cleanly when nothing controls the page.

Bump 1.57.7 -> 1.57.8.
This commit is contained in:
2026-05-02 15:55:12 +02:00
parent 4ed0251bb4
commit 6875e8762e
2 changed files with 13 additions and 7 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "homepage", "name": "homepage",
"version": "1.57.7", "version": "1.57.8",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
+12 -6
View File
@@ -129,8 +129,10 @@ export async function downloadAllRecipes(
} }
async function precacheMainPages(_fetchFn: typeof fetch): Promise<void> { async function precacheMainPages(_fetchFn: typeof fetch): Promise<void> {
// Only attempt if service worker is available // Only attempt if service worker is available and controlling the page.
if (!('serviceWorker' in navigator)) return; // `serviceWorker.ready` would hang forever in environments where no SW is
// registered (e.g. `vite dev`), so gate on `controller` first.
if (!('serviceWorker' in navigator) || !navigator.serviceWorker.controller) return;
const registration = await navigator.serviceWorker.ready; const registration = await navigator.serviceWorker.ready;
if (!registration.active) return; if (!registration.active) return;
@@ -186,8 +188,10 @@ async function precacheMainPages(_fetchFn: typeof fetch): Promise<void> {
} }
async function precacheRecipeData(recipes: BriefRecipeType[]): Promise<void> { async function precacheRecipeData(recipes: BriefRecipeType[]): Promise<void> {
// Only attempt if service worker is available // Only attempt if service worker is available and controlling the page.
if (!('serviceWorker' in navigator)) return; // `serviceWorker.ready` would hang forever in environments where no SW is
// registered (e.g. `vite dev`), so gate on `controller` first.
if (!('serviceWorker' in navigator) || !navigator.serviceWorker.controller) return;
const registration = await navigator.serviceWorker.ready; const registration = await navigator.serviceWorker.ready;
if (!registration.active) return; if (!registration.active) return;
@@ -264,8 +268,10 @@ async function precacheThumbnails(
recipes: BriefRecipeType[], recipes: BriefRecipeType[],
onProgress?: ProgressCallback onProgress?: ProgressCallback
): Promise<void> { ): Promise<void> {
// Only attempt if service worker is available // Only attempt if service worker is available and controlling the page.
if (!('serviceWorker' in navigator)) return; // `serviceWorker.ready` would hang forever in environments where no SW is
// registered (e.g. `vite dev`), so gate on `controller` first.
if (!('serviceWorker' in navigator) || !navigator.serviceWorker.controller) return;
const registration = await navigator.serviceWorker.ready; const registration = await navigator.serviceWorker.ready;
if (!registration.active) return; if (!registration.active) return;