diff --git a/.changeset/fix-offline-mutations-changes-field.md b/.changeset/fix-offline-mutations-changes-field.md new file mode 100644 index 000000000..8fc9eb37f --- /dev/null +++ b/.changeset/fix-offline-mutations-changes-field.md @@ -0,0 +1,5 @@ +--- +'@tanstack/offline-transactions': patch +--- + +Fix mutation.changes field being lost during offline transaction serialization. Previously, the changes field was not included in serialized mutations, causing it to be empty ({}) after app restart. This led to sync functions receiving incomplete data when using mutation.changes for partial updates. diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 000000000..f3509559e --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,5 @@ +{ + "permissions": { + "allow": ["Bash(git checkout:*)", "Bash(npx sherif:*)"] + } +} diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 000000000..0bfe39ff1 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +pnpm 10.26.0 +nodejs 22.13.1 diff --git a/packages/db-collections/package.json b/packages/db-collections/package.json new file mode 100644 index 000000000..074afba15 --- /dev/null +++ b/packages/db-collections/package.json @@ -0,0 +1,5 @@ +{ + "name": "db-collections", + "version": "0.0.0", + "private": true +} diff --git a/packages/offline-transactions/src/outbox/TransactionSerializer.ts b/packages/offline-transactions/src/outbox/TransactionSerializer.ts index 92142010f..67a62d41f 100644 --- a/packages/offline-transactions/src/outbox/TransactionSerializer.ts +++ b/packages/offline-transactions/src/outbox/TransactionSerializer.ts @@ -66,6 +66,7 @@ export class TransactionSerializer { type: mutation.type, modified: this.serializeValue(mutation.modified), original: this.serializeValue(mutation.original), + changes: this.serializeValue(mutation.changes), collectionId: registryKey, // Store registry key instead of collection.id } } @@ -83,11 +84,11 @@ export class TransactionSerializer { type: data.type as any, modified: this.deserializeValue(data.modified), original: this.deserializeValue(data.original), + changes: this.deserializeValue(data.changes) ?? {}, collection, // These fields would need to be reconstructed by the executor mutationId: ``, // Will be regenerated key: null, // Will be extracted from the data - changes: {}, // Will be recalculated metadata: undefined, syncMetadata: {}, optimistic: true, @@ -108,7 +109,7 @@ export class TransactionSerializer { if (typeof value === `object`) { const result: any = Array.isArray(value) ? [] : {} for (const key in value) { - if (value.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(value, key)) { result[key] = this.serializeValue(value[key]) } } @@ -139,7 +140,7 @@ export class TransactionSerializer { if (typeof value === `object`) { const result: any = Array.isArray(value) ? [] : {} for (const key in value) { - if (value.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(value, key)) { result[key] = this.deserializeValue(value[key]) } } diff --git a/packages/offline-transactions/src/types.ts b/packages/offline-transactions/src/types.ts index 9221e323a..e0b1f6df7 100644 --- a/packages/offline-transactions/src/types.ts +++ b/packages/offline-transactions/src/types.ts @@ -21,6 +21,7 @@ export interface SerializedMutation { type: string modified: any original: any + changes: any collectionId: string } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7b7a4ae4..f415ce675 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -842,6 +842,8 @@ importers: specifier: ^3.2.4 version: 3.2.4(@types/debug@4.1.12)(@types/node@24.7.0)(@vitest/ui@3.2.4(vitest@3.2.4))(jiti@2.6.1)(jsdom@27.4.0)(lightningcss@1.30.2)(sass@1.90.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.1) + packages/db-collections: {} + packages/db-ivm: dependencies: fractional-indexing: