Fix thread OOM: hard-truncate events client-side, remove batchFetchProfileAges from thread

This commit is contained in:
Jure
2026-04-13 22:16:02 +02:00
parent a87abb6d97
commit 018ee0e0f3
2 changed files with 8 additions and 9 deletions
+1 -2
View File
@@ -4,7 +4,7 @@ import { useAutoResize } from "../../hooks/useAutoResize";
import { useUIStore } from "../../stores/ui";
import { useUserStore } from "../../stores/user";
import { useMuteStore } from "../../stores/mute";
import { fetchNoteById, fetchThreadEvents, fetchAncestors, publishReply, getNDK, ensureConnected, batchFetchProfileAges } from "../../lib/nostr";
import { fetchNoteById, fetchThreadEvents, fetchAncestors, publishReply, getNDK, ensureConnected } from "../../lib/nostr";
import { buildThreadTree, getRootEventId } from "../../lib/threadTree";
import type { ThreadNode } from "../../lib/threadTree";
import { debug } from "../../lib/debug";
@@ -106,7 +106,6 @@ export function ThreadView() {
const built = buildThreadTree(root.id, allEvents);
setTree(built);
batchFetchProfileAges([...new Set(allEvents.map((e) => e.pubkey))]);
} catch (err) {
debug.error("Failed to load thread:", err);
if (!cancelled) setLoadError(`Failed to load: ${err}`);
+7 -7
View File
@@ -146,16 +146,16 @@ export async function fetchThreadEvents(rootId: string): Promise<NDKEvent[]> {
const directEvents = await fetchWithTimeout(instance, directFilter, THREAD_TIMEOUT);
const allEvents = new Map<string, NDKEvent>();
for (const e of directEvents) allEvents.set(e.id, e);
// Hard-truncate: relays often ignore `limit` on #e filters, so we enforce it client-side
for (const e of [...directEvents].slice(0, THREAD_EVENT_LIMIT)) allEvents.set(e.id, e);
// Round-trip 2: replies to events in the thread — only if round 1 returned < limit
// Skip deep fetch on large threads to avoid OOM
if (allEvents.size < THREAD_EVENT_LIMIT) {
const knownIds = Array.from(allEvents.keys()).slice(0, 50); // cap #e filter size
// Round-trip 2: only attempt if round 1 was small (skip entirely on big threads)
if (allEvents.size < 50) {
const knownIds = Array.from(allEvents.keys());
if (knownIds.length > 0) {
const deepFilter: NDKFilter = { kinds: [NDKKind.Text], "#e": knownIds, limit: THREAD_EVENT_LIMIT - allEvents.size };
const deepFilter: NDKFilter = { kinds: [NDKKind.Text], "#e": knownIds, limit: THREAD_EVENT_LIMIT };
const deepEvents = await fetchWithTimeout(instance, deepFilter, THREAD_TIMEOUT);
for (const e of deepEvents) allEvents.set(e.id, e);
for (const e of [...deepEvents].slice(0, THREAD_EVENT_LIMIT - allEvents.size)) allEvents.set(e.id, e);
}
}