@qiaopeng/tanstack-query-plus 0.5.9 → 0.5.10
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/README.md +86 -55
- package/dist/{types/base.d.ts → base-CHnwqfyz.d.cts} +12 -14
- package/dist/base-CHnwqfyz.d.ts +52 -0
- package/dist/chunk-52ZO6Y67.cjs +1121 -0
- package/dist/chunk-52ZO6Y67.cjs.map +1 -0
- package/dist/chunk-5J6OXSLW.cjs +36 -0
- package/dist/chunk-5J6OXSLW.cjs.map +1 -0
- package/dist/chunk-6MAYHLTE.cjs +310 -0
- package/dist/chunk-6MAYHLTE.cjs.map +1 -0
- package/dist/chunk-ADS2QTMP.js +144 -0
- package/dist/chunk-ADS2QTMP.js.map +1 -0
- package/dist/chunk-APXNNHBD.cjs +374 -0
- package/dist/chunk-APXNNHBD.cjs.map +1 -0
- package/dist/chunk-AXMWOGNX.js +134 -0
- package/dist/chunk-AXMWOGNX.js.map +1 -0
- package/dist/chunk-B4KO3K3E.cjs +521 -0
- package/dist/chunk-B4KO3K3E.cjs.map +1 -0
- package/dist/chunk-BK3OTIBD.cjs +15 -0
- package/dist/chunk-BK3OTIBD.cjs.map +1 -0
- package/dist/chunk-BYAOQALW.js +13 -0
- package/dist/chunk-BYAOQALW.js.map +1 -0
- package/dist/chunk-CRTVS7VI.cjs +162 -0
- package/dist/chunk-CRTVS7VI.cjs.map +1 -0
- package/dist/chunk-EXITP7QO.js +288 -0
- package/dist/chunk-EXITP7QO.js.map +1 -0
- package/dist/chunk-GMO3PRZZ.js +565 -0
- package/dist/chunk-GMO3PRZZ.js.map +1 -0
- package/dist/chunk-HRO2DWKZ.js +12 -0
- package/dist/chunk-HRO2DWKZ.js.map +1 -0
- package/dist/chunk-JHDKUQSB.js +1069 -0
- package/dist/chunk-JHDKUQSB.js.map +1 -0
- package/dist/chunk-JN2Y6RSY.js +23 -0
- package/dist/chunk-JN2Y6RSY.js.map +1 -0
- package/dist/chunk-JRJSKRZW.cjs +29 -0
- package/dist/chunk-JRJSKRZW.cjs.map +1 -0
- package/dist/chunk-KC62H4VJ.js +123 -0
- package/dist/chunk-KC62H4VJ.js.map +1 -0
- package/dist/chunk-LHEHSLD5.js +31 -0
- package/dist/chunk-LHEHSLD5.js.map +1 -0
- package/dist/chunk-N4264P7N.cjs +156 -0
- package/dist/chunk-N4264P7N.cjs.map +1 -0
- package/dist/chunk-NF5QYPYC.cjs +133 -0
- package/dist/chunk-NF5QYPYC.cjs.map +1 -0
- package/dist/chunk-OFLCHKKE.cjs +28 -0
- package/dist/chunk-OFLCHKKE.cjs.map +1 -0
- package/dist/chunk-PCNSWVA5.cjs +602 -0
- package/dist/chunk-PCNSWVA5.cjs.map +1 -0
- package/dist/chunk-STOMAA2X.js +85 -0
- package/dist/chunk-STOMAA2X.js.map +1 -0
- package/dist/chunk-UVF5S6LX.cjs +15 -0
- package/dist/chunk-UVF5S6LX.cjs.map +1 -0
- package/dist/chunk-WEIXCDCA.cjs +90 -0
- package/dist/chunk-WEIXCDCA.cjs.map +1 -0
- package/dist/chunk-X3ZTSLBQ.js +355 -0
- package/dist/chunk-X3ZTSLBQ.js.map +1 -0
- package/dist/chunk-YEV73J4J.js +504 -0
- package/dist/chunk-YEV73J4J.js.map +1 -0
- package/dist/chunk-YW5PNTRU.cjs +14 -0
- package/dist/chunk-YW5PNTRU.cjs.map +1 -0
- package/dist/chunk-ZNXSWUIS.js +12 -0
- package/dist/chunk-ZNXSWUIS.js.map +1 -0
- package/dist/chunk-ZUEMBY4W.js +21 -0
- package/dist/chunk-ZUEMBY4W.js.map +1 -0
- package/dist/components/index.cjs +60 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.cts +43 -0
- package/dist/components/index.d.ts +43 -4
- package/dist/components/index.js +3 -4
- package/dist/components/index.js.map +1 -0
- package/dist/core/devtools.cjs +25 -0
- package/dist/core/devtools.cjs.map +1 -0
- package/dist/core/devtools.d.cts +17 -0
- package/dist/core/devtools.d.ts +9 -7
- package/dist/core/devtools.js +4 -16
- package/dist/core/devtools.js.map +1 -0
- package/dist/core/index.cjs +220 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +196 -0
- package/dist/core/index.d.ts +196 -9
- package/dist/core/index.js +7 -8
- package/dist/core/index.js.map +1 -0
- package/dist/features/index.cjs +76 -0
- package/dist/features/index.cjs.map +1 -0
- package/dist/features/index.d.cts +86 -0
- package/dist/features/index.d.ts +86 -4
- package/dist/features/index.js +7 -3
- package/dist/features/index.js.map +1 -0
- package/dist/hooks/index.cjs +209 -0
- package/dist/hooks/index.cjs.map +1 -0
- package/dist/hooks/index.d.cts +377 -0
- package/dist/hooks/index.d.ts +377 -10
- package/dist/hooks/index.js +8 -9
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useInViewPrefetch.cjs +33 -0
- package/dist/hooks/useInViewPrefetch.cjs.map +1 -0
- package/dist/hooks/useInViewPrefetch.d.cts +12 -0
- package/dist/hooks/useInViewPrefetch.d.ts +6 -4
- package/dist/hooks/useInViewPrefetch.js +30 -20
- package/dist/hooks/useInViewPrefetch.js.map +1 -0
- package/dist/index.cjs +811 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +36 -0
- package/dist/index.d.ts +36 -8
- package/dist/index.js +89 -7
- package/dist/index.js.map +1 -0
- package/dist/{types/offline.d.ts → offline-DVPtgoAS.d.ts} +15 -13
- package/dist/offline-xxeA_-6V.d.cts +99 -0
- package/dist/persistence-MRtkmhqq.d.cts +216 -0
- package/dist/persistence-tIrEb0pR.d.ts +216 -0
- package/dist/react-query/index.cjs +52 -0
- package/dist/react-query/index.cjs.map +1 -0
- package/dist/react-query/index.d.cts +1 -0
- package/dist/react-query/index.d.ts +1 -3
- package/dist/react-query/index.js +3 -1
- package/dist/react-query/index.js.map +1 -0
- package/dist/types/index.cjs +43 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +157 -0
- package/dist/types/index.d.ts +116 -12
- package/dist/types/index.js +6 -8
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.cjs +234 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +272 -0
- package/dist/utils/index.d.ts +272 -10
- package/dist/utils/index.js +9 -9
- package/dist/utils/index.js.map +1 -0
- package/package.json +13 -3
- package/dist/PersistQueryClientProvider.d.ts +0 -22
- package/dist/PersistQueryClientProvider.d.ts.map +0 -1
- package/dist/PersistQueryClientProvider.js +0 -57
- package/dist/components/LoadingFallback.d.ts +0 -16
- package/dist/components/LoadingFallback.d.ts.map +0 -1
- package/dist/components/LoadingFallback.js +0 -27
- package/dist/components/QueryErrorBoundary.d.ts +0 -12
- package/dist/components/QueryErrorBoundary.d.ts.map +0 -1
- package/dist/components/QueryErrorBoundary.js +0 -9
- package/dist/components/SuspenseWrapper.d.ts +0 -14
- package/dist/components/SuspenseWrapper.d.ts.map +0 -1
- package/dist/components/SuspenseWrapper.js +0 -9
- package/dist/components/index.d.ts.map +0 -1
- package/dist/components/internal/ErrorBoundary.d.ts +0 -27
- package/dist/components/internal/ErrorBoundary.d.ts.map +0 -1
- package/dist/components/internal/ErrorBoundary.js +0 -37
- package/dist/core/config.d.ts +0 -80
- package/dist/core/config.d.ts.map +0 -1
- package/dist/core/config.js +0 -327
- package/dist/core/devtools.d.ts.map +0 -1
- package/dist/core/env.d.ts +0 -4
- package/dist/core/env.d.ts.map +0 -1
- package/dist/core/env.js +0 -26
- package/dist/core/focusManager.d.ts +0 -33
- package/dist/core/focusManager.d.ts.map +0 -1
- package/dist/core/focusManager.js +0 -122
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/keys.d.ts +0 -59
- package/dist/core/keys.d.ts.map +0 -1
- package/dist/core/keys.js +0 -107
- package/dist/core/queryOptions.d.ts +0 -19
- package/dist/core/queryOptions.d.ts.map +0 -1
- package/dist/core/queryOptions.js +0 -32
- package/dist/features/index.d.ts.map +0 -1
- package/dist/features/offline.d.ts +0 -49
- package/dist/features/offline.d.ts.map +0 -1
- package/dist/features/offline.js +0 -300
- package/dist/features/persistence.d.ts +0 -36
- package/dist/features/persistence.d.ts.map +0 -1
- package/dist/features/persistence.js +0 -187
- package/dist/hooks/batchQueries.d.ts +0 -129
- package/dist/hooks/batchQueries.d.ts.map +0 -1
- package/dist/hooks/batchQueries.js +0 -301
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/useDataGuardMutation.d.ts +0 -39
- package/dist/hooks/useDataGuardMutation.d.ts.map +0 -1
- package/dist/hooks/useDataGuardMutation.js +0 -137
- package/dist/hooks/useDataGuardQuery.d.ts +0 -28
- package/dist/hooks/useDataGuardQuery.d.ts.map +0 -1
- package/dist/hooks/useDataGuardQuery.js +0 -71
- package/dist/hooks/useFocusManager.d.ts +0 -41
- package/dist/hooks/useFocusManager.d.ts.map +0 -1
- package/dist/hooks/useFocusManager.js +0 -109
- package/dist/hooks/useInViewPrefetch.d.ts.map +0 -1
- package/dist/hooks/useInfiniteQuery.d.ts +0 -33
- package/dist/hooks/useInfiniteQuery.d.ts.map +0 -1
- package/dist/hooks/useInfiniteQuery.js +0 -61
- package/dist/hooks/useMutation.d.ts +0 -25
- package/dist/hooks/useMutation.d.ts.map +0 -1
- package/dist/hooks/useMutation.js +0 -180
- package/dist/hooks/usePrefetch.d.ts +0 -54
- package/dist/hooks/usePrefetch.d.ts.map +0 -1
- package/dist/hooks/usePrefetch.js +0 -229
- package/dist/hooks/useQuery.d.ts +0 -21
- package/dist/hooks/useQuery.d.ts.map +0 -1
- package/dist/hooks/useQuery.js +0 -46
- package/dist/hooks/useSuspenseQuery.d.ts +0 -11
- package/dist/hooks/useSuspenseQuery.d.ts.map +0 -1
- package/dist/hooks/useSuspenseQuery.js +0 -19
- package/dist/index.d.ts.map +0 -1
- package/dist/react-query/index.d.ts.map +0 -1
- package/dist/types/base.d.ts.map +0 -1
- package/dist/types/base.js +0 -26
- package/dist/types/dataGuard.d.ts +0 -69
- package/dist/types/dataGuard.d.ts.map +0 -1
- package/dist/types/dataGuard.js +0 -10
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/infinite.d.ts +0 -39
- package/dist/types/infinite.d.ts.map +0 -1
- package/dist/types/infinite.js +0 -1
- package/dist/types/offline.d.ts.map +0 -1
- package/dist/types/offline.js +0 -8
- package/dist/types/optimistic.d.ts +0 -126
- package/dist/types/optimistic.d.ts.map +0 -1
- package/dist/types/optimistic.js +0 -7
- package/dist/types/persistence.d.ts +0 -9
- package/dist/types/persistence.d.ts.map +0 -1
- package/dist/types/persistence.js +0 -1
- package/dist/types/selectors.d.ts +0 -11
- package/dist/types/selectors.d.ts.map +0 -1
- package/dist/types/selectors.js +0 -1
- package/dist/types/suspense.d.ts +0 -67
- package/dist/types/suspense.d.ts.map +0 -1
- package/dist/types/suspense.js +0 -1
- package/dist/utils/dataGuard.d.ts +0 -37
- package/dist/utils/dataGuard.d.ts.map +0 -1
- package/dist/utils/dataGuard.js +0 -251
- package/dist/utils/fieldMapper.d.ts +0 -9
- package/dist/utils/fieldMapper.d.ts.map +0 -1
- package/dist/utils/fieldMapper.js +0 -27
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/network.d.ts +0 -9
- package/dist/utils/network.d.ts.map +0 -1
- package/dist/utils/network.js +0 -43
- package/dist/utils/optimisticUtils.d.ts +0 -45
- package/dist/utils/optimisticUtils.d.ts.map +0 -1
- package/dist/utils/optimisticUtils.js +0 -116
- package/dist/utils/placeholderData.d.ts +0 -3
- package/dist/utils/placeholderData.d.ts.map +0 -1
- package/dist/utils/placeholderData.js +0 -28
- package/dist/utils/prefetchManager.d.ts +0 -111
- package/dist/utils/prefetchManager.d.ts.map +0 -1
- package/dist/utils/prefetchManager.js +0 -246
- package/dist/utils/queryKey.d.ts +0 -26
- package/dist/utils/queryKey.d.ts.map +0 -1
- package/dist/utils/queryKey.js +0 -89
- package/dist/utils/selectors.d.ts +0 -30
- package/dist/utils/selectors.d.ts.map +0 -1
- package/dist/utils/selectors.js +0 -18
- package/dist/utils/storage.d.ts +0 -7
- package/dist/utils/storage.d.ts.map +0 -1
- package/dist/utils/storage.js +0 -84
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import { isStorageAvailable } from './chunk-STOMAA2X.js';
|
|
2
|
+
import { TIME_CONSTANTS } from './chunk-EXITP7QO.js';
|
|
3
|
+
import { onlineManager } from '@tanstack/react-query';
|
|
4
|
+
|
|
5
|
+
function setupOnlineManager() {
|
|
6
|
+
if (typeof window === "undefined") 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
|
+
var isOnline = () => onlineManager.isOnline();
|
|
19
|
+
function subscribeToOnlineStatus(callback) {
|
|
20
|
+
return onlineManager.subscribe(callback);
|
|
21
|
+
}
|
|
22
|
+
function configureOfflineQueries(_queryClient) {
|
|
23
|
+
}
|
|
24
|
+
function sortObjectKeys(value) {
|
|
25
|
+
if (value === null || value === void 0) return value;
|
|
26
|
+
if (typeof value !== "object") return value;
|
|
27
|
+
if (Array.isArray(value)) return value.map(sortObjectKeys);
|
|
28
|
+
const sorted = {};
|
|
29
|
+
Object.keys(value).sort().forEach((key) => {
|
|
30
|
+
sorted[key] = sortObjectKeys(value[key]);
|
|
31
|
+
});
|
|
32
|
+
return sorted;
|
|
33
|
+
}
|
|
34
|
+
function serializeMutationKey(mutationKey) {
|
|
35
|
+
try {
|
|
36
|
+
if (typeof mutationKey === "string") return mutationKey;
|
|
37
|
+
return JSON.stringify(sortObjectKeys(mutationKey));
|
|
38
|
+
} catch {
|
|
39
|
+
return String(mutationKey);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
var DEFAULT_QUEUE_CONFIG = { enabled: true, maxSize: 100, persist: true, storageKey: "tanstack-query-offline-queue", autoExecuteInterval: 5e3, executeOnReconnect: true, operationTimeout: 3e4, concurrency: 3 };
|
|
43
|
+
function calculateExponentialBackoff(attempt, baseDelay = 1e3, maxDelay = 3e4) {
|
|
44
|
+
const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
|
|
45
|
+
const jitter = Math.random() * 0.3 * delay;
|
|
46
|
+
return Math.floor(delay + jitter);
|
|
47
|
+
}
|
|
48
|
+
var MutationRegistry = class {
|
|
49
|
+
constructor() {
|
|
50
|
+
this.registry = /* @__PURE__ */ new Map();
|
|
51
|
+
}
|
|
52
|
+
register(key, fn) {
|
|
53
|
+
this.registry.set(key, fn);
|
|
54
|
+
}
|
|
55
|
+
get(key) {
|
|
56
|
+
return this.registry.get(key);
|
|
57
|
+
}
|
|
58
|
+
unregister(key) {
|
|
59
|
+
this.registry.delete(key);
|
|
60
|
+
}
|
|
61
|
+
clear() {
|
|
62
|
+
this.registry.clear();
|
|
63
|
+
}
|
|
64
|
+
getKeys() {
|
|
65
|
+
return Array.from(this.registry.keys());
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var mutationRegistry = new MutationRegistry();
|
|
69
|
+
var OfflineQueueManager = class {
|
|
70
|
+
constructor(config = {}) {
|
|
71
|
+
this.queue = [];
|
|
72
|
+
this.isExecuting = false;
|
|
73
|
+
this.executionTimer = null;
|
|
74
|
+
this.unsubscribeOnline = null;
|
|
75
|
+
this.executingOperations = /* @__PURE__ */ new Set();
|
|
76
|
+
this.config = { ...DEFAULT_QUEUE_CONFIG, ...config };
|
|
77
|
+
if (!this.config.enabled) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (this.config.persist) {
|
|
81
|
+
this.loadQueue();
|
|
82
|
+
}
|
|
83
|
+
if (this.config.executeOnReconnect) {
|
|
84
|
+
this.setupOnlineListener();
|
|
85
|
+
}
|
|
86
|
+
if (this.config.autoExecuteInterval > 0) {
|
|
87
|
+
this.startAutoExecution();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async add(operation) {
|
|
91
|
+
if (!this.config.enabled) {
|
|
92
|
+
throw new Error("Offline queue is disabled");
|
|
93
|
+
}
|
|
94
|
+
const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
95
|
+
const newOperation = { ...operation, id, createdAt: /* @__PURE__ */ new Date(), retryCount: 0 };
|
|
96
|
+
if (this.queue.length >= this.config.maxSize) {
|
|
97
|
+
throw new Error(`Queue is full (max size: ${this.config.maxSize})`);
|
|
98
|
+
}
|
|
99
|
+
const insertIndex = this.queue.findIndex((op) => op.priority < newOperation.priority);
|
|
100
|
+
if (insertIndex === -1) {
|
|
101
|
+
this.queue.push(newOperation);
|
|
102
|
+
} else {
|
|
103
|
+
this.queue.splice(insertIndex, 0, newOperation);
|
|
104
|
+
}
|
|
105
|
+
if (this.config.persist) {
|
|
106
|
+
await this.persistQueue();
|
|
107
|
+
}
|
|
108
|
+
return id;
|
|
109
|
+
}
|
|
110
|
+
async remove(operationId) {
|
|
111
|
+
const index = this.queue.findIndex((op) => op.id === operationId);
|
|
112
|
+
if (index === -1) return false;
|
|
113
|
+
this.queue.splice(index, 1);
|
|
114
|
+
if (this.config.persist) {
|
|
115
|
+
await this.persistQueue();
|
|
116
|
+
}
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
getState() {
|
|
120
|
+
const online = isOnline();
|
|
121
|
+
return { isOffline: !online, networkStatus: { isOnline: online, isOffline: !online, connectionQuality: "unknown" /* UNKNOWN */ }, queuedOperations: this.queue.length, failedQueries: this.queue.filter((op) => op.lastError).length, lastSyncAt: this.queue.length === 0 ? /* @__PURE__ */ new Date() : void 0, isRecovering: this.isExecuting };
|
|
122
|
+
}
|
|
123
|
+
getOperations() {
|
|
124
|
+
return [...this.queue];
|
|
125
|
+
}
|
|
126
|
+
async clear() {
|
|
127
|
+
this.queue = [];
|
|
128
|
+
if (this.config.persist) {
|
|
129
|
+
await this.persistQueue();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async execute() {
|
|
133
|
+
if (!this.config.enabled) {
|
|
134
|
+
return { success: 0, failed: 0, skipped: this.queue.length };
|
|
135
|
+
}
|
|
136
|
+
if (this.isExecuting) {
|
|
137
|
+
return { success: 0, failed: 0, skipped: this.queue.length };
|
|
138
|
+
}
|
|
139
|
+
if (!isOnline()) {
|
|
140
|
+
return { success: 0, failed: 0, skipped: this.queue.length };
|
|
141
|
+
}
|
|
142
|
+
this.isExecuting = true;
|
|
143
|
+
let successCount = 0;
|
|
144
|
+
let failedCount = 0;
|
|
145
|
+
let skippedCount = 0;
|
|
146
|
+
try {
|
|
147
|
+
const sortedOperations = this.sortOperationsByDependency();
|
|
148
|
+
const batches = this.createBatches(sortedOperations, this.config.concurrency);
|
|
149
|
+
for (const batch of batches) {
|
|
150
|
+
const results = await Promise.allSettled(batch.map((op) => this.executeOperation(op)));
|
|
151
|
+
results.forEach((result) => {
|
|
152
|
+
if (result.status === "fulfilled") {
|
|
153
|
+
if (result.value) {
|
|
154
|
+
successCount++;
|
|
155
|
+
} else {
|
|
156
|
+
skippedCount++;
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
failedCount++;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
this.queue = this.queue.filter((op) => op.lastError !== void 0);
|
|
164
|
+
if (this.config.persist) {
|
|
165
|
+
await this.persistQueue();
|
|
166
|
+
}
|
|
167
|
+
return { success: successCount, failed: failedCount, skipped: skippedCount };
|
|
168
|
+
} finally {
|
|
169
|
+
this.isExecuting = false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async executeOperation(operation) {
|
|
173
|
+
if (this.executingOperations.has(operation.id)) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
if (operation.dependsOn && operation.dependsOn.length > 0) {
|
|
177
|
+
const dependenciesMet = operation.dependsOn.every((depId) => !this.queue.find((op) => op.id === depId));
|
|
178
|
+
if (!dependenciesMet) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
this.executingOperations.add(operation.id);
|
|
183
|
+
try {
|
|
184
|
+
const mutationKey = serializeMutationKey(operation.mutationKey);
|
|
185
|
+
const legacyMutationKey = Array.isArray(operation.mutationKey) ? operation.mutationKey.join("-") : String(operation.mutationKey);
|
|
186
|
+
const mutationFn = mutationRegistry.get(mutationKey) || mutationRegistry.get(legacyMutationKey) || operation.mutationFn;
|
|
187
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
188
|
+
setTimeout(() => reject(new Error("Operation timeout")), this.config.operationTimeout);
|
|
189
|
+
});
|
|
190
|
+
await Promise.race([mutationFn(), timeoutPromise]);
|
|
191
|
+
await this.remove(operation.id);
|
|
192
|
+
return true;
|
|
193
|
+
} catch (error) {
|
|
194
|
+
operation.retryCount++;
|
|
195
|
+
operation.lastError = error instanceof Error ? error : new Error(String(error));
|
|
196
|
+
if (operation.retryCount >= 5) ;
|
|
197
|
+
if (this.config.persist) {
|
|
198
|
+
await this.persistQueue();
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
} finally {
|
|
202
|
+
this.executingOperations.delete(operation.id);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
sortOperationsByDependency() {
|
|
206
|
+
const sorted = [];
|
|
207
|
+
const visited = /* @__PURE__ */ new Set();
|
|
208
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
209
|
+
const visit = (operation) => {
|
|
210
|
+
if (visited.has(operation.id)) return;
|
|
211
|
+
if (visiting.has(operation.id)) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
visiting.add(operation.id);
|
|
215
|
+
if (operation.dependsOn) {
|
|
216
|
+
for (const depId of operation.dependsOn) {
|
|
217
|
+
const dep = this.queue.find((op) => op.id === depId);
|
|
218
|
+
if (dep) {
|
|
219
|
+
visit(dep);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
visiting.delete(operation.id);
|
|
224
|
+
visited.add(operation.id);
|
|
225
|
+
sorted.push(operation);
|
|
226
|
+
};
|
|
227
|
+
const prioritySorted = [...this.queue].sort((a, b) => b.priority - a.priority);
|
|
228
|
+
for (const operation of prioritySorted) {
|
|
229
|
+
visit(operation);
|
|
230
|
+
}
|
|
231
|
+
return sorted;
|
|
232
|
+
}
|
|
233
|
+
createBatches(operations, batchSize) {
|
|
234
|
+
const batches = [];
|
|
235
|
+
for (let i = 0; i < operations.length; i += batchSize) {
|
|
236
|
+
batches.push(operations.slice(i, i + batchSize));
|
|
237
|
+
}
|
|
238
|
+
return batches;
|
|
239
|
+
}
|
|
240
|
+
async persistQueue() {
|
|
241
|
+
if (!isStorageAvailable("localStorage" /* LOCAL */)) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
const serialized = JSON.stringify(this.queue.map((op) => ({ ...op, createdAt: op.createdAt.toISOString(), mutationFn: void 0 })));
|
|
246
|
+
localStorage.setItem(this.config.storageKey, serialized);
|
|
247
|
+
} catch (error) {
|
|
248
|
+
if (error instanceof Error && error.name === "QuotaExceededError") {
|
|
249
|
+
this.cleanupOldOperations();
|
|
250
|
+
try {
|
|
251
|
+
const serialized = JSON.stringify(this.queue.map((op) => ({ ...op, createdAt: op.createdAt.toISOString(), mutationFn: void 0 })));
|
|
252
|
+
localStorage.setItem(this.config.storageKey, serialized);
|
|
253
|
+
} catch {
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
loadQueue() {
|
|
259
|
+
if (!isStorageAvailable("localStorage" /* LOCAL */)) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
try {
|
|
263
|
+
const stored = localStorage.getItem(this.config.storageKey);
|
|
264
|
+
if (!stored) return;
|
|
265
|
+
const parsed = JSON.parse(stored);
|
|
266
|
+
if (!Array.isArray(parsed)) {
|
|
267
|
+
this.queue = [];
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
this.queue = parsed.map((op) => ({ ...op, createdAt: new Date(op.createdAt), mutationFn: op.mutationFn || (() => Promise.reject(new Error("Mutation function not registered"))) }));
|
|
271
|
+
} catch {
|
|
272
|
+
this.queue = [];
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
cleanupOldOperations() {
|
|
276
|
+
const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1e3);
|
|
277
|
+
this.queue = this.queue.filter((op) => op.createdAt > oneDayAgo);
|
|
278
|
+
}
|
|
279
|
+
setupOnlineListener() {
|
|
280
|
+
this.unsubscribeOnline = subscribeToOnlineStatus((online) => {
|
|
281
|
+
if (online && this.queue.length > 0) {
|
|
282
|
+
this.execute().catch(() => {
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
startAutoExecution() {
|
|
288
|
+
this.executionTimer = setInterval(() => {
|
|
289
|
+
if (isOnline() && this.queue.length > 0 && !this.isExecuting) {
|
|
290
|
+
this.execute().catch(() => {
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}, this.config.autoExecuteInterval);
|
|
294
|
+
}
|
|
295
|
+
stopAutoExecution() {
|
|
296
|
+
if (this.executionTimer) {
|
|
297
|
+
clearInterval(this.executionTimer);
|
|
298
|
+
this.executionTimer = null;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
destroy() {
|
|
302
|
+
this.stopAutoExecution();
|
|
303
|
+
if (this.unsubscribeOnline) {
|
|
304
|
+
this.unsubscribeOnline();
|
|
305
|
+
this.unsubscribeOnline = null;
|
|
306
|
+
}
|
|
307
|
+
this.executingOperations.clear();
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
function createOfflineQueueManager(config) {
|
|
311
|
+
return new OfflineQueueManager(config);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// src/features/persistence.ts
|
|
315
|
+
function isSerializable(data) {
|
|
316
|
+
try {
|
|
317
|
+
JSON.stringify(data);
|
|
318
|
+
return true;
|
|
319
|
+
} catch {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function handleStorageQuotaError(error, key) {
|
|
324
|
+
if (error instanceof Error && error.name === "QuotaExceededError") {
|
|
325
|
+
try {
|
|
326
|
+
window.localStorage.removeItem(key);
|
|
327
|
+
} catch {
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function createSafeStorage(storage, key) {
|
|
332
|
+
return {
|
|
333
|
+
getItem: (storageKey) => {
|
|
334
|
+
try {
|
|
335
|
+
return storage.getItem(storageKey);
|
|
336
|
+
} catch {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
setItem: (storageKey, value) => {
|
|
341
|
+
try {
|
|
342
|
+
storage.setItem(storageKey, value);
|
|
343
|
+
} catch (error) {
|
|
344
|
+
handleStorageQuotaError(error, key);
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
removeItem: (storageKey) => {
|
|
348
|
+
try {
|
|
349
|
+
storage.removeItem(storageKey);
|
|
350
|
+
} catch {
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
clear: () => {
|
|
354
|
+
try {
|
|
355
|
+
storage.clear();
|
|
356
|
+
} catch {
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
key: (index) => {
|
|
360
|
+
try {
|
|
361
|
+
return storage.key(index);
|
|
362
|
+
} catch {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
get length() {
|
|
367
|
+
try {
|
|
368
|
+
return storage.length;
|
|
369
|
+
} catch {
|
|
370
|
+
return 0;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function createPersistOptions(config = {}) {
|
|
376
|
+
const { maxAge = TIME_CONSTANTS.ONE_DAY, onlyPersistSuccess = true, dehydrateOptions } = config;
|
|
377
|
+
return {
|
|
378
|
+
maxAge,
|
|
379
|
+
dehydrateOptions: {
|
|
380
|
+
...dehydrateOptions,
|
|
381
|
+
shouldDehydrateQuery: dehydrateOptions?.shouldDehydrateQuery || (onlyPersistSuccess ? (query) => {
|
|
382
|
+
if (query.state.status !== "success") return false;
|
|
383
|
+
if (!isSerializable(query.state.data)) return false;
|
|
384
|
+
return true;
|
|
385
|
+
} : void 0)
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
function createPersister(storageKey = "tanstack-query-cache", storage, onError) {
|
|
390
|
+
if (typeof window === "undefined") {
|
|
391
|
+
return void 0;
|
|
392
|
+
}
|
|
393
|
+
const targetStorage = storage || window.localStorage;
|
|
394
|
+
if (!targetStorage) {
|
|
395
|
+
return void 0;
|
|
396
|
+
}
|
|
397
|
+
try {
|
|
398
|
+
const safeStorage = createSafeStorage(targetStorage, storageKey);
|
|
399
|
+
const persister = {
|
|
400
|
+
persistClient: async (client) => {
|
|
401
|
+
try {
|
|
402
|
+
safeStorage.setItem(storageKey, JSON.stringify(client));
|
|
403
|
+
} catch (e) {
|
|
404
|
+
if (onError && e instanceof Error) {
|
|
405
|
+
onError(e);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
restoreClient: async () => {
|
|
410
|
+
try {
|
|
411
|
+
const raw = safeStorage.getItem(storageKey);
|
|
412
|
+
return raw ? JSON.parse(raw) : void 0;
|
|
413
|
+
} catch (e) {
|
|
414
|
+
if (onError && e instanceof Error) {
|
|
415
|
+
onError(e);
|
|
416
|
+
}
|
|
417
|
+
return void 0;
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
removeClient: async () => {
|
|
421
|
+
try {
|
|
422
|
+
safeStorage.removeItem(storageKey);
|
|
423
|
+
} catch (e) {
|
|
424
|
+
if (onError && e instanceof Error) {
|
|
425
|
+
onError(e);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
return persister;
|
|
431
|
+
} catch {
|
|
432
|
+
return void 0;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
function clearCache(key = "tanstack-query-cache") {
|
|
436
|
+
try {
|
|
437
|
+
window.localStorage.removeItem(key);
|
|
438
|
+
} catch {
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function clearExpiredCache(key = "tanstack-query-cache", maxAge = TIME_CONSTANTS.ONE_DAY) {
|
|
442
|
+
try {
|
|
443
|
+
const stored = window.localStorage.getItem(key);
|
|
444
|
+
if (!stored) return;
|
|
445
|
+
const parsed = JSON.parse(stored);
|
|
446
|
+
const now = Date.now();
|
|
447
|
+
if (parsed.timestamp && now - parsed.timestamp > maxAge) {
|
|
448
|
+
window.localStorage.removeItem(key);
|
|
449
|
+
}
|
|
450
|
+
} catch {
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
async function migrateToIndexedDB(localStorageKey = "tanstack-query-cache", indexedDBKey = "tanstack-query-cache", indexedDBStorage) {
|
|
454
|
+
try {
|
|
455
|
+
const localData = window.localStorage.getItem(localStorageKey);
|
|
456
|
+
if (!localData) {
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
const parsed = JSON.parse(localData);
|
|
460
|
+
if (!parsed.clientState) {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
const setItemResult = indexedDBStorage.setItem(indexedDBKey, localData);
|
|
464
|
+
if (setItemResult instanceof Promise) {
|
|
465
|
+
await setItemResult;
|
|
466
|
+
}
|
|
467
|
+
window.localStorage.removeItem(localStorageKey);
|
|
468
|
+
return true;
|
|
469
|
+
} catch {
|
|
470
|
+
return false;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
function checkStorageSize(key = "tanstack-query-cache") {
|
|
474
|
+
try {
|
|
475
|
+
const data = window.localStorage.getItem(key);
|
|
476
|
+
if (!data) {
|
|
477
|
+
return { sizeInBytes: 0, sizeInMB: 0, shouldMigrate: false, message: "No cache data found" };
|
|
478
|
+
}
|
|
479
|
+
const sizeInBytes = new Blob([data]).size;
|
|
480
|
+
const sizeInMB = sizeInBytes / (1024 * 1024);
|
|
481
|
+
const shouldMigrate = sizeInMB > 5;
|
|
482
|
+
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.` };
|
|
483
|
+
} catch {
|
|
484
|
+
return { sizeInBytes: 0, sizeInMB: 0, shouldMigrate: false, message: "Failed to check storage size" };
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function getStorageStats(key = "tanstack-query-cache") {
|
|
488
|
+
try {
|
|
489
|
+
const data = window.localStorage.getItem(key);
|
|
490
|
+
if (!data) {
|
|
491
|
+
return { exists: false, sizeInfo: checkStorageSize(key) };
|
|
492
|
+
}
|
|
493
|
+
const parsed = JSON.parse(data);
|
|
494
|
+
const now = Date.now();
|
|
495
|
+
const age = parsed.timestamp ? now - parsed.timestamp : void 0;
|
|
496
|
+
return { exists: true, age, queriesCount: parsed.clientState?.queries?.length, mutationsCount: parsed.clientState?.mutations?.length, sizeInfo: checkStorageSize(key) };
|
|
497
|
+
} catch {
|
|
498
|
+
return { exists: false, sizeInfo: checkStorageSize(key) };
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export { OfflineQueueManager, calculateExponentialBackoff, checkStorageSize, clearCache, clearExpiredCache, configureOfflineQueries, createOfflineQueueManager, createPersistOptions, createPersister, getStorageStats, isOnline, migrateToIndexedDB, mutationRegistry, serializeMutationKey, setupOnlineManager, subscribeToOnlineStatus };
|
|
503
|
+
//# sourceMappingURL=chunk-YEV73J4J.js.map
|
|
504
|
+
//# sourceMappingURL=chunk-YEV73J4J.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/offline.ts","../src/features/persistence.ts"],"names":[],"mappings":";;;;AAMO,SAAS,kBAAA,GAAqB;AACnC,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,EAAA,aAAA,CAAc,gBAAA,CAAiB,CAAC,SAAA,KAAc;AAC5C,IAAA,MAAM,YAAA,GAAe,MAAM,SAAA,CAAU,IAAI,CAAA;AACzC,IAAA,MAAM,aAAA,GAAgB,MAAM,SAAA,CAAU,KAAK,CAAA;AAC3C,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,YAAY,CAAA;AAC9C,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,aAAa,CAAA;AAChD,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,UAAU,YAAY,CAAA;AACjD,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,aAAa,CAAA;AAAA,IACrD,CAAA;AAAA,EACF,CAAC,CAAA;AACH;AACO,IAAM,QAAA,GAAW,MAAM,aAAA,CAAc,QAAA;AACrC,SAAS,wBAAwB,QAAA,EAAqC;AAAE,EAAA,OAAO,aAAA,CAAc,UAAU,QAAQ,CAAA;AAAG;AAClH,SAAS,wBAAwB,YAAA,EAA2B;AAAC;AAEpE,SAAS,eAAe,KAAA,EAAiB;AACvC,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW,OAAO,KAAA;AAClD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAI,cAAc,CAAA;AACzD,EAAA,MAAM,SAA8B,EAAC;AACrC,EAAA,MAAA,CAAO,KAAK,KAAK,CAAA,CAAE,MAAK,CAAE,OAAA,CAAQ,CAAC,GAAA,KAAQ;AAAE,IAAA,MAAA,CAAO,GAAG,CAAA,GAAI,cAAA,CAAe,KAAA,CAAM,GAAG,CAAC,CAAA;AAAA,EAAG,CAAC,CAAA;AACxF,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,qBAAqB,WAAA,EAA8B;AACjE,EAAA,IAAI;AACF,IAAA,IAAI,OAAO,WAAA,KAAgB,QAAA,EAAU,OAAO,WAAA;AAC5C,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,cAAA,CAAe,WAAW,CAAC,CAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,OAAO,WAAW,CAAA;AAAA,EAC3B;AACF;AAEA,IAAM,uBAA2C,EAAE,OAAA,EAAS,IAAA,EAAM,OAAA,EAAS,KAAK,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,8BAAA,EAAgC,qBAAqB,GAAA,EAAM,kBAAA,EAAoB,MAAM,gBAAA,EAAkB,GAAA,EAAO,aAAa,CAAA,EAAE;AACjO,SAAS,2BAAA,CAA4B,OAAA,EAAiB,SAAA,GAAY,GAAA,EAAM,WAAW,GAAA,EAAe;AACvG,EAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,SAAA,GAAY,CAAA,IAAK,SAAS,QAAQ,CAAA;AACzD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,EAAO,GAAI,GAAA,GAAM,KAAA;AACrC,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,MAAM,CAAA;AAClC;AACA,IAAM,mBAAN,MAA2D;AAAA,EAA3D,WAAA,GAAA;AACE,IAAA,IAAA,CAAQ,QAAA,uBAAe,GAAA,EAAoC;AAAA,EAAA;AAAA,EAC3D,QAAA,CAAS,KAAa,EAAA,EAAkC;AAAE,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAA,EAAK,EAAE,CAAA;AAAA,EAAG;AAAA,EACtF,IAAI,GAAA,EAAmD;AAAE,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAAA,EAAG;AAAA,EACxF,WAAW,GAAA,EAAmB;AAAE,IAAA,IAAA,CAAK,QAAA,CAAS,OAAO,GAAG,CAAA;AAAA,EAAG;AAAA,EAC3D,KAAA,GAAc;AAAE,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AAAA,EAAG;AAAA,EACvC,OAAA,GAAoB;AAAE,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA;AAAA,EAAG;AACjE,CAAA;AACO,IAAM,gBAAA,GAAmB,IAAI,gBAAA;AAE7B,IAAM,sBAAN,MAA0B;AAAA,EAO/B,WAAA,CAAY,MAAA,GAAsC,EAAC,EAAG;AANtD,IAAA,IAAA,CAAQ,QAAoC,EAAC;AAE7C,IAAA,IAAA,CAAQ,WAAA,GAAc,KAAA;AACtB,IAAA,IAAA,CAAQ,cAAA,GAAwC,IAAA;AAChD,IAAA,IAAA,CAAQ,iBAAA,GAAyC,IAAA;AACjD,IAAA,IAAA,CAAQ,mBAAA,uBAA0B,GAAA,EAAY;AAE5C,IAAA,IAAA,CAAK,MAAA,GAAS,EAAE,GAAG,oBAAA,EAAsB,GAAG,MAAA,EAAO;AACnD,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS;AAAE,MAAA;AAAA,IAAQ;AACpC,IAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AAAE,MAAA,IAAA,CAAK,SAAA,EAAU;AAAA,IAAG;AAC7C,IAAA,IAAI,IAAA,CAAK,OAAO,kBAAA,EAAoB;AAAE,MAAA,IAAA,CAAK,mBAAA,EAAoB;AAAA,IAAG;AAClE,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,mBAAA,GAAsB,CAAA,EAAG;AAAE,MAAA,IAAA,CAAK,kBAAA,EAAmB;AAAA,IAAG;AAAA,EACxE;AAAA,EACA,MAAM,IAAI,SAAA,EAA+F;AACvG,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS;AAAE,MAAA,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAAA,IAAG;AAC1E,IAAA,MAAM,EAAA,GAAK,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,MAAA,CAAO,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AACnE,IAAA,MAAM,YAAA,GAAyC,EAAE,GAAG,SAAA,EAAW,EAAA,EAAI,2BAAW,IAAI,IAAA,EAAK,EAAG,UAAA,EAAY,CAAA,EAAE;AACxG,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,IAAU,IAAA,CAAK,OAAO,OAAA,EAAS;AAAE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,IAAG;AACrH,IAAA,MAAM,WAAA,GAAc,KAAK,KAAA,CAAM,SAAA,CAAU,CAAC,EAAA,KAAO,EAAA,CAAG,QAAA,GAAW,YAAA,CAAa,QAAQ,CAAA;AACpF,IAAA,IAAI,gBAAgB,EAAA,EAAI;AAAE,MAAA,IAAA,CAAK,KAAA,CAAM,KAAK,YAAY,CAAA;AAAA,IAAG,CAAA,MAAO;AAAE,MAAA,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,WAAA,EAAa,CAAA,EAAG,YAAY,CAAA;AAAA,IAAG;AACnH,IAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AAAE,MAAA,MAAM,KAAK,YAAA,EAAa;AAAA,IAAG;AACtD,IAAA,OAAO,EAAA;AAAA,EACT;AAAA,EACA,MAAM,OAAO,WAAA,EAAuC;AAClD,IAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,CAAM,SAAA,CAAU,CAAC,EAAA,KAAO,EAAA,CAAG,OAAO,WAAW,CAAA;AAChE,IAAA,IAAI,KAAA,KAAU,IAAI,OAAO,KAAA;AACzB,IAAA,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,KAAA,EAAO,CAAC,CAAA;AAC1B,IAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AAAE,MAAA,MAAM,KAAK,YAAA,EAAa;AAAA,IAAG;AACtD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EACA,QAAA,GAAyB;AACvB,IAAA,MAAM,SAAS,QAAA,EAAS;AACxB,IAAA,OAAO,EAAE,SAAA,EAAW,CAAC,MAAA,EAAQ,aAAA,EAAe,EAAE,QAAA,EAAU,MAAA,EAAQ,SAAA,EAAW,CAAC,QAAQ,iBAAA,EAAA,SAAA,gBAA6C,EAAG,kBAAkB,IAAA,CAAK,KAAA,CAAM,QAAQ,aAAA,EAAe,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,CAAC,EAAA,KAAO,EAAA,CAAG,SAAS,CAAA,CAAE,QAAQ,UAAA,EAAY,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,oBAAI,IAAI,IAAA,KAAS,MAAA,EAAW,YAAA,EAAc,KAAK,WAAA,EAAY;AAAA,EACvU;AAAA,EACA,aAAA,GAA4C;AAAE,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,KAAK,CAAA;AAAA,EAAG;AAAA,EACtE,MAAM,KAAA,GAAuB;AAAE,IAAA,IAAA,CAAK,QAAQ,EAAC;AAAG,IAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AAAE,MAAA,MAAM,KAAK,YAAA,EAAa;AAAA,IAAG;AAAA,EAAE;AAAA,EACxG,MAAM,OAAA,GAAyE;AAC7E,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS;AAAE,MAAA,OAAO,EAAE,SAAS,CAAA,EAAG,MAAA,EAAQ,GAAG,OAAA,EAAS,IAAA,CAAK,MAAM,MAAA,EAAO;AAAA,IAAG;AAC1F,IAAA,IAAI,KAAK,WAAA,EAAa;AAAE,MAAA,OAAO,EAAE,SAAS,CAAA,EAAG,MAAA,EAAQ,GAAG,OAAA,EAAS,IAAA,CAAK,MAAM,MAAA,EAAO;AAAA,IAAG;AACtF,IAAA,IAAI,CAAC,UAAS,EAAG;AAAE,MAAA,OAAO,EAAE,SAAS,CAAA,EAAG,MAAA,EAAQ,GAAG,OAAA,EAAS,IAAA,CAAK,MAAM,MAAA,EAAO;AAAA,IAAG;AACjF,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,IAAA,IAAI,YAAA,GAAe,CAAA;AAAG,IAAA,IAAI,WAAA,GAAc,CAAA;AAAG,IAAA,IAAI,YAAA,GAAe,CAAA;AAC9D,IAAA,IAAI;AACF,MAAA,MAAM,gBAAA,GAAmB,KAAK,0BAAA,EAA2B;AACzD,MAAA,MAAM,UAAU,IAAA,CAAK,aAAA,CAAc,gBAAA,EAAkB,IAAA,CAAK,OAAO,WAAW,CAAA;AAC5E,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,QAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,UAAA,CAAW,KAAA,CAAM,GAAA,CAAI,CAAC,EAAA,KAAO,IAAA,CAAK,gBAAA,CAAiB,EAAE,CAAC,CAAC,CAAA;AACrF,QAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,MAAA,KAAW;AAC1B,UAAA,IAAI,MAAA,CAAO,WAAW,WAAA,EAAa;AAAE,YAAA,IAAI,OAAO,KAAA,EAAO;AAAE,cAAA,YAAA,EAAA;AAAA,YAAgB,CAAA,MAAO;AAAE,cAAA,YAAA,EAAA;AAAA,YAAgB;AAAA,UAAE,CAAA,MAAO;AAAE,YAAA,WAAA,EAAA;AAAA,UAAe;AAAA,QAC9H,CAAC,CAAA;AAAA,MACH;AACA,MAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,KAAA,CAAM,MAAA,CAAO,CAAC,EAAA,KAAO,EAAA,CAAG,cAAc,KAAA,CAAS,CAAA;AACjE,MAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AAAE,QAAA,MAAM,KAAK,YAAA,EAAa;AAAA,MAAG;AACtD,MAAA,OAAO,EAAE,OAAA,EAAS,YAAA,EAAc,MAAA,EAAQ,WAAA,EAAa,SAAS,YAAA,EAAa;AAAA,IAC7E,CAAA,SAAE;AAAU,MAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AAAA,IAAO;AAAA,EACxC;AAAA,EACA,MAAc,iBAAiB,SAAA,EAAuD;AACpF,IAAA,IAAI,IAAA,CAAK,mBAAA,CAAoB,GAAA,CAAI,SAAA,CAAU,EAAE,CAAA,EAAG;AAAE,MAAA,OAAO,KAAA;AAAA,IAAO;AAChE,IAAA,IAAI,SAAA,CAAU,SAAA,IAAa,SAAA,CAAU,SAAA,CAAU,SAAS,CAAA,EAAG;AACzD,MAAA,MAAM,eAAA,GAAkB,SAAA,CAAU,SAAA,CAAU,KAAA,CAAM,CAAC,KAAA,KAAU,CAAC,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,EAAA,KAAO,EAAA,CAAG,EAAA,KAAO,KAAK,CAAC,CAAA;AACtG,MAAA,IAAI,CAAC,eAAA,EAAiB;AAAE,QAAA,OAAO,KAAA;AAAA,MAAO;AAAA,IACxC;AACA,IAAA,IAAA,CAAK,mBAAA,CAAoB,GAAA,CAAI,SAAA,CAAU,EAAE,CAAA;AACzC,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,oBAAA,CAAqB,SAAA,CAAU,WAAW,CAAA;AAC9D,MAAA,MAAM,iBAAA,GAAoB,KAAA,CAAM,OAAA,CAAQ,SAAA,CAAU,WAAW,CAAA,GAAI,SAAA,CAAU,WAAA,CAAY,IAAA,CAAK,GAAG,CAAA,GAAI,MAAA,CAAO,UAAU,WAAW,CAAA;AAC/H,MAAA,MAAM,UAAA,GAAa,iBAAiB,GAAA,CAAI,WAAW,KAAK,gBAAA,CAAiB,GAAA,CAAI,iBAAiB,CAAA,IAAK,SAAA,CAAU,UAAA;AAC7G,MAAA,MAAM,cAAA,GAAiB,IAAI,OAAA,CAAe,CAAC,GAAG,MAAA,KAAW;AAAE,QAAA,UAAA,CAAW,MAAM,OAAO,IAAI,KAAA,CAAM,mBAAmB,CAAC,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,gBAAgB,CAAA;AAAA,MAAG,CAAC,CAAA;AACpJ,MAAA,MAAM,QAAQ,IAAA,CAAK,CAAC,UAAA,EAAW,EAAG,cAAc,CAAC,CAAA;AACjD,MAAA,MAAM,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,EAAE,CAAA;AAC9B,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,SAAA,CAAU,UAAA,EAAA;AACV,MAAA,SAAA,CAAU,SAAA,GAAY,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAC9E,MAAA,IAAI,SAAA,CAAU,cAAc,CAAA,EAAG;AAC/B,MAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AAAE,QAAA,MAAM,KAAK,YAAA,EAAa;AAAA,MAAG;AACtD,MAAA,OAAO,KAAA;AAAA,IACT,CAAA,SAAE;AAAU,MAAA,IAAA,CAAK,mBAAA,CAAoB,MAAA,CAAO,SAAA,CAAU,EAAE,CAAA;AAAA,IAAG;AAAA,EAC7D;AAAA,EACQ,0BAAA,GAAyD;AAC/D,IAAA,MAAM,SAAqC,EAAC;AAC5C,IAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,IAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,IAAA,MAAM,KAAA,GAAQ,CAAC,SAAA,KAAwC;AACrD,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,SAAA,CAAU,EAAE,CAAA,EAAG;AAC/B,MAAA,IAAI,QAAA,CAAS,GAAA,CAAI,SAAA,CAAU,EAAE,CAAA,EAAG;AAAE,QAAA;AAAA,MAAQ;AAC1C,MAAA,QAAA,CAAS,GAAA,CAAI,UAAU,EAAE,CAAA;AACzB,MAAA,IAAI,UAAU,SAAA,EAAW;AACvB,QAAA,KAAA,MAAW,KAAA,IAAS,UAAU,SAAA,EAAW;AACvC,UAAA,MAAM,GAAA,GAAM,KAAK,KAAA,CAAM,IAAA,CAAK,CAAC,EAAA,KAAO,EAAA,CAAG,OAAO,KAAK,CAAA;AACnD,UAAA,IAAI,GAAA,EAAK;AAAE,YAAA,KAAA,CAAM,GAAG,CAAA;AAAA,UAAG;AAAA,QACzB;AAAA,MACF;AACA,MAAA,QAAA,CAAS,MAAA,CAAO,UAAU,EAAE,CAAA;AAC5B,MAAA,OAAA,CAAQ,GAAA,CAAI,UAAU,EAAE,CAAA;AACxB,MAAA,MAAA,CAAO,KAAK,SAAS,CAAA;AAAA,IACvB,CAAA;AACA,IAAA,MAAM,cAAA,GAAiB,CAAC,GAAG,IAAA,CAAK,KAAK,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,QAAA,GAAW,EAAE,QAAQ,CAAA;AAC7E,IAAA,KAAA,MAAW,aAAa,cAAA,EAAgB;AAAE,MAAA,KAAA,CAAM,SAAS,CAAA;AAAA,IAAG;AAC5D,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EACQ,aAAA,CAAc,YAAwC,SAAA,EAAiD;AAC7G,IAAA,MAAM,UAAwC,EAAC;AAC/C,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,UAAA,CAAW,MAAA,EAAQ,KAAK,SAAA,EAAW;AAAE,MAAA,OAAA,CAAQ,KAAK,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,SAAS,CAAC,CAAA;AAAA,IAAG;AAC3G,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EACA,MAAc,YAAA,GAA8B;AAC1C,IAAA,IAAI,CAAC,8CAAoC,EAAG;AAAE,MAAA;AAAA,IAAQ;AACtD,IAAA,IAAI;AACF,MAAA,MAAM,aAAa,IAAA,CAAK,SAAA,CAAU,KAAK,KAAA,CAAM,GAAA,CAAI,CAAC,EAAA,MAAQ,EAAE,GAAG,EAAA,EAAI,SAAA,EAAW,GAAG,SAAA,CAAU,WAAA,IAAe,UAAA,EAAY,KAAA,CAAA,GAAY,CAAC,CAAA;AACnI,MAAA,YAAA,CAAa,OAAA,CAAQ,IAAA,CAAK,MAAA,CAAO,UAAA,EAAY,UAAU,CAAA;AAAA,IACzD,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,oBAAA,EAAsB;AACjE,QAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,QAAA,IAAI;AACF,UAAA,MAAM,aAAa,IAAA,CAAK,SAAA,CAAU,KAAK,KAAA,CAAM,GAAA,CAAI,CAAC,EAAA,MAAQ,EAAE,GAAG,EAAA,EAAI,SAAA,EAAW,GAAG,SAAA,CAAU,WAAA,IAAe,UAAA,EAAY,KAAA,CAAA,GAAY,CAAC,CAAA;AACnI,UAAA,YAAA,CAAa,OAAA,CAAQ,IAAA,CAAK,MAAA,CAAO,UAAA,EAAY,UAAU,CAAA;AAAA,QACzD,CAAA,CAAA,MAAQ;AAAA,QAAC;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EACQ,SAAA,GAAkB;AACxB,IAAA,IAAI,CAAC,8CAAoC,EAAG;AAAE,MAAA;AAAA,IAAQ;AACtD,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,YAAA,CAAa,OAAA,CAAQ,IAAA,CAAK,OAAO,UAAU,CAAA;AAC1D,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAChC,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAAE,QAAA,IAAA,CAAK,QAAQ,EAAC;AAAG,QAAA;AAAA,MAAQ;AACvD,MAAA,IAAA,CAAK,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,CAAC,EAAA,MAAa,EAAE,GAAG,EAAA,EAAI,SAAA,EAAW,IAAI,IAAA,CAAK,EAAA,CAAG,SAAmB,CAAA,EAAG,UAAA,EAAY,EAAA,CAAG,UAAA,KAAe,MAAM,OAAA,CAAQ,MAAA,CAAO,IAAI,KAAA,CAAM,kCAAkC,CAAC,CAAA,CAAA,EAAG,CAA8B,CAAA;AAAA,IAC/N,CAAA,CAAA,MAAQ;AAAE,MAAA,IAAA,CAAK,QAAQ,EAAC;AAAA,IAAG;AAAA,EAC7B;AAAA,EACQ,oBAAA,GAA6B;AACnC,IAAA,MAAM,SAAA,GAAY,IAAI,IAAA,CAAK,IAAA,CAAK,KAAI,GAAI,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,GAAI,CAAA;AAC3D,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,KAAA,CAAM,MAAA,CAAO,CAAC,EAAA,KAAO,EAAA,CAAG,YAAY,SAAS,CAAA;AAAA,EACjE;AAAA,EACQ,mBAAA,GAA4B;AAClC,IAAA,IAAA,CAAK,iBAAA,GAAoB,uBAAA,CAAwB,CAAC,MAAA,KAAW;AAAE,MAAA,IAAI,MAAA,IAAU,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AAAE,QAAA,IAAA,CAAK,OAAA,EAAQ,CAAE,KAAA,CAAM,MAAM;AAAA,QAAC,CAAC,CAAA;AAAA,MAAG;AAAA,IAAE,CAAC,CAAA;AAAA,EAC3I;AAAA,EACQ,kBAAA,GAA2B;AACjC,IAAA,IAAA,CAAK,cAAA,GAAiB,YAAY,MAAM;AACtC,MAAA,IAAI,QAAA,MAAc,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA,IAAK,CAAC,KAAK,WAAA,EAAa;AAAE,QAAA,IAAA,CAAK,OAAA,EAAQ,CAAE,KAAA,CAAM,MAAM;AAAA,QAAC,CAAC,CAAA;AAAA,MAAG;AAAA,IAClG,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,mBAAmB,CAAA;AAAA,EACpC;AAAA,EACQ,iBAAA,GAA0B;AAChC,IAAA,IAAI,KAAK,cAAA,EAAgB;AAAE,MAAA,aAAA,CAAc,KAAK,cAAc,CAAA;AAAG,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,IAAM;AAAA,EAC7F;AAAA,EACA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,iBAAA,EAAkB;AACvB,IAAA,IAAI,KAAK,iBAAA,EAAmB;AAAE,MAAA,IAAA,CAAK,iBAAA,EAAkB;AAAG,MAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,IAAM;AACvF,IAAA,IAAA,CAAK,oBAAoB,KAAA,EAAM;AAAA,EACjC;AACF;AACO,SAAS,0BAA0B,MAAA,EAA2D;AAAE,EAAA,OAAO,IAAI,oBAAoB,MAAM,CAAA;AAAG;;;AC9M/I,SAAS,eAAe,IAAA,EAAwB;AAC9C,EAAA,IAAI;AAAE,IAAA,IAAA,CAAK,UAAU,IAAI,CAAA;AAAG,IAAA,OAAO,IAAA;AAAA,EAAM,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,KAAA;AAAA,EAAO;AACnE;AACA,SAAS,uBAAA,CAAwB,OAAgB,GAAA,EAAmB;AAClE,EAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,oBAAA,EAAsB;AACjE,IAAA,IAAI;AAAE,MAAA,MAAA,CAAO,YAAA,CAAa,WAAW,GAAG,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAA,IAAC;AAAA,EACtD;AACF;AACA,SAAS,iBAAA,CAAkB,SAAkB,GAAA,EAAsB;AACjE,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAC,UAAA,KAAuB;AAAE,MAAA,IAAI;AAAE,QAAA,OAAO,OAAA,CAAQ,QAAQ,UAAU,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAE,QAAA,OAAO,IAAA;AAAA,MAAM;AAAA,IAAE,CAAA;AAAA,IACtG,OAAA,EAAS,CAAC,UAAA,EAAoB,KAAA,KAAkB;AAAE,MAAA,IAAI;AAAE,QAAA,OAAA,CAAQ,OAAA,CAAQ,YAAY,KAAK,CAAA;AAAA,MAAG,SAAS,KAAA,EAAO;AAAE,QAAA,uBAAA,CAAwB,OAAO,GAAG,CAAA;AAAA,MAAG;AAAA,IAAE,CAAA;AAAA,IACrJ,UAAA,EAAY,CAAC,UAAA,KAAuB;AAAE,MAAA,IAAI;AAAE,QAAA,OAAA,CAAQ,WAAW,UAAU,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAC;AAAA,IAAE,CAAA;AAAA,IACvF,OAAO,MAAM;AAAE,MAAA,IAAI;AAAE,QAAA,OAAA,CAAQ,KAAA,EAAM;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAC;AAAA,IAAE,CAAA;AAAA,IACjD,GAAA,EAAK,CAAC,KAAA,KAAkB;AAAE,MAAA,IAAI;AAAE,QAAA,OAAO,OAAA,CAAQ,IAAI,KAAK,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAE,QAAA,OAAO,IAAA;AAAA,MAAM;AAAA,IAAE,CAAA;AAAA,IACpF,IAAI,MAAA,GAAS;AACX,MAAA,IAAI;AAAE,QAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,MAAQ,CAAA,CAAA,MAAQ;AAAE,QAAA,OAAO,CAAA;AAAA,MAAG;AAAA,IACnD;AAAA,GACF;AACF;AAEO,SAAS,oBAAA,CAAqB,MAAA,GAAkC,EAAC,EAAgG;AACtK,EAAA,MAAM,EAAE,MAAA,GAAS,cAAA,CAAe,SAAS,kBAAA,GAAqB,IAAA,EAAM,kBAAiB,GAAI,MAAA;AACzF,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,gBAAA,EAAkB;AAAA,MAChB,GAAG,gBAAA;AAAA,MACH,oBAAA,EACE,gBAAA,EAAkB,oBAAA,KACjB,kBAAA,GACG,CAAC,KAAA,KAAiB;AAChB,QAAA,IAAI,KAAA,CAAM,KAAA,CAAM,MAAA,KAAW,SAAA,EAAW,OAAO,KAAA;AAC7C,QAAA,IAAI,CAAC,cAAA,CAAe,KAAA,CAAM,KAAA,CAAM,IAAI,GAAG,OAAO,KAAA;AAC9C,QAAA,OAAO,IAAA;AAAA,MACT,CAAA,GACA,MAAA;AAAA;AACR,GACF;AACF;AACO,SAAS,eAAA,CAAgB,UAAA,GAAa,sBAAA,EAAwB,OAAA,EAAmB,OAAA,EAAyD;AAC/I,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAAE,IAAA,OAAO,MAAA;AAAA,EAAW;AACvD,EAAA,MAAM,aAAA,GAAgB,WAAW,MAAA,CAAO,YAAA;AACxC,EAAA,IAAI,CAAC,aAAA,EAAe;AAAE,IAAA,OAAO,MAAA;AAAA,EAAW;AACxC,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAAc,iBAAA,CAAkB,aAAA,EAAe,UAAU,CAAA;AAC/D,IAAA,MAAM,SAAA,GAAuB;AAAA,MAC3B,aAAA,EAAe,OAAO,MAAA,KAA4B;AAAE,QAAA,IAAI;AAAE,UAAA,WAAA,CAAY,OAAA,CAAQ,UAAA,EAAY,IAAA,CAAK,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,QAAG,SAAS,CAAA,EAAG;AAAE,UAAA,IAAI,OAAA,IAAW,aAAa,KAAA,EAAO;AAAE,YAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,UAAG;AAAA,QAAE;AAAA,MAAE,CAAA;AAAA,MACtL,eAAe,YAAY;AAAE,QAAA,IAAI;AAAE,UAAA,MAAM,GAAA,GAAM,WAAA,CAAY,OAAA,CAAQ,UAAU,CAAA;AAAG,UAAA,OAAO,GAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,GAAwB,KAAA,CAAA;AAAA,QAAW,SAAS,CAAA,EAAG;AAAE,UAAA,IAAI,OAAA,IAAW,aAAa,KAAA,EAAO;AAAE,YAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,UAAG;AAAE,UAAA,OAAO,KAAA,CAAA;AAAA,QAAW;AAAA,MAAE,CAAA;AAAA,MACpO,cAAc,YAAY;AAAE,QAAA,IAAI;AAAE,UAAA,WAAA,CAAY,WAAW,UAAU,CAAA;AAAA,QAAG,SAAS,CAAA,EAAG;AAAE,UAAA,IAAI,OAAA,IAAW,aAAa,KAAA,EAAO;AAAE,YAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,UAAG;AAAA,QAAE;AAAA,MAAE;AAAA,KAC3I;AACA,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,MAAA;AAAA,EAAW;AAC9B;AACO,SAAS,UAAA,CAAW,MAAM,sBAAA,EAA8B;AAAE,EAAA,IAAI;AAAE,IAAA,MAAA,CAAO,YAAA,CAAa,WAAW,GAAG,CAAA;AAAA,EAAG,CAAA,CAAA,MAAQ;AAAA,EAAC;AAAE;AAChH,SAAS,iBAAA,CAAkB,GAAA,GAAM,sBAAA,EAAwB,MAAA,GAAS,eAAe,OAAA,EAAe;AACrG,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,GAAG,CAAA;AAC9C,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAChC,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,MAAA,CAAO,SAAA,IAAa,GAAA,GAAM,MAAA,CAAO,YAAY,MAAA,EAAQ;AAAE,MAAA,MAAA,CAAO,YAAA,CAAa,WAAW,GAAG,CAAA;AAAA,IAAG;AAAA,EAClG,CAAA,CAAA,MAAQ;AAAA,EAAC;AACX;AACA,eAAsB,kBAAA,CAAmB,eAAA,GAAkB,sBAAA,EAAwB,YAAA,GAAe,wBAAwB,gBAAA,EAA0G;AAClO,EAAA,IAAI;AACF,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,eAAe,CAAA;AAC7D,IAAA,IAAI,CAAC,SAAA,EAAW;AAAE,MAAA,OAAO,IAAA;AAAA,IAAM;AAC/B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AACnC,IAAA,IAAI,CAAC,OAAO,WAAA,EAAa;AAAE,MAAA,OAAO,KAAA;AAAA,IAAO;AACzC,IAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,OAAA,CAAQ,YAAA,EAAc,SAAS,CAAA;AACtE,IAAA,IAAI,yBAAyB,OAAA,EAAS;AAAE,MAAA,MAAM,aAAA;AAAA,IAAe;AAC7D,IAAA,MAAA,CAAO,YAAA,CAAa,WAAW,eAAe,CAAA;AAC9C,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,KAAA;AAAA,EAAO;AAC1B;AACO,SAAS,gBAAA,CAAiB,MAAM,sBAAA,EAA4G;AACjJ,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,GAAG,CAAA;AAC5C,IAAA,IAAI,CAAC,IAAA,EAAM;AAAE,MAAA,OAAO,EAAE,aAAa,CAAA,EAAG,QAAA,EAAU,GAAG,aAAA,EAAe,KAAA,EAAO,SAAS,qBAAA,EAAsB;AAAA,IAAG;AAC3G,IAAA,MAAM,cAAc,IAAI,IAAA,CAAK,CAAC,IAAI,CAAC,CAAA,CAAE,IAAA;AACrC,IAAA,MAAM,QAAA,GAAW,eAAe,IAAA,GAAO,IAAA,CAAA;AACvC,IAAA,MAAM,gBAAgB,QAAA,GAAW,CAAA;AACjC,IAAA,OAAO,EAAE,aAAa,QAAA,EAAU,IAAA,CAAK,MAAM,QAAA,GAAW,GAAG,CAAA,GAAI,GAAA,EAAK,aAAA,EAAe,OAAA,EAAS,gBAAgB,CAAA,YAAA,EAAe,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAC,CAAA,+DAAA,CAAA,GAAoE,eAAe,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAC,CAAA,+BAAA,CAAA,EAAkC;AAAA,EACtR,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,EAAE,aAAa,CAAA,EAAG,QAAA,EAAU,GAAG,aAAA,EAAe,KAAA,EAAO,SAAS,8BAAA,EAA+B;AAAA,EAAG;AACnH;AACO,SAAS,eAAA,CAAgB,MAAM,sBAAA,EAA0J;AAC9L,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,YAAA,CAAa,OAAA,CAAQ,GAAG,CAAA;AAC5C,IAAA,IAAI,CAAC,IAAA,EAAM;AAAE,MAAA,OAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,QAAA,EAAU,gBAAA,CAAiB,GAAG,CAAA,EAAE;AAAA,IAAG;AACxE,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC9B,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,SAAA,GAAY,GAAA,GAAM,OAAO,SAAA,GAAY,KAAA,CAAA;AACxD,IAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,GAAA,EAAK,YAAA,EAAc,OAAO,WAAA,EAAa,OAAA,EAAS,MAAA,EAAQ,cAAA,EAAgB,OAAO,WAAA,EAAa,SAAA,EAAW,QAAQ,QAAA,EAAU,gBAAA,CAAiB,GAAG,CAAA,EAAE;AAAA,EACxK,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,QAAA,EAAU,gBAAA,CAAiB,GAAG,CAAA,EAAE;AAAA,EAAG;AACvE","file":"chunk-YEV73J4J.js","sourcesContent":["import type { QueryClient } from \"@tanstack/react-query\";\nimport type { MutationFunctionRegistry, OfflineMutationOperation, OfflineQueueConfig, OfflineState } from \"../types/offline\";\nimport { onlineManager } from \"@tanstack/react-query\";\nimport { ConnectionQuality, StorageType } from \"../types/base.js\";\nimport { isStorageAvailable } from \"../utils/storage.js\";\n\nexport function setupOnlineManager() {\n if (typeof window === \"undefined\") return;\n onlineManager.setEventListener((setOnline) => {\n const handleOnline = () => setOnline(true);\n const handleOffline = () => setOnline(false);\n window.addEventListener(\"online\", handleOnline);\n window.addEventListener(\"offline\", handleOffline);\n return () => {\n window.removeEventListener(\"online\", handleOnline);\n window.removeEventListener(\"offline\", handleOffline);\n };\n });\n}\nexport const isOnline = () => onlineManager.isOnline();\nexport function subscribeToOnlineStatus(callback: (online: boolean) => void) { return onlineManager.subscribe(callback); }\nexport function configureOfflineQueries(_queryClient: QueryClient) {}\n\nfunction sortObjectKeys(value: any): any {\n if (value === null || value === undefined) return value;\n if (typeof value !== \"object\") return value;\n if (Array.isArray(value)) return value.map(sortObjectKeys);\n const sorted: Record<string, any> = {};\n Object.keys(value).sort().forEach((key) => { sorted[key] = sortObjectKeys(value[key]); });\n return sorted;\n}\n\nexport function serializeMutationKey(mutationKey: unknown): string {\n try {\n if (typeof mutationKey === \"string\") return mutationKey;\n return JSON.stringify(sortObjectKeys(mutationKey));\n } catch {\n return String(mutationKey);\n }\n}\n\nconst DEFAULT_QUEUE_CONFIG: OfflineQueueConfig = { enabled: true, maxSize: 100, persist: true, storageKey: \"tanstack-query-offline-queue\", autoExecuteInterval: 5000, executeOnReconnect: true, operationTimeout: 30000, concurrency: 3 };\nexport function calculateExponentialBackoff(attempt: number, baseDelay = 1000, maxDelay = 30000): number {\n const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);\n const jitter = Math.random() * 0.3 * delay;\n return Math.floor(delay + jitter);\n}\nclass MutationRegistry implements MutationFunctionRegistry {\n private registry = new Map<string, () => Promise<unknown>>();\n register(key: string, fn: () => Promise<unknown>): void { this.registry.set(key, fn); }\n get(key: string): (() => Promise<unknown>) | undefined { return this.registry.get(key); }\n unregister(key: string): void { this.registry.delete(key); }\n clear(): void { this.registry.clear(); }\n getKeys(): string[] { return Array.from(this.registry.keys()); }\n}\nexport const mutationRegistry = new MutationRegistry();\n\nexport class OfflineQueueManager {\n private queue: OfflineMutationOperation[] = [];\n private config: OfflineQueueConfig;\n private isExecuting = false;\n private executionTimer: NodeJS.Timeout | null = null;\n private unsubscribeOnline: (() => void) | null = null;\n private executingOperations = new Set<string>();\n constructor(config: Partial<OfflineQueueConfig> = {}) {\n this.config = { ...DEFAULT_QUEUE_CONFIG, ...config };\n if (!this.config.enabled) { return; }\n if (this.config.persist) { this.loadQueue(); }\n if (this.config.executeOnReconnect) { this.setupOnlineListener(); }\n if (this.config.autoExecuteInterval > 0) { this.startAutoExecution(); }\n }\n async add(operation: Omit<OfflineMutationOperation, \"id\" | \"createdAt\" | \"retryCount\">): Promise<string> {\n if (!this.config.enabled) { throw new Error(\"Offline queue is disabled\"); }\n const id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const newOperation: OfflineMutationOperation = { ...operation, id, createdAt: new Date(), retryCount: 0 };\n if (this.queue.length >= this.config.maxSize) { throw new Error(`Queue is full (max size: ${this.config.maxSize})`); }\n const insertIndex = this.queue.findIndex((op) => op.priority < newOperation.priority);\n if (insertIndex === -1) { this.queue.push(newOperation); } else { this.queue.splice(insertIndex, 0, newOperation); }\n if (this.config.persist) { await this.persistQueue(); }\n return id;\n }\n async remove(operationId: string): Promise<boolean> {\n const index = this.queue.findIndex((op) => op.id === operationId);\n if (index === -1) return false;\n this.queue.splice(index, 1);\n if (this.config.persist) { await this.persistQueue(); }\n return true;\n }\n getState(): OfflineState {\n const online = isOnline();\n 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 };\n }\n getOperations(): OfflineMutationOperation[] { return [...this.queue]; }\n async clear(): Promise<void> { this.queue = []; if (this.config.persist) { await this.persistQueue(); } }\n async execute(): Promise<{ success: number; failed: number; skipped: number }> {\n if (!this.config.enabled) { return { success: 0, failed: 0, skipped: this.queue.length }; }\n if (this.isExecuting) { return { success: 0, failed: 0, skipped: this.queue.length }; }\n if (!isOnline()) { return { success: 0, failed: 0, skipped: this.queue.length }; }\n this.isExecuting = true;\n let successCount = 0; let failedCount = 0; let skippedCount = 0;\n try {\n const sortedOperations = this.sortOperationsByDependency();\n const batches = this.createBatches(sortedOperations, this.config.concurrency);\n for (const batch of batches) {\n const results = await Promise.allSettled(batch.map((op) => this.executeOperation(op)));\n results.forEach((result) => {\n if (result.status === \"fulfilled\") { if (result.value) { successCount++; } else { skippedCount++; } } else { failedCount++; }\n });\n }\n this.queue = this.queue.filter((op) => op.lastError !== undefined);\n if (this.config.persist) { await this.persistQueue(); }\n return { success: successCount, failed: failedCount, skipped: skippedCount };\n } finally { this.isExecuting = false; }\n }\n private async executeOperation(operation: OfflineMutationOperation): Promise<boolean> {\n if (this.executingOperations.has(operation.id)) { return false; }\n if (operation.dependsOn && operation.dependsOn.length > 0) {\n const dependenciesMet = operation.dependsOn.every((depId) => !this.queue.find((op) => op.id === depId));\n if (!dependenciesMet) { return false; }\n }\n this.executingOperations.add(operation.id);\n try {\n const mutationKey = serializeMutationKey(operation.mutationKey);\n const legacyMutationKey = Array.isArray(operation.mutationKey) ? operation.mutationKey.join(\"-\") : String(operation.mutationKey);\n const mutationFn = mutationRegistry.get(mutationKey) || mutationRegistry.get(legacyMutationKey) || operation.mutationFn;\n const timeoutPromise = new Promise<never>((_, reject) => { setTimeout(() => reject(new Error(\"Operation timeout\")), this.config.operationTimeout); });\n await Promise.race([mutationFn(), timeoutPromise]);\n await this.remove(operation.id);\n return true;\n } catch (error) {\n operation.retryCount++;\n operation.lastError = error instanceof Error ? error : new Error(String(error));\n if (operation.retryCount >= 5) { /* noop */ }\n if (this.config.persist) { await this.persistQueue(); }\n return false;\n } finally { this.executingOperations.delete(operation.id); }\n }\n private sortOperationsByDependency(): OfflineMutationOperation[] {\n const sorted: OfflineMutationOperation[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n const visit = (operation: OfflineMutationOperation) => {\n if (visited.has(operation.id)) return;\n if (visiting.has(operation.id)) { return; }\n visiting.add(operation.id);\n if (operation.dependsOn) {\n for (const depId of operation.dependsOn) {\n const dep = this.queue.find((op) => op.id === depId);\n if (dep) { visit(dep); }\n }\n }\n visiting.delete(operation.id);\n visited.add(operation.id);\n sorted.push(operation);\n };\n const prioritySorted = [...this.queue].sort((a, b) => b.priority - a.priority);\n for (const operation of prioritySorted) { visit(operation); }\n return sorted;\n }\n private createBatches(operations: OfflineMutationOperation[], batchSize: number): OfflineMutationOperation[][] {\n const batches: OfflineMutationOperation[][] = [];\n for (let i = 0; i < operations.length; i += batchSize) { batches.push(operations.slice(i, i + batchSize)); }\n return batches;\n }\n private async persistQueue(): Promise<void> {\n if (!isStorageAvailable(StorageType.LOCAL)) { return; }\n try {\n const serialized = JSON.stringify(this.queue.map((op) => ({ ...op, createdAt: op.createdAt.toISOString(), mutationFn: undefined })));\n localStorage.setItem(this.config.storageKey, serialized);\n } catch (error) {\n if (error instanceof Error && error.name === \"QuotaExceededError\") {\n this.cleanupOldOperations();\n try {\n const serialized = JSON.stringify(this.queue.map((op) => ({ ...op, createdAt: op.createdAt.toISOString(), mutationFn: undefined })));\n localStorage.setItem(this.config.storageKey, serialized);\n } catch {}\n }\n }\n }\n private loadQueue(): void {\n if (!isStorageAvailable(StorageType.LOCAL)) { return; }\n try {\n const stored = localStorage.getItem(this.config.storageKey);\n if (!stored) return;\n const parsed = JSON.parse(stored);\n if (!Array.isArray(parsed)) { this.queue = []; return; }\n this.queue = parsed.map((op: any) => ({ ...op, createdAt: new Date(op.createdAt as string), mutationFn: op.mutationFn || (() => Promise.reject(new Error(\"Mutation function not registered\"))) } as OfflineMutationOperation));\n } catch { this.queue = []; }\n }\n private cleanupOldOperations(): void {\n const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);\n this.queue = this.queue.filter((op) => op.createdAt > oneDayAgo);\n }\n private setupOnlineListener(): void {\n this.unsubscribeOnline = subscribeToOnlineStatus((online) => { if (online && this.queue.length > 0) { this.execute().catch(() => {}); } });\n }\n private startAutoExecution(): void {\n this.executionTimer = setInterval(() => {\n if (isOnline() && this.queue.length > 0 && !this.isExecuting) { this.execute().catch(() => {}); }\n }, this.config.autoExecuteInterval);\n }\n private stopAutoExecution(): void {\n if (this.executionTimer) { clearInterval(this.executionTimer); this.executionTimer = null; }\n }\n destroy(): void {\n this.stopAutoExecution();\n if (this.unsubscribeOnline) { this.unsubscribeOnline(); this.unsubscribeOnline = null; }\n this.executingOperations.clear();\n }\n}\nexport function createOfflineQueueManager(config?: Partial<OfflineQueueConfig>): OfflineQueueManager { return new OfflineQueueManager(config); }\n","import type { Query } from \"@tanstack/react-query\";\nimport type { PersistedClient, Persister } from \"@tanstack/react-query-persist-client\";\nimport { TIME_CONSTANTS } from \"../core/config.js\";\n\nfunction isSerializable(data: unknown): boolean {\n try { JSON.stringify(data); return true; } catch { return false; }\n}\nfunction handleStorageQuotaError(error: unknown, key: string): void {\n if (error instanceof Error && error.name === \"QuotaExceededError\") {\n try { window.localStorage.removeItem(key); } catch {}\n }\n}\nfunction createSafeStorage(storage: Storage, key: string): Storage {\n return {\n getItem: (storageKey: string) => { try { return storage.getItem(storageKey); } catch { return null; } },\n setItem: (storageKey: string, value: string) => { try { storage.setItem(storageKey, value); } catch (error) { handleStorageQuotaError(error, key); } },\n removeItem: (storageKey: string) => { try { storage.removeItem(storageKey); } catch {} },\n clear: () => { try { storage.clear(); } catch {} },\n key: (index: number) => { try { return storage.key(index); } catch { return null; } },\n get length() {\n try { return storage.length; } catch { return 0; }\n }\n } as Storage;\n}\nexport interface PersistOptions { maxAge?: number; onlyPersistSuccess?: boolean; dehydrateOptions?: { shouldDehydrateQuery?: (query: Query) => boolean } }\nexport function createPersistOptions(config: Partial<PersistOptions> = {}): { maxAge: number; dehydrateOptions?: { shouldDehydrateQuery?: (query: Query) => boolean } } {\n const { maxAge = TIME_CONSTANTS.ONE_DAY, onlyPersistSuccess = true, dehydrateOptions } = config;\n return {\n maxAge,\n dehydrateOptions: {\n ...dehydrateOptions,\n shouldDehydrateQuery:\n dehydrateOptions?.shouldDehydrateQuery ||\n (onlyPersistSuccess\n ? (query: Query) => {\n if (query.state.status !== \"success\") return false;\n if (!isSerializable(query.state.data)) return false;\n return true;\n }\n : undefined)\n }\n };\n}\nexport function createPersister(storageKey = \"tanstack-query-cache\", storage?: Storage, onError?: (error: Error) => void): Persister | undefined {\n if (typeof window === \"undefined\") { return undefined; }\n const targetStorage = storage || window.localStorage;\n if (!targetStorage) { return undefined; }\n try {\n const safeStorage = createSafeStorage(targetStorage, storageKey);\n const persister: Persister = {\n persistClient: async (client: PersistedClient) => { try { safeStorage.setItem(storageKey, JSON.stringify(client)); } catch (e) { if (onError && e instanceof Error) { onError(e); } } },\n restoreClient: async () => { try { const raw = safeStorage.getItem(storageKey); return raw ? (JSON.parse(raw) as PersistedClient) : undefined; } catch (e) { if (onError && e instanceof Error) { onError(e); } return undefined; } },\n removeClient: async () => { try { safeStorage.removeItem(storageKey); } catch (e) { if (onError && e instanceof Error) { onError(e); } } }\n };\n return persister;\n } catch { return undefined; }\n}\nexport function clearCache(key = \"tanstack-query-cache\"): void { try { window.localStorage.removeItem(key); } catch {} }\nexport function clearExpiredCache(key = \"tanstack-query-cache\", maxAge = TIME_CONSTANTS.ONE_DAY): void {\n try {\n const stored = window.localStorage.getItem(key);\n if (!stored) return;\n const parsed = JSON.parse(stored) as PersistedClient;\n const now = Date.now();\n if (parsed.timestamp && now - parsed.timestamp > maxAge) { window.localStorage.removeItem(key); }\n } catch {}\n}\nexport async function migrateToIndexedDB(localStorageKey = \"tanstack-query-cache\", indexedDBKey = \"tanstack-query-cache\", indexedDBStorage: Storage | { setItem: (key: string, value: string) => Promise<void> }): Promise<boolean> {\n try {\n const localData = window.localStorage.getItem(localStorageKey);\n if (!localData) { return true; }\n const parsed = JSON.parse(localData) as PersistedClient;\n if (!parsed.clientState) { return false; }\n const setItemResult = indexedDBStorage.setItem(indexedDBKey, localData);\n if (setItemResult instanceof Promise) { await setItemResult; }\n window.localStorage.removeItem(localStorageKey);\n return true;\n } catch { return false; }\n}\nexport function checkStorageSize(key = \"tanstack-query-cache\"): { sizeInBytes: number; sizeInMB: number; shouldMigrate: boolean; message: string } {\n try {\n const data = window.localStorage.getItem(key);\n if (!data) { return { sizeInBytes: 0, sizeInMB: 0, shouldMigrate: false, message: \"No cache data found\" }; }\n const sizeInBytes = new Blob([data]).size;\n const sizeInMB = sizeInBytes / (1024 * 1024);\n const shouldMigrate = sizeInMB > 5;\n 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.` };\n } catch { return { sizeInBytes: 0, sizeInMB: 0, shouldMigrate: false, message: \"Failed to check storage size\" }; }\n}\nexport function getStorageStats(key = \"tanstack-query-cache\"): { exists: boolean; age?: number; queriesCount?: number; mutationsCount?: number; sizeInfo: ReturnType<typeof checkStorageSize> } {\n try {\n const data = window.localStorage.getItem(key);\n if (!data) { return { exists: false, sizeInfo: checkStorageSize(key) }; }\n const parsed = JSON.parse(data) as PersistedClient;\n const now = Date.now();\n const age = parsed.timestamp ? now - parsed.timestamp : undefined;\n return { exists: true, age, queriesCount: parsed.clientState?.queries?.length, mutationsCount: parsed.clientState?.mutations?.length, sizeInfo: checkStorageSize(key) };\n } catch { return { exists: false, sizeInfo: checkStorageSize(key) }; }\n}\nexport type { PersistedClient, Persister };\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/types/dataGuard.ts
|
|
4
|
+
var ConflictError = class extends Error {
|
|
5
|
+
constructor(details) {
|
|
6
|
+
super("Data conflict detected");
|
|
7
|
+
this.details = details;
|
|
8
|
+
this.name = "ConflictError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
exports.ConflictError = ConflictError;
|
|
13
|
+
//# sourceMappingURL=chunk-YW5PNTRU.cjs.map
|
|
14
|
+
//# sourceMappingURL=chunk-YW5PNTRU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/dataGuard.ts"],"names":[],"mappings":";;;AAuEO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EACvC,YAAmB,OAAA,EAAc;AAC/B,IAAA,KAAA,CAAM,wBAAwB,CAAA;AADb,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAEjB,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AACF","file":"chunk-YW5PNTRU.cjs","sourcesContent":["import type { QueryKey } from \"@tanstack/react-query\";\n\n/**\n * 数据防护策略类型\n */\nexport type DataGuardStrategy = \"version\" | \"timestamp\" | \"hash\" | \"none\";\n\n/**\n * 带版本控制的实体基础接口\n */\nexport interface VersionedEntity {\n id: string | number;\n version?: number;\n updatedAt?: string;\n}\n\n/**\n * 带版本控制的分页响应\n */\nexport interface VersionedPaginatedResponse<T> {\n items: T[];\n total: number;\n page?: number;\n pageSize?: number;\n version?: number;\n updatedAt?: string;\n _hash?: string;\n _recentlyUpdatedIds?: Array<string | number> | Set<string | number>;\n}\n\n/**\n * 旧数据检测信息\n */\nexport interface StaleDataInfo {\n reason: string;\n strategy: DataGuardStrategy;\n queryKey: QueryKey;\n cached: any;\n rejected: any;\n}\n\n/**\n * 数据防护应用信息\n */\nexport interface DataGuardInfo {\n strategy: DataGuardStrategy;\n passed: boolean;\n details: any;\n}\n\n/**\n * 数据防护配置选项\n */\nexport interface DataGuardOptions {\n /** 时间戳模式下,最大接受的数据年龄(毫秒),默认 10000 */\n maxDataAge?: number;\n /** 启用版本号检查,默认 true */\n enableVersionCheck?: boolean;\n /** 启用时间戳检查,默认 true */\n enableTimestampCheck?: boolean;\n /** 启用哈希检查(兜底),默认 true */\n enableHashCheck?: boolean;\n /** 检测到旧数据时的回调 */\n onStaleDataDetected?: (info: StaleDataInfo) => void;\n /** 应用防护时的回调 */\n onDataGuardApplied?: (info: DataGuardInfo) => void;\n}\n\n/**\n * 冲突错误类\n */\nexport class ConflictError extends Error {\n constructor(public details: any) {\n super(\"Data conflict detected\");\n this.name = \"ConflictError\";\n }\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// src/types/optimistic.ts
|
|
2
|
+
var OptimisticOperationType = { CREATE: "create", UPDATE: "update", DELETE: "delete", BATCH: "batch" };
|
|
3
|
+
var ListOperationType = /* @__PURE__ */ ((ListOperationType2) => {
|
|
4
|
+
ListOperationType2["ADD"] = "add";
|
|
5
|
+
ListOperationType2["UPDATE"] = "update";
|
|
6
|
+
ListOperationType2["REMOVE"] = "remove";
|
|
7
|
+
return ListOperationType2;
|
|
8
|
+
})(ListOperationType || {});
|
|
9
|
+
|
|
10
|
+
export { ListOperationType, OptimisticOperationType };
|
|
11
|
+
//# sourceMappingURL=chunk-ZNXSWUIS.js.map
|
|
12
|
+
//# sourceMappingURL=chunk-ZNXSWUIS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types/optimistic.ts"],"names":["ListOperationType"],"mappings":";AAIO,IAAM,uBAAA,GAA0B,EAAE,MAAA,EAAQ,QAAA,EAAU,QAAQ,QAAA,EAAU,MAAA,EAAQ,QAAA,EAAU,KAAA,EAAO,OAAA;AAG/F,IAAK,iBAAA,qBAAAA,kBAAAA,KAAL;AAAyB,EAAAA,mBAAA,KAAA,CAAA,GAAM,KAAA;AAAO,EAAAA,mBAAA,QAAA,CAAA,GAAS,QAAA;AAAU,EAAAA,mBAAA,QAAA,CAAA,GAAS,QAAA;AAA7D,EAAA,OAAAA,kBAAAA;AAAA,CAAA,EAAA,iBAAA,IAAA,EAAA","file":"chunk-ZNXSWUIS.js","sourcesContent":["import type { QueryKey } from \"@tanstack/react-query\";\nimport type { EntityWithId } from \"./selectors\";\nexport interface OptimisticUpdateConfig<TData = unknown, TVariables = unknown> { queryKey: QueryKey; updater: (oldData: TData | undefined, variables: TVariables) => TData | undefined; rollback?: (previousData: TData, error: Error) => void; enabled?: boolean }\nexport interface OptimisticContext<TData = unknown> { previousData?: TData; timestamp: number; operationType: OptimisticOperationTypeValue }\nexport const OptimisticOperationType = { CREATE: \"create\", UPDATE: \"update\", DELETE: \"delete\", BATCH: \"batch\" } as const;\nexport type OptimisticOperationTypeValue = (typeof OptimisticOperationType)[keyof typeof OptimisticOperationType];\nexport interface ListOperationConfig<T extends EntityWithId> { queryKey: QueryKey; operation: ListOperationType; onRollback?: (error: Error, context: OptimisticContext<T[]>) => void }\nexport enum ListOperationType { ADD = \"add\", UPDATE = \"update\", REMOVE = \"remove\" }\nexport interface BatchQueryResult<TData = unknown, TError = Error> { data: TData | undefined; isLoading: boolean; isError: boolean; error: TError | null; status: \"pending\" | \"error\" | \"success\" }\nexport type OptimisticUpdater<TData = unknown, TVariables = unknown> = (oldData: TData | undefined, variables: TVariables) => TData;\nexport type RollbackFunction<TData = unknown> = (previousData: TData, error: Error) => void;\nexport type ListUpdater<T extends EntityWithId> = { add: (items: T[] | undefined, newItem: T) => T[]; update: (items: T[] | undefined, updatedItem: Partial<T> & { id: T[\"id\"] }) => T[]; remove: (items: T[] | undefined, itemId: T[\"id\"]) => T[] };\nexport interface OptimisticGlobalConfig { enabledByDefault: boolean; defaultRollbackDelay: number; debugMode: boolean; maxRetries: number }\nexport interface BatchQueryStats { total: number; loading: number; success: number; error: number; stale: number; successRate: number; errorRate: number }\nexport interface BatchQueryConfig<TData = unknown, TError = Error> { enableStats?: boolean; enableBatchOperations?: boolean; autoRefreshInterval?: number; onBatchSuccess?: (results: TData[]) => void; onBatchError?: (errors: TError[]) => void; onBatchSettled?: (results: TData[], errors: TError[]) => void; retryConfig?: BatchRetryConfig; enablePartialSuccess?: boolean; onPartialSuccess?: (report: BatchOperationReport<TData, TError>) => void }\nexport interface BatchRetryConfig { maxRetries?: number; retryDelay?: number | ((attemptIndex: number) => number); retryOnlyFailed?: boolean; shouldRetry?: (error: Error, attemptCount: number) => boolean }\nexport interface BatchOperationReport<TData = unknown, TError = Error> { total: number; successful: number; failed: number; successResults: Array<{ index: number; data: TData }>; failureErrors: Array<{ index: number; error: TError; queryKey?: unknown[] }>; isPartialSuccess: boolean; isFullSuccess: boolean; isFullFailure: boolean; duration: number; retryCount?: number }\nexport interface BatchErrorAggregate<TError = Error> { totalErrors: number; errors: Array<{ index: number; error: TError; queryKey?: unknown[] }>; errorsByType: Map<string, TError[]>; firstError: TError | null; lastError: TError | null; errorSummary: string }\nexport interface BatchQueryOperations { refetchAll: () => Promise<PromiseSettledResult<unknown>[]>; invalidateAll: () => Promise<PromiseSettledResult<void>[]>; cancelAll: () => Promise<PromiseSettledResult<void>[]>; resetAll: () => Promise<PromiseSettledResult<void>[]>; removeAll: () => void; retryFailed: () => Promise<BatchOperationReport>; getErrorAggregate: () => BatchErrorAggregate; getOperationReport: () => BatchOperationReport }\nexport interface EnhancedBatchQueryResult<TData = unknown, TCombinedResult = TData, TError = Error> { data: TCombinedResult; stats: BatchQueryStats; operations: BatchQueryOperations; config: BatchQueryConfig<TData, TError> }"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isProd } from './chunk-JN2Y6RSY.js';
|
|
2
|
+
export { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
|
3
|
+
|
|
4
|
+
var defaultDevToolsConfig = {
|
|
5
|
+
initialIsOpen: false,
|
|
6
|
+
position: "bottom-right",
|
|
7
|
+
enabled: !isProd
|
|
8
|
+
};
|
|
9
|
+
function createDevToolsConfig(overrides) {
|
|
10
|
+
return {
|
|
11
|
+
...defaultDevToolsConfig,
|
|
12
|
+
...overrides
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function isDevToolsEnabled() {
|
|
16
|
+
return !isProd;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { createDevToolsConfig, defaultDevToolsConfig, isDevToolsEnabled };
|
|
20
|
+
//# sourceMappingURL=chunk-ZUEMBY4W.js.map
|
|
21
|
+
//# sourceMappingURL=chunk-ZUEMBY4W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/devtools.ts"],"names":[],"mappings":";;;AAcO,IAAM,qBAAA,GAAwC;AAAA,EACnD,aAAA,EAAe,KAAA;AAAA,EACf,QAAA,EAAU,cAAA;AAAA,EACV,SAAS,CAAC;AACZ;AAEO,SAAS,qBAAqB,SAAA,EAAqD;AACxF,EAAA,OAAO;AAAA,IACL,GAAG,qBAAA;AAAA,IACH,GAAG;AAAA,GACL;AACF;AAEO,SAAS,iBAAA,GAA6B;AAC3C,EAAA,OAAO,CAAC,MAAA;AACV","file":"chunk-ZUEMBY4W.js","sourcesContent":["import type { ComponentProps } from \"react\";\nimport { isProd } from \"./env.js\";\nexport { ReactQueryDevtools } from \"@tanstack/react-query-devtools\";\n\nexport interface DevToolsConfig {\n initialIsOpen?: boolean;\n position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n enabled?: boolean;\n buttonPosition?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n panelProps?: ComponentProps<\"div\">;\n closeButtonProps?: ComponentProps<\"button\">;\n toggleButtonProps?: ComponentProps<\"button\">;\n}\n\nexport const defaultDevToolsConfig: DevToolsConfig = {\n initialIsOpen: false,\n position: \"bottom-right\",\n enabled: !isProd\n};\n\nexport function createDevToolsConfig(overrides?: Partial<DevToolsConfig>): DevToolsConfig {\n return {\n ...defaultDevToolsConfig,\n ...overrides\n };\n}\n\nexport function isDevToolsEnabled(): boolean {\n return !isProd;\n}"]}
|