import { fetchJson } from "#lib/fetchJson.ts";
import type { Fetch } from "#lib/fetch.ts";
const BLOG_URLS = ["https://tangled.org/blog", "https://next-dev.tangled.org/blog"];
const BLOG_ORIGINS = new Set(BLOG_URLS.map((url) => new URL(url).origin));
const FEED_TTL = 5 * 60_000;
export interface BlogFeedItem {
url: string;
title: string;
summary?: string;
image?: string;
date_published: string;
tags?: string[];
authors?: { name: string; url?: string }[];
}
let cached: { expires: number; items: BlogFeedItem[] } | undefined;
export const loadBlogFeed = async (
fetch: Fetch,
timeout = 2500
): Promise<BlogFeedItem[] | null> => {
if (cached && cached.expires > Date.now()) return cached.items;
const feeds = BLOG_URLS.map((blogUrl) =>
fetchJson<{ items?: BlogFeedItem[] }>(fetch, `${blogUrl}/feed.json`, timeout)
);
for (const pending of feeds) {
const feed = await pending;
if (!Array.isArray(feed?.items)) continue;
const items = feed.items.flatMap((item) => {
const url = URL.parse(item.url);
return url && BLOG_ORIGINS.has(url.origin) ? [{ ...item, url: url.href }] : [];
});
cached = { expires: Date.now() + FEED_TTL, items };
return items;
}
return null;
};