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