@navios/react-query 0.7.1 → 1.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 (117) hide show
  1. package/CHANGELOG.md +171 -1
  2. package/README.md +152 -4
  3. package/coverage/base.css +224 -0
  4. package/coverage/block-navigation.js +87 -0
  5. package/coverage/client/declare-client.mts.html +1264 -0
  6. package/coverage/client/index.html +116 -0
  7. package/coverage/clover.xml +160 -0
  8. package/coverage/coverage-final.json +8 -0
  9. package/coverage/favicon.png +0 -0
  10. package/coverage/index.html +146 -0
  11. package/coverage/mutation/index.html +131 -0
  12. package/coverage/mutation/key-creator.mts.html +277 -0
  13. package/coverage/mutation/make-hook.mts.html +952 -0
  14. package/coverage/prettify.css +1 -0
  15. package/coverage/prettify.js +2 -0
  16. package/coverage/query/index.html +161 -0
  17. package/coverage/query/key-creator.mts.html +415 -0
  18. package/coverage/query/make-infinite-options.mts.html +601 -0
  19. package/coverage/query/make-options.mts.html +838 -0
  20. package/coverage/query/prefetch.mts.html +1063 -0
  21. package/coverage/sort-arrow-sprite.png +0 -0
  22. package/coverage/sorter.js +210 -0
  23. package/dist/src/__tests__/errorSchema.spec.d.mts +2 -0
  24. package/dist/src/__tests__/errorSchema.spec.d.mts.map +1 -0
  25. package/dist/src/__tests__/prefetch.spec.d.mts +2 -0
  26. package/dist/src/__tests__/prefetch.spec.d.mts.map +1 -0
  27. package/dist/src/client/__type-tests__/from-endpoint.spec-d.d.mts +2 -0
  28. package/dist/src/client/__type-tests__/from-endpoint.spec-d.d.mts.map +1 -0
  29. package/dist/src/client/__type-tests__/infinite-query.spec-d.d.mts +2 -0
  30. package/dist/src/client/__type-tests__/infinite-query.spec-d.d.mts.map +1 -0
  31. package/dist/src/client/__type-tests__/multipart-mutation.spec-d.d.mts +2 -0
  32. package/dist/src/client/__type-tests__/multipart-mutation.spec-d.d.mts.map +1 -0
  33. package/dist/src/client/__type-tests__/mutation.spec-d.d.mts +2 -0
  34. package/dist/src/client/__type-tests__/mutation.spec-d.d.mts.map +1 -0
  35. package/dist/src/client/__type-tests__/query.spec-d.d.mts +2 -0
  36. package/dist/src/client/__type-tests__/query.spec-d.d.mts.map +1 -0
  37. package/dist/src/client/declare-client.d.mts +15 -8
  38. package/dist/src/client/declare-client.d.mts.map +1 -1
  39. package/dist/src/client/types/from-endpoint.d.mts +130 -0
  40. package/dist/src/client/types/from-endpoint.d.mts.map +1 -0
  41. package/dist/src/client/types/helpers.d.mts +74 -0
  42. package/dist/src/client/types/helpers.d.mts.map +1 -0
  43. package/dist/src/client/types/index.d.mts +21 -0
  44. package/dist/src/client/types/index.d.mts.map +1 -0
  45. package/dist/src/client/types/infinite-query.d.mts +61 -0
  46. package/dist/src/client/types/infinite-query.d.mts.map +1 -0
  47. package/dist/src/client/types/multipart-mutation.d.mts +98 -0
  48. package/dist/src/client/types/multipart-mutation.d.mts.map +1 -0
  49. package/dist/src/client/types/mutation.d.mts +75 -0
  50. package/dist/src/client/types/mutation.d.mts.map +1 -0
  51. package/dist/src/client/types/query.d.mts +65 -0
  52. package/dist/src/client/types/query.d.mts.map +1 -0
  53. package/dist/src/client/types.d.mts +1 -608
  54. package/dist/src/client/types.d.mts.map +1 -1
  55. package/dist/src/common/types.d.mts +40 -3
  56. package/dist/src/common/types.d.mts.map +1 -1
  57. package/dist/src/mutation/index.d.mts +1 -0
  58. package/dist/src/mutation/index.d.mts.map +1 -1
  59. package/dist/src/mutation/make-hook.d.mts +42 -16
  60. package/dist/src/mutation/make-hook.d.mts.map +1 -1
  61. package/dist/src/mutation/optimistic.d.mts +172 -0
  62. package/dist/src/mutation/optimistic.d.mts.map +1 -0
  63. package/dist/src/mutation/types.d.mts +41 -20
  64. package/dist/src/mutation/types.d.mts.map +1 -1
  65. package/dist/src/query/index.d.mts +1 -0
  66. package/dist/src/query/index.d.mts.map +1 -1
  67. package/dist/src/query/key-creator.d.mts.map +1 -1
  68. package/dist/src/query/make-infinite-options.d.mts +3 -2
  69. package/dist/src/query/make-infinite-options.d.mts.map +1 -1
  70. package/dist/src/query/make-options.d.mts +42 -12
  71. package/dist/src/query/make-options.d.mts.map +1 -1
  72. package/dist/src/query/prefetch.d.mts +245 -0
  73. package/dist/src/query/prefetch.d.mts.map +1 -0
  74. package/dist/src/query/types.d.mts +25 -18
  75. package/dist/src/query/types.d.mts.map +1 -1
  76. package/dist/tsconfig.tsbuildinfo +1 -1
  77. package/lib/index.cjs +451 -28
  78. package/lib/index.cjs.map +1 -1
  79. package/lib/index.d.cts +1019 -600
  80. package/lib/index.d.cts.map +1 -1
  81. package/lib/index.d.mts +1016 -597
  82. package/lib/index.d.mts.map +1 -1
  83. package/lib/index.mjs +447 -29
  84. package/lib/index.mjs.map +1 -1
  85. package/package.json +3 -3
  86. package/src/__tests__/declare-client.spec.mts +229 -2
  87. package/src/__tests__/errorSchema.spec.mts +391 -0
  88. package/src/__tests__/make-mutation.spec.mts +6 -5
  89. package/src/__tests__/makeDataTag.spec.mts +2 -1
  90. package/src/__tests__/makeQueryOptions.spec.mts +2 -1
  91. package/src/__tests__/prefetch.spec.mts +310 -0
  92. package/src/client/__type-tests__/from-endpoint.spec-d.mts +550 -0
  93. package/src/client/__type-tests__/infinite-query.spec-d.mts +648 -0
  94. package/src/client/__type-tests__/multipart-mutation.spec-d.mts +725 -0
  95. package/src/client/__type-tests__/mutation.spec-d.mts +757 -0
  96. package/src/client/__type-tests__/query.spec-d.mts +701 -0
  97. package/src/client/declare-client.mts +59 -34
  98. package/src/client/types/from-endpoint.mts +344 -0
  99. package/src/client/types/helpers.mts +140 -0
  100. package/src/client/types/index.mts +26 -0
  101. package/src/client/types/infinite-query.mts +133 -0
  102. package/src/client/types/multipart-mutation.mts +264 -0
  103. package/src/client/types/mutation.mts +176 -0
  104. package/src/client/types/query.mts +132 -0
  105. package/src/client/types.mts +1 -1935
  106. package/src/common/types.mts +67 -3
  107. package/src/mutation/index.mts +1 -0
  108. package/src/mutation/make-hook.mts +171 -63
  109. package/src/mutation/optimistic.mts +300 -0
  110. package/src/mutation/types.mts +87 -30
  111. package/src/query/index.mts +1 -0
  112. package/src/query/key-creator.mts +24 -13
  113. package/src/query/make-infinite-options.mts +53 -10
  114. package/src/query/make-options.mts +184 -43
  115. package/src/query/prefetch.mts +326 -0
  116. package/src/query/types.mts +56 -17
  117. package/src/client/__type-tests__/client-instance.spec-d.mts +0 -852
@@ -0,0 +1,310 @@
1
+ import { QueryClient } from '@tanstack/react-query'
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
3
+
4
+ import {
5
+ createPrefetchHelper,
6
+ createPrefetchHelpers,
7
+ prefetchAll,
8
+ } from '../query/prefetch.mjs'
9
+
10
+ describe('createPrefetchHelper', () => {
11
+ let queryClient: QueryClient
12
+
13
+ beforeEach(() => {
14
+ queryClient = new QueryClient({
15
+ defaultOptions: {
16
+ queries: {
17
+ retry: false,
18
+ },
19
+ },
20
+ })
21
+ })
22
+
23
+ it('should create a prefetch helper with all methods', () => {
24
+ const mockQueryOptions = vi.fn((params: { userId: string }) => ({
25
+ queryKey: ['users', params.userId] as const,
26
+ queryFn: async () => ({ id: params.userId, name: 'Test User' }),
27
+ }))
28
+
29
+ const helper = createPrefetchHelper(mockQueryOptions)
30
+
31
+ expect(helper).toHaveProperty('prefetch')
32
+ expect(helper).toHaveProperty('ensureData')
33
+ expect(helper).toHaveProperty('getQueryOptions')
34
+ expect(helper).toHaveProperty('prefetchMany')
35
+ expect(typeof helper.prefetch).toBe('function')
36
+ expect(typeof helper.ensureData).toBe('function')
37
+ expect(typeof helper.getQueryOptions).toBe('function')
38
+ expect(typeof helper.prefetchMany).toBe('function')
39
+ })
40
+
41
+ describe('prefetch', () => {
42
+ it('should call queryClient.prefetchQuery with correct options', async () => {
43
+ const mockQueryFn = vi.fn().mockResolvedValue({ id: '123', name: 'Test' })
44
+ const mockQueryOptions = vi.fn((params: { userId: string }) => ({
45
+ queryKey: ['users', params.userId] as const,
46
+ queryFn: mockQueryFn,
47
+ }))
48
+
49
+ const helper = createPrefetchHelper(mockQueryOptions)
50
+ await helper.prefetch(queryClient, { userId: '123' })
51
+
52
+ expect(mockQueryOptions).toHaveBeenCalledWith({ userId: '123' })
53
+ expect(mockQueryFn).toHaveBeenCalled()
54
+ })
55
+
56
+ it('should prefetch data and store in cache', async () => {
57
+ const userData = { id: '456', name: 'Cached User' }
58
+ const mockQueryOptions = vi.fn((params: { userId: string }) => ({
59
+ queryKey: ['users', params.userId] as const,
60
+ queryFn: async () => userData,
61
+ }))
62
+
63
+ const helper = createPrefetchHelper(mockQueryOptions)
64
+ await helper.prefetch(queryClient, { userId: '456' })
65
+
66
+ const cachedData = queryClient.getQueryData(['users', '456'])
67
+ expect(cachedData).toEqual(userData)
68
+ })
69
+ })
70
+
71
+ describe('ensureData', () => {
72
+ it('should return data after ensuring it exists in cache', async () => {
73
+ const userData = { id: '789', name: 'Ensured User' }
74
+ const mockQueryOptions = vi.fn((params: { userId: string }) => ({
75
+ queryKey: ['users', params.userId] as const,
76
+ queryFn: async () => userData,
77
+ }))
78
+
79
+ const helper = createPrefetchHelper(mockQueryOptions)
80
+ const result = await helper.ensureData(queryClient, { userId: '789' })
81
+
82
+ expect(result).toEqual(userData)
83
+ })
84
+
85
+ it('should not refetch if data is already cached', async () => {
86
+ const mockQueryFn = vi.fn().mockResolvedValue({ id: '111', name: 'User' })
87
+ const mockQueryOptions = vi.fn((params: { userId: string }) => ({
88
+ queryKey: ['users', params.userId] as const,
89
+ queryFn: mockQueryFn,
90
+ }))
91
+
92
+ // Pre-populate cache
93
+ queryClient.setQueryData(['users', '111'], {
94
+ id: '111',
95
+ name: 'Cached User',
96
+ })
97
+
98
+ const helper = createPrefetchHelper(mockQueryOptions)
99
+ const result = await helper.ensureData(queryClient, { userId: '111' })
100
+
101
+ expect(result).toEqual({ id: '111', name: 'Cached User' })
102
+ expect(mockQueryFn).not.toHaveBeenCalled()
103
+ })
104
+ })
105
+
106
+ describe('getQueryOptions', () => {
107
+ it('should return query options for given params', () => {
108
+ const mockQueryOptions = vi.fn((params: { userId: string }) => ({
109
+ queryKey: ['users', params.userId] as const,
110
+ queryFn: async () => ({ id: params.userId }),
111
+ }))
112
+
113
+ const helper = createPrefetchHelper(mockQueryOptions)
114
+ const options = helper.getQueryOptions({ userId: 'abc' })
115
+
116
+ expect(mockQueryOptions).toHaveBeenCalledWith({ userId: 'abc' })
117
+ expect(options).toHaveProperty('queryKey', ['users', 'abc'])
118
+ expect(options).toHaveProperty('queryFn')
119
+ })
120
+ })
121
+
122
+ describe('prefetchMany', () => {
123
+ it('should prefetch multiple queries in parallel', async () => {
124
+ const mockQueryFn = vi.fn().mockImplementation(async (userId: string) => ({
125
+ id: userId,
126
+ name: `User ${userId}`,
127
+ }))
128
+
129
+ const mockQueryOptions = vi.fn((params: { userId: string }) => ({
130
+ queryKey: ['users', params.userId] as const,
131
+ queryFn: () => mockQueryFn(params.userId),
132
+ }))
133
+
134
+ const helper = createPrefetchHelper(mockQueryOptions)
135
+ await helper.prefetchMany(queryClient, [
136
+ { userId: '1' },
137
+ { userId: '2' },
138
+ { userId: '3' },
139
+ ])
140
+
141
+ expect(queryClient.getQueryData(['users', '1'])).toEqual({
142
+ id: '1',
143
+ name: 'User 1',
144
+ })
145
+ expect(queryClient.getQueryData(['users', '2'])).toEqual({
146
+ id: '2',
147
+ name: 'User 2',
148
+ })
149
+ expect(queryClient.getQueryData(['users', '3'])).toEqual({
150
+ id: '3',
151
+ name: 'User 3',
152
+ })
153
+ })
154
+
155
+ it('should handle empty params list', async () => {
156
+ const mockQueryOptions = vi.fn((params: { userId: string }) => ({
157
+ queryKey: ['users', params.userId] as const,
158
+ queryFn: async () => ({ id: params.userId }),
159
+ }))
160
+
161
+ const helper = createPrefetchHelper(mockQueryOptions)
162
+ await helper.prefetchMany(queryClient, [])
163
+
164
+ expect(mockQueryOptions).not.toHaveBeenCalled()
165
+ })
166
+ })
167
+ })
168
+
169
+ describe('createPrefetchHelpers', () => {
170
+ let queryClient: QueryClient
171
+
172
+ beforeEach(() => {
173
+ queryClient = new QueryClient({
174
+ defaultOptions: {
175
+ queries: {
176
+ retry: false,
177
+ },
178
+ },
179
+ })
180
+ })
181
+
182
+ it('should create helpers for multiple queries', () => {
183
+ const queries = {
184
+ user: vi.fn((params: { userId: string }) => ({
185
+ queryKey: ['users', params.userId] as const,
186
+ queryFn: async () => ({ id: params.userId }),
187
+ })),
188
+ posts: vi.fn((params: { userId: string }) => ({
189
+ queryKey: ['users', params.userId, 'posts'] as const,
190
+ queryFn: async () => [{ id: '1', title: 'Post 1' }],
191
+ })),
192
+ }
193
+
194
+ const helpers = createPrefetchHelpers(queries)
195
+
196
+ expect(helpers).toHaveProperty('user')
197
+ expect(helpers).toHaveProperty('posts')
198
+ expect(helpers.user).toHaveProperty('prefetch')
199
+ expect(helpers.posts).toHaveProperty('prefetch')
200
+ })
201
+
202
+ it('should work with individual helpers independently', async () => {
203
+ const queries = {
204
+ user: vi.fn((params: { userId: string }) => ({
205
+ queryKey: ['users', params.userId] as const,
206
+ queryFn: async () => ({ id: params.userId, name: 'User' }),
207
+ })),
208
+ posts: vi.fn((params: { userId: string }) => ({
209
+ queryKey: ['users', params.userId, 'posts'] as const,
210
+ queryFn: async () => [{ id: '1', title: 'Post' }],
211
+ })),
212
+ }
213
+
214
+ const helpers = createPrefetchHelpers(queries)
215
+
216
+ await helpers.user.prefetch(queryClient, { userId: '123' })
217
+ await helpers.posts.prefetch(queryClient, { userId: '123' })
218
+
219
+ expect(queryClient.getQueryData(['users', '123'])).toEqual({
220
+ id: '123',
221
+ name: 'User',
222
+ })
223
+ expect(queryClient.getQueryData(['users', '123', 'posts'])).toEqual([
224
+ { id: '1', title: 'Post' },
225
+ ])
226
+ })
227
+ })
228
+
229
+ describe('prefetchAll', () => {
230
+ let queryClient: QueryClient
231
+
232
+ beforeEach(() => {
233
+ queryClient = new QueryClient({
234
+ defaultOptions: {
235
+ queries: {
236
+ retry: false,
237
+ },
238
+ },
239
+ })
240
+ })
241
+
242
+ it('should prefetch all queries in parallel', async () => {
243
+ const userHelper = createPrefetchHelper(
244
+ vi.fn((params: { userId: string }) => ({
245
+ queryKey: ['users', params.userId] as const,
246
+ queryFn: async () => ({ id: params.userId, name: 'User' }),
247
+ })),
248
+ )
249
+
250
+ const postsHelper = createPrefetchHelper(
251
+ vi.fn((params: { userId: string; limit: number }) => ({
252
+ queryKey: ['users', params.userId, 'posts', params.limit] as const,
253
+ queryFn: async () => [{ id: '1', title: 'Post' }],
254
+ })),
255
+ )
256
+
257
+ await prefetchAll(queryClient, [
258
+ { helper: userHelper, params: { userId: '123' } },
259
+ { helper: postsHelper, params: { userId: '123', limit: 10 } },
260
+ ])
261
+
262
+ expect(queryClient.getQueryData(['users', '123'])).toEqual({
263
+ id: '123',
264
+ name: 'User',
265
+ })
266
+ expect(queryClient.getQueryData(['users', '123', 'posts', 10])).toEqual([
267
+ { id: '1', title: 'Post' },
268
+ ])
269
+ })
270
+
271
+ it('should handle empty prefetches array', async () => {
272
+ await expect(prefetchAll(queryClient, [])).resolves.toBeUndefined()
273
+ })
274
+
275
+ it('should handle errors in individual prefetches', async () => {
276
+ const errorHelper = createPrefetchHelper<
277
+ Record<string, never>,
278
+ { error: boolean }
279
+ >(
280
+ vi.fn(() => ({
281
+ queryKey: ['error'] as const,
282
+ queryFn: async (): Promise<{ error: boolean }> => {
283
+ throw new Error('Fetch failed')
284
+ },
285
+ })),
286
+ )
287
+
288
+ const successHelper = createPrefetchHelper<
289
+ Record<string, never>,
290
+ { success: boolean }
291
+ >(
292
+ vi.fn(() => ({
293
+ queryKey: ['success'] as const,
294
+ queryFn: async () => ({ success: true }),
295
+ })),
296
+ )
297
+
298
+ // prefetchAll should not throw even if individual queries fail
299
+ // because prefetchQuery doesn't throw
300
+ await expect(
301
+ prefetchAll(queryClient, [
302
+ { helper: errorHelper, params: {} },
303
+ { helper: successHelper, params: {} },
304
+ ]),
305
+ ).resolves.toBeUndefined()
306
+
307
+ // Success query should still be cached
308
+ expect(queryClient.getQueryData(['success'])).toEqual({ success: true })
309
+ })
310
+ })