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