@tanstack/solid-query 5.29.3 → 5.30.1
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 +48 -52
- package/build/dev.js +50 -54
- package/build/index.cjs +48 -52
- package/build/index.js +50 -54
- package/package.json +1 -4
- package/src/__tests__/createQuery.test.tsx +121 -1
- package/src/createBaseQuery.ts +58 -69
- package/src/index.ts +0 -3
- package/src/setBatchUpdatesFn.ts +0 -4
package/build/dev.cjs
CHANGED
|
@@ -5,8 +5,7 @@ var solidJs = require('solid-js');
|
|
|
5
5
|
var web = require('solid-js/web');
|
|
6
6
|
var store = require('solid-js/store');
|
|
7
7
|
|
|
8
|
-
// src/
|
|
9
|
-
queryCore.notifyManager.setBatchNotifyFunction(solidJs.batch);
|
|
8
|
+
// src/index.ts
|
|
10
9
|
exports.QueryClient = class QueryClient extends queryCore.QueryClient {
|
|
11
10
|
constructor(config = {}) {
|
|
12
11
|
super(config);
|
|
@@ -103,9 +102,8 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
103
102
|
const [observer, setObserver] = solidJs.createSignal(
|
|
104
103
|
new Observer(client(), defaultedOptions())
|
|
105
104
|
);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
);
|
|
105
|
+
let observerResult = observer().getOptimisticResult(defaultedOptions());
|
|
106
|
+
const [state, setState] = store.createStore(observerResult);
|
|
109
107
|
const createServerSubscriber = (resolve, reject) => {
|
|
110
108
|
return observer().subscribe((result) => {
|
|
111
109
|
queryCore.notifyManager.batchCalls(() => {
|
|
@@ -130,32 +128,34 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
130
128
|
const createClientSubscriber = () => {
|
|
131
129
|
const obs = observer();
|
|
132
130
|
return obs.subscribe((result) => {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (!queryResource.error && queryResource()?.data && result.data && !queryResource.loading) {
|
|
136
|
-
setState((store) => {
|
|
137
|
-
return reconcileFn(
|
|
138
|
-
store,
|
|
139
|
-
result,
|
|
140
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
141
|
-
);
|
|
142
|
-
});
|
|
143
|
-
mutate(state);
|
|
144
|
-
} else {
|
|
145
|
-
setState((store) => {
|
|
146
|
-
return reconcileFn(
|
|
147
|
-
store,
|
|
148
|
-
result,
|
|
149
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
150
|
-
);
|
|
151
|
-
});
|
|
152
|
-
refetch();
|
|
153
|
-
}
|
|
154
|
-
})();
|
|
131
|
+
observerResult = result;
|
|
132
|
+
queueMicrotask(() => refetch());
|
|
155
133
|
});
|
|
156
134
|
};
|
|
135
|
+
function setStateWithReconciliation(res) {
|
|
136
|
+
const reconcileOptions = observer().options.reconcile;
|
|
137
|
+
setState((store) => {
|
|
138
|
+
return reconcileFn(
|
|
139
|
+
store,
|
|
140
|
+
res,
|
|
141
|
+
reconcileOptions === void 0 ? false : reconcileOptions
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function createDeepSignal() {
|
|
146
|
+
return [
|
|
147
|
+
() => state,
|
|
148
|
+
(v) => {
|
|
149
|
+
const unwrapped = store.unwrap(state);
|
|
150
|
+
if (typeof v === "function") {
|
|
151
|
+
v = v(unwrapped);
|
|
152
|
+
}
|
|
153
|
+
setStateWithReconciliation(v);
|
|
154
|
+
}
|
|
155
|
+
];
|
|
156
|
+
}
|
|
157
157
|
let unsubscribe = null;
|
|
158
|
-
const [queryResource, { refetch
|
|
158
|
+
const [queryResource, { refetch }] = solidJs.createResource(
|
|
159
159
|
() => {
|
|
160
160
|
const obs = observer();
|
|
161
161
|
return new Promise((resolve, reject) => {
|
|
@@ -165,18 +165,22 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
165
165
|
unsubscribe = createClientSubscriber();
|
|
166
166
|
}
|
|
167
167
|
obs.updateResult();
|
|
168
|
-
if (!
|
|
168
|
+
if (observerResult.isError && !observerResult.isFetching && !isRestoring() && shouldThrowError(obs.options.throwOnError, [
|
|
169
|
+
observerResult.error,
|
|
170
|
+
obs.getCurrentQuery()
|
|
171
|
+
])) {
|
|
172
|
+
setStateWithReconciliation(observerResult);
|
|
173
|
+
return reject(observerResult.error);
|
|
174
|
+
}
|
|
175
|
+
if (!observerResult.isLoading) {
|
|
169
176
|
const query = obs.getCurrentQuery();
|
|
170
|
-
resolve(hydratableObserverResult(query,
|
|
177
|
+
return resolve(hydratableObserverResult(query, observerResult));
|
|
171
178
|
}
|
|
179
|
+
setStateWithReconciliation(observerResult);
|
|
172
180
|
});
|
|
173
181
|
},
|
|
174
182
|
{
|
|
175
|
-
|
|
176
|
-
// If initialData is provided, we resolve the resource immediately
|
|
177
|
-
get ssrLoadFrom() {
|
|
178
|
-
return options().initialData ? "initial" : "server";
|
|
179
|
-
},
|
|
183
|
+
storage: createDeepSignal,
|
|
180
184
|
get deferStream() {
|
|
181
185
|
return options().deferStream;
|
|
182
186
|
},
|
|
@@ -254,29 +258,21 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
254
258
|
[observer, defaultedOptions],
|
|
255
259
|
([obs, opts]) => {
|
|
256
260
|
obs.setOptions(opts);
|
|
257
|
-
|
|
261
|
+
setStateWithReconciliation(obs.getOptimisticResult(opts));
|
|
258
262
|
},
|
|
259
263
|
{ defer: true }
|
|
260
264
|
)
|
|
261
265
|
);
|
|
262
|
-
solidJs.createComputed(
|
|
263
|
-
solidJs.on(
|
|
264
|
-
() => state.status,
|
|
265
|
-
() => {
|
|
266
|
-
const obs = observer();
|
|
267
|
-
if (state.isError && !state.isFetching && !isRestoring() && shouldThrowError(obs.options.throwOnError, [
|
|
268
|
-
state.error,
|
|
269
|
-
obs.getCurrentQuery()
|
|
270
|
-
])) {
|
|
271
|
-
throw state.error;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
)
|
|
275
|
-
);
|
|
276
266
|
const handler = {
|
|
277
267
|
get(target, prop) {
|
|
278
|
-
|
|
279
|
-
|
|
268
|
+
if (prop === "data") {
|
|
269
|
+
const opts = observer().options;
|
|
270
|
+
if (opts.placeholderData) {
|
|
271
|
+
return queryResource.latest?.data;
|
|
272
|
+
}
|
|
273
|
+
return queryResource()?.data;
|
|
274
|
+
}
|
|
275
|
+
return Reflect.get(target, prop);
|
|
280
276
|
}
|
|
281
277
|
};
|
|
282
278
|
return new Proxy(state, handler);
|
package/build/dev.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { QueryClient as QueryClient$1, MutationObserver, replaceEqualDeep, QueriesObserver, hydrate, QueryObserver, InfiniteQueryObserver, notifyManager } from '@tanstack/query-core';
|
|
2
2
|
export * from '@tanstack/query-core';
|
|
3
|
-
import {
|
|
3
|
+
import { createContext, useContext, createRenderEffect, onCleanup, createMemo, createSignal, createComputed, on, createEffect, mergeProps, createResource, batch, onMount } from 'solid-js';
|
|
4
4
|
import { createComponent, isServer } from 'solid-js/web';
|
|
5
5
|
import { createStore, unwrap, reconcile } from 'solid-js/store';
|
|
6
6
|
|
|
7
|
-
// src/
|
|
8
|
-
notifyManager.setBatchNotifyFunction(batch);
|
|
7
|
+
// src/index.ts
|
|
9
8
|
var QueryClient = class extends QueryClient$1 {
|
|
10
9
|
constructor(config = {}) {
|
|
11
10
|
super(config);
|
|
@@ -102,9 +101,8 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
102
101
|
const [observer, setObserver] = createSignal(
|
|
103
102
|
new Observer(client(), defaultedOptions())
|
|
104
103
|
);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
);
|
|
104
|
+
let observerResult = observer().getOptimisticResult(defaultedOptions());
|
|
105
|
+
const [state, setState] = createStore(observerResult);
|
|
108
106
|
const createServerSubscriber = (resolve, reject) => {
|
|
109
107
|
return observer().subscribe((result) => {
|
|
110
108
|
notifyManager.batchCalls(() => {
|
|
@@ -129,32 +127,34 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
129
127
|
const createClientSubscriber = () => {
|
|
130
128
|
const obs = observer();
|
|
131
129
|
return obs.subscribe((result) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (!queryResource.error && queryResource()?.data && result.data && !queryResource.loading) {
|
|
135
|
-
setState((store) => {
|
|
136
|
-
return reconcileFn(
|
|
137
|
-
store,
|
|
138
|
-
result,
|
|
139
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
140
|
-
);
|
|
141
|
-
});
|
|
142
|
-
mutate(state);
|
|
143
|
-
} else {
|
|
144
|
-
setState((store) => {
|
|
145
|
-
return reconcileFn(
|
|
146
|
-
store,
|
|
147
|
-
result,
|
|
148
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
refetch();
|
|
152
|
-
}
|
|
153
|
-
})();
|
|
130
|
+
observerResult = result;
|
|
131
|
+
queueMicrotask(() => refetch());
|
|
154
132
|
});
|
|
155
133
|
};
|
|
134
|
+
function setStateWithReconciliation(res) {
|
|
135
|
+
const reconcileOptions = observer().options.reconcile;
|
|
136
|
+
setState((store) => {
|
|
137
|
+
return reconcileFn(
|
|
138
|
+
store,
|
|
139
|
+
res,
|
|
140
|
+
reconcileOptions === void 0 ? false : reconcileOptions
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function createDeepSignal() {
|
|
145
|
+
return [
|
|
146
|
+
() => state,
|
|
147
|
+
(v) => {
|
|
148
|
+
const unwrapped = unwrap(state);
|
|
149
|
+
if (typeof v === "function") {
|
|
150
|
+
v = v(unwrapped);
|
|
151
|
+
}
|
|
152
|
+
setStateWithReconciliation(v);
|
|
153
|
+
}
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
156
|
let unsubscribe = null;
|
|
157
|
-
const [queryResource, { refetch
|
|
157
|
+
const [queryResource, { refetch }] = createResource(
|
|
158
158
|
() => {
|
|
159
159
|
const obs = observer();
|
|
160
160
|
return new Promise((resolve, reject) => {
|
|
@@ -164,18 +164,22 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
164
164
|
unsubscribe = createClientSubscriber();
|
|
165
165
|
}
|
|
166
166
|
obs.updateResult();
|
|
167
|
-
if (!
|
|
167
|
+
if (observerResult.isError && !observerResult.isFetching && !isRestoring() && shouldThrowError(obs.options.throwOnError, [
|
|
168
|
+
observerResult.error,
|
|
169
|
+
obs.getCurrentQuery()
|
|
170
|
+
])) {
|
|
171
|
+
setStateWithReconciliation(observerResult);
|
|
172
|
+
return reject(observerResult.error);
|
|
173
|
+
}
|
|
174
|
+
if (!observerResult.isLoading) {
|
|
168
175
|
const query = obs.getCurrentQuery();
|
|
169
|
-
resolve(hydratableObserverResult(query,
|
|
176
|
+
return resolve(hydratableObserverResult(query, observerResult));
|
|
170
177
|
}
|
|
178
|
+
setStateWithReconciliation(observerResult);
|
|
171
179
|
});
|
|
172
180
|
},
|
|
173
181
|
{
|
|
174
|
-
|
|
175
|
-
// If initialData is provided, we resolve the resource immediately
|
|
176
|
-
get ssrLoadFrom() {
|
|
177
|
-
return options().initialData ? "initial" : "server";
|
|
178
|
-
},
|
|
182
|
+
storage: createDeepSignal,
|
|
179
183
|
get deferStream() {
|
|
180
184
|
return options().deferStream;
|
|
181
185
|
},
|
|
@@ -253,29 +257,21 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
253
257
|
[observer, defaultedOptions],
|
|
254
258
|
([obs, opts]) => {
|
|
255
259
|
obs.setOptions(opts);
|
|
256
|
-
|
|
260
|
+
setStateWithReconciliation(obs.getOptimisticResult(opts));
|
|
257
261
|
},
|
|
258
262
|
{ defer: true }
|
|
259
263
|
)
|
|
260
264
|
);
|
|
261
|
-
createComputed(
|
|
262
|
-
on(
|
|
263
|
-
() => state.status,
|
|
264
|
-
() => {
|
|
265
|
-
const obs = observer();
|
|
266
|
-
if (state.isError && !state.isFetching && !isRestoring() && shouldThrowError(obs.options.throwOnError, [
|
|
267
|
-
state.error,
|
|
268
|
-
obs.getCurrentQuery()
|
|
269
|
-
])) {
|
|
270
|
-
throw state.error;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
)
|
|
274
|
-
);
|
|
275
265
|
const handler = {
|
|
276
266
|
get(target, prop) {
|
|
277
|
-
|
|
278
|
-
|
|
267
|
+
if (prop === "data") {
|
|
268
|
+
const opts = observer().options;
|
|
269
|
+
if (opts.placeholderData) {
|
|
270
|
+
return queryResource.latest?.data;
|
|
271
|
+
}
|
|
272
|
+
return queryResource()?.data;
|
|
273
|
+
}
|
|
274
|
+
return Reflect.get(target, prop);
|
|
279
275
|
}
|
|
280
276
|
};
|
|
281
277
|
return new Proxy(state, handler);
|
package/build/index.cjs
CHANGED
|
@@ -5,8 +5,7 @@ var solidJs = require('solid-js');
|
|
|
5
5
|
var web = require('solid-js/web');
|
|
6
6
|
var store = require('solid-js/store');
|
|
7
7
|
|
|
8
|
-
// src/
|
|
9
|
-
queryCore.notifyManager.setBatchNotifyFunction(solidJs.batch);
|
|
8
|
+
// src/index.ts
|
|
10
9
|
exports.QueryClient = class QueryClient extends queryCore.QueryClient {
|
|
11
10
|
constructor(config = {}) {
|
|
12
11
|
super(config);
|
|
@@ -103,9 +102,8 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
103
102
|
const [observer, setObserver] = solidJs.createSignal(
|
|
104
103
|
new Observer(client(), defaultedOptions())
|
|
105
104
|
);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
);
|
|
105
|
+
let observerResult = observer().getOptimisticResult(defaultedOptions());
|
|
106
|
+
const [state, setState] = store.createStore(observerResult);
|
|
109
107
|
const createServerSubscriber = (resolve, reject) => {
|
|
110
108
|
return observer().subscribe((result) => {
|
|
111
109
|
queryCore.notifyManager.batchCalls(() => {
|
|
@@ -130,32 +128,34 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
130
128
|
const createClientSubscriber = () => {
|
|
131
129
|
const obs = observer();
|
|
132
130
|
return obs.subscribe((result) => {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (!queryResource.error && queryResource()?.data && result.data && !queryResource.loading) {
|
|
136
|
-
setState((store) => {
|
|
137
|
-
return reconcileFn(
|
|
138
|
-
store,
|
|
139
|
-
result,
|
|
140
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
141
|
-
);
|
|
142
|
-
});
|
|
143
|
-
mutate(state);
|
|
144
|
-
} else {
|
|
145
|
-
setState((store) => {
|
|
146
|
-
return reconcileFn(
|
|
147
|
-
store,
|
|
148
|
-
result,
|
|
149
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
150
|
-
);
|
|
151
|
-
});
|
|
152
|
-
refetch();
|
|
153
|
-
}
|
|
154
|
-
})();
|
|
131
|
+
observerResult = result;
|
|
132
|
+
queueMicrotask(() => refetch());
|
|
155
133
|
});
|
|
156
134
|
};
|
|
135
|
+
function setStateWithReconciliation(res) {
|
|
136
|
+
const reconcileOptions = observer().options.reconcile;
|
|
137
|
+
setState((store) => {
|
|
138
|
+
return reconcileFn(
|
|
139
|
+
store,
|
|
140
|
+
res,
|
|
141
|
+
reconcileOptions === void 0 ? false : reconcileOptions
|
|
142
|
+
);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function createDeepSignal() {
|
|
146
|
+
return [
|
|
147
|
+
() => state,
|
|
148
|
+
(v) => {
|
|
149
|
+
const unwrapped = store.unwrap(state);
|
|
150
|
+
if (typeof v === "function") {
|
|
151
|
+
v = v(unwrapped);
|
|
152
|
+
}
|
|
153
|
+
setStateWithReconciliation(v);
|
|
154
|
+
}
|
|
155
|
+
];
|
|
156
|
+
}
|
|
157
157
|
let unsubscribe = null;
|
|
158
|
-
const [queryResource, { refetch
|
|
158
|
+
const [queryResource, { refetch }] = solidJs.createResource(
|
|
159
159
|
() => {
|
|
160
160
|
const obs = observer();
|
|
161
161
|
return new Promise((resolve, reject) => {
|
|
@@ -165,18 +165,22 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
165
165
|
unsubscribe = createClientSubscriber();
|
|
166
166
|
}
|
|
167
167
|
obs.updateResult();
|
|
168
|
-
if (!
|
|
168
|
+
if (observerResult.isError && !observerResult.isFetching && !isRestoring() && shouldThrowError(obs.options.throwOnError, [
|
|
169
|
+
observerResult.error,
|
|
170
|
+
obs.getCurrentQuery()
|
|
171
|
+
])) {
|
|
172
|
+
setStateWithReconciliation(observerResult);
|
|
173
|
+
return reject(observerResult.error);
|
|
174
|
+
}
|
|
175
|
+
if (!observerResult.isLoading) {
|
|
169
176
|
const query = obs.getCurrentQuery();
|
|
170
|
-
resolve(hydratableObserverResult(query,
|
|
177
|
+
return resolve(hydratableObserverResult(query, observerResult));
|
|
171
178
|
}
|
|
179
|
+
setStateWithReconciliation(observerResult);
|
|
172
180
|
});
|
|
173
181
|
},
|
|
174
182
|
{
|
|
175
|
-
|
|
176
|
-
// If initialData is provided, we resolve the resource immediately
|
|
177
|
-
get ssrLoadFrom() {
|
|
178
|
-
return options().initialData ? "initial" : "server";
|
|
179
|
-
},
|
|
183
|
+
storage: createDeepSignal,
|
|
180
184
|
get deferStream() {
|
|
181
185
|
return options().deferStream;
|
|
182
186
|
},
|
|
@@ -254,29 +258,21 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
254
258
|
[observer, defaultedOptions],
|
|
255
259
|
([obs, opts]) => {
|
|
256
260
|
obs.setOptions(opts);
|
|
257
|
-
|
|
261
|
+
setStateWithReconciliation(obs.getOptimisticResult(opts));
|
|
258
262
|
},
|
|
259
263
|
{ defer: true }
|
|
260
264
|
)
|
|
261
265
|
);
|
|
262
|
-
solidJs.createComputed(
|
|
263
|
-
solidJs.on(
|
|
264
|
-
() => state.status,
|
|
265
|
-
() => {
|
|
266
|
-
const obs = observer();
|
|
267
|
-
if (state.isError && !state.isFetching && !isRestoring() && shouldThrowError(obs.options.throwOnError, [
|
|
268
|
-
state.error,
|
|
269
|
-
obs.getCurrentQuery()
|
|
270
|
-
])) {
|
|
271
|
-
throw state.error;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
)
|
|
275
|
-
);
|
|
276
266
|
const handler = {
|
|
277
267
|
get(target, prop) {
|
|
278
|
-
|
|
279
|
-
|
|
268
|
+
if (prop === "data") {
|
|
269
|
+
const opts = observer().options;
|
|
270
|
+
if (opts.placeholderData) {
|
|
271
|
+
return queryResource.latest?.data;
|
|
272
|
+
}
|
|
273
|
+
return queryResource()?.data;
|
|
274
|
+
}
|
|
275
|
+
return Reflect.get(target, prop);
|
|
280
276
|
}
|
|
281
277
|
};
|
|
282
278
|
return new Proxy(state, handler);
|
package/build/index.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { QueryClient as QueryClient$1, MutationObserver, replaceEqualDeep, QueriesObserver, hydrate, QueryObserver, InfiniteQueryObserver, notifyManager } from '@tanstack/query-core';
|
|
2
2
|
export * from '@tanstack/query-core';
|
|
3
|
-
import {
|
|
3
|
+
import { createContext, useContext, createRenderEffect, onCleanup, createMemo, createSignal, createComputed, on, createEffect, mergeProps, createResource, batch, onMount } from 'solid-js';
|
|
4
4
|
import { createComponent, isServer } from 'solid-js/web';
|
|
5
5
|
import { createStore, unwrap, reconcile } from 'solid-js/store';
|
|
6
6
|
|
|
7
|
-
// src/
|
|
8
|
-
notifyManager.setBatchNotifyFunction(batch);
|
|
7
|
+
// src/index.ts
|
|
9
8
|
var QueryClient = class extends QueryClient$1 {
|
|
10
9
|
constructor(config = {}) {
|
|
11
10
|
super(config);
|
|
@@ -102,9 +101,8 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
102
101
|
const [observer, setObserver] = createSignal(
|
|
103
102
|
new Observer(client(), defaultedOptions())
|
|
104
103
|
);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
);
|
|
104
|
+
let observerResult = observer().getOptimisticResult(defaultedOptions());
|
|
105
|
+
const [state, setState] = createStore(observerResult);
|
|
108
106
|
const createServerSubscriber = (resolve, reject) => {
|
|
109
107
|
return observer().subscribe((result) => {
|
|
110
108
|
notifyManager.batchCalls(() => {
|
|
@@ -129,32 +127,34 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
129
127
|
const createClientSubscriber = () => {
|
|
130
128
|
const obs = observer();
|
|
131
129
|
return obs.subscribe((result) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (!queryResource.error && queryResource()?.data && result.data && !queryResource.loading) {
|
|
135
|
-
setState((store) => {
|
|
136
|
-
return reconcileFn(
|
|
137
|
-
store,
|
|
138
|
-
result,
|
|
139
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
140
|
-
);
|
|
141
|
-
});
|
|
142
|
-
mutate(state);
|
|
143
|
-
} else {
|
|
144
|
-
setState((store) => {
|
|
145
|
-
return reconcileFn(
|
|
146
|
-
store,
|
|
147
|
-
result,
|
|
148
|
-
reconcileOptions === void 0 ? false : reconcileOptions
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
refetch();
|
|
152
|
-
}
|
|
153
|
-
})();
|
|
130
|
+
observerResult = result;
|
|
131
|
+
queueMicrotask(() => refetch());
|
|
154
132
|
});
|
|
155
133
|
};
|
|
134
|
+
function setStateWithReconciliation(res) {
|
|
135
|
+
const reconcileOptions = observer().options.reconcile;
|
|
136
|
+
setState((store) => {
|
|
137
|
+
return reconcileFn(
|
|
138
|
+
store,
|
|
139
|
+
res,
|
|
140
|
+
reconcileOptions === void 0 ? false : reconcileOptions
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function createDeepSignal() {
|
|
145
|
+
return [
|
|
146
|
+
() => state,
|
|
147
|
+
(v) => {
|
|
148
|
+
const unwrapped = unwrap(state);
|
|
149
|
+
if (typeof v === "function") {
|
|
150
|
+
v = v(unwrapped);
|
|
151
|
+
}
|
|
152
|
+
setStateWithReconciliation(v);
|
|
153
|
+
}
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
156
|
let unsubscribe = null;
|
|
157
|
-
const [queryResource, { refetch
|
|
157
|
+
const [queryResource, { refetch }] = createResource(
|
|
158
158
|
() => {
|
|
159
159
|
const obs = observer();
|
|
160
160
|
return new Promise((resolve, reject) => {
|
|
@@ -164,18 +164,22 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
164
164
|
unsubscribe = createClientSubscriber();
|
|
165
165
|
}
|
|
166
166
|
obs.updateResult();
|
|
167
|
-
if (!
|
|
167
|
+
if (observerResult.isError && !observerResult.isFetching && !isRestoring() && shouldThrowError(obs.options.throwOnError, [
|
|
168
|
+
observerResult.error,
|
|
169
|
+
obs.getCurrentQuery()
|
|
170
|
+
])) {
|
|
171
|
+
setStateWithReconciliation(observerResult);
|
|
172
|
+
return reject(observerResult.error);
|
|
173
|
+
}
|
|
174
|
+
if (!observerResult.isLoading) {
|
|
168
175
|
const query = obs.getCurrentQuery();
|
|
169
|
-
resolve(hydratableObserverResult(query,
|
|
176
|
+
return resolve(hydratableObserverResult(query, observerResult));
|
|
170
177
|
}
|
|
178
|
+
setStateWithReconciliation(observerResult);
|
|
171
179
|
});
|
|
172
180
|
},
|
|
173
181
|
{
|
|
174
|
-
|
|
175
|
-
// If initialData is provided, we resolve the resource immediately
|
|
176
|
-
get ssrLoadFrom() {
|
|
177
|
-
return options().initialData ? "initial" : "server";
|
|
178
|
-
},
|
|
182
|
+
storage: createDeepSignal,
|
|
179
183
|
get deferStream() {
|
|
180
184
|
return options().deferStream;
|
|
181
185
|
},
|
|
@@ -253,29 +257,21 @@ function createBaseQuery(options, Observer, queryClient) {
|
|
|
253
257
|
[observer, defaultedOptions],
|
|
254
258
|
([obs, opts]) => {
|
|
255
259
|
obs.setOptions(opts);
|
|
256
|
-
|
|
260
|
+
setStateWithReconciliation(obs.getOptimisticResult(opts));
|
|
257
261
|
},
|
|
258
262
|
{ defer: true }
|
|
259
263
|
)
|
|
260
264
|
);
|
|
261
|
-
createComputed(
|
|
262
|
-
on(
|
|
263
|
-
() => state.status,
|
|
264
|
-
() => {
|
|
265
|
-
const obs = observer();
|
|
266
|
-
if (state.isError && !state.isFetching && !isRestoring() && shouldThrowError(obs.options.throwOnError, [
|
|
267
|
-
state.error,
|
|
268
|
-
obs.getCurrentQuery()
|
|
269
|
-
])) {
|
|
270
|
-
throw state.error;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
)
|
|
274
|
-
);
|
|
275
265
|
const handler = {
|
|
276
266
|
get(target, prop) {
|
|
277
|
-
|
|
278
|
-
|
|
267
|
+
if (prop === "data") {
|
|
268
|
+
const opts = observer().options;
|
|
269
|
+
if (opts.placeholderData) {
|
|
270
|
+
return queryResource.latest?.data;
|
|
271
|
+
}
|
|
272
|
+
return queryResource()?.data;
|
|
273
|
+
}
|
|
274
|
+
return Reflect.get(target, prop);
|
|
279
275
|
}
|
|
280
276
|
};
|
|
281
277
|
return new Proxy(state, handler);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/solid-query",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.30.1",
|
|
4
4
|
"description": "Primitives for managing, caching and syncing asynchronous and remote data in Solid",
|
|
5
5
|
"author": "tannerlinsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,9 +39,6 @@
|
|
|
39
39
|
"default": "./build/index.cjs"
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
|
-
"sideEffects": [
|
|
43
|
-
"./src/setBatchUpdatesFn.ts"
|
|
44
|
-
],
|
|
45
42
|
"files": [
|
|
46
43
|
"build",
|
|
47
44
|
"src"
|
|
@@ -2407,6 +2407,7 @@ describe('createQuery', () => {
|
|
|
2407
2407
|
|
|
2408
2408
|
return (
|
|
2409
2409
|
<div>
|
|
2410
|
+
<h1>{state.data}</h1>
|
|
2410
2411
|
<h1>{state.status}</h1>
|
|
2411
2412
|
<h2>{state.error?.message}</h2>
|
|
2412
2413
|
</div>
|
|
@@ -2426,6 +2427,124 @@ describe('createQuery', () => {
|
|
|
2426
2427
|
consoleMock.mockRestore()
|
|
2427
2428
|
})
|
|
2428
2429
|
|
|
2430
|
+
it('should throw error inside the same component if queryFn throws and throwOnError is in use', async () => {
|
|
2431
|
+
const key = queryKey()
|
|
2432
|
+
|
|
2433
|
+
const consoleMock = vi
|
|
2434
|
+
.spyOn(console, 'error')
|
|
2435
|
+
.mockImplementation(() => undefined)
|
|
2436
|
+
|
|
2437
|
+
function Page() {
|
|
2438
|
+
const state = createQuery(() => ({
|
|
2439
|
+
queryKey: key,
|
|
2440
|
+
queryFn: () => Promise.reject(new Error('Error test')),
|
|
2441
|
+
retry: false,
|
|
2442
|
+
throwOnError: true,
|
|
2443
|
+
}))
|
|
2444
|
+
|
|
2445
|
+
return (
|
|
2446
|
+
<div>
|
|
2447
|
+
<ErrorBoundary fallback={() => <div>error boundary</div>}>
|
|
2448
|
+
<h1>{state.data}</h1>
|
|
2449
|
+
<h1>{state.status}</h1>
|
|
2450
|
+
<h2>{state.error?.message}</h2>
|
|
2451
|
+
</ErrorBoundary>
|
|
2452
|
+
</div>
|
|
2453
|
+
)
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2456
|
+
const rendered = render(() => (
|
|
2457
|
+
<QueryClientProvider client={queryClient}>
|
|
2458
|
+
<Page />
|
|
2459
|
+
</QueryClientProvider>
|
|
2460
|
+
))
|
|
2461
|
+
|
|
2462
|
+
await waitFor(() => rendered.getByText('error boundary'))
|
|
2463
|
+
|
|
2464
|
+
consoleMock.mockRestore()
|
|
2465
|
+
})
|
|
2466
|
+
|
|
2467
|
+
it('should throw error inside the same component if queryFn throws and show the correct error message', async () => {
|
|
2468
|
+
const key = queryKey()
|
|
2469
|
+
|
|
2470
|
+
const consoleMock = vi
|
|
2471
|
+
.spyOn(console, 'error')
|
|
2472
|
+
.mockImplementation(() => undefined)
|
|
2473
|
+
|
|
2474
|
+
function Page() {
|
|
2475
|
+
const state = createQuery(() => ({
|
|
2476
|
+
queryKey: key,
|
|
2477
|
+
queryFn: () => Promise.reject(new Error('Error test')),
|
|
2478
|
+
retry: false,
|
|
2479
|
+
throwOnError: true,
|
|
2480
|
+
}))
|
|
2481
|
+
|
|
2482
|
+
return (
|
|
2483
|
+
<div>
|
|
2484
|
+
<ErrorBoundary
|
|
2485
|
+
fallback={(err) => <div>Fallback error: {err.message}</div>}
|
|
2486
|
+
>
|
|
2487
|
+
<h1>{state.data}</h1>
|
|
2488
|
+
<h1>{state.status}</h1>
|
|
2489
|
+
<h2>{state.error?.message}</h2>
|
|
2490
|
+
</ErrorBoundary>
|
|
2491
|
+
</div>
|
|
2492
|
+
)
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2495
|
+
const rendered = render(() => (
|
|
2496
|
+
<QueryClientProvider client={queryClient}>
|
|
2497
|
+
<Page />
|
|
2498
|
+
</QueryClientProvider>
|
|
2499
|
+
))
|
|
2500
|
+
|
|
2501
|
+
await waitFor(() => rendered.getByText('Fallback error: Error test'))
|
|
2502
|
+
|
|
2503
|
+
consoleMock.mockRestore()
|
|
2504
|
+
})
|
|
2505
|
+
|
|
2506
|
+
it('should show the correct error message on the error property when accessed outside error boundary', async () => {
|
|
2507
|
+
const key = queryKey()
|
|
2508
|
+
|
|
2509
|
+
const consoleMock = vi
|
|
2510
|
+
.spyOn(console, 'error')
|
|
2511
|
+
.mockImplementation(() => undefined)
|
|
2512
|
+
|
|
2513
|
+
function Page() {
|
|
2514
|
+
const state = createQuery(() => ({
|
|
2515
|
+
queryKey: key,
|
|
2516
|
+
queryFn: () => Promise.reject(new Error('Error test')),
|
|
2517
|
+
retry: false,
|
|
2518
|
+
throwOnError: true,
|
|
2519
|
+
}))
|
|
2520
|
+
|
|
2521
|
+
return (
|
|
2522
|
+
<div>
|
|
2523
|
+
<h2>Outside error boundary: {state.error?.message}</h2>
|
|
2524
|
+
<ErrorBoundary
|
|
2525
|
+
fallback={(err) => <div>Fallback error: {err.message}</div>}
|
|
2526
|
+
>
|
|
2527
|
+
<h1>{state.data}</h1>
|
|
2528
|
+
<h1>{state.status}</h1>
|
|
2529
|
+
</ErrorBoundary>
|
|
2530
|
+
</div>
|
|
2531
|
+
)
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
const rendered = render(() => (
|
|
2535
|
+
<QueryClientProvider client={queryClient}>
|
|
2536
|
+
<Page />
|
|
2537
|
+
</QueryClientProvider>
|
|
2538
|
+
))
|
|
2539
|
+
|
|
2540
|
+
await waitFor(() =>
|
|
2541
|
+
rendered.getByText('Outside error boundary: Error test'),
|
|
2542
|
+
)
|
|
2543
|
+
await waitFor(() => rendered.getByText('Fallback error: Error test'))
|
|
2544
|
+
|
|
2545
|
+
consoleMock.mockRestore()
|
|
2546
|
+
})
|
|
2547
|
+
|
|
2429
2548
|
it('should update with data if we observe no properties and throwOnError', async () => {
|
|
2430
2549
|
const key = queryKey()
|
|
2431
2550
|
|
|
@@ -2491,7 +2610,7 @@ describe('createQuery', () => {
|
|
|
2491
2610
|
const key = queryKey()
|
|
2492
2611
|
|
|
2493
2612
|
function Page() {
|
|
2494
|
-
const state = createQuery
|
|
2613
|
+
const state = createQuery(() => ({
|
|
2495
2614
|
queryKey: key,
|
|
2496
2615
|
queryFn: () => Promise.reject(new Error('Remote Error')),
|
|
2497
2616
|
retry: false,
|
|
@@ -2500,6 +2619,7 @@ describe('createQuery', () => {
|
|
|
2500
2619
|
|
|
2501
2620
|
return (
|
|
2502
2621
|
<div>
|
|
2622
|
+
<div>{state.data}</div>
|
|
2503
2623
|
<h1>{state.status}</h1>
|
|
2504
2624
|
<h2>{state.error?.message ?? ''}</h2>
|
|
2505
2625
|
</div>
|
package/src/createBaseQuery.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { useQueryClient } from './QueryClientProvider'
|
|
|
16
16
|
import { shouldThrowError } from './utils'
|
|
17
17
|
import { useIsRestoring } from './isRestoring'
|
|
18
18
|
import type { CreateBaseQueryOptions } from './types'
|
|
19
|
-
import type { Accessor } from 'solid-js'
|
|
19
|
+
import type { Accessor, Signal } from 'solid-js'
|
|
20
20
|
import type { QueryClient } from './QueryClient'
|
|
21
21
|
import type {
|
|
22
22
|
InfiniteQueryObserverResult,
|
|
@@ -144,9 +144,9 @@ export function createBaseQuery<
|
|
|
144
144
|
new Observer(client(), defaultedOptions()),
|
|
145
145
|
)
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
let observerResult = observer().getOptimisticResult(defaultedOptions())
|
|
148
|
+
const [state, setState] =
|
|
149
|
+
createStore<QueryObserverResult<TData, TError>>(observerResult)
|
|
150
150
|
|
|
151
151
|
const createServerSubscriber = (
|
|
152
152
|
resolve: (
|
|
@@ -180,49 +180,43 @@ export function createBaseQuery<
|
|
|
180
180
|
const createClientSubscriber = () => {
|
|
181
181
|
const obs = observer()
|
|
182
182
|
return obs.subscribe((result) => {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
observerResult = result
|
|
184
|
+
queueMicrotask(() => refetch())
|
|
185
|
+
})
|
|
186
|
+
}
|
|
187
187
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
store,
|
|
199
|
-
result,
|
|
200
|
-
reconcileOptions === undefined ? false : reconcileOptions,
|
|
201
|
-
)
|
|
202
|
-
})
|
|
203
|
-
mutate(state)
|
|
204
|
-
} else {
|
|
205
|
-
setState((store) => {
|
|
206
|
-
return reconcileFn(
|
|
207
|
-
store,
|
|
208
|
-
result,
|
|
209
|
-
reconcileOptions === undefined ? false : reconcileOptions,
|
|
210
|
-
)
|
|
211
|
-
})
|
|
212
|
-
refetch()
|
|
213
|
-
}
|
|
214
|
-
})()
|
|
188
|
+
function setStateWithReconciliation(res: typeof observerResult) {
|
|
189
|
+
// @ts-expect-error - Reconcile option is not correctly typed internally
|
|
190
|
+
const reconcileOptions = observer().options.reconcile
|
|
191
|
+
|
|
192
|
+
setState((store) => {
|
|
193
|
+
return reconcileFn(
|
|
194
|
+
store,
|
|
195
|
+
res,
|
|
196
|
+
reconcileOptions === undefined ? false : reconcileOptions,
|
|
197
|
+
)
|
|
215
198
|
})
|
|
216
199
|
}
|
|
217
200
|
|
|
201
|
+
function createDeepSignal<T>(): Signal<T> {
|
|
202
|
+
return [
|
|
203
|
+
() => state,
|
|
204
|
+
(v: T) => {
|
|
205
|
+
const unwrapped = unwrap(state)
|
|
206
|
+
if (typeof v === 'function') {
|
|
207
|
+
v = v(unwrapped)
|
|
208
|
+
}
|
|
209
|
+
setStateWithReconciliation(v as any)
|
|
210
|
+
},
|
|
211
|
+
] as Signal<T>
|
|
212
|
+
}
|
|
213
|
+
|
|
218
214
|
/**
|
|
219
215
|
* Unsubscribe is set lazily, so that we can subscribe after hydration when needed.
|
|
220
216
|
*/
|
|
221
217
|
let unsubscribe: (() => void) | null = null
|
|
222
218
|
|
|
223
|
-
const [queryResource, { refetch
|
|
224
|
-
ResourceData | undefined
|
|
225
|
-
>(
|
|
219
|
+
const [queryResource, { refetch }] = createResource<ResourceData | undefined>(
|
|
226
220
|
() => {
|
|
227
221
|
const obs = observer()
|
|
228
222
|
return new Promise((resolve, reject) => {
|
|
@@ -233,19 +227,28 @@ export function createBaseQuery<
|
|
|
233
227
|
}
|
|
234
228
|
obs.updateResult()
|
|
235
229
|
|
|
236
|
-
if (
|
|
230
|
+
if (
|
|
231
|
+
observerResult.isError &&
|
|
232
|
+
!observerResult.isFetching &&
|
|
233
|
+
!isRestoring() &&
|
|
234
|
+
shouldThrowError(obs.options.throwOnError, [
|
|
235
|
+
observerResult.error,
|
|
236
|
+
obs.getCurrentQuery(),
|
|
237
|
+
])
|
|
238
|
+
) {
|
|
239
|
+
setStateWithReconciliation(observerResult)
|
|
240
|
+
return reject(observerResult.error)
|
|
241
|
+
}
|
|
242
|
+
if (!observerResult.isLoading) {
|
|
237
243
|
const query = obs.getCurrentQuery()
|
|
238
|
-
resolve(hydratableObserverResult(query,
|
|
244
|
+
return resolve(hydratableObserverResult(query, observerResult))
|
|
239
245
|
}
|
|
246
|
+
|
|
247
|
+
setStateWithReconciliation(observerResult)
|
|
240
248
|
})
|
|
241
249
|
},
|
|
242
250
|
{
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
// If initialData is provided, we resolve the resource immediately
|
|
246
|
-
get ssrLoadFrom() {
|
|
247
|
-
return options().initialData ? 'initial' : 'server'
|
|
248
|
-
},
|
|
251
|
+
storage: createDeepSignal,
|
|
249
252
|
|
|
250
253
|
get deferStream() {
|
|
251
254
|
return options().deferStream
|
|
@@ -338,39 +341,25 @@ export function createBaseQuery<
|
|
|
338
341
|
[observer, defaultedOptions],
|
|
339
342
|
([obs, opts]) => {
|
|
340
343
|
obs.setOptions(opts)
|
|
341
|
-
|
|
344
|
+
setStateWithReconciliation(obs.getOptimisticResult(opts))
|
|
342
345
|
},
|
|
343
346
|
{ defer: true },
|
|
344
347
|
),
|
|
345
348
|
)
|
|
346
349
|
|
|
347
|
-
createComputed(
|
|
348
|
-
on(
|
|
349
|
-
() => state.status,
|
|
350
|
-
() => {
|
|
351
|
-
const obs = observer()
|
|
352
|
-
if (
|
|
353
|
-
state.isError &&
|
|
354
|
-
!state.isFetching &&
|
|
355
|
-
!isRestoring() &&
|
|
356
|
-
shouldThrowError(obs.options.throwOnError, [
|
|
357
|
-
state.error,
|
|
358
|
-
obs.getCurrentQuery(),
|
|
359
|
-
])
|
|
360
|
-
) {
|
|
361
|
-
throw state.error
|
|
362
|
-
}
|
|
363
|
-
},
|
|
364
|
-
),
|
|
365
|
-
)
|
|
366
|
-
|
|
367
350
|
const handler = {
|
|
368
351
|
get(
|
|
369
352
|
target: QueryObserverResult<TData, TError>,
|
|
370
353
|
prop: keyof QueryObserverResult<TData, TError>,
|
|
371
354
|
): any {
|
|
372
|
-
|
|
373
|
-
|
|
355
|
+
if (prop === 'data') {
|
|
356
|
+
const opts = observer().options
|
|
357
|
+
if (opts.placeholderData) {
|
|
358
|
+
return queryResource.latest?.data
|
|
359
|
+
}
|
|
360
|
+
return queryResource()?.data
|
|
361
|
+
}
|
|
362
|
+
return Reflect.get(target, prop)
|
|
374
363
|
},
|
|
375
364
|
}
|
|
376
365
|
|
package/src/index.ts
CHANGED
package/src/setBatchUpdatesFn.ts
DELETED