Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

Paginated live query fetches entire collection if shared rows unload while the first page is in flight

Aberta
#2,260 0 comentários 1 reação 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
4/5
Tempo estimado
1-2 dias
Facilidade para iniciantes
48/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
typescript
Domínio
database

Direção de pesquisa

Start with packages/db/src/query/live/ordered-source-loader.ts, especially invalidateSourceOrdering, and read the ownership cleanup path in cleanupQueryInternal alongside the linked issues #1880, #1886 and #2194. Run the supplied reproduction as packages/query-db-collection/tests/ownership-cleanup-repro.test.ts with npx vitest run tests/ownership-cleanup-repro.test.ts from packages/query-db-collection, then inspect the four named failures in the ordered source loader oracle tests. Done means the reproduction passes while those existing tests continue to pass and the first-page request remains bounded.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

Title: Paginated live query fetches entire collection if shared rows unload while its first page is in flight

  • I've validated the bug against the latest version of DB packages

Describe the bug

Follow-up to #1880, #1886 and #2194.

One syncMode: 'on-demand' query collection serves two live queries:

  • Query A loads rows by id: where(inArray(id, ids)).
  • Query B is paginated: orderBy(createdAt desc).orderBy(id desc) with useLiveInfiniteQuery.

Here's what happens when the app navigates from a page that uses query A to a page that uses query B:

  1. Query B mounts and requests its first page.
  2. Query A unmounts before that page returns, and its rows unload.
  3. B then requests the whole collection: no where, orderBy or limit.

Expected: one page. Actual: the whole collection is requested until query B is usable. (In my situation, it's 100,000 rows!)

I can reliably reproduce this behavior by flipping on 3G throttling.

Cause:

  1. B begins by showing rows already in the collection from A. B also requests its first page.
  2. A unloads. cleanupQueryInternal deletes the rows that no other subset owns.
  3. OrderedSourceLoader.onSourceChanges sees deletes of rows that B shows. It calls invalidateSourceOrdering().
  4. No request has settled, so the loader owes full repair, not bounded.
  5. The loader calls loadFullSource().

If B's first page arrives before A unloads its rows, then everything behaves as expected: B re-fetches just one page.

To Reproduce

ownership-cleanup-repro.test.ts

Put the attached file named ownership-cleanup-repro.test.ts in packages/query-db-collection/tests/. Then, in packages/query-db-collection run:

npx vitest run tests/ownership-cleanup-repro.test.ts

Result:

AssertionError: expected [ { offset: undefined } ] to deeply equal []

The first test unloads query A while query B's first page is held. The second test is the control: it deletes after the first page settles.

Reproduces on @tanstack/db 0.15.2, @tanstack/query-db-collection 1.4.8 and main (d2935d0).

Expected behavior

B re-fetches one page, whether A unloads before or after B's first page arrives.

Screenshots

N/A

Desktop (please complete the following information):

  • OS: macOS. The test also reproduces it in Node.
  • Browser: any
  • Version: N/A

Smartphone (please complete the following information):

N/A

Additional context

A possible change in invalidateSourceOrdering:

// packages/db/src/query/live/ordered-source-loader.ts
       this.oweDebt(
-        this.hasSettledSourceRequest && this.work.kind === `idle`
+        !this.hasSettledSourceRequest || this.work.kind === `idle`
           ? `bounded`
           : `full`,
       )

The change makes the repro pass. But it breaks tests, so I have not opened a PR.

  • #1886: the one-page repair runs only when the first page has arrived and no request is in flight.
  • #2194: it also runs with requests in flight, but still only after the first page arrives.
  • Before the first page arrives, the loader still reads the whole collection.

With the change, 14 cases fail in four tests in ordered-source-loader-state-oracle.test.ts and ordered-source-loader-oracle.test.ts:

  • "keeps full-source recovery authoritative across an initial page overlap"
  • "a page failure while a full-source demand is held releases only the page"
  • "repairs ordering before an explicit window consumes a staged ordinary continuation"
  • "releases each failed lease once, at a covering replay or the explicit retry"

My fix breaks these tests. I'm sure I don't understand the deeper reasoning. Is there a reason the loader needs to fetch the whole collection here? Please let me know if it is appropriate to open a PR for this.

Linguagem predominante
TypeScript
Estrelas
4k
Forks
277
Merge médio
1d 6h
PRs com merge (30d)
199

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de TanStack/db

Todas as issues de TanStack/db

Issues semelhantes

Mais issues de TypeScript

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.