fix(db): preserve mutation handler key and utility types - #1849
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review. 📝 WalkthroughWalkthroughCollection and transaction types now preserve declared collection keys and adapter utilities through mutation handlers. Electric and Query utility interfaces are closed. Type-level tests cover core, Electric, PowerSync, and Query collections. A changeset marks three packages for minor releases. ChangesMutation Handler Type Preservation
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to No actionable risk remains from the reviewed change; it is ready to merge. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 13 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
More templates
@tanstack/angular-db
@tanstack/browser-db-sqlite-persistence
@tanstack/capacitor-db-sqlite-persistence
@tanstack/cloudflare-durable-objects-db-sqlite-persistence
@tanstack/db
@tanstack/db-ivm
@tanstack/db-sqlite-persistence-core
@tanstack/electric-db-collection
@tanstack/electron-db-sqlite-persistence
@tanstack/expo-db-sqlite-persistence
@tanstack/node-db-sqlite-persistence
@tanstack/offline-transactions
@tanstack/powersync-db-collection
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/react-native-db-sqlite-persistence
@tanstack/react-router-with-db
@tanstack/rxdb-db-collection
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/tauri-db-sqlite-persistence
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
|
Size Change: +6 B (0%) Total Size: 165 kB 📦 View Changed
ℹ️ View Unchanged
|
|
Size Change: 0 B Total Size: 7.34 kB ℹ️ View Unchanged
|
Mutation handlers now preserve their collection's exact key and utility types through nested transaction mutations, and Query/Electric utility namespaces reject helpers that do not exist at runtime. This is a type-only correction: emitted runtime JavaScript is byte-identical.
Root cause
Three type boundaries independently erased information:
PendingMutation.keywasany.TransactionWithMutationsretained the row and operation but discarded the concrete collection, so nested mutations lost their key and adapter utilities.CollectionImpl.utilswidened utilities to a generic record, while Query and Electric utility interfaces inherited an open string index signature. That made nonexistent cross-adapter helpers type-check asany.The result was an inconsistent handler contract: the sibling
collectionparameter could be precise whiletransaction.mutations[n].collectionwas not.Approach
TransactionWithMutationsand all insert/update/delete handler parameters.TUtilsonCollectionImpl, including requiring the corresponding runtime utility object when callers explicitly claim a closed, non-empty utility namespace.Key invariants
collectionparameter.any.refetch, Electric hasawaitTxId, and PowerSync hasgetMeta.CollectionImplrequires a matching runtime utility object.transaction.isPersisted.promiseremains the existing local transaction-settlement receipt; it is not redefined as backend confirmation.Non-goals
Collection.updatekey-input compatibility shape.ElectricCollectionConfigkey generics; that remains separate design work.Trade-offs
TransactionWithMutationsgains a collection generic so precise information can cross the handler boundary.PendingMutation.keynow follows the collection's declared key type instead ofany; collections using the default key type—including current Electric options—exposestring | number, while callers can declareTKeyexplicitly or use schema inference for a narrower key. This narrowing and the closed adapter utility interfaces intentionally turn previously accepted unsound code into compile errors, so the changeset classifies the release as minor. The precision adds 574 declaration bytes in total and approximately 1.6% more source-only TypeScript instantiations, with no measured check-time regression.Verification
Focused type owners and their surrounding packages:
Also verified:
Hostile-mutant evidence
The permanent owners reject all three original failure modes: restoring
key: any, dropping the concrete collection from handler transactions, or reopening Query/Electric utilities withUtilsRecord. The initial base probe produced 25 diagnostics across insert/update/delete, branded and numeric keys, exactIsAnychecks, wrong-key assignments, and cross-adapter utility controls.Output and compiler diagnostics
@tanstack/db, Query Collection, and Electric Collection.Files changed
packages/db/src/types.ts: preserve collection, key, and utility types in mutation handler transactions.packages/db/src/collection/{index,mutations}.ts: retain concrete utilities and thread precise collections through runtime-owned handler calls.packages/db/tests/mutation-handler-type-oracle.test-d.ts: add the cross-operation type oracle and hostile controls.packages/query-db-collection/src/query.ts: close and propagate Query utilities; derive wrapper parameter types.packages/electric-db-collection/src/electric.ts: close the Electric utility namespace.*.test-d.tsowners: assert nested handler precision and cross-adapter rejection..changeset/tighten-transaction-handler-types.md: release notes for the corrected public types.Summary by CodeRabbit
string | number, while explicitly typed collections retain their declared key type.