{{ message }}
fix: guard openNodeDetail against a stale-response race (#97)#113
Merged
Conversation
Clicking table A in the fullscreen schema graph then quickly clicking table B before A's fetch resolved let A's slower response land last and silently replace B's already-mounted detail pane + selection ring — last-resolved-wins instead of last-clicked-wins. openNodeDetail now tracks the most recently requested node per overlay document and drops a fetch whose click has since been superseded. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01784dKCpk5W7rdpUAwcQnix
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.

What & why
The fullscreen schema graph's node detail pane had a stale-response race: click table A, then quickly click table B before A's
ch.loadTableDetailfetch resolves, and if A resolves after B, A'sopenDetailPanecall fires last and silently replaces B's already-mounted pane + selection ring with A's stale data — last-resolved wins instead of last-clicked. Filed as #97 during #85's review; predates that PR.openNodeDetailnow stashes the clicked node as a per-overlay-document token (keyed by the same document resolutionopenDetailPaneuses) before kicking off the fetch, and checks it's still current before the final mount — a superseded fetch's result is dropped.Verification
tests/unit/app.test.js) deterministically forcing the out-of-order resolution via a manually-controlled promise.createAppfixture (per-repo pattern, deleted after use): reproduced the exact race — reverting just theapp.jsfix made the test fail (pane reverted to the stalelin.events), confirming both that the test discriminates and that the fix holds.npm run test:e2e(Chromium/Firefox/WebKit): Chromium + WebKit clean; 13 FirefoxbeforeEachtimeouts reproduced identically on unmodifiedmainin this sandbox (pre-existing environment flakiness, unrelated to this change).Checklist
npm testpasses (the per-file coverage gate is non-negotiable)npm run buildsucceeds (single-filedist/sql.html)src/core/, network insrc/net/(injected fetch), DOM insrc/ui/CHANGELOG.md([Unreleased]) updatedinboxitem, not tracked in roadmap Roadmap to 1.0.0 #68 or an ADRCloses #97
🤖 Generated with Claude Code
https://claude.ai/code/session_01784dKCpk5W7rdpUAwcQnix