import type { BaseDatabase } from './database';
import type { EntityMetadata } from './metadata';
import type { DatabaseSession } from './session';
export type DatabaseEntityMutationOperation = 'create' | 'update' | 'delete';
export type DatabaseQueryMutationOperation = 'update' | 'delete';
export type DatabaseEntitySnapshot = Readonly<Record<string, unknown>>;
export interface DatabaseEntityMutation {
    readonly kind: 'entity';
    readonly operation: DatabaseEntityMutationOperation;
    readonly entity: object;
    readonly metadata: EntityMetadata;
    readonly before: DatabaseEntitySnapshot | null;
    readonly after: DatabaseEntitySnapshot | null;
    readonly changedFields: readonly string[];
}
/**
 * A mutation performed directly by QueryBuilder. It deliberately does not pretend to contain an
 * entity before/after image: consumers that require one can reject it or load the affected rows in
 * their own policy layer.
 */
export interface DatabaseQueryMutation {
    readonly kind: 'query';
    readonly operation: DatabaseQueryMutationOperation;
    readonly metadata: EntityMetadata;
    readonly primaryKeys: readonly Readonly<Record<string, unknown>>[];
    /** Persisted values requested by interceptors immediately before the query mutation. */
    readonly before: readonly DatabaseEntitySnapshot[];
    /** Persisted property names changed by the patch, including fields nested under `$inc`. */
    readonly changedFields: readonly string[];
    readonly patch?: Readonly<Record<string, unknown>>;
}
export type DatabaseMutation = DatabaseEntityMutation | DatabaseQueryMutation;
export interface DatabaseMutationCommitContext {
    readonly database: BaseDatabase;
    readonly session: DatabaseSession;
    readonly mutations: readonly DatabaseMutation[];
}
export interface DatabaseMutationInterceptor {
    /** Limits capture and delivery to entity classes relevant to this interceptor. */
    observes?(metadata: EntityMetadata): boolean;
    /** Requests persisted property values needed to validate a QueryBuilder mutation. */
    querySnapshotFields?(metadata: EntityMetadata): readonly string[];
    beforeCommit(context: DatabaseMutationCommitContext): void | Promise<void>;
}
interface PendingEntityMutation {
    readonly sequence: number;
    readonly entity: object;
    readonly metadata: EntityMetadata;
    readonly primaryKeys: readonly unknown[];
    readonly before: DatabaseEntitySnapshot | null;
    readonly after: DatabaseEntitySnapshot | null;
}
interface PendingQueryMutation {
    readonly sequence: number;
    readonly mutation: DatabaseQueryMutation;
}
export interface DatabaseMutationCheckpoint {
    readonly entityMutations: ReadonlyMap<object, PendingEntityMutation>;
    readonly queryMutations: readonly PendingQueryMutation[];
    readonly nextSequence: number;
}
export declare class DatabaseMutationAccumulator {
    private entityMutations;
    private queryMutations;
    private nextSequence;
    recordEntity(entity: object, metadata: EntityMetadata, before: DatabaseEntitySnapshot | null, after: DatabaseEntitySnapshot | null): void;
    recordQuery(mutation: DatabaseQueryMutation): void;
    checkpoint(): DatabaseMutationCheckpoint;
    restore(checkpoint: DatabaseMutationCheckpoint): void;
    getMutations(): DatabaseMutation[];
}
export {};
//# sourceMappingURL=mutation.d.ts.map