atproto user agency toolkit for individuals and groups
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 89 lines 1.9 kB view raw
1/** 2 * DID cache using in-memory Map with TTL. 3 * Replaces Cloudflare Workers Cache API from Cirrus. 4 */ 5 6import { defs, type DidDocument } from "@atcute/identity"; 7 8export interface CacheResult { 9 did: string; 10 doc: DidDocument; 11 updatedAt: number; 12 stale: boolean; 13 expired: boolean; 14} 15 16export interface DidCache { 17 cacheDid( 18 did: string, 19 doc: DidDocument, 20 prevResult?: CacheResult, 21 ): Promise<void>; 22 checkCache(did: string): Promise<CacheResult | null>; 23 refreshCache( 24 did: string, 25 getDoc: () => Promise<DidDocument | null>, 26 prevResult?: CacheResult, 27 ): Promise<void>; 28 clearEntry(did: string): Promise<void>; 29 clear(): Promise<void>; 30} 31 32const STALE_TTL = 60 * 60 * 1000; // 1 hour 33const MAX_TTL = 24 * 60 * 60 * 1000; // 24 hours 34 35interface CacheEntry { 36 doc: DidDocument; 37 cachedAt: number; 38} 39 40export class InMemoryDidCache implements DidCache { 41 private cache = new Map<string, CacheEntry>(); 42 43 async cacheDid(did: string, doc: DidDocument): Promise<void> { 44 this.cache.set(did, { doc, cachedAt: Date.now() }); 45 } 46 47 async checkCache(did: string): Promise<CacheResult | null> { 48 const entry = this.cache.get(did); 49 if (!entry) return null; 50 51 const now = Date.now(); 52 const age = now - entry.cachedAt; 53 54 // Validate document 55 const parsed = defs.didDocument.try(entry.doc); 56 if (!parsed.ok || parsed.value.id !== did) { 57 this.cache.delete(did); 58 return null; 59 } 60 61 return { 62 did, 63 doc: parsed.value, 64 updatedAt: entry.cachedAt, 65 stale: age > STALE_TTL, 66 expired: age > MAX_TTL, 67 }; 68 } 69 70 async refreshCache( 71 did: string, 72 getDoc: () => Promise<DidDocument | null>, 73 ): Promise<void> { 74 // Background refresh (fire and forget) 75 getDoc().then((doc) => { 76 if (doc) { 77 this.cacheDid(did, doc); 78 } 79 }); 80 } 81 82 async clearEntry(did: string): Promise<void> { 83 this.cache.delete(did); 84 } 85 86 async clear(): Promise<void> { 87 this.cache.clear(); 88 } 89}