import { Datastore, Query } from 'interface-datastore';
import { ValidateFunction } from 'ajv';
import { JSONSchema4, JSONSchema6, JSONSchema7 } from 'json-schema';
import { Dispatcher, Instance, JsonPatchStore } from '@textile/threads-store';
import { FilterQuery } from './query';
export declare const resolve: (object: any, path: string, defaultValue?: any) => any;
export { FilterQuery };
export declare type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
export declare const existingKeyError: Error;
interface FindOptions<T extends Instance> extends Partial<Pick<Query<T>, 'limit' | 'offset' | 'keysOnly'>> {
    sort?: {
        [key in keyof T]?: 1 | -1;
    };
}
export interface Config {
    name: string;
    schema: JSONSchema;
}
/**
 * Options for creating a new collection.
 */
export interface Options<T extends Instance> {
    child?: Datastore<T>;
    dispatcher?: Dispatcher;
}
/**
 * Document is a wrapper around a Collection and a (proxy to) an Instance object.
 */
export declare class Document<T extends Instance = any> {
    private _collection;
    private _data;
    constructor(_collection: Collection<T>, _data: T);
    /**
     * Save this Instance to its parent collection.
     */
    save(): Promise<void>;
    /**
     * Remove this Instance (by id) from its parent collection.
     */
    remove(): Promise<void>;
    /**
     * Check if this Instance (by id) exists in its parent collection.
     */
    exists(): Promise<boolean>;
    /**
     * Get a JSON representation of this Instance.
     */
    toJSON(): T;
    private toCBOR;
}
export interface Collection<T extends Instance = any> {
    (data: Partial<T>): Document<T> & T;
    new (data: Partial<T>): Document<T> & T;
}
export declare class ReadonlyCollection<T extends Instance = any> {
    readonly name: string;
    /**
     * Validator is a function for validating inputs against a given schema.
     */
    validator: ValidateFunction;
    /**
     * Child is the underlying datastore.
     */
    child: JsonPatchStore<T>;
    /**
     * Collection creates a new collection.
     * @param name A name for the collection.
     * @param schema A valid JSON schema object.
     * @param options The underlying collection options.
     */
    constructor(name: string, schema: JSONSchema, options?: Options<T>);
    static fromCollection<T extends Instance>(other: Collection<T>): ReadonlyCollection<any>;
    /**
     * Find an Instance by _id
     * @param id The Instance id.
     */
    findById(id: string): Promise<T>;
    /**
     * Check that a given Instance exists.
     * @param id The Instance id.
     */
    has(id: string): Promise<boolean>;
    /**
     * Find all entities matching the query
     * @param query Mongodb-style filter query.
     * @param options Additional options to control query operation.
     */
    find(query?: FilterQuery<T>, options?: FindOptions<T>): AsyncIterable<import("interface-datastore").Result<T>>;
    /**
     * Find the first Instance matching the query
     * @param query Mongodb-style filter query.
     * @param options Additional search options.
     */
    findOne(query: FilterQuery<T>, options?: FindOptions<T>): Promise<IteratorResult<import("interface-datastore").Result<T>, any>>;
    /**
     * Count all entities matching the query
     * @param query Mongodb-style filter query.
     * @param options Additional search options.
     */
    count(query: FilterQuery<T>, options?: FindOptions<T>): Promise<number>;
}
/**
 * Collection is a store of entities defined by a single schema.
 */
export declare class Collection<T extends Instance = any> extends ReadonlyCollection<T> {
    readonly name: string;
    /**
     * Collection creates a new collection.
     * @param name A name for the collection.
     * @param schema A valid JSON schema object.
     * @param options The underlying collection options.
     */
    constructor(name: string, schema: JSONSchema, options?: Options<T>);
    /**
     * Save (multiple) entities.
     * @note Save is similar to insert, except it allows saving/overwriting existing entities.
     * @param entities A variadic array of entities.
     */
    save(...entities: T[]): Promise<void>;
    /**
     * Remove entities by id.
     * @param ids
     */
    delete(...ids: string[]): Promise<void>;
    /**
     * Insert (multiple) new instances.
     * @note Insert is similar to save, except it will not allow saving/overwriting existing entities.
     * @param instances
     */
    insert(...instances: T[]): Promise<void>;
    /**
     * Lock the collection for readonly operations.
     * @param cb A callback that takes a readonly collection.
     * @param timeout How long to wait to obtain the read lock. If after timeout seconds the lock
     * is not obtained, the method will error.
     * @note Currenrly, transactions are not atomic, or even really transactions in the normal sense.
     * They only provide locking for multi-read/single-write access to the given collection.
     */
    readTransaction(cb: (c: ReadonlyCollection<T>) => Promise<void> | void, timeout?: number): Promise<void>;
    /**
     * Lock the collection for exclusive write operations.
     * @param cb A callback that takes a collection.
     * @param timeout How long to wait to obtain the write lock. If after timeout seconds the lock
     * is not obtained, the method will error.
     * @note Currenrly, transactions are not atomic, or even really transactions in the normal sense.
     * They only provide locking for multi-read/single-write access to the given collection.
     */
    writeTransaction(cb: (c: Collection<T>) => Promise<void> | void, timeout?: number): Promise<void>;
}
