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;
};
/**
 * 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 | null;
    fileName?: string | null;
};
/**
 * 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 = 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 | 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 | 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 | BaseAction>): Promise<Document<T, 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<A | BaseAction>[];
    /**
     * 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;

export { Action as A, BaseDocument as B, Document as D, FileRegistry as F, ImmutableReducer as I, LoadStateAction as L, Operation as O, PruneAction as P, RedoAction as R, SetNameAction as S, UndoAction as U, BaseAction as a, DocumentFile as b, Attachment as c, DocumentHeader as d, Reducer as e, applyMixins as f };
