@tanstack/solid-query 4.12.0 → 4.13.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/solid-query",
3
- "version": "4.12.0",
3
+ "version": "4.13.0",
4
4
  "description": "Primitives for managing, caching and syncing asynchronous and remote data in Solid",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -36,7 +36,7 @@
36
36
  "solid-jest": "^0.2.0"
37
37
  },
38
38
  "dependencies": {
39
- "@tanstack/query-core": "4.12.0"
39
+ "@tanstack/query-core": "4.13.0"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "solid-js": "^1.5.7"
@@ -80,6 +80,7 @@ describe('useInfiniteQuery', () => {
80
80
  error: null,
81
81
  errorUpdatedAt: 0,
82
82
  failureCount: 0,
83
+ failureReason: null,
83
84
  errorUpdateCount: 0,
84
85
  fetchNextPage: expect.any(Function),
85
86
  fetchPreviousPage: expect.any(Function),
@@ -113,6 +114,7 @@ describe('useInfiniteQuery', () => {
113
114
  error: null,
114
115
  errorUpdatedAt: 0,
115
116
  failureCount: 0,
117
+ failureReason: null,
116
118
  errorUpdateCount: 0,
117
119
  fetchNextPage: expect.any(Function),
118
120
  fetchPreviousPage: expect.any(Function),
@@ -170,6 +170,64 @@ describe('useMutation', () => {
170
170
  expect(onSettledMock).toHaveBeenCalledWith(3)
171
171
  })
172
172
 
173
+ it('should set correct values for `failureReason` and `failureCount` on multiple mutate calls', async () => {
174
+ const [count, setCount] = createSignal(0)
175
+ type Value = { count: number }
176
+
177
+ const mutateFn = jest.fn<Promise<Value>, [value: Value]>()
178
+
179
+ mutateFn.mockImplementationOnce(() => {
180
+ return Promise.reject('Error test Jonas')
181
+ })
182
+
183
+ mutateFn.mockImplementation(async (value) => {
184
+ await sleep(10)
185
+ return Promise.resolve(value)
186
+ })
187
+
188
+ function Page() {
189
+ const mutation = createMutation<Value, string, Value>(mutateFn)
190
+
191
+ return (
192
+ <div>
193
+ <h1>Data {mutation.data?.count}</h1>
194
+ <h2>Status {mutation.status}</h2>
195
+ <h2>Failed {mutation.failureCount} times</h2>
196
+ <h2>Failed because {mutation.failureReason ?? 'null'}</h2>
197
+ <button
198
+ onClick={() => {
199
+ setCount((c) => c + 1)
200
+ return mutation.mutate({ count: count() })
201
+ }}
202
+ >
203
+ mutate
204
+ </button>
205
+ </div>
206
+ )
207
+ }
208
+
209
+ render(() => (
210
+ <QueryClientProvider client={queryClient}>
211
+ <Page />
212
+ </QueryClientProvider>
213
+ ))
214
+
215
+ await waitFor(() => screen.getByText('Data'))
216
+
217
+ fireEvent.click(screen.getByRole('button', { name: /mutate/i }))
218
+ await waitFor(() => screen.getByText('Data'))
219
+ await waitFor(() => screen.getByText('Status error'))
220
+ await waitFor(() => screen.getByText('Failed 1 times'))
221
+ await waitFor(() => screen.getByText('Failed because Error test Jonas'))
222
+
223
+ fireEvent.click(screen.getByRole('button', { name: /mutate/i }))
224
+ await waitFor(() => screen.getByText('Status loading'))
225
+ await waitFor(() => screen.getByText('Status success'))
226
+ await waitFor(() => screen.getByText('Data 2'))
227
+ await waitFor(() => screen.getByText('Failed 0 times'))
228
+ await waitFor(() => screen.getByText('Failed because null'))
229
+ })
230
+
173
231
  it('should be able to call `onError` and `onSettled` after each failed mutate', async () => {
174
232
  const onErrorMock = jest.fn()
175
233
  const onSettledMock = jest.fn()
@@ -656,21 +714,25 @@ describe('useMutation', () => {
656
714
  isLoading: false,
657
715
  isPaused: false,
658
716
  failureCount: 0,
717
+ failureReason: null,
659
718
  })
660
719
  expect(states[1]).toMatchObject({
661
720
  isLoading: true,
662
721
  isPaused: false,
663
722
  failureCount: 0,
723
+ failureReason: null,
664
724
  })
665
725
  expect(states[2]).toMatchObject({
666
726
  isLoading: true,
667
727
  isPaused: false,
668
728
  failureCount: 1,
729
+ failureReason: 'oops',
669
730
  })
670
731
  expect(states[3]).toMatchObject({
671
732
  isLoading: true,
672
733
  isPaused: true,
673
734
  failureCount: 1,
735
+ failureReason: 'oops',
674
736
  })
675
737
 
676
738
  onlineMock.mockReturnValue(true)
@@ -683,11 +745,13 @@ describe('useMutation', () => {
683
745
  isLoading: true,
684
746
  isPaused: false,
685
747
  failureCount: 1,
748
+ failureReason: 'oops',
686
749
  })
687
750
  expect(states[5]).toMatchObject({
688
751
  isLoading: false,
689
752
  isPaused: false,
690
- failureCount: 1,
753
+ failureCount: 0,
754
+ failureReason: null,
691
755
  data: 'data',
692
756
  })
693
757
 
@@ -266,6 +266,7 @@ describe('createQuery', () => {
266
266
  error: null,
267
267
  errorUpdatedAt: 0,
268
268
  failureCount: 0,
269
+ failureReason: null,
269
270
  errorUpdateCount: 0,
270
271
  isError: false,
271
272
  isFetched: false,
@@ -293,6 +294,7 @@ describe('createQuery', () => {
293
294
  error: null,
294
295
  errorUpdatedAt: 0,
295
296
  failureCount: 0,
297
+ failureReason: null,
296
298
  errorUpdateCount: 0,
297
299
  isError: false,
298
300
  isFetched: true,
@@ -338,6 +340,7 @@ describe('createQuery', () => {
338
340
  <div>
339
341
  <h1>Status: {state.status}</h1>
340
342
  <div>Failure Count: {state.failureCount}</div>
343
+ <div>Failure Reason: {state.failureReason}</div>
341
344
  </div>
342
345
  )
343
346
  }
@@ -356,6 +359,7 @@ describe('createQuery', () => {
356
359
  error: null,
357
360
  errorUpdatedAt: 0,
358
361
  failureCount: 0,
362
+ failureReason: null,
359
363
  errorUpdateCount: 0,
360
364
  isError: false,
361
365
  isFetched: false,
@@ -383,6 +387,7 @@ describe('createQuery', () => {
383
387
  error: null,
384
388
  errorUpdatedAt: 0,
385
389
  failureCount: 1,
390
+ failureReason: 'rejected',
386
391
  errorUpdateCount: 0,
387
392
  isError: false,
388
393
  isFetched: false,
@@ -410,6 +415,7 @@ describe('createQuery', () => {
410
415
  error: 'rejected',
411
416
  errorUpdatedAt: expect.any(Number),
412
417
  failureCount: 2,
418
+ failureReason: 'rejected',
413
419
  errorUpdateCount: 1,
414
420
  isError: true,
415
421
  isFetched: true,
@@ -3238,6 +3244,7 @@ describe('createQuery', () => {
3238
3244
  <div>
3239
3245
  <div>error: {result.error ?? 'null'}</div>
3240
3246
  <div>failureCount: {result.failureCount}</div>
3247
+ <div>failureReason: {result.failureReason}</div>
3241
3248
  </div>
3242
3249
  )
3243
3250
  }
@@ -3262,6 +3269,7 @@ describe('createQuery', () => {
3262
3269
  ))
3263
3270
 
3264
3271
  await waitFor(() => screen.getByText('failureCount: 1'))
3272
+ await waitFor(() => screen.getByText('failureReason: some error'))
3265
3273
  fireEvent.click(screen.getByRole('button', { name: /hide/i }))
3266
3274
  await waitFor(() => screen.getByRole('button', { name: /show/i }))
3267
3275
  fireEvent.click(screen.getByRole('button', { name: /show/i }))
@@ -3292,6 +3300,7 @@ describe('createQuery', () => {
3292
3300
  <div>
3293
3301
  <div>error: {result.error ?? 'null'}</div>
3294
3302
  <div>failureCount: {result.failureCount}</div>
3303
+ <div>failureReason: {result.failureReason}</div>
3295
3304
  </div>
3296
3305
  )
3297
3306
  }
@@ -3321,6 +3330,7 @@ describe('createQuery', () => {
3321
3330
  ))
3322
3331
 
3323
3332
  await waitFor(() => screen.getByText('failureCount: 1'))
3333
+ await waitFor(() => screen.getByText('failureReason: some error'))
3324
3334
  fireEvent.click(screen.getByRole('button', { name: /hide/i }))
3325
3335
  fireEvent.click(screen.getByRole('button', { name: /cancel/i }))
3326
3336
  await waitFor(() => screen.getByRole('button', { name: /show/i }))
@@ -3584,7 +3594,7 @@ describe('createQuery', () => {
3584
3594
  })
3585
3595
 
3586
3596
  function Page() {
3587
- const state = createQuery(key, queryFn, {
3597
+ const state = createQuery<unknown, string>(key, queryFn, {
3588
3598
  retry: 1,
3589
3599
  retryDelay: 1,
3590
3600
  })
@@ -3593,6 +3603,7 @@ describe('createQuery', () => {
3593
3603
  <div>
3594
3604
  <h1>{state.status}</h1>
3595
3605
  <h2>Failed {state.failureCount} times</h2>
3606
+ <h2>Failed because {state.failureReason}</h2>
3596
3607
  </div>
3597
3608
  )
3598
3609
  }
@@ -3608,6 +3619,7 @@ describe('createQuery', () => {
3608
3619
 
3609
3620
  // query should fail `retry + 1` times, since first time isn't a "retry"
3610
3621
  await waitFor(() => screen.getByText('Failed 2 times'))
3622
+ await waitFor(() => screen.getByText('Failed because Error test Barrett'))
3611
3623
 
3612
3624
  expect(queryFn).toHaveBeenCalledTimes(2)
3613
3625
  })
@@ -3635,6 +3647,7 @@ describe('createQuery', () => {
3635
3647
  <div>
3636
3648
  <h1>{state.status}</h1>
3637
3649
  <h2>Failed {state.failureCount} times</h2>
3650
+ <h2>Failed because {state.failureReason}</h2>
3638
3651
  <h2>{state.error}</h2>
3639
3652
  </div>
3640
3653
  )
@@ -3648,8 +3661,8 @@ describe('createQuery', () => {
3648
3661
 
3649
3662
  await waitFor(() => screen.getByText('loading'))
3650
3663
  await waitFor(() => screen.getByText('error'))
3651
-
3652
3664
  await waitFor(() => screen.getByText('Failed 2 times'))
3665
+ await waitFor(() => screen.getByText('Failed because NoRetry'))
3653
3666
  await waitFor(() => screen.getByText('NoRetry'))
3654
3667
 
3655
3668
  expect(queryFn).toHaveBeenCalledTimes(2)
@@ -3666,7 +3679,7 @@ describe('createQuery', () => {
3666
3679
  })
3667
3680
 
3668
3681
  function Page() {
3669
- const state = createQuery(key, queryFn, {
3682
+ const state = createQuery<unknown, DelayError>(key, queryFn, {
3670
3683
  retry: 1,
3671
3684
  retryDelay: (_, error: DelayError) => error.delay,
3672
3685
  })
@@ -3675,6 +3688,7 @@ describe('createQuery', () => {
3675
3688
  <div>
3676
3689
  <h1>{state.status}</h1>
3677
3690
  <h2>Failed {state.failureCount} times</h2>
3691
+ <h2>Failed because DelayError: {state.failureReason?.delay}ms</h2>
3678
3692
  </div>
3679
3693
  )
3680
3694
  }
@@ -3689,6 +3703,7 @@ describe('createQuery', () => {
3689
3703
 
3690
3704
  expect(queryFn).toHaveBeenCalledTimes(1)
3691
3705
 
3706
+ await waitFor(() => screen.getByText('Failed because DelayError: 50ms'))
3692
3707
  await waitFor(() => screen.getByText('Failed 2 times'))
3693
3708
 
3694
3709
  expect(queryFn).toHaveBeenCalledTimes(2)
@@ -3704,7 +3719,7 @@ describe('createQuery', () => {
3704
3719
  let count = 0
3705
3720
 
3706
3721
  function Page() {
3707
- const query = createQuery(
3722
+ const query = createQuery<unknown, string>(
3708
3723
  key,
3709
3724
  () => {
3710
3725
  count++
@@ -3721,6 +3736,7 @@ describe('createQuery', () => {
3721
3736
  <div>error {String(query.error)}</div>
3722
3737
  <div>status {query.status}</div>
3723
3738
  <div>failureCount {query.failureCount}</div>
3739
+ <div>failureReason {query.failureReason}</div>
3724
3740
  </div>
3725
3741
  )
3726
3742
  }
@@ -3733,24 +3749,28 @@ describe('createQuery', () => {
3733
3749
 
3734
3750
  // The query should display the first error result
3735
3751
  await waitFor(() => screen.getByText('failureCount 1'))
3752
+ await waitFor(() => screen.getByText('failureReason fetching error 1'))
3736
3753
  await waitFor(() => screen.getByText('status loading'))
3737
3754
  await waitFor(() => screen.getByText('error null'))
3738
3755
 
3739
3756
  // Check if the query really paused
3740
3757
  await sleep(10)
3741
3758
  await waitFor(() => screen.getByText('failureCount 1'))
3759
+ await waitFor(() => screen.getByText('failureReason fetching error 1'))
3742
3760
 
3743
3761
  visibilityMock.mockRestore()
3744
3762
  window.dispatchEvent(new FocusEvent('focus'))
3745
3763
 
3746
3764
  // Wait for the final result
3747
3765
  await waitFor(() => screen.getByText('failureCount 4'))
3766
+ await waitFor(() => screen.getByText('failureReason fetching error 4'))
3748
3767
  await waitFor(() => screen.getByText('status error'))
3749
3768
  await waitFor(() => screen.getByText('error fetching error 4'))
3750
3769
 
3751
3770
  // Check if the query really stopped
3752
3771
  await sleep(10)
3753
3772
  await waitFor(() => screen.getByText('failureCount 4'))
3773
+ await waitFor(() => screen.getByText('failureReason fetching error 4'))
3754
3774
 
3755
3775
  // Check if the error has been logged in the console
3756
3776
  expect(mockLogger.error).toHaveBeenCalledWith('fetching error 4')
@@ -3931,13 +3951,13 @@ describe('createQuery', () => {
3931
3951
  })
3932
3952
 
3933
3953
  // See https://github.com/tannerlinsley/react-query/issues/190
3934
- it('should reset failureCount on successful fetch', async () => {
3954
+ it('should reset failureCount and failureReason on successful fetch', async () => {
3935
3955
  const key = queryKey()
3936
3956
 
3937
3957
  function Page() {
3938
3958
  let counter = 0
3939
3959
 
3940
- const query = createQuery(
3960
+ const query = createQuery<unknown, Error>(
3941
3961
  key,
3942
3962
  async () => {
3943
3963
  if (counter < 2) {
@@ -3953,6 +3973,7 @@ describe('createQuery', () => {
3953
3973
  return (
3954
3974
  <div>
3955
3975
  <div>failureCount {query.failureCount}</div>
3976
+ <div>failureReason {query.failureReason?.message ?? 'null'}</div>
3956
3977
  </div>
3957
3978
  )
3958
3979
  }
@@ -3964,7 +3985,9 @@ describe('createQuery', () => {
3964
3985
  ))
3965
3986
 
3966
3987
  await waitFor(() => screen.getByText('failureCount 2'))
3988
+ await waitFor(() => screen.getByText('failureReason error'))
3967
3989
  await waitFor(() => screen.getByText('failureCount 0'))
3990
+ await waitFor(() => screen.getByText('failureReason null'))
3968
3991
  })
3969
3992
 
3970
3993
  // See https://github.com/tannerlinsley/react-query/issues/199
@@ -5553,7 +5576,7 @@ describe('createQuery', () => {
5553
5576
  let count = 0
5554
5577
 
5555
5578
  function Page() {
5556
- const state = createQuery({
5579
+ const state = createQuery<unknown, string, string>({
5557
5580
  queryKey: key,
5558
5581
  queryFn: async () => {
5559
5582
  count++
@@ -5568,6 +5591,7 @@ describe('createQuery', () => {
5568
5591
  status: {state.status}, fetchStatus: {state.fetchStatus},
5569
5592
  failureCount: {state.failureCount}
5570
5593
  </div>
5594
+ <div>failureReason: {state.failureReason ?? 'null'}</div>
5571
5595
  <div>data: {state.data}</div>
5572
5596
  <button
5573
5597
  onClick={() => queryClient.invalidateQueries({ queryKey: key() })}
@@ -5594,6 +5618,7 @@ describe('createQuery', () => {
5594
5618
  'status: success, fetchStatus: paused, failureCount: 0',
5595
5619
  ),
5596
5620
  )
5621
+ await waitFor(() => screen.getByText('failureReason: null'))
5597
5622
 
5598
5623
  onlineMock.mockReturnValue(true)
5599
5624
  window.dispatchEvent(new Event('online'))
@@ -5603,9 +5628,11 @@ describe('createQuery', () => {
5603
5628
  'status: success, fetchStatus: fetching, failureCount: 0',
5604
5629
  ),
5605
5630
  )
5631
+ await waitFor(() => screen.getByText('failureReason: null'))
5606
5632
  await waitFor(() =>
5607
5633
  screen.getByText('status: success, fetchStatus: idle, failureCount: 0'),
5608
5634
  )
5635
+ await waitFor(() => screen.getByText('failureReason: null'))
5609
5636
 
5610
5637
  await waitFor(() => {
5611
5638
  expect(screen.getByText('data: data2')).toBeInTheDocument()
@@ -5856,7 +5883,7 @@ describe('createQuery', () => {
5856
5883
  let count = 0
5857
5884
 
5858
5885
  function Page() {
5859
- const state = createQuery({
5886
+ const state = createQuery<unknown, Error>({
5860
5887
  queryKey: key,
5861
5888
  queryFn: async (): Promise<unknown> => {
5862
5889
  count++
@@ -5873,6 +5900,7 @@ describe('createQuery', () => {
5873
5900
  status: {state.status}, fetchStatus: {state.fetchStatus},
5874
5901
  failureCount: {state.failureCount}
5875
5902
  </div>
5903
+ <div>failureReason: {state.failureReason?.message ?? 'null'}</div>
5876
5904
  </div>
5877
5905
  )
5878
5906
  }
@@ -5888,6 +5916,7 @@ describe('createQuery', () => {
5888
5916
  'status: loading, fetchStatus: fetching, failureCount: 1',
5889
5917
  ),
5890
5918
  )
5919
+ await waitFor(() => screen.getByText('failureReason: failed1'))
5891
5920
 
5892
5921
  const onlineMock = mockNavigatorOnLine(false)
5893
5922
 
@@ -5898,6 +5927,7 @@ describe('createQuery', () => {
5898
5927
  'status: loading, fetchStatus: paused, failureCount: 1',
5899
5928
  ),
5900
5929
  )
5930
+ await waitFor(() => screen.getByText('failureReason: failed1'))
5901
5931
 
5902
5932
  expect(count).toBe(1)
5903
5933
 
@@ -5907,6 +5937,7 @@ describe('createQuery', () => {
5907
5937
  await waitFor(() =>
5908
5938
  screen.getByText('status: error, fetchStatus: idle, failureCount: 3'),
5909
5939
  )
5940
+ await waitFor(() => screen.getByText('failureReason: failed3'))
5910
5941
 
5911
5942
  expect(count).toBe(3)
5912
5943
 
@@ -6219,7 +6250,7 @@ describe('createQuery', () => {
6219
6250
  let count = 0
6220
6251
 
6221
6252
  function Page() {
6222
- const state = createQuery({
6253
+ const state = createQuery<unknown, Error>({
6223
6254
  queryKey: key,
6224
6255
  queryFn: async (): Promise<unknown> => {
6225
6256
  count++
@@ -6237,6 +6268,7 @@ describe('createQuery', () => {
6237
6268
  status: {state.status}, fetchStatus: {state.fetchStatus},
6238
6269
  failureCount: {state.failureCount}
6239
6270
  </div>
6271
+ <div>failureReason: {state.failureReason?.message ?? 'null'}</div>
6240
6272
  </div>
6241
6273
  )
6242
6274
  }
@@ -6252,6 +6284,7 @@ describe('createQuery', () => {
6252
6284
  'status: loading, fetchStatus: paused, failureCount: 1',
6253
6285
  ),
6254
6286
  )
6287
+ await waitFor(() => screen.getByText('failureReason: failed1'))
6255
6288
 
6256
6289
  expect(count).toBe(1)
6257
6290
 
@@ -6261,6 +6294,7 @@ describe('createQuery', () => {
6261
6294
  await waitFor(() =>
6262
6295
  screen.getByText('status: error, fetchStatus: idle, failureCount: 3'),
6263
6296
  )
6297
+ await waitFor(() => screen.getByText('failureReason: failed3'))
6264
6298
 
6265
6299
  expect(count).toBe(3)
6266
6300