Skip to content

fix: unobserve entry.target for once, not the current element prop#153

Merged
metonym merged 1 commit into
masterfrom
metonym/fix-once-unobserve-target
Jul 5, 2026
Merged

fix: unobserve entry.target for once, not the current element prop#153
metonym merged 1 commit into
masterfrom
metonym/fix-once-unobserve-target

Conversation

@metonym

@metonym metonym commented Jul 5, 2026

Copy link
Copy Markdown
Owner

The once callback in IntersectionObserver.svelte was unobserving the current element prop rather than the entry's own target. Since IntersectionObserver callbacks are delivered asynchronously, a stale entry could arrive after the element prop had already changed, causing unobserve to run against the new element instead of the one the entry actually belonged to. That left the new element unobserved and the old one potentially still observed, silently breaking the wiring after a fast element swap with once set.

The fix unobserves entry.target directly, matching the approach already used in MultipleIntersectionObserver and createIntersectionGroup.

Added a fixture and unit test that reproduce the race by swapping the observed element and then delivering a stale entry for the old element, confirming the new element stays observed and the old one does not. The test fails against the prior implementation and passes with the fix. Risk is low since the change only affects the once code path and mirrors existing, already-correct behavior elsewhere in the codebase.

Intersection callbacks are delivered asynchronously. If the `element`
prop changed between observation and delivery, a stale entry for the
old element ran `unobserve(element)` against the *new* element,
leaving the new element unobserved and the wiring silently dead.
Unobserve the entry's own target instead.

MultipleIntersectionObserver and createIntersectionGroup already used
entry.target; only the single-element component was affected.
@render
render Bot temporarily deployed to metonym/fix-once-unobserve-target - svelte-intersection-observer PR #153 July 5, 2026 20:21 Destroyed
@metonym
metonym merged commit 0a6efa8 into master Jul 5, 2026
3 checks passed
@metonym
metonym deleted the metonym/fix-once-unobserve-target branch July 5, 2026 20:23
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.

1 participant