list<T, R extends IRequest> method

Future<Iterable<ParallelResult<T>>> list<T, R extends IRequest>({
  1. required RequestBuilder<R> requestBuilder,
  2. required ListOperation<T, R> interface,
  3. ParallelResultTransformer<T>? transformer,
  4. ParallelExceptionHandler<T>? onException,
  5. ParallelInitialItems<T>? initial,
})

Fetches a list of items of type T in parallel.

The requestBuilder parameter is a function that builds a list of requests to be made. The interface parameter is a function that performs the list operation for each request. The transformer parameter is an optional function that transforms the results of each request. The onException parameter is an optional function that handles exceptions that occur during the processing of the requests. The initial parameter is an optional function that provides an initial list of items.

Returns a Future that completes with a list of items of type T.

Implementation

Future<Iterable<ParallelResult<T>>> list<T, R extends IRequest>({
  required RequestBuilder<R> requestBuilder,
  required ListOperation<T, R> interface,
  ParallelResultTransformer<T>? transformer,
  ParallelExceptionHandler<T>? onException,
  ParallelInitialItems<T>? initial,
}) async {
  final requests = await requestBuilder();

  final responses = await Future.wait(
    requests.map((x) async {
      return ParallelRawResult(
        page: x.page,
        results: await interface.list(x.request),
      );
    }),
    eagerError: true,
  );

  final results = await responses.mapAsync(
    (response) async => guardAsync(
      function: () async {
        if (transformer != null) {
          return await transformer(response.results);
        }

        final successResponse = response.results.asSuccess();

        return ParallelResult(
          page: response.page,
          results: successResponse.data,
        );
      },
      onError: (error, stackTrace) async {
        if (onException != null) {
          return await onException(error);
        }

        throw ParallelProcessingException(error, stackTrace);
      },
    ),
  );

  final sortedResults =
      results.sorted((a, b) => a.page.compareTo(b.page)).map((e) => e);

  if (initial == null) {
    return sortedResults;
  }

  final initialItems = ParallelResult(page: 0, results: await initial());

  return [initialItems, ...sortedResults];
}