A fullstack app for indexing standard.site documents
at main 49 lines 1.4 kB view raw
1// PDS cache TTL: 1 hour (PDS endpoints rarely change) 2const PDS_CACHE_TTL_MS = 60 * 60 * 1000; 3 4function isPdsCacheValid(cachedAt: string | null): boolean { 5 if (!cachedAt) return false; 6 const cacheTime = new Date(cachedAt).getTime(); 7 return Date.now() - cacheTime < PDS_CACHE_TTL_MS; 8} 9 10export async function resolvePds( 11 db: D1Database, 12 did: string 13): Promise<string | null> { 14 const cached = await db 15 .prepare("SELECT pds_endpoint, cached_at FROM pds_cache WHERE did = ?") 16 .bind(did) 17 .first<{ pds_endpoint: string; cached_at: string }>(); 18 19 if (cached && isPdsCacheValid(cached.cached_at)) { 20 return cached.pds_endpoint; 21 } 22 23 try { 24 const response = await fetch(`https://plc.directory/${did}`); 25 if (!response.ok) return null; 26 27 const doc = (await response.json()) as { 28 service?: Array<{ id: string; type: string; serviceEndpoint: string }>; 29 }; 30 31 const pds = doc.service?.find((s) => s.id === "#atproto_pds"); 32 if (pds?.serviceEndpoint) { 33 await db 34 .prepare( 35 `INSERT INTO pds_cache (did, pds_endpoint, cached_at) 36 VALUES (?, ?, datetime('now')) 37 ON CONFLICT(did) DO UPDATE SET pds_endpoint = ?, cached_at = datetime('now')` 38 ) 39 .bind(did, pds.serviceEndpoint, pds.serviceEndpoint) 40 .run(); 41 42 return pds.serviceEndpoint; 43 } 44 45 return null; 46 } catch { 47 return null; 48 } 49}