fix(streamdown): re-render memoized components when node offset changes - #538
fix(streamdown): re-render memoized components when node offset changes#538julesyoungberg wants to merge 3 commits into
Conversation
|
@julesyoungberg is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
|
This fixes the case where content grows, but there is a case it cannot reach: a replacement of the same length moves no offset either. const { container, rerender } = render(<Streamdown>{"Revenue grew"}</Streamdown>);
rerender(<Streamdown>{"Booking grew"}</Streamdown>); // same length, same offsets
container.textContent; // "Revenue grew" — with or without this PR
The reason offset does not close it is that any position — line, column or offset — describes where the text came from, not what the component renders. I opened #584, which replaces the position comparison with React's own shallow prop comparison minus Not trying to steamroll this one — if the maintainers prefer the narrower change, the offset fix here is strictly better than what is on |
|
Thanks for PR @julesyoungberg, I'm closing this in favor of #584. |
Description
Fixes stale DOM when markdown is updated in the middle of an existing block. Memoized leaf components (
ol,ul,p, headings, etc.) usesameNodePositionto skip re-renders, but it only comparedlineandcolumn. When content changed without updating line/column (onlyoffset, e.g. injecting a link mid-line), React kept stale output until Streamdown remounted.sameNodePositionis shared by all memoized markdown components viasameClassAndNode, so this fix applies broadly rather than to a single element type.Type of Change
Changes Made
offset?: numbertoMarkdownPointand compareposition.start.offset/position.end.offsetinsameNodePosition(packages/streamdown/lib/components.tsx)"should re-render when only offset changes"(packages/streamdown/__tests__/components-rerender.test.tsx).changeset/fair-balloons-share.md)Testing
pnpm exec vitest run __tests__/components-rerender.test.tsxAll 18 tests in that file pass.
Checklist
pnpm changeset)Additional Notes
No documentation or inline comment changes — this is an internal comparator fix with no API surface change. The new test documents the edge case.