🐛 fix: folder monitor re-detect deleted files, atomic sync save

- Folder monitor: clear _seenFiles entry on file unlink so re-added
  files (e.g. re-encoded) are detected again
- Sync IPC save (beforeunload): use atomic write pattern with backup
  (.bak) creation, matching the async _atomicWrite behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Administrator 2026-03-21 13:31:54 +01:00
parent f6d4a7de3d
commit 4ecf406660
2 changed files with 17 additions and 1 deletions

View File

@ -35,6 +35,11 @@ class FolderMonitor extends EventEmitter {
this._watcher = chokidar.watch(folderPath, watchOptions); this._watcher = chokidar.watch(folderPath, watchOptions);
this._watcher.on('add', (filePath) => this._onNewFile(filePath)); this._watcher.on('add', (filePath) => this._onNewFile(filePath));
this._watcher.on('unlink', (filePath) => {
// Allow re-added files (e.g. re-encoded) to be detected again
const normalized = filePath.replace(/\\/g, '/').toLowerCase();
this._seenFiles.delete(normalized);
});
this._watcher.on('error', (err) => this.emit('error', err)); this._watcher.on('error', (err) => this.emit('error', err));
} }

13
main.js
View File

@ -883,11 +883,22 @@ ipcMain.handle('save-global-settings', async (_event, globalSettings) => {
}); });
// Synchronous save for beforeunload — blocks renderer until write completes // Synchronous save for beforeunload — blocks renderer until write completes
// Uses atomic write pattern (tmp + backup + rename) to prevent corruption
ipcMain.on('save-global-settings-sync', (event, globalSettings) => { ipcMain.on('save-global-settings-sync', (event, globalSettings) => {
try { try {
const current = configStore.load(); const current = configStore.load();
current.globalSettings = globalSettings; current.globalSettings = globalSettings;
fs.writeFileSync(configStore.filePath, JSON.stringify(current, null, 2)); const data = JSON.stringify(current, null, 2);
const tmpPath = configStore.filePath + '.tmp';
const backupPath = configStore.filePath + '.bak';
fs.writeFileSync(tmpPath, data, 'utf-8');
if (fs.existsSync(configStore.filePath)) {
const existing = fs.readFileSync(configStore.filePath, 'utf-8');
if (existing && existing.trim().length > 2) {
fs.writeFileSync(backupPath, existing, 'utf-8');
}
}
fs.renameSync(tmpPath, configStore.filePath);
} catch {} } catch {}
event.returnValue = true; event.returnValue = true;
}); });