@umituz/react-native-tanstack 1.2.17 → 1.2.19

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.
@@ -0,0 +1,237 @@
1
+ /**
2
+ * usePrefetch Hook
3
+ * Presentation layer - Query prefetching utilities
4
+ *
5
+ * General-purpose prefetching for any React Native app
6
+ */
7
+
8
+ import { useQueryClient } from '@tanstack/react-query';
9
+ import { useCallback, useEffect, useRef } from 'react';
10
+ import type { QueryKey, QueryFunction } from '@tanstack/react-query';
11
+
12
+ export interface PrefetchOptions<TData> {
13
+ /**
14
+ * Time in ms that the prefetched data should stay fresh
15
+ */
16
+ staleTime?: number;
17
+
18
+ /**
19
+ * Time in ms that unused data stays in cache
20
+ */
21
+ gcTime?: number;
22
+ }
23
+
24
+ /**
25
+ * Hook for prefetching query data
26
+ *
27
+ * Useful for:
28
+ * - Preloading data before navigation
29
+ * - Warming up cache on mount
30
+ * - Background data refresh
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * function UserProfileList({ userIds }: { userIds: string[] }) {
35
+ * const prefetchUser = usePrefetchQuery(['user'], async (id) => fetchUser(id));
36
+ *
37
+ * return (
38
+ * <FlatList
39
+ * data={userIds}
40
+ * onViewableItemsChanged={({ viewableItems }) => {
41
+ * viewableItems.forEach((item) => {
42
+ * prefetchUser(item.key);
43
+ * });
44
+ * }}
45
+ * />
46
+ * );
47
+ * }
48
+ * ```
49
+ */
50
+ export function usePrefetchQuery<
51
+ TQueryFnData = unknown,
52
+ TVariables = string | number,
53
+ >(
54
+ queryKey: QueryKey,
55
+ queryFn: (variables: TVariables) => Promise<TQueryFnData>,
56
+ options: PrefetchOptions<TQueryFnData> = {},
57
+ ) {
58
+ const queryClient = useQueryClient();
59
+ const prefetchingRef = new Set<TVariables>();
60
+
61
+ const prefetch = useCallback(
62
+ async (variables: TVariables) => {
63
+ if (prefetchingRef.has(variables)) {
64
+ return;
65
+ }
66
+
67
+ prefetchingRef.add(variables);
68
+
69
+ try {
70
+ await queryClient.prefetchQuery({
71
+ queryKey: [...queryKey, variables],
72
+ queryFn: () => queryFn(variables),
73
+ staleTime: options.staleTime,
74
+ gcTime: options.gcTime,
75
+ });
76
+
77
+ if (__DEV__) {
78
+ // eslint-disable-next-line no-console
79
+ console.log('[TanStack Query] Prefetched:', [...queryKey, variables]);
80
+ }
81
+ } finally {
82
+ prefetchingRef.delete(variables);
83
+ }
84
+ },
85
+ [queryClient, queryKey, queryFn, options.staleTime, options.gcTime],
86
+ );
87
+
88
+ return prefetch;
89
+ }
90
+
91
+ /**
92
+ * Hook for prefetching infinite query data
93
+ *
94
+ * Useful for:
95
+ * - Preloading infinite scroll content
96
+ * - Warming up paginated feeds
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * function FeedScreen() {
101
+ * const prefetchFeed = usePrefetchInfiniteQuery(
102
+ * ['feed'],
103
+ * ({ pageParam }) => fetchFeed({ cursor: pageParam })
104
+ * );
105
+ *
106
+ * useEffect(() => {
107
+ * prefetchFeed();
108
+ * }, []);
109
+ * }
110
+ * ```
111
+ */
112
+ export function usePrefetchInfiniteQuery<
113
+ TQueryFnData = unknown,
114
+ TPageParam = unknown,
115
+ >(
116
+ queryKey: QueryKey,
117
+ queryFn: QueryFunction<TQueryFnData, QueryKey, TPageParam>,
118
+ options: PrefetchOptions<TQueryFnData> = {},
119
+ ) {
120
+ const queryClient = useQueryClient();
121
+ const hasPrefetchedRef = useRef(false);
122
+
123
+ const prefetch = useCallback(async () => {
124
+ if (hasPrefetchedRef.current) {
125
+ return;
126
+ }
127
+
128
+ hasPrefetchedRef.current = true;
129
+
130
+ try {
131
+ await queryClient.prefetchInfiniteQuery({
132
+ queryKey,
133
+ queryFn,
134
+ staleTime: options.staleTime,
135
+ gcTime: options.gcTime,
136
+ initialPageParam: undefined as unknown as TPageParam,
137
+ });
138
+
139
+ if (__DEV__) {
140
+ // eslint-disable-next-line no-console
141
+ console.log('[TanStack Query] Prefetched infinite:', queryKey);
142
+ }
143
+ } catch {
144
+ hasPrefetchedRef.current = false;
145
+ }
146
+ }, [queryClient, queryKey, queryFn, options.staleTime, options.gcTime]);
147
+
148
+ return prefetch;
149
+ }
150
+
151
+ /**
152
+ * Hook for prefetching on mount
153
+ *
154
+ * Convenience hook that prefetches data when component mounts
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * function UserProfile({ userId }: { userId: string }) {
159
+ * usePrefetchOnMount(
160
+ * ['user', userId],
161
+ * () => fetchUser(userId),
162
+ * { staleTime: TIME_MS.MINUTE }
163
+ * );
164
+ *
165
+ * // Component will prefetch user data on mount
166
+ * }
167
+ * ```
168
+ */
169
+ export function usePrefetchOnMount<TData = unknown>(
170
+ queryKey: QueryKey,
171
+ queryFn: () => Promise<TData>,
172
+ options: PrefetchOptions<TData> = {},
173
+ ) {
174
+ const queryClient = useQueryClient();
175
+
176
+ useEffect(() => {
177
+ queryClient.prefetchQuery({
178
+ queryKey,
179
+ queryFn,
180
+ staleTime: options.staleTime,
181
+ gcTime: options.gcTime,
182
+ });
183
+
184
+ if (__DEV__) {
185
+ // eslint-disable-next-line no-console
186
+ console.log('[TanStack Query] Prefetched on mount:', queryKey);
187
+ }
188
+ }, [queryClient, queryKey, queryFn, options.staleTime, options.gcTime]);
189
+ }
190
+
191
+ /**
192
+ * Hook for prefetching multiple queries
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * function Dashboard() {
197
+ * const prefetchMultiple = usePrefetchMultiple();
198
+ *
199
+ * useEffect(() => {
200
+ * prefetchMultiple([
201
+ * { queryKey: ['user'], queryFn: fetchUser },
202
+ * { queryKey: ['posts'], queryFn: fetchPosts },
203
+ * { queryKey: ['notifications'], queryFn: fetchNotifications },
204
+ * ]);
205
+ * }, []);
206
+ * }
207
+ * ```
208
+ */
209
+ export function usePrefetchMultiple<TData = unknown>() {
210
+ const queryClient = useQueryClient();
211
+
212
+ return useCallback(
213
+ async (queries: Array<{
214
+ queryKey: QueryKey;
215
+ queryFn: () => Promise<TData>;
216
+ staleTime?: number;
217
+ gcTime?: number;
218
+ }>) => {
219
+ await Promise.all(
220
+ queries.map(({ queryKey, queryFn, staleTime, gcTime }) =>
221
+ queryClient.prefetchQuery({
222
+ queryKey,
223
+ queryFn,
224
+ staleTime,
225
+ gcTime,
226
+ }),
227
+ ),
228
+ );
229
+
230
+ if (__DEV__) {
231
+ // eslint-disable-next-line no-console
232
+ console.log('[TanStack Query] Prefetched multiple:', queries.length);
233
+ }
234
+ },
235
+ [queryClient],
236
+ );
237
+ }