fix(renderer): preserve hydrated Show range ownership - #165
Merged
Conversation
smiggleworth
force-pushed
the
fix/mixed-show-tail-hydration
branch
from
July 27, 2026 20:55
b5bca4c to
0c39a34
Compare
There was a problem hiding this comment.
Pull request overview
This PR addresses askr#164 by tightening hydration cursor/ownership handling when empty <Show> boundaries precede populated boundaries/components, preventing tail duplication and preserving server-rendered node identity. It also extends SSR/SSG portal output with stable comment anchors to support strict hydration parity without inserting visible wrapper elements.
Changes:
- Preserve hydration cursor/ownership across empty
Showboundaries and transparent multi-node component results (fragment/array), including rollback-safe range adoption. - Introduce SSR portal anchor markers (
askr-portal-anchor:*) and retain empty automatic portal host markers when needed for hydration stability. - Add regression coverage for empty-
Showtails, keyedForadoption after static siblings, component-returned arrays, and default portal hydration parity; update docs and version.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/jsdom/ssr/portal-rendering.test.tsx | Updates SSR expectations to include portal hydration anchors. |
| tests/jsdom/ssr/for-static-sibling-hydration.test.tsx | Adds regression test for keyed For adoption after a static sibling during hydration. |
| tests/jsdom/ssr/empty-show-tail-hydration.test.tsx | Adds regression coverage for empty Show boundaries preserving tail identity and rollback behavior. |
| tests/jsdom/ssr/default-portal-hydration-parity.test.tsx | Adds parity test ensuring default portal anchors/DOM topology remain stable through hydration and updates. |
| tests/jsdom/ssr/component-array-hydration.test.tsx | Adds hydration tests for component-returned arrays, nested scopes, and portal identity preservation. |
| tests/jsdom/ssg/static-gen.test.tsx | Updates SSG expectations to include retained portal anchor markers. |
| tests/jsdom/dom/component-array-structure.test.tsx | Adds SPA structure/update/rollback coverage for component-returned arrays. |
| src/ssr/render-sync.ts | Renders SSR_PORTAL_ANCHOR tokens and retains empty automatic host markers when required for hydration. |
| src/runtime/portal.ts | Emits SSR portal anchor tokens at writer sites; centralizes portal token creation. |
| src/runtime/context.ts | Makes scope providers transparent and introduces durable internal identity keys for hydration ownership. |
| src/runtime/component-commit.ts | Allows placeholder replacement to target comment hosts for ownership/placeholder tracking. |
| src/renderer/element-children.ts | Improves mixed control cursor handling and hydrator sync for components (incl. hydration range end + empty cursor preservation). |
| src/renderer/dom-host.ts | Extends syncComponentElement signature to support hydration range end and cursor preservation options. |
| src/renderer/component-range-commit.ts | Adds fast-path for transparent nested results during component range replacement. |
| src/renderer/component-host.ts | Supports SSR portal anchor comment hosts and adopts hydrated multi-node component ranges with bounded end cursors. |
| src/renderer/component-host-results.ts | Adds utilities for retaining owner chains and materializing empty hydration placeholders/SSR portal anchor adoption. |
| src/renderer/component-host-instances.ts | Extends identity matching to include internal identity keys and range-based matching for stable hydration. |
| src/renderer/component-fragment-range.ts | Implements adoption of hydrated multi-node ranges and preserves foreign automatic portal hosts during staging. |
| src/renderer/child-shape.ts | Defines “transparent component result” and “transparent range result” helpers used across hydration/commit paths. |
| src/renderer/boundary-range-sync.ts | Improves adoption gating for hydrated boundary elements and handles pending hydration in mixed parents. |
| src/renderer/boundary-range-adoption.ts | Adds canAdoptHydratedElement helper and extends host sync signature to match hydration needs. |
| src/renderer/boundaries.ts | Extends boundary host sync signature for hydration cursor/range handling. |
| src/common/portal.ts | Introduces portal anchor symbol, token helpers, and marker detection for hydration anchors. |
| src/common/control.ts | Adds transparent-result marking/detection for component result handling. |
| package.json | Bumps version to 0.0.78. |
| package-lock.json | Locks version bump to 0.0.78. |
| docs/guides/platform-recipes.md | Updates documented verified version to 0.0.78. |
| docs/core/rendering.md | Documents transparent component ranges and portal anchor retention behavior in SSR/SSG/hydration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This resolves askr#164: hydration must preserve existing tail identity when an inactive
<Show>precedes an active<Show>in the same boundary chain.The branch adds a targeted SSR+SPA hydration fix and regression coverage for mixed populated Show tails.
Closes #164