@tanstack/solid-query 5.30.1 → 5.30.3
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/build/dev.cjs +31 -7
- package/build/dev.js +31 -7
- package/build/index.cjs +22 -7
- package/build/index.js +22 -7
- package/package.json +1 -1
- package/src/__tests__/createQuery.test.tsx +3 -1
- package/src/createBaseQuery.ts +38 -5
package/build/dev.cjs
CHANGED
|
@@ -51,14 +51,30 @@ exports.useIsRestoring = () => solidJs.useContext(IsRestoringContext);
|
|
|
51
51
|
exports.IsRestoringProvider = IsRestoringContext.Provider;
|
|
52
52
|
|
|
53
53
|
// src/createBaseQuery.ts
|
|
54
|
-
function reconcileFn(store$1, result, reconcileOption) {
|
|
54
|
+
function reconcileFn(store$1, result, reconcileOption, queryHash) {
|
|
55
55
|
if (reconcileOption === false)
|
|
56
56
|
return result;
|
|
57
57
|
if (typeof reconcileOption === "function") {
|
|
58
58
|
const newData2 = reconcileOption(store$1.data, result.data);
|
|
59
59
|
return { ...result, data: newData2 };
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
let data = result.data;
|
|
62
|
+
if (store$1.data === void 0) {
|
|
63
|
+
try {
|
|
64
|
+
data = structuredClone(data);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
{
|
|
67
|
+
if (error instanceof Error) {
|
|
68
|
+
console.warn(
|
|
69
|
+
`Unable to correctly reconcile data for query key: ${queryHash}. Possibly because the query data contains data structures that aren't supported by the 'structuredClone' algorithm. Consider using a callback function instead to manage the reconciliation manually.
|
|
70
|
+
|
|
71
|
+
Error Received: ${error.name} - ${error.message}`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const newData = store.reconcile(data, { key: reconcileOption })(store$1.data);
|
|
62
78
|
return { ...result, data: newData };
|
|
63
79
|
}
|
|
64
80
|
var hydratableObserverResult = (query, result) => {
|
|
@@ -133,12 +149,14 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
133
149
|
});
|
|
134
150
|
};
|
|
135
151
|
function setStateWithReconciliation(res) {
|
|
136
|
-
const
|
|
152
|
+
const opts = observer().options;
|
|
153
|
+
const reconcileOptions = opts.reconcile;
|
|
137
154
|
setState((store) => {
|
|
138
155
|
return reconcileFn(
|
|
139
156
|
store,
|
|
140
157
|
res,
|
|
141
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
158
|
+
reconcileOptions === void 0 ? false : reconcileOptions,
|
|
159
|
+
opts.queryHash
|
|
142
160
|
);
|
|
143
161
|
});
|
|
144
162
|
}
|
|
@@ -155,10 +173,12 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
155
173
|
];
|
|
156
174
|
}
|
|
157
175
|
let unsubscribe = null;
|
|
176
|
+
let resolver = null;
|
|
158
177
|
const [queryResource, { refetch }] = solidJs.createResource(
|
|
159
178
|
() => {
|
|
160
179
|
const obs = observer();
|
|
161
180
|
return new Promise((resolve, reject) => {
|
|
181
|
+
resolver = resolve;
|
|
162
182
|
if (web.isServer) {
|
|
163
183
|
unsubscribe = createServerSubscriber(resolve, reject);
|
|
164
184
|
} else if (!unsubscribe && !isRestoring()) {
|
|
@@ -174,6 +194,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
174
194
|
}
|
|
175
195
|
if (!observerResult.isLoading) {
|
|
176
196
|
const query = obs.getCurrentQuery();
|
|
197
|
+
resolver = null;
|
|
177
198
|
return resolve(hydratableObserverResult(query, observerResult));
|
|
178
199
|
}
|
|
179
200
|
setStateWithReconciliation(observerResult);
|
|
@@ -211,7 +232,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
211
232
|
newOptions.refetchOnMount = false;
|
|
212
233
|
}
|
|
213
234
|
observer().setOptions(newOptions);
|
|
214
|
-
|
|
235
|
+
setStateWithReconciliation(observer().getOptimisticResult(newOptions));
|
|
215
236
|
unsubscribe = createClientSubscriber();
|
|
216
237
|
}
|
|
217
238
|
}
|
|
@@ -252,6 +273,10 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
252
273
|
unsubscribe();
|
|
253
274
|
unsubscribe = null;
|
|
254
275
|
}
|
|
276
|
+
if (resolver && !web.isServer) {
|
|
277
|
+
resolver(observerResult);
|
|
278
|
+
resolver = null;
|
|
279
|
+
}
|
|
255
280
|
});
|
|
256
281
|
solidJs.createComputed(
|
|
257
282
|
solidJs.on(
|
|
@@ -266,8 +291,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
266
291
|
const handler = {
|
|
267
292
|
get(target, prop) {
|
|
268
293
|
if (prop === "data") {
|
|
269
|
-
|
|
270
|
-
if (opts.placeholderData) {
|
|
294
|
+
if (state.data !== void 0) {
|
|
271
295
|
return queryResource.latest?.data;
|
|
272
296
|
}
|
|
273
297
|
return queryResource()?.data;
|
package/build/dev.js
CHANGED
|
@@ -50,14 +50,30 @@ var useIsRestoring = () => useContext(IsRestoringContext);
|
|
|
50
50
|
var IsRestoringProvider = IsRestoringContext.Provider;
|
|
51
51
|
|
|
52
52
|
// src/createBaseQuery.ts
|
|
53
|
-
function reconcileFn(store, result, reconcileOption) {
|
|
53
|
+
function reconcileFn(store, result, reconcileOption, queryHash) {
|
|
54
54
|
if (reconcileOption === false)
|
|
55
55
|
return result;
|
|
56
56
|
if (typeof reconcileOption === "function") {
|
|
57
57
|
const newData2 = reconcileOption(store.data, result.data);
|
|
58
58
|
return { ...result, data: newData2 };
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
let data = result.data;
|
|
61
|
+
if (store.data === void 0) {
|
|
62
|
+
try {
|
|
63
|
+
data = structuredClone(data);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
{
|
|
66
|
+
if (error instanceof Error) {
|
|
67
|
+
console.warn(
|
|
68
|
+
`Unable to correctly reconcile data for query key: ${queryHash}. Possibly because the query data contains data structures that aren't supported by the 'structuredClone' algorithm. Consider using a callback function instead to manage the reconciliation manually.
|
|
69
|
+
|
|
70
|
+
Error Received: ${error.name} - ${error.message}`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const newData = reconcile(data, { key: reconcileOption })(store.data);
|
|
61
77
|
return { ...result, data: newData };
|
|
62
78
|
}
|
|
63
79
|
var hydratableObserverResult = (query, result) => {
|
|
@@ -132,12 +148,14 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
132
148
|
});
|
|
133
149
|
};
|
|
134
150
|
function setStateWithReconciliation(res) {
|
|
135
|
-
const
|
|
151
|
+
const opts = observer().options;
|
|
152
|
+
const reconcileOptions = opts.reconcile;
|
|
136
153
|
setState((store) => {
|
|
137
154
|
return reconcileFn(
|
|
138
155
|
store,
|
|
139
156
|
res,
|
|
140
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
157
|
+
reconcileOptions === void 0 ? false : reconcileOptions,
|
|
158
|
+
opts.queryHash
|
|
141
159
|
);
|
|
142
160
|
});
|
|
143
161
|
}
|
|
@@ -154,10 +172,12 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
154
172
|
];
|
|
155
173
|
}
|
|
156
174
|
let unsubscribe = null;
|
|
175
|
+
let resolver = null;
|
|
157
176
|
const [queryResource, { refetch }] = createResource(
|
|
158
177
|
() => {
|
|
159
178
|
const obs = observer();
|
|
160
179
|
return new Promise((resolve, reject) => {
|
|
180
|
+
resolver = resolve;
|
|
161
181
|
if (isServer) {
|
|
162
182
|
unsubscribe = createServerSubscriber(resolve, reject);
|
|
163
183
|
} else if (!unsubscribe && !isRestoring()) {
|
|
@@ -173,6 +193,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
173
193
|
}
|
|
174
194
|
if (!observerResult.isLoading) {
|
|
175
195
|
const query = obs.getCurrentQuery();
|
|
196
|
+
resolver = null;
|
|
176
197
|
return resolve(hydratableObserverResult(query, observerResult));
|
|
177
198
|
}
|
|
178
199
|
setStateWithReconciliation(observerResult);
|
|
@@ -210,7 +231,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
210
231
|
newOptions.refetchOnMount = false;
|
|
211
232
|
}
|
|
212
233
|
observer().setOptions(newOptions);
|
|
213
|
-
|
|
234
|
+
setStateWithReconciliation(observer().getOptimisticResult(newOptions));
|
|
214
235
|
unsubscribe = createClientSubscriber();
|
|
215
236
|
}
|
|
216
237
|
}
|
|
@@ -251,6 +272,10 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
251
272
|
unsubscribe();
|
|
252
273
|
unsubscribe = null;
|
|
253
274
|
}
|
|
275
|
+
if (resolver && !isServer) {
|
|
276
|
+
resolver(observerResult);
|
|
277
|
+
resolver = null;
|
|
278
|
+
}
|
|
254
279
|
});
|
|
255
280
|
createComputed(
|
|
256
281
|
on(
|
|
@@ -265,8 +290,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
265
290
|
const handler = {
|
|
266
291
|
get(target, prop) {
|
|
267
292
|
if (prop === "data") {
|
|
268
|
-
|
|
269
|
-
if (opts.placeholderData) {
|
|
293
|
+
if (state.data !== void 0) {
|
|
270
294
|
return queryResource.latest?.data;
|
|
271
295
|
}
|
|
272
296
|
return queryResource()?.data;
|
package/build/index.cjs
CHANGED
|
@@ -51,14 +51,21 @@ exports.useIsRestoring = () => solidJs.useContext(IsRestoringContext);
|
|
|
51
51
|
exports.IsRestoringProvider = IsRestoringContext.Provider;
|
|
52
52
|
|
|
53
53
|
// src/createBaseQuery.ts
|
|
54
|
-
function reconcileFn(store$1, result, reconcileOption) {
|
|
54
|
+
function reconcileFn(store$1, result, reconcileOption, queryHash) {
|
|
55
55
|
if (reconcileOption === false)
|
|
56
56
|
return result;
|
|
57
57
|
if (typeof reconcileOption === "function") {
|
|
58
58
|
const newData2 = reconcileOption(store$1.data, result.data);
|
|
59
59
|
return { ...result, data: newData2 };
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
let data = result.data;
|
|
62
|
+
if (store$1.data === void 0) {
|
|
63
|
+
try {
|
|
64
|
+
data = structuredClone(data);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const newData = store.reconcile(data, { key: reconcileOption })(store$1.data);
|
|
62
69
|
return { ...result, data: newData };
|
|
63
70
|
}
|
|
64
71
|
var hydratableObserverResult = (query, result) => {
|
|
@@ -133,12 +140,14 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
133
140
|
});
|
|
134
141
|
};
|
|
135
142
|
function setStateWithReconciliation(res) {
|
|
136
|
-
const
|
|
143
|
+
const opts = observer().options;
|
|
144
|
+
const reconcileOptions = opts.reconcile;
|
|
137
145
|
setState((store) => {
|
|
138
146
|
return reconcileFn(
|
|
139
147
|
store,
|
|
140
148
|
res,
|
|
141
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
149
|
+
reconcileOptions === void 0 ? false : reconcileOptions,
|
|
150
|
+
opts.queryHash
|
|
142
151
|
);
|
|
143
152
|
});
|
|
144
153
|
}
|
|
@@ -155,10 +164,12 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
155
164
|
];
|
|
156
165
|
}
|
|
157
166
|
let unsubscribe = null;
|
|
167
|
+
let resolver = null;
|
|
158
168
|
const [queryResource, { refetch }] = solidJs.createResource(
|
|
159
169
|
() => {
|
|
160
170
|
const obs = observer();
|
|
161
171
|
return new Promise((resolve, reject) => {
|
|
172
|
+
resolver = resolve;
|
|
162
173
|
if (web.isServer) {
|
|
163
174
|
unsubscribe = createServerSubscriber(resolve, reject);
|
|
164
175
|
} else if (!unsubscribe && !isRestoring()) {
|
|
@@ -174,6 +185,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
174
185
|
}
|
|
175
186
|
if (!observerResult.isLoading) {
|
|
176
187
|
const query = obs.getCurrentQuery();
|
|
188
|
+
resolver = null;
|
|
177
189
|
return resolve(hydratableObserverResult(query, observerResult));
|
|
178
190
|
}
|
|
179
191
|
setStateWithReconciliation(observerResult);
|
|
@@ -211,7 +223,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
211
223
|
newOptions.refetchOnMount = false;
|
|
212
224
|
}
|
|
213
225
|
observer().setOptions(newOptions);
|
|
214
|
-
|
|
226
|
+
setStateWithReconciliation(observer().getOptimisticResult(newOptions));
|
|
215
227
|
unsubscribe = createClientSubscriber();
|
|
216
228
|
}
|
|
217
229
|
}
|
|
@@ -252,6 +264,10 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
252
264
|
unsubscribe();
|
|
253
265
|
unsubscribe = null;
|
|
254
266
|
}
|
|
267
|
+
if (resolver && !web.isServer) {
|
|
268
|
+
resolver(observerResult);
|
|
269
|
+
resolver = null;
|
|
270
|
+
}
|
|
255
271
|
});
|
|
256
272
|
solidJs.createComputed(
|
|
257
273
|
solidJs.on(
|
|
@@ -266,8 +282,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
266
282
|
const handler = {
|
|
267
283
|
get(target, prop) {
|
|
268
284
|
if (prop === "data") {
|
|
269
|
-
|
|
270
|
-
if (opts.placeholderData) {
|
|
285
|
+
if (state.data !== void 0) {
|
|
271
286
|
return queryResource.latest?.data;
|
|
272
287
|
}
|
|
273
288
|
return queryResource()?.data;
|
package/build/index.js
CHANGED
|
@@ -50,14 +50,21 @@ var useIsRestoring = () => useContext(IsRestoringContext);
|
|
|
50
50
|
var IsRestoringProvider = IsRestoringContext.Provider;
|
|
51
51
|
|
|
52
52
|
// src/createBaseQuery.ts
|
|
53
|
-
function reconcileFn(store, result, reconcileOption) {
|
|
53
|
+
function reconcileFn(store, result, reconcileOption, queryHash) {
|
|
54
54
|
if (reconcileOption === false)
|
|
55
55
|
return result;
|
|
56
56
|
if (typeof reconcileOption === "function") {
|
|
57
57
|
const newData2 = reconcileOption(store.data, result.data);
|
|
58
58
|
return { ...result, data: newData2 };
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
let data = result.data;
|
|
61
|
+
if (store.data === void 0) {
|
|
62
|
+
try {
|
|
63
|
+
data = structuredClone(data);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const newData = reconcile(data, { key: reconcileOption })(store.data);
|
|
61
68
|
return { ...result, data: newData };
|
|
62
69
|
}
|
|
63
70
|
var hydratableObserverResult = (query, result) => {
|
|
@@ -132,12 +139,14 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
132
139
|
});
|
|
133
140
|
};
|
|
134
141
|
function setStateWithReconciliation(res) {
|
|
135
|
-
const
|
|
142
|
+
const opts = observer().options;
|
|
143
|
+
const reconcileOptions = opts.reconcile;
|
|
136
144
|
setState((store) => {
|
|
137
145
|
return reconcileFn(
|
|
138
146
|
store,
|
|
139
147
|
res,
|
|
140
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
148
|
+
reconcileOptions === void 0 ? false : reconcileOptions,
|
|
149
|
+
opts.queryHash
|
|
141
150
|
);
|
|
142
151
|
});
|
|
143
152
|
}
|
|
@@ -154,10 +163,12 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
154
163
|
];
|
|
155
164
|
}
|
|
156
165
|
let unsubscribe = null;
|
|
166
|
+
let resolver = null;
|
|
157
167
|
const [queryResource, { refetch }] = createResource(
|
|
158
168
|
() => {
|
|
159
169
|
const obs = observer();
|
|
160
170
|
return new Promise((resolve, reject) => {
|
|
171
|
+
resolver = resolve;
|
|
161
172
|
if (isServer) {
|
|
162
173
|
unsubscribe = createServerSubscriber(resolve, reject);
|
|
163
174
|
} else if (!unsubscribe && !isRestoring()) {
|
|
@@ -173,6 +184,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
173
184
|
}
|
|
174
185
|
if (!observerResult.isLoading) {
|
|
175
186
|
const query = obs.getCurrentQuery();
|
|
187
|
+
resolver = null;
|
|
176
188
|
return resolve(hydratableObserverResult(query, observerResult));
|
|
177
189
|
}
|
|
178
190
|
setStateWithReconciliation(observerResult);
|
|
@@ -210,7 +222,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
210
222
|
newOptions.refetchOnMount = false;
|
|
211
223
|
}
|
|
212
224
|
observer().setOptions(newOptions);
|
|
213
|
-
|
|
225
|
+
setStateWithReconciliation(observer().getOptimisticResult(newOptions));
|
|
214
226
|
unsubscribe = createClientSubscriber();
|
|
215
227
|
}
|
|
216
228
|
}
|
|
@@ -251,6 +263,10 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
251
263
|
unsubscribe();
|
|
252
264
|
unsubscribe = null;
|
|
253
265
|
}
|
|
266
|
+
if (resolver && !isServer) {
|
|
267
|
+
resolver(observerResult);
|
|
268
|
+
resolver = null;
|
|
269
|
+
}
|
|
254
270
|
});
|
|
255
271
|
createComputed(
|
|
256
272
|
on(
|
|
@@ -265,8 +281,7 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
265
281
|
const handler = {
|
|
266
282
|
get(target, prop) {
|
|
267
283
|
if (prop === "data") {
|
|
268
|
-
|
|
269
|
-
if (opts.placeholderData) {
|
|
284
|
+
if (state.data !== void 0) {
|
|
270
285
|
return queryResource.latest?.data;
|
|
271
286
|
}
|
|
272
287
|
return queryResource()?.data;
|
package/package.json
CHANGED
|
@@ -1051,7 +1051,9 @@ describe('createQuery', () => {
|
|
|
1051
1051
|
count++
|
|
1052
1052
|
return count === 1 ? result1 : result2
|
|
1053
1053
|
},
|
|
1054
|
-
reconcile:
|
|
1054
|
+
reconcile: (oldData, newData) => {
|
|
1055
|
+
return reconcile(newData)(oldData)
|
|
1056
|
+
},
|
|
1055
1057
|
}))
|
|
1056
1058
|
|
|
1057
1059
|
createRenderEffect(() => {
|
package/src/createBaseQuery.ts
CHANGED
|
@@ -34,13 +34,31 @@ function reconcileFn<TData, TError>(
|
|
|
34
34
|
| string
|
|
35
35
|
| false
|
|
36
36
|
| ((oldData: TData | undefined, newData: TData) => TData),
|
|
37
|
+
queryHash?: string,
|
|
37
38
|
): QueryObserverResult<TData, TError> {
|
|
38
39
|
if (reconcileOption === false) return result
|
|
39
40
|
if (typeof reconcileOption === 'function') {
|
|
40
41
|
const newData = reconcileOption(store.data, result.data as TData)
|
|
41
42
|
return { ...result, data: newData } as typeof result
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
+
let data = result.data
|
|
45
|
+
if (store.data === undefined) {
|
|
46
|
+
try {
|
|
47
|
+
data = structuredClone(data)
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
50
|
+
if (error instanceof Error) {
|
|
51
|
+
console.warn(
|
|
52
|
+
`Unable to correctly reconcile data for query key: ${queryHash}. ` +
|
|
53
|
+
`Possibly because the query data contains data structures that aren't supported ` +
|
|
54
|
+
`by the 'structuredClone' algorithm. Consider using a callback function instead ` +
|
|
55
|
+
`to manage the reconciliation manually.\n\n Error Received: ${error.name} - ${error.message}`,
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const newData = reconcile(data, { key: reconcileOption })(store.data)
|
|
44
62
|
return { ...result, data: newData } as typeof result
|
|
45
63
|
}
|
|
46
64
|
|
|
@@ -186,14 +204,16 @@ export function createBaseQuery<
|
|
|
186
204
|
}
|
|
187
205
|
|
|
188
206
|
function setStateWithReconciliation(res: typeof observerResult) {
|
|
207
|
+
const opts = observer().options
|
|
189
208
|
// @ts-expect-error - Reconcile option is not correctly typed internally
|
|
190
|
-
const reconcileOptions =
|
|
209
|
+
const reconcileOptions = opts.reconcile
|
|
191
210
|
|
|
192
211
|
setState((store) => {
|
|
193
212
|
return reconcileFn(
|
|
194
213
|
store,
|
|
195
214
|
res,
|
|
196
215
|
reconcileOptions === undefined ? false : reconcileOptions,
|
|
216
|
+
opts.queryHash,
|
|
197
217
|
)
|
|
198
218
|
})
|
|
199
219
|
}
|
|
@@ -216,10 +236,19 @@ export function createBaseQuery<
|
|
|
216
236
|
*/
|
|
217
237
|
let unsubscribe: (() => void) | null = null
|
|
218
238
|
|
|
239
|
+
/*
|
|
240
|
+
Fixes #7275
|
|
241
|
+
In a few cases, the observer could unmount before the resource is loaded.
|
|
242
|
+
This leads to Suspense boundaries to be suspended indefinitely.
|
|
243
|
+
This resolver will be called when the observer is unmounting
|
|
244
|
+
but the resource is still in a loading state
|
|
245
|
+
*/
|
|
246
|
+
let resolver: ((value: ResourceData) => void) | null = null
|
|
219
247
|
const [queryResource, { refetch }] = createResource<ResourceData | undefined>(
|
|
220
248
|
() => {
|
|
221
249
|
const obs = observer()
|
|
222
250
|
return new Promise((resolve, reject) => {
|
|
251
|
+
resolver = resolve
|
|
223
252
|
if (isServer) {
|
|
224
253
|
unsubscribe = createServerSubscriber(resolve, reject)
|
|
225
254
|
} else if (!unsubscribe && !isRestoring()) {
|
|
@@ -241,6 +270,7 @@ export function createBaseQuery<
|
|
|
241
270
|
}
|
|
242
271
|
if (!observerResult.isLoading) {
|
|
243
272
|
const query = obs.getCurrentQuery()
|
|
273
|
+
resolver = null
|
|
244
274
|
return resolve(hydratableObserverResult(query, observerResult))
|
|
245
275
|
}
|
|
246
276
|
|
|
@@ -290,7 +320,7 @@ export function createBaseQuery<
|
|
|
290
320
|
// Setting the options as an immutable object to prevent
|
|
291
321
|
// wonky behavior with observer subscriptions
|
|
292
322
|
observer().setOptions(newOptions)
|
|
293
|
-
|
|
323
|
+
setStateWithReconciliation(observer().getOptimisticResult(newOptions))
|
|
294
324
|
unsubscribe = createClientSubscriber()
|
|
295
325
|
},
|
|
296
326
|
},
|
|
@@ -334,6 +364,10 @@ export function createBaseQuery<
|
|
|
334
364
|
unsubscribe()
|
|
335
365
|
unsubscribe = null
|
|
336
366
|
}
|
|
367
|
+
if (resolver && !isServer) {
|
|
368
|
+
resolver(observerResult)
|
|
369
|
+
resolver = null
|
|
370
|
+
}
|
|
337
371
|
})
|
|
338
372
|
|
|
339
373
|
createComputed(
|
|
@@ -353,8 +387,7 @@ export function createBaseQuery<
|
|
|
353
387
|
prop: keyof QueryObserverResult<TData, TError>,
|
|
354
388
|
): any {
|
|
355
389
|
if (prop === 'data') {
|
|
356
|
-
|
|
357
|
-
if (opts.placeholderData) {
|
|
390
|
+
if (state.data !== undefined) {
|
|
358
391
|
return queryResource.latest?.data
|
|
359
392
|
}
|
|
360
393
|
return queryResource()?.data
|