@tanstack/lit-query 0.0.1 → 0.2.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 (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -43
  3. package/dist/QueryClientProvider.d.ts +85 -0
  4. package/dist/QueryClientProvider.d.ts.map +1 -0
  5. package/dist/QueryClientProvider.js +137 -0
  6. package/dist/QueryClientProvider.js.map +1 -0
  7. package/dist/accessor.d.ts +32 -0
  8. package/dist/accessor.d.ts.map +1 -0
  9. package/dist/accessor.js +12 -0
  10. package/dist/accessor.js.map +1 -0
  11. package/dist/context.d.ts +59 -0
  12. package/dist/context.d.ts.map +1 -0
  13. package/dist/context.js +100 -0
  14. package/dist/context.js.map +1 -0
  15. package/dist/controllers/BaseController.d.ts +38 -0
  16. package/dist/controllers/BaseController.d.ts.map +1 -0
  17. package/dist/controllers/BaseController.js +204 -0
  18. package/dist/controllers/BaseController.js.map +1 -0
  19. package/dist/createInfiniteQueryController.d.ts +76 -0
  20. package/dist/createInfiniteQueryController.d.ts.map +1 -0
  21. package/dist/createInfiniteQueryController.js +221 -0
  22. package/dist/createInfiniteQueryController.js.map +1 -0
  23. package/dist/createMutationController.d.ts +79 -0
  24. package/dist/createMutationController.d.ts.map +1 -0
  25. package/dist/createMutationController.js +193 -0
  26. package/dist/createMutationController.js.map +1 -0
  27. package/dist/createQueriesController.d.ts +145 -0
  28. package/dist/createQueriesController.d.ts.map +1 -0
  29. package/dist/createQueriesController.js +302 -0
  30. package/dist/createQueriesController.js.map +1 -0
  31. package/dist/createQueryController.d.ts +67 -0
  32. package/dist/createQueryController.d.ts.map +1 -0
  33. package/dist/createQueryController.js +211 -0
  34. package/dist/createQueryController.js.map +1 -0
  35. package/dist/index.d.ts +24 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +15 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/infiniteQueryOptions.d.ts +21 -0
  40. package/dist/infiniteQueryOptions.d.ts.map +1 -0
  41. package/dist/infiniteQueryOptions.js +22 -0
  42. package/dist/infiniteQueryOptions.js.map +1 -0
  43. package/dist/mutationOptions.d.ts +19 -0
  44. package/dist/mutationOptions.d.ts.map +1 -0
  45. package/dist/mutationOptions.js +20 -0
  46. package/dist/mutationOptions.js.map +1 -0
  47. package/dist/queryOptions.d.ts +62 -0
  48. package/dist/queryOptions.d.ts.map +1 -0
  49. package/dist/queryOptions.js +4 -0
  50. package/dist/queryOptions.js.map +1 -0
  51. package/dist/types.d.ts +31 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +2 -0
  54. package/dist/types.js.map +1 -0
  55. package/dist/useIsFetching.d.ts +45 -0
  56. package/dist/useIsFetching.d.ts.map +1 -0
  57. package/dist/useIsFetching.js +116 -0
  58. package/dist/useIsFetching.js.map +1 -0
  59. package/dist/useIsMutating.d.ts +45 -0
  60. package/dist/useIsMutating.d.ts.map +1 -0
  61. package/dist/useIsMutating.js +116 -0
  62. package/dist/useIsMutating.js.map +1 -0
  63. package/dist/useMutationState.d.ts +57 -0
  64. package/dist/useMutationState.d.ts.map +1 -0
  65. package/dist/useMutationState.js +132 -0
  66. package/dist/useMutationState.js.map +1 -0
  67. package/dist-cjs/QueryClientProvider.d.cts +84 -0
  68. package/dist-cjs/QueryClientProvider.js +141 -0
  69. package/dist-cjs/QueryClientProvider.js.map +1 -0
  70. package/dist-cjs/accessor.d.cts +31 -0
  71. package/dist-cjs/accessor.js +16 -0
  72. package/dist-cjs/accessor.js.map +1 -0
  73. package/dist-cjs/context.d.cts +58 -0
  74. package/dist-cjs/context.js +109 -0
  75. package/dist-cjs/context.js.map +1 -0
  76. package/dist-cjs/controllers/BaseController.d.cts +37 -0
  77. package/dist-cjs/controllers/BaseController.js +208 -0
  78. package/dist-cjs/controllers/BaseController.js.map +1 -0
  79. package/dist-cjs/createInfiniteQueryController.d.cts +75 -0
  80. package/dist-cjs/createInfiniteQueryController.js +224 -0
  81. package/dist-cjs/createInfiniteQueryController.js.map +1 -0
  82. package/dist-cjs/createMutationController.d.cts +78 -0
  83. package/dist-cjs/createMutationController.js +196 -0
  84. package/dist-cjs/createMutationController.js.map +1 -0
  85. package/dist-cjs/createQueriesController.d.cts +144 -0
  86. package/dist-cjs/createQueriesController.js +305 -0
  87. package/dist-cjs/createQueriesController.js.map +1 -0
  88. package/dist-cjs/createQueryController.d.cts +66 -0
  89. package/dist-cjs/createQueryController.js +214 -0
  90. package/dist-cjs/createQueryController.js.map +1 -0
  91. package/dist-cjs/index.d.cts +23 -0
  92. package/dist-cjs/index.js +49 -0
  93. package/dist-cjs/index.js.map +1 -0
  94. package/dist-cjs/infiniteQueryOptions.d.cts +20 -0
  95. package/dist-cjs/infiniteQueryOptions.js +25 -0
  96. package/dist-cjs/infiniteQueryOptions.js.map +1 -0
  97. package/dist-cjs/mutationOptions.d.cts +18 -0
  98. package/dist-cjs/mutationOptions.js +23 -0
  99. package/dist-cjs/mutationOptions.js.map +1 -0
  100. package/dist-cjs/package.json +3 -0
  101. package/dist-cjs/queryOptions.d.cts +61 -0
  102. package/dist-cjs/queryOptions.js +7 -0
  103. package/dist-cjs/queryOptions.js.map +1 -0
  104. package/dist-cjs/types.d.cts +30 -0
  105. package/dist-cjs/types.js +3 -0
  106. package/dist-cjs/types.js.map +1 -0
  107. package/dist-cjs/useIsFetching.d.cts +44 -0
  108. package/dist-cjs/useIsFetching.js +119 -0
  109. package/dist-cjs/useIsFetching.js.map +1 -0
  110. package/dist-cjs/useIsMutating.d.cts +44 -0
  111. package/dist-cjs/useIsMutating.js +119 -0
  112. package/dist-cjs/useIsMutating.js.map +1 -0
  113. package/dist-cjs/useMutationState.d.cts +56 -0
  114. package/dist-cjs/useMutationState.js +135 -0
  115. package/dist-cjs/useMutationState.js.map +1 -0
  116. package/package.json +73 -8
  117. package/src/QueryClientProvider.ts +174 -0
  118. package/src/accessor.ts +43 -0
  119. package/src/context.ts +120 -0
  120. package/src/controllers/BaseController.ts +284 -0
  121. package/src/createInfiniteQueryController.ts +394 -0
  122. package/src/createMutationController.ts +361 -0
  123. package/src/createQueriesController.ts +633 -0
  124. package/src/createQueryController.ts +342 -0
  125. package/src/index.ts +72 -0
  126. package/src/infiniteQueryOptions.ts +48 -0
  127. package/src/mutationOptions.ts +31 -0
  128. package/src/queryOptions.ts +143 -0
  129. package/src/types.ts +77 -0
  130. package/src/useIsFetching.ts +159 -0
  131. package/src/useIsMutating.ts +159 -0
  132. package/src/useMutationState.ts +201 -0
@@ -0,0 +1,342 @@
1
+ import {
2
+ QueryObserver,
3
+ type DefaultError,
4
+ type DefaultedQueryObserverOptions,
5
+ type QueryKey,
6
+ type QueryObserverOptions,
7
+ type QueryObserverResult,
8
+ } from '@tanstack/query-core'
9
+ import type { QueryClient } from '@tanstack/query-core'
10
+ import type { ReactiveControllerHost } from 'lit'
11
+ import {
12
+ createValueAccessor,
13
+ readAccessor,
14
+ type Accessor,
15
+ type ValueAccessor,
16
+ } from './accessor.js'
17
+ import { createMissingQueryClientError } from './context.js'
18
+ import { BaseController } from './controllers/BaseController.js'
19
+
20
+ /**
21
+ * Options accepted by `createQueryController`.
22
+ *
23
+ * This is the Lit adapter shape for `QueryObserverOptions`. It can be passed
24
+ * directly to `createQueryController`, or wrapped in an `Accessor` when the
25
+ * options depend on Lit host state.
26
+ */
27
+ export type CreateQueryOptions<
28
+ TQueryFnData = unknown,
29
+ TError = DefaultError,
30
+ TData = TQueryFnData,
31
+ TQueryData = TQueryFnData,
32
+ TQueryKey extends QueryKey = QueryKey,
33
+ > = QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
34
+
35
+ /**
36
+ * Accessor returned by `createQueryController`.
37
+ *
38
+ * Call the accessor or read its `current` property to get the latest query
39
+ * result. The attached methods delegate to the active query observer.
40
+ */
41
+ export type QueryResultAccessor<TData, TError> = ValueAccessor<
42
+ QueryObserverResult<TData, TError>
43
+ > & {
44
+ /** Refetches the current query. */
45
+ refetch: QueryObserverResult<TData, TError>['refetch']
46
+ /** Resolves with an optimistic query result, fetching first when needed. */
47
+ suspense: () => Promise<QueryObserverResult<TData, TError>>
48
+ /** Removes the controller from its Lit host and unsubscribes observers. */
49
+ destroy: () => void
50
+ }
51
+
52
+ function createPendingQueryResult<TData, TError>(): QueryObserverResult<
53
+ TData,
54
+ TError
55
+ > {
56
+ return {
57
+ data: undefined,
58
+ dataUpdatedAt: 0,
59
+ error: null,
60
+ errorUpdatedAt: 0,
61
+ failureCount: 0,
62
+ failureReason: null,
63
+ errorUpdateCount: 0,
64
+ isError: false,
65
+ isFetched: false,
66
+ isFetchedAfterMount: false,
67
+ isFetching: false,
68
+ isInitialLoading: false,
69
+ isLoading: false,
70
+ isLoadingError: false,
71
+ isPaused: false,
72
+ isPending: true,
73
+ isPlaceholderData: false,
74
+ isRefetchError: false,
75
+ isRefetching: false,
76
+ isStale: true,
77
+ isEnabled: true,
78
+ isSuccess: false,
79
+ fetchStatus: 'idle',
80
+ status: 'pending',
81
+ refetch: (() =>
82
+ Promise.reject(createMissingQueryClientError())) as QueryObserverResult<
83
+ TData,
84
+ TError
85
+ >['refetch'],
86
+ promise: Promise.resolve(undefined as never),
87
+ } as unknown as QueryObserverResult<TData, TError>
88
+ }
89
+
90
+ class QueryController<
91
+ TQueryFnData,
92
+ TError,
93
+ TData,
94
+ TQueryData,
95
+ TQueryKey extends QueryKey,
96
+ > extends BaseController<QueryObserverResult<TData, TError>> {
97
+ private readonly options: Accessor<
98
+ CreateQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
99
+ >
100
+ private observer:
101
+ | QueryObserver<TQueryFnData, TError, TData, TQueryData, TQueryKey>
102
+ | undefined
103
+ private unsubscribe: (() => void) | undefined
104
+ private queryClient: QueryClient | undefined
105
+
106
+ constructor(
107
+ host: ReactiveControllerHost,
108
+ options: Accessor<
109
+ CreateQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
110
+ >,
111
+ queryClient?: QueryClient,
112
+ ) {
113
+ const initialClient = queryClient
114
+ super(host, createPendingQueryResult(), queryClient)
115
+ this.options = options
116
+
117
+ if (!initialClient) {
118
+ return
119
+ }
120
+
121
+ if (typeof options === 'function') {
122
+ return
123
+ }
124
+
125
+ const defaulted = this.defaultOptions(initialClient)
126
+ const observer = new QueryObserver(initialClient, defaulted)
127
+ this.queryClient = initialClient
128
+ this.observer = observer
129
+ this.result = observer.getOptimisticResult(defaulted)
130
+ }
131
+
132
+ protected onConnected(): void {
133
+ if (!this.syncClient()) {
134
+ return
135
+ }
136
+
137
+ this.refreshOptions()
138
+ this.subscribe()
139
+ this.observer?.updateResult()
140
+ if (this.observer) {
141
+ this.setResult(this.observer.getCurrentResult())
142
+ }
143
+ }
144
+
145
+ protected onDisconnected(): void {
146
+ this.unsubscribeObserver()
147
+ this.syncClient()
148
+ }
149
+
150
+ protected onHostUpdate(): void {
151
+ if (typeof this.options !== 'function') {
152
+ return
153
+ }
154
+
155
+ this.refreshOptions()
156
+ }
157
+
158
+ protected onQueryClientChanged(): void {
159
+ if (!this.syncClient()) {
160
+ return
161
+ }
162
+
163
+ if (!this.connectedState) {
164
+ return
165
+ }
166
+
167
+ this.refreshOptions()
168
+ this.subscribe()
169
+ this.observer?.updateResult()
170
+ if (this.observer) {
171
+ this.setResult(this.observer.getCurrentResult())
172
+ }
173
+ }
174
+
175
+ refetch: QueryObserverResult<TData, TError>['refetch'] = (...args) => {
176
+ if (!this.refreshOptions()) {
177
+ return Promise.reject(createMissingQueryClientError())
178
+ }
179
+
180
+ return this.result.refetch(...args)
181
+ }
182
+
183
+ suspense = async (): Promise<QueryObserverResult<TData, TError>> => {
184
+ if (!this.syncClient() || !this.observer || !this.queryClient) {
185
+ throw createMissingQueryClientError()
186
+ }
187
+
188
+ const options = this.defaultOptions(this.queryClient)
189
+ this.observer.setOptions(options)
190
+ const optimistic = this.observer.getOptimisticResult(options)
191
+ if (options.enabled !== false && optimistic.isStale) {
192
+ return this.observer.fetchOptimistic(options)
193
+ }
194
+
195
+ return optimistic
196
+ }
197
+
198
+ private subscribe(): void {
199
+ if (!this.observer) {
200
+ return
201
+ }
202
+
203
+ if (this.unsubscribe) {
204
+ return
205
+ }
206
+
207
+ this.unsubscribe = this.observer.subscribe((next) => {
208
+ this.setResult(next)
209
+ })
210
+ }
211
+
212
+ private unsubscribeObserver(): void {
213
+ this.unsubscribe?.()
214
+ this.unsubscribe = undefined
215
+ }
216
+
217
+ private syncClient(): boolean {
218
+ const nextClient = this.tryGetQueryClient()
219
+ if (!nextClient) {
220
+ this.unsubscribeObserver()
221
+ this.queryClient = undefined
222
+ this.observer = undefined
223
+ this.setResult(createPendingQueryResult())
224
+ return false
225
+ }
226
+
227
+ if (nextClient === this.queryClient && this.observer) {
228
+ return true
229
+ }
230
+
231
+ this.unsubscribeObserver()
232
+ this.queryClient = nextClient
233
+ const options = this.defaultOptions()
234
+ this.observer = new QueryObserver(this.queryClient, options)
235
+ this.setResult(this.observer.getOptimisticResult(options))
236
+ return true
237
+ }
238
+
239
+ private refreshOptions(): boolean {
240
+ if (!this.syncClient() || !this.observer) {
241
+ return false
242
+ }
243
+
244
+ const options = this.defaultOptions(this.queryClient)
245
+ this.observer.setOptions(options)
246
+ this.setResult(this.observer.getOptimisticResult(options))
247
+ return true
248
+ }
249
+
250
+ private defaultOptions(
251
+ client = this.queryClient,
252
+ ): DefaultedQueryObserverOptions<
253
+ TQueryFnData,
254
+ TError,
255
+ TData,
256
+ TQueryData,
257
+ TQueryKey
258
+ > {
259
+ const resolvedClient = client ?? this.tryGetQueryClient()
260
+ if (!resolvedClient) {
261
+ throw createMissingQueryClientError()
262
+ }
263
+
264
+ this.queryClient = resolvedClient
265
+ const defaulted = resolvedClient.defaultQueryOptions(
266
+ readAccessor(this.options),
267
+ ) as DefaultedQueryObserverOptions<
268
+ TQueryFnData,
269
+ TError,
270
+ TData,
271
+ TQueryData,
272
+ TQueryKey
273
+ >
274
+ ;(defaulted as { _optimisticResults?: 'optimistic' })._optimisticResults =
275
+ 'optimistic'
276
+ return defaulted
277
+ }
278
+ }
279
+
280
+ /**
281
+ * Creates a Lit reactive controller that subscribes the host to a single query.
282
+ *
283
+ * The returned accessor is callable and also exposes `current`, `refetch`,
284
+ * `suspense`, and `destroy`. When `options` is a function, it is re-read during
285
+ * host updates so query keys and options can follow reactive host state.
286
+ *
287
+ * If `queryClient` is omitted, the controller resolves the client from the
288
+ * nearest connected `QueryClientProvider`.
289
+ *
290
+ * @param host - The Lit reactive controller host that owns the query
291
+ * subscription.
292
+ * @param options - Query observer options, or a getter that returns options.
293
+ * @param queryClient - Optional explicit query client. Provide this for
294
+ * controllers that should not resolve a client from Lit context.
295
+ * @returns An accessor for the latest query result with query helper methods.
296
+ *
297
+ * @example
298
+ * ```ts
299
+ * import { LitElement, html } from 'lit'
300
+ * import { createQueryController } from '@tanstack/lit-query'
301
+ *
302
+ * class TodosView extends LitElement {
303
+ * private readonly todos = createQueryController(this, {
304
+ * queryKey: ['todos'],
305
+ * queryFn: async () => fetch('/api/todos').then((r) => r.json()),
306
+ * })
307
+ *
308
+ * render() {
309
+ * const query = this.todos()
310
+ *
311
+ * if (query.isPending) return html`Loading...`
312
+ * if (query.isError) return html`Error`
313
+ *
314
+ * return html`<ul>${query.data.map((todo) => html`<li>${todo.title}</li>`)}</ul>`
315
+ * }
316
+ * }
317
+ * ```
318
+ */
319
+ export function createQueryController<
320
+ TQueryFnData = unknown,
321
+ TError = DefaultError,
322
+ TData = TQueryFnData,
323
+ TQueryData = TQueryFnData,
324
+ TQueryKey extends QueryKey = QueryKey,
325
+ >(
326
+ host: ReactiveControllerHost,
327
+ options: Accessor<
328
+ CreateQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
329
+ >,
330
+ queryClient?: QueryClient,
331
+ ): QueryResultAccessor<TData, TError> {
332
+ const controller = new QueryController(host, options, queryClient)
333
+
334
+ return Object.assign(
335
+ createValueAccessor(() => controller.current),
336
+ {
337
+ refetch: controller.refetch,
338
+ suspense: controller.suspense,
339
+ destroy: () => controller.destroy(),
340
+ },
341
+ )
342
+ }
package/src/index.ts ADDED
@@ -0,0 +1,72 @@
1
+ /* istanbul ignore file */
2
+
3
+ export * from '@tanstack/query-core'
4
+
5
+ export type { Accessor, ValueAccessor } from './accessor.js'
6
+
7
+ export {
8
+ getDefaultQueryClient,
9
+ queryClientContext,
10
+ registerDefaultQueryClient,
11
+ resolveQueryClient,
12
+ unregisterDefaultQueryClient,
13
+ useQueryClient,
14
+ } from './context.js'
15
+
16
+ export { QueryClientProvider } from './QueryClientProvider.js'
17
+
18
+ export type {
19
+ CreateInfiniteQueryOptions,
20
+ InfiniteQueryResultAccessor,
21
+ } from './createInfiniteQueryController.js'
22
+ export { createInfiniteQueryController } from './createInfiniteQueryController.js'
23
+
24
+ export type {
25
+ CreateMutationOptions,
26
+ MutationResultAccessor,
27
+ } from './createMutationController.js'
28
+ export { createMutationController } from './createMutationController.js'
29
+
30
+ export type {
31
+ CreateQueriesControllerOptions,
32
+ CreateQueriesInput,
33
+ QueriesResultAccessor,
34
+ } from './createQueriesController.js'
35
+ export { createQueriesController } from './createQueriesController.js'
36
+
37
+ export type {
38
+ CreateQueryOptions,
39
+ QueryResultAccessor,
40
+ } from './createQueryController.js'
41
+ export { createQueryController } from './createQueryController.js'
42
+
43
+ export type { IsFetchingAccessor } from './useIsFetching.js'
44
+ export { useIsFetching } from './useIsFetching.js'
45
+
46
+ export type { IsMutatingAccessor } from './useIsMutating.js'
47
+ export { useIsMutating } from './useIsMutating.js'
48
+
49
+ export type {
50
+ MutationStateAccessor,
51
+ MutationStateOptions,
52
+ } from './useMutationState.js'
53
+ export { useMutationState } from './useMutationState.js'
54
+
55
+ export type {
56
+ DefinedInitialDataOptions,
57
+ UndefinedInitialDataOptions,
58
+ UnusedSkipTokenOptions,
59
+ } from './queryOptions.js'
60
+ export { queryOptions } from './queryOptions.js'
61
+
62
+ export { infiniteQueryOptions } from './infiniteQueryOptions.js'
63
+ export { mutationOptions } from './mutationOptions.js'
64
+
65
+ export type {
66
+ InfiniteQueryControllerOptions,
67
+ MutationControllerOptions,
68
+ MutationControllerResult,
69
+ QueriesControllerOptions,
70
+ QueryControllerOptions,
71
+ QueryControllerResult,
72
+ } from './types.js'
@@ -0,0 +1,48 @@
1
+ import type {
2
+ DefaultError,
3
+ InfiniteData,
4
+ InfiniteQueryObserverOptions,
5
+ QueryKey,
6
+ } from '@tanstack/query-core'
7
+
8
+ /**
9
+ * Preserves and types infinite query options for reuse across Lit Query APIs.
10
+ *
11
+ * @param options - Infinite query options to preserve.
12
+ * @returns The same options object.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { infiniteQueryOptions } from '@tanstack/lit-query'
17
+ *
18
+ * const projectsOptions = infiniteQueryOptions({
19
+ * queryKey: ['projects'],
20
+ * queryFn: ({ pageParam }) => fetchProjects(pageParam),
21
+ * initialPageParam: 0,
22
+ * getNextPageParam: (lastPage) => lastPage.nextCursor,
23
+ * })
24
+ * ```
25
+ */
26
+ export function infiniteQueryOptions<
27
+ TQueryFnData = unknown,
28
+ TError = DefaultError,
29
+ TData = InfiniteData<TQueryFnData>,
30
+ TQueryKey extends QueryKey = QueryKey,
31
+ TPageParam = unknown,
32
+ >(
33
+ options: InfiniteQueryObserverOptions<
34
+ TQueryFnData,
35
+ TError,
36
+ TData,
37
+ TQueryKey,
38
+ TPageParam
39
+ >,
40
+ ): InfiniteQueryObserverOptions<
41
+ TQueryFnData,
42
+ TError,
43
+ TData,
44
+ TQueryKey,
45
+ TPageParam
46
+ > {
47
+ return options
48
+ }
@@ -0,0 +1,31 @@
1
+ import type {
2
+ DefaultError,
3
+ MutationObserverOptions,
4
+ } from '@tanstack/query-core'
5
+
6
+ /**
7
+ * Preserves and types mutation options for reuse across Lit Query APIs.
8
+ *
9
+ * @param options - Mutation options to preserve.
10
+ * @returns The same options object.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { mutationOptions } from '@tanstack/lit-query'
15
+ *
16
+ * const addTodoOptions = mutationOptions({
17
+ * mutationKey: ['add-todo'],
18
+ * mutationFn: (title: string) => addTodo(title),
19
+ * })
20
+ * ```
21
+ */
22
+ export function mutationOptions<
23
+ TData = unknown,
24
+ TError = DefaultError,
25
+ TVariables = void,
26
+ TOnMutateResult = unknown,
27
+ >(
28
+ options: MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>,
29
+ ): MutationObserverOptions<TData, TError, TVariables, TOnMutateResult> {
30
+ return options
31
+ }
@@ -0,0 +1,143 @@
1
+ import type {
2
+ DataTag,
3
+ DefaultError,
4
+ InitialDataFunction,
5
+ NonUndefinedGuard,
6
+ OmitKeyof,
7
+ QueryFunction,
8
+ QueryKey,
9
+ QueryObserverOptions,
10
+ SkipToken,
11
+ } from '@tanstack/query-core'
12
+
13
+ /**
14
+ * Query options with `initialData` that guarantees defined query data.
15
+ */
16
+ export type DefinedInitialDataOptions<
17
+ TQueryFnData = unknown,
18
+ TError = DefaultError,
19
+ TData = TQueryFnData,
20
+ TQueryKey extends QueryKey = QueryKey,
21
+ > = Omit<
22
+ QueryObserverOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>,
23
+ 'queryFn'
24
+ > & {
25
+ initialData:
26
+ | NonUndefinedGuard<TQueryFnData>
27
+ | (() => NonUndefinedGuard<TQueryFnData>)
28
+ queryFn?: QueryFunction<TQueryFnData, TQueryKey>
29
+ }
30
+
31
+ /**
32
+ * Query options where `queryFn` is present and not a `skipToken`.
33
+ */
34
+ export type UnusedSkipTokenOptions<
35
+ TQueryFnData = unknown,
36
+ TError = DefaultError,
37
+ TData = TQueryFnData,
38
+ TQueryKey extends QueryKey = QueryKey,
39
+ > = OmitKeyof<
40
+ QueryObserverOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>,
41
+ 'queryFn'
42
+ > & {
43
+ queryFn?: Exclude<
44
+ QueryObserverOptions<
45
+ TQueryFnData,
46
+ TError,
47
+ TData,
48
+ TQueryFnData,
49
+ TQueryKey
50
+ >['queryFn'],
51
+ SkipToken | undefined
52
+ >
53
+ }
54
+
55
+ /**
56
+ * Query options where `initialData` can be omitted or undefined.
57
+ */
58
+ export type UndefinedInitialDataOptions<
59
+ TQueryFnData = unknown,
60
+ TError = DefaultError,
61
+ TData = TQueryFnData,
62
+ TQueryKey extends QueryKey = QueryKey,
63
+ > = QueryObserverOptions<
64
+ TQueryFnData,
65
+ TError,
66
+ TData,
67
+ TQueryFnData,
68
+ TQueryKey
69
+ > & {
70
+ initialData?:
71
+ | undefined
72
+ | InitialDataFunction<NonUndefinedGuard<TQueryFnData>>
73
+ | NonUndefinedGuard<TQueryFnData>
74
+ }
75
+
76
+ /**
77
+ * Brands query options so the `queryKey` carries the query function data and
78
+ * error types across TanStack Query APIs.
79
+ *
80
+ * @param options - Query options to preserve and brand.
81
+ * @returns The same options object with a typed `queryKey`.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * import { queryOptions } from '@tanstack/lit-query'
86
+ *
87
+ * const todosOptions = queryOptions({
88
+ * queryKey: ['todos'],
89
+ * queryFn: fetchTodos,
90
+ * initialData: [],
91
+ * })
92
+ * ```
93
+ */
94
+ export function queryOptions<
95
+ TQueryFnData = unknown,
96
+ TError = DefaultError,
97
+ TData = TQueryFnData,
98
+ TQueryKey extends QueryKey = QueryKey,
99
+ >(
100
+ options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
101
+ ): DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey> & {
102
+ queryKey: DataTag<TQueryKey, TQueryFnData, TError>
103
+ }
104
+
105
+ /**
106
+ * Brands query options so the `queryKey` carries the query function data and
107
+ * error types across TanStack Query APIs.
108
+ *
109
+ * @param options - Query options to preserve and brand.
110
+ * @returns The same options object with a typed `queryKey`.
111
+ */
112
+ export function queryOptions<
113
+ TQueryFnData = unknown,
114
+ TError = DefaultError,
115
+ TData = TQueryFnData,
116
+ TQueryKey extends QueryKey = QueryKey,
117
+ >(
118
+ options: UnusedSkipTokenOptions<TQueryFnData, TError, TData, TQueryKey>,
119
+ ): UnusedSkipTokenOptions<TQueryFnData, TError, TData, TQueryKey> & {
120
+ queryKey: DataTag<TQueryKey, TQueryFnData, TError>
121
+ }
122
+
123
+ /**
124
+ * Brands query options so the `queryKey` carries the query function data and
125
+ * error types across TanStack Query APIs.
126
+ *
127
+ * @param options - Query options to preserve and brand.
128
+ * @returns The same options object with a typed `queryKey`.
129
+ */
130
+ export function queryOptions<
131
+ TQueryFnData = unknown,
132
+ TError = DefaultError,
133
+ TData = TQueryFnData,
134
+ TQueryKey extends QueryKey = QueryKey,
135
+ >(
136
+ options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
137
+ ): UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey> & {
138
+ queryKey: DataTag<TQueryKey, TQueryFnData, TError>
139
+ }
140
+
141
+ export function queryOptions(options: unknown) {
142
+ return options
143
+ }
package/src/types.ts ADDED
@@ -0,0 +1,77 @@
1
+ import type {
2
+ DefaultError,
3
+ InfiniteData,
4
+ MutationObserverResult,
5
+ QueryKey,
6
+ QueryObserverResult,
7
+ } from '@tanstack/query-core'
8
+ import type { Accessor } from './accessor.js'
9
+ import type { CreateInfiniteQueryOptions } from './createInfiniteQueryController.js'
10
+ import type { CreateMutationOptions } from './createMutationController.js'
11
+ import type {
12
+ CreateQueriesControllerOptions,
13
+ CreateQueriesResults,
14
+ } from './createQueriesController.js'
15
+ import type { CreateQueryOptions } from './createQueryController.js'
16
+
17
+ /**
18
+ * Accessor-wrapped options accepted by `createQueryController`.
19
+ */
20
+ export type QueryControllerOptions<
21
+ TQueryFnData = unknown,
22
+ TError = DefaultError,
23
+ TData = TQueryFnData,
24
+ TQueryData = TQueryFnData,
25
+ TQueryKey extends QueryKey = QueryKey,
26
+ > = Accessor<
27
+ CreateQueryOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
28
+ >
29
+
30
+ /**
31
+ * Result object produced by a Lit query controller.
32
+ */
33
+ export type QueryControllerResult<
34
+ TData = unknown,
35
+ TError = DefaultError,
36
+ > = QueryObserverResult<TData, TError>
37
+
38
+ /**
39
+ * Accessor-wrapped options accepted by `createInfiniteQueryController`.
40
+ */
41
+ export type InfiniteQueryControllerOptions<
42
+ TQueryFnData = unknown,
43
+ TError = DefaultError,
44
+ TData = InfiniteData<TQueryFnData>,
45
+ TQueryKey extends QueryKey = QueryKey,
46
+ TPageParam = unknown,
47
+ > = Accessor<
48
+ CreateInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
49
+ >
50
+
51
+ /**
52
+ * Accessor-wrapped options accepted by `createMutationController`.
53
+ */
54
+ export type MutationControllerOptions<
55
+ TData = unknown,
56
+ TError = DefaultError,
57
+ TVariables = void,
58
+ TOnMutateResult = unknown,
59
+ > = Accessor<CreateMutationOptions<TData, TError, TVariables, TOnMutateResult>>
60
+
61
+ /**
62
+ * Result object produced by a Lit mutation controller.
63
+ */
64
+ export type MutationControllerResult<
65
+ TData = unknown,
66
+ TError = DefaultError,
67
+ TVariables = void,
68
+ TOnMutateResult = unknown,
69
+ > = MutationObserverResult<TData, TError, TVariables, TOnMutateResult>
70
+
71
+ /**
72
+ * Accessor-wrapped options accepted by `createQueriesController`.
73
+ */
74
+ export type QueriesControllerOptions<
75
+ TQueryOptions extends Array<any> = Array<any>,
76
+ TCombinedResult = CreateQueriesResults<TQueryOptions>,
77
+ > = Accessor<CreateQueriesControllerOptions<TQueryOptions, TCombinedResult>>