import type { Fn, Nullable } from "@thi.ng/api";
import { type CommonOpts, type ISubscription } from "./api.js";
import { Subscription } from "./subscription.js";
export interface MetaStreamOpts extends CommonOpts {
    /**
     * If true, emits the last received value from the metastream's
     * current child stream (if any) when the metastream's parent is
     * calling `.done()`.
     *
     * @defaultValue false
     */
    emitLast: boolean;
}
/**
 * Returns a {@link Subscription} which transforms each incoming value into a
 * new {@link ISubscription}, subscribes to it (via an hidden / internal
 * subscription) and then only passes values from that stream to its own
 * subscribers.
 *
 * @remarks
 * If a new value is received, the metastream first unsubscribes from any still
 * active previous stream (if any), before creating and subscribing to the new
 * one. Hence this stream type is useful for cases where streams need to be
 * dynamically created & inserted into an existing dataflow topology.
 *
 * The user supplied `factory` function will be called for each incoming value
 * and is responsible for creating the new stream instances. If the function
 * returns null/undefined, no further action will be taken (acts like a filter
 * transducer).
 *
 * The factory function does NOT need to create *new* streams, but can merely
 * return other existing streams, and so making the meta stream act like a
 * switch with arbitrary criteria. However, if the meta stream itself is the
 * only subscriber to such existing input streams, you'll need to configure the
 * input's {@link CommonOpts.closeOut} option to keep them alive and support
 * dynamic switching between them.
 *
 * @example
 * ```ts tangle:../export/metastream.ts
 * import { fromIterable, metaStream, trace } from "@thi.ng/rstream";
 * import { repeat } from "@thi.ng/transducers";
 *
 * // transform each received odd number into a stream
 * // producing 3 copies of that number in the metastream
 * // even numbers are ignored
 * const a = metaStream<number, number>(
 *   (x) => (x & 1)
 *     ? fromIterable(repeat(x, 3), { delay: 100 })
 *     : null
 * );
 *
 * a.subscribe(trace())
 * a.next(23)
 *
 * // 23
 * // 23
 * // 23
 *
 * setTimeout(() => a.next(42), 500); // value 42 ignored by metastream
 *
 * setTimeout(() => a.next(43), 1000);
 * // 43
 * // 43
 * // 43
 * ```
 *
 * @example
 * ```ts tangle:../export/metastream-2.ts
 * import { fromIterable, metaStream, trace } from "@thi.ng/rstream";
 * import { cycle, repeat } from "@thi.ng/transducers";
 *
 * // infinite inputs (important: closeOut mode = "never"!)
 * const a = fromIterable(
 *   repeat("a"),
 *   { delay: 100, closeOut: "never" }
 * );
 * const b = fromIterable(
 *   repeat("b"),
 *   { delay: 100, closeOut: "never" }
 * );
 *
 * // stream selector / switch
 * const m = metaStream<boolean, string>((x) => (x ? a : b));
 * m.subscribe(trace("meta from: "));
 *
 * // create infinite stream of true/false and pipe into
 * // the metastream and switch which source to use
 * fromIterable(cycle([true, false]), { delay: 500 })
 *   .subscribe({ next(x) { m.next(x); } });
 *
 * // a
 * // a
 * // a
 * // a
 * // a
 * // b
 * // b
 * // b
 * // b
 * // b
 * // a
 * // a
 * // ...
 * ```
 *
 * @param factory -
 * @param id -
 */
export declare const metaStream: <A, B>(factory: Fn<A, Nullable<ISubscription<B, B>>>, opts?: Partial<MetaStreamOpts>) => MetaStream<A, B>;
/**
 * See {@link metaStream} for reference & examples.
 */
export declare class MetaStream<A, B> extends Subscription<A, B> {
    factory: Fn<A, Nullable<ISubscription<B, B>>>;
    stream?: ISubscription<B, B>;
    sub?: ISubscription<B, B>;
    emitLast: boolean;
    doneRequested: boolean;
    constructor(factory: Fn<A, Nullable<ISubscription<B, B>>>, opts?: Partial<MetaStreamOpts>);
    next(x: A): void;
    done(): void;
    unsubscribe(sub?: ISubscription<B, any>): boolean;
    protected detach(force: boolean): void;
}
//# sourceMappingURL=metastream.d.ts.map