Send and receive messages with follow-bottom behavior, scroll-away detection, bulk loading, and live virtualization stats.
Messages are stored oldest-first and rendered top-to-bottom — normal chronological
order, no inverted geometry. Identity comes from getMessageId, not
array indices.
Two states only: following the bottom, or scrolled away. Send a message while pinned
and the viewport tracks it; scroll up and it holds your position.
Only the messages inside the viewport (plus overscan) live in the DOM. Add 100
messages and watch In-DOM stay small while Total climbs.
Heights are measured with ResizeObserver and cached as prefix sums, so scroll
positioning stays smooth even across hundreds of variable-height rows.