@tanstack/solid-query 4.24.10 → 5.0.0-alpha.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.
Files changed (158) hide show
  1. package/build/cjs/index.js +300 -0
  2. package/build/cjs/index.js.map +1 -0
  3. package/build/esm/index.js +285 -0
  4. package/build/esm/index.js.map +1 -0
  5. package/build/source/QueryClientProvider.jsx +21 -0
  6. package/build/source/__tests__/QueryClientProvider.test.jsx +120 -0
  7. package/build/{solid → source}/__tests__/createInfiniteQuery.test.jsx +228 -372
  8. package/build/{solid → source}/__tests__/createMutation.test.jsx +174 -165
  9. package/build/{solid → source}/__tests__/createQueries.test.jsx +86 -367
  10. package/build/{solid → source}/__tests__/createQuery.test.jsx +991 -943
  11. package/build/{solid → source}/__tests__/createQuery.types.test.jsx +35 -24
  12. package/build/{solid → source}/__tests__/suspense.test.jsx +177 -148
  13. package/build/{solid → source}/__tests__/transition.test.jsx +7 -4
  14. package/build/{solid → source}/__tests__/useIsFetching.test.jsx +68 -85
  15. package/build/{solid → source}/__tests__/useIsMutating.test.jsx +78 -93
  16. package/build/{solid → source}/__tests__/utils.jsx +3 -9
  17. package/build/source/createBaseQuery.js +147 -0
  18. package/build/source/createInfiniteQuery.js +8 -0
  19. package/build/{solid → source}/createMutation.js +7 -9
  20. package/build/source/createQueries.js +32 -0
  21. package/build/source/createQuery.js +6 -0
  22. package/build/{solid → source}/index.js +5 -3
  23. package/build/source/setBatchUpdatesFn.js +3 -0
  24. package/build/source/useIsFetching.js +12 -0
  25. package/build/source/useIsMutating.js +12 -0
  26. package/build/source/utils.js +7 -0
  27. package/build/types/QueryClientProvider.d.ts +9 -0
  28. package/build/{lib → types}/__tests__/utils.d.ts +3 -8
  29. package/build/types/createBaseQuery.d.ts +4 -0
  30. package/build/types/createInfiniteQuery.d.ts +3 -0
  31. package/build/types/createMutation.d.ts +3 -0
  32. package/build/{lib → types}/createQueries.d.ts +10 -8
  33. package/build/types/createQuery.d.ts +11 -0
  34. package/build/{lib → types}/index.d.ts +4 -3
  35. package/build/types/setBatchUpdatesFn.d.ts +1 -0
  36. package/build/types/types.d.ts +33 -0
  37. package/build/types/useIsFetching.d.ts +8 -0
  38. package/build/types/useIsMutating.d.ts +8 -0
  39. package/build/types/utils.d.ts +1 -0
  40. package/build/umd/index.js +2 -0
  41. package/build/umd/index.js.map +1 -0
  42. package/package.json +25 -17
  43. package/src/QueryClientProvider.tsx +17 -86
  44. package/src/__tests__/QueryClientProvider.test.tsx +37 -140
  45. package/src/__tests__/createInfiniteQuery.test.tsx +277 -508
  46. package/src/__tests__/createMutation.test.tsx +177 -225
  47. package/src/__tests__/createQueries.test.tsx +180 -528
  48. package/src/__tests__/createQuery.test.tsx +970 -1200
  49. package/src/__tests__/createQuery.types.test.tsx +30 -25
  50. package/src/__tests__/suspense.test.tsx +141 -178
  51. package/src/__tests__/transition.test.tsx +7 -4
  52. package/src/__tests__/useIsFetching.test.tsx +77 -122
  53. package/src/__tests__/useIsMutating.test.tsx +83 -128
  54. package/src/__tests__/utils.tsx +4 -11
  55. package/src/createBaseQuery.ts +148 -60
  56. package/src/createInfiniteQuery.ts +16 -94
  57. package/src/createMutation.ts +9 -63
  58. package/src/createQueries.ts +44 -55
  59. package/src/createQuery.ts +42 -127
  60. package/src/index.ts +6 -3
  61. package/src/setBatchUpdatesFn.ts +4 -0
  62. package/src/types.ts +81 -75
  63. package/src/useIsFetching.ts +12 -44
  64. package/src/useIsMutating.ts +13 -29
  65. package/src/utils.ts +5 -79
  66. package/build/lib/QueryClientProvider.d.ts +0 -24
  67. package/build/lib/QueryClientProvider.esm.js +0 -74
  68. package/build/lib/QueryClientProvider.esm.js.map +0 -1
  69. package/build/lib/QueryClientProvider.js +0 -80
  70. package/build/lib/QueryClientProvider.js.map +0 -1
  71. package/build/lib/QueryClientProvider.mjs +0 -74
  72. package/build/lib/QueryClientProvider.mjs.map +0 -1
  73. package/build/lib/createBaseQuery.d.ts +0 -4
  74. package/build/lib/createBaseQuery.esm.js +0 -93
  75. package/build/lib/createBaseQuery.esm.js.map +0 -1
  76. package/build/lib/createBaseQuery.js +0 -97
  77. package/build/lib/createBaseQuery.js.map +0 -1
  78. package/build/lib/createBaseQuery.mjs +0 -93
  79. package/build/lib/createBaseQuery.mjs.map +0 -1
  80. package/build/lib/createInfiniteQuery.d.ts +0 -5
  81. package/build/lib/createInfiniteQuery.esm.js +0 -20
  82. package/build/lib/createInfiniteQuery.esm.js.map +0 -1
  83. package/build/lib/createInfiniteQuery.js +0 -24
  84. package/build/lib/createInfiniteQuery.js.map +0 -1
  85. package/build/lib/createInfiniteQuery.mjs +0 -20
  86. package/build/lib/createInfiniteQuery.mjs.map +0 -1
  87. package/build/lib/createMutation.d.ts +0 -6
  88. package/build/lib/createMutation.esm.js +0 -45
  89. package/build/lib/createMutation.esm.js.map +0 -1
  90. package/build/lib/createMutation.js +0 -49
  91. package/build/lib/createMutation.js.map +0 -1
  92. package/build/lib/createMutation.mjs +0 -45
  93. package/build/lib/createMutation.mjs.map +0 -1
  94. package/build/lib/createQueries.esm.js +0 -54
  95. package/build/lib/createQueries.esm.js.map +0 -1
  96. package/build/lib/createQueries.js +0 -58
  97. package/build/lib/createQueries.js.map +0 -1
  98. package/build/lib/createQueries.mjs +0 -54
  99. package/build/lib/createQueries.mjs.map +0 -1
  100. package/build/lib/createQuery.d.ts +0 -23
  101. package/build/lib/createQuery.esm.js +0 -25
  102. package/build/lib/createQuery.esm.js.map +0 -1
  103. package/build/lib/createQuery.js +0 -29
  104. package/build/lib/createQuery.js.map +0 -1
  105. package/build/lib/createQuery.mjs +0 -25
  106. package/build/lib/createQuery.mjs.map +0 -1
  107. package/build/lib/index.esm.js +0 -9
  108. package/build/lib/index.esm.js.map +0 -1
  109. package/build/lib/index.js +0 -31
  110. package/build/lib/index.js.map +0 -1
  111. package/build/lib/index.mjs +0 -9
  112. package/build/lib/index.mjs.map +0 -1
  113. package/build/lib/types.d.ts +0 -47
  114. package/build/lib/useIsFetching.d.ts +0 -7
  115. package/build/lib/useIsFetching.esm.js +0 -29
  116. package/build/lib/useIsFetching.esm.js.map +0 -1
  117. package/build/lib/useIsFetching.js +0 -33
  118. package/build/lib/useIsFetching.js.map +0 -1
  119. package/build/lib/useIsFetching.mjs +0 -29
  120. package/build/lib/useIsFetching.mjs.map +0 -1
  121. package/build/lib/useIsMutating.d.ts +0 -8
  122. package/build/lib/useIsMutating.esm.js +0 -22
  123. package/build/lib/useIsMutating.esm.js.map +0 -1
  124. package/build/lib/useIsMutating.js +0 -26
  125. package/build/lib/useIsMutating.js.map +0 -1
  126. package/build/lib/useIsMutating.mjs +0 -22
  127. package/build/lib/useIsMutating.mjs.map +0 -1
  128. package/build/lib/utils.d.ts +0 -14
  129. package/build/lib/utils.esm.js +0 -63
  130. package/build/lib/utils.esm.js.map +0 -1
  131. package/build/lib/utils.js +0 -72
  132. package/build/lib/utils.js.map +0 -1
  133. package/build/lib/utils.mjs +0 -63
  134. package/build/lib/utils.mjs.map +0 -1
  135. package/build/solid/QueryClientProvider.jsx +0 -49
  136. package/build/solid/__tests__/QueryClientProvider.test.jsx +0 -185
  137. package/build/solid/createBaseQuery.js +0 -81
  138. package/build/solid/createInfiniteQuery.js +0 -16
  139. package/build/solid/createQueries.js +0 -39
  140. package/build/solid/createQuery.js +0 -16
  141. package/build/solid/useIsFetching.js +0 -23
  142. package/build/solid/useIsMutating.js +0 -16
  143. package/build/solid/utils.js +0 -45
  144. package/build/umd/index.development.js +0 -3577
  145. package/build/umd/index.development.js.map +0 -1
  146. package/build/umd/index.production.js +0 -2
  147. package/build/umd/index.production.js.map +0 -1
  148. /package/build/{solid → source}/types.js +0 -0
  149. /package/build/{lib → types}/__tests__/QueryClientProvider.test.d.ts +0 -0
  150. /package/build/{lib → types}/__tests__/createInfiniteQuery.test.d.ts +0 -0
  151. /package/build/{lib → types}/__tests__/createMutation.test.d.ts +0 -0
  152. /package/build/{lib → types}/__tests__/createQueries.test.d.ts +0 -0
  153. /package/build/{lib → types}/__tests__/createQuery.test.d.ts +0 -0
  154. /package/build/{lib → types}/__tests__/createQuery.types.test.d.ts +0 -0
  155. /package/build/{lib → types}/__tests__/suspense.test.d.ts +0 -0
  156. /package/build/{lib → types}/__tests__/transition.test.d.ts +0 -0
  157. /package/build/{lib → types}/__tests__/useIsFetching.test.d.ts +0 -0
  158. /package/build/{lib → types}/__tests__/useIsMutating.test.d.ts +0 -0
@@ -1,8 +1,8 @@
1
1
  import '@testing-library/jest-dom';
2
2
  import { createEffect, createMemo, createRenderEffect, createSignal, ErrorBoundary, Match, on, Switch, } from 'solid-js';
3
3
  import { fireEvent, render, screen, waitFor } from 'solid-testing-library';
4
- import { createQuery, QueryCache, QueryClientProvider } from '..';
5
- import { Blink, createQueryClient, expectType, mockLogger, mockNavigatorOnLine, mockVisibilityState, queryKey, setActTimeout, sleep, } from './utils';
4
+ import { createQuery, QueryCache, QueryClientProvider, keepPreviousData, } from '..';
5
+ import { Blink, createQueryClient, expectType, mockNavigatorOnLine, mockVisibilityState, queryKey, setActTimeout, sleep, } from './utils';
6
6
  describe('createQuery', () => {
7
7
  const queryCache = new QueryCache();
8
8
  const queryClient = createQueryClient({ queryCache });
@@ -12,75 +12,100 @@ describe('createQuery', () => {
12
12
  // eslint-disable-next-line
13
13
  function Page() {
14
14
  // unspecified query function should default to unknown
15
- const noQueryFn = createQuery(key);
15
+ const noQueryFn = createQuery(() => ({ queryKey: key }));
16
16
  expectType(noQueryFn.data);
17
17
  expectType(noQueryFn.error);
18
18
  // it should infer the result type from the query function
19
- const fromQueryFn = createQuery(key, () => 'test');
19
+ const fromQueryFn = createQuery(() => ({
20
+ queryKey: key,
21
+ queryFn: () => 'test',
22
+ }));
20
23
  expectType(fromQueryFn.data);
21
24
  expectType(fromQueryFn.error);
22
25
  // it should be possible to specify the result type
23
- const withResult = createQuery(key, () => 'test');
26
+ const withResult = createQuery(() => ({
27
+ queryKey: key,
28
+ queryFn: () => 'test',
29
+ }));
24
30
  expectType(withResult.data);
25
31
  expectType(withResult.error);
26
32
  // it should be possible to specify the error type
27
- const withError = createQuery(key, () => 'test');
33
+ const withError = createQuery(() => ({
34
+ queryKey: key,
35
+ queryFn: () => 'test',
36
+ }));
28
37
  expectType(withError.data);
29
38
  expectType(withError.error);
30
39
  // it should provide the result type in the configuration
31
- createQuery(() => [key()], async () => true, {
40
+ createQuery(() => ({
41
+ queryKey: [key],
42
+ queryFn: async () => true,
32
43
  onSuccess: (data) => expectType(data),
33
44
  onSettled: (data) => expectType(data),
34
- });
45
+ }));
35
46
  // it should be possible to specify a union type as result type
36
- const unionTypeSync = createQuery(key, () => (Math.random() > 0.5 ? 'a' : 'b'), {
47
+ const unionTypeSync = createQuery(() => ({
48
+ queryKey: key,
49
+ queryFn: () => (Math.random() > 0.5 ? 'a' : 'b'),
37
50
  onSuccess: (data) => expectType(data),
38
- });
51
+ }));
39
52
  expectType(unionTypeSync.data);
40
- const unionTypeAsync = createQuery(key, () => Promise.resolve(Math.random() > 0.5 ? 'a' : 'b'), {
53
+ const unionTypeAsync = createQuery(() => ({
54
+ queryKey: key,
55
+ queryFn: () => Promise.resolve(Math.random() > 0.5 ? 'a' : 'b'),
41
56
  onSuccess: (data) => expectType(data),
42
- });
57
+ }));
43
58
  expectType(unionTypeAsync.data);
44
59
  // should error when the query function result does not match with the specified type
45
60
  // @ts-expect-error
46
- createQuery(key, () => 'test');
61
+ createQuery(() => ({ queryKey: key, queryFn: () => 'test' }));
47
62
  // it should infer the result type from a generic query function
48
63
  function queryFn() {
49
64
  return Promise.resolve({});
50
65
  }
51
- const fromGenericQueryFn = createQuery(key, () => queryFn());
66
+ const fromGenericQueryFn = createQuery(() => ({
67
+ queryKey: key,
68
+ queryFn: () => queryFn(),
69
+ }));
52
70
  expectType(fromGenericQueryFn.data);
53
71
  expectType(fromGenericQueryFn.error);
54
- const fromGenericOptionsQueryFn = createQuery({
72
+ const fromGenericOptionsQueryFn = createQuery(() => ({
55
73
  queryKey: key,
56
74
  queryFn: () => queryFn(),
57
- });
75
+ }));
58
76
  expectType(fromGenericOptionsQueryFn.data);
59
77
  expectType(fromGenericOptionsQueryFn.error);
60
78
  const getMyDataArrayKey = async ({ queryKey: [, n], }) => {
61
79
  return n + 42;
62
80
  };
63
- createQuery({
64
- queryKey: () => ['my-data', 100],
81
+ createQuery(() => ({
82
+ queryKey: ['my-data', 100],
65
83
  queryFn: getMyDataArrayKey,
66
- });
84
+ }));
67
85
  const getMyDataStringKey = async (context) => {
68
86
  expectType(context.queryKey);
69
87
  return Number(context.queryKey[0]) + 42;
70
88
  };
71
- createQuery({
72
- queryKey: () => ['1'],
89
+ createQuery(() => ({
90
+ queryKey: ['1'],
73
91
  queryFn: getMyDataStringKey,
74
- });
92
+ }));
75
93
  // it should handle query-functions that return Promise<any>
76
- createQuery(key, () => fetch('return Promise<any>').then((resp) => resp.json()));
94
+ createQuery(() => ({
95
+ queryKey: key,
96
+ queryFn: () => fetch('return Promise<any>').then((resp) => resp.json()),
97
+ }));
77
98
  // handles wrapped queries with custom fetcher passed as inline queryFn
78
- const useWrappedQuery = (qk, fetcher, options) => createQuery(qk, () => fetcher(qk()[1], 'token'), options);
79
- const test = useWrappedQuery(() => [''], async () => '1');
99
+ const useWrappedQuery = (qk, fetcher, options) => createQuery(() => ({
100
+ queryKey: qk,
101
+ queryFn: () => fetcher(qk[1], 'token'),
102
+ ...options,
103
+ }));
104
+ const test = useWrappedQuery([''], async () => '1');
80
105
  expectType(test.data);
81
106
  // handles wrapped queries with custom fetcher passed directly to createQuery
82
- const useWrappedFuncStyleQuery = (qk, fetcher, options) => createQuery(qk, fetcher, options);
83
- const testFuncStyle = useWrappedFuncStyleQuery(() => [''], async () => true);
107
+ const useWrappedFuncStyleQuery = (qk, fetcher, options) => createQuery(() => ({ queryKey: qk, queryFn: fetcher, ...options }));
108
+ const testFuncStyle = useWrappedFuncStyleQuery([''], async () => true);
84
109
  expectType(testFuncStyle.data);
85
110
  }
86
111
  });
@@ -88,10 +113,13 @@ describe('createQuery', () => {
88
113
  it('should allow to set default data value', async () => {
89
114
  const key = queryKey();
90
115
  function Page() {
91
- const state = createQuery(key, async () => {
92
- await sleep(10);
93
- return 'test';
94
- });
116
+ const state = createQuery(() => ({
117
+ queryKey: key,
118
+ queryFn: async () => {
119
+ await sleep(10);
120
+ return 'test';
121
+ },
122
+ }));
95
123
  return (<div>
96
124
  <h1>{state.data ?? 'default'}</h1>
97
125
  </div>);
@@ -106,14 +134,17 @@ describe('createQuery', () => {
106
134
  const key = queryKey();
107
135
  const states = [];
108
136
  function Page() {
109
- const state = createQuery(key, async () => {
110
- await sleep(10);
111
- return 'test';
112
- });
137
+ const state = createQuery(() => ({
138
+ queryKey: key,
139
+ queryFn: async () => {
140
+ await sleep(10);
141
+ return 'test';
142
+ },
143
+ }));
113
144
  createRenderEffect(() => {
114
145
  states.push({ ...state });
115
146
  });
116
- if (state.isLoading) {
147
+ if (state.isPending) {
117
148
  expectType(state.data);
118
149
  expectType(state.error);
119
150
  }
@@ -126,8 +157,8 @@ describe('createQuery', () => {
126
157
  expectType(state.error);
127
158
  }
128
159
  return (<Switch fallback={<span>{state.data}</span>}>
129
- <Match when={state.isLoading}>
130
- <span>loading</span>
160
+ <Match when={state.isPending}>
161
+ <span>pending</span>
131
162
  </Match>
132
163
  <Match when={state.isLoadingError}>
133
164
  <span>{state.error.message}</span>
@@ -152,18 +183,17 @@ describe('createQuery', () => {
152
183
  isFetchedAfterMount: false,
153
184
  isFetching: true,
154
185
  isPaused: false,
155
- isLoading: true,
186
+ isPending: true,
156
187
  isInitialLoading: true,
188
+ isLoading: true,
157
189
  isLoadingError: false,
158
190
  isPlaceholderData: false,
159
- isPreviousData: false,
160
191
  isRefetchError: false,
161
192
  isRefetching: false,
162
193
  isStale: true,
163
194
  isSuccess: false,
164
195
  refetch: expect.any(Function),
165
- remove: expect.any(Function),
166
- status: 'loading',
196
+ status: 'pending',
167
197
  fetchStatus: 'fetching',
168
198
  });
169
199
  expect(states[1]).toEqual({
@@ -179,17 +209,16 @@ describe('createQuery', () => {
179
209
  isFetchedAfterMount: true,
180
210
  isFetching: false,
181
211
  isPaused: false,
182
- isLoading: false,
212
+ isPending: false,
183
213
  isInitialLoading: false,
214
+ isLoading: false,
184
215
  isLoadingError: false,
185
216
  isPlaceholderData: false,
186
- isPreviousData: false,
187
217
  isRefetchError: false,
188
218
  isRefetching: false,
189
219
  isStale: true,
190
220
  isSuccess: true,
191
221
  refetch: expect.any(Function),
192
- remove: expect.any(Function),
193
222
  status: 'success',
194
223
  fetchStatus: 'idle',
195
224
  });
@@ -198,17 +227,19 @@ describe('createQuery', () => {
198
227
  const key = queryKey();
199
228
  const states = [];
200
229
  function Page() {
201
- const state = createQuery(key, () => Promise.reject('rejected'), {
230
+ const state = createQuery(() => ({
231
+ queryKey: key,
232
+ queryFn: () => Promise.reject(new Error('rejected')),
202
233
  retry: 1,
203
234
  retryDelay: 1,
204
- });
235
+ }));
205
236
  createRenderEffect(() => {
206
237
  states.push({ ...state });
207
238
  });
208
239
  return (<div>
209
240
  <h1>Status: {state.status}</h1>
210
241
  <div>Failure Count: {state.failureCount}</div>
211
- <div>Failure Reason: {state.failureReason}</div>
242
+ <div>Failure Reason: {state.failureReason?.message}</div>
212
243
  </div>);
213
244
  }
214
245
  render(() => (<QueryClientProvider client={queryClient}>
@@ -228,18 +259,17 @@ describe('createQuery', () => {
228
259
  isFetchedAfterMount: false,
229
260
  isFetching: true,
230
261
  isPaused: false,
231
- isLoading: true,
262
+ isPending: true,
232
263
  isInitialLoading: true,
264
+ isLoading: true,
233
265
  isLoadingError: false,
234
266
  isPlaceholderData: false,
235
- isPreviousData: false,
236
267
  isRefetchError: false,
237
268
  isRefetching: false,
238
269
  isStale: true,
239
270
  isSuccess: false,
240
271
  refetch: expect.any(Function),
241
- remove: expect.any(Function),
242
- status: 'loading',
272
+ status: 'pending',
243
273
  fetchStatus: 'fetching',
244
274
  });
245
275
  expect(states[1]).toEqual({
@@ -248,51 +278,49 @@ describe('createQuery', () => {
248
278
  error: null,
249
279
  errorUpdatedAt: 0,
250
280
  failureCount: 1,
251
- failureReason: 'rejected',
281
+ failureReason: new Error('rejected'),
252
282
  errorUpdateCount: 0,
253
283
  isError: false,
254
284
  isFetched: false,
255
285
  isFetchedAfterMount: false,
256
286
  isFetching: true,
257
287
  isPaused: false,
258
- isLoading: true,
288
+ isPending: true,
259
289
  isInitialLoading: true,
290
+ isLoading: true,
260
291
  isLoadingError: false,
261
292
  isPlaceholderData: false,
262
- isPreviousData: false,
263
293
  isRefetchError: false,
264
294
  isRefetching: false,
265
295
  isStale: true,
266
296
  isSuccess: false,
267
297
  refetch: expect.any(Function),
268
- remove: expect.any(Function),
269
- status: 'loading',
298
+ status: 'pending',
270
299
  fetchStatus: 'fetching',
271
300
  });
272
301
  expect(states[2]).toEqual({
273
302
  data: undefined,
274
303
  dataUpdatedAt: 0,
275
- error: 'rejected',
304
+ error: new Error('rejected'),
276
305
  errorUpdatedAt: expect.any(Number),
277
306
  failureCount: 2,
278
- failureReason: 'rejected',
307
+ failureReason: new Error('rejected'),
279
308
  errorUpdateCount: 1,
280
309
  isError: true,
281
310
  isFetched: true,
282
311
  isFetchedAfterMount: true,
283
312
  isFetching: false,
284
313
  isPaused: false,
285
- isLoading: false,
314
+ isPending: false,
286
315
  isInitialLoading: false,
316
+ isLoading: false,
287
317
  isLoadingError: true,
288
318
  isPlaceholderData: false,
289
- isPreviousData: false,
290
319
  isRefetchError: false,
291
320
  isRefetching: false,
292
321
  isStale: true,
293
322
  isSuccess: false,
294
323
  refetch: expect.any(Function),
295
- remove: expect.any(Function),
296
324
  status: 'error',
297
325
  fetchStatus: 'idle',
298
326
  });
@@ -300,10 +328,15 @@ describe('createQuery', () => {
300
328
  it('should set isFetchedAfterMount to true after a query has been fetched', async () => {
301
329
  const key = queryKey();
302
330
  const states = [];
303
- // TODO(lukemurray): do we want reactivity on this key?
304
- await queryClient.prefetchQuery(key(), () => 'prefetched');
331
+ await queryClient.prefetchQuery({
332
+ queryKey: key,
333
+ queryFn: () => 'prefetched',
334
+ });
305
335
  function Page() {
306
- const state = createQuery(key, () => 'data');
336
+ const state = createQuery(() => ({
337
+ queryKey: key,
338
+ queryFn: () => 'data',
339
+ }));
307
340
  createRenderEffect(() => {
308
341
  states.push({ ...state });
309
342
  });
@@ -330,10 +363,14 @@ describe('createQuery', () => {
330
363
  const states = [];
331
364
  const onSuccess = jest.fn();
332
365
  function Page() {
333
- const state = createQuery(key, async () => {
334
- await sleep(10);
335
- return 'data';
336
- }, { onSuccess });
366
+ const state = createQuery(() => ({
367
+ queryKey: key,
368
+ queryFn: async () => {
369
+ await sleep(10);
370
+ return 'data';
371
+ },
372
+ onSuccess,
373
+ }));
337
374
  createRenderEffect(() => {
338
375
  states.push({ ...state });
339
376
  });
@@ -347,44 +384,17 @@ describe('createQuery', () => {
347
384
  expect(onSuccess).toHaveBeenCalledTimes(1);
348
385
  expect(onSuccess).toHaveBeenCalledWith('data');
349
386
  });
350
- it('should call onSuccess after a query has been refetched', async () => {
351
- const key = queryKey();
352
- const states = [];
353
- const onSuccess = jest.fn();
354
- let count = 0;
355
- function Page() {
356
- const state = createQuery(key, async () => {
357
- count++;
358
- await sleep(10);
359
- return 'data' + count;
360
- }, { onSuccess });
361
- createRenderEffect(on(() => [state.data, state.refetch], () => {
362
- states.push(state);
363
- }));
364
- return (<div>
365
- <div>data: {state.data}</div>
366
- <button onClick={() => state.refetch()}>refetch</button>
367
- </div>);
368
- }
369
- render(() => (<QueryClientProvider client={queryClient}>
370
- <Page />
371
- </QueryClientProvider>));
372
- await screen.findByText('data: data1');
373
- fireEvent.click(screen.getByRole('button', { name: /refetch/i }));
374
- await screen.findByText('data: data2');
375
- expect(states.length).toBe(3); //loading, success, success after refetch
376
- expect(count).toBe(2);
377
- expect(onSuccess).toHaveBeenCalledTimes(2);
378
- });
379
387
  it('should call onSuccess after a disabled query has been fetched', async () => {
380
388
  const key = queryKey();
381
389
  const states = [];
382
390
  const onSuccess = jest.fn();
383
391
  function Page() {
384
- const state = createQuery(key, () => 'data', {
392
+ const state = createQuery(() => ({
393
+ queryKey: key,
394
+ queryFn: () => 'data',
385
395
  enabled: false,
386
396
  onSuccess,
387
- });
397
+ }));
388
398
  createRenderEffect(() => {
389
399
  states.push({ ...state });
390
400
  });
@@ -415,10 +425,14 @@ describe('createQuery', () => {
415
425
  return <>{show() && <Component />}</>;
416
426
  }
417
427
  function Component() {
418
- const state = createQuery(key, async () => {
419
- await sleep(10);
420
- return 'data';
421
- }, { onSuccess });
428
+ const state = createQuery(() => ({
429
+ queryKey: key,
430
+ queryFn: async () => {
431
+ await sleep(10);
432
+ return 'data';
433
+ },
434
+ onSuccess,
435
+ }));
422
436
  createRenderEffect(() => {
423
437
  states.push({ ...state });
424
438
  });
@@ -436,10 +450,12 @@ describe('createQuery', () => {
436
450
  const states = [];
437
451
  const onError = jest.fn();
438
452
  function Page() {
439
- const state = createQuery(key, () => Promise.reject('error'), {
453
+ const state = createQuery(() => ({
454
+ queryKey: key,
455
+ queryFn: () => Promise.reject(new Error('error')),
440
456
  retry: false,
441
457
  onError,
442
- });
458
+ }));
443
459
  createRenderEffect(() => {
444
460
  states.push({ ...state });
445
461
  });
@@ -451,18 +467,20 @@ describe('createQuery', () => {
451
467
  await sleep(10);
452
468
  expect(states.length).toBe(2);
453
469
  expect(onError).toHaveBeenCalledTimes(1);
454
- expect(onError).toHaveBeenCalledWith('error');
470
+ expect(onError).toHaveBeenCalledWith(new Error('error'));
455
471
  });
456
472
  it('should not call onError when receiving a CancelledError', async () => {
457
473
  const key = queryKey();
458
474
  const onError = jest.fn();
459
475
  function Page() {
460
- const state = createQuery(key, async () => {
461
- await sleep(10);
462
- return 23;
463
- }, {
476
+ const state = createQuery(() => ({
477
+ queryKey: key,
478
+ queryFn: async () => {
479
+ await sleep(10);
480
+ return 23;
481
+ },
464
482
  onError,
465
- });
483
+ }));
466
484
  return (<span>
467
485
  status: {state.status}, fetchStatus: {state.fetchStatus}
468
486
  </span>);
@@ -471,9 +489,9 @@ describe('createQuery', () => {
471
489
  <Page />
472
490
  </QueryClientProvider>));
473
491
  await sleep(5);
474
- await queryClient.cancelQueries(key());
492
+ await queryClient.cancelQueries({ queryKey: key });
475
493
  // query cancellation will reset the query to it's initial state
476
- await waitFor(() => screen.getByText('status: loading, fetchStatus: idle'));
494
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'));
477
495
  expect(onError).not.toHaveBeenCalled();
478
496
  });
479
497
  it('should call onSettled after a query has been fetched', async () => {
@@ -481,7 +499,11 @@ describe('createQuery', () => {
481
499
  const states = [];
482
500
  const onSettled = jest.fn();
483
501
  function Page() {
484
- const state = createQuery(key, () => 'data', { onSettled });
502
+ const state = createQuery(() => ({
503
+ queryKey: key,
504
+ queryFn: () => 'data',
505
+ onSettled,
506
+ }));
485
507
  createRenderEffect(() => {
486
508
  states.push({ ...state });
487
509
  });
@@ -500,10 +522,12 @@ describe('createQuery', () => {
500
522
  const states = [];
501
523
  const onSettled = jest.fn();
502
524
  function Page() {
503
- const state = createQuery(key, () => Promise.reject('error'), {
525
+ const state = createQuery(() => ({
526
+ queryKey: key,
527
+ queryFn: () => Promise.reject('error'),
504
528
  retry: false,
505
529
  onSettled,
506
- });
530
+ }));
507
531
  createRenderEffect(() => {
508
532
  states.push({ ...state });
509
533
  });
@@ -521,11 +545,16 @@ describe('createQuery', () => {
521
545
  const key = queryKey();
522
546
  let fetchCount = 0;
523
547
  function Page() {
524
- const state = createQuery(key, async () => {
525
- fetchCount++;
526
- await sleep(10);
527
- return 'data';
528
- }, { enabled: false, initialData: 'initialData' });
548
+ const state = createQuery(() => ({
549
+ queryKey: key,
550
+ queryFn: async () => {
551
+ fetchCount++;
552
+ await sleep(10);
553
+ return 'data';
554
+ },
555
+ enabled: false,
556
+ initialData: 'initialData',
557
+ }));
529
558
  createEffect(() => {
530
559
  setActTimeout(() => {
531
560
  state.refetch();
@@ -547,11 +576,16 @@ describe('createQuery', () => {
547
576
  const key = queryKey();
548
577
  let fetchCount = 0;
549
578
  function Page() {
550
- const state = createQuery(key, async () => {
551
- fetchCount++;
552
- await sleep(10);
553
- return 'data';
554
- }, { enabled: false, initialData: 'initialData' });
579
+ const state = createQuery(() => ({
580
+ queryKey: key,
581
+ queryFn: async () => {
582
+ fetchCount++;
583
+ await sleep(10);
584
+ return 'data';
585
+ },
586
+ enabled: false,
587
+ initialData: 'initialData',
588
+ }));
555
589
  createEffect(() => {
556
590
  setActTimeout(() => {
557
591
  state.refetch();
@@ -573,11 +607,15 @@ describe('createQuery', () => {
573
607
  const key = queryKey();
574
608
  let fetchCount = 0;
575
609
  function Page() {
576
- const state = createQuery(key, async () => {
577
- fetchCount++;
578
- await sleep(10);
579
- return 'data';
580
- }, { enabled: false });
610
+ const state = createQuery(() => ({
611
+ queryKey: key,
612
+ queryFn: async () => {
613
+ fetchCount++;
614
+ await sleep(10);
615
+ return 'data';
616
+ },
617
+ enabled: false,
618
+ }));
581
619
  createEffect(() => {
582
620
  setActTimeout(() => {
583
621
  state.refetch();
@@ -598,10 +636,9 @@ describe('createQuery', () => {
598
636
  it('should be able to watch a query without providing a query function', async () => {
599
637
  const key = queryKey();
600
638
  const states = [];
601
- // TODO(lukemurray): do we want this to be reactive.
602
- queryClient.setQueryDefaults(key(), { queryFn: () => 'data' });
639
+ queryClient.setQueryDefaults(key, { queryFn: () => 'data' });
603
640
  function Page() {
604
- const state = createQuery(key);
641
+ const state = createQuery(() => ({ queryKey: key }));
605
642
  createRenderEffect(() => {
606
643
  states.push({ ...state });
607
644
  });
@@ -615,7 +652,7 @@ describe('createQuery', () => {
615
652
  expect(states[0]).toMatchObject({ data: undefined });
616
653
  expect(states[1]).toMatchObject({ data: 'data' });
617
654
  });
618
- it('should pick up a query when re-mounting with cacheTime 0', async () => {
655
+ it('should pick up a query when re-mounting with gcTime 0', async () => {
619
656
  const key = queryKey();
620
657
  const states = [];
621
658
  function Page() {
@@ -633,13 +670,14 @@ describe('createQuery', () => {
633
670
  </div>);
634
671
  }
635
672
  function Component({ value }) {
636
- const state = createQuery(key, async () => {
637
- await sleep(10);
638
- return 'data: ' + value;
639
- }, {
640
- cacheTime: 0,
641
- notifyOnChangeProps: 'all',
642
- });
673
+ const state = createQuery(() => ({
674
+ queryKey: key,
675
+ queryFn: async () => {
676
+ await sleep(10);
677
+ return 'data: ' + value;
678
+ },
679
+ gcTime: 0,
680
+ }));
643
681
  createRenderEffect(() => {
644
682
  states.push({ ...state });
645
683
  });
@@ -656,78 +694,38 @@ describe('createQuery', () => {
656
694
  expect(states.length).toBe(4);
657
695
  // First load
658
696
  expect(states[0]).toMatchObject({
659
- isLoading: true,
697
+ isPending: true,
660
698
  isSuccess: false,
661
699
  isFetching: true,
662
700
  });
663
701
  // First success
664
702
  expect(states[1]).toMatchObject({
665
- isLoading: false,
703
+ isPending: false,
666
704
  isSuccess: true,
667
705
  isFetching: false,
668
706
  });
669
707
  // Switch, goes to fetching
670
708
  expect(states[2]).toMatchObject({
671
- isLoading: false,
709
+ isPending: false,
672
710
  isSuccess: true,
673
711
  isFetching: true,
674
712
  });
675
713
  // Second success
676
714
  expect(states[3]).toMatchObject({
677
- isLoading: false,
715
+ isPending: false,
678
716
  isSuccess: true,
679
717
  isFetching: false,
680
718
  });
681
719
  });
682
- it.skip('should not get into an infinite loop when removing a query with cacheTime 0 and rerendering', async () => {
683
- const key = queryKey();
684
- const states = [];
685
- function Page() {
686
- //@ts-expect-error -- skip this test
687
- const [, rerender] = NotReact.useState({});
688
- const state = createQuery(key, async () => {
689
- await sleep(5);
690
- return 'data';
691
- }, {
692
- cacheTime: 0,
693
- notifyOnChangeProps: 'all',
694
- });
695
- createRenderEffect(() => {
696
- states.push({ ...state });
697
- });
698
- const { remove } = state;
699
- //@ts-expect-error skip this test
700
- NotReact.useEffect(() => {
701
- setActTimeout(() => {
702
- remove();
703
- rerender({});
704
- }, 20);
705
- }, [remove]);
706
- return null;
707
- }
708
- render(() => (<QueryClientProvider client={queryClient}>
709
- <Page />
710
- </QueryClientProvider>));
711
- await sleep(100);
712
- expect(states.length).toBe(5);
713
- // First load
714
- expect(states[0]).toMatchObject({ isLoading: true, isSuccess: false });
715
- // First success
716
- expect(states[1]).toMatchObject({ isLoading: false, isSuccess: true });
717
- // Remove
718
- expect(states[2]).toMatchObject({ isLoading: true, isSuccess: false });
719
- // Hook state update
720
- expect(states[3]).toMatchObject({ isLoading: true, isSuccess: false });
721
- // Second success
722
- expect(states[4]).toMatchObject({ isLoading: false, isSuccess: true });
723
- });
724
720
  it('should fetch when refetchOnMount is false and nothing has been fetched yet', async () => {
725
721
  const key = queryKey();
726
722
  const states = [];
727
723
  function Page() {
728
- const state = createQuery(key, () => 'test', {
724
+ const state = createQuery(() => ({
725
+ queryKey: key,
726
+ queryFn: () => 'test',
729
727
  refetchOnMount: false,
730
- });
728
+ }));
731
729
  createRenderEffect(() => {
732
730
  states.push({ ...state });
733
731
  });
@@ -744,11 +742,13 @@ describe('createQuery', () => {
744
742
  it('should not fetch when refetchOnMount is false and data has been fetched already', async () => {
745
743
  const key = queryKey();
746
744
  const states = [];
747
- queryClient.setQueryData(key(), 'prefetched');
745
+ queryClient.setQueryData(key, 'prefetched');
748
746
  function Page() {
749
- const state = createQuery(key, () => 'test', {
747
+ const state = createQuery(() => ({
748
+ queryKey: key,
749
+ queryFn: () => 'test',
750
750
  refetchOnMount: false,
751
- });
751
+ }));
752
752
  createRenderEffect(() => {
753
753
  states.push({ ...state });
754
754
  });
@@ -765,9 +765,11 @@ describe('createQuery', () => {
765
765
  const key = queryKey();
766
766
  const states = [];
767
767
  function Page() {
768
- const state = createQuery(key, () => ({ name: 'test' }), {
768
+ const state = createQuery(() => ({
769
+ queryKey: key,
770
+ queryFn: () => ({ name: 'test' }),
769
771
  select: (data) => data.name,
770
- });
772
+ }));
771
773
  createRenderEffect(() => {
772
774
  states.push({ ...state });
773
775
  });
@@ -785,11 +787,11 @@ describe('createQuery', () => {
785
787
  const key = queryKey();
786
788
  const states = [];
787
789
  function Page() {
788
- const state = createQuery({
790
+ const state = createQuery(() => ({
789
791
  queryKey: key,
790
792
  queryFn: () => ({ name: 'test' }),
791
793
  select: (data) => data.name,
792
- });
794
+ }));
793
795
  createRenderEffect(() => {
794
796
  states.push({ ...state });
795
797
  });
@@ -803,23 +805,18 @@ describe('createQuery', () => {
803
805
  expect(states[0]).toMatchObject({ data: undefined });
804
806
  expect(states[1]).toMatchObject({ data: 'test' });
805
807
  });
806
- it('should not re-render when it should only re-render only data change and the selected data did not change', async () => {
808
+ it('should be able to select a part of the data with select in object syntax', async () => {
807
809
  const key = queryKey();
808
810
  const states = [];
809
811
  function Page() {
810
- const state = createQuery(key, () => ({ name: 'test' }), {
812
+ const state = createQuery(() => ({
813
+ queryKey: key,
814
+ queryFn: () => ({ name: 'test' }),
811
815
  select: (data) => data.name,
812
- notifyOnChangeProps: ['data'],
813
- });
816
+ }));
814
817
  createRenderEffect(() => {
815
818
  states.push({ ...state });
816
819
  });
817
- createEffect(() => {
818
- const refetch = state.refetch;
819
- setActTimeout(() => {
820
- refetch();
821
- }, 5);
822
- });
823
820
  return null;
824
821
  }
825
822
  render(() => (<QueryClientProvider client={queryClient}>
@@ -830,69 +827,71 @@ describe('createQuery', () => {
830
827
  expect(states[0]).toMatchObject({ data: undefined });
831
828
  expect(states[1]).toMatchObject({ data: 'test' });
832
829
  });
833
- it('should throw an error when a selector throws', async () => {
830
+ it('should not re-render when it should only re-render only data change and the selected data did not change', async () => {
834
831
  const key = queryKey();
835
832
  const states = [];
836
- const error = new Error('Select Error');
837
833
  function Page() {
838
- const state = createQuery(key, () => ({ name: 'test' }), {
839
- select: () => {
840
- throw error;
834
+ const state = createQuery(() => ({
835
+ queryKey: key,
836
+ queryFn: async () => {
837
+ await sleep(10);
838
+ return { name: 'test' };
841
839
  },
842
- });
840
+ select: (data) => data.name,
841
+ notifyOnChangeProps: ['data'],
842
+ }));
843
843
  createRenderEffect(() => {
844
844
  states.push({ ...state });
845
845
  });
846
- return null;
846
+ return (<div>
847
+ data: {state.data}
848
+ <button onClick={() => state.refetch()}>refetch</button>
849
+ </div>);
847
850
  }
848
851
  render(() => (<QueryClientProvider client={queryClient}>
849
852
  <Page />
850
853
  </QueryClientProvider>));
851
- await sleep(10);
852
- expect(mockLogger.error).toHaveBeenCalledWith(error);
854
+ await waitFor(() => screen.getByText('data: test'));
853
855
  expect(states.length).toBe(2);
854
- expect(states[0]).toMatchObject({ status: 'loading', data: undefined });
855
- expect(states[1]).toMatchObject({ status: 'error', error });
856
+ expect(states[0]).toMatchObject({ data: undefined });
857
+ expect(states[1]).toMatchObject({ data: 'test' });
856
858
  });
857
- it.skip('should not re-run a stable select when it re-renders if selector throws an error', async () => {
859
+ it('should throw an error when a selector throws', async () => {
858
860
  const key = queryKey();
861
+ const states = [];
859
862
  const error = new Error('Select Error');
860
- let runs = 0;
861
863
  function Page() {
862
- //@ts-expect-error -- we skip this test, and no such thing as rerender in solid
863
- const [, rerender] = NotReact.useReducer(() => ({}), {});
864
- const state = createQuery(key, () => (runs === 0 ? 'test' : 'test2'), {
864
+ const state = createQuery(() => ({
865
+ queryKey: key,
866
+ queryFn: () => ({ name: 'test' }),
865
867
  select: () => {
866
- runs++;
867
868
  throw error;
868
869
  },
870
+ }));
871
+ createRenderEffect(() => {
872
+ states.push({ ...state });
869
873
  });
870
- return (<div>
871
- <div>error: {state.error?.message}</div>
872
- <button onClick={rerender}>rerender</button>
873
- <button onClick={() => state.refetch()}>refetch</button>
874
- </div>);
874
+ return null;
875
875
  }
876
876
  render(() => (<QueryClientProvider client={queryClient}>
877
877
  <Page />
878
878
  </QueryClientProvider>));
879
- await waitFor(() => screen.getByText('error: Select Error'));
880
- expect(runs).toEqual(1);
881
- fireEvent.click(screen.getByRole('button', { name: 'rerender' }));
882
- await sleep(10);
883
- expect(runs).toEqual(1);
884
- fireEvent.click(screen.getByRole('button', { name: 'refetch' }));
885
879
  await sleep(10);
886
- expect(runs).toEqual(2);
880
+ expect(states.length).toBe(2);
881
+ expect(states[0]).toMatchObject({ status: 'pending', data: undefined });
882
+ expect(states[1]).toMatchObject({ status: 'error', error });
887
883
  });
888
884
  it('should track properties and only re-render when a tracked property changes', async () => {
889
885
  const key = queryKey();
890
886
  const states = [];
891
887
  function Page() {
892
- const state = createQuery(key, async () => {
893
- await sleep(10);
894
- return 'test';
895
- });
888
+ const state = createQuery(() => ({
889
+ queryKey: key,
890
+ queryFn: async () => {
891
+ await sleep(10);
892
+ return 'test';
893
+ },
894
+ }));
896
895
  createRenderEffect(() => {
897
896
  states.push({ ...state });
898
897
  });
@@ -922,7 +921,10 @@ describe('createQuery', () => {
922
921
  let renderCount = 0;
923
922
  const states = [];
924
923
  function Page() {
925
- const state = createQuery(key, () => 'test');
924
+ const state = createQuery(() => ({
925
+ queryKey: key,
926
+ queryFn: () => 'test',
927
+ }));
926
928
  createRenderEffect(() => {
927
929
  states.push({ ...state });
928
930
  });
@@ -942,80 +944,6 @@ describe('createQuery', () => {
942
944
  expect(states[0]).toMatchObject({ data: undefined });
943
945
  expect(states[1]).toMatchObject({ data: 'test' });
944
946
  });
945
- it.skip('should be able to remove a query', async () => {
946
- const key = queryKey();
947
- const states = [];
948
- let count = 0;
949
- function Page() {
950
- //@ts-expect-error -- we skip this test, and no such thing as rerender in solid
951
- const [, rerender] = NotReact.useState({});
952
- const state = createQuery(key, () => ++count, {
953
- notifyOnChangeProps: 'all',
954
- });
955
- createRenderEffect(() => {
956
- states.push({ ...state });
957
- });
958
- const { remove } = state;
959
- return (<div>
960
- <button onClick={() => remove()}>remove</button>
961
- <button onClick={() => rerender({})}>rerender</button>
962
- data: {state.data ?? 'null'}
963
- </div>);
964
- }
965
- render(() => (<QueryClientProvider client={queryClient}>
966
- <Page />
967
- </QueryClientProvider>));
968
- await waitFor(() => screen.getByText('data: 1'));
969
- fireEvent.click(screen.getByRole('button', { name: /remove/i }));
970
- await sleep(20);
971
- fireEvent.click(screen.getByRole('button', { name: /rerender/i }));
972
- await waitFor(() => screen.getByText('data: 2'));
973
- expect(states.length).toBe(4);
974
- // Initial
975
- expect(states[0]).toMatchObject({ status: 'loading', data: undefined });
976
- // Fetched
977
- expect(states[1]).toMatchObject({ status: 'success', data: 1 });
978
- // Remove + Hook state update, batched
979
- expect(states[2]).toMatchObject({ status: 'loading', data: undefined });
980
- // Fetched
981
- expect(states[3]).toMatchObject({ status: 'success', data: 2 });
982
- });
983
- it('should create a new query when refetching a removed query', async () => {
984
- const key = queryKey();
985
- const states = [];
986
- let count = 0;
987
- function Page() {
988
- const state = createQuery(key, async () => {
989
- await sleep(10);
990
- return ++count;
991
- }, { notifyOnChangeProps: 'all' });
992
- createRenderEffect(() => {
993
- states.push({ ...state });
994
- });
995
- return (<div>
996
- <button onClick={() => state.remove()}>remove</button>
997
- <button onClick={() => state.refetch()}>refetch</button>
998
- data: {state.data ?? 'null'}
999
- </div>);
1000
- }
1001
- render(() => (<QueryClientProvider client={queryClient}>
1002
- <Page />
1003
- </QueryClientProvider>));
1004
- await waitFor(() => screen.getByText('data: 1'));
1005
- fireEvent.click(screen.getByRole('button', { name: /remove/i }));
1006
- await sleep(50);
1007
- fireEvent.click(screen.getByRole('button', { name: /refetch/i }));
1008
- await waitFor(() => screen.getByText('data: 2'));
1009
- expect(states.length).toBe(4);
1010
- // Initial
1011
- expect(states[0]).toMatchObject({ data: undefined, dataUpdatedAt: 0 });
1012
- // Fetched
1013
- expect(states[1]).toMatchObject({ data: 1 });
1014
- // Switch
1015
- expect(states[2]).toMatchObject({ data: undefined, dataUpdatedAt: 0 });
1016
- // Fetched
1017
- expect(states[3]).toMatchObject({ data: 2 });
1018
- });
1019
947
  it('should share equal data structures between query results', async () => {
1020
948
  const key = queryKey();
1021
949
  const result1 = [
@@ -1029,11 +957,15 @@ describe('createQuery', () => {
1029
957
  const states = [];
1030
958
  let count = 0;
1031
959
  function Page() {
1032
- const state = createQuery(key, async () => {
1033
- await sleep(10);
1034
- count++;
1035
- return count === 1 ? result1 : result2;
1036
- }, { notifyOnChangeProps: 'all' });
960
+ const state = createQuery(() => ({
961
+ queryKey: key,
962
+ queryFn: async () => {
963
+ await sleep(10);
964
+ count++;
965
+ return count === 1 ? result1 : result2;
966
+ },
967
+ notifyOnChangeProps: 'all',
968
+ }));
1037
969
  createRenderEffect(() => {
1038
970
  states.push({ ...state });
1039
971
  });
@@ -1067,21 +999,23 @@ describe('createQuery', () => {
1067
999
  it('should use query function from hook when the existing query does not have a query function', async () => {
1068
1000
  const key = queryKey();
1069
1001
  const results = [];
1070
- queryClient.setQueryData(key(), 'set');
1002
+ queryClient.setQueryData(key, 'set');
1071
1003
  function Page() {
1072
- const result = createQuery(key, async () => {
1073
- await sleep(10);
1074
- return 'fetched';
1075
- }, {
1004
+ const result = createQuery(() => ({
1005
+ queryKey: key,
1006
+ queryFn: async () => {
1007
+ await sleep(10);
1008
+ return 'fetched';
1009
+ },
1076
1010
  initialData: 'initial',
1077
1011
  staleTime: Infinity,
1078
- });
1012
+ }));
1079
1013
  createRenderEffect(() => {
1080
1014
  results.push({ ...result });
1081
1015
  });
1082
1016
  return (<div>
1083
1017
  <div>isFetching: {result.isFetching}</div>
1084
- <button onClick={() => queryClient.refetchQueries(key())}>
1018
+ <button onClick={() => queryClient.refetchQueries({ queryKey: key })}>
1085
1019
  refetch
1086
1020
  </button>
1087
1021
  data: {result.data}
@@ -1103,16 +1037,20 @@ describe('createQuery', () => {
1103
1037
  const states = [];
1104
1038
  let count = 0;
1105
1039
  function Page() {
1106
- const state = createQuery(key, async () => {
1107
- await sleep(10);
1108
- count++;
1109
- return count;
1110
- }, { staleTime: Infinity, notifyOnChangeProps: 'all' });
1040
+ const state = createQuery(() => ({
1041
+ queryKey: key,
1042
+ queryFn: async () => {
1043
+ await sleep(10);
1044
+ count++;
1045
+ return count;
1046
+ },
1047
+ staleTime: Infinity,
1048
+ }));
1111
1049
  createEffect(() => {
1112
1050
  states.push({ ...state });
1113
1051
  });
1114
1052
  return (<div>
1115
- <button onClick={() => queryClient.invalidateQueries(key())}>
1053
+ <button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
1116
1054
  invalidate
1117
1055
  </button>
1118
1056
  data: {state.data}
@@ -1159,17 +1097,21 @@ describe('createQuery', () => {
1159
1097
  const states = [];
1160
1098
  let count = 0;
1161
1099
  function Page() {
1162
- const state = createQuery(key, async () => {
1163
- await sleep(10);
1164
- count++;
1165
- return count;
1166
- }, { enabled: false });
1100
+ const state = createQuery(() => ({
1101
+ queryKey: key,
1102
+ queryFn: async () => {
1103
+ await sleep(10);
1104
+ count++;
1105
+ return count;
1106
+ },
1107
+ enabled: false,
1108
+ }));
1167
1109
  createRenderEffect(() => {
1168
1110
  states.push({ ...state });
1169
1111
  });
1170
1112
  createEffect(() => {
1171
1113
  setActTimeout(() => {
1172
- queryClient.refetchQueries({ queryKey: key() });
1114
+ queryClient.refetchQueries({ queryKey: key });
1173
1115
  }, 20);
1174
1116
  });
1175
1117
  return null;
@@ -1191,17 +1133,21 @@ describe('createQuery', () => {
1191
1133
  const states = [];
1192
1134
  let count = 0;
1193
1135
  function Page() {
1194
- const state = createQuery(key, async () => {
1195
- await sleep(10);
1196
- count++;
1197
- return count;
1198
- }, { enabled: false });
1136
+ const state = createQuery(() => ({
1137
+ queryKey: key,
1138
+ queryFn: async () => {
1139
+ await sleep(10);
1140
+ count++;
1141
+ return count;
1142
+ },
1143
+ enabled: false,
1144
+ }));
1199
1145
  createRenderEffect(() => {
1200
1146
  states.push({ ...state });
1201
1147
  });
1202
1148
  createEffect(() => {
1203
1149
  setActTimeout(() => {
1204
- queryClient.invalidateQueries(key());
1150
+ queryClient.invalidateQueries({ queryKey: key });
1205
1151
  }, 20);
1206
1152
  });
1207
1153
  return null;
@@ -1223,14 +1169,14 @@ describe('createQuery', () => {
1223
1169
  const states = [];
1224
1170
  function Page() {
1225
1171
  const [count, setCount] = createSignal(0);
1226
- const state = createQuery(() => [key(), count()], async () => {
1227
- await sleep(5);
1228
- return count();
1229
- }, {
1230
- get enabled() {
1231
- return count() === 0;
1172
+ const state = createQuery(() => ({
1173
+ queryKey: [key, count()],
1174
+ queryFn: async () => {
1175
+ await sleep(5);
1176
+ return count();
1232
1177
  },
1233
- });
1178
+ enabled: count() === 0,
1179
+ }));
1234
1180
  createRenderEffect(() => {
1235
1181
  states.push({ ...state });
1236
1182
  });
@@ -1248,7 +1194,6 @@ describe('createQuery', () => {
1248
1194
  expect(states.length).toBe(3);
1249
1195
  // Fetch query
1250
1196
  expect(states[0]).toMatchObject({
1251
- data: undefined,
1252
1197
  isFetching: true,
1253
1198
  isSuccess: false,
1254
1199
  });
@@ -1260,20 +1205,23 @@ describe('createQuery', () => {
1260
1205
  });
1261
1206
  // Switch to disabled query
1262
1207
  expect(states[2]).toMatchObject({
1263
- data: undefined,
1264
1208
  isFetching: false,
1265
1209
  isSuccess: false,
1266
1210
  });
1267
1211
  });
1268
- it('should keep the previous data when keepPreviousData is set', async () => {
1212
+ it('should keep the previous data when placeholderData is set', async () => {
1269
1213
  const key = queryKey();
1270
1214
  const states = [];
1271
1215
  function Page() {
1272
1216
  const [count, setCount] = createSignal(0);
1273
- const state = createQuery(() => [key(), count()], async () => {
1274
- await sleep(10);
1275
- return count();
1276
- }, { keepPreviousData: true });
1217
+ const state = createQuery(() => ({
1218
+ queryKey: [key, count()],
1219
+ queryFn: async () => {
1220
+ await sleep(10);
1221
+ return count();
1222
+ },
1223
+ placeholderData: keepPreviousData,
1224
+ }));
1277
1225
  createRenderEffect(() => {
1278
1226
  states.push({ ...state });
1279
1227
  });
@@ -1293,139 +1241,44 @@ describe('createQuery', () => {
1293
1241
  data: undefined,
1294
1242
  isFetching: true,
1295
1243
  isSuccess: false,
1296
- isPreviousData: false,
1244
+ isPlaceholderData: false,
1297
1245
  });
1298
1246
  // Fetched
1299
1247
  expect(states[1]).toMatchObject({
1300
1248
  data: 0,
1301
1249
  isFetching: false,
1302
1250
  isSuccess: true,
1303
- isPreviousData: false,
1251
+ isPlaceholderData: false,
1304
1252
  });
1305
1253
  // Set state
1306
1254
  expect(states[2]).toMatchObject({
1307
1255
  data: 0,
1308
1256
  isFetching: true,
1309
1257
  isSuccess: true,
1310
- isPreviousData: true,
1258
+ isPlaceholderData: true,
1311
1259
  });
1312
1260
  // New data
1313
1261
  expect(states[3]).toMatchObject({
1314
1262
  data: 1,
1315
1263
  isFetching: false,
1316
1264
  isSuccess: true,
1317
- isPreviousData: false,
1318
- });
1319
- });
1320
- // this test relies on rerenders which don't exist in solid
1321
- it.skip('should transition to error state when keepPreviousData is set', async () => {
1322
- const key = queryKey();
1323
- const states = [];
1324
- function Page(props) {
1325
- const state = createQuery(() => [key(), props.count], async () => {
1326
- await sleep(10);
1327
- if (props.count === 2) {
1328
- throw new Error('Error test');
1329
- }
1330
- return Promise.resolve(props.count);
1331
- }, {
1332
- retry: false,
1333
- keepPreviousData: true,
1334
- });
1335
- createRenderEffect(() => {
1336
- states.push({ ...state });
1337
- });
1338
- return (<div>
1339
- <h1>data: {state.data}</h1>
1340
- <h2>error: {state.error?.message}</h2>
1341
- <p>previous data: {state.isPreviousData}</p>
1342
- </div>);
1343
- }
1344
- render(() => (<QueryClientProvider client={queryClient}>
1345
- <Page count={0}/>
1346
- </QueryClientProvider>));
1347
- await waitFor(() => screen.getByText('data: 0'));
1348
- // @ts-expect-error we skip this test and rerenders don't exist in solid
1349
- act(() => screen.rerender(<Page count={1}/>));
1350
- await waitFor(() => screen.getByText('data: 1'));
1351
- // @ts-expect-error we skip this test and rerenders don't exist in solid
1352
- act(() => screen.rerender(<Page count={2}/>));
1353
- await waitFor(() => screen.getByText('error: Error test'));
1354
- await waitFor(() => expect(states.length).toBe(8));
1355
- // Initial
1356
- expect(states[0]).toMatchObject({
1357
- data: undefined,
1358
- isFetching: true,
1359
- status: 'loading',
1360
- error: null,
1361
- isPreviousData: false,
1362
- });
1363
- // Fetched
1364
- expect(states[1]).toMatchObject({
1365
- data: 0,
1366
- isFetching: false,
1367
- status: 'success',
1368
- error: null,
1369
- isPreviousData: false,
1370
- });
1371
- // rerender Page 1
1372
- expect(states[2]).toMatchObject({
1373
- data: 0,
1374
- isFetching: true,
1375
- status: 'success',
1376
- error: null,
1377
- isPreviousData: true,
1378
- });
1379
- // Hook state update
1380
- expect(states[3]).toMatchObject({
1381
- data: 0,
1382
- isFetching: true,
1383
- status: 'success',
1384
- error: null,
1385
- isPreviousData: true,
1386
- });
1387
- // New data
1388
- expect(states[4]).toMatchObject({
1389
- data: 1,
1390
- isFetching: false,
1391
- status: 'success',
1392
- error: null,
1393
- isPreviousData: false,
1394
- });
1395
- // rerender Page 2
1396
- expect(states[5]).toMatchObject({
1397
- data: 1,
1398
- isFetching: true,
1399
- status: 'success',
1400
- error: null,
1401
- isPreviousData: true,
1402
- });
1403
- // Hook state update again
1404
- expect(states[6]).toMatchObject({
1405
- data: 1,
1406
- isFetching: true,
1407
- status: 'success',
1408
- error: null,
1409
- isPreviousData: true,
1410
- });
1411
- // Error
1412
- expect(states[7]).toMatchObject({
1413
- data: undefined,
1414
- isFetching: false,
1415
- status: 'error',
1416
- isPreviousData: false,
1265
+ isPlaceholderData: false,
1417
1266
  });
1418
- expect(states[7]?.error).toHaveProperty('message', 'Error test');
1419
1267
  });
1420
- it('should not show initial data from next query if keepPreviousData is set', async () => {
1268
+ it('should not show initial data from next query if placeholderData is set', async () => {
1421
1269
  const key = queryKey();
1422
1270
  const states = [];
1423
1271
  function Page() {
1424
1272
  const [count, setCount] = createSignal(0);
1425
- const state = createQuery(() => [key(), count()], async () => {
1426
- await sleep(10);
1427
- return count();
1428
- }, { initialData: 99, keepPreviousData: true });
1273
+ const state = createQuery(() => ({
1274
+ queryKey: [key, count()],
1275
+ queryFn: async () => {
1276
+ await sleep(10);
1277
+ return count();
1278
+ },
1279
+ initialData: 99,
1280
+ placeholderData: keepPreviousData,
1281
+ }));
1429
1282
  createRenderEffect(() => {
1430
1283
  states.push({ ...state });
1431
1284
  });
@@ -1449,39 +1302,45 @@ describe('createQuery', () => {
1449
1302
  data: 99,
1450
1303
  isFetching: true,
1451
1304
  isSuccess: true,
1452
- isPreviousData: false,
1305
+ isPlaceholderData: false,
1453
1306
  });
1454
1307
  // Fetched
1455
1308
  expect(states[1]).toMatchObject({
1456
1309
  data: 0,
1457
1310
  isFetching: false,
1458
1311
  isSuccess: true,
1459
- isPreviousData: false,
1312
+ isPlaceholderData: false,
1460
1313
  });
1461
1314
  // Set state
1462
1315
  expect(states[2]).toMatchObject({
1463
1316
  data: 99,
1464
1317
  isFetching: true,
1465
1318
  isSuccess: true,
1466
- isPreviousData: false,
1319
+ isPlaceholderData: false,
1467
1320
  });
1468
1321
  // New data
1469
1322
  expect(states[3]).toMatchObject({
1470
1323
  data: 1,
1471
1324
  isFetching: false,
1472
1325
  isSuccess: true,
1473
- isPreviousData: false,
1326
+ isPlaceholderData: false,
1474
1327
  });
1475
1328
  });
1476
- it('should keep the previous data on disabled query when keepPreviousData is set', async () => {
1329
+ it('should keep the previous data on disabled query when placeholderData is set to identity function', async () => {
1477
1330
  const key = queryKey();
1478
1331
  const states = [];
1479
1332
  function Page() {
1480
1333
  const [count, setCount] = createSignal(0);
1481
- const state = createQuery(() => [key(), count()], async () => {
1482
- await sleep(10);
1483
- return count();
1484
- }, { enabled: false, keepPreviousData: true, notifyOnChangeProps: 'all' });
1334
+ const state = createQuery(() => ({
1335
+ queryKey: [key, count()],
1336
+ queryFn: async () => {
1337
+ await sleep(10);
1338
+ return count();
1339
+ },
1340
+ enabled: false,
1341
+ placeholderData: keepPreviousData,
1342
+ notifyOnChangeProps: 'all',
1343
+ }));
1485
1344
  createRenderEffect(() => {
1486
1345
  states.push({ ...state });
1487
1346
  });
@@ -1507,55 +1366,61 @@ describe('createQuery', () => {
1507
1366
  data: undefined,
1508
1367
  isFetching: false,
1509
1368
  isSuccess: false,
1510
- isPreviousData: false,
1369
+ isPlaceholderData: false,
1511
1370
  });
1512
1371
  // Fetching query
1513
1372
  expect(states[1]).toMatchObject({
1514
1373
  data: undefined,
1515
1374
  isFetching: true,
1516
1375
  isSuccess: false,
1517
- isPreviousData: false,
1376
+ isPlaceholderData: false,
1518
1377
  });
1519
1378
  // Fetched query
1520
1379
  expect(states[2]).toMatchObject({
1521
1380
  data: 0,
1522
1381
  isFetching: false,
1523
1382
  isSuccess: true,
1524
- isPreviousData: false,
1383
+ isPlaceholderData: false,
1525
1384
  });
1526
1385
  // Set state
1527
1386
  expect(states[3]).toMatchObject({
1528
1387
  data: 0,
1529
1388
  isFetching: false,
1530
1389
  isSuccess: true,
1531
- isPreviousData: true,
1390
+ isPlaceholderData: true,
1532
1391
  });
1533
1392
  // Fetching new query
1534
1393
  expect(states[4]).toMatchObject({
1535
1394
  data: 0,
1536
1395
  isFetching: true,
1537
1396
  isSuccess: true,
1538
- isPreviousData: true,
1397
+ isPlaceholderData: true,
1539
1398
  });
1540
1399
  // Fetched new query
1541
1400
  expect(states[5]).toMatchObject({
1542
1401
  data: 1,
1543
1402
  isFetching: false,
1544
1403
  isSuccess: true,
1545
- isPreviousData: false,
1404
+ isPlaceholderData: false,
1546
1405
  });
1547
1406
  });
1548
- it('should keep the previous data on disabled query when keepPreviousData is set and switching query key multiple times', async () => {
1407
+ it('should keep the previous data on disabled query when placeholderData is set and switching query key multiple times', async () => {
1549
1408
  const key = queryKey();
1550
1409
  const states = [];
1551
- queryClient.setQueryData([key(), 10], 10);
1410
+ queryClient.setQueryData([key, 10], 10);
1552
1411
  await sleep(10);
1553
1412
  function Page() {
1554
1413
  const [count, setCount] = createSignal(10);
1555
- const state = createQuery(() => [key(), count()], async () => {
1556
- await sleep(10);
1557
- return count();
1558
- }, { enabled: false, keepPreviousData: true, notifyOnChangeProps: 'all' });
1414
+ const state = createQuery(() => ({
1415
+ queryKey: [key, count()],
1416
+ queryFn: async () => {
1417
+ await sleep(10);
1418
+ return count();
1419
+ },
1420
+ enabled: false,
1421
+ placeholderData: keepPreviousData,
1422
+ notifyOnChangeProps: 'all',
1423
+ }));
1559
1424
  createRenderEffect(() => {
1560
1425
  states.push({ ...state });
1561
1426
  });
@@ -1583,38 +1448,41 @@ describe('createQuery', () => {
1583
1448
  data: 10,
1584
1449
  isFetching: false,
1585
1450
  isSuccess: true,
1586
- isPreviousData: false,
1451
+ isPlaceholderData: false,
1587
1452
  });
1588
1453
  // Set state
1589
1454
  expect(states[1]).toMatchObject({
1590
1455
  data: 10,
1591
1456
  isFetching: false,
1592
1457
  isSuccess: true,
1593
- isPreviousData: true,
1458
+ isPlaceholderData: true,
1594
1459
  });
1595
1460
  // Refetch
1596
1461
  expect(states[2]).toMatchObject({
1597
1462
  data: 10,
1598
1463
  isFetching: true,
1599
1464
  isSuccess: true,
1600
- isPreviousData: true,
1465
+ isPlaceholderData: true,
1601
1466
  });
1602
1467
  // Refetch done
1603
1468
  expect(states[3]).toMatchObject({
1604
1469
  data: 12,
1605
1470
  isFetching: false,
1606
1471
  isSuccess: true,
1607
- isPreviousData: false,
1472
+ isPlaceholderData: false,
1608
1473
  });
1609
1474
  });
1610
1475
  it('should use the correct query function when components use different configurations', async () => {
1611
1476
  const key = queryKey();
1612
1477
  const states = [];
1613
1478
  function FirstComponent() {
1614
- const state = createQuery(key, async () => {
1615
- await sleep(10);
1616
- return 1;
1617
- }, { notifyOnChangeProps: 'all' });
1479
+ const state = createQuery(() => ({
1480
+ queryKey: key,
1481
+ queryFn: async () => {
1482
+ await sleep(10);
1483
+ return 1;
1484
+ },
1485
+ }));
1618
1486
  createRenderEffect(() => {
1619
1487
  states.push({ ...state });
1620
1488
  });
@@ -1624,7 +1492,10 @@ describe('createQuery', () => {
1624
1492
  </div>);
1625
1493
  }
1626
1494
  function SecondComponent() {
1627
- createQuery(key, () => 2, { notifyOnChangeProps: 'all' });
1495
+ createQuery(() => ({
1496
+ queryKey: key,
1497
+ queryFn: () => 2,
1498
+ }));
1628
1499
  return null;
1629
1500
  }
1630
1501
  function Page() {
@@ -1657,30 +1528,37 @@ describe('createQuery', () => {
1657
1528
  const key = queryKey();
1658
1529
  const states1 = [];
1659
1530
  const states2 = [];
1660
- await queryClient.prefetchQuery(key(), async () => {
1661
- await sleep(10);
1662
- return 'prefetch';
1531
+ await queryClient.prefetchQuery({
1532
+ queryKey: key,
1533
+ queryFn: async () => {
1534
+ await sleep(10);
1535
+ return 'prefetch';
1536
+ },
1663
1537
  });
1664
1538
  await sleep(20);
1665
1539
  function FirstComponent() {
1666
- const state = createQuery(key, async () => {
1667
- await sleep(10);
1668
- return 'one';
1669
- }, {
1540
+ const state = createQuery(() => ({
1541
+ queryKey: key,
1542
+ queryFn: async () => {
1543
+ await sleep(10);
1544
+ return 'one';
1545
+ },
1670
1546
  staleTime: 100,
1671
- });
1547
+ }));
1672
1548
  createRenderEffect(() => {
1673
1549
  states1.push({ ...state });
1674
1550
  });
1675
1551
  return null;
1676
1552
  }
1677
1553
  function SecondComponent() {
1678
- const state = createQuery(key, async () => {
1679
- await sleep(10);
1680
- return 'two';
1681
- }, {
1554
+ const state = createQuery(() => ({
1555
+ queryKey: key,
1556
+ queryFn: async () => {
1557
+ await sleep(10);
1558
+ return 'two';
1559
+ },
1682
1560
  staleTime: 10,
1683
- });
1561
+ }));
1684
1562
  createRenderEffect(() => {
1685
1563
  states2.push({ ...state });
1686
1564
  });
@@ -1742,9 +1620,11 @@ describe('createQuery', () => {
1742
1620
  const key = queryKey();
1743
1621
  const states = [];
1744
1622
  function Page() {
1745
- const state = createQuery(key, () => 'test', {
1623
+ const state = createQuery(() => ({
1624
+ queryKey: key,
1625
+ queryFn: () => 'test',
1746
1626
  staleTime: 50,
1747
- });
1627
+ }));
1748
1628
  createRenderEffect(() => {
1749
1629
  states.push({ ...state });
1750
1630
  });
@@ -1763,12 +1643,14 @@ describe('createQuery', () => {
1763
1643
  const key = queryKey();
1764
1644
  const states = [];
1765
1645
  function Page() {
1766
- const state = createQuery(key, async () => {
1767
- await sleep(5);
1768
- return 'test';
1769
- }, {
1646
+ const state = createQuery(() => ({
1647
+ queryKey: key,
1648
+ queryFn: async () => {
1649
+ await sleep(5);
1650
+ return 'test';
1651
+ },
1770
1652
  notifyOnChangeProps: ['data'],
1771
- });
1653
+ }));
1772
1654
  createRenderEffect(() => {
1773
1655
  states.push({ ...state });
1774
1656
  });
@@ -1787,7 +1669,7 @@ describe('createQuery', () => {
1787
1669
  expect(states.length).toBe(2);
1788
1670
  expect(states[0]).toMatchObject({
1789
1671
  data: undefined,
1790
- status: 'loading',
1672
+ status: 'pending',
1791
1673
  isFetching: true,
1792
1674
  });
1793
1675
  expect(states[1]).toMatchObject({
@@ -1801,14 +1683,18 @@ describe('createQuery', () => {
1801
1683
  const key1 = queryKey();
1802
1684
  const key2 = queryKey();
1803
1685
  function Page() {
1804
- const first = createQuery(key1, () => 'data', {
1686
+ const first = createQuery(() => ({
1687
+ queryKey: key1,
1688
+ queryFn: () => 'data',
1805
1689
  enabled: false,
1806
1690
  initialData: 'init',
1807
- });
1808
- const second = createQuery(key2, () => 'data', {
1691
+ }));
1692
+ const second = createQuery(() => ({
1693
+ queryKey: key2,
1694
+ queryFn: () => 'data',
1809
1695
  enabled: false,
1810
1696
  initialData: 'init',
1811
- });
1697
+ }));
1812
1698
  return (<div>
1813
1699
  <h2>First Data: {first.data}</h2>
1814
1700
  <h2>Second Data: {second.data}</h2>
@@ -1835,14 +1721,14 @@ describe('createQuery', () => {
1835
1721
  return 'data2';
1836
1722
  };
1837
1723
  function Page() {
1838
- createQuery(key, queryFn1);
1839
- createQuery(key, queryFn2);
1724
+ createQuery(() => ({ queryKey: key, queryFn: queryFn1 }));
1725
+ createQuery(() => ({ queryKey: key, queryFn: queryFn2 }));
1840
1726
  return null;
1841
1727
  }
1842
1728
  render(() => (<QueryClientProvider client={queryClient}>
1843
1729
  <Page />
1844
1730
  </QueryClientProvider>));
1845
- expect(queryCache.find(key()).options.queryFn).toBe(queryFn1);
1731
+ expect(queryCache.find({ queryKey: key }).options.queryFn).toBe(queryFn1);
1846
1732
  });
1847
1733
  it('should batch re-renders', async () => {
1848
1734
  const key = queryKey();
@@ -1852,8 +1738,8 @@ describe('createQuery', () => {
1852
1738
  return 'data';
1853
1739
  };
1854
1740
  function Page() {
1855
- createQuery(key, queryFn);
1856
- createQuery(key, queryFn);
1741
+ createQuery(() => ({ queryKey: key, queryFn }));
1742
+ createQuery(() => ({ queryKey: key, queryFn }));
1857
1743
  renders++;
1858
1744
  return null;
1859
1745
  }
@@ -1875,16 +1761,20 @@ describe('createQuery', () => {
1875
1761
  };
1876
1762
  function Page() {
1877
1763
  const [count, setCount] = createSignal(0);
1878
- createQuery(key, queryFn, {
1764
+ createQuery(() => ({
1765
+ queryKey: key,
1766
+ queryFn,
1879
1767
  onSuccess: () => {
1880
1768
  setCount((x) => x + 1);
1881
1769
  },
1882
- });
1883
- createQuery(key, queryFn, {
1770
+ }));
1771
+ createQuery(() => ({
1772
+ queryKey: key,
1773
+ queryFn,
1884
1774
  onSuccess: () => {
1885
1775
  setCount((x) => x + 1);
1886
1776
  },
1887
- });
1777
+ }));
1888
1778
  createEffect(() => {
1889
1779
  renders++;
1890
1780
  callbackCount = count();
@@ -1904,10 +1794,13 @@ describe('createQuery', () => {
1904
1794
  const key = queryKey();
1905
1795
  function Page() {
1906
1796
  const [, setNewState] = createSignal('state');
1907
- const state = createQuery(key, () => 'data');
1797
+ const state = createQuery(() => ({
1798
+ queryKey: key,
1799
+ queryFn: () => 'data',
1800
+ }));
1908
1801
  createEffect(() => {
1909
1802
  setActTimeout(() => {
1910
- queryClient.setQueryData(key(), 'new');
1803
+ queryClient.setQueryData(key, 'new');
1911
1804
  // Update with same state to make react discard the next render
1912
1805
  setNewState('state');
1913
1806
  }, 10);
@@ -1920,14 +1813,19 @@ describe('createQuery', () => {
1920
1813
  await waitFor(() => screen.getByText('new'));
1921
1814
  });
1922
1815
  // See https://github.com/tannerlinsley/react-query/issues/170
1923
- it('should start with status loading, fetchStatus idle if enabled is false', async () => {
1816
+ it('should start with status pending, fetchStatus idle if enabled is false', async () => {
1924
1817
  const key1 = queryKey();
1925
1818
  const key2 = queryKey();
1926
1819
  function Page() {
1927
- const first = createQuery(key1, () => 'data', {
1820
+ const first = createQuery(() => ({
1821
+ queryKey: key1,
1822
+ queryFn: () => 'data',
1928
1823
  enabled: false,
1929
- });
1930
- const second = createQuery(key2, () => 'data');
1824
+ }));
1825
+ const second = createQuery(() => ({
1826
+ queryKey: key2,
1827
+ queryFn: () => 'data',
1828
+ }));
1931
1829
  return (<div>
1932
1830
  <div>
1933
1831
  First Status: {first.status}, {first.fetchStatus}
@@ -1941,36 +1839,41 @@ describe('createQuery', () => {
1941
1839
  <Page />
1942
1840
  </QueryClientProvider>));
1943
1841
  // use "act" to wait for state update and prevent console warning
1944
- screen.getByText('First Status: loading, idle');
1945
- await waitFor(() => screen.getByText('Second Status: loading, fetching'));
1842
+ screen.getByText('First Status: pending, idle');
1843
+ await waitFor(() => screen.getByText('Second Status: pending, fetching'));
1946
1844
  await waitFor(() => screen.getByText('Second Status: success, idle'));
1947
1845
  });
1948
1846
  // See https://github.com/tannerlinsley/react-query/issues/144
1949
- it('should be in "loading" state by default', async () => {
1847
+ it('should be in "pending" state by default', async () => {
1950
1848
  const key = queryKey();
1951
1849
  function Page() {
1952
- const { status } = createQuery(key, async () => {
1953
- await sleep(10);
1954
- return 'test';
1955
- });
1850
+ const { status } = createQuery(() => ({
1851
+ queryKey: key,
1852
+ queryFn: async () => {
1853
+ await sleep(10);
1854
+ return 'test';
1855
+ },
1856
+ }));
1956
1857
  return <div>status: {status}</div>;
1957
1858
  }
1958
1859
  render(() => (<QueryClientProvider client={queryClient}>
1959
1860
  <Page />
1960
1861
  </QueryClientProvider>));
1961
- screen.getByText('status: loading');
1862
+ screen.getByText('status: pending');
1962
1863
  });
1963
1864
  // See https://github.com/tannerlinsley/react-query/issues/147
1964
1865
  it('should not pass stringified variables to query function', async () => {
1965
1866
  const key = queryKey();
1966
1867
  const variables = { number: 5, boolean: false, object: {}, array: [] };
1967
1868
  const states = [];
1968
- // TODO(lukemurray): extract the query function to a variable queryFn
1969
1869
  function Page() {
1970
- const state = createQuery(() => [key(), variables], async (ctx) => {
1971
- await sleep(10);
1972
- return ctx.queryKey;
1973
- });
1870
+ const state = createQuery(() => ({
1871
+ queryKey: [key, variables],
1872
+ queryFn: async (ctx) => {
1873
+ await sleep(10);
1874
+ return ctx.queryKey;
1875
+ },
1876
+ }));
1974
1877
  createRenderEffect(() => {
1975
1878
  states.push({ ...state });
1976
1879
  });
@@ -1980,15 +1883,17 @@ describe('createQuery', () => {
1980
1883
  <Page />
1981
1884
  </QueryClientProvider>));
1982
1885
  await sleep(20);
1983
- expect(states[1]?.data).toEqual([key(), variables]);
1886
+ expect(states[1]?.data).toEqual([key, variables]);
1984
1887
  });
1985
1888
  it('should not refetch query on focus when `enabled` is set to `false`', async () => {
1986
1889
  const key = queryKey();
1987
1890
  const queryFn = jest.fn().mockReturnValue('data');
1988
1891
  function Page() {
1989
- const { data = 'default' } = createQuery(key, queryFn, {
1892
+ const { data = 'default' } = createQuery(() => ({
1893
+ queryKey: key,
1894
+ queryFn,
1990
1895
  enabled: false,
1991
- });
1896
+ }));
1992
1897
  return (<div>
1993
1898
  <h1>{data}</h1>
1994
1899
  </div>);
@@ -1997,7 +1902,7 @@ describe('createQuery', () => {
1997
1902
  <Page />
1998
1903
  </QueryClientProvider>));
1999
1904
  await waitFor(() => screen.getByText('default'));
2000
- window.dispatchEvent(new FocusEvent('focus'));
1905
+ window.dispatchEvent(new Event('visibilitychange'));
2001
1906
  expect(queryFn).not.toHaveBeenCalled();
2002
1907
  });
2003
1908
  it('should not refetch stale query on focus when `refetchOnWindowFocus` is set to `false`', async () => {
@@ -2005,10 +1910,12 @@ describe('createQuery', () => {
2005
1910
  const states = [];
2006
1911
  let count = 0;
2007
1912
  function Page() {
2008
- const state = createQuery(key, () => count++, {
1913
+ const state = createQuery(() => ({
1914
+ queryKey: key,
1915
+ queryFn: () => count++,
2009
1916
  staleTime: 0,
2010
1917
  refetchOnWindowFocus: false,
2011
- });
1918
+ }));
2012
1919
  createRenderEffect(() => {
2013
1920
  states.push({ ...state });
2014
1921
  });
@@ -2018,7 +1925,7 @@ describe('createQuery', () => {
2018
1925
  <Page />
2019
1926
  </QueryClientProvider>));
2020
1927
  await sleep(10);
2021
- window.dispatchEvent(new FocusEvent('focus'));
1928
+ window.dispatchEvent(new Event('visibilitychange'));
2022
1929
  await sleep(10);
2023
1930
  expect(states.length).toBe(2);
2024
1931
  expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
@@ -2029,10 +1936,12 @@ describe('createQuery', () => {
2029
1936
  const states = [];
2030
1937
  let count = 0;
2031
1938
  function Page() {
2032
- const state = createQuery(key, () => count++, {
1939
+ const state = createQuery(() => ({
1940
+ queryKey: key,
1941
+ queryFn: () => count++,
2033
1942
  staleTime: 0,
2034
1943
  refetchOnWindowFocus: () => false,
2035
- });
1944
+ }));
2036
1945
  createRenderEffect(() => {
2037
1946
  states.push({ ...state });
2038
1947
  });
@@ -2042,7 +1951,7 @@ describe('createQuery', () => {
2042
1951
  <Page />
2043
1952
  </QueryClientProvider>));
2044
1953
  await sleep(10);
2045
- window.dispatchEvent(new FocusEvent('focus'));
1954
+ window.dispatchEvent(new Event('visibilitychange'));
2046
1955
  await sleep(10);
2047
1956
  expect(states.length).toBe(2);
2048
1957
  expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
@@ -2053,10 +1962,12 @@ describe('createQuery', () => {
2053
1962
  const states = [];
2054
1963
  let count = 0;
2055
1964
  function Page() {
2056
- const state = createQuery(key, () => count++, {
1965
+ const state = createQuery(() => ({
1966
+ queryKey: key,
1967
+ queryFn: () => count++,
2057
1968
  staleTime: Infinity,
2058
1969
  refetchOnWindowFocus: true,
2059
- });
1970
+ }));
2060
1971
  createRenderEffect(() => {
2061
1972
  states.push({ ...state });
2062
1973
  });
@@ -2066,7 +1977,7 @@ describe('createQuery', () => {
2066
1977
  <Page />
2067
1978
  </QueryClientProvider>));
2068
1979
  await sleep(10);
2069
- window.dispatchEvent(new FocusEvent('focus'));
1980
+ window.dispatchEvent(new Event('visibilitychange'));
2070
1981
  await sleep(10);
2071
1982
  expect(states.length).toBe(2);
2072
1983
  expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
@@ -2077,13 +1988,15 @@ describe('createQuery', () => {
2077
1988
  const states = [];
2078
1989
  let count = 0;
2079
1990
  function Page() {
2080
- const state = createQuery(key, async () => {
2081
- await sleep(10);
2082
- return count++;
2083
- }, {
1991
+ const state = createQuery(() => ({
1992
+ queryKey: key,
1993
+ queryFn: async () => {
1994
+ await sleep(10);
1995
+ return count++;
1996
+ },
2084
1997
  staleTime: Infinity,
2085
1998
  refetchOnWindowFocus: 'always',
2086
- });
1999
+ }));
2087
2000
  createRenderEffect(() => {
2088
2001
  states.push({ ...state });
2089
2002
  });
@@ -2093,7 +2006,7 @@ describe('createQuery', () => {
2093
2006
  <Page />
2094
2007
  </QueryClientProvider>));
2095
2008
  await sleep(20);
2096
- window.dispatchEvent(new FocusEvent('focus'));
2009
+ window.dispatchEvent(new Event('visibilitychange'));
2097
2010
  await sleep(20);
2098
2011
  await waitFor(() => expect(states.length).toBe(4));
2099
2012
  expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
@@ -2106,14 +2019,16 @@ describe('createQuery', () => {
2106
2019
  const states = [];
2107
2020
  let count = 0;
2108
2021
  function Page() {
2109
- const state = createQuery(key, async () => {
2110
- await sleep(10);
2111
- return count++;
2112
- }, {
2022
+ const state = createQuery(() => ({
2023
+ queryKey: key,
2024
+ queryFn: async () => {
2025
+ await sleep(10);
2026
+ return count++;
2027
+ },
2113
2028
  staleTime: 0,
2114
2029
  retry: 0,
2115
2030
  refetchOnWindowFocus: (query) => (query.state.data || 0) < 1,
2116
- });
2031
+ }));
2117
2032
  createRenderEffect(() => {
2118
2033
  states.push({ ...state });
2119
2034
  });
@@ -2126,7 +2041,7 @@ describe('createQuery', () => {
2126
2041
  expect(states.length).toBe(2);
2127
2042
  expect(states[0]).toMatchObject({ data: undefined, isFetching: true });
2128
2043
  expect(states[1]).toMatchObject({ data: 0, isFetching: false });
2129
- window.dispatchEvent(new FocusEvent('focus'));
2044
+ window.dispatchEvent(new Event('visibilitychange'));
2130
2045
  await screen.findByText('data: 1');
2131
2046
  // refetch should happen
2132
2047
  expect(states.length).toBe(4);
@@ -2139,12 +2054,17 @@ describe('createQuery', () => {
2139
2054
  it('should refetch fresh query when refetchOnMount is set to always', async () => {
2140
2055
  const key = queryKey();
2141
2056
  const states = [];
2142
- await queryClient.prefetchQuery(key(), () => 'prefetched');
2057
+ await queryClient.prefetchQuery({
2058
+ queryKey: key,
2059
+ queryFn: () => 'prefetched',
2060
+ });
2143
2061
  function Page() {
2144
- const state = createQuery(key, () => 'data', {
2062
+ const state = createQuery(() => ({
2063
+ queryKey: key,
2064
+ queryFn: () => 'data',
2145
2065
  refetchOnMount: 'always',
2146
2066
  staleTime: Infinity,
2147
- });
2067
+ }));
2148
2068
  createRenderEffect(() => {
2149
2069
  states.push({ ...state });
2150
2070
  });
@@ -2169,13 +2089,18 @@ describe('createQuery', () => {
2169
2089
  it('should refetch stale query when refetchOnMount is set to true', async () => {
2170
2090
  const key = queryKey();
2171
2091
  const states = [];
2172
- await queryClient.prefetchQuery(key(), () => 'prefetched');
2092
+ await queryClient.prefetchQuery({
2093
+ queryKey: key,
2094
+ queryFn: () => 'prefetched',
2095
+ });
2173
2096
  await sleep(10);
2174
2097
  function Page() {
2175
- const state = createQuery(key, () => 'data', {
2098
+ const state = createQuery(() => ({
2099
+ queryKey: key,
2100
+ queryFn: () => 'data',
2176
2101
  refetchOnMount: true,
2177
2102
  staleTime: 0,
2178
- });
2103
+ }));
2179
2104
  createRenderEffect(() => {
2180
2105
  states.push({ ...state });
2181
2106
  });
@@ -2200,12 +2125,16 @@ describe('createQuery', () => {
2200
2125
  it('should set status to error if queryFn throws', async () => {
2201
2126
  const key = queryKey();
2202
2127
  function Page() {
2203
- const state = createQuery(key, () => {
2204
- return Promise.reject('Error test jaylen');
2205
- }, { retry: false });
2128
+ const state = createQuery(() => ({
2129
+ queryKey: key,
2130
+ queryFn: () => {
2131
+ return Promise.reject(new Error('Error test jaylen'));
2132
+ },
2133
+ retry: false,
2134
+ }));
2206
2135
  return (<div>
2207
2136
  <h1>{state.status}</h1>
2208
- <h2>{state.error}</h2>
2137
+ <h2>{state.error?.message}</h2>
2209
2138
  </div>);
2210
2139
  }
2211
2140
  render(() => (<QueryClientProvider client={queryClient}>
@@ -2214,13 +2143,18 @@ describe('createQuery', () => {
2214
2143
  await waitFor(() => screen.getByText('error'));
2215
2144
  await waitFor(() => screen.getByText('Error test jaylen'));
2216
2145
  });
2217
- it('should throw error if queryFn throws and useErrorBoundary is in use', async () => {
2146
+ it('should throw error if queryFn throws and throwErrors is in use', async () => {
2218
2147
  const key = queryKey();
2219
2148
  function Page() {
2220
- const state = createQuery(key, () => Promise.reject('Error test jaylen'), { retry: false, useErrorBoundary: true });
2149
+ const state = createQuery(() => ({
2150
+ queryKey: key,
2151
+ queryFn: () => Promise.reject(new Error('Error test jaylen')),
2152
+ retry: false,
2153
+ throwErrors: true,
2154
+ }));
2221
2155
  return (<div>
2222
2156
  <h1>{state.status}</h1>
2223
- <h2>{state.error}</h2>
2157
+ <h2>{state.error?.message}</h2>
2224
2158
  </div>);
2225
2159
  }
2226
2160
  render(() => (<QueryClientProvider client={queryClient}>
@@ -2230,13 +2164,15 @@ describe('createQuery', () => {
2230
2164
  </QueryClientProvider>));
2231
2165
  await waitFor(() => screen.getByText('error boundary'));
2232
2166
  });
2233
- it('should update with data if we observe no properties and useErrorBoundary', async () => {
2167
+ it('should update with data if we observe no properties and throwErrors', async () => {
2234
2168
  const key = queryKey();
2235
2169
  let result;
2236
2170
  function Page() {
2237
- const query = createQuery(key, () => Promise.resolve('data'), {
2238
- useErrorBoundary: true,
2239
- });
2171
+ const query = createQuery(() => ({
2172
+ queryKey: key,
2173
+ queryFn: () => Promise.resolve('data'),
2174
+ throwErrors: true,
2175
+ }));
2240
2176
  createEffect(() => {
2241
2177
  result = query;
2242
2178
  });
@@ -2251,13 +2187,15 @@ describe('createQuery', () => {
2251
2187
  it('should set status to error instead of throwing when error should not be thrown', async () => {
2252
2188
  const key = queryKey();
2253
2189
  function Page() {
2254
- const state = createQuery(key, () => Promise.reject('Local Error'), {
2190
+ const state = createQuery(() => ({
2191
+ queryKey: key,
2192
+ queryFn: () => Promise.reject(new Error('Local Error')),
2255
2193
  retry: false,
2256
- useErrorBoundary: (err) => err !== 'Local Error',
2257
- });
2194
+ throwErrors: (err) => err.message !== 'Local Error',
2195
+ }));
2258
2196
  return (<div>
2259
2197
  <h1>{state.status}</h1>
2260
- <h2>{state.error}</h2>
2198
+ <h2>{state.error?.message}</h2>
2261
2199
  </div>);
2262
2200
  }
2263
2201
  render(() => (<QueryClientProvider client={queryClient}>
@@ -2271,10 +2209,12 @@ describe('createQuery', () => {
2271
2209
  it('should throw error instead of setting status when error should be thrown', async () => {
2272
2210
  const key = queryKey();
2273
2211
  function Page() {
2274
- const state = createQuery(key, () => Promise.reject(new Error('Remote Error')), {
2212
+ const state = createQuery(() => ({
2213
+ queryKey: key,
2214
+ queryFn: () => Promise.reject(new Error('Remote Error')),
2275
2215
  retry: false,
2276
- useErrorBoundary: (err) => err.message !== 'Local Error',
2277
- });
2216
+ throwErrors: (err) => err.message !== 'Local Error',
2217
+ }));
2278
2218
  return (<div>
2279
2219
  <h1>{state.status}</h1>
2280
2220
  <h2>{state.error?.message ?? ''}</h2>
@@ -2296,18 +2236,20 @@ describe('createQuery', () => {
2296
2236
  const key = queryKey();
2297
2237
  let count = 0;
2298
2238
  function Page() {
2299
- const result = createQuery(key, async () => {
2300
- count++;
2301
- await sleep(10);
2302
- return Promise.reject('some error');
2303
- }, {
2239
+ const result = createQuery(() => ({
2240
+ queryKey: key,
2241
+ queryFn: async () => {
2242
+ count++;
2243
+ await sleep(10);
2244
+ return Promise.reject(new Error('some error'));
2245
+ },
2304
2246
  retry: 2,
2305
2247
  retryDelay: 100,
2306
- });
2248
+ }));
2307
2249
  return (<div>
2308
- <div>error: {result.error ?? 'null'}</div>
2250
+ <div>error: {result.error?.message ?? 'null'}</div>
2309
2251
  <div>failureCount: {result.failureCount}</div>
2310
- <div>failureReason: {result.failureReason}</div>
2252
+ <div>failureReason: {result.failureReason?.message}</div>
2311
2253
  </div>);
2312
2254
  }
2313
2255
  function App() {
@@ -2333,18 +2275,20 @@ describe('createQuery', () => {
2333
2275
  const key = queryKey();
2334
2276
  let count = 0;
2335
2277
  function Page() {
2336
- const result = createQuery(key, async () => {
2337
- count++;
2338
- await sleep(10);
2339
- return Promise.reject('some error');
2340
- }, {
2278
+ const result = createQuery(() => ({
2279
+ queryKey: key,
2280
+ queryFn: async () => {
2281
+ count++;
2282
+ await sleep(10);
2283
+ return Promise.reject(new Error('some error'));
2284
+ },
2341
2285
  retry: 2,
2342
2286
  retryDelay: 100,
2343
- });
2287
+ }));
2344
2288
  return (<div>
2345
- <div>error: {result.error ?? 'null'}</div>
2289
+ <div>error: {result.error?.message ?? 'null'}</div>
2346
2290
  <div>failureCount: {result.failureCount}</div>
2347
- <div>failureReason: {result.failureReason}</div>
2291
+ <div>failureReason: {result.failureReason?.message}</div>
2348
2292
  </div>);
2349
2293
  }
2350
2294
  function App() {
@@ -2352,7 +2296,7 @@ describe('createQuery', () => {
2352
2296
  const toggle = () => setShow((s) => !s);
2353
2297
  return (<div>
2354
2298
  <button onClick={toggle}>{show() ? 'hide' : 'show'}</button>
2355
- <button onClick={() => queryClient.cancelQueries({ queryKey: key() })}>
2299
+ <button onClick={() => queryClient.cancelQueries({ queryKey: key })}>
2356
2300
  cancel
2357
2301
  </button>
2358
2302
  {show() && <Page />}
@@ -2374,12 +2318,17 @@ describe('createQuery', () => {
2374
2318
  it('should always fetch if refetchOnMount is set to always', async () => {
2375
2319
  const key = queryKey();
2376
2320
  const states = [];
2377
- await queryClient.prefetchQuery(key(), () => 'prefetched');
2321
+ await queryClient.prefetchQuery({
2322
+ queryKey: key,
2323
+ queryFn: () => 'prefetched',
2324
+ });
2378
2325
  function Page() {
2379
- const state = createQuery(key, () => 'data', {
2326
+ const state = createQuery(() => ({
2327
+ queryKey: key,
2328
+ queryFn: () => 'data',
2380
2329
  refetchOnMount: 'always',
2381
2330
  staleTime: 50,
2382
- });
2331
+ }));
2383
2332
  createRenderEffect(() => {
2384
2333
  states.push({ ...state });
2385
2334
  });
@@ -2414,9 +2363,11 @@ describe('createQuery', () => {
2414
2363
  const key = queryKey();
2415
2364
  const states = [];
2416
2365
  function Page() {
2417
- const state = createQuery(key, () => 'data', {
2366
+ const state = createQuery(() => ({
2367
+ queryKey: key,
2368
+ queryFn: () => 'data',
2418
2369
  initialData: 'initial',
2419
- });
2370
+ }));
2420
2371
  createRenderEffect(() => {
2421
2372
  states.push({ ...state });
2422
2373
  });
@@ -2442,10 +2393,12 @@ describe('createQuery', () => {
2442
2393
  const key = queryKey();
2443
2394
  const states = [];
2444
2395
  function Page() {
2445
- const state = createQuery(key, () => 'data', {
2396
+ const state = createQuery(() => ({
2397
+ queryKey: key,
2398
+ queryFn: () => 'data',
2446
2399
  staleTime: 50,
2447
2400
  initialData: 'initial',
2448
- });
2401
+ }));
2449
2402
  createRenderEffect(() => {
2450
2403
  states.push({ ...state });
2451
2404
  });
@@ -2472,11 +2425,13 @@ describe('createQuery', () => {
2472
2425
  const states = [];
2473
2426
  const oneSecondAgo = Date.now() - 1000;
2474
2427
  function Page() {
2475
- const state = createQuery(key, () => 'data', {
2428
+ const state = createQuery(() => ({
2429
+ queryKey: key,
2430
+ queryFn: () => 'data',
2476
2431
  staleTime: 50,
2477
2432
  initialData: 'initial',
2478
2433
  initialDataUpdatedAt: oneSecondAgo,
2479
- });
2434
+ }));
2480
2435
  createRenderEffect(() => {
2481
2436
  states.push({ ...state });
2482
2437
  });
@@ -2507,11 +2462,13 @@ describe('createQuery', () => {
2507
2462
  const key = queryKey();
2508
2463
  const states = [];
2509
2464
  function Page() {
2510
- const state = createQuery(key, () => 'data', {
2465
+ const state = createQuery(() => ({
2466
+ queryKey: key,
2467
+ queryFn: () => 'data',
2511
2468
  staleTime: 10 * 1000,
2512
2469
  initialData: 'initial',
2513
2470
  initialDataUpdatedAt: 0,
2514
- });
2471
+ }));
2515
2472
  createRenderEffect(() => {
2516
2473
  states.push({ ...state });
2517
2474
  });
@@ -2538,10 +2495,12 @@ describe('createQuery', () => {
2538
2495
  const states = [];
2539
2496
  function Page() {
2540
2497
  const [count, setCount] = createSignal(0);
2541
- const state = createQuery(() => [key(), count()], () => ({ count: 10 }), {
2498
+ const state = createQuery(() => ({
2499
+ queryKey: [key, count()],
2500
+ queryFn: () => ({ count: 10 }),
2542
2501
  staleTime: Infinity,
2543
2502
  initialData: () => ({ count: count() }),
2544
- });
2503
+ }));
2545
2504
  createRenderEffect(() => {
2546
2505
  states.push({ ...state });
2547
2506
  });
@@ -2566,23 +2525,25 @@ describe('createQuery', () => {
2566
2525
  const key = queryKey();
2567
2526
  const queryFn = jest.fn();
2568
2527
  queryFn.mockImplementation(() => {
2569
- return Promise.reject('Error test Barrett');
2528
+ return Promise.reject(new Error('Error test Barrett'));
2570
2529
  });
2571
2530
  function Page() {
2572
- const state = createQuery(key, queryFn, {
2531
+ const state = createQuery(() => ({
2532
+ queryKey: key,
2533
+ queryFn,
2573
2534
  retry: 1,
2574
2535
  retryDelay: 1,
2575
- });
2536
+ }));
2576
2537
  return (<div>
2577
2538
  <h1>{state.status}</h1>
2578
2539
  <h2>Failed {state.failureCount} times</h2>
2579
- <h2>Failed because {state.failureReason}</h2>
2540
+ <h2>Failed because {state.failureReason?.message}</h2>
2580
2541
  </div>);
2581
2542
  }
2582
2543
  render(() => (<QueryClientProvider client={queryClient}>
2583
2544
  <Page />
2584
2545
  </QueryClientProvider>));
2585
- await waitFor(() => screen.getByText('loading'));
2546
+ await waitFor(() => screen.getByText('pending'));
2586
2547
  await waitFor(() => screen.getByText('error'));
2587
2548
  // query should fail `retry + 1` times, since first time isn't a "retry"
2588
2549
  await waitFor(() => screen.getByText('Failed 2 times'));
@@ -2593,27 +2554,29 @@ describe('createQuery', () => {
2593
2554
  const key = queryKey();
2594
2555
  const queryFn = jest.fn();
2595
2556
  queryFn.mockImplementationOnce(() => {
2596
- return Promise.reject('Error test Tanner');
2557
+ return Promise.reject(new Error('Error test Tanner'));
2597
2558
  });
2598
2559
  queryFn.mockImplementation(() => {
2599
- return Promise.reject('NoRetry');
2560
+ return Promise.reject(new Error('NoRetry'));
2600
2561
  });
2601
2562
  function Page() {
2602
- const state = createQuery(key, queryFn, {
2563
+ const state = createQuery(() => ({
2564
+ queryKey: key,
2565
+ queryFn,
2603
2566
  retryDelay: 1,
2604
- retry: (_failureCount, err) => err !== 'NoRetry',
2605
- });
2567
+ retry: (_failureCount, err) => err.message !== 'NoRetry',
2568
+ }));
2606
2569
  return (<div>
2607
2570
  <h1>{state.status}</h1>
2608
2571
  <h2>Failed {state.failureCount} times</h2>
2609
- <h2>Failed because {state.failureReason}</h2>
2610
- <h2>{state.error}</h2>
2572
+ <h2>Failed because {state.failureReason?.message}</h2>
2573
+ <h2>{state.error?.message}</h2>
2611
2574
  </div>);
2612
2575
  }
2613
2576
  render(() => (<QueryClientProvider client={queryClient}>
2614
2577
  <Page />
2615
2578
  </QueryClientProvider>));
2616
- await waitFor(() => screen.getByText('loading'));
2579
+ await waitFor(() => screen.getByText('pending'));
2617
2580
  await waitFor(() => screen.getByText('error'));
2618
2581
  await waitFor(() => screen.getByText('Failed 2 times'));
2619
2582
  await waitFor(() => screen.getByText('Failed because NoRetry'));
@@ -2627,10 +2590,12 @@ describe('createQuery', () => {
2627
2590
  return Promise.reject({ delay: 50 });
2628
2591
  });
2629
2592
  function Page() {
2630
- const state = createQuery(key, queryFn, {
2593
+ const state = createQuery(() => ({
2594
+ queryKey: key,
2595
+ queryFn,
2631
2596
  retry: 1,
2632
2597
  retryDelay: (_, error) => error.delay,
2633
- });
2598
+ }));
2634
2599
  return (<div>
2635
2600
  <h1>{state.status}</h1>
2636
2601
  <h2>Failed {state.failureCount} times</h2>
@@ -2653,13 +2618,15 @@ describe('createQuery', () => {
2653
2618
  const visibilityMock = mockVisibilityState('hidden');
2654
2619
  let count = 0;
2655
2620
  function Page() {
2656
- const query = createQuery(key, () => {
2657
- count++;
2658
- return Promise.reject(`fetching error ${count}`);
2659
- }, {
2621
+ const query = createQuery(() => ({
2622
+ queryKey: key,
2623
+ queryFn: () => {
2624
+ count++;
2625
+ return Promise.reject(`fetching error ${count}`);
2626
+ },
2660
2627
  retry: 3,
2661
2628
  retryDelay: 1,
2662
- });
2629
+ }));
2663
2630
  return (<div>
2664
2631
  <div>error {String(query.error)}</div>
2665
2632
  <div>status {query.status}</div>
@@ -2673,14 +2640,14 @@ describe('createQuery', () => {
2673
2640
  // The query should display the first error result
2674
2641
  await waitFor(() => screen.getByText('failureCount 1'));
2675
2642
  await waitFor(() => screen.getByText('failureReason fetching error 1'));
2676
- await waitFor(() => screen.getByText('status loading'));
2643
+ await waitFor(() => screen.getByText('status pending'));
2677
2644
  await waitFor(() => screen.getByText('error null'));
2678
2645
  // Check if the query really paused
2679
2646
  await sleep(10);
2680
2647
  await waitFor(() => screen.getByText('failureCount 1'));
2681
2648
  await waitFor(() => screen.getByText('failureReason fetching error 1'));
2682
2649
  visibilityMock.mockRestore();
2683
- window.dispatchEvent(new FocusEvent('focus'));
2650
+ window.dispatchEvent(new Event('visibilitychange'));
2684
2651
  // Wait for the final result
2685
2652
  await waitFor(() => screen.getByText('failureCount 4'));
2686
2653
  await waitFor(() => screen.getByText('failureReason fetching error 4'));
@@ -2690,15 +2657,16 @@ describe('createQuery', () => {
2690
2657
  await sleep(10);
2691
2658
  await waitFor(() => screen.getByText('failureCount 4'));
2692
2659
  await waitFor(() => screen.getByText('failureReason fetching error 4'));
2693
- // Check if the error has been logged in the console
2694
- expect(mockLogger.error).toHaveBeenCalledWith('fetching error 4');
2695
2660
  });
2696
2661
  it('should fetch on mount when a query was already created with setQueryData', async () => {
2697
2662
  const key = queryKey();
2698
2663
  const states = [];
2699
- queryClient.setQueryData(key(), 'prefetched');
2664
+ queryClient.setQueryData(key, 'prefetched');
2700
2665
  function Page() {
2701
- const state = createQuery(key, () => 'data');
2666
+ const state = createQuery(() => ({
2667
+ queryKey: key,
2668
+ queryFn: () => 'data',
2669
+ }));
2702
2670
  createRenderEffect(() => {
2703
2671
  states.push({ ...state });
2704
2672
  });
@@ -2728,12 +2696,15 @@ describe('createQuery', () => {
2728
2696
  // make page unfocused
2729
2697
  const visibilityMock = mockVisibilityState('hidden');
2730
2698
  // set data in cache to check if the hook query fn is actually called
2731
- queryClient.setQueryData(key(), 'prefetched');
2699
+ queryClient.setQueryData(key, 'prefetched');
2732
2700
  function Page() {
2733
- const state = createQuery(key, async () => {
2734
- await sleep(10);
2735
- return 'data';
2736
- });
2701
+ const state = createQuery(() => ({
2702
+ queryKey: key,
2703
+ queryFn: async () => {
2704
+ await sleep(10);
2705
+ return 'data';
2706
+ },
2707
+ }));
2737
2708
  createRenderEffect(() => {
2738
2709
  states.push({ ...state });
2739
2710
  });
@@ -2747,7 +2718,7 @@ describe('createQuery', () => {
2747
2718
  await waitFor(() => expect(states.length).toBe(2));
2748
2719
  // reset visibilityState to original value
2749
2720
  visibilityMock.mockRestore();
2750
- window.dispatchEvent(new FocusEvent('focus'));
2721
+ window.dispatchEvent(new Event('visibilitychange'));
2751
2722
  await waitFor(() => expect(states.length).toBe(4));
2752
2723
  expect(states).toMatchObject([
2753
2724
  {
@@ -2780,12 +2751,14 @@ describe('createQuery', () => {
2780
2751
  queryFn.mockImplementation(() => 'data');
2781
2752
  const prefetchQueryFn = jest.fn();
2782
2753
  prefetchQueryFn.mockImplementation(() => 'not yet...');
2783
- await queryClient.prefetchQuery(key(), prefetchQueryFn, {
2754
+ await queryClient.prefetchQuery({
2755
+ queryKey: key,
2756
+ queryFn: prefetchQueryFn,
2784
2757
  staleTime: 10,
2785
2758
  });
2786
2759
  await sleep(11);
2787
2760
  function Page() {
2788
- const state = createQuery(key, queryFn);
2761
+ const state = createQuery(() => ({ queryKey: key, queryFn }));
2789
2762
  createRenderEffect(() => {
2790
2763
  states.push({ ...state });
2791
2764
  });
@@ -2807,14 +2780,14 @@ describe('createQuery', () => {
2807
2780
  await sleep(10);
2808
2781
  return 'not yet...';
2809
2782
  });
2810
- await queryClient.prefetchQuery(key(), prefetchQueryFn, {
2783
+ await queryClient.prefetchQuery({
2784
+ queryKey: key,
2785
+ queryFn: prefetchQueryFn,
2811
2786
  staleTime: 1000,
2812
2787
  });
2813
2788
  await sleep(0);
2814
2789
  function Page() {
2815
- createQuery(key, queryFn, {
2816
- staleTime: 1000,
2817
- });
2790
+ createQuery(() => ({ queryKey: key, queryFn, staleTime: 1000 }));
2818
2791
  return null;
2819
2792
  }
2820
2793
  render(() => (<QueryClientProvider client={queryClient}>
@@ -2829,15 +2802,19 @@ describe('createQuery', () => {
2829
2802
  const key = queryKey();
2830
2803
  function Page() {
2831
2804
  let counter = 0;
2832
- const query = createQuery(key, async () => {
2833
- if (counter < 2) {
2834
- counter++;
2835
- throw new Error('error');
2836
- }
2837
- else {
2838
- return 'data';
2839
- }
2840
- }, { retryDelay: 10 });
2805
+ const query = createQuery(() => ({
2806
+ queryKey: key,
2807
+ queryFn: async () => {
2808
+ if (counter < 2) {
2809
+ counter++;
2810
+ throw new Error('error');
2811
+ }
2812
+ else {
2813
+ return 'data';
2814
+ }
2815
+ },
2816
+ retryDelay: 10,
2817
+ }));
2841
2818
  return (<div>
2842
2819
  <div>failureCount {query.failureCount}</div>
2843
2820
  <div>failureReason {query.failureReason?.message ?? 'null'}</div>
@@ -2858,18 +2835,21 @@ describe('createQuery', () => {
2858
2835
  function Page() {
2859
2836
  const [enabled, setEnabled] = createSignal(false);
2860
2837
  const [isPrefetched, setPrefetched] = createSignal(false);
2861
- const query = createQuery(key, async () => {
2862
- count++;
2863
- await sleep(10);
2864
- return count;
2865
- }, {
2866
- get enabled() {
2867
- return enabled();
2838
+ const query = createQuery(() => ({
2839
+ queryKey: key,
2840
+ queryFn: async () => {
2841
+ count++;
2842
+ await sleep(10);
2843
+ return count;
2868
2844
  },
2869
- });
2845
+ enabled: enabled(),
2846
+ }));
2870
2847
  createEffect(() => {
2871
2848
  async function prefetch() {
2872
- await queryClient.prefetchQuery(key(), () => Promise.resolve('prefetched data'));
2849
+ await queryClient.prefetchQuery({
2850
+ queryKey: key,
2851
+ queryFn: () => Promise.resolve('prefetched data'),
2852
+ });
2873
2853
  setPrefetched(true);
2874
2854
  }
2875
2855
  prefetch();
@@ -2893,11 +2873,11 @@ describe('createQuery', () => {
2893
2873
  const key = queryKey();
2894
2874
  function Page() {
2895
2875
  const [shouldFetch, setShouldFetch] = createSignal(false);
2896
- const query = createQuery(key, () => 'data', {
2897
- get enabled() {
2898
- return shouldFetch();
2899
- },
2900
- });
2876
+ const query = createQuery(() => ({
2877
+ queryKey: key,
2878
+ queryFn: () => 'data',
2879
+ enabled: shouldFetch(),
2880
+ }));
2901
2881
  return (<div>
2902
2882
  <div>FetchStatus: {query.fetchStatus}</div>
2903
2883
  <h2>Data: {query.data || 'no data'}</h2>
@@ -2920,27 +2900,37 @@ describe('createQuery', () => {
2920
2900
  const key = queryKey();
2921
2901
  const results = [];
2922
2902
  function Page() {
2923
- const result = createQuery(key, () => 'serverData', {
2924
- initialData: 'data',
2925
- });
2903
+ const result = createQuery(() => ({
2904
+ queryKey: key,
2905
+ queryFn: async () => {
2906
+ await sleep(10);
2907
+ return 'serverData';
2908
+ },
2909
+ initialData: 'initialData',
2910
+ }));
2926
2911
  createRenderEffect(() => {
2927
2912
  results.push({ ...result });
2928
2913
  });
2929
- return null;
2914
+ return <div>data: {result.data}</div>;
2930
2915
  }
2931
2916
  render(() => (<QueryClientProvider client={queryClient}>
2932
2917
  <Page />
2933
2918
  </QueryClientProvider>));
2934
- await sleep(10);
2919
+ await waitFor(() => screen.getByText('data: initialData'));
2920
+ await waitFor(() => screen.getByText('data: serverData'));
2935
2921
  expect(results.length).toBe(2);
2936
- expect(results[0]).toMatchObject({ data: 'data', isFetching: true });
2922
+ expect(results[0]).toMatchObject({ data: 'initialData', isFetching: true });
2937
2923
  expect(results[1]).toMatchObject({ data: 'serverData', isFetching: false });
2938
2924
  });
2939
2925
  it('should initialize state properly, when initialData is falsy', async () => {
2940
2926
  const key = queryKey();
2941
2927
  const results = [];
2942
2928
  function Page() {
2943
- const result = createQuery(key, () => 1, { initialData: 0 });
2929
+ const result = createQuery(() => ({
2930
+ queryKey: key,
2931
+ queryFn: () => 1,
2932
+ initialData: 0,
2933
+ }));
2944
2934
  createRenderEffect(() => {
2945
2935
  results.push({ ...result });
2946
2936
  });
@@ -2960,14 +2950,12 @@ describe('createQuery', () => {
2960
2950
  const results = [];
2961
2951
  function Page() {
2962
2952
  const [shouldFetch, setShouldFetch] = createSignal(true);
2963
- const result = createQuery(key, () => 'fetched data', {
2964
- get enabled() {
2965
- return shouldFetch();
2966
- },
2967
- get initialData() {
2968
- return shouldFetch() ? 'initial' : 'initial falsy';
2969
- },
2970
- });
2953
+ const result = createQuery(() => ({
2954
+ queryKey: key,
2955
+ queryFn: () => 'fetched data',
2956
+ enabled: shouldFetch(),
2957
+ initialData: shouldFetch() ? 'initial' : 'initial falsy',
2958
+ }));
2971
2959
  createRenderEffect(() => {
2972
2960
  results.push({ ...result });
2973
2961
  });
@@ -2992,27 +2980,29 @@ describe('createQuery', () => {
2992
2980
  const queryFn = jest.fn();
2993
2981
  queryFn.mockImplementation(() => 'data');
2994
2982
  function Page() {
2995
- const { fetchStatus } = createQuery({
2983
+ const { fetchStatus } = createQuery(() => ({
2996
2984
  queryKey: key,
2997
2985
  queryFn,
2998
2986
  enabled: false,
2999
- });
2987
+ }));
3000
2988
  return <div>fetchStatus: {fetchStatus}</div>;
3001
2989
  }
3002
2990
  render(() => (<QueryClientProvider client={queryClient}>
3003
2991
  <Page />
3004
2992
  </QueryClientProvider>));
3005
2993
  expect(queryFn).not.toHaveBeenCalled();
3006
- expect(queryCache.find(key())).not.toBeUndefined();
2994
+ expect(queryCache.find({ queryKey: key })).not.toBeUndefined();
3007
2995
  screen.getByText('fetchStatus: idle');
3008
2996
  });
3009
2997
  // See https://github.com/tannerlinsley/react-query/issues/360
3010
- it('should init to status:loading, fetchStatus:idle when enabled is false', async () => {
2998
+ it('should init to status:pending, fetchStatus:idle when enabled is false', async () => {
3011
2999
  const key = queryKey();
3012
3000
  function Page() {
3013
- const query = createQuery(key, () => 'data', {
3001
+ const query = createQuery(() => ({
3002
+ queryKey: key,
3003
+ queryFn: () => 'data',
3014
3004
  enabled: false,
3015
- });
3005
+ }));
3016
3006
  return (<div>
3017
3007
  <div>
3018
3008
  status: {query.status}, {query.fetchStatus}
@@ -3022,38 +3012,60 @@ describe('createQuery', () => {
3022
3012
  render(() => (<QueryClientProvider client={queryClient}>
3023
3013
  <Page />
3024
3014
  </QueryClientProvider>));
3025
- await waitFor(() => screen.getByText('status: loading, idle'));
3015
+ await waitFor(() => screen.getByText('status: pending, idle'));
3026
3016
  });
3027
- it('should not schedule garbage collection, if cacheTimeout is set to `Infinity`', async () => {
3017
+ it('should not schedule garbage collection, if gcTimeout is set to `Infinity`', async () => {
3028
3018
  const key = queryKey();
3029
3019
  function Page() {
3030
- const query = createQuery(key, () => 'fetched data', {
3031
- cacheTime: Infinity,
3032
- });
3020
+ const query = createQuery(() => ({
3021
+ queryKey: key,
3022
+ queryFn: () => 'fetched data',
3023
+ gcTime: Infinity,
3024
+ }));
3025
+ return <div>{query.data}</div>;
3026
+ }
3027
+ const result = render(() => (<QueryClientProvider client={queryClient}>
3028
+ <Page />
3029
+ </QueryClientProvider>));
3030
+ await waitFor(() => screen.getByText('fetched data'));
3031
+ const setTimeoutSpy = jest.spyOn(window, 'setTimeout');
3032
+ result.unmount();
3033
+ expect(setTimeoutSpy).not.toHaveBeenCalled();
3034
+ });
3035
+ it('should schedule garbage collection, if gcTimeout is not set to `Infinity`', async () => {
3036
+ const key = queryKey();
3037
+ function Page() {
3038
+ const query = createQuery(() => ({
3039
+ queryKey: key,
3040
+ queryFn: () => 'fetched data',
3041
+ gcTime: 1000 * 60 * 10, //10 Minutes
3042
+ }));
3033
3043
  return <div>{query.data}</div>;
3034
3044
  }
3035
3045
  const result = render(() => (<QueryClientProvider client={queryClient}>
3036
3046
  <Page />
3037
3047
  </QueryClientProvider>));
3038
3048
  await waitFor(() => screen.getByText('fetched data'));
3049
+ const setTimeoutSpy = jest.spyOn(window, 'setTimeout');
3039
3050
  result.unmount();
3040
- const query = queryCache.find(key());
3041
- // @ts-expect-error
3042
- expect(query.cacheTimeout).toBe(undefined);
3051
+ expect(setTimeoutSpy).toHaveBeenLastCalledWith(expect.any(Function), 1000 * 60 * 10);
3043
3052
  });
3044
3053
  it('should not cause memo churn when data does not change', async () => {
3045
3054
  const key = queryKey();
3046
3055
  const queryFn = jest.fn().mockReturnValue('data');
3047
3056
  const memoFn = jest.fn();
3048
3057
  function Page() {
3049
- const result = createQuery(key, async () => {
3050
- await sleep(10);
3051
- return (queryFn() || {
3052
- data: {
3053
- nested: true,
3054
- },
3055
- });
3056
- });
3058
+ const result = createQuery(() => ({
3059
+ queryKey: key,
3060
+ queryFn: async () => {
3061
+ await sleep(10);
3062
+ return (queryFn() || {
3063
+ data: {
3064
+ nested: true,
3065
+ },
3066
+ });
3067
+ },
3068
+ }));
3057
3069
  createMemo(() => {
3058
3070
  memoFn();
3059
3071
  return result.data;
@@ -3067,7 +3079,7 @@ describe('createQuery', () => {
3067
3079
  render(() => (<QueryClientProvider client={queryClient}>
3068
3080
  <Page />
3069
3081
  </QueryClientProvider>));
3070
- await waitFor(() => screen.getByText('status loading'));
3082
+ await waitFor(() => screen.getByText('status pending'));
3071
3083
  await waitFor(() => screen.getByText('status success'));
3072
3084
  fireEvent.click(screen.getByText('refetch'));
3073
3085
  await waitFor(() => screen.getByText('isFetching true'));
@@ -3080,11 +3092,11 @@ describe('createQuery', () => {
3080
3092
  let count = 0;
3081
3093
  function Page() {
3082
3094
  const [int, setInt] = createSignal(200);
3083
- const state = createQuery(key, () => count++, {
3084
- get refetchInterval() {
3085
- return int();
3086
- },
3087
- });
3095
+ const state = createQuery(() => ({
3096
+ queryKey: key,
3097
+ queryFn: () => count++,
3098
+ refetchInterval: int(),
3099
+ }));
3088
3100
  createEffect(() => {
3089
3101
  if (state.data === 2) {
3090
3102
  setInt(0);
@@ -3105,12 +3117,14 @@ describe('createQuery', () => {
3105
3117
  let count = 0;
3106
3118
  const states = [];
3107
3119
  function Page() {
3108
- const state = createQuery(key, async () => {
3109
- await sleep(10);
3110
- return count++;
3111
- }, {
3120
+ const state = createQuery(() => ({
3121
+ queryKey: key,
3122
+ queryFn: async () => {
3123
+ await sleep(10);
3124
+ return count++;
3125
+ },
3112
3126
  refetchInterval: (data = 0) => (data < 2 ? 10 : false),
3113
- });
3127
+ }));
3114
3128
  createRenderEffect(() => {
3115
3129
  states.push({ ...state });
3116
3130
  });
@@ -3128,7 +3142,7 @@ describe('createQuery', () => {
3128
3142
  expect(states.length).toEqual(6);
3129
3143
  expect(states).toMatchObject([
3130
3144
  {
3131
- status: 'loading',
3145
+ status: 'pending',
3132
3146
  isFetching: true,
3133
3147
  data: undefined,
3134
3148
  },
@@ -3163,9 +3177,11 @@ describe('createQuery', () => {
3163
3177
  const key = queryKey();
3164
3178
  const states = [];
3165
3179
  function Page() {
3166
- const state = createQuery(key, () => 1, {
3180
+ const state = createQuery(() => ({
3181
+ queryKey: key,
3182
+ queryFn: () => 1,
3167
3183
  refetchInterval: 0,
3168
- });
3184
+ }));
3169
3185
  createRenderEffect(() => {
3170
3186
  states.push({ ...state });
3171
3187
  });
@@ -3179,7 +3195,7 @@ describe('createQuery', () => {
3179
3195
  expect(states.length).toEqual(2);
3180
3196
  expect(states).toMatchObject([
3181
3197
  {
3182
- status: 'loading',
3198
+ status: 'pending',
3183
3199
  isFetching: true,
3184
3200
  data: undefined,
3185
3201
  },
@@ -3192,7 +3208,10 @@ describe('createQuery', () => {
3192
3208
  });
3193
3209
  it('should accept an empty string as query key', async () => {
3194
3210
  function Page() {
3195
- const result = createQuery(() => [''], (ctx) => ctx.queryKey);
3211
+ const result = createQuery(() => ({
3212
+ queryKey: [''],
3213
+ queryFn: (ctx) => ctx.queryKey,
3214
+ }));
3196
3215
  return <>{JSON.stringify(result.data)}</>;
3197
3216
  }
3198
3217
  render(() => (<QueryClientProvider client={queryClient}>
@@ -3202,7 +3221,10 @@ describe('createQuery', () => {
3202
3221
  });
3203
3222
  it('should accept an object as query key', async () => {
3204
3223
  function Page() {
3205
- const result = createQuery(() => [{ a: 'a' }], (ctx) => ctx.queryKey);
3224
+ const result = createQuery(() => ({
3225
+ queryKey: [{ a: 'a' }],
3226
+ queryFn: (ctx) => ctx.queryKey,
3227
+ }));
3206
3228
  return <>{JSON.stringify(result.data)}</>;
3207
3229
  }
3208
3230
  render(() => (<QueryClientProvider client={queryClient}>
@@ -3214,16 +3236,16 @@ describe('createQuery', () => {
3214
3236
  const key = queryKey();
3215
3237
  const queryFn = jest.fn().mockReturnValue('data');
3216
3238
  function Disabled() {
3217
- createQuery(key, queryFn, { enabled: false });
3239
+ createQuery(() => ({ queryKey: key, queryFn, enabled: false }));
3218
3240
  return null;
3219
3241
  }
3220
3242
  function Page() {
3221
3243
  const [enabled, setEnabled] = createSignal(false);
3222
- const result = createQuery(key, queryFn, {
3223
- get enabled() {
3224
- return enabled();
3225
- },
3226
- });
3244
+ const result = createQuery(() => ({
3245
+ queryKey: key,
3246
+ queryFn,
3247
+ enabled: enabled(),
3248
+ }));
3227
3249
  return (<>
3228
3250
  <Disabled />
3229
3251
  <div>{result.data}</div>
@@ -3242,9 +3264,11 @@ describe('createQuery', () => {
3242
3264
  const key1 = queryKey();
3243
3265
  const states = [];
3244
3266
  function Page() {
3245
- const state = createQuery(key1, () => 'data', {
3267
+ const state = createQuery(() => ({
3268
+ queryKey: key1,
3269
+ queryFn: () => 'data',
3246
3270
  placeholderData: 'placeholder',
3247
- });
3271
+ }));
3248
3272
  createRenderEffect(() => {
3249
3273
  states.push({ ...state });
3250
3274
  });
@@ -3275,12 +3299,12 @@ describe('createQuery', () => {
3275
3299
  const states = [];
3276
3300
  function Page() {
3277
3301
  const [count, setCount] = createSignal(0);
3278
- const state = createQuery(key1, () => 'data', {
3302
+ const state = createQuery(() => ({
3303
+ queryKey: key1,
3304
+ queryFn: () => 'data',
3279
3305
  placeholderData: 'placeholder',
3280
- get enabled() {
3281
- return count() === 0;
3282
- },
3283
- });
3306
+ enabled: count() === 0,
3307
+ }));
3284
3308
  createRenderEffect(() => {
3285
3309
  states.push({ state: { ...state }, count: count() });
3286
3310
  });
@@ -3327,10 +3351,12 @@ describe('createQuery', () => {
3327
3351
  const key1 = queryKey();
3328
3352
  const states = [];
3329
3353
  function Page() {
3330
- const state = createQuery(key1, () => 1, {
3354
+ const state = createQuery(() => ({
3355
+ queryKey: key1,
3356
+ queryFn: () => 1,
3331
3357
  placeholderData: 23,
3332
3358
  select: (data) => String(data * 2),
3333
- });
3359
+ }));
3334
3360
  createRenderEffect(() => {
3335
3361
  states.push({ ...state });
3336
3362
  });
@@ -3361,13 +3387,15 @@ describe('createQuery', () => {
3361
3387
  const states = [];
3362
3388
  let placeholderFunctionRunCount = 0;
3363
3389
  function Page() {
3364
- const state = createQuery(key1, () => 1, {
3390
+ const state = createQuery(() => ({
3391
+ queryKey: key1,
3392
+ queryFn: () => 1,
3365
3393
  placeholderData: () => {
3366
3394
  placeholderFunctionRunCount++;
3367
3395
  return 23;
3368
3396
  },
3369
3397
  select: (data) => String(data * 2),
3370
- });
3398
+ }));
3371
3399
  createRenderEffect(() => {
3372
3400
  states.push({ ...state });
3373
3401
  });
@@ -3394,40 +3422,6 @@ describe('createQuery', () => {
3394
3422
  ]);
3395
3423
  expect(placeholderFunctionRunCount).toEqual(1);
3396
3424
  });
3397
- // React Specific implementation. Not really needed since solid functions are stable
3398
- it.skip('select should only run when dependencies change if memoized', async () => {
3399
- const key1 = queryKey();
3400
- let selectRun = 0;
3401
- function Page() {
3402
- //@ts-expect-error skip this test
3403
- const [count, inc] = NotReact.useReducer((prev) => prev + 1, 2);
3404
- const state = createQuery(key1, async () => {
3405
- await sleep(10);
3406
- return 0;
3407
- }, {
3408
- //@ts-expect-error skip this test
3409
- select: NotReact.useCallback((data) => {
3410
- selectRun++;
3411
- return `selected ${data + count}`;
3412
- }, [count]),
3413
- placeholderData: 99,
3414
- });
3415
- return (<div>
3416
- <h2>Data: {state.data}</h2>
3417
- <button onClick={inc}>inc: {count}</button>
3418
- </div>);
3419
- }
3420
- render(() => (<QueryClientProvider client={queryClient}>
3421
- <Page />
3422
- </QueryClientProvider>));
3423
- await waitFor(() => screen.getByText('Data: selected 101')); // 99 + 2
3424
- expect(selectRun).toBe(1);
3425
- await waitFor(() => screen.getByText('Data: selected 2')); // 0 + 2
3426
- expect(selectRun).toBe(2);
3427
- fireEvent.click(screen.getByRole('button', { name: /inc/i }));
3428
- await waitFor(() => screen.getByText('Data: selected 3')); // 0 + 3
3429
- expect(selectRun).toBe(3);
3430
- });
3431
3425
  it('select should always return the correct state', async () => {
3432
3426
  const key1 = queryKey();
3433
3427
  function Page() {
@@ -3439,16 +3433,18 @@ describe('createQuery', () => {
3439
3433
  const forceUpdate = () => {
3440
3434
  setForceValue((prev) => prev + 1);
3441
3435
  };
3442
- const state = createQuery(key1, async () => {
3443
- await sleep(10);
3444
- return 0;
3445
- }, {
3436
+ const state = createQuery(() => ({
3437
+ queryKey: key1,
3438
+ queryFn: async () => {
3439
+ await sleep(10);
3440
+ return 0;
3441
+ },
3446
3442
  get select() {
3447
3443
  const currentCount = count();
3448
3444
  return (data) => `selected ${data + currentCount}`;
3449
3445
  },
3450
3446
  placeholderData: 99,
3451
- });
3447
+ }));
3452
3448
  return (<div>
3453
3449
  <h2>Data: {state.data}</h2>
3454
3450
  <h2>forceValue: {forceValue()}</h2>
@@ -3473,12 +3469,14 @@ describe('createQuery', () => {
3473
3469
  const states = [];
3474
3470
  function Page() {
3475
3471
  const [forceValue, setForceValue] = createSignal(1);
3476
- const state = createQuery(key1, async () => {
3477
- await sleep(10);
3478
- return [1, 2];
3479
- }, {
3472
+ const state = createQuery(() => ({
3473
+ queryKey: key1,
3474
+ queryFn: async () => {
3475
+ await sleep(10);
3476
+ return [1, 2];
3477
+ },
3480
3478
  select: (res) => res.map((x) => x + 1),
3481
- });
3479
+ }));
3482
3480
  createEffect(() => {
3483
3481
  if (state.data) {
3484
3482
  states.push(state.data);
@@ -3516,7 +3514,7 @@ describe('createQuery', () => {
3516
3514
  return promise;
3517
3515
  };
3518
3516
  function Page() {
3519
- const state = createQuery(key, queryFn);
3517
+ const state = createQuery(() => ({ queryKey: key, queryFn }));
3520
3518
  return (<div>
3521
3519
  <h1>Status: {state.status}</h1>
3522
3520
  </div>);
@@ -3534,12 +3532,16 @@ describe('createQuery', () => {
3534
3532
  const states = [];
3535
3533
  const queryFn = async (ctx) => {
3536
3534
  const [, limit] = ctx.queryKey;
3535
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
3537
3536
  const value = limit % 2 && ctx.signal ? 'abort' : `data ${limit}`;
3538
3537
  await sleep(25);
3539
3538
  return value;
3540
3539
  };
3541
3540
  function Page(props) {
3542
- const state = createQuery(() => [key(), props.limit], queryFn);
3541
+ const state = createQuery(() => ({
3542
+ queryKey: [key, props.limit],
3543
+ queryFn,
3544
+ }));
3543
3545
  states[props.limit] = state;
3544
3546
  return (<div>
3545
3547
  <h1>Status: {state.status}</h1>
@@ -3557,24 +3559,24 @@ describe('createQuery', () => {
3557
3559
  await waitFor(() => screen.getByText('off'));
3558
3560
  await sleep(20);
3559
3561
  await waitFor(() => expect(states).toHaveLength(4));
3560
- expect(queryCache.find([key(), 0])?.state).toMatchObject({
3562
+ expect(queryCache.find({ queryKey: [key, 0] })?.state).toMatchObject({
3561
3563
  data: 'data 0',
3562
3564
  status: 'success',
3563
3565
  dataUpdateCount: 1,
3564
3566
  });
3565
- expect(queryCache.find([key(), 1])?.state).toMatchObject({
3567
+ expect(queryCache.find({ queryKey: [key, 1] })?.state).toMatchObject({
3566
3568
  data: undefined,
3567
- status: 'loading',
3569
+ status: 'pending',
3568
3570
  fetchStatus: 'idle',
3569
3571
  });
3570
- expect(queryCache.find([key(), 2])?.state).toMatchObject({
3572
+ expect(queryCache.find({ queryKey: [key, 2] })?.state).toMatchObject({
3571
3573
  data: 'data 2',
3572
3574
  status: 'success',
3573
3575
  dataUpdateCount: 1,
3574
3576
  });
3575
- expect(queryCache.find([key(), 3])?.state).toMatchObject({
3577
+ expect(queryCache.find({ queryKey: [key, 3] })?.state).toMatchObject({
3576
3578
  data: undefined,
3577
- status: 'loading',
3579
+ status: 'pending',
3578
3580
  fetchStatus: 'idle',
3579
3581
  });
3580
3582
  });
@@ -3588,7 +3590,7 @@ describe('createQuery', () => {
3588
3590
  function Page() {
3589
3591
  const [id, setId] = createSignal(1);
3590
3592
  const [hasChanged, setHasChanged] = createSignal(false);
3591
- const state = createQuery(() => [key(), id()], queryFn);
3593
+ const state = createQuery(() => ({ queryKey: [key, id()], queryFn }));
3592
3594
  createRenderEffect(() => {
3593
3595
  states.push({ ...state });
3594
3596
  });
@@ -3605,7 +3607,7 @@ describe('createQuery', () => {
3605
3607
  expect(states.length).toBe(2);
3606
3608
  // Load query 1
3607
3609
  expect(states[0]).toMatchObject({
3608
- status: 'loading',
3610
+ status: 'pending',
3609
3611
  error: null,
3610
3612
  });
3611
3613
  // No rerenders - No state updates
@@ -3620,16 +3622,22 @@ describe('createQuery', () => {
3620
3622
  const states = [];
3621
3623
  let count = 0;
3622
3624
  function Page() {
3623
- const state = createQuery(key, async () => {
3624
- await sleep(10);
3625
- count++;
3626
- return count;
3627
- }, { staleTime: Infinity });
3625
+ const state = createQuery(() => ({
3626
+ queryKey: key,
3627
+ queryFn: async () => {
3628
+ await sleep(10);
3629
+ count++;
3630
+ return count;
3631
+ },
3632
+ staleTime: Infinity,
3633
+ }));
3628
3634
  createRenderEffect(() => {
3629
3635
  states.push({ ...state });
3630
3636
  });
3631
3637
  return (<div>
3632
- <button onClick={() => queryClient.resetQueries(key())}>reset</button>
3638
+ <button onClick={() => queryClient.resetQueries({ queryKey: key })}>
3639
+ reset
3640
+ </button>
3633
3641
  <div>data: {state.data ?? 'null'}</div>
3634
3642
  <div>isFetching: {state.isFetching}</div>
3635
3643
  </div>);
@@ -3643,29 +3651,27 @@ describe('createQuery', () => {
3643
3651
  await waitFor(() => screen.getByText('data: 2'));
3644
3652
  expect(count).toBe(2);
3645
3653
  expect(states[0]).toMatchObject({
3646
- data: undefined,
3647
- isLoading: true,
3654
+ isPending: true,
3648
3655
  isFetching: true,
3649
3656
  isSuccess: false,
3650
3657
  isStale: true,
3651
3658
  });
3652
3659
  expect(states[1]).toMatchObject({
3653
3660
  data: 1,
3654
- isLoading: false,
3661
+ isPending: false,
3655
3662
  isFetching: false,
3656
3663
  isSuccess: true,
3657
3664
  isStale: false,
3658
3665
  });
3659
3666
  expect(states[2]).toMatchObject({
3660
- data: undefined,
3661
- isLoading: true,
3667
+ isPending: true,
3662
3668
  isFetching: true,
3663
3669
  isSuccess: false,
3664
3670
  isStale: true,
3665
3671
  });
3666
3672
  expect(states[3]).toMatchObject({
3667
3673
  data: 2,
3668
- isLoading: false,
3674
+ isPending: false,
3669
3675
  isFetching: false,
3670
3676
  isSuccess: true,
3671
3677
  isStale: false,
@@ -3676,18 +3682,26 @@ describe('createQuery', () => {
3676
3682
  const states = [];
3677
3683
  let count = 0;
3678
3684
  function Page() {
3679
- const state = createQuery(key, async () => {
3680
- await sleep(10);
3681
- count++;
3682
- return count;
3683
- }, { staleTime: Infinity, enabled: false, notifyOnChangeProps: 'all' });
3685
+ const state = createQuery(() => ({
3686
+ queryKey: key,
3687
+ queryFn: async () => {
3688
+ await sleep(10);
3689
+ count++;
3690
+ return count;
3691
+ },
3692
+ staleTime: Infinity,
3693
+ enabled: false,
3694
+ notifyOnChangeProps: 'all',
3695
+ }));
3684
3696
  createRenderEffect(() => {
3685
3697
  states.push({ ...state });
3686
3698
  });
3687
3699
  const { refetch } = state;
3688
3700
  return (<div>
3689
3701
  <button onClick={() => refetch()}>refetch</button>
3690
- <button onClick={() => queryClient.resetQueries(key())}>reset</button>
3702
+ <button onClick={() => queryClient.resetQueries({ queryKey: key })}>
3703
+ reset
3704
+ </button>
3691
3705
  <div>data: {state.data ?? 'null'}</div>
3692
3706
  </div>);
3693
3707
  }
@@ -3702,29 +3716,26 @@ describe('createQuery', () => {
3702
3716
  await waitFor(() => expect(states.length).toBe(4));
3703
3717
  expect(count).toBe(1);
3704
3718
  expect(states[0]).toMatchObject({
3705
- data: undefined,
3706
- isLoading: true,
3719
+ isPending: true,
3707
3720
  isFetching: false,
3708
3721
  isSuccess: false,
3709
3722
  isStale: true,
3710
3723
  });
3711
3724
  expect(states[1]).toMatchObject({
3712
- data: undefined,
3713
- isLoading: true,
3725
+ isPending: true,
3714
3726
  isFetching: true,
3715
3727
  isSuccess: false,
3716
3728
  isStale: true,
3717
3729
  });
3718
3730
  expect(states[2]).toMatchObject({
3719
3731
  data: 1,
3720
- isLoading: false,
3732
+ isPending: false,
3721
3733
  isFetching: false,
3722
3734
  isSuccess: true,
3723
3735
  isStale: false,
3724
3736
  });
3725
3737
  expect(states[3]).toMatchObject({
3726
- data: undefined,
3727
- isLoading: true,
3738
+ isPending: true,
3728
3739
  isFetching: false,
3729
3740
  isSuccess: false,
3730
3741
  isStale: true,
@@ -3739,7 +3750,11 @@ describe('createQuery', () => {
3739
3750
  return JSON.stringify(x);
3740
3751
  }
3741
3752
  function Page() {
3742
- const state = createQuery(key, () => 'test', { queryKeyHashFn });
3753
+ const state = createQuery(() => ({
3754
+ queryKey: key,
3755
+ queryFn: () => 'test',
3756
+ queryKeyHashFn,
3757
+ }));
3743
3758
  createEffect(on(() => state.status, () => {
3744
3759
  renders++;
3745
3760
  }));
@@ -3758,18 +3773,18 @@ describe('createQuery', () => {
3758
3773
  return Promise.reject(new Error('Suspense Error Bingo'));
3759
3774
  });
3760
3775
  function Page(props) {
3761
- const state = createQuery(() => ['key'], queryFn, {
3762
- get enabled() {
3763
- return props.enabled;
3764
- },
3776
+ const state = createQuery(() => ({
3777
+ queryKey: ['key'],
3778
+ queryFn,
3779
+ enabled: props.enabled,
3765
3780
  retry: false,
3766
3781
  retryOnMount: false,
3767
3782
  refetchOnMount: false,
3768
3783
  refetchOnWindowFocus: false,
3769
- });
3784
+ }));
3770
3785
  return (<Switch fallback={<div>rendered</div>}>
3771
- <Match when={state.isLoading}>
3772
- <div>status: loading</div>
3786
+ <Match when={state.isPending}>
3787
+ <div>status: pending</div>
3773
3788
  </Match>
3774
3789
  <Match when={state.error instanceof Error}>
3775
3790
  <div>error</div>
@@ -3790,7 +3805,7 @@ describe('createQuery', () => {
3790
3805
  <App />
3791
3806
  </QueryClientProvider>));
3792
3807
  // initial state check
3793
- screen.getByText('status: loading');
3808
+ screen.getByText('status: pending');
3794
3809
  // // render error state component
3795
3810
  await waitFor(() => screen.getByText('error'));
3796
3811
  expect(queryFn).toBeCalledTimes(1);
@@ -3804,23 +3819,25 @@ describe('createQuery', () => {
3804
3819
  });
3805
3820
  it('should refetch when query key changed when previous status is error', async () => {
3806
3821
  function Page(props) {
3807
- const state = createQuery(() => [props.id], async () => {
3808
- await sleep(10);
3809
- if (props.id % 2 === 1) {
3810
- return Promise.reject(new Error('Error'));
3811
- }
3812
- else {
3813
- return 'data';
3814
- }
3815
- }, {
3822
+ const state = createQuery(() => ({
3823
+ queryKey: [props.id],
3824
+ queryFn: async () => {
3825
+ await sleep(10);
3826
+ if (props.id % 2 === 1) {
3827
+ return Promise.reject(new Error('Error'));
3828
+ }
3829
+ else {
3830
+ return 'data';
3831
+ }
3832
+ },
3816
3833
  retry: false,
3817
3834
  retryOnMount: false,
3818
3835
  refetchOnMount: false,
3819
3836
  refetchOnWindowFocus: false,
3820
- });
3837
+ }));
3821
3838
  return (<Switch fallback={<div>rendered</div>}>
3822
- <Match when={state.isLoading}>
3823
- <div>status: loading</div>
3839
+ <Match when={state.isPending}>
3840
+ <div>status: pending</div>
3824
3841
  </Match>
3825
3842
  <Match when={state.error instanceof Error}>
3826
3843
  <div>error</div>
@@ -3841,7 +3858,7 @@ describe('createQuery', () => {
3841
3858
  <App />
3842
3859
  </QueryClientProvider>));
3843
3860
  // initial state check
3844
- screen.getByText('status: loading');
3861
+ screen.getByText('status: pending');
3845
3862
  // render error state component
3846
3863
  await waitFor(() => screen.getByText('error'));
3847
3864
  // change to unmount query
@@ -3853,15 +3870,17 @@ describe('createQuery', () => {
3853
3870
  });
3854
3871
  it('should refetch when query key changed when switching between erroneous queries', async () => {
3855
3872
  function Page(props) {
3856
- const state = createQuery(() => [props.id], async () => {
3857
- await sleep(10);
3858
- return Promise.reject(new Error('Error'));
3859
- }, {
3873
+ const state = createQuery(() => ({
3874
+ queryKey: [props.id],
3875
+ queryFn: async () => {
3876
+ await sleep(10);
3877
+ return Promise.reject(new Error('Error'));
3878
+ },
3860
3879
  retry: false,
3861
3880
  retryOnMount: false,
3862
3881
  refetchOnMount: false,
3863
3882
  refetchOnWindowFocus: false,
3864
- });
3883
+ }));
3865
3884
  return (<Switch fallback={<div>rendered</div>}>
3866
3885
  <Match when={state.isFetching}>
3867
3886
  <div>status: fetching</div>
@@ -3897,28 +3916,30 @@ describe('createQuery', () => {
3897
3916
  await waitFor(() => screen.getByText('status: fetching'));
3898
3917
  await waitFor(() => screen.getByText('error'));
3899
3918
  });
3900
- it('should have no error in loading state when refetching after error occurred', async () => {
3919
+ it('should have no error in pending state when refetching after error occurred', async () => {
3901
3920
  const key = queryKey();
3902
3921
  const states = [];
3903
3922
  const error = new Error('oops');
3904
3923
  let count = 0;
3905
3924
  function Page() {
3906
- const state = createQuery(key, async () => {
3907
- await sleep(10);
3908
- if (count === 0) {
3909
- count++;
3910
- throw error;
3911
- }
3912
- return 5;
3913
- }, {
3925
+ const state = createQuery(() => ({
3926
+ queryKey: key,
3927
+ queryFn: async () => {
3928
+ await sleep(10);
3929
+ if (count === 0) {
3930
+ count++;
3931
+ throw error;
3932
+ }
3933
+ return 5;
3934
+ },
3914
3935
  retry: false,
3915
- });
3936
+ }));
3916
3937
  createRenderEffect(() => {
3917
3938
  states.push({ ...state });
3918
3939
  });
3919
3940
  return (<Switch fallback={<div>data: {state.data}</div>}>
3920
- <Match when={state.isLoading}>
3921
- <div>status: loading</div>
3941
+ <Match when={state.isPending}>
3942
+ <div>status: pending</div>
3922
3943
  </Match>
3923
3944
  <Match when={state.error instanceof Error}>
3924
3945
  <div>
@@ -3936,7 +3957,7 @@ describe('createQuery', () => {
3936
3957
  await waitFor(() => screen.getByText('data: 5'));
3937
3958
  await waitFor(() => expect(states.length).toBe(4));
3938
3959
  expect(states[0]).toMatchObject({
3939
- status: 'loading',
3960
+ status: 'pending',
3940
3961
  data: undefined,
3941
3962
  error: null,
3942
3963
  });
@@ -3946,7 +3967,7 @@ describe('createQuery', () => {
3946
3967
  error,
3947
3968
  });
3948
3969
  expect(states[2]).toMatchObject({
3949
- status: 'loading',
3970
+ status: 'pending',
3950
3971
  data: undefined,
3951
3972
  error: null,
3952
3973
  });
@@ -3962,13 +3983,13 @@ describe('createQuery', () => {
3962
3983
  const key = queryKey();
3963
3984
  const states = [];
3964
3985
  function Page() {
3965
- const state = createQuery({
3986
+ const state = createQuery(() => ({
3966
3987
  queryKey: key,
3967
3988
  queryFn: async () => {
3968
3989
  await sleep(10);
3969
3990
  return 'data';
3970
3991
  },
3971
- });
3992
+ }));
3972
3993
  createEffect(() => {
3973
3994
  states.push(state.fetchStatus);
3974
3995
  });
@@ -3982,7 +4003,7 @@ describe('createQuery', () => {
3982
4003
  render(() => (<QueryClientProvider client={queryClient}>
3983
4004
  <Page />
3984
4005
  </QueryClientProvider>));
3985
- await waitFor(() => screen.getByText('status: loading, isPaused: true'));
4006
+ await waitFor(() => screen.getByText('status: pending, isPaused: true'));
3986
4007
  onlineMock.mockReturnValue(true);
3987
4008
  window.dispatchEvent(new Event('online'));
3988
4009
  await waitFor(() => screen.getByText('status: success, isPaused: false'));
@@ -3996,14 +4017,14 @@ describe('createQuery', () => {
3996
4017
  const key = queryKey();
3997
4018
  let count = 0;
3998
4019
  function Page() {
3999
- const state = createQuery({
4020
+ const state = createQuery(() => ({
4000
4021
  queryKey: key,
4001
4022
  queryFn: async () => {
4002
4023
  count++;
4003
4024
  await sleep(10);
4004
4025
  return 'data' + count;
4005
4026
  },
4006
- });
4027
+ }));
4007
4028
  return (<div>
4008
4029
  <div>
4009
4030
  status: {state.status}, fetchStatus: {state.fetchStatus},
@@ -4011,7 +4032,7 @@ describe('createQuery', () => {
4011
4032
  </div>
4012
4033
  <div>failureReason: {state.failureReason ?? 'null'}</div>
4013
4034
  <div>data: {state.data}</div>
4014
- <button onClick={() => queryClient.invalidateQueries({ queryKey: key() })}>
4035
+ <button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
4015
4036
  invalidate
4016
4037
  </button>
4017
4038
  </div>);
@@ -4039,20 +4060,20 @@ describe('createQuery', () => {
4039
4060
  const key = queryKey();
4040
4061
  let count = 0;
4041
4062
  function Page() {
4042
- const state = createQuery({
4063
+ const state = createQuery(() => ({
4043
4064
  queryKey: key,
4044
4065
  queryFn: async () => {
4045
4066
  count++;
4046
4067
  await sleep(10);
4047
4068
  return 'data' + count;
4048
4069
  },
4049
- });
4070
+ }));
4050
4071
  return (<div>
4051
4072
  <div>
4052
4073
  status: {state.status}, fetchStatus: {state.fetchStatus}
4053
4074
  </div>
4054
4075
  <div>data: {state.data}</div>
4055
- <button onClick={() => queryClient.invalidateQueries({ queryKey: key() })}>
4076
+ <button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
4056
4077
  invalidate
4057
4078
  </button>
4058
4079
  </div>);
@@ -4064,7 +4085,7 @@ describe('createQuery', () => {
4064
4085
  const onlineMock = mockNavigatorOnLine(false);
4065
4086
  fireEvent.click(screen.getByRole('button', { name: /invalidate/i }));
4066
4087
  await waitFor(() => screen.getByText('status: success, fetchStatus: paused'));
4067
- window.dispatchEvent(new FocusEvent('focus'));
4088
+ window.dispatchEvent(new Event('visibilitychange'));
4068
4089
  await sleep(15);
4069
4090
  await waitFor(() => expect(screen.queryByText('data: data2')).not.toBeInTheDocument());
4070
4091
  expect(count).toBe(1);
@@ -4074,20 +4095,20 @@ describe('createQuery', () => {
4074
4095
  const key = queryKey();
4075
4096
  let count = 0;
4076
4097
  function Page() {
4077
- const state = createQuery({
4098
+ const state = createQuery(() => ({
4078
4099
  queryKey: key,
4079
4100
  queryFn: async () => {
4080
4101
  count++;
4081
4102
  await sleep(10);
4082
4103
  return 'data' + count;
4083
4104
  },
4084
- });
4105
+ }));
4085
4106
  return (<div>
4086
4107
  <div>
4087
4108
  status: {state.status}, fetchStatus: {state.fetchStatus}
4088
4109
  </div>
4089
4110
  <div>data: {state.data}</div>
4090
- <button onClick={() => queryClient.invalidateQueries({ queryKey: key() })}>
4111
+ <button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
4091
4112
  invalidate
4092
4113
  </button>
4093
4114
  </div>);
@@ -4096,11 +4117,11 @@ describe('createQuery', () => {
4096
4117
  render(() => (<QueryClientProvider client={queryClient}>
4097
4118
  <Page />
4098
4119
  </QueryClientProvider>));
4099
- await waitFor(() => screen.getByText('status: loading, fetchStatus: paused'));
4120
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: paused'));
4100
4121
  fireEvent.click(screen.getByRole('button', { name: /invalidate/i }));
4101
4122
  await sleep(15);
4102
4123
  // invalidation should not trigger a refetch
4103
- await waitFor(() => screen.getByText('status: loading, fetchStatus: paused'));
4124
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: paused'));
4104
4125
  expect(count).toBe(0);
4105
4126
  onlineMock.mockRestore();
4106
4127
  });
@@ -4108,7 +4129,7 @@ describe('createQuery', () => {
4108
4129
  const key = queryKey();
4109
4130
  let count = 0;
4110
4131
  function Page() {
4111
- const state = createQuery({
4132
+ const state = createQuery(() => ({
4112
4133
  queryKey: key,
4113
4134
  queryFn: async () => {
4114
4135
  count++;
@@ -4116,13 +4137,13 @@ describe('createQuery', () => {
4116
4137
  return 'data' + count;
4117
4138
  },
4118
4139
  initialData: 'initial',
4119
- });
4140
+ }));
4120
4141
  return (<div>
4121
4142
  <div>
4122
4143
  status: {state.status}, fetchStatus: {state.fetchStatus}
4123
4144
  </div>
4124
4145
  <div>data: {state.data}</div>
4125
- <button onClick={() => queryClient.invalidateQueries({ queryKey: key() })}>
4146
+ <button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
4126
4147
  invalidate
4127
4148
  </button>
4128
4149
  </div>);
@@ -4146,7 +4167,7 @@ describe('createQuery', () => {
4146
4167
  const key = queryKey();
4147
4168
  let count = 0;
4148
4169
  function Page() {
4149
- const state = createQuery({
4170
+ const state = createQuery(() => ({
4150
4171
  queryKey: key,
4151
4172
  queryFn: async () => {
4152
4173
  count++;
@@ -4154,13 +4175,13 @@ describe('createQuery', () => {
4154
4175
  return 'data' + count;
4155
4176
  },
4156
4177
  initialData: 'initial',
4157
- });
4178
+ }));
4158
4179
  return (<div>
4159
4180
  <div>
4160
4181
  status: {state.status}, fetchStatus: {state.fetchStatus}
4161
4182
  </div>
4162
4183
  <div>data: {state.data}</div>
4163
- <button onClick={() => queryClient.invalidateQueries({ queryKey: key() })}>
4184
+ <button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
4164
4185
  invalidate
4165
4186
  </button>
4166
4187
  </div>);
@@ -4178,7 +4199,7 @@ describe('createQuery', () => {
4178
4199
  await sleep(15);
4179
4200
  await waitFor(() => screen.getByText('status: success, fetchStatus: paused'));
4180
4201
  // triggers a second pause
4181
- window.dispatchEvent(new FocusEvent('focus'));
4202
+ window.dispatchEvent(new Event('visibilitychange'));
4182
4203
  onlineMock.mockReturnValue(true);
4183
4204
  window.dispatchEvent(new Event('online'));
4184
4205
  await waitFor(() => screen.getByText('status: success, fetchStatus: idle'));
@@ -4192,7 +4213,7 @@ describe('createQuery', () => {
4192
4213
  const key = queryKey();
4193
4214
  let count = 0;
4194
4215
  function Page() {
4195
- const state = createQuery({
4216
+ const state = createQuery(() => ({
4196
4217
  queryKey: key,
4197
4218
  queryFn: async () => {
4198
4219
  count++;
@@ -4201,7 +4222,7 @@ describe('createQuery', () => {
4201
4222
  },
4202
4223
  retry: 2,
4203
4224
  retryDelay: 10,
4204
- });
4225
+ }));
4205
4226
  return (<div>
4206
4227
  <div>
4207
4228
  status: {state.status}, fetchStatus: {state.fetchStatus},
@@ -4213,11 +4234,11 @@ describe('createQuery', () => {
4213
4234
  render(() => (<QueryClientProvider client={queryClient}>
4214
4235
  <Page />
4215
4236
  </QueryClientProvider>));
4216
- await waitFor(() => screen.getByText('status: loading, fetchStatus: fetching, failureCount: 1'));
4237
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: fetching, failureCount: 1'));
4217
4238
  await waitFor(() => screen.getByText('failureReason: failed1'));
4218
4239
  const onlineMock = mockNavigatorOnLine(false);
4219
4240
  await sleep(20);
4220
- await waitFor(() => screen.getByText('status: loading, fetchStatus: paused, failureCount: 1'));
4241
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: paused, failureCount: 1'));
4221
4242
  await waitFor(() => screen.getByText('failureReason: failed1'));
4222
4243
  expect(count).toBe(1);
4223
4244
  onlineMock.mockReturnValue(true);
@@ -4231,14 +4252,14 @@ describe('createQuery', () => {
4231
4252
  const key = queryKey();
4232
4253
  let count = 0;
4233
4254
  function Component() {
4234
- const state = createQuery({
4255
+ const state = createQuery(() => ({
4235
4256
  queryKey: key,
4236
4257
  queryFn: async () => {
4237
4258
  count++;
4238
4259
  await sleep(10);
4239
4260
  return 'data' + count;
4240
4261
  },
4241
- });
4262
+ }));
4242
4263
  return (<div>
4243
4264
  <div>
4244
4265
  status: {state.status}, fetchStatus: {state.fetchStatus}
@@ -4257,12 +4278,12 @@ describe('createQuery', () => {
4257
4278
  render(() => (<QueryClientProvider client={queryClient}>
4258
4279
  <Page />
4259
4280
  </QueryClientProvider>));
4260
- await waitFor(() => screen.getByText('status: loading, fetchStatus: paused'));
4281
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: paused'));
4261
4282
  fireEvent.click(screen.getByRole('button', { name: /hide/i }));
4262
4283
  onlineMock.mockReturnValue(true);
4263
4284
  window.dispatchEvent(new Event('online'));
4264
4285
  await sleep(15);
4265
- expect(queryClient.getQueryState(key())).toMatchObject({
4286
+ expect(queryClient.getQueryState(key)).toMatchObject({
4266
4287
  fetchStatus: 'idle',
4267
4288
  status: 'success',
4268
4289
  });
@@ -4273,7 +4294,7 @@ describe('createQuery', () => {
4273
4294
  const key = queryKey();
4274
4295
  let count = 0;
4275
4296
  function Page() {
4276
- const state = createQuery({
4297
+ const state = createQuery(() => ({
4277
4298
  queryKey: key,
4278
4299
  queryFn: async () => {
4279
4300
  count++;
@@ -4281,9 +4302,9 @@ describe('createQuery', () => {
4281
4302
  return 'data' + count;
4282
4303
  },
4283
4304
  refetchOnReconnect: false,
4284
- });
4305
+ }));
4285
4306
  return (<div>
4286
- <button onClick={() => queryClient.cancelQueries({ queryKey: key() })}>
4307
+ <button onClick={() => queryClient.cancelQueries({ queryKey: key })}>
4287
4308
  cancel
4288
4309
  </button>
4289
4310
  <div>
@@ -4296,14 +4317,14 @@ describe('createQuery', () => {
4296
4317
  render(() => (<QueryClientProvider client={queryClient}>
4297
4318
  <Page />
4298
4319
  </QueryClientProvider>));
4299
- await waitFor(() => screen.getByText('status: loading, fetchStatus: paused'));
4320
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: paused'));
4300
4321
  fireEvent.click(screen.getByRole('button', { name: /cancel/i }));
4301
- await waitFor(() => screen.getByText('status: loading, fetchStatus: idle'));
4322
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'));
4302
4323
  expect(count).toBe(0);
4303
4324
  onlineMock.mockReturnValue(true);
4304
4325
  window.dispatchEvent(new Event('online'));
4305
4326
  await sleep(15);
4306
- await waitFor(() => screen.getByText('status: loading, fetchStatus: idle'));
4327
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: idle'));
4307
4328
  expect(count).toBe(0);
4308
4329
  onlineMock.mockRestore();
4309
4330
  });
@@ -4311,14 +4332,14 @@ describe('createQuery', () => {
4311
4332
  const key = queryKey();
4312
4333
  let count = 0;
4313
4334
  function Component() {
4314
- const state = createQuery({
4335
+ const state = createQuery(() => ({
4315
4336
  queryKey: key,
4316
- queryFn: async ({ signal }) => {
4337
+ queryFn: async ({ signal: _signal }) => {
4317
4338
  count++;
4318
4339
  await sleep(10);
4319
- return `${signal ? 'signal' : 'data'}${count}`;
4340
+ return `signal${count}`;
4320
4341
  },
4321
- });
4342
+ }));
4322
4343
  return (<div>
4323
4344
  <div>
4324
4345
  status: {state.status}, fetchStatus: {state.fetchStatus}
@@ -4331,7 +4352,7 @@ describe('createQuery', () => {
4331
4352
  return (<div>
4332
4353
  {show() && <Component />}
4333
4354
  <button onClick={() => setShow(false)}>hide</button>
4334
- <button onClick={() => queryClient.invalidateQueries({ queryKey: key() })}>
4355
+ <button onClick={() => queryClient.invalidateQueries({ queryKey: key })}>
4335
4356
  invalidate
4336
4357
  </button>
4337
4358
  </div>);
@@ -4348,7 +4369,7 @@ describe('createQuery', () => {
4348
4369
  onlineMock.mockReturnValue(true);
4349
4370
  window.dispatchEvent(new Event('online'));
4350
4371
  await sleep(15);
4351
- expect(queryClient.getQueryState(key())).toMatchObject({
4372
+ expect(queryClient.getQueryState(key)).toMatchObject({
4352
4373
  fetchStatus: 'idle',
4353
4374
  status: 'success',
4354
4375
  });
@@ -4362,7 +4383,7 @@ describe('createQuery', () => {
4362
4383
  const key = queryKey();
4363
4384
  let count = 0;
4364
4385
  function Page() {
4365
- const state = createQuery({
4386
+ const state = createQuery(() => ({
4366
4387
  queryKey: key,
4367
4388
  queryFn: async () => {
4368
4389
  count++;
@@ -4370,7 +4391,7 @@ describe('createQuery', () => {
4370
4391
  return 'data ' + count;
4371
4392
  },
4372
4393
  networkMode: 'always',
4373
- });
4394
+ }));
4374
4395
  return (<div>
4375
4396
  <div>
4376
4397
  status: {state.status}, isPaused: {String(state.isPaused)}
@@ -4392,7 +4413,7 @@ describe('createQuery', () => {
4392
4413
  const key = queryKey();
4393
4414
  let count = 0;
4394
4415
  function Page() {
4395
- const state = createQuery({
4416
+ const state = createQuery(() => ({
4396
4417
  queryKey: key,
4397
4418
  queryFn: async () => {
4398
4419
  count++;
@@ -4402,7 +4423,7 @@ describe('createQuery', () => {
4402
4423
  networkMode: 'always',
4403
4424
  retry: 1,
4404
4425
  retryDelay: 5,
4405
- });
4426
+ }));
4406
4427
  return (<div>
4407
4428
  <div>
4408
4429
  status: {state.status}, isPaused: {String(state.isPaused)}
@@ -4429,7 +4450,7 @@ describe('createQuery', () => {
4429
4450
  const key = queryKey();
4430
4451
  let count = 0;
4431
4452
  function Page() {
4432
- const state = createQuery({
4453
+ const state = createQuery(() => ({
4433
4454
  queryKey: key,
4434
4455
  queryFn: async () => {
4435
4456
  count++;
@@ -4439,7 +4460,7 @@ describe('createQuery', () => {
4439
4460
  retry: 2,
4440
4461
  retryDelay: 1,
4441
4462
  networkMode: 'offlineFirst',
4442
- });
4463
+ }));
4443
4464
  return (<div>
4444
4465
  <div>
4445
4466
  status: {state.status}, fetchStatus: {state.fetchStatus},
@@ -4451,7 +4472,7 @@ describe('createQuery', () => {
4451
4472
  render(() => (<QueryClientProvider client={queryClient}>
4452
4473
  <Page />
4453
4474
  </QueryClientProvider>));
4454
- await waitFor(() => screen.getByText('status: loading, fetchStatus: paused, failureCount: 1'));
4475
+ await waitFor(() => screen.getByText('status: pending, fetchStatus: paused, failureCount: 1'));
4455
4476
  await waitFor(() => screen.getByText('failureReason: failed1'));
4456
4477
  expect(count).toBe(1);
4457
4478
  onlineMock.mockReturnValue(true);
@@ -4470,16 +4491,18 @@ describe('createQuery', () => {
4470
4491
  throw error;
4471
4492
  };
4472
4493
  function Page() {
4473
- const state = createQuery(key, queryFn, {
4494
+ const state = createQuery(() => ({
4495
+ queryKey: key,
4496
+ queryFn,
4474
4497
  retry: false,
4475
4498
  retryOnMount: false,
4476
- });
4499
+ }));
4477
4500
  createRenderEffect(() => {
4478
4501
  states.push({ ...state });
4479
4502
  });
4480
4503
  return <></>;
4481
4504
  }
4482
- await queryClient.prefetchQuery(key(), queryFn);
4505
+ await queryClient.prefetchQuery({ queryKey: key, queryFn });
4483
4506
  render(() => (<QueryClientProvider client={queryClient}>
4484
4507
  <Page />
4485
4508
  </QueryClientProvider>));
@@ -4493,10 +4516,14 @@ describe('createQuery', () => {
4493
4516
  const key = queryKey();
4494
4517
  const onSuccess = jest.fn();
4495
4518
  function Page() {
4496
- const state = createQuery(key, () => 'data', { onSuccess });
4519
+ const state = createQuery(() => ({
4520
+ queryKey: key,
4521
+ queryFn: () => 'data',
4522
+ onSuccess,
4523
+ }));
4497
4524
  return (<div>
4498
4525
  <div>data: {state.data}</div>
4499
- <button onClick={() => queryClient.setQueryData(key(), 'newData')}>
4526
+ <button onClick={() => queryClient.setQueryData(key, 'newData')}>
4500
4527
  setQueryData
4501
4528
  </button>
4502
4529
  </div>);
@@ -4513,11 +4540,16 @@ describe('createQuery', () => {
4513
4540
  it('setQueryData - should respect updatedAt', async () => {
4514
4541
  const key = queryKey();
4515
4542
  function Page() {
4516
- const state = createQuery(key, () => 'data');
4543
+ const state = createQuery(() => ({
4544
+ queryKey: key,
4545
+ queryFn: () => 'data',
4546
+ }));
4517
4547
  return (<div>
4518
4548
  <div>data: {state.data}</div>
4519
4549
  <div>dataUpdatedAt: {state.dataUpdatedAt}</div>
4520
- <button onClick={() => queryClient.setQueryData(key(), 'newData', { updatedAt: 100 })}>
4550
+ <button onClick={() => queryClient.setQueryData(key, 'newData', {
4551
+ updatedAt: 100,
4552
+ })}>
4521
4553
  setQueryData
4522
4554
  </button>
4523
4555
  </div>);
@@ -4536,11 +4568,13 @@ describe('createQuery', () => {
4536
4568
  const key = queryKey();
4537
4569
  const error = new Error('oops');
4538
4570
  function Page() {
4539
- const state = createQuery(key, async () => {
4540
- throw error;
4541
- }, {
4571
+ const state = createQuery(() => ({
4572
+ queryKey: key,
4573
+ queryFn: async () => {
4574
+ throw error;
4575
+ },
4542
4576
  retry: false,
4543
- });
4577
+ }));
4544
4578
  return (<div>
4545
4579
  <button onClick={() => state.refetch()}>refetch</button>
4546
4580
  <span>data: {state.errorUpdateCount}</span>
@@ -4556,4 +4590,18 @@ describe('createQuery', () => {
4556
4590
  fireEvent.click(fetchBtn);
4557
4591
  await waitFor(() => screen.getByText('data: 3'));
4558
4592
  });
4593
+ it('should use provided custom queryClient', async () => {
4594
+ const key = queryKey();
4595
+ const queryFn = () => {
4596
+ return Promise.resolve('custom client');
4597
+ };
4598
+ function Page() {
4599
+ const state = createQuery(() => ({ queryKey: key, queryFn }), () => queryClient);
4600
+ return (<div>
4601
+ <h1>Status: {state.data}</h1>
4602
+ </div>);
4603
+ }
4604
+ render(() => <Page />);
4605
+ await waitFor(() => screen.getByText('Status: custom client'));
4606
+ });
4559
4607
  });