Repository navigation
test(web): pin #4372, a rejected streamed fragment emptying a text-only region - #4389
Conversation
…4374) A `<Loading>` with a bare-string fallback, the sole content of a markerless parent, leaves the hole's `current` as that string after the root pass. `reclaimRegion` bailed for non-node currents, so after the streamed `$df` swap the content pass reconciled against the stale string: the server's text stayed beside a fresh copy (a nested Errored's fallback rendered twice), or text after an element moved or was replaced instead of adopted. While hydrating, a disconnected-or-primitive `current` now re-claims the region, as it does when the nodes it tracks are gone. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
…d its node (#4372) An Errored outside a streamed Loading whose fragment rejects: the client hydrated the shell, so the root insert tracked the claimed fallback's text ("[LOAD]") as a sole text child. The fragment's swap replaced that node, and the rejected fragment's fresh render cleared what the swap put in, so the Errored's fallback text was written to `parent.firstChild`, which was null: TypeError, REACTIVITY_HALTED, an empty <main>. The text fast path now needs that node to exist; with none, the value is inserted like a first one, as the element path already does. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
🦋 Changeset detectedLatest commit: cb53a88 The changes in this PR will be included in the next version bump. This PR includes changesets to release 15 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Size (brotli, eager entry chunk)
|
Coverage Report for CI Build 40800912527Warning Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes. Coverage remained the same at 78.516%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Merging this PR will not alter performance1 warning
Comparing Footnotes
|
…ext node back (#4372) Moves the #4372 fix off `insertExpression`'s hot text path, which every app ships, to the cold path that breaks its assumption. A streamed Loading whose fallback an insert claimed as its sole text child: the fragment's swap takes that text node with the placeholder range, and the rejected fragment's fresh render clears what the swap put in, leaving the region empty. The next text value (an outer Errored's fallback, or text the content renders fresh) was then written to a missing first child. The clear now leaves an emptied region an empty text node, which that write fills. The insert fast path is back as it was on next; the hand-removal spec is pinned as a known failure. Adds the `text` shape: an empty rejected template under no Errored, the same crash on next. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
… next A `placeholder(id)` helper serves the region capture and the two existing `pl-*` lookups, so the fix costs +42 B minified in hydrating bundles (from +85 B) and 0 B in every CSR scenario and the non-hydrating floors. The three scenarios that sat at their recorded minified get a dated ledger line. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
…dration.ts clear and its ledger edits (#4382 covers #4372) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
Summary
Covers #4372, which is fixed by #4382. This PR is stacked on #4382's branch: merge #4382 first. After that, this PR's diff is tests only.
Before.
<main><Errored fallback={() => "[ERR]"}><Loading fallback="[LOAD]"><span>{m()}</span></Loading></Errored></main>, wheremrejects after the shell. When the client hydrates the shell and the rejected fragment arrives later (the normal streaming order),insertExpressionthrowsTypeError: Cannot set properties of null (setting 'data'). The reactive system halts withREACTIVITY_HALTEDand<main>is left empty.After. Each case shows its outcome (
[ERR]or!a). Nothing throws, reactivity stays up, and the client never asks again.How. An earlier version of this PR changed solid's
hydration.ts(+42 B). #4382'sreclaimRegionchange fixes the same root cause in@solidjs/web: a hole holding the fallback's raw string re-claims its region after the swap. It also covers a case thehydration.tschange missed, where a non-text node sits in the region. So thehydration.tschange, its changeset and its ledger edits are dropped, and only the tests stay.How did you test this change?
packages/web/test/hydration/errored-outside-loading-4372.spec.tsx(hydrate config, real bootstrap viaharness/hydration-bootstrap.ts). It covers 5 shapes (app,inner,sibling,element,text), each hydrated both after and before the chunk. Onnext,app,innerandtextbefore the chunk fail. With fix(web): a hydrating hole holding a raw string re-claims its region (#4374) #4382, all 10 pass.test/server/hydration-harness.spec.tsx.packages/web/test/insert-sole-text-removed-4372.spec.tsxstays pinned astest.fails: code outside Solid that removes a sole text child by hand still breaks the next write.Suites, after merging
next@ 957f065 and #4382, then a cleanturbo build --force:served-error-no-reask"[streamed] the content waits for its sheet")Size: no source change beyond #4382.
🤖 Generated with Claude Code
https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2