@veloxts/client 0.4.2 → 0.4.3
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/dist/react/__tests__/hooks.test.d.ts +5 -0
- package/dist/react/__tests__/hooks.test.d.ts.map +1 -0
- package/dist/react/__tests__/hooks.test.js +230 -0
- package/dist/react/__tests__/hooks.test.js.map +1 -0
- package/dist/react/__tests__/provider.test.d.ts +5 -0
- package/dist/react/__tests__/provider.test.d.ts.map +1 -0
- package/dist/react/__tests__/provider.test.js +77 -0
- package/dist/react/__tests__/provider.test.js.map +1 -0
- package/dist/react/hooks.d.ts +182 -0
- package/dist/react/hooks.d.ts.map +1 -0
- package/dist/react/hooks.js +224 -0
- package/dist/react/hooks.js.map +1 -0
- package/dist/react/index.d.ts +63 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +67 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/provider.d.ts +108 -0
- package/dist/react/provider.d.ts.map +1 -0
- package/dist/react/provider.js +162 -0
- package/dist/react/provider.js.map +1 -0
- package/dist/react/types.d.ts +83 -0
- package/dist/react/types.d.ts.map +1 -0
- package/dist/react/types.js +10 -0
- package/dist/react/types.js.map +1 -0
- package/dist/react/utils.d.ts +151 -0
- package/dist/react/utils.d.ts.map +1 -0
- package/dist/react/utils.js +181 -0
- package/dist/react/utils.js.map +1 -0
- package/dist/test-setup.d.ts +7 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +7 -0
- package/dist/test-setup.js.map +1 -0
- package/package.json +27 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.test.d.ts","sourceRoot":"","sources":["../../../src/react/__tests__/hooks.test.tsx"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Unit tests for React hooks (useQuery, useMutation, useQueryClient)
|
|
4
|
+
*/
|
|
5
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
6
|
+
import { act, renderHook, waitFor } from '@testing-library/react';
|
|
7
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
8
|
+
import { useMutation, useQuery, useQueryClient } from '../hooks.js';
|
|
9
|
+
import { VeloxProvider } from '../provider.js';
|
|
10
|
+
// Mock client
|
|
11
|
+
const mockGetUser = vi.fn();
|
|
12
|
+
const mockListUsers = vi.fn();
|
|
13
|
+
const mockCreateUser = vi.fn();
|
|
14
|
+
const mockUpdateUser = vi.fn();
|
|
15
|
+
const mockClient = {
|
|
16
|
+
users: {
|
|
17
|
+
getUser: mockGetUser,
|
|
18
|
+
listUsers: mockListUsers,
|
|
19
|
+
createUser: mockCreateUser,
|
|
20
|
+
updateUser: mockUpdateUser,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
// Mock createClient to return our mock client
|
|
24
|
+
vi.mock('../../client.js', () => ({
|
|
25
|
+
createClient: vi.fn(() => mockClient),
|
|
26
|
+
}));
|
|
27
|
+
// Wrapper component for hooks
|
|
28
|
+
function createWrapper() {
|
|
29
|
+
const queryClient = new QueryClient({
|
|
30
|
+
defaultOptions: {
|
|
31
|
+
queries: { retry: false },
|
|
32
|
+
mutations: { retry: false },
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
function Wrapper({ children }) {
|
|
36
|
+
return (_jsx(VeloxProvider, { config: { baseUrl: '/api' }, queryClient: queryClient, children: children }));
|
|
37
|
+
}
|
|
38
|
+
return { Wrapper, queryClient };
|
|
39
|
+
}
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// useQuery Tests
|
|
42
|
+
// ============================================================================
|
|
43
|
+
describe('useQuery', () => {
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
vi.clearAllMocks();
|
|
46
|
+
});
|
|
47
|
+
afterEach(() => {
|
|
48
|
+
vi.clearAllMocks();
|
|
49
|
+
});
|
|
50
|
+
it('fetches data successfully', async () => {
|
|
51
|
+
const mockUser = { id: '123', name: 'Test User', email: 'test@example.com' };
|
|
52
|
+
mockGetUser.mockResolvedValueOnce(mockUser);
|
|
53
|
+
const { Wrapper } = createWrapper();
|
|
54
|
+
const { result } = renderHook(() => useQuery('users', 'getUser', { id: '123' }), { wrapper: Wrapper });
|
|
55
|
+
// Initially loading
|
|
56
|
+
expect(result.current.isLoading).toBe(true);
|
|
57
|
+
// Wait for data
|
|
58
|
+
await waitFor(() => expect(result.current.isSuccess).toBe(true));
|
|
59
|
+
expect(result.current.data).toEqual(mockUser);
|
|
60
|
+
expect(mockGetUser).toHaveBeenCalledWith({ id: '123' });
|
|
61
|
+
});
|
|
62
|
+
it('handles errors', async () => {
|
|
63
|
+
const error = new Error('Not found');
|
|
64
|
+
mockGetUser.mockRejectedValueOnce(error);
|
|
65
|
+
const { Wrapper } = createWrapper();
|
|
66
|
+
const { result } = renderHook(() => useQuery('users', 'getUser', { id: 'invalid' }), { wrapper: Wrapper });
|
|
67
|
+
await waitFor(() => expect(result.current.isError).toBe(true));
|
|
68
|
+
expect(result.current.error).toBeDefined();
|
|
69
|
+
expect(result.current.error?.message).toBe('Not found');
|
|
70
|
+
});
|
|
71
|
+
it('respects enabled option', async () => {
|
|
72
|
+
const { Wrapper } = createWrapper();
|
|
73
|
+
const { result } = renderHook(() => useQuery('users', 'getUser', { id: '123' }, { enabled: false }), { wrapper: Wrapper });
|
|
74
|
+
// Should not be loading when disabled
|
|
75
|
+
expect(result.current.isLoading).toBe(false);
|
|
76
|
+
expect(result.current.fetchStatus).toBe('idle');
|
|
77
|
+
expect(mockGetUser).not.toHaveBeenCalled();
|
|
78
|
+
});
|
|
79
|
+
it('refetches on input change', async () => {
|
|
80
|
+
const user1 = { id: '1', name: 'User 1', email: 'user1@example.com' };
|
|
81
|
+
const user2 = { id: '2', name: 'User 2', email: 'user2@example.com' };
|
|
82
|
+
mockGetUser.mockResolvedValueOnce(user1).mockResolvedValueOnce(user2);
|
|
83
|
+
const { Wrapper } = createWrapper();
|
|
84
|
+
const { result, rerender } = renderHook(({ id }) => useQuery('users', 'getUser', { id }), { wrapper: Wrapper, initialProps: { id: '1' } });
|
|
85
|
+
await waitFor(() => expect(result.current.data).toEqual(user1));
|
|
86
|
+
// Change input
|
|
87
|
+
rerender({ id: '2' });
|
|
88
|
+
await waitFor(() => expect(result.current.data).toEqual(user2));
|
|
89
|
+
expect(mockGetUser).toHaveBeenCalledTimes(2);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// useMutation Tests
|
|
94
|
+
// ============================================================================
|
|
95
|
+
describe('useMutation', () => {
|
|
96
|
+
beforeEach(() => {
|
|
97
|
+
vi.clearAllMocks();
|
|
98
|
+
});
|
|
99
|
+
afterEach(() => {
|
|
100
|
+
vi.clearAllMocks();
|
|
101
|
+
});
|
|
102
|
+
it('executes mutation successfully', async () => {
|
|
103
|
+
const newUser = { id: 'new-id', name: 'New User', email: 'new@example.com' };
|
|
104
|
+
mockCreateUser.mockResolvedValueOnce(newUser);
|
|
105
|
+
const { Wrapper } = createWrapper();
|
|
106
|
+
const { result } = renderHook(() => useMutation('users', 'createUser'), { wrapper: Wrapper });
|
|
107
|
+
expect(result.current.isPending).toBe(false);
|
|
108
|
+
// Execute mutation
|
|
109
|
+
act(() => {
|
|
110
|
+
result.current.mutate({ name: 'New User', email: 'new@example.com' });
|
|
111
|
+
});
|
|
112
|
+
await waitFor(() => expect(result.current.isSuccess).toBe(true));
|
|
113
|
+
expect(result.current.data).toEqual(newUser);
|
|
114
|
+
expect(mockCreateUser).toHaveBeenCalledWith({ name: 'New User', email: 'new@example.com' });
|
|
115
|
+
});
|
|
116
|
+
it('handles mutation errors', async () => {
|
|
117
|
+
const error = new Error('Validation failed');
|
|
118
|
+
mockCreateUser.mockRejectedValueOnce(error);
|
|
119
|
+
const { Wrapper } = createWrapper();
|
|
120
|
+
const { result } = renderHook(() => useMutation('users', 'createUser'), { wrapper: Wrapper });
|
|
121
|
+
act(() => {
|
|
122
|
+
result.current.mutate({ name: '', email: 'invalid' });
|
|
123
|
+
});
|
|
124
|
+
await waitFor(() => expect(result.current.isError).toBe(true));
|
|
125
|
+
expect(result.current.error?.message).toBe('Validation failed');
|
|
126
|
+
});
|
|
127
|
+
it('calls onSuccess callback', async () => {
|
|
128
|
+
const newUser = { id: 'new-id', name: 'New User', email: 'new@example.com' };
|
|
129
|
+
mockCreateUser.mockResolvedValueOnce(newUser);
|
|
130
|
+
const onSuccess = vi.fn();
|
|
131
|
+
const { Wrapper } = createWrapper();
|
|
132
|
+
const { result } = renderHook(() => useMutation('users', 'createUser', { onSuccess }), { wrapper: Wrapper });
|
|
133
|
+
act(() => {
|
|
134
|
+
result.current.mutate({ name: 'New User', email: 'new@example.com' });
|
|
135
|
+
});
|
|
136
|
+
await waitFor(() => expect(result.current.isSuccess).toBe(true));
|
|
137
|
+
expect(onSuccess).toHaveBeenCalledWith(newUser, { name: 'New User', email: 'new@example.com' }, undefined);
|
|
138
|
+
});
|
|
139
|
+
it('calls onError callback', async () => {
|
|
140
|
+
const error = new Error('Server error');
|
|
141
|
+
mockCreateUser.mockRejectedValueOnce(error);
|
|
142
|
+
const onError = vi.fn();
|
|
143
|
+
const { Wrapper } = createWrapper();
|
|
144
|
+
const { result } = renderHook(() => useMutation('users', 'createUser', { onError }), { wrapper: Wrapper });
|
|
145
|
+
act(() => {
|
|
146
|
+
result.current.mutate({ name: 'Test', email: 'test@example.com' });
|
|
147
|
+
});
|
|
148
|
+
await waitFor(() => expect(result.current.isError).toBe(true));
|
|
149
|
+
expect(onError).toHaveBeenCalled();
|
|
150
|
+
});
|
|
151
|
+
it('supports mutateAsync for promise-based usage', async () => {
|
|
152
|
+
const newUser = { id: 'new-id', name: 'New User', email: 'new@example.com' };
|
|
153
|
+
mockCreateUser.mockResolvedValueOnce(newUser);
|
|
154
|
+
const { Wrapper } = createWrapper();
|
|
155
|
+
const { result } = renderHook(() => useMutation('users', 'createUser'), { wrapper: Wrapper });
|
|
156
|
+
let returnedUser;
|
|
157
|
+
await act(async () => {
|
|
158
|
+
returnedUser = await result.current.mutateAsync({
|
|
159
|
+
name: 'New User',
|
|
160
|
+
email: 'new@example.com',
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
expect(returnedUser).toEqual(newUser);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
// ============================================================================
|
|
167
|
+
// useQueryClient Tests
|
|
168
|
+
// ============================================================================
|
|
169
|
+
describe('useQueryClient', () => {
|
|
170
|
+
it('returns the QueryClient instance', () => {
|
|
171
|
+
const { Wrapper, queryClient: expectedClient } = createWrapper();
|
|
172
|
+
const { result } = renderHook(() => useQueryClient(), { wrapper: Wrapper });
|
|
173
|
+
expect(result.current).toBe(expectedClient);
|
|
174
|
+
});
|
|
175
|
+
it('allows manual cache manipulation', async () => {
|
|
176
|
+
const { Wrapper, queryClient } = createWrapper();
|
|
177
|
+
const { result } = renderHook(() => useQueryClient(), { wrapper: Wrapper });
|
|
178
|
+
// Set data manually
|
|
179
|
+
act(() => {
|
|
180
|
+
result.current.setQueryData(['users', 'getUser', { id: '123' }], {
|
|
181
|
+
id: '123',
|
|
182
|
+
name: 'Cached User',
|
|
183
|
+
email: 'cached@example.com',
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
const cachedData = queryClient.getQueryData(['users', 'getUser', { id: '123' }]);
|
|
187
|
+
expect(cachedData).toEqual({
|
|
188
|
+
id: '123',
|
|
189
|
+
name: 'Cached User',
|
|
190
|
+
email: 'cached@example.com',
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
// ============================================================================
|
|
195
|
+
// Integration Tests
|
|
196
|
+
// ============================================================================
|
|
197
|
+
describe('hooks integration', () => {
|
|
198
|
+
beforeEach(() => {
|
|
199
|
+
vi.clearAllMocks();
|
|
200
|
+
});
|
|
201
|
+
it('mutation onSuccess callback receives correct data', async () => {
|
|
202
|
+
const newUser = { id: '2', name: 'User 2', email: 'user2@example.com' };
|
|
203
|
+
mockCreateUser.mockResolvedValueOnce(newUser);
|
|
204
|
+
const { Wrapper } = createWrapper();
|
|
205
|
+
const onSuccessData = [];
|
|
206
|
+
const { result } = renderHook(() => useMutation('users', 'createUser', {
|
|
207
|
+
onSuccess: (data) => {
|
|
208
|
+
onSuccessData.push(data);
|
|
209
|
+
},
|
|
210
|
+
}), { wrapper: Wrapper });
|
|
211
|
+
// Execute mutation
|
|
212
|
+
act(() => {
|
|
213
|
+
result.current.mutate({ name: 'User 2', email: 'user2@example.com' });
|
|
214
|
+
});
|
|
215
|
+
await waitFor(() => expect(result.current.isSuccess).toBe(true));
|
|
216
|
+
// onSuccess should have received the created user
|
|
217
|
+
expect(onSuccessData).toHaveLength(1);
|
|
218
|
+
expect(onSuccessData[0]).toEqual(newUser);
|
|
219
|
+
});
|
|
220
|
+
it('useQueryClient returns a working query client instance', async () => {
|
|
221
|
+
const { Wrapper } = createWrapper();
|
|
222
|
+
const { result } = renderHook(() => useQueryClient(), { wrapper: Wrapper });
|
|
223
|
+
// Should be a QueryClient instance
|
|
224
|
+
expect(result.current).toBeDefined();
|
|
225
|
+
expect(typeof result.current.invalidateQueries).toBe('function');
|
|
226
|
+
expect(typeof result.current.setQueryData).toBe('function');
|
|
227
|
+
expect(typeof result.current.getQueryData).toBe('function');
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
//# sourceMappingURL=hooks.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.test.js","sourceRoot":"","sources":["../../../src/react/__tests__/hooks.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.test.d.ts","sourceRoot":"","sources":["../../../src/react/__tests__/provider.test.tsx"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Unit tests for VeloxProvider component
|
|
4
|
+
*/
|
|
5
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
6
|
+
import { render, screen } from '@testing-library/react';
|
|
7
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
8
|
+
import { useVeloxContext, VeloxProvider } from '../provider.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Test Setup
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Mock the createClient function
|
|
13
|
+
vi.mock('../../client.js', () => ({
|
|
14
|
+
createClient: vi.fn((config) => ({
|
|
15
|
+
_config: config,
|
|
16
|
+
users: {
|
|
17
|
+
getUser: vi.fn().mockResolvedValue({ id: '123', name: 'Test User' }),
|
|
18
|
+
},
|
|
19
|
+
})),
|
|
20
|
+
}));
|
|
21
|
+
// Test consumer component that uses the context
|
|
22
|
+
function TestConsumer() {
|
|
23
|
+
const { client } = useVeloxContext();
|
|
24
|
+
return _jsx("div", { "data-testid": "has-client", children: client ? 'Client available' : 'No client' });
|
|
25
|
+
}
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// VeloxProvider Tests
|
|
28
|
+
// ============================================================================
|
|
29
|
+
describe('VeloxProvider', () => {
|
|
30
|
+
let queryClient;
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
queryClient = new QueryClient({
|
|
33
|
+
defaultOptions: {
|
|
34
|
+
queries: { retry: false },
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
queryClient.clear();
|
|
40
|
+
});
|
|
41
|
+
it('renders children', () => {
|
|
42
|
+
render(_jsx(VeloxProvider, { config: { baseUrl: '/api' }, queryClient: queryClient, children: _jsx("div", { "data-testid": "child", children: "Hello" }) }));
|
|
43
|
+
expect(screen.getByTestId('child')).toHaveTextContent('Hello');
|
|
44
|
+
});
|
|
45
|
+
it('provides client context to children', () => {
|
|
46
|
+
render(_jsx(VeloxProvider, { config: { baseUrl: '/api' }, queryClient: queryClient, children: _jsx(TestConsumer, {}) }));
|
|
47
|
+
expect(screen.getByTestId('has-client')).toHaveTextContent('Client available');
|
|
48
|
+
});
|
|
49
|
+
it('accepts custom QueryClient', () => {
|
|
50
|
+
const customQueryClient = new QueryClient();
|
|
51
|
+
render(_jsx(VeloxProvider, { config: { baseUrl: '/api' }, queryClient: customQueryClient, children: _jsx(TestConsumer, {}) }));
|
|
52
|
+
expect(screen.getByTestId('has-client')).toHaveTextContent('Client available');
|
|
53
|
+
});
|
|
54
|
+
it('creates default QueryClient when not provided', () => {
|
|
55
|
+
render(_jsx(VeloxProvider, { config: { baseUrl: '/api' }, children: _jsx(TestConsumer, {}) }));
|
|
56
|
+
expect(screen.getByTestId('has-client')).toHaveTextContent('Client available');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// useVeloxContext Tests
|
|
61
|
+
// ============================================================================
|
|
62
|
+
describe('useVeloxContext', () => {
|
|
63
|
+
it('throws when used outside VeloxProvider', () => {
|
|
64
|
+
// Suppress console.error for this test
|
|
65
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
66
|
+
expect(() => {
|
|
67
|
+
render(_jsx(TestConsumer, {}));
|
|
68
|
+
}).toThrow('useVeloxContext must be used within a VeloxProvider');
|
|
69
|
+
consoleSpy.mockRestore();
|
|
70
|
+
});
|
|
71
|
+
it('returns context with client when inside VeloxProvider', () => {
|
|
72
|
+
const queryClient = new QueryClient();
|
|
73
|
+
render(_jsx(VeloxProvider, { config: { baseUrl: '/api' }, queryClient: queryClient, children: _jsx(TestConsumer, {}) }));
|
|
74
|
+
expect(screen.getByTestId('has-client')).toHaveTextContent('Client available');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=provider.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.test.js","sourceRoot":"","sources":["../../../src/react/__tests__/provider.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hooks for VeloxTS API calls
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe hooks for queries and mutations
|
|
5
|
+
* with full integration with React Query.
|
|
6
|
+
*
|
|
7
|
+
* @module @veloxts/client/react/hooks
|
|
8
|
+
*/
|
|
9
|
+
import { type QueryClient, type UseMutationResult, type UseQueryResult } from '@tanstack/react-query';
|
|
10
|
+
import type { InferProcedureInput, InferProcedureOutput } from '../types.js';
|
|
11
|
+
import type { GetProcedure, GetProceduresFromCollection, VeloxUseMutationOptions, VeloxUseQueryOptions } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Type-safe query hook for VeloxTS procedures
|
|
14
|
+
*
|
|
15
|
+
* Wraps React Query's useQuery with automatic type inference from
|
|
16
|
+
* your backend procedure definitions. The hook automatically:
|
|
17
|
+
* - Builds a stable query key from namespace, procedure, and input
|
|
18
|
+
* - Provides full type safety for input and output
|
|
19
|
+
* - Integrates with React Query's caching and refetching
|
|
20
|
+
*
|
|
21
|
+
* @template TRouter - The router type (typeof imported procedures)
|
|
22
|
+
* @template TNamespace - The namespace key (e.g., 'users', 'posts')
|
|
23
|
+
* @template TProcedureName - The procedure name (e.g., 'getUser', 'listUsers')
|
|
24
|
+
*
|
|
25
|
+
* @param namespace - Resource namespace (e.g., 'users')
|
|
26
|
+
* @param procedureName - Procedure name (e.g., 'getUser')
|
|
27
|
+
* @param input - Input matching the procedure's input schema
|
|
28
|
+
* @param options - React Query options (optional)
|
|
29
|
+
*
|
|
30
|
+
* @returns UseQueryResult with typed data and error
|
|
31
|
+
*
|
|
32
|
+
* @example Basic usage
|
|
33
|
+
* ```tsx
|
|
34
|
+
* function UserProfile({ userId }: { userId: string }) {
|
|
35
|
+
* const { data: user, isLoading, error } = useQuery(
|
|
36
|
+
* 'users',
|
|
37
|
+
* 'getUser',
|
|
38
|
+
* { id: userId }
|
|
39
|
+
* );
|
|
40
|
+
*
|
|
41
|
+
* if (isLoading) return <div>Loading...</div>;
|
|
42
|
+
* if (error) return <div>Error: {error.message}</div>;
|
|
43
|
+
* if (!user) return <div>User not found</div>;
|
|
44
|
+
*
|
|
45
|
+
* return <div>{user.name}</div>;
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @example With options
|
|
50
|
+
* ```tsx
|
|
51
|
+
* const { data } = useQuery(
|
|
52
|
+
* 'users',
|
|
53
|
+
* 'listUsers',
|
|
54
|
+
* { page: 1, limit: 10 },
|
|
55
|
+
* {
|
|
56
|
+
* staleTime: 60_000,
|
|
57
|
+
* refetchOnWindowFocus: true,
|
|
58
|
+
* }
|
|
59
|
+
* );
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example Conditional query
|
|
63
|
+
* ```tsx
|
|
64
|
+
* const { data } = useQuery(
|
|
65
|
+
* 'users',
|
|
66
|
+
* 'getUser',
|
|
67
|
+
* { id: userId },
|
|
68
|
+
* { enabled: !!userId }
|
|
69
|
+
* );
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function useQuery<TRouter, TNamespace extends keyof TRouter, TProcedureName extends keyof GetProceduresFromCollection<TRouter[TNamespace]>>(namespace: TNamespace, procedureName: TProcedureName, input: InferProcedureInput<GetProcedure<TRouter, TNamespace, TProcedureName>>, options?: VeloxUseQueryOptions<InferProcedureOutput<GetProcedure<TRouter, TNamespace, TProcedureName>>>): UseQueryResult<InferProcedureOutput<GetProcedure<TRouter, TNamespace, TProcedureName>>, Error>;
|
|
73
|
+
/**
|
|
74
|
+
* Type-safe mutation hook for VeloxTS procedures
|
|
75
|
+
*
|
|
76
|
+
* Wraps React Query's useMutation with automatic type inference from
|
|
77
|
+
* your backend procedure definitions. The hook provides:
|
|
78
|
+
* - Full type safety for input and output
|
|
79
|
+
* - Access to mutation lifecycle callbacks (onSuccess, onError, etc.)
|
|
80
|
+
* - Optimistic update support via context
|
|
81
|
+
*
|
|
82
|
+
* @template TRouter - The router type
|
|
83
|
+
* @template TNamespace - The namespace key
|
|
84
|
+
* @template TProcedureName - The procedure name (should be a mutation)
|
|
85
|
+
*
|
|
86
|
+
* @param namespace - Resource namespace (e.g., 'users')
|
|
87
|
+
* @param procedureName - Procedure name (e.g., 'createUser')
|
|
88
|
+
* @param options - React Query mutation options (optional)
|
|
89
|
+
*
|
|
90
|
+
* @returns UseMutationResult with typed variables, data, and error
|
|
91
|
+
*
|
|
92
|
+
* @example Basic usage
|
|
93
|
+
* ```tsx
|
|
94
|
+
* function CreateUserForm() {
|
|
95
|
+
* const { mutate: createUser, isPending, error } = useMutation(
|
|
96
|
+
* 'users',
|
|
97
|
+
* 'createUser'
|
|
98
|
+
* );
|
|
99
|
+
*
|
|
100
|
+
* const handleSubmit = (e: FormEvent) => {
|
|
101
|
+
* e.preventDefault();
|
|
102
|
+
* createUser({ name: 'Alice', email: 'alice@example.com' });
|
|
103
|
+
* };
|
|
104
|
+
*
|
|
105
|
+
* return (
|
|
106
|
+
* <form onSubmit={handleSubmit}>
|
|
107
|
+
* <button type="submit" disabled={isPending}>
|
|
108
|
+
* {isPending ? 'Creating...' : 'Create User'}
|
|
109
|
+
* </button>
|
|
110
|
+
* {error && <div>{error.message}</div>}
|
|
111
|
+
* </form>
|
|
112
|
+
* );
|
|
113
|
+
* }
|
|
114
|
+
* ```
|
|
115
|
+
*
|
|
116
|
+
* @example With cache invalidation
|
|
117
|
+
* ```tsx
|
|
118
|
+
* const queryClient = useQueryClient();
|
|
119
|
+
*
|
|
120
|
+
* const { mutate } = useMutation('users', 'createUser', {
|
|
121
|
+
* onSuccess: () => {
|
|
122
|
+
* queryClient.invalidateQueries({ queryKey: ['users', 'listUsers'] });
|
|
123
|
+
* },
|
|
124
|
+
* });
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @example With optimistic update
|
|
128
|
+
* ```tsx
|
|
129
|
+
* const { mutate } = useMutation('users', 'updateUser', {
|
|
130
|
+
* onMutate: async (newUser) => {
|
|
131
|
+
* await queryClient.cancelQueries({ queryKey: ['users', 'getUser', { id: newUser.id }] });
|
|
132
|
+
* const previousUser = queryClient.getQueryData(['users', 'getUser', { id: newUser.id }]);
|
|
133
|
+
* queryClient.setQueryData(['users', 'getUser', { id: newUser.id }], newUser);
|
|
134
|
+
* return { previousUser };
|
|
135
|
+
* },
|
|
136
|
+
* onError: (err, newUser, context) => {
|
|
137
|
+
* if (context?.previousUser) {
|
|
138
|
+
* queryClient.setQueryData(['users', 'getUser', { id: newUser.id }], context.previousUser);
|
|
139
|
+
* }
|
|
140
|
+
* },
|
|
141
|
+
* });
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
export declare function useMutation<TRouter, TNamespace extends keyof TRouter, TProcedureName extends keyof GetProceduresFromCollection<TRouter[TNamespace]>, TContext = unknown>(namespace: TNamespace, procedureName: TProcedureName, options?: VeloxUseMutationOptions<InferProcedureOutput<GetProcedure<TRouter, TNamespace, TProcedureName>>, InferProcedureInput<GetProcedure<TRouter, TNamespace, TProcedureName>>, Error, TContext>): UseMutationResult<InferProcedureOutput<GetProcedure<TRouter, TNamespace, TProcedureName>>, Error, InferProcedureInput<GetProcedure<TRouter, TNamespace, TProcedureName>>, TContext>;
|
|
145
|
+
/**
|
|
146
|
+
* Hook to access React Query's QueryClient for manual cache operations
|
|
147
|
+
*
|
|
148
|
+
* This is a direct re-export of React Query's useQueryClient for convenience.
|
|
149
|
+
* Use this for manual cache invalidation, prefetching, or optimistic updates.
|
|
150
|
+
*
|
|
151
|
+
* @returns The QueryClient instance
|
|
152
|
+
*
|
|
153
|
+
* @example Cache invalidation
|
|
154
|
+
* ```tsx
|
|
155
|
+
* function MyComponent() {
|
|
156
|
+
* const queryClient = useQueryClient();
|
|
157
|
+
* const { mutate } = useMutation('users', 'createUser', {
|
|
158
|
+
* onSuccess: () => {
|
|
159
|
+
* // Invalidate and refetch users list
|
|
160
|
+
* queryClient.invalidateQueries({ queryKey: ['users', 'listUsers'] });
|
|
161
|
+
* },
|
|
162
|
+
* });
|
|
163
|
+
* }
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @example Prefetching
|
|
167
|
+
* ```tsx
|
|
168
|
+
* function UserListItem({ userId }: { userId: string }) {
|
|
169
|
+
* const queryClient = useQueryClient();
|
|
170
|
+
*
|
|
171
|
+
* const handleMouseEnter = () => {
|
|
172
|
+
* // Prefetch user data on hover
|
|
173
|
+
* queryClient.prefetchQuery({
|
|
174
|
+
* queryKey: ['users', 'getUser', { id: userId }],
|
|
175
|
+
* queryFn: () => api.users.getUser({ id: userId }),
|
|
176
|
+
* });
|
|
177
|
+
* };
|
|
178
|
+
* }
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
export declare function useQueryClient(): QueryClient;
|
|
182
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAIpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,KAAK,EACV,YAAY,EACZ,2BAA2B,EAC3B,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAOpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EACP,UAAU,SAAS,MAAM,OAAO,EAChC,cAAc,SAAS,MAAM,2BAA2B,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,EAE7E,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,EAC7B,KAAK,EAAE,mBAAmB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,EAC7E,OAAO,CAAC,EAAE,oBAAoB,CAC5B,oBAAoB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,CACxE,GACA,cAAc,CAAC,oBAAoB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,CA2BhG;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EACP,UAAU,SAAS,MAAM,OAAO,EAChC,cAAc,SAAS,MAAM,2BAA2B,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,EAC7E,QAAQ,GAAG,OAAO,EAElB,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,EAC7B,OAAO,CAAC,EAAE,uBAAuB,CAC/B,oBAAoB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,EACvE,mBAAmB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,EACtE,KAAK,EACL,QAAQ,CACT,GACA,iBAAiB,CAClB,oBAAoB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,EACvE,KAAK,EACL,mBAAmB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,EACtE,QAAQ,CACT,CAwBA;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAE5C"}
|