@@ -140,7 +140,47 @@ export function useDeleteTask() {
140140 return client . deleteTask ( taskId ) ;
141141 } ,
142142 {
143- onSuccess : ( ) => {
143+ onMutate : async ( taskId ) => {
144+ // Cancel outgoing refetches to avoid overwriting optimistic update
145+ await queryClient . cancelQueries ( { queryKey : taskKeys . lists ( ) } ) ;
146+
147+ // Snapshot all task list queries for rollback
148+ const previousQueries : Array < { queryKey : unknown ; data : Task [ ] } > = [ ] ;
149+ const queries = queryClient . getQueriesData < Task [ ] > ( {
150+ queryKey : taskKeys . lists ( ) ,
151+ } ) ;
152+ for ( const [ queryKey , data ] of queries ) {
153+ if ( data ) {
154+ previousQueries . push ( { queryKey, data } ) ;
155+ }
156+ }
157+
158+ // Optimistically remove the task from all list queries
159+ queryClient . setQueriesData < Task [ ] > (
160+ { queryKey : taskKeys . lists ( ) } ,
161+ ( old ) => old ?. filter ( ( task ) => task . id !== taskId ) ,
162+ ) ;
163+
164+ return { previousQueries } ;
165+ } ,
166+ onError : ( _err , _taskId , context ) => {
167+ // Rollback all queries on error
168+ const ctx = context as
169+ | {
170+ previousQueries : Array < {
171+ queryKey : readonly unknown [ ] ;
172+ data : Task [ ] ;
173+ } > ;
174+ }
175+ | undefined ;
176+ if ( ctx ?. previousQueries ) {
177+ for ( const { queryKey, data } of ctx . previousQueries ) {
178+ queryClient . setQueryData ( queryKey , data ) ;
179+ }
180+ }
181+ } ,
182+ onSettled : ( ) => {
183+ // Always refetch to ensure sync with server
144184 queryClient . invalidateQueries ( { queryKey : taskKeys . lists ( ) } ) ;
145185 } ,
146186 } ,
0 commit comments