fix(editor): stop keystrokes being overwritten on large schemas - #809
Open
nycjay wants to merge 1 commit into
Open
fix(editor): stop keystrokes being overwritten on large schemas#809nycjay wants to merge 1 commit into
nycjay wants to merge 1 commit into
Conversation
The query editor rendered <Editor value={...}> as a controlled component and
fed that prop from onContentChange on every keystroke. @monaco-editor/react's
controlled-value effect runs executeEdits over the full model range whenever
the prop changes and differs from the buffer; when a keystroke lands between
the state update and the re-render, the prop is one keystroke stale, so the
full-range edit rewrites the buffer and snaps the caret to line 1. A large
schemaContext widens that window (extra parse/render work), which is why it
showed up on large-schema connections and not on the small samples.
Make the editor uncontrolled: pass defaultValue instead of value, so the
library's value effect early-returns, and route external changes (tab switch,
Format, Clear, setValue) through the existing useEffect([value]) that guards
self-echoes via lastSyncedValueRef.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
The query editor rendered
<Editor value={...}>as a controlled component and fed that prop from onContentChange on every keystroke. @monaco-editor/react's controlled-value effect runs executeEdits over the full model range whenever the prop changes and differs from the buffer; when a keystroke lands between the state update and the re-render, the prop is one keystroke stale, so the full-range edit rewrites the buffer and snaps the caret to line 1. A large schemaContext widens that window (extra parse/render work), which is why it showed up on large-schema connections and not on the small samples.Make the editor uncontrolled: pass defaultValue instead of value, so the library's value effect early-returns, and route external changes (tab switch, Format, Clear, setValue) through the existing useEffect([value]) that guards self-echoes via lastSyncedValueRef.
Description
Fixes a bug where typing in the query editor on a large-schema connection dropped and reordered characters and reset the cursor to line 1. The editor is now uncontrolled on the keystroke path, so a keystroke no longer races a stale
valueprop.Type of Change
Related Issue
Closes #808
Changes Made
src/components/QueryEditor.tsx: passdefaultValue={value}instead ofvalue={value}so@monaco-editor/react's controlled-value effect stays at its early return and no longer runs a full-rangeexecuteEditson a stale prop.useEffect([value]), which guards self-echoes vialastSyncedValueRefso it does not clobber the buffer during active typing.tests/components/QueryEditor.test.tsx: added regression tests for the uncontrolled-editor contract and the stale-echo guard.Testing
Reproduced and confirmed the fix in a real browser against a 400-table SQLite schema. Before: typing
SELECT id FROM entity_0001 WHERE owner_id = 42 ORDER BY created_at DESCproducedSEETi RMett_01WEEonri 2ODRB rae_tDSC. After: the text lands verbatim, the caret only moves forward, and instrumenting the live editor showed zerosetValue/executeEditscalls during typing (one applyEdits per character, which is the normal insertion path).Test Environment
Screenshots (if applicable)
N/A
Reproducing manually
The bug only shows up on a large schema, so you need one to see it. This script builds a 400-table SQLite database you can connect to. Save it as
gen-large-sqlite.mjsand runbun gen-large-sqlite.mjs(it writes todata/large-schema-test.dbby default; pass a count and path to override, e.g.bun gen-large-sqlite.mjs 800 /tmp/big.db).Then add a SQLite connection in the UI pointing at the generated file, open a query tab, and type a sentence at a normal pace. On
mainthe characters scramble and the cursor jumps to line 1, with this fix typing is much more smooth. I didn't include this reproduction script in the codebase itself as a test fixture, but can if maintainers would prefer.Checklist
bun run test:coverageandbun run coverage:check)src/lib/db/providers/, I updated the matchingdocs/providers/documentation andtests/integration/db/tests in the same PR (provider triad)Additional Notes
Documentation checkbox is left unchecked because this is an editor-behavior fix with no user-facing docs to update. The provider-triad checkbox does not apply: this PR does not touch
src/lib/db/providers/.On the coverage gate: I could not run the full merged gate locally (
tests/run-core.shusesmapfile, which needs bash 4+, and this machine is on bash 3.2; Helm is not installed so the chart checks cannot run either). I ran the component suite directly (108 pass) and measured the merged component lcov for the changed file at 100% (QueryEditor.tsx427/427 lines). The CI job is the authoritative gate for the full merged report.