import { Document as Document$1 } from 'document-model-graphql';
import * as document_model_graphql_dist_generated_document from 'document-model-graphql/dist/generated/document';
import JSZip from 'jszip';
import { WritableDraft } from 'immer/dist/internal';

type BaseAction = Document$1.BaseAction;

/**
 * Defines the basic structure of an action.
 *
 * @typeParam T - The name of the action type. A `string` type by default.
 */
type Action<T = string> = {
    /** The name of the action. */
    type: T;
    /** The payload of the action. */
    input?: unknown;
};
/**
 * A pure function that takes an action and the previous state
 * of the document and returns the new state.
 *
 * @typeParam State - The type of the document data.
 * @typeParam A - The type of the actions supported by the reducer.
 */
type Reducer<State, A extends Action> = (state: Document<State, A>, action: A) => Document<State, A>;
/**
 * A {@link Reducer} that prevents mutable code from changing the previous state.
 *
 * @remarks
 * This reducer is wrapped with {@link https://immerjs.github.io/immer/ | Immer}.
 * This allows the reducer code to be mutable, making it simpler and
 * avoiding unintended changes in the provided state.
 * The returned state will always be a new object.
 *
 * @typeParam State - The type of the document data.
 * @typeParam A - The type of the actions supported by the reducer.
 */
type ImmutableReducer<State, A extends Action> = (state: WritableDraft<Document<State, A>>, action: A) => Document<State, A> | void;
/**
 * An operation that was applied to a {@link Document}.
 *
 * @remarks
 * Wraps an action with an index, to be added to the operations history of a Document.
 * The `index` field is used to keep all operations in order and enable replaying the
 * document's history from the beginning.
 *
 * @typeParam A - The type of the action.
 */
type Operation<A extends Action = Action> = A & {
    /** Position of the operation in the history */
    index: number;
    /** Timestamp of when the operation was added */
    timestamp: string;
    /** Hash of the resulting document data after the operation */
    hash: string;
};
/**
 * The base attributes of a {@link Document}.
 */
type DocumentHeader = {
    /** The name of the document. */
    name: string;
    /** The number of operations applied to the document. */
    revision: number;
    /** The type of the document model. */
    documentType: string;
    /** The timestamp of the creation date of the document. */
    created: string;
    /** The timestamp of the last change in the document. */
    lastModified: string;
};
/**
 * The attributes stored for a file. Namely, attachments of a document.
 */
type DocumentFile = {
    /** The binary data of the attachment in Base64 */
    data: string;
    /** The MIME type of the attachment */
    mimeType: string;
    extension?: string;
    fileName?: string;
};
/**
 * Object that indexes attachments of a Document.
 *
 * @remarks
 * This is used to reduce memory usage to avoid
 * multiple instances of the binary data of the attachments.
 *
 */
type FileRegistry = Record<Attachment, DocumentFile>;
/**
 * The base type of a document model.
 *
 * @remarks
 * This type is extended by all Document models.
 *
 * @typeParam Data - The type of the document data attribute.
 * @typeParam A - The type of the actions supported by the Document.
 */
type Document<Data = unknown, A extends Action = Action> = DocumentHeader & {
    /** The document model specific state. */
    data: Data;
    /** The operations history of the document. */
    operations: Operation<A | BaseAction>[];
    /** The initial state of the document, enabling replaying operations. */
    initialState: Omit<Document<Data, A>, 'initialState'>;
    /** The index of document attachments. */
    fileRegistry: FileRegistry;
};
/**
 * String type representing an attachment in a Document.
 *
 * @remarks
 * Attachment string is formatted as `attachment://<filename>`.
 */
type Attachment = `attachment://${string}`;

/**
 * This is an abstract class representing a document and provides methods
 * for creating and manipulating documents.
 * @typeparam T - The type of data stored in the document.
 * @typeparam A - The type of action the document can take.
 */
declare abstract class BaseDocument<T, A extends Action> {
    protected state: Document<T, A>;
    private reducer;
    /**
     * Constructs a BaseDocument instance with an initial state.
     * @param reducer - The reducer function that updates the state.
     * @param initialState - The initial state of the document.
     */
    constructor(reducer: Reducer<T, A | Document$1.BaseAction>, initialState?: Partial<Document<T, A>> & {
        data: T;
    });
    /**
     * Dispatches an action to update the state of the document.
     * @param action - The action to dispatch.
     * @returns The Document instance.
     */
    protected dispatch(action: A | Document$1.BaseAction): this;
    /**
     * Saves the state of the document to a file.
     * @param path - The file path where the state should be saved.
     * @param extension - The file extension to use when saving the state.
     * @returns The file path where the state was saved.
     */
    protected saveToFile(path: string, extension: string, name?: string): Promise<string>;
    /**
     * Loads the state of the document from a file.
     * @param path - The file path where the state is stored.
     */
    loadFromFile(path: string): Promise<void>;
    /**
     * Loads the state of the document from a file and returns it.
     * @param path - The file path where the state is stored.
     * @param reducer - The reducer function that updates the state.
     * @returns The state of the document.
     */
    protected static stateFromFile<T, A extends Action>(path: string, reducer: Reducer<T, A | Document$1.BaseAction>): Promise<Document<T, Document$1.BaseAction | A>>;
    /**
     * Gets the name of the document.
     */
    get name(): string;
    /**
     * Gets the type of document.
     */
    get documentType(): string;
    /**
     * Gets the timestamp of the date the document was created.
     */
    get created(): string;
    /**
     * Gets the timestamp of the date the document was last modified.
     */
    get lastModified(): string;
    /**
     * Gets the revision number of the document.
     */
    get revision(): number;
    /**
     * Gets the initial state of the document.
     */
    get initialState(): Omit<Document<T, A>, "initialState">;
    /**
     *    Gets the list of operations performed on the document.
     */
    get operations(): Operation<Document$1.BaseAction | A>[];
    /**
     * Gets the attachment associated with the given key.
     * @param attachment - The key of the attachment to retrieve.
     */
    getAttachment(attachment: Attachment): DocumentFile;
    /**
     * Sets the name of the document.
     * @param name - The new name of the document.
     */
    setName(name: string): void;
    /**
     * Reverts a number of actions from the document.
     * @param count - The number of actions to revert.
     */
    undo(count: number): void;
    /**
     * Reapplies a number of actions to the document.
     * @param count - The number of actions to reapply.
     */
    redo(count: number): void;
    /**
     * Removes a range of operations from the document.
     * @param start - The starting index of the range to remove.
     * @param end - The ending index of the range to remove.
     */
    prune(start?: number | undefined, end?: number | undefined): void;
    /**
     * Loads a document state and a set of operations.
     * @param state - The state to load.
     * @param operations - The operations to apply to the document.
     */
    loadState(state: Pick<Document<T, A>, 'data' | 'name'>, operations: number): void;
}
/**
 * Applies multiple mixins to a base class.
 * Used to have separate mixins to group methods by actions.
 *
 * @remarks
 * {@link https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern}
 *
 * @param derivedCtor - The class to apply the mixins to.
 * @param constructors - The constructors of the mixins.
 */
declare function applyMixins(derivedCtor: any, constructors: any[]): void;

type FileInput = string | number[] | Uint8Array | ArrayBuffer | Blob;
declare const createZip: (document: Document) => Promise<JSZip>;
/**
 * Saves a document to a ZIP file.
 *
 * @remarks
 * This function creates a ZIP file containing the document's state, operations,
 * and file attachments. The file is saved to the specified path.
 *
 * @param document - The document to save to the file.
 * @param path - The path to save the file to.
 * @param extension - The extension to use for the file.
 * @returns A promise that resolves to the path of the saved file.
 */
declare const saveToFile: (document: Document, path: string, extension: string, name?: string) => Promise<string>;
/**
 * Loads a document from a ZIP file.
 *
 * @remarks
 * This function reads a ZIP file and returns the document state after
 * applying all the operations. The reducer is used to apply the operations.
 *
 * @typeParam S - The type of the state object.
 * @typeParam A - The type of the actions that can be applied to the state object.
 *
 * @param path - The path to the ZIP file.
 * @param reducer - The reducer to apply the operations to the state object.
 * @returns A promise that resolves to the document state after applying all the operations.
 * @throws An error if the initial state or the operations history is not found in the ZIP file.
 */
declare const loadFromFile: <S, A extends Action<string>>(path: string, reducer: Reducer<S, document_model_graphql_dist_generated_document.BaseAction | A>) => Promise<Document<S, document_model_graphql_dist_generated_document.BaseAction | A>>;
declare const loadFromInput: <S, A extends Action<string>>(input: FileInput, reducer: Reducer<S, document_model_graphql_dist_generated_document.BaseAction | A>) => Promise<Document<S, document_model_graphql_dist_generated_document.BaseAction | A>>;
/**
 * Fetches an attachment from a URL and returns its base64-encoded data and MIME type.
 * @param url - The URL of the attachment to fetch.
 * @returns A Promise that resolves to an object containing the base64-encoded data and MIME type of the attachment.
 */
declare function getRemoteFile(url: string): Promise<DocumentFile>;
/**
 * Reads an attachment from a file and returns its base64-encoded data and MIME type.
 * @param path - The path of the attachment file to read.
 * @returns A Promise that resolves to an object containing the base64-encoded data and MIME type of the attachment.
 */
declare function getLocalFile(path: string): Promise<DocumentFile>;
/**
 * Returns the SHA1 hash of the given attachment data.
 * @param data - The base64-encoded data of the attachment to hash.
 * @returns The hash of the attachment data.
 */
declare function hashAttachment(data: string): string;

export { Action as A, BaseDocument as B, DocumentFile as D, FileInput as F, ImmutableReducer as I, Operation as O, Reducer as R, Document as a, BaseAction as b, createZip as c, getRemoteFile as d, loadFromInput as e, Attachment as f, getLocalFile as g, hashAttachment as h, DocumentHeader as i, FileRegistry as j, applyMixins as k, loadFromFile as l, saveToFile as s };
