@usels/integrations 0.0.1-beta.3

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 ADDED
@@ -0,0 +1,18 @@
1
+ # @usels/integrations
2
+
3
+
4
+ ## Overview
5
+
6
+ ## Peer Dependencies
7
+
8
+ This package requires the following peer dependencies:
9
+
10
+ - `@legendapp/state`: ^2.0.0 (optional)
11
+ - `react`: ^18.0.0 || ^19.0.0 (optional)
12
+ - `react-dom`: ^18.0.0 || ^19.0.0 (optional)
13
+
14
+ The peer dependencies are marked as optional because you may use this package in different contexts (React components, vanilla JS, Node.js, etc.).
15
+
16
+ ## License
17
+
18
+ MIT
@@ -0,0 +1,310 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { QueryClient, QueryKey, MutationKey, QueryFunctionContext, InfiniteData } from '@tanstack/query-core';
4
+ export { QueryClient } from '@tanstack/query-core';
5
+ import { QueryClient as QueryClient$1 } from '@tanstack/react-query';
6
+ import { Observable } from '@legendapp/state';
7
+ import { MaybeObservable } from '@usels/core';
8
+
9
+ interface QueryClientProviderProps {
10
+ client: QueryClient;
11
+ children: ReactNode;
12
+ }
13
+ /**
14
+ * Provider component that makes QueryClient available to hooks
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * import { QueryClient } from '@tanstack/react-query'
19
+ * import { QueryClientProvider } from '@usels/integrations'
20
+ *
21
+ * const queryClient = new QueryClient()
22
+ *
23
+ * function App() {
24
+ * return (
25
+ * <QueryClientProvider client={queryClient}>
26
+ * <YourApp />
27
+ * </QueryClientProvider>
28
+ * )
29
+ * }
30
+ * ```
31
+ */
32
+ declare function QueryClientProvider({ client, children, }: QueryClientProviderProps): react_jsx_runtime.JSX.Element;
33
+
34
+ /**
35
+ * Hook to retrieve the QueryClient from context
36
+ *
37
+ * @throws Error if used outside of QueryClientProvider
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * import { useQueryClient } from '@usels/integrations'
42
+ *
43
+ * function MyComponent() {
44
+ * const queryClient = useQueryClient()
45
+ * // Use queryClient...
46
+ * }
47
+ * ```
48
+ */
49
+ declare function useQueryClient(): QueryClient$1;
50
+
51
+ interface UseQueryOptions<TData = unknown> {
52
+ queryKey: QueryKey;
53
+ queryFn: () => Promise<TData>;
54
+ enabled?: MaybeObservable<boolean>;
55
+ staleTime?: MaybeObservable<number>;
56
+ gcTime?: MaybeObservable<number>;
57
+ retry?: MaybeObservable<number | boolean>;
58
+ refetchOnWindowFocus?: MaybeObservable<boolean>;
59
+ refetchOnMount?: MaybeObservable<boolean>;
60
+ refetchOnReconnect?: MaybeObservable<boolean>;
61
+ /**
62
+ * Set this to `true` to throw errors to the nearest error boundary.
63
+ * Set to a function to control which errors should be thrown.
64
+ */
65
+ throwOnError?: boolean | ((error: Error) => boolean);
66
+ /**
67
+ * Set this to `true` to enable React Suspense mode.
68
+ * The hook will throw a promise while fetching, suspending the component.
69
+ *
70
+ * Note: Requires a React Suspense boundary in the component tree.
71
+ * The query state is still available as an observable when not suspended.
72
+ */
73
+ suspense?: boolean;
74
+ }
75
+ interface QueryState<TData = unknown> {
76
+ data: TData | undefined;
77
+ error: Error | null;
78
+ status: "pending" | "error" | "success";
79
+ fetchStatus: "fetching" | "paused" | "idle";
80
+ isPending: boolean;
81
+ isSuccess: boolean;
82
+ isError: boolean;
83
+ isLoadingError: boolean;
84
+ isRefetchError: boolean;
85
+ isFetching: boolean;
86
+ isPaused: boolean;
87
+ isRefetching: boolean;
88
+ isLoading: boolean;
89
+ /**
90
+ * @deprecated Use `isLoading` instead. Will be removed in TanStack Query v6.
91
+ */
92
+ isInitialLoading: boolean;
93
+ isStale: boolean;
94
+ isPlaceholderData: boolean;
95
+ isFetched: boolean;
96
+ isFetchedAfterMount: boolean;
97
+ isEnabled: boolean;
98
+ dataUpdatedAt: number;
99
+ errorUpdatedAt: number;
100
+ failureCount: number;
101
+ failureReason: Error | null;
102
+ errorUpdateCount: number;
103
+ refetch: () => void;
104
+ }
105
+ /**
106
+ * TanStack Query와 Legend-App-State를 연결하는 커스텀 훅
107
+ * QueryObserver를 사용하여 쿼리 상태를 observable로 관리합니다.
108
+ *
109
+ * Observable 값을 파라미터로 받을 수 있으며, 변경 시 자동으로 refetch됩니다.
110
+ *
111
+ * @example
112
+ * ```tsx
113
+ * import { QueryClient } from '@tanstack/react-query'
114
+ * import { QueryClientProvider, useQuery } from '@usels/integrations'
115
+ *
116
+ * // QueryClient를 생성하고 Provider로 제공
117
+ * const queryClient = new QueryClient()
118
+ *
119
+ * function App() {
120
+ * return (
121
+ * <QueryClientProvider client={queryClient}>
122
+ * <YourApp />
123
+ * </QueryClientProvider>
124
+ * )
125
+ * }
126
+ *
127
+ * // 컴포넌트에서 사용
128
+ * function YourComponent() {
129
+ * // 일반 값
130
+ * const products$ = useQuery({
131
+ * queryKey: ['products'],
132
+ * queryFn: () => fetch('/api/products').then(r => r.json())
133
+ * })
134
+ *
135
+ * // Observable 값 (자동 반응)
136
+ * const filter$ = useObservable({ category: 'electronics' })
137
+ * const filteredProducts$ = useQuery({
138
+ * queryKey: ['products', filter$],
139
+ * queryFn: () => fetch(`/api/products?category=${filter$.category.get()}`).then(r => r.json())
140
+ * })
141
+ * // filter$가 변경되면 자동으로 refetch!
142
+ *
143
+ *
144
+ * // 렌더링
145
+ * return (
146
+ * <Show if={() => products$.isSuccess.get()}>
147
+ * {() => (
148
+ * <For each={() => products$.data.get()}>
149
+ * {(product$) => <ProductCard $product={product$} />}
150
+ * </For>
151
+ * )}
152
+ * </Show>
153
+ * )
154
+ * }
155
+ * ```
156
+ */
157
+ declare function useQuery<TData = unknown>(options: MaybeObservable<UseQueryOptions<TData>>): Observable<QueryState<TData>>;
158
+
159
+ interface UseMutationOptions<TData = unknown, TVariables = void, TContext = unknown> {
160
+ mutationKey?: MutationKey;
161
+ mutationFn: (variables: TVariables) => Promise<TData>;
162
+ onMutate?: (variables: TVariables) => TContext | Promise<TContext>;
163
+ onSuccess?: (data: TData, variables: TVariables, context: TContext | undefined) => void | Promise<void>;
164
+ onError?: (error: Error, variables: TVariables, context: TContext | undefined) => void | Promise<void>;
165
+ onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables, context: TContext | undefined) => void | Promise<void>;
166
+ }
167
+ interface MutationState<TData = unknown, TVariables = void, TContext = unknown> {
168
+ data: TData | undefined;
169
+ error: Error | null;
170
+ status: "idle" | "pending" | "error" | "success";
171
+ isIdle: boolean;
172
+ isPending: boolean;
173
+ isPaused: boolean;
174
+ isSuccess: boolean;
175
+ isError: boolean;
176
+ failureCount: number;
177
+ failureReason: Error | null;
178
+ submittedAt: number;
179
+ variables: TVariables | undefined;
180
+ context: TContext | undefined;
181
+ mutate: (variables: TVariables) => void;
182
+ mutateAsync: (variables: TVariables) => Promise<TData>;
183
+ reset: () => void;
184
+ }
185
+ /**
186
+ * TanStack Query Mutation과 Legend-App-State를 연결하는 커스텀 훅
187
+ * MutationObserver를 사용하여 뮤테이션 상태를 observable로 관리합니다.
188
+ *
189
+ * @example
190
+ * ```tsx
191
+ * import { QueryClient } from '@tanstack/react-query'
192
+ * import { QueryClientProvider, useMutation } from '@usels/integrations'
193
+ *
194
+ * // QueryClient를 생성하고 Provider로 제공
195
+ * const queryClient = new QueryClient()
196
+ *
197
+ * function App() {
198
+ * return (
199
+ * <QueryClientProvider client={queryClient}>
200
+ * <YourApp />
201
+ * </QueryClientProvider>
202
+ * )
203
+ * }
204
+ *
205
+ * // 컴포넌트에서 사용
206
+ * function YourComponent() {
207
+ * const createProduct$ = useMutation({
208
+ * mutationFn: (product: NewProduct) =>
209
+ * fetch('/api/products', {
210
+ * method: 'POST',
211
+ * body: JSON.stringify(product)
212
+ * }).then(r => r.json()),
213
+ * onSuccess: () => {
214
+ * alert('Product created!')
215
+ * }
216
+ * })
217
+ *
218
+ * const handleSubmit = (product: NewProduct) => {
219
+ * createProduct$.mutate(product)
220
+ * }
221
+ * }
222
+ * ```
223
+ */
224
+ declare function useMutation<TData = unknown, TVariables = void, TContext = unknown>(options: UseMutationOptions<TData, TVariables, TContext>): Observable<MutationState<TData, TVariables, TContext>>;
225
+
226
+ interface UseInfiniteQueryOptions<TQueryFnData = unknown, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown> {
227
+ queryKey: TQueryKey;
228
+ queryFn: (context: QueryFunctionContext<TQueryKey, TPageParam>) => Promise<TQueryFnData>;
229
+ initialPageParam: TPageParam;
230
+ getNextPageParam: (lastPage: TQueryFnData, allPages: Array<TQueryFnData>, lastPageParam: TPageParam, allPageParams: Array<TPageParam>) => TPageParam | undefined | null;
231
+ getPreviousPageParam?: (firstPage: TQueryFnData, allPages: Array<TQueryFnData>, firstPageParam: TPageParam, allPageParams: Array<TPageParam>) => TPageParam | undefined | null;
232
+ enabled?: MaybeObservable<boolean>;
233
+ staleTime?: MaybeObservable<number>;
234
+ gcTime?: MaybeObservable<number>;
235
+ retry?: MaybeObservable<number | boolean>;
236
+ refetchOnWindowFocus?: MaybeObservable<boolean>;
237
+ refetchOnMount?: MaybeObservable<boolean>;
238
+ refetchOnReconnect?: MaybeObservable<boolean>;
239
+ maxPages?: number;
240
+ }
241
+ interface InfiniteQueryState<TData = unknown> {
242
+ data: TData | undefined;
243
+ error: Error | null;
244
+ status: "pending" | "error" | "success";
245
+ fetchStatus: "fetching" | "paused" | "idle";
246
+ isPending: boolean;
247
+ isSuccess: boolean;
248
+ isError: boolean;
249
+ isLoadingError: boolean;
250
+ isRefetchError: boolean;
251
+ isFetching: boolean;
252
+ isPaused: boolean;
253
+ isRefetching: boolean;
254
+ isLoading: boolean;
255
+ isStale: boolean;
256
+ isPlaceholderData: boolean;
257
+ isFetched: boolean;
258
+ isFetchedAfterMount: boolean;
259
+ dataUpdatedAt: number;
260
+ errorUpdatedAt: number;
261
+ failureCount: number;
262
+ failureReason: Error | null;
263
+ errorUpdateCount: number;
264
+ isEnabled: boolean;
265
+ /**
266
+ * @deprecated Use isLoading instead. Will be removed in TanStack Query v6.
267
+ */
268
+ isInitialLoading: boolean;
269
+ hasNextPage: boolean;
270
+ hasPreviousPage: boolean;
271
+ isFetchingNextPage: boolean;
272
+ isFetchingPreviousPage: boolean;
273
+ isFetchNextPageError: boolean;
274
+ isFetchPreviousPageError: boolean;
275
+ refetch: () => void;
276
+ fetchNextPage: () => void;
277
+ fetchPreviousPage: () => void;
278
+ }
279
+ /**
280
+ * TanStack Query Infinite Query와 Legend-App-State를 연결하는 커스텀 훅
281
+ * InfiniteQueryObserver를 사용하여 쿼리 상태를 observable로 관리합니다.
282
+ *
283
+ * Observable 값을 파라미터로 받을 수 있으며, 변경 시 자동으로 refetch됩니다.
284
+ *
285
+ * @example
286
+ * ```tsx
287
+ * // Cursor-based pagination
288
+ * const items$ = useInfiniteQuery({
289
+ * queryKey: ['items'],
290
+ * queryFn: ({ pageParam }) =>
291
+ * fetch(`/api/items?cursor=${pageParam}`).then(r => r.json()),
292
+ * initialPageParam: undefined,
293
+ * getNextPageParam: (lastPage) => lastPage.nextCursor,
294
+ * })
295
+ *
296
+ * // Observable reactivity
297
+ * const filter$ = useObservable({ category: 'electronics' })
298
+ * const items$ = useInfiniteQuery({
299
+ * queryKey: ['items', filter$],
300
+ * queryFn: ({ pageParam }) =>
301
+ * fetch(`/api/items?category=${filter$.category.get()}&cursor=${pageParam}`)
302
+ * .then(r => r.json()),
303
+ * initialPageParam: undefined,
304
+ * getNextPageParam: (lastPage) => lastPage.nextCursor,
305
+ * })
306
+ * ```
307
+ */
308
+ declare function useInfiniteQuery<TQueryFnData = unknown, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(options: MaybeObservable<UseInfiniteQueryOptions<TQueryFnData, TQueryKey, TPageParam>>): Observable<InfiniteQueryState<InfiniteData<TQueryFnData>>>;
309
+
310
+ export { type InfiniteQueryState, type MutationState, QueryClientProvider, type QueryState, type UseInfiniteQueryOptions, type UseMutationOptions, type UseQueryOptions, useInfiniteQuery, useMutation, useQuery, useQueryClient };
@@ -0,0 +1,310 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { QueryClient, QueryKey, MutationKey, QueryFunctionContext, InfiniteData } from '@tanstack/query-core';
4
+ export { QueryClient } from '@tanstack/query-core';
5
+ import { QueryClient as QueryClient$1 } from '@tanstack/react-query';
6
+ import { Observable } from '@legendapp/state';
7
+ import { MaybeObservable } from '@usels/core';
8
+
9
+ interface QueryClientProviderProps {
10
+ client: QueryClient;
11
+ children: ReactNode;
12
+ }
13
+ /**
14
+ * Provider component that makes QueryClient available to hooks
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * import { QueryClient } from '@tanstack/react-query'
19
+ * import { QueryClientProvider } from '@usels/integrations'
20
+ *
21
+ * const queryClient = new QueryClient()
22
+ *
23
+ * function App() {
24
+ * return (
25
+ * <QueryClientProvider client={queryClient}>
26
+ * <YourApp />
27
+ * </QueryClientProvider>
28
+ * )
29
+ * }
30
+ * ```
31
+ */
32
+ declare function QueryClientProvider({ client, children, }: QueryClientProviderProps): react_jsx_runtime.JSX.Element;
33
+
34
+ /**
35
+ * Hook to retrieve the QueryClient from context
36
+ *
37
+ * @throws Error if used outside of QueryClientProvider
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * import { useQueryClient } from '@usels/integrations'
42
+ *
43
+ * function MyComponent() {
44
+ * const queryClient = useQueryClient()
45
+ * // Use queryClient...
46
+ * }
47
+ * ```
48
+ */
49
+ declare function useQueryClient(): QueryClient$1;
50
+
51
+ interface UseQueryOptions<TData = unknown> {
52
+ queryKey: QueryKey;
53
+ queryFn: () => Promise<TData>;
54
+ enabled?: MaybeObservable<boolean>;
55
+ staleTime?: MaybeObservable<number>;
56
+ gcTime?: MaybeObservable<number>;
57
+ retry?: MaybeObservable<number | boolean>;
58
+ refetchOnWindowFocus?: MaybeObservable<boolean>;
59
+ refetchOnMount?: MaybeObservable<boolean>;
60
+ refetchOnReconnect?: MaybeObservable<boolean>;
61
+ /**
62
+ * Set this to `true` to throw errors to the nearest error boundary.
63
+ * Set to a function to control which errors should be thrown.
64
+ */
65
+ throwOnError?: boolean | ((error: Error) => boolean);
66
+ /**
67
+ * Set this to `true` to enable React Suspense mode.
68
+ * The hook will throw a promise while fetching, suspending the component.
69
+ *
70
+ * Note: Requires a React Suspense boundary in the component tree.
71
+ * The query state is still available as an observable when not suspended.
72
+ */
73
+ suspense?: boolean;
74
+ }
75
+ interface QueryState<TData = unknown> {
76
+ data: TData | undefined;
77
+ error: Error | null;
78
+ status: "pending" | "error" | "success";
79
+ fetchStatus: "fetching" | "paused" | "idle";
80
+ isPending: boolean;
81
+ isSuccess: boolean;
82
+ isError: boolean;
83
+ isLoadingError: boolean;
84
+ isRefetchError: boolean;
85
+ isFetching: boolean;
86
+ isPaused: boolean;
87
+ isRefetching: boolean;
88
+ isLoading: boolean;
89
+ /**
90
+ * @deprecated Use `isLoading` instead. Will be removed in TanStack Query v6.
91
+ */
92
+ isInitialLoading: boolean;
93
+ isStale: boolean;
94
+ isPlaceholderData: boolean;
95
+ isFetched: boolean;
96
+ isFetchedAfterMount: boolean;
97
+ isEnabled: boolean;
98
+ dataUpdatedAt: number;
99
+ errorUpdatedAt: number;
100
+ failureCount: number;
101
+ failureReason: Error | null;
102
+ errorUpdateCount: number;
103
+ refetch: () => void;
104
+ }
105
+ /**
106
+ * TanStack Query와 Legend-App-State를 연결하는 커스텀 훅
107
+ * QueryObserver를 사용하여 쿼리 상태를 observable로 관리합니다.
108
+ *
109
+ * Observable 값을 파라미터로 받을 수 있으며, 변경 시 자동으로 refetch됩니다.
110
+ *
111
+ * @example
112
+ * ```tsx
113
+ * import { QueryClient } from '@tanstack/react-query'
114
+ * import { QueryClientProvider, useQuery } from '@usels/integrations'
115
+ *
116
+ * // QueryClient를 생성하고 Provider로 제공
117
+ * const queryClient = new QueryClient()
118
+ *
119
+ * function App() {
120
+ * return (
121
+ * <QueryClientProvider client={queryClient}>
122
+ * <YourApp />
123
+ * </QueryClientProvider>
124
+ * )
125
+ * }
126
+ *
127
+ * // 컴포넌트에서 사용
128
+ * function YourComponent() {
129
+ * // 일반 값
130
+ * const products$ = useQuery({
131
+ * queryKey: ['products'],
132
+ * queryFn: () => fetch('/api/products').then(r => r.json())
133
+ * })
134
+ *
135
+ * // Observable 값 (자동 반응)
136
+ * const filter$ = useObservable({ category: 'electronics' })
137
+ * const filteredProducts$ = useQuery({
138
+ * queryKey: ['products', filter$],
139
+ * queryFn: () => fetch(`/api/products?category=${filter$.category.get()}`).then(r => r.json())
140
+ * })
141
+ * // filter$가 변경되면 자동으로 refetch!
142
+ *
143
+ *
144
+ * // 렌더링
145
+ * return (
146
+ * <Show if={() => products$.isSuccess.get()}>
147
+ * {() => (
148
+ * <For each={() => products$.data.get()}>
149
+ * {(product$) => <ProductCard $product={product$} />}
150
+ * </For>
151
+ * )}
152
+ * </Show>
153
+ * )
154
+ * }
155
+ * ```
156
+ */
157
+ declare function useQuery<TData = unknown>(options: MaybeObservable<UseQueryOptions<TData>>): Observable<QueryState<TData>>;
158
+
159
+ interface UseMutationOptions<TData = unknown, TVariables = void, TContext = unknown> {
160
+ mutationKey?: MutationKey;
161
+ mutationFn: (variables: TVariables) => Promise<TData>;
162
+ onMutate?: (variables: TVariables) => TContext | Promise<TContext>;
163
+ onSuccess?: (data: TData, variables: TVariables, context: TContext | undefined) => void | Promise<void>;
164
+ onError?: (error: Error, variables: TVariables, context: TContext | undefined) => void | Promise<void>;
165
+ onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables, context: TContext | undefined) => void | Promise<void>;
166
+ }
167
+ interface MutationState<TData = unknown, TVariables = void, TContext = unknown> {
168
+ data: TData | undefined;
169
+ error: Error | null;
170
+ status: "idle" | "pending" | "error" | "success";
171
+ isIdle: boolean;
172
+ isPending: boolean;
173
+ isPaused: boolean;
174
+ isSuccess: boolean;
175
+ isError: boolean;
176
+ failureCount: number;
177
+ failureReason: Error | null;
178
+ submittedAt: number;
179
+ variables: TVariables | undefined;
180
+ context: TContext | undefined;
181
+ mutate: (variables: TVariables) => void;
182
+ mutateAsync: (variables: TVariables) => Promise<TData>;
183
+ reset: () => void;
184
+ }
185
+ /**
186
+ * TanStack Query Mutation과 Legend-App-State를 연결하는 커스텀 훅
187
+ * MutationObserver를 사용하여 뮤테이션 상태를 observable로 관리합니다.
188
+ *
189
+ * @example
190
+ * ```tsx
191
+ * import { QueryClient } from '@tanstack/react-query'
192
+ * import { QueryClientProvider, useMutation } from '@usels/integrations'
193
+ *
194
+ * // QueryClient를 생성하고 Provider로 제공
195
+ * const queryClient = new QueryClient()
196
+ *
197
+ * function App() {
198
+ * return (
199
+ * <QueryClientProvider client={queryClient}>
200
+ * <YourApp />
201
+ * </QueryClientProvider>
202
+ * )
203
+ * }
204
+ *
205
+ * // 컴포넌트에서 사용
206
+ * function YourComponent() {
207
+ * const createProduct$ = useMutation({
208
+ * mutationFn: (product: NewProduct) =>
209
+ * fetch('/api/products', {
210
+ * method: 'POST',
211
+ * body: JSON.stringify(product)
212
+ * }).then(r => r.json()),
213
+ * onSuccess: () => {
214
+ * alert('Product created!')
215
+ * }
216
+ * })
217
+ *
218
+ * const handleSubmit = (product: NewProduct) => {
219
+ * createProduct$.mutate(product)
220
+ * }
221
+ * }
222
+ * ```
223
+ */
224
+ declare function useMutation<TData = unknown, TVariables = void, TContext = unknown>(options: UseMutationOptions<TData, TVariables, TContext>): Observable<MutationState<TData, TVariables, TContext>>;
225
+
226
+ interface UseInfiniteQueryOptions<TQueryFnData = unknown, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown> {
227
+ queryKey: TQueryKey;
228
+ queryFn: (context: QueryFunctionContext<TQueryKey, TPageParam>) => Promise<TQueryFnData>;
229
+ initialPageParam: TPageParam;
230
+ getNextPageParam: (lastPage: TQueryFnData, allPages: Array<TQueryFnData>, lastPageParam: TPageParam, allPageParams: Array<TPageParam>) => TPageParam | undefined | null;
231
+ getPreviousPageParam?: (firstPage: TQueryFnData, allPages: Array<TQueryFnData>, firstPageParam: TPageParam, allPageParams: Array<TPageParam>) => TPageParam | undefined | null;
232
+ enabled?: MaybeObservable<boolean>;
233
+ staleTime?: MaybeObservable<number>;
234
+ gcTime?: MaybeObservable<number>;
235
+ retry?: MaybeObservable<number | boolean>;
236
+ refetchOnWindowFocus?: MaybeObservable<boolean>;
237
+ refetchOnMount?: MaybeObservable<boolean>;
238
+ refetchOnReconnect?: MaybeObservable<boolean>;
239
+ maxPages?: number;
240
+ }
241
+ interface InfiniteQueryState<TData = unknown> {
242
+ data: TData | undefined;
243
+ error: Error | null;
244
+ status: "pending" | "error" | "success";
245
+ fetchStatus: "fetching" | "paused" | "idle";
246
+ isPending: boolean;
247
+ isSuccess: boolean;
248
+ isError: boolean;
249
+ isLoadingError: boolean;
250
+ isRefetchError: boolean;
251
+ isFetching: boolean;
252
+ isPaused: boolean;
253
+ isRefetching: boolean;
254
+ isLoading: boolean;
255
+ isStale: boolean;
256
+ isPlaceholderData: boolean;
257
+ isFetched: boolean;
258
+ isFetchedAfterMount: boolean;
259
+ dataUpdatedAt: number;
260
+ errorUpdatedAt: number;
261
+ failureCount: number;
262
+ failureReason: Error | null;
263
+ errorUpdateCount: number;
264
+ isEnabled: boolean;
265
+ /**
266
+ * @deprecated Use isLoading instead. Will be removed in TanStack Query v6.
267
+ */
268
+ isInitialLoading: boolean;
269
+ hasNextPage: boolean;
270
+ hasPreviousPage: boolean;
271
+ isFetchingNextPage: boolean;
272
+ isFetchingPreviousPage: boolean;
273
+ isFetchNextPageError: boolean;
274
+ isFetchPreviousPageError: boolean;
275
+ refetch: () => void;
276
+ fetchNextPage: () => void;
277
+ fetchPreviousPage: () => void;
278
+ }
279
+ /**
280
+ * TanStack Query Infinite Query와 Legend-App-State를 연결하는 커스텀 훅
281
+ * InfiniteQueryObserver를 사용하여 쿼리 상태를 observable로 관리합니다.
282
+ *
283
+ * Observable 값을 파라미터로 받을 수 있으며, 변경 시 자동으로 refetch됩니다.
284
+ *
285
+ * @example
286
+ * ```tsx
287
+ * // Cursor-based pagination
288
+ * const items$ = useInfiniteQuery({
289
+ * queryKey: ['items'],
290
+ * queryFn: ({ pageParam }) =>
291
+ * fetch(`/api/items?cursor=${pageParam}`).then(r => r.json()),
292
+ * initialPageParam: undefined,
293
+ * getNextPageParam: (lastPage) => lastPage.nextCursor,
294
+ * })
295
+ *
296
+ * // Observable reactivity
297
+ * const filter$ = useObservable({ category: 'electronics' })
298
+ * const items$ = useInfiniteQuery({
299
+ * queryKey: ['items', filter$],
300
+ * queryFn: ({ pageParam }) =>
301
+ * fetch(`/api/items?category=${filter$.category.get()}&cursor=${pageParam}`)
302
+ * .then(r => r.json()),
303
+ * initialPageParam: undefined,
304
+ * getNextPageParam: (lastPage) => lastPage.nextCursor,
305
+ * })
306
+ * ```
307
+ */
308
+ declare function useInfiniteQuery<TQueryFnData = unknown, TQueryKey extends QueryKey = QueryKey, TPageParam = unknown>(options: MaybeObservable<UseInfiniteQueryOptions<TQueryFnData, TQueryKey, TPageParam>>): Observable<InfiniteQueryState<InfiniteData<TQueryFnData>>>;
309
+
310
+ export { type InfiniteQueryState, type MutationState, QueryClientProvider, type QueryState, type UseInfiniteQueryOptions, type UseMutationOptions, type UseQueryOptions, useInfiniteQuery, useMutation, useQuery, useQueryClient };