/// <reference types="node" />
type InputMaybe<T> = T | null | undefined;
/** All built-in and custom scalars, mapped to their actual values */
type Scalars = {
    ID: string;
    String: string;
    Boolean: boolean;
    Int: number;
    Float: number;
    Address: `${string}:0x${string}`;
    DateTime: string;
    Unknown: unknown;
};
type BaseAction = LoadStateAction | PruneAction | RedoAction | SetNameAction | UndoAction;
type Load_State = 'LOAD_STATE';
type LoadStateAction = {
    input: LoadStateActionInput;
    type: Load_State | `${Load_State}`;
};
type LoadStateActionInput = {
    operations: Scalars['Int'];
    state: LoadStateActionStateInput;
};
type LoadStateActionStateInput = {
    data?: InputMaybe<Scalars['Unknown']>;
    name: Scalars['String'];
};
type Prune = 'PRUNE';
type PruneAction = {
    input: PruneActionInput;
    type: Prune | `${Prune}`;
};
type PruneActionInput = {
    end?: InputMaybe<Scalars['Int']>;
    start?: InputMaybe<Scalars['Int']>;
};
type Redo = 'REDO';
type RedoAction = {
    input: Scalars['Int'];
    type: Redo | `${Redo}`;
};
type Set_Name = 'SET_NAME';
type SetNameAction = {
    input: Scalars['String'];
    type: Set_Name | `${Set_Name}`;
};
type Undo = 'UNDO';
type UndoAction = {
    input: Scalars['Int'];
    type: Undo | `${Undo}`;
};

declare type PrimitiveType = number | string | boolean;
/** Object types that should never be mapped */
declare type AtomicObject = Function | Promise<any> | Date | RegExp;
/**
 * If the lib "ES2015.Collection" is not included in tsconfig.json,
 * types like ReadonlyArray, WeakMap etc. fall back to `any` (specified nowhere)
 * or `{}` (from the node types), in both cases entering an infinite recursion in
 * pattern matching type mappings
 * This type can be used to cast these types to `void` in these cases.
 */
declare type IfAvailable<T, Fallback = void> = true | false extends (T extends never ? true : false) ? Fallback : keyof T extends never ? Fallback : T;
/**
 * These should also never be mapped but must be tested after regular Map and
 * Set
 */
declare type WeakReferences = IfAvailable<WeakMap<any, any>> | IfAvailable<WeakSet<any>>;
declare type WritableDraft<T> = {
    -readonly [K in keyof T]: Draft<T[K]>;
};
/** Convert a readonly type into a mutable type, if possible */
declare type Draft<T> = T extends PrimitiveType ? T : T extends AtomicObject ? T : T extends IfAvailable<ReadonlyMap<infer K, infer V>> ? Map<Draft<K>, Draft<V>> : T extends IfAvailable<ReadonlySet<infer V>> ? Set<Draft<V>> : T extends WeakReferences ? T : T extends object ? WritableDraft<T> : T;

/**
 * Defines the basic structure of an action.
 *
 * @typeParam T - The name of the action type. A `string` type by default.
 */
type Action<T extends string = string, I = unknown> = {
    /** The name of the action. */
    type: T;
    /** The payload of the action. */
    input: I;
    /** The attachments included in the action. */
    attachments?: InputDocumentFile[] | undefined;
};
/**
 * 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 | BaseAction) => 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: Draft<Document<State, A>>, action: A | BaseAction) => Document<State, A> | void;
type ImmutableStateReducer<State, A extends Action> = (state: Draft<State>, action: A) => State | 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 | null;
    fileName?: string | null;
};
type InputDocumentFile = DocumentFile & {
    hash: 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>;
type ExtendedState<State = unknown> = DocumentHeader & {
    /** The document model specific state. */
    state: State;
    /** The index of document attachments. */
    attachments: FileRegistry;
};
/**
 * 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<S = unknown, A extends Action = Action> = 
/** The document model specific state. */
ExtendedState<S> & {
    /** The operations history of the document. */
    operations: Operation<A | BaseAction>[];
    /** The initial state of the document, enabling replaying operations. */
    initialState: ExtendedState<S>;
};
/**
 * String type representing an attachment in a Document.
 *
 * @remarks
 * Attachment string is formatted as `attachment://<filename>`.
 */
type 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 _document: 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>, initialState?: Partial<ExtendedState<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 | 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>): Promise<Document<T, A>>;
    /**
     *    Gets the current state of the document.
     */
    get state(): T;
    /**
     *    Gets the list of operations performed on the document.
     */
    get operations(): Operation<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(): ExtendedState<T>;
    /**
     * 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<ExtendedState<T>, 'state' | '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 definitions for JSZip 3.1
// Project: http://stuk.github.com/jszip/, https://github.com/stuk/jszip
// Definitions by: mzeiher <https://github.com/mzeiher>, forabi <https://github.com/forabi>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.3


interface JSZipSupport {
    arraybuffer: boolean;
    uint8array: boolean;
    blob: boolean;
    nodebuffer: boolean;
}

type Compression = 'STORE' | 'DEFLATE';

/**
 * Depends on the compression type. With `STORE` (no compression), these options are ignored. With
 * `DEFLATE`, you can give the compression level between 1 (best speed) and 9 (best compression).
 */
interface CompressionOptions {
    level: number;
}

interface InputByType {
    base64: string;
    string: string;
    text: string;
    binarystring: string;
    array: number[];
    uint8array: Uint8Array;
    arraybuffer: ArrayBuffer;
    blob: Blob;
    stream: NodeJS.ReadableStream;
}

interface OutputByType {
    base64: string;
    string: string;
    text: string;
    binarystring: string;
    array: number[];
    uint8array: Uint8Array;
    arraybuffer: ArrayBuffer;
    blob: Blob;
    nodebuffer: Buffer;
}

// This private `_data` property on a JSZipObject uses this interface.
// If/when it is made public this should be uncommented.
// interface CompressedObject {
//     compressedSize: number;
//     uncompressedSize: number;
//     crc32: number;
//     compression: object;
//     compressedContent: string|ArrayBuffer|Uint8Array|Buffer;
// }

type InputFileFormat = InputByType[keyof InputByType] | Promise<InputByType[keyof InputByType]>;

declare namespace JSZip {
    type InputType = keyof InputByType;

    type OutputType = keyof OutputByType;

    interface JSZipMetadata {
        percent: number;
        currentFile: string | null;
    }

    type OnUpdateCallback = (metadata: JSZipMetadata) => void;

    interface JSZipObject {
        name: string;
        /**
         * Present for files loadded with `loadAsync`. May contain ".." path components that could
         * result in a zip-slip attack. See https://snyk.io/research/zip-slip-vulnerability
         */
        unsafeOriginalName?: string;
        dir: boolean;
        date: Date;
        comment: string;
        /** The UNIX permissions of the file, if any. */
        unixPermissions: number | string | null;
        /** The UNIX permissions of the file, if any. */
        dosPermissions: number | null;
        options: JSZipObjectOptions;

        /**
         * Prepare the content in the asked type.
         * @param type the type of the result.
         * @param onUpdate a function to call on each internal update.
         * @return Promise the promise of the result.
         */
        async<T extends OutputType>(type: T, onUpdate?: OnUpdateCallback): Promise<OutputByType[T]>;
        nodeStream(type?: 'nodebuffer', onUpdate?: OnUpdateCallback): NodeJS.ReadableStream;
    }

    interface JSZipFileOptions {
        /** Set to `true` if the data is `base64` encoded. For example image data from a `<canvas>` element. Plain text and HTML do not need this option. */
        base64?: boolean;
        /**
         * Set to `true` if the data should be treated as raw content, `false` if this is a text. If `base64` is used,
         * this defaults to `true`, if the data is not a `string`, this will be set to `true`.
         */
        binary?: boolean;
        /**
         * The last modification date, defaults to the current date.
         */
        date?: Date;
        /**
         * Sets per file compression. The `compressionOptions` parameter depends on the compression type.
         */
        compression?: Compression;
        /**
         * Sets per file compression level for `DEFLATE` compression.
         */
        compressionOptions?: null | CompressionOptions;
        comment?: string;
        /** Set to `true` if (and only if) the input is a "binary string" and has already been prepared with a `0xFF` mask. */
        optimizedBinaryString?: boolean;
        /** Set to `true` if folders in the file path should be automatically created, otherwise there will only be virtual folders that represent the path to the file. */
        createFolders?: boolean;
        /** Set to `true` if this is a directory and content should be ignored. */
        dir?: boolean;

        /** 6 bits number. The DOS permissions of the file, if any. */
        dosPermissions?: number | null;
        /**
         * 16 bits number. The UNIX permissions of the file, if any.
         * Also accepts a `string` representing the octal value: `"644"`, `"755"`, etc.
         */
        unixPermissions?: number | string | null;
    }

    interface JSZipObjectOptions {
        compression: Compression;
    }

    interface JSZipGeneratorOptions<T extends OutputType = OutputType> {
        /**
         * Sets compression option for all entries that have not specified their own `compression` option
         */
        compression?: Compression;
        /**
         * Sets compression level for `DEFLATE` compression.
         */
        compressionOptions?: null | CompressionOptions;
        type?: T;
        comment?: string;
        /**
         * mime-type for the generated file.
         * Useful when you need to generate a file with a different extension, ie: “.ods”.
         * @default 'application/zip'
         */
        mimeType?: string;
        encodeFileName?(filename: string): string;
        /** Stream the files and create file descriptors */
        streamFiles?: boolean;
        /** DOS (default) or UNIX */
        platform?: 'DOS' | 'UNIX';
    }

    interface JSZipLoadOptions {
        base64?: boolean;
        checkCRC32?: boolean;
        optimizedBinaryString?: boolean;
        createFolders?: boolean;
        decodeFileName?: (bytes: string[] | Uint8Array | Buffer) => string;
    }

    type DataEventCallback<T> = (dataChunk: T, metadata: JSZipMetadata) => void
    type EndEventCallback = () => void
    type ErrorEventCallback = (error: Error) => void

    interface JSZipStreamHelper<T> {
        /**
         * Register a listener on an event
         */
        on(event: 'data', callback: DataEventCallback<T>): this;
        on(event: 'end', callback: EndEventCallback): this;
        on(event: 'error', callback: ErrorEventCallback): this;

        /**
         * Read the whole stream and call a callback with the complete content
         *
         * @param updateCallback The function called every time the stream updates
         * @return A Promise of the full content
         */
        accumulate(updateCallback?: (metadata: JSZipMetadata) => void): Promise<T>;

        /**
         * Resume the stream if the stream is paused. Once resumed, the stream starts sending data events again
         *
         * @return The current StreamHelper object, for chaining
         */
        resume(): this;

        /**
         * Pause the stream if the stream is running. Once paused, the stream stops sending data events
         *
         * @return The current StreamHelper object, for chaining
         */
        pause(): this;
    }
}

interface JSZip {
    files: {[key: string]: JSZip.JSZipObject};

    /**
     * Get a file from the archive
     *
     * @param Path relative path to file
     * @return File matching path, null if no file found
     */
    file(path: string): JSZip.JSZipObject | null;

    /**
     * Get files matching a RegExp from archive
     *
     * @param path RegExp to match
     * @return Return all matching files or an empty array
     */
    file(path: RegExp): JSZip.JSZipObject[];

    /**
     * Add a file to the archive
     *
     * @param path Relative path to file
     * @param data Content of the file
     * @param options Optional information about the file
     * @return JSZip object
     */
    file<T extends JSZip.InputType>(path: string, data: InputByType[T] | Promise<InputByType[T]>, options?: JSZip.JSZipFileOptions): this;
    file<T extends JSZip.InputType>(path: string, data: null, options?: JSZip.JSZipFileOptions & { dir: true }): this;

    /**
     * Returns an new JSZip instance with the given folder as root
     *
     * @param name Name of the folder
     * @return New JSZip object with the given folder as root or null
     */
    folder(name: string): JSZip | null;

    /**
     * Returns new JSZip instances with the matching folders as root
     *
     * @param name RegExp to match
     * @return New array of JSZipFile objects which match the RegExp
     */
    folder(name: RegExp): JSZip.JSZipObject[];

    /**
     * Call a callback function for each entry at this folder level.
     *
     * @param callback function
     */
    forEach(callback: (relativePath: string, file: JSZip.JSZipObject) => void): void;

    /**
     * Get all files which match the given filter function
     *
     * @param predicate Filter function
     * @return Array of matched elements
     */
    filter(predicate: (relativePath: string, file: JSZip.JSZipObject) => boolean): JSZip.JSZipObject[];

    /**
     * Removes the file or folder from the archive
     *
     * @param path Relative path of file or folder
     * @return Returns the JSZip instance
     */
    remove(path: string): JSZip;

    /**
     * Generates a new archive asynchronously
     *
     * @param options Optional options for the generator
     * @param onUpdate The optional function called on each internal update with the metadata.
     * @return The serialized archive
     */
    generateAsync<T extends JSZip.OutputType>(options?: JSZip.JSZipGeneratorOptions<T>, onUpdate?: JSZip.OnUpdateCallback): Promise<OutputByType[T]>;

    /**
     * Generates a new archive asynchronously
     *
     * @param options Optional options for the generator
     * @param onUpdate The optional function called on each internal update with the metadata.
     * @return A Node.js `ReadableStream`
     */
    generateNodeStream(options?: JSZip.JSZipGeneratorOptions<'nodebuffer'>, onUpdate?: JSZip.OnUpdateCallback): NodeJS.ReadableStream;

    /**
     * Generates the complete zip file with the internal stream implementation
     *
     * @param options Optional options for the generator
     * @return a StreamHelper
     */
    generateInternalStream<T extends JSZip.OutputType>(options?: JSZip.JSZipGeneratorOptions<T>): JSZip.JSZipStreamHelper<OutputByType[T]>;

    /**
     * Deserialize zip file asynchronously
     *
     * @param data Serialized zip file
     * @param options Options for deserializing
     * @return Returns promise
     */
    loadAsync(data: InputFileFormat, options?: JSZip.JSZipLoadOptions): Promise<JSZip>;

    /**
     * Create JSZip instance
     */
    new(): this;

    (): JSZip;

    prototype: JSZip;
    support: JSZipSupport;
    external: {
        Promise: PromiseConstructorLike;
    };
    version: string;
}

declare var JSZip: JSZip;

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>;
declare const saveToFileHandle: (document: Document, input: FileSystemFileHandle) => Promise<void>;
/**
 * 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, unknown>>(path: string, reducer: Reducer<S, A>) => Promise<Document<S, A>>;
declare const loadFromInput: <S, A extends Action<string, unknown>>(input: FileInput, reducer: Reducer<S, A>) => Promise<Document<S, 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, Document as D, ExtendedState as E, FileInput as F, InputDocumentFile as I, LoadStateAction as L, Operation as O, PruneAction as P, Reducer as R, SetNameAction as S, UndoAction as U, RedoAction as a, DocumentFile as b, BaseAction as c, ImmutableStateReducer as d, createZip as e, getRemoteFile as f, getLocalFile as g, hashAttachment as h, loadFromInput as i, saveToFileHandle as j, Attachment as k, loadFromFile as l, DocumentHeader as m, FileRegistry as n, ImmutableReducer as o, applyMixins as p, saveToFile as s };
