fix(core): handlers inside each lose their loop variables in the headless runtime - #142
Merged
Merged
Conversation
…less runtime
resolveTree expands an each into one copy of its children per item, with
item and index in scope while props resolve. It didn't keep them on the node,
and dispatch resolved handlers against state and data only. A button in a list
with on_click setting '{item.id}' wrote an empty value. NodeRenderer passes
loop context to handlers, so the headless runtime disagreed with it.
Nodes resolved inside a loop now carry a loop field, and dispatch layers it
back into the resolver context. Nodes outside a loop are unchanged.
dispatchHandler takes an optional loop argument for the same reason.
The new test clicks the second of two rows, since a one-row loop could pass
by accident.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Sep 27, 2026
DevRohit06
added this pull request to stack #144
September 27, 2026 05:37
DevRohit06
added a commit
that referenced
this pull request
Sep 27, 2026
…145) Bumps @ripple-ui/svelte to 0.8.0 and @ripple-ui/core to 0.6.0 for the release that carries the slim headless runtime, the slim manifest and the loop-variable fix for headless handlers (#142, #143). The release workflow used to try npm on every v* tag. Every such run failed without an NPM_TOKEN, and with a token set anywhere a tag would publish whether or not that was intended. npm publishing now runs only on a manual dispatch with publish_npm: true. A tag creates the GitHub release alone. That release now carries a packed tarball of each package next to the manifest bundle, with svelte's core dependency rewritten to ^<core version> as the npm step does, so it can be installed without npm. Simulated on a copy of both packages: ripple-ui-core-0.6.0.tgz and ripple-ui-svelte-0.8.0.tgz, the latter depending on @ripple-ui/core ^0.6.0. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
A button inside an
eachwhose handler uses{item.id}works inNodeRendererbut writes an empty value in the headless runtime.resolveTreeexpands the loop withitemandindexin scope, so props come out right. The loop variables weren't kept on the resolved node, though, andruntime.dispatchresolved handlers against{state, data}only. By the time a handler runs, the loop that produced the node is gone.The fix:
ResolvedNode.loopholds the loop variables, and only nodes resolved inside aneachget it. Every other node is byte-for-byte what it was.dispatchlayersnode.loopback into the resolver context.dispatchHandlertakes an optionalloopargument, so both paths share one context builder.Tests: a two-row list where the test clicks the second row and expects
b:1(it got':'before the fix; a one-row list could pass by accident), plus a check that nodes outside a loop carry noloop. The core suite passes (298),tscis clean, and the svelte package'sstate-paritytest passes.🤖 Generated with Claude Code