suspenders-js
Version:
Asynchronous programming library utilizing coroutines, functional reactive programming and structured concurrency.
155 lines (154 loc) • 6.24 kB
TypeScript
import { Scope } from "./Scope";
import { CoroutineFactory, Suspender, Observer, Collector } from "./Types";
/**
* Abstract class for emitting multiple values. A cold flow is doesn't start producing values until
* it is yield in a coroutine with .collect() or .collectLatest(). Sharing a cold flow with multiple
* coroutines requires converting it into a SharedEventSubject or SharedStateSubject. Hot flows
* are EventSubjects and StateSubjects.
*/
export declare abstract class Flow<T> {
/**
* Starts emitting values to an observer. If this is a single use cold Flow, this can only be
* called once. Hot flows like subjects and shared flows accept multiple observers.
* adding more than one observer.
* @param {Observer<T>} observer
*/
abstract addObserver(observer: Observer<T>): void;
/**
* Removes an observer from receiving new values from a flow. Only pass in observers that have
* been previously added. If this is a single use cold flow, it will cancel any running upstream
* coroutines.
* @param {Observer<T>} observer
*/
abstract removeObserver(observer: Observer<T>): void;
/**
* Converts values emitted using mapper function.
* @param {(value) => R} mapper
* @returns {Flow<R>}
*/
map<R>(mapper: (value: T) => R): Flow<R>;
/**
* Values that don't return true from predicate function are not emitted downstream.
* @param predicate
*/
filter(predicate: (value: T) => boolean): Flow<T>;
/**
* Runs binder on each emitted value and combines outputs into a single flow.
* @param binder
*/
mergeMap<R>(binder: (value: T) => Flow<R>): Flow<R>;
/**
* Runs f on each value but doesn't change values emitted in downstream flow.
* @param f
*/
onEach(f: (value: T) => void): Flow<T>;
/**
* Consumes values in upstream Flow. Shares values with downstream flow. Replays last value
* emitted on new observers.
* @returns {Flow<T>}
*/
sharedState(): Flow<T>;
/**
* Consumes values in upstream Flow. Shares values with downstream flow.
* @returns {Flow<T>}
*/
sharedEvent(): Flow<T>;
/**
* Collects Flow in scope, ignoring emitted values.
* @param scope
*/
launchIn(scope: Scope): void;
/**
* Consumes Flow in scope. Runs collector function on emitted values.
* @param {(value: T) => void} collector
* @returns {Suspender<void>}
*/
collect(collector: (value: T) => void): Suspender<void>;
/**
* Consumes Flow in scope. Runs collector coroutine on emitted values. Cancels previously started
* coroutine if it has not completed.
* @param {(value: T) => CoroutineFactory<void>} coroutineFactory
*/
collectLatest(coroutineFactory: (value: T) => CoroutineFactory<void>): Suspender<void>;
/**
* Runs coroutine on each value and emits values through observer. Waits for each
* coroutine to complete before starting the next. Because there is no backpressure with flow, use
* care to make sure that emitted values don't buffer uncontrollably.
* @param transformer
*/
transform<R>(transformer: (value: T, collector: Collector<R>) => CoroutineFactory<void>): Flow<R>;
/**
* Errors thrown upstream are caught and passed into coroutine factory. Resumes sending values
* emitted to observer.
* @param factory
*/
catch(factory: (error: unknown, collector: Collector<T>) => CoroutineFactory<void>): Flow<T>;
/**
* Runs a coroutine on each value and emits values through observer. Cancels previous coroutine if
* it has not completed.
* @param transformer
*/
transformLatest<R>(transformer: (value: T, collector: Collector<R>) => CoroutineFactory<void>): Flow<R>;
}
export declare const flowOf: <T>(factory: (collector: Collector<T>) => CoroutineFactory<void>) => Flow<T>;
export declare const flowOfValues: <T>(...args: T[]) => Flow<T>;
/**
* Starts observing a upstream flow and shares received values to downstream observers.
* SharedStateFlow replay the last emitted value to new observers.
*/
export declare class SharedStateFlow<T> extends Flow<T> implements Observer<T> {
private _flow;
private _observers;
private _last?;
private _hasCompleted;
constructor(_flow: Flow<T>);
addObserver(observer: Observer<T>): void;
removeObserver(observer: Observer<T>): void;
emit(value: T): void;
complete(): void;
error(error: unknown): void;
}
/**
* EventSubjects update their observers when there is a new event. Previously emitted values are not
* replayed on new observers. To replay the last emitted value, use StateSubject. Subjects are hot
* and can be shared with multipler observers. New flows that observe subjects start cold.
*/
export declare class EventSubject<T> extends Flow<T> implements Collector<T> {
private _observers;
addObserver(observer: Observer<T>): void;
removeObserver(observer: Observer<T>): void;
/**
* Emits a value to the observer.
* @param value
*/
emit(value: T): void;
}
/**
* StateSubject always have a value. When new observers are added, the last emitted value is
* replayed. This is generally used used for hot observables like the mouse position. Subjects are
* hot and can be shared with multipler observers. New flows that observe subjects start cold.
*/
export declare class StateSubject<T> extends Flow<T> implements Collector<T> {
value: T;
private _observers;
constructor(value: T);
addObserver(observer: Observer<T>): void;
removeObserver(observer: Observer<T>): void;
emit(value: T): void;
get(): T;
}
/**
* Starts observing a upstream flow and shares received values to downstream observers.
* SharedEventFlow doesn't replay any past emitted values.
*/
export declare class SharedEventFlow<T> extends Flow<T> implements Observer<T> {
private _flow;
private _observers;
private _hasCompleted;
constructor(_flow: Flow<T>);
addObserver(observer: Observer<T>): void;
removeObserver(observer: Observer<T>): void;
emit(value: T): void;
complete(): void;
error(error: unknown): void;
}