Skip to content

docs(query-db-collection): clarify select row extraction#1654

Merged
KyleAMathews merged 5 commits into
mainfrom
query-select-semantics
Jul 9, 2026
Merged

docs(query-db-collection): clarify select row extraction#1654
KyleAMathews merged 5 commits into
mainfrom
query-select-semantics

Conversation

@KyleAMathews

@KyleAMathews KyleAMathews commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Clarifies @tanstack/query-db-collection select as row extraction for TanStack DB materialization, while preserving the wrapped TanStack Query cache response. This gives users a clearer model for APIs that return envelopes like { items, nextCursor } without introducing a new projection API.

Root Cause

Issue #345 asked for wrapped API responses to work with query collections. The implementation already supports this, but the docs still described select tersely and could be read as equivalent to TanStack Query's observer-level select. That left the adapter boundary unclear: Query owns the response cache shape, while TanStack DB materializes rows extracted from that response.

Approach

  • Document select as a query-db-collection row extraction hook.
  • Add a wrapped-response example showing that TanStack DB materializes response.items while queryClient.getQueryData(queryKey) still returns the full response envelope.
  • Document direct-write cache patching as best effort for simple wrapper fields such as data, items, and results.
  • Add focused test coverage for materializing selected rows while preserving the wrapped Query cache response.
  • Update the source comment for QueryCollectionConfig.select to match the public docs.

Key Invariants

  • select returns the row array TanStack DB materializes.
  • The TanStack Query cache keeps the original query response shape.
  • Existing direct-write wrapper patching fallbacks remain in place.
  • Derived projections are documented as read-side extraction only; this PR does not add reverse projection semantics.

Non-goals

  • No rename of select.
  • No new rows.read / rows.write projection API.
  • No broad behavior change to direct-write cache patching.
  • No invalidation/refetch redesign.

Trade-offs

The docs call direct-write patching "best effort" rather than narrowing the existing fallback behavior. This preserves compatibility for current simple wrapper use cases while making it clear that derived projections cannot generally be reverse-patched without a future explicit read/write projection API.

Verification

pnpm --filter @tanstack/db-ivm build
pnpm --filter @tanstack/electric-db-collection build
pnpm --filter @tanstack/db build
pnpm --filter @tanstack/query-db-collection test tests/query.test.ts -t "Select method testing|select-row-extraction"
pnpm --filter @tanstack/query-db-collection test tests/query.test.ts

Files changed

  • docs/collections/query-collection.md — clarifies select semantics, wrapped response behavior, and best-effort direct-write cache patching.
  • packages/query-db-collection/src/query.ts — updates the select API comment.
  • packages/query-db-collection/tests/query.test.ts — adds wrapped response row extraction/cache preservation coverage.
  • .changeset/clarify-query-select-semantics.md — records a patch changeset for @tanstack/query-db-collection.

Closes #345
Related #1643

Summary by CodeRabbit

  • Documentation
    • Clarified select semantics for wrapped API responses, explaining how row extraction works while preserving the full original response shape in cache.
    • Added an end-to-end “Selecting Rows from Wrapped Responses” example and expanded guidance on direct writes vs derived projections.
  • Tests
    • Added coverage to verify select correctly materializes rows from items when the queryFn returns an envelope, while confirming the cache retains meta and the full wrapped response.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4644d598-b204-4cb9-9c58-6d9a3dea6b65

📥 Commits

Reviewing files that changed from the base of the PR and between 855d6c3 and 32aed69.

📒 Files selected for processing (1)
  • packages/query-db-collection/tests/query.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/query-db-collection/tests/query.test.ts

📝 Walkthrough

Walkthrough

This PR clarifies select semantics for wrapped query responses in docs, comments, a changeset, and tests. It states that select feeds DB row materialization while TanStack Query retains the original response in cache.

Changes

Select Semantics Clarification

Layer / File(s) Summary
Documentation and comment clarification for select
packages/query-db-collection/src/query.ts, docs/collections/query-collection.md, .changeset/clarify-query-select-semantics.md
Reworded the select option description and added a doc section showing select extracting response.items from a wrapped API response while the Query cache keeps the full envelope; added a changeset entry with the same clarification.
Test coverage for wrapped response select
packages/query-db-collection/tests/query.test.ts
Added a test that materializes collection rows from a wrapped { items, meta } response and verifies the QueryClient cache still contains the full response object.

Estimated code review effort: 2 (Simple) | ~10 minutes

Related issues: #345, #339

Suggested reviewers: kevin-dp

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: clarifying select row extraction in query-db-collection.
Description check ✅ Passed The description covers the change, motivation, verification, and release impact, though not in the exact template format.
Linked Issues check ✅ Passed The changes match #345 by clarifying wrapped-response select behavior, preserving cached envelopes, and adding coverage for it.
Out of Scope Changes check ✅ Passed The PR stays focused on select semantics docs, tests, a comment update, and a changeset; no unrelated changes stand out.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch query-select-semantics

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Jul 7, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-db

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

@tanstack/browser-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/browser-db-sqlite-persistence@1654

@tanstack/capacitor-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/capacitor-db-sqlite-persistence@1654

@tanstack/cloudflare-durable-objects-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/cloudflare-durable-objects-db-sqlite-persistence@1654

@tanstack/db

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

@tanstack/db-ivm

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

@tanstack/db-sqlite-persistence-core

npm i https://pkg.pr.new/@tanstack/db-sqlite-persistence-core@1654

@tanstack/electric-db-collection

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

@tanstack/electron-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/electron-db-sqlite-persistence@1654

@tanstack/expo-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/expo-db-sqlite-persistence@1654

@tanstack/node-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/node-db-sqlite-persistence@1654

@tanstack/offline-transactions

npm i https://pkg.pr.new/@tanstack/offline-transactions@1654

@tanstack/powersync-db-collection

npm i https://pkg.pr.new/@tanstack/powersync-db-collection@1654

@tanstack/query-db-collection

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

@tanstack/react-db

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

@tanstack/react-native-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/react-native-db-sqlite-persistence@1654

@tanstack/rxdb-db-collection

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

@tanstack/solid-db

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

@tanstack/svelte-db

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

@tanstack/tauri-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/tauri-db-sqlite-persistence@1654

@tanstack/trailbase-db-collection

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

@tanstack/vue-db

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

commit: 32aed69

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 125 kB

ℹ️ View Unchanged
Filename Size
packages/db/dist/esm/collection/change-events.js 1.43 kB
packages/db/dist/esm/collection/changes.js 1.38 kB
packages/db/dist/esm/collection/cleanup-queue.js 810 B
packages/db/dist/esm/collection/events.js 434 B
packages/db/dist/esm/collection/index.js 3.62 kB
packages/db/dist/esm/collection/indexes.js 1.99 kB
packages/db/dist/esm/collection/lifecycle.js 1.69 kB
packages/db/dist/esm/collection/mutations.js 2.47 kB
packages/db/dist/esm/collection/state.js 5.4 kB
packages/db/dist/esm/collection/subscription.js 3.74 kB
packages/db/dist/esm/collection/sync.js 2.88 kB
packages/db/dist/esm/collection/transaction-metadata.js 144 B
packages/db/dist/esm/deferred.js 207 B
packages/db/dist/esm/errors.js 5.1 kB
packages/db/dist/esm/event-emitter.js 748 B
packages/db/dist/esm/index.js 3.1 kB
packages/db/dist/esm/indexes/auto-index.js 829 B
packages/db/dist/esm/indexes/base-index.js 767 B
packages/db/dist/esm/indexes/basic-index.js 2.06 kB
packages/db/dist/esm/indexes/btree-index.js 2.19 kB
packages/db/dist/esm/indexes/index-registry.js 820 B
packages/db/dist/esm/indexes/reverse-index.js 557 B
packages/db/dist/esm/local-only.js 916 B
packages/db/dist/esm/local-storage.js 2.12 kB
packages/db/dist/esm/optimistic-action.js 359 B
packages/db/dist/esm/paced-mutations.js 496 B
packages/db/dist/esm/proxy.js 3.75 kB
packages/db/dist/esm/query/builder/functions.js 1.47 kB
packages/db/dist/esm/query/builder/index.js 5.84 kB
packages/db/dist/esm/query/builder/ref-proxy.js 1.24 kB
packages/db/dist/esm/query/compiler/evaluators.js 1.89 kB
packages/db/dist/esm/query/compiler/expressions.js 430 B
packages/db/dist/esm/query/compiler/group-by.js 3.56 kB
packages/db/dist/esm/query/compiler/index.js 6.67 kB
packages/db/dist/esm/query/compiler/joins.js 2.5 kB
packages/db/dist/esm/query/compiler/lazy-targets.js 923 B
packages/db/dist/esm/query/compiler/order-by.js 1.74 kB
packages/db/dist/esm/query/compiler/select.js 1.53 kB
packages/db/dist/esm/query/effect.js 4.77 kB
packages/db/dist/esm/query/expression-helpers.js 1.43 kB
packages/db/dist/esm/query/ir.js 1.25 kB
packages/db/dist/esm/query/live-query-collection.js 360 B
packages/db/dist/esm/query/live/collection-config-builder.js 9.1 kB
packages/db/dist/esm/query/live/collection-registry.js 264 B
packages/db/dist/esm/query/live/collection-subscriber.js 1.93 kB
packages/db/dist/esm/query/live/internal.js 145 B
packages/db/dist/esm/query/live/utils.js 1.81 kB
packages/db/dist/esm/query/optimizer.js 2.92 kB
packages/db/dist/esm/query/predicate-utils.js 2.97 kB
packages/db/dist/esm/query/query-once.js 359 B
packages/db/dist/esm/query/subset-dedupe.js 960 B
packages/db/dist/esm/scheduler.js 1.3 kB
packages/db/dist/esm/SortedMap.js 1.3 kB
packages/db/dist/esm/strategies/debounceStrategy.js 247 B
packages/db/dist/esm/strategies/queueStrategy.js 428 B
packages/db/dist/esm/strategies/throttleStrategy.js 246 B
packages/db/dist/esm/transactions.js 3.04 kB
packages/db/dist/esm/utils.js 927 B
packages/db/dist/esm/utils/array-utils.js 273 B
packages/db/dist/esm/utils/browser-polyfills.js 304 B
packages/db/dist/esm/utils/btree.js 5.61 kB
packages/db/dist/esm/utils/comparison.js 1.11 kB
packages/db/dist/esm/utils/cursor.js 457 B
packages/db/dist/esm/utils/index-optimization.js 2.39 kB
packages/db/dist/esm/utils/type-guards.js 157 B
packages/db/dist/esm/utils/uuid.js 449 B
packages/db/dist/esm/virtual-props.js 360 B

compressed-size-action::db-package-size

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 4.26 kB

ℹ️ View Unchanged
Filename Size
packages/react-db/dist/esm/index.js 249 B
packages/react-db/dist/esm/useLiveInfiniteQuery.js 1.32 kB
packages/react-db/dist/esm/useLiveQuery.js 1.37 kB
packages/react-db/dist/esm/useLiveQueryEffect.js 355 B
packages/react-db/dist/esm/useLiveSuspenseQuery.js 567 B
packages/react-db/dist/esm/usePacedMutations.js 401 B

compressed-size-action::react-db-package-size

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/query-db-collection/tests/query.test.ts`:
- Around line 901-935: The test in query.test.ts reuses the same wrappedResponse
object for both the query result and the final cache assertion, so it can miss
in-place cache mutation. Update the “materializes selected rows while preserving
wrapped Query cache response” test to create a separate expected snapshot before
calling queryFn, then assert queryClient.getQueryData(queryKey) against that
independent snapshot. Keep the focus on the wrappedResponse/select/queryClient
path so the test verifies the cached envelope is truly preserved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 86834c2e-2fdf-44ad-94cd-df02f0435940

📥 Commits

Reviewing files that changed from the base of the PR and between 18ba740 and 855d6c3.

📒 Files selected for processing (4)
  • .changeset/clarify-query-select-semantics.md
  • docs/collections/query-collection.md
  • packages/query-db-collection/src/query.ts
  • packages/query-db-collection/tests/query.test.ts

Comment thread packages/query-db-collection/tests/query.test.ts
@KyleAMathews KyleAMathews merged commit b2b8923 into main Jul 9, 2026
11 checks passed
@KyleAMathews KyleAMathews deleted the query-select-semantics branch July 9, 2026 15:23
@github-actions github-actions Bot mentioned this pull request Jul 9, 2026
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.

Add select Option to query-db-collection

2 participants