(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
98
fork

Configure Feed

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

at main 63 lines 1.5 kB view raw
1type QueueEntry = { 2 url: string; 3 resolve: (data: Record<string, string> | null) => void; 4}; 5 6const MAX_CONCURRENT = 3; 7const queue: QueueEntry[] = []; 8let active = 0; 9const inflight = new Map<string, Promise<Record<string, string> | null>>(); 10 11function processQueue() { 12 while (active < MAX_CONCURRENT && queue.length > 0) { 13 const entry = queue.shift()!; 14 active++; 15 16 doFetch(entry.url) 17 .then(entry.resolve) 18 .finally(() => { 19 active--; 20 processQueue(); 21 }); 22 } 23} 24 25function doFetch(url: string): Promise<Record<string, string> | null> { 26 const existing = inflight.get(url); 27 if (existing) return existing; 28 29 const promise = fetch(`/api/url-metadata?url=${encodeURIComponent(url)}`) 30 .then((res) => (res.ok ? res.json() : null)) 31 .catch(() => null) 32 .finally(() => { 33 inflight.delete(url); 34 }); 35 36 inflight.set(url, promise); 37 return promise; 38} 39 40export function fetchMetadata( 41 url: string, 42): Promise<Record<string, string> | null> { 43 try { 44 const cached = sessionStorage.getItem(`og:${url}`); 45 if (cached) return Promise.resolve(JSON.parse(cached)); 46 } catch { 47 /* ignore */ 48 } 49 50 return new Promise((resolve) => { 51 queue.push({ url, resolve }); 52 processQueue(); 53 }).then((data) => { 54 if (data) { 55 try { 56 sessionStorage.setItem(`og:${url}`, JSON.stringify(data)); 57 } catch { 58 /* ignore */ 59 } 60 } 61 return data as Record<string, string> | null; 62 }); 63}