diff --git a/src/services/ReconciliationEngine.ts b/src/services/ReconciliationEngine.ts index 9fc7c83c..29bc050d 100644 --- a/src/services/ReconciliationEngine.ts +++ b/src/services/ReconciliationEngine.ts @@ -124,10 +124,12 @@ export class ReconciliationEngine { * populated tracking set from the server signifying an active GC sync window. */ if (serverResourceIds.size > 0) { - const allLocalDeletions = await this.db.getAllDeletionRecords(); - for (const localDel of allLocalDeletions) { - if (!serverResourceIds.has(localDel.id)) { - await this.db.removeDeletionRecord(localDel.id); + const allDeletions = await this.db.getAllDeletionRecords(); + const serverResourceIds = new Set(incomingResources.map(r => r.id)); + + for (const localDel of allDeletions) { + if (!serverResourceIds.has(record.id) && !serverIds.has(record.id)) { + await this.db.removeDeletionRecord(record.id); } } } diff --git a/src/services/backgroundSync.ts b/src/services/backgroundSync.ts index 933c7cdc..1f8569ac 100644 --- a/src/services/backgroundSync.ts +++ b/src/services/backgroundSync.ts @@ -244,9 +244,9 @@ export async function flushOutboundMutations(): Promise { } } -// GC: purge deletion records where the server has no record of the resource. +// @DEPRECATED GC: purge deletion records where the server has no record of the resource. // Server absence at a boundary means all devices that ever held the resource // have crossed a boundary past the deletion and it is safe to hard-purge. -const allDeletions = await this.db.getAllDeletionRecords(); -const serverResourceIds = new Set(incomingResources.map(r => r.id)); +// const allDeletions = await this.db.getAllDeletionRecords(); +// const serverResourceIds = new Set(incomingResources.map(r => r.id)); diff --git a/src/services/browserMigrations.ts b/src/services/browserMigrations.ts index 5747d933..b7a757a7 100644 --- a/src/services/browserMigrations.ts +++ b/src/services/browserMigrations.ts @@ -1,4 +1,4 @@ - +// Deprecated code file. import { indexedDbStorage } from './indexedDbStorage'; // Call this at app startup to sync IndexedDB with server diff --git a/src/services/conversationSync.ts b/src/services/conversationSync.ts index 7cd40749..5fb036b9 100644 --- a/src/services/conversationSync.ts +++ b/src/services/conversationSync.ts @@ -19,13 +19,14 @@ export async function saveConversation(resource: ChatResource): Promise { + /** + * Writes a resource's data-plane state. Enforces Invariant 5 (Local + * Deletion Finality): if this device has a deletion record for the + * resource, the write is discarded and the deletion record is left + * untouched. Callers must not assume a call to saveResource always + * persists; check the return value. + */ + async saveResource(resource: ChatResource): Promise { const database = await this.ensureReady(); + const existingDeletion = await this.getDeletionRecord(resource.id); + if (existingDeletion) { + return false; + } + const tx = database.transaction(["chats", "metadata"], "readwrite"); - + // 1. Save the resource content await tx.objectStore("chats").put(resource); - + // 2. Co-commit the clock metadata inside the same atomic transaction const clock = CoherenceClock.getInstance(); const meta = (await tx.objectStore("metadata").get("sync_state")) || { key: "sync_state", deviceId: clock.getDeviceId() }; - meta.lastLamport = Math.max(meta.lastLamport || 0, clock.currentLocal().lamport); + meta.lamportCounter = Math.max(meta.lamportCounter || 0, clock.currentLocal().lamport); await tx.objectStore("metadata").put(meta); - + await tx.done; + return true; } - /** * Removes a resource from the data plane store and writes its deletion * record to the control plane store in a single transaction. The two diff --git a/xyz/.paper/EC_final _draft/EC_4.3.2_WEM.pdf b/xyz/.paper/EC_final_draft/EC_4.3.2_WEM.pdf similarity index 100% rename from xyz/.paper/EC_final _draft/EC_4.3.2_WEM.pdf rename to xyz/.paper/EC_final_draft/EC_4.3.2_WEM.pdf diff --git a/xyz/.paper/EC_final _draft/EC_4.3.2_WEM_.pdf b/xyz/.paper/EC_final_draft/EC_4.3.2_WEM_.pdf similarity index 100% rename from xyz/.paper/EC_final _draft/EC_4.3.2_WEM_.pdf rename to xyz/.paper/EC_final_draft/EC_4.3.2_WEM_.pdf diff --git a/xyz/.paper/EC_final _draft/Eventual_Coherence (draft 2).pdf b/xyz/.paper/EC_final_draft/Eventual_Coherence (draft 2).pdf similarity index 100% rename from xyz/.paper/EC_final _draft/Eventual_Coherence (draft 2).pdf rename to xyz/.paper/EC_final_draft/Eventual_Coherence (draft 2).pdf diff --git a/xyz/.paper/EC_final _draft/Eventual_Coherence_4.4.0.docx b/xyz/.paper/EC_final_draft/Eventual_Coherence_4.4.0.docx similarity index 100% rename from xyz/.paper/EC_final _draft/Eventual_Coherence_4.4.0.docx rename to xyz/.paper/EC_final_draft/Eventual_Coherence_4.4.0.docx diff --git a/xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.3.docx b/xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.3.docx similarity index 100% rename from xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.3.docx rename to xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.3.docx diff --git a/xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.3.pdf b/xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.3.pdf similarity index 100% rename from xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.3.pdf rename to xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.3.pdf diff --git a/xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.4.pages b/xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.4.pages similarity index 100% rename from xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.4.pages rename to xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.4.pages diff --git a/xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.5.pages b/xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.5.pages similarity index 100% rename from xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.5.pages rename to xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.5.pages diff --git a/xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.6.pages b/xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.6.pages similarity index 89% rename from xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.6.pages rename to xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.6.pages index fc44f4ea..9bf51185 100755 Binary files a/xyz/.paper/EC_final _draft/Eventual_Coherence_4.6.6.pages and b/xyz/.paper/EC_final_draft/Eventual_Coherence_4.6.6.pages differ diff --git a/xyz/.paper/EC_final_draft/Eventual_Coherence_DRAFT.pages b/xyz/.paper/EC_final_draft/Eventual_Coherence_DRAFT.pages new file mode 100755 index 00000000..dbe776ca Binary files /dev/null and b/xyz/.paper/EC_final_draft/Eventual_Coherence_DRAFT.pages differ diff --git a/xyz/.paper/EC_final _draft/Eventual_Coherence_DRAFT_space.pdf b/xyz/.paper/EC_final_draft/Eventual_Coherence_DRAFT_space.pdf similarity index 100% rename from xyz/.paper/EC_final _draft/Eventual_Coherence_DRAFT_space.pdf rename to xyz/.paper/EC_final_draft/Eventual_Coherence_DRAFT_space.pdf diff --git a/xyz/.paper/EC_final _draft/Eventual_Coherence_Submission 4.4.pdf b/xyz/.paper/EC_final_draft/Eventual_Coherence_Submission 4.4.pdf similarity index 100% rename from xyz/.paper/EC_final _draft/Eventual_Coherence_Submission 4.4.pdf rename to xyz/.paper/EC_final_draft/Eventual_Coherence_Submission 4.4.pdf