import type { AnyEntity, EntityData, EntityMetadata, EntityName, EntityProperty, FilterQuery, Primary } from '../typings.js';
import { Collection } from '../entity/Collection.js';
import { Reference } from '../entity/Reference.js';
import { ChangeSet, ChangeSetType } from './ChangeSet.js';
import { ChangeSetPersister } from './ChangeSetPersister.js';
import type { EntityManager } from '../EntityManager.js';
import { IdentityMap } from './IdentityMap.js';
import type { LockOptions } from '../drivers/IDatabaseDriver.js';
/** Implements the Unit of Work pattern: tracks entity changes, computes change sets, and flushes them to the database. */
export declare class UnitOfWork {
    #private;
    constructor(em: EntityManager);
    /** Merges an entity into the identity map, taking a snapshot of its current state. */
    merge<T extends object>(entity: T, visited?: Set<AnyEntity>): void;
    /**
     * Entity data can wary in its shape, e.g. we might get a deep relation graph with joined strategy, but for diffing,
     * we need to normalize the shape, so relation values are only raw FKs. This method handles that.
     * @internal
     */
    normalizeEntityData<T extends object>(meta: EntityMetadata<T>, data: EntityData<T>): void;
    /**
     * @internal
     */
    register<T extends object>(entity: T, data?: EntityData<T>, options?: RegisterOptions): T;
    /**
     * @internal
     */
    dispatchOnLoadEvent(): Promise<void>;
    /**
     * @internal
     */
    unmarkAsLoaded(entity: AnyEntity): void;
    /**
     * Returns entity from the identity map. For composite keys, you need to pass an array of PKs in the same order as they are defined in `meta.primaryKeys`.
     */
    getById<T extends object>(entityName: EntityName<T>, id: Primary<T> | Primary<T>[], schema?: string, convertCustomTypes?: boolean): T | undefined;
    /**
     * Returns entity from the identity map by an alternate key (non-PK property).
     * @param convertCustomTypes - If true, the value is in database format and will be converted to JS format for lookup.
     *                             If false (default), the value is assumed to be in JS format already.
     */
    getByKey<T extends object>(entityName: EntityName<T>, key: string, value: unknown, schema?: string, convertCustomTypes?: boolean): T | undefined;
    /**
     * Stores an entity in the identity map under an alternate key (non-PK property).
     * Also sets the property value on the entity.
     * @param convertCustomTypes - If true, the value is in database format and will be converted to JS format.
     *                             If false (default), the value is assumed to be in JS format already.
     */
    storeByKey<T extends object>(entity: T, key: string, value: unknown, schema?: string, convertCustomTypes?: boolean): void;
    /** Attempts to extract a primary key from the where condition and look up the entity in the identity map. */
    tryGetById<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, schema?: string, strict?: boolean): T | null;
    /**
     * Returns map of all managed entities.
     */
    getIdentityMap(): IdentityMap;
    /**
     * Returns stored snapshot of entity state that is used for change set computation.
     */
    getOriginalEntityData<T extends object>(entity: T): EntityData<T> | undefined;
    /** Returns the set of entities scheduled for persistence. */
    getPersistStack(): Set<AnyEntity>;
    /** Returns the set of entities scheduled for removal. */
    getRemoveStack(): Set<AnyEntity>;
    /** Returns all computed change sets for the current flush. */
    getChangeSets(): ChangeSet<AnyEntity>[];
    /** Returns all M:N collections that need synchronization. */
    getCollectionUpdates(): Collection<AnyEntity>[];
    /** Returns extra updates needed for relations that could not be resolved in the initial pass. */
    getExtraUpdates(): Set<[
        AnyEntity,
        string | string[],
        AnyEntity | AnyEntity[] | Reference<any> | Collection<any>,
        ChangeSet<any> | undefined,
        ChangeSetType
    ]>;
    /** Checks whether an auto-flush is needed before querying the given entity type. */
    shouldAutoFlush<T extends object>(meta: EntityMetadata<T>): boolean;
    /** Clears the queue of entity types that triggered auto-flush detection. */
    clearActionsQueue(): void;
    /** Computes and registers a change set for the given entity. */
    computeChangeSet<T extends object>(entity: T, type?: ChangeSetType): void;
    /** Recomputes and merges the change set for an already-tracked entity. */
    recomputeSingleChangeSet<T extends object>(entity: T): void;
    /** Marks an entity for persistence, cascading to related entities. */
    persist<T extends object>(entity: T, visited?: Set<AnyEntity>, options?: {
        checkRemoveStack?: boolean;
        cascade?: boolean;
    }): void;
    /** Marks an entity for removal, cascading to related entities. */
    remove<T extends object>(entity: T, visited?: Set<AnyEntity>, options?: {
        cascade?: boolean;
    }): void;
    /** Flushes all pending changes to the database within a transaction. */
    commit(): Promise<void>;
    private doCommit;
    lock<T extends object>(entity: T, options: LockOptions): Promise<void>;
    clear(): void;
    unsetIdentity(entity: AnyEntity): void;
    computeChangeSets(): void;
    scheduleExtraUpdate<T extends object>(changeSet: ChangeSet<T>, props: EntityProperty<T>[]): void;
    scheduleOrphanRemoval(entity?: AnyEntity, visited?: Set<AnyEntity>): void;
    cancelOrphanRemoval(entity: AnyEntity, visited?: Set<AnyEntity>): void;
    getOrphanRemoveStack(): Set<AnyEntity>;
    getChangeSetPersister(): ChangeSetPersister;
    private findNewEntities;
    /**
     * For TPT inheritance, creates separate changesets for each table in the hierarchy.
     * Uses the same entity instance for all changesets - only the metadata and payload differ.
     */
    private createTPTChangeSets;
    /**
     * Returns `true` when the change set should be skipped as it will be empty after the extra update.
     */
    private checkUniqueProps;
    private expandUniqueProps;
    private initIdentifier;
    private processReference;
    private processToOneReference;
    private processToManyReference;
    private runHooks;
    private postCommitCleanup;
    private cascade;
    private cascadeReference;
    private isCollectionSelfReferenced;
    private shouldCascade;
    private lockPessimistic;
    private lockOptimistic;
    private fixMissingReference;
    private persistToDatabase;
    private commitCreateChangeSets;
    private findExtraUpdates;
    private findEarlyUpdates;
    private commitUpdateChangeSets;
    private commitDeleteChangeSets;
    private commitExtraUpdates;
    private commitCollectionUpdates;
    private filterCollectionUpdates;
    /**
     * Orders change sets so FK constrains are maintained, ensures stable order (needed for node < 11)
     */
    private getChangeSetGroups;
    private getCommitOrder;
    private resetTransaction;
    /**
     * Takes snapshots of all processed collections
     */
    private takeCollectionSnapshots;
}
export interface RegisterOptions {
    refresh?: boolean;
    newEntity?: boolean;
    loaded?: boolean;
}
