@veloxts/client 0.4.2 → 0.4.4
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 +37 -13
- package/LICENSE +0 -21
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for React hooks integration
|
|
3
|
+
*
|
|
4
|
+
* Provides type utilities for building type-safe React Query hooks
|
|
5
|
+
* that work with VeloxTS procedure definitions.
|
|
6
|
+
*
|
|
7
|
+
* @module @veloxts/client/react/types
|
|
8
|
+
*/
|
|
9
|
+
import type { UseMutationOptions, UseQueryOptions } from '@tanstack/react-query';
|
|
10
|
+
import type { ClientConfig, ClientFromRouter, InferProcedureInput, InferProcedureOutput, ProcedureCollection } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Extracts a specific procedure from the router type
|
|
13
|
+
*
|
|
14
|
+
* Enables type inference for procedure input/output in hooks.
|
|
15
|
+
*
|
|
16
|
+
* @template TRouter - The router type (collection of procedure collections)
|
|
17
|
+
* @template TNamespace - The namespace key (e.g., 'users', 'posts')
|
|
18
|
+
* @template TProcedureName - The procedure name (e.g., 'getUser', 'listUsers')
|
|
19
|
+
*/
|
|
20
|
+
export type GetProcedure<TRouter, TNamespace extends keyof TRouter, TProcedureName extends keyof GetProceduresFromCollection<TRouter[TNamespace]>> = TRouter[TNamespace] extends ProcedureCollection<infer TProcedures> ? TProcedureName extends keyof TProcedures ? TProcedures[TProcedureName] : never : never;
|
|
21
|
+
/**
|
|
22
|
+
* Extracts the procedures record from a collection
|
|
23
|
+
*
|
|
24
|
+
* @template TCollection - The procedure collection type
|
|
25
|
+
*/
|
|
26
|
+
export type GetProceduresFromCollection<TCollection> = TCollection extends ProcedureCollection ? TCollection['procedures'] : never;
|
|
27
|
+
/**
|
|
28
|
+
* Options for useQuery hook
|
|
29
|
+
*
|
|
30
|
+
* Omits queryKey and queryFn since those are provided automatically
|
|
31
|
+
* based on the procedure namespace, name, and input.
|
|
32
|
+
*
|
|
33
|
+
* @template TData - The expected response data type
|
|
34
|
+
* @template TError - The error type (defaults to Error)
|
|
35
|
+
*/
|
|
36
|
+
export type VeloxUseQueryOptions<TData, TError = Error> = Omit<UseQueryOptions<TData, TError>, 'queryKey' | 'queryFn'>;
|
|
37
|
+
/**
|
|
38
|
+
* Options for useMutation hook
|
|
39
|
+
*
|
|
40
|
+
* Omits mutationFn since that's provided automatically
|
|
41
|
+
* based on the procedure namespace and name.
|
|
42
|
+
*
|
|
43
|
+
* @template TData - The expected response data type
|
|
44
|
+
* @template TInput - The mutation input type
|
|
45
|
+
* @template TError - The error type (defaults to Error)
|
|
46
|
+
* @template TContext - The mutation context type
|
|
47
|
+
*/
|
|
48
|
+
export type VeloxUseMutationOptions<TData, TInput, TError = Error, TContext = unknown> = Omit<UseMutationOptions<TData, TError, TInput, TContext>, 'mutationFn'>;
|
|
49
|
+
/**
|
|
50
|
+
* Query key structure for VeloxTS
|
|
51
|
+
*
|
|
52
|
+
* Format: [namespace, procedureName, input?]
|
|
53
|
+
*
|
|
54
|
+
* This structure enables:
|
|
55
|
+
* - Invalidating all queries for a namespace: `['users']`
|
|
56
|
+
* - Invalidating a specific procedure: `['users', 'getUser']`
|
|
57
|
+
* - Invalidating a specific query: `['users', 'getUser', { id: '123' }]`
|
|
58
|
+
*/
|
|
59
|
+
export type VeloxQueryKey = readonly [string, string] | readonly [string, string, Record<string, unknown>];
|
|
60
|
+
/**
|
|
61
|
+
* Context value provided by VeloxProvider
|
|
62
|
+
*
|
|
63
|
+
* @template TRouter - The router type for type-safe client access
|
|
64
|
+
*/
|
|
65
|
+
export interface VeloxContextValue<TRouter> {
|
|
66
|
+
/** The typed client instance */
|
|
67
|
+
readonly client: ClientFromRouter<TRouter>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Props for VeloxProvider component
|
|
71
|
+
*
|
|
72
|
+
* @template _TRouter - The router type for type-safe client configuration (used for generic inference)
|
|
73
|
+
*/
|
|
74
|
+
export interface VeloxProviderProps<_TRouter> {
|
|
75
|
+
/** React children to render within the provider */
|
|
76
|
+
readonly children: React.ReactNode;
|
|
77
|
+
/** Client configuration (baseUrl, headers, etc.) */
|
|
78
|
+
readonly config: ClientConfig;
|
|
79
|
+
/** Optional pre-configured QueryClient instance */
|
|
80
|
+
readonly queryClient?: import('@tanstack/react-query').QueryClient;
|
|
81
|
+
}
|
|
82
|
+
export type { InferProcedureInput, InferProcedureOutput, ProcedureCollection, ClientConfig, ClientFromRouter, };
|
|
83
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEjF,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAMrB;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,CACtB,OAAO,EACP,UAAU,SAAS,MAAM,OAAO,EAChC,cAAc,SAAS,MAAM,2BAA2B,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAC3E,OAAO,CAAC,UAAU,CAAC,SAAS,mBAAmB,CAAC,MAAM,WAAW,CAAC,GAClE,cAAc,SAAS,MAAM,WAAW,GACtC,WAAW,CAAC,cAAc,CAAC,GAC3B,KAAK,GACP,KAAK,CAAC;AAEV;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,CAAC,WAAW,IAAI,WAAW,SAAS,mBAAmB,GAC1F,WAAW,CAAC,YAAY,CAAC,GACzB,KAAK,CAAC;AAMV;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,IAAI,CAC5D,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,EAC9B,UAAU,GAAG,SAAS,CACvB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,QAAQ,GAAG,OAAO,IAAI,IAAI,CAC3F,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EACnD,YAAY,CACb,CAAC;AAMF;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GACrB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GACzB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAMvD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB,CAAC,OAAO;IACxC,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;CAC5C;AAED;;;;GAIG;AAEH,MAAM,WAAW,kBAAkB,CAAC,QAAQ;IAC1C,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,uBAAuB,EAAE,WAAW,CAAC;CACpE;AAMD,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,GACjB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for React hooks integration
|
|
3
|
+
*
|
|
4
|
+
* Provides type utilities for building type-safe React Query hooks
|
|
5
|
+
* that work with VeloxTS procedure definitions.
|
|
6
|
+
*
|
|
7
|
+
* @module @veloxts/client/react/types
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for React Query integration
|
|
3
|
+
*
|
|
4
|
+
* Provides query key builders and cache invalidation helpers
|
|
5
|
+
* for consistent and predictable caching behavior.
|
|
6
|
+
*
|
|
7
|
+
* @module @veloxts/client/react/utils
|
|
8
|
+
*/
|
|
9
|
+
import type { QueryClient } from '@tanstack/react-query';
|
|
10
|
+
import type { VeloxQueryKey } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Builds a stable query key for React Query
|
|
13
|
+
*
|
|
14
|
+
* Query keys are structured as: [namespace, procedureName, input?]
|
|
15
|
+
* This enables efficient cache invalidation by namespace or procedure.
|
|
16
|
+
*
|
|
17
|
+
* The key structure follows React Query best practices:
|
|
18
|
+
* - Keys are arrays for hierarchical invalidation
|
|
19
|
+
* - Input is serialized for stable identity
|
|
20
|
+
*
|
|
21
|
+
* @param namespace - The procedure namespace (e.g., 'users')
|
|
22
|
+
* @param procedureName - The procedure name (e.g., 'getUser')
|
|
23
|
+
* @param input - Optional input parameters
|
|
24
|
+
* @returns A stable query key array
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Query with no input
|
|
29
|
+
* buildQueryKey('health', 'check');
|
|
30
|
+
* // => ['health', 'check']
|
|
31
|
+
*
|
|
32
|
+
* // Query with object input
|
|
33
|
+
* buildQueryKey('users', 'getUser', { id: '123' });
|
|
34
|
+
* // => ['users', 'getUser', { id: '123' }]
|
|
35
|
+
*
|
|
36
|
+
* // Query with primitive input (wrapped)
|
|
37
|
+
* buildQueryKey('users', 'getCount', 10);
|
|
38
|
+
* // => ['users', 'getCount', { value: 10 }]
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildQueryKey(namespace: string, procedureName: string, input?: unknown): VeloxQueryKey;
|
|
42
|
+
/**
|
|
43
|
+
* Invalidates all queries for a namespace
|
|
44
|
+
*
|
|
45
|
+
* This is useful after mutations that may affect multiple resources
|
|
46
|
+
* within the same namespace.
|
|
47
|
+
*
|
|
48
|
+
* @param queryClient - The React Query client instance
|
|
49
|
+
* @param namespace - The namespace to invalidate (e.g., 'users')
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const queryClient = useQueryClient();
|
|
54
|
+
*
|
|
55
|
+
* // After deleting a user, invalidate all user queries
|
|
56
|
+
* await invalidateNamespace(queryClient, 'users');
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function invalidateNamespace(queryClient: QueryClient, namespace: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Invalidates all queries for a specific procedure
|
|
62
|
+
*
|
|
63
|
+
* This is useful when you want to refetch all instances of a specific
|
|
64
|
+
* query without affecting other queries in the same namespace.
|
|
65
|
+
*
|
|
66
|
+
* @param queryClient - The React Query client instance
|
|
67
|
+
* @param namespace - The procedure namespace (e.g., 'users')
|
|
68
|
+
* @param procedureName - The procedure name (e.g., 'getUser')
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const queryClient = useQueryClient();
|
|
73
|
+
*
|
|
74
|
+
* // After updating a user, invalidate all getUser queries
|
|
75
|
+
* await invalidateProcedure(queryClient, 'users', 'getUser');
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare function invalidateProcedure(queryClient: QueryClient, namespace: string, procedureName: string): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Invalidates a specific query by its exact key
|
|
81
|
+
*
|
|
82
|
+
* This is useful when you know the exact input and want to invalidate
|
|
83
|
+
* only that specific cached query.
|
|
84
|
+
*
|
|
85
|
+
* @param queryClient - The React Query client instance
|
|
86
|
+
* @param namespace - The procedure namespace (e.g., 'users')
|
|
87
|
+
* @param procedureName - The procedure name (e.g., 'getUser')
|
|
88
|
+
* @param input - The exact input used in the query
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const queryClient = useQueryClient();
|
|
93
|
+
*
|
|
94
|
+
* // After updating user 123, invalidate only that specific query
|
|
95
|
+
* await invalidateQuery(queryClient, 'users', 'getUser', { id: '123' });
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare function invalidateQuery(queryClient: QueryClient, namespace: string, procedureName: string, input?: unknown): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Gets cached data for a specific query
|
|
101
|
+
*
|
|
102
|
+
* Useful for optimistic updates where you need the current cached value.
|
|
103
|
+
*
|
|
104
|
+
* @param queryClient - The React Query client instance
|
|
105
|
+
* @param namespace - The procedure namespace
|
|
106
|
+
* @param procedureName - The procedure name
|
|
107
|
+
* @param input - The query input
|
|
108
|
+
* @returns The cached data or undefined if not cached
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const queryClient = useQueryClient();
|
|
113
|
+
*
|
|
114
|
+
* // Get current cached user before optimistic update
|
|
115
|
+
* const previousUser = getQueryData<User>(
|
|
116
|
+
* queryClient,
|
|
117
|
+
* 'users',
|
|
118
|
+
* 'getUser',
|
|
119
|
+
* { id: '123' }
|
|
120
|
+
* );
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare function getQueryData<TData>(queryClient: QueryClient, namespace: string, procedureName: string, input?: unknown): TData | undefined;
|
|
124
|
+
/**
|
|
125
|
+
* Sets cached data for a specific query
|
|
126
|
+
*
|
|
127
|
+
* Useful for optimistic updates where you want to update the cache
|
|
128
|
+
* immediately before the mutation completes.
|
|
129
|
+
*
|
|
130
|
+
* @param queryClient - The React Query client instance
|
|
131
|
+
* @param namespace - The procedure namespace
|
|
132
|
+
* @param procedureName - The procedure name
|
|
133
|
+
* @param input - The query input
|
|
134
|
+
* @param data - The data to cache
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* const queryClient = useQueryClient();
|
|
139
|
+
*
|
|
140
|
+
* // Optimistically update user in cache
|
|
141
|
+
* setQueryData<User>(
|
|
142
|
+
* queryClient,
|
|
143
|
+
* 'users',
|
|
144
|
+
* 'getUser',
|
|
145
|
+
* { id: '123' },
|
|
146
|
+
* { ...previousUser, name: 'New Name' }
|
|
147
|
+
* );
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
export declare function setQueryData<TData>(queryClient: QueryClient, namespace: string, procedureName: string, input: unknown, data: TData): void;
|
|
151
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/react/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,OAAO,GACd,aAAa,CAYf;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,IAAI,CAAC,CAGf;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAChC,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,OAAO,GACd,KAAK,GAAG,SAAS,CAGnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAChC,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,KAAK,GACV,IAAI,CAGN"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for React Query integration
|
|
3
|
+
*
|
|
4
|
+
* Provides query key builders and cache invalidation helpers
|
|
5
|
+
* for consistent and predictable caching behavior.
|
|
6
|
+
*
|
|
7
|
+
* @module @veloxts/client/react/utils
|
|
8
|
+
*/
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Query Key Builders
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Builds a stable query key for React Query
|
|
14
|
+
*
|
|
15
|
+
* Query keys are structured as: [namespace, procedureName, input?]
|
|
16
|
+
* This enables efficient cache invalidation by namespace or procedure.
|
|
17
|
+
*
|
|
18
|
+
* The key structure follows React Query best practices:
|
|
19
|
+
* - Keys are arrays for hierarchical invalidation
|
|
20
|
+
* - Input is serialized for stable identity
|
|
21
|
+
*
|
|
22
|
+
* @param namespace - The procedure namespace (e.g., 'users')
|
|
23
|
+
* @param procedureName - The procedure name (e.g., 'getUser')
|
|
24
|
+
* @param input - Optional input parameters
|
|
25
|
+
* @returns A stable query key array
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* // Query with no input
|
|
30
|
+
* buildQueryKey('health', 'check');
|
|
31
|
+
* // => ['health', 'check']
|
|
32
|
+
*
|
|
33
|
+
* // Query with object input
|
|
34
|
+
* buildQueryKey('users', 'getUser', { id: '123' });
|
|
35
|
+
* // => ['users', 'getUser', { id: '123' }]
|
|
36
|
+
*
|
|
37
|
+
* // Query with primitive input (wrapped)
|
|
38
|
+
* buildQueryKey('users', 'getCount', 10);
|
|
39
|
+
* // => ['users', 'getCount', { value: 10 }]
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export function buildQueryKey(namespace, procedureName, input) {
|
|
43
|
+
if (input === undefined || input === null) {
|
|
44
|
+
return [namespace, procedureName];
|
|
45
|
+
}
|
|
46
|
+
// For objects, include directly in key for proper caching
|
|
47
|
+
if (typeof input === 'object') {
|
|
48
|
+
return [namespace, procedureName, input];
|
|
49
|
+
}
|
|
50
|
+
// For primitives, wrap in object to maintain consistent key structure
|
|
51
|
+
return [namespace, procedureName, { value: input }];
|
|
52
|
+
}
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Cache Invalidation Helpers
|
|
55
|
+
// ============================================================================
|
|
56
|
+
/**
|
|
57
|
+
* Invalidates all queries for a namespace
|
|
58
|
+
*
|
|
59
|
+
* This is useful after mutations that may affect multiple resources
|
|
60
|
+
* within the same namespace.
|
|
61
|
+
*
|
|
62
|
+
* @param queryClient - The React Query client instance
|
|
63
|
+
* @param namespace - The namespace to invalidate (e.g., 'users')
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const queryClient = useQueryClient();
|
|
68
|
+
*
|
|
69
|
+
* // After deleting a user, invalidate all user queries
|
|
70
|
+
* await invalidateNamespace(queryClient, 'users');
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export async function invalidateNamespace(queryClient, namespace) {
|
|
74
|
+
await queryClient.invalidateQueries({ queryKey: [namespace] });
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Invalidates all queries for a specific procedure
|
|
78
|
+
*
|
|
79
|
+
* This is useful when you want to refetch all instances of a specific
|
|
80
|
+
* query without affecting other queries in the same namespace.
|
|
81
|
+
*
|
|
82
|
+
* @param queryClient - The React Query client instance
|
|
83
|
+
* @param namespace - The procedure namespace (e.g., 'users')
|
|
84
|
+
* @param procedureName - The procedure name (e.g., 'getUser')
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const queryClient = useQueryClient();
|
|
89
|
+
*
|
|
90
|
+
* // After updating a user, invalidate all getUser queries
|
|
91
|
+
* await invalidateProcedure(queryClient, 'users', 'getUser');
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export async function invalidateProcedure(queryClient, namespace, procedureName) {
|
|
95
|
+
await queryClient.invalidateQueries({ queryKey: [namespace, procedureName] });
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Invalidates a specific query by its exact key
|
|
99
|
+
*
|
|
100
|
+
* This is useful when you know the exact input and want to invalidate
|
|
101
|
+
* only that specific cached query.
|
|
102
|
+
*
|
|
103
|
+
* @param queryClient - The React Query client instance
|
|
104
|
+
* @param namespace - The procedure namespace (e.g., 'users')
|
|
105
|
+
* @param procedureName - The procedure name (e.g., 'getUser')
|
|
106
|
+
* @param input - The exact input used in the query
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const queryClient = useQueryClient();
|
|
111
|
+
*
|
|
112
|
+
* // After updating user 123, invalidate only that specific query
|
|
113
|
+
* await invalidateQuery(queryClient, 'users', 'getUser', { id: '123' });
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export async function invalidateQuery(queryClient, namespace, procedureName, input) {
|
|
117
|
+
const queryKey = buildQueryKey(namespace, procedureName, input);
|
|
118
|
+
await queryClient.invalidateQueries({ queryKey });
|
|
119
|
+
}
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// Cache Data Accessors
|
|
122
|
+
// ============================================================================
|
|
123
|
+
/**
|
|
124
|
+
* Gets cached data for a specific query
|
|
125
|
+
*
|
|
126
|
+
* Useful for optimistic updates where you need the current cached value.
|
|
127
|
+
*
|
|
128
|
+
* @param queryClient - The React Query client instance
|
|
129
|
+
* @param namespace - The procedure namespace
|
|
130
|
+
* @param procedureName - The procedure name
|
|
131
|
+
* @param input - The query input
|
|
132
|
+
* @returns The cached data or undefined if not cached
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* const queryClient = useQueryClient();
|
|
137
|
+
*
|
|
138
|
+
* // Get current cached user before optimistic update
|
|
139
|
+
* const previousUser = getQueryData<User>(
|
|
140
|
+
* queryClient,
|
|
141
|
+
* 'users',
|
|
142
|
+
* 'getUser',
|
|
143
|
+
* { id: '123' }
|
|
144
|
+
* );
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export function getQueryData(queryClient, namespace, procedureName, input) {
|
|
148
|
+
const queryKey = buildQueryKey(namespace, procedureName, input);
|
|
149
|
+
return queryClient.getQueryData(queryKey);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Sets cached data for a specific query
|
|
153
|
+
*
|
|
154
|
+
* Useful for optimistic updates where you want to update the cache
|
|
155
|
+
* immediately before the mutation completes.
|
|
156
|
+
*
|
|
157
|
+
* @param queryClient - The React Query client instance
|
|
158
|
+
* @param namespace - The procedure namespace
|
|
159
|
+
* @param procedureName - The procedure name
|
|
160
|
+
* @param input - The query input
|
|
161
|
+
* @param data - The data to cache
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* const queryClient = useQueryClient();
|
|
166
|
+
*
|
|
167
|
+
* // Optimistically update user in cache
|
|
168
|
+
* setQueryData<User>(
|
|
169
|
+
* queryClient,
|
|
170
|
+
* 'users',
|
|
171
|
+
* 'getUser',
|
|
172
|
+
* { id: '123' },
|
|
173
|
+
* { ...previousUser, name: 'New Name' }
|
|
174
|
+
* );
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
export function setQueryData(queryClient, namespace, procedureName, input, data) {
|
|
178
|
+
const queryKey = buildQueryKey(namespace, procedureName, input);
|
|
179
|
+
queryClient.setQueryData(queryKey, data);
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/react/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAiB,EACjB,aAAqB,EACrB,KAAe;IAEf,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,CAAC,SAAS,EAAE,aAAa,CAAU,CAAC;IAC7C,CAAC;IAED,0DAA0D;IAC1D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,SAAS,EAAE,aAAa,EAAE,KAAgC,CAAU,CAAC;IAC/E,CAAC;IAED,sEAAsE;IACtE,OAAO,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAU,CAAC;AAC/D,CAAC;AAED,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAE/E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAwB,EACxB,SAAiB;IAEjB,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAwB,EACxB,SAAiB,EACjB,aAAqB;IAErB,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAwB,EACxB,SAAiB,EACjB,aAAqB,EACrB,KAAe;IAEf,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;IAChE,MAAM,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,YAAY,CAC1B,WAAwB,EACxB,SAAiB,EACjB,aAAqB,EACrB,KAAe;IAEf,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;IAChE,OAAO,WAAW,CAAC,YAAY,CAAQ,QAAQ,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,YAAY,CAC1B,WAAwB,EACxB,SAAiB,EACjB,aAAqB,EACrB,KAAc,EACd,IAAW;IAEX,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;IAChE,WAAW,CAAC,YAAY,CAAQ,QAAQ,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../src/test-setup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,kCAAkC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-setup.js","sourceRoot":"","sources":["../src/test-setup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,kCAAkC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/client",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "Type-safe frontend API client for VeloxTS framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,15 +9,46 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./react": {
|
|
14
|
+
"types": "./dist/react/index.d.ts",
|
|
15
|
+
"import": "./dist/react/index.js"
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
"files": [
|
|
15
19
|
"dist",
|
|
16
20
|
"README.md"
|
|
17
21
|
],
|
|
18
|
-
"
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"dev": "tsc --watch",
|
|
25
|
+
"type-check": "tsc --noEmit",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:watch": "vitest",
|
|
28
|
+
"test:coverage": "vitest run --coverage",
|
|
29
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@tanstack/react-query": "^5.0.0",
|
|
33
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependenciesMeta": {
|
|
36
|
+
"@tanstack/react-query": {
|
|
37
|
+
"optional": true
|
|
38
|
+
},
|
|
39
|
+
"react": {
|
|
40
|
+
"optional": true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
19
43
|
"devDependencies": {
|
|
44
|
+
"@tanstack/react-query": "5.62.11",
|
|
45
|
+
"@testing-library/jest-dom": "6.9.1",
|
|
46
|
+
"@testing-library/react": "16.3.0",
|
|
47
|
+
"@types/react": "18.3.18",
|
|
20
48
|
"@vitest/coverage-v8": "4.0.15",
|
|
49
|
+
"jsdom": "26.1.0",
|
|
50
|
+
"react": "18.3.1",
|
|
51
|
+
"react-dom": "18.3.1",
|
|
21
52
|
"typescript": "5.9.3",
|
|
22
53
|
"vitest": "4.0.15"
|
|
23
54
|
},
|
|
@@ -26,7 +57,9 @@
|
|
|
26
57
|
"client",
|
|
27
58
|
"api",
|
|
28
59
|
"fetch",
|
|
29
|
-
"typescript"
|
|
60
|
+
"typescript",
|
|
61
|
+
"react",
|
|
62
|
+
"react-query"
|
|
30
63
|
],
|
|
31
64
|
"license": "MIT",
|
|
32
65
|
"repository": {
|
|
@@ -39,14 +72,5 @@
|
|
|
39
72
|
},
|
|
40
73
|
"publishConfig": {
|
|
41
74
|
"access": "public"
|
|
42
|
-
},
|
|
43
|
-
"scripts": {
|
|
44
|
-
"build": "tsc",
|
|
45
|
-
"dev": "tsc --watch",
|
|
46
|
-
"type-check": "tsc --noEmit",
|
|
47
|
-
"test": "vitest run",
|
|
48
|
-
"test:watch": "vitest",
|
|
49
|
-
"test:coverage": "vitest run --coverage",
|
|
50
|
-
"clean": "rm -rf dist tsconfig.tsbuildinfo"
|
|
51
75
|
}
|
|
52
|
-
}
|
|
76
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 VeloxTS Framework Contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|