@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.
Files changed (127) hide show
  1. package/dist/PersistQueryClientProvider.d.ts +22 -0
  2. package/dist/PersistQueryClientProvider.d.ts.map +1 -0
  3. package/dist/PersistQueryClientProvider.js +47 -0
  4. package/dist/components/LoadingFallback.d.ts +16 -0
  5. package/dist/components/LoadingFallback.d.ts.map +1 -0
  6. package/dist/components/LoadingFallback.js +27 -0
  7. package/dist/components/QueryErrorBoundary.d.ts +12 -0
  8. package/dist/components/QueryErrorBoundary.d.ts.map +1 -0
  9. package/dist/components/QueryErrorBoundary.js +9 -0
  10. package/dist/components/SuspenseWrapper.d.ts +14 -0
  11. package/dist/components/SuspenseWrapper.d.ts.map +1 -0
  12. package/dist/components/SuspenseWrapper.js +9 -0
  13. package/dist/components/index.d.ts +4 -0
  14. package/dist/components/index.d.ts.map +1 -0
  15. package/dist/components/index.js +3 -0
  16. package/dist/components/internal/ErrorBoundary.d.ts +26 -0
  17. package/dist/components/internal/ErrorBoundary.d.ts.map +1 -0
  18. package/dist/components/internal/ErrorBoundary.js +28 -0
  19. package/dist/core/config.d.ts +36 -0
  20. package/dist/core/config.d.ts.map +1 -0
  21. package/dist/core/config.js +213 -0
  22. package/dist/core/devtools.d.ts +14 -0
  23. package/dist/core/devtools.d.ts.map +1 -0
  24. package/dist/core/devtools.js +16 -0
  25. package/dist/core/env.d.ts +3 -0
  26. package/dist/core/env.d.ts.map +1 -0
  27. package/dist/core/env.js +2 -0
  28. package/dist/core/focusManager.d.ts +33 -0
  29. package/dist/core/focusManager.d.ts.map +1 -0
  30. package/dist/core/focusManager.js +122 -0
  31. package/dist/core/index.d.ts +6 -0
  32. package/dist/core/index.d.ts.map +1 -0
  33. package/dist/core/index.js +5 -0
  34. package/dist/core/keys.d.ts +59 -0
  35. package/dist/core/keys.d.ts.map +1 -0
  36. package/dist/core/keys.js +107 -0
  37. package/dist/core/queryOptions.d.ts +30 -0
  38. package/dist/core/queryOptions.d.ts.map +1 -0
  39. package/dist/core/queryOptions.js +30 -0
  40. package/dist/features/index.d.ts +4 -0
  41. package/dist/features/index.d.ts.map +1 -0
  42. package/dist/features/index.js +3 -0
  43. package/dist/features/offline.d.ts +48 -0
  44. package/dist/features/offline.d.ts.map +1 -0
  45. package/dist/features/offline.js +269 -0
  46. package/dist/features/persistence.d.ts +36 -0
  47. package/dist/features/persistence.d.ts.map +1 -0
  48. package/dist/features/persistence.js +175 -0
  49. package/dist/hooks/batchQueries.d.ts +128 -0
  50. package/dist/hooks/batchQueries.d.ts.map +1 -0
  51. package/dist/hooks/batchQueries.js +301 -0
  52. package/dist/hooks/index.d.ts +8 -0
  53. package/dist/hooks/index.d.ts.map +1 -0
  54. package/dist/hooks/index.js +7 -0
  55. package/dist/hooks/useFocusManager.d.ts +41 -0
  56. package/dist/hooks/useFocusManager.d.ts.map +1 -0
  57. package/dist/hooks/useFocusManager.js +109 -0
  58. package/dist/hooks/useInfiniteQuery.d.ts +58 -0
  59. package/dist/hooks/useInfiniteQuery.d.ts.map +1 -0
  60. package/dist/hooks/useInfiniteQuery.js +61 -0
  61. package/dist/hooks/useMutation.d.ts +34 -0
  62. package/dist/hooks/useMutation.d.ts.map +1 -0
  63. package/dist/hooks/useMutation.js +176 -0
  64. package/dist/hooks/usePrefetch.d.ts +54 -0
  65. package/dist/hooks/usePrefetch.d.ts.map +1 -0
  66. package/dist/hooks/usePrefetch.js +203 -0
  67. package/dist/hooks/useQuery.d.ts +5 -0
  68. package/dist/hooks/useQuery.d.ts.map +1 -0
  69. package/dist/hooks/useQuery.js +5 -0
  70. package/dist/hooks/useSuspenseQuery.d.ts +11 -0
  71. package/dist/hooks/useSuspenseQuery.d.ts.map +1 -0
  72. package/dist/hooks/useSuspenseQuery.js +19 -0
  73. package/dist/index.d.ts +8 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +7 -0
  76. package/dist/types/base.d.ts +54 -0
  77. package/dist/types/base.d.ts.map +1 -0
  78. package/dist/types/base.js +26 -0
  79. package/dist/types/index.d.ts +23 -0
  80. package/dist/types/index.d.ts.map +1 -0
  81. package/dist/types/index.js +7 -0
  82. package/dist/types/infinite.d.ts +39 -0
  83. package/dist/types/infinite.d.ts.map +1 -0
  84. package/dist/types/infinite.js +1 -0
  85. package/dist/types/offline.d.ts +97 -0
  86. package/dist/types/offline.d.ts.map +1 -0
  87. package/dist/types/offline.js +8 -0
  88. package/dist/types/optimistic.d.ts +126 -0
  89. package/dist/types/optimistic.d.ts.map +1 -0
  90. package/dist/types/optimistic.js +7 -0
  91. package/dist/types/persistence.d.ts +9 -0
  92. package/dist/types/persistence.d.ts.map +1 -0
  93. package/dist/types/persistence.js +1 -0
  94. package/dist/types/selectors.d.ts +11 -0
  95. package/dist/types/selectors.d.ts.map +1 -0
  96. package/dist/types/selectors.js +1 -0
  97. package/dist/types/suspense.d.ts +67 -0
  98. package/dist/types/suspense.d.ts.map +1 -0
  99. package/dist/types/suspense.js +1 -0
  100. package/dist/utils/fieldMapper.d.ts +9 -0
  101. package/dist/utils/fieldMapper.d.ts.map +1 -0
  102. package/dist/utils/fieldMapper.js +27 -0
  103. package/dist/utils/index.d.ts +9 -0
  104. package/dist/utils/index.d.ts.map +1 -0
  105. package/dist/utils/index.js +8 -0
  106. package/dist/utils/network.d.ts +9 -0
  107. package/dist/utils/network.d.ts.map +1 -0
  108. package/dist/utils/network.js +43 -0
  109. package/dist/utils/optimisticUtils.d.ts +34 -0
  110. package/dist/utils/optimisticUtils.d.ts.map +1 -0
  111. package/dist/utils/optimisticUtils.js +76 -0
  112. package/dist/utils/placeholderData.d.ts +2 -0
  113. package/dist/utils/placeholderData.d.ts.map +1 -0
  114. package/dist/utils/placeholderData.js +1 -0
  115. package/dist/utils/prefetchManager.d.ts +111 -0
  116. package/dist/utils/prefetchManager.d.ts.map +1 -0
  117. package/dist/utils/prefetchManager.js +246 -0
  118. package/dist/utils/queryKey.d.ts +24 -0
  119. package/dist/utils/queryKey.d.ts.map +1 -0
  120. package/dist/utils/queryKey.js +77 -0
  121. package/dist/utils/selectors.d.ts +30 -0
  122. package/dist/utils/selectors.d.ts.map +1 -0
  123. package/dist/utils/selectors.js +18 -0
  124. package/dist/utils/storage.d.ts +7 -0
  125. package/dist/utils/storage.d.ts.map +1 -0
  126. package/dist/utils/storage.js +84 -0
  127. package/package.json +70 -0
@@ -0,0 +1,301 @@
1
+ import { useQueries, useQuery, useQueryClient, useSuspenseQueries } from "@tanstack/react-query";
2
+ import { useEffect, useMemo, useRef } from "react";
3
+ function createErrorAggregate(results, queries) {
4
+ const errors = [];
5
+ const errorsByType = new Map();
6
+ results.forEach((result, index) => {
7
+ if (result.isError && result.error) {
8
+ const error = result.error;
9
+ const queryKey = queries[index]?.queryKey;
10
+ errors.push({ index, error, queryKey });
11
+ const errorType = error instanceof Error ? error.constructor.name : "Unknown";
12
+ if (!errorsByType.has(errorType)) {
13
+ errorsByType.set(errorType, []);
14
+ }
15
+ errorsByType.get(errorType).push(error);
16
+ }
17
+ });
18
+ const firstError = errors.length > 0 ? errors[0].error : null;
19
+ const lastError = errors.length > 0 ? errors[errors.length - 1].error : null;
20
+ const errorSummary = errors.length === 0 ? "No errors" : errors.length === 1 ? `1 error: ${firstError instanceof Error ? firstError.message : String(firstError)}` : `${errors.length} errors: ${Array.from(errorsByType.entries()).map(([type, errs]) => `${type}(${errs.length})`).join(", ")}`;
21
+ return { totalErrors: errors.length, errors, errorsByType, firstError, lastError, errorSummary };
22
+ }
23
+ function createOperationReport(results, queries, startTime, retryCount = 0) {
24
+ const total = results.length;
25
+ const successResults = [];
26
+ const failureErrors = [];
27
+ results.forEach((result, index) => {
28
+ if (result.isSuccess && result.data !== undefined) {
29
+ successResults.push({ index, data: result.data });
30
+ }
31
+ else if (result.isError && result.error) {
32
+ failureErrors.push({ index, error: result.error, queryKey: queries[index]?.queryKey });
33
+ }
34
+ });
35
+ const successful = successResults.length;
36
+ const failed = failureErrors.length;
37
+ const isFullSuccess = successful === total && failed === 0;
38
+ const isFullFailure = failed === total && successful === 0;
39
+ const isPartialSuccess = successful > 0 && failed > 0;
40
+ return { total, successful, failed, successResults, failureErrors, isPartialSuccess, isFullSuccess, isFullFailure, duration: Date.now() - startTime, retryCount };
41
+ }
42
+ async function executeBatchOperationWithRetry(operation, retryConfig) {
43
+ const maxRetries = retryConfig?.maxRetries ?? 0;
44
+ const retryDelay = retryConfig?.retryDelay ?? 1000;
45
+ const shouldRetry = retryConfig?.shouldRetry;
46
+ let retryCount = 0;
47
+ let results = await operation();
48
+ if (maxRetries === 0) {
49
+ return { results, retryCount };
50
+ }
51
+ while (retryCount < maxRetries) {
52
+ const hasFailures = results.some((r) => r.status === "rejected");
53
+ if (!hasFailures)
54
+ break;
55
+ if (shouldRetry) {
56
+ const firstError = results.find((r) => r.status === "rejected");
57
+ if (firstError && firstError.status === "rejected") {
58
+ const error = firstError.reason instanceof Error ? firstError.reason : new Error(String(firstError.reason));
59
+ if (!shouldRetry(error, retryCount + 1)) {
60
+ break;
61
+ }
62
+ }
63
+ }
64
+ const delay = typeof retryDelay === "function" ? retryDelay(retryCount) : retryDelay;
65
+ await new Promise((resolve) => setTimeout(resolve, delay));
66
+ retryCount++;
67
+ results = await operation();
68
+ }
69
+ return { results, retryCount };
70
+ }
71
+ export function calculateBatchStats(results) {
72
+ const total = results.length;
73
+ const loading = results.filter((result) => result.isLoading).length;
74
+ const success = results.filter((result) => result.isSuccess).length;
75
+ const error = results.filter((result) => result.isError).length;
76
+ const stale = results.filter((result) => result.isStale).length;
77
+ return { total, loading, success, error, stale, successRate: total > 0 ? (success / total) * 100 : 0, errorRate: total > 0 ? (error / total) * 100 : 0 };
78
+ }
79
+ export function useEnhancedQueries(queries, config = {}) {
80
+ const queryClient = useQueryClient();
81
+ const { results, stats } = useQueries({ queries, combine: (results) => ({ results, stats: calculateBatchStats(results) }) });
82
+ const retryCountRef = useRef(0);
83
+ const operations = {
84
+ _queryClient: queryClient,
85
+ _queries: queries,
86
+ _results: results,
87
+ refetchAll: async () => {
88
+ const operation = () => {
89
+ const promises = queries.map((query) => queryClient.refetchQueries({ queryKey: query.queryKey, exact: true }));
90
+ return Promise.allSettled(promises);
91
+ };
92
+ const { results: settledResults, retryCount } = await executeBatchOperationWithRetry(operation, config.retryConfig);
93
+ retryCountRef.current = retryCount;
94
+ if (config.enablePartialSuccess) {
95
+ const report = operations.getOperationReport();
96
+ if (report.isPartialSuccess && config.onPartialSuccess) {
97
+ config.onPartialSuccess(report);
98
+ }
99
+ }
100
+ return settledResults;
101
+ },
102
+ invalidateAll: async () => {
103
+ const operation = () => {
104
+ const promises = queries.map((query) => queryClient.invalidateQueries({ queryKey: query.queryKey, exact: true }));
105
+ return Promise.allSettled(promises);
106
+ };
107
+ const { results: settledResults, retryCount } = await executeBatchOperationWithRetry(operation, config.retryConfig);
108
+ retryCountRef.current = retryCount;
109
+ return settledResults;
110
+ },
111
+ cancelAll: async () => {
112
+ const promises = queries.map((query) => queryClient.cancelQueries({ queryKey: query.queryKey, exact: true }));
113
+ return Promise.allSettled(promises);
114
+ },
115
+ resetAll: async () => {
116
+ const operation = () => {
117
+ const promises = queries.map((query) => queryClient.resetQueries({ queryKey: query.queryKey, exact: true }));
118
+ return Promise.allSettled(promises);
119
+ };
120
+ const { results: settledResults, retryCount } = await executeBatchOperationWithRetry(operation, config.retryConfig);
121
+ retryCountRef.current = retryCount;
122
+ return settledResults;
123
+ },
124
+ removeAll: () => {
125
+ queries.forEach((query) => { queryClient.removeQueries({ queryKey: query.queryKey, exact: true }); });
126
+ },
127
+ retryFailed: async () => {
128
+ const failedIndices = results.map((result, index) => (result.isError ? index : -1)).filter((index) => index !== -1);
129
+ if (failedIndices.length === 0) {
130
+ return createOperationReport(results, queries, 0, 0);
131
+ }
132
+ const retryPromises = failedIndices.map((index) => {
133
+ const query = queries[index];
134
+ return queryClient.refetchQueries({ queryKey: query.queryKey, exact: true });
135
+ });
136
+ await Promise.allSettled(retryPromises);
137
+ retryCountRef.current++;
138
+ return operations.getOperationReport();
139
+ },
140
+ getErrorAggregate: () => { return createErrorAggregate(results, queries); },
141
+ getOperationReport: () => { return createOperationReport(results, queries, 0, retryCountRef.current); }
142
+ };
143
+ return { data: results, stats, operations, config };
144
+ }
145
+ export function useEnhancedSuspenseQueries(queries, config = {}) {
146
+ const queryClient = useQueryClient();
147
+ const { results, stats } = useSuspenseQueries({ queries, combine: (results) => ({ results, stats: calculateBatchStats(results) }) });
148
+ const retryCountRef = useRef(0);
149
+ const operations = {
150
+ _queryClient: queryClient,
151
+ _queries: queries,
152
+ _results: results,
153
+ refetchAll: async () => {
154
+ const operation = () => {
155
+ const promises = queries.map((query) => queryClient.refetchQueries({ queryKey: query.queryKey, exact: true }));
156
+ return Promise.allSettled(promises);
157
+ };
158
+ const { results: settledResults, retryCount } = await executeBatchOperationWithRetry(operation, config.retryConfig);
159
+ retryCountRef.current = retryCount;
160
+ if (config.enablePartialSuccess) {
161
+ const report = operations.getOperationReport();
162
+ if (report.isPartialSuccess && config.onPartialSuccess) {
163
+ config.onPartialSuccess(report);
164
+ }
165
+ }
166
+ return settledResults;
167
+ },
168
+ invalidateAll: async () => {
169
+ const operation = () => {
170
+ const promises = queries.map((query) => queryClient.invalidateQueries({ queryKey: query.queryKey, exact: true }));
171
+ return Promise.allSettled(promises);
172
+ };
173
+ const { results: settledResults, retryCount } = await executeBatchOperationWithRetry(operation, config.retryConfig);
174
+ retryCountRef.current = retryCount;
175
+ return settledResults;
176
+ },
177
+ cancelAll: async () => {
178
+ const promises = queries.map((query) => queryClient.cancelQueries({ queryKey: query.queryKey, exact: true }));
179
+ return Promise.allSettled(promises);
180
+ },
181
+ resetAll: async () => {
182
+ const operation = () => {
183
+ const promises = queries.map((query) => queryClient.resetQueries({ queryKey: query.queryKey, exact: true }));
184
+ return Promise.allSettled(promises);
185
+ };
186
+ const { results: settledResults, retryCount } = await executeBatchOperationWithRetry(operation, config.retryConfig);
187
+ retryCountRef.current = retryCount;
188
+ return settledResults;
189
+ },
190
+ removeAll: () => {
191
+ queries.forEach((query) => { queryClient.removeQueries({ queryKey: query.queryKey, exact: true }); });
192
+ },
193
+ retryFailed: async () => {
194
+ const failedIndices = results.map((result, index) => (result.isError ? index : -1)).filter((index) => index !== -1);
195
+ if (failedIndices.length === 0) {
196
+ return createOperationReport(results, queries, 0, 0);
197
+ }
198
+ const retryPromises = failedIndices.map((index) => {
199
+ const query = queries[index];
200
+ return queryClient.refetchQueries({ queryKey: query.queryKey, exact: true });
201
+ });
202
+ await Promise.allSettled(retryPromises);
203
+ retryCountRef.current++;
204
+ return operations.getOperationReport();
205
+ },
206
+ getErrorAggregate: () => { return createErrorAggregate(results, queries); },
207
+ getOperationReport: () => { return createOperationReport(results, queries, 0, retryCountRef.current); }
208
+ };
209
+ return { data: results, stats, operations, config };
210
+ }
211
+ export function createBatchQueryConfig(config = {}) {
212
+ return { enableStats: true, enableBatchOperations: true, autoRefreshInterval: undefined, onBatchSuccess: undefined, onBatchError: undefined, onBatchSettled: undefined, enablePartialSuccess: false, onPartialSuccess: undefined, retryConfig: undefined, ...config };
213
+ }
214
+ export const batchQueryUtils = {
215
+ isAllLoading: (results) => results.every((result) => result.isLoading),
216
+ isAllSuccess: (results) => results.every((result) => result.isSuccess),
217
+ hasError: (results) => results.some((result) => result.isError),
218
+ hasStale: (results) => results.some((result) => result.isStale),
219
+ getAllErrors: (results) => results.filter((result) => result.isError).map((result) => result.error).filter((error) => error instanceof Error),
220
+ getAllData: (results) => results.filter((result) => result.isSuccess).map((result) => result.data),
221
+ isAllPending: (results) => results.every((result) => result.isPending),
222
+ isAnyFetching: (results) => results.some((result) => result.isFetching),
223
+ getSuccessData: (results) => results.filter((result) => result.isSuccess && result.data !== undefined).map((result) => result.data),
224
+ getFirstError: (results) => { const errorResult = results.find((result) => result.isError); return errorResult?.error instanceof Error ? errorResult.error : null; },
225
+ createErrorAggregate: (results, queries) => createErrorAggregate(results, queries),
226
+ createOperationReport: (results, queries, startTime, retryCount = 0) => createOperationReport(results, queries, startTime, retryCount)
227
+ };
228
+ export function useCombinedQueries(options) {
229
+ return useQueries(options);
230
+ }
231
+ export function useDynamicBatchQueries(options) {
232
+ const { items, queryKeyPrefix, queryFn, enabled = true, staleTime, gcTime, config = {} } = options;
233
+ const queries = useMemo(() => {
234
+ if (!enabled || items.length === 0)
235
+ return [];
236
+ return items.map((item) => ({ queryKey: [...queryKeyPrefix, item], queryFn: () => queryFn(item), staleTime, gcTime, enabled }));
237
+ }, [items, queryKeyPrefix, queryFn, enabled, staleTime, gcTime]);
238
+ return useEnhancedQueries(queries, config);
239
+ }
240
+ export function useDependentBatchQueries(options) {
241
+ const { primaryQuery, dependentQueries, config = {} } = options;
242
+ const primaryResult = useQuery(primaryQuery);
243
+ const queries = useMemo(() => {
244
+ try {
245
+ if (!primaryResult.data) {
246
+ return [];
247
+ }
248
+ return dependentQueries(primaryResult.data);
249
+ }
250
+ catch {
251
+ return [];
252
+ }
253
+ }, [primaryResult.data, dependentQueries]);
254
+ const enhancedQueriesResult = useEnhancedQueries(queries, config);
255
+ return { primaryResult, results: enhancedQueriesResult.data, stats: enhancedQueriesResult.stats, operations: enhancedQueriesResult.operations };
256
+ }
257
+ export function useAutoRefreshBatchQueries(options) {
258
+ const { queries, refreshInterval = 30000, enabled = true, config = {} } = options;
259
+ const result = useEnhancedQueries(queries, config);
260
+ useEffect(() => {
261
+ if (!enabled || !refreshInterval || !result.operations)
262
+ return;
263
+ const intervalId = setInterval(() => { result.operations?.refetchAll(); }, refreshInterval);
264
+ return () => clearInterval(intervalId);
265
+ }, [enabled, refreshInterval, result.operations]);
266
+ return result;
267
+ }
268
+ export function useDashboardQueries(queriesMap) {
269
+ const queries = useMemo(() => { return Object.values(queriesMap); }, [queriesMap]);
270
+ const { results, combinedData, stats } = useQueries({ queries, combine: (results) => {
271
+ const keys = Object.keys(queriesMap);
272
+ const data = {};
273
+ keys.forEach((key, index) => { data[key] = results[index].data; });
274
+ return { results, combinedData: data, stats: calculateBatchStats(results) };
275
+ } });
276
+ const isLoading = results.some((r) => r.isLoading);
277
+ const isError = results.some((r) => r.isError);
278
+ const isSuccess = results.every((r) => r.isSuccess);
279
+ return { data: combinedData, results, stats, isLoading, isError, isSuccess };
280
+ }
281
+ export function usePaginatedBatchQueries(options) {
282
+ const { pageNumbers, queryKeyPrefix, queryFn, staleTime, config } = options;
283
+ return useDynamicBatchQueries({ items: pageNumbers, queryKeyPrefix, queryFn, staleTime, config });
284
+ }
285
+ export function useConditionalBatchQueries(queries) {
286
+ const enabledQueries = useMemo(() => { return queries.filter((q) => q.enabled !== false); }, [queries]);
287
+ return useEnhancedQueries(enabledQueries);
288
+ }
289
+ export function useRetryBatchQueries(options) {
290
+ const { queries, retry, retryDelay, config } = options;
291
+ const queriesWithRetry = useMemo(() => { return queries.map((query) => ({ ...query, retry: query.retry ?? retry, retryDelay: query.retryDelay ?? retryDelay })); }, [queries, retry, retryDelay]);
292
+ return useEnhancedQueries(queriesWithRetry, config);
293
+ }
294
+ export function useBatchQueryPerformance(results) {
295
+ return useMemo(() => {
296
+ const stats = calculateBatchStats(results);
297
+ const fetchTimes = results.filter((r) => r.dataUpdatedAt > 0).map((r) => r.dataUpdatedAt);
298
+ const avgFetchTime = fetchTimes.length > 0 ? fetchTimes.reduce((a, b) => a + b, 0) / fetchTimes.length : 0;
299
+ return { ...stats, avgFetchTime, totalQueries: results.length, activeQueries: results.filter((r) => r.isFetching).length, cachedQueries: results.filter((r) => !r.isStale).length };
300
+ }, [results]);
301
+ }
@@ -0,0 +1,8 @@
1
+ export { batchQueryUtils, calculateBatchStats, createBatchQueryConfig, useAutoRefreshBatchQueries, useBatchQueryPerformance, useCombinedQueries, useConditionalBatchQueries, useDashboardQueries, useDependentBatchQueries, useDynamicBatchQueries, useEnhancedQueries, useEnhancedSuspenseQueries, usePaginatedBatchQueries, useRetryBatchQueries } from "./batchQueries.js";
2
+ export { useConditionalFocusRefetch, useFocusCallback, useFocusRefetch, type UseFocusRefetchOptions, useFocusState, usePageVisibility, usePauseFocus, type UsePauseFocusOptions, useSmartFocusManager } from "./useFocusManager.js";
3
+ export { createCursorPaginationOptions, createOffsetPaginationOptions, createPageNumberPaginationOptions, useEnhancedInfiniteQuery } from "./useInfiniteQuery.js";
4
+ export { cancelQueriesBatch, invalidateQueriesBatch, type MutationDefaultsConfig, type MutationKey, setQueryDataBatch, setupMutationDefaults, useBatchMutation, useConditionalOptimisticMutation, useListMutation, useMutation } from "./useMutation.js";
5
+ export { type HoverPrefetchOptions, type InViewPrefetchOptions, type PrefetchOptions, useBatchPrefetch, useConditionalPrefetch, useHoverPrefetch, useIdlePrefetch, useInViewPrefetch, usePeriodicPrefetch, usePredictivePrefetch, usePriorityPrefetch, useRoutePrefetch, useSmartPrefetch } from "./usePrefetch.js";
6
+ export { skipToken, useEnhancedQuery } from "./useQuery.js";
7
+ export { createSuspenseInfiniteQuery, createSuspenseQuery, useEnhancedSuspenseInfiniteQuery, useEnhancedSuspenseQuery } from "./useSuspenseQuery.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,kBAAkB,EAClB,0BAA0B,EAC1B,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,EACtB,kBAAkB,EAClB,0BAA0B,EAC1B,wBAAwB,EACxB,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,eAAe,EACf,KAAK,sBAAsB,EAC3B,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,KAAK,oBAAoB,EACzB,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,6BAA6B,EAAE,6BAA6B,EAAE,iCAAiC,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAClK,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,gCAAgC,EAChC,eAAe,EACf,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,gCAAgC,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { batchQueryUtils, calculateBatchStats, createBatchQueryConfig, useAutoRefreshBatchQueries, useBatchQueryPerformance, useCombinedQueries, useConditionalBatchQueries, useDashboardQueries, useDependentBatchQueries, useDynamicBatchQueries, useEnhancedQueries, useEnhancedSuspenseQueries, usePaginatedBatchQueries, useRetryBatchQueries } from "./batchQueries.js";
2
+ export { useConditionalFocusRefetch, useFocusCallback, useFocusRefetch, useFocusState, usePageVisibility, usePauseFocus, useSmartFocusManager } from "./useFocusManager.js";
3
+ export { createCursorPaginationOptions, createOffsetPaginationOptions, createPageNumberPaginationOptions, useEnhancedInfiniteQuery } from "./useInfiniteQuery.js";
4
+ export { cancelQueriesBatch, invalidateQueriesBatch, setQueryDataBatch, setupMutationDefaults, useBatchMutation, useConditionalOptimisticMutation, useListMutation, useMutation } from "./useMutation.js";
5
+ export { useBatchPrefetch, useConditionalPrefetch, useHoverPrefetch, useIdlePrefetch, useInViewPrefetch, usePeriodicPrefetch, usePredictivePrefetch, usePriorityPrefetch, useRoutePrefetch, useSmartPrefetch } from "./usePrefetch.js";
6
+ export { skipToken, useEnhancedQuery } from "./useQuery.js";
7
+ export { createSuspenseInfiniteQuery, createSuspenseQuery, useEnhancedSuspenseInfiniteQuery, useEnhancedSuspenseQuery } from "./useSuspenseQuery.js";
@@ -0,0 +1,41 @@
1
+ import type { QueryKey } from "@tanstack/react-query";
2
+ export interface UseFocusRefetchOptions {
3
+ enabled?: boolean;
4
+ minInterval?: number;
5
+ queryKeys?: QueryKey[];
6
+ }
7
+ export interface UsePauseFocusOptions {
8
+ autoPause?: boolean;
9
+ pauseWhen?: boolean;
10
+ }
11
+ export declare function useFocusState(): boolean;
12
+ export declare function useFocusRefetch(options?: UseFocusRefetchOptions): void;
13
+ export declare function usePauseFocus(options?: UsePauseFocusOptions): {
14
+ pause: () => void;
15
+ resume: () => void;
16
+ };
17
+ export declare function useSmartFocusManager(): {
18
+ pause: () => void;
19
+ resume: () => void;
20
+ getStats: () => {
21
+ isPaused: boolean;
22
+ pauseCount: number;
23
+ isFocused: boolean;
24
+ };
25
+ stats: {
26
+ isPaused: boolean;
27
+ pauseCount: number;
28
+ isFocused: boolean;
29
+ };
30
+ };
31
+ export declare function useConditionalFocusRefetch(queryKey: QueryKey, condition: () => boolean, options?: {
32
+ minInterval?: number;
33
+ enabled?: boolean;
34
+ }): void;
35
+ export declare function useFocusCallback(callback: () => void, options?: {
36
+ minInterval?: number;
37
+ enabled?: boolean;
38
+ queryKey?: QueryKey;
39
+ }): void;
40
+ export declare function usePageVisibility(): boolean;
41
+ //# sourceMappingURL=useFocusManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFocusManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useFocusManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAKtD,MAAM,WAAW,sBAAsB;IAAG,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;CAAE;AAC3G,MAAM,WAAW,oBAAoB;IAAG,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE;AAElF,wBAAgB,aAAa,IAAI,OAAO,CAOvC;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,QAkBnE;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB;;;EAW/D;AAED,wBAAgB,oBAAoB;;;;;;;;;;;;;EAMnC;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,EAAE,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,QAkBjJ;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAO,QAyBpI;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C"}
@@ -0,0 +1,109 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { focusManager, getSmartFocusManager, pauseFocusManager, resumeFocusManager } from "../core/focusManager.js";
4
+ export function useFocusState() {
5
+ const [focused, setFocused] = useState(focusManager.isFocused());
6
+ useEffect(() => {
7
+ const unsubscribe = focusManager.subscribe((isFocused) => { setFocused(isFocused); });
8
+ return unsubscribe;
9
+ }, []);
10
+ return focused;
11
+ }
12
+ export function useFocusRefetch(options = {}) {
13
+ const queryClient = useQueryClient();
14
+ const { enabled = true, minInterval = 5000, queryKeys = [] } = options;
15
+ const smartManager = getSmartFocusManager();
16
+ const queryKeysJson = JSON.stringify(queryKeys);
17
+ const stableQueryKeys = useMemo(() => queryKeys, [queryKeysJson]);
18
+ useEffect(() => {
19
+ if (!enabled || stableQueryKeys.length === 0)
20
+ return;
21
+ const unsubscribe = focusManager.subscribe((isFocused) => {
22
+ if (!isFocused)
23
+ return;
24
+ stableQueryKeys.forEach((queryKey) => {
25
+ if (smartManager.shouldRefetch(queryKey, minInterval)) {
26
+ queryClient.invalidateQueries({ queryKey });
27
+ }
28
+ });
29
+ });
30
+ return unsubscribe;
31
+ }, [queryClient, enabled, minInterval, stableQueryKeys, smartManager]);
32
+ }
33
+ export function usePauseFocus(options = {}) {
34
+ const { autoPause = false, pauseWhen = false } = options;
35
+ useEffect(() => {
36
+ if (autoPause || pauseWhen) {
37
+ pauseFocusManager();
38
+ return () => { resumeFocusManager(); };
39
+ }
40
+ }, [autoPause, pauseWhen]);
41
+ const pause = useCallback(() => { pauseFocusManager(); }, []);
42
+ const resume = useCallback(() => { resumeFocusManager(); }, []);
43
+ return { pause, resume };
44
+ }
45
+ export function useSmartFocusManager() {
46
+ const manager = getSmartFocusManager();
47
+ const pause = useCallback(() => { manager.pause(); }, [manager]);
48
+ const resume = useCallback(() => { manager.resume(); }, [manager]);
49
+ const getStats = useCallback(() => { return manager.getStats(); }, [manager]);
50
+ return { pause, resume, getStats, stats: manager.getStats() };
51
+ }
52
+ export function useConditionalFocusRefetch(queryKey, condition, options = {}) {
53
+ const queryClient = useQueryClient();
54
+ const { minInterval = 5000, enabled = true } = options;
55
+ const smartManager = getSmartFocusManager();
56
+ const queryKeyJson = JSON.stringify(queryKey);
57
+ const stableQueryKey = useMemo(() => queryKey, [queryKeyJson]);
58
+ const conditionRef = useRef(condition);
59
+ useEffect(() => { conditionRef.current = condition; }, [condition]);
60
+ useEffect(() => {
61
+ if (!enabled)
62
+ return;
63
+ const unsubscribe = focusManager.subscribe((isFocused) => {
64
+ if (!isFocused || !conditionRef.current())
65
+ return;
66
+ if (smartManager.shouldRefetch(stableQueryKey, minInterval)) {
67
+ queryClient.invalidateQueries({ queryKey: stableQueryKey });
68
+ }
69
+ });
70
+ return unsubscribe;
71
+ }, [queryClient, stableQueryKey, minInterval, enabled, smartManager]);
72
+ }
73
+ export function useFocusCallback(callback, options = {}) {
74
+ const { minInterval = 0, enabled = true, queryKey } = options;
75
+ const lastCallTime = useRef(0);
76
+ const smartManager = getSmartFocusManager();
77
+ const queryKeyJson = JSON.stringify(queryKey);
78
+ const stableQueryKey = useMemo(() => queryKey, [queryKeyJson]);
79
+ const callbackRef = useRef(callback);
80
+ useEffect(() => { callbackRef.current = callback; }, [callback]);
81
+ useEffect(() => {
82
+ if (!enabled)
83
+ return;
84
+ const unsubscribe = focusManager.subscribe((isFocused) => {
85
+ if (!isFocused)
86
+ return;
87
+ if (stableQueryKey !== undefined) {
88
+ if (smartManager.shouldRefetch(stableQueryKey, minInterval)) {
89
+ callbackRef.current();
90
+ }
91
+ return;
92
+ }
93
+ const now = Date.now();
94
+ if (minInterval > 0 && now - lastCallTime.current < minInterval)
95
+ return;
96
+ lastCallTime.current = now;
97
+ callbackRef.current();
98
+ });
99
+ return unsubscribe;
100
+ }, [minInterval, enabled, stableQueryKey, smartManager]);
101
+ }
102
+ export function usePageVisibility() {
103
+ const [isVisible, setIsVisible] = useState(typeof document !== "undefined" ? !document.hidden : true);
104
+ useEffect(() => {
105
+ const unsubscribe = focusManager.subscribe((isFocused) => { setIsVisible(isFocused); });
106
+ return unsubscribe;
107
+ }, []);
108
+ return isVisible;
109
+ }
@@ -0,0 +1,58 @@
1
+ import type { QueryFunction, QueryKey, UseInfiniteQueryOptions, UseInfiniteQueryResult } from "@tanstack/react-query";
2
+ import type { CursorPaginatedResponse, OffsetPaginatedResponse, PageNumberPaginatedResponse } from "../types/infinite";
3
+ export declare function useEnhancedInfiniteQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(options: UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>): UseInfiniteQueryResult<TData, TError>;
4
+ export declare function createInfiniteQueryOptions<TQueryFnData = unknown, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(config: {
5
+ queryKey: TQueryKey;
6
+ queryFn: QueryFunction<TQueryFnData, TQueryKey, TPageParam>;
7
+ initialPageParam: TPageParam;
8
+ getNextPageParam: (lastPage: TQueryFnData, allPages: TQueryFnData[], lastPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null;
9
+ getPreviousPageParam?: (firstPage: TQueryFnData, allPages: TQueryFnData[], firstPageParam: TPageParam, allPageParams: TPageParam[]) => TPageParam | undefined | null;
10
+ staleTime?: number;
11
+ gcTime?: number;
12
+ }): import("@tanstack/query-core").OmitKeyof<UseInfiniteQueryOptions<TQueryFnData, Error, import("@tanstack/query-core").InfiniteData<TQueryFnData, unknown>, TQueryKey, TPageParam>, "queryFn"> & {
13
+ queryFn?: QueryFunction<TQueryFnData, TQueryKey, TPageParam> | undefined;
14
+ } & {
15
+ queryKey: import("@tanstack/query-core").DataTag<TQueryKey, import("@tanstack/query-core").InfiniteData<TQueryFnData, unknown>, Error>;
16
+ };
17
+ export declare function createCursorPaginationOptions<T>(config: {
18
+ queryKey: QueryKey;
19
+ queryFn: (cursor: string | null) => Promise<CursorPaginatedResponse<T>>;
20
+ initialCursor?: string | null;
21
+ staleTime?: number;
22
+ gcTime?: number;
23
+ }): import("@tanstack/query-core").OmitKeyof<UseInfiniteQueryOptions<CursorPaginatedResponse<T>, Error, import("@tanstack/query-core").InfiniteData<CursorPaginatedResponse<T>, unknown>, readonly unknown[], string | null>, "queryFn"> & {
24
+ queryFn?: QueryFunction<CursorPaginatedResponse<T>, readonly unknown[], string | null> | undefined;
25
+ } & {
26
+ queryKey: readonly unknown[] & {
27
+ [dataTagSymbol]: import("@tanstack/query-core").InfiniteData<CursorPaginatedResponse<T>, unknown>;
28
+ [dataTagErrorSymbol]: Error;
29
+ };
30
+ };
31
+ export declare function createOffsetPaginationOptions<T>(config: {
32
+ queryKey: QueryKey;
33
+ queryFn: (offset: number, limit: number) => Promise<OffsetPaginatedResponse<T>>;
34
+ limit?: number;
35
+ staleTime?: number;
36
+ gcTime?: number;
37
+ }): import("@tanstack/query-core").OmitKeyof<UseInfiniteQueryOptions<OffsetPaginatedResponse<T>, Error, import("@tanstack/query-core").InfiniteData<OffsetPaginatedResponse<T>, unknown>, unknown[], number>, "queryFn"> & {
38
+ queryFn?: QueryFunction<OffsetPaginatedResponse<T>, unknown[], number> | undefined;
39
+ } & {
40
+ queryKey: unknown[] & {
41
+ [dataTagSymbol]: import("@tanstack/query-core").InfiniteData<OffsetPaginatedResponse<T>, unknown>;
42
+ [dataTagErrorSymbol]: Error;
43
+ };
44
+ };
45
+ export declare function createPageNumberPaginationOptions<T>(config: {
46
+ queryKey: QueryKey;
47
+ queryFn: (page: number) => Promise<PageNumberPaginatedResponse<T>>;
48
+ staleTime?: number;
49
+ gcTime?: number;
50
+ }): import("@tanstack/query-core").OmitKeyof<UseInfiniteQueryOptions<PageNumberPaginatedResponse<T>, Error, import("@tanstack/query-core").InfiniteData<PageNumberPaginatedResponse<T>, unknown>, readonly unknown[], number>, "queryFn"> & {
51
+ queryFn?: QueryFunction<PageNumberPaginatedResponse<T>, readonly unknown[], number> | undefined;
52
+ } & {
53
+ queryKey: readonly unknown[] & {
54
+ [dataTagSymbol]: import("@tanstack/query-core").InfiniteData<PageNumberPaginatedResponse<T>, unknown>;
55
+ [dataTagErrorSymbol]: Error;
56
+ };
57
+ };
58
+ //# sourceMappingURL=useInfiniteQuery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInfiniteQuery.d.ts","sourceRoot":"","sources":["../../src/hooks/useInfiniteQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACtH,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAEvH,wBAAgB,wBAAwB,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG,YAAY,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,OAAO,EAAE,OAAO,EAAE,uBAAuB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAE/R;AACD,wBAAgB,0BAA0B,CAAC,YAAY,GAAG,OAAO,EAAE,SAAS,SAAS,QAAQ,GAAG,QAAQ,EAAE,UAAU,GAAG,OAAO,EAAE,MAAM,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,aAAa,CAAC,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAAC,gBAAgB,EAAE,UAAU,CAAC;IAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IAAC,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;;;;EAEnmB;AACD,wBAAgB,6BAA6B,CAAC,CAAC,EAAE,MAAM,EAAE;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;EAU3N;AACD,wBAAgB,6BAA6B,CAAC,CAAC,EAAE,MAAM,EAAE;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;EAmBpN;AACD,wBAAgB,iCAAiC,CAAC,CAAC,EAAE,MAAM,EAAE;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;EAiB3L"}
@@ -0,0 +1,61 @@
1
+ import { infiniteQueryOptions, useInfiniteQuery } from "@tanstack/react-query";
2
+ export function useEnhancedInfiniteQuery(options) {
3
+ return useInfiniteQuery(options);
4
+ }
5
+ export function createInfiniteQueryOptions(config) {
6
+ return infiniteQueryOptions(config);
7
+ }
8
+ export function createCursorPaginationOptions(config) {
9
+ return createInfiniteQueryOptions({
10
+ queryKey: config.queryKey,
11
+ queryFn: ({ pageParam }) => config.queryFn(pageParam),
12
+ initialPageParam: config.initialCursor ?? null,
13
+ getNextPageParam: (lastPage) => lastPage.cursor ?? null,
14
+ getPreviousPageParam: () => null,
15
+ staleTime: config.staleTime,
16
+ gcTime: config.gcTime
17
+ });
18
+ }
19
+ export function createOffsetPaginationOptions(config) {
20
+ const limit = config.limit ?? 20;
21
+ return createInfiniteQueryOptions({
22
+ queryKey: [...config.queryKey, limit],
23
+ queryFn: ({ pageParam }) => config.queryFn(pageParam, limit),
24
+ initialPageParam: 0,
25
+ getNextPageParam: (lastPage, allPages) => {
26
+ if (lastPage.hasMore === false)
27
+ return undefined;
28
+ const currentOffset = allPages.length * limit;
29
+ if (currentOffset >= lastPage.total)
30
+ return undefined;
31
+ return currentOffset;
32
+ },
33
+ getPreviousPageParam: (_firstPage, allPages) => {
34
+ if (allPages.length <= 1)
35
+ return undefined;
36
+ return (allPages.length - 2) * limit;
37
+ },
38
+ staleTime: config.staleTime,
39
+ gcTime: config.gcTime
40
+ });
41
+ }
42
+ export function createPageNumberPaginationOptions(config) {
43
+ return createInfiniteQueryOptions({
44
+ queryKey: config.queryKey,
45
+ queryFn: ({ pageParam }) => config.queryFn(pageParam),
46
+ initialPageParam: 1,
47
+ getNextPageParam: (lastPage, allPages) => {
48
+ const nextPage = allPages.length + 1;
49
+ if (nextPage > lastPage.totalPages)
50
+ return undefined;
51
+ return nextPage;
52
+ },
53
+ getPreviousPageParam: (_firstPage, allPages) => {
54
+ if (allPages.length <= 1)
55
+ return undefined;
56
+ return allPages.length - 1;
57
+ },
58
+ staleTime: config.staleTime,
59
+ gcTime: config.gcTime
60
+ });
61
+ }
@@ -0,0 +1,34 @@
1
+ import type { MutationFunction, MutationKey, QueryClient, QueryKey, UseMutationOptions as TanStackUseMutationOptions, UseMutationResult } from "@tanstack/react-query";
2
+ import type { MutationContext, MutationOptions } from "../types";
3
+ import type { EntityWithId } from "../types/selectors";
4
+ export type { MutationKey };
5
+ export interface MutationDefaultsConfig {
6
+ [key: string]: TanStackUseMutationOptions<any, any, any, any>;
7
+ }
8
+ export declare function useMutation<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(options: MutationOptions<TData, TError, TVariables, TContext>): UseMutationResult<TData, TError, TVariables, TContext>;
9
+ export declare function setupMutationDefaults(queryClient: QueryClient, config: MutationDefaultsConfig): void;
10
+ export declare function useListMutation<T extends EntityWithId>(mutationFn: MutationFunction<T, {
11
+ operation: string;
12
+ data: Partial<T>;
13
+ }>, queryKey: QueryKey, options?: TanStackUseMutationOptions<T, Error, {
14
+ operation: string;
15
+ data: Partial<T>;
16
+ }> & {
17
+ mutationKey?: readonly unknown[];
18
+ }): UseMutationResult<T, Error, {
19
+ operation: string;
20
+ data: Partial<T>;
21
+ }, unknown>;
22
+ export declare function useBatchMutation<TData = unknown, TError = Error, TVariables = unknown[]>(mutationFn: MutationFunction<TData[], TVariables>, options?: TanStackUseMutationOptions<TData[], TError, TVariables> & {
23
+ mutationKey?: readonly unknown[];
24
+ }): UseMutationResult<TData[], TError, TVariables, unknown>;
25
+ export declare function useConditionalOptimisticMutation<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(mutationFn: MutationFunction<TData, TVariables>, condition: (variables: TVariables) => boolean, options?: Omit<MutationOptions<TData, TError, TVariables, TContext>, "mutationFn"> & {
26
+ mutationKey?: readonly unknown[];
27
+ }): UseMutationResult<TData, TError, TVariables, MutationContext<unknown, TContext>>;
28
+ export declare function cancelQueriesBatch(queryClient: QueryClient, queryKeys: Array<Parameters<QueryClient["cancelQueries"]>[0]>): Promise<void>;
29
+ export declare function setQueryDataBatch(queryClient: QueryClient, updates: Array<{
30
+ queryKey: Parameters<QueryClient["setQueryData"]>[0];
31
+ updater: Parameters<QueryClient["setQueryData"]>[1];
32
+ }>): void;
33
+ export declare function invalidateQueriesBatch(queryClient: QueryClient, queryKeys: Array<Parameters<QueryClient["invalidateQueries"]>[0]>): Promise<void>;
34
+ //# sourceMappingURL=useMutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMutation.d.ts","sourceRoot":"","sources":["../../src/hooks/useMutation.ts"],"names":[],"mappings":"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"}