@tanstack/query-core 5.59.16 → 5.59.20

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 (30) hide show
  1. package/build/legacy/queriesObserver.cjs +8 -0
  2. package/build/legacy/queriesObserver.cjs.map +1 -1
  3. package/build/legacy/queriesObserver.js +8 -0
  4. package/build/legacy/queriesObserver.js.map +1 -1
  5. package/build/modern/queriesObserver.cjs +8 -0
  6. package/build/modern/queriesObserver.cjs.map +1 -1
  7. package/build/modern/queriesObserver.js +8 -0
  8. package/build/modern/queriesObserver.js.map +1 -1
  9. package/package.json +3 -2
  10. package/src/queriesObserver.ts +9 -0
  11. package/src/__tests__/OmitKeyof.test-d.ts +0 -175
  12. package/src/__tests__/focusManager.test.tsx +0 -163
  13. package/src/__tests__/hydration.test.tsx +0 -1069
  14. package/src/__tests__/infiniteQueryBehavior.test.tsx +0 -427
  15. package/src/__tests__/infiniteQueryObserver.test-d.tsx +0 -64
  16. package/src/__tests__/infiniteQueryObserver.test.tsx +0 -198
  17. package/src/__tests__/mutationCache.test.tsx +0 -376
  18. package/src/__tests__/mutationObserver.test.tsx +0 -326
  19. package/src/__tests__/mutations.test.tsx +0 -603
  20. package/src/__tests__/notifyManager.test.tsx +0 -85
  21. package/src/__tests__/onlineManager.test.tsx +0 -168
  22. package/src/__tests__/queriesObserver.test.tsx +0 -267
  23. package/src/__tests__/query.test.tsx +0 -1049
  24. package/src/__tests__/queryCache.test.tsx +0 -350
  25. package/src/__tests__/queryClient.test-d.tsx +0 -156
  26. package/src/__tests__/queryClient.test.tsx +0 -2031
  27. package/src/__tests__/queryObserver.test-d.tsx +0 -108
  28. package/src/__tests__/queryObserver.test.tsx +0 -1236
  29. package/src/__tests__/utils.test.tsx +0 -468
  30. package/src/__tests__/utils.ts +0 -59
@@ -1,168 +0,0 @@
1
- import { beforeEach, describe, expect, test, vi } from 'vitest'
2
- import { OnlineManager } from '../onlineManager'
3
- import { setIsServer, sleep } from './utils'
4
-
5
- describe('onlineManager', () => {
6
- let onlineManager: OnlineManager
7
- beforeEach(() => {
8
- onlineManager = new OnlineManager()
9
- })
10
-
11
- test('isOnline should return true if navigator is undefined', () => {
12
- const navigatorSpy = vi.spyOn(globalThis, 'navigator', 'get')
13
-
14
- // Force navigator to be undefined
15
- // @ts-expect-error
16
- navigatorSpy.mockImplementation(() => undefined)
17
- expect(onlineManager.isOnline()).toBeTruthy()
18
-
19
- navigatorSpy.mockRestore()
20
- })
21
-
22
- test('isOnline should return true if navigator.onLine is true', () => {
23
- const navigatorSpy = vi.spyOn(navigator, 'onLine', 'get')
24
- navigatorSpy.mockImplementation(() => true)
25
-
26
- expect(onlineManager.isOnline()).toBeTruthy()
27
-
28
- navigatorSpy.mockRestore()
29
- })
30
-
31
- test('setEventListener should use online boolean arg', async () => {
32
- let count = 0
33
-
34
- const setup = (setOnline: (online: boolean) => void) => {
35
- setTimeout(() => {
36
- count++
37
- setOnline(false)
38
- }, 20)
39
- return () => void 0
40
- }
41
-
42
- onlineManager.setEventListener(setup)
43
-
44
- await sleep(30)
45
- expect(count).toEqual(1)
46
- expect(onlineManager.isOnline()).toBeFalsy()
47
- })
48
-
49
- test('setEventListener should call previous remove handler when replacing an event listener', () => {
50
- const remove1Spy = vi.fn()
51
- const remove2Spy = vi.fn()
52
-
53
- onlineManager.setEventListener(() => remove1Spy)
54
- onlineManager.setEventListener(() => remove2Spy)
55
-
56
- expect(remove1Spy).toHaveBeenCalledTimes(1)
57
- expect(remove2Spy).not.toHaveBeenCalled()
58
- })
59
-
60
- test('cleanup (removeEventListener) should not be called if window is not defined', async () => {
61
- const restoreIsServer = setIsServer(true)
62
-
63
- const removeEventListenerSpy = vi.spyOn(globalThis, 'removeEventListener')
64
-
65
- const unsubscribe = onlineManager.subscribe(() => undefined)
66
-
67
- unsubscribe()
68
-
69
- expect(removeEventListenerSpy).not.toHaveBeenCalled()
70
-
71
- restoreIsServer()
72
- })
73
-
74
- test('cleanup (removeEventListener) should not be called if window.addEventListener is not defined', async () => {
75
- const { addEventListener } = globalThis.window
76
-
77
- // @ts-expect-error
78
- globalThis.window.addEventListener = undefined
79
-
80
- const removeEventListenerSpy = vi.spyOn(globalThis, 'removeEventListener')
81
-
82
- const unsubscribe = onlineManager.subscribe(() => undefined)
83
-
84
- unsubscribe()
85
-
86
- expect(removeEventListenerSpy).not.toHaveBeenCalled()
87
-
88
- globalThis.window.addEventListener = addEventListener
89
- })
90
-
91
- test('it should replace default window listener when a new event listener is set', async () => {
92
- const addEventListenerSpy = vi.spyOn(globalThis.window, 'addEventListener')
93
-
94
- const removeEventListenerSpy = vi.spyOn(
95
- globalThis.window,
96
- 'removeEventListener',
97
- )
98
-
99
- // Should set the default event listener with window event listeners
100
- const unsubscribe = onlineManager.subscribe(() => undefined)
101
- expect(addEventListenerSpy).toHaveBeenCalledTimes(2)
102
-
103
- // Should replace the window default event listener by a new one
104
- // and it should call window.removeEventListener twice
105
- onlineManager.setEventListener(() => {
106
- return () => void 0
107
- })
108
-
109
- expect(removeEventListenerSpy).toHaveBeenCalledTimes(2)
110
-
111
- unsubscribe()
112
- addEventListenerSpy.mockRestore()
113
- removeEventListenerSpy.mockRestore()
114
- })
115
-
116
- test('should call removeEventListener when last listener unsubscribes', () => {
117
- const addEventListenerSpy = vi.spyOn(globalThis.window, 'addEventListener')
118
-
119
- const removeEventListenerSpy = vi.spyOn(
120
- globalThis.window,
121
- 'removeEventListener',
122
- )
123
-
124
- const unsubscribe1 = onlineManager.subscribe(() => undefined)
125
- const unsubscribe2 = onlineManager.subscribe(() => undefined)
126
- expect(addEventListenerSpy).toHaveBeenCalledTimes(2) // online + offline
127
-
128
- unsubscribe1()
129
- expect(removeEventListenerSpy).toHaveBeenCalledTimes(0)
130
- unsubscribe2()
131
- expect(removeEventListenerSpy).toHaveBeenCalledTimes(2) // online + offline
132
- })
133
-
134
- test('should keep setup function even if last listener unsubscribes', () => {
135
- const setupSpy = vi.fn().mockImplementation(() => () => undefined)
136
-
137
- onlineManager.setEventListener(setupSpy)
138
-
139
- const unsubscribe1 = onlineManager.subscribe(() => undefined)
140
-
141
- expect(setupSpy).toHaveBeenCalledTimes(1)
142
-
143
- unsubscribe1()
144
-
145
- const unsubscribe2 = onlineManager.subscribe(() => undefined)
146
-
147
- expect(setupSpy).toHaveBeenCalledTimes(2)
148
-
149
- unsubscribe2()
150
- })
151
-
152
- test('should call listeners when setOnline is called', () => {
153
- const listener = vi.fn()
154
-
155
- onlineManager.subscribe(listener)
156
-
157
- onlineManager.setOnline(false)
158
- onlineManager.setOnline(false)
159
-
160
- expect(listener).toHaveBeenNthCalledWith(1, false)
161
-
162
- onlineManager.setOnline(true)
163
- onlineManager.setOnline(true)
164
-
165
- expect(listener).toHaveBeenCalledTimes(2)
166
- expect(listener).toHaveBeenNthCalledWith(2, true)
167
- })
168
- })
@@ -1,267 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
2
- import { waitFor } from '@testing-library/react'
3
- import { QueriesObserver } from '..'
4
- import { createQueryClient, queryKey, sleep } from './utils'
5
- import type { QueryClient, QueryObserverResult } from '..'
6
-
7
- describe('queriesObserver', () => {
8
- let queryClient: QueryClient
9
-
10
- beforeEach(() => {
11
- queryClient = createQueryClient()
12
- queryClient.mount()
13
- })
14
-
15
- afterEach(() => {
16
- queryClient.clear()
17
- })
18
-
19
- test('should return an array with all query results', async () => {
20
- const key1 = queryKey()
21
- const key2 = queryKey()
22
- const queryFn1 = vi.fn().mockReturnValue(1)
23
- const queryFn2 = vi.fn().mockReturnValue(2)
24
- const observer = new QueriesObserver(queryClient, [
25
- { queryKey: key1, queryFn: queryFn1 },
26
- { queryKey: key2, queryFn: queryFn2 },
27
- ])
28
- let observerResult
29
- const unsubscribe = observer.subscribe((result) => {
30
- observerResult = result
31
- })
32
- await sleep(1)
33
- unsubscribe()
34
- expect(observerResult).toMatchObject([{ data: 1 }, { data: 2 }])
35
- })
36
-
37
- test('should update when a query updates', async () => {
38
- const key1 = queryKey()
39
- const key2 = queryKey()
40
- const queryFn1 = vi.fn().mockReturnValue(1)
41
- const queryFn2 = vi.fn().mockReturnValue(2)
42
- const observer = new QueriesObserver(queryClient, [
43
- { queryKey: key1, queryFn: queryFn1 },
44
- { queryKey: key2, queryFn: queryFn2 },
45
- ])
46
- const results: Array<Array<QueryObserverResult>> = []
47
- results.push(observer.getCurrentResult())
48
- const unsubscribe = observer.subscribe((result) => {
49
- results.push(result)
50
- })
51
- await sleep(1)
52
- queryClient.setQueryData(key2, 3)
53
- await sleep(1)
54
- unsubscribe()
55
- expect(results.length).toBe(6)
56
- expect(results[0]).toMatchObject([
57
- { status: 'pending', fetchStatus: 'idle', data: undefined },
58
- { status: 'pending', fetchStatus: 'idle', data: undefined },
59
- ])
60
- expect(results[1]).toMatchObject([
61
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
62
- { status: 'pending', fetchStatus: 'idle', data: undefined },
63
- ])
64
- expect(results[2]).toMatchObject([
65
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
66
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
67
- ])
68
- expect(results[3]).toMatchObject([
69
- { status: 'success', data: 1 },
70
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
71
- ])
72
- expect(results[4]).toMatchObject([
73
- { status: 'success', data: 1 },
74
- { status: 'success', data: 2 },
75
- ])
76
- expect(results[5]).toMatchObject([
77
- { status: 'success', data: 1 },
78
- { status: 'success', data: 3 },
79
- ])
80
- })
81
-
82
- test('should update when a query is removed', async () => {
83
- const key1 = queryKey()
84
- const key2 = queryKey()
85
- const queryFn1 = vi.fn().mockReturnValue(1)
86
- const queryFn2 = vi.fn().mockReturnValue(2)
87
- const observer = new QueriesObserver(queryClient, [
88
- { queryKey: key1, queryFn: queryFn1 },
89
- { queryKey: key2, queryFn: queryFn2 },
90
- ])
91
- const results: Array<Array<QueryObserverResult>> = []
92
- results.push(observer.getCurrentResult())
93
- const unsubscribe = observer.subscribe((result) => {
94
- results.push(result)
95
- })
96
- await sleep(1)
97
- observer.setQueries([{ queryKey: key2, queryFn: queryFn2 }])
98
- await sleep(1)
99
- const queryCache = queryClient.getQueryCache()
100
- expect(queryCache.find({ queryKey: key1, type: 'active' })).toBeUndefined()
101
- expect(queryCache.find({ queryKey: key2, type: 'active' })).toBeDefined()
102
- unsubscribe()
103
- expect(queryCache.find({ queryKey: key1, type: 'active' })).toBeUndefined()
104
- expect(queryCache.find({ queryKey: key2, type: 'active' })).toBeUndefined()
105
- expect(results.length).toBe(6)
106
- expect(results[0]).toMatchObject([
107
- { status: 'pending', fetchStatus: 'idle', data: undefined },
108
- { status: 'pending', fetchStatus: 'idle', data: undefined },
109
- ])
110
- expect(results[1]).toMatchObject([
111
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
112
- { status: 'pending', fetchStatus: 'idle', data: undefined },
113
- ])
114
- expect(results[2]).toMatchObject([
115
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
116
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
117
- ])
118
- expect(results[3]).toMatchObject([
119
- { status: 'success', data: 1 },
120
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
121
- ])
122
- expect(results[4]).toMatchObject([
123
- { status: 'success', data: 1 },
124
- { status: 'success', data: 2 },
125
- ])
126
- expect(results[5]).toMatchObject([{ status: 'success', data: 2 }])
127
- })
128
-
129
- test('should update when a query changed position', async () => {
130
- const key1 = queryKey()
131
- const key2 = queryKey()
132
- const queryFn1 = vi.fn().mockReturnValue(1)
133
- const queryFn2 = vi.fn().mockReturnValue(2)
134
- const observer = new QueriesObserver(queryClient, [
135
- { queryKey: key1, queryFn: queryFn1 },
136
- { queryKey: key2, queryFn: queryFn2 },
137
- ])
138
- const results: Array<Array<QueryObserverResult>> = []
139
- results.push(observer.getCurrentResult())
140
- const unsubscribe = observer.subscribe((result) => {
141
- results.push(result)
142
- })
143
- await sleep(1)
144
- observer.setQueries([
145
- { queryKey: key2, queryFn: queryFn2 },
146
- { queryKey: key1, queryFn: queryFn1 },
147
- ])
148
- await sleep(1)
149
- unsubscribe()
150
- expect(results.length).toBe(6)
151
- expect(results[0]).toMatchObject([
152
- { status: 'pending', fetchStatus: 'idle', data: undefined },
153
- { status: 'pending', fetchStatus: 'idle', data: undefined },
154
- ])
155
- expect(results[1]).toMatchObject([
156
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
157
- { status: 'pending', fetchStatus: 'idle', data: undefined },
158
- ])
159
- expect(results[2]).toMatchObject([
160
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
161
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
162
- ])
163
- expect(results[3]).toMatchObject([
164
- { status: 'success', data: 1 },
165
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
166
- ])
167
- expect(results[4]).toMatchObject([
168
- { status: 'success', data: 1 },
169
- { status: 'success', data: 2 },
170
- ])
171
- expect(results[5]).toMatchObject([
172
- { status: 'success', data: 2 },
173
- { status: 'success', data: 1 },
174
- ])
175
- })
176
-
177
- test('should not update when nothing has changed', async () => {
178
- const key1 = queryKey()
179
- const key2 = queryKey()
180
- const queryFn1 = vi.fn().mockReturnValue(1)
181
- const queryFn2 = vi.fn().mockReturnValue(2)
182
- const observer = new QueriesObserver(queryClient, [
183
- { queryKey: key1, queryFn: queryFn1 },
184
- { queryKey: key2, queryFn: queryFn2 },
185
- ])
186
- const results: Array<Array<QueryObserverResult>> = []
187
- results.push(observer.getCurrentResult())
188
- const unsubscribe = observer.subscribe((result) => {
189
- results.push(result)
190
- })
191
- await sleep(1)
192
- observer.setQueries([
193
- { queryKey: key1, queryFn: queryFn1 },
194
- { queryKey: key2, queryFn: queryFn2 },
195
- ])
196
- await sleep(1)
197
- unsubscribe()
198
- expect(results.length).toBe(5)
199
- expect(results[0]).toMatchObject([
200
- { status: 'pending', fetchStatus: 'idle', data: undefined },
201
- { status: 'pending', fetchStatus: 'idle', data: undefined },
202
- ])
203
- expect(results[1]).toMatchObject([
204
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
205
- { status: 'pending', fetchStatus: 'idle', data: undefined },
206
- ])
207
- expect(results[2]).toMatchObject([
208
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
209
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
210
- ])
211
- expect(results[3]).toMatchObject([
212
- { status: 'success', data: 1 },
213
- { status: 'pending', fetchStatus: 'fetching', data: undefined },
214
- ])
215
- expect(results[4]).toMatchObject([
216
- { status: 'success', data: 1 },
217
- { status: 'success', data: 2 },
218
- ])
219
- })
220
-
221
- test('should trigger all fetches when subscribed', async () => {
222
- const key1 = queryKey()
223
- const key2 = queryKey()
224
- const queryFn1 = vi.fn().mockReturnValue(1)
225
- const queryFn2 = vi.fn().mockReturnValue(2)
226
- const observer = new QueriesObserver(queryClient, [
227
- { queryKey: key1, queryFn: queryFn1 },
228
- { queryKey: key2, queryFn: queryFn2 },
229
- ])
230
- const unsubscribe = observer.subscribe(() => undefined)
231
- await sleep(1)
232
- unsubscribe()
233
- expect(queryFn1).toHaveBeenCalledTimes(1)
234
- expect(queryFn2).toHaveBeenCalledTimes(1)
235
- })
236
-
237
- test('should not destroy the observer if there is still a subscription', async () => {
238
- const key1 = queryKey()
239
- const observer = new QueriesObserver(queryClient, [
240
- {
241
- queryKey: key1,
242
- queryFn: async () => {
243
- await sleep(20)
244
- return 1
245
- },
246
- },
247
- ])
248
-
249
- const subscription1Handler = vi.fn()
250
- const subscription2Handler = vi.fn()
251
-
252
- const unsubscribe1 = observer.subscribe(subscription1Handler)
253
- const unsubscribe2 = observer.subscribe(subscription2Handler)
254
-
255
- unsubscribe1()
256
-
257
- await waitFor(() => {
258
- // 1 call: pending
259
- expect(subscription1Handler).toBeCalledTimes(1)
260
- // 1 call: success
261
- expect(subscription2Handler).toBeCalledTimes(1)
262
- })
263
-
264
- // Clean-up
265
- unsubscribe2()
266
- })
267
- })