UNPKG

bigblocks

Version:

Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React

117 lines (116 loc) 4.43 kB
/** * Cookie-based storage adapter * Works in both browser and server environments * Note: In browser, httpOnly cookies cannot be accessed */ export function createCookieStorage(options) { const prefix = options?.prefix ?? "bigblocks:"; // Helper to parse cookies const parseCookies = (cookieString) => { const cookies = {}; if (!cookieString) return cookies; for (const cookie of cookieString.split(";")) { const [name, value] = cookie.trim().split("="); if (name && value) { cookies[name] = decodeURIComponent(value); } } return cookies; }; // Helper to serialize cookie const serializeCookie = (name, value) => { const parts = [`${name}=${encodeURIComponent(value)}`]; if (options?.domain) parts.push(`Domain=${options.domain}`); if (options?.path) parts.push(`Path=${options.path}`); if (options?.expires) parts.push(`Expires=${options.expires.toUTCString()}`); if (options?.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`); if (options?.secure) parts.push("Secure"); if (options?.httpOnly) parts.push("HttpOnly"); if (options?.sameSite) parts.push(`SameSite=${options.sameSite}`); return parts.join("; "); }; // Check environment const isBrowser = typeof window !== "undefined" && typeof document !== "undefined"; if (isBrowser) { // Browser implementation return { async get(key) { try { const cookies = parseCookies(document.cookie); return cookies[prefix + key] ?? null; } catch (error) { console.error("cookie.get error:", error); return null; } }, async set(key, value) { try { // In browser, we can't set httpOnly cookies const cookieOptions = { ...options, httpOnly: false }; document.cookie = serializeCookie(prefix + key, value); } catch (error) { console.error("cookie.set error:", error); throw error; } }, async delete(key) { try { // Delete by setting expired date const cookieName = prefix + key; // Set empty value with expired date document.cookie = `${cookieName}=; Path=${options?.path || "/"}; Expires=Thu, 01 Jan 1970 00:00:01 GMT`; // Also try max-age=0 for better compatibility document.cookie = `${cookieName}=; Path=${options?.path || "/"}; Max-Age=0`; } catch (error) { console.error("cookie.delete error:", error); } }, async clear() { try { const cookies = parseCookies(document.cookie); for (const name in cookies) { if (name.startsWith(prefix)) { document.cookie = `${name}=; Path=${options?.path || "/"}; Expires=Thu, 01 Jan 1970 00:00:01 GMT`; } } } catch (error) { console.error("cookie.clear error:", error); } }, }; } // Server implementation - requires request/response context console.warn("Cookie storage in server environment requires request/response context. Using memory storage as fallback."); // Return memory storage as fallback for server-side const fallbackStore = new Map(); return { async get(key) { return fallbackStore.get(prefix + key) ?? null; }, async set(key, value) { fallbackStore.set(prefix + key, value); }, async delete(key) { fallbackStore.delete(prefix + key); }, async clear() { for (const key of fallbackStore.keys()) { if (key.startsWith(prefix)) { fallbackStore.delete(key); } } }, }; }