Skip to content

entry_state_changed SSE events don't update unread/starred counts #572

@brendanlong

Description

@brendanlong

This is related to #580 and a PR fixing this should target the tanstack-db branch.

Problem

When an entry_state_changed event arrives via SSE (e.g., from another tab or device marking an entry as read/starred), the handler in src/lib/cache/event-handlers.ts:226-238 updates the entry's read/starred state in the collections and React Query cache, but does not adjust any counts:

  • Global counts (all/starred/saved unread)
  • Subscription unread counts
  • Tag unread counts
  • Uncategorized unread counts

This means if you mark entries as read in one tab, the other tab's sidebar counts stay stale until you perform a mutation in that tab (which triggers setCounts/setBulkCounts with server-provided absolute counts).

Current behavior

// src/lib/cache/event-handlers.ts:226-238
case "entry_state_changed":
  // Updates entry state ✅
  utils.entries.get.setData({ id: event.entryId }, ...);
  updateEntryReadInCollection(collections ?? null, [event.entryId], event.read);
  updateEntryStarredInCollection(collections ?? null, event.entryId, event.starred);
  // No count updates ❌
  break;

Compare with new_entry which correctly adjusts counts, and mutations which use setCounts/setBulkCounts.

Root cause

The entry_state_changed SSE event doesn't currently carry enough data to compute all count deltas — specifically, it's missing subscriptionId (needed for subscription and tag count lookups).

Possible solutions

  1. Include subscriptionId in the entry_state_changed event from the server (in src/server/redis/pubsub.ts), then compute full count deltas client-side using the subscription's tag membership
  2. Include previous read/starred state in the event so the client can compute deltas without looking up current state
  3. Call refreshGlobalCounts() after receiving state change events — simpler but adds server round-trips
  4. Some combination — e.g., include subscriptionId for precise subscription/tag deltas, and compute global count deltas from the read/starred change direction

Option 1 is probably cleanest since the server already has the subscription context when publishing the event.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions