Skip to content

feat(wait)!: Auto-disconnect observer after wait() resolves#70

Merged
untemps merged 2 commits into
betafrom
feat/50-auto-disconnect-after-wait
May 1, 2026
Merged

feat(wait)!: Auto-disconnect observer after wait() resolves#70
untemps merged 2 commits into
betafrom
feat/50-auto-disconnect-after-wait

Conversation

@untemps
Copy link
Copy Markdown
Owner

@untemps untemps commented May 1, 2026

Summary

Calls this.clear() inside settle() before resolve() so the internal observer is disconnected synchronously before the Promise settles. Previously, cleanup relied solely on .finally(), which runs after .then() handlers — meaning isObserving could be observed as true inside a .then() chained on the returned promise. The .finally() is kept as a safety net for the cancel/reject path.

Changes

  • src/DOMObserver.tssettle() now calls this.clear() before resolve(value)
  • src/__tests__/DOMObserver.test.ts — two new tests: isObserving === false inside .then() handler; clear() after wait() is a no-op
  • README.md — explicit example showing isObserving === false after await wait(), note that clear() afterwards is a safe no-op

⚠️ Breaking changes

  • isObserving: returns false immediately after wait() resolves. Code that branched on obs.isObserving === true right after await obs.wait() must be updated.
  • Migration: no changes needed for the common await obs.wait() pattern. Calling obs.clear() after wait() resolves continues to work (no-op).

Test plan

  • tsc --noEmit passes
  • All 83 tests pass (vitest run)
  • Coverage remains at 100% statements/functions/lines
  • isObserving === false verified inside .then() handler (new test)
  • Double clear() after wait() is safe (new test)

Closes #50

untemps added 2 commits May 1, 2026 14:28
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.
@untemps untemps merged commit 235af7c into beta May 1, 2026
@untemps untemps deleted the feat/50-auto-disconnect-after-wait branch May 1, 2026 14:36
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.
@untemps
Copy link
Copy Markdown
Owner Author

untemps commented May 1, 2026

🎉 This PR is included in version 5.0.0-beta.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@untemps untemps mentioned this pull request May 2, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant