fix(canvas): persist deletions immediately to prevent resurrection

Destructive operations (forget, delete, remember) now flush to
IndexedDB + localStorage immediately instead of using 2s debounce,
preventing deleted items from reappearing on page reload.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-22 13:29:33 -07:00
parent e0f0426e59
commit 4f9e29e5e7
1 changed files with 15 additions and 3 deletions

View File

@ -699,7 +699,7 @@ export class CommunitySync extends EventTarget {
this.dispatchEvent(new CustomEvent("shape-state-changed", {
detail: { shapeId, state: 'forgotten', data: this.#doc.shapes?.[shapeId] }
}));
this.#scheduleSave();
this.#saveImmediate();
this.#syncToServer();
}
@ -734,7 +734,7 @@ export class CommunitySync extends EventTarget {
this.dispatchEvent(new CustomEvent("shape-state-changed", {
detail: { shapeId, state: 'present', data: this.#doc.shapes?.[shapeId] }
}));
this.#scheduleSave();
this.#saveImmediate();
this.#syncToServer();
}
@ -756,7 +756,7 @@ export class CommunitySync extends EventTarget {
this.dispatchEvent(new CustomEvent("shape-state-changed", {
detail: { shapeId, state: 'deleted', data: this.#doc.shapes?.[shapeId] }
}));
this.#scheduleSave();
this.#saveImmediate();
this.#syncToServer();
}
@ -1013,6 +1013,18 @@ export class CommunitySync extends EventTarget {
}, 2000);
}
/** Flush doc to IndexedDB immediately (no debounce). Use for destructive ops. */
#saveImmediate(): void {
if (!this.#offlineStore) return;
if (this.#saveDebounceTimer) {
clearTimeout(this.#saveDebounceTimer);
this.#saveDebounceTimer = null;
}
const binary = Automerge.save(this.#doc);
this.#offlineStore.saveDocImmediate(this.#communitySlug, binary);
this.#offlineStore.saveDocEmergency(this.#communitySlug, binary);
}
#persistSyncState(): void {
if (!this.#offlineStore) return;