import { DiagramLayout, LogicalModel } from '../core/types'; import { OpEmission } from './op'; /** 편집 대상 상태 — 분리된 논리 모델 + 다이어그램 레이아웃 */ export interface EditorState { logical: LogicalModel; layout: DiagramLayout; } /** * 명령(Command) — 레거시 EMAction 대응. * apply로 상태를 변경하고 invert로 정확히 되돌린다(do/undo 대칭). */ export interface Command { readonly label: string; /** * 연속 동종 변경(키보드 미세 이동 등)을 하나의 undo 단위로 병합하기 위한 키. * 직전 명령의 키와 같으면 스택에서 합쳐진다(시작 상태 복원을 승계). undefined면 병합하지 않음. */ readonly coalesceKey?: string; apply(state: EditorState): void; invert(state: EditorState): void; /** * 자신을 forward/invert op로 파생한다(트랙 B (가)). **apply() 이후 호출 계약**(계약 1) — * invert op이 apply가 캡처한 memento에 의존하므로(move=이전 좌표, removeEntity=cascade 대상). * * 옵셔널 — 점진 마이그레이션 중 미구현 command는 op를 산출하지 않는다. 호스트 영속 경로(stack * emit 훅, B-2)는 이 메서드 부재를 런타임 가드로 감지해야 op 누락이 조용히 새지 않는다. */ emitOps?(state: EditorState): OpEmission; }