Refactor fetchMentions function to return structured results with debug information
All checks were successful
Deploy / deploy (push) Successful in 1m18s

This commit is contained in:
Adrian Altner 2026-04-22 02:25:37 +02:00
parent 1d57e23d19
commit 4f67fb99d4

View file

@ -24,9 +24,15 @@ interface Props {
const { target, locale = getLocaleFromUrl(Astro.url) ?? DEFAULT_LOCALE } = Astro.props; const { target, locale = getLocaleFromUrl(Astro.url) ?? DEFAULT_LOCALE } = Astro.props;
async function fetchMentions(target: string): Promise<WMEntry[]> { interface FetchResult {
mentions: WMEntry[];
debug: string;
}
async function fetchMentions(target: string): Promise<FetchResult> {
const token = import.meta.env.WEBMENTION_TOKEN; const token = import.meta.env.WEBMENTION_TOKEN;
if (!token) return []; const tokenLen = typeof token === 'string' ? token.length : 0;
if (!token) return { mentions: [], debug: `no-token(len=${tokenLen})` };
const withSlash = target.endsWith('/') ? target : `${target}/`; const withSlash = target.endsWith('/') ? target : `${target}/`;
const withoutSlash = target.replace(/\/+$/, ''); const withoutSlash = target.replace(/\/+$/, '');
const fetchOne = async (t: string) => { const fetchOne = async (t: string) => {
@ -35,24 +41,27 @@ async function fetchMentions(target: string): Promise<WMEntry[]> {
url.searchParams.set('token', token); url.searchParams.set('token', token);
url.searchParams.set('per-page', '100'); url.searchParams.set('per-page', '100');
const res = await fetch(url); const res = await fetch(url);
if (!res.ok) return [] as WMEntry[]; if (!res.ok) return { entries: [] as WMEntry[], status: res.status };
const json = (await res.json()) as { children?: WMEntry[] }; const json = (await res.json()) as { children?: WMEntry[] };
return json.children ?? []; return { entries: json.children ?? [], status: 200 };
}; };
const [a, b] = await Promise.all([fetchOne(withSlash), fetchOne(withoutSlash)]); const [a, b] = await Promise.all([fetchOne(withSlash), fetchOne(withoutSlash)]);
const seen = new Set<number>(); const seen = new Set<number>();
const merged: WMEntry[] = []; const merged: WMEntry[] = [];
for (const m of [...a, ...b]) { for (const m of [...a.entries, ...b.entries]) {
const id = m['wm-id']; const id = m['wm-id'];
if (id == null || seen.has(id)) continue; if (id == null || seen.has(id)) continue;
seen.add(id); seen.add(id);
merged.push(m); merged.push(m);
} }
return merged; return {
mentions: merged,
debug: `len=${tokenLen} slash=${a.status}:${a.entries.length} noslash=${b.status}:${b.entries.length}`,
};
} }
const targetStr = target.toString(); const targetStr = target.toString();
const all = await fetchMentions(targetStr); const { mentions: all, debug: fetchDebug } = await fetchMentions(targetStr);
const likes = all.filter((m) => m['wm-property'] === 'like-of'); const likes = all.filter((m) => m['wm-property'] === 'like-of');
const reposts = all.filter((m) => m['wm-property'] === 'repost-of'); const reposts = all.filter((m) => m['wm-property'] === 'repost-of');
@ -79,7 +88,7 @@ function formatDate(iso?: string) {
const hasAny = facepile.length > 0 || replies.length > 0 || mentions.length > 0; const hasAny = facepile.length > 0 || replies.length > 0 || mentions.length > 0;
--- ---
<div data-webmentions-debug data-target={targetStr} data-all={all.length} data-facepile={facepile.length} data-hasany={String(hasAny)} hidden></div> <div data-webmentions-debug data-target={targetStr} data-fetch={fetchDebug} data-all={all.length} data-facepile={facepile.length} data-hasany={String(hasAny)} hidden></div>
{ {
hasAny && ( hasAny && (