/** * One undo stack for two kinds of change. * * Geometry history belongs to the canvas package, which is the only thing that * knows a hundred pointer samples are one drag. Metadata history — text, tags, * motivation, layer, notes — belongs to Mango, which is the only thing that * knows what a tag is. Neither can own the whole stack, and a user pressing * undo does not care which of the two they are undoing: they want the last * thing they did reversed, in order. * * So Mango keeps the ordering and delegates the geometry steps. Each entry * either carries a metadata change to invert, or is a marker saying "the next * step down is the canvas package's". */ import type { ResolvedAnnotation } from '../../iiif/annotationResolver'; /** Something that can undo and redo its own geometry steps. */ export type GeometryHistory = { undo(): boolean; redo(): boolean; readonly canUndo: boolean; readonly canRedo: boolean; }; export type MetadataChange = { kind: 'metadata'; annotationId: string; /** The annotation as it was. Null when the entry created it. */ before: ResolvedAnnotation | null; /** The annotation as it became. Null when the entry deleted it. */ after: ResolvedAnnotation | null; /** Names the step for an announcement, e.g. "tags" or "text". */ label: string; /** Internal coalescing boundary for continuous text input. */ recordedAt?: number; }; /** * A geometry step recorded by the canvas package. * * Carries no payload: reversing it means asking the editor to undo, and holding * a copy of the geometry here would be a second source of truth that drifts the * first time the editor coalesces differently than expected. */ export type GeometryMarker = { kind: 'geometry'; annotationId: string; label: string; }; export type CommandEntry = MetadataChange | GeometryMarker; export type CommandStackOptions = { limit?: number; /** Applies a metadata state. Called for both undo and redo. */ apply: (annotationId: string, annotation: ResolvedAnnotation | null) => void; geometry?: () => GeometryHistory | null; onChange?: (state: CommandStackState) => void; }; export type CommandStackState = { canUndo: boolean; canRedo: boolean; /** What undo would reverse, for an announcement or a tooltip. */ undoLabel?: string; redoLabel?: string; }; export type CommandStack = { /** Records a metadata change. */ record(change: Omit): void; /** Records that the canvas package committed a geometry step. */ recordGeometry(annotationId: string, label: string): void; undo(): boolean; redo(): boolean; clear(): void; state(): CommandStackState; }; export declare const createCommandStack: (options: CommandStackOptions) => CommandStack; /** Names the field a patch touched, for the undo announcement. */ export declare const labelForPatch: (patch: Partial) => string;