@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,5 +1,5 @@
1
1
  import { fireEvent, render, screen, waitFor } from 'solid-testing-library';
2
- import { createContext, createEffect, createRenderEffect, createSignal, ErrorBoundary, Show, } from 'solid-js';
2
+ import { createEffect, createRenderEffect, createSignal, Show } from 'solid-js';
3
3
  import { createQuery, QueryCache, QueryClientProvider, useIsFetching } from '..';
4
4
  import { createQueryClient, queryKey, setActTimeout, sleep } from './utils';
5
5
  describe('useIsFetching', () => {
@@ -14,14 +14,14 @@ describe('useIsFetching', () => {
14
14
  }
15
15
  function Query() {
16
16
  const [ready, setReady] = createSignal(false);
17
- createQuery(key, async () => {
18
- await sleep(50);
19
- return 'test';
20
- }, {
21
- get enabled() {
22
- return ready();
17
+ createQuery(() => ({
18
+ queryKey: key,
19
+ queryFn: async () => {
20
+ await sleep(50);
21
+ return 'test';
23
22
  },
24
- });
23
+ enabled: ready(),
24
+ }));
25
25
  return <button onClick={() => setReady(true)}>setReady</button>;
26
26
  }
27
27
  function Page() {
@@ -52,17 +52,23 @@ describe('useIsFetching', () => {
52
52
  return null;
53
53
  }
54
54
  function FirstQuery() {
55
- createQuery(key1, async () => {
56
- await sleep(100);
57
- return 'data';
58
- });
55
+ createQuery(() => ({
56
+ queryKey: key1,
57
+ queryFn: async () => {
58
+ await sleep(150);
59
+ return 'data';
60
+ },
61
+ }));
59
62
  return null;
60
63
  }
61
64
  function SecondQuery() {
62
- createQuery(key2, async () => {
63
- await sleep(100);
64
- return 'data';
65
- });
65
+ createQuery(() => ({
66
+ queryKey: key2,
67
+ queryFn: async () => {
68
+ await sleep(200);
69
+ return 'data';
70
+ },
71
+ }));
66
72
  return null;
67
73
  }
68
74
  function Page() {
@@ -70,7 +76,7 @@ describe('useIsFetching', () => {
70
76
  createEffect(() => {
71
77
  setActTimeout(() => {
72
78
  setRenderSecond(true);
73
- }, 50);
79
+ }, 100);
74
80
  });
75
81
  return (<>
76
82
  <IsFetching />
@@ -92,22 +98,32 @@ describe('useIsFetching', () => {
92
98
  const key2 = queryKey();
93
99
  const isFetchings = [];
94
100
  function One() {
95
- createQuery(key1, async () => {
96
- await sleep(10);
97
- return 'test';
98
- });
101
+ createQuery(() => ({
102
+ queryKey: key1,
103
+ queryFn: async () => {
104
+ await sleep(10);
105
+ return 'test';
106
+ },
107
+ }));
99
108
  return null;
100
109
  }
101
110
  function Two() {
102
- createQuery(key2, async () => {
103
- await sleep(20);
104
- return 'test';
105
- });
111
+ createQuery(() => ({
112
+ queryKey: key2,
113
+ queryFn: async () => {
114
+ await sleep(20);
115
+ return 'test';
116
+ },
117
+ }));
106
118
  return null;
107
119
  }
108
120
  function Page() {
109
121
  const [started, setStarted] = createSignal(false);
110
- const isFetching = useIsFetching(key1);
122
+ const isFetching = useIsFetching(() => ({
123
+ filters: {
124
+ queryKey: key1,
125
+ },
126
+ }));
111
127
  createRenderEffect(() => {
112
128
  isFetchings.push(isFetching());
113
129
  });
@@ -132,69 +148,17 @@ describe('useIsFetching', () => {
132
148
  // at no point should we have isFetching: 2
133
149
  expect(isFetchings).toEqual(expect.not.arrayContaining([2]));
134
150
  });
135
- describe('with custom context', () => {
136
- it('should update as queries start and stop fetching', async () => {
137
- const context = createContext(undefined);
138
- const queryCache = new QueryCache();
139
- const queryClient = createQueryClient({ queryCache });
140
- const key = queryKey();
141
- function Page() {
142
- const [ready, setReady] = createSignal(false);
143
- const isFetching = useIsFetching(undefined, { context: context });
144
- createQuery(key, async () => {
145
- await sleep(50);
146
- return 'test';
147
- }, {
148
- get enabled() {
149
- return ready();
150
- },
151
- context,
152
- });
153
- return (<div>
154
- <div>isFetching: {isFetching}</div>
155
- <button onClick={() => setReady(true)}>setReady</button>
156
- </div>);
157
- }
158
- render(() => (<QueryClientProvider client={queryClient} context={context}>
159
- <Page />
160
- </QueryClientProvider>));
161
- await screen.findByText('isFetching: 0');
162
- fireEvent.click(screen.getByRole('button', { name: /setReady/i }));
163
- await screen.findByText('isFetching: 1');
164
- await screen.findByText('isFetching: 0');
165
- });
166
- it('should throw if the context is not passed to useIsFetching', async () => {
167
- const context = createContext(undefined);
168
- const queryCache = new QueryCache();
169
- const queryClient = createQueryClient({ queryCache });
170
- const key = queryKey();
171
- function Page() {
172
- const isFetching = useIsFetching();
173
- createQuery(key, async () => 'test', {
174
- enabled: true,
175
- context,
176
- useErrorBoundary: true,
177
- });
178
- return (<div>
179
- <div>isFetching: {isFetching}</div>
180
- </div>);
181
- }
182
- render(() => (<QueryClientProvider client={queryClient} context={context}>
183
- <ErrorBoundary fallback={() => <div>error boundary</div>}>
184
- <Page />
185
- </ErrorBoundary>
186
- </QueryClientProvider>));
187
- await waitFor(() => screen.getByText('error boundary'));
188
- });
189
- });
190
151
  it('should show the correct fetching state when mounted after a query', async () => {
191
152
  const queryClient = createQueryClient();
192
153
  const key = queryKey();
193
154
  function Page() {
194
- createQuery(key, async () => {
195
- await sleep(10);
196
- return 'test';
197
- });
155
+ createQuery(() => ({
156
+ queryKey: key,
157
+ queryFn: async () => {
158
+ await sleep(10);
159
+ return 'test';
160
+ },
161
+ }));
198
162
  const isFetching = useIsFetching();
199
163
  return (<div>
200
164
  <div>isFetching: {isFetching()}</div>
@@ -206,4 +170,23 @@ describe('useIsFetching', () => {
206
170
  await screen.findByText('isFetching: 1');
207
171
  await screen.findByText('isFetching: 0');
208
172
  });
173
+ it('should use provided custom queryClient', async () => {
174
+ const queryClient = createQueryClient();
175
+ const key = queryKey();
176
+ function Page() {
177
+ createQuery(() => ({
178
+ queryKey: key,
179
+ queryFn: async () => {
180
+ await sleep(10);
181
+ return 'test';
182
+ },
183
+ }), () => queryClient);
184
+ const isFetching = useIsFetching(() => ({ queryClient }));
185
+ return (<div>
186
+ <div>isFetching: {isFetching}</div>
187
+ </div>);
188
+ }
189
+ render(() => <Page></Page>);
190
+ await screen.findByText('isFetching: 1');
191
+ });
209
192
  });
@@ -1,7 +1,7 @@
1
1
  import { fireEvent, screen, waitFor } from 'solid-testing-library';
2
- import { createMutation, QueryClient, QueryClientProvider, useIsMutating, } from '..';
2
+ import { createMutation, QueryClientProvider, useIsMutating } from '..';
3
3
  import { createQueryClient, sleep } from './utils';
4
- import { createContext, createEffect, createRenderEffect, createSignal, ErrorBoundary, Show, } from 'solid-js';
4
+ import { createEffect, createRenderEffect, createSignal, Show } from 'solid-js';
5
5
  import { render } from 'solid-testing-library';
6
6
  import * as MutationCacheModule from '../../../query-core/src/mutationCache';
7
7
  import { setActTimeout } from './utils';
@@ -17,14 +17,20 @@ describe('useIsMutating', () => {
17
17
  return null;
18
18
  }
19
19
  function Mutations() {
20
- const { mutate: mutate1 } = createMutation(['mutation1'], async () => {
21
- await sleep(150);
22
- return 'data';
23
- });
24
- const { mutate: mutate2 } = createMutation(['mutation2'], async () => {
25
- await sleep(50);
26
- return 'data';
27
- });
20
+ const { mutate: mutate1 } = createMutation(() => ({
21
+ mutationKey: ['mutation1'],
22
+ mutationFn: async () => {
23
+ await sleep(150);
24
+ return 'data';
25
+ },
26
+ }));
27
+ const { mutate: mutate2 } = createMutation(() => ({
28
+ mutationKey: ['mutation2'],
29
+ mutationFn: async () => {
30
+ await sleep(50);
31
+ return 'data';
32
+ },
33
+ }));
28
34
  createEffect(() => {
29
35
  mutate1();
30
36
  setActTimeout(() => {
@@ -48,21 +54,29 @@ describe('useIsMutating', () => {
48
54
  const isMutatings = [];
49
55
  const queryClient = createQueryClient();
50
56
  function IsMutating() {
51
- const isMutating = useIsMutating(['mutation1']);
57
+ const isMutating = useIsMutating(() => ({
58
+ filters: { mutationKey: ['mutation1'] },
59
+ }));
52
60
  createRenderEffect(() => {
53
61
  isMutatings.push(isMutating());
54
62
  });
55
63
  return null;
56
64
  }
57
65
  function Page() {
58
- const { mutate: mutate1 } = createMutation(['mutation1'], async () => {
59
- await sleep(100);
60
- return 'data';
61
- });
62
- const { mutate: mutate2 } = createMutation(['mutation2'], async () => {
63
- await sleep(100);
64
- return 'data';
65
- });
66
+ const { mutate: mutate1 } = createMutation(() => ({
67
+ mutationKey: ['mutation1'],
68
+ mutationFn: async () => {
69
+ await sleep(100);
70
+ return 'data';
71
+ },
72
+ }));
73
+ const { mutate: mutate2 } = createMutation(() => ({
74
+ mutationKey: ['mutation2'],
75
+ mutationFn: async () => {
76
+ await sleep(100);
77
+ return 'data';
78
+ },
79
+ }));
66
80
  createEffect(() => {
67
81
  mutate1();
68
82
  mutate2();
@@ -79,23 +93,31 @@ describe('useIsMutating', () => {
79
93
  const isMutatings = [];
80
94
  const queryClient = createQueryClient();
81
95
  function IsMutating() {
82
- const isMutating = useIsMutating({
83
- predicate: (mutation) => mutation.options.mutationKey?.[0] === 'mutation1',
84
- });
96
+ const isMutating = useIsMutating(() => ({
97
+ filters: {
98
+ predicate: (mutation) => mutation.options.mutationKey?.[0] === 'mutation1',
99
+ },
100
+ }));
85
101
  createRenderEffect(() => {
86
102
  isMutatings.push(isMutating());
87
103
  });
88
104
  return null;
89
105
  }
90
106
  function Page() {
91
- const { mutate: mutate1 } = createMutation(['mutation1'], async () => {
92
- await sleep(100);
93
- return 'data';
94
- });
95
- const { mutate: mutate2 } = createMutation(['mutation2'], async () => {
96
- await sleep(100);
97
- return 'data';
98
- });
107
+ const { mutate: mutate1 } = createMutation(() => ({
108
+ mutationKey: ['mutation1'],
109
+ mutationFn: async () => {
110
+ await sleep(100);
111
+ return 'data';
112
+ },
113
+ }));
114
+ const { mutate: mutate2 } = createMutation(() => ({
115
+ mutationKey: ['mutation2'],
116
+ mutationFn: async () => {
117
+ await sleep(100);
118
+ return 'data';
119
+ },
120
+ }));
99
121
  createEffect(() => {
100
122
  mutate1();
101
123
  mutate2();
@@ -129,10 +151,13 @@ describe('useIsMutating', () => {
129
151
  }
130
152
  function Page() {
131
153
  const [mounted, setMounted] = createSignal(true);
132
- const { mutate: mutate1 } = createMutation(['mutation1'], async () => {
133
- await sleep(10);
134
- return 'data';
135
- });
154
+ const { mutate: mutate1 } = createMutation(() => ({
155
+ mutationKey: ['mutation1'],
156
+ mutationFn: async () => {
157
+ await sleep(10);
158
+ return 'data';
159
+ },
160
+ }));
136
161
  createEffect(() => {
137
162
  mutate1();
138
163
  });
@@ -152,65 +177,25 @@ describe('useIsMutating', () => {
152
177
  await sleep(20);
153
178
  MutationCacheSpy.mockRestore();
154
179
  });
155
- describe('with custom context', () => {
156
- it('should return the number of fetching mutations', async () => {
157
- const context = createContext(undefined);
158
- const isMutatings = [];
159
- const queryClient = new QueryClient();
160
- function IsMutating() {
161
- const isMutating = useIsMutating(undefined, { context });
162
- createRenderEffect(() => {
163
- isMutatings.push(isMutating());
164
- });
165
- return null;
166
- }
167
- function Page() {
168
- const { mutate: mutate1 } = createMutation(['mutation1'], async () => {
169
- await sleep(150);
170
- return 'data';
171
- }, { context });
172
- const { mutate: mutate2 } = createMutation(['mutation2'], async () => {
173
- await sleep(50);
180
+ it('should use provided custom queryClient', async () => {
181
+ const queryClient = createQueryClient();
182
+ function Page() {
183
+ const isMutating = useIsMutating(() => ({ queryClient }));
184
+ const { mutate } = createMutation(() => ({
185
+ mutationKey: ['mutation1'],
186
+ mutationFn: async () => {
187
+ await sleep(10);
174
188
  return 'data';
175
- }, { context });
176
- createEffect(() => {
177
- mutate1();
178
- setActTimeout(() => {
179
- mutate2();
180
- }, 50);
181
- });
182
- return <IsMutating />;
183
- }
184
- render(() => (<QueryClientProvider client={queryClient} context={context}>
185
- <Page />
186
- </QueryClientProvider>));
187
- await waitFor(() => expect(isMutatings).toEqual([0, 1, 2, 1, 0]));
188
- });
189
- it('should throw if the context is not passed to useIsMutating', async () => {
190
- const context = createContext(undefined);
191
- const isMutatings = [];
192
- const queryClient = new QueryClient();
193
- function IsMutating() {
194
- const isMutating = useIsMutating(undefined);
195
- isMutatings.push(isMutating());
196
- return null;
197
- }
198
- function Page() {
199
- const { mutate } = createMutation(['mutation'], async () => 'data', {
200
- useErrorBoundary: true,
201
- context,
202
- });
203
- createEffect(() => {
204
- mutate();
205
- });
206
- return <IsMutating />;
207
- }
208
- render(() => (<QueryClientProvider client={queryClient} context={context}>
209
- <ErrorBoundary fallback={() => <div>error boundary</div>}>
210
- <Page />
211
- </ErrorBoundary>
212
- </QueryClientProvider>));
213
- await waitFor(() => screen.getByText('error boundary'));
214
- });
189
+ },
190
+ }), () => queryClient);
191
+ createEffect(() => {
192
+ mutate();
193
+ });
194
+ return (<div>
195
+ <div>mutating: {isMutating}</div>
196
+ </div>);
197
+ }
198
+ render(() => <Page></Page>);
199
+ await waitFor(() => screen.findByText('mutating: 1'));
215
200
  });
216
201
  });
@@ -2,8 +2,8 @@ import { QueryClient } from '@tanstack/query-core';
2
2
  import { createEffect, createSignal, onCleanup, Show } from 'solid-js';
3
3
  let queryKeyCount = 0;
4
4
  export function queryKey() {
5
- const localQueryKeyCount = queryKeyCount++;
6
- return () => [`query_${localQueryKeyCount}`];
5
+ queryKeyCount++;
6
+ return [`query_${queryKeyCount}`];
7
7
  }
8
8
  export const Blink = (props) => {
9
9
  const [shouldShow, setShouldShow] = createSignal(true);
@@ -17,8 +17,7 @@ export const Blink = (props) => {
17
17
  </Show>);
18
18
  };
19
19
  export function createQueryClient(config) {
20
- jest.spyOn(console, 'error').mockImplementation(() => undefined);
21
- return new QueryClient({ logger: mockLogger, ...config });
20
+ return new QueryClient(config);
22
21
  }
23
22
  export function mockVisibilityState(value) {
24
23
  return jest.spyOn(document, 'visibilityState', 'get').mockReturnValue(value);
@@ -26,11 +25,6 @@ export function mockVisibilityState(value) {
26
25
  export function mockNavigatorOnLine(value) {
27
26
  return jest.spyOn(navigator, 'onLine', 'get').mockReturnValue(value);
28
27
  }
29
- export const mockLogger = {
30
- log: jest.fn(),
31
- warn: jest.fn(),
32
- error: jest.fn(),
33
- };
34
28
  export function sleep(timeout) {
35
29
  return new Promise((resolve, _reject) => {
36
30
  setTimeout(resolve, timeout);
@@ -0,0 +1,147 @@
1
+ import { hydrate } from '@tanstack/query-core';
2
+ import { notifyManager } from '@tanstack/query-core';
3
+ import { isServer } from 'solid-js/web';
4
+ import { createComputed, createMemo, createResource, on, onCleanup, onMount, } from 'solid-js';
5
+ import { createStore, unwrap } from 'solid-js/store';
6
+ import { useQueryClient } from './QueryClientProvider';
7
+ import { shouldThrowError } from './utils';
8
+ // Base Query Function that is used to create the query.
9
+ export function createBaseQuery(options, Observer, queryClient) {
10
+ const client = createMemo(() => useQueryClient(queryClient?.()));
11
+ const defaultedOptions = client().defaultQueryOptions(options());
12
+ defaultedOptions._optimisticResults = 'optimistic';
13
+ if (isServer) {
14
+ defaultedOptions.retry = false;
15
+ defaultedOptions.throwErrors = true;
16
+ }
17
+ const observer = new Observer(client(), defaultedOptions);
18
+ const [state, setState] = createStore(observer.getOptimisticResult(defaultedOptions));
19
+ const createServerSubscriber = (resolve, reject) => {
20
+ return observer.subscribe((result) => {
21
+ notifyManager.batchCalls(() => {
22
+ const unwrappedResult = { ...unwrap(result) };
23
+ if (unwrappedResult.isError) {
24
+ if (process.env['NODE_ENV'] === 'development') {
25
+ console.error(unwrappedResult.error);
26
+ }
27
+ reject(unwrappedResult.error);
28
+ }
29
+ if (unwrappedResult.isSuccess) {
30
+ resolve(unwrappedResult);
31
+ }
32
+ })();
33
+ });
34
+ };
35
+ const createClientSubscriber = () => {
36
+ return observer.subscribe((result) => {
37
+ notifyManager.batchCalls(() => {
38
+ const unwrappedResult = { ...unwrap(result) };
39
+ // If the query has data we dont suspend but instead mutate the resource
40
+ // This could happen when placeholderData/initialData is defined
41
+ if (queryResource()?.data &&
42
+ unwrappedResult.data &&
43
+ !queryResource.loading) {
44
+ setState(unwrappedResult);
45
+ mutate(state);
46
+ }
47
+ else {
48
+ setState(unwrappedResult);
49
+ refetch();
50
+ }
51
+ })();
52
+ });
53
+ };
54
+ /**
55
+ * Unsubscribe is set lazily, so that we can subscribe after hydration when needed.
56
+ */
57
+ let unsubscribe = null;
58
+ const [queryResource, { refetch, mutate }] = createResource(() => {
59
+ return new Promise((resolve, reject) => {
60
+ if (isServer) {
61
+ unsubscribe = createServerSubscriber(resolve, reject);
62
+ }
63
+ else {
64
+ if (!unsubscribe) {
65
+ unsubscribe = createClientSubscriber();
66
+ }
67
+ }
68
+ if (!state.isLoading) {
69
+ resolve(state);
70
+ }
71
+ });
72
+ }, {
73
+ initialValue: state,
74
+ // If initialData is provided, we resolve the resource immediately
75
+ ssrLoadFrom: options().initialData ? 'initial' : 'server',
76
+ get deferStream() {
77
+ return options().deferStream;
78
+ },
79
+ /**
80
+ * If this resource was populated on the server (either sync render, or streamed in over time), onHydrated
81
+ * will be called. This is the point at which we can hydrate the query cache state, and setup the query subscriber.
82
+ *
83
+ * Leveraging onHydrated allows us to plug into the async and streaming support that solidjs resources already support.
84
+ *
85
+ * Note that this is only invoked on the client, for queries that were originally run on the server.
86
+ */
87
+ onHydrated(_k, info) {
88
+ if (info.value) {
89
+ hydrate(client(), {
90
+ queries: [
91
+ {
92
+ queryKey: defaultedOptions.queryKey,
93
+ queryHash: defaultedOptions.queryHash,
94
+ state: info.value,
95
+ },
96
+ ],
97
+ });
98
+ }
99
+ if (!unsubscribe) {
100
+ /**
101
+ * Do not refetch query on mount if query was fetched on server,
102
+ * even if `staleTime` is not set.
103
+ */
104
+ const newOptions = { ...defaultedOptions };
105
+ if (defaultedOptions.staleTime || !defaultedOptions.initialData) {
106
+ newOptions.refetchOnMount = false;
107
+ }
108
+ // Setting the options as an immutable object to prevent
109
+ // wonky behavior with observer subscriptions
110
+ observer.setOptions(newOptions);
111
+ setState(observer.getOptimisticResult(newOptions));
112
+ unsubscribe = createClientSubscriber();
113
+ }
114
+ },
115
+ });
116
+ onCleanup(() => {
117
+ if (unsubscribe) {
118
+ unsubscribe();
119
+ unsubscribe = null;
120
+ }
121
+ });
122
+ onMount(() => {
123
+ observer.setOptions(defaultedOptions, { listeners: false });
124
+ });
125
+ createComputed(() => {
126
+ observer.setOptions(client().defaultQueryOptions(options()));
127
+ });
128
+ createComputed(on(() => state.status, () => {
129
+ if (state.isError &&
130
+ !state.isFetching &&
131
+ shouldThrowError(observer.options.throwErrors, [
132
+ state.error,
133
+ observer.getCurrentQuery(),
134
+ ])) {
135
+ throw state.error;
136
+ }
137
+ }));
138
+ const handler = {
139
+ get(target, prop) {
140
+ if (prop === 'data') {
141
+ return queryResource()?.data;
142
+ }
143
+ return Reflect.get(target, prop);
144
+ },
145
+ };
146
+ return new Proxy(state, handler);
147
+ }
@@ -0,0 +1,8 @@
1
+ import { InfiniteQueryObserver } from '@tanstack/query-core';
2
+ import { createBaseQuery } from './createBaseQuery';
3
+ import { createMemo } from 'solid-js';
4
+ export function createInfiniteQuery(options, queryClient) {
5
+ return createBaseQuery(createMemo(() => options()),
6
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
7
+ InfiniteQueryObserver, queryClient);
8
+ }
@@ -1,12 +1,12 @@
1
- import { parseMutationArgs, MutationObserver } from '@tanstack/query-core';
1
+ import { MutationObserver } from '@tanstack/query-core';
2
2
  import { useQueryClient } from './QueryClientProvider';
3
3
  import { createComputed, onCleanup, on } from 'solid-js';
4
4
  import { createStore } from 'solid-js/store';
5
5
  import { shouldThrowError } from './utils';
6
- export function createMutation(arg1, arg2, arg3) {
7
- const [options, setOptions] = createStore(parseMutationArgs(arg1, arg2, arg3));
8
- const queryClient = useQueryClient({ context: options.context });
9
- const observer = new MutationObserver(queryClient, options);
6
+ // HOOK
7
+ export function createMutation(options, queryClient) {
8
+ const client = useQueryClient(queryClient?.());
9
+ const observer = new MutationObserver(client, options());
10
10
  const mutate = (variables, mutateOptions) => {
11
11
  observer.mutate(variables, mutateOptions).catch(noop);
12
12
  };
@@ -16,13 +16,11 @@ export function createMutation(arg1, arg2, arg3) {
16
16
  mutateAsync: observer.getCurrentResult().mutate,
17
17
  });
18
18
  createComputed(() => {
19
- const newParsedOptions = parseMutationArgs(arg1, arg2, arg3);
20
- setOptions(newParsedOptions);
21
- observer.setOptions(newParsedOptions);
19
+ observer.setOptions(options());
22
20
  });
23
21
  createComputed(on(() => state.status, () => {
24
22
  if (state.isError &&
25
- shouldThrowError(observer.options.useErrorBoundary, [state.error])) {
23
+ shouldThrowError(observer.options.throwErrors, [state.error])) {
26
24
  throw state.error;
27
25
  }
28
26
  }));