"use client"; import { createContext, useContext } from "react"; import useSWR from "swr"; import { callRPC } from "app/api/rpc/client"; import type { StandardSitePostData } from "app/api/rpc/[command]/get_standard_site_posts"; type Resolver = (data: StandardSitePostData | null) => void; let pendingURIs = new Set(); let pendingResolvers = new Map(); let flushScheduled = false; function scheduleFlush() { if (flushScheduled) return; flushScheduled = true; queueMicrotask(async () => { const uris = Array.from(pendingURIs); pendingURIs = new Set(); const resolvers = pendingResolvers; pendingResolvers = new Map(); flushScheduled = false; if (uris.length === 0) return; try { const res = await callRPC("get_standard_site_posts", { uris }); const byUri = new Map( (res?.result.posts || []).map((p) => [p.uri, p] as const), ); for (const uri of uris) { const post = byUri.get(uri) ?? null; for (const r of resolvers.get(uri) || []) r(post); } } catch { for (const uri of uris) { for (const r of resolvers.get(uri) || []) r(null); } } }); } function batchFetchStandardSitePost( uri: string, ): Promise { return new Promise((resolve) => { pendingURIs.add(uri); const existing = pendingResolvers.get(uri) || []; existing.push(resolve); pendingResolvers.set(uri, existing); scheduleFlush(); }); } export const StandardSitePostDataContext = createContext | null>(null); export function StandardSitePostDataProvider(props: { posts: StandardSitePostData[]; children: React.ReactNode; }) { const map: Record = {}; for (const p of props.posts) map[p.uri] = p; return ( {props.children} ); } export function useStandardSitePost(uri: string | null | undefined) { const ctx = useContext(StandardSitePostDataContext); const fromContext = uri ? ctx?.[uri] : undefined; const swr = useSWR( !uri || fromContext ? null : `standard-site-post:${uri}`, () => batchFetchStandardSitePost(uri!), { revalidateOnFocus: false, revalidateIfStale: false }, ); return { data: fromContext ?? swr.data, isLoading: !fromContext && swr.isLoading, }; }