From 0434a399e9212aa44fba4a11c307f6e923c3f488 Mon Sep 17 00:00:00 2001 From: Silberengel Date: Thu, 14 May 2026 01:23:27 +0200 Subject: [PATCH] bug-fixes --- src/services/client-events.service.ts | 15 +++++++++++++++ src/services/note-stats.service.ts | 27 ++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/services/client-events.service.ts b/src/services/client-events.service.ts index 1fdb6e52..0a7642e0 100644 --- a/src/services/client-events.service.ts +++ b/src/services/client-events.service.ts @@ -245,6 +245,21 @@ export class EventService { return undefined } + /** + * IndexedDB publication store only (no session wait, no relay). Used to paint note stats before REQ. + */ + async peekPublicationStoreEvent(hexId: string): Promise { + const id = hexId.trim().toLowerCase() + if (!/^[0-9a-f]{64}$/.test(id)) return undefined + const fromDb = await indexedDb.getEventFromPublicationStore(id) + if (fromDb && !shouldDropEventOnIngest(fromDb, { explicitNoteLookupHexId: id })) { + const ev = fromDb as NEvent + this.addEventToCache(ev, { explicitNoteLookupHexId: id }) + return ev + } + return undefined + } + /** * When a matching event is added to the session cache, invoke `callback` (and when already cached). * Supports hex / note1 / nevent1 and **naddr1** (replaceable coordinate: kind + pubkey + `d`). diff --git a/src/services/note-stats.service.ts b/src/services/note-stats.service.ts index f7fcd371..825f2dcb 100644 --- a/src/services/note-stats.service.ts +++ b/src/services/note-stats.service.ts @@ -187,6 +187,14 @@ class NoteStatsService { const eventId = this.statsKey(event.id) const foreground = opts?.foreground === true + /** Session LRU already has many reactions/replies/zaps — paint counts before relay batch runs. */ + if (event.kind !== ExtendedKind.RSS_THREAD_ROOT) { + const preFromSession = eventService.getSessionEventsForNoteStatsTarget(event) + if (preFromSession.length > 0) { + this.updateNoteStatsByEvents(preFromSession, event.pubkey, { statsRootEvent: event }) + } + } + const rememberRoot = () => { if (event.kind === ExtendedKind.RSS_THREAD_ROOT) { this.pendingSyntheticRootById.set(eventId, event) @@ -267,6 +275,14 @@ class NoteStatsService { } const hexIds = [...hexIdsSet] + for (const r of hexReplies) { + if (r.kind === ExtendedKind.RSS_THREAD_ROOT) continue + const pre = eventService.getSessionEventsForNoteStatsTarget(r) + if (pre.length > 0) { + this.updateNoteStatsByEvents(pre, r.pubkey) + } + } + const markHexTargetsLoaded = () => { for (const id of hexIds) { this.touchStatsLoadedMarker(id) @@ -458,7 +474,16 @@ class NoteStatsService { this.pendingSyntheticRootById.delete(eventId) const callerRoot = this.pendingStatsRootEventById.get(eventId) this.pendingStatsRootEventById.delete(eventId) - resolvedEvent = synthetic ?? callerRoot ?? (await eventService.fetchEvent(eventId)) + resolvedEvent = synthetic ?? callerRoot + if (!resolvedEvent && this.hexNoteStatsIdRe.test(eventId)) { + resolvedEvent = eventService.peekSessionCachedEvent(eventId) + } + if (!resolvedEvent && this.hexNoteStatsIdRe.test(eventId)) { + resolvedEvent = await eventService.peekPublicationStoreEvent(eventId) + } + if (!resolvedEvent) { + resolvedEvent = await eventService.fetchEvent(eventId) + } if (!resolvedEvent) { markStatsLoaded(eventId) return