Streams previously prefetched every particle through an unbounded Firestore
subscription. This adds a windowed source that anchors a `created_at desc`
limit query at the newest particle and grows it backward on demand, so the
already-seen history before a viewer's playback marker is no longer loaded.
- `useWindowedStreamParticles`: tail-anchored live window that grows backward
to cover the resume marker and to service `loadOlder()` (list scroll-up).
Because the window always includes the newest particle, new arrivals stream
in and forward playback never needs a fetch. Includes anti-eviction growth
so a new tail particle never pushes loaded particles out of the window.
- `useStreamPlayback`: consumes the windowed source instead of loading all
children. New-tail and removal handling are derived from the children array
(Firestore change events can't tell a genuine arrival from pagination
backfill). Resume-from-marker waits for backward growth to reach an older
marker; `prev` at the window edge pulls in older history.
Playback resume, forward-only marker persistence, auto-advance-on-new, and
removal fallback are all preserved. List view and progress indicator continue
to render off the (now windowed) children; their pagination UX is a follow-up.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01V8gsmdVd7R8PJtn4UFnC4J