Prototype fix for emberjs#19344: single native listener per event (invoker pattern) - #38
Open
johanrd wants to merge 1 commit into
Open
Prototype fix for emberjs#19344: single native listener per event (invoker pattern)#38johanrd wants to merge 1 commit into
johanrd wants to merge 1 commit into
Conversation
johanrd
force-pushed
the
todo-test-gh19344
branch
from
July 28, 2026 06:53
52caf45 to
8423c82
Compare
…voker
All {{on}} handlers for the same (element, event, capture/passive bucket)
now register with a single native listener that dispatches to a snapshot
of the handler list. Sibling handlers therefore run in one callback frame:
a render flush scheduled by one handler cannot run at a microtask
checkpoint and tear down the others before they are invoked.
Same architecture as Vue's event invoker. once= is implemented
per-handler; adds/removes counters track logical handler registration,
matching previous test expectations. Flips the GH#19344 repro from @todo
to a passing @test. Full suite: 9437 tests, 0 failures.
johanrd
force-pushed
the
prototype-fix-gh19344
branch
from
July 28, 2026 09:29
07b24ab to
7a84253
Compare
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.
Prototype for emberjs#19344, stacked on the failing-test branch (emberjs#21530).
All
{{on}}handlers for the same (element, event, capture/passive bucket) share one native listener dispatching to a snapshot of the handler list — sibling handlers run in a single callback frame, so a render flush scheduled by one handler cannot interleave at a microtask checkpoint and tear down the rest (Vue's invoker architecture).onceis per-handler; counters track logical registration.Scope: covers the reported same-element case. A cross-element variant exists (a handler's flush destroying an ancestor's
{{on}}before the event bubbles up to it); fixing that requires deferring teardown past the dispatch — i.e. deciding whether handlers may fire after their component is destroyed — which needs maintainer input and is deliberately not attempted here.Precedent — every mainstream framework funnels its handlers through a single native callback per dispatch; the surfaces that don't are exactly where this bug class lives:
el[veiKey]), handler swaps mutateinvoker.value, stale-event guard viae._vts <= invoker.attachednode[$$event]props