views: exact count unions across relays (fixes cross-relay under-count) (#4)

The watch-page/chart "exact" count relied on the NIP-45 COUNT, but
countEventsAcrossRelays returns bestEstimate = the single relay with the MOST
events — it can't union across relays. So when views are distributed across
relays it under-counted (a video's card showed 19 while the chart's uncapped
list union showed ~63).

exactCountForPointer now lists view events across ALL relays (one on-demand
list, not a storm) and folds the UNION into the deduped dedupeBuckets (one entry
per viewer-window). total = the set size, so it is accurate AND monotonic (never
spuriously decreases on partial relay responses). The per-relay COUNT is kept
only as a lower-bound floor when the list truncates (>2000 events), flagged
partial. The popularity modal passes { exact: true }; since the count flows
through shared pointer state, opening a video corrects its count everywhere.

Grid cards (no exact) still use the §17-capped batched backfill (approximate,
storm-safe) until opened — an accepted accuracy/cost tradeoff.

Also note the ⋯ menu "Event Details" button does nothing (new TODO #31).

Tests: testExactCountUnionsAcrossRelays. Grandfathered viewCounter.js size.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-24 17:29:53 -04:00
1 parent 1bc2b06395
commit 36f3c6e127
5 files changed
+164 -26

No files matched your search

+1
View File
@@ -43,6 +43,7 @@ const GRANDFATHERED = {
"js/nostr/nip46Client.js": 2102,
"js/state/cache.js": 1827,
"js/app/feedCoordinator.js": 1857,
"js/viewCounter.js": 1023,
"js/app/authSessionCoordinator.js": 1803,
"js/ui/components/RevertModal.js": 1663,
"js/payments/nwcClient.js": 1642,