Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#2,260 0 commenti 1 reazione 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
1-2 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
typescript
Ambito
database

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.

Lingua principale
TypeScript
Stelle
4k
Fork
277
Merge medio
21h 21m
PR unite (30g)
218

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di TanStack/db

Tutte le issue di TanStack/db

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.