Skip to content

Commit 60861e3

Browse files
committed
fix: prevent overwriting unsaved user edits during async save in executeSave function
バグ: executeSave の await 中にユーザー入力 → save完了後 古い内容でstore上書き → CodeMirror/Monaco エディタ巻き戻り。さらに clearSaveTimer が新タイマー消去 → 新入力も永久に保存されない。 原因コード(修正前): await fileRepository.saveFileByPath(projectId, path, content); savingPaths.delete(path); clearSaveTimer(path); // 新タイマー消す updateAllTabsByPath(path, content, false); // 古いcontentでstore上書き await 中に v2 入力 → store: v2、タイマー: 新 → save完了 → clearSaveTimer で新タイマー消去、updateAllTabsByPath で store を v1 に戻す → valtio検知 → React re-render → content prop変化 → CodeMirror view.dispatch 即座に全文置換、Monaco model.setValue で巻き戻り。 修正後: await fileRepository.saveFileByPath(projectId, path, content); savingPaths.delete(path); const currentContent = getContentFromPanes(tabState.panes, path); if (currentContent === undefined || currentContent === content) { clearSaveTimer(path); updateAllTabsByPath(path, content, false); } // 変わってたら何もしない → 新タイマー生存、store維持 save中に入力あり → 何もしない。新タイマーが生存し次のsaveで v2 保存。store上書きなし → re-renderなし → エディタ巻き戻りなし。
1 parent be74314 commit 60861e3

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

src/stores/tabState/contentSync.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,16 @@ async function executeSave(path: string, content: string): Promise<boolean> {
103103
savingPaths.add(path);
104104
await fileRepository.saveFileByPath(projectId, path, content);
105105
savingPaths.delete(path);
106-
clearSaveTimer(path);
107-
updateAllTabsByPath(path, content, false);
106+
107+
// Check if the user typed new content during the async save.
108+
// If so: do NOT overwrite the store/model (would revert edits) and do NOT
109+
// cancel the new debounce timer (it must fire to persist the newer content).
110+
const currentContent = getContentFromPanes(tabState.panes, path);
111+
if (currentContent === undefined || currentContent === content) {
112+
clearSaveTimer(path);
113+
updateAllTabsByPath(path, content, false);
114+
}
115+
108116
for (const l of saveListeners) l(path, true);
109117
return true;
110118
} catch (error) {

0 commit comments

Comments
 (0)