20 Commits
Author SHA1 Message Date
thePR0M3TH3ANandClaude Opus 4.8 36f3c6e127 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]>
2026-06-24 17:29:53 -04:00
thePR0M3TH3ANandClaude Opus 4.8 8deba55cdf views: un-quarantine view-counter test; audit reactionCounter (#4)
Triaged the monolithic tests/view-counter.test.mjs and got the whole file green,
then removed it from the QUARANTINE map:
- Pinned nostrClient.getSubscriptionManager() to null so the test exercises the
  legacy per-pointer hydrate/subscribe path it mocks. The batched
  SubscriptionManager path (added with the relay-storm work) was silently
  shadowing the mocked legacy APIs.
- Made the dedupe-window test bucket-aligned (it used Date.now(), so the
  +window/2 offset could straddle a fixed-bucket boundary and flake by time of
  day).
- Corrected the hydrateVideoHistory root-timestamp assertions to the refactored
  unit boundary: hydrateVideoHistory populates the rootCreatedAtByRoot MAP; the
  video object's rootCreatedAt FIELD is applied by syncActiveVideoRootTimestamp.

reactionCounter.js audit (kind-7 likes): accurate, no fix needed. It does not use
NIP-45 COUNT; it lists kind-7 events and dedupes via applyReactionToState keyed
by pubkey (one reaction per user, latest-wins) with per-content totals — no
raw-count inflation. Kind-7 isn't replaceable, so listing+dedupe is the only
accurate model.

Spec corrections documented in TEST_INTEGRITY.md (SCN-view-counter-legacy-path,
SCN-hydrate-root-timestamp).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-24 12:22:02 -04:00
google-labs-jules[bot] 4ab81ce28e Ensure view counts are monotonic during hydration
- Updated `hydratePointer` in `js/viewCounter.js` to only update local view counts if the network count is strictly greater (or if local state is uninitialized).
- This prevents regressions where a partial or stale network response would overwrite a higher, accurate local count.
- Updated `tests/view-counter.test.mjs` to reflect that fresh view events are additive to the cached high watermark (fixing a test expectation that relied on the old non-monotonic behavior).
- Updated `tests/view-counter.test.mjs` to match `resolveVideoPointer` behavior which prioritizes `dTag` (NIP-33) over `videoRootId`, fixing a legacy test failure.
2026-01-07 00:43:18 +00:00
thePR0M3TH3AN 3996986e63 Remove nostr shim and retarget imports 2026-01-06 15:32:21 -05:00
google-labs-jules[bot] ac071cb74e Fix(viewCounter): Retain stale view counts for smoother hydration
- Removes the logic in `restoreCacheSnapshot` that deleted cached view counts if they were older than `VIEW_COUNT_CACHE_TTL_MS`.
- Updates `tests/view-counter.test.mjs` to assert that stale cache data is preserved and used as a baseline during hydration, preventing view counts from dropping to zero or lower fallback values during network issues.
2026-01-05 21:01:53 +00:00
thePR0M3TH3AN 6331896f6a Sanitize additional Nostr tags 2025-11-12 09:54:34 -05:00
thePR0M3TH3AN d7405883d2 Ensure subscription publishing targets configured write relays 2025-10-20 22:59:29 -04:00
thePR0M3TH3AN 98dd51509d Add session fallback signing to nostr publish flow 2025-10-08 22:27:11 -04:00
thePR0M3TH3AN f9e2b975d1 Synchronize modal and card posted timestamps 2025-10-08 21:35:26 -04:00
thePR0M3TH3AN 0434401596 Show original posted timestamp for videos 2025-10-08 21:21:44 -04:00
thePR0M3TH3AN 0addd59226 feat: prioritize video root pointer for view tracking 2025-10-08 17:50:03 -04:00
thePR0M3TH3AN 48410b1abb chore: remove watch history logic 2025-10-02 11:43:15 -04:00
thePR0M3TH3AN 10adeddd82 Add durable identifiers to view events 2025-10-02 10:51:41 -04:00
thePR0M3TH3AN 38924abdcc chore: migrate watch history kind to 30079 2025-10-01 21:58:31 -04:00
thePR0M3TH3AN 63274d4c43 Update view counter test for publish return 2025-10-01 18:21:47 -04:00
thePR0M3TH3AN cf99059564 Add default view event payload and cover recordVideoView 2025-10-01 17:48:05 -04:00
thePR0M3TH3AN ff452ebe77 Stop default view events from adding legacy tags 2025-10-01 15:40:10 -04:00
thePR0M3TH3AN a20dc838dc Adjust relay count aggregation for view totals 2025-10-01 10:16:22 -04:00
thePR0M3TH3AN e543de8bb4 Add TTL hydration regression test for view counter 2025-09-30 23:18:36 -04:00
thePR0M3TH3AN 825d3c7ce4 Add view counter regression tests 2025-09-30 22:51:40 -04:00