import { ComponentDescription, Schema, FullKWLName } from "./schema_raw";
import { AnnotatedSchema, AnnotatedSubtreeDescription, AnnotatedComponentDescription } from "./schema_annotated";
import * as WebSocket from "./node_ws";
import { CommonCommandOptions, CommonWriteOptions, KeywordPayload, NamedTableRowView, NamedTableView, Nestable, FullPath, RelativePath, SubtreePayload, TableRowView, TableView, VSocketView, WaitUntilOptions, Watcher, WriteOptions } from "./vmodel";
export declare const enum ExecutionStrategy {
    Immediate = 0,
    Lazy = 1
}
export declare const enum ListenerType {
    Permanent = 0,
    OneShot = 1
}
export declare class Listener {
    readonly listener_type: ListenerType;
    readonly kwl: string;
    readonly kw: string;
    readonly id: string;
    private readonly destructor;
    constructor(listener_type: ListenerType, kwl: string, kw: string, id: string, destructor: () => void);
    unregister(): void;
}
export declare class GlobalListener {
    readonly id: string;
    private readonly destructor;
    constructor(id: string, destructor: () => void);
    unregister(): void;
}
export declare class ThumbnailListener {
    readonly id: string;
    private readonly destructor;
    constructor(id: string, destructor: () => void);
    unregister(): void;
}
export interface BuildInfo {
    version: string;
    commit: string;
    bsp_commit: string;
    built_by: string;
    timestamp: string;
    changelog: string;
}
export interface WebServerBuildInfo {
    date: string;
    time: string;
}
export declare type Request = {
    op: "subscribe" | "unsubscribe" | "readAll";
    kwl: string[] | string;
    kw?: string[];
} | {
    op: "data";
    kwl: string;
    kw: {
        [kw_name: string]: KeywordPayload | {
            [array_row_index: number]: KeywordPayload;
        };
    };
} | {
    op: "tree";
    kwl: SubtreePayload;
} | {
    op: "readAll";
    kwl: string[] | string;
} | {
    op: "readAll";
    kwl: string;
    kw: string;
} | {
    op: "flags";
    flags: {
        "report errors"?: boolean;
    };
} | {
    op: "marker";
    marker: number;
};
declare type KeywordHandler<T = KeywordPayload> = (value: T) => void;
interface ProtocolFeatures {
    create_row_request_id: boolean;
}
declare const enum EventHandlerType {
    Open = 0,
    Close = 1,
    Error = 2,
    ComponentStateChange = 3
}
export declare class EventHandler {
    readonly handler_type: EventHandlerType;
    readonly id: string;
    private readonly destructor;
    constructor(handler_type: EventHandlerType, id: string, destructor: () => void);
    unregister(): void;
}
declare const enum TowelState {
    Blocking = 0,
    Set = 1,
    Unset = 2
}
export declare type VSocketParameters = WebSocket.Parameters & {
    timeout_ms?: number;
};
export interface PendingMarker {
    expiryDateMS: number;
    resolve: () => void;
    reject: (error: Error) => void;
}
interface TableRequests {
    next_table_request_id: number;
}
export declare class VSocket {
    static readonly INTERVAL_SECS = 1;
    private static schema_cache;
    private static s_timeout_scale;
    private m_table_requests;
    private state;
    private web_socket;
    private subscription_interval;
    private lazy_handler_interval;
    private reconnect_interval;
    private connect_timer;
    private id_pool;
    private m_current_towel?;
    private m_expected_message_type;
    check_towel_on_write: boolean;
    check_component_liveness: boolean;
    static scaledTimeout(msSuggested?: number): number;
    static setTimeoutScale(factor: number): void;
    private listeners;
    private globalListeners;
    private pending_markers;
    private pending_lazy_kw_updates;
    private pending_subscriptions;
    private open_handlers;
    private error_handlers;
    private close_handlers;
    private thumbnails;
    private reconnect_automatically;
    private is_online;
    private readonly connection_pars;
    private snoop_outbound_handler;
    private snoop_inbound_handler;
    constructor(pars: VSocketParameters);
    is_ready(): boolean;
    get protocol_features(): ProtocolFeatures;
    set_snooper(pars: {
        inbound?: null | ((data: any) => void);
        outbound?: null | ((requests: Request[]) => void);
    }): void;
    get current_towel(): {
        value: string;
        state: TowelState;
    };
    get build_info(): BuildInfo;
    get ip(): string;
    get protocol(): string;
    get port(): number;
    get towel(): string;
    get runtime_constants(): RuntimeConstants;
    get schema(): AnnotatedSchema;
    get module_registry(): ModuleRegistry;
    get root(): Root;
    place_towel(): Promise<void>;
    marker(pars?: {
        id?: number;
        timeout?: number;
    }): Promise<void>;
    query_cache(kwl: string, kw: string): KeywordPayload | undefined;
    find_runtime_constant(constant_string: string): number | boolean | undefined;
    get_runtime_constant(constant_string: string): number | boolean;
    send(req: Request[]): void;
    /**
     * registers an event handler that will be executed when the
     * underlying websocket connection opens (or reopens)
     */
    on_open(f: () => void, suggested_id?: string): EventHandler;
    /**
     * registers an event handler that will be executed when the
     * underlying websocket connection closes
     */
    on_close(f: (ev: WebSocket.WSCloseEvent, suggested_id?: string) => void, suggested_id?: string): EventHandler;
    /**
     * registers an event handler that will be executed on websocket errors
     */
    on_error(f: (ev: WebSocket.WSErrorEvent) => void, suggested_id?: string): EventHandler;
    static open(pars: VSocketParameters & {
        timeout_ms?: number;
    }): Promise<VSocket>;
    private arm_reconnect_timer;
    close(): Promise<void>;
    reboot(pars?: {
        command?: "reboot" | "system0" | "system1";
        timeout?: number;
    }): Promise<void>;
    reset(pars?: {
        timeout?: number;
    }): Promise<void>;
    execute_pending_subscription_requests(): void;
    recovery(pars?: {
        timeout?: number;
    }): Promise<void>;
    dump_listener_stats(): {
        kwl_bytes: number;
        kw_bytes: number;
        id_bytes: number;
    };
    private get_id;
    private ensure_kw_listener;
    private renew_subscriptions;
    private safely_delete_handler;
    register_kw_listener<T extends KeywordPayload = KeywordPayload>(pars: {
        kwl: string;
        kw: string;
        listener_id?: string;
        cache?: boolean;
        defer_subscription: boolean;
        listener_type: ListenerType;
        execution_strategy: ExecutionStrategy;
    }, handler: KeywordHandler<T>): Listener;
    register_global_listener<T extends KeywordPayload = KeywordPayload>(handler: (kwl: FullKWLName, kw: string, payload: T) => void, pars: {
        listener_id?: string;
    }): GlobalListener;
    register_thumbnail_listener(handler: KeywordHandler<WebSocket.Binary>, pars?: {
        listener_id?: string;
    }): ThumbnailListener;
    private execute_lazy_handlers;
    private open_ws;
    private initialize;
    private handle_incoming;
}
export declare class Subtree implements VSocketView {
    readonly socket: VSocket;
    readonly m_kwl: string | null;
    private m_description;
    constructor(socket: VSocket, m_kwl: string | null);
    get description(): AnnotatedSubtreeDescription | AnnotatedComponentDescription[];
    get kwl(): string;
    get parent(): Subtree;
    private tableness;
    as_table(_?: {
        check_type?: boolean;
    }): Table;
    table(relative_kwl: string, _?: {
        check_type?: boolean;
    }): Table;
    as_named_table(_?: {
        check_type?: boolean;
    }): NamedTable;
    named_table(relative_kwl: string, _?: {
        check_type?: boolean;
    }): NamedTable;
    get children(): import("./schema_raw").ChildDescription<import("./schema_annotated").SubtreeAnnotations, import("./schema_annotated").AtomicSubtreeAnnotations, import("./schema_annotated").ScalarAnnotations>[];
    write_unchecked(relative_path: RelativePath, payload: KeywordPayload | {
        [array_row_index: number]: KeywordPayload;
    }): void;
    write_tree_unchecked(relative_path: RelativePath, payload: SubtreePayload): void;
    read_unchecked<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, timeout_secs?: number): Promise<T>;
    protected full_path(relative_path: RelativePath): FullPath;
    read<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, opts?: CommonCommandOptions & {
        use_cache_if_present?: boolean;
    }): Promise<T>;
    write<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, payload: T | {
        [array_element_index: number]: T;
    }, opts?: WriteOptions<T>): Promise<void>;
    wait_until<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, criterion: (payload: T) => boolean, opts?: WaitUntilOptions): Promise<T>;
    update<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, opts?: CommonCommandOptions & {
        defer_subscription?: boolean;
    }): Promise<T>;
    watch<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, handler: (payload: T) => void, opts?: CommonCommandOptions & {
        defer_subscription?: boolean;
    }): Promise<Watcher>;
    deref(relative_path: RelativePath, opts?: CommonCommandOptions): Promise<null | Subtree>;
    find(relative_kwl: string, _?: {
        check_type?: boolean;
    }): Subtree;
    full_kwl(relative_kwl?: string): string;
}
export declare class Root extends Subtree {
    readonly socket: VSocket;
    private readonly m_table_requests;
    constructor(socket: VSocket, m_table_requests: TableRequests);
    protected do_check(check_towel: boolean, check_component_liveness: boolean, full_kwl: string): Promise<void>;
    protected do_check_readonly(check_component_liveness: boolean, full_kwl: string): void;
    reboot(pars?: {
        command?: "reboot" | "system0" | "system1";
        timeout?: number;
    }): Promise<void>;
    reset(pars?: {
        timeout?: number;
    }): Promise<void>;
    read<T extends KeywordPayload = KeywordPayload>(path: FullPath, opts?: CommonCommandOptions & {
        use_cache_if_present?: boolean;
    }): Promise<T>;
    write<T extends KeywordPayload = KeywordPayload>(path: FullPath, payload: T | {
        [array_element_index: number]: T;
    }, opts?: WriteOptions<T>): Promise<void>;
    wait_until<T extends KeywordPayload = KeywordPayload>(path: FullPath, criterion: (payload: T) => boolean, opts?: WaitUntilOptions): Promise<T>;
    watch<T extends KeywordPayload = KeywordPayload>(path: FullPath, handler: (payload: T) => void, opts?: CommonCommandOptions & {
        defer_subscription?: boolean;
    }): Promise<Watcher>;
    update<T extends KeywordPayload = KeywordPayload>(path: FullPath, opts?: CommonCommandOptions & {
        defer_subscription?: boolean;
    }): Promise<T>;
    deref(path: FullPath, opts?: CommonCommandOptions): Promise<null | Subtree>;
    read_unchecked<T extends KeywordPayload = KeywordPayload>(path: FullPath, timeout_secs?: number): Promise<T>;
    write_tree_unchecked(path: FullPath, payload: SubtreePayload): void;
    write_unchecked(path: FullPath, payload: KeywordPayload | {
        [array_row_index: number]: KeywordPayload;
    }): void;
    /**
     * attempt to create a new row within table <table_kwl>, returning the newly
     * created row's index and name if successful and null otherwise. If neither
     * <desired_index> nor <desired_name> are specified, the system will choose an
     * unoccupied row index at its own discretion. Throws on allocation failure
     */
    table_create_row(table_kwl: string, opts?: CommonWriteOptions & {
        index?: number;
        name?: string;
        allow_reuse_row?: boolean;
    }): Promise<[number, string]>;
    table_rename_row(kwl: string, desired_name: string, opts?: CommonWriteOptions): Promise<void>;
    /**
     * returns the currently allocated row indices of table <table_kwl>.
     */
    table_indices(table_kwl: string, opts?: CommonCommandOptions): Promise<number[]>;
    /**
     * returns the currently allocated row names of table <table_kwl>.
     */
    table_rows(table_kwl: string, opts?: CommonCommandOptions): Promise<string[]>;
    /**
     * checks whether <table_kwl>[<index>] is currently allocated
     */
    table_has_row(table_kwl: string, index: number, opts?: CommonCommandOptions): Promise<boolean>;
    /**
     * attempts to delete <table_kwl>[<index>]. Note that a delete request may be
     * refused, as some allocatable objects need to be deactivated prior to removal
     */
    table_delete_row(table_kwl: string, index: number, opts?: CommonWriteOptions): Promise<void>;
    full_kwl(relative_kwl?: string): string;
}
export declare class Table extends Subtree implements TableView<Nestable<VSocketView>> {
    constructor(socket: VSocket, kwl: string);
    allocated_indices(opts?: CommonCommandOptions): Promise<number[]>;
    is_allocated(index: number, opts?: CommonCommandOptions): Promise<boolean>;
    rows(opts?: CommonCommandOptions): Promise<TableRow[]>;
    row(index: number, _?: CommonCommandOptions): TableRow;
    row_unchecked(index: number): TableRow;
}
export declare class NamedTable extends Table implements NamedTableView<Nestable<VSocketView>> {
    constructor(socket: VSocket, kwl: string);
    create_row(opts?: CommonWriteOptions & {
        index?: number;
        name?: string;
        allow_reuse_row?: boolean;
    }): Promise<NamedTableRow>;
    rows(opts?: CommonCommandOptions): Promise<NamedTableRow[]>;
    row(index: number, _?: CommonCommandOptions): NamedTableRow;
    row_unchecked(index: number): NamedTableRow;
}
export declare class TableRow extends Subtree implements TableRowView<VSocketView> {
    readonly index: number;
    readonly enclosing_table: Table;
    constructor(socket: VSocket, kwl: string, index: number, enclosing_table: Table);
}
export declare class NamedTableRow extends TableRow implements NamedTableRowView<VSocketView> {
    readonly index: number;
    readonly enclosing_table: NamedTable;
    constructor(socket: VSocket, kwl: string, index: number, enclosing_table: NamedTable);
    rename(name: string, opts?: CommonWriteOptions): Promise<void>;
    delete(opts?: CommonWriteOptions): Promise<void>;
}
export declare enum ComponentState {
    Unknown = 0,
    Disabled = 1,
    Uninitialized = 2,
    Running = 3,
    Crashed = 4
}
export declare type ChangeHandler = (component_sys_name: string, state: ComponentState) => void;
export declare class ModuleRegistry {
    private static DISABLED;
    private data;
    private sys_names;
    private change_handlers;
    private next_id;
    private constructor();
    translate_component_ua_name(component_ua_name: string): string;
    on_change(f: (component_sys_name: string, state: ComponentState) => void): EventHandler;
    static initialize(components: ComponentDescription[], socket: VSocket, timeout_ms: number): Promise<ModuleRegistry>;
    is_online(component_sys_name: string): boolean;
    is_disabled(component_sys_name: string): boolean;
    get_status(component_sys_name: string): {
        pid: number;
        crashed: boolean;
    };
}
export interface RawRuntimeConstants {
    [component_sys_name: string]: {
        [constant_name: string]: number | boolean;
    };
}
export declare class RuntimeConstants {
    private readonly data;
    private constructor();
    find_constant(component_sys_name: string, constant_name: string): number | boolean;
    get_constant(component_sys_name: string, constant_name: string): number | boolean;
    equal(other: RuntimeConstants): boolean;
    static initialize(schema: Schema, mr: ModuleRegistry, socket: VSocket, timeout_ms: number): Promise<RuntimeConstants>;
}
export {};
