@@ -19,6 +19,7 @@ import {
19
19
makeUrl ,
20
20
marshal ,
21
21
setupInvalidation ,
22
+ setupOptimisticUpdate ,
22
23
type APIContext ,
23
24
} from '../runtime/common' ;
24
25
@@ -50,18 +51,21 @@ export const Provider = RequestHandlerContext.Provider;
50
51
* @param url The request URL.
51
52
* @param args The request args object, URL-encoded and appended as "?q=" parameter
52
53
* @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
53
56
* @returns useQuery hook
54
57
*/
55
58
export function useModelQuery < R > (
56
59
model : string ,
57
60
url : string ,
58
61
args ?: unknown ,
59
62
options ?: Omit < UseQueryOptions < R > , 'queryKey' > ,
60
- fetch ?: FetchFn
63
+ fetch ?: FetchFn ,
64
+ optimisticUpdate = false
61
65
) {
62
66
const reqUrl = makeUrl ( url , args ) ;
63
67
return useQuery ( {
64
- queryKey : getQueryKey ( model , url , args ) ,
68
+ queryKey : getQueryKey ( model , url , args , false , optimisticUpdate ) ,
65
69
queryFn : ( ) => fetcher < R , false > ( reqUrl , undefined , fetch , false ) ,
66
70
...options ,
67
71
} ) ;
@@ -74,6 +78,7 @@ export function useModelQuery<R>(
74
78
* @param url The request URL.
75
79
* @param args The initial request args object, URL-encoded and appended as "?q=" parameter
76
80
* @param options The react-query infinite query options object
81
+ * @param fetch The fetch function to use for sending the HTTP request
77
82
* @returns useInfiniteQuery hook
78
83
*/
79
84
export function useInfiniteModelQuery < R > (
@@ -84,14 +89,27 @@ export function useInfiniteModelQuery<R>(
84
89
fetch ?: FetchFn
85
90
) {
86
91
return useInfiniteQuery ( {
87
- queryKey : getQueryKey ( model , url , args ) ,
92
+ queryKey : getQueryKey ( model , url , args , true ) ,
88
93
queryFn : ( { pageParam } ) => {
89
94
return fetcher < R , false > ( makeUrl ( url , pageParam ?? args ) , undefined , fetch , false ) ;
90
95
} ,
91
96
...options ,
92
97
} ) ;
93
98
}
94
99
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
+ */
95
113
export function useModelMutation < T , R = any , C extends boolean = boolean , Result = C extends true ? R | undefined : R > (
96
114
model : string ,
97
115
method : 'POST' | 'PUT' | 'DELETE' ,
@@ -100,7 +118,8 @@ export function useModelMutation<T, R = any, C extends boolean = boolean, Result
100
118
options ?: Omit < UseMutationOptions < Result , unknown , T > , 'mutationFn' > ,
101
119
fetch ?: FetchFn ,
102
120
invalidateQueries = true ,
103
- checkReadBack ?: C
121
+ checkReadBack ?: C ,
122
+ optimisticUpdate = false
104
123
) {
105
124
const queryClient = useQueryClient ( ) ;
106
125
const mutationFn = ( data : any ) => {
@@ -118,10 +137,11 @@ export function useModelMutation<T, R = any, C extends boolean = boolean, Result
118
137
} ;
119
138
120
139
const finalOptions = { ...options , mutationFn } ;
121
- if ( invalidateQueries ) {
140
+ const operation = url . split ( '/' ) . pop ( ) ;
141
+
142
+ if ( operation ) {
122
143
const { logging } = useContext ( RequestHandlerContext ) ;
123
- const operation = url . split ( '/' ) . pop ( ) ;
124
- if ( operation ) {
144
+ if ( invalidateQueries ) {
125
145
setupInvalidation (
126
146
model ,
127
147
operation ,
@@ -131,6 +151,19 @@ export function useModelMutation<T, R = any, C extends boolean = boolean, Result
131
151
logging
132
152
) ;
133
153
}
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
+ }
134
167
}
135
168
136
169
return useMutation ( finalOptions ) ;
0 commit comments