@thi.ng/rstream
Version:
Reactive streams & subscription primitives for constructing dataflow graphs / pipelines
155 lines • 6.34 kB
TypeScript
import type { Always, Derefed, IObjectOf } from "@thi.ng/api";
import { type PartitionSync } from "@thi.ng/transducers/partition-sync";
import type { ISubscribable, ISubscription, TransformableOpts } from "./api.js";
import { Subscription } from "./subscription.js";
export type SyncTuple<T extends IObjectOf<ISubscribable<any>>> = {
[id in keyof T]: Always<Derefed<T[id]>>;
};
export interface StreamSyncOpts<A extends IObjectOf<ISubscribable<any>>, B = SyncTuple<A>> extends TransformableOpts<SyncTuple<A>, B> {
/**
* An object of input streams / subscribables. The object keys are used to
* label the inputs in the result tuple object.
*/
src: A;
/**
* If true (default: false) *no* input synchronization (waiting for
* values) is applied and `StreamSync` will emit potentially
* partially populated tuple objects for each received input value.
* However, as with the default behavior, tuples will retain the
* most recent consumed value from other inputs.
*/
mergeOnly: boolean;
/**
* If true, StreamSync waits for new values from *all* inputs before
* a new tuple is produced. If false, that synchronization
* only happens for the very first tuple.
*
* @defaultValue false
*/
reset: boolean;
/**
* By default, the last emitted tuple is allowed to be incomplete
* (in case all inputs closed). To only allow complete tuples, set
* the `all` to false.
*
* @defaultValue true
*/
all: boolean;
/**
* If greater than 0, then each labeled input will cache upto the
* stated number of input values, even if other inputs have not yet
* produced new values. Once the limit is reached, `partitionSync()`
* will throw an `IllegalState` error.
*
* Enabling this option will cause the same behavior as if `reset`
* is enabled (regardless of the actual configured `reset` setting).
* I.e. new results are only produced when ALL required inputs have
* available values...
*/
backPressure: number;
/**
* Remove previously received value of an input in result tuple when
* input is removed.
*
* @defaultValue false
*/
clean: boolean;
}
/**
* Similar to {@link StreamMerge}, but with extra synchronization of inputs.
* Before emitting any new values, {@link StreamSync} collects values until at
* least one has been received from *all* inputs. Once that's the case, the
* collected values are sent as labeled tuple object to downstream subscribers.
*
* @remarks
* Each value in the emitted tuple objects is stored under their input stream's
* ID. Only the last value received from each input is passed on. After the
* initial tuple has been emitted, you can choose from two possible behaviors:
*
* 1) Any future change in any input will produce a new result tuple. These
* tuples will retain the most recently read values from other inputs. This
* behavior is the default and illustrated in the above schematic.
* 2) If the `reset` option is `true`, every input will have to provide at least
* one new value again until another result tuple is produced.
*
* Any done inputs are automatically removed. By default, `StreamSync` calls
* {@link ISubscriber.done} when the last active input is done, but this
* behavior can be overridden via the provided options.
*
* Input streams can be added and removed dynamically and the emitted tuple size
* adjusts to the current number of inputs (the next time a value is received
* from any input). After an input is removed (or done) its last received value
* can also be removed from the result tuple. This behavior can be configured
* via the `clean` option given to `sync()` (disabled by default).
*
* If the `reset` option is enabled, the last emitted tuple is allowed to be
* incomplete, by default. To only allow complete tuples, also set the `all`
* option to `false`.
*
* The synchronization is done via the
* [`partitionSync`](https://docs.thi.ng/umbrella/transducers/functions/partitionSync-1.html)
* transducer from the [`thi.ng/transducers`](https://thi.ng/transducers)
* package. See this function's docs for further details.
*
* @example
* ```ts tangle:../export/sync.ts
* import { stream, sync, trace } from "@thi.ng/rstream";
*
* const a = stream<number>();
* const b = stream<number>();
*
* const main = sync({ src: { a, b } }).subscribe(trace("result: "));
*
* a.next(1);
* // main received value, but does not yet emit...
*
* b.next(2);
* // now that `b` has delivered a value, `main` will produce its 1st result tuple
* // result: { a: 1, b: 2 }
*
* // any further input changes will trigger new results
* // (with cached values from other inputs)
* b.next(3);
* // result: { a: 1, b: 3 }
* ```
*
* Also see: {@link StreamSyncOpts}
*
* @param opts -
*/
export declare const sync: <A extends IObjectOf<ISubscribable<any>>, B = SyncTuple<A>>(opts: Partial<StreamSyncOpts<A, B>>) => StreamSync<A, B>;
/**
* See {@link sync} for reference & examples.
*/
export declare class StreamSync<A extends IObjectOf<ISubscribable<any>>, B = SyncTuple<A>> extends Subscription<any, B> {
/**
* maps actual inputs to their virtual input subs
*/
sources: Map<ISubscribable<any>, ISubscription<any, [string, any]>>;
/**
* maps real source IDs to their actual input
*/
idSources: Map<string, ISubscribable<any>>;
/**
* maps (potentially aliased) input IDs to their actual src.id
*/
realSourceIDs: Map<string, string>;
/**
* maps real src.id to (potentially aliased) input IDs
*/
invRealSourceIDs: Map<string, string>;
psync: PartitionSync<[string, any]>;
clean: boolean;
constructor(opts: Partial<StreamSyncOpts<A, B>>);
add(src: ISubscribable<any>, id?: string): void;
addAll(src: Partial<A>): void;
remove(src: ISubscribable<any>): boolean;
removeID(id: string): boolean;
removeAll(src: Iterable<ISubscribable<any>>): boolean;
removeAllIDs(ids: Iterable<string>): boolean;
getSourceForID(id: string): ISubscribable<any> | undefined;
getSources(): A;
unsubscribe(sub?: ISubscription<B, any>): boolean;
protected markDone(src: ISubscribable<any>): void;
}
//# sourceMappingURL=sync.d.ts.map