Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
3ebacfe
feat(db): carry join compilation on imported join operators
Oct 22, 2026
16c0be5
feat(db): name the missing join operator when .join() gets the old ca…
Oct 22, 2026
92ad30e
feat(db): carry grouping on aggregates and groupKeys
Oct 22, 2026
3473d76
feat(db): carry the include materializer on include values
Oct 22, 2026
9ffd904
feat(db): make live-query pooling opt-in with pooledLiveQueries
Oct 22, 2026
318ffda
test: migrate packages to opt-in operators and pooling
Oct 22, 2026
8b721ec
docs: document opt-in operators and pooling
Oct 22, 2026
b2abee4
test(db): check that an app bundles only the operators it imports
Oct 22, 2026
3c5b369
ci: apply automated fixes
autofix-ci[bot] Oct 22, 2026
e1e0297
fix(db): keep pool out of DbClient query identity; let Angular params…
Oct 23, 2026
f0668bf
refactor(db): carry one join runtime; join apps skip the include mate…
Oct 23, 2026
c796f6e
fix(db): reject bare caseWhen subqueries in types and check include()…
Oct 23, 2026
922bd9b
docs: update skills, JSDoc, and changeset for opt-in operators
Oct 23, 2026
4ecfdd8
ci: apply automated fixes
autofix-ci[bot] Oct 23, 2026
a637079
fix(db): keep join conditions compiling without noImplicitAny
Oct 23, 2026
003daac
test(db): compile join conditions with noImplicitAny on and off
Oct 23, 2026
938ac83
test: typecheck doc and skill examples; reject bare subqueries in select
Oct 23, 2026
5dcd8e3
Merge remote-tracking branch 'origin/opt-in-operators' into opt-in-op…
Oct 23, 2026
32d3f34
test: key the doc example baseline on tokens, not formatting
Oct 23, 2026
ec50aae
test: check opt-in pooling in every adapter input form
Oct 23, 2026
e9e5d9c
fix: map package subpath exports to source in the doc example check
Oct 23, 2026
48a1541
Merge remote-tracking branch 'origin/main' into opt-in-operators
Oct 23, 2026
141b7bd
fix: address the xhigh review of opt-in operators
Oct 23, 2026
5cc975c
ci: apply automated fixes
autofix-ci[bot] Oct 23, 2026
1d28d81
fix: address the medium review of opt-in operators
Oct 23, 2026
39796da
Merge remote-tracking branch 'origin/opt-in-operators' into opt-in-op…
Oct 23, 2026
f050427
revert(db): keep joins in core with the existing join API
Oct 23, 2026
c943cd9
Merge remote-tracking branch 'origin/main' into opt-in-operators
Oct 23, 2026
e642360
ci: apply automated fixes
autofix-ci[bot] Oct 23, 2026
9287e21
fix: address the xhigh review of opt-in grouping, includes, and pooling
Oct 26, 2026
ee06210
Merge remote-tracking branch 'origin/main' into opt-in-operators
Oct 26, 2026
17cb8e6
docs: regenerate the API reference; update the changeset's size
Oct 26, 2026
a19d861
Merge origin/main (#2235: preact-db and shared adapter identity) into…
Oct 26, 2026
e0ab8d5
fix: evaluate the high review of opt-in operators
Oct 26, 2026
f8e4e7b
test(angular-db): route ErrorHandler reports to the rejecting handle
Oct 26, 2026
fd76046
fix: close the third high review of opt-in operators
Oct 26, 2026
b8461e5
test: strengthen the opt-in operator oracles
Oct 26, 2026
2bf2462
test: lift the aggregate-select oracle's orderBy and grouping limits
Oct 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
18 changes: 18 additions & 0 deletions .changeset/opt-in-operators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@tanstack/db': minor
'@tanstack/react-db': patch
'@tanstack/preact-db': patch
'@tanstack/svelte-db': patch
'@tanstack/vue-db': patch
'@tanstack/solid-db': patch
'@tanstack/angular-db': patch
---

Breaking: grouping, includes, and pooling are now opt-in. An app bundles an operator's code only when it imports the value for that operator. Joins do not change. A typical app is about 8 kB smaller after gzip. This app has a query collection, a filtered live query, and React `useLiveQuery`.

- An include needs `include()`, `toArray()`, or `materialize()`. Change `issues: q.from(...)` in `select()` to `issues: include(q.from(...))`. A subquery in `select()` without one of these throws `IncludeOperatorRequiredError`.
- Aggregates such as `count()` need no change. A `groupBy` with no aggregate takes `groupKeys()`: `.groupBy(groupKeys(({ todo }) => todo.status))`. Without it, the query throws `GroupingOperatorRequiredError`.
- Hooks do not pool live queries by default. To share one partition among many equality-filtered queries, pass `pool: pooledLiveQueries` in the hook's query config: `useLiveQuery({ query, pool: pooledLiveQueries })`. Results do not change. Angular's `{ params, query }` form takes `pool` the same way. Any other `pool` value, such as the old boolean, throws `InvalidPoolOptionError`, also for a disabled query. For adapter authors: the `pool` option of `resolveLiveQueryValue` is now `pooledLiveQueries` or `false`, not a boolean. An adapter that reads `pool` from its own options checks it with `configPool` first.
- Code that builds query IR by hand must supply the operator code. `IR.Aggregate` takes `groupingCompiler` as its third argument. `IR.IncludesSubquery` takes `includesRuntime` as its fifth argument, before `parentFilters`. Import both from `@tanstack/db`. IR without them throws `GroupingOperatorRequiredError` or `IncludeOperatorRequiredError` when it compiles, unless another aggregate or `groupKeys()` in the query supplies the grouping compiler. Queries that the query builder builds need no change.
- Operator code is part of query identity. A hook that re-renders a grouped query without `groupKeys()` now throws `GroupingOperatorRequiredError`. Before, React and Preact kept the grouped query.
- Vue: when a changed query fails to compile, `useLiveQuery` no longer shows the rows of the previous query.
2 changes: 2 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
uses: tanstack/config/.github/setup@e4b48f16568324f76f467aa4c2aac2f05db632c3
- name: Check lint
run: pnpm run lint:check
- name: Typecheck doc and skill examples
run: pnpm run test:doc-snippets
- name: Check oracle lint without inline directives
run: pnpm run lint:oracles
- name: Test oracle lint rules
Expand Down
92 changes: 90 additions & 2 deletions docs/contributing/oracle-coverage.md

Large diffs are not rendered by default.

56 changes: 53 additions & 3 deletions docs/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,36 @@ Development builds show the full message. For example:
[useLiveQuery] Collection ID "todos" named a different source Collection than one this live query already read. While the hook is mounted, each Collection ID must keep naming one source Collection. Unmount the hook and clean up its previous source and client scope before reusing the ID.
```

<a id="error-247"></a>

## Error 247: `GroupingOperatorRequiredError`

Development builds show the full message. For example:

```text
groupBy() without an aggregate needs groupKeys(), such as .groupBy(groupKeys(({ todo }) => todo.status)). Import groupKeys from @tanstack/db. A query with an aggregate such as count() needs nothing extra. Query IR built by hand passes groupingCompiler to each IR.Aggregate.
```

<a id="error-248"></a>

## Error 248: `IncludeOperatorRequiredError`

Development builds show the full message. For example:

```text
A subquery in select() needs include(), toArray(), or materialize(). Wrap the issues field: issues: include(q.from({ i: issues }).where(...)). Import include from @tanstack/db. Query IR built by hand passes includesRuntime to each IR.IncludesSubquery.
```

<a id="error-251"></a>

## Error 251: `InvalidPoolOptionError`

Development builds show the full message. For example:

```text
A live query's pool option takes pooledLiveQueries from @tanstack/db, or nothing. Pooling is opt-in: pass pool: pooledLiveQueries to share one partition among equality-filtered queries.
```

## Other errors and log messages

These are plain `Error`, `TypeError`, `RangeError`, or
Expand Down Expand Up @@ -1668,7 +1698,7 @@ Query '${this.id}' has no collection sources. This should not happen; please rep

<a id="error-154"></a>

## Error 154: `query/live/materialized-pipeline.ts`
## Error 154: `query/live/public-key-reduction.ts`

Development builds show this message, with `${...}` replaced by values:

Expand All @@ -1678,7 +1708,7 @@ Canonical query row has negative multiplicity

<a id="error-155"></a>

## Error 155: `query/live/materialized-pipeline.ts`
## Error 155: `query/live/public-key-reduction.ts`

Development builds show this message, with `${...}` replaced by values:

Expand All @@ -1688,7 +1718,7 @@ Canonical query row has no positive contributor

<a id="error-156"></a>

## Error 156: `query/live/materialized-pipeline.ts`
## Error 156: `query/live/public-key-reduction.ts`

Development builds show this message, with `${...}` replaced by values:

Expand Down Expand Up @@ -2489,3 +2519,23 @@ Development builds show this message, with `${...}` replaced by values:
```text
getNextPageParam is not supported by useLiveInfiniteQuery. Use an on-demand collection and fulfill meta.loadSubsetOptions in queryFn for server pagination.
```

<a id="error-249"></a>

## Error 249: `query/builder/index.ts`

Development builds show this message, with `${...}` replaced by values:

```text
include() must wrap a subquery builder
```

<a id="error-250"></a>

## Error 250: `query/builder/index.ts`

Development builds show this message, with `${...}` replaced by values:

```text
include() must wrap a subquery builder
```
30 changes: 22 additions & 8 deletions docs/framework/angular/reference/functions/injectLiveQuery.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ title: injectLiveQuery
function injectLiveQuery<TContext, TParams>(options): InjectLiveQueryResult<TContext>;
```

Defined in: [index.ts:119](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L119)
Defined in: [angular-db/src/index.ts:121](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L121)

### Type Parameters

Expand All @@ -29,6 +29,13 @@ Defined in: [index.ts:119](https://github.com/TanStack/db/blob/main/packages/ang

() => `TParams`

##### pool?

\{
\}

Pass `pooledLiveQueries` to share one partition among equal-shape queries.

##### query

(`args`) => `QueryBuilder`\<`TContext`\>
Expand All @@ -43,7 +50,7 @@ Defined in: [index.ts:119](https://github.com/TanStack/db/blob/main/packages/ang
function injectLiveQuery<TContext, TParams>(options): InjectConditionalLiveQueryResult<TContext>;
```

Defined in: [index.ts:129](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L129)
Defined in: [angular-db/src/index.ts:133](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L133)

### Type Parameters

Expand All @@ -63,6 +70,13 @@ Defined in: [index.ts:129](https://github.com/TanStack/db/blob/main/packages/ang

() => `TParams`

##### pool?

\{
\}

Pass `pooledLiveQueries` to share one partition among equal-shape queries.

##### query

(`args`) => `QueryBuilder`\<`TContext`\> \| `null` \| `undefined`
Expand All @@ -77,7 +91,7 @@ Defined in: [index.ts:129](https://github.com/TanStack/db/blob/main/packages/ang
function injectLiveQuery<TContext>(queryFn): InjectLiveQueryResult<TContext>;
```

Defined in: [index.ts:139](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L139)
Defined in: [angular-db/src/index.ts:145](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L145)

### Type Parameters

Expand All @@ -101,7 +115,7 @@ Defined in: [index.ts:139](https://github.com/TanStack/db/blob/main/packages/ang
function injectLiveQuery<TContext>(queryFn): InjectConditionalLiveQueryResult<TContext>;
```

Defined in: [index.ts:142](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L142)
Defined in: [angular-db/src/index.ts:148](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L148)

### Type Parameters

Expand All @@ -125,7 +139,7 @@ Defined in: [index.ts:142](https://github.com/TanStack/db/blob/main/packages/ang
function injectLiveQuery<TContext>(config): InjectLiveQueryResult<TContext>;
```

Defined in: [index.ts:147](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L147)
Defined in: [angular-db/src/index.ts:153](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L153)

### Type Parameters

Expand All @@ -137,7 +151,7 @@ Defined in: [index.ts:147](https://github.com/TanStack/db/blob/main/packages/ang

#### config

`LiveQueryCollectionConfig`\<`TContext`\>
`LiveQueryHookConfig`\<`TContext`\>

### Returns

Expand All @@ -149,7 +163,7 @@ Defined in: [index.ts:147](https://github.com/TanStack/db/blob/main/packages/ang
function injectLiveQuery<TResult, TKey, TUtils>(liveQueryCollection): InjectLiveQueryResultWithCollection<TResult, TKey, TUtils>;
```

Defined in: [index.ts:151](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L151)
Defined in: [angular-db/src/index.ts:157](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L157)

### Type Parameters

Expand Down Expand Up @@ -181,7 +195,7 @@ Defined in: [index.ts:151](https://github.com/TanStack/db/blob/main/packages/ang
function injectLiveQuery<TResult, TKey, TUtils>(liveQueryCollection): InjectLiveQueryResultWithSingleResultCollection<TResult, TKey, TUtils>;
```

Defined in: [index.ts:159](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L159)
Defined in: [angular-db/src/index.ts:165](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L165)

### Type Parameters

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ id: InjectLiveQueryResult
title: InjectLiveQueryResult
---

Defined in: [index.ts:41](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L41)
Defined in: [angular-db/src/index.ts:43](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L43)

The result of calling `injectLiveQuery`.
Contains reactive signals for the query state and data.
Expand All @@ -25,7 +25,7 @@ collection: Signal<
| null>;
```

Defined in: [index.ts:47](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L47)
Defined in: [angular-db/src/index.ts:49](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L49)

A signal containing the underlying collection instance (null for disabled queries)

Expand All @@ -37,7 +37,7 @@ A signal containing the underlying collection instance (null for disabled querie
data: Signal<InferResultType<TContext>>;
```

Defined in: [index.ts:45](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L45)
Defined in: [angular-db/src/index.ts:47](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L47)

A signal containing the results as an array, or single result for findOne queries

Expand All @@ -49,7 +49,7 @@ A signal containing the results as an array, or single result for findOne querie
isCleanedUp: Signal<boolean>;
```

Defined in: [index.ts:66](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L66)
Defined in: [angular-db/src/index.ts:68](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L68)

A signal indicating whether the collection has been cleaned up

Expand All @@ -61,7 +61,7 @@ A signal indicating whether the collection has been cleaned up
isError: Signal<boolean>;
```

Defined in: [index.ts:64](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L64)
Defined in: [angular-db/src/index.ts:66](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L66)

A signal indicating whether the collection has an error

Expand All @@ -73,7 +73,7 @@ A signal indicating whether the collection has an error
isIdle: Signal<boolean>;
```

Defined in: [index.ts:62](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L62)
Defined in: [angular-db/src/index.ts:64](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L64)

A signal indicating whether the collection is idle

Expand All @@ -85,7 +85,7 @@ A signal indicating whether the collection is idle
isLoading: Signal<boolean>;
```

Defined in: [index.ts:55](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L55)
Defined in: [angular-db/src/index.ts:57](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L57)

A signal indicating whether the collection is currently loading

Expand All @@ -97,7 +97,7 @@ A signal indicating whether the collection is currently loading
isPersistedReady: Signal<boolean>;
```

Defined in: [index.ts:59](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L59)
Defined in: [angular-db/src/index.ts:61](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L61)

***

Expand All @@ -107,7 +107,7 @@ Defined in: [index.ts:59](https://github.com/TanStack/db/blob/main/packages/angu
isReady: Signal<boolean>;
```

Defined in: [index.ts:57](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L57)
Defined in: [angular-db/src/index.ts:59](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L59)

A signal indicating whether the collection is ready

Expand All @@ -119,7 +119,7 @@ A signal indicating whether the collection is ready
persistedError: Signal<unknown>;
```

Defined in: [index.ts:60](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L60)
Defined in: [angular-db/src/index.ts:62](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L62)

***

Expand All @@ -129,7 +129,7 @@ Defined in: [index.ts:60](https://github.com/TanStack/db/blob/main/packages/angu
persistedStatus: Signal<LiveQueryPersistedStatus>;
```

Defined in: [index.ts:58](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L58)
Defined in: [angular-db/src/index.ts:60](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L60)

***

Expand All @@ -139,7 +139,7 @@ Defined in: [index.ts:58](https://github.com/TanStack/db/blob/main/packages/angu
state: Signal<Map<string | number, { [K in string | number | symbol]: ResultValue<TContext>[K] }>>;
```

Defined in: [index.ts:43](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L43)
Defined in: [angular-db/src/index.ts:45](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L45)

A signal containing the complete state map of results keyed by their ID

Expand All @@ -151,6 +151,6 @@ A signal containing the complete state map of results keyed by their ID
status: Signal<CollectionStatus | "disabled">;
```

Defined in: [index.ts:53](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L53)
Defined in: [angular-db/src/index.ts:55](https://github.com/TanStack/db/blob/main/packages/angular-db/src/index.ts#L55)

A signal containing the current status of the collection
Loading
Loading