diff --git a/.changeset/fix-join-on-demand-sync.md b/.changeset/fix-join-on-demand-sync.md new file mode 100644 index 000000000..163062d62 --- /dev/null +++ b/.changeset/fix-join-on-demand-sync.md @@ -0,0 +1,5 @@ +--- +'@tanstack/db': patch +--- + +Fix on-demand sync collections not loading data when used in join queries. Previously, collections with `syncMode: 'on-demand'` would remain idle when used as sources in join queries, causing empty results. Now `startSyncImmediate()` is called on all source collections in `subscribeToAllCollections()` to ensure sync is properly initialized. diff --git a/packages/db/src/query/live/collection-config-builder.ts b/packages/db/src/query/live/collection-config-builder.ts index b663fdad5..1706be42c 100644 --- a/packages/db/src/query/live/collection-config-builder.ts +++ b/packages/db/src/query/live/collection-config-builder.ts @@ -866,6 +866,11 @@ export class CollectionConfigBuilder< }) syncState.unsubscribeCallbacks.add(statusUnsubscribe) + // Ensure sync is started for all source collections in the query. + // This is critical for on-demand sync collections used in joins - without this, + // they remain idle and requestSnapshot() calls from lazy join loading won't work. + collection.startSyncImmediate() + const subscription = collectionSubscriber.subscribe() // Store subscription by alias (not collection ID) to support lazy loading // which needs to look up subscriptions by their query alias diff --git a/packages/db/src/query/live/collection-subscriber.ts b/packages/db/src/query/live/collection-subscriber.ts index 303c833fc..c56e610c2 100644 --- a/packages/db/src/query/live/collection-subscriber.ts +++ b/packages/db/src/query/live/collection-subscriber.ts @@ -197,6 +197,12 @@ export class CollectionSubscriber< whereExpression, }) + // Trigger initial data load for on-demand sync collections. + // This is called regardless of includeInitialState because on-demand collections + // need to explicitly request data loading. For lazy aliases in joins, + // includeInitialState is false but we still need to trigger the sync layer. + subscription.requestSnapshot({}) + return subscription }