-
Notifications
You must be signed in to change notification settings - Fork 132
Make optimistic mutations opt-in #953
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
Draft
KyleAMathews
wants to merge
5
commits into
main
Choose a base branch
from
claude/optional-optimistic-mutations-01WjqmYsFBmB18tKib9SXVZx
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Make optimistic mutations opt-in #953
KyleAMathews
wants to merge
5
commits into
main
from
claude/optional-optimistic-mutations-01WjqmYsFBmB18tKib9SXVZx
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Introduce discriminated union types for collection configuration that
enforce mutation handler usage based on the `mutations` flag:
- Add `MutableCollectionConfig` (mutations: true) - allows onInsert,
onUpdate, onDelete handlers
- Add `ReadOnlyCollectionConfig` (mutations?: false) - disallows
mutation handlers with TypeScript errors
- Make `CollectionConfig` a union of both types
TypeScript now errors when trying to use onInsert/onUpdate/onDelete
without explicitly setting `mutations: true`:
```typescript
// ✅ Works - read-only, no handlers
const readOnly = createCollection({
getKey: (t) => t.id,
sync: { ... }
})
// ✅ Works - mutations enabled with handlers
const mutable = createCollection({
getKey: (t) => t.id,
mutations: true,
onInsert: async ({ transaction }) => { ... }
})
// ❌ TypeScript Error: "onInsert" requires mutations: true
const broken = createCollection({
getKey: (t) => t.id,
onInsert: async () => { ... } // Error!
})
```
This is the first step toward making optimistic mutation code opt-in
for bundle size reduction. Tree-shaking analysis shows ~50KB of
mutation-specific code that could be eliminated for read-only use cases.
…rror Add runtime enforcement of the `mutations: true` config flag: - `MutationsNotEnabledError` thrown when calling insert/update/delete on collections without `mutations: true` - CollectionMutationsManager only instantiated when mutations enabled - localStorageCollectionOptions now includes `mutations: true` by default Update all tests to include `mutations: true` where mutation methods are used, ensuring both compile-time and runtime safety.
Change the mutations config from `mutations: true` to a plugin-based approach
using `import { mutations } from "@tanstack/db"` and passing it to the collection
config. This enables tree-shaking to exclude mutation code for read-only collections.
Key changes:
- Add MutationsPlugin interface and mutations export
- Update collection to use plugin's _createManager for mutation setup
- Update all adapters (powersync, rxdb, query, trailbase, electric) to use mutations plugin
- Update all tests to import and use mutations plugin
- Tree-shaking results: 58.5KB (read-only) vs 78.3KB (with mutations) = ~25% reduction
🦋 Changeset detectedLatest commit: 41a64fc The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 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: |
Contributor
|
Size Change: +287 B (+0.33%) Total Size: 87.4 kB
ℹ️ View Unchanged
|
Contributor
|
Size Change: 0 B Total Size: 3.34 kB ℹ️ View Unchanged
|
- Add comprehensive changeset documenting the breaking change for opt-in mutations - Fix type test by explicitly passing ElectricCollectionUtils type parameter to createCollection - Update PR description with bundle size metrics and migration guide
Instead of trying to assign the entire utils object to ElectricCollectionUtils type, check that the individual utility methods (awaitTxId, awaitMatch) exist and are properly typed. This matches the pattern used in other adapter tests.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
🎯 Changes
This PR makes optimistic mutations opt-in via a plugin pattern, enabling tree-shaking to eliminate ~25% of bundle size for read-only collections.
Key Changes
mutationsplugin to enable mutation capabilitiesonInsert,onUpdate,onDeletehandlers without the mutations plugin.insert(),.update(), or.delete()without the mutations plugin throwsMutationsNotEnabledErrorBundle Size Impact
Migration Example
Before:
After:
Read-only (no mutations needed):
✅ Checklist
pnpm test:pr.🚀 Release Impact
📦 Affected Packages
@tanstack/db- Core API change@tanstack/electric-db-collection- Updated to use mutations plugin@tanstack/powersync-db-collection- Updated to use mutations plugin@tanstack/query-db-collection- Updated to use mutations plugin@tanstack/rxdb-db-collection- Updated to use mutations plugin@tanstack/trailbase-db-collection- Updated to use mutations plugin🔍 Technical Details
The implementation uses a plugin object that provides a
_createManagermethod, which is called conditionally when the plugin is present. Modern bundlers can tree-shake the entire mutations module chain when the plugin is not imported:collection/mutations.js- CollectionMutationsManagerproxy.js- Change tracking proxytransactions.js- Transaction systemTotal eliminated: ~43KB raw → ~20KB minified