bigblocks
Version:
Complete Bitcoin UI component library - authentication, social, wallet, market, inscriptions, and blockchain interactions for React
117 lines (116 loc) • 4.43 kB
JavaScript
/**
* 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);
}
}
},
};
}