Description
On a connection with a large schema, typing in the query editor drops and reorders characters, and the cursor jumps back to the start of the document. It gets bad enough that you can't write a query normally. It does not happen on the small sample connections, so it is easy to miss until you connect to a real database with a few hundred tables.
Steps to Reproduce
- Connect to a database with a large schema. I reproduced it on SQLite with 400 tables, but any provider with a large schema does it.
- Open a query tab and click into the editor.
- Type a sentence at a normal pace, for example
SELECT id FROM entity_0001 WHERE owner_id = 42 ORDER BY created_at DESC.
- Watch characters land out of order and the cursor snap to line 1.
Expected Behavior
Each character is inserted at the caret and the caret moves forward one position, regardless of schema size.
Actual Behavior
Characters are dropped and reordered as you type, and the caret resets to the top. Typing the string above produced SEETi RMett_01WEEonri 2ODRB rae_tDSC in the buffer instead of the text I typed. The same typing into a small-schema connection is fine, as it typing very slowly.
Screenshots
N/A.
Environment
Please provide the following information:
- LibreDB Studio Version: 0.15.0
- Browser: Chrome
- OS: macOS 26.6.2
- Node.js/Bun Version: Bun 1.4.0
- Database Type: SQLite
- Database Version: SQLite 3 (bundled)
Additional Context
The editor is @monaco-editor/react 4.7.0, running under Next.js 16.3.4 with Turbopack. The schema size is an amplifier, not the cause. A larger schema makes the surrounding UI do more render work per keystroke, which widens the timing window the bug depends on, so it shows up on large-schema connections and not on the small samples.
Possible Solution
QueryEditor renders Monaco as a controlled component with value={value}, and that prop is fed from onContentChange on every keystroke. Studio writes each keystroke into currentTab.query, which flows straight back in as value. @monaco-editor/react runs an executeEdits over the full model range whenever the value prop changes and differs from the buffer. When a keystroke lands in the model between the state update and the re-render, the prop arrives one keystroke stale, the full-range edit rewrites the whole buffer, and the caret resets to (1,1).
One fix is to stop driving the buffer from the value prop on the keystroke path. Make the editor uncontrolled with defaultValue, and route external changes such as tab switch, Format, and Clear through a single guarded effect. I have this working and confirmed on the 400-table setup: typing lands verbatim, the caret only moves forward, and there are no full-buffer rewrites during typing. I will open a PR against this issue.
Logs
No console errors. The failure is a silent buffer rewrite, not a thrown error.
Description
On a connection with a large schema, typing in the query editor drops and reorders characters, and the cursor jumps back to the start of the document. It gets bad enough that you can't write a query normally. It does not happen on the small sample connections, so it is easy to miss until you connect to a real database with a few hundred tables.
Steps to Reproduce
SELECT id FROM entity_0001 WHERE owner_id = 42 ORDER BY created_at DESC.Expected Behavior
Each character is inserted at the caret and the caret moves forward one position, regardless of schema size.
Actual Behavior
Characters are dropped and reordered as you type, and the caret resets to the top. Typing the string above produced
SEETi RMett_01WEEonri 2ODRB rae_tDSCin the buffer instead of the text I typed. The same typing into a small-schema connection is fine, as it typing very slowly.Screenshots
N/A.
Environment
Please provide the following information:
Additional Context
The editor is @monaco-editor/react 4.7.0, running under Next.js 16.3.4 with Turbopack. The schema size is an amplifier, not the cause. A larger schema makes the surrounding UI do more render work per keystroke, which widens the timing window the bug depends on, so it shows up on large-schema connections and not on the small samples.
Possible Solution
QueryEditorrenders Monaco as a controlled component withvalue={value}, and that prop is fed fromonContentChangeon every keystroke. Studio writes each keystroke intocurrentTab.query, which flows straight back in as value. @monaco-editor/react runs anexecuteEditsover the full model range whenever the value prop changes and differs from the buffer. When a keystroke lands in the model between the state update and the re-render, the prop arrives one keystroke stale, the full-range edit rewrites the whole buffer, and the caret resets to (1,1).One fix is to stop driving the buffer from the value prop on the keystroke path. Make the editor uncontrolled with defaultValue, and route external changes such as tab switch, Format, and Clear through a single guarded effect. I have this working and confirmed on the 400-table setup: typing lands verbatim, the caret only moves forward, and there are no full-buffer rewrites during typing. I will open a PR against this issue.
Logs
No console errors. The failure is a silent buffer rewrite, not a thrown error.