Skip to content

[feat/MAT-358] undo/redo command 패턴 HistoryManager#300

Open
b0nsu wants to merge 1 commit intorefactor/mat-355-renderingfrom
refactor/mat-358-undo-redo
Open

[feat/MAT-358] undo/redo command 패턴 HistoryManager#300
b0nsu wants to merge 1 commit intorefactor/mat-355-renderingfrom
refactor/mat-358-undo-redo

Conversation

@b0nsu
Copy link
Copy Markdown
Collaborator

@b0nsu b0nsu commented Apr 30, 2026

Summary

배열 기반 히스토리를 command pattern HistoryManager로 교체합니다.
DocumentSnapshot + StrokeBounds로 undo 시 O(1) 복원, 이후 eraser 최적화 기반을 마련합니다.

Stacked PR 3/10 — base: refactor/mat-355-rendering

Linear

Changes

  • engine/HistoryManager.ts 생성 — command pattern (AppendStroke, EraseStrokes, ReplaceDocument)
  • DrawingCanvas에서 기존 배열 히스토리 제거 → HistoryManager 사용
  • DocumentSnapshot, DrawingCanvasProps 타입을 drawingTypes.ts에 추가

Testing

  • pnpm typecheck 통과
  • pnpm lint 통과

Risk / Impact

  • 영향 범위: undo/redo 동작 로직 전면 교체
  • 확인이 필요한 부분: undo/redo 동작 동일성, 히스토리 상한(50)
  • 배포 시 유의사항: 없음

@linear
Copy link
Copy Markdown

linear Bot commented Apr 30, 2026

MAT-358 undo/redo

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pointer-admin Ready Ready Preview, Comment May 8, 2026 3:04pm

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the existing array-based undo/redo history in pointer-native-drawing with a command-pattern HistoryManager, using lightweight document snapshots to enable fast state restoration and prepare for future eraser optimizations (bounds/cached paths).

Changes:

  • Added HistoryManager with command entries for append-stroke / erase-strokes / replace-document.
  • Updated DrawingCanvas to push/undo/redo via HistoryManager instead of deep-copied history arrays.
  • Introduced new drawing model types (DrawingCanvasProps, DocumentSnapshot, etc.) to support snapshot/history workflows.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
packages/pointer-native-drawing/src/model/drawingTypes.ts Adds new public-facing(?) types for canvas props and snapshot/history modeling.
packages/pointer-native-drawing/src/engine/HistoryManager.ts Implements the command-pattern history stack with undo/redo, eviction hooks, and erase transactions.
packages/pointer-native-drawing/src/DrawingCanvas.tsx Rewires stroke/text editing + undo/redo to use HistoryManager and snapshot application.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 26 to 33
import {
type DrawingCanvasProps,
type DrawingCanvasRef,
type DocumentSnapshot,
type Point,
type Stroke,
type TextItem,
type DrawingCanvasRef,
} from './model/drawingTypes';
type DrawingCanvasRef,
} from './model/drawingTypes';
import { deepCopyStrokes, deepCopyTexts, safeMax } from './model/strokeUtils';
import { deepCopyTexts, safeMax, computeStrokeBounds } from './model/strokeUtils';
Comment on lines +115 to +119
/** 현재 stroke 상태의 경량 스냅샷 (reference 저장, deep copy 아님) */
const createSnapshot = useCallback((): DocumentSnapshot => ({
strokes: strokesRef.current,
bounds: strokesRef.current.map((s) => computeStrokeBounds(s.points)),
}), []);
Comment on lines +54 to +70
export type DrawingCanvasProps = {
strokeColor?: string;
strokeWidth?: number;
onChange?: (strokes: Stroke[]) => void;
onHistoryChange?: (canUndo: boolean, canRedo: boolean) => void;
eraserMode?: boolean;
eraserSize?: number;
textMode?: boolean;
textFontPath?: number;
};

// ── Snapshot (lightweight — stores references, not deep copies) ─

export type DocumentSnapshot = {
readonly strokes: readonly Stroke[];
readonly bounds: readonly StrokeBounds[];
};
@b0nsu b0nsu force-pushed the refactor/mat-355-rendering branch from 9289a05 to 41f727a Compare May 8, 2026 14:59
…ncremental + lazy init

- engine/HistoryManager.ts: command 패턴 (AppendStroke / EraseStrokes)
  - append-stroke undo: O(1) — slice로 마지막 stroke 제거
  - erase-strokes: snapshot 복원 (begin/commit/discardTransaction)
- model/drawingTypes.ts: DocumentSnapshot, DrawingCanvasProps 추가
- DrawingCanvas.tsx:
  - HistoryManager 통합 (legacy historyRef/saveToHistory/restoreFromHistory 제거)
  - strokeBoundsRef incremental 관리 — createSnapshot 매 호출 N×P 재계산 회피 (Critical fix)
  - HistoryManager lazy init — useRef(null) + nullish-coalescing assign

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants