import {execute} from 'abort-controller-x'; import {EmptyError, Observable} from 'rxjs'; export interface LastValueFromConfig { defaultValue: T; } export function lastValueFrom( signal: AbortSignal, source: Observable, config: LastValueFromConfig, ): Promise; export function lastValueFrom( signal: AbortSignal, source: Observable, ): Promise; /** * Like original `lastValueFrom` from RxJS, but accepts `AbortSignal`. When that * signal is aborted, unsubscribes from the observable and throws `AbortError`. */ export function lastValueFrom( signal: AbortSignal, source: Observable, config?: LastValueFromConfig, ): Promise { const hasConfig = typeof config === 'object'; return execute(signal, (resolve, reject) => { let _hasValue = false; let _value: T; const subscription = source.subscribe({ next: value => { _value = value; _hasValue = true; }, error: reject, complete: () => { if (_hasValue) { resolve(_value); } else if (hasConfig) { resolve(config!.defaultValue); } else { reject(new EmptyError()); } }, }); return () => { subscription.unsubscribe(); }; }); }