reduce<R extends Object> method
Reduces any nested Outcome structure into a single TResolvableOption.
This flattens all Outcome layers (Option, Result, Resolvable) into a final container that is always a Resolvable holding an Option. An Err state at any level will result in a failed Resolvable.
The implementation is iterative: a chain of Some(Some(Some(... 42)))
thousands deep does not consume a stack frame per layer. Only crossing
into an asynchronous layer (Async, or a Future lurking inside a
Some/Ok) hands off to a single async continuation.
Implementation
TResolvableOption<R> reduce<R extends Object>() {
// The loop variable is reassigned to various sealed-Outcome subtypes plus
// raw payload values, so the static type must widen to `Object`. The cast
// achieves that without an explicit-type annotation the lint dislikes.
var current = this as Object;
while (true) {
if (current is None) {
return syncNone<R>();
}
if (current is Err) {
// `transfErr<Option<R>>` preserves statusCode, stackTrace AND
// breadcrumbs. A hand-rolled Err() reconstruction dropped breadcrumbs,
// so any `.named()` labels attached upstream vanished on reduce.
return Sync.err(current.transfErr<Option<R>>());
}
if (current is Async) {
final futureResult = current.value;
return Async<Option<R>>(() async {
final result = await futureResult;
return (await result.reduce<R>().value).unwrap();
});
}
if (current is Outcome) {
final inner = current.value;
if (inner is Future) {
return Async<Option<R>>(() async {
final resolved = await inner;
if (resolved is Outcome<Object>) {
return (await resolved.reduce<R>().value).unwrap();
}
return Some(resolved as R);
});
}
current = inner;
continue;
}
// Innermost raw, non-Outcome value.
final raw = current;
return Sync(() => Some(raw as R));
}
}