@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.
- package/LICENSE +21 -0
- package/README.md +125 -43
- package/dist/QueryClientProvider.d.ts +85 -0
- package/dist/QueryClientProvider.d.ts.map +1 -0
- package/dist/QueryClientProvider.js +137 -0
- package/dist/QueryClientProvider.js.map +1 -0
- package/dist/accessor.d.ts +32 -0
- package/dist/accessor.d.ts.map +1 -0
- package/dist/accessor.js +12 -0
- package/dist/accessor.js.map +1 -0
- package/dist/context.d.ts +59 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +100 -0
- package/dist/context.js.map +1 -0
- package/dist/controllers/BaseController.d.ts +38 -0
- package/dist/controllers/BaseController.d.ts.map +1 -0
- package/dist/controllers/BaseController.js +204 -0
- package/dist/controllers/BaseController.js.map +1 -0
- package/dist/createInfiniteQueryController.d.ts +76 -0
- package/dist/createInfiniteQueryController.d.ts.map +1 -0
- package/dist/createInfiniteQueryController.js +221 -0
- package/dist/createInfiniteQueryController.js.map +1 -0
- package/dist/createMutationController.d.ts +79 -0
- package/dist/createMutationController.d.ts.map +1 -0
- package/dist/createMutationController.js +193 -0
- package/dist/createMutationController.js.map +1 -0
- package/dist/createQueriesController.d.ts +145 -0
- package/dist/createQueriesController.d.ts.map +1 -0
- package/dist/createQueriesController.js +302 -0
- package/dist/createQueriesController.js.map +1 -0
- package/dist/createQueryController.d.ts +67 -0
- package/dist/createQueryController.d.ts.map +1 -0
- package/dist/createQueryController.js +211 -0
- package/dist/createQueryController.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/infiniteQueryOptions.d.ts +21 -0
- package/dist/infiniteQueryOptions.d.ts.map +1 -0
- package/dist/infiniteQueryOptions.js +22 -0
- package/dist/infiniteQueryOptions.js.map +1 -0
- package/dist/mutationOptions.d.ts +19 -0
- package/dist/mutationOptions.d.ts.map +1 -0
- package/dist/mutationOptions.js +20 -0
- package/dist/mutationOptions.js.map +1 -0
- package/dist/queryOptions.d.ts +62 -0
- package/dist/queryOptions.d.ts.map +1 -0
- package/dist/queryOptions.js +4 -0
- package/dist/queryOptions.js.map +1 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/useIsFetching.d.ts +45 -0
- package/dist/useIsFetching.d.ts.map +1 -0
- package/dist/useIsFetching.js +116 -0
- package/dist/useIsFetching.js.map +1 -0
- package/dist/useIsMutating.d.ts +45 -0
- package/dist/useIsMutating.d.ts.map +1 -0
- package/dist/useIsMutating.js +116 -0
- package/dist/useIsMutating.js.map +1 -0
- package/dist/useMutationState.d.ts +57 -0
- package/dist/useMutationState.d.ts.map +1 -0
- package/dist/useMutationState.js +132 -0
- package/dist/useMutationState.js.map +1 -0
- package/dist-cjs/QueryClientProvider.d.cts +84 -0
- package/dist-cjs/QueryClientProvider.js +141 -0
- package/dist-cjs/QueryClientProvider.js.map +1 -0
- package/dist-cjs/accessor.d.cts +31 -0
- package/dist-cjs/accessor.js +16 -0
- package/dist-cjs/accessor.js.map +1 -0
- package/dist-cjs/context.d.cts +58 -0
- package/dist-cjs/context.js +109 -0
- package/dist-cjs/context.js.map +1 -0
- package/dist-cjs/controllers/BaseController.d.cts +37 -0
- package/dist-cjs/controllers/BaseController.js +208 -0
- package/dist-cjs/controllers/BaseController.js.map +1 -0
- package/dist-cjs/createInfiniteQueryController.d.cts +75 -0
- package/dist-cjs/createInfiniteQueryController.js +224 -0
- package/dist-cjs/createInfiniteQueryController.js.map +1 -0
- package/dist-cjs/createMutationController.d.cts +78 -0
- package/dist-cjs/createMutationController.js +196 -0
- package/dist-cjs/createMutationController.js.map +1 -0
- package/dist-cjs/createQueriesController.d.cts +144 -0
- package/dist-cjs/createQueriesController.js +305 -0
- package/dist-cjs/createQueriesController.js.map +1 -0
- package/dist-cjs/createQueryController.d.cts +66 -0
- package/dist-cjs/createQueryController.js +214 -0
- package/dist-cjs/createQueryController.js.map +1 -0
- package/dist-cjs/index.d.cts +23 -0
- package/dist-cjs/index.js +49 -0
- package/dist-cjs/index.js.map +1 -0
- package/dist-cjs/infiniteQueryOptions.d.cts +20 -0
- package/dist-cjs/infiniteQueryOptions.js +25 -0
- package/dist-cjs/infiniteQueryOptions.js.map +1 -0
- package/dist-cjs/mutationOptions.d.cts +18 -0
- package/dist-cjs/mutationOptions.js +23 -0
- package/dist-cjs/mutationOptions.js.map +1 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/queryOptions.d.cts +61 -0
- package/dist-cjs/queryOptions.js +7 -0
- package/dist-cjs/queryOptions.js.map +1 -0
- package/dist-cjs/types.d.cts +30 -0
- package/dist-cjs/types.js +3 -0
- package/dist-cjs/types.js.map +1 -0
- package/dist-cjs/useIsFetching.d.cts +44 -0
- package/dist-cjs/useIsFetching.js +119 -0
- package/dist-cjs/useIsFetching.js.map +1 -0
- package/dist-cjs/useIsMutating.d.cts +44 -0
- package/dist-cjs/useIsMutating.js +119 -0
- package/dist-cjs/useIsMutating.js.map +1 -0
- package/dist-cjs/useMutationState.d.cts +56 -0
- package/dist-cjs/useMutationState.js +135 -0
- package/dist-cjs/useMutationState.js.map +1 -0
- package/package.json +73 -8
- package/src/QueryClientProvider.ts +174 -0
- package/src/accessor.ts +43 -0
- package/src/context.ts +120 -0
- package/src/controllers/BaseController.ts +284 -0
- package/src/createInfiniteQueryController.ts +394 -0
- package/src/createMutationController.ts +361 -0
- package/src/createQueriesController.ts +633 -0
- package/src/createQueryController.ts +342 -0
- package/src/index.ts +72 -0
- package/src/infiniteQueryOptions.ts +48 -0
- package/src/mutationOptions.ts +31 -0
- package/src/queryOptions.ts +143 -0
- package/src/types.ts +77 -0
- package/src/useIsFetching.ts +159 -0
- package/src/useIsMutating.ts +159 -0
- package/src/useMutationState.ts +201 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MutationObserver,
|
|
3
|
+
type DefaultError,
|
|
4
|
+
type MutateOptions,
|
|
5
|
+
type MutationObserverOptions,
|
|
6
|
+
type MutationObserverResult,
|
|
7
|
+
} from '@tanstack/query-core'
|
|
8
|
+
import type { QueryClient } from '@tanstack/query-core'
|
|
9
|
+
import type { ReactiveControllerHost } from 'lit'
|
|
10
|
+
import {
|
|
11
|
+
createValueAccessor,
|
|
12
|
+
readAccessor,
|
|
13
|
+
type Accessor,
|
|
14
|
+
type ValueAccessor,
|
|
15
|
+
} from './accessor.js'
|
|
16
|
+
import { createMissingQueryClientError } from './context.js'
|
|
17
|
+
import { BaseController } from './controllers/BaseController.js'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Options accepted by `createMutationController`.
|
|
21
|
+
*
|
|
22
|
+
* This is the Lit adapter shape for `MutationObserverOptions`. Pass it directly
|
|
23
|
+
* or through an `Accessor` when the options depend on Lit host state.
|
|
24
|
+
*/
|
|
25
|
+
export type CreateMutationOptions<
|
|
26
|
+
TData = unknown,
|
|
27
|
+
TError = DefaultError,
|
|
28
|
+
TVariables = void,
|
|
29
|
+
TOnMutateResult = unknown,
|
|
30
|
+
> = MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Accessor returned by `createMutationController`.
|
|
34
|
+
*
|
|
35
|
+
* Call the accessor or read its `current` property to get the latest mutation
|
|
36
|
+
* result. The attached methods delegate to the active mutation observer.
|
|
37
|
+
*/
|
|
38
|
+
export type MutationResultAccessor<TData, TError, TVariables, TOnMutateResult> =
|
|
39
|
+
ValueAccessor<
|
|
40
|
+
MutationObserverResult<TData, TError, TVariables, TOnMutateResult>
|
|
41
|
+
> & {
|
|
42
|
+
/**
|
|
43
|
+
* Starts the mutation and swallows the returned promise.
|
|
44
|
+
*
|
|
45
|
+
* Throws synchronously if no `QueryClient` can be resolved.
|
|
46
|
+
*/
|
|
47
|
+
mutate: (
|
|
48
|
+
variables: TVariables,
|
|
49
|
+
options?: MutateOptions<TData, TError, TVariables, TOnMutateResult>,
|
|
50
|
+
) => void
|
|
51
|
+
/**
|
|
52
|
+
* Starts the mutation and returns the observer promise.
|
|
53
|
+
*
|
|
54
|
+
* Rejects if no `QueryClient` can be resolved.
|
|
55
|
+
*/
|
|
56
|
+
mutateAsync: MutationObserverResult<
|
|
57
|
+
TData,
|
|
58
|
+
TError,
|
|
59
|
+
TVariables,
|
|
60
|
+
TOnMutateResult
|
|
61
|
+
>['mutate']
|
|
62
|
+
/** Resets the mutation observer to its idle state. */
|
|
63
|
+
reset: MutationObserverResult<
|
|
64
|
+
TData,
|
|
65
|
+
TError,
|
|
66
|
+
TVariables,
|
|
67
|
+
TOnMutateResult
|
|
68
|
+
>['reset']
|
|
69
|
+
/** Removes the controller from its Lit host and unsubscribes observers. */
|
|
70
|
+
destroy: () => void
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function createIdleMutationResult<
|
|
74
|
+
TData,
|
|
75
|
+
TError,
|
|
76
|
+
TVariables,
|
|
77
|
+
TOnMutateResult,
|
|
78
|
+
>(): MutationObserverResult<TData, TError, TVariables, TOnMutateResult> {
|
|
79
|
+
return {
|
|
80
|
+
context: undefined,
|
|
81
|
+
data: undefined,
|
|
82
|
+
error: null,
|
|
83
|
+
failureCount: 0,
|
|
84
|
+
failureReason: null,
|
|
85
|
+
isError: false,
|
|
86
|
+
isIdle: true,
|
|
87
|
+
isPending: false,
|
|
88
|
+
isPaused: false,
|
|
89
|
+
isSuccess: false,
|
|
90
|
+
status: 'idle',
|
|
91
|
+
submittedAt: 0,
|
|
92
|
+
variables: undefined,
|
|
93
|
+
mutate: (() =>
|
|
94
|
+
Promise.reject(
|
|
95
|
+
createMissingQueryClientError(),
|
|
96
|
+
)) as MutationObserverResult<
|
|
97
|
+
TData,
|
|
98
|
+
TError,
|
|
99
|
+
TVariables,
|
|
100
|
+
TOnMutateResult
|
|
101
|
+
>['mutate'],
|
|
102
|
+
reset: (() => undefined) as MutationObserverResult<
|
|
103
|
+
TData,
|
|
104
|
+
TError,
|
|
105
|
+
TVariables,
|
|
106
|
+
TOnMutateResult
|
|
107
|
+
>['reset'],
|
|
108
|
+
} as MutationObserverResult<TData, TError, TVariables, TOnMutateResult>
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
class MutationController<
|
|
112
|
+
TData,
|
|
113
|
+
TError,
|
|
114
|
+
TVariables,
|
|
115
|
+
TOnMutateResult,
|
|
116
|
+
> extends BaseController<
|
|
117
|
+
MutationObserverResult<TData, TError, TVariables, TOnMutateResult>
|
|
118
|
+
> {
|
|
119
|
+
private readonly options: Accessor<
|
|
120
|
+
CreateMutationOptions<TData, TError, TVariables, TOnMutateResult>
|
|
121
|
+
>
|
|
122
|
+
private observer:
|
|
123
|
+
| MutationObserver<TData, TError, TVariables, TOnMutateResult>
|
|
124
|
+
| undefined
|
|
125
|
+
private unsubscribe: (() => void) | undefined
|
|
126
|
+
private queryClient: QueryClient | undefined
|
|
127
|
+
|
|
128
|
+
constructor(
|
|
129
|
+
host: ReactiveControllerHost,
|
|
130
|
+
options: Accessor<
|
|
131
|
+
CreateMutationOptions<TData, TError, TVariables, TOnMutateResult>
|
|
132
|
+
>,
|
|
133
|
+
queryClient?: QueryClient,
|
|
134
|
+
) {
|
|
135
|
+
super(host, createIdleMutationResult(), queryClient)
|
|
136
|
+
this.options = options
|
|
137
|
+
|
|
138
|
+
if (!queryClient) {
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (typeof options === 'function') {
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const observer = new MutationObserver(
|
|
147
|
+
queryClient,
|
|
148
|
+
this.defaultOptions(queryClient),
|
|
149
|
+
)
|
|
150
|
+
this.queryClient = queryClient
|
|
151
|
+
this.observer = observer
|
|
152
|
+
this.result = observer.getCurrentResult()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
protected onConnected(): void {
|
|
156
|
+
if (!this.syncClient()) {
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
this.refreshOptions()
|
|
161
|
+
this.subscribe()
|
|
162
|
+
if (this.observer) {
|
|
163
|
+
this.setResult(this.observer.getCurrentResult())
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
protected onDisconnected(): void {
|
|
168
|
+
this.unsubscribeObserver()
|
|
169
|
+
this.syncClient()
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
protected onHostUpdate(): void {
|
|
173
|
+
if (typeof this.options !== 'function') {
|
|
174
|
+
return
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
this.refreshOptions()
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
protected onQueryClientChanged(): void {
|
|
181
|
+
if (!this.syncClient() || !this.connectedState) {
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
this.refreshOptions()
|
|
186
|
+
this.subscribe()
|
|
187
|
+
if (this.observer) {
|
|
188
|
+
this.setResult(this.observer.getCurrentResult())
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
mutate = (
|
|
193
|
+
variables: TVariables,
|
|
194
|
+
mutateOptions?: MutateOptions<TData, TError, TVariables, TOnMutateResult>,
|
|
195
|
+
): void => {
|
|
196
|
+
if (!this.syncClient() || !this.observer) {
|
|
197
|
+
throw createMissingQueryClientError()
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
void this.observer.mutate(variables, mutateOptions).catch(() => {
|
|
201
|
+
// Intentionally swallow in sync mutate path.
|
|
202
|
+
})
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
mutateAsync: MutationObserverResult<
|
|
206
|
+
TData,
|
|
207
|
+
TError,
|
|
208
|
+
TVariables,
|
|
209
|
+
TOnMutateResult
|
|
210
|
+
>['mutate'] = (...args) => {
|
|
211
|
+
if (!this.syncClient() || !this.observer) {
|
|
212
|
+
return Promise.reject(createMissingQueryClientError())
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return this.observer.mutate(...args)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
reset: MutationObserverResult<
|
|
219
|
+
TData,
|
|
220
|
+
TError,
|
|
221
|
+
TVariables,
|
|
222
|
+
TOnMutateResult
|
|
223
|
+
>['reset'] = () => {
|
|
224
|
+
if (!this.syncClient() || !this.observer) {
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
this.observer.reset()
|
|
229
|
+
this.setResult(this.observer.getCurrentResult())
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private subscribe(): void {
|
|
233
|
+
if (!this.observer) {
|
|
234
|
+
return
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (this.unsubscribe) {
|
|
238
|
+
return
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
this.unsubscribe = this.observer.subscribe((next) => {
|
|
242
|
+
this.setResult(next)
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private unsubscribeObserver(): void {
|
|
247
|
+
this.unsubscribe?.()
|
|
248
|
+
this.unsubscribe = undefined
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
private syncClient(): boolean {
|
|
252
|
+
const nextClient = this.tryGetQueryClient()
|
|
253
|
+
if (!nextClient) {
|
|
254
|
+
this.unsubscribeObserver()
|
|
255
|
+
this.queryClient = undefined
|
|
256
|
+
this.observer = undefined
|
|
257
|
+
this.setResult(createIdleMutationResult())
|
|
258
|
+
return false
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (nextClient === this.queryClient) {
|
|
262
|
+
return true
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
this.unsubscribeObserver()
|
|
266
|
+
this.queryClient = nextClient
|
|
267
|
+
this.observer = new MutationObserver(
|
|
268
|
+
this.queryClient,
|
|
269
|
+
this.defaultOptions(this.queryClient),
|
|
270
|
+
)
|
|
271
|
+
this.setResult(this.observer.getCurrentResult())
|
|
272
|
+
return true
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
private refreshOptions(): boolean {
|
|
276
|
+
if (!this.syncClient() || !this.observer || !this.queryClient) {
|
|
277
|
+
return false
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
this.observer.setOptions(this.defaultOptions())
|
|
281
|
+
this.setResult(this.observer.getCurrentResult())
|
|
282
|
+
return true
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private defaultOptions(
|
|
286
|
+
client = this.queryClient,
|
|
287
|
+
): MutationObserverOptions<TData, TError, TVariables, TOnMutateResult> {
|
|
288
|
+
if (!client) {
|
|
289
|
+
throw createMissingQueryClientError()
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return client.defaultMutationOptions(readAccessor(this.options))
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Creates a Lit reactive controller that subscribes the host to a mutation.
|
|
298
|
+
*
|
|
299
|
+
* The returned accessor is callable and also exposes `current`, `mutate`,
|
|
300
|
+
* `mutateAsync`, `reset`, and `destroy`. When `options` is a function, it is
|
|
301
|
+
* re-read during host updates so mutation options can follow reactive host
|
|
302
|
+
* state.
|
|
303
|
+
*
|
|
304
|
+
* If `queryClient` is omitted, the controller resolves the client from the
|
|
305
|
+
* nearest connected `QueryClientProvider`.
|
|
306
|
+
*
|
|
307
|
+
* @param host - The Lit reactive controller host that owns the mutation
|
|
308
|
+
* subscription.
|
|
309
|
+
* @param options - Mutation observer options, or a getter that returns options.
|
|
310
|
+
* @param queryClient - Optional explicit query client. Provide this for
|
|
311
|
+
* controllers that should not resolve a client from Lit context.
|
|
312
|
+
* @returns An accessor for the latest mutation result with mutation helper
|
|
313
|
+
* methods.
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* ```ts
|
|
317
|
+
* import { LitElement, html } from 'lit'
|
|
318
|
+
* import { createMutationController } from '@tanstack/lit-query'
|
|
319
|
+
*
|
|
320
|
+
* class AddTodoForm extends LitElement {
|
|
321
|
+
* private readonly addTodo = createMutationController(this, {
|
|
322
|
+
* mutationFn: (title: string) =>
|
|
323
|
+
* fetch('/api/todos', { method: 'POST', body: JSON.stringify({ title }) }),
|
|
324
|
+
* })
|
|
325
|
+
*
|
|
326
|
+
* render() {
|
|
327
|
+
* const mutation = this.addTodo()
|
|
328
|
+
*
|
|
329
|
+
* return html`
|
|
330
|
+
* <button ?disabled=${mutation.isPending} @click=${() => this.addTodo.mutate('Ship docs')}>
|
|
331
|
+
* Add todo
|
|
332
|
+
* </button>
|
|
333
|
+
* `
|
|
334
|
+
* }
|
|
335
|
+
* }
|
|
336
|
+
* ```
|
|
337
|
+
*/
|
|
338
|
+
export function createMutationController<
|
|
339
|
+
TData = unknown,
|
|
340
|
+
TError = DefaultError,
|
|
341
|
+
TVariables = void,
|
|
342
|
+
TOnMutateResult = unknown,
|
|
343
|
+
>(
|
|
344
|
+
host: ReactiveControllerHost,
|
|
345
|
+
options: Accessor<
|
|
346
|
+
CreateMutationOptions<TData, TError, TVariables, TOnMutateResult>
|
|
347
|
+
>,
|
|
348
|
+
queryClient?: QueryClient,
|
|
349
|
+
): MutationResultAccessor<TData, TError, TVariables, TOnMutateResult> {
|
|
350
|
+
const controller = new MutationController(host, options, queryClient)
|
|
351
|
+
|
|
352
|
+
return Object.assign(
|
|
353
|
+
createValueAccessor(() => controller.current),
|
|
354
|
+
{
|
|
355
|
+
mutate: controller.mutate,
|
|
356
|
+
mutateAsync: controller.mutateAsync,
|
|
357
|
+
reset: controller.reset,
|
|
358
|
+
destroy: () => controller.destroy(),
|
|
359
|
+
},
|
|
360
|
+
)
|
|
361
|
+
}
|