Skip to content

Commit 688e6f0

Browse files
committed
Merge branch 'main' into feature/base-url
2 parents 016ec53 + 80dd0db commit 688e6f0

144 files changed

Lines changed: 4335 additions & 3410 deletions

File tree

Some content is hidden

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

docs/framework/react/devtools.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ Wave your hands in the air and shout hooray because React Query comes with dedic
77

88
When you begin your React Query journey, you'll want these devtools by your side. They help visualize all the inner workings of React Query and will likely save you hours of debugging if you find yourself in a pinch!
99

10-
> Please note that for now, the devtools **do not support React Native**. If you would like to help us make the devtools platform-agnostic, please let us know!
11-
12-
> Exciting News: We now have a separate package for React Native React Query DevTools! This new addition brings native support, allowing you to integrate DevTools directly into your React Native projects. Check it out and contribute here: [react-native-react-query-devtools](https://github.com/LovesWorking/react-native-react-query-devtools)
13-
14-
> An external tool is also available that enables the use of React Query DevTools via an external dashboard. Find out more and contribute on [react-query-external-sync](https://github.com/LovesWorking/react-query-external-sync)
10+
> For React Native users: A third-party native macOS app is available for debugging React Query in ANY js-based application. Monitor queries across devices in real-time. Check it out here: [rn-better-dev-tools](https://github.com/LovesWorking/rn-better-dev-tools)
1511
1612
> Note that since version 5, the dev tools support observing mutations as well.
1713

docs/framework/react/guides/advanced-ssr.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ This part is pretty similar to what we did in the SSR guide, we just need to spl
101101

102102
### Prefetching and de/hydrating data
103103

104-
Let's next look at how to actually prefetch data and dehydrate and hydrate it. This is what it looked like using the **Next.js pages router**:
104+
Next, let’s look at how to actually prefetch data, then dehydrate and hydrate it. This is what it looked like using the **Next.js Pages Router**:
105105

106106
```tsx
107107
// pages/posts.tsx

docs/framework/react/guides/infinite-queries.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ function Projects() {
8282
<div>
8383
<button
8484
onClick={() => fetchNextPage()}
85-
disabled={!hasNextPage || isFetchingNextPage}
85+
disabled={!hasNextPage || isFetching}
8686
>
8787
{isFetchingNextPage
8888
? 'Loading more...'
@@ -110,7 +110,7 @@ To ensure a seamless querying process without conflicts, it's highly recommended
110110
[//]: # 'Example1'
111111

112112
```jsx
113-
<List onEndReached={() => !isFetchingNextPage && fetchNextPage()} />
113+
<List onEndReached={() => hasNextPage && !isFetching && fetchNextPage()} />
114114
```
115115

116116
[//]: # 'Example1'

docs/framework/react/plugins/createPersister.md

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
id: createPersister
3-
title: experimental_createPersister
3+
title: experimental_createQueryPersister
44
---
55

66
## Installation
@@ -33,9 +33,9 @@ bun add @tanstack/query-persist-client-core
3333
3434
## Usage
3535

36-
- Import the `experimental_createPersister` function
37-
- Create a new `experimental_createPersister`
38-
- you can pass any `storage` to it that adheres to the `AsyncStorage` or `Storage` interface - the example below uses the async-storage from React Native.
36+
- Import the `experimental_createQueryPersister` function
37+
- Create a new `experimental_createQueryPersister`
38+
- you can pass any `storage` to it that adheres to the `AsyncStorage` interface - the example below uses the async-storage from React Native.
3939
- Pass that `persister` as an option to your Query. This can be done either by passing it to the `defaultOptions` of the `QueryClient` or to any `useQuery` hook instance.
4040
- If you pass this `persister` as `defaultOptions`, all queries will be persisted to the provided `storage`. You can additionally narrow this down by passing `filters`. In contrast to the `persistClient` plugin, this will not persist the whole query client as a single item, but each query separately. As a key, the query hash is used.
4141
- If you provide this `persister` to a single `useQuery` hook, only this Query will be persisted.
@@ -48,16 +48,18 @@ Garbage collecting a Query from memory **does not** affect the persisted data. T
4848
```tsx
4949
import AsyncStorage from '@react-native-async-storage/async-storage'
5050
import { QueryClient } from '@tanstack/react-query'
51-
import { experimental_createPersister } from '@tanstack/query-persist-client-core'
51+
import { experimental_createQueryPersister } from '@tanstack/query-persist-client-core'
52+
53+
const persister = experimental_createQueryPersister({
54+
storage: AsyncStorage,
55+
maxAge: 1000 * 60 * 60 * 12, // 12 hours
56+
})
5257

5358
const queryClient = new QueryClient({
5459
defaultOptions: {
5560
queries: {
5661
gcTime: 1000 * 30, // 30 seconds
57-
persister: experimental_createPersister({
58-
storage: AsyncStorage,
59-
maxAge: 1000 * 60 * 60 * 12, // 12 hours
60-
}),
62+
persister: persister.persisterFn,
6163
},
6264
},
6365
})
@@ -67,12 +69,62 @@ const queryClient = new QueryClient({
6769

6870
The `createPersister` plugin technically wraps the `queryFn`, so it doesn't restore if the `queryFn` doesn't run. In that way, it acts as a caching layer between the Query and the network. Thus, the `networkMode` defaults to `'offlineFirst'` when a persister is used, so that restoring from the persistent storage can also happen even if there is no network connection.
6971

72+
## Additional utilities
73+
74+
Invoking `experimental_createQueryPersister` returns additional utilities in addition to `persisterFn` for easier implementation of userland functionalities.
75+
76+
### `persistQueryByKey(queryKey: QueryKey, queryClient: QueryClient): Promise<void>`
77+
78+
This function will persist `Query` to storage and key defined when creating persister.
79+
This utility might be used along `setQueryData` to persist optimistic update to storage without waiting for invalidation.
80+
81+
```tsx
82+
const persister = experimental_createQueryPersister({
83+
storage: AsyncStorage,
84+
maxAge: 1000 * 60 * 60 * 12, // 12 hours
85+
})
86+
87+
const queryClient = useQueryClient()
88+
89+
useMutation({
90+
mutationFn: updateTodo,
91+
onMutate: async (newTodo) => {
92+
...
93+
// Optimistically update to the new value
94+
queryClient.setQueryData(['todos'], (old) => [...old, newTodo])
95+
// And persist it to storage
96+
persister.persistQueryByKey(['todos'], queryClient)
97+
...
98+
},
99+
})
100+
```
101+
102+
### `retrieveQuery<T>(queryHash: string): Promise<T | undefined>`
103+
104+
This function would attempt to retrieve persisted query by `queryHash`.
105+
If `query` is `expired`, `busted` or `malformed` it would be removed from the storage instead, and `undefined` would be returned.
106+
107+
### `persisterGc(): Promise<void>`
108+
109+
This function can be used to sporadically clean up stoage from `expired`, `busted` or `malformed` entries.
110+
111+
For this function to work, your storage must expose `entries` method that would return a `key-value tuple array`.
112+
For example `Object.entries(localStorage)` for `localStorage` or `entries` from `idb-keyval`.
113+
114+
### `persisterRestoreAll(queryClient: QueryClient): Promise<void>`
115+
116+
This function can be used to restore all queries that are currently stored by persister in one go.
117+
For example when your app is starting up in offline mode, or you want data from previous session to be immediately available without intermediate `loading` state.
118+
119+
For this function to work, your storage must expose `entries` method that would return a `key-value tuple array`.
120+
For example `Object.entries(localStorage)` for `localStorage` or `entries` from `idb-keyval`.
121+
70122
## API
71123

72-
### `experimental_createPersister`
124+
### `experimental_createQueryPersister`
73125

74126
```tsx
75-
experimental_createPersister(options: StoragePersisterOptions)
127+
experimental_createQueryPersister(options: StoragePersisterOptions)
76128
```
77129

78130
#### `Options`
@@ -116,10 +168,11 @@ export interface StoragePersisterOptions {
116168
filters?: QueryFilters
117169
}
118170

119-
interface AsyncStorage {
120-
getItem: (key: string) => Promise<string | undefined | null>
121-
setItem: (key: string, value: string) => Promise<unknown>
122-
removeItem: (key: string) => Promise<void>
171+
interface AsyncStorage<TStorageValue = string> {
172+
getItem: (key: string) => MaybePromise<TStorageValue | undefined | null>
173+
setItem: (key: string, value: TStorageValue) => MaybePromise<unknown>
174+
removeItem: (key: string) => MaybePromise<void>
175+
entries?: () => MaybePromise<Array<[key: string, value: TStorageValue]>>
123176
}
124177
```
125178

docs/framework/react/react-native.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@ id: react-native
33
title: React Native
44
---
55

6-
React Query is designed to work out of the box with React Native, with the exception of the devtools, which are only supported with React DOM at this time.
6+
React Query is designed to work out of the box with React Native.
77

8-
There is a 3rd party [Expo](https://docs.expo.dev/) plugin which you can try: https://github.com/expo/dev-plugins/tree/main/packages/react-query
8+
## DevTools Support
99

10-
There is a 3rd party [Flipper](https://fbflipper.com/docs/getting-started/react-native/) plugin which you can try: https://github.com/bgaleotti/react-query-native-devtools
10+
There are several options available for React Native DevTools integration:
1111

12-
There is a 3rd party [Reactotron](https://github.com/infinitered/reactotron/) plugin which you can try: https://github.com/hsndmr/reactotron-react-query
12+
1. **Native macOS App**: A 3rd party app for debugging React Query in any js-based application:
13+
https://github.com/LovesWorking/rn-better-dev-tools
1314

14-
If you would like to help us make the built-in devtools platform agnostic, please let us know!
15+
2. **Flipper Plugin**: A 3rd party plugin for Flipper users:
16+
https://github.com/bgaleotti/react-query-native-devtools
17+
18+
3. **Reactotron Plugin**: A 3rd party plugin for Reactotron users:
19+
https://github.com/hsndmr/reactotron-react-query
1520

1621
## Online status management
1722

docs/framework/vue/plugins/createPersister.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
id: createPersister
3-
title: experimental_createPersister
3+
title: experimental_createQueryPersister
44
---
55

66
## Installation
@@ -31,8 +31,8 @@ bun add @tanstack/query-persist-client-core
3131

3232
## Usage
3333

34-
- Import the `experimental_createPersister` function
35-
- Create a new `experimental_createPersister`
34+
- Import the `experimental_createQueryPersister` function
35+
- Create a new `experimental_createQueryPersister`
3636
- you can pass any `storage` to it that adheres to the `AsyncStorage` or `Storage` interface
3737
- Pass that `persister` as an option to your Query. This can be done either by passing it to the `defaultOptions` of the `QueryClient` or to any `useQuery` hook instance.
3838
- If you pass this `persister` as `defaultOptions`, all queries will be persisted to the provided `storage`. You can additionally narrow this down by passing `filters`. In contrast to the `persistClient` plugin, this will not persist the whole query client as a single item, but each query separately. As a key, the query hash is used.
@@ -44,16 +44,18 @@ Garbage collecting a Query from memory **does not** affect the persisted data. T
4444

4545
```tsx
4646
import { QueryClient } from '@tanstack/vue-query'
47-
import { experimental_createPersister } from '@tanstack/query-persist-client-core'
47+
import { experimental_createQueryPersister } from '@tanstack/query-persist-client-core'
48+
49+
const persister = experimental_createQueryPersister({
50+
storage: AsyncStorage,
51+
maxAge: 1000 * 60 * 60 * 12, // 12 hours
52+
})
4853

4954
const queryClient = new QueryClient({
5055
defaultOptions: {
5156
queries: {
5257
gcTime: 1000 * 30, // 30 seconds
53-
persister: experimental_createPersister({
54-
storage: localStorage,
55-
maxAge: 1000 * 60 * 60 * 12, // 12 hours
56-
}),
58+
persister: persister.persisterFn,
5759
},
5860
},
5961
})
@@ -65,10 +67,10 @@ The `createPersister` plugin technically wraps the `queryFn`, so it doesn't rest
6567

6668
## API
6769

68-
### `experimental_createPersister`
70+
### `experimental_createQueryPersister`
6971

7072
```tsx
71-
experimental_createPersister(options: StoragePersisterOptions)
73+
experimental_createQueryPersister(options: StoragePersisterOptions)
7274
```
7375

7476
#### `Options`

examples/angular/auto-refetching/angular.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,31 @@
100100
}
101101
}
102102
}
103+
},
104+
"schematics": {
105+
"@schematics/angular:component": {
106+
"type": "component"
107+
},
108+
"@schematics/angular:directive": {
109+
"type": "directive"
110+
},
111+
"@schematics/angular:service": {
112+
"type": "service"
113+
},
114+
"@schematics/angular:guard": {
115+
"typeSeparator": "."
116+
},
117+
"@schematics/angular:interceptor": {
118+
"typeSeparator": "."
119+
},
120+
"@schematics/angular:module": {
121+
"typeSeparator": "."
122+
},
123+
"@schematics/angular:pipe": {
124+
"typeSeparator": "."
125+
},
126+
"@schematics/angular:resolver": {
127+
"typeSeparator": "."
128+
}
103129
}
104130
}

examples/angular/auto-refetching/package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@
99
},
1010
"private": true,
1111
"dependencies": {
12-
"@angular/common": "^19.2.4",
13-
"@angular/compiler": "^19.2.4",
14-
"@angular/core": "^19.2.4",
15-
"@angular/platform-browser": "^19.2.4",
16-
"@angular/platform-browser-dynamic": "^19.2.4",
17-
"@tanstack/angular-query-experimental": "^5.75.8",
12+
"@angular/common": "^20.0.0-rc.0",
13+
"@angular/compiler": "^20.0.0-rc.0",
14+
"@angular/core": "^20.0.0-rc.0",
15+
"@angular/platform-browser": "^20.0.0-rc.0",
16+
"@angular/platform-browser-dynamic": "^20.0.0-rc.0",
17+
"@tanstack/angular-query-experimental": "^5.76.2",
1818
"rxjs": "^7.8.2",
1919
"tslib": "^2.8.1",
2020
"zone.js": "0.15.0"
2121
},
2222
"devDependencies": {
23-
"@angular/build": "^19.2.5",
24-
"@angular/cli": "^19.2.5",
25-
"@angular/compiler-cli": "^19.2.4",
23+
"@angular/build": "^20.0.0-rc.2",
24+
"@angular/cli": "^20.0.0-rc.2",
25+
"@angular/compiler-cli": "^20.0.0-rc.0",
2626
"typescript": "5.8.3"
2727
}
2828
}

examples/angular/basic-persister/package.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@
99
},
1010
"private": true,
1111
"dependencies": {
12-
"@angular/common": "^19.2.4",
13-
"@angular/compiler": "^19.2.4",
14-
"@angular/core": "^19.2.4",
15-
"@angular/platform-browser": "^19.2.4",
16-
"@angular/platform-browser-dynamic": "^19.2.4",
17-
"@tanstack/angular-query-experimental": "^5.75.8",
12+
"@angular/common": "^20.0.0-rc.0",
13+
"@angular/compiler": "^20.0.0-rc.0",
14+
"@angular/core": "^20.0.0-rc.0",
15+
"@angular/platform-browser": "^20.0.0-rc.0",
16+
"@angular/platform-browser-dynamic": "^20.0.0-rc.0",
17+
"@tanstack/angular-query-experimental": "^5.76.2",
1818
"@tanstack/angular-query-persist-client": "^5.62.7",
19-
"@tanstack/query-sync-storage-persister": "^5.75.7",
19+
"@tanstack/query-sync-storage-persister": "^5.76.2",
2020
"rxjs": "^7.8.2",
2121
"tslib": "^2.8.1",
22-
"zone.js": "^0.15.0"
22+
"zone.js": "0.15.0"
2323
},
2424
"devDependencies": {
25-
"@angular/build": "^19.2.5",
26-
"@angular/cli": "^19.2.5",
27-
"@angular/compiler-cli": "^19.2.4",
25+
"@angular/build": "^20.0.0-rc.2",
26+
"@angular/cli": "^20.0.0-rc.2",
27+
"@angular/compiler-cli": "^20.0.0-rc.0",
2828
"typescript": "5.8.3"
2929
}
3030
}

examples/angular/basic/angular.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,31 @@
100100
}
101101
}
102102
}
103+
},
104+
"schematics": {
105+
"@schematics/angular:component": {
106+
"type": "component"
107+
},
108+
"@schematics/angular:directive": {
109+
"type": "directive"
110+
},
111+
"@schematics/angular:service": {
112+
"type": "service"
113+
},
114+
"@schematics/angular:guard": {
115+
"typeSeparator": "."
116+
},
117+
"@schematics/angular:interceptor": {
118+
"typeSeparator": "."
119+
},
120+
"@schematics/angular:module": {
121+
"typeSeparator": "."
122+
},
123+
"@schematics/angular:pipe": {
124+
"typeSeparator": "."
125+
},
126+
"@schematics/angular:resolver": {
127+
"typeSeparator": "."
128+
}
103129
}
104130
}

0 commit comments

Comments
 (0)