BloomMutation<T, P> class

Asynchronous mutation manager with automated optimistic updates, automatic rollback, and cache invalidation.

BloomMutation orchestrates side-effecting operations (such as HTTP POST, PUT, DELETE):

  • Optimistic Updates: Immediately writes anticipated state changes into the BloomData cache via optimisticData before the network response completes.
  • Automated Rollback: If the network call fails or throws, BloomMutation automatically reverts the cache entry at optimisticKey to its exact pre-mutation snapshot.
  • Cache Invalidation: Automatically calls BloomData.invalidateQueries for all keys in invalidateKeys upon successful completion, triggering background refetches in active BloomQuery instances.
  • Reactive Signals: Exposes data, status, and error as ReadonlySignal instances, allowing UI components to track loading and error states reactively.

Execution Flow

  1. status changes to MutationStatus.pending and error is cleared to null.
  2. If optimisticKey and optimisticData are set, snapshot current cache data and apply optimistic update.
  3. onMutate hook is executed; its returned value becomes the context.
  4. mutateFn is executed with the supplied parameters.
  5. On Success:
  6. On Error:

Backend Behavior

  • Browser (mount): Subscribed Live descriptors update reactively across pending, success, and error states.
  • SSR (renderToHtml): Safe to instantiate. Initial state is MutationStatus.idle.

Example

final createTodo = mutation<Todo, String>(
  mutate: (title) => httpClient.post<Todo>('/todos', body: {'title': title}),
  optimisticKey: ['todos'],
  optimisticData: (title, oldTodos) => [
    ...?oldTodos as List<Todo>?,
    Todo(id: 'temp-id', title: title, done: false),
  ],
  invalidateKeys: [['todos']],
  onError: (err, title, context) => print('Failed to add todo: $err'),
);

BloomNode buildAddTodoForm() {
  return Div(
    children: [
      Button(
        text: 'Create',
        on: {'click': (e) => createTodo.mutate('Buy groceries')},
      ),
      Live(() => createTodo.isPending ? Span(text: ' Saving...') : Span(text: '')),
    ],
  );
}

See also:

  • mutation, the convenience factory function for creating mutations.
  • BloomQuery, for managing cached queries that this mutation invalidates.
  • BloomData, the underlying cache manager.

Constructors

BloomMutation({required MutationFn<T, P> mutateFn, List? optimisticKey, OptimisticUpdater<T, P>? optimisticData, List<List> invalidateKeys = const [], OnMutateCallback<P>? onMutate, OnSuccessCallback<T, P>? onSuccess, OnErrorCallback<P>? onError, OnSettledCallback<T, P>? onSettled})
Creates a BloomMutation instance with execution hooks and cache invalidation targets.

Properties

data ReadonlySignal<T?>
Reactive signal holding the latest successful result data, or null if unexecuted or failed.
no setter
error ReadonlySignal<Object?>
Reactive signal holding the unhandled exception thrown during execution, or null if idle/successful.
no setter
hashCode int
The hash code for this object.
no setterinherited
invalidateKeys List<List>
List of query cache key prefixes invalidated upon successful mutation completion.
final
isError bool
Whether the mutation failed with an error (MutationStatus.error).
no setter
isIdle bool
Whether the mutation is in MutationStatus.idle status (unexecuted or reset).
no setter
isPending bool
Whether the mutation is actively in-flight (MutationStatus.pending).
no setter
isSuccess bool
Whether the mutation completed successfully (MutationStatus.success).
no setter
mutateFn MutationFn<T, P>
The underlying asynchronous execution function performing the mutation.
final
onError OnErrorCallback<P>?
Optional hook invoked when the mutation fails with an error.
final
onMutate OnMutateCallback<P>?
Optional hook invoked immediately prior to executing the mutation.
final
onSettled OnSettledCallback<T, P>?
Optional hook invoked when the mutation settles (either success or error).
final
onSuccess OnSuccessCallback<T, P>?
Optional hook invoked upon successful mutation resolution.
final
optimisticData OptimisticUpdater<T, P>?
Optimistic data transformation callback applied to the cache before network resolution.
final
optimisticKey List?
Optional query cache key targeted for automated optimistic updates and rollback.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
status ReadonlySignal<MutationStatus>
Reactive signal indicating the current lifecycle MutationStatus (idle, pending, success, error).
no setter

Methods

mutate(P params) Future<T?>
Safely executes the mutation with params.
mutateAsync(P params) Future<T>
Executes the mutation with params, returning the resolved data or rethrowing the caught error.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
reset() → void
Resets the mutation state back to MutationStatus.idle, clearing data and error to null.
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited