import type { Fn, NumOrString } from "@thi.ng/api";
import type { ISubscribable } from "@thi.ng/rstream";
import type { IComponent, IMountWithState, NumOrElement } from "./api.js";
import { Component } from "./component.js";
/**
 * Reactive component wrapper to dynamically switch/replace itself with one of
 * the given components depending on subscribed value.
 *
 * @remarks
 * Subscribes to `src`, then calls `keyFn` for each received value and uses
 * result to call one of the given `ctors` async component factories. The value
 * returned from the chosen factory will be passsed to {@link $compile} and then
 * mounted in place of this `$switch` wrapper. If an uncaught error occurs in
 * the selected component factory, the `error` component factory will be used
 * instead (which is expected to succeed).
 *
 * When a new value is received from `src`, the currently active inner component
 * (if any) will always be fist `unmount`ed and if the optional `loader` is
 * given, it will be temporarily mounted whilst the actual `ctor` component
 * factory executes. This is can be used to show a pre-loaders.
 *
 * **IMPORTANT:** When a `null` or `undefined` value is received from `src`, the
 * currently active inner component will be unmounted and the optional loader
 * shown. However, no other inner component constructor will be called in this
 * case (until the next valid/non-null value is received).
 *
 * All component factories are async functions to facilitate dynamic `import()`
 * / code splitting and other async initializations (WASM etc.)
 *
 * @example
 * ```ts
 * import { $switch } from "@thi.ng/rdom";
 * import { fromInterval } from "@thi.ng/rstream";
 *
 * $switch(
 *   fromInterval(1000),
 *   (x) => x % 3,
 *   {
 *     0: async (x) => {
 *       await delayed(null, 500); // fake preload
 *       return ["div.green", {}, x];
 *     },
 *     1: async (x) => ["div.yellow", {}, x]
 *   },
 *   async (err) => ["div.bg-red", {}, err],
 *   async () => ["div", {}, "Loading..."]
 * ).mount(document.body)
 * ```
 *
 * This example uses a 1Hz counter to delegate to 3 different possible
 * components, however only two are defined, causing the last option to
 * throw an error and so trigger/use the error component.
 *
 * @param src -
 * @param keyFn -
 * @param ctors -
 * @param error -
 * @param loader -
 */
export declare const $switch: <T>(src: ISubscribable<T>, keyFn: Fn<T, NumOrString>, ctors: Record<NumOrString, Fn<T, Promise<any>>>, error?: Fn<Error, Promise<any>>, loader?: Fn<T, Promise<any>>) => IComponent<T>;
/**
 * Syntax sugar for {@link $switch} for cases when there's only a single
 * component which should transition through its entire lifecycle for
 * each reactive value change.
 *
 * @remarks
 * In other words, for each new value received from `src`. The wrapped
 * component will first be unmounted, an optional pre-`loader` shown
 * whilst the async `ctor` component factory executes, its result
 * `$compile`d and then getting re-mounted. See {@link $switch} for
 * further details.
 *
 * Also see {@link $replace}.
 *
 * @example
 * ```ts
 * import { $refresh } from "@thi.ng/rdom";
 * import { fromInterval } from "@thi.ng/rstream";
 *
 * $refresh(fromInterval(1000), async (x) => ["div", {}, x])
 * ```
 *
 * @param src -
 * @param ctor -
 * @param error -
 * @param loader -
 */
export declare const $refresh: <T>(src: ISubscribable<T>, ctor: Fn<T, Promise<any>>, error?: Fn<Error, Promise<any>>, loader?: Fn<T, Promise<any>>) => IComponent<T>;
export declare class Switch<T> extends Component implements IMountWithState<T> {
    protected keyFn: Fn<T, NumOrString>;
    protected ctors: Record<NumOrString, Fn<T, Promise<any>>>;
    protected error: Fn<Error, Promise<any>>;
    protected loader: Fn<T, Promise<any>>;
    protected val?: T;
    protected parent?: ParentNode;
    protected inner?: IComponent<T>;
    protected index?: NumOrElement;
    constructor(keyFn: Fn<T, NumOrString>, ctors: Record<NumOrString, Fn<T, Promise<any>>>, error?: Fn<Error, Promise<any>>, loader?: Fn<T, Promise<any>>);
    mount(parent: ParentNode, index: NumOrElement, val: T): Promise<Element>;
    unmount(): Promise<void>;
    update(val: T): Promise<void>;
}
//# sourceMappingURL=switch.d.ts.map