import { JSONObject, JSONValue, PartialJSONValue } from '@lumino/coreutils';
import { IDisposable } from '@lumino/disposable';
import { ISignal } from '@lumino/signaling';
import { IObservableJSON } from './observablejson';
import { IObservableMap } from './observablemap';
import { IObservableString } from './observablestring';
import { IObservableUndoableList } from './undoablelist';
/**
 * String type annotations for Observable objects that can be
 * created and placed in the IModelDB interface.
 */
export declare type ObservableType = 'Map' | 'List' | 'String' | 'Value';
/**
 * Base interface for Observable objects.
 */
export interface IObservable extends IDisposable {
    /**
     * The type of this object.
     */
    readonly type: ObservableType;
}
/**
 * Interface for an Observable object that represents
 * an opaque JSON value.
 */
export interface IObservableValue extends IObservable {
    /**
     * The type of this object.
     */
    readonly type: 'Value';
    /**
     * The changed signal.
     */
    readonly changed: ISignal<IObservableValue, ObservableValue.IChangedArgs>;
    /**
     * Get the current value, or `undefined` if it has not been set.
     */
    get(): PartialJSONValue | undefined;
    /**
     * Set the value.
     */
    set(value: PartialJSONValue): void;
}
/**
 * Interface for an object representing a single collaborator
 * on a realtime model.
 */
export interface ICollaborator extends JSONObject {
    /**
     * A user id for the collaborator.
     * This might not be unique, if the user has more than
     * one editing session at a time.
     */
    readonly userId: string;
    /**
     * A session id, which should be unique to a
     * particular view on a collaborative model.
     */
    readonly sessionId: string;
    /**
     * A human-readable display name for a collaborator.
     */
    readonly displayName: string;
    /**
     * A color to be used to identify the collaborator in
     * UI elements.
     */
    readonly color: string;
    /**
     * A human-readable short name for a collaborator, for
     * use in places where the full `displayName` would take
     * too much space.
     */
    readonly shortName: string;
}
/**
 * Interface for an IObservableMap that tracks collaborators.
 */
export interface ICollaboratorMap extends IObservableMap<ICollaborator> {
    /**
     * The local collaborator on a model.
     */
    readonly localCollaborator: ICollaborator;
}
/**
 * An interface for a path based database for
 * creating and storing values, which is agnostic
 * to the particular type of store in the backend.
 */
export interface IModelDB extends IDisposable {
    /**
     * The base path for the `IModelDB`. This is prepended
     * to all the paths that are passed in to the member
     * functions of the object.
     */
    readonly basePath: string;
    /**
     * Whether the database has been disposed.
     */
    readonly isDisposed: boolean;
    /**
     * Whether the database has been populated
     * with model values prior to connection.
     */
    readonly isPrepopulated: boolean;
    /**
     * Whether the database is collaborative.
     */
    readonly isCollaborative: boolean;
    /**
     * A promise that resolves when the database
     * has connected to its backend, if any.
     */
    readonly connected: Promise<void>;
    /**
     * A map of the currently active collaborators
     * for the database, including the local user.
     */
    readonly collaborators?: ICollaboratorMap;
    /**
     * Get a value for a path.
     *
     * @param path: the path for the object.
     *
     * @returns an `IObservable`.
     */
    get(path: string): IObservable | undefined;
    /**
     * Whether the `IModelDB` has an object at this path.
     *
     * @param path: the path for the object.
     *
     * @returns a boolean for whether an object is at `path`.
     */
    has(path: string): boolean;
    /**
     * Create a string and insert it in the database.
     *
     * @param path: the path for the string.
     *
     * @returns the string that was created.
     */
    createString(path: string): IObservableString;
    /**
     * Create an undoable list and insert it in the database.
     *
     * @param path: the path for the list.
     *
     * @returns the list that was created.
     *
     * #### Notes
     * The list can only store objects that are simple
     * JSON Objects and primitives.
     */
    createList<T extends JSONValue>(path: string): IObservableUndoableList<T>;
    /**
     * Create a map and insert it in the database.
     *
     * @param path: the path for the map.
     *
     * @returns the map that was created.
     *
     * #### Notes
     * The map can only store objects that are simple
     * JSON Objects and primitives.
     */
    createMap(path: string): IObservableJSON;
    /**
     * Create an opaque value and insert it in the database.
     *
     * @param path: the path for the value.
     *
     * @returns the value that was created.
     */
    createValue(path: string): IObservableValue;
    /**
     * Get a value at a path, or `undefined if it has not been set
     * That value must already have been created using `createValue`.
     *
     * @param path: the path for the value.
     */
    getValue(path: string): JSONValue | undefined;
    /**
     * Set a value at a path. That value must already have
     * been created using `createValue`.
     *
     * @param path: the path for the value.
     *
     * @param value: the new value.
     */
    setValue(path: string, value: JSONValue): void;
    /**
     * Create a view onto a subtree of the model database.
     *
     * @param basePath: the path for the root of the subtree.
     *
     * @returns an `IModelDB` with a view onto the original
     *   `IModelDB`, with `basePath` prepended to all paths.
     */
    view(basePath: string): IModelDB;
    /**
     * Dispose of the resources held by the database.
     */
    dispose(): void;
}
/**
 * A concrete implementation of an `IObservableValue`.
 */
export declare class ObservableValue implements IObservableValue {
    /**
     * Constructor for the value.
     *
     * @param initialValue: the starting value for the `ObservableValue`.
     */
    constructor(initialValue?: JSONValue);
    /**
     * The observable type.
     */
    get type(): 'Value';
    /**
     * Whether the value has been disposed.
     */
    get isDisposed(): boolean;
    /**
     * The changed signal.
     */
    get changed(): ISignal<this, ObservableValue.IChangedArgs>;
    /**
     * Get the current value, or `undefined` if it has not been set.
     */
    get(): JSONValue;
    /**
     * Set the current value.
     */
    set(value: JSONValue): void;
    /**
     * Dispose of the resources held by the value.
     */
    dispose(): void;
    private _value;
    private _changed;
    private _isDisposed;
}
/**
 * The namespace for the `ObservableValue` class statics.
 */
export declare namespace ObservableValue {
    /**
     * The changed args object emitted by the `IObservableValue`.
     */
    class IChangedArgs {
        /**
         * The old value.
         */
        oldValue: JSONValue | undefined;
        /**
         * The new value.
         */
        newValue: JSONValue | undefined;
    }
}
/**
 * A concrete implementation of an `IModelDB`.
 */
export declare class ModelDB implements IModelDB {
    /**
     * Constructor for the `ModelDB`.
     */
    constructor(options?: ModelDB.ICreateOptions);
    /**
     * The base path for the `ModelDB`. This is prepended
     * to all the paths that are passed in to the member
     * functions of the object.
     */
    get basePath(): string;
    /**
     * Whether the database is disposed.
     */
    get isDisposed(): boolean;
    /**
     * Whether the model has been populated with
     * any model values.
     */
    readonly isPrepopulated: boolean;
    /**
     * Whether the model is collaborative.
     */
    readonly isCollaborative: boolean;
    /**
     * A promise resolved when the model is connected
     * to its backend. For the in-memory ModelDB it
     * is immediately resolved.
     */
    readonly connected: Promise<void>;
    /**
     * Get a value for a path.
     *
     * @param path: the path for the object.
     *
     * @returns an `IObservable`.
     */
    get(path: string): IObservable | undefined;
    /**
     * Whether the `IModelDB` has an object at this path.
     *
     * @param path: the path for the object.
     *
     * @returns a boolean for whether an object is at `path`.
     */
    has(path: string): boolean;
    /**
     * Create a string and insert it in the database.
     *
     * @param path: the path for the string.
     *
     * @returns the string that was created.
     */
    createString(path: string): IObservableString;
    /**
     * Create an undoable list and insert it in the database.
     *
     * @param path: the path for the list.
     *
     * @returns the list that was created.
     *
     * #### Notes
     * The list can only store objects that are simple
     * JSON Objects and primitives.
     */
    createList<T extends JSONValue>(path: string): IObservableUndoableList<T>;
    /**
     * Create a map and insert it in the database.
     *
     * @param path: the path for the map.
     *
     * @returns the map that was created.
     *
     * #### Notes
     * The map can only store objects that are simple
     * JSON Objects and primitives.
     */
    createMap(path: string): IObservableJSON;
    /**
     * Create an opaque value and insert it in the database.
     *
     * @param path: the path for the value.
     *
     * @returns the value that was created.
     */
    createValue(path: string): IObservableValue;
    /**
     * Get a value at a path, or `undefined if it has not been set
     * That value must already have been created using `createValue`.
     *
     * @param path: the path for the value.
     */
    getValue(path: string): JSONValue | undefined;
    /**
     * Set a value at a path. That value must already have
     * been created using `createValue`.
     *
     * @param path: the path for the value.
     *
     * @param value: the new value.
     */
    setValue(path: string, value: JSONValue): void;
    /**
     * Create a view onto a subtree of the model database.
     *
     * @param basePath: the path for the root of the subtree.
     *
     * @returns an `IModelDB` with a view onto the original
     *   `IModelDB`, with `basePath` prepended to all paths.
     */
    view(basePath: string): ModelDB;
    /**
     * Set a value at a path. Not intended to
     * be called by user code, instead use the
     * `create*` factory methods.
     *
     * @param path: the path to set the value at.
     *
     * @param value: the value to set at the path.
     */
    set(path: string, value: IObservable): void;
    /**
     * Dispose of the resources held by the database.
     */
    dispose(): void;
    /**
     * Compute the fully resolved path for a path argument.
     */
    private _resolvePath;
    private _basePath;
    private _db;
    private _toDispose;
    private _isDisposed;
    private _disposables;
}
/**
 * A namespace for the `ModelDB` class statics.
 */
export declare namespace ModelDB {
    /**
     * Options for creating a `ModelDB` object.
     */
    interface ICreateOptions {
        /**
         * The base path to prepend to all the path arguments.
         */
        basePath?: string;
        /**
         * A ModelDB to use as the store for this
         * ModelDB. If none is given, it uses its own store.
         */
        baseDB?: ModelDB;
    }
    /**
     * A factory interface for creating `IModelDB` objects.
     */
    interface IFactory {
        /**
         * Create a new `IModelDB` instance.
         */
        createNew(path: string): IModelDB;
    }
}
