1992
return this._value!;
1993
}
1995
>
1996
>
export class LazyStatefulPromise<T> {
1997
>
private readonly _promise = new Lazy(() => new StatefulPromise(this._compute()));
1998
>
1999
>
constructor(
2000
private readonly _compute: () => Promise<T>,
2001
) { }
2003
>
/**
2004
>
* Returns the resolved value.
2005
>
* Throws if the promise is not resolved yet.
2006
>
*/
2007
>
public requireValue(): T {
2008
return this._promise.value.requireValue();
2009
}
2011
>
/**
2012
>
* Returns the promise (and triggers a computation of the promise if not yet done so).
2013
>
*/
2014
>
public getPromise(): Promise<T> {
2015
return this._promise.value.promise;
2016
}
2018
>
/**
2019
>
* Reads the current value without triggering a computation of the promise.
2020
>
*/
2021
>
public get currentValue(): T | undefined {
2022
return this._promise.rawValue?.value;
2023
}
2025
>
2026
>
//#endregion
2027
>
2028
>
//#region
2029
>
2030
>
const enum AsyncIterableSourceState {
2031
>
Initial,
2032
>
DoneOK,
2033
>
DoneError,
2034
>
}
2035
>
2036
>
/**
2037
>
* An object that allows to emit async values asynchronously or bring the iterable to an error state using `reject()`.
2038
>
* This emitter is valid only for the duration of the executor (until the promise returned by the executor settles).
2039
>
*/
2040
>
export interface AsyncIterableEmitter<T> {
2041
>
/**
2042
>
* The value will be appended at the end.
2043
>
*
2044
>
* **NOTE** If `reject()` has already been called, this method has no effect.
2045
>
*/
2046
>
emitOne(value: T): void;
2047
>
/**
2048
>
* The values will be appended at the end.
2049
>
*
2050
>
* **NOTE** If `reject()` has already been called, this method has no effect.
2051
>
*/
2052
>
emitMany(values: T[]): void;
2053
>
/**
2054
>
* Writing an error will permanently invalidate this iterable.
2055
>
* The current users will receive an error thrown, as will all future users.
2056
>
*
2057
>
* **NOTE** If `reject()` have already been called, this method has no effect.
2058
>
*/
2059
>
reject(error: Error): void;
2060
>
}
2061
>
2062
>
/**
2063
>
* An executor for the `AsyncIterableObject` that has access to an emitter.
2064
>
*/
2065
>
export interface AsyncIterableExecutor<T> {
2066
>
/**
2067
>
* @param emitter An object that allows to emit async values valid only for the duration of the executor.
2068
>
*/
2069
>
(emitter: AsyncIterableEmitter<T>): unknown | Promise<unknown>;
2070
>
}
2071
>
2072
>
/**
2073
>
* A rich implementation for an `AsyncIterable<T>`.
2074
>
*/
2075
>
export class AsyncIterableObject<T> implements AsyncIterable<T> {
2076
>
2077
>
public static fromArray<T>(items: T[]): AsyncIterableObject<T> {
2078
>
return new AsyncIterableObject<T>((writer) => {
2079
>
writer.emitMany(items);
2080
>
});
2081
>
}
2082
>
2083
>
public static fromPromise<T>(promise: Promise<T[]>): AsyncIterableObject<T> {
2084
return new AsyncIterableObject<T>(async (emitter) => {
2085
emitter.emitMany(await promise);
2086
});
2087
}
2089
>
public static fromPromisesResolveOrder<T>(promises: Promise<T>[]): AsyncIterableObject<T> {
2090
return new AsyncIterableObject<T>(async (emitter) => {
2091
await Promise.all(promises.map(async (p) => emitter.emitOne(await p)));
2092
});
2093
}
2095
>
public static merge<T>(iterables: AsyncIterable<T>[]): AsyncIterableObject<T> {
2096
return new AsyncIterableObject(async (emitter) => {
2097
await Promise.all(iterables.map(async (iterable) => {