@tanstack/svelte-query 6.1.48 → 6.2.1

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 (50) hide show
  1. package/dist/context.d.ts +27 -2
  2. package/dist/context.d.ts.map +1 -1
  3. package/dist/context.js +27 -2
  4. package/dist/createInfiniteQuery.d.ts +97 -1
  5. package/dist/createInfiniteQuery.d.ts.map +1 -1
  6. package/dist/createMutation.svelte.d.ts +156 -2
  7. package/dist/createMutation.svelte.d.ts.map +1 -1
  8. package/dist/createMutation.svelte.js +156 -2
  9. package/dist/createQueries.svelte.d.ts +71 -0
  10. package/dist/createQueries.svelte.d.ts.map +1 -1
  11. package/dist/createQueries.svelte.js +71 -0
  12. package/dist/createQuery.d.ts +209 -0
  13. package/dist/createQuery.d.ts.map +1 -1
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/infiniteQueryOptions.d.ts +95 -2
  17. package/dist/infiniteQueryOptions.d.ts.map +1 -1
  18. package/dist/mutationOptions.d.ts +52 -0
  19. package/dist/mutationOptions.d.ts.map +1 -1
  20. package/dist/queryOptions.d.ts +73 -0
  21. package/dist/queryOptions.d.ts.map +1 -1
  22. package/dist/types.d.ts +3 -1
  23. package/dist/types.d.ts.map +1 -1
  24. package/dist/useHydrate.d.ts +28 -0
  25. package/dist/useHydrate.d.ts.map +1 -1
  26. package/dist/useHydrate.js +28 -0
  27. package/dist/useIsFetching.svelte.d.ts +35 -0
  28. package/dist/useIsFetching.svelte.d.ts.map +1 -1
  29. package/dist/useIsFetching.svelte.js +35 -0
  30. package/dist/useIsMutating.svelte.d.ts +23 -0
  31. package/dist/useIsMutating.svelte.d.ts.map +1 -1
  32. package/dist/useIsMutating.svelte.js +23 -0
  33. package/dist/useMutationState.svelte.d.ts +70 -0
  34. package/dist/useMutationState.svelte.d.ts.map +1 -1
  35. package/dist/useMutationState.svelte.js +70 -0
  36. package/package.json +3 -3
  37. package/src/context.ts +27 -2
  38. package/src/createInfiniteQuery.ts +143 -2
  39. package/src/createMutation.svelte.ts +156 -2
  40. package/src/createQueries.svelte.ts +71 -0
  41. package/src/createQuery.ts +209 -0
  42. package/src/index.ts +4 -0
  43. package/src/infiniteQueryOptions.ts +162 -4
  44. package/src/mutationOptions.ts +53 -0
  45. package/src/queryOptions.ts +73 -0
  46. package/src/types.ts +7 -0
  47. package/src/useHydrate.ts +28 -0
  48. package/src/useIsFetching.svelte.ts +35 -0
  49. package/src/useIsMutating.svelte.ts +23 -0
  50. package/src/useMutationState.svelte.ts +70 -0
@@ -11,8 +11,162 @@ import type {
11
11
  import type { DefaultError, QueryClient } from '@tanstack/query-core'
12
12
 
13
13
  /**
14
- * @param options - A function that returns mutation options
15
- * @param queryClient - Custom query client which overrides provider
14
+ * Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects.
15
+ * `createMutation` is the function for that.
16
+ *
17
+ * @see {@link mutationOptions} to share these options across multiple `createMutation` call sites, or to look
18
+ * the mutation up elsewhere via its `mutationKey` (e.g. with `useMutationState`).
19
+ * @param options - The {@link CreateMutationOptions} to use, wrapped in an {@link Accessor} so options can be
20
+ * reactive.
21
+ * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
22
+ * be used.
23
+ * @returns `mutate`/`mutateAsync` also accept per-call `onSuccess`/`onError`/`onSettled` callbacks as a second
24
+ * argument, useful for triggering call-site side effects (e.g. navigation) without coupling them to the shared
25
+ * mutation definition. If you make multiple requests, `onSuccess` will fire only after the latest call you've
26
+ * made.
27
+ *
28
+ * @example
29
+ * ```svelte
30
+ * <script lang="ts">
31
+ * import { createMutation, useQueryClient } from '@tanstack/svelte-query'
32
+ *
33
+ * const queryClient = useQueryClient()
34
+ *
35
+ * const addMutation = createMutation(() => ({
36
+ * mutationFn: addTodo,
37
+ * onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
38
+ * }))
39
+ * </script>
40
+ *
41
+ * <button
42
+ * onclick={() =>
43
+ * addMutation.mutate('Item', {
44
+ * onError: (error) => console.error('Failed to add item:', error),
45
+ * })
46
+ * }
47
+ * >
48
+ * Add
49
+ * </button>
50
+ * ```
51
+ *
52
+ * @example
53
+ * Rendering the mutation's own state, rather than just firing it off:
54
+ * ```svelte
55
+ * <script lang="ts">
56
+ * import { createMutation, useQueryClient } from '@tanstack/svelte-query'
57
+ *
58
+ * const queryClient = useQueryClient()
59
+ *
60
+ * const addMutation = createMutation(() => ({
61
+ * mutationFn: addTodo,
62
+ * onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
63
+ * }))
64
+ * </script>
65
+ *
66
+ * {#if addMutation.isPending}
67
+ * Adding todo...
68
+ * {:else}
69
+ * {#if addMutation.isError}
70
+ * <div>An error occurred: {addMutation.error.message}</div>
71
+ * {/if}
72
+ * <button onclick={() => addMutation.mutate('Item')}>Add</button>
73
+ * {/if}
74
+ * ```
75
+ *
76
+ * @example
77
+ * Optimistic update via `onMutate`, rolling back on `onError`:
78
+ * ```svelte
79
+ * <script lang="ts">
80
+ * import { createMutation, useQueryClient } from '@tanstack/svelte-query'
81
+ *
82
+ * const queryClient = useQueryClient()
83
+ *
84
+ * const addMutation = createMutation(() => ({
85
+ * mutationFn: addTodo,
86
+ * onMutate: async (newTodo: string) => {
87
+ * await queryClient.cancelQueries({ queryKey: ['todos'] })
88
+ * const previousTodos = queryClient.getQueryData<Array<string>>(['todos'])
89
+ *
90
+ * queryClient.setQueryData<Array<string>>(['todos'], (old) => [
91
+ * ...(old ?? []),
92
+ * newTodo,
93
+ * ])
94
+ *
95
+ * // Passed to `onError` as `onMutateResult` if the mutation fails.
96
+ * return { previousTodos }
97
+ * },
98
+ * onError: (_err, _newTodo, onMutateResult) => {
99
+ * queryClient.setQueryData(['todos'], onMutateResult?.previousTodos)
100
+ * },
101
+ * onSettled: () => {
102
+ * queryClient.invalidateQueries({ queryKey: ['todos'] })
103
+ * },
104
+ * }))
105
+ * </script>
106
+ *
107
+ * <button onclick={() => addMutation.mutate('Item')}>Add</button>
108
+ * ```
109
+ *
110
+ * @example
111
+ * Callbacks passed per call to `mutate` only fire for the last call — `mutateAsync` gives you a
112
+ * promise per call instead, so you can wait for all of them when they succeed:
113
+ * ```svelte
114
+ * <script lang="ts">
115
+ * import { createMutation, useQueryClient } from '@tanstack/svelte-query'
116
+ *
117
+ * const queryClient = useQueryClient()
118
+ *
119
+ * const addMutation = createMutation(() => ({
120
+ * mutationFn: addTodo,
121
+ * onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
122
+ * }))
123
+ *
124
+ * async function handleAddAll(todos: Array<string>) {
125
+ * try {
126
+ * await Promise.all(todos.map((todo) => addMutation.mutateAsync(todo)))
127
+ * } catch (error) {
128
+ * console.error('Failed to add todos:', error)
129
+ * }
130
+ * }
131
+ * </script>
132
+ *
133
+ * <button onclick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
134
+ * Add all
135
+ * </button>
136
+ * ```
137
+ *
138
+ * @example
139
+ * If some of the mutations above can fail independently of the others, and you want to know which ones
140
+ * did — rather than losing that information the moment the first one rejects — swap `Promise.all` for
141
+ * `Promise.allSettled`:
142
+ * ```svelte
143
+ * <script lang="ts">
144
+ * import { createMutation, useQueryClient } from '@tanstack/svelte-query'
145
+ *
146
+ * const queryClient = useQueryClient()
147
+ *
148
+ * const addMutation = createMutation(() => ({
149
+ * mutationFn: addTodo,
150
+ * onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }),
151
+ * }))
152
+ *
153
+ * async function handleAddAll(todos: Array<string>) {
154
+ * const addResults = await Promise.allSettled(
155
+ * todos.map((todo) => addMutation.mutateAsync(todo)),
156
+ * )
157
+ *
158
+ * addResults.forEach((addResult, index) => {
159
+ * if (addResult.status === 'rejected') {
160
+ * console.error(`Failed to add "${todos[index]}":`, addResult.reason)
161
+ * }
162
+ * })
163
+ * }
164
+ * </script>
165
+ *
166
+ * <button onclick={() => handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])}>
167
+ * Add all
168
+ * </button>
169
+ * ```
16
170
  */
17
171
  export function createMutation<
18
172
  TData = unknown,
@@ -186,6 +186,77 @@ export type QueriesResults<
186
186
  >
187
187
  : { [K in keyof T]: GetCreateQueryResult<T[K]> }
188
188
 
189
+ /**
190
+ * @param createQueriesOptions - The `queries` array to run, and an optional `combine` function, wrapped in an
191
+ * {@link Accessor} so options can be reactive.
192
+ * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context
193
+ * will be used.
194
+ * @returns An array with one result per query, in the same order as `queries` — or, if `combine` is provided,
195
+ * whatever `combine` returns.
196
+ *
197
+ * @example
198
+ * ```svelte
199
+ * <script lang="ts">
200
+ * import { createQueries } from '@tanstack/svelte-query'
201
+ *
202
+ * let { ids }: { ids: Array<number> } = $props()
203
+ *
204
+ * const postQueries = createQueries(() => ({
205
+ * queries: ids.map((id) => ({
206
+ * queryKey: ['post', id],
207
+ * queryFn: () => fetchPost(id),
208
+ * staleTime: Infinity,
209
+ * })),
210
+ * }))
211
+ * </script>
212
+ *
213
+ * <ul>
214
+ * {#each postQueries as query, index (ids[index])}
215
+ * {#if query.isPending}
216
+ * <li>Loading...</li>
217
+ * {:else if query.isError}
218
+ * <li>Error: {query.error.message}</li>
219
+ * {:else}
220
+ * <li>{query.data.title}</li>
221
+ * {/if}
222
+ * {/each}
223
+ * </ul>
224
+ * ```
225
+ *
226
+ * @example
227
+ * Combining results into a single value:
228
+ * ```svelte
229
+ * <script lang="ts">
230
+ * import { createQueries } from '@tanstack/svelte-query'
231
+ *
232
+ * let { ids }: { ids: Array<number> } = $props()
233
+ *
234
+ * const combined = createQueries(() => ({
235
+ * queries: ids.map((id) => ({
236
+ * queryKey: ['post', id],
237
+ * queryFn: () => fetchPost(id),
238
+ * })),
239
+ * combine: (postQueries) => ({
240
+ * data: postQueries.map((query) => query.data),
241
+ * isPending: postQueries.some((query) => query.isPending),
242
+ * isError: postQueries.some((query) => query.isError),
243
+ * }),
244
+ * }))
245
+ * </script>
246
+ *
247
+ * {#if combined.isPending}
248
+ * Loading...
249
+ * {:else if combined.isError}
250
+ * Error loading posts
251
+ * {:else}
252
+ * <ul>
253
+ * {#each combined.data as post}
254
+ * <li>{post?.title}</li>
255
+ * {/each}
256
+ * </ul>
257
+ * {/if}
258
+ * ```
259
+ */
189
260
  export function createQueries<
190
261
  T extends Array<any>,
191
262
  TCombinedResult = QueriesResults<T>,
@@ -12,6 +12,65 @@ import type {
12
12
  UndefinedInitialDataOptions,
13
13
  } from './queryOptions.js'
14
14
 
15
+ /**
16
+ * @see {@link queryOptions} to share these options between `createQuery` and imperative APIs like `queryClient.query`.
17
+ * @param options - The {@link UndefinedInitialDataOptions} to use — everything you can pass to `createQuery`,
18
+ * wrapped in an {@link Accessor} so options can be reactive.
19
+ * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
20
+ * be used.
21
+ * @returns The current query result. `status` is `pending` if there is no cached data to display, `error` if
22
+ * the last fetch attempt failed, or `success` if the query has data to display. `isPending`/`isSuccess`/`isError`
23
+ * are derived booleans for convenience.
24
+ *
25
+ * @example
26
+ * ```svelte
27
+ * <script lang="ts">
28
+ * import { createQuery } from '@tanstack/svelte-query'
29
+ *
30
+ * const query = createQuery(() => ({
31
+ * queryKey: ['posts'],
32
+ * queryFn: fetchPosts,
33
+ * }))
34
+ * </script>
35
+ *
36
+ * {#if query.status === 'pending'}
37
+ * Loading...
38
+ * {:else if query.status === 'error'}
39
+ * <span>Error: {query.error.message}</span>
40
+ * {:else}
41
+ * <ul>
42
+ * {#each query.data as post (post.id)}
43
+ * <li>{post.title}</li>
44
+ * {/each}
45
+ * </ul>
46
+ * {/if}
47
+ * ```
48
+ *
49
+ * @example
50
+ * The same query, checking `isPending`/`isError` instead of `status` — pick whichever reads better to you:
51
+ * ```svelte
52
+ * <script lang="ts">
53
+ * import { createQuery } from '@tanstack/svelte-query'
54
+ *
55
+ * const query = createQuery(() => ({
56
+ * queryKey: ['posts'],
57
+ * queryFn: fetchPosts,
58
+ * }))
59
+ * </script>
60
+ *
61
+ * {#if query.isPending}
62
+ * Loading...
63
+ * {:else if query.isError}
64
+ * <span>Error: {query.error.message}</span>
65
+ * {:else}
66
+ * <ul>
67
+ * {#each query.data as post (post.id)}
68
+ * <li>{post.title}</li>
69
+ * {/each}
70
+ * </ul>
71
+ * {/if}
72
+ * ```
73
+ */
15
74
  export function createQuery<
16
75
  TQueryFnData = unknown,
17
76
  TError = DefaultError,
@@ -24,6 +83,42 @@ export function createQuery<
24
83
  queryClient?: Accessor<QueryClient>,
25
84
  ): CreateQueryResult<TData, TError>
26
85
 
86
+ /**
87
+ * This overload is selected when `initialData` is set, so the resulting `data` is never `undefined`.
88
+ *
89
+ * @see {@link queryOptions} to share these options between `createQuery` and imperative APIs like `queryClient.query`.
90
+ * @param options - The {@link DefinedInitialDataOptions} to use — everything you can pass to `createQuery`,
91
+ * with `initialData` set, wrapped in an {@link Accessor} so options can be reactive.
92
+ * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
93
+ * be used.
94
+ * @returns The current query result, typed so that `status` is `success` — or `error` if a fetch attempt
95
+ * fails while keeping the existing data (`status` never resolves to `pending` in this overload's type,
96
+ * since `initialData` guarantees data upfront). `isSuccess`/`isError` are derived booleans for convenience.
97
+ *
98
+ * @example
99
+ * ```svelte
100
+ * <script lang="ts">
101
+ * import { createQuery } from '@tanstack/svelte-query'
102
+ *
103
+ * // `data` is `Post[]`, never `undefined`, thanks to `initialData` — even if a refetch fails,
104
+ * // so the list stays visible alongside the error.
105
+ * const query = createQuery(() => ({
106
+ * queryKey: ['posts'],
107
+ * queryFn: fetchPosts,
108
+ * initialData: [],
109
+ * }))
110
+ * </script>
111
+ *
112
+ * {#if query.isError}
113
+ * <span>Error: {query.error.message}</span>
114
+ * {/if}
115
+ * <ul>
116
+ * {#each query.data as post (post.id)}
117
+ * <li>{post.title}</li>
118
+ * {/each}
119
+ * </ul>
120
+ * ```
121
+ */
27
122
  export function createQuery<
28
123
  TQueryFnData = unknown,
29
124
  TError = DefaultError,
@@ -36,6 +131,120 @@ export function createQuery<
36
131
  queryClient?: Accessor<QueryClient>,
37
132
  ): DefinedCreateQueryResult<TData, TError>
38
133
 
134
+ /**
135
+ * @see {@link queryOptions} to share these options between `createQuery` and imperative APIs like `queryClient.query`.
136
+ * @param options - The {@link CreateQueryOptions} to use — everything you can pass to `createQuery`, wrapped
137
+ * in an {@link Accessor} so options can be reactive.
138
+ * @param queryClient - Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will
139
+ * be used.
140
+ * @returns The current query result. `status` is `pending` if there is no cached data to display, `error` if
141
+ * the last fetch attempt failed, or `success` if the query has data to display. `isPending`/`isSuccess`/`isError`
142
+ * are derived booleans for convenience.
143
+ *
144
+ * @example
145
+ * `select` derives whatever `data` a component needs from the cached value, without changing what's
146
+ * actually stored in the cache — the cache still holds the full `Post[]`, but `data` here is a `number`:
147
+ * ```svelte
148
+ * <script lang="ts">
149
+ * import { createQuery } from '@tanstack/svelte-query'
150
+ *
151
+ * const query = createQuery(() => ({
152
+ * queryKey: ['posts'],
153
+ * queryFn: fetchPosts,
154
+ * select: (posts) => posts.length,
155
+ * }))
156
+ * </script>
157
+ *
158
+ * {#if query.isPending}
159
+ * Loading...
160
+ * {:else if query.isError}
161
+ * <span>Error: {query.error.message}</span>
162
+ * {:else}
163
+ * <span>{query.data} posts</span>
164
+ * {/if}
165
+ * ```
166
+ *
167
+ * @example
168
+ * A dependent query, only enabled once `postId` is set — use `isLoading`, not `isPending`, so the
169
+ * loading state doesn't show while the query is disabled:
170
+ * ```svelte
171
+ * <script lang="ts">
172
+ * import { createQuery } from '@tanstack/svelte-query'
173
+ *
174
+ * let { postId }: { postId: number | undefined } = $props()
175
+ *
176
+ * const query = createQuery(() => ({
177
+ * queryKey: ['post', postId],
178
+ * queryFn: () => fetchPost(postId!),
179
+ * enabled: postId != null,
180
+ * }))
181
+ * </script>
182
+ *
183
+ * {#if postId == null}
184
+ * Select a post
185
+ * {:else if query.isLoading}
186
+ * Loading...
187
+ * {:else if query.isError}
188
+ * <span>Error: {query.error.message}</span>
189
+ * {:else}
190
+ * <h1>{query.data?.title}</h1>
191
+ * {/if}
192
+ * ```
193
+ *
194
+ * @example
195
+ * Seeding a detail query from an already-cached list, to skip the loading state:
196
+ * ```svelte
197
+ * <script lang="ts">
198
+ * import { createQuery, useQueryClient } from '@tanstack/svelte-query'
199
+ *
200
+ * let { postId }: { postId: number } = $props()
201
+ *
202
+ * const queryClient = useQueryClient()
203
+ *
204
+ * const query = createQuery(() => ({
205
+ * queryKey: ['post', postId],
206
+ * queryFn: () => fetchPost(postId),
207
+ * initialData: () =>
208
+ * queryClient
209
+ * .getQueryData<Array<Post>>(['posts'])
210
+ * ?.find((post) => post.id === postId),
211
+ * }))
212
+ * </script>
213
+ *
214
+ * {#if query.isError}
215
+ * <span>Error: {query.error.message}</span>
216
+ * {/if}
217
+ * <h1>{query.data?.title}</h1>
218
+ * ```
219
+ *
220
+ * @example
221
+ * Paginated data, keeping the previous page's data visible while the next page loads:
222
+ * ```svelte
223
+ * <script lang="ts">
224
+ * import { createQuery, keepPreviousData } from '@tanstack/svelte-query'
225
+ *
226
+ * let page = $state(0)
227
+ *
228
+ * const query = createQuery(() => ({
229
+ * queryKey: ['posts', page],
230
+ * queryFn: () => fetchPosts(page),
231
+ * placeholderData: keepPreviousData,
232
+ * }))
233
+ * </script>
234
+ *
235
+ * {#if query.isError}
236
+ * <span>Error: {query.error.message}</span>
237
+ * {/if}
238
+ * <ul>
239
+ * {#each query.data ?? [] as post (post.id)}
240
+ * <li>{post.title}</li>
241
+ * {/each}
242
+ * </ul>
243
+ * <button disabled={query.isPlaceholderData} onclick={() => page++}>
244
+ * Next Page
245
+ * </button>
246
+ * ```
247
+ */
39
248
  export function createQuery<
40
249
  TQueryFnData,
41
250
  TError = DefaultError,
package/src/index.ts CHANGED
@@ -16,6 +16,10 @@ export type {
16
16
  export { queryOptions } from './queryOptions.js'
17
17
  export { createQueries } from './createQueries.svelte.js'
18
18
  export { createInfiniteQuery } from './createInfiniteQuery.js'
19
+ export type {
20
+ DefinedInitialDataInfiniteOptions,
21
+ UndefinedInitialDataInfiniteOptions,
22
+ } from './infiniteQueryOptions.js'
19
23
  export { infiniteQueryOptions } from './infiniteQueryOptions.js'
20
24
  export { mutationOptions } from './mutationOptions.js'
21
25
  export { createMutation } from './createMutation.svelte.js'
@@ -1,6 +1,94 @@
1
- import type { DefaultError, InfiniteData, QueryKey } from '@tanstack/query-core'
1
+ import type {
2
+ DefaultError,
3
+ InfiniteData,
4
+ InitialDataFunction,
5
+ NonUndefinedGuard,
6
+ QueryKey,
7
+ QueryKeyWithDataTag,
8
+ } from '@tanstack/query-core'
2
9
  import type { CreateInfiniteQueryOptions } from './types.js'
3
10
 
11
+ export type UndefinedInitialDataInfiniteOptions<
12
+ TQueryFnData = unknown,
13
+ TError = DefaultError,
14
+ TData = InfiniteData<TQueryFnData>,
15
+ TQueryKey extends QueryKey = QueryKey,
16
+ TPageParam = unknown,
17
+ > = CreateInfiniteQueryOptions<
18
+ TQueryFnData,
19
+ TError,
20
+ TData,
21
+ TQueryKey,
22
+ TPageParam
23
+ > & {
24
+ initialData?:
25
+ | undefined
26
+ | NonUndefinedGuard<InfiniteData<TQueryFnData, TPageParam>>
27
+ | InitialDataFunction<
28
+ NonUndefinedGuard<InfiniteData<TQueryFnData, TPageParam>>
29
+ >
30
+ }
31
+
32
+ export type DefinedInitialDataInfiniteOptions<
33
+ TQueryFnData = unknown,
34
+ TError = DefaultError,
35
+ TData = InfiniteData<TQueryFnData>,
36
+ TQueryKey extends QueryKey = QueryKey,
37
+ TPageParam = unknown,
38
+ > = CreateInfiniteQueryOptions<
39
+ TQueryFnData,
40
+ TError,
41
+ TData,
42
+ TQueryKey,
43
+ TPageParam
44
+ > & {
45
+ initialData:
46
+ | NonUndefinedGuard<InfiniteData<TQueryFnData, TPageParam>>
47
+ | (() => NonUndefinedGuard<InfiniteData<TQueryFnData, TPageParam>>)
48
+ }
49
+
50
+ /**
51
+ * You can generally pass everything to `infiniteQueryOptions` that you can also pass to `createInfiniteQuery`.
52
+ * These options can be shared across `createInfiniteQuery` calls and imperative APIs such as
53
+ * `queryClient.infiniteQuery`. `options.queryKey` is required and is the query key to generate options for.
54
+ *
55
+ * This overload is selected when `initialData` is set.
56
+ *
57
+ * @see {@link createInfiniteQuery} to run an infinite query with these options.
58
+ * @param options - The {@link DefinedInitialDataInfiniteOptions} to use — everything you can pass to
59
+ * `createInfiniteQuery`, with `initialData` set.
60
+ * @returns The same options object, typed so that `queryKey` carries the inferred data type.
61
+ *
62
+ * @example
63
+ * `initialData` skips the loading state on first render — even if a refetch fails, the list stays
64
+ * visible alongside the error:
65
+ * ```svelte
66
+ * <script lang="ts">
67
+ * import { infiniteQueryOptions, createInfiniteQuery } from '@tanstack/svelte-query'
68
+ *
69
+ * const projectsOptions = infiniteQueryOptions({
70
+ * queryKey: ['projects'],
71
+ * queryFn: ({ pageParam }) => fetchProjects(pageParam),
72
+ * initialPageParam: 0,
73
+ * getNextPageParam: (lastPage) => lastPage.nextId,
74
+ * initialData: { pages: [], pageParams: [] },
75
+ * })
76
+ *
77
+ * const query = createInfiniteQuery(() => projectsOptions)
78
+ * </script>
79
+ *
80
+ * {#if query.isError}
81
+ * <span>Error: {query.error.message}</span>
82
+ * {/if}
83
+ * <ul>
84
+ * {#each query.data.pages as page}
85
+ * {#each page.projects as project (project.id)}
86
+ * <li>{project.name}</li>
87
+ * {/each}
88
+ * {/each}
89
+ * </ul>
90
+ * ```
91
+ */
4
92
  export function infiniteQueryOptions<
5
93
  TQueryFnData,
6
94
  TError = DefaultError,
@@ -8,19 +96,89 @@ export function infiniteQueryOptions<
8
96
  TQueryKey extends QueryKey = QueryKey,
9
97
  TPageParam = unknown,
10
98
  >(
11
- options: CreateInfiniteQueryOptions<
99
+ options: DefinedInitialDataInfiniteOptions<
12
100
  TQueryFnData,
13
101
  TError,
14
102
  TData,
15
103
  TQueryKey,
16
104
  TPageParam
17
105
  >,
18
- ): CreateInfiniteQueryOptions<
106
+ ): DefinedInitialDataInfiniteOptions<
19
107
  TQueryFnData,
20
108
  TError,
21
109
  TData,
22
110
  TQueryKey,
23
111
  TPageParam
24
- > {
112
+ > &
113
+ QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData>, TError>
114
+
115
+ /**
116
+ * You can generally pass everything to `infiniteQueryOptions` that you can also pass to `createInfiniteQuery`.
117
+ * These options can be shared across `createInfiniteQuery` calls and imperative APIs such as
118
+ * `queryClient.infiniteQuery`. `options.queryKey` is required and is the query key to generate options for.
119
+ *
120
+ * @see {@link createInfiniteQuery} to run an infinite query with these options.
121
+ * @param options - The {@link UndefinedInitialDataInfiniteOptions} to use — everything you can pass to
122
+ * `createInfiniteQuery`.
123
+ * @returns The same options object, typed so that `queryKey` carries the inferred data type.
124
+ *
125
+ * @example
126
+ * A parameterized factory, so the same options object can be reused per `postId`:
127
+ * ```svelte
128
+ * <script lang="ts">
129
+ * import { infiniteQueryOptions, createInfiniteQuery } from '@tanstack/svelte-query'
130
+ *
131
+ * let { postId }: { postId: string } = $props()
132
+ *
133
+ * const commentsOptions = (postId: string) =>
134
+ * infiniteQueryOptions({
135
+ * queryKey: ['post', postId, 'comments'],
136
+ * queryFn: ({ pageParam }) => fetchComments(postId, pageParam),
137
+ * initialPageParam: 0,
138
+ * getNextPageParam: (lastPage) => lastPage.nextId,
139
+ * })
140
+ *
141
+ * const query = createInfiniteQuery(() => commentsOptions(postId))
142
+ * </script>
143
+ *
144
+ * {#if query.isPending}
145
+ * Loading...
146
+ * {:else if query.isError}
147
+ * <span>Error: {query.error.message}</span>
148
+ * {:else}
149
+ * <ul>
150
+ * {#each query.data.pages as page}
151
+ * {#each page.comments as comment (comment.id)}
152
+ * <li>{comment.text}</li>
153
+ * {/each}
154
+ * {/each}
155
+ * </ul>
156
+ * {/if}
157
+ * ```
158
+ */
159
+ export function infiniteQueryOptions<
160
+ TQueryFnData,
161
+ TError = DefaultError,
162
+ TData = InfiniteData<TQueryFnData>,
163
+ TQueryKey extends QueryKey = QueryKey,
164
+ TPageParam = unknown,
165
+ >(
166
+ options: UndefinedInitialDataInfiniteOptions<
167
+ TQueryFnData,
168
+ TError,
169
+ TData,
170
+ TQueryKey,
171
+ TPageParam
172
+ >,
173
+ ): UndefinedInitialDataInfiniteOptions<
174
+ TQueryFnData,
175
+ TError,
176
+ TData,
177
+ TQueryKey,
178
+ TPageParam
179
+ > &
180
+ QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData>, TError>
181
+
182
+ export function infiniteQueryOptions(options: unknown) {
25
183
  return options
26
184
  }