import { Network } from '@textile/threads-network';
import { EventEmitter2 } from 'eventemitter2';
import { Dispatcher, Instance, DomainDatastore } from '@textile/threads-store';
import { Datastore } from 'interface-datastore';
import { ThreadID, ThreadKey, Multiaddr, Identity, Libp2pCryptoIdentity, LogInfo } from '@textile/threads-core';
import { EventBus } from './eventbus';
import { Collection, JSONSchema, Config } from './collection';
export declare const mismatchError: Error;
export declare const missingIdentity: Error;
/**
 * DatabaseSettings specifies a set of settings to constrol the operation of the Database.
 * Implementations should provide reasonable defaults.
 */
export interface DatabaseSettings {
    /**
     * Dispatcher is used to dispatch local events from producers to reducers (collections).
     * This option should generally be left undefined to use defaults.
     */
    dispatcher: Dispatcher;
    /**
     * EventBus is used to marshal events to and from a Threads network.
     * This option should generally be left undefined to use defaults.
     */
    eventBus: EventBus;
    /**
     * Network is the networking layer. Can be used to provide a custom networking configuration.
     */
    network: Network;
    /**
     * The primary datastore. It is used to partition out "sub-domains" for collections.
     * By default, this will be a LevelDatastore.
     */
    child: Datastore<any>;
}
export interface StartOptions {
    /**
     * An array of Collection Config objects to use when initializing the Database
     */
    collections?: Config[];
    /**
     * The ID of the Thread to use for this database. If specified for a new database,
     * a Thread with the given ID will be used to orchestrate the database. If accessing an existing
     * database by name, this should be left undefined.
     */
    threadID?: ThreadID;
}
export declare class Database extends EventEmitter2 implements DatabaseSettings {
    /**
     * Collections is a map of collections (database tables)
     */
    collections: Map<string, Collection>;
    /**
     * Network is the networking layer
     */
    network: Network;
    /**
     * EventBus is used to marshal events to and from a Threads network
     */
    eventBus: EventBus;
    /**
     * Dispatcher is used to dispatch local events from producers to reducers (collections)
     */
    dispatcher: Dispatcher;
    /**
     * Child is the primary datastore. It is used to partition out "sub-domains" for collections.
     */
    child: DomainDatastore<any>;
    /**
     * The ID of the Thread to use for this database.
     */
    threadID?: ThreadID;
    /**
     * Database creates a new database using the provided thread.
     * @param datastore The primary datastore or a name for a datastore.
     * It is used to partition out "sub-domains" for collections.
     * @param options A set of database options.
     * These are used to control the operation of the underlying database.
     */
    constructor(store: Datastore<any> | string, options?: Partial<DatabaseSettings>);
    ownLogInfo(): Promise<LogInfo | undefined>;
    /**
     * newCollectionFromObject creates a new collection from an initial input object.
     * It will attempt to infer the JSON schema from the input object.
     * @param name A name for the collection.
     * @param data A valid JSON object.
     */
    newCollectionFromObject<T extends Instance>(name: string, data: T): Promise<Collection<T>>;
    /**
     * newCollection creates a new empty collection from an input JSON schema.
     * @param name A name for the collection.
     * @param schema A valid JSON schema object.
     */
    newCollection<T extends Instance>(name: string, schema: JSONSchema): Promise<Collection<T>>;
    /**
     * Open (and sync) a remote database.
     * Opens the underlying datastore if not already open, and enables the dispatcher and
     * underlying services (event bus, network network, etc). This method will also begin pulling
     * from the underlying remote Thread. Only one of `start` or `startFromAddress` should be used.
     * @param identity An identity to use for creating records in the database. A random identity
     * can be created with `Database.randomIdentity()`, however, it is not easy/possible to migrate
     * identities after the fact. Please store or otherwise persist any identity information
     * if you wish to retrieve user data later, or use an external identity provider.
     * @param addr The address for the thread with which to connect.
     * Should be of the form /ip4/<url/ip-address>/tcp/<port>/p2p/<peer-id>/thread/<thread-id>
     * @param threadKey Set of symmetric keys.
     * @param opts A set of options to configure the setup and usage of the underlying database.
     */
    startFromAddress(identity: Identity, addr: Multiaddr, threadKey?: ThreadKey, opts?: StartOptions): Promise<void>;
    /**
     * Open the database.
     * Opens the underlying datastore if not already open, and enables the dispatcher and
     * underlying services (event bus, network network, etc).
     * @param identity An identity to use for creating records in the database. A random identity
     * can be created with `Database.randomIdentity()`, however, it is not easy/possible to migrate
     * identities after the fact. Please store or otherwise persist any identity information
     * if you wish to retrieve user data later, or use an external identity provider.
     * @param opts A set of options to configure the setup and usage of the underlying database.
     */
    start(identity: Identity, opts?: StartOptions): Promise<void>;
    /**
     * Return db (remote) address and keys.
     */
    getInfo(): Promise<{
        key: ThreadKey | undefined;
        addrs: Set<Multiaddr> | undefined;
    } | undefined>;
    /**
     * Close and stop the database.
     * Stops the underlying datastore if not already stopped, and disables the dispatcher and
     * underlying services (event bus, network network, etc.)
     */
    close(): Promise<void>;
    private onRecord;
    private onEvents;
    private onUpdate;
    private rehydrate;
    /**
     * Create a random user identity.
     */
    static randomIdentity(): Promise<Libp2pCryptoIdentity>;
}
