@qiaopeng/tanstack-query-plus 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PersistQueryClientProvider.d.ts +22 -0
- package/dist/PersistQueryClientProvider.d.ts.map +1 -0
- package/dist/PersistQueryClientProvider.js +47 -0
- package/dist/components/LoadingFallback.d.ts +16 -0
- package/dist/components/LoadingFallback.d.ts.map +1 -0
- package/dist/components/LoadingFallback.js +27 -0
- package/dist/components/QueryErrorBoundary.d.ts +12 -0
- package/dist/components/QueryErrorBoundary.d.ts.map +1 -0
- package/dist/components/QueryErrorBoundary.js +9 -0
- package/dist/components/SuspenseWrapper.d.ts +14 -0
- package/dist/components/SuspenseWrapper.d.ts.map +1 -0
- package/dist/components/SuspenseWrapper.js +9 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +3 -0
- package/dist/components/internal/ErrorBoundary.d.ts +26 -0
- package/dist/components/internal/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/internal/ErrorBoundary.js +28 -0
- package/dist/core/config.d.ts +36 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +213 -0
- package/dist/core/devtools.d.ts +14 -0
- package/dist/core/devtools.d.ts.map +1 -0
- package/dist/core/devtools.js +16 -0
- package/dist/core/env.d.ts +3 -0
- package/dist/core/env.d.ts.map +1 -0
- package/dist/core/env.js +2 -0
- package/dist/core/focusManager.d.ts +33 -0
- package/dist/core/focusManager.d.ts.map +1 -0
- package/dist/core/focusManager.js +122 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +5 -0
- package/dist/core/keys.d.ts +59 -0
- package/dist/core/keys.d.ts.map +1 -0
- package/dist/core/keys.js +107 -0
- package/dist/core/queryOptions.d.ts +30 -0
- package/dist/core/queryOptions.d.ts.map +1 -0
- package/dist/core/queryOptions.js +30 -0
- package/dist/features/index.d.ts +4 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +3 -0
- package/dist/features/offline.d.ts +48 -0
- package/dist/features/offline.d.ts.map +1 -0
- package/dist/features/offline.js +269 -0
- package/dist/features/persistence.d.ts +36 -0
- package/dist/features/persistence.d.ts.map +1 -0
- package/dist/features/persistence.js +175 -0
- package/dist/hooks/batchQueries.d.ts +128 -0
- package/dist/hooks/batchQueries.d.ts.map +1 -0
- package/dist/hooks/batchQueries.js +301 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +7 -0
- package/dist/hooks/useFocusManager.d.ts +41 -0
- package/dist/hooks/useFocusManager.d.ts.map +1 -0
- package/dist/hooks/useFocusManager.js +109 -0
- package/dist/hooks/useInfiniteQuery.d.ts +58 -0
- package/dist/hooks/useInfiniteQuery.d.ts.map +1 -0
- package/dist/hooks/useInfiniteQuery.js +61 -0
- package/dist/hooks/useMutation.d.ts +34 -0
- package/dist/hooks/useMutation.d.ts.map +1 -0
- package/dist/hooks/useMutation.js +176 -0
- package/dist/hooks/usePrefetch.d.ts +54 -0
- package/dist/hooks/usePrefetch.d.ts.map +1 -0
- package/dist/hooks/usePrefetch.js +203 -0
- package/dist/hooks/useQuery.d.ts +5 -0
- package/dist/hooks/useQuery.d.ts.map +1 -0
- package/dist/hooks/useQuery.js +5 -0
- package/dist/hooks/useSuspenseQuery.d.ts +11 -0
- package/dist/hooks/useSuspenseQuery.d.ts.map +1 -0
- package/dist/hooks/useSuspenseQuery.js +19 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/types/base.d.ts +54 -0
- package/dist/types/base.d.ts.map +1 -0
- package/dist/types/base.js +26 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/infinite.d.ts +39 -0
- package/dist/types/infinite.d.ts.map +1 -0
- package/dist/types/infinite.js +1 -0
- package/dist/types/offline.d.ts +97 -0
- package/dist/types/offline.d.ts.map +1 -0
- package/dist/types/offline.js +8 -0
- package/dist/types/optimistic.d.ts +126 -0
- package/dist/types/optimistic.d.ts.map +1 -0
- package/dist/types/optimistic.js +7 -0
- package/dist/types/persistence.d.ts +9 -0
- package/dist/types/persistence.d.ts.map +1 -0
- package/dist/types/persistence.js +1 -0
- package/dist/types/selectors.d.ts +11 -0
- package/dist/types/selectors.d.ts.map +1 -0
- package/dist/types/selectors.js +1 -0
- package/dist/types/suspense.d.ts +67 -0
- package/dist/types/suspense.d.ts.map +1 -0
- package/dist/types/suspense.js +1 -0
- package/dist/utils/fieldMapper.d.ts +9 -0
- package/dist/utils/fieldMapper.d.ts.map +1 -0
- package/dist/utils/fieldMapper.js +27 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/network.d.ts +9 -0
- package/dist/utils/network.d.ts.map +1 -0
- package/dist/utils/network.js +43 -0
- package/dist/utils/optimisticUtils.d.ts +34 -0
- package/dist/utils/optimisticUtils.d.ts.map +1 -0
- package/dist/utils/optimisticUtils.js +76 -0
- package/dist/utils/placeholderData.d.ts +2 -0
- package/dist/utils/placeholderData.d.ts.map +1 -0
- package/dist/utils/placeholderData.js +1 -0
- package/dist/utils/prefetchManager.d.ts +111 -0
- package/dist/utils/prefetchManager.d.ts.map +1 -0
- package/dist/utils/prefetchManager.js +246 -0
- package/dist/utils/queryKey.d.ts +24 -0
- package/dist/utils/queryKey.d.ts.map +1 -0
- package/dist/utils/queryKey.js +77 -0
- package/dist/utils/selectors.d.ts +30 -0
- package/dist/utils/selectors.d.ts.map +1 -0
- package/dist/utils/selectors.js +18 -0
- package/dist/utils/storage.d.ts +7 -0
- package/dist/utils/storage.d.ts.map +1 -0
- package/dist/utils/storage.js +84 -0
- package/package.json +70 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { onlineManager } from "@tanstack/react-query";
|
|
2
|
+
import { ConnectionQuality, StorageType } from "../types/base.js";
|
|
3
|
+
import { isStorageAvailable } from "../utils/storage.js";
|
|
4
|
+
export function setupOnlineManager() {
|
|
5
|
+
if (typeof window === "undefined")
|
|
6
|
+
return;
|
|
7
|
+
onlineManager.setEventListener((setOnline) => {
|
|
8
|
+
const handleOnline = () => setOnline(true);
|
|
9
|
+
const handleOffline = () => setOnline(false);
|
|
10
|
+
window.addEventListener("online", handleOnline);
|
|
11
|
+
window.addEventListener("offline", handleOffline);
|
|
12
|
+
return () => {
|
|
13
|
+
window.removeEventListener("online", handleOnline);
|
|
14
|
+
window.removeEventListener("offline", handleOffline);
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export const isOnline = () => onlineManager.isOnline();
|
|
19
|
+
export function subscribeToOnlineStatus(callback) { return onlineManager.subscribe(callback); }
|
|
20
|
+
export function configureOfflineQueries(_queryClient) { }
|
|
21
|
+
const DEFAULT_QUEUE_CONFIG = { enabled: true, maxSize: 100, persist: true, storageKey: "tanstack-query-offline-queue", autoExecuteInterval: 5000, executeOnReconnect: true, operationTimeout: 30000, concurrency: 3 };
|
|
22
|
+
export function calculateExponentialBackoff(attempt, baseDelay = 1000, maxDelay = 30000) {
|
|
23
|
+
const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
|
|
24
|
+
const jitter = Math.random() * 0.3 * delay;
|
|
25
|
+
return Math.floor(delay + jitter);
|
|
26
|
+
}
|
|
27
|
+
class MutationRegistry {
|
|
28
|
+
constructor() {
|
|
29
|
+
this.registry = new Map();
|
|
30
|
+
}
|
|
31
|
+
register(key, fn) { this.registry.set(key, fn); }
|
|
32
|
+
get(key) { return this.registry.get(key); }
|
|
33
|
+
unregister(key) { this.registry.delete(key); }
|
|
34
|
+
clear() { this.registry.clear(); }
|
|
35
|
+
getKeys() { return Array.from(this.registry.keys()); }
|
|
36
|
+
}
|
|
37
|
+
export const mutationRegistry = new MutationRegistry();
|
|
38
|
+
export class OfflineQueueManager {
|
|
39
|
+
constructor(config = {}) {
|
|
40
|
+
this.queue = [];
|
|
41
|
+
this.isExecuting = false;
|
|
42
|
+
this.executionTimer = null;
|
|
43
|
+
this.unsubscribeOnline = null;
|
|
44
|
+
this.executingOperations = new Set();
|
|
45
|
+
this.config = { ...DEFAULT_QUEUE_CONFIG, ...config };
|
|
46
|
+
if (this.config.persist) {
|
|
47
|
+
this.loadQueue();
|
|
48
|
+
}
|
|
49
|
+
if (this.config.executeOnReconnect) {
|
|
50
|
+
this.setupOnlineListener();
|
|
51
|
+
}
|
|
52
|
+
if (this.config.autoExecuteInterval > 0) {
|
|
53
|
+
this.startAutoExecution();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async add(operation) {
|
|
57
|
+
const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
58
|
+
const newOperation = { ...operation, id, createdAt: new Date(), retryCount: 0 };
|
|
59
|
+
if (this.queue.length >= this.config.maxSize) {
|
|
60
|
+
throw new Error(`Queue is full (max size: ${this.config.maxSize})`);
|
|
61
|
+
}
|
|
62
|
+
const insertIndex = this.queue.findIndex((op) => op.priority < newOperation.priority);
|
|
63
|
+
if (insertIndex === -1) {
|
|
64
|
+
this.queue.push(newOperation);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
this.queue.splice(insertIndex, 0, newOperation);
|
|
68
|
+
}
|
|
69
|
+
if (this.config.persist) {
|
|
70
|
+
await this.persistQueue();
|
|
71
|
+
}
|
|
72
|
+
return id;
|
|
73
|
+
}
|
|
74
|
+
async remove(operationId) {
|
|
75
|
+
const index = this.queue.findIndex((op) => op.id === operationId);
|
|
76
|
+
if (index === -1)
|
|
77
|
+
return false;
|
|
78
|
+
this.queue.splice(index, 1);
|
|
79
|
+
if (this.config.persist) {
|
|
80
|
+
await this.persistQueue();
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
getState() {
|
|
85
|
+
const online = isOnline();
|
|
86
|
+
return { isOffline: !online, networkStatus: { isOnline: online, isOffline: !online, connectionQuality: ConnectionQuality.UNKNOWN }, queuedOperations: this.queue.length, failedQueries: this.queue.filter((op) => op.lastError).length, lastSyncAt: this.queue.length === 0 ? new Date() : undefined, isRecovering: this.isExecuting };
|
|
87
|
+
}
|
|
88
|
+
getOperations() { return [...this.queue]; }
|
|
89
|
+
async clear() { this.queue = []; if (this.config.persist) {
|
|
90
|
+
await this.persistQueue();
|
|
91
|
+
} }
|
|
92
|
+
async execute() {
|
|
93
|
+
if (this.isExecuting) {
|
|
94
|
+
return { success: 0, failed: 0, skipped: this.queue.length };
|
|
95
|
+
}
|
|
96
|
+
if (!isOnline()) {
|
|
97
|
+
return { success: 0, failed: 0, skipped: this.queue.length };
|
|
98
|
+
}
|
|
99
|
+
this.isExecuting = true;
|
|
100
|
+
let successCount = 0;
|
|
101
|
+
let failedCount = 0;
|
|
102
|
+
let skippedCount = 0;
|
|
103
|
+
try {
|
|
104
|
+
const sortedOperations = this.sortOperationsByDependency();
|
|
105
|
+
const batches = this.createBatches(sortedOperations, this.config.concurrency);
|
|
106
|
+
for (const batch of batches) {
|
|
107
|
+
const results = await Promise.allSettled(batch.map((op) => this.executeOperation(op)));
|
|
108
|
+
results.forEach((result) => {
|
|
109
|
+
if (result.status === "fulfilled") {
|
|
110
|
+
if (result.value) {
|
|
111
|
+
successCount++;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
skippedCount++;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
failedCount++;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
this.queue = this.queue.filter((op) => op.lastError !== undefined);
|
|
123
|
+
if (this.config.persist) {
|
|
124
|
+
await this.persistQueue();
|
|
125
|
+
}
|
|
126
|
+
return { success: successCount, failed: failedCount, skipped: skippedCount };
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
this.isExecuting = false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async executeOperation(operation) {
|
|
133
|
+
if (this.executingOperations.has(operation.id)) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
if (operation.dependsOn && operation.dependsOn.length > 0) {
|
|
137
|
+
const dependenciesMet = operation.dependsOn.every((depId) => !this.queue.find((op) => op.id === depId));
|
|
138
|
+
if (!dependenciesMet) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
this.executingOperations.add(operation.id);
|
|
143
|
+
try {
|
|
144
|
+
const mutationKey = Array.isArray(operation.mutationKey) ? operation.mutationKey.join("-") : String(operation.mutationKey);
|
|
145
|
+
const mutationFn = mutationRegistry.get(mutationKey) || operation.mutationFn;
|
|
146
|
+
const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error("Operation timeout")), this.config.operationTimeout); });
|
|
147
|
+
await Promise.race([mutationFn(), timeoutPromise]);
|
|
148
|
+
await this.remove(operation.id);
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
operation.retryCount++;
|
|
153
|
+
operation.lastError = error instanceof Error ? error : new Error(String(error));
|
|
154
|
+
if (operation.retryCount >= 5) { /* noop */ }
|
|
155
|
+
if (this.config.persist) {
|
|
156
|
+
await this.persistQueue();
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
this.executingOperations.delete(operation.id);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
sortOperationsByDependency() {
|
|
165
|
+
const sorted = [];
|
|
166
|
+
const visited = new Set();
|
|
167
|
+
const visiting = new Set();
|
|
168
|
+
const visit = (operation) => {
|
|
169
|
+
if (visited.has(operation.id))
|
|
170
|
+
return;
|
|
171
|
+
if (visiting.has(operation.id)) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
visiting.add(operation.id);
|
|
175
|
+
if (operation.dependsOn) {
|
|
176
|
+
for (const depId of operation.dependsOn) {
|
|
177
|
+
const dep = this.queue.find((op) => op.id === depId);
|
|
178
|
+
if (dep) {
|
|
179
|
+
visit(dep);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
visiting.delete(operation.id);
|
|
184
|
+
visited.add(operation.id);
|
|
185
|
+
sorted.push(operation);
|
|
186
|
+
};
|
|
187
|
+
const prioritySorted = [...this.queue].sort((a, b) => b.priority - a.priority);
|
|
188
|
+
for (const operation of prioritySorted) {
|
|
189
|
+
visit(operation);
|
|
190
|
+
}
|
|
191
|
+
return sorted;
|
|
192
|
+
}
|
|
193
|
+
createBatches(operations, batchSize) {
|
|
194
|
+
const batches = [];
|
|
195
|
+
for (let i = 0; i < operations.length; i += batchSize) {
|
|
196
|
+
batches.push(operations.slice(i, i + batchSize));
|
|
197
|
+
}
|
|
198
|
+
return batches;
|
|
199
|
+
}
|
|
200
|
+
async persistQueue() {
|
|
201
|
+
if (!isStorageAvailable(StorageType.LOCAL)) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
const serialized = JSON.stringify(this.queue.map((op) => ({ ...op, createdAt: op.createdAt.toISOString(), mutationFn: undefined })));
|
|
206
|
+
localStorage.setItem(this.config.storageKey, serialized);
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
if (error instanceof Error && error.name === "QuotaExceededError") {
|
|
210
|
+
this.cleanupOldOperations();
|
|
211
|
+
try {
|
|
212
|
+
const serialized = JSON.stringify(this.queue.map((op) => ({ ...op, createdAt: op.createdAt.toISOString(), mutationFn: undefined })));
|
|
213
|
+
localStorage.setItem(this.config.storageKey, serialized);
|
|
214
|
+
}
|
|
215
|
+
catch { }
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
loadQueue() {
|
|
220
|
+
if (!isStorageAvailable(StorageType.LOCAL)) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
const stored = localStorage.getItem(this.config.storageKey);
|
|
225
|
+
if (!stored)
|
|
226
|
+
return;
|
|
227
|
+
const parsed = JSON.parse(stored);
|
|
228
|
+
if (!Array.isArray(parsed)) {
|
|
229
|
+
this.queue = [];
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
this.queue = parsed.map((op) => ({ ...op, createdAt: new Date(op.createdAt), mutationFn: op.mutationFn || (() => Promise.reject(new Error("Mutation function not registered"))) }));
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
this.queue = [];
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
cleanupOldOperations() {
|
|
239
|
+
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
240
|
+
this.queue = this.queue.filter((op) => op.createdAt > oneDayAgo);
|
|
241
|
+
}
|
|
242
|
+
setupOnlineListener() {
|
|
243
|
+
this.unsubscribeOnline = subscribeToOnlineStatus((online) => { if (online && this.queue.length > 0) {
|
|
244
|
+
this.execute().catch(() => { });
|
|
245
|
+
} });
|
|
246
|
+
}
|
|
247
|
+
startAutoExecution() {
|
|
248
|
+
this.executionTimer = setInterval(() => {
|
|
249
|
+
if (isOnline() && this.queue.length > 0 && !this.isExecuting) {
|
|
250
|
+
this.execute().catch(() => { });
|
|
251
|
+
}
|
|
252
|
+
}, this.config.autoExecuteInterval);
|
|
253
|
+
}
|
|
254
|
+
stopAutoExecution() {
|
|
255
|
+
if (this.executionTimer) {
|
|
256
|
+
clearInterval(this.executionTimer);
|
|
257
|
+
this.executionTimer = null;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
destroy() {
|
|
261
|
+
this.stopAutoExecution();
|
|
262
|
+
if (this.unsubscribeOnline) {
|
|
263
|
+
this.unsubscribeOnline();
|
|
264
|
+
this.unsubscribeOnline = null;
|
|
265
|
+
}
|
|
266
|
+
this.executingOperations.clear();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
export function createOfflineQueueManager(config) { return new OfflineQueueManager(config); }
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Query } from "@tanstack/react-query";
|
|
2
|
+
import type { PersistedClient, Persister } from "@tanstack/react-query-persist-client";
|
|
3
|
+
export interface PersistOptions {
|
|
4
|
+
maxAge?: number;
|
|
5
|
+
onlyPersistSuccess?: boolean;
|
|
6
|
+
dehydrateOptions?: {
|
|
7
|
+
shouldDehydrateQuery?: (query: Query) => boolean;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare function createPersistOptions(config?: Partial<PersistOptions>): {
|
|
11
|
+
maxAge: number;
|
|
12
|
+
dehydrateOptions?: {
|
|
13
|
+
shouldDehydrateQuery?: (query: Query) => boolean;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare function createPersister(storageKey?: string, storage?: Storage): Persister | undefined;
|
|
17
|
+
export declare function clearCache(key?: string): void;
|
|
18
|
+
export declare function clearExpiredCache(key?: string, maxAge?: number): void;
|
|
19
|
+
export declare function migrateToIndexedDB(localStorageKey: string | undefined, indexedDBKey: string | undefined, indexedDBStorage: Storage | {
|
|
20
|
+
setItem: (key: string, value: string) => Promise<void>;
|
|
21
|
+
}): Promise<boolean>;
|
|
22
|
+
export declare function checkStorageSize(key?: string): {
|
|
23
|
+
sizeInBytes: number;
|
|
24
|
+
sizeInMB: number;
|
|
25
|
+
shouldMigrate: boolean;
|
|
26
|
+
message: string;
|
|
27
|
+
};
|
|
28
|
+
export declare function getStorageStats(key?: string): {
|
|
29
|
+
exists: boolean;
|
|
30
|
+
age?: number;
|
|
31
|
+
queriesCount?: number;
|
|
32
|
+
mutationsCount?: number;
|
|
33
|
+
sizeInfo: ReturnType<typeof checkStorageSize>;
|
|
34
|
+
};
|
|
35
|
+
export type { PersistedClient, Persister };
|
|
36
|
+
//# sourceMappingURL=persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/features/persistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAsBvF,MAAM,WAAW,cAAc;IAAG,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE;QAAE,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;KAAE,CAAA;CAAE;AAC1J,wBAAgB,oBAAoB,CAAC,MAAM,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE;QAAE,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;KAAE,CAAA;CAAE,CAiBtK;AACD,wBAAgB,eAAe,CAAC,UAAU,SAAyB,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAa7G;AACD,wBAAgB,UAAU,CAAC,GAAG,SAAyB,GAAG,IAAI,CAA0D;AACxH,wBAAgB,iBAAiB,CAAC,GAAG,SAAyB,EAAE,MAAM,SAAsB,GAAG,IAAI,CAQlG;AACD,wBAAsB,kBAAkB,CAAC,eAAe,oBAAyB,EAAE,YAAY,oBAAyB,EAAE,gBAAgB,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAWlO;AACD,wBAAgB,gBAAgB,CAAC,GAAG,SAAyB,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CASjJ;AACD,wBAAgB,eAAe,CAAC,GAAG,SAAyB,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAA;CAAE,CAS9L;AACD,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
function isSerializable(data) {
|
|
2
|
+
try {
|
|
3
|
+
JSON.stringify(data);
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function handleStorageQuotaError(error, key) {
|
|
11
|
+
if (error instanceof Error && error.name === "QuotaExceededError") {
|
|
12
|
+
try {
|
|
13
|
+
window.localStorage.removeItem(key);
|
|
14
|
+
}
|
|
15
|
+
catch { }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function createSafeStorage(storage, key) {
|
|
19
|
+
return {
|
|
20
|
+
getItem: (storageKey) => { try {
|
|
21
|
+
return storage.getItem(storageKey);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
} },
|
|
26
|
+
setItem: (storageKey, value) => { try {
|
|
27
|
+
storage.setItem(storageKey, value);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
handleStorageQuotaError(error, key);
|
|
31
|
+
} },
|
|
32
|
+
removeItem: (storageKey) => { try {
|
|
33
|
+
storage.removeItem(storageKey);
|
|
34
|
+
}
|
|
35
|
+
catch { } },
|
|
36
|
+
clear: () => { try {
|
|
37
|
+
storage.clear();
|
|
38
|
+
}
|
|
39
|
+
catch { } },
|
|
40
|
+
key: (index) => { try {
|
|
41
|
+
return storage.key(index);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
} },
|
|
46
|
+
get length() {
|
|
47
|
+
try {
|
|
48
|
+
return storage.length;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export function createPersistOptions(config = {}) {
|
|
57
|
+
const { maxAge = 1000 * 60 * 60 * 24, onlyPersistSuccess = true, dehydrateOptions } = config;
|
|
58
|
+
return {
|
|
59
|
+
maxAge,
|
|
60
|
+
dehydrateOptions: {
|
|
61
|
+
...dehydrateOptions,
|
|
62
|
+
shouldDehydrateQuery: dehydrateOptions?.shouldDehydrateQuery ||
|
|
63
|
+
(onlyPersistSuccess
|
|
64
|
+
? (query) => {
|
|
65
|
+
if (query.state.status !== "success")
|
|
66
|
+
return false;
|
|
67
|
+
if (!isSerializable(query.state.data))
|
|
68
|
+
return false;
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
: undefined)
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function createPersister(storageKey = "tanstack-query-cache", storage) {
|
|
76
|
+
if (typeof window === "undefined") {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
const targetStorage = storage || window.localStorage;
|
|
80
|
+
if (!targetStorage) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const safeStorage = createSafeStorage(targetStorage, storageKey);
|
|
85
|
+
const persister = {
|
|
86
|
+
persistClient: async (client) => { try {
|
|
87
|
+
safeStorage.setItem(storageKey, JSON.stringify(client));
|
|
88
|
+
}
|
|
89
|
+
catch { } },
|
|
90
|
+
restoreClient: async () => { try {
|
|
91
|
+
const raw = safeStorage.getItem(storageKey);
|
|
92
|
+
return raw ? JSON.parse(raw) : undefined;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return undefined;
|
|
96
|
+
} },
|
|
97
|
+
removeClient: async () => { try {
|
|
98
|
+
safeStorage.removeItem(storageKey);
|
|
99
|
+
}
|
|
100
|
+
catch { } }
|
|
101
|
+
};
|
|
102
|
+
return persister;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export function clearCache(key = "tanstack-query-cache") { try {
|
|
109
|
+
window.localStorage.removeItem(key);
|
|
110
|
+
}
|
|
111
|
+
catch { } }
|
|
112
|
+
export function clearExpiredCache(key = "tanstack-query-cache", maxAge = 1000 * 60 * 60 * 24) {
|
|
113
|
+
try {
|
|
114
|
+
const stored = window.localStorage.getItem(key);
|
|
115
|
+
if (!stored)
|
|
116
|
+
return;
|
|
117
|
+
const parsed = JSON.parse(stored);
|
|
118
|
+
const now = Date.now();
|
|
119
|
+
if (parsed.timestamp && now - parsed.timestamp > maxAge) {
|
|
120
|
+
window.localStorage.removeItem(key);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch { }
|
|
124
|
+
}
|
|
125
|
+
export async function migrateToIndexedDB(localStorageKey = "tanstack-query-cache", indexedDBKey = "tanstack-query-cache", indexedDBStorage) {
|
|
126
|
+
try {
|
|
127
|
+
const localData = window.localStorage.getItem(localStorageKey);
|
|
128
|
+
if (!localData) {
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
const parsed = JSON.parse(localData);
|
|
132
|
+
if (!parsed.clientState) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
const setItemResult = indexedDBStorage.setItem(indexedDBKey, localData);
|
|
136
|
+
if (setItemResult instanceof Promise) {
|
|
137
|
+
await setItemResult;
|
|
138
|
+
}
|
|
139
|
+
window.localStorage.removeItem(localStorageKey);
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export function checkStorageSize(key = "tanstack-query-cache") {
|
|
147
|
+
try {
|
|
148
|
+
const data = window.localStorage.getItem(key);
|
|
149
|
+
if (!data) {
|
|
150
|
+
return { sizeInBytes: 0, sizeInMB: 0, shouldMigrate: false, message: "No cache data found" };
|
|
151
|
+
}
|
|
152
|
+
const sizeInBytes = new Blob([data]).size;
|
|
153
|
+
const sizeInMB = sizeInBytes / (1024 * 1024);
|
|
154
|
+
const shouldMigrate = sizeInMB > 5;
|
|
155
|
+
return { sizeInBytes, sizeInMB: Math.round(sizeInMB * 100) / 100, shouldMigrate, message: shouldMigrate ? `Cache size (${sizeInMB.toFixed(2)}MB) exceeds recommended limit. Consider migrating to IndexedDB.` : `Cache size (${sizeInMB.toFixed(2)}MB) is within acceptable range.` };
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return { sizeInBytes: 0, sizeInMB: 0, shouldMigrate: false, message: "Failed to check storage size" };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
export function getStorageStats(key = "tanstack-query-cache") {
|
|
162
|
+
try {
|
|
163
|
+
const data = window.localStorage.getItem(key);
|
|
164
|
+
if (!data) {
|
|
165
|
+
return { exists: false, sizeInfo: checkStorageSize(key) };
|
|
166
|
+
}
|
|
167
|
+
const parsed = JSON.parse(data);
|
|
168
|
+
const now = Date.now();
|
|
169
|
+
const age = parsed.timestamp ? now - parsed.timestamp : undefined;
|
|
170
|
+
return { exists: true, age, queriesCount: parsed.clientState?.queries?.length, mutationsCount: parsed.clientState?.mutations?.length, sizeInfo: checkStorageSize(key) };
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return { exists: false, sizeInfo: checkStorageSize(key) };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { QueryClient, UseQueryOptions, UseQueryResult, UseSuspenseQueryOptions, UseSuspenseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import type { BatchErrorAggregate, BatchOperationReport, BatchQueryConfig, BatchQueryOperations, BatchQueryStats } from "../types/optimistic";
|
|
3
|
+
interface InternalBatchQueryOperations extends BatchQueryOperations {
|
|
4
|
+
_queryClient: QueryClient;
|
|
5
|
+
_queries: UseQueryOptions[];
|
|
6
|
+
_results: UseQueryResult[] | UseSuspenseQueryResult[];
|
|
7
|
+
}
|
|
8
|
+
export declare function calculateBatchStats(results: UseQueryResult[] | UseSuspenseQueryResult[]): BatchQueryStats;
|
|
9
|
+
export declare function useEnhancedQueries(queries: UseQueryOptions[], config?: BatchQueryConfig): {
|
|
10
|
+
data: UseQueryResult<unknown, Error>[];
|
|
11
|
+
stats: BatchQueryStats;
|
|
12
|
+
operations: InternalBatchQueryOperations;
|
|
13
|
+
config: BatchQueryConfig<unknown, Error>;
|
|
14
|
+
};
|
|
15
|
+
export declare function useEnhancedSuspenseQueries(queries: UseSuspenseQueryOptions[], config?: BatchQueryConfig): {
|
|
16
|
+
data: UseSuspenseQueryResult<unknown, Error>[];
|
|
17
|
+
stats: BatchQueryStats;
|
|
18
|
+
operations: InternalBatchQueryOperations;
|
|
19
|
+
config: BatchQueryConfig<unknown, Error>;
|
|
20
|
+
};
|
|
21
|
+
export declare function createBatchQueryConfig(config?: Partial<BatchQueryConfig>): BatchQueryConfig;
|
|
22
|
+
export declare const batchQueryUtils: {
|
|
23
|
+
isAllLoading: (results: UseQueryResult[] | UseSuspenseQueryResult[]) => boolean;
|
|
24
|
+
isAllSuccess: (results: UseQueryResult[] | UseSuspenseQueryResult[]) => boolean;
|
|
25
|
+
hasError: (results: UseQueryResult[] | UseSuspenseQueryResult[]) => boolean;
|
|
26
|
+
hasStale: (results: UseQueryResult[] | UseSuspenseQueryResult[]) => boolean;
|
|
27
|
+
getAllErrors: (results: UseQueryResult[] | UseSuspenseQueryResult[]) => Error[];
|
|
28
|
+
getAllData: (results: UseQueryResult[] | UseSuspenseQueryResult[]) => unknown[];
|
|
29
|
+
isAllPending: (results: UseQueryResult[] | UseSuspenseQueryResult[]) => boolean;
|
|
30
|
+
isAnyFetching: (results: UseQueryResult[] | UseSuspenseQueryResult[]) => boolean;
|
|
31
|
+
getSuccessData: <T>(results: UseQueryResult<T>[]) => T[];
|
|
32
|
+
getFirstError: (results: UseQueryResult[] | UseSuspenseQueryResult[]) => Error | null;
|
|
33
|
+
createErrorAggregate: <TError = Error>(results: UseQueryResult[] | UseSuspenseQueryResult[], queries: UseQueryOptions[]) => BatchErrorAggregate<TError>;
|
|
34
|
+
createOperationReport: <TData = unknown, TError = Error>(results: UseQueryResult[] | UseSuspenseQueryResult[], queries: UseQueryOptions[], startTime: number, retryCount?: number) => BatchOperationReport<TData, TError>;
|
|
35
|
+
};
|
|
36
|
+
export declare function useCombinedQueries<TCombinedResult = UseQueryResult[]>(options: {
|
|
37
|
+
queries: UseQueryOptions[];
|
|
38
|
+
combine?: (results: UseQueryResult[]) => TCombinedResult;
|
|
39
|
+
}): TCombinedResult;
|
|
40
|
+
export declare function useDynamicBatchQueries<TItem, TData = unknown>(options: {
|
|
41
|
+
items: TItem[];
|
|
42
|
+
queryKeyPrefix: unknown[];
|
|
43
|
+
queryFn: (item: TItem) => Promise<TData>;
|
|
44
|
+
enabled?: boolean;
|
|
45
|
+
staleTime?: number;
|
|
46
|
+
gcTime?: number;
|
|
47
|
+
config?: BatchQueryConfig;
|
|
48
|
+
}): {
|
|
49
|
+
data: UseQueryResult<unknown, Error>[];
|
|
50
|
+
stats: BatchQueryStats;
|
|
51
|
+
operations: InternalBatchQueryOperations;
|
|
52
|
+
config: BatchQueryConfig<unknown, Error>;
|
|
53
|
+
};
|
|
54
|
+
export declare function useDependentBatchQueries<TPrimaryData>(options: {
|
|
55
|
+
primaryQuery: UseQueryOptions<TPrimaryData>;
|
|
56
|
+
dependentQueries: (data: TPrimaryData) => UseQueryOptions[];
|
|
57
|
+
config?: BatchQueryConfig;
|
|
58
|
+
}): {
|
|
59
|
+
primaryResult: UseQueryResult<import("@tanstack/query-core").NoInfer<TPrimaryData>, Error>;
|
|
60
|
+
results: UseQueryResult<unknown, Error>[];
|
|
61
|
+
stats: BatchQueryStats;
|
|
62
|
+
operations: InternalBatchQueryOperations;
|
|
63
|
+
};
|
|
64
|
+
export declare function useAutoRefreshBatchQueries(options: {
|
|
65
|
+
queries: UseQueryOptions[];
|
|
66
|
+
refreshInterval?: number;
|
|
67
|
+
enabled?: boolean;
|
|
68
|
+
config?: BatchQueryConfig;
|
|
69
|
+
}): {
|
|
70
|
+
data: UseQueryResult<unknown, Error>[];
|
|
71
|
+
stats: BatchQueryStats;
|
|
72
|
+
operations: InternalBatchQueryOperations;
|
|
73
|
+
config: BatchQueryConfig<unknown, Error>;
|
|
74
|
+
};
|
|
75
|
+
export declare function useDashboardQueries<T extends Record<string, UseQueryOptions>>(queriesMap: T): {
|
|
76
|
+
data: { [K in keyof T]: T[K] extends UseQueryOptions<infer TData, Error, infer TData, readonly unknown[]> ? TData : unknown; };
|
|
77
|
+
results: UseQueryResult<unknown, Error>[];
|
|
78
|
+
stats: BatchQueryStats;
|
|
79
|
+
isLoading: boolean;
|
|
80
|
+
isError: boolean;
|
|
81
|
+
isSuccess: boolean;
|
|
82
|
+
};
|
|
83
|
+
export declare function usePaginatedBatchQueries<TData = unknown>(options: {
|
|
84
|
+
pageNumbers: number[];
|
|
85
|
+
queryKeyPrefix: unknown[];
|
|
86
|
+
queryFn: (page: number) => Promise<TData>;
|
|
87
|
+
staleTime?: number;
|
|
88
|
+
config?: BatchQueryConfig;
|
|
89
|
+
}): {
|
|
90
|
+
data: UseQueryResult<unknown, Error>[];
|
|
91
|
+
stats: BatchQueryStats;
|
|
92
|
+
operations: InternalBatchQueryOperations;
|
|
93
|
+
config: BatchQueryConfig<unknown, Error>;
|
|
94
|
+
};
|
|
95
|
+
export declare function useConditionalBatchQueries(queries: (UseQueryOptions & {
|
|
96
|
+
enabled?: boolean;
|
|
97
|
+
})[]): {
|
|
98
|
+
data: UseQueryResult<unknown, Error>[];
|
|
99
|
+
stats: BatchQueryStats;
|
|
100
|
+
operations: InternalBatchQueryOperations;
|
|
101
|
+
config: BatchQueryConfig<unknown, Error>;
|
|
102
|
+
};
|
|
103
|
+
export declare function useRetryBatchQueries(options: {
|
|
104
|
+
queries: UseQueryOptions[];
|
|
105
|
+
retry?: number | ((failureCount: number, error: Error) => boolean);
|
|
106
|
+
retryDelay?: number | ((attemptIndex: number) => number);
|
|
107
|
+
config?: BatchQueryConfig;
|
|
108
|
+
}): {
|
|
109
|
+
data: UseQueryResult<unknown, Error>[];
|
|
110
|
+
stats: BatchQueryStats;
|
|
111
|
+
operations: InternalBatchQueryOperations;
|
|
112
|
+
config: BatchQueryConfig<unknown, Error>;
|
|
113
|
+
};
|
|
114
|
+
export declare function useBatchQueryPerformance(results: UseQueryResult[] | UseSuspenseQueryResult[]): {
|
|
115
|
+
avgFetchTime: number;
|
|
116
|
+
totalQueries: number;
|
|
117
|
+
activeQueries: number;
|
|
118
|
+
cachedQueries: number;
|
|
119
|
+
total: number;
|
|
120
|
+
loading: number;
|
|
121
|
+
success: number;
|
|
122
|
+
error: number;
|
|
123
|
+
stale: number;
|
|
124
|
+
successRate: number;
|
|
125
|
+
errorRate: number;
|
|
126
|
+
};
|
|
127
|
+
export {};
|
|
128
|
+
//# sourceMappingURL=batchQueries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batchQueries.d.ts","sourceRoot":"","sources":["../../src/hooks/batchQueries.ts"],"names":[],"mappings":"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"}
|