Skip to content

Commit a0d2c27

Browse files
authored
Merge branch 'main' into test/query
2 parents 76278bb + 5c9bd11 commit a0d2c27

File tree

45 files changed

+508
-187
lines changed

Some content is hidden

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

45 files changed

+508
-187
lines changed

docs/framework/react/plugins/createPersister.md

+68-15
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/vue/plugins/createPersister.md

+12-10
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/basic-persister/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"@angular/platform-browser-dynamic": "^19.2.4",
1717
"@tanstack/angular-query-experimental": "^5.76.0",
1818
"@tanstack/angular-query-persist-client": "^5.62.7",
19-
"@tanstack/query-sync-storage-persister": "^5.76.0",
19+
"@tanstack/query-sync-storage-persister": "^5.76.1",
2020
"rxjs": "^7.8.2",
2121
"tslib": "^2.8.1",
2222
"zone.js": "^0.15.0"

examples/react/algolia/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
},
1010
"dependencies": {
1111
"@algolia/client-search": "5.2.1",
12-
"@tanstack/react-query": "^5.76.0",
13-
"@tanstack/react-query-devtools": "^5.76.0",
12+
"@tanstack/react-query": "^5.76.1",
13+
"@tanstack/react-query-devtools": "^5.76.1",
1414
"react": "^19.0.0",
1515
"react-dom": "^19.0.0"
1616
},

examples/react/auto-refetching/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"next": "^15.3.1",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0"

examples/react/basic-graphql-request/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"preview": "vite preview"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"graphql": "^16.9.0",
1414
"graphql-request": "^7.1.2",
1515
"react": "^19.0.0",

examples/react/basic/package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
"test:eslint": "eslint ./src"
1010
},
1111
"dependencies": {
12-
"@tanstack/query-sync-storage-persister": "^5.76.0",
13-
"@tanstack/react-query": "^5.76.0",
14-
"@tanstack/react-query-devtools": "^5.76.0",
15-
"@tanstack/react-query-persist-client": "^5.76.0",
12+
"@tanstack/query-sync-storage-persister": "^5.76.1",
13+
"@tanstack/react-query": "^5.76.1",
14+
"@tanstack/react-query-devtools": "^5.76.1",
15+
"@tanstack/react-query-persist-client": "^5.76.1",
1616
"react": "^19.0.0",
1717
"react-dom": "^19.0.0"
1818
},

examples/react/chat/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"preview": "vite preview"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"react": "^19.0.0",
1414
"react-dom": "^19.0.0"
1515
},

examples/react/default-query-function/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"preview": "vite preview"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"react": "^19.0.0",
1414
"react-dom": "^19.0.0"
1515
},

examples/react/devtools-panel/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"preview": "vite preview"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"react": "^19.0.0",
1414
"react-dom": "^19.0.0"
1515
},

examples/react/eslint-legacy/package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
"test:eslint": "ESLINT_USE_FLAT_CONFIG=false eslint ./src/**/*.tsx"
1010
},
1111
"dependencies": {
12-
"@tanstack/query-sync-storage-persister": "^5.76.0",
13-
"@tanstack/react-query": "^5.76.0",
14-
"@tanstack/react-query-devtools": "^5.76.0",
15-
"@tanstack/react-query-persist-client": "^5.76.0",
12+
"@tanstack/query-sync-storage-persister": "^5.76.1",
13+
"@tanstack/react-query": "^5.76.1",
14+
"@tanstack/react-query-devtools": "^5.76.1",
15+
"@tanstack/react-query-persist-client": "^5.76.1",
1616
"react": "^19.0.0",
1717
"react-dom": "^19.0.0"
1818
},

examples/react/infinite-query-with-max-pages/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"next": "^15.3.1",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0"

examples/react/load-more-infinite-scroll/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"next": "^15.3.1",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0",

examples/react/nextjs-app-prefetching/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"next": "^15.3.1",
1414
"react": "^19.0.0",
1515
"react-dom": "^19.0.0"

examples/react/nextjs-suspense-streaming/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
13-
"@tanstack/react-query-next-experimental": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
13+
"@tanstack/react-query-next-experimental": "^5.76.1",
1414
"next": "^15.3.1",
1515
"react": "^18.2.0",
1616
"react-dom": "^18.2.0"

examples/react/nextjs/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"next": "^15.3.1",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0"

examples/react/offline/package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
"preview": "vite preview"
99
},
1010
"dependencies": {
11-
"@tanstack/query-sync-storage-persister": "^5.76.0",
11+
"@tanstack/query-sync-storage-persister": "^5.76.1",
1212
"@tanstack/react-location": "^3.7.4",
13-
"@tanstack/react-query": "^5.76.0",
14-
"@tanstack/react-query-devtools": "^5.76.0",
15-
"@tanstack/react-query-persist-client": "^5.76.0",
13+
"@tanstack/react-query": "^5.76.1",
14+
"@tanstack/react-query-devtools": "^5.76.1",
15+
"@tanstack/react-query-persist-client": "^5.76.1",
1616
"msw": "^2.6.6",
1717
"react": "^19.0.0",
1818
"react-dom": "^19.0.0",

examples/react/optimistic-updates-cache/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"next": "^15.3.1",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0"

examples/react/optimistic-updates-ui/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"next": "^15.3.1",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0"

examples/react/pagination/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.76.0",
12-
"@tanstack/react-query-devtools": "^5.76.0",
11+
"@tanstack/react-query": "^5.76.1",
12+
"@tanstack/react-query-devtools": "^5.76.1",
1313
"next": "^15.3.1",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0"

0 commit comments

Comments
 (0)