import { LoggingOptions } from "../Logging.js";
import { MergeListReader, MergedItem } from "../util/MergeList.js";
import { MemberOptions } from "../Options.js";
export type Script<E> = (el: E, basis: () => void) => void;
export type ScriptAsync<E> = (el: E, basis: () => Promise<void>) => Promise<void>;
export type Handler<E = unknown, R = void> = (el: E) => R;
export declare enum Mode {
    default = 0,
    autonomous = 1,
    manualMount = 2,
    rootNode = 4
}
export declare enum Priority {
    realtime = 0,
    normal = 1,
    background = 2
}
export declare abstract class ReactiveNode<E = unknown> {
    abstract readonly key: string;
    abstract readonly driver: ReactiveNodeDriver<E>;
    abstract readonly declaration: Readonly<ReactiveNodeDecl<E>>;
    abstract readonly level: number;
    abstract readonly owner: ReactiveNode;
    abstract element: E;
    abstract readonly host: ReactiveNode;
    abstract readonly children: MergeListReader<ReactiveNode>;
    abstract readonly slot: MergedItem<ReactiveNode<E>> | undefined;
    abstract readonly stamp: number;
    abstract readonly outer: ReactiveNode;
    abstract readonly context: ReactiveNodeContext | undefined;
    abstract priority?: Priority;
    abstract childrenShuffling: boolean;
    abstract strictOrder: boolean;
    abstract has(mode: Mode): boolean;
    abstract configureReactronic(options: Partial<MemberOptions>): MemberOptions;
    static readonly shortFrameDuration = 16;
    static readonly longFrameDuration = 300;
    static currentScriptPriority: Priority;
    static frameDuration: number;
    static declare<E = void>(driver: ReactiveNodeDriver<E>, script?: Script<E>, scriptAsync?: ScriptAsync<E>, key?: string, mode?: Mode, preparation?: Script<E>, preparationAsync?: ScriptAsync<E>, finalization?: Script<E>, triggers?: unknown, basis?: ReactiveNodeDecl<E>): ReactiveNode<E>;
    static declare<E = void>(driver: ReactiveNodeDriver<E>, declaration?: ReactiveNodeDecl<E>): ReactiveNode<E>;
    static declare<E = void>(driver: ReactiveNodeDriver<E>, scriptOrDeclaration?: Script<E> | ReactiveNodeDecl<E>, scriptAsync?: ScriptAsync<E>, key?: string, mode?: Mode, preparation?: Script<E>, preparationAsync?: ScriptAsync<E>, finalization?: Script<E>, triggers?: unknown, basis?: ReactiveNodeDecl<E>): ReactiveNode<E>;
    static withBasis<E = void>(declaration?: ReactiveNodeDecl<E>, basis?: ReactiveNodeDecl<E>): ReactiveNodeDecl<E>;
    static get isFirstScriptRun(): boolean;
    static get key(): string;
    static get stamp(): number;
    static get triggers(): unknown;
    static get priority(): Priority;
    static set priority(value: Priority);
    static get childrenShuffling(): boolean;
    static set childrenShuffling(value: boolean);
    static triggerScriptRun(node: ReactiveNode<any>, triggers: unknown): void;
    static triggerFinalization(node: ReactiveNode<any>): void;
    static runNestedNodeScriptsThenDo(action: (error: unknown) => void): void;
    static markAsMounted(node: ReactiveNode<any>, yes: boolean): void;
    static findMatchingHost<E = unknown, R = unknown>(node: ReactiveNode<E>, match: Handler<ReactiveNode<E>, boolean>): ReactiveNode<R> | undefined;
    static findMatchingPrevSibling<E = unknown, R = unknown>(node: ReactiveNode<E>, match: Handler<ReactiveNode<E>, boolean>): ReactiveNode<R> | undefined;
    static forEachChildRecursively<E = unknown>(node: ReactiveNode<E>, action: Handler<ReactiveNode<E>>): void;
    static getDefaultLoggingOptions(): LoggingOptions | undefined;
    static setDefaultLoggingOptions(logging?: LoggingOptions): void;
}
export type ReactiveNodeDecl<E = unknown> = {
    script?: Script<E>;
    scriptAsync?: ScriptAsync<E>;
    key?: string;
    mode?: Mode;
    preparation?: Script<E>;
    preparationAsync?: ScriptAsync<E>;
    finalization?: Script<E>;
    triggers?: unknown;
    basis?: ReactiveNodeDecl<E>;
};
export type ReactiveNodeDriver<E = unknown> = {
    readonly name: string;
    readonly isPartition: boolean;
    readonly initialize?: Handler<E>;
    create(node: ReactiveNode<E>): E;
    runPreparation(node: ReactiveNode<E>): void;
    runFinalization(node: ReactiveNode<E>, isLeader: boolean): boolean;
    runMount(node: ReactiveNode<E>): void;
    runScript(node: ReactiveNode<E>): void | Promise<void>;
    declareChild(ownerNode: ReactiveNode<E>, childDriver: ReactiveNodeDriver<any>, childDeclaration?: ReactiveNodeDecl<any>, childBasis?: ReactiveNodeDecl<any>): MergedItem<ReactiveNode> | undefined;
    provideHost(node: ReactiveNode<E>): ReactiveNode<E>;
};
export type ReactiveNodeContext<T extends Object = Object> = {
    value: T;
};
export declare abstract class BaseDriver<E = unknown> implements ReactiveNodeDriver<E> {
    readonly name: string;
    readonly isPartition: boolean;
    readonly initialize?: Handler<E> | undefined;
    constructor(name: string, isPartition: boolean, initialize?: Handler<E> | undefined);
    abstract create(node: ReactiveNode<E>): E;
    runPreparation(node: ReactiveNode<E>): void | Promise<void>;
    runFinalization(node: ReactiveNode<E>, isLeader: boolean): boolean;
    runMount(node: ReactiveNode<E>): void;
    runScript(node: ReactiveNode<E>): void | Promise<void>;
    declareChild(ownerNode: ReactiveNode<E>, childDriver: ReactiveNodeDriver<any>, childDeclaration?: ReactiveNodeDecl<any>, childBasis?: ReactiveNodeDecl<any>): MergedItem<ReactiveNode> | undefined;
    provideHost(node: ReactiveNode<E>): ReactiveNode<E>;
}
export declare class ReactiveNodeVariable<T extends Object = Object> {
    readonly defaultValue: T | undefined;
    constructor(defaultValue?: T);
    set value(value: T);
    get value(): T;
    get valueOrUndefined(): T | undefined;
}
