diff --git a/src/blog/tanstack-db-0.1-the-embedded-client-database-for-tanstack-query.md b/src/blog/tanstack-db-0.1-the-embedded-client-database-for-tanstack-query.md index eb838ea64..6558e51a6 100644 --- a/src/blog/tanstack-db-0.1-the-embedded-client-database-for-tanstack-query.md +++ b/src/blog/tanstack-db-0.1-the-embedded-client-database-for-tanstack-query.md @@ -191,9 +191,13 @@ const Todos = () => { // ✅ Define a Query Collection import { createCollection } from '@tanstack/react-db' import { queryCollectionOptions } from '@tanstack/query-db-collection' +import { QueryClient } from '@tanstack/query-core' + +const queryClient = new QueryClient() const todoCollection = createCollection( queryCollectionOptions({ + queryClient, queryKey: ['todos'], queryFn: async () => api.todos.getAll('/api/todos'), @@ -289,18 +293,30 @@ You can do this: ```typescript // Load normalized collections upfront (3 broader calls) -const todoCollection = createQueryCollection({ - queryKey: ['todos'], - queryFn: fetchAllTodos, -}) -const userCollection = createQueryCollection({ - queryKey: ['users'], - queryFn: fetchAllUsers, -}) -const projectCollection = createQueryCollection({ - queryKey: ['projects'], - queryFn: fetchAllProjects, -}) +const todoCollection = createCollection( + queryCollectionOptions({ + queryClient, + queryKey: ['todos'], + queryFn: fetchAllTodos, + getKey: (todo) => todo.id, + }), +) +const userCollection = createCollection( + queryCollectionOptions({ + queryClient, + queryKey: ['users'], + queryFn: fetchAllUsers, + getKey: (user) => user.id, + }), +) +const projectCollection = createCollection( + queryCollectionOptions({ + queryClient, + queryKey: ['projects'], + queryFn: fetchAllProjects, + getKey: (project) => project.id, + }), +) // Navigation is instant, no new API calls needed const { data: activeProjectTodos } = useLiveQuery( diff --git a/src/blog/tanstack-db-0.5-query-driven-sync.md b/src/blog/tanstack-db-0.5-query-driven-sync.md index bb60765c8..63352759a 100644 --- a/src/blog/tanstack-db-0.5-query-driven-sync.md +++ b/src/blog/tanstack-db-0.5-query-driven-sync.md @@ -18,7 +18,9 @@ You don't need a new API for every component. With 0.5, the component's query _i const { data: projectTodos } = useLiveQuery((q) => q .from({ todos }) - .join({ projects }, (t, p) => eq(t.projectId, p.id)) + .join({ projects }, ({ todos, projects }) => + eq(todos.projectId, projects.id), + ) .where(({ todos }) => eq(todos.status, 'active')) .where(({ projects }) => eq(projects.id, 123)), ) @@ -106,9 +108,15 @@ Let's see how each works. With 0.5, you add one line to your collection: ```tsx +import { QueryClient } from '@tanstack/query-core' + +const queryClient = new QueryClient() + const productsCollection = createCollection( queryCollectionOptions({ + queryClient, queryKey: ['products'], + getKey: (product) => product.id, queryFn: async (ctx) => { // Parse your query predicates into API parameters const params = parseLoadSubsetOptions(ctx.meta?.loadSubsetOptions) @@ -179,11 +187,19 @@ TanStack DB compares predicates across all live queries and deduplicates request When you navigate from viewing 10 products to viewing 20, DB doesn't reload everything: ```tsx +import { createLiveQueryCollection } from '@tanstack/react-db' + // Initial query: loads 10 products -const { data } = useLiveQuery((q) => q.from({ products }).limit(10)) +const productsQuery = createLiveQueryCollection((q) => + q + .from({ products: productsCollection }) + .orderBy(({ products }) => products.id) + .limit(10), +) +const { data } = useLiveQuery(productsQuery) // User clicks "load more": loads ONLY the next 10 -fetchNextPage() +await productsQuery.utils.setWindow({ limit: 20 }) ``` ``` @@ -206,7 +222,9 @@ Complex joins don't cause request explosions. They trigger a minimal set of filt const { data } = useLiveQuery((q) => q .from({ todos }) - .join({ projects }, (t, p) => eq(t.projectId, p.id)) + .join({ projects }, ({ todos, projects }) => + eq(todos.projectId, projects.id), + ) .where(({ todos }) => eq(todos.status, 'active')), ) @@ -225,8 +243,10 @@ Query Collection integrates with TanStack Query's `staleTime` and `gcTime`: ```tsx const productsCollection = createCollection(queryCollectionOptions({ + queryClient, queryKey: ['products'], queryFn: fetchProducts, + getKey: (product) => product.id, staleTime: 5 * 60 * 1000, // 5 minutes syncMode: 'on-demand' })) @@ -254,7 +274,8 @@ That's progressive mode: load what you need immediately, sync everything in the ```tsx const todoCollection = createCollection( electricCollectionOptions({ - table: 'todos', + shapeOptions: { url: '/api/todos' }, + getKey: (todo) => todo.id, syncMode: 'progressive', }), ) diff --git a/src/blog/tanstack-db-0.6-app-ready-with-persistence-and-includes.md b/src/blog/tanstack-db-0.6-app-ready-with-persistence-and-includes.md index 4972b9ce7..26b63d609 100644 --- a/src/blog/tanstack-db-0.6-app-ready-with-persistence-and-includes.md +++ b/src/blog/tanstack-db-0.6-app-ready-with-persistence-and-includes.md @@ -89,6 +89,7 @@ In practice, the React Native setup looks like this: import { open } from '@op-engineering/op-sqlite' import { createCollection } from '@tanstack/db' import { queryCollectionOptions } from '@tanstack/query-db-collection' +import { QueryClient } from '@tanstack/query-core' import { createReactNativeSQLitePersistence, persistedCollectionOptions, @@ -109,11 +110,14 @@ const persistence = createReactNativeSQLitePersistence({ database, }) +const queryClient = new QueryClient() + export const shoppingItemsCollection = createCollection( persistedCollectionOptions({ persistence, schemaVersion: 1, ...queryCollectionOptions({ + queryClient, queryKey: ['shopping-items'], queryFn: async () => api.shoppingItems.getAll(), getKey: (item) => item.id,