import { GardState, Transaction } from 'wordgard/state';
import { ChangeSet } from 'wordgard/doc';

/**
Create an instance of the collaborative editing plugin.
*/
declare function collab(config?: collab.Config): GardState.Extension;
declare namespace collab {
    /**
    Options to {@link collab}.
    */
    type Config = {
        /**
        The starting document version. Defaults to 0.
        */
        startVersion?: number;
        /**
        This client's identifying {@link collab.getClientID ID}. Will be a
        randomly generated string if not provided.
        */
        clientID?: string;
        /**
        It is possible to share information other than document changes
        through this extension. If you provide this option, your
        function will be called on each transaction, and the effects it
        returns will be sent to the server, much like changes are. Such
        effects are automatically remapped when conflicting remote
        changes come in.
        */
        sharedEffects?: (tr: Transaction) => readonly Transaction.Effect<any>[];
    };
    /**
    An update is a set of changes and effects.
    */
    interface Update {
        /**
        The document version that this update starts from.
        */
        versionBefore: number;
        /**
        The new version, as determined by the client creating the
        update.
        */
        versionAfter: number;
        /**
        The changes made by this update.
        */
        changes: ChangeSet;
        /**
        The effects in this update. There'll only ever be effects here
        when you configure your collab extension with a {@link
        collab.Config.sharedEffects `sharedEffects`} option.
        */
        effects?: readonly Transaction.Effect<unknown>[];
        /**
        The {@link collab.Config.clientID ID} of the client who
        created this update.
        */
        clientID: string;
    }
    /**
    Create a transaction that represents a set of new updates received
    from the authority. Applying this transaction moves the state
    forward to, for remote changes, integrate them into our local
    state, and for our own changes, drop them from the set of
    unconfirmed local changes.
    */
    function receive(state: GardState, updates: readonly collab.Update[]): Transaction;
    /**
    If there are unconfirmed local changes that need to be sent to the
    server,return them as an `Update` object.
    */
    function sendableUpdate(state: GardState): collab.Update | null;
    /**
    Get the version up to which the collab plugin has synced with the
    central authority.
    */
    function getSyncedVersion(state: GardState): number;
    /**
    Get this editor's collaborative editing client ID.
    */
    function getClientID(state: GardState): string;
}

export { collab };
