@tanstack/query-core 4.0.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 (85) hide show
  1. package/build/cjs/focusManager.js +101 -0
  2. package/build/cjs/focusManager.js.map +1 -0
  3. package/build/cjs/hydration.js +112 -0
  4. package/build/cjs/hydration.js.map +1 -0
  5. package/build/cjs/index.js +51 -0
  6. package/build/cjs/index.js.map +1 -0
  7. package/build/cjs/infiniteQueryBehavior.js +160 -0
  8. package/build/cjs/infiniteQueryBehavior.js.map +1 -0
  9. package/build/cjs/infiniteQueryObserver.js +92 -0
  10. package/build/cjs/infiniteQueryObserver.js.map +1 -0
  11. package/build/cjs/logger.js +18 -0
  12. package/build/cjs/logger.js.map +1 -0
  13. package/build/cjs/mutation.js +258 -0
  14. package/build/cjs/mutation.js.map +1 -0
  15. package/build/cjs/mutationCache.js +99 -0
  16. package/build/cjs/mutationCache.js.map +1 -0
  17. package/build/cjs/mutationObserver.js +130 -0
  18. package/build/cjs/mutationObserver.js.map +1 -0
  19. package/build/cjs/notifyManager.js +114 -0
  20. package/build/cjs/notifyManager.js.map +1 -0
  21. package/build/cjs/onlineManager.js +100 -0
  22. package/build/cjs/onlineManager.js.map +1 -0
  23. package/build/cjs/queriesObserver.js +170 -0
  24. package/build/cjs/queriesObserver.js.map +1 -0
  25. package/build/cjs/query.js +474 -0
  26. package/build/cjs/query.js.map +1 -0
  27. package/build/cjs/queryCache.js +140 -0
  28. package/build/cjs/queryCache.js.map +1 -0
  29. package/build/cjs/queryClient.js +357 -0
  30. package/build/cjs/queryClient.js.map +1 -0
  31. package/build/cjs/queryObserver.js +521 -0
  32. package/build/cjs/queryObserver.js.map +1 -0
  33. package/build/cjs/removable.js +47 -0
  34. package/build/cjs/removable.js.map +1 -0
  35. package/build/cjs/retryer.js +177 -0
  36. package/build/cjs/retryer.js.map +1 -0
  37. package/build/cjs/subscribable.js +43 -0
  38. package/build/cjs/subscribable.js.map +1 -0
  39. package/build/cjs/utils.js +356 -0
  40. package/build/cjs/utils.js.map +1 -0
  41. package/build/esm/index.js +3077 -0
  42. package/build/esm/index.js.map +1 -0
  43. package/build/stats-html.html +2689 -0
  44. package/build/umd/index.development.js +3106 -0
  45. package/build/umd/index.development.js.map +1 -0
  46. package/build/umd/index.production.js +12 -0
  47. package/build/umd/index.production.js.map +1 -0
  48. package/package.json +25 -0
  49. package/src/focusManager.ts +89 -0
  50. package/src/hydration.ts +164 -0
  51. package/src/index.ts +35 -0
  52. package/src/infiniteQueryBehavior.ts +214 -0
  53. package/src/infiniteQueryObserver.ts +159 -0
  54. package/src/logger.native.ts +11 -0
  55. package/src/logger.ts +9 -0
  56. package/src/mutation.ts +349 -0
  57. package/src/mutationCache.ts +157 -0
  58. package/src/mutationObserver.ts +195 -0
  59. package/src/notifyManager.ts +96 -0
  60. package/src/onlineManager.ts +89 -0
  61. package/src/queriesObserver.ts +211 -0
  62. package/src/query.ts +612 -0
  63. package/src/queryCache.ts +206 -0
  64. package/src/queryClient.ts +716 -0
  65. package/src/queryObserver.ts +748 -0
  66. package/src/removable.ts +37 -0
  67. package/src/retryer.ts +215 -0
  68. package/src/subscribable.ts +33 -0
  69. package/src/tests/focusManager.test.tsx +155 -0
  70. package/src/tests/hydration.test.tsx +429 -0
  71. package/src/tests/infiniteQueryBehavior.test.tsx +124 -0
  72. package/src/tests/infiniteQueryObserver.test.tsx +64 -0
  73. package/src/tests/mutationCache.test.tsx +260 -0
  74. package/src/tests/mutationObserver.test.tsx +75 -0
  75. package/src/tests/mutations.test.tsx +363 -0
  76. package/src/tests/notifyManager.test.tsx +51 -0
  77. package/src/tests/onlineManager.test.tsx +148 -0
  78. package/src/tests/queriesObserver.test.tsx +330 -0
  79. package/src/tests/query.test.tsx +888 -0
  80. package/src/tests/queryCache.test.tsx +236 -0
  81. package/src/tests/queryClient.test.tsx +1435 -0
  82. package/src/tests/queryObserver.test.tsx +802 -0
  83. package/src/tests/utils.test.tsx +360 -0
  84. package/src/types.ts +705 -0
  85. package/src/utils.ts +435 -0
@@ -0,0 +1,236 @@
1
+ import { sleep, queryKey, createQueryClient } from '../../../../tests/utils'
2
+ import { QueryCache, QueryClient } from '..'
3
+ import { Query } from '.././query'
4
+
5
+ describe('queryCache', () => {
6
+ let queryClient: QueryClient
7
+ let queryCache: QueryCache
8
+
9
+ beforeEach(() => {
10
+ queryClient = createQueryClient()
11
+ queryCache = queryClient.getQueryCache()
12
+ })
13
+
14
+ afterEach(() => {
15
+ queryClient.clear()
16
+ })
17
+
18
+ describe('subscribe', () => {
19
+ test('should pass the correct query', async () => {
20
+ const key = queryKey()
21
+ const subscriber = jest.fn()
22
+ const unsubscribe = queryCache.subscribe(subscriber)
23
+ queryClient.setQueryData(key, 'foo')
24
+ const query = queryCache.find(key)
25
+ await sleep(1)
26
+ expect(subscriber).toHaveBeenCalledWith({ query, type: 'added' })
27
+ unsubscribe()
28
+ })
29
+
30
+ test('should notify listeners when new query is added', async () => {
31
+ const key = queryKey()
32
+ const callback = jest.fn()
33
+ queryCache.subscribe(callback)
34
+ queryClient.prefetchQuery(key, () => 'data')
35
+ await sleep(100)
36
+ expect(callback).toHaveBeenCalled()
37
+ })
38
+
39
+ test('should include the queryCache and query when notifying listeners', async () => {
40
+ const key = queryKey()
41
+ const callback = jest.fn()
42
+ queryCache.subscribe(callback)
43
+ queryClient.prefetchQuery(key, () => 'data')
44
+ const query = queryCache.find(key)
45
+ await sleep(100)
46
+ expect(callback).toHaveBeenCalledWith({ query, type: 'added' })
47
+ })
48
+
49
+ test('should notify subscribers when new query with initialData is added', async () => {
50
+ const key = queryKey()
51
+ const callback = jest.fn()
52
+ queryCache.subscribe(callback)
53
+ queryClient.prefetchQuery(key, () => 'data', {
54
+ initialData: 'initial',
55
+ })
56
+ await sleep(100)
57
+ expect(callback).toHaveBeenCalled()
58
+ })
59
+ })
60
+
61
+ describe('find', () => {
62
+ test('find should filter correctly', async () => {
63
+ const key = queryKey()
64
+ await queryClient.prefetchQuery(key, () => 'data1')
65
+ const query = queryCache.find(key)!
66
+ expect(query).toBeDefined()
67
+ })
68
+
69
+ test('find should filter correctly with exact set to false', async () => {
70
+ const key = queryKey()
71
+ await queryClient.prefetchQuery(key, () => 'data1')
72
+ const query = queryCache.find(key, { exact: false })!
73
+ expect(query).toBeDefined()
74
+ })
75
+ })
76
+
77
+ describe('findAll', () => {
78
+ test('should filter correctly', async () => {
79
+ const key1 = queryKey()
80
+ const key2 = queryKey()
81
+ const keyFetching = queryKey()
82
+ await queryClient.prefetchQuery(key1, () => 'data1')
83
+ await queryClient.prefetchQuery(key2, () => 'data2')
84
+ await queryClient.prefetchQuery([{ a: 'a', b: 'b' }], () => 'data3')
85
+ await queryClient.prefetchQuery(['posts', 1], () => 'data4')
86
+ queryClient.invalidateQueries(key2)
87
+ const query1 = queryCache.find(key1)!
88
+ const query2 = queryCache.find(key2)!
89
+ const query3 = queryCache.find([{ a: 'a', b: 'b' }])!
90
+ const query4 = queryCache.find(['posts', 1])!
91
+
92
+ expect(queryCache.findAll(key1)).toEqual([query1])
93
+ // wrapping in an extra array doesn't yield the same results anymore since v4 because keys need to be an array
94
+ expect(queryCache.findAll([key1])).toEqual([])
95
+ expect(queryCache.findAll()).toEqual([query1, query2, query3, query4])
96
+ expect(queryCache.findAll({})).toEqual([query1, query2, query3, query4])
97
+ expect(queryCache.findAll(key1, { type: 'inactive' })).toEqual([query1])
98
+ expect(queryCache.findAll(key1, { type: 'active' })).toEqual([])
99
+ expect(queryCache.findAll(key1, { stale: true })).toEqual([])
100
+ expect(queryCache.findAll(key1, { stale: false })).toEqual([query1])
101
+ expect(
102
+ queryCache.findAll(key1, { stale: false, type: 'active' }),
103
+ ).toEqual([])
104
+ expect(
105
+ queryCache.findAll(key1, { stale: false, type: 'inactive' }),
106
+ ).toEqual([query1])
107
+ expect(
108
+ queryCache.findAll(key1, {
109
+ stale: false,
110
+ type: 'inactive',
111
+ exact: true,
112
+ }),
113
+ ).toEqual([query1])
114
+
115
+ expect(queryCache.findAll(key2)).toEqual([query2])
116
+ expect(queryCache.findAll(key2, { stale: undefined })).toEqual([query2])
117
+ expect(queryCache.findAll(key2, { stale: true })).toEqual([query2])
118
+ expect(queryCache.findAll(key2, { stale: false })).toEqual([])
119
+ expect(queryCache.findAll([{ b: 'b' }])).toEqual([query3])
120
+ expect(queryCache.findAll([{ a: 'a' }], { exact: false })).toEqual([
121
+ query3,
122
+ ])
123
+ expect(queryCache.findAll([{ a: 'a' }], { exact: true })).toEqual([])
124
+ expect(queryCache.findAll([{ a: 'a', b: 'b' }], { exact: true })).toEqual(
125
+ [query3],
126
+ )
127
+ expect(queryCache.findAll([{ a: 'a', b: 'b' }])).toEqual([query3])
128
+ expect(queryCache.findAll([{ a: 'a', b: 'b', c: 'c' }])).toEqual([])
129
+ expect(queryCache.findAll([{ a: 'a' }], { stale: false })).toEqual([
130
+ query3,
131
+ ])
132
+ expect(queryCache.findAll([{ a: 'a' }], { stale: true })).toEqual([])
133
+ expect(queryCache.findAll([{ a: 'a' }], { type: 'active' })).toEqual([])
134
+ expect(queryCache.findAll([{ a: 'a' }], { type: 'inactive' })).toEqual([
135
+ query3,
136
+ ])
137
+ expect(
138
+ queryCache.findAll({ predicate: (query) => query === query3 }),
139
+ ).toEqual([query3])
140
+ expect(queryCache.findAll(['posts'])).toEqual([query4])
141
+
142
+ expect(queryCache.findAll({ fetchStatus: 'idle' })).toEqual([
143
+ query1,
144
+ query2,
145
+ query3,
146
+ query4,
147
+ ])
148
+ expect(queryCache.findAll(key2, { fetchStatus: undefined })).toEqual([
149
+ query2,
150
+ ])
151
+
152
+ const promise = queryClient.prefetchQuery(keyFetching, async () => {
153
+ await sleep(20)
154
+ return 'dataFetching'
155
+ })
156
+ expect(queryCache.findAll({ fetchStatus: 'fetching' })).toEqual([
157
+ queryCache.find(keyFetching),
158
+ ])
159
+ await promise
160
+ expect(queryCache.findAll({ fetchStatus: 'fetching' })).toEqual([])
161
+ })
162
+
163
+ test('should return all the queries when no filters are defined', async () => {
164
+ const key1 = queryKey()
165
+ const key2 = queryKey()
166
+ await queryClient.prefetchQuery(key1, () => 'data1')
167
+ await queryClient.prefetchQuery(key2, () => 'data2')
168
+ expect(queryCache.findAll().length).toBe(2)
169
+ })
170
+ })
171
+
172
+ describe('QueryCacheConfig.onError', () => {
173
+ test('should be called when a query errors', async () => {
174
+ const key = queryKey()
175
+ const onError = jest.fn()
176
+ const testCache = new QueryCache({ onError })
177
+ const testClient = createQueryClient({ queryCache: testCache })
178
+ await testClient.prefetchQuery(key, () =>
179
+ Promise.reject<unknown>('error'),
180
+ )
181
+ const query = testCache.find(key)
182
+ expect(onError).toHaveBeenCalledWith('error', query)
183
+ })
184
+ })
185
+
186
+ describe('QueryCacheConfig.onSuccess', () => {
187
+ test('should be called when a query is successful', async () => {
188
+ const key = queryKey()
189
+ const onSuccess = jest.fn()
190
+ const testCache = new QueryCache({ onSuccess })
191
+ const testClient = createQueryClient({ queryCache: testCache })
192
+ await testClient.prefetchQuery(key, () => Promise.resolve({ data: 5 }))
193
+ const query = testCache.find(key)
194
+ expect(onSuccess).toHaveBeenCalledWith({ data: 5 }, query)
195
+ })
196
+ })
197
+
198
+ describe('QueryCache.add', () => {
199
+ test('should not try to add a query already added to the cache', async () => {
200
+ const key = queryKey()
201
+ const hash = `["${key}"]`
202
+
203
+ await queryClient.prefetchQuery(key, () => 'data1')
204
+
205
+ // Directly add the query from the cache
206
+ // to simulate a race condition
207
+ const query = queryCache['queriesMap'][hash] as Query
208
+ const queryClone = Object.assign({}, query)
209
+
210
+ // No error should be thrown when trying to add the query
211
+ queryCache.add(queryClone)
212
+ expect(queryCache['queries'].length).toEqual(1)
213
+
214
+ // Clean-up to avoid an error when queryClient.clear()
215
+ delete queryCache['queriesMap'][hash]
216
+ })
217
+
218
+ describe('QueryCache.remove', () => {
219
+ test('should not try to remove a query already removed from the cache', async () => {
220
+ const key = queryKey()
221
+ const hash = `["${key}"]`
222
+
223
+ await queryClient.prefetchQuery(key, () => 'data1')
224
+
225
+ // Directly remove the query from the cache
226
+ // to simulate a race condition
227
+ const query = queryCache['queriesMap'][hash] as Query
228
+ const queryClone = Object.assign({}, query)
229
+ delete queryCache['queriesMap'][hash]
230
+
231
+ // No error should be thrown when trying to remove the query
232
+ expect(() => queryCache.remove(queryClone)).not.toThrow()
233
+ })
234
+ })
235
+ })
236
+ })