iteratorValueProvider<T> function
OffsetIteratorAsyncValue<T> Function(OffsetIterator<T> iterator)
iteratorValueProvider<T>(
- ProviderRef<
OffsetIteratorAsyncValue< ref, {T> > - int initialDemand = 1,
Pulls an OffsetIterator on demand, and exposes the most recently pulled OffsetIteratorAsyncValue.
Implementation
OffsetIteratorAsyncValue<T> Function(
OffsetIterator<T> iterator,
) iteratorValueProvider<T>(
ProviderRef<OffsetIteratorAsyncValue<T>> ref, {
int initialDemand = 1,
}) =>
(iterator) {
var canSetValue = false;
var disposed = false;
ref.onDispose(() => disposed = true);
bool shouldPullMore(int remaining) =>
!disposed && remaining > 0 && !iterator.drained;
late Future<void> Function() maybePull;
Future<void> doPull(int remaining) =>
Future.value(iterator.pull()).then((value) {
if (disposed) return null;
final pullMore = shouldPullMore(remaining - 1);
if (canSetValue) {
ref.state = OffsetIteratorAsyncValue(
value
.p(O.map(AsyncValue.data))
.p(O.alt(() => O.fromNullable(ref.state.value)))
.p(O.getOrElse(AsyncValue.loading)),
iterator.hasMore(),
pullMore,
maybePull,
);
}
return pullMore ? doPull(remaining - 1) : Future.value();
}).catchError((err, stack) {
if (disposed) return null;
ref.state = OffsetIteratorAsyncValue(
AsyncValue.error(err, stackTrace: stack),
iterator.hasMore(),
false,
maybePull,
);
return null;
});
maybePull = () {
if (!shouldPullMore(1)) return Future.value();
return doPull(1);
};
if (shouldPullMore(initialDemand)) {
doPull(initialDemand);
}
canSetValue = true;
return OffsetIteratorAsyncValue(
iterator.value.p(O.fold(
() => const AsyncValue.loading(),
(v) => AsyncValue.data(v),
)),
iterator.hasMore(),
initialDemand > 0,
maybePull,
);
};