@@ -19,6 +19,7 @@ import {
1919 makeUrl ,
2020 marshal ,
2121 setupInvalidation ,
22+ setupOptimisticUpdate ,
2223 type APIContext ,
2324} from '../runtime/common' ;
2425
@@ -50,18 +51,21 @@ export const Provider = RequestHandlerContext.Provider;
5051 * @param url The request URL.
5152 * @param args The request args object, URL-encoded and appended as "?q=" parameter
5253 * @param options The react-query options object
54+ * @param fetch The fetch function to use for sending the HTTP request
55+ * @param optimisticUpdate Whether to enable automatic optimistic update
5356 * @returns useQuery hook
5457 */
5558export function useModelQuery < R > (
5659 model : string ,
5760 url : string ,
5861 args ?: unknown ,
5962 options ?: Omit < UseQueryOptions < R > , 'queryKey' > ,
60- fetch ?: FetchFn
63+ fetch ?: FetchFn ,
64+ optimisticUpdate = false
6165) {
6266 const reqUrl = makeUrl ( url , args ) ;
6367 return useQuery ( {
64- queryKey : getQueryKey ( model , url , args ) ,
68+ queryKey : getQueryKey ( model , url , args , false , optimisticUpdate ) ,
6569 queryFn : ( ) => fetcher < R , false > ( reqUrl , undefined , fetch , false ) ,
6670 ...options ,
6771 } ) ;
@@ -74,6 +78,7 @@ export function useModelQuery<R>(
7478 * @param url The request URL.
7579 * @param args The initial request args object, URL-encoded and appended as "?q=" parameter
7680 * @param options The react-query infinite query options object
81+ * @param fetch The fetch function to use for sending the HTTP request
7782 * @returns useInfiniteQuery hook
7883 */
7984export function useInfiniteModelQuery < R > (
@@ -84,14 +89,27 @@ export function useInfiniteModelQuery<R>(
8489 fetch ?: FetchFn
8590) {
8691 return useInfiniteQuery ( {
87- queryKey : getQueryKey ( model , url , args ) ,
92+ queryKey : getQueryKey ( model , url , args , true ) ,
8893 queryFn : ( { pageParam } ) => {
8994 return fetcher < R , false > ( makeUrl ( url , pageParam ?? args ) , undefined , fetch , false ) ;
9095 } ,
9196 ...options ,
9297 } ) ;
9398}
9499
100+ /**
101+ * Creates a react-query mutation
102+ *
103+ * @param model The name of the model under mutation.
104+ * @param method The HTTP method.
105+ * @param url The request URL.
106+ * @param modelMeta The model metadata.
107+ * @param options The react-query options.
108+ * @param fetch The fetch function to use for sending the HTTP request
109+ * @param invalidateQueries Whether to invalidate queries after mutation.
110+ * @param checkReadBack Whether to check for read back errors and return undefined if found.
111+ * @param optimisticUpdate Whether to enable automatic optimistic update
112+ */
95113export function useModelMutation < T , R = any , C extends boolean = boolean , Result = C extends true ? R | undefined : R > (
96114 model : string ,
97115 method : 'POST' | 'PUT' | 'DELETE' ,
@@ -100,7 +118,8 @@ export function useModelMutation<T, R = any, C extends boolean = boolean, Result
100118 options ?: Omit < UseMutationOptions < Result , unknown , T > , 'mutationFn' > ,
101119 fetch ?: FetchFn ,
102120 invalidateQueries = true ,
103- checkReadBack ?: C
121+ checkReadBack ?: C ,
122+ optimisticUpdate = false
104123) {
105124 const queryClient = useQueryClient ( ) ;
106125 const mutationFn = ( data : any ) => {
@@ -118,10 +137,11 @@ export function useModelMutation<T, R = any, C extends boolean = boolean, Result
118137 } ;
119138
120139 const finalOptions = { ...options , mutationFn } ;
121- if ( invalidateQueries ) {
140+ const operation = url . split ( '/' ) . pop ( ) ;
141+
142+ if ( operation ) {
122143 const { logging } = useContext ( RequestHandlerContext ) ;
123- const operation = url . split ( '/' ) . pop ( ) ;
124- if ( operation ) {
144+ if ( invalidateQueries ) {
125145 setupInvalidation (
126146 model ,
127147 operation ,
@@ -131,6 +151,19 @@ export function useModelMutation<T, R = any, C extends boolean = boolean, Result
131151 logging
132152 ) ;
133153 }
154+
155+ if ( optimisticUpdate ) {
156+ setupOptimisticUpdate (
157+ model ,
158+ operation ,
159+ modelMeta ,
160+ finalOptions ,
161+ queryClient . getQueryCache ( ) . getAll ( ) ,
162+ ( queryKey , data ) => queryClient . setQueryData < unknown > ( queryKey , data ) ,
163+ invalidateQueries ? ( predicate ) => queryClient . invalidateQueries ( { predicate } ) : undefined ,
164+ logging
165+ ) ;
166+ }
134167 }
135168
136169 return useMutation ( finalOptions ) ;
0 commit comments