@tanstack/solid-query 5.24.1 → 5.24.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 CHANGED
@@ -45,6 +45,8 @@ function shouldThrowError(throwError, params) {
45
45
  }
46
46
  return !!throwError;
47
47
  }
48
+ function noop() {
49
+ }
48
50
  var IsRestoringContext = solidJs.createContext(() => false);
49
51
  exports.useIsRestoring = () => solidJs.useContext(IsRestoringContext);
50
52
  exports.IsRestoringProvider = IsRestoringContext.Provider;
@@ -86,22 +88,19 @@ var hydratableObserverResult = (query, result) => {
86
88
  function createBaseQuery(options, Observer, queryClient) {
87
89
  const client = solidJs.createMemo(() => exports.useQueryClient(queryClient?.()));
88
90
  const isRestoring = exports.useIsRestoring();
89
- const defaultedOptions = solidJs.createMemo(
90
- () => solidJs.mergeProps(client()?.defaultQueryOptions(options()) || {}, {
91
- get _optimisticResults() {
92
- return isRestoring() ? "isRestoring" : "optimistic";
93
- },
94
- structuralSharing: false,
95
- ...web.isServer && { retry: false, throwOnError: true }
96
- })
97
- );
91
+ let unsubscribeQueued = false;
92
+ const defaultedOptions = solidJs.createMemo(() => {
93
+ const defaultOptions = client().defaultQueryOptions(options());
94
+ defaultOptions._optimisticResults = isRestoring() ? "isRestoring" : "optimistic";
95
+ defaultOptions.structuralSharing = false;
96
+ if (web.isServer) {
97
+ defaultOptions.retry = false;
98
+ defaultOptions.throwOnError = true;
99
+ }
100
+ return defaultOptions;
101
+ });
98
102
  const [observer, setObserver] = solidJs.createSignal(
99
- new Observer(client(), solidJs.untrack(defaultedOptions))
100
- );
101
- solidJs.createComputed(
102
- solidJs.on(client, (c) => setObserver(new Observer(c, defaultedOptions())), {
103
- defer: true
104
- })
103
+ new Observer(client(), defaultedOptions())
105
104
  );
106
105
  const [state, setState] = store.createStore(
107
106
  observer().getOptimisticResult(defaultedOptions())
@@ -113,28 +112,44 @@ function createBaseQuery(options, Observer, queryClient) {
113
112
  const unwrappedResult = hydratableObserverResult(query, result);
114
113
  if (unwrappedResult.isError) {
115
114
  reject(unwrappedResult.error);
115
+ unsubscribeIfQueued();
116
116
  } else {
117
117
  resolve(unwrappedResult);
118
+ unsubscribeIfQueued();
118
119
  }
119
120
  })();
120
121
  });
121
122
  };
123
+ const unsubscribeIfQueued = () => {
124
+ if (unsubscribeQueued) {
125
+ unsubscribe?.();
126
+ unsubscribeQueued = false;
127
+ }
128
+ };
122
129
  const createClientSubscriber = () => {
123
130
  const obs = observer();
124
131
  return obs.subscribe((result) => {
125
132
  queryCore.notifyManager.batchCalls(() => {
126
133
  const reconcileOptions = obs.options.reconcile;
127
- setState((store) => {
128
- return reconcileFn(
129
- store,
130
- result,
131
- reconcileOptions === void 0 ? false : reconcileOptions
132
- );
133
- });
134
- if (queryResource()?.data && result.data && !queryResource.loading && isRestoring())
134
+ if (queryResource()?.data && result.data && !queryResource.loading) {
135
+ setState((store) => {
136
+ return reconcileFn(
137
+ store,
138
+ result,
139
+ reconcileOptions === void 0 ? false : reconcileOptions
140
+ );
141
+ });
135
142
  mutate(state);
136
- else
143
+ } else {
144
+ setState((store) => {
145
+ return reconcileFn(
146
+ store,
147
+ result,
148
+ reconcileOptions === void 0 ? false : reconcileOptions
149
+ );
150
+ });
137
151
  refetch();
152
+ }
138
153
  })();
139
154
  });
140
155
  };
@@ -143,12 +158,13 @@ function createBaseQuery(options, Observer, queryClient) {
143
158
  () => {
144
159
  const obs = observer();
145
160
  return new Promise((resolve, reject) => {
146
- if (web.isServer)
161
+ if (web.isServer) {
147
162
  unsubscribe = createServerSubscriber(resolve, reject);
148
- else if (!unsubscribe && !isRestoring())
163
+ } else if (!unsubscribe && !isRestoring()) {
149
164
  unsubscribe = createClientSubscriber();
165
+ }
150
166
  obs.updateResult();
151
- if (!state.isLoading && !isRestoring()) {
167
+ if (!state.isLoading) {
152
168
  const query = obs.getCurrentQuery();
153
169
  resolve(hydratableObserverResult(query, state));
154
170
  }
@@ -198,18 +214,30 @@ function createBaseQuery(options, Observer, queryClient) {
198
214
  );
199
215
  solidJs.createComputed(
200
216
  solidJs.on(
201
- [isRestoring, observer],
202
- ([restoring]) => {
203
- const _unsubscribe = unsubscribe;
204
- queueMicrotask(() => _unsubscribe?.());
205
- unsubscribe = null;
206
- if (!restoring)
207
- refetch();
217
+ client,
218
+ (c) => {
219
+ if (unsubscribe) {
220
+ unsubscribe();
221
+ }
222
+ const newObserver = new Observer(c, defaultedOptions());
223
+ unsubscribe = createClientSubscriber();
224
+ setObserver(newObserver);
208
225
  },
209
- { defer: true }
226
+ {
227
+ defer: true
228
+ }
210
229
  )
211
230
  );
231
+ solidJs.createComputed(() => {
232
+ if (!isRestoring()) {
233
+ refetch();
234
+ }
235
+ });
212
236
  solidJs.onCleanup(() => {
237
+ if (web.isServer && queryResource.loading) {
238
+ unsubscribeQueued = true;
239
+ return;
240
+ }
213
241
  if (unsubscribe) {
214
242
  unsubscribe();
215
243
  unsubscribe = null;
@@ -222,11 +250,7 @@ function createBaseQuery(options, Observer, queryClient) {
222
250
  obs.setOptions(opts);
223
251
  setState(obs.getOptimisticResult(opts));
224
252
  },
225
- {
226
- // Defer because we don't need to trigger on first render
227
- // This only cares about changes to options after the observer is created
228
- defer: true
229
- }
253
+ { defer: true }
230
254
  )
231
255
  );
232
256
  solidJs.createComputed(
@@ -317,8 +341,6 @@ function createMutation(options, queryClient) {
317
341
  solidJs.onCleanup(unsubscribe);
318
342
  return state;
319
343
  }
320
- function noop() {
321
- }
322
344
  function useIsMutating(filters, queryClient) {
323
345
  const client = solidJs.createMemo(() => exports.useQueryClient(queryClient?.()));
324
346
  const mutationCache = solidJs.createMemo(() => client().getMutationCache());
package/build/dev.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { notifyManager, QueryClient as QueryClient$1, MutationObserver, replaceEqualDeep, QueriesObserver, hydrate, QueryObserver, InfiniteQueryObserver } from '@tanstack/query-core';
2
2
  export * from '@tanstack/query-core';
3
- import { batch, createContext, useContext, createRenderEffect, onCleanup, createMemo, createSignal, createComputed, on, createEffect, mergeProps, createResource, onMount, untrack } from 'solid-js';
3
+ import { batch, createContext, useContext, createRenderEffect, onCleanup, createMemo, createSignal, createComputed, on, createEffect, mergeProps, createResource, 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
 
@@ -44,6 +44,8 @@ function shouldThrowError(throwError, params) {
44
44
  }
45
45
  return !!throwError;
46
46
  }
47
+ function noop() {
48
+ }
47
49
  var IsRestoringContext = createContext(() => false);
48
50
  var useIsRestoring = () => useContext(IsRestoringContext);
49
51
  var IsRestoringProvider = IsRestoringContext.Provider;
@@ -85,22 +87,19 @@ var hydratableObserverResult = (query, result) => {
85
87
  function createBaseQuery(options, Observer, queryClient) {
86
88
  const client = createMemo(() => useQueryClient(queryClient?.()));
87
89
  const isRestoring = useIsRestoring();
88
- const defaultedOptions = createMemo(
89
- () => mergeProps(client()?.defaultQueryOptions(options()) || {}, {
90
- get _optimisticResults() {
91
- return isRestoring() ? "isRestoring" : "optimistic";
92
- },
93
- structuralSharing: false,
94
- ...isServer && { retry: false, throwOnError: true }
95
- })
96
- );
90
+ let unsubscribeQueued = false;
91
+ const defaultedOptions = createMemo(() => {
92
+ const defaultOptions = client().defaultQueryOptions(options());
93
+ defaultOptions._optimisticResults = isRestoring() ? "isRestoring" : "optimistic";
94
+ defaultOptions.structuralSharing = false;
95
+ if (isServer) {
96
+ defaultOptions.retry = false;
97
+ defaultOptions.throwOnError = true;
98
+ }
99
+ return defaultOptions;
100
+ });
97
101
  const [observer, setObserver] = createSignal(
98
- new Observer(client(), untrack(defaultedOptions))
99
- );
100
- createComputed(
101
- on(client, (c) => setObserver(new Observer(c, defaultedOptions())), {
102
- defer: true
103
- })
102
+ new Observer(client(), defaultedOptions())
104
103
  );
105
104
  const [state, setState] = createStore(
106
105
  observer().getOptimisticResult(defaultedOptions())
@@ -112,28 +111,44 @@ function createBaseQuery(options, Observer, queryClient) {
112
111
  const unwrappedResult = hydratableObserverResult(query, result);
113
112
  if (unwrappedResult.isError) {
114
113
  reject(unwrappedResult.error);
114
+ unsubscribeIfQueued();
115
115
  } else {
116
116
  resolve(unwrappedResult);
117
+ unsubscribeIfQueued();
117
118
  }
118
119
  })();
119
120
  });
120
121
  };
122
+ const unsubscribeIfQueued = () => {
123
+ if (unsubscribeQueued) {
124
+ unsubscribe?.();
125
+ unsubscribeQueued = false;
126
+ }
127
+ };
121
128
  const createClientSubscriber = () => {
122
129
  const obs = observer();
123
130
  return obs.subscribe((result) => {
124
131
  notifyManager.batchCalls(() => {
125
132
  const reconcileOptions = obs.options.reconcile;
126
- setState((store) => {
127
- return reconcileFn(
128
- store,
129
- result,
130
- reconcileOptions === void 0 ? false : reconcileOptions
131
- );
132
- });
133
- if (queryResource()?.data && result.data && !queryResource.loading && isRestoring())
133
+ if (queryResource()?.data && result.data && !queryResource.loading) {
134
+ setState((store) => {
135
+ return reconcileFn(
136
+ store,
137
+ result,
138
+ reconcileOptions === void 0 ? false : reconcileOptions
139
+ );
140
+ });
134
141
  mutate(state);
135
- else
142
+ } else {
143
+ setState((store) => {
144
+ return reconcileFn(
145
+ store,
146
+ result,
147
+ reconcileOptions === void 0 ? false : reconcileOptions
148
+ );
149
+ });
136
150
  refetch();
151
+ }
137
152
  })();
138
153
  });
139
154
  };
@@ -142,12 +157,13 @@ function createBaseQuery(options, Observer, queryClient) {
142
157
  () => {
143
158
  const obs = observer();
144
159
  return new Promise((resolve, reject) => {
145
- if (isServer)
160
+ if (isServer) {
146
161
  unsubscribe = createServerSubscriber(resolve, reject);
147
- else if (!unsubscribe && !isRestoring())
162
+ } else if (!unsubscribe && !isRestoring()) {
148
163
  unsubscribe = createClientSubscriber();
164
+ }
149
165
  obs.updateResult();
150
- if (!state.isLoading && !isRestoring()) {
166
+ if (!state.isLoading) {
151
167
  const query = obs.getCurrentQuery();
152
168
  resolve(hydratableObserverResult(query, state));
153
169
  }
@@ -197,18 +213,30 @@ function createBaseQuery(options, Observer, queryClient) {
197
213
  );
198
214
  createComputed(
199
215
  on(
200
- [isRestoring, observer],
201
- ([restoring]) => {
202
- const _unsubscribe = unsubscribe;
203
- queueMicrotask(() => _unsubscribe?.());
204
- unsubscribe = null;
205
- if (!restoring)
206
- refetch();
216
+ client,
217
+ (c) => {
218
+ if (unsubscribe) {
219
+ unsubscribe();
220
+ }
221
+ const newObserver = new Observer(c, defaultedOptions());
222
+ unsubscribe = createClientSubscriber();
223
+ setObserver(newObserver);
207
224
  },
208
- { defer: true }
225
+ {
226
+ defer: true
227
+ }
209
228
  )
210
229
  );
230
+ createComputed(() => {
231
+ if (!isRestoring()) {
232
+ refetch();
233
+ }
234
+ });
211
235
  onCleanup(() => {
236
+ if (isServer && queryResource.loading) {
237
+ unsubscribeQueued = true;
238
+ return;
239
+ }
212
240
  if (unsubscribe) {
213
241
  unsubscribe();
214
242
  unsubscribe = null;
@@ -221,11 +249,7 @@ function createBaseQuery(options, Observer, queryClient) {
221
249
  obs.setOptions(opts);
222
250
  setState(obs.getOptimisticResult(opts));
223
251
  },
224
- {
225
- // Defer because we don't need to trigger on first render
226
- // This only cares about changes to options after the observer is created
227
- defer: true
228
- }
252
+ { defer: true }
229
253
  )
230
254
  );
231
255
  createComputed(
@@ -316,8 +340,6 @@ function createMutation(options, queryClient) {
316
340
  onCleanup(unsubscribe);
317
341
  return state;
318
342
  }
319
- function noop() {
320
- }
321
343
  function useIsMutating(filters, queryClient) {
322
344
  const client = createMemo(() => useQueryClient(queryClient?.()));
323
345
  const mutationCache = createMemo(() => client().getMutationCache());
package/build/index.cjs CHANGED
@@ -45,6 +45,8 @@ function shouldThrowError(throwError, params) {
45
45
  }
46
46
  return !!throwError;
47
47
  }
48
+ function noop() {
49
+ }
48
50
  var IsRestoringContext = solidJs.createContext(() => false);
49
51
  exports.useIsRestoring = () => solidJs.useContext(IsRestoringContext);
50
52
  exports.IsRestoringProvider = IsRestoringContext.Provider;
@@ -86,22 +88,19 @@ var hydratableObserverResult = (query, result) => {
86
88
  function createBaseQuery(options, Observer, queryClient) {
87
89
  const client = solidJs.createMemo(() => exports.useQueryClient(queryClient?.()));
88
90
  const isRestoring = exports.useIsRestoring();
89
- const defaultedOptions = solidJs.createMemo(
90
- () => solidJs.mergeProps(client()?.defaultQueryOptions(options()) || {}, {
91
- get _optimisticResults() {
92
- return isRestoring() ? "isRestoring" : "optimistic";
93
- },
94
- structuralSharing: false,
95
- ...web.isServer && { retry: false, throwOnError: true }
96
- })
97
- );
91
+ let unsubscribeQueued = false;
92
+ const defaultedOptions = solidJs.createMemo(() => {
93
+ const defaultOptions = client().defaultQueryOptions(options());
94
+ defaultOptions._optimisticResults = isRestoring() ? "isRestoring" : "optimistic";
95
+ defaultOptions.structuralSharing = false;
96
+ if (web.isServer) {
97
+ defaultOptions.retry = false;
98
+ defaultOptions.throwOnError = true;
99
+ }
100
+ return defaultOptions;
101
+ });
98
102
  const [observer, setObserver] = solidJs.createSignal(
99
- new Observer(client(), solidJs.untrack(defaultedOptions))
100
- );
101
- solidJs.createComputed(
102
- solidJs.on(client, (c) => setObserver(new Observer(c, defaultedOptions())), {
103
- defer: true
104
- })
103
+ new Observer(client(), defaultedOptions())
105
104
  );
106
105
  const [state, setState] = store.createStore(
107
106
  observer().getOptimisticResult(defaultedOptions())
@@ -113,28 +112,44 @@ function createBaseQuery(options, Observer, queryClient) {
113
112
  const unwrappedResult = hydratableObserverResult(query, result);
114
113
  if (unwrappedResult.isError) {
115
114
  reject(unwrappedResult.error);
115
+ unsubscribeIfQueued();
116
116
  } else {
117
117
  resolve(unwrappedResult);
118
+ unsubscribeIfQueued();
118
119
  }
119
120
  })();
120
121
  });
121
122
  };
123
+ const unsubscribeIfQueued = () => {
124
+ if (unsubscribeQueued) {
125
+ unsubscribe?.();
126
+ unsubscribeQueued = false;
127
+ }
128
+ };
122
129
  const createClientSubscriber = () => {
123
130
  const obs = observer();
124
131
  return obs.subscribe((result) => {
125
132
  queryCore.notifyManager.batchCalls(() => {
126
133
  const reconcileOptions = obs.options.reconcile;
127
- setState((store) => {
128
- return reconcileFn(
129
- store,
130
- result,
131
- reconcileOptions === void 0 ? false : reconcileOptions
132
- );
133
- });
134
- if (queryResource()?.data && result.data && !queryResource.loading && isRestoring())
134
+ if (queryResource()?.data && result.data && !queryResource.loading) {
135
+ setState((store) => {
136
+ return reconcileFn(
137
+ store,
138
+ result,
139
+ reconcileOptions === void 0 ? false : reconcileOptions
140
+ );
141
+ });
135
142
  mutate(state);
136
- else
143
+ } else {
144
+ setState((store) => {
145
+ return reconcileFn(
146
+ store,
147
+ result,
148
+ reconcileOptions === void 0 ? false : reconcileOptions
149
+ );
150
+ });
137
151
  refetch();
152
+ }
138
153
  })();
139
154
  });
140
155
  };
@@ -143,12 +158,13 @@ function createBaseQuery(options, Observer, queryClient) {
143
158
  () => {
144
159
  const obs = observer();
145
160
  return new Promise((resolve, reject) => {
146
- if (web.isServer)
161
+ if (web.isServer) {
147
162
  unsubscribe = createServerSubscriber(resolve, reject);
148
- else if (!unsubscribe && !isRestoring())
163
+ } else if (!unsubscribe && !isRestoring()) {
149
164
  unsubscribe = createClientSubscriber();
165
+ }
150
166
  obs.updateResult();
151
- if (!state.isLoading && !isRestoring()) {
167
+ if (!state.isLoading) {
152
168
  const query = obs.getCurrentQuery();
153
169
  resolve(hydratableObserverResult(query, state));
154
170
  }
@@ -198,18 +214,30 @@ function createBaseQuery(options, Observer, queryClient) {
198
214
  );
199
215
  solidJs.createComputed(
200
216
  solidJs.on(
201
- [isRestoring, observer],
202
- ([restoring]) => {
203
- const _unsubscribe = unsubscribe;
204
- queueMicrotask(() => _unsubscribe?.());
205
- unsubscribe = null;
206
- if (!restoring)
207
- refetch();
217
+ client,
218
+ (c) => {
219
+ if (unsubscribe) {
220
+ unsubscribe();
221
+ }
222
+ const newObserver = new Observer(c, defaultedOptions());
223
+ unsubscribe = createClientSubscriber();
224
+ setObserver(newObserver);
208
225
  },
209
- { defer: true }
226
+ {
227
+ defer: true
228
+ }
210
229
  )
211
230
  );
231
+ solidJs.createComputed(() => {
232
+ if (!isRestoring()) {
233
+ refetch();
234
+ }
235
+ });
212
236
  solidJs.onCleanup(() => {
237
+ if (web.isServer && queryResource.loading) {
238
+ unsubscribeQueued = true;
239
+ return;
240
+ }
213
241
  if (unsubscribe) {
214
242
  unsubscribe();
215
243
  unsubscribe = null;
@@ -222,11 +250,7 @@ function createBaseQuery(options, Observer, queryClient) {
222
250
  obs.setOptions(opts);
223
251
  setState(obs.getOptimisticResult(opts));
224
252
  },
225
- {
226
- // Defer because we don't need to trigger on first render
227
- // This only cares about changes to options after the observer is created
228
- defer: true
229
- }
253
+ { defer: true }
230
254
  )
231
255
  );
232
256
  solidJs.createComputed(
@@ -317,8 +341,6 @@ function createMutation(options, queryClient) {
317
341
  solidJs.onCleanup(unsubscribe);
318
342
  return state;
319
343
  }
320
- function noop() {
321
- }
322
344
  function useIsMutating(filters, queryClient) {
323
345
  const client = solidJs.createMemo(() => exports.useQueryClient(queryClient?.()));
324
346
  const mutationCache = solidJs.createMemo(() => client().getMutationCache());
package/build/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { notifyManager, QueryClient as QueryClient$1, MutationObserver, replaceEqualDeep, QueriesObserver, hydrate, QueryObserver, InfiniteQueryObserver } from '@tanstack/query-core';
2
2
  export * from '@tanstack/query-core';
3
- import { batch, createContext, useContext, createRenderEffect, onCleanup, createMemo, createSignal, createComputed, on, createEffect, mergeProps, createResource, onMount, untrack } from 'solid-js';
3
+ import { batch, createContext, useContext, createRenderEffect, onCleanup, createMemo, createSignal, createComputed, on, createEffect, mergeProps, createResource, 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
 
@@ -44,6 +44,8 @@ function shouldThrowError(throwError, params) {
44
44
  }
45
45
  return !!throwError;
46
46
  }
47
+ function noop() {
48
+ }
47
49
  var IsRestoringContext = createContext(() => false);
48
50
  var useIsRestoring = () => useContext(IsRestoringContext);
49
51
  var IsRestoringProvider = IsRestoringContext.Provider;
@@ -85,22 +87,19 @@ var hydratableObserverResult = (query, result) => {
85
87
  function createBaseQuery(options, Observer, queryClient) {
86
88
  const client = createMemo(() => useQueryClient(queryClient?.()));
87
89
  const isRestoring = useIsRestoring();
88
- const defaultedOptions = createMemo(
89
- () => mergeProps(client()?.defaultQueryOptions(options()) || {}, {
90
- get _optimisticResults() {
91
- return isRestoring() ? "isRestoring" : "optimistic";
92
- },
93
- structuralSharing: false,
94
- ...isServer && { retry: false, throwOnError: true }
95
- })
96
- );
90
+ let unsubscribeQueued = false;
91
+ const defaultedOptions = createMemo(() => {
92
+ const defaultOptions = client().defaultQueryOptions(options());
93
+ defaultOptions._optimisticResults = isRestoring() ? "isRestoring" : "optimistic";
94
+ defaultOptions.structuralSharing = false;
95
+ if (isServer) {
96
+ defaultOptions.retry = false;
97
+ defaultOptions.throwOnError = true;
98
+ }
99
+ return defaultOptions;
100
+ });
97
101
  const [observer, setObserver] = createSignal(
98
- new Observer(client(), untrack(defaultedOptions))
99
- );
100
- createComputed(
101
- on(client, (c) => setObserver(new Observer(c, defaultedOptions())), {
102
- defer: true
103
- })
102
+ new Observer(client(), defaultedOptions())
104
103
  );
105
104
  const [state, setState] = createStore(
106
105
  observer().getOptimisticResult(defaultedOptions())
@@ -112,28 +111,44 @@ function createBaseQuery(options, Observer, queryClient) {
112
111
  const unwrappedResult = hydratableObserverResult(query, result);
113
112
  if (unwrappedResult.isError) {
114
113
  reject(unwrappedResult.error);
114
+ unsubscribeIfQueued();
115
115
  } else {
116
116
  resolve(unwrappedResult);
117
+ unsubscribeIfQueued();
117
118
  }
118
119
  })();
119
120
  });
120
121
  };
122
+ const unsubscribeIfQueued = () => {
123
+ if (unsubscribeQueued) {
124
+ unsubscribe?.();
125
+ unsubscribeQueued = false;
126
+ }
127
+ };
121
128
  const createClientSubscriber = () => {
122
129
  const obs = observer();
123
130
  return obs.subscribe((result) => {
124
131
  notifyManager.batchCalls(() => {
125
132
  const reconcileOptions = obs.options.reconcile;
126
- setState((store) => {
127
- return reconcileFn(
128
- store,
129
- result,
130
- reconcileOptions === void 0 ? false : reconcileOptions
131
- );
132
- });
133
- if (queryResource()?.data && result.data && !queryResource.loading && isRestoring())
133
+ if (queryResource()?.data && result.data && !queryResource.loading) {
134
+ setState((store) => {
135
+ return reconcileFn(
136
+ store,
137
+ result,
138
+ reconcileOptions === void 0 ? false : reconcileOptions
139
+ );
140
+ });
134
141
  mutate(state);
135
- else
142
+ } else {
143
+ setState((store) => {
144
+ return reconcileFn(
145
+ store,
146
+ result,
147
+ reconcileOptions === void 0 ? false : reconcileOptions
148
+ );
149
+ });
136
150
  refetch();
151
+ }
137
152
  })();
138
153
  });
139
154
  };
@@ -142,12 +157,13 @@ function createBaseQuery(options, Observer, queryClient) {
142
157
  () => {
143
158
  const obs = observer();
144
159
  return new Promise((resolve, reject) => {
145
- if (isServer)
160
+ if (isServer) {
146
161
  unsubscribe = createServerSubscriber(resolve, reject);
147
- else if (!unsubscribe && !isRestoring())
162
+ } else if (!unsubscribe && !isRestoring()) {
148
163
  unsubscribe = createClientSubscriber();
164
+ }
149
165
  obs.updateResult();
150
- if (!state.isLoading && !isRestoring()) {
166
+ if (!state.isLoading) {
151
167
  const query = obs.getCurrentQuery();
152
168
  resolve(hydratableObserverResult(query, state));
153
169
  }
@@ -197,18 +213,30 @@ function createBaseQuery(options, Observer, queryClient) {
197
213
  );
198
214
  createComputed(
199
215
  on(
200
- [isRestoring, observer],
201
- ([restoring]) => {
202
- const _unsubscribe = unsubscribe;
203
- queueMicrotask(() => _unsubscribe?.());
204
- unsubscribe = null;
205
- if (!restoring)
206
- refetch();
216
+ client,
217
+ (c) => {
218
+ if (unsubscribe) {
219
+ unsubscribe();
220
+ }
221
+ const newObserver = new Observer(c, defaultedOptions());
222
+ unsubscribe = createClientSubscriber();
223
+ setObserver(newObserver);
207
224
  },
208
- { defer: true }
225
+ {
226
+ defer: true
227
+ }
209
228
  )
210
229
  );
230
+ createComputed(() => {
231
+ if (!isRestoring()) {
232
+ refetch();
233
+ }
234
+ });
211
235
  onCleanup(() => {
236
+ if (isServer && queryResource.loading) {
237
+ unsubscribeQueued = true;
238
+ return;
239
+ }
212
240
  if (unsubscribe) {
213
241
  unsubscribe();
214
242
  unsubscribe = null;
@@ -221,11 +249,7 @@ function createBaseQuery(options, Observer, queryClient) {
221
249
  obs.setOptions(opts);
222
250
  setState(obs.getOptimisticResult(opts));
223
251
  },
224
- {
225
- // Defer because we don't need to trigger on first render
226
- // This only cares about changes to options after the observer is created
227
- defer: true
228
- }
252
+ { defer: true }
229
253
  )
230
254
  );
231
255
  createComputed(
@@ -316,8 +340,6 @@ function createMutation(options, queryClient) {
316
340
  onCleanup(unsubscribe);
317
341
  return state;
318
342
  }
319
- function noop() {
320
- }
321
343
  function useIsMutating(filters, queryClient) {
322
344
  const client = createMemo(() => useQueryClient(queryClient?.()));
323
345
  const mutationCache = createMemo(() => client().getMutationCache());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/solid-query",
3
- "version": "5.24.1",
3
+ "version": "5.24.3",
4
4
  "description": "Primitives for managing, caching and syncing asynchronous and remote data in Solid",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -48,7 +48,7 @@
48
48
  ],
49
49
  "dependencies": {
50
50
  "solid-js": "^1.8.14",
51
- "@tanstack/query-core": "5.24.1"
51
+ "@tanstack/query-core": "5.24.2"
52
52
  },
53
53
  "devDependencies": {
54
54
  "tsup-preset-solid": "^2.2.0",
@@ -64,6 +64,7 @@
64
64
  "test:lib": "vitest --retry=3",
65
65
  "test:lib:dev": "pnpm run test:lib --watch",
66
66
  "test:build": "publint --strict",
67
- "build": "tsup"
67
+ "build": "tsup",
68
+ "build:watch": "tsup --watch"
68
69
  }
69
70
  }
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2
1
  // Had to disable the lint rule because isServer type is defined as false
3
2
  // in solid-js/web package. I'll create a GitHub issue with them to see
4
3
  // why that happens.
@@ -9,10 +8,8 @@ import {
9
8
  createMemo,
10
9
  createResource,
11
10
  createSignal,
12
- mergeProps,
13
11
  on,
14
12
  onCleanup,
15
- untrack,
16
13
  } from 'solid-js'
17
14
  import { createStore, reconcile, unwrap } from 'solid-js/store'
18
15
  import { useQueryClient } from './QueryClientProvider'
@@ -123,26 +120,27 @@ export function createBaseQuery<
123
120
 
124
121
  const client = createMemo(() => useQueryClient(queryClient?.()))
125
122
  const isRestoring = useIsRestoring()
126
-
127
- const defaultedOptions = createMemo(() =>
128
- mergeProps(client()?.defaultQueryOptions(options()) || {}, {
129
- get _optimisticResults() {
130
- return isRestoring() ? 'isRestoring' : 'optimistic'
131
- },
132
- structuralSharing: false,
133
- ...(isServer && { retry: false, throwOnError: true }),
134
- }),
135
- )
123
+ // There are times when we run a query on the server but the resource is never read
124
+ // This could lead to times when the queryObserver is unsubscribed before the resource has loaded
125
+ // Causing a time out error. To prevent this we will queue the unsubscribe if the cleanup is called
126
+ // before the resource has loaded
127
+ let unsubscribeQueued = false
128
+
129
+ const defaultedOptions = createMemo(() => {
130
+ const defaultOptions = client().defaultQueryOptions(options())
131
+ defaultOptions._optimisticResults = isRestoring()
132
+ ? 'isRestoring'
133
+ : 'optimistic'
134
+ defaultOptions.structuralSharing = false
135
+ if (isServer) {
136
+ defaultOptions.retry = false
137
+ defaultOptions.throwOnError = true
138
+ }
139
+ return defaultOptions
140
+ })
136
141
 
137
142
  const [observer, setObserver] = createSignal(
138
- new Observer(client(), untrack(defaultedOptions)),
139
- )
140
- // we set the value in a computed because `createMemo`
141
- // returns undefined during transitions
142
- createComputed(
143
- on(client, (c) => setObserver(new Observer(c, defaultedOptions())), {
144
- defer: true,
145
- }),
143
+ new Observer(client(), defaultedOptions()),
146
144
  )
147
145
 
148
146
  const [state, setState] = createStore<QueryObserverResult<TData, TError>>(
@@ -162,13 +160,22 @@ export function createBaseQuery<
162
160
 
163
161
  if (unwrappedResult.isError) {
164
162
  reject(unwrappedResult.error)
163
+ unsubscribeIfQueued()
165
164
  } else {
166
165
  resolve(unwrappedResult)
166
+ unsubscribeIfQueued()
167
167
  }
168
168
  })()
169
169
  })
170
170
  }
171
171
 
172
+ const unsubscribeIfQueued = () => {
173
+ if (unsubscribeQueued) {
174
+ unsubscribe?.()
175
+ unsubscribeQueued = false
176
+ }
177
+ }
178
+
172
179
  const createClientSubscriber = () => {
173
180
  const obs = observer()
174
181
  return obs.subscribe((result) => {
@@ -177,23 +184,27 @@ export function createBaseQuery<
177
184
  // exist on the query-core QueryObserverResult type
178
185
  const reconcileOptions = obs.options.reconcile
179
186
 
180
- setState((store) => {
181
- return reconcileFn(
182
- store,
183
- result,
184
- reconcileOptions === undefined ? false : reconcileOptions,
185
- )
186
- })
187
187
  // If the query has data we don't suspend but instead mutate the resource
188
188
  // This could happen when placeholderData/initialData is defined
189
- if (
190
- queryResource()?.data &&
191
- result.data &&
192
- !queryResource.loading &&
193
- isRestoring()
194
- )
189
+ if (queryResource()?.data && result.data && !queryResource.loading) {
190
+ setState((store) => {
191
+ return reconcileFn(
192
+ store,
193
+ result,
194
+ reconcileOptions === undefined ? false : reconcileOptions,
195
+ )
196
+ })
195
197
  mutate(state)
196
- else refetch()
198
+ } else {
199
+ setState((store) => {
200
+ return reconcileFn(
201
+ store,
202
+ result,
203
+ reconcileOptions === undefined ? false : reconcileOptions,
204
+ )
205
+ })
206
+ refetch()
207
+ }
197
208
  })()
198
209
  })
199
210
  }
@@ -209,13 +220,14 @@ export function createBaseQuery<
209
220
  () => {
210
221
  const obs = observer()
211
222
  return new Promise((resolve, reject) => {
212
- if (isServer) unsubscribe = createServerSubscriber(resolve, reject)
213
- else if (!unsubscribe && !isRestoring())
223
+ if (isServer) {
224
+ unsubscribe = createServerSubscriber(resolve, reject)
225
+ } else if (!unsubscribe && !isRestoring()) {
214
226
  unsubscribe = createClientSubscriber()
215
-
227
+ }
216
228
  obs.updateResult()
217
229
 
218
- if (!state.isLoading && !isRestoring()) {
230
+ if (!state.isLoading) {
219
231
  const query = obs.getCurrentQuery()
220
232
  resolve(hydratableObserverResult(query, state))
221
233
  }
@@ -275,18 +287,32 @@ export function createBaseQuery<
275
287
 
276
288
  createComputed(
277
289
  on(
278
- [isRestoring, observer],
279
- ([restoring]) => {
280
- const _unsubscribe = unsubscribe
281
- queueMicrotask(() => _unsubscribe?.())
282
- unsubscribe = null
283
- if (!restoring) refetch()
290
+ client,
291
+ (c) => {
292
+ if (unsubscribe) {
293
+ unsubscribe()
294
+ }
295
+ const newObserver = new Observer(c, defaultedOptions())
296
+ unsubscribe = createClientSubscriber()
297
+ setObserver(newObserver)
298
+ },
299
+ {
300
+ defer: true,
284
301
  },
285
- { defer: true },
286
302
  ),
287
303
  )
288
304
 
305
+ createComputed(() => {
306
+ if (!isRestoring()) {
307
+ refetch()
308
+ }
309
+ })
310
+
289
311
  onCleanup(() => {
312
+ if (isServer && queryResource.loading) {
313
+ unsubscribeQueued = true
314
+ return
315
+ }
290
316
  if (unsubscribe) {
291
317
  unsubscribe()
292
318
  unsubscribe = null
@@ -300,11 +326,7 @@ export function createBaseQuery<
300
326
  obs.setOptions(opts)
301
327
  setState(obs.getOptimisticResult(opts))
302
328
  },
303
- {
304
- // Defer because we don't need to trigger on first render
305
- // This only cares about changes to options after the observer is created
306
- defer: true,
307
- },
329
+ { defer: true },
308
330
  ),
309
331
  )
310
332
 
@@ -2,7 +2,7 @@ import { MutationObserver } from '@tanstack/query-core'
2
2
  import { createComputed, createMemo, on, onCleanup } from 'solid-js'
3
3
  import { createStore } from 'solid-js/store'
4
4
  import { useQueryClient } from './QueryClientProvider'
5
- import { shouldThrowError } from './utils'
5
+ import { noop, shouldThrowError } from './utils'
6
6
  import type { DefaultError } from '@tanstack/query-core'
7
7
  import type { QueryClient } from './QueryClient'
8
8
  import type {
@@ -74,5 +74,3 @@ export function createMutation<
74
74
 
75
75
  return state
76
76
  }
77
-
78
- function noop() {}
package/src/utils.ts CHANGED
@@ -9,3 +9,5 @@ export function shouldThrowError<T extends (...args: Array<any>) => boolean>(
9
9
 
10
10
  return !!throwError
11
11
  }
12
+
13
+ export function noop() {}