a a vibe-coded abomination experiment of a fragrance review platform built on the atmosphere. drydown.social
at main 51 lines 1.2 kB view raw
1interface CacheEntry<T> { 2 value: T 3 expiresAt: number 4} 5 6class SimpleCache { 7 private store = new Map<string, CacheEntry<unknown>>() 8 9 get<T>(key: string): T | null { 10 const entry = this.store.get(key) 11 if (!entry) return null 12 if (Date.now() > entry.expiresAt) { 13 this.store.delete(key) 14 return null 15 } 16 return entry.value as T 17 } 18 19 set<T>(key: string, value: T, ttlMs: number): void { 20 this.store.set(key, { value, expiresAt: Date.now() + ttlMs }) 21 } 22 23 delete(key: string): void { 24 this.store.delete(key) 25 } 26 27 clear(): void { 28 this.store.clear() 29 } 30 31 async getOrFetch<T>(key: string, ttlMs: number, fetcher: () => Promise<T>): Promise<T> { 32 const cached = this.get<T>(key) 33 if (cached !== null) return cached 34 const value = await fetcher() 35 this.set(key, value, ttlMs) 36 return value 37 } 38} 39 40export const cache = new SimpleCache() 41 42// TTL constants (ms) 43export const TTL = { 44 DID: 60 * 60 * 1000, // 1 hour 45 PDS: 60 * 60 * 1000, // 1 hour 46 PROFILE: 5 * 60 * 1000, // 5 minutes 47 FRAGRANCE: 30 * 60 * 1000, // 30 minutes 48 HOUSE: 30 * 60 * 1000, // 30 minutes 49 REVIEWS: 2 * 60 * 1000, // 2 minutes 50 SETTINGS: 30 * 60 * 1000, // 30 minutes 51}