**Hook signature (TypeScript)**ts
type OptimisticUpdate<TData, TVariables> = (vars: TVariables, current: TData | undefined) => TData;
type Rollback<TData> = (prev: TData | undefined) => void;
function useOptimisticMutation<TData, TVariables>({
mutationFn,
optimisticUpdate,
rollback,
onConflict,
onError,
onSuccess,
cacheClient, // e.g., QueryClient from react-query or ApolloClient
}: {
mutationFn: (vars: TVariables) => Promise<TData>;
optimisticUpdate: OptimisticUpdate<TData, TVariables>;
rollback?: Rollback<TData>;
onConflict?: (local: TData, remote: TData) => Promise<'merge' | 'overwrite' | 'reject'>;
onError?: (error: unknown, vars: TVariables, context?: any) => void;
onSuccess?: (data: TData, vars: TVariables) => void;
cacheClient?: any;
}) : {
mutate: (vars: TVariables) => Promise<void>;
status: 'idle' | 'optimistic' | 'committing' | 'success' | 'error';
error?: unknown;
rollback: () => void;
}
**High-level implementation plan**- Inputs: mutation function, optimisticUpdate (pure), optional rollback, conflict callback, error/success callbacks, cache client.- Flow: 1. Snapshot current cache state (per affected query keys). 2. Apply optimisticUpdate synchronously to cache (set status 'optimistic'); store snapshot in context. 3. Call mutationFn; set status 'committing' when network resolves. 4. On success: fetch/compare server response with local; if mismatch invoke onConflict to decide merge/overwrite/reject. Update cache accordingly, call onSuccess, clear snapshots. 5. On error or reject: run rollback (or restore snapshot), set status 'error', call onError.- Error handling: try/catch around mutationFn, ensure finally restores consistency; expose error and rollback API.- Integration points: use QueryClient.setQueryData/getQueryData for React Query, Apollo cache.writeQuery/readQuery for Apollo; use cache keys provided or inferred from variables.- Conflict detection: shallow/deep diff between optimistic and server data; defer to onConflict for merge strategy; support automatic 3-way merge if provided.- Concurrency: queue concurrent optimistic updates per resource, chain snapshots, or use version tags from server to detect stale writes.**Testing strategy**- Unit tests for optimisticUpdate and rollback functions.- Integration tests mocking network: - Success path: optimistic applied, then server response merges/overwrites. - Error path: optimistic applied, then network error triggers rollback. - Conflict path: server returns divergent data and onConflict behaviors validated.- Use React Testing Library + MSW to simulate network and assert cache states and UI transitions.- Add property-based tests for merges and snapshot/restores; include race-condition tests with multiple simultaneous mutations.