@navios/react-query 1.0.0-alpha.1 → 1.0.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.
- package/CHANGELOG.md +27 -1
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/client/declare-client.mts.html +1264 -0
- package/coverage/client/index.html +116 -0
- package/coverage/clover.xml +160 -0
- package/coverage/coverage-final.json +8 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +146 -0
- package/coverage/mutation/index.html +131 -0
- package/coverage/mutation/key-creator.mts.html +277 -0
- package/coverage/mutation/make-hook.mts.html +952 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/query/index.html +161 -0
- package/coverage/query/key-creator.mts.html +415 -0
- package/coverage/query/make-infinite-options.mts.html +601 -0
- package/coverage/query/make-options.mts.html +838 -0
- package/coverage/query/prefetch.mts.html +1063 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/src/__tests__/prefetch.spec.d.mts +2 -0
- package/dist/src/__tests__/prefetch.spec.d.mts.map +1 -0
- package/dist/src/client/types/from-endpoint.d.mts +1 -16
- package/dist/src/client/types/from-endpoint.d.mts.map +1 -1
- package/dist/src/common/types.d.mts +10 -0
- package/dist/src/common/types.d.mts.map +1 -1
- package/dist/src/mutation/optimistic.d.mts +7 -1
- package/dist/src/mutation/optimistic.d.mts.map +1 -1
- package/dist/src/mutation/types.d.mts +1 -12
- package/dist/src/mutation/types.d.mts.map +1 -1
- package/dist/src/query/types.d.mts +2 -13
- package/dist/src/query/types.d.mts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/index.cjs +6 -0
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +21 -40
- package/lib/index.d.cts.map +1 -1
- package/lib/index.d.mts +21 -40
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +6 -0
- package/lib/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/declare-client.spec.mts +228 -0
- package/src/__tests__/prefetch.spec.mts +310 -0
- package/src/client/__type-tests__/from-endpoint.spec-d.mts +55 -7
- package/src/client/__type-tests__/infinite-query.spec-d.mts +1 -1
- package/src/client/types/from-endpoint.mts +2 -24
- package/src/common/types.mts +19 -0
- package/src/mutation/optimistic.mts +7 -1
- package/src/mutation/types.mts +4 -20
- package/src/query/types.mts +1 -22
|
@@ -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
|
+
})
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
EndpointHandler,
|
|
3
|
+
ErrorSchemaRecord,
|
|
4
|
+
StreamHandler,
|
|
5
|
+
} from '@navios/builder'
|
|
2
6
|
import type { DataTag, UseSuspenseQueryOptions } from '@tanstack/react-query'
|
|
3
7
|
import type { z } from 'zod/v4'
|
|
4
8
|
|
|
@@ -126,9 +130,23 @@ declare const endpointWithErrors: EndpointHandler<
|
|
|
126
130
|
false
|
|
127
131
|
>
|
|
128
132
|
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
133
|
+
// Stream endpoints for testing
|
|
134
|
+
declare const streamEndpoint: StreamHandler<
|
|
135
|
+
{
|
|
136
|
+
method: 'GET'
|
|
137
|
+
url: '/files/$fileId/download'
|
|
138
|
+
},
|
|
139
|
+
false
|
|
140
|
+
>
|
|
141
|
+
|
|
142
|
+
declare const streamEndpointWithRequest: StreamHandler<
|
|
143
|
+
{
|
|
144
|
+
method: 'POST'
|
|
145
|
+
url: '/files/generate'
|
|
146
|
+
requestSchema: typeof requestSchema
|
|
147
|
+
},
|
|
148
|
+
false
|
|
149
|
+
>
|
|
132
150
|
|
|
133
151
|
// Discriminator mode endpoints
|
|
134
152
|
declare const endpointWithErrorsDiscriminator: EndpointHandler<
|
|
@@ -360,9 +378,39 @@ describe('ClientInstance<false> mutationFromEndpoint() method', () => {
|
|
|
360
378
|
})
|
|
361
379
|
})
|
|
362
380
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
381
|
+
describe('stream endpoints', () => {
|
|
382
|
+
test('stream endpoint returns Blob', () => {
|
|
383
|
+
const mutation = client.mutationFromEndpoint(streamEndpoint)
|
|
384
|
+
const { mutate, data } = mutation()
|
|
385
|
+
|
|
386
|
+
// Should require urlParams for stream endpoint
|
|
387
|
+
mutate({ urlParams: { fileId: '123' } })
|
|
388
|
+
|
|
389
|
+
// Data should be Blob, not never
|
|
390
|
+
assertType<Blob | undefined>(data)
|
|
391
|
+
})
|
|
392
|
+
|
|
393
|
+
test('stream endpoint with request schema', () => {
|
|
394
|
+
const mutation = client.mutationFromEndpoint(streamEndpointWithRequest)
|
|
395
|
+
const { mutate, data } = mutation()
|
|
396
|
+
|
|
397
|
+
// Should require data for stream endpoint with requestSchema
|
|
398
|
+
mutate({ data: { name: 'test', email: 'test@test.com' } })
|
|
399
|
+
|
|
400
|
+
// Data should be Blob
|
|
401
|
+
assertType<Blob | undefined>(data)
|
|
402
|
+
})
|
|
403
|
+
|
|
404
|
+
test('stream endpoint with processResponse', () => {
|
|
405
|
+
client.mutationFromEndpoint(streamEndpoint, {
|
|
406
|
+
processResponse: (data) => {
|
|
407
|
+
// data should be Blob
|
|
408
|
+
assertType<Blob>(data)
|
|
409
|
+
return { url: URL.createObjectURL(data) }
|
|
410
|
+
},
|
|
411
|
+
})
|
|
412
|
+
})
|
|
413
|
+
})
|
|
366
414
|
|
|
367
415
|
describe('callback options', () => {
|
|
368
416
|
test('onMutate receives variables and context', () => {
|
|
@@ -70,7 +70,7 @@ describe('ClientInstance<false> infiniteQuery() method', () => {
|
|
|
70
70
|
url: '/users',
|
|
71
71
|
querySchema,
|
|
72
72
|
responseSchema,
|
|
73
|
-
getNextPageParam: (
|
|
73
|
+
getNextPageParam: (_lastPage, _allPages, _lastPageParam, _allPageParams) =>
|
|
74
74
|
undefined,
|
|
75
75
|
})
|
|
76
76
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
BaseEndpointConfig,
|
|
3
2
|
BaseEndpointOptions,
|
|
4
3
|
EndpointOptions,
|
|
5
4
|
InferEndpointParams,
|
|
@@ -319,27 +318,6 @@ export interface ClientFromEndpointMethods<
|
|
|
319
318
|
? MutationHelpers<Config['url'], Result>
|
|
320
319
|
: {}) &
|
|
321
320
|
(Config extends EndpointOptions
|
|
322
|
-
? EndpointHelper<
|
|
323
|
-
|
|
324
|
-
method: Config['method']
|
|
325
|
-
url: Config['url']
|
|
326
|
-
responseSchema: Config['responseSchema']
|
|
327
|
-
querySchema: Config['querySchema']
|
|
328
|
-
requestSchema: Config['requestSchema']
|
|
329
|
-
errorSchema: Config['errorSchema']
|
|
330
|
-
urlParamsSchema: Config['urlParamsSchema']
|
|
331
|
-
},
|
|
332
|
-
UseDiscriminator
|
|
333
|
-
>
|
|
334
|
-
: StreamHelper<
|
|
335
|
-
{
|
|
336
|
-
method: Config['method']
|
|
337
|
-
url: Config['url']
|
|
338
|
-
querySchema: Config['querySchema']
|
|
339
|
-
requestSchema: Config['requestSchema']
|
|
340
|
-
errorSchema: Config['errorSchema']
|
|
341
|
-
urlParamsSchema: Config['urlParamsSchema']
|
|
342
|
-
},
|
|
343
|
-
UseDiscriminator
|
|
344
|
-
>)
|
|
321
|
+
? EndpointHelper<Config, UseDiscriminator>
|
|
322
|
+
: StreamHelper<Config, UseDiscriminator>)
|
|
345
323
|
}
|
package/src/common/types.mts
CHANGED
|
@@ -24,6 +24,25 @@ export type ProcessResponseFunction<TData = unknown, TVariables = unknown> = (
|
|
|
24
24
|
variables: TVariables,
|
|
25
25
|
) => Promise<TData> | TData
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Compute the response input type based on discriminator and error schema.
|
|
29
|
+
* When UseDiscriminator=true and errorSchema is present, errors are included as a union.
|
|
30
|
+
* When UseDiscriminator=false, only the success type is returned (errors are thrown).
|
|
31
|
+
*
|
|
32
|
+
* @template UseDiscriminator - Whether to include error types in the response union
|
|
33
|
+
* @template ResponseSchema - The success response schema
|
|
34
|
+
* @template ErrorSchema - The error schema record (optional)
|
|
35
|
+
*/
|
|
36
|
+
export type ComputeResponseInput<
|
|
37
|
+
UseDiscriminator extends boolean,
|
|
38
|
+
ResponseSchema extends ZodType,
|
|
39
|
+
ErrorSchema extends ErrorSchemaRecord | undefined,
|
|
40
|
+
> = UseDiscriminator extends true
|
|
41
|
+
? ErrorSchema extends ErrorSchemaRecord
|
|
42
|
+
? z.output<ResponseSchema> | InferErrorSchemaOutput<ErrorSchema>
|
|
43
|
+
: z.output<ResponseSchema>
|
|
44
|
+
: z.output<ResponseSchema>
|
|
45
|
+
|
|
27
46
|
/**
|
|
28
47
|
* Options for creating a client instance.
|
|
29
48
|
*
|
|
@@ -8,7 +8,7 @@ import type { QueryClient } from '@tanstack/react-query'
|
|
|
8
8
|
* @template TQueryData - The query cache data type
|
|
9
9
|
*/
|
|
10
10
|
export interface OptimisticUpdateConfig<
|
|
11
|
-
|
|
11
|
+
_TData,
|
|
12
12
|
TVariables,
|
|
13
13
|
TQueryData,
|
|
14
14
|
> {
|
|
@@ -86,6 +86,9 @@ export interface OptimisticUpdateCallbacks<TData, TVariables, TQueryData> {
|
|
|
86
86
|
* 2. onError: Rollback cache to previous value on failure
|
|
87
87
|
* 3. onSettled: Invalidate query to refetch fresh data
|
|
88
88
|
*
|
|
89
|
+
* @experimental This API is experimental and may change in future versions.
|
|
90
|
+
* Use with caution in production code.
|
|
91
|
+
*
|
|
89
92
|
* @param config - Configuration for the optimistic update
|
|
90
93
|
* @returns Object containing onMutate, onError, and onSettled callbacks
|
|
91
94
|
*
|
|
@@ -206,6 +209,9 @@ export function createOptimisticUpdate<
|
|
|
206
209
|
*
|
|
207
210
|
* Useful when a mutation affects multiple cached queries.
|
|
208
211
|
*
|
|
212
|
+
* @experimental This API is experimental and may change in future versions.
|
|
213
|
+
* Use with caution in production code.
|
|
214
|
+
*
|
|
209
215
|
* @param configs - Array of optimistic update configurations
|
|
210
216
|
* @returns Combined callbacks that handle all specified queries
|
|
211
217
|
*
|
package/src/mutation/types.mts
CHANGED
|
@@ -13,26 +13,10 @@ import type {
|
|
|
13
13
|
} from '@tanstack/react-query'
|
|
14
14
|
import type { z, ZodObject, ZodType } from 'zod/v4'
|
|
15
15
|
|
|
16
|
-
import type {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* When UseDiscriminator=true and errorSchema is present, errors are included as a union.
|
|
21
|
-
* When UseDiscriminator=false, only the success type is returned (errors are thrown).
|
|
22
|
-
*
|
|
23
|
-
* @template UseDiscriminator - Whether to include error types in the response union
|
|
24
|
-
* @template ResponseSchema - The success response schema
|
|
25
|
-
* @template ErrorSchema - The error schema record (optional)
|
|
26
|
-
*/
|
|
27
|
-
type ComputeResponseInput<
|
|
28
|
-
UseDiscriminator extends boolean,
|
|
29
|
-
ResponseSchema extends ZodType,
|
|
30
|
-
ErrorSchema extends ErrorSchemaRecord | undefined,
|
|
31
|
-
> = UseDiscriminator extends true
|
|
32
|
-
? ErrorSchema extends ErrorSchemaRecord
|
|
33
|
-
? z.output<ResponseSchema> | InferErrorSchemaOutput<ErrorSchema>
|
|
34
|
-
: z.output<ResponseSchema>
|
|
35
|
-
: z.output<ResponseSchema>
|
|
16
|
+
import type {
|
|
17
|
+
ComputeResponseInput,
|
|
18
|
+
ProcessResponseFunction,
|
|
19
|
+
} from '../common/types.mjs'
|
|
36
20
|
|
|
37
21
|
/**
|
|
38
22
|
* Arguments for mutation functions based on URL params, request schema, and query schema.
|
package/src/query/types.mts
CHANGED
|
@@ -2,10 +2,8 @@ import type {
|
|
|
2
2
|
AnyEndpointConfig,
|
|
3
3
|
BaseEndpointConfig,
|
|
4
4
|
EndpointOptions,
|
|
5
|
-
ErrorSchemaRecord,
|
|
6
5
|
HttpMethod,
|
|
7
6
|
InferEndpointReturn,
|
|
8
|
-
InferErrorSchemaOutput,
|
|
9
7
|
RequestArgs,
|
|
10
8
|
Simplify,
|
|
11
9
|
UrlHasParams,
|
|
@@ -20,26 +18,7 @@ import type {
|
|
|
20
18
|
} from '@tanstack/react-query'
|
|
21
19
|
import type { z, ZodObject, ZodType } from 'zod/v4'
|
|
22
20
|
|
|
23
|
-
import type { Split } from '../common/types.mjs'
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Compute the response input type based on discriminator and error schema.
|
|
27
|
-
* When UseDiscriminator=true and errorSchema is present, errors are included as a union.
|
|
28
|
-
* When UseDiscriminator=false, only the success type is returned (errors are thrown).
|
|
29
|
-
*
|
|
30
|
-
* @template UseDiscriminator - Whether to include error types in the response union
|
|
31
|
-
* @template ResponseSchema - The success response schema
|
|
32
|
-
* @template ErrorSchema - The error schema record (optional)
|
|
33
|
-
*/
|
|
34
|
-
type ComputeResponseInput<
|
|
35
|
-
UseDiscriminator extends boolean,
|
|
36
|
-
ResponseSchema extends ZodType,
|
|
37
|
-
ErrorSchema extends ErrorSchemaRecord | undefined,
|
|
38
|
-
> = UseDiscriminator extends true
|
|
39
|
-
? ErrorSchema extends ErrorSchemaRecord
|
|
40
|
-
? z.output<ResponseSchema> | InferErrorSchemaOutput<ErrorSchema>
|
|
41
|
-
: z.output<ResponseSchema>
|
|
42
|
-
: z.output<ResponseSchema>
|
|
21
|
+
import type { ComputeResponseInput, Split } from '../common/types.mjs'
|
|
43
22
|
|
|
44
23
|
/**
|
|
45
24
|
* Helper type to extract the result type from processResponse.
|