Skip to content

Fix reactive list separators corrupting sibling output - #454

Merged
timotheeguerin merged 1 commit into
alloy-framework:mainfrom
qiaozha:fix/reactive-joiner-node-identity
Nov 3, 2026
Merged

timotheeguerin merged 1 commit into
alloy-framework:mainfrom
qiaozha:fix/reactive-joiner-node-identity

Conversation

@qiaozha

@qiaozha qiaozha commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Keep mapJoin separators in a shallowRef so rendered Alloy nodes retain their identity during reactive updates.

This fixes output corruption affecting multipart <For> separators, including TypeScript union members that resolve through forward references.

Root cause

Since the AlloyNode renderer introduced in #402, JSX intrinsics are live nodes with parent and sibling pointers. A separator such as <><br />{"| "}</> contains one of these nodes.

createJoinerRef currently stores separators in a deep Vue ref. This proxies the node and its sibling pointers. Runtime range reconciliation compares sibling pointers with their original end-marker objects; a proxied pointer no longer equals the raw marker, so updating an item can remove subsequent items and even output following the list.

For example, a union of three forward-referenced interfaces becomes:

type Example = First | ;

Using a shallowRef preserves reactive separator replacement without proxying the rendered children. It also removes the unnecessary cast previously used by createJoinerRef.

Coverage

  • Core regression: update three non-empty list items with a multipart separator, preserve a following sibling, then remove and restore the middle item's content.
  • TypeScript regression: emit a union whose three interface declarations follow it, with a multipart separator.
  • Both regression tests fail on the current base and pass with this fix.
  • Document the use of shallow refs for rendered children and include a Chronus fix entry.

Discovered while validating Azure/js-provisioning-lib#599 after upgrading Alloy core from 0.23.0 to 0.24.1.

Validation

  • pnpm format
  • pnpm build
  • pnpm test: 243 test files and 2,116 tests passed
  • pnpm lint
  • pnpm run sync-publish-config:check
  • Regenerated the downstream serialization AST using the built fixed core: zero TypeScript parse errors, and the complete output matches the pre-upgrade AST after formatting normalization.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • ✅ @alloy-js/core
Show changes

@alloy-js/core - fix ✏️

Preserve rendered node identity in multipart list separators so reactive item updates and forward references do not remove subsequent output.

@timotheeguerin
timotheeguerin merged commit e6c9a4c into alloy-framework:main Nov 3, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants