@tanstack/solid-query 4.24.9 → 5.0.0-alpha.0

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 +298 -0
  2. package/build/cjs/index.js.map +1 -0
  3. package/build/esm/index.js +283 -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 +6 -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 +15 -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 -3572
  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
@@ -2,21 +2,13 @@ import { fireEvent, render, screen, waitFor } from 'solid-testing-library'
2
2
 
3
3
  import * as QueriesObserverModule from '../../../query-core/src/queriesObserver'
4
4
 
5
- import type { QueryFunctionContext } from '@tanstack/query-core'
6
- import {
7
- createContext,
8
- createMemo,
9
- createRenderEffect,
10
- createSignal,
11
- ErrorBoundary,
12
- } from 'solid-js'
5
+ import type { QueryFunctionContext, QueryKey } from '@tanstack/query-core'
6
+ import { createRenderEffect, createSignal } from 'solid-js'
13
7
  import type {
14
- CreateQueryOptions,
15
8
  CreateQueryResult,
16
- QueryClient,
17
9
  QueryFunction,
18
10
  QueryObserverResult,
19
- SolidQueryKey,
11
+ SolidQueryOptions,
20
12
  } from '..'
21
13
  import {
22
14
  createQueries,
@@ -42,7 +34,7 @@ describe('useQueries', () => {
42
34
  const results: CreateQueryResult[][] = []
43
35
 
44
36
  function Page() {
45
- const result = createQueries({
37
+ const result = createQueries(() => ({
46
38
  queries: [
47
39
  {
48
40
  queryKey: key1,
@@ -59,7 +51,7 @@ describe('useQueries', () => {
59
51
  },
60
52
  },
61
53
  ],
62
- })
54
+ }))
63
55
 
64
56
  createRenderEffect(() => {
65
57
  results.push([...result])
@@ -89,305 +81,32 @@ describe('useQueries', () => {
89
81
  expect(results[2]).toMatchObject([{ data: 1 }, { data: 2 }])
90
82
  })
91
83
 
92
- it('should keep previous data if amount of queries is the same', async () => {
84
+ it('handles type parameter - tuple of tuples', async () => {
93
85
  const key1 = queryKey()
94
86
  const key2 = queryKey()
95
- const states: CreateQueryResult[][] = []
87
+ const key3 = queryKey()
96
88
 
89
+ // @ts-expect-error (Page component is not rendered)
90
+ // eslint-disable-next-line
97
91
  function Page() {
98
- const [count, setCount] = createSignal(1)
99
- const result = createQueries({
100
- queries: [
101
- {
102
- queryKey: () => [key1(), count()],
103
- keepPreviousData: true,
104
- queryFn: async () => {
105
- await sleep(10)
106
- return count() * 2
107
- },
108
- },
109
- {
110
- queryKey: () => [key2(), count()],
111
- keepPreviousData: true,
112
- queryFn: async () => {
113
- await sleep(35)
114
- return count() * 5
92
+ const result1 = createQueries<[[number], [string], [string[], boolean]]>(
93
+ () => ({
94
+ queries: [
95
+ {
96
+ queryKey: key1,
97
+ queryFn: () => 1,
115
98
  },
116
- },
117
- ],
118
- })
119
-
120
- createRenderEffect(() => {
121
- states.push([...result])
122
- })
123
-
124
- const isFetching = createMemo(() => result.some((r) => r.isFetching))
125
-
126
- return (
127
- <div>
128
- <div>
129
- data1: {String(result[0].data ?? 'null')}, data2:{' '}
130
- {String(result[1].data ?? 'null')}
131
- </div>
132
- <div>isFetching: {String(isFetching())}</div>
133
- <button onClick={() => setCount((prev) => prev + 1)}>inc</button>
134
- </div>
135
- )
136
- }
137
-
138
- render(() => (
139
- <QueryClientProvider client={queryClient}>
140
- <Page />
141
- </QueryClientProvider>
142
- ))
143
-
144
- await waitFor(() => screen.getByText('data1: 2, data2: 5'))
145
- fireEvent.click(screen.getByRole('button', { name: /inc/i }))
146
-
147
- await waitFor(() => screen.getByText('data1: 4, data2: 10'))
148
- await waitFor(() => screen.getByText('isFetching: false'))
149
-
150
- expect(states[states.length - 1]).toMatchObject([
151
- { status: 'success', data: 4, isPreviousData: false, isFetching: false },
152
- { status: 'success', data: 10, isPreviousData: false, isFetching: false },
153
- ])
154
- })
155
-
156
- it('should keep previous data for variable amounts of useQueries', async () => {
157
- const key = queryKey()
158
- const states: CreateQueryResult[][] = []
159
-
160
- function Page() {
161
- const [count, setCount] = createSignal(2)
162
- const result = createQueries({
163
- // TODO(lukemurray): reactive queries doesn't appear to work
164
- get queries() {
165
- return Array.from({ length: count() }, (_, i) => ({
166
- queryKey: () => [key(), count(), i + 1],
167
- keepPreviousData: true,
168
- queryFn: async () => {
169
- await sleep(35 * (i + 1))
170
- return (i + 1) * count() * 2
99
+ {
100
+ queryKey: key2,
101
+ queryFn: () => 'string',
171
102
  },
172
- }))
173
- },
174
- })
175
-
176
- createRenderEffect(() => {
177
- states.push([...result])
178
- })
179
-
180
- const isFetching = createMemo(() => result.some((r) => r.isFetching))
181
-
182
- return (
183
- <div>
184
- <div>data: {result.map((it) => it.data).join(',')}</div>
185
- <div>isFetching: {String(isFetching())}</div>
186
- <button onClick={() => setCount((prev) => prev + 1)}>inc</button>
187
- </div>
188
- )
189
- }
190
-
191
- render(() => (
192
- <QueryClientProvider client={queryClient}>
193
- <Page />
194
- </QueryClientProvider>
195
- ))
196
-
197
- await waitFor(() => screen.getByText('data: 4,8'))
198
- fireEvent.click(screen.getByRole('button', { name: /inc/i }))
199
-
200
- await waitFor(() => screen.getByText('data: 6,12,18'))
201
- await waitFor(() => screen.getByText('isFetching: false'))
202
-
203
- expect(states[states.length - 1]).toMatchObject([
204
- { status: 'success', data: 6, isPreviousData: false, isFetching: false },
205
- { status: 'success', data: 12, isPreviousData: false, isFetching: false },
206
- { status: 'success', data: 18, isPreviousData: false, isFetching: false },
207
- ])
208
- })
209
-
210
- it('should keep previous data when switching between queries', async () => {
211
- const key = queryKey()
212
- const states: CreateQueryResult[][] = []
213
-
214
- function Page() {
215
- const [series1, setSeries1] = createSignal(1)
216
- const [series2, setSeries2] = createSignal(2)
217
- const ids = [series1, series2]
218
-
219
- const result = createQueries({
220
- queries: ids.map((id) => {
221
- return {
222
- queryKey: () => [key(), id()],
223
- queryFn: async () => {
224
- await sleep(5)
225
- return id() * 5
103
+ {
104
+ queryKey: key3,
105
+ queryFn: () => ['string[]'],
226
106
  },
227
- keepPreviousData: true,
228
- }
107
+ ],
229
108
  }),
230
- })
231
-
232
- createRenderEffect(() => {
233
- states.push([...result])
234
- })
235
-
236
- const isFetching = createMemo(() => result.some((r) => r.isFetching))
237
-
238
- return (
239
- <div>
240
- <div>
241
- data1: {String(result[0]?.data ?? 'null')}, data2:{' '}
242
- {String(result[1]?.data ?? 'null')}
243
- </div>
244
- <div>isFetching: {String(isFetching())}</div>
245
- <button onClick={() => setSeries2(3)}>setSeries2</button>
246
- <button onClick={() => setSeries1(2)}>setSeries1</button>
247
- </div>
248
109
  )
249
- }
250
-
251
- render(() => (
252
- <QueryClientProvider client={queryClient}>
253
- <Page />
254
- </QueryClientProvider>
255
- ))
256
-
257
- await waitFor(() => screen.getByText('data1: 5, data2: 10'))
258
- fireEvent.click(screen.getByRole('button', { name: /setSeries2/i }))
259
-
260
- await waitFor(() => screen.getByText('data1: 5, data2: 15'))
261
- fireEvent.click(screen.getByRole('button', { name: /setSeries1/i }))
262
-
263
- await waitFor(() => screen.getByText('data1: 10, data2: 15'))
264
- await waitFor(() => screen.getByText('isFetching: false'))
265
-
266
- expect(states[states.length - 1]).toMatchObject([
267
- { status: 'success', data: 10, isPreviousData: false, isFetching: false },
268
- { status: 'success', data: 15, isPreviousData: false, isFetching: false },
269
- ])
270
- })
271
-
272
- it('should not go to infinite render loop with previous data when toggling queries', async () => {
273
- const key = queryKey()
274
- const states: CreateQueryResult[][] = []
275
-
276
- function Page() {
277
- const [enableId1, setEnableId1] = createSignal(true)
278
- const ids = createMemo(() => (enableId1() ? [1, 2] : [2]))
279
-
280
- const result = createQueries({
281
- // TODO(lukemurray): same issue queries should be reactive
282
- get queries() {
283
- return ids().map((id) => {
284
- return {
285
- queryKey: () => [key(), id],
286
- queryFn: async () => {
287
- await sleep(5)
288
- return id * 5
289
- },
290
- keepPreviousData: true,
291
- }
292
- })
293
- },
294
- })
295
-
296
- createRenderEffect(() => {
297
- states.push([...result])
298
- })
299
-
300
- const text = createMemo(() => {
301
- return result
302
- .map((r, idx) => `data${idx + 1}: ${r.data ?? 'null'}`)
303
- .join(' ')
304
- })
305
-
306
- const isFetching = createMemo(() => result.some((r) => r.isFetching))
307
-
308
- return (
309
- <div>
310
- <div>{text()}</div>
311
- <div>isFetching: {String(isFetching())}</div>
312
- <button onClick={() => setEnableId1(false)}>set1Disabled</button>
313
- <button onClick={() => setEnableId1(true)}>set2Enabled</button>
314
- </div>
315
- )
316
- }
317
-
318
- render(() => (
319
- <QueryClientProvider client={queryClient}>
320
- <Page />
321
- </QueryClientProvider>
322
- ))
323
-
324
- await waitFor(() => screen.getByText('data1: 5 data2: 10'))
325
- fireEvent.click(screen.getByRole('button', { name: /set1Disabled/i }))
326
-
327
- await waitFor(() => screen.getByText('data1: 10'))
328
- await waitFor(() => screen.getByText('isFetching: false'))
329
- fireEvent.click(screen.getByRole('button', { name: /set2Enabled/i }))
330
-
331
- await waitFor(() => screen.getByText('data1: 5 data2: 10'))
332
- await waitFor(() => screen.getByText('isFetching: false'))
333
-
334
- await waitFor(() => expect(states.length).toBe(5))
335
-
336
- expect(states[0]).toMatchObject([
337
- {
338
- status: 'loading',
339
- data: undefined,
340
- isPreviousData: false,
341
- isFetching: true,
342
- },
343
- {
344
- status: 'loading',
345
- data: undefined,
346
- isPreviousData: false,
347
- isFetching: true,
348
- },
349
- ])
350
- expect(states[1]).toMatchObject([
351
- { status: 'success', data: 5, isPreviousData: false, isFetching: false },
352
- { status: 'success', data: 10, isPreviousData: false, isFetching: false },
353
- ])
354
- expect(states[2]).toMatchObject([
355
- { status: 'success', data: 10, isPreviousData: false, isFetching: false },
356
- ])
357
- expect(states[3]).toMatchObject([
358
- { status: 'success', data: 5, isPreviousData: false, isFetching: true },
359
- { status: 'success', data: 10, isPreviousData: false, isFetching: false },
360
- ])
361
- expect(states[4]).toMatchObject([
362
- { status: 'success', data: 5, isPreviousData: false, isFetching: false },
363
- { status: 'success', data: 10, isPreviousData: false, isFetching: false },
364
- ])
365
- })
366
-
367
- it('handles type parameter - tuple of tuples', async () => {
368
- const key1 = queryKey()
369
- const key2 = queryKey()
370
- const key3 = queryKey()
371
-
372
- // @ts-expect-error (Page component is not rendered)
373
- // eslint-disable-next-line
374
- function Page() {
375
- const result1 = createQueries<[[number], [string], [string[], boolean]]>({
376
- queries: [
377
- {
378
- queryKey: key1,
379
- queryFn: () => 1,
380
- },
381
- {
382
- queryKey: key2,
383
- queryFn: () => 'string',
384
- },
385
- {
386
- queryKey: key3,
387
- queryFn: () => ['string[]'],
388
- },
389
- ],
390
- })
391
110
  expectType<QueryObserverResult<number, unknown>>(result1[0])
392
111
  expectType<QueryObserverResult<string, unknown>>(result1[1])
393
112
  expectType<QueryObserverResult<string[], boolean>>(result1[2])
@@ -399,7 +118,7 @@ describe('useQueries', () => {
399
118
  // TData (3rd element) takes precedence over TQueryFnData (1st element)
400
119
  const result2 = createQueries<
401
120
  [[string, unknown, string], [string, unknown, number]]
402
- >({
121
+ >(() => ({
403
122
  queries: [
404
123
  {
405
124
  queryKey: key1,
@@ -420,65 +139,65 @@ describe('useQueries', () => {
420
139
  },
421
140
  },
422
141
  ],
423
- })
142
+ }))
424
143
  expectType<QueryObserverResult<string, unknown>>(result2[0])
425
144
  expectType<QueryObserverResult<number, unknown>>(result2[1])
426
145
  expectType<string | undefined>(result2[0].data)
427
146
  expectType<number | undefined>(result2[1].data)
428
147
 
429
148
  // types should be enforced
430
- createQueries<[[string, unknown, string], [string, boolean, number]]>({
431
- queries: [
432
- {
433
- queryKey: key1,
434
- queryFn: () => 'string',
435
- select: (a) => {
436
- expectType<string>(a)
437
- expectTypeNotAny(a)
438
- return a.toLowerCase()
439
- },
440
- onSuccess: (a) => {
441
- expectType<string>(a)
442
- expectTypeNotAny(a)
443
- },
444
- placeholderData: 'string',
445
- // @ts-expect-error (initialData: string)
446
- initialData: 123,
447
- },
448
- {
449
- queryKey: key2,
450
- queryFn: () => 'string',
451
- select: (a) => {
452
- expectType<string>(a)
453
- expectTypeNotAny(a)
454
- return parseInt(a)
455
- },
456
- onSuccess: (a) => {
457
- expectType<number>(a)
458
- expectTypeNotAny(a)
149
+ createQueries<[[string, unknown, string], [string, boolean, number]]>(
150
+ () => ({
151
+ queries: [
152
+ {
153
+ queryKey: key1,
154
+ queryFn: () => 'string',
155
+ select: (a) => {
156
+ expectType<string>(a)
157
+ expectTypeNotAny(a)
158
+ return a.toLowerCase()
159
+ },
160
+ onSuccess: (a) => {
161
+ expectType<string>(a)
162
+ expectTypeNotAny(a)
163
+ },
164
+ placeholderData: 'string',
165
+ // @ts-expect-error (initialData: string)
166
+ initialData: 123,
459
167
  },
460
- onError: (e) => {
461
- expectType<boolean>(e)
462
- expectTypeNotAny(e)
168
+ {
169
+ queryKey: key2,
170
+ queryFn: () => 'string',
171
+ select: (a) => {
172
+ expectType<string>(a)
173
+ expectTypeNotAny(a)
174
+ return parseInt(a)
175
+ },
176
+ onSuccess: (a) => {
177
+ expectType<number>(a)
178
+ expectTypeNotAny(a)
179
+ },
180
+ onError: (e) => {
181
+ expectType<boolean>(e)
182
+ expectTypeNotAny(e)
183
+ },
184
+ placeholderData: 'string',
185
+ // @ts-expect-error (initialData: string)
186
+ initialData: 123,
463
187
  },
464
- placeholderData: 'string',
465
- // @ts-expect-error (initialData: string)
466
- initialData: 123,
467
- },
468
- ],
469
- })
188
+ ],
189
+ }),
190
+ )
470
191
 
471
192
  // field names should be enforced
472
- createQueries<[[string]]>({
193
+ createQueries<[[string]]>(() => ({
473
194
  queries: [
474
195
  {
475
196
  queryKey: key1,
476
197
  queryFn: () => 'string',
477
- // @ts-expect-error (invalidField)
478
- someInvalidField: [],
479
198
  },
480
199
  ],
481
- })
200
+ }))
482
201
  }
483
202
  })
484
203
 
@@ -496,7 +215,7 @@ describe('useQueries', () => {
496
215
  { queryFnData: string },
497
216
  { queryFnData: string[]; error: boolean },
498
217
  ]
499
- >({
218
+ >(() => ({
500
219
  queries: [
501
220
  {
502
221
  queryKey: key1,
@@ -511,7 +230,7 @@ describe('useQueries', () => {
511
230
  queryFn: () => ['string[]'],
512
231
  },
513
232
  ],
514
- })
233
+ }))
515
234
  expectType<QueryObserverResult<number, unknown>>(result1[0])
516
235
  expectType<QueryObserverResult<string, unknown>>(result1[1])
517
236
  expectType<QueryObserverResult<string[], boolean>>(result1[2])
@@ -526,7 +245,7 @@ describe('useQueries', () => {
526
245
  { queryFnData: string; data: string },
527
246
  { queryFnData: string; data: number },
528
247
  ]
529
- >({
248
+ >(() => ({
530
249
  queries: [
531
250
  {
532
251
  queryKey: key1,
@@ -547,35 +266,37 @@ describe('useQueries', () => {
547
266
  },
548
267
  },
549
268
  ],
550
- })
269
+ }))
551
270
  expectType<QueryObserverResult<string, unknown>>(result2[0])
552
271
  expectType<QueryObserverResult<number, unknown>>(result2[1])
553
272
  expectType<string | undefined>(result2[0].data)
554
273
  expectType<number | undefined>(result2[1].data)
555
274
 
556
275
  // can pass only TData (data prop) although TQueryFnData will be left unknown
557
- const result3 = createQueries<[{ data: string }, { data: number }]>({
558
- queries: [
559
- {
560
- queryKey: key1,
561
- queryFn: () => 'string',
562
- select: (a) => {
563
- expectType<unknown>(a)
564
- expectTypeNotAny(a)
565
- return a as string
276
+ const result3 = createQueries<[{ data: string }, { data: number }]>(
277
+ () => ({
278
+ queries: [
279
+ {
280
+ queryKey: key1,
281
+ queryFn: () => 'string',
282
+ select: (a) => {
283
+ expectType<unknown>(a)
284
+ expectTypeNotAny(a)
285
+ return a as string
286
+ },
566
287
  },
567
- },
568
- {
569
- queryKey: key2,
570
- queryFn: () => 'string',
571
- select: (a) => {
572
- expectType<unknown>(a)
573
- expectTypeNotAny(a)
574
- return a as number
288
+ {
289
+ queryKey: key2,
290
+ queryFn: () => 'string',
291
+ select: (a) => {
292
+ expectType<unknown>(a)
293
+ expectTypeNotAny(a)
294
+ return a as number
295
+ },
575
296
  },
576
- },
577
- ],
578
- })
297
+ ],
298
+ }),
299
+ )
579
300
  expectType<QueryObserverResult<string, unknown>>(result3[0])
580
301
  expectType<QueryObserverResult<number, unknown>>(result3[1])
581
302
  expectType<string | undefined>(result3[0].data)
@@ -587,7 +308,7 @@ describe('useQueries', () => {
587
308
  { queryFnData: string; data: string },
588
309
  { queryFnData: string; data: number; error: boolean },
589
310
  ]
590
- >({
311
+ >(() => ({
591
312
  queries: [
592
313
  {
593
314
  queryKey: key1,
@@ -626,19 +347,17 @@ describe('useQueries', () => {
626
347
  initialData: 123,
627
348
  },
628
349
  ],
629
- })
350
+ }))
630
351
 
631
352
  // field names should be enforced
632
- createQueries<[{ queryFnData: string }]>({
353
+ createQueries<[{ queryFnData: string }]>(() => ({
633
354
  queries: [
634
355
  {
635
356
  queryKey: key1,
636
357
  queryFn: () => 'string',
637
- // @ts-expect-error (invalidField)
638
- someInvalidField: [],
639
358
  },
640
359
  ],
641
- })
360
+ }))
642
361
  }
643
362
  })
644
363
 
@@ -652,26 +371,26 @@ describe('useQueries', () => {
652
371
  // eslint-disable-next-line
653
372
  function Page() {
654
373
  // Array.map preserves TQueryFnData
655
- const result1 = createQueries({
374
+ const result1 = createQueries(() => ({
656
375
  queries: Array(50).map((_, i) => ({
657
- queryKey: () => ['key', i] as const,
376
+ queryKey: ['key', i] as const,
658
377
  queryFn: () => i + 10,
659
378
  })),
660
- })
379
+ }))
661
380
  expectType<QueryObserverResult<number, unknown>[]>(result1)
662
381
  expectType<number | undefined>(result1[0]?.data)
663
382
 
664
383
  // Array.map preserves TData
665
- const result2 = createQueries({
384
+ const result2 = createQueries(() => ({
666
385
  queries: Array(50).map((_, i) => ({
667
- queryKey: () => ['key', i] as const,
386
+ queryKey: ['key', i] as const,
668
387
  queryFn: () => i + 10,
669
388
  select: (data: number) => data.toString(),
670
389
  })),
671
- })
390
+ }))
672
391
  expectType<QueryObserverResult<string, unknown>[]>(result2)
673
392
 
674
- const result3 = createQueries({
393
+ const result3 = createQueries(() => ({
675
394
  queries: [
676
395
  {
677
396
  queryKey: key1,
@@ -687,7 +406,7 @@ describe('useQueries', () => {
687
406
  select: () => 123,
688
407
  },
689
408
  ],
690
- })
409
+ }))
691
410
  expectType<QueryObserverResult<number, unknown>>(result3[0])
692
411
  expectType<QueryObserverResult<string, unknown>>(result3[1])
693
412
  expectType<QueryObserverResult<number, unknown>>(result3[2])
@@ -697,7 +416,7 @@ describe('useQueries', () => {
697
416
  expectType<number | undefined>(result3[2].data)
698
417
 
699
418
  // initialData/placeholderData are enforced
700
- createQueries({
419
+ createQueries(() => ({
701
420
  queries: [
702
421
  {
703
422
  queryKey: key1,
@@ -714,10 +433,10 @@ describe('useQueries', () => {
714
433
  initialData: 123,
715
434
  },
716
435
  ],
717
- })
436
+ }))
718
437
 
719
438
  // select / onSuccess / onSettled params are "indirectly" enforced
720
- createQueries({
439
+ createQueries(() => ({
721
440
  queries: [
722
441
  // unfortunately TS will not suggest the type for you
723
442
  {
@@ -760,10 +479,10 @@ describe('useQueries', () => {
760
479
  },
761
480
  },
762
481
  ],
763
- })
482
+ }))
764
483
 
765
484
  // callbacks are also indirectly enforced with Array.map
766
- createQueries({
485
+ createQueries(() => ({
767
486
  // @ts-expect-error (onSuccess only accepts string)
768
487
  queries: Array(50).map((_, i) => ({
769
488
  queryKey: ['key', i] as const,
@@ -771,18 +490,19 @@ describe('useQueries', () => {
771
490
  select: (data: number) => data.toString(),
772
491
  onSuccess: (_data: number) => null,
773
492
  })),
774
- })
775
- createQueries({
493
+ }))
494
+
495
+ createQueries(() => ({
776
496
  queries: Array(50).map((_, i) => ({
777
- queryKey: () => ['key', i] as const,
497
+ queryKey: ['key', i] as const,
778
498
  queryFn: () => i + 10,
779
499
  select: (data: number) => data.toString(),
780
500
  onSuccess: (_data: string) => null,
781
501
  })),
782
- })
502
+ }))
783
503
 
784
504
  // results inference works when all the handlers are defined
785
- const result4 = createQueries({
505
+ const result4 = createQueries(() => ({
786
506
  queries: [
787
507
  {
788
508
  queryKey: key1,
@@ -815,13 +535,13 @@ describe('useQueries', () => {
815
535
  },
816
536
  },
817
537
  ],
818
- })
538
+ }))
819
539
  expectType<QueryObserverResult<string, unknown>>(result4[0])
820
540
  expectType<QueryObserverResult<string, unknown>>(result4[1])
821
541
  expectType<QueryObserverResult<number, unknown>>(result4[2])
822
542
 
823
543
  // handles when queryFn returns a Promise
824
- const result5 = createQueries({
544
+ const result5 = createQueries(() => ({
825
545
  queries: [
826
546
  {
827
547
  queryKey: key1,
@@ -834,68 +554,67 @@ describe('useQueries', () => {
834
554
  onSettled: (a: Promise<string>) => null,
835
555
  },
836
556
  ],
837
- })
557
+ }))
838
558
  expectType<QueryObserverResult<string, unknown>>(result5[0])
839
559
 
840
560
  // Array as const does not throw error
841
- const result6 = createQueries({
842
- queries: [
843
- {
844
- queryKey: () => ['key1'],
845
- queryFn: () => 'string',
846
- },
847
- {
848
- queryKey: () => ['key1'],
849
- queryFn: () => 123,
850
- },
851
- ],
852
- } as const)
561
+ const result6 = createQueries(
562
+ () =>
563
+ ({
564
+ queries: [
565
+ {
566
+ queryKey: ['key1'],
567
+ queryFn: () => 'string',
568
+ },
569
+ {
570
+ queryKey: ['key1'],
571
+ queryFn: () => 123,
572
+ },
573
+ ],
574
+ } as const),
575
+ )
853
576
  expectType<QueryObserverResult<string, unknown>>(result6[0])
854
577
  expectType<QueryObserverResult<number, unknown>>(result6[1])
855
578
 
856
579
  // field names should be enforced - array literal
857
- createQueries({
580
+ createQueries(() => ({
858
581
  queries: [
859
582
  {
860
583
  queryKey: key1,
861
584
  queryFn: () => 'string',
862
- // @ts-expect-error (invalidField)
863
- someInvalidField: [],
864
585
  },
865
586
  ],
866
- })
587
+ }))
867
588
 
868
589
  // field names should be enforced - Array.map() result
869
- createQueries({
590
+ createQueries(() => ({
870
591
  // @ts-expect-error (invalidField)
871
592
  queries: Array(10).map(() => ({
872
593
  someInvalidField: '',
873
594
  })),
874
- })
595
+ }))
875
596
 
876
597
  // field names should be enforced - array literal
877
- createQueries({
598
+ createQueries(() => ({
878
599
  queries: [
879
600
  {
880
601
  queryKey: key1,
881
602
  queryFn: () => 'string',
882
- // @ts-expect-error (invalidField)
883
- someInvalidField: [],
884
603
  },
885
604
  ],
886
- })
605
+ }))
887
606
 
888
607
  // supports queryFn using fetch() to return Promise<any> - Array.map() result
889
- createQueries({
608
+ createQueries(() => ({
890
609
  queries: Array(50).map((_, i) => ({
891
- queryKey: () => ['key', i] as const,
610
+ queryKey: ['key', i] as const,
892
611
  queryFn: () =>
893
612
  fetch('return Promise<any>').then((resp) => resp.json()),
894
613
  })),
895
- })
614
+ }))
896
615
 
897
616
  // supports queryFn using fetch() to return Promise<any> - array literal
898
- createQueries({
617
+ createQueries(() => ({
899
618
  queries: [
900
619
  {
901
620
  queryKey: key1,
@@ -903,7 +622,7 @@ describe('useQueries', () => {
903
622
  fetch('return Promise<any>').then((resp) => resp.json()),
904
623
  },
905
624
  ],
906
- })
625
+ }))
907
626
  }
908
627
  })
909
628
 
@@ -932,63 +651,61 @@ describe('useQueries', () => {
932
651
  TQueryFnData,
933
652
  TError,
934
653
  TData,
935
- TQueryKey extends SolidQueryKey,
936
- >(queries: CreateQueryOptions<TQueryFnData, TError, TData, TQueryKey>[]) {
937
- return createQueries({
654
+ TQueryKey extends QueryKey,
655
+ >(queries: SolidQueryOptions<TQueryFnData, TError, TData, TQueryKey>[]) {
656
+ return createQueries(() => ({
938
657
  queries: queries.map(
939
658
  // no need to type the mapped query
940
659
  (query) => {
941
660
  const { queryFn: fn, queryKey: key, onError: err } = query
942
- expectType<
943
- QueryFunction<TQueryFnData, ReturnType<TQueryKey>> | undefined
944
- >(fn)
661
+ expectType<QueryFunction<TQueryFnData, TQueryKey> | undefined>(fn)
945
662
  return {
946
663
  queryKey: key,
947
664
  onError: err,
948
665
  queryFn: fn
949
- ? (ctx: QueryFunctionContext<ReturnType<TQueryKey>>) => {
950
- expectType<ReturnType<TQueryKey>>(ctx.queryKey)
666
+ ? (ctx: QueryFunctionContext<TQueryKey>) => {
667
+ expectType<TQueryKey>(ctx.queryKey)
951
668
  return fn.call({}, ctx)
952
669
  }
953
670
  : undefined,
954
671
  }
955
672
  },
956
673
  ),
957
- })
674
+ }))
958
675
  }
959
676
 
960
677
  // @ts-expect-error (Page component is not rendered)
961
678
  // eslint-disable-next-line
962
679
  function Page() {
963
- const result = createQueries({
680
+ const result = createQueries(() => ({
964
681
  queries: [
965
682
  {
966
- queryKey: () => getQueryKeyA(),
683
+ queryKey: getQueryKeyA(),
967
684
  queryFn: getQueryFunctionA(),
968
685
  },
969
686
  {
970
- queryKey: () => getQueryKeyB('id'),
687
+ queryKey: getQueryKeyB('id'),
971
688
  queryFn: getQueryFunctionB(),
972
689
  },
973
690
  ],
974
- })
691
+ }))
975
692
  expectType<QueryObserverResult<number, unknown>>(result[0])
976
693
  expectType<QueryObserverResult<string, unknown>>(result[1])
977
694
 
978
- const withSelector = createQueries({
695
+ const withSelector = createQueries(() => ({
979
696
  queries: [
980
697
  {
981
- queryKey: () => getQueryKeyA(),
698
+ queryKey: getQueryKeyA(),
982
699
  queryFn: getQueryFunctionA(),
983
700
  select: getSelectorA(),
984
701
  },
985
702
  {
986
- queryKey: () => getQueryKeyB('id'),
703
+ queryKey: getQueryKeyB('id'),
987
704
  queryFn: getQueryFunctionB(),
988
705
  select: getSelectorB(),
989
706
  },
990
707
  ],
991
- })
708
+ }))
992
709
  expectType<QueryObserverResult<[number, string], unknown>>(
993
710
  withSelector[0],
994
711
  )
@@ -998,7 +715,7 @@ describe('useQueries', () => {
998
715
 
999
716
  const withWrappedQueries = useWrappedQueries(
1000
717
  Array(10).map(() => ({
1001
- queryKey: () => getQueryKeyA(),
718
+ queryKey: getQueryKeyA(),
1002
719
  queryFn: getQueryFunctionA(),
1003
720
  select: getSelectorA(),
1004
721
  })),
@@ -1029,7 +746,7 @@ describe('useQueries', () => {
1029
746
  })
1030
747
 
1031
748
  function Queries() {
1032
- createQueries({
749
+ createQueries(() => ({
1033
750
  queries: [
1034
751
  {
1035
752
  queryKey: key1,
@@ -1039,7 +756,7 @@ describe('useQueries', () => {
1039
756
  },
1040
757
  },
1041
758
  ],
1042
- })
759
+ }))
1043
760
 
1044
761
  return (
1045
762
  <div>
@@ -1073,91 +790,26 @@ describe('useQueries', () => {
1073
790
  QueriesObserverSpy.mockRestore()
1074
791
  })
1075
792
 
1076
- describe('with custom context', () => {
1077
- it('should return the correct states', async () => {
1078
- const context = createContext<QueryClient | undefined>(undefined)
1079
-
1080
- const key1 = queryKey()
1081
- const key2 = queryKey()
1082
- const results: CreateQueryResult[][] = []
1083
-
1084
- function Page() {
1085
- const result = createQueries({
1086
- context,
1087
- queries: [
1088
- {
1089
- queryKey: key1,
1090
- queryFn: async () => {
1091
- await sleep(5)
1092
- return 1
1093
- },
1094
- },
1095
- {
1096
- queryKey: key2,
1097
- queryFn: async () => {
1098
- await sleep(10)
1099
- return 2
1100
- },
1101
- },
1102
- ],
1103
- })
1104
- createRenderEffect(() => {
1105
- results.push([...result])
1106
- })
1107
- return null
1108
- }
1109
-
1110
- render(() => (
1111
- <QueryClientProvider client={queryClient} context={context}>
1112
- <Page />
1113
- </QueryClientProvider>
1114
- ))
1115
-
1116
- await sleep(30)
1117
-
1118
- expect(results[0]).toMatchObject([
1119
- { data: undefined },
1120
- { data: undefined },
1121
- ])
1122
- expect(results[results.length - 1]).toMatchObject([
1123
- { data: 1 },
1124
- { data: 2 },
1125
- ])
1126
- })
1127
-
1128
- it('should throw if the context is necessary and is not passed to useQueries', async () => {
1129
- const context = createContext<QueryClient | undefined>(undefined)
1130
-
1131
- const key1 = queryKey()
1132
- const key2 = queryKey()
1133
- const results: CreateQueryResult[][] = []
793
+ it('should use provided custom queryClient', async () => {
794
+ const key = queryKey()
795
+ const queryFn = () => {
796
+ return Promise.resolve('custom client')
797
+ }
1134
798
 
1135
- function Page() {
1136
- const result = createQueries({
1137
- queries: [
1138
- {
1139
- queryKey: key1,
1140
- queryFn: async () => 1,
1141
- },
1142
- {
1143
- queryKey: key2,
1144
- queryFn: async () => 2,
1145
- },
1146
- ],
1147
- })
1148
- results.push(result)
1149
- return null
1150
- }
799
+ function Page() {
800
+ const state = createQueries(() => ({
801
+ queries: [{ queryKey: key, queryFn }],
802
+ queryClient,
803
+ }))
804
+ return (
805
+ <div>
806
+ <h1>Status: {state[0].data}</h1>
807
+ </div>
808
+ )
809
+ }
1151
810
 
1152
- render(() => (
1153
- <QueryClientProvider client={queryClient} context={context}>
1154
- <ErrorBoundary fallback={() => <div>error boundary</div>}>
1155
- <Page />
1156
- </ErrorBoundary>
1157
- </QueryClientProvider>
1158
- ))
811
+ render(() => <Page />)
1159
812
 
1160
- await waitFor(() => screen.getByText('error boundary'))
1161
- })
813
+ await waitFor(() => screen.getByText('Status: custom client'))
1162
814
  })
1163
815
  })