Skip to content

cache: persist folded timeline snapshots instead of a raw event log #481

Description

@gbasin

Context

The web/mobile timeline cache (shared/src/cache.ts, web/src/cacheIdb.ts) persists a raw event log per channel (CachedTimeline = { events: WireEvent[], hasMore }, max 300/channel): message.posted rows with their original text plus separate modifier events accumulated from the ack/WS path. On warm reload, mergeHistory (shared/src/timeline.ts) must re-apply those modifiers or acked edits/reactions silently vanish — this replay is the last structurally load-bearing copy of the client fold and has been the root of the warm-reload staleness family (#454, #460, #467).

Unlocked by the folded catch-up wire

Once reconnect/catch-up ships watermarked folded rows (lastModifierId on wire rows, server change-feed keyed by message_state.last_modifier_id), the cache can stop being an event log:

  • Persist folded rows only (the wire shape already IS the folded shape; cached rows carry lastModifierId).
  • Live WS modifiers update the cached row in place (or are dropped — the next delta heals) instead of appending to a replay log.
  • mergeHistory's modifier-replay path and cachedTimelineNeedsStructuralRepair retire entirely; warm reload becomes hydrate + watermark-gated delta.

Notes

  • Needs cache schema versioning (existing IndexedDB data is a raw log; simplest migration: drop and refetch on version bump).
  • Effect schemas ignore excess keys, so cached folded rows are forward/backward tolerant.
  • Deliberately split out of the folded-wire PR to keep that train reviewable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions