ATProto forum built with ESAV
at main 1.7 kB view raw
1import React, { createContext, useContext, useCallback } from 'react'; 2import { get as idbGet, set as idbSet, del as idbDel } from 'idb-keyval'; 3 4type PersistentValue = { 5 value: string; 6 time: number; 7}; 8 9type PersistentStoreContextType = { 10 get: (key: string) => Promise<PersistentValue | null>; 11 set: (key: string, value: string) => Promise<void>; 12 remove: (key: string) => Promise<void>; 13}; 14 15const PersistentStoreContext = createContext<PersistentStoreContextType | null>(null); 16 17export const PersistentStoreProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { 18 const get = useCallback(async (key: string): Promise<PersistentValue | null> => { 19 if (typeof window === 'undefined') return null; 20 const raw = await idbGet(key); 21 if (!raw) return null; 22 try { 23 return JSON.parse(raw) as PersistentValue; 24 } catch { 25 return null; 26 } 27 }, []); 28 29 const set = useCallback(async (key: string, value: string) => { 30 if (typeof window === 'undefined') return; 31 const entry: PersistentValue = { value, time: Date.now() }; 32 await idbSet(key, JSON.stringify(entry)); 33 }, []); 34 35 const remove = useCallback(async (key: string) => { 36 if (typeof window === 'undefined') return; 37 await idbDel(key); 38 }, []); 39 40 return ( 41 <PersistentStoreContext.Provider value={{ get, set, remove }}> 42 {children} 43 </PersistentStoreContext.Provider> 44 ); 45}; 46 47export const usePersistentStore = (): PersistentStoreContextType => { 48 const context = useContext(PersistentStoreContext); 49 if (!context) throw new Error('usePersistentStore must be used within a PersistentStoreProvider'); 50 return context; 51};