import { config } from "../config.js"; import { createPage, findRootPage, listCollectives, listPages, type PageInfoDto } from "./collectivesClient.js"; let collectiveIdPromise: Promise | null = null; let parentPagePromise: Promise | null = null; let cachedTopics: Map | null = null; let cachedAt = 0; function getCollectiveId(): Promise { if (!collectiveIdPromise) { collectiveIdPromise = listCollectives().then((collectives) => { const match = collectives.find((c) => c.name === config.collectiveName); if (!match) { const available = collectives.map((c) => c.name).join(", "); throw new Error( `Collective "${config.collectiveName}" not found. Available collectives: ${available}` ); } return match.id; }); } return collectiveIdPromise; } export function getParentPage(): Promise { if (!parentPagePromise) { parentPagePromise = (async () => { const collectiveId = await getCollectiveId(); const pages = await listPages(collectiveId); const root = findRootPage(pages); if (!root) { throw new Error(`Could not find root page for collective "${config.collectiveName}"`); } const existing = pages.find( (p) => p.parentId === root.id && p.title === config.parentPageTitle ); if (existing) { return existing; } return createPage(collectiveId, root.id, config.parentPageTitle); })(); } return parentPagePromise; } async function refreshTopics(force = false): Promise> { if (!force && cachedTopics && Date.now() - cachedAt < config.topicCacheTtlMs) { return cachedTopics; } const collectiveId = await getCollectiveId(); const parent = await getParentPage(); const pages = await listPages(collectiveId); const map = new Map(); for (const page of pages) { if (page.parentId === parent.id) { map.set(page.title, page); } } cachedTopics = map; cachedAt = Date.now(); return map; } export async function listTopics(): Promise<{ title: string }[]> { const map = await refreshTopics(); return [...map.keys()].sort((a, b) => a.localeCompare(b)).map((title) => ({ title })); } export async function getOrCreateTopicPage(title: string): Promise { let map = await refreshTopics(); let page = map.get(title); if (page) { return page; } map = await refreshTopics(true); page = map.get(title); if (page) { return page; } const collectiveId = await getCollectiveId(); const parent = await getParentPage(); const created = await createPage(collectiveId, parent.id, title); map.set(created.title, created); cachedTopics = map; return created; }