import { EventEmitter } from "eventemitter3";
import { DocHandle } from "./DocHandle.js";
import { NetworkAdapterInterface, type PeerMetadata } from "./network/NetworkAdapterInterface.js";
import { NetworkSubsystem } from "./network/NetworkSubsystem.js";
import { StorageAdapterInterface } from "./storage/StorageAdapterInterface.js";
import { StorageSubsystem } from "./storage/StorageSubsystem.js";
import { StorageId } from "./storage/types.js";
import type { AnyDocumentId, DocumentId, PeerId } from "./types.js";
/** A Repo is a collection of documents with networking, syncing, and storage capabilities. */
/** The `Repo` is the main entry point of this library
 *
 * @remarks
 * To construct a `Repo` you will need an {@link StorageAdapter} and one or
 * more {@link NetworkAdapter}s. Once you have a `Repo` you can use it to
 * obtain {@link DocHandle}s.
 */
export declare class Repo extends EventEmitter<RepoEvents> {
    #private;
    /** @hidden */
    networkSubsystem: NetworkSubsystem;
    /** @hidden */
    storageSubsystem?: StorageSubsystem;
    /** The debounce rate is adjustable on the repo. */
    /** @hidden */
    saveDebounceRate: number;
    /** By default, we share generously with all peers. */
    /** @hidden */
    sharePolicy: SharePolicy;
    /** maps peer id to to persistence information (storageId, isEphemeral), access by collection synchronizer  */
    /** @hidden */
    peerMetadataByPeerId: Record<PeerId, PeerMetadata>;
    constructor({ storage, network, peerId, sharePolicy, isEphemeral, enableRemoteHeadsGossiping, }?: RepoConfig);
    /** Returns all the handles we have cached. */
    get handles(): Record<DocumentId, DocHandle<any>>;
    /** Returns a list of all connected peer ids */
    get peers(): PeerId[];
    getStorageIdOfPeer(peerId: PeerId): StorageId | undefined;
    /**
     * Creates a new document and returns a handle to it. The initial value of the document is an
     * empty object `{}` unless an initial value is provided. Its documentId is generated by the
     * system. we emit a `document` event to advertise interest in the document.
     */
    create<T>(initialValue?: T): DocHandle<T>;
    /** Create a new DocHandle by cloning the history of an existing DocHandle.
     *
     * @param clonedHandle - The handle to clone
     *
     * @remarks This is a wrapper around the `clone` function in the Automerge library.
     * The new `DocHandle` will have a new URL but will share history with the original,
     * which means that changes made to the cloned handle can be sensibly merged back
     * into the original.
     *
     * Any peers this `Repo` is connected to for whom `sharePolicy` returns `true` will
     * be notified of the newly created DocHandle.
     *
     * @throws if the cloned handle is not yet ready or if
     * `clonedHandle.docSync()` returns `undefined` (i.e. the handle is unavailable).
     */
    clone<T>(clonedHandle: DocHandle<T>): DocHandle<T>;
    /**
     * Retrieves a document by id. It gets data from the local system, but also emits a `document`
     * event to advertise interest in the document.
     */
    find<T>(
    /** The url or documentId of the handle to retrieve */
    id: AnyDocumentId): DocHandle<T>;
    delete(
    /** The url or documentId of the handle to delete */
    id: AnyDocumentId): void;
    /**
     * Exports a document to a binary format.
     * @param id - The url or documentId of the handle to export
     *
     * @returns Promise<Uint8Array | undefined> - A Promise containing the binary document,
     * or undefined if the document is unavailable.
     */
    export(id: AnyDocumentId): Promise<Uint8Array | undefined>;
    /**
     * Imports document binary into the repo.
     * @param binary - The binary to import
     */
    import<T>(binary: Uint8Array): DocHandle<T>;
    subscribeToRemotes: (remotes: StorageId[]) => void;
    storageId: () => Promise<StorageId | undefined>;
    /**
     * Writes Documents to a disk.
     * @hidden this API is experimental and may change.
     * @param documents - if provided, only writes the specified documents.
     * @returns Promise<void>
     */
    flush(documents?: DocumentId[]): Promise<void>;
}
export interface RepoConfig {
    /** Our unique identifier */
    peerId?: PeerId;
    /** Indicates whether other peers should persist the sync state of this peer.
     * Sync state is only persisted for non-ephemeral peers */
    isEphemeral?: boolean;
    /** A storage adapter can be provided, or not */
    storage?: StorageAdapterInterface;
    /** A list of network adapters (more can be added at runtime). */
    network?: NetworkAdapterInterface[];
    /**
     * Normal peers typically share generously with everyone (meaning we sync all our documents with
     * all peers). A server only syncs documents that a peer explicitly requests by ID.
     */
    sharePolicy?: SharePolicy;
    /**
     * Whether to enable the experimental remote heads gossiping feature
     */
    enableRemoteHeadsGossiping?: boolean;
}
/** A function that determines whether we should share a document with a peer
 *
 * @remarks
 * This function is called by the {@link Repo} every time a new document is created
 * or discovered (such as when another peer starts syncing with us). If this
 * function returns `true` then the {@link Repo} will begin sharing the new
 * document with the peer given by `peerId`.
 * */
export type SharePolicy = (peerId: PeerId, documentId?: DocumentId) => Promise<boolean>;
export interface RepoEvents {
    /** A new document was created or discovered */
    document: (arg: DocumentPayload) => void;
    /** A document was deleted */
    "delete-document": (arg: DeleteDocumentPayload) => void;
    /** A document was marked as unavailable (we don't have it and none of our peers have it) */
    "unavailable-document": (arg: DeleteDocumentPayload) => void;
}
export interface DocumentPayload {
    handle: DocHandle<any>;
    isNew: boolean;
}
export interface DeleteDocumentPayload {
    documentId: DocumentId;
}
//# sourceMappingURL=Repo.d.ts.map