Fork of atp.tools as a universal profile for people on the ATmosphere
at main 79 lines 1.8 kB view raw
1export interface CacheEntry { 2 data: any; 3 timestamp: number; 4} 5 6export interface UserCache { 7 get(key: string): CacheEntry | undefined; 8 set(key: string, value: CacheEntry): void; 9 delete(key: string): void; 10 clear(): void; 11 clean(): void; 12} 13 14export class PersistentUserCache implements UserCache { 15 private cache: Map<string, CacheEntry>; 16 private readonly CACHE_KEY = "bsky_user_cache"; 17 private readonly CACHE_DURATION = 24 * 60 * 60 * 1000; // 1 day 18 19 constructor() { 20 this.cache = new Map(); 21 this.loadFromStorage(); 22 } 23 24 private loadFromStorage() { 25 try { 26 const stored = localStorage.getItem(this.CACHE_KEY); 27 if (stored) { 28 const parsed = JSON.parse(stored); 29 this.cache = new Map(Object.entries(parsed)); 30 } 31 } catch (error) { 32 console.warn("Failed to load cache from storage:", error); 33 } 34 } 35 36 private saveToStorage() { 37 try { 38 const obj = Object.fromEntries(this.cache); 39 localStorage.setItem(this.CACHE_KEY, JSON.stringify(obj)); 40 } catch (error) { 41 console.warn("Failed to save cache to storage:", error); 42 } 43 } 44 45 get(key: string): CacheEntry | undefined { 46 return this.cache.get(key); 47 } 48 49 set(key: string, value: CacheEntry) { 50 this.cache.set(key, value); 51 this.saveToStorage(); 52 } 53 54 delete(key: string) { 55 this.cache.delete(key); 56 this.saveToStorage(); 57 } 58 59 clear() { 60 this.cache.clear(); 61 this.saveToStorage(); 62 } 63 64 clean() { 65 const now = Date.now(); 66 let hasChanges = false; 67 68 for (const [key, value] of this.cache.entries()) { 69 if (now - value.timestamp > this.CACHE_DURATION) { 70 this.cache.delete(key); 71 hasChanges = true; 72 } 73 } 74 75 if (hasChanges) { 76 this.saveToStorage(); 77 } 78 } 79}