singleton property

Resolvable<T> get singleton

Returns the singleton instance currentInstance, or creating it if necessary.

If _constructor itself throws, the throw is absorbed into a Sync.err(...) so this getter honours the package contract that only @unsafeOrError members can escape with a thrown exception. The failed Sync.err is cached just like a successful construction would be — subsequent reads see the same Err until resetSingleton is called.

If _constructor itself reads singleton (direct or indirect recursion into the same Lazy), this returns a Sync.err(...) rather than recursing forever — a stack-overflow is unacceptable in a life-critical pipeline. The error message names the offending re-entrance so callers can find the circular dependency.

Implementation

@pragma('vm:prefer-inline')
Resolvable<T> get singleton {
  final cached = currentInstance;
  if (cached is Some<Resolvable<T>>) return cached.value;
  if (_constructing) {
    return Sync.err(
      Err<T>(
        'Lazy<$T>.singleton was accessed re-entrantly from inside its own '
        'constructor — circular dependency detected.',
      ),
    );
  }
  _constructing = true;
  Resolvable<T> fresh;
  try {
    fresh = _constructor();
  } on Err catch (err) {
    fresh = Sync.err(err.transfErr<T>());
  } catch (error, stackTrace) {
    fresh = Sync.err(Err<T>(error, stackTrace: stackTrace));
  } finally {
    _constructing = false;
  }
  currentInstance = Some(fresh);
  return fresh;
}