Rich card data
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import type { PageEnrichment } from '../shared/enrichment.ts';
|
||||
|
||||
// One request per article shared by hero, collection and detail views. No wallet data is sent.
|
||||
const cache = new Map<number, { expires: number; job: Promise<PageEnrichment> }>();
|
||||
function load(pageId: number): Promise<PageEnrichment> {
|
||||
const existing=cache.get(pageId);
|
||||
if(existing && existing.expires>Date.now())return existing.job;
|
||||
const job=(async()=>{
|
||||
const response=await fetch(`/api/wikipedia/${pageId}`,{signal:AbortSignal.timeout(15000),cache:'no-store'});
|
||||
if(!response.ok)throw new Error('Live Wikipedia data unavailable');
|
||||
return await response.json() as PageEnrichment;
|
||||
})();
|
||||
cache.set(pageId,{expires:Date.now()+5*60*1000,job});
|
||||
if(cache.size>128)cache.delete(cache.keys().next().value!);
|
||||
return job;
|
||||
}
|
||||
export function useEnrichment(pageId: number) {
|
||||
const [data,setData]=useState<PageEnrichment>();
|
||||
const [error,setError]=useState(false);
|
||||
const [attempt,setAttempt]=useState(0);
|
||||
useEffect(()=>{
|
||||
let active=true;setData(undefined);setError(false);
|
||||
load(pageId).then(value=>{if(active)setData(value);},()=>{if(active)setError(true);});
|
||||
return()=>{active=false;};
|
||||
},[pageId,attempt]);
|
||||
return {data,error,retry:()=>{cache.delete(pageId);setAttempt(n=>n+1);}};
|
||||
}
|
||||
Reference in New Issue
Block a user