Skip to content

Commit 88b9e83

Browse files
authored
Merge branch 'main' into feat/mutationfn-context
2 parents 0bf7733 + b43af57 commit 88b9e83

File tree

94 files changed

+604
-184
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+604
-184
lines changed

docs/config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,10 @@
757757
{
758758
"label": "notifyManager",
759759
"to": "reference/notifyManager"
760+
},
761+
{
762+
"label": "timeoutManager",
763+
"to": "reference/timeoutManager"
760764
}
761765
],
762766
"frameworks": [

docs/framework/react/plugins/persistQueryClient.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ It should be set as the same value or higher than persistQueryClient's `maxAge`
2121

2222
You can also pass it `Infinity` to disable garbage collection behavior entirely.
2323

24-
Due to a Javascript limitation, the maximum allowed `gcTime` is about 24 days (see [more](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value)).
24+
Due to a JavaScript limitation, the maximum allowed `gcTime` is about [24 days](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value), although it is possible to work around this limit using [timeoutManager.setTimeoutProvider](../../../../reference/timeoutManager.md#timeoutmanagersettimeoutprovider).
2525

2626
```tsx
2727
const queryClient = new QueryClient({

docs/framework/react/reference/useMutation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ mutate(variables, {
5656
- `gcTime: number | Infinity`
5757
- The time in milliseconds that unused/inactive cache data remains in memory. When a mutation's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different cache times are specified, the longest one will be used.
5858
- If set to `Infinity`, will disable garbage collection
59-
- Note: the maximum allowed time is about 24 days. See [more](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value).
59+
- Note: the maximum allowed time is about [24 days](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value), although it is possible to work around this limit using [timeoutManager.setTimeoutProvider](../../../../reference/timeoutManager.md#timeoutmanagersettimeoutprovider).
6060
- `mutationKey: unknown[]`
6161
- Optional
6262
- A mutation key can be set to inherit defaults set with `queryClient.setMutationDefaults`.

docs/framework/react/reference/useQuery.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const {
101101
- `gcTime: number | Infinity`
102102
- Defaults to `5 * 60 * 1000` (5 minutes) or `Infinity` during SSR
103103
- The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different garbage collection times are specified, the longest one will be used.
104-
- Note: the maximum allowed time is about 24 days. See [more](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value).
104+
- Note: the maximum allowed time is about [24 days](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value), although it is possible to work around this limit using [timeoutManager.setTimeoutProvider](../../../../reference/timeoutManager.md#timeoutmanagersettimeoutprovider).
105105
- If set to `Infinity`, will disable garbage collection
106106
- `queryKeyHashFn: (queryKey: QueryKey) => string`
107107
- Optional

docs/framework/solid/reference/useQuery.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,9 @@ function App() {
223223
- ##### `gcTime: number | Infinity`
224224
- Defaults to `5 * 60 * 1000` (5 minutes) or `Infinity` during SSR
225225
- The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different garbage collection times are specified, the longest one will be used.
226-
- Note: the maximum allowed time is about 24 days. See [more](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value).
226+
- Note: the maximum allowed time is about [24 days](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#maximum_delay_value), although it is possible to work around this limit using [timeoutManager.setTimeoutProvider](../../../../reference/timeoutManager.md#timeoutmanagersettimeoutprovider).
227227
- If set to `Infinity`, will disable garbage collection
228-
- ##### `networkMode: 'online' | 'always' | 'offlineFirst`
228+
- ##### `networkMode: 'online' | 'always' | 'offlineFirst'`
229229
- optional
230230
- defaults to `'online'`
231231
- see [Network Mode](../../guides/network-mode.md) for more information.

docs/reference/timeoutManager.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
id: TimeoutManager
3+
title: TimeoutManager
4+
---
5+
6+
The `TimeoutManager` handles `setTimeout` and `setInterval` timers in TanStack Query.
7+
8+
TanStack Query uses timers to implement features like query `staleTime` and `gcTime`, as well as retries, throttling, and debouncing.
9+
10+
By default, TimeoutManager uses the global `setTimeout` and `setInterval`, but it can be configured to use custom implementations instead.
11+
12+
Its available methods are:
13+
14+
- [`timeoutManager.setTimeoutProvider`](#timeoutmanagersettimeoutprovider)
15+
- [`TimeoutProvider`](#timeoutprovider)
16+
- [`timeoutManager.setTimeout`](#timeoutmanagersettimeout)
17+
- [`timeoutManager.clearTimeout`](#timeoutmanagercleartimeout)
18+
- [`timeoutManager.setInterval`](#timeoutmanagersetinterval)
19+
- [`timeoutManager.clearInterval`](#timeoutmanagerclearinterval)
20+
21+
## `timeoutManager.setTimeoutProvider`
22+
23+
`setTimeoutProvider` can be used to set a custom implementation of the `setTimeout`, `clearTimeout`, `setInterval`, `clearInterval` functions, called a `TimeoutProvider`.
24+
25+
This may be useful if you notice event loop performance issues with thousands of queries. A custom TimeoutProvider could also support timer delays longer than the global `setTimeout` maximum delay value of about [24 days](https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout#maximum_delay_value).
26+
27+
It is important to call `setTimeoutProvider` before creating a QueryClient or queries, so that the same provider is used consistently for all timers in the application, since different TimeoutProviders cannot cancel each others' timers.
28+
29+
```tsx
30+
import { timeoutManager, QueryClient } from '@tanstack/react-query'
31+
import { CustomTimeoutProvider } from './CustomTimeoutProvider'
32+
33+
timeoutManager.setTimeoutProvider(new CustomTimeoutProvider())
34+
35+
export const queryClient = new QueryClient()
36+
```
37+
38+
### `TimeoutProvider`
39+
40+
Timers are very performance sensitive. Short term timers (such as those with delays less than 5 seconds) tend to be latency sensitive, where long-term timers may benefit more from [timer coalescing](https://en.wikipedia.org/wiki/Timer_coalescing) - batching timers with similar deadlines together - using a data structure like a [hierarchical time wheel](https://www.npmjs.com/package/timer-wheel).
41+
42+
The `TimeoutProvider` type requires that implementations handle timer ID objects that can be converted to `number` via [Symbol.toPrimitive][toPrimitive] because runtimes like NodeJS return [objects][nodejs-timeout] from their global `setTimeout` and `setInterval` functions. TimeoutProvider implementations are free to coerce timer IDs to number internally, or to return their own custom object type that implements `{ [Symbol.toPrimitive]: () => number }`.
43+
44+
[nodejs-timeout]: https://nodejs.org/api/timers.html#class-timeout
45+
[toPrimitive]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive
46+
47+
```tsx
48+
type ManagedTimerId = number | { [Symbol.toPrimitive]: () => number }
49+
50+
type TimeoutProvider<TTimerId extends ManagedTimerId = ManagedTimerId> = {
51+
readonly setTimeout: (callback: TimeoutCallback, delay: number) => TTimerId
52+
readonly clearTimeout: (timeoutId: TTimerId | undefined) => void
53+
54+
readonly setInterval: (callback: TimeoutCallback, delay: number) => TTimerId
55+
readonly clearInterval: (intervalId: TTimerId | undefined) => void
56+
}
57+
```
58+
59+
## `timeoutManager.setTimeout`
60+
61+
`setTimeout(callback, delayMs)` schedules a callback to run after approximately `delay` milliseconds, like the global [setTimeout function](https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout).The callback can be canceled with `timeoutManager.clearTimeout`.
62+
63+
It returns a timer ID, which may be a number or an object that can be coerced to a number via [Symbol.toPrimitive][toPrimitive].
64+
65+
```tsx
66+
import { timeoutManager } from '@tanstack/react-query'
67+
68+
const timeoutId = timeoutManager.setTimeout(
69+
() => console.log('ran at:', new Date()),
70+
1000,
71+
)
72+
73+
const timeoutIdNumber: number = Number(timeoutId)
74+
```
75+
76+
## `timeoutManager.clearTimeout`
77+
78+
`clearTimeout(timerId)` cancels a timeout callback scheduled with `setTimeout`, like the global [clearTimeout function](https://developer.mozilla.org/en-US/docs/Web/API/Window/clearTimeout). It should be called with a timer ID returned by `timeoutManager.setTimeout`.
79+
80+
```tsx
81+
import { timeoutManager } from '@tanstack/react-query'
82+
83+
const timeoutId = timeoutManager.setTimeout(
84+
() => console.log('ran at:', new Date()),
85+
1000,
86+
)
87+
88+
timeoutManager.clearTimeout(timeoutId)
89+
```
90+
91+
## `timeoutManager.setInterval`
92+
93+
`setInterval(callback, intervalMs)` schedules a callback to be called approximately every `intervalMs`, like the global [setInterval function](https://developer.mozilla.org/en-US/docs/Web/API/Window/setInterval).
94+
95+
Like `setTimeout`, it returns a timer ID, which may be a number or an object that can be coerced to a number via [Symbol.toPrimitive](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive).
96+
97+
```tsx
98+
import { timeoutManager } from '@tanstack/react-query'
99+
100+
const intervalId = timeoutManager.setInterval(
101+
() => console.log('ran at:', new Date()),
102+
1000,
103+
)
104+
```
105+
106+
## `timeoutManager.clearInterval`
107+
108+
`clearInterval(intervalId)` can be used to cancel an interval, like the global [clearInterval function](https://developer.mozilla.org/en-US/docs/Web/API/Window/clearInterval). It should be called with an interval ID returned by `timeoutManager.setInterval`.
109+
110+
```tsx
111+
import { timeoutManager } from '@tanstack/react-query'
112+
113+
const intervalId = timeoutManager.setInterval(
114+
() => console.log('ran at:', new Date()),
115+
1000,
116+
)
117+
118+
timeoutManager.clearInterval(intervalId)
119+
```

examples/angular/auto-refetching/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"@angular/compiler": "^20.0.0",
1414
"@angular/core": "^20.0.0",
1515
"@angular/platform-browser": "^20.0.0",
16-
"@tanstack/angular-query-experimental": "^5.86.0",
16+
"@tanstack/angular-query-experimental": "^5.87.0",
1717
"rxjs": "^7.8.2",
1818
"tslib": "^2.8.1",
1919
"zone.js": "0.15.0"

examples/angular/basic-persister/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
"@angular/compiler": "^20.0.0",
1414
"@angular/core": "^20.0.0",
1515
"@angular/platform-browser": "^20.0.0",
16-
"@tanstack/angular-query-experimental": "^5.86.0",
16+
"@tanstack/angular-query-experimental": "^5.87.0",
1717
"@tanstack/angular-query-persist-client": "^5.62.7",
18-
"@tanstack/query-async-storage-persister": "^5.86.0",
18+
"@tanstack/query-async-storage-persister": "^5.87.0",
1919
"rxjs": "^7.8.2",
2020
"tslib": "^2.8.1",
2121
"zone.js": "0.15.0"

examples/angular/basic/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"@angular/compiler": "^20.0.0",
1414
"@angular/core": "^20.0.0",
1515
"@angular/platform-browser": "^20.0.0",
16-
"@tanstack/angular-query-experimental": "^5.86.0",
16+
"@tanstack/angular-query-experimental": "^5.87.0",
1717
"rxjs": "^7.8.2",
1818
"tslib": "^2.8.1",
1919
"zone.js": "0.15.0"

examples/angular/devtools-panel/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
"@angular/core": "^20.0.0",
1515
"@angular/platform-browser": "^20.0.0",
1616
"@angular/router": "^20.0.0",
17-
"@tanstack/angular-query-devtools-experimental": "^5.86.0",
18-
"@tanstack/angular-query-experimental": "^5.86.0",
17+
"@tanstack/angular-query-devtools-experimental": "^5.87.0",
18+
"@tanstack/angular-query-experimental": "^5.87.0",
1919
"rxjs": "^7.8.2",
2020
"tslib": "^2.8.1",
2121
"zone.js": "0.15.0"

0 commit comments

Comments
 (0)