ATProto forum built with ESAV
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};