import { useEffect } from "preact/hooks";
// Simple safe storage functions to avoid errorHandling.ts dependency
function safeLocalStorage() {
try {
if (typeof localStorage === "undefined") {
return null;
}
// Test if localStorage is accessible
const testKey = "__test__";
localStorage.setItem(testKey, "test");
localStorage.removeItem(testKey);
return localStorage;
} catch {
return null;
}
}
function safeSessionStorage() {
try {
if (typeof sessionStorage === "undefined") {
return null;
}
// Test if sessionStorage is accessible
const testKey = "__test__";
sessionStorage.setItem(testKey, "test");
sessionStorage.removeItem(testKey);
return sessionStorage;
} catch {
return null;
}
}
/**
* Custom hook to manage Service Worker registration
* Handles registration, unregistration, and session-based updates
* Includes robust error handling for network issues and broken pipes
*
* @example
* ```tsx
* function MyComponent() {
* useServiceWorker();
* return
Component content
;
* }
* ```
*/
export function useServiceWorker() {
useEffect(() => {
if ("serviceWorker" in navigator) {
// Check if this is a new user experience (session start)
const storage = safeSessionStorage();
const isNewSession = !storage?.getItem("sw_registered");
// Add timeout for service worker operations
// const registrationTimeout = setTimeout(() => {
// console.warn("Service Worker registration taking longer than expected");
// }, 10000);
navigator.serviceWorker.getRegistrations().then((registrations) => {
const activeSW = registrations.find((reg) =>
reg.active?.scriptURL.includes("fetch_sw.js")
);
if (activeSW && !isNewSession) {
// Service worker already active and not a new session - skip registration
// console.log("Service Worker already active.");
// clearTimeout(registrationTimeout);
return;
}
// New session or no active SW - unregister old versions and register new
const unregisterPromises = registrations.map((registration) =>
registration.unregister().catch((_err) => {
// Log but don't fail if unregistration fails
// console.warn("Failed to unregister old service worker:", err);
return Promise.resolve();
})
);
return Promise.all(unregisterPromises).then(() => {
// Register the new service worker after unregistering old ones
return navigator.serviceWorker.register("/fetch_sw.js");
}).then(() => {
// console.log("Service Worker registered.");
const swStorage = safeSessionStorage();
swStorage?.setItem("sw_registered", "true");
// clearTimeout(registrationTimeout);
}).catch((_regError) => {
// Handle registration errors gracefully
// console.error("Service Worker registration failed:", regError);
// clearTimeout(registrationTimeout);
// Don't throw - allow app to continue without service worker
});
}).catch((_error) => {
//clearTimeout(registrationTimeout);
// Handle different error types
// const errorMessage = error instanceof Error ? error.message : String(error);
// if (error instanceof TypeError || errorMessage.includes("network")) {
// console.error("Network error during service worker setup:", error);
// } else if (errorMessage.includes("broken pipe")) {
// console.error("Connection broken during service worker setup:", error);
// } else {
// console.error("Service Worker registration failed:", error);
// }
// App should continue functioning without service worker
});
}
// else {
// console.log("Service Worker not supported in this browser.");
// }
// Cleanup function
return () => {
// No cleanup needed for service worker registration
};
}, []);
}
/**
* Custom hook to manage logout button state
* Handles post-logout redirect cleanup
* Includes error handling for localStorage access issues
*/
export function useLogoutCleanup() {
useEffect(() => {
try {
// Use safe localStorage access
const storage = safeLocalStorage();
if (!storage) {
console.warn("localStorage not available");
return;
}
const lastClickedButton = storage.getItem("lastClickedButton");
if (lastClickedButton === "logout") {
storage.removeItem("lastClickedButton");
// Add try-catch for URL manipulation and redirect
try {
const url = new URL(globalThis.location.href);
globalThis.location.href = url.origin + "?popstate=true";
} catch (urlError) {
console.error("Error during logout redirect:", urlError);
// Fallback to simple redirect
globalThis.location.href = "/";
}
}
} catch (error) {
// Handle localStorage access errors (quota exceeded, privacy mode, etc.)
console.error("Error during logout cleanup:", error);
}
}, []);
}