Mutations and Invalidation
Use mutations and invalidation with the current published Askr packages.
@askrjs/askr/data0.0.59
How to use mutations and invalidation
Describe the write, the cache prefixes it affects, and whether successful writes invalidate those prefixes.
- Import the published @askrjs/askr/data entrypoint.
- Keep mutations and invalidation configuration next to the component, route, or server composition root that owns it.
- Handle pending, unavailable, cancellation, and failure states, then verify the production path.
import { createMutation } from '@askrjs/askr/data';
const renameProject = createMutation({
action: ({ id, name }, { signal }) => api.projects.rename(id, name, { signal }),
affects: ({ id }) => ['project:' + id, 'projects'],
afterSuccess: 'invalidate',
});
await renameProject.execute({ id, name });Create a mutation
createMutation(options) takes an action(input, { signal }) function that performs the write and returns the result. What comes back is a Mutation<TInput, TResult> with execute(input), abort(), and reset() methods, plus status fields you read directly rather than through a callback.
Write lifecycle
A mutation's status is always one of 'idle', 'pending', 'success', or 'error', and the pending/error/result fields line up with whichever status you're in — result is only populated once status is 'success', error only once it's 'error'. Calling reset() puts it back to idle, and abort() cancels an in-flight execute() via the signal passed into the action function.
Targeted invalidation
The affects(input, result) option on MutationOptions maps a completed write to the list of query key prefixes it should invalidate, so a successful mutation automatically triggers invalidate() on exactly the queries it touched rather than clearing the whole cache. For writes that happen outside a mutation entirely, invalidate(prefix, options) and queryScope().invalidate() are available directly, and invalidateOnInterval() covers periodic invalidation gated by options like visibleOnly or focusedOnly.
Optimistic UI
There's no dedicated optimistic-value API on MutationOptions — no optimisticData field to set. Optimistic UI is built by hand: keep local state for the value you're predicting, render it while mutation.status is 'pending', and reconcile or roll it back once status settles to 'success' or 'error'. The afterSuccess: 'invalidate' option can be paired with this to refetch the real data as soon as the write completes, replacing your optimistic guess with the server's actual response.