feat(wait)!: Auto-disconnect observer after wait() resolves#70
Merged
Conversation
Call this.clear() in settle() before resolve() so the observer is disconnected synchronously before the promise resolves, rather than relying on .finally() alone. Callers see isObserving === false in .then() handlers and immediately after await. .finally() is kept as a safety net for the cancel/reject path. BREAKING CHANGE: isObserving returns false immediately after wait() resolves. Code branching on isObserving === true after await obs.wait() must be updated. Calling clear() after wait() is still safe (no-op).
Add explicit isObserving example showing false after await, and note that calling clear() afterwards is a safe no-op.
github-actions Bot
pushed a commit
that referenced
this pull request
May 1, 2026
# [5.0.0-beta.1](v4.8.0...v5.0.0-beta.1) (2026-05-01) ### Features * Auto-disconnect observer after wait() resolves ([#70](#70)) ([235af7c](235af7c)) ### BREAKING CHANGES * wait() now clears internal state synchronously before the Promise resolves, instead of relying on .finally() for deferred cleanup. Before: const { node } = await obs.wait('#foo') obs.isObserving // true — observer still running at this point After: const { node } = await obs.wait('#foo') obs.isObserving // false — cleared before promise settles Affected scenarios: - Code checking obs.isObserving === true after await obs.wait() must update that expectation to false. - Code calling obs.clear() after wait() resolves continues to work (no-op). - Code relying on the timeout timer firing after resolution: cleanup now happens at resolution time, not when the timer would have expired.
Owner
Author
|
🎉 This PR is included in version 5.0.0-beta.1 🎉 The release is available on: Your semantic-release bot 📦🚀 |
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.
Summary
Calls
this.clear()insidesettle()beforeresolve()so the internal observer is disconnected synchronously before the Promise settles. Previously, cleanup relied solely on.finally(), which runs after.then()handlers — meaningisObservingcould be observed astrueinside a.then()chained on the returned promise. The.finally()is kept as a safety net for the cancel/reject path.Changes
src/DOMObserver.ts—settle()now callsthis.clear()beforeresolve(value)src/__tests__/DOMObserver.test.ts— two new tests:isObserving === falseinside.then()handler;clear()afterwait()is a no-opREADME.md— explicit example showingisObserving === falseafterawait wait(), note thatclear()afterwards is a safe no-opisObserving: returnsfalseimmediately afterwait()resolves. Code that branched onobs.isObserving === trueright afterawait obs.wait()must be updated.await obs.wait()pattern. Callingobs.clear()afterwait()resolves continues to work (no-op).Test plan
tsc --noEmitpassesvitest run)isObserving === falseverified inside.then()handler (new test)clear()afterwait()is safe (new test)Closes #50