Skip to content

Conversation

@marbemac
Copy link
Contributor

fixes #722

🎯 Changes

Fixed an issue where acceptMutations() wasn't working for manual transactions with local-only collections. The data would appear optimistically but then disappear after the transaction committed.

When filtering mutations to find ones belonging to the collection, it was comparing against syncResult.collection, which is null at the time acceptMutations is called. This is because the collection reference gets set during the sync callback, but utils aren't assigned to the collection until after construction completes. So all mutations were being filtered out and nothing was persisted.

To resolve this, I updated the mutation filtering to compare function references instead.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

@changeset-bot
Copy link

changeset-bot bot commented Oct 25, 2025

🦋 Changeset detected

Latest commit: fc100e1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@tanstack/db Patch
@tanstack/angular-db Patch
@tanstack/electric-db-collection Patch
@tanstack/query-db-collection Patch
@tanstack/react-db Patch
@tanstack/rxdb-db-collection Patch
@tanstack/solid-db Patch
@tanstack/svelte-db Patch
@tanstack/trailbase-db-collection Patch
@tanstack/vue-db Patch
todos Patch
@tanstack/db-example-react-todo Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 25, 2025

More templates

@tanstack/angular-db

npm i https://pkg.pr.new/@tanstack/angular-db@723

@tanstack/db

npm i https://pkg.pr.new/@tanstack/db@723

@tanstack/db-ivm

npm i https://pkg.pr.new/@tanstack/db-ivm@723

@tanstack/electric-db-collection

npm i https://pkg.pr.new/@tanstack/electric-db-collection@723

@tanstack/query-db-collection

npm i https://pkg.pr.new/@tanstack/query-db-collection@723

@tanstack/react-db

npm i https://pkg.pr.new/@tanstack/react-db@723

@tanstack/rxdb-db-collection

npm i https://pkg.pr.new/@tanstack/rxdb-db-collection@723

@tanstack/solid-db

npm i https://pkg.pr.new/@tanstack/solid-db@723

@tanstack/svelte-db

npm i https://pkg.pr.new/@tanstack/svelte-db@723

@tanstack/trailbase-db-collection

npm i https://pkg.pr.new/@tanstack/trailbase-db-collection@723

@tanstack/vue-db

npm i https://pkg.pr.new/@tanstack/vue-db@723

commit: fc100e1

@marbemac
Copy link
Contributor Author

Actually this might affect local only collection mutations in general (not just via manual transactions).

@KyleAMathews
Copy link
Collaborator

So it turns out we solved this in a different way in local-storage.ts — which seems a bit less fragile than this:

// local-storage.ts:503-510
const collectionMutations = transaction.mutations.filter((m) => {
  // Try to match by collection reference first
  if (sync.collection && m.collection === sync.collection) {
    return true
  }
  // Fall back to matching by collection ID
  return m.collection.id === collectionId
})

@marbemac
Copy link
Contributor Author

So it turns out we solved this in a different way in local-storage.ts

Yeah I noticed this, but this works because local storage has a much stronger guarantee of a unique id to operate off of. Since storageKey is required, it falls back to that if the user did not provide the optional collection id. The local collection has no such guarantee.

// Default id to a pattern based on storage key if not provided
const collectionId = id ?? `local-collection:${config.storageKey}`

@KyleAMathews
Copy link
Collaborator

All collections have stable ids though — if one isn't passed, a UUID is generated.

@marbemac
Copy link
Contributor Author

Ah ok I missed that! Will take a look today

@marbemac marbemac force-pushed the mbm/local-manual-transactions-fix branch 2 times, most recently from 8881363 to 1626573 Compare October 27, 2025 19:04
@marbemac marbemac force-pushed the mbm/local-manual-transactions-fix branch from 1626573 to fc100e1 Compare October 27, 2025 19:06
const { initialData, onInsert, onUpdate, onDelete, id, ...restConfig } =
config

const collectionId = id ?? crypto.randomUUID()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KyleAMathews ok updated with the uuid approach. As far as I can tell, the id automatically generated by the base collection impl is not available in time for use in the collection filtering below, so I had to generate it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Local collection manual transaction does not work

2 participants