rpcMutation<TInput, TOutput> function

BloomMutation<TOutput, TInput> rpcMutation<TInput, TOutput>(
  1. BloomRpcClient client,
  2. BloomRpcContract<TInput, TOutput> contract, {
  3. List<List> invalidateKeys = const [],
  4. List<BloomRpcContract> invalidateContracts = const [],
  5. Map<String, dynamic>? pathParamsBuilder(
    1. TInput input
    )?,
  6. Map<String, dynamic>? defaultPathParams,
  7. Map<String, dynamic>? queryParameters,
  8. Map<String, String>? headers,
  9. Duration? timeout,
  10. List? optimisticKey,
  11. OptimisticUpdater<TOutput, TInput>? optimisticData,
  12. OnMutateCallback<TInput>? onMutate,
  13. OnSuccessCallback<TOutput, TInput>? onSuccess,
  14. OnErrorCallback<TInput>? onError,
  15. OnSettledCallback<TOutput, TInput>? onSettled,
})

Creates a declarative BloomMutation bound to an RPC contract.

Automatically executes client.call on BloomMutation.mutate, with support for:

  • Automated Cache Invalidation: Invalidates cache queries matching invalidateKeys or invalidateContracts upon successful resolution.
  • Optimistic Updates & Rollback: Writes anticipated state changes to optimisticKey before network response and automatically rolls back if the mutation fails.
  • Reactive Signals: Exposes reactive BloomMutation.status, BloomMutation.data, and BloomMutation.error signals.
final createTodo = rpcMutation<CreateTodoInput, Todo>(
  client,
  createTodoContract,
  invalidateContracts: [getTodoListContract],
  onError: (err, input, ctx) => print('Failed to create todo: $err'),
);

await createTodo.mutate(CreateTodoInput(title: 'New task'));

See also:

Implementation

BloomMutation<TOutput, TInput> rpcMutation<TInput, TOutput>(
  BloomRpcClient client,
  BloomRpcContract<TInput, TOutput> contract, {
  List<List<dynamic>> invalidateKeys = const [],
  List<BloomRpcContract<dynamic, dynamic>> invalidateContracts = const [],
  Map<String, dynamic>? Function(TInput input)? pathParamsBuilder,
  Map<String, dynamic>? defaultPathParams,
  Map<String, dynamic>? queryParameters,
  Map<String, String>? headers,
  Duration? timeout,
  List<dynamic>? optimisticKey,
  OptimisticUpdater<TOutput, TInput>? optimisticData,
  OnMutateCallback<TInput>? onMutate,
  OnSuccessCallback<TOutput, TInput>? onSuccess,
  OnErrorCallback<TInput>? onError,
  OnSettledCallback<TOutput, TInput>? onSettled,
}) {
  final combinedInvalidateKeys = <List<dynamic>>[
    ...invalidateKeys,
    for (final c in invalidateContracts)
      ['rpc', c.method.value.toLowerCase(), c.pathTemplate],
  ];

  return BloomMutation<TOutput, TInput>(
    mutateFn: (params) {
      final pathParams = pathParamsBuilder != null
          ? pathParamsBuilder(params)
          : defaultPathParams;
      return client.call(
        contract,
        params,
        pathParams: pathParams,
        queryParameters: queryParameters,
        headers: headers,
        timeout: timeout,
      );
    },
    optimisticKey: optimisticKey,
    optimisticData: optimisticData,
    invalidateKeys: combinedInvalidateKeys,
    onMutate: onMutate,
    onSuccess: onSuccess,
    onError: onError,
    onSettled: onSettled,
  );
}