import { kachelCacheName } from "./cache-storage"; const SHELL_REPAIR_TRIED = "karte-shell-repaired"; export type BootRepairPorts = { registrations(): Promise }>>; cacheNames(): Promise; deleteCache(name: string): Promise; }; type FlagStore = { getItem(key: string): string | null; setItem(key: string, value: string): void; removeItem(key: string): void; }; /** Drop the installed app shell. Kacheln stay in their own cache. */ export async function repairAppShell(ports: BootRepairPorts): Promise { const registrations = await ports.registrations(); await Promise.all(registrations.map((registration) => registration.unregister())); const names = await ports.cacheNames(); await Promise.all( names .filter((name) => name !== kachelCacheName) .map((name) => ports.deleteCache(name)), ); } /** Drop every stored Kachel. The heruntergeladen marks stay. */ export async function deleteKachelCache(ports: Pick): Promise { await ports.deleteCache(kachelCacheName); } export function bootFailureText(error: unknown): string { if (error instanceof Error && error.message.trim()) return error.message; return "Unbekannter Fehler"; } export function createBrowserBootRepair(): BootRepairPorts { return { async registrations() { if (!navigator.serviceWorker) return []; return navigator.serviceWorker.getRegistrations(); }, cacheNames: () => caches.keys(), deleteCache: (name) => caches.delete(name), }; } export function shellRepairWasTried(store: FlagStore | null = browserFlags()): boolean { try { return store?.getItem(SHELL_REPAIR_TRIED) === "1"; } catch { return false; } } export function markShellRepairTried(store: FlagStore | null = browserFlags()): void { try { store?.setItem(SHELL_REPAIR_TRIED, "1"); } catch { // sessionStorage can be blocked. The repair still runs. } } export function clearShellRepairTried(store: FlagStore | null = browserFlags()): void { try { store?.removeItem(SHELL_REPAIR_TRIED); } catch { // sessionStorage can be blocked. } } function browserFlags(): FlagStore | null { try { if (typeof sessionStorage === "undefined") return null; return sessionStorage; } catch { return null; } }