import { AnnotatedChildDescription, AnnotatedSubtreeDescription, AnnotatedComponentDescription } from "./schema_annotated";
export interface CommonCommandOptions {
    check_component_liveness?: boolean;
    timeout?: number;
}
export interface WaitUntilOptions extends CommonCommandOptions {
    skip_initial_read?: boolean;
}
export declare type KeywordPayload = null | boolean | string | number | KeywordPayload[] | [number, KeywordPayload];
export declare type SubtreePayload = {
    kw: {
        [name: string]: KeywordPayload;
    };
    kwl: {
        [name: string]: SubtreePayload;
    };
};
export interface CommonWriteOptions extends CommonCommandOptions {
    check_towel?: boolean;
    retry_interval_ms?: number;
}
export declare type WriteOptions<T> = CommonWriteOptions & {
    retry_until?: {
        criterion: "status";
        validator: (status: T) => boolean;
    } | {
        criterion: "custom";
        validator: () => Promise<boolean>;
    };
};
export interface Nestable<T> {
    readonly parent: Nestable<T>;
    find(relative_kwl: string, opts?: {
        check_type?: boolean;
    }): Nestable<T>;
}
export interface RelativePath {
    kwl?: string;
    kw: string;
}
export interface FullPath {
    kwl: string;
    kw: string;
}
export declare type RowMask = string;
interface ViewBase {
    readonly kwl: string;
    readonly description: AnnotatedSubtreeDescription | AnnotatedComponentDescription[];
    readonly children: AnnotatedChildDescription[];
    /**
     * dispatch a write request <kwl>.<kw> := <payload>.
     *
     * This function returns immediately and will
     * silently fail if the requested change operation cannot be executed.
     */
    write_unchecked(relative_path: RelativePath, payload: KeywordPayload | {
        [array_element_index: number]: KeywordPayload;
    }): void;
    write_tree_unchecked(relative_path: {
        kwl?: string;
    }, payload: SubtreePayload): void;
    /**
     * read <kwl>.<kw> := <payload> without prior type or liveness checks
     */
    read_unchecked<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, timeout_secs?: number): Promise<T>;
    read<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, opts?: CommonCommandOptions): Promise<T>;
    /**
     * change <kwl>.<kw> to <payload>. By default, write will repeatedly
     * dispatch change requests until the timeout expires or until the
     * corresponding status keyword's value changes to <payload>. Alternative
     * success criteria can be specified using <opts.retry_until>.
     */
    write<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, payload: T | {
        [array_element_index: number]: T;
    }, opts?: WriteOptions<T>): Promise<void>;
}
interface WithDeref<T> {
    /**
     * read reference keyword <kwl>.<kw> and return a new View pointing to
     * the referenced keyword list (if any)
     */
    deref(relative_path: RelativePath, opts?: CommonCommandOptions): Promise<null | T>;
}
/**
 * views provide read/write access to (sub-)trees and can be backed
 * either by in-memory data structures, or by VSocket connections
 */
export declare type View = ViewBase & Nestable<View> & WithDeref<View>;
export interface TableView<S, R extends TableRowView<S> = TableRowView<S>> {
    allocated_indices(opts?: CommonCommandOptions): Promise<number[]>;
    is_allocated(index: number, opts?: CommonCommandOptions): Promise<boolean>;
    row(index: number, opts?: CommonCommandOptions): R;
    rows(opts?: CommonCommandOptions): Promise<R[]>;
}
export interface NamedTableView<S, R extends NamedTableRowView<S> = NamedTableRowView<S>> {
    allocated_indices(opts?: CommonCommandOptions): Promise<number[]>;
    create_row(opts?: CommonWriteOptions & {
        index?: number;
        name?: string;
        allow_reuse_row?: boolean;
    }): Promise<R>;
    is_allocated(index: number, opts?: CommonCommandOptions): Promise<boolean>;
    row(index: number, opts?: CommonCommandOptions): R;
    rows(opts?: CommonCommandOptions): Promise<R[]>;
}
export declare type RowView<S> = S & {
    readonly index: number;
};
export declare type TableRowView<S> = RowView<S> & {
    readonly enclosing_table: TableView<S>;
};
export declare type NamedTableRowView<S> = RowView<S> & {
    readonly enclosing_table: NamedTableView<S>;
    rename(name: string, opts?: CommonWriteOptions): Promise<void>;
    delete(opts?: CommonWriteOptions): Promise<void>;
};
export declare class Watcher {
    readonly kwl: string;
    readonly kw: string;
    private readonly destructor;
    constructor(kwl: string, kw: string, destructor: () => void);
    unwatch(): void;
}
export interface VSocketView extends ViewBase, Nestable<VSocketView>, WithDeref<VSocketView | NamedTableRowView<VSocketView>> {
    /**
     * read <kwl>.<kw>, potentially using cached values to avoid network
     * roundtrips if use_cache_if_present is either unspecified or set to true
     */
    read<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, opts?: CommonCommandOptions & {
        use_cache_if_present?: boolean;
    }): Promise<T>;
    /**
     * wait until <kwl.kw> fulfills <criterion>, or until <timeout> expires
     * (specified in seconds)
     */
    wait_until<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, criterion: (payload: T) => boolean, opts?: CommonCommandOptions): Promise<T>;
    /**
     * wait for the next update to <kwl>.<kw>, or until <timeout> expires.
     * Note that updates do not necessarily imply a change to the keyword
     * value
     */
    update<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, opts?: CommonCommandOptions & {
        defer_subscription?: boolean;
    }): Promise<T>;
    /**
     * subscribe to <kwl>.<kw> and execute <handler> on every incoming
     * value. Returns a watcher object that can later be unregistered using
     * watcher.unregister()
     */
    watch<T extends KeywordPayload = KeywordPayload>(relative_path: RelativePath, handler: ((payload: T) => void) | ((payload: T) => Promise<void>), opts?: CommonCommandOptions & {
        defer_subscription?: boolean;
    }): Promise<Watcher>;
}
export declare type IDHandler = (payload: KeywordPayload, id: number) => void;
export interface IDIntervalListener {
    unregister(): void;
}
export interface IDIntervalMap<T> {
    register(interval: [number, number], handler: IDHandler): T;
    find(keyword_id: number): IDHandler[];
}
export {};
