Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
13 commits
Select commit Hold shift + click to select a range
b4fb163
docs: 탭 삭제 Undo 경계 정책 주석 추가
eun-yeon Jul 15, 2026
9221524
feat: 글래스 블러 반경 상향과 비용 모델 주석 정정
eun-yeon Jul 15, 2026
f0a4a1a
feat: 스크림·사이드 패널 라이브 블러 복원과 글래스 투과 다이얼 완화
eun-yeon Jul 15, 2026
496cfda
feat: 캔버스 더블클릭 편집 진입과 홀드 전용 그랩 커서로 클릭 인터랙션 개편
eun-yeon Jul 15, 2026
567add2
feat: 드래그 입력을 Pointer Events 캡처 기반으로 전환하고 다중 드래그를 공통 훅으로 통합
eun-yeon Jul 15, 2026
bb7a0f8
feat: 사운드 편집 모달을 전면 시트로 개편하고 파형 색 토큰화와 스페이스 재생 추가
eun-yeon Jul 16, 2026
ffec3ca
feat: 컬러피커를 인하우스 프리미티브로 개편하고 색 스와치를 2층 구조로 통일
eun-yeon Jul 16, 2026
4f0e115
perf: 노트 캔버스를 트랙 영역으로 crop하고 depth 버퍼와 완료 노트 잔류 렌더 제거
eun-yeon Jul 17, 2026
d324e03
perf: 카운터 애니메이션과 그래프·통계 유휴 갱신의 불필요한 React 커밋 제거
eun-yeon Jul 17, 2026
0e0411f
perf: 노브 active 이미지를 선행 디코드해 첫 입력 히치 방지
eun-yeon Jul 17, 2026
ac1cf5f
perf: 플러그인 요소 리렌더를 변경된 요소로 격리하고 스마트 가이드 전역 구독 제거
eun-yeon Jul 17, 2026
b05ba70
merge: 선행 리뷰 수정 반영
lee-sihun Aug 4, 2026
94a7628
fix: 다중 드래그 그룹 bounds 기준 고정
lee-sihun Aug 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@
"lenis": "^1.3.15",
"ogl": "^1.0.11",
"react": "^19.2.4",
"react-color-palette": "^7.3.1",
"react-dom": "^19.2.4",
"three": "^0.180.0",
"zod": "^4.1.11",
Expand Down
34 changes: 34 additions & 0 deletions src/renderer/__tests__/keyStatsDedupe.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* keyStatsService 유휴 통지 dedupe 회귀 테스트
* 50ms 주기 틱이 값 미변경 시 리스너 fan-out을 만들지 않아야 함
*/
import { describe, it, expect, vi } from 'vitest';
import { keyStatsService } from '@utils/keyStatsService';

type ServicePrivate = {
updateStats: () => void;
timestamps: number[];
};

describe('keyStatsService 유휴 통지 dedupe', () => {
it('값이 변하지 않으면 주기 틱이 리스너를 호출하지 않는다', () => {
const listener = vi.fn();
const unsubscribe = keyStatsService.subscribe(listener);
const svc = keyStatsService as unknown as ServicePrivate;

// 구독 즉시 1회 + 첫 틱(lastNotified 초기화) 허용
svc.updateStats();
listener.mockClear();

// 유휴 200틱 (수정 전: 200회 통지)
for (let i = 0; i < 200; i += 1) svc.updateStats();
expect(listener).toHaveBeenCalledTimes(0);

// 키 입력 발생 → 통지 재개
svc.timestamps.push(Date.now());
svc.updateStats();
expect(listener).toHaveBeenCalledTimes(1);

unsubscribe();
});
});
Loading