until<TSuper extends Object, TSub extends TSuper> method
Waits until a dependency of type TSuper or its subtype TSub is
registered. TSuper should typically be the most general type expected.
Implementation
Resolvable<TSub> until<TSuper extends Object, TSub extends TSuper>({
Entity groupEntity = const DefaultEntity(),
bool traverse = true,
}) {
final typeEntity = TypeEntity(TSuper);
final g = groupEntity.preferOverDefault(focusGroup);
// Already-registered fast path: bail out with the resolved Resolvable.
if (get<TSuper>(groupEntity: g, traverse: traverse)
case Some(value: final r)) {
return r.transf();
}
final completer = switch (getSyncOrNone<ReservedSafeCompleter<TSuper>>(
groupEntity: g,
traverse: traverse,
)) {
Some(value: final c) => c,
None() => _seedCompleter<TSuper>(typeEntity, g, traverse),
};
return completer
.resolvable()
.then((_) {
unregister<ReservedSafeCompleter<TSuper>>(
groupEntity: g,
traverse: traverse,
).end();
// Surface Err on a post-resolution race rather than throw.
return switch (get<TSuper>(groupEntity: g, traverse: traverse)) {
Some(value: final r) => r,
None() => Sync<TSuper>.err(
Err('until<$TSuper>: completer resolved but post-resolution '
'lookup returned None (raced with unregister).'),
),
};
})
.flatten()
.transf();
}