@tanstack/lit-query 0.2.11 → 0.2.13

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 (143) hide show
  1. package/README.md +17 -0
  2. package/build/legacy/index.cjs +1585 -0
  3. package/build/legacy/index.cjs.map +1 -0
  4. package/build/legacy/index.d.cts +781 -0
  5. package/build/legacy/index.d.cts.map +1 -0
  6. package/build/legacy/index.d.ts +781 -0
  7. package/build/legacy/index.d.ts.map +1 -0
  8. package/build/legacy/index.js +1561 -0
  9. package/build/legacy/index.js.map +1 -0
  10. package/build/modern/index.cjs +1569 -0
  11. package/build/modern/index.cjs.map +1 -0
  12. package/build/modern/index.d.cts +781 -0
  13. package/build/modern/index.d.cts.map +1 -0
  14. package/build/modern/index.d.ts +781 -0
  15. package/build/modern/index.d.ts.map +1 -0
  16. package/build/modern/index.js +1545 -0
  17. package/build/modern/index.js.map +1 -0
  18. package/package.json +27 -30
  19. package/src/createInfiniteQueryController.ts +0 -1
  20. package/src/createMutationController.ts +9 -7
  21. package/src/createQueriesController.ts +0 -2
  22. package/src/createQueryController.ts +0 -1
  23. package/src/infiniteQueryOptions.ts +10 -4
  24. package/dist/QueryClientProvider.d.ts +0 -85
  25. package/dist/QueryClientProvider.d.ts.map +0 -1
  26. package/dist/QueryClientProvider.js +0 -137
  27. package/dist/QueryClientProvider.js.map +0 -1
  28. package/dist/accessor.d.ts +0 -32
  29. package/dist/accessor.d.ts.map +0 -1
  30. package/dist/accessor.js +0 -12
  31. package/dist/accessor.js.map +0 -1
  32. package/dist/context.d.ts +0 -59
  33. package/dist/context.d.ts.map +0 -1
  34. package/dist/context.js +0 -100
  35. package/dist/context.js.map +0 -1
  36. package/dist/controllers/BaseController.d.ts +0 -39
  37. package/dist/controllers/BaseController.d.ts.map +0 -1
  38. package/dist/controllers/BaseController.js +0 -213
  39. package/dist/controllers/BaseController.js.map +0 -1
  40. package/dist/createInfiniteQueryController.d.ts +0 -76
  41. package/dist/createInfiniteQueryController.d.ts.map +0 -1
  42. package/dist/createInfiniteQueryController.js +0 -248
  43. package/dist/createInfiniteQueryController.js.map +0 -1
  44. package/dist/createMutationController.d.ts +0 -79
  45. package/dist/createMutationController.d.ts.map +0 -1
  46. package/dist/createMutationController.js +0 -193
  47. package/dist/createMutationController.js.map +0 -1
  48. package/dist/createQueriesController.d.ts +0 -145
  49. package/dist/createQueriesController.d.ts.map +0 -1
  50. package/dist/createQueriesController.js +0 -367
  51. package/dist/createQueriesController.js.map +0 -1
  52. package/dist/createQueryController.d.ts +0 -67
  53. package/dist/createQueryController.d.ts.map +0 -1
  54. package/dist/createQueryController.js +0 -238
  55. package/dist/createQueryController.js.map +0 -1
  56. package/dist/index.d.ts +0 -24
  57. package/dist/index.d.ts.map +0 -1
  58. package/dist/index.js +0 -15
  59. package/dist/index.js.map +0 -1
  60. package/dist/infiniteQueryOptions.d.ts +0 -21
  61. package/dist/infiniteQueryOptions.d.ts.map +0 -1
  62. package/dist/infiniteQueryOptions.js +0 -22
  63. package/dist/infiniteQueryOptions.js.map +0 -1
  64. package/dist/mutationOptions.d.ts +0 -19
  65. package/dist/mutationOptions.d.ts.map +0 -1
  66. package/dist/mutationOptions.js +0 -20
  67. package/dist/mutationOptions.js.map +0 -1
  68. package/dist/queryObserverResultTracker.d.ts +0 -14
  69. package/dist/queryObserverResultTracker.d.ts.map +0 -1
  70. package/dist/queryObserverResultTracker.js +0 -18
  71. package/dist/queryObserverResultTracker.js.map +0 -1
  72. package/dist/queryOptions.d.ts +0 -62
  73. package/dist/queryOptions.d.ts.map +0 -1
  74. package/dist/queryOptions.js +0 -4
  75. package/dist/queryOptions.js.map +0 -1
  76. package/dist/types.d.ts +0 -31
  77. package/dist/types.d.ts.map +0 -1
  78. package/dist/types.js +0 -2
  79. package/dist/types.js.map +0 -1
  80. package/dist/useIsFetching.d.ts +0 -45
  81. package/dist/useIsFetching.d.ts.map +0 -1
  82. package/dist/useIsFetching.js +0 -116
  83. package/dist/useIsFetching.js.map +0 -1
  84. package/dist/useIsMutating.d.ts +0 -45
  85. package/dist/useIsMutating.d.ts.map +0 -1
  86. package/dist/useIsMutating.js +0 -116
  87. package/dist/useIsMutating.js.map +0 -1
  88. package/dist/useMutationState.d.ts +0 -57
  89. package/dist/useMutationState.d.ts.map +0 -1
  90. package/dist/useMutationState.js +0 -136
  91. package/dist/useMutationState.js.map +0 -1
  92. package/dist-cjs/QueryClientProvider.d.cts +0 -84
  93. package/dist-cjs/QueryClientProvider.js +0 -141
  94. package/dist-cjs/QueryClientProvider.js.map +0 -1
  95. package/dist-cjs/accessor.d.cts +0 -31
  96. package/dist-cjs/accessor.js +0 -16
  97. package/dist-cjs/accessor.js.map +0 -1
  98. package/dist-cjs/context.d.cts +0 -58
  99. package/dist-cjs/context.js +0 -109
  100. package/dist-cjs/context.js.map +0 -1
  101. package/dist-cjs/controllers/BaseController.d.cts +0 -38
  102. package/dist-cjs/controllers/BaseController.js +0 -217
  103. package/dist-cjs/controllers/BaseController.js.map +0 -1
  104. package/dist-cjs/createInfiniteQueryController.d.cts +0 -75
  105. package/dist-cjs/createInfiniteQueryController.js +0 -251
  106. package/dist-cjs/createInfiniteQueryController.js.map +0 -1
  107. package/dist-cjs/createMutationController.d.cts +0 -78
  108. package/dist-cjs/createMutationController.js +0 -196
  109. package/dist-cjs/createMutationController.js.map +0 -1
  110. package/dist-cjs/createQueriesController.d.cts +0 -144
  111. package/dist-cjs/createQueriesController.js +0 -370
  112. package/dist-cjs/createQueriesController.js.map +0 -1
  113. package/dist-cjs/createQueryController.d.cts +0 -66
  114. package/dist-cjs/createQueryController.js +0 -241
  115. package/dist-cjs/createQueryController.js.map +0 -1
  116. package/dist-cjs/index.d.cts +0 -23
  117. package/dist-cjs/index.js +0 -49
  118. package/dist-cjs/index.js.map +0 -1
  119. package/dist-cjs/infiniteQueryOptions.d.cts +0 -20
  120. package/dist-cjs/infiniteQueryOptions.js +0 -25
  121. package/dist-cjs/infiniteQueryOptions.js.map +0 -1
  122. package/dist-cjs/mutationOptions.d.cts +0 -18
  123. package/dist-cjs/mutationOptions.js +0 -23
  124. package/dist-cjs/mutationOptions.js.map +0 -1
  125. package/dist-cjs/package.json +0 -3
  126. package/dist-cjs/queryObserverResultTracker.d.cts +0 -13
  127. package/dist-cjs/queryObserverResultTracker.js +0 -22
  128. package/dist-cjs/queryObserverResultTracker.js.map +0 -1
  129. package/dist-cjs/queryOptions.d.cts +0 -61
  130. package/dist-cjs/queryOptions.js +0 -7
  131. package/dist-cjs/queryOptions.js.map +0 -1
  132. package/dist-cjs/types.d.cts +0 -30
  133. package/dist-cjs/types.js +0 -3
  134. package/dist-cjs/types.js.map +0 -1
  135. package/dist-cjs/useIsFetching.d.cts +0 -44
  136. package/dist-cjs/useIsFetching.js +0 -119
  137. package/dist-cjs/useIsFetching.js.map +0 -1
  138. package/dist-cjs/useIsMutating.d.cts +0 -44
  139. package/dist-cjs/useIsMutating.js +0 -119
  140. package/dist-cjs/useIsMutating.js.map +0 -1
  141. package/dist-cjs/useMutationState.d.cts +0 -56
  142. package/dist-cjs/useMutationState.js +0 -139
  143. package/dist-cjs/useMutationState.js.map +0 -1
@@ -0,0 +1,1545 @@
1
+ import { InfiniteQueryObserver, MutationObserver, QueriesObserver, QueryObserver, replaceEqualDeep } from "@tanstack/query-core";
2
+ import { ContextEvent, ContextProvider, createContext } from "@lit/context";
3
+ import { LitElement, html } from "lit";
4
+ export * from "@tanstack/query-core";
5
+ //#region src/context.ts
6
+ /**
7
+ * Lit context key used by `QueryClientProvider` and host-bound APIs to share a
8
+ * `QueryClient` through the DOM tree.
9
+ *
10
+ * Most applications use `QueryClientProvider` instead of interacting with this
11
+ * context directly.
12
+ */
13
+ const queryClientContext = createContext(Symbol.for("tanstack-query-client"));
14
+ const missingQueryClientMessage = "No QueryClient available. Pass one explicitly or render within QueryClientProvider.";
15
+ const ambiguousQueryClientMessage = "Multiple QueryClients are mounted. Pass one explicitly instead of relying on global QueryClient helpers.";
16
+ const registeredClients = /* @__PURE__ */ new Map();
17
+ let defaultClient;
18
+ /**
19
+ * Registers a `QueryClient` as a process-local fallback for APIs that resolve a
20
+ * client without an explicit argument.
21
+ *
22
+ * `QueryClientProvider` calls this automatically while it is connected. Prefer
23
+ * passing an explicit client or rendering under a provider when possible.
24
+ *
25
+ * @param client - The query client to register as the current default.
26
+ */
27
+ function registerDefaultQueryClient(client) {
28
+ registeredClients.set(client, (registeredClients.get(client) ?? 0) + 1);
29
+ defaultClient = client;
30
+ }
31
+ /**
32
+ * Unregisters a client previously registered with
33
+ * `registerDefaultQueryClient`.
34
+ *
35
+ * `QueryClientProvider` calls this automatically when it disconnects.
36
+ *
37
+ * @param client - The query client registration to release.
38
+ */
39
+ function unregisterDefaultQueryClient(client) {
40
+ const count = registeredClients.get(client);
41
+ if (count === void 0) return;
42
+ if (count > 1) {
43
+ registeredClients.set(client, count - 1);
44
+ return;
45
+ }
46
+ registeredClients.delete(client);
47
+ if (defaultClient !== client) return;
48
+ defaultClient = [...registeredClients.keys()].at(-1);
49
+ }
50
+ /**
51
+ * Returns the registered default `QueryClient`, if exactly one default client is
52
+ * available.
53
+ *
54
+ * @returns The default query client, or `undefined` when there is no registered
55
+ * client or more than one registered client.
56
+ */
57
+ function getDefaultQueryClient() {
58
+ if (registeredClients.size > 1) return;
59
+ return defaultClient;
60
+ }
61
+ function createMissingQueryClientError() {
62
+ return /* @__PURE__ */ new Error(missingQueryClientMessage);
63
+ }
64
+ function createAmbiguousQueryClientError() {
65
+ return /* @__PURE__ */ new Error(ambiguousQueryClientMessage);
66
+ }
67
+ /**
68
+ * Resolves the current default `QueryClient` registered by a connected
69
+ * `QueryClientProvider`.
70
+ *
71
+ * This helper is useful outside a Lit reactive controller when a single
72
+ * provider is mounted. It throws if no client is registered or if multiple
73
+ * clients are mounted and the default would be ambiguous.
74
+ *
75
+ * @returns The single registered query client.
76
+ */
77
+ function useQueryClient() {
78
+ const client = getDefaultQueryClient();
79
+ if (client) return client;
80
+ if (registeredClients.size > 1) throw createAmbiguousQueryClientError();
81
+ throw createMissingQueryClientError();
82
+ }
83
+ /**
84
+ * Resolves an explicit `QueryClient` or falls back to `useQueryClient`.
85
+ *
86
+ * @param explicit - Optional client supplied by the caller.
87
+ * @returns The explicit client when provided, otherwise the current default
88
+ * client.
89
+ */
90
+ function resolveQueryClient(explicit) {
91
+ return explicit ?? useQueryClient();
92
+ }
93
+ //#endregion
94
+ //#region src/QueryClientProvider.ts
95
+ /**
96
+ * Lit element that provides a `QueryClient` to descendant Lit Query
97
+ * controllers through Lit context.
98
+ *
99
+ * The `client` is a property, not an attribute. When rendering this element in
100
+ * a Lit template, bind it with property binding: `.client=${queryClient}`.
101
+ * The provider throws if it connects without a client, or if an already
102
+ * connected provider has its client cleared.
103
+ *
104
+ * This class is not registered as a custom element by the package. Applications
105
+ * must register either a subclass or the class itself with
106
+ * `customElements.define`.
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * import { html, LitElement } from 'lit'
111
+ * import { QueryClient, QueryClientProvider } from '@tanstack/lit-query'
112
+ *
113
+ * const queryClient = new QueryClient()
114
+ *
115
+ * class AppQueryProvider extends QueryClientProvider {
116
+ * constructor() {
117
+ * super()
118
+ * this.client = queryClient
119
+ * }
120
+ * }
121
+ *
122
+ * customElements.define('app-query-provider', AppQueryProvider)
123
+ *
124
+ * class AppRoot extends LitElement {
125
+ * render() {
126
+ * return html`<app-query-provider><todos-view></todos-view></app-query-provider>`
127
+ * }
128
+ * }
129
+ * ```
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * import { html } from 'lit'
134
+ * import { QueryClient, QueryClientProvider } from '@tanstack/lit-query'
135
+ *
136
+ * const queryClient = new QueryClient()
137
+ *
138
+ * customElements.define('query-client-provider', QueryClientProvider)
139
+ *
140
+ * const view = html`
141
+ * <query-client-provider .client=${queryClient}>
142
+ * <todos-view></todos-view>
143
+ * </query-client-provider>
144
+ * `
145
+ * ```
146
+ */
147
+ var QueryClientProvider = class extends LitElement {
148
+ static {
149
+ this.properties = { client: { attribute: false } };
150
+ }
151
+ constructor() {
152
+ super();
153
+ this.contextProvider = new ContextProvider(this, { context: queryClientContext });
154
+ }
155
+ /** @internal */
156
+ connectedCallback() {
157
+ super.connectedCallback();
158
+ const client = this.requireClient();
159
+ this.contextProvider.setValue(client);
160
+ this.mountClient(client);
161
+ }
162
+ /** @internal */
163
+ disconnectedCallback() {
164
+ this.unmountClient(this.mountedClient);
165
+ super.disconnectedCallback();
166
+ }
167
+ /** @internal */
168
+ willUpdate(changedProperties) {
169
+ if (!changedProperties.has("client")) return;
170
+ const nextClient = this.client;
171
+ if (!nextClient) {
172
+ if (this.isConnected) {
173
+ this.unmountClient(this.mountedClient);
174
+ this.contextProvider.setValue(void 0);
175
+ throw createMissingQueryClientError();
176
+ }
177
+ return;
178
+ }
179
+ const previousClient = changedProperties.get("client");
180
+ if (previousClient && previousClient !== nextClient && this.isConnected) this.unmountClient(previousClient);
181
+ this.contextProvider.setValue(nextClient);
182
+ if (this.isConnected) this.mountClient(nextClient);
183
+ }
184
+ /** @internal */
185
+ render() {
186
+ return html`<slot></slot>`;
187
+ }
188
+ mountClient(client) {
189
+ if (this.mountedClient === client) return;
190
+ if (this.mountedClient) this.unmountClient(this.mountedClient);
191
+ client.mount();
192
+ registerDefaultQueryClient(client);
193
+ this.mountedClient = client;
194
+ }
195
+ unmountClient(client) {
196
+ if (!client) return;
197
+ client.unmount();
198
+ unregisterDefaultQueryClient(client);
199
+ if (this.mountedClient === client) this.mountedClient = void 0;
200
+ }
201
+ requireClient() {
202
+ if (!this.client) throw createMissingQueryClientError();
203
+ return this.client;
204
+ }
205
+ };
206
+ //#endregion
207
+ //#region src/accessor.ts
208
+ function readAccessor(value) {
209
+ return typeof value === "function" ? value() : value;
210
+ }
211
+ function createValueAccessor(getter) {
212
+ const accessor = (() => getter());
213
+ Object.defineProperty(accessor, "current", {
214
+ get: getter,
215
+ enumerable: true
216
+ });
217
+ return accessor;
218
+ }
219
+ //#endregion
220
+ //#region src/controllers/BaseController.ts
221
+ var BaseController = class {
222
+ constructor(host, initialResult, queryClient) {
223
+ this.host = host;
224
+ this.connected = false;
225
+ this.destroyed = false;
226
+ this.updateQueued = false;
227
+ this.clientChangeQueued = false;
228
+ this.connectionAttempt = 0;
229
+ this.isHostUpdating = false;
230
+ this.explicitClient = queryClient;
231
+ this.result = initialResult;
232
+ this.queryClientResolutionState = queryClient ? "bound" : "pre-connect";
233
+ host.addController(this);
234
+ }
235
+ hostConnected() {
236
+ if (this.connected || this.destroyed) return;
237
+ this.connected = true;
238
+ let contextResolutionAttempt;
239
+ if (this.explicitClient) this.queryClientResolutionState = "bound";
240
+ else {
241
+ contextResolutionAttempt = ++this.connectionAttempt;
242
+ this.beginContextResolution();
243
+ }
244
+ queueMicrotask(() => {
245
+ if (this.connected && !this.destroyed) this.onConnected();
246
+ });
247
+ if (contextResolutionAttempt !== void 0) this.queueContextResolution(contextResolutionAttempt);
248
+ }
249
+ hostDisconnected() {
250
+ if (!this.connected) return;
251
+ this.connected = false;
252
+ if (!this.explicitClient) {
253
+ this.connectionAttempt += 1;
254
+ this.clearContextClient();
255
+ this.updateQueryClientResolutionState("pre-connect");
256
+ }
257
+ this.onDisconnected();
258
+ }
259
+ hostUpdate() {
260
+ if (this.destroyed) return;
261
+ this.isHostUpdating = true;
262
+ try {
263
+ this.onHostUpdate();
264
+ } finally {
265
+ this.isHostUpdating = false;
266
+ }
267
+ }
268
+ destroy() {
269
+ if (this.destroyed) return;
270
+ this.destroyed = true;
271
+ this.connected = false;
272
+ this.connectionAttempt += 1;
273
+ this.clearContextClient();
274
+ this.queryClientResolutionState = this.explicitClient ? "bound" : "pre-connect";
275
+ this.onDisconnected();
276
+ if ("removeController" in this.host) this.host.removeController(this);
277
+ }
278
+ tryGetQueryClient() {
279
+ return this.explicitClient ?? this.contextClient;
280
+ }
281
+ getQueryClient() {
282
+ const client = this.tryGetQueryClient();
283
+ if (!client) throw createMissingQueryClientError();
284
+ return client;
285
+ }
286
+ setResult(next) {
287
+ if (Object.is(this.result, next)) return;
288
+ this.result = next;
289
+ if (!this.isHostUpdating) this.queueUpdate();
290
+ }
291
+ get current() {
292
+ if (this.queryClientResolutionState === "missing") throw createMissingQueryClientError();
293
+ return this.result;
294
+ }
295
+ get connectedState() {
296
+ return this.connected;
297
+ }
298
+ queueUpdate() {
299
+ if (this.updateQueued) return;
300
+ this.updateQueued = true;
301
+ queueMicrotask(() => {
302
+ this.updateQueued = false;
303
+ if (!this.destroyed) this.host.requestUpdate();
304
+ });
305
+ }
306
+ queueQueryClientChanged() {
307
+ if (this.clientChangeQueued) return;
308
+ this.clientChangeQueued = true;
309
+ queueMicrotask(() => {
310
+ this.clientChangeQueued = false;
311
+ if (!this.destroyed) this.onQueryClientChanged();
312
+ });
313
+ }
314
+ beginContextResolution() {
315
+ this.clearContextClient();
316
+ this.updateQueryClientResolutionState("awaiting-context");
317
+ }
318
+ queueContextResolution(attempt) {
319
+ queueMicrotask(() => {
320
+ if (this.destroyed || !this.connected || attempt !== this.connectionAttempt || this.queryClientResolutionState !== "awaiting-context") return;
321
+ this.dispatchContextRequest(attempt);
322
+ this.queueInitialContextResolutionCompletion(attempt);
323
+ });
324
+ }
325
+ dispatchContextRequest(attempt) {
326
+ if (!("dispatchEvent" in this.host)) return;
327
+ const contextTarget = this.host;
328
+ contextTarget.dispatchEvent(new ContextEvent(queryClientContext, contextTarget, (value, unsubscribe) => {
329
+ if (this.destroyed || !this.connected || attempt !== this.connectionAttempt) {
330
+ unsubscribe?.();
331
+ return;
332
+ }
333
+ if (this.contextUnsubscribe && this.contextUnsubscribe !== unsubscribe) this.contextUnsubscribe();
334
+ const resolutionChanged = this.updateQueryClientResolutionState(value === void 0 ? "missing" : "bound");
335
+ const clientChanged = this.contextClient !== value;
336
+ this.contextClient = value;
337
+ this.contextUnsubscribe = unsubscribe;
338
+ if (resolutionChanged || clientChanged) {
339
+ this.queueUpdate();
340
+ this.queueQueryClientChanged();
341
+ }
342
+ }, true));
343
+ }
344
+ queueInitialContextResolutionCompletion(attempt) {
345
+ queueMicrotask(() => {
346
+ if (this.destroyed || !this.connected || attempt !== this.connectionAttempt || this.queryClientResolutionState !== "awaiting-context") return;
347
+ if (this.updateQueryClientResolutionState("missing")) {
348
+ this.queueUpdate();
349
+ this.queueQueryClientChanged();
350
+ }
351
+ });
352
+ }
353
+ clearContextClient() {
354
+ this.contextUnsubscribe?.();
355
+ this.contextUnsubscribe = void 0;
356
+ this.contextClient = void 0;
357
+ }
358
+ updateQueryClientResolutionState(nextState) {
359
+ if (this.queryClientResolutionState === nextState) return false;
360
+ this.queryClientResolutionState = nextState;
361
+ return true;
362
+ }
363
+ };
364
+ //#endregion
365
+ //#region src/queryObserverResultTracker.ts
366
+ var QueryObserverResultTracker = class {
367
+ constructor() {
368
+ this.usesTracking = false;
369
+ }
370
+ reset() {
371
+ this.result = void 0;
372
+ this.usesTracking = false;
373
+ }
374
+ update(observer, result) {
375
+ const usesTracking = !!observer && !observer.options.notifyOnChangeProps;
376
+ if (Object.is(this.result, result) && this.usesTracking === usesTracking) return;
377
+ this.result = result;
378
+ this.usesTracking = usesTracking;
379
+ return usesTracking ? observer.trackResult(result) : result;
380
+ }
381
+ };
382
+ //#endregion
383
+ //#region src/createInfiniteQueryController.ts
384
+ function createPendingInfiniteQueryResult() {
385
+ return {
386
+ data: void 0,
387
+ dataUpdatedAt: 0,
388
+ error: null,
389
+ errorUpdatedAt: 0,
390
+ failureCount: 0,
391
+ failureReason: null,
392
+ errorUpdateCount: 0,
393
+ isError: false,
394
+ isFetched: false,
395
+ isFetchedAfterMount: false,
396
+ isFetching: false,
397
+ isInitialLoading: false,
398
+ isLoading: false,
399
+ isLoadingError: false,
400
+ isPaused: false,
401
+ isPending: true,
402
+ isPlaceholderData: false,
403
+ isRefetchError: false,
404
+ isRefetching: false,
405
+ isStale: true,
406
+ isEnabled: true,
407
+ isSuccess: false,
408
+ fetchStatus: "idle",
409
+ status: "pending",
410
+ refetch: (() => Promise.reject(createMissingQueryClientError())),
411
+ fetchNextPage: (() => Promise.reject(createMissingQueryClientError())),
412
+ fetchPreviousPage: (() => Promise.reject(createMissingQueryClientError())),
413
+ hasNextPage: false,
414
+ hasPreviousPage: false,
415
+ isFetchNextPageError: false,
416
+ isFetchingNextPage: false,
417
+ isFetchPreviousPageError: false,
418
+ isFetchingPreviousPage: false
419
+ };
420
+ }
421
+ var InfiniteQueryController = class extends BaseController {
422
+ constructor(host, options, queryClient) {
423
+ super(host, createPendingInfiniteQueryResult(), queryClient);
424
+ this.resultTracker = new QueryObserverResultTracker();
425
+ this.refetch = (...args) => {
426
+ if (!this.applyOptions() || !this.observer) return Promise.reject(createMissingQueryClientError());
427
+ return this.observer.refetch(...args);
428
+ };
429
+ this.fetchNextPage = (...args) => {
430
+ if (!this.applyOptions() || !this.observer) return Promise.reject(createMissingQueryClientError());
431
+ return this.observer.fetchNextPage(...args);
432
+ };
433
+ this.fetchPreviousPage = (...args) => {
434
+ if (!this.applyOptions() || !this.observer) return Promise.reject(createMissingQueryClientError());
435
+ return this.observer.fetchPreviousPage(...args);
436
+ };
437
+ this.options = options;
438
+ if (!queryClient) return;
439
+ if (typeof options === "function") return;
440
+ const defaulted = this.defaultOptions(queryClient);
441
+ const observer = new InfiniteQueryObserver(queryClient, defaulted);
442
+ this.queryClient = queryClient;
443
+ this.observer = observer;
444
+ this.assignObserverResult(observer.getOptimisticResult(defaulted));
445
+ }
446
+ onConnected() {
447
+ if (!this.syncClient()) return;
448
+ this.refreshOptions();
449
+ this.subscribe();
450
+ this.observer?.updateResult();
451
+ if (this.observer) this.setObserverResult(this.observer.getCurrentResult());
452
+ }
453
+ onDisconnected() {
454
+ this.unsubscribeObserver();
455
+ this.syncClient();
456
+ }
457
+ onHostUpdate() {
458
+ if (typeof this.options !== "function") return;
459
+ this.refreshOptions();
460
+ }
461
+ onQueryClientChanged() {
462
+ if (!this.syncClient() || !this.connectedState) return;
463
+ this.refreshOptions();
464
+ this.subscribe();
465
+ this.observer?.updateResult();
466
+ if (this.observer) this.setObserverResult(this.observer.getCurrentResult());
467
+ }
468
+ readCurrent() {
469
+ if (this.observer) this.assignObserverResult(this.observer.getCurrentResult());
470
+ return this.current;
471
+ }
472
+ subscribe() {
473
+ if (!this.observer) return;
474
+ if (this.unsubscribe) return;
475
+ this.unsubscribe = this.observer.subscribe((next) => {
476
+ this.setObserverResult(next);
477
+ });
478
+ }
479
+ unsubscribeObserver() {
480
+ this.unsubscribe?.();
481
+ this.unsubscribe = void 0;
482
+ }
483
+ syncClient() {
484
+ const nextClient = this.tryGetQueryClient();
485
+ if (!nextClient) {
486
+ this.unsubscribeObserver();
487
+ this.queryClient = void 0;
488
+ this.observer = void 0;
489
+ this.resultTracker.reset();
490
+ this.setResult(createPendingInfiniteQueryResult());
491
+ return false;
492
+ }
493
+ if (nextClient === this.queryClient) return true;
494
+ this.unsubscribeObserver();
495
+ this.queryClient = nextClient;
496
+ const options = this.defaultOptions(this.queryClient);
497
+ this.observer = new InfiniteQueryObserver(this.queryClient, options);
498
+ this.setObserverResult(this.observer.getOptimisticResult(options));
499
+ return true;
500
+ }
501
+ applyOptions() {
502
+ if (!this.syncClient() || !this.observer || !this.queryClient) return false;
503
+ const options = this.defaultOptions(this.queryClient);
504
+ this.observer.setOptions(options);
505
+ return true;
506
+ }
507
+ refreshOptions() {
508
+ if (!this.applyOptions() || !this.observer) return false;
509
+ this.setObserverResult(this.observer.getCurrentResult());
510
+ return true;
511
+ }
512
+ assignObserverResult(result) {
513
+ const trackedResult = this.resultTracker.update(this.observer, result);
514
+ if (trackedResult) this.result = trackedResult;
515
+ }
516
+ setObserverResult(result) {
517
+ const trackedResult = this.resultTracker.update(this.observer, result);
518
+ if (trackedResult) this.setResult(trackedResult);
519
+ }
520
+ defaultOptions(client = this.queryClient) {
521
+ if (!client) throw createMissingQueryClientError();
522
+ const defaulted = client.defaultQueryOptions(readAccessor(this.options));
523
+ defaulted._optimisticResults = "optimistic";
524
+ return defaulted;
525
+ }
526
+ };
527
+ /**
528
+ * Creates a Lit reactive controller that subscribes the host to an infinite
529
+ * query.
530
+ *
531
+ * The returned accessor is callable and also exposes `current`, `refetch`,
532
+ * `fetchNextPage`, `fetchPreviousPage`, and `destroy`. When `options` is a
533
+ * function, it is re-read during host updates so query keys and options can
534
+ * follow reactive host state.
535
+ *
536
+ * If `queryClient` is omitted, the controller resolves the client from the
537
+ * nearest connected `QueryClientProvider`.
538
+ *
539
+ * @param host - The Lit reactive controller host that owns the infinite query
540
+ * subscription.
541
+ * @param options - Infinite query observer options, or a getter that returns
542
+ * options.
543
+ * @param queryClient - Optional explicit query client. Provide this for
544
+ * controllers that should not resolve a client from Lit context.
545
+ * @returns An accessor for the latest infinite query result with page helper
546
+ * methods.
547
+ *
548
+ * @example
549
+ * ```ts
550
+ * import { LitElement, html } from 'lit'
551
+ * import { createInfiniteQueryController } from '@tanstack/lit-query'
552
+ *
553
+ * class ProjectsView extends LitElement {
554
+ * private readonly projects = createInfiniteQueryController(this, {
555
+ * queryKey: ['projects'],
556
+ * queryFn: ({ pageParam }) => fetchProjects(pageParam),
557
+ * initialPageParam: 0,
558
+ * getNextPageParam: (lastPage) => lastPage.nextCursor,
559
+ * })
560
+ *
561
+ * render() {
562
+ * const query = this.projects()
563
+ *
564
+ * return html`
565
+ * <button ?disabled=${!query.hasNextPage} @click=${() => this.projects.fetchNextPage()}>
566
+ * Load more
567
+ * </button>
568
+ * `
569
+ * }
570
+ * }
571
+ * ```
572
+ */
573
+ function createInfiniteQueryController(host, options, queryClient) {
574
+ const controller = new InfiniteQueryController(host, options, queryClient);
575
+ return Object.assign(createValueAccessor(() => controller.readCurrent()), {
576
+ refetch: controller.refetch,
577
+ fetchNextPage: controller.fetchNextPage,
578
+ fetchPreviousPage: controller.fetchPreviousPage,
579
+ destroy: () => controller.destroy()
580
+ });
581
+ }
582
+ //#endregion
583
+ //#region src/createMutationController.ts
584
+ function createIdleMutationResult() {
585
+ return {
586
+ context: void 0,
587
+ data: void 0,
588
+ error: null,
589
+ failureCount: 0,
590
+ failureReason: null,
591
+ isError: false,
592
+ isIdle: true,
593
+ isPending: false,
594
+ isPaused: false,
595
+ isSuccess: false,
596
+ status: "idle",
597
+ submittedAt: 0,
598
+ variables: void 0,
599
+ mutate: (() => Promise.reject(createMissingQueryClientError())),
600
+ reset: (() => void 0)
601
+ };
602
+ }
603
+ var MutationController = class extends BaseController {
604
+ constructor(host, options, queryClient) {
605
+ super(host, createIdleMutationResult(), queryClient);
606
+ this.mutate = (...args) => {
607
+ if (!this.syncClient() || !this.observer) throw createMissingQueryClientError();
608
+ this.observer.mutate(args[0], args[1]).catch(() => {});
609
+ };
610
+ this.mutateAsync = (...args) => {
611
+ if (!this.syncClient() || !this.observer) return Promise.reject(createMissingQueryClientError());
612
+ return this.observer.mutate(args[0], args[1]);
613
+ };
614
+ this.reset = () => {
615
+ if (!this.syncClient() || !this.observer) return;
616
+ this.observer.reset();
617
+ this.setResult(this.observer.getCurrentResult());
618
+ };
619
+ this.options = options;
620
+ if (!queryClient) return;
621
+ if (typeof options === "function") return;
622
+ const observer = new MutationObserver(queryClient, this.defaultOptions(queryClient));
623
+ this.queryClient = queryClient;
624
+ this.observer = observer;
625
+ this.result = observer.getCurrentResult();
626
+ }
627
+ onConnected() {
628
+ if (!this.syncClient()) return;
629
+ this.refreshOptions();
630
+ this.subscribe();
631
+ if (this.observer) this.setResult(this.observer.getCurrentResult());
632
+ }
633
+ onDisconnected() {
634
+ this.unsubscribeObserver();
635
+ this.syncClient();
636
+ }
637
+ onHostUpdate() {
638
+ if (typeof this.options !== "function") return;
639
+ this.refreshOptions();
640
+ }
641
+ onQueryClientChanged() {
642
+ if (!this.syncClient() || !this.connectedState) return;
643
+ this.refreshOptions();
644
+ this.subscribe();
645
+ if (this.observer) this.setResult(this.observer.getCurrentResult());
646
+ }
647
+ subscribe() {
648
+ if (!this.observer) return;
649
+ if (this.unsubscribe) return;
650
+ this.unsubscribe = this.observer.subscribe((next) => {
651
+ this.setResult(next);
652
+ });
653
+ }
654
+ unsubscribeObserver() {
655
+ this.unsubscribe?.();
656
+ this.unsubscribe = void 0;
657
+ }
658
+ syncClient() {
659
+ const nextClient = this.tryGetQueryClient();
660
+ if (!nextClient) {
661
+ this.unsubscribeObserver();
662
+ this.queryClient = void 0;
663
+ this.observer = void 0;
664
+ this.setResult(createIdleMutationResult());
665
+ return false;
666
+ }
667
+ if (nextClient === this.queryClient) return true;
668
+ this.unsubscribeObserver();
669
+ this.queryClient = nextClient;
670
+ this.observer = new MutationObserver(this.queryClient, this.defaultOptions(this.queryClient));
671
+ this.setResult(this.observer.getCurrentResult());
672
+ return true;
673
+ }
674
+ refreshOptions() {
675
+ if (!this.syncClient() || !this.observer || !this.queryClient) return false;
676
+ this.observer.setOptions(this.defaultOptions());
677
+ this.setResult(this.observer.getCurrentResult());
678
+ return true;
679
+ }
680
+ defaultOptions(client = this.queryClient) {
681
+ if (!client) throw createMissingQueryClientError();
682
+ return client.defaultMutationOptions(readAccessor(this.options));
683
+ }
684
+ };
685
+ /**
686
+ * Creates a Lit reactive controller that subscribes the host to a mutation.
687
+ *
688
+ * The returned accessor is callable and also exposes `current`, `mutate`,
689
+ * `mutateAsync`, `reset`, and `destroy`. When `options` is a function, it is
690
+ * re-read during host updates so mutation options can follow reactive host
691
+ * state.
692
+ *
693
+ * If `queryClient` is omitted, the controller resolves the client from the
694
+ * nearest connected `QueryClientProvider`.
695
+ *
696
+ * @param host - The Lit reactive controller host that owns the mutation
697
+ * subscription.
698
+ * @param options - Mutation observer options, or a getter that returns options.
699
+ * @param queryClient - Optional explicit query client. Provide this for
700
+ * controllers that should not resolve a client from Lit context.
701
+ * @returns An accessor for the latest mutation result with mutation helper
702
+ * methods.
703
+ *
704
+ * @example
705
+ * ```ts
706
+ * import { LitElement, html } from 'lit'
707
+ * import { createMutationController } from '@tanstack/lit-query'
708
+ *
709
+ * class AddTodoForm extends LitElement {
710
+ * private readonly addTodo = createMutationController(this, {
711
+ * mutationFn: (title: string) =>
712
+ * fetch('/api/todos', { method: 'POST', body: JSON.stringify({ title }) }),
713
+ * })
714
+ *
715
+ * render() {
716
+ * const mutation = this.addTodo()
717
+ *
718
+ * return html`
719
+ * <button ?disabled=${mutation.isPending} @click=${() => this.addTodo.mutate('Ship docs')}>
720
+ * Add todo
721
+ * </button>
722
+ * `
723
+ * }
724
+ * }
725
+ * ```
726
+ */
727
+ function createMutationController(host, options, queryClient) {
728
+ const controller = new MutationController(host, options, queryClient);
729
+ return Object.assign(createValueAccessor(() => controller.current), {
730
+ mutate: controller.mutate,
731
+ mutateAsync: controller.mutateAsync,
732
+ reset: controller.reset,
733
+ destroy: () => controller.destroy()
734
+ });
735
+ }
736
+ //#endregion
737
+ //#region src/createQueriesController.ts
738
+ function createPendingQueryObserverResult() {
739
+ return {
740
+ data: void 0,
741
+ dataUpdatedAt: 0,
742
+ error: null,
743
+ errorUpdatedAt: 0,
744
+ failureCount: 0,
745
+ failureReason: null,
746
+ errorUpdateCount: 0,
747
+ isError: false,
748
+ isFetched: false,
749
+ isFetchedAfterMount: false,
750
+ isFetching: false,
751
+ isInitialLoading: false,
752
+ isLoading: false,
753
+ isLoadingError: false,
754
+ isPaused: false,
755
+ isPending: true,
756
+ isPlaceholderData: false,
757
+ isRefetchError: false,
758
+ isRefetching: false,
759
+ isStale: true,
760
+ isEnabled: true,
761
+ isSuccess: false,
762
+ fetchStatus: "idle",
763
+ status: "pending",
764
+ refetch: (() => Promise.reject(createMissingQueryClientError()))
765
+ };
766
+ }
767
+ function createPlaceholderQueryObserverResult(query) {
768
+ const initialData = typeof query.initialData === "function" ? query.initialData() : query.initialData;
769
+ if (initialData === void 0) return createPendingQueryObserverResult();
770
+ const data = query.select ? query.select(initialData) : initialData;
771
+ const initialDataUpdatedAt = typeof query.initialDataUpdatedAt === "function" ? query.initialDataUpdatedAt() : query.initialDataUpdatedAt;
772
+ return {
773
+ ...createPendingQueryObserverResult(),
774
+ data,
775
+ dataUpdatedAt: initialDataUpdatedAt ?? Date.now(),
776
+ isPending: false,
777
+ isInitialLoading: false,
778
+ isLoading: false,
779
+ isSuccess: true,
780
+ status: "success"
781
+ };
782
+ }
783
+ function resolveQueriesOptions(optionsAccessor, client) {
784
+ const resolvedOptions = readAccessor(optionsAccessor);
785
+ const resolvedQueries = readAccessor(resolvedOptions.queries);
786
+ const combine = resolvedOptions.combine;
787
+ return {
788
+ queries: resolvedQueries.map((query) => {
789
+ const defaulted = client.defaultQueryOptions(query);
790
+ defaulted._optimisticResults = "optimistic";
791
+ return defaulted;
792
+ }),
793
+ combine
794
+ };
795
+ }
796
+ var QueriesController = class QueriesController extends BaseController {
797
+ constructor(host, options, queryClient) {
798
+ super(host, [], queryClient);
799
+ this.queries = [];
800
+ this.rawResult = [];
801
+ this.placeholderInitialized = false;
802
+ this.placeholderRetryableFailure = true;
803
+ this.options = options;
804
+ queueMicrotask(() => {
805
+ this.placeholderRetryableFailure = false;
806
+ });
807
+ if (!queryClient) return;
808
+ if (this.shouldRefreshOnHostUpdate()) return;
809
+ this.tryInitializeExplicitClient(queryClient);
810
+ }
811
+ onConnected() {
812
+ if (!this.syncClient()) return;
813
+ this.refreshOptions();
814
+ this.subscribe();
815
+ }
816
+ onDisconnected() {
817
+ this.unsubscribeObserver();
818
+ this.syncClient();
819
+ }
820
+ onHostUpdate() {
821
+ if (!this.shouldRefreshOnHostUpdate()) return;
822
+ if (!this.refreshOptions()) this.setPlaceholderResult();
823
+ }
824
+ onQueryClientChanged() {
825
+ if (!this.syncClient() || !this.connectedState) return;
826
+ this.refreshOptions();
827
+ this.subscribe();
828
+ }
829
+ subscribe() {
830
+ if (!this.observer) return;
831
+ if (this.unsubscribe) return;
832
+ this.unsubscribe = this.observer.subscribe((next) => {
833
+ this.setObserverResult(next);
834
+ });
835
+ }
836
+ tryInitializeExplicitClient(queryClient) {
837
+ try {
838
+ const { queries, combine } = resolveQueriesOptions(this.options, queryClient);
839
+ this.queries = queries;
840
+ this.combine = combine;
841
+ const observer = new QueriesObserver(queryClient, this.queries, { combine: this.combine });
842
+ this.queryClient = queryClient;
843
+ this.observer = observer;
844
+ this.assignObserverResult(observer.getCurrentResult(), true);
845
+ this.explicitInitializationError = void 0;
846
+ this.placeholderInitialized = true;
847
+ return true;
848
+ } catch (error) {
849
+ this.explicitInitializationError = error;
850
+ this.queryClient = void 0;
851
+ this.observer = void 0;
852
+ return false;
853
+ }
854
+ }
855
+ retryExplicitInitializationIfNeeded() {
856
+ if (!this.explicitInitializationError || this.shouldRefreshOnHostUpdate()) return false;
857
+ const explicitClient = this.tryGetQueryClient();
858
+ if (!explicitClient) return false;
859
+ return this.tryInitializeExplicitClient(explicitClient);
860
+ }
861
+ unsubscribeObserver() {
862
+ this.unsubscribe?.();
863
+ this.unsubscribe = void 0;
864
+ }
865
+ syncClient() {
866
+ const nextClient = this.tryGetQueryClient();
867
+ if (!nextClient) {
868
+ this.unsubscribeObserver();
869
+ this.queryClient = void 0;
870
+ this.observer = void 0;
871
+ this.queries = [];
872
+ this.combine = void 0;
873
+ this.combinedResult = void 0;
874
+ this.rawResult = [];
875
+ this.setPlaceholderResult();
876
+ return false;
877
+ }
878
+ if (nextClient === this.queryClient) return true;
879
+ this.unsubscribeObserver();
880
+ this.queryClient = nextClient;
881
+ const { queries, combine } = this.readResolvedOptions();
882
+ this.queries = queries;
883
+ this.combine = combine;
884
+ this.observer = new QueriesObserver(this.queryClient, this.queries, { combine: this.combine });
885
+ this.setObserverResult(this.observer.getCurrentResult(), true);
886
+ this.placeholderInitialized = true;
887
+ return true;
888
+ }
889
+ refreshOptions() {
890
+ if (!this.syncClient() || !this.observer) return false;
891
+ const { queries, combine } = this.readResolvedOptions();
892
+ this.queries = queries;
893
+ this.combine = combine;
894
+ this.observer.setQueries(this.queries, { combine: this.combine });
895
+ this.setObserverResult(this.observer.getCurrentResult(), true);
896
+ return true;
897
+ }
898
+ readResolvedOptions(client = this.queryClient) {
899
+ if (!client) throw createMissingQueryClientError();
900
+ return resolveQueriesOptions(this.options, client);
901
+ }
902
+ shouldRefreshOnHostUpdate() {
903
+ if (typeof this.options === "function") return true;
904
+ return typeof this.options.queries === "function";
905
+ }
906
+ createResult(rawResult) {
907
+ const trackedResult = this.trackResult(rawResult);
908
+ const combine = this.combine;
909
+ if (!combine) return trackedResult;
910
+ this.combinedResult = replaceEqualDeep(this.combinedResult, combine(trackedResult));
911
+ return this.combinedResult;
912
+ }
913
+ assignObserverResult(rawResult, force = false) {
914
+ if (!force && this.hasObserverResult(rawResult)) return;
915
+ this.rawResult = rawResult;
916
+ this.result = this.createResult(rawResult);
917
+ }
918
+ setObserverResult(rawResult, force = false) {
919
+ if (!force && this.hasObserverResult(rawResult)) return;
920
+ this.rawResult = rawResult;
921
+ this.setResult(this.createResult(rawResult));
922
+ }
923
+ hasObserverResult(rawResult) {
924
+ return this.rawResult.length === rawResult.length && rawResult.every((result, index) => Object.is(this.rawResult[index], result));
925
+ }
926
+ getCurrentObserverResults() {
927
+ if (!this.observer) return [];
928
+ return this.observer.getObservers().map((observer) => observer.getCurrentResult());
929
+ }
930
+ trackResult(rawResult) {
931
+ if (!this.observer) return rawResult;
932
+ const observers = this.observer.getObservers();
933
+ return rawResult.map((result, index) => {
934
+ const observer = observers[index];
935
+ if (!observer || observer.options.notifyOnChangeProps) return result;
936
+ return observer.trackResult(result, (accessedProp) => {
937
+ observers.forEach((observer) => {
938
+ observer.trackProp(accessedProp);
939
+ });
940
+ });
941
+ });
942
+ }
943
+ static createPlaceholderResult(optionsAccessor) {
944
+ const resolvedOptions = readAccessor(optionsAccessor);
945
+ const placeholders = readAccessor(resolvedOptions.queries).map((query) => createPlaceholderQueryObserverResult(query));
946
+ return resolvedOptions.combine ? resolvedOptions.combine(placeholders) : placeholders;
947
+ }
948
+ readCurrent() {
949
+ if (this.retryExplicitInitializationIfNeeded()) return this.current;
950
+ if (this.explicitInitializationError && !this.placeholderRetryableFailure) throw this.explicitInitializationError;
951
+ if (!this.queryClient && !this.observer && !this.placeholderInitialized) try {
952
+ this.setPlaceholderResult();
953
+ } catch (error) {
954
+ if (!this.placeholderRetryableFailure) throw error;
955
+ }
956
+ if (this.observer) this.assignObserverResult(this.getCurrentObserverResults());
957
+ return this.current;
958
+ }
959
+ setPlaceholderResult() {
960
+ this.rawResult = [];
961
+ this.result = QueriesController.createPlaceholderResult(this.options);
962
+ this.placeholderInitialized = true;
963
+ }
964
+ };
965
+ /**
966
+ * Creates a Lit reactive controller that subscribes the host to multiple
967
+ * queries.
968
+ *
969
+ * The returned accessor is callable and also exposes `current` and `destroy`.
970
+ * When `options` or `options.queries` is a function, it is re-read during host
971
+ * updates so the query list can follow reactive host state.
972
+ *
973
+ * If `queryClient` is omitted, the controller resolves the client from the
974
+ * nearest connected `QueryClientProvider`.
975
+ *
976
+ * @param host - The Lit reactive controller host that owns the queries
977
+ * subscription.
978
+ * @param options - Queries controller options, or a getter that returns options.
979
+ * @param queryClient - Optional explicit query client. Provide this for
980
+ * controllers that should not resolve a client from Lit context.
981
+ * @returns An accessor for the latest query results, or the value returned by
982
+ * `combine`.
983
+ *
984
+ * @example
985
+ * ```ts
986
+ * import { LitElement, html } from 'lit'
987
+ * import { createQueriesController } from '@tanstack/lit-query'
988
+ *
989
+ * class DashboardView extends LitElement {
990
+ * private readonly dashboard = createQueriesController(this, {
991
+ * queries: [
992
+ * { queryKey: ['stats'], queryFn: fetchStats },
993
+ * { queryKey: ['projects'], queryFn: fetchProjects },
994
+ * ],
995
+ * combine: ([stats, projects]) => ({
996
+ * stats: stats.data,
997
+ * projects: projects.data ?? [],
998
+ * isPending: stats.isPending || projects.isPending,
999
+ * }),
1000
+ * })
1001
+ *
1002
+ * render() {
1003
+ * const dashboard = this.dashboard()
1004
+ * return html`<p>Projects: ${dashboard.projects.length}</p>`
1005
+ * }
1006
+ * }
1007
+ * ```
1008
+ */
1009
+ function createQueriesController(host, options, queryClient) {
1010
+ const controller = new QueriesController(host, options, queryClient);
1011
+ return Object.assign(createValueAccessor(() => controller.readCurrent()), { destroy: () => controller.destroy() });
1012
+ }
1013
+ //#endregion
1014
+ //#region src/createQueryController.ts
1015
+ function createPendingQueryResult() {
1016
+ return {
1017
+ data: void 0,
1018
+ dataUpdatedAt: 0,
1019
+ error: null,
1020
+ errorUpdatedAt: 0,
1021
+ failureCount: 0,
1022
+ failureReason: null,
1023
+ errorUpdateCount: 0,
1024
+ isError: false,
1025
+ isFetched: false,
1026
+ isFetchedAfterMount: false,
1027
+ isFetching: false,
1028
+ isInitialLoading: false,
1029
+ isLoading: false,
1030
+ isLoadingError: false,
1031
+ isPaused: false,
1032
+ isPending: true,
1033
+ isPlaceholderData: false,
1034
+ isRefetchError: false,
1035
+ isRefetching: false,
1036
+ isStale: true,
1037
+ isEnabled: true,
1038
+ isSuccess: false,
1039
+ fetchStatus: "idle",
1040
+ status: "pending",
1041
+ refetch: (() => Promise.reject(createMissingQueryClientError()))
1042
+ };
1043
+ }
1044
+ var QueryController = class extends BaseController {
1045
+ constructor(host, options, queryClient) {
1046
+ const initialClient = queryClient;
1047
+ super(host, createPendingQueryResult(), queryClient);
1048
+ this.resultTracker = new QueryObserverResultTracker();
1049
+ this.refetch = (...args) => {
1050
+ if (!this.applyOptions() || !this.observer) return Promise.reject(createMissingQueryClientError());
1051
+ return this.observer.refetch(...args);
1052
+ };
1053
+ this.suspense = async () => {
1054
+ if (!this.syncClient() || !this.observer || !this.queryClient) throw createMissingQueryClientError();
1055
+ const options = this.defaultOptions(this.queryClient);
1056
+ this.observer.setOptions(options);
1057
+ const optimistic = this.observer.getOptimisticResult(options);
1058
+ if (options.enabled !== false && optimistic.isStale) return this.observer.fetchOptimistic(options);
1059
+ return optimistic;
1060
+ };
1061
+ this.options = options;
1062
+ if (!initialClient) return;
1063
+ if (typeof options === "function") return;
1064
+ const defaulted = this.defaultOptions(initialClient);
1065
+ const observer = new QueryObserver(initialClient, defaulted);
1066
+ this.queryClient = initialClient;
1067
+ this.observer = observer;
1068
+ this.assignObserverResult(observer.getOptimisticResult(defaulted));
1069
+ }
1070
+ onConnected() {
1071
+ if (!this.syncClient()) return;
1072
+ this.refreshOptions();
1073
+ this.subscribe();
1074
+ this.observer?.updateResult();
1075
+ if (this.observer) this.setObserverResult(this.observer.getCurrentResult());
1076
+ }
1077
+ onDisconnected() {
1078
+ this.unsubscribeObserver();
1079
+ this.syncClient();
1080
+ }
1081
+ onHostUpdate() {
1082
+ if (typeof this.options !== "function") return;
1083
+ this.refreshOptions();
1084
+ }
1085
+ onQueryClientChanged() {
1086
+ if (!this.syncClient()) return;
1087
+ if (!this.connectedState) return;
1088
+ this.refreshOptions();
1089
+ this.subscribe();
1090
+ this.observer?.updateResult();
1091
+ if (this.observer) this.setObserverResult(this.observer.getCurrentResult());
1092
+ }
1093
+ readCurrent() {
1094
+ if (this.observer) this.assignObserverResult(this.observer.getCurrentResult());
1095
+ return this.current;
1096
+ }
1097
+ subscribe() {
1098
+ if (!this.observer) return;
1099
+ if (this.unsubscribe) return;
1100
+ this.unsubscribe = this.observer.subscribe((next) => {
1101
+ this.setObserverResult(next);
1102
+ });
1103
+ }
1104
+ unsubscribeObserver() {
1105
+ this.unsubscribe?.();
1106
+ this.unsubscribe = void 0;
1107
+ }
1108
+ syncClient() {
1109
+ const nextClient = this.tryGetQueryClient();
1110
+ if (!nextClient) {
1111
+ this.unsubscribeObserver();
1112
+ this.queryClient = void 0;
1113
+ this.observer = void 0;
1114
+ this.resultTracker.reset();
1115
+ this.setResult(createPendingQueryResult());
1116
+ return false;
1117
+ }
1118
+ if (nextClient === this.queryClient && this.observer) return true;
1119
+ this.unsubscribeObserver();
1120
+ this.queryClient = nextClient;
1121
+ const options = this.defaultOptions();
1122
+ this.observer = new QueryObserver(this.queryClient, options);
1123
+ this.setObserverResult(this.observer.getOptimisticResult(options));
1124
+ return true;
1125
+ }
1126
+ applyOptions() {
1127
+ if (!this.syncClient() || !this.observer) return false;
1128
+ const options = this.defaultOptions(this.queryClient);
1129
+ this.observer.setOptions(options);
1130
+ return true;
1131
+ }
1132
+ refreshOptions() {
1133
+ if (!this.applyOptions() || !this.observer) return false;
1134
+ this.setObserverResult(this.observer.getCurrentResult());
1135
+ return true;
1136
+ }
1137
+ assignObserverResult(result) {
1138
+ const trackedResult = this.resultTracker.update(this.observer, result);
1139
+ if (trackedResult) this.result = trackedResult;
1140
+ }
1141
+ setObserverResult(result) {
1142
+ const trackedResult = this.resultTracker.update(this.observer, result);
1143
+ if (trackedResult) this.setResult(trackedResult);
1144
+ }
1145
+ defaultOptions(client = this.queryClient) {
1146
+ const resolvedClient = client ?? this.tryGetQueryClient();
1147
+ if (!resolvedClient) throw createMissingQueryClientError();
1148
+ this.queryClient = resolvedClient;
1149
+ const defaulted = resolvedClient.defaultQueryOptions(readAccessor(this.options));
1150
+ defaulted._optimisticResults = "optimistic";
1151
+ return defaulted;
1152
+ }
1153
+ };
1154
+ /**
1155
+ * Creates a Lit reactive controller that subscribes the host to a single query.
1156
+ *
1157
+ * The returned accessor is callable and also exposes `current`, `refetch`,
1158
+ * `suspense`, and `destroy`. When `options` is a function, it is re-read during
1159
+ * host updates so query keys and options can follow reactive host state.
1160
+ *
1161
+ * If `queryClient` is omitted, the controller resolves the client from the
1162
+ * nearest connected `QueryClientProvider`.
1163
+ *
1164
+ * @param host - The Lit reactive controller host that owns the query
1165
+ * subscription.
1166
+ * @param options - Query observer options, or a getter that returns options.
1167
+ * @param queryClient - Optional explicit query client. Provide this for
1168
+ * controllers that should not resolve a client from Lit context.
1169
+ * @returns An accessor for the latest query result with query helper methods.
1170
+ *
1171
+ * @example
1172
+ * ```ts
1173
+ * import { LitElement, html } from 'lit'
1174
+ * import { createQueryController } from '@tanstack/lit-query'
1175
+ *
1176
+ * class TodosView extends LitElement {
1177
+ * private readonly todos = createQueryController(this, {
1178
+ * queryKey: ['todos'],
1179
+ * queryFn: async () => fetch('/api/todos').then((r) => r.json()),
1180
+ * })
1181
+ *
1182
+ * render() {
1183
+ * const query = this.todos()
1184
+ *
1185
+ * if (query.isPending) return html`Loading...`
1186
+ * if (query.isError) return html`Error`
1187
+ *
1188
+ * return html`<ul>${query.data.map((todo) => html`<li>${todo.title}</li>`)}</ul>`
1189
+ * }
1190
+ * }
1191
+ * ```
1192
+ */
1193
+ function createQueryController(host, options, queryClient) {
1194
+ const controller = new QueryController(host, options, queryClient);
1195
+ return Object.assign(createValueAccessor(() => controller.readCurrent()), {
1196
+ refetch: controller.refetch,
1197
+ suspense: controller.suspense,
1198
+ destroy: () => controller.destroy()
1199
+ });
1200
+ }
1201
+ //#endregion
1202
+ //#region src/useIsFetching.ts
1203
+ var IsFetchingController = class extends BaseController {
1204
+ constructor(host, filters = {}, queryClient) {
1205
+ super(host, 0, queryClient);
1206
+ this.filters = filters;
1207
+ if (!queryClient) return;
1208
+ this.queryClient = queryClient;
1209
+ this.result = this.computeValue();
1210
+ }
1211
+ onConnected() {
1212
+ if (!this.syncClient()) {
1213
+ this.setResult(0);
1214
+ return;
1215
+ }
1216
+ this.subscribe();
1217
+ this.setResult(this.computeValue());
1218
+ }
1219
+ onDisconnected() {
1220
+ this.unsubscribe?.();
1221
+ this.unsubscribe = void 0;
1222
+ this.syncClient();
1223
+ }
1224
+ onHostUpdate() {
1225
+ if (typeof this.filters !== "function") return;
1226
+ this.setResult(this.syncClient() ? this.computeValue() : 0);
1227
+ }
1228
+ onQueryClientChanged() {
1229
+ if (!this.syncClient()) {
1230
+ this.setResult(0);
1231
+ return;
1232
+ }
1233
+ if (this.connectedState) {
1234
+ this.subscribe();
1235
+ this.setResult(this.computeValue());
1236
+ }
1237
+ }
1238
+ syncClient() {
1239
+ const nextClient = this.tryGetQueryClient();
1240
+ if (!nextClient) {
1241
+ this.unsubscribe?.();
1242
+ this.unsubscribe = void 0;
1243
+ this.queryClient = void 0;
1244
+ return false;
1245
+ }
1246
+ if (nextClient === this.queryClient) return true;
1247
+ this.unsubscribe?.();
1248
+ this.unsubscribe = void 0;
1249
+ this.queryClient = nextClient;
1250
+ return true;
1251
+ }
1252
+ subscribe() {
1253
+ if (!this.queryClient) return;
1254
+ if (this.unsubscribe) return;
1255
+ this.unsubscribe = this.queryClient.getQueryCache().subscribe(() => {
1256
+ this.setResult(this.computeValue());
1257
+ });
1258
+ }
1259
+ computeValue() {
1260
+ if (!this.queryClient) return 0;
1261
+ return this.queryClient.isFetching(readAccessor(this.filters));
1262
+ }
1263
+ };
1264
+ /**
1265
+ * Creates a Lit reactive controller that tracks how many matching queries are
1266
+ * currently fetching.
1267
+ *
1268
+ * When `filters` is a function, it is re-read during host updates so the count
1269
+ * can follow reactive host state. If `queryClient` is omitted, the controller
1270
+ * resolves the client from the nearest connected `QueryClientProvider`.
1271
+ *
1272
+ * @param host - The Lit reactive controller host that owns the cache
1273
+ * subscription.
1274
+ * @param filters - Query filters, or a getter that returns query filters.
1275
+ * @param queryClient - Optional explicit query client. Provide this for
1276
+ * controllers that should not resolve a client from Lit context.
1277
+ * @returns An accessor for the current number of matching fetching queries.
1278
+ *
1279
+ * @example
1280
+ * ```ts
1281
+ * import { LitElement, html } from 'lit'
1282
+ * import { useIsFetching } from '@tanstack/lit-query'
1283
+ *
1284
+ * class TodosStatus extends LitElement {
1285
+ * private readonly todosFetching = useIsFetching(this, {
1286
+ * queryKey: ['todos'],
1287
+ * })
1288
+ *
1289
+ * render() {
1290
+ * return html`<span>${this.todosFetching()} active todo fetches</span>`
1291
+ * }
1292
+ * }
1293
+ * ```
1294
+ */
1295
+ function useIsFetching(host, filters = {}, queryClient) {
1296
+ const controller = new IsFetchingController(host, filters, queryClient);
1297
+ return Object.assign(createValueAccessor(() => controller.current), { destroy: () => controller.destroy() });
1298
+ }
1299
+ //#endregion
1300
+ //#region src/useIsMutating.ts
1301
+ var IsMutatingController = class extends BaseController {
1302
+ constructor(host, filters = {}, queryClient) {
1303
+ super(host, 0, queryClient);
1304
+ this.filters = filters;
1305
+ if (!queryClient) return;
1306
+ this.queryClient = queryClient;
1307
+ this.result = this.computeValue();
1308
+ }
1309
+ onConnected() {
1310
+ if (!this.syncClient()) {
1311
+ this.setResult(0);
1312
+ return;
1313
+ }
1314
+ this.subscribe();
1315
+ this.setResult(this.computeValue());
1316
+ }
1317
+ onDisconnected() {
1318
+ this.unsubscribe?.();
1319
+ this.unsubscribe = void 0;
1320
+ this.syncClient();
1321
+ }
1322
+ onHostUpdate() {
1323
+ if (typeof this.filters !== "function") return;
1324
+ this.setResult(this.syncClient() ? this.computeValue() : 0);
1325
+ }
1326
+ onQueryClientChanged() {
1327
+ if (!this.syncClient()) {
1328
+ this.setResult(0);
1329
+ return;
1330
+ }
1331
+ if (this.connectedState) {
1332
+ this.subscribe();
1333
+ this.setResult(this.computeValue());
1334
+ }
1335
+ }
1336
+ syncClient() {
1337
+ const nextClient = this.tryGetQueryClient();
1338
+ if (!nextClient) {
1339
+ this.unsubscribe?.();
1340
+ this.unsubscribe = void 0;
1341
+ this.queryClient = void 0;
1342
+ return false;
1343
+ }
1344
+ if (nextClient === this.queryClient) return true;
1345
+ this.unsubscribe?.();
1346
+ this.unsubscribe = void 0;
1347
+ this.queryClient = nextClient;
1348
+ return true;
1349
+ }
1350
+ subscribe() {
1351
+ if (!this.queryClient) return;
1352
+ if (this.unsubscribe) return;
1353
+ this.unsubscribe = this.queryClient.getMutationCache().subscribe(() => {
1354
+ this.setResult(this.computeValue());
1355
+ });
1356
+ }
1357
+ computeValue() {
1358
+ if (!this.queryClient) return 0;
1359
+ return this.queryClient.isMutating(readAccessor(this.filters));
1360
+ }
1361
+ };
1362
+ /**
1363
+ * Creates a Lit reactive controller that tracks how many matching mutations are
1364
+ * currently pending.
1365
+ *
1366
+ * When `filters` is a function, it is re-read during host updates so the count
1367
+ * can follow reactive host state. If `queryClient` is omitted, the controller
1368
+ * resolves the client from the nearest connected `QueryClientProvider`.
1369
+ *
1370
+ * @param host - The Lit reactive controller host that owns the cache
1371
+ * subscription.
1372
+ * @param filters - Mutation filters, or a getter that returns mutation filters.
1373
+ * @param queryClient - Optional explicit query client. Provide this for
1374
+ * controllers that should not resolve a client from Lit context.
1375
+ * @returns An accessor for the current number of matching pending mutations.
1376
+ *
1377
+ * @example
1378
+ * ```ts
1379
+ * import { LitElement, html } from 'lit'
1380
+ * import { useIsMutating } from '@tanstack/lit-query'
1381
+ *
1382
+ * class MutationStatus extends LitElement {
1383
+ * private readonly savesPending = useIsMutating(this, {
1384
+ * mutationKey: ['save-project'],
1385
+ * })
1386
+ *
1387
+ * render() {
1388
+ * return html`<span>${this.savesPending()} saves pending</span>`
1389
+ * }
1390
+ * }
1391
+ * ```
1392
+ */
1393
+ function useIsMutating(host, filters = {}, queryClient) {
1394
+ const controller = new IsMutatingController(host, filters, queryClient);
1395
+ return Object.assign(createValueAccessor(() => controller.current), { destroy: () => controller.destroy() });
1396
+ }
1397
+ //#endregion
1398
+ //#region src/useMutationState.ts
1399
+ var MutationStateController = class extends BaseController {
1400
+ constructor(host, options, queryClient) {
1401
+ super(host, [], queryClient);
1402
+ this.options = options;
1403
+ if (!queryClient) return;
1404
+ this.queryClient = queryClient;
1405
+ this.result = this.computeState();
1406
+ }
1407
+ onConnected() {
1408
+ if (!this.syncClient()) {
1409
+ this.setMutationState([]);
1410
+ return;
1411
+ }
1412
+ this.subscribe();
1413
+ this.setMutationState(this.computeState());
1414
+ }
1415
+ onDisconnected() {
1416
+ this.unsubscribe?.();
1417
+ this.unsubscribe = void 0;
1418
+ this.syncClient();
1419
+ }
1420
+ onHostUpdate() {
1421
+ if (!this.shouldRefreshOnHostUpdate()) return;
1422
+ this.setMutationState(this.syncClient() ? this.computeState() : []);
1423
+ }
1424
+ onQueryClientChanged() {
1425
+ if (!this.syncClient()) {
1426
+ this.setMutationState([]);
1427
+ return;
1428
+ }
1429
+ if (this.connectedState) {
1430
+ this.subscribe();
1431
+ this.setMutationState(this.computeState());
1432
+ }
1433
+ }
1434
+ syncClient() {
1435
+ const nextClient = this.tryGetQueryClient();
1436
+ if (!nextClient) {
1437
+ this.unsubscribe?.();
1438
+ this.unsubscribe = void 0;
1439
+ this.queryClient = void 0;
1440
+ return false;
1441
+ }
1442
+ if (nextClient === this.queryClient) return true;
1443
+ this.unsubscribe?.();
1444
+ this.unsubscribe = void 0;
1445
+ this.queryClient = nextClient;
1446
+ return true;
1447
+ }
1448
+ subscribe() {
1449
+ if (!this.queryClient) return;
1450
+ if (this.unsubscribe) return;
1451
+ this.unsubscribe = this.queryClient.getMutationCache().subscribe(() => {
1452
+ this.setMutationState(this.computeState());
1453
+ });
1454
+ }
1455
+ setMutationState(next) {
1456
+ this.setResult(replaceEqualDeep(this.result, next));
1457
+ }
1458
+ shouldRefreshOnHostUpdate() {
1459
+ return typeof this.options.filters === "function" || typeof this.options.select === "function";
1460
+ }
1461
+ computeState() {
1462
+ if (!this.queryClient) return [];
1463
+ const filters = this.options.filters ? readAccessor(this.options.filters) : void 0;
1464
+ const select = this.options.select;
1465
+ return this.queryClient.getMutationCache().findAll(filters).map((mutation) => {
1466
+ if (select) return select(mutation);
1467
+ return mutation.state;
1468
+ });
1469
+ }
1470
+ };
1471
+ /**
1472
+ * Creates a Lit reactive controller that selects state from matching mutations
1473
+ * in the mutation cache.
1474
+ *
1475
+ * When `options.filters` is a function, it is re-read during host updates so
1476
+ * the selection can follow reactive host state. If `queryClient` is omitted,
1477
+ * the controller resolves the client from the nearest connected
1478
+ * `QueryClientProvider`.
1479
+ *
1480
+ * @param host - The Lit reactive controller host that owns the mutation cache
1481
+ * subscription.
1482
+ * @param options - Mutation state filters and optional selector.
1483
+ * @param queryClient - Optional explicit query client. Provide this for
1484
+ * controllers that should not resolve a client from Lit context.
1485
+ * @returns An accessor for the selected mutation state array.
1486
+ *
1487
+ * @example
1488
+ * ```ts
1489
+ * import { LitElement, html } from 'lit'
1490
+ * import { useMutationState } from '@tanstack/lit-query'
1491
+ *
1492
+ * class PendingUploads extends LitElement {
1493
+ * private readonly uploads = useMutationState(this, {
1494
+ * filters: { mutationKey: ['upload'], status: 'pending' },
1495
+ * select: (mutation) => mutation.state.variables as File,
1496
+ * })
1497
+ *
1498
+ * render() {
1499
+ * return html`<span>${this.uploads().length} uploads pending</span>`
1500
+ * }
1501
+ * }
1502
+ * ```
1503
+ */
1504
+ function useMutationState(host, options = {}, queryClient) {
1505
+ const controller = new MutationStateController(host, options, queryClient);
1506
+ return Object.assign(createValueAccessor(() => controller.current), { destroy: () => controller.destroy() });
1507
+ }
1508
+ //#endregion
1509
+ //#region src/queryOptions.ts
1510
+ function queryOptions(options) {
1511
+ return options;
1512
+ }
1513
+ //#endregion
1514
+ //#region src/infiniteQueryOptions.ts
1515
+ function infiniteQueryOptions(options) {
1516
+ return options;
1517
+ }
1518
+ //#endregion
1519
+ //#region src/mutationOptions.ts
1520
+ /**
1521
+ * Preserves and types mutation options for reuse across Lit Query APIs.
1522
+ *
1523
+ * @param options - Mutation options to preserve.
1524
+ * @returns The same options object.
1525
+ *
1526
+ * @example
1527
+ * ```ts
1528
+ * import { mutationOptions } from '@tanstack/lit-query'
1529
+ *
1530
+ * const addTodoOptions = mutationOptions({
1531
+ * mutationKey: ['add-todo'],
1532
+ * mutationFn: (title: string) => addTodo(title),
1533
+ * })
1534
+ * ```
1535
+ */
1536
+ function mutationOptions(options) {
1537
+ return options;
1538
+ }
1539
+ //#endregion
1540
+ //#region src/index.ts
1541
+ /* istanbul ignore file */
1542
+ //#endregion
1543
+ export { QueryClientProvider, createInfiniteQueryController, createMutationController, createQueriesController, createQueryController, getDefaultQueryClient, infiniteQueryOptions, mutationOptions, queryClientContext, queryOptions, registerDefaultQueryClient, resolveQueryClient, unregisterDefaultQueryClient, useIsFetching, useIsMutating, useMutationState, useQueryClient };
1544
+
1545
+ //# sourceMappingURL=index.js.map