hydrate<T> method

AsyncValue<T> hydrate<T>(
  1. T? newData, {
  2. required Future<T> read(),
  3. required Future<void> write(
    1. T
    ),
})

A mechanism to persist changes made to some provided state. Unlike persist, hydrate allows you to pass in the state to persist, if there is one, to enable easier composition with other side effects.

Defines a way to interact with a storage provider of your choice through the read and write parameters.

  • If newData is Some, then newData will be persisted and overwrite any existing persisted data.
  • If newData is None, then no changes will be made to the currently persisted value (for when you don't have state to persist yet).

read is only called once; it is assumed that if write is successful, then calling read again would reflect the new state that we already have access to. Thus, calling read again is skipped as an optimization.

Implementation

AsyncValue<T> hydrate<T>(
  T? newData, {
  required Future<T> Function() read,
  required Future<void> Function(T) write,
}) {
  final readFuture = use.callonce(read);
  final readState = use.future(readFuture);
  final (getPrevData, setPrevData) = use.data<T?>(null);
  final (getWriteFuture, setWriteFuture) = use.data<Future<T>?>(null);

  if (newData != null && newData != getPrevData()) {
    setPrevData(newData);
    setWriteFuture(() async {
      await write(newData);
      return newData;
    }());
  }

  final writeState = use.nullableFuture(getWriteFuture());
  return (writeState ?? readState).fillInPreviousData(readState.data);
}