Skip to content

Conversation

samwillis
Copy link
Collaborator

Summary

Extends useLiveInfiniteQuery to accept pre-created LiveQueryCollection instances in addition to query functions, enabling router loader patterns where collections can be created, awaited for preload, and then passed to route components.

Changes

Core Functionality

  • useLiveInfiniteQuery now accepts either:
    • A query function: (q) => q.from(...).orderBy(...).limit(...)
    • A pre-created collection: createLiveQueryCollection({ query: ... })
  • Added automatic window validation and adjustment for pre-created collections
  • Window adjustments happen in effects to avoid React subscription timing issues
  • Pagination state resets when collection instance changes

New API: getWindow() on LiveQueryCollectionUtils

  • Added getWindow() method to inspect current window settings
  • Returns { offset: number, limit: number } | undefined
  • Returns undefined for non-windowed queries
  • Tracks window state internally in CollectionConfigBuilder

Validation & Error Handling

  • Pre-created collections must have an orderBy clause (throws error if missing)
  • Input validation ensures first argument is either a CollectionImpl or function
  • Logs warning when pre-created collection's initial window doesn't match expected values
  • Warning only appears once per collection instance

Type Safety

  • Added overload signatures for type inference based on input type
  • Proper type narrowing for both collection and query function paths
  • Uses instanceof CollectionImpl for reliable runtime type checking

Example Usage

Router Loader Pattern

// In router loader
export async function loader() {
  const postsQuery = createLiveQueryCollection({
    query: (q) => q
      .from({ posts: postsCollection })
      .orderBy(({ posts }) => posts.createdAt, 'desc')
      .limit(20)
      .offset(0)
  })
  
  await postsQuery.preload()
  return { postsQuery }
}

// In component
function PostsList() {
  const { postsQuery } = useLoaderData()
  
  const { data, pages, hasNextPage, fetchNextPage } = useLiveInfiniteQuery(
    postsQuery,
    { pageSize: 20 }
  )
  
  // ... render
}

Traditional Query Function (unchanged)

const { data, pages, hasNextPage, fetchNextPage } = useLiveInfiniteQuery(
  (q) => q
    .from({ posts: postsCollection })
    .orderBy(({ posts }) => posts.createdAt, 'desc'),
  { pageSize: 20 }
)

Testing

  • ✅ 24 tests passing (7 new tests for pre-created collections)
  • ✅ No linter errors
  • ✅ No React warnings
  • Tests cover: preloaded collections, pagination, instance changes, error cases, window validation, live updates, and router loader patterns

Implementation Notes

  • Window adjustment happens in useEffect after useLiveQuery subscribes to avoid triggering subscription callbacks during render which React will log warnings about
  • Uses hasValidatedCollectionRef to track first-time validation and only log warnings once
  • Delegates as much work as possible to the underlying useLiveQuery hook
  • Both collection and query function code paths use a unified window adjustment effect

Copy link

changeset-bot bot commented Oct 16, 2025

🦋 Changeset detected

Latest commit: 34f8801

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

This PR includes changesets to release 12 packages
Name Type
@tanstack/react-db Patch
@tanstack/db Patch
@tanstack/db-example-react-todo Patch
@tanstack/angular-db Patch
@tanstack/electric-db-collection Patch
@tanstack/query-db-collection 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

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

Copy link

pkg-pr-new bot commented Oct 16, 2025

More templates

@tanstack/angular-db

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

@tanstack/db

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

@tanstack/db-ivm

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

@tanstack/electric-db-collection

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

@tanstack/query-db-collection

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

@tanstack/react-db

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

@tanstack/rxdb-db-collection

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

@tanstack/solid-db

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

@tanstack/svelte-db

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

@tanstack/trailbase-db-collection

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

@tanstack/vue-db

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

commit: 34f8801

Copy link
Contributor

Size Change: +56 B (+0.07%)

Total Size: 83.7 kB

Filename Size Change
./packages/db/dist/esm/query/live/collection-config-builder.js 5.54 kB +56 B (+1.02%)
ℹ️ View Unchanged
Filename Size
./packages/db/dist/esm/collection/change-events.js 963 B
./packages/db/dist/esm/collection/changes.js 1.01 kB
./packages/db/dist/esm/collection/events.js 413 B
./packages/db/dist/esm/collection/index.js 3.23 kB
./packages/db/dist/esm/collection/indexes.js 1.16 kB
./packages/db/dist/esm/collection/lifecycle.js 1.8 kB
./packages/db/dist/esm/collection/mutations.js 2.52 kB
./packages/db/dist/esm/collection/state.js 3.79 kB
./packages/db/dist/esm/collection/subscription.js 2.2 kB
./packages/db/dist/esm/collection/sync.js 2.2 kB
./packages/db/dist/esm/deferred.js 230 B
./packages/db/dist/esm/errors.js 3.57 kB
./packages/db/dist/esm/event-emitter.js 798 B
./packages/db/dist/esm/index.js 1.65 kB
./packages/db/dist/esm/indexes/auto-index.js 794 B
./packages/db/dist/esm/indexes/base-index.js 835 B
./packages/db/dist/esm/indexes/btree-index.js 2 kB
./packages/db/dist/esm/indexes/lazy-index.js 1.21 kB
./packages/db/dist/esm/indexes/reverse-index.js 577 B
./packages/db/dist/esm/local-only.js 967 B
./packages/db/dist/esm/local-storage.js 2.33 kB
./packages/db/dist/esm/optimistic-action.js 294 B
./packages/db/dist/esm/proxy.js 3.86 kB
./packages/db/dist/esm/query/builder/functions.js 615 B
./packages/db/dist/esm/query/builder/index.js 4.04 kB
./packages/db/dist/esm/query/builder/ref-proxy.js 938 B
./packages/db/dist/esm/query/compiler/evaluators.js 1.55 kB
./packages/db/dist/esm/query/compiler/expressions.js 760 B
./packages/db/dist/esm/query/compiler/group-by.js 2.04 kB
./packages/db/dist/esm/query/compiler/index.js 2.21 kB
./packages/db/dist/esm/query/compiler/joins.js 2.65 kB
./packages/db/dist/esm/query/compiler/order-by.js 1.43 kB
./packages/db/dist/esm/query/compiler/select.js 1.28 kB
./packages/db/dist/esm/query/ir.js 785 B
./packages/db/dist/esm/query/live-query-collection.js 404 B
./packages/db/dist/esm/query/live/collection-registry.js 233 B
./packages/db/dist/esm/query/live/collection-subscriber.js 2.11 kB
./packages/db/dist/esm/query/optimizer.js 3.26 kB
./packages/db/dist/esm/scheduler.js 1.29 kB
./packages/db/dist/esm/SortedMap.js 1.24 kB
./packages/db/dist/esm/transactions.js 3.05 kB
./packages/db/dist/esm/utils.js 1.01 kB
./packages/db/dist/esm/utils/browser-polyfills.js 365 B
./packages/db/dist/esm/utils/btree.js 6.01 kB
./packages/db/dist/esm/utils/comparison.js 754 B
./packages/db/dist/esm/utils/index-optimization.js 1.73 kB

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

Copy link
Contributor

Size Change: 0 B

Total Size: 2.36 kB

ℹ️ View Unchanged
Filename Size
./packages/react-db/dist/esm/index.js 168 B
./packages/react-db/dist/esm/useLiveInfiniteQuery.js 885 B
./packages/react-db/dist/esm/useLiveQuery.js 1.31 kB

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

Copy link
Contributor

@kevin-dp kevin-dp left a comment

Choose a reason for hiding this comment

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

Great work!

@KyleAMathews KyleAMathews merged commit 5566b26 into main Oct 16, 2025
6 checks passed
@KyleAMathews KyleAMathews deleted the samwillis/live-inf-query-preload branch October 16, 2025 19:22
@github-actions github-actions bot mentioned this pull request Oct 16, 2025
Copy link
Contributor

🎉 This PR has been released!

Thank you for your contribution!

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.

3 participants