UNPKG

next-shared-state

Version:

Enhanced state sharing for Next.js with IndexedDB persistence and URL data transfer between pages and components.

116 lines (115 loc) 3.93 kB
// src/createStore.ts import { useState, useEffect } from "react"; import { setMemory, getMemory } from "./memoryStore"; import { URLTransfer } from "./urlTransfer"; import { enhancedIndexedDB } from "./enhancedIndexedDB"; import { TTL } from "./ttlPresets"; function parseTTL(ttl) { if (ttl === undefined) return undefined; if (typeof ttl === "string" && TTL[ttl] !== undefined) { return TTL[ttl]; } if (typeof ttl === "number") { return ttl; } if (typeof ttl === "string") { const match = ttl.match(/^(\d+)\s*(minute|hour|day|week|month|year)s?$/i); if (match) { const value = parseInt(match[1]); const unit = match[2].toLowerCase(); const multipliers = { minute: 60 * 1000, hour: 60 * 60 * 1000, day: 24 * 60 * 60 * 1000, week: 7 * 24 * 60 * 60 * 1000, month: 30 * 24 * 60 * 60 * 1000, year: 365 * 24 * 60 * 60 * 1000, }; return value * multipliers[unit]; } const simpleNumber = parseInt(ttl); if (!isNaN(simpleNumber)) { return simpleNumber * 60 * 1000; } } return undefined; } export function useSharedData(key, initialValue, options = {}) { const [value, setValue] = useState(() => { if (typeof window !== "undefined") { const urlData = URLTransfer.extractFromURL(); if (urlData && urlData[key] !== undefined) { return urlData[key]; } } const memoryValue = getMemory(key); if (memoryValue !== undefined) return memoryValue; return initialValue; }); useEffect(() => { const loadFromIndexedDB = async () => { if (options.persist === "indexedDB") { try { const persisted = await enhancedIndexedDB.get(key); if (persisted !== null) { setValue(persisted); setMemory(key, persisted); } } catch (error) { console.warn("Failed to load from IndexedDB:", error); } } }; loadFromIndexedDB(); }, [key, options.persist]); useEffect(() => { if (value !== undefined) { setMemory(key, value); if (options.persist === "indexedDB") { const ttlMs = parseTTL(options.ttl); enhancedIndexedDB .set(key, value, { ttl: ttlMs, category: options.category, }) .catch((error) => { console.warn("Failed to persist to IndexedDB:", error); }); } } }, [key, value, options.persist, options.ttl, options.category]); return [value, setValue]; } export function setSharedData(key, value, options = {}) { setMemory(key, value); if (options.persist === "indexedDB") { const ttlMs = parseTTL(options.ttl); enhancedIndexedDB .set(key, value, { ttl: ttlMs, category: options.category, }) .catch((error) => { console.warn("Failed to persist to IndexedDB:", error); }); } } export function createTransferURL(path, data) { return URLTransfer.createTransferURL(path, data); } export async function clearPersistedData(category) { return enhancedIndexedDB.clear(category); } export async function getPersistedKeys() { return enhancedIndexedDB.getKeys(); } export async function exportAllData() { return enhancedIndexedDB.exportData(); } export async function importData(jsonData) { return enhancedIndexedDB.importData(jsonData); } export { enhancedIndexedDB as indexedDBStore, TTL };