From 239888d6eff0466e9ff9041c9409200580e3f51f Mon Sep 17 00:00:00 2001 From: Kevin De Porre Date: Mon, 17 Nov 2025 15:52:50 +0100 Subject: [PATCH 1/2] Do not dedupe loadSubset in query collection --- packages/query-db-collection/src/query.ts | 25 ++--------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/packages/query-db-collection/src/query.ts b/packages/query-db-collection/src/query.ts index ee915aabf..d1d07b664 100644 --- a/packages/query-db-collection/src/query.ts +++ b/packages/query-db-collection/src/query.ts @@ -1,5 +1,4 @@ import { QueryObserver, hashKey } from "@tanstack/query-core" -import { DeduplicatedLoadSubset } from "@tanstack/db" import { GetKeyRequiredError, QueryClientRequiredError, @@ -824,21 +823,6 @@ export function queryCollectionOptions( return handleQueryResult } - // This function is called when a loadSubset call is deduplicated - // meaning that we have all the data locally available to answer the query - // so we execute the query locally - const createLocalQuery = (opts: LoadSubsetOptions) => { - const queryFn = ({ meta }: QueryFunctionContext) => { - const inserts = collection.currentStateAsChanges( - meta!.loadSubsetOptions as LoadSubsetOptions - )! - const data = inserts.map(({ value }) => value) - return Promise.resolve(data) - } - - createQueryFromOpts(opts, queryFn) - } - const isSubscribed = (hashedQueryKey: string) => { return unsubscribes.has(hashedQueryKey) } @@ -972,15 +956,10 @@ export function queryCollectionOptions( // This prevents redundant snapshot requests when multiple concurrent // live queries request overlapping or subset predicates const loadSubsetDedupe = - syncMode === `eager` - ? undefined - : new DeduplicatedLoadSubset({ - loadSubset: createQueryFromOpts, - onDeduplicate: createLocalQuery, - }) + syncMode === `eager` ? undefined : createQueryFromOpts return { - loadSubset: loadSubsetDedupe?.loadSubset, + loadSubset: loadSubsetDedupe, cleanup, } } From df1de286bcce63eb9967d4fc510980bf30d86b71 Mon Sep 17 00:00:00 2001 From: Kevin De Porre Date: Mon, 17 Nov 2025 16:29:21 +0100 Subject: [PATCH 2/2] Fix dedupe unit test --- .../query-db-collection/tests/query.test.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/query-db-collection/tests/query.test.ts b/packages/query-db-collection/tests/query.test.ts index 2f218d73a..4babe3574 100644 --- a/packages/query-db-collection/tests/query.test.ts +++ b/packages/query-db-collection/tests/query.test.ts @@ -3424,7 +3424,7 @@ describe(`QueryCollection`, () => { expect(collection.has(`4`)).toBe(false) }) - it(`should deduplicate queries and handle GC correctly when queries are ordered and have a LIMIT`, async () => { + it(`should handle GC correctly when queries are ordered and have a LIMIT`, async () => { const baseQueryKey = [`deduplication-gc-test`] // Mock queryFn to return different data based on predicates @@ -3434,12 +3434,14 @@ describe(`QueryCollection`, () => { const { where, limit } = loadSubsetOptions // Query 1: all items with category A (no limit) - if (isCategory(`A`, where) && !limit) { - return Promise.resolve([ + if (isCategory(`A`, where)) { + const items = [ { id: `1`, name: `Item 1`, category: `A` }, { id: `2`, name: `Item 2`, category: `A` }, { id: `3`, name: `Item 3`, category: `A` }, - ]) + ] + // Slice to limit if provided + return Promise.resolve(limit ? items.slice(0, limit) : items) } return Promise.resolve([]) @@ -3510,10 +3512,9 @@ describe(`QueryCollection`, () => { await flushPromises() - // Second query should still only have been called once - // since query2 is deduplicated so it is executed against the local collection - // and not via queryFn - expect(queryFn).toHaveBeenCalledTimes(1) + // queryFn should have been called twice + // because we do not dedupe the 2nd query + expect(queryFn).toHaveBeenCalledTimes(2) // Collection should still have all 3 items (deduplication doesn't remove data) expect(collection.size).toBe(3)