Commit edb3e36
Arm clientOnly's swap without an owner so sibling hydration ids stay aligned
A hydrated clientOnly desynced DOM bookkeeping for every FOLLOWING sibling:
the client half armed its post-settle swap with onSettled, which registers a
tracked effect — a non-transparent owner, and every such owner consumes one
of the component's child ids at creation. The server half's only owner is the
fallback mirror memo, so the client ran one id ahead: a sibling created after
the clientOnly derived its hydration id one slot past the server's (_hk=30
server, key 40 asked), its template claim missed the registry, and insert
tracked a freshly-cloned phantom node that was never inserted (insertExpression
skips while hydrating). The DOM looked correct — the unclaimed server node
just stayed put — until the sibling's first post-hydration re-render
reconciled against the detached phantom and inserted the new content beside
the orphaned server node instead of replacing it. First surfaced as duplicated
nodes after an HMR hot-swap of a component following a clientOnly; any
signal-driven element swap in a following sibling hits it.
The swap is now armed through sharedConfig.onHydrationEnd — the ownerless
"all hydration complete" channel (waits for pending streamed boundaries,
microtask-fires when already done) — so clientOnly consumes exactly one child
id on both sides. New parity-harness scenario client-only-sibling-update pins
the contract: a resolving clientOnly followed by an element-swapping hole,
asserting the post-settle update REPLACES (both loaded and streamed modes).
Co-authored-by: Cursor <cursoragent@cursor.com>1 parent 2bb02e0 commit edb3e36
4 files changed
Lines changed: 59 additions & 8 deletions
File tree
- .changeset
- packages/solid-web
- src
- test/harness
- __artifacts__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
22 | 21 | | |
23 | 22 | | |
24 | 23 | | |
| |||
495 | 494 | | |
496 | 495 | | |
497 | 496 | | |
498 | | - | |
| 497 | + | |
499 | 498 | | |
500 | | - | |
501 | | - | |
502 | | - | |
| 499 | + | |
503 | 500 | | |
504 | 501 | | |
505 | 502 | | |
506 | 503 | | |
507 | 504 | | |
508 | 505 | | |
509 | 506 | | |
510 | | - | |
511 | | - | |
512 | | - | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
513 | 519 | | |
514 | 520 | | |
515 | 521 | | |
| |||
Lines changed: 5 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
649 | 649 | | |
650 | 650 | | |
651 | 651 | | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
652 | 677 | | |
653 | 678 | | |
654 | 679 | | |
| |||
924 | 949 | | |
925 | 950 | | |
926 | 951 | | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
927 | 962 | | |
928 | 963 | | |
929 | 964 | | |
| |||
0 commit comments