@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
@@ -1,15 +1,17 @@
1
1
  import '@testing-library/jest-dom';
2
- import { createContext, createEffect, createRenderEffect, createSignal, ErrorBoundary, } from 'solid-js';
2
+ import { createEffect, createRenderEffect, createSignal, ErrorBoundary, } from 'solid-js';
3
3
  import { fireEvent, render, screen, waitFor } from 'solid-testing-library';
4
4
  import { createMutation, MutationCache, QueryCache, QueryClientProvider, } from '..';
5
5
  import { createQueryClient, mockNavigatorOnLine, queryKey, setActTimeout, sleep, } from './utils';
6
- describe('useMutation', () => {
6
+ describe('createMutation', () => {
7
7
  const queryCache = new QueryCache();
8
8
  const mutationCache = new MutationCache();
9
9
  const queryClient = createQueryClient({ queryCache, mutationCache });
10
10
  it('should be able to reset `data`', async () => {
11
11
  function Page() {
12
- const mutation = createMutation(() => Promise.resolve('mutation'));
12
+ const mutation = createMutation(() => ({
13
+ mutationFn: () => Promise.resolve('mutation'),
14
+ }));
13
15
  return (<div>
14
16
  <h1>{mutation.data ?? 'empty'}</h1>
15
17
  <button onClick={() => mutation.reset()}>reset</button>
@@ -31,11 +33,13 @@ describe('useMutation', () => {
31
33
  });
32
34
  it('should be able to reset `error`', async () => {
33
35
  function Page() {
34
- const mutation = createMutation(() => {
35
- const err = new Error('Expected mock error. All is well!');
36
- err.stack = '';
37
- return Promise.reject(err);
38
- });
36
+ const mutation = createMutation(() => ({
37
+ mutationFn: () => {
38
+ const err = new Error('Expected mock error. All is well!');
39
+ err.stack = '';
40
+ return Promise.reject(err);
41
+ },
42
+ }));
39
43
  return (<div>
40
44
  {mutation.error && <h1>{mutation.error.message}</h1>}
41
45
  <button onClick={() => mutation.reset()}>reset</button>
@@ -62,14 +66,15 @@ describe('useMutation', () => {
62
66
  const onSuccessMock = jest.fn();
63
67
  const onSettledMock = jest.fn();
64
68
  function Page() {
65
- const mutation = createMutation((vars) => Promise.resolve(vars.count), {
69
+ const mutation = createMutation(() => ({
70
+ mutationFn: (vars) => Promise.resolve(vars.count),
66
71
  onSuccess: (data) => {
67
72
  onSuccessMock(data);
68
73
  },
69
74
  onSettled: (data) => {
70
75
  onSettledMock(data);
71
76
  },
72
- });
77
+ }));
73
78
  return (<div>
74
79
  <h1>{count()}</h1>
75
80
  <button onClick={() => {
@@ -107,19 +112,21 @@ describe('useMutation', () => {
107
112
  const [count, setCount] = createSignal(0);
108
113
  const mutateFn = jest.fn();
109
114
  mutateFn.mockImplementationOnce(() => {
110
- return Promise.reject('Error test Jonas');
115
+ return Promise.reject(new Error('Error test Jonas'));
111
116
  });
112
117
  mutateFn.mockImplementation(async (value) => {
113
118
  await sleep(10);
114
119
  return Promise.resolve(value);
115
120
  });
116
121
  function Page() {
117
- const mutation = createMutation(mutateFn);
122
+ const mutation = createMutation(() => ({
123
+ mutationFn: mutateFn,
124
+ }));
118
125
  return (<div>
119
126
  <h1>Data {mutation.data?.count}</h1>
120
127
  <h2>Status {mutation.status}</h2>
121
128
  <h2>Failed {mutation.failureCount} times</h2>
122
- <h2>Failed because {mutation.failureReason ?? 'null'}</h2>
129
+ <h2>Failed because {mutation.failureReason?.message ?? 'null'}</h2>
123
130
  <button onClick={() => {
124
131
  setCount((c) => c + 1);
125
132
  return mutation.mutate({ count: count() });
@@ -138,7 +145,7 @@ describe('useMutation', () => {
138
145
  await waitFor(() => screen.getByText('Failed 1 times'));
139
146
  await waitFor(() => screen.getByText('Failed because Error test Jonas'));
140
147
  fireEvent.click(screen.getByRole('button', { name: /mutate/i }));
141
- await waitFor(() => screen.getByText('Status loading'));
148
+ await waitFor(() => screen.getByText('Status pending'));
142
149
  await waitFor(() => screen.getByText('Status success'));
143
150
  await waitFor(() => screen.getByText('Data 2'));
144
151
  await waitFor(() => screen.getByText('Failed 0 times'));
@@ -149,18 +156,19 @@ describe('useMutation', () => {
149
156
  const onSettledMock = jest.fn();
150
157
  const [count, setCount] = createSignal(0);
151
158
  function Page() {
152
- const mutation = createMutation((vars) => {
153
- const error = new Error(`Expected mock error. All is well! ${vars.count}`);
154
- error.stack = '';
155
- return Promise.reject(error);
156
- }, {
159
+ const mutation = createMutation(() => ({
160
+ mutationFn: (vars) => {
161
+ const error = new Error(`Expected mock error. All is well! ${vars.count}`);
162
+ error.stack = '';
163
+ return Promise.reject(error);
164
+ },
157
165
  onError: (error) => {
158
166
  onErrorMock(error.message);
159
167
  },
160
168
  onSettled: (_data, error) => {
161
169
  onSettledMock(error?.message);
162
170
  },
163
- });
171
+ }));
164
172
  return (<div>
165
173
  <h1>{count()}</h1>
166
174
  <button onClick={() => {
@@ -197,14 +205,15 @@ describe('useMutation', () => {
197
205
  it('should be able to override the useMutation success callbacks', async () => {
198
206
  const callbacks = [];
199
207
  function Page() {
200
- const mutation = createMutation(async (text) => text, {
208
+ const mutation = createMutation(() => ({
209
+ mutationFn: async (text) => text,
201
210
  onSuccess: async () => {
202
211
  callbacks.push('useMutation.onSuccess');
203
212
  },
204
213
  onSettled: async () => {
205
214
  callbacks.push('useMutation.onSettled');
206
215
  },
207
- });
216
+ }));
208
217
  createEffect(() => {
209
218
  const { mutateAsync } = mutation;
210
219
  setActTimeout(async () => {
@@ -239,14 +248,15 @@ describe('useMutation', () => {
239
248
  it('should be able to override the error callbacks when using mutateAsync', async () => {
240
249
  const callbacks = [];
241
250
  function Page() {
242
- const mutation = createMutation(async (_text) => Promise.reject('oops'), {
251
+ const mutation = createMutation(() => ({
252
+ mutationFn: async (_text) => Promise.reject(new Error('oops')),
243
253
  onError: async () => {
244
254
  callbacks.push('useMutation.onError');
245
255
  },
246
256
  onSettled: async () => {
247
257
  callbacks.push('useMutation.onSettled');
248
258
  },
249
- });
259
+ }));
250
260
  createEffect(() => {
251
261
  const { mutateAsync } = mutation;
252
262
  setActTimeout(async () => {
@@ -261,7 +271,7 @@ describe('useMutation', () => {
261
271
  });
262
272
  }
263
273
  catch (error) {
264
- callbacks.push(`mutateAsync.error:${error}`);
274
+ callbacks.push(`mutateAsync.error:${error.message}`);
265
275
  }
266
276
  }, 10);
267
277
  });
@@ -281,7 +291,7 @@ describe('useMutation', () => {
281
291
  });
282
292
  it('should be able to use mutation defaults', async () => {
283
293
  const key = queryKey();
284
- queryClient.setMutationDefaults(key(), {
294
+ queryClient.setMutationDefaults(key, {
285
295
  mutationFn: async (text) => {
286
296
  await sleep(10);
287
297
  return text;
@@ -289,7 +299,9 @@ describe('useMutation', () => {
289
299
  });
290
300
  const states = [];
291
301
  function Page() {
292
- const mutation = createMutation(key());
302
+ const mutation = createMutation(() => ({
303
+ mutationKey: key,
304
+ }));
293
305
  createRenderEffect(() => {
294
306
  states.push({ ...mutation });
295
307
  });
@@ -306,20 +318,21 @@ describe('useMutation', () => {
306
318
  </QueryClientProvider>));
307
319
  await sleep(100);
308
320
  expect(states.length).toBe(3);
309
- expect(states[0]).toMatchObject({ data: undefined, isLoading: false });
310
- expect(states[1]).toMatchObject({ data: undefined, isLoading: true });
311
- expect(states[2]).toMatchObject({ data: 'todo', isLoading: false });
321
+ expect(states[0]).toMatchObject({ data: undefined, isPending: false });
322
+ expect(states[1]).toMatchObject({ data: undefined, isPending: true });
323
+ expect(states[2]).toMatchObject({ data: 'todo', isPending: false });
312
324
  });
313
325
  it('should be able to retry a failed mutation', async () => {
314
326
  let count = 0;
315
327
  function Page() {
316
- const mutation = createMutation((_text) => {
317
- count++;
318
- return Promise.reject('oops');
319
- }, {
328
+ const mutation = createMutation(() => ({
329
+ mutationFn: (_text) => {
330
+ count++;
331
+ return Promise.reject(new Error('oops'));
332
+ },
320
333
  retry: 1,
321
334
  retryDelay: 5,
322
- });
335
+ }));
323
336
  createEffect(() => {
324
337
  const { mutate } = mutation;
325
338
  setActTimeout(() => {
@@ -338,13 +351,14 @@ describe('useMutation', () => {
338
351
  const onlineMock = mockNavigatorOnLine(false);
339
352
  let count = 0;
340
353
  function Page() {
341
- const mutation = createMutation((_text) => {
342
- count++;
343
- return Promise.reject(new Error('oops'));
344
- }, {
354
+ const mutation = createMutation(() => ({
355
+ mutationFn: (_text) => {
356
+ count++;
357
+ return Promise.reject(new Error('oops'));
358
+ },
345
359
  retry: 1,
346
360
  retryDelay: 5,
347
- });
361
+ }));
348
362
  return (<div>
349
363
  <button onClick={() => mutation.mutate('todo')}>mutate</button>
350
364
  <div>
@@ -360,7 +374,7 @@ describe('useMutation', () => {
360
374
  });
361
375
  fireEvent.click(screen.getByRole('button', { name: /mutate/i }));
362
376
  await waitFor(() => {
363
- expect(screen.getByText('error: null, status: loading, isPaused: true')).toBeInTheDocument();
377
+ expect(screen.getByText('error: null, status: pending, isPaused: true')).toBeInTheDocument();
364
378
  });
365
379
  expect(count).toBe(0);
366
380
  onlineMock.mockReturnValue(true);
@@ -377,13 +391,14 @@ describe('useMutation', () => {
377
391
  const onMutate = jest.fn();
378
392
  let count = 0;
379
393
  function Page() {
380
- const mutation = createMutation(async (_text) => {
381
- count++;
382
- await sleep(10);
383
- return count;
384
- }, {
394
+ const mutation = createMutation(() => ({
395
+ mutationFn: async (_text) => {
396
+ count++;
397
+ await sleep(10);
398
+ return count;
399
+ },
385
400
  onMutate,
386
- });
401
+ }));
387
402
  return (<div>
388
403
  <button onClick={() => mutation.mutate('todo')}>mutate</button>
389
404
  <div>
@@ -397,7 +412,7 @@ describe('useMutation', () => {
397
412
  </QueryClientProvider>));
398
413
  await screen.findByText('data: null, status: idle, isPaused: false');
399
414
  fireEvent.click(screen.getByRole('button', { name: /mutate/i }));
400
- await screen.findByText('data: null, status: loading, isPaused: true');
415
+ await screen.findByText('data: null, status: pending, isPaused: true');
401
416
  expect(onMutate).toHaveBeenCalledTimes(1);
402
417
  expect(onMutate).toHaveBeenCalledWith('todo');
403
418
  onlineMock.mockReturnValue(true);
@@ -412,11 +427,13 @@ describe('useMutation', () => {
412
427
  let count = 0;
413
428
  const states = [];
414
429
  function Page() {
415
- const mutation = createMutation(async (_text) => {
416
- count++;
417
- await sleep(10);
418
- return count;
419
- });
430
+ const mutation = createMutation(() => ({
431
+ mutationFn: async (_text) => {
432
+ count++;
433
+ await sleep(10);
434
+ return count;
435
+ },
436
+ }));
420
437
  createRenderEffect(() => {
421
438
  states.push(`${mutation.status}, ${mutation.isPaused}`);
422
439
  });
@@ -433,10 +450,10 @@ describe('useMutation', () => {
433
450
  </QueryClientProvider>));
434
451
  await screen.findByText('data: null, status: idle, isPaused: false');
435
452
  fireEvent.click(screen.getByRole('button', { name: /mutate/i }));
436
- await screen.findByText('data: null, status: loading, isPaused: true');
437
- // no intermediate 'loading, false' state is expected because we don't start mutating!
453
+ await screen.findByText('data: null, status: pending, isPaused: true');
454
+ // no intermediate 'pending, false' state is expected because we don't start mutating!
438
455
  expect(states[0]).toBe('idle, false');
439
- expect(states[1]).toBe('loading, true');
456
+ expect(states[1]).toBe('pending, true');
440
457
  onlineMock.mockReturnValue(true);
441
458
  window.dispatchEvent(new Event('online'));
442
459
  await screen.findByText('data: 1, status: success, isPaused: false');
@@ -447,15 +464,18 @@ describe('useMutation', () => {
447
464
  let count = 0;
448
465
  const states = [];
449
466
  function Page() {
450
- const mutation = createMutation(async (_text) => {
451
- await sleep(1);
452
- count++;
453
- return count > 1 ? Promise.resolve('data') : Promise.reject('oops');
454
- }, {
467
+ const mutation = createMutation(() => ({
468
+ mutationFn: async (_text) => {
469
+ await sleep(1);
470
+ count++;
471
+ return count > 1
472
+ ? Promise.resolve('data')
473
+ : Promise.reject(new Error('oops'));
474
+ },
455
475
  retry: 1,
456
476
  retryDelay: 5,
457
477
  networkMode: 'offlineFirst',
458
- });
478
+ }));
459
479
  createRenderEffect(() => {
460
480
  states.push({ ...mutation });
461
481
  });
@@ -473,41 +493,41 @@ describe('useMutation', () => {
473
493
  await sleep(50);
474
494
  expect(states.length).toBe(4);
475
495
  expect(states[0]).toMatchObject({
476
- isLoading: false,
496
+ isPending: false,
477
497
  isPaused: false,
478
498
  failureCount: 0,
479
499
  failureReason: null,
480
500
  });
481
501
  expect(states[1]).toMatchObject({
482
- isLoading: true,
502
+ isPending: true,
483
503
  isPaused: false,
484
504
  failureCount: 0,
485
505
  failureReason: null,
486
506
  });
487
507
  expect(states[2]).toMatchObject({
488
- isLoading: true,
508
+ isPending: true,
489
509
  isPaused: false,
490
510
  failureCount: 1,
491
- failureReason: 'oops',
511
+ failureReason: new Error('oops'),
492
512
  });
493
513
  expect(states[3]).toMatchObject({
494
- isLoading: true,
514
+ isPending: true,
495
515
  isPaused: true,
496
516
  failureCount: 1,
497
- failureReason: 'oops',
517
+ failureReason: new Error('oops'),
498
518
  });
499
519
  onlineMock.mockReturnValue(true);
500
520
  window.dispatchEvent(new Event('online'));
501
521
  await sleep(50);
502
522
  expect(states.length).toBe(6);
503
523
  expect(states[4]).toMatchObject({
504
- isLoading: true,
524
+ isPending: true,
505
525
  isPaused: false,
506
526
  failureCount: 1,
507
- failureReason: 'oops',
527
+ failureReason: new Error('oops'),
508
528
  });
509
529
  expect(states[5]).toMatchObject({
510
- isLoading: false,
530
+ isPending: false,
511
531
  isPaused: false,
512
532
  failureCount: 0,
513
533
  failureReason: null,
@@ -517,7 +537,7 @@ describe('useMutation', () => {
517
537
  });
518
538
  it('should not change state if unmounted', async () => {
519
539
  function Mutates() {
520
- const mutation = createMutation(() => sleep(10));
540
+ const mutation = createMutation(() => ({ mutationFn: () => sleep(10) }));
521
541
  return <button onClick={() => mutation.mutate()}>mutate</button>;
522
542
  }
523
543
  function Page() {
@@ -533,13 +553,16 @@ describe('useMutation', () => {
533
553
  fireEvent.click(screen.getByText('mutate'));
534
554
  fireEvent.click(screen.getByText('unmount'));
535
555
  });
536
- it('should be able to throw an error when useErrorBoundary is set to true', async () => {
556
+ it('should be able to throw an error when throwErrors is set to true', async () => {
537
557
  function Page() {
538
- const mutation = createMutation(() => {
539
- const err = new Error('Expected mock error. All is well!');
540
- err.stack = '';
541
- return Promise.reject(err);
542
- }, { useErrorBoundary: true });
558
+ const mutation = createMutation(() => ({
559
+ mutationFn: () => {
560
+ const err = new Error('Expected mock error. All is well!');
561
+ err.stack = '';
562
+ return Promise.reject(err);
563
+ },
564
+ throwErrors: true,
565
+ }));
543
566
  return (<div>
544
567
  <button onClick={() => mutation.mutate()}>mutate</button>
545
568
  </div>);
@@ -556,19 +579,20 @@ describe('useMutation', () => {
556
579
  expect(screen.queryByText('error')).not.toBeNull();
557
580
  });
558
581
  });
559
- it('should be able to throw an error when useErrorBoundary is a function that returns true', async () => {
582
+ it('should be able to throw an error when throwErrors is a function that returns true', async () => {
560
583
  let boundary = false;
561
584
  function Page() {
562
- const mutation = createMutation(() => {
563
- const err = new Error('mock error');
564
- err.stack = '';
565
- return Promise.reject(err);
566
- }, {
567
- useErrorBoundary: () => {
585
+ const mutation = createMutation(() => ({
586
+ mutationFn: () => {
587
+ const err = new Error('mock error');
588
+ err.stack = '';
589
+ return Promise.reject(err);
590
+ },
591
+ throwErrors: () => {
568
592
  boundary = !boundary;
569
593
  return !boundary;
570
594
  },
571
- });
595
+ }));
572
596
  return (<div>
573
597
  <button onClick={() => mutation.mutate()}>mutate</button>
574
598
  {mutation.error && mutation.error.message}
@@ -608,14 +632,16 @@ describe('useMutation', () => {
608
632
  const metaSuccessMessage = 'mutation succeeded';
609
633
  const metaErrorMessage = 'mutation failed';
610
634
  function Page() {
611
- const mutationSucceed = createMutation(async () => '', {
635
+ const mutationSucceed = createMutation(() => ({
636
+ mutationFn: async () => '',
612
637
  meta: { metaSuccessMessage },
613
- });
614
- const mutationError = createMutation(async () => {
615
- throw new Error('');
616
- }, {
638
+ }));
639
+ const mutationError = createMutation(() => ({
640
+ mutationFn: async () => {
641
+ throw new Error('');
642
+ },
617
643
  meta: { metaErrorMessage },
618
- });
644
+ }));
619
645
  return (<div>
620
646
  <button onClick={() => mutationSucceed.mutate()}>succeed</button>
621
647
  <button onClick={() => mutationError.mutate()}>error</button>
@@ -652,16 +678,17 @@ describe('useMutation', () => {
652
678
  </div>);
653
679
  }
654
680
  function Component() {
655
- const mutation = createMutation(async (_text) => {
656
- count++;
657
- await sleep(10);
658
- return count;
659
- }, {
660
- mutationKey: mutationKey(),
661
- cacheTime: 0,
681
+ const mutation = createMutation(() => ({
682
+ mutationFn: async (_text) => {
683
+ count++;
684
+ await sleep(10);
685
+ return count;
686
+ },
687
+ mutationKey: mutationKey,
688
+ gcTime: 0,
662
689
  onSuccess,
663
690
  onSettled,
664
- });
691
+ }));
665
692
  return (<div>
666
693
  <button onClick={() => mutation.mutate('todo', {
667
694
  onSuccess: onSuccessMutate,
@@ -682,7 +709,7 @@ describe('useMutation', () => {
682
709
  fireEvent.click(screen.getByRole('button', { name: /mutate/i }));
683
710
  fireEvent.click(screen.getByRole('button', { name: /hide/i }));
684
711
  await waitFor(() => {
685
- expect(queryClient.getMutationCache().findAll({ mutationKey: mutationKey() })).toHaveLength(0);
712
+ expect(queryClient.getMutationCache().findAll({ mutationKey: mutationKey })).toHaveLength(0);
686
713
  });
687
714
  expect(count).toBe(1);
688
715
  expect(onSuccess).toHaveBeenCalledTimes(1);
@@ -690,49 +717,6 @@ describe('useMutation', () => {
690
717
  expect(onSuccessMutate).toHaveBeenCalledTimes(0);
691
718
  expect(onSettledMutate).toHaveBeenCalledTimes(0);
692
719
  });
693
- describe('with custom context', () => {
694
- it('should be able to reset `data`', async () => {
695
- const context = createContext(undefined);
696
- function Page() {
697
- const mutation = createMutation(() => Promise.resolve('mutation'), {
698
- context,
699
- });
700
- return (<div>
701
- <h1>{mutation.data ?? 'empty'}</h1>
702
- <button onClick={() => mutation.reset()}>reset</button>
703
- <button onClick={() => mutation.mutate()}>mutate</button>
704
- </div>);
705
- }
706
- render(() => (<QueryClientProvider client={queryClient} context={context}>
707
- <Page />
708
- </QueryClientProvider>));
709
- expect(screen.getByRole('heading').textContent).toBe('empty');
710
- fireEvent.click(screen.getByRole('button', { name: /mutate/i }));
711
- await waitFor(() => {
712
- expect(screen.getByRole('heading').textContent).toBe('mutation');
713
- });
714
- fireEvent.click(screen.getByRole('button', { name: /reset/i }));
715
- await waitFor(() => {
716
- expect(screen.getByRole('heading').textContent).toBe('empty');
717
- });
718
- });
719
- it('should throw if the context is not passed to useMutation', async () => {
720
- const context = createContext(undefined);
721
- function Page() {
722
- const { data = '' } = createMutation(() => Promise.resolve('mutation'));
723
- return (<div>
724
- <h1 data-testid="title">{data}</h1>
725
- </div>);
726
- }
727
- render(() => (<QueryClientProvider client={queryClient} context={context}>
728
- <ErrorBoundary fallback={() => <div>error boundary</div>}>
729
- <Page />
730
- </ErrorBoundary>
731
- ,
732
- </QueryClientProvider>));
733
- await waitFor(() => screen.getByText('error boundary'));
734
- });
735
- });
736
720
  it('should call mutate callbacks only for the last observer', async () => {
737
721
  const onSuccess = jest.fn();
738
722
  const onSuccessMutate = jest.fn();
@@ -740,14 +724,15 @@ describe('useMutation', () => {
740
724
  const onSettledMutate = jest.fn();
741
725
  let count = 0;
742
726
  function Page() {
743
- const mutation = createMutation(async (_text) => {
744
- count++;
745
- await sleep(10);
746
- return `result${count}`;
747
- }, {
727
+ const mutation = createMutation(() => ({
728
+ mutationFn: async (_text) => {
729
+ count++;
730
+ await sleep(10);
731
+ return `result${count}`;
732
+ },
748
733
  onSuccess,
749
734
  onSettled,
750
- });
735
+ }));
751
736
  return (<div>
752
737
  <button onClick={() => mutation.mutate('todo', {
753
738
  onSuccess: onSuccessMutate,
@@ -779,13 +764,14 @@ describe('useMutation', () => {
779
764
  const error = new Error('error from onSuccess');
780
765
  const onError = jest.fn();
781
766
  function Page() {
782
- const mutation = createMutation(async (_text) => {
783
- await sleep(10);
784
- return 'result';
785
- }, {
767
+ const mutation = createMutation(() => ({
768
+ mutationFn: async (_text) => {
769
+ await sleep(10);
770
+ return 'result';
771
+ },
786
772
  onSuccess: () => Promise.reject(error),
787
773
  onError,
788
- });
774
+ }));
789
775
  return (<div>
790
776
  <button onClick={() => mutation.mutate('todo')}>mutate</button>
791
777
  <div>status: {mutation.status}</div>
@@ -803,12 +789,13 @@ describe('useMutation', () => {
803
789
  const error = new Error('error from onError');
804
790
  const mutateFnError = new Error('mutateFnError');
805
791
  function Page() {
806
- const mutation = createMutation(async (_text) => {
807
- await sleep(10);
808
- throw mutateFnError;
809
- }, {
792
+ const mutation = createMutation(() => ({
793
+ mutationFn: async (_text) => {
794
+ await sleep(10);
795
+ throw mutateFnError;
796
+ },
810
797
  onError: () => Promise.reject(error),
811
- });
798
+ }));
812
799
  return (<div>
813
800
  <button onClick={() => mutation.mutate('todo')}>mutate</button>
814
801
  <div>
@@ -830,13 +817,14 @@ describe('useMutation', () => {
830
817
  const mutateFnError = new Error('mutateFnError');
831
818
  const onError = jest.fn();
832
819
  function Page() {
833
- const mutation = createMutation(async (_text) => {
834
- await sleep(10);
835
- throw mutateFnError;
836
- }, {
820
+ const mutation = createMutation(() => ({
821
+ mutationFn: async (_text) => {
822
+ await sleep(10);
823
+ throw mutateFnError;
824
+ },
837
825
  onSettled: () => Promise.reject(error),
838
826
  onError,
839
- });
827
+ }));
840
828
  return (<div>
841
829
  <button onClick={() => mutation.mutate('todo')}>mutate</button>
842
830
  <div>
@@ -854,4 +842,25 @@ describe('useMutation', () => {
854
842
  await screen.findByText('error: mutateFnError, status: error');
855
843
  expect(onError).toHaveBeenCalledWith(mutateFnError, 'todo', undefined);
856
844
  });
845
+ it('should use provided custom queryClient', async () => {
846
+ function Page() {
847
+ const mutation = createMutation(() => ({
848
+ mutationFn: async (text) => {
849
+ return Promise.resolve(text);
850
+ },
851
+ }), () => queryClient);
852
+ return (<div>
853
+ <button onClick={() => mutation.mutate('custom client')}>
854
+ mutate
855
+ </button>
856
+ <div>
857
+ data: {mutation.data ?? 'null'}, status: {mutation.status}
858
+ </div>
859
+ </div>);
860
+ }
861
+ render(() => <Page></Page>);
862
+ await screen.findByText('data: null, status: idle');
863
+ fireEvent.click(screen.getByRole('button', { name: /mutate/i }));
864
+ await screen.findByText('data: custom client, status: success');
865
+ });
857
866
  });