A persister for synchronous storages, to be used with TanStack/Query
npx @tessl/cli install tessl/npm-tanstack--query-sync-storage-persister@5.86.00
# TanStack Query Sync Storage Persister
1
2
TanStack Query Sync Storage Persister provides a synchronous storage persister for TanStack Query that enables caching and persistence of query data to synchronous storage systems like localStorage or sessionStorage. It implements throttled persistence with configurable serialization, retry logic, and error handling.
3
4
## Package Information
5
6
- **Package Name**: @tanstack/query-sync-storage-persister
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @tanstack/query-sync-storage-persister`
10
11
## Core Imports
12
13
```typescript
14
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { createSyncStoragePersister } = require("@tanstack/query-sync-storage-persister");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";
27
import { persistQueryClient } from "@tanstack/query-persist-client-core";
28
import { QueryClient } from "@tanstack/query-core";
29
30
// Create a query client
31
const queryClient = new QueryClient();
32
33
// Create a persister with localStorage (uses default key 'REACT_QUERY_OFFLINE_CACHE')
34
const persister = createSyncStoragePersister({
35
storage: window.localStorage,
36
throttleTime: 2000, // Throttle saves to 2 seconds
37
});
38
39
// Setup persistence
40
persistQueryClient({
41
queryClient,
42
persister,
43
buster: "v1.0", // Cache buster string
44
});
45
```
46
47
## Architecture
48
49
The package provides a single main export that creates a `Persister` object compatible with TanStack Query's persistence system:
50
51
- **Throttled Persistence**: Automatically throttles storage operations to prevent excessive writes
52
- **Error Handling**: Built-in retry mechanisms with configurable retry strategies
53
- **Serialization**: Configurable serialization/deserialization for storage compatibility
54
- **Graceful Fallbacks**: Returns no-op functions when storage is unavailable
55
56
## Capabilities
57
58
### Sync Storage Persister Creation
59
60
Creates a synchronous storage persister for TanStack Query persistence.
61
62
```typescript { .api }
63
/**
64
* @deprecated use `createAsyncStoragePersister` from `@tanstack/query-async-storage-persister` instead.
65
*/
66
function createSyncStoragePersister(
67
options: CreateSyncStoragePersisterOptions
68
): Persister;
69
70
interface CreateSyncStoragePersisterOptions {
71
/** The storage client used for setting and retrieving items from cache.
72
* For SSR pass in `undefined`. Note that window.localStorage can be
73
* `null` in Android WebViews depending on how they are configured.
74
*/
75
storage: Storage | undefined | null;
76
/** The key to use when storing the cache */
77
key?: string;
78
/** To avoid spamming,
79
* pass a time in ms to throttle saving the cache to disk */
80
throttleTime?: number;
81
/**
82
* How to serialize the data to storage.
83
* @default `JSON.stringify`
84
*/
85
serialize?: (client: PersistedClient) => string;
86
/**
87
* How to deserialize the data from storage.
88
* @default `JSON.parse`
89
*/
90
deserialize?: (cachedString: string) => PersistedClient;
91
/** Retry strategy for handling storage errors */
92
retry?: PersistRetryer;
93
}
94
```
95
96
**Usage Examples:**
97
98
```typescript
99
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";
100
import { removeOldestQuery } from "@tanstack/query-persist-client-core";
101
102
// Basic usage with localStorage
103
const persister = createSyncStoragePersister({
104
storage: window.localStorage,
105
});
106
107
// Custom configuration
108
const customPersister = createSyncStoragePersister({
109
storage: window.sessionStorage,
110
key: "custom-app-cache",
111
throttleTime: 5000, // 5 second throttle
112
serialize: (data) => JSON.stringify(data, null, 2),
113
deserialize: (str) => JSON.parse(str),
114
retry: removeOldestQuery, // Remove oldest queries when storage is full
115
});
116
117
// Server-side rendering safe (no storage)
118
const ssrPersister = createSyncStoragePersister({
119
storage: undefined, // Returns no-op functions
120
});
121
```
122
123
## Types
124
125
```typescript { .api }
126
interface Storage {
127
getItem: (key: string) => string | null;
128
setItem: (key: string, value: string) => void;
129
removeItem: (key: string) => void;
130
}
131
132
interface Persister {
133
persistClient: (persistClient: PersistedClient) => Promisable<void>;
134
restoreClient: () => Promisable<PersistedClient | undefined>;
135
removeClient: () => Promisable<void>;
136
}
137
138
interface PersistedClient {
139
timestamp: number;
140
buster: string;
141
clientState: DehydratedState;
142
}
143
144
type PersistRetryer = (props: {
145
persistedClient: PersistedClient;
146
error: Error;
147
errorCount: number;
148
}) => PersistedClient | undefined;
149
150
type Promisable<T> = T | PromiseLike<T>;
151
152
// Imported from @tanstack/query-core
153
interface DehydratedState {
154
mutations: Array<any>;
155
queries: Array<any>;
156
}
157
```
158
159
## Error Handling
160
161
When storage operations fail, the persister uses the configured retry strategy:
162
163
```typescript
164
import { removeOldestQuery } from "@tanstack/query-persist-client-core";
165
166
const persister = createSyncStoragePersister({
167
storage: window.localStorage,
168
retry: removeOldestQuery, // Removes oldest cached queries when storage is full
169
});
170
```
171
172
If no retry strategy is provided and storage fails, the operation is silently ignored. When storage is not available (SSR, private browsing, etc.), the persister returns no-op functions that safely do nothing.
173
174
## Common Use Cases
175
176
### Browser Persistence
177
178
```typescript
179
// Persist to localStorage with custom settings
180
const persister = createSyncStoragePersister({
181
storage: window.localStorage,
182
key: "my-app-v1.2",
183
throttleTime: 1000,
184
});
185
```
186
187
### Storage Full Handling
188
189
```typescript
190
import { removeOldestQuery } from "@tanstack/query-persist-client-core";
191
192
// Handle storage quota exceeded errors
193
const persister = createSyncStoragePersister({
194
storage: window.localStorage,
195
retry: removeOldestQuery, // Remove old queries when storage is full
196
});
197
```
198
199
### Custom Serialization
200
201
```typescript
202
// Custom serialization for complex data types
203
const persister = createSyncStoragePersister({
204
storage: window.localStorage,
205
serialize: (data) => {
206
// Custom serialization logic
207
return JSON.stringify(data, (key, value) => {
208
if (value instanceof Date) {
209
return { __type: 'Date', value: value.toISOString() };
210
}
211
return value;
212
});
213
},
214
deserialize: (str) => {
215
// Custom deserialization logic
216
return JSON.parse(str, (key, value) => {
217
if (value && value.__type === 'Date') {
218
return new Date(value.value);
219
}
220
return value;
221
});
222
},
223
});
224
```