-
Notifications
You must be signed in to change notification settings - Fork 132
Automatically start sync when there's any mutations #918
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Automatically start sync when there's any mutations #918
Conversation
…ions On-demand collections were throwing SyncNotInitializedError when users tried to call writeUpsert or other write operations. This happened because the sync function was only invoked when startSync: true was explicitly set, but write operations require the sync infrastructure to be initialized. For on-demand collections, starting sync is cheap (no data is fetched until loadSubset is called), so we now automatically start sync when syncMode is 'on-demand'. This ensures write operations work immediately while maintaining the on-demand loading behavior. Fixes the issue where users with on-demand collections could not manually insert related records using writeUpsert.
🦋 Changeset detectedLatest commit: 13c7314 The changes in this PR will be included in the next version bump. This PR includes changesets to release 12 packages
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 |
More templates
@tanstack/angular-db
@tanstack/db
@tanstack/db-ivm
@tanstack/electric-db-collection
@tanstack/offline-transactions
@tanstack/powersync-db-collection
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/rxdb-db-collection
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
|
Size Change: +49 B (+0.06%) Total Size: 87.2 kB
ℹ️ View Unchanged
|
|
Size Change: 0 B Total Size: 3.35 kB ℹ️ View Unchanged
|
On-demand collections now start in 'ready' status immediately since sync is auto-started to enable write operations. Updated the test to expect 'ready' instead of 'idle' initial status while still verifying no data is loaded until loadSubset is called.
Instead of only auto-starting sync for on-demand collections, we now auto-start sync whenever any write operation is called on a collection that hasn't been initialized yet. This provides a more general solution that works for both eager and on-demand collections. Changes: - Modified QueryCollectionUtilsImpl to store a collection reference - Write methods now call _ensureSyncStarted() before executing - Collection passes its reference to utils via _setCollection() - Updated tests to verify sync auto-starts on first write operation
…ctions Extended the auto-start sync behavior to cover both mutations and write operations: 1. Mutations (insert, update, delete) - handled by adding 'idle' to the validateCollectionUsable() switch case in lifecycle.ts 2. Write operations (writeInsert, writeUpsert, etc.) - handled by passing the collection reference to utils via _setCollection() so they can call startSyncImmediate() when needed This ensures both types of write operations work on collections that haven't been explicitly preloaded, fixing SyncNotInitializedError.
Instead of passing collection reference via _setCollection, make utils a getter that calls validateCollectionUsable() before returning. This auto-starts sync when any util method is accessed, without needing special internal APIs. Changes: - Made utils a getter/setter in CollectionImpl that validates on access - Removed _setCollection and _ensureSyncStarted from QueryCollectionUtilsImpl - Updated test to reflect new auto-start behavior when accessing utils
samwillis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't fix the issue. It only works on query collections with direct writes.
| // Utilities namespace | ||
| // This is populated by createCollection | ||
| public utils: Record<string, Fn> = {} | ||
| // Utilities namespace - stored privately, accessed via getter that validates collection state | ||
| private _utils: Record<string, Fn> = {} | ||
|
|
||
| public get utils(): Record<string, Fn> { | ||
| this._lifecycle.validateCollectionUsable(`utils`) | ||
| return this._utils | ||
| } | ||
|
|
||
| public set utils(value: Record<string, Fn>) { | ||
| this._utils = value | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very strange way to implement this. It seems to be a hack that means that when you access the collection utils at all it will call _lifecycle.validateCollectionUsable and trigger sync to start?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah — it seems like a reasonable approach to me — the other way was to have query collection manually call startSync but the idea here is that if a collection is active in any way to start sync. Which covers a lot of stuff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this doesn't fix , and will trigger sync to start for any collection implementation that places anything it want on the utils, some of which could very much be intended not to start sync.collection.insert or using a custom mutation (are they also broken?)
I really don't think this is the right approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
say a sync engine added a utils.status, accessing that would trigger sync to start.
| expect(collection.get(`1`)).toEqual(newItem) | ||
|
|
||
| // Test writeUpsert (the specific operation from the bug report) | ||
| collection.utils.writeUpsert({ id: `2`, name: `Item 2`, value: 20 }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the issue was with any mutation, not just the direct writes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah we handle regular mutations here https://github.com/TanStack/db/pull/918/files#diff-03176e533aea8affa9d789787bfdf48e6a7ce75817f44712dd9c1fe8cf9bd2eb
Fixed
SyncNotInitializedErrorbeing thrown when calling write operations (writeUpsert,writeInsert, etc.) or mutations (insert,update,delete) on collections before sync is started. Previously, these operations requiredstartSync: trueto be explicitly set orpreload()to be called first. Now, sync is automatically started when any write operation or mutation is called on an idle collection, enabling these operations to work immediately without explicit initialization.Fixes the issue where users with on-demand collections could not manually insert related records using writeUpsert.