diff --git a/src/bulk-edit-modal.ts b/src/bulk-edit-modal.ts index 0a5e493..68db0b2 100644 --- a/src/bulk-edit-modal.ts +++ b/src/bulk-edit-modal.ts @@ -644,9 +644,8 @@ export class BulkEditModal extends Modal { const selProp = this.plugin.settings.selectionProperty; const deselect = this.deselectWhenFinished; - this.plugin.settings.lastSelectedProperty = property; try { - await this.plugin.saveSettings(); + await this.plugin.updateSetting("lastSelectedProperty", property); } catch (err: unknown) { console.warn("bulk-properties: failed to save lastSelectedProperty:", err); } diff --git a/src/main.ts b/src/main.ts index 970b8dd..b4a840e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,6 +10,7 @@ export default class BulkPropertiesPlugin extends Plugin { settings!: BulkPropertiesSettings; private statusBarEl: HTMLElement | null = null; private statusBarTimer: ReturnType | null = null; + private saveQueue: Promise = Promise.resolve(); override async onload() { await this.loadSettings(); @@ -167,7 +168,21 @@ export default class BulkPropertiesPlugin extends Plugin { } } - async saveSettings() { - await this.saveData(this.settings); + /** + * Serializes settings writes through a queue with copy-on-write + * semantics. Builds a candidate snapshot per call; only assigns + * it to `this.settings` after persistence succeeds. + */ + updateSetting( + key: K, + value: BulkPropertiesSettings[K], + ): Promise { + const save = this.saveQueue.then(async () => { + const candidate = {...this.settings, [key]: value}; + await this.saveData(candidate); + this.settings = candidate; + }); + this.saveQueue = save.then(() => {}, () => {}); + return save; } } diff --git a/src/settings.ts b/src/settings.ts index af779bf..231463a 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -98,7 +98,6 @@ export const DEFAULT_SETTINGS: BulkPropertiesSettings = { export class BulkPropertiesSettingTab extends PluginSettingTab { plugin: BulkPropertiesPlugin; - private saveQueue: Promise = Promise.resolve(); constructor(app: App, plugin: BulkPropertiesPlugin) { super(app, plugin); @@ -106,28 +105,21 @@ export class BulkPropertiesSettingTab extends PluginSettingTab { } /** - * Serializes settings writes through a queue so overlapping - * onChange calls cannot race. Each call snapshots the live - * settings only after all prior saves have committed. + * Updates a single setting key via the plugin's serialized + * copy-on-write save queue. */ - private updateSetting( + private async updateSetting( key: K, value: BulkPropertiesSettings[K], ): Promise { - const result = this.saveQueue.then(async () => { - const candidate = {...this.plugin.settings, [key]: value}; - try { - await this.plugin.saveData(candidate); - this.plugin.settings = candidate; - return true; - } catch (err: unknown) { - console.error("bulk-properties: failed to save settings:", err); - new Notice("Failed to save settings. Check disk space and permissions."); - return false; - } - }); - this.saveQueue = result.then(() => {}); - return result; + try { + await this.plugin.updateSetting(key, value); + return true; + } catch (err: unknown) { + console.error("bulk-properties: failed to save settings:", err); + new Notice("Failed to save settings. Check disk space and permissions."); + return false; + } } display(): void {