Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Progressive collection live queries remain suspended after their requested subset finishes loading

已关闭
#2,113 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

已经有一个关联 PR 被合并了。

  • #2115 来自 @KyleAMathews —— 已合并

评估

难度
4/5
预计耗时
3-5 天
新手友好度
25/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
停滞
领域
backend, database

调研方向

Start by reading the progressive on-demand sync and live query readiness paths in the @tanstack/db package, then run the standalone reproduction from the issue with Node.js 24. Trace how subset completion and outstanding query subsets affect readiness and preload(). Done means the requested subsets make the query ready and resolve preload() while source full sync is pending, with unrelated outstanding subsets still awaited; an open linked pull request already addresses this issue.

由索引模型根据 Issue 内容生成。

描述

  • I've validated the bug against the latest version of DB packages (@tanstack/[email protected], tested 2026-10-12).

Describe the bug

A filtered root live query remains unready after its requested on-demand subset has completed and the matching row is already present in query.toArray. query.preload() remains pending until the source collection calls markReady().

We encountered this with Electric progressive collections and useLiveSuspenseQuery: a detail page's loading fallback waited for the entire source collection to finish syncing, instead of rendering after its requested subset was available. The reproduction below isolates the readiness behavior in @tanstack/db; it does not require React or an Electric server.

To reproduce

Use Node.js 24 and an otherwise empty directory:

yarn init -y
yarn add @tanstack/[email protected] [email protected]
# Save the following code as repro.mjs:
node repro.mjs

The custom sync adapter models the relevant progressive-sync lifecycle: it publishes the requested subset and resolves loadSubset, while deliberately withholding the source's full-sync markReady() until after the first observation. Electric exposes progressive mode to DB as an on-demand source.

import assert from 'node:assert/strict';
import {setTimeout as delay} from 'node:timers/promises';
import {createCollection, eq, liveQueryCollectionOptions} from '@tanstack/db';

// Model Electric progressive sync: the requested subset can finish before
// background full sync calls markReady(). No Electric server is needed.
const subsetRequested = Promise.withResolvers();
const subsetFinished = Promise.withResolvers();
let publish;
let finishFullSync;
const source = createCollection({
  getKey: (row) => row.id,
  syncMode: 'on-demand',
  gcTime: 0,
  sync: {
    sync: ({begin, write, commit, markReady}) => {
      finishFullSync = markReady;
      publish = async () => {
        begin();
        write({type: 'insert', value: {id: 1, uid: 'target'}});
        await commit();
      };
      return {
        loadSubset: () => {
          subsetRequested.resolve();
          return subsetFinished.promise;
        },
        cleanup: () => {},
      };
    },
  },
});
const query = createCollection(liveQueryCollectionOptions({
  query: (q) => q.from({item: source})
    .where(({item}) => eq(item.uid, 'target'))
    .findOne(),
  gcTime: 0,
}));

let preloadResolved = false;
const preload = query.preload().then(() => { preloadResolved = true; });

try {
  await subsetRequested.promise;
  await publish();
  subsetFinished.resolve();
  // Allow asynchronous query processing to settle. Full sync is deliberately
  // held until after we capture this state; no network timing is involved.
  await delay(100);
  const beforeFullSync = {
    requestedRows: query.toArray.map(({id, uid}) => ({id, uid})),
    sourceReady: source.isReady(),
    queryReady: query.isReady(),
    preloadResolved,
  };
  console.log('After requested subset completes:', beforeFullSync);

  finishFullSync();
  await preload;
  console.log('After full sync completes:', {queryReady: query.isReady(), preloadResolved});

  assert.deepEqual(beforeFullSync.requestedRows, [{id: 1, uid: 'target'}]);
  assert.equal(beforeFullSync.sourceReady, false);
  assert.equal(beforeFullSync.queryReady, true,
    'Query should be ready after its requested subset completes, before full sync');
  assert.equal(beforeFullSync.preloadResolved, true);
} finally {
  await query.cleanup();
  await source.cleanup();
}

Actual behavior

Reproduced with @tanstack/db 0.12.3 and 0.13.0:

After requested subset completes: {
  requestedRows: [ { id: 1, uid: 'target' } ],
  sourceReady: false,
  queryReady: false,
  preloadResolved: false
}
After full sync completes: { queryReady: true, preloadResolved: true }
AssertionError: Query should be ready after its requested subset completes, before full sync

Expected behavior

After the query's requested subset has completed, the query should become ready and preload() should resolve even while the progressive source's full background sync is still running. It should still wait for any outstanding subsets required by the query; the presence of a row alone is not enough to indicate readiness.

Environment

  • macOS, Node.js 24.21.0, Yarn 4.5.0.
  • Standalone reproduction: @tanstack/db 0.12.3 and 0.13.0.
  • Original React/Electric application: @tanstack/db 0.12.3, @tanstack/react-db 0.5.7, @tanstack/electric-db-collection 0.5.8, Microsoft Edge.
主要语言
TypeScript
星标
3.9k
派生
272
平均合并
1 天 1 小时
30 天内合并 PR
235

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

TanStack/db 的其他 Issue

查看 TanStack/db 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。