mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
The GUI history filter requested the broad CHANNEL_EVENT_KINDS set (reactions, edits, deletions alongside messages), so a 200-event "limit" budget bought only visible-message depth diluted by aux events — measured 136 messages / 200 events on a reaction-heavy channel, deterministic across runs. Scrollback inherited the same dilution, and same-second events could shuffle position when merged from two REQs (history vs live-sub). Fix, per the invariant converged on in #buzz-bugs: 1. Base history filter = visible content kinds only (CHANNEL_TIMELINE_CONTENT_KINDS, mirroring isTimelineContentEvent), so the limit budget maps to visible rows. 2. Backfill reactions/edits/deletions by `#e` over the loaded message ids — by reference, not by time window, so a late edit/delete for a visible old message still applies (avoids the silent-stale-state trap). 3. Keep the broad-kind live subscription for future aux events; cold/scrollback correctness comes from the #e backfill, not the tail. 4. Sort GUI merges by (created_at, id) so same-second merges are deterministic — both the cache sort (sortMessages) and the history-resolve sort (sortEvents) carry the id tiebreaker, keeping the two on one invariant. Extracted the channel filter-builders into relayChannelFilters.ts to keep relayClientSession.ts under its size cap. Aux backfill lives in its own module (auxBackfill.ts) to avoid coupling useFetchOlderMessages to hooks.ts. Regression tests prove the reducer applies aux by `#e` reference regardless of timestamp (far-future edit rewrites an old body; far-future deletion hides an old message), plus sort order-independence for both sort functions. Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: Tyler Longwell <tlongwell@block.xyz>