Ionosphere.tv
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: fetch concordance client-side to avoid OOM on SSR

The concordance index is ~10k entries and took 3.5 min to build,
causing OOM kills on the 256MB frontend machines. Now fetched
client-side with a loading state. Also bumped frontend to 512MB.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+25 -6
+22 -1
apps/ionosphere/src/app/concordance/IndexContent.tsx
··· 146 146 147 147 // --- Component --- 148 148 149 - export default function IndexContent({ entries }: { entries: IndexEntry[] }) { 149 + export default function IndexContent({ entries: initialEntries }: { entries: IndexEntry[] | null }) { 150 + const [entries, setEntries] = useState<IndexEntry[] | null>(initialEntries); 151 + const [loading, setLoading] = useState(!initialEntries); 152 + 153 + useEffect(() => { 154 + if (initialEntries) return; 155 + const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:9401"; 156 + fetch(`${API_BASE}/xrpc/tv.ionosphere.getConcordance`) 157 + .then((r) => r.json()) 158 + .then((d) => { setEntries(d.entries); setLoading(false); }) 159 + .catch(() => setLoading(false)); 160 + }, [initialEntries]); 161 + 150 162 const [selectedTalk, setSelectedTalk] = useState<{ 151 163 rkey: string; title: string; videoUri: string; 152 164 offsetNs: number; document: any; seekToNs: number; ··· 182 194 183 195 // Filter entries 184 196 const filteredEntries = useMemo(() => { 197 + if (!entries) return []; 185 198 if (!filter) return entries; 186 199 try { 187 200 const pattern = isRegex ? new RegExp(filter, "i") : null; ··· 258 271 const el = document.getElementById(id); 259 272 if (el) el.scrollIntoView({ behavior: "smooth", block: "start" }); 260 273 }, []); 274 + 275 + if (loading) { 276 + return ( 277 + <div className="h-full flex items-center justify-center text-neutral-500 text-sm"> 278 + Building concordance index... this takes a few minutes the first time. 279 + </div> 280 + ); 281 + } 261 282 262 283 return ( 263 284 <div className="h-full flex">
+2 -4
apps/ionosphere/src/app/concordance/page.tsx
··· 1 - import { getIndex } from "@/lib/api"; 2 1 import IndexContent from "./IndexContent"; 3 2 4 - export default async function IndexPage() { 5 - const { entries } = await getIndex(); 6 - return <IndexContent entries={entries} />; 3 + export default function IndexPage() { 4 + return <IndexContent entries={null} />; 7 5 }
+1 -1
fly.web.toml
··· 20 20 21 21 [[vm]] 22 22 size = "shared-cpu-1x" 23 - memory = "256mb" 23 + memory = "512mb"