// Optional PWA notifications for the whole-corpus sweep — a long run can finish // or pause (e.g. on a usage limit) while the user has stepped away, so a system // notification is a welcome nudge. Strictly best-effort and a graceful no-op // everywhere it doesn't apply: // • no Notification API → no-op; // • permission not granted → no-op (firing never prompts); // • the tab is focused → no-op (don't nag someone who's watching); // • not an installed/opt-in PWA → no permission is ever requested (the // request is gated on a registered service worker, which only PWA-shipping // sites have — see export/app/lib/mode.ts shipsPwa()). function supported(): boolean { return typeof window !== "undefined" && "Notification" in window; } // Fire a sweep notification IF permission is granted and the tab is hidden (the // user has stepped away). Never prompts; never throws. export function notifySweep(title: string, body: string): void { if (!supported() || Notification.permission !== "granted") return; // Only nudge when the user isn't already looking at the tab. if (typeof document !== "undefined" && document.visibilityState === "visible") { return; } try { new Notification(title, { body }); } catch { /* some engines require notifications go through the SW registration; ignore */ } } // Ask for notification permission once, at the start of a sweep (a user gesture), // but ONLY on a PWA-shipping site — proxied by a registered service worker, which // a dumb (non-PWA) site never has. No-op if already decided or unsupported. export async function ensureSweepNotifyPermission(): Promise { if (!supported() || Notification.permission !== "default") return; try { const reg = await navigator.serviceWorker?.getRegistration?.(); if (!reg) return; // not an installed/opt-in PWA — don't prompt await Notification.requestPermission(); } catch { /* permission flow unavailable — no-op */ } }