v3.0.4: 업로드 패널 컴파일 캐시 — 컴파일 후 업로드 시 재컴파일 생략

- 컴파일 결과를 (code, fqbn) 키로 캐시
- 사이드바 🔨 컴파일 성공 시에도 캐시 저장
- 캐시 히트 시 업로드/다운로드에서 컴파일 단계 건너뜀

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kim
2026-06-19 00:04:06 +09:00
co-authored by Claude Sonnet 4.6
parent 4caa35aac2
commit 5a7c38b26d
+23 -5
View File
@@ -1567,6 +1567,12 @@ async function csbCompileOnly() {
const kb = data.size ? (data.size / 1024).toFixed(1) : null; const kb = data.size ? (data.size / 1024).toFixed(1) : null;
const extra = data.autoInstalled?.length ? `\n자동 설치된 라이브러리: ${data.autoInstalled.join(', ')}` : ''; const extra = data.autoInstalled?.length ? `\n자동 설치된 라이브러리: ${data.autoInstalled.join(', ')}` : '';
codeAiAppend('system', `✅ 컴파일 성공${kb ? ` (${kb} KB)` : ''} — 오류 없음.${extra}`); codeAiAppend('system', `✅ 컴파일 성공${kb ? ` (${kb} KB)` : ''} — 오류 없음.${extra}`);
// 업로드 패널에서 재컴파일 없이 바로 업로드할 수 있도록 캐시
_cupCompiledData = data;
_cupCompiledForCode = code;
_cupCompiledForFqbn = _csbSelBoard.fqbn;
_cupCode = code; _cupFqbn = _csbSelBoard.fqbn;
_cupBoardName = _csbSelBoard.name; _cupFname = file.name;
} }
} catch (e) { } catch (e) {
codeAiAppend('system', `컴파일 오류: ${e.message}`); codeAiAppend('system', `컴파일 오류: ${e.message}`);
@@ -5825,6 +5831,8 @@ let _cupPort = null;
let _cupBusy = false; let _cupBusy = false;
let _cupCode = '', _cupFqbn = '', _cupBoardName = '', _cupFname = ''; let _cupCode = '', _cupFqbn = '', _cupBoardName = '', _cupFname = '';
let _cupCompiledData = null; let _cupCompiledData = null;
let _cupCompiledForCode = '';
let _cupCompiledForFqbn = '';
let _cupBoardOptions = []; let _cupBoardOptions = [];
let _cupSelOptions = {}; let _cupSelOptions = {};
let _cupMonActive = false; let _cupMonActive = false;
@@ -5999,12 +6007,20 @@ async function _cupCompile() {
if (data.error) { cupLog('컴파일 오류:\n' + data.error, 'err'); _cupSetStatus('error', '컴파일 실패'); return null; } if (data.error) { cupLog('컴파일 오류:\n' + data.error, 'err'); _cupSetStatus('error', '컴파일 실패'); return null; }
const kb = data.size ? ` (${(data.size/1024).toFixed(1)} KB)` : ''; const kb = data.size ? ` (${(data.size/1024).toFixed(1)} KB)` : '';
cupLog(`✅ 컴파일 완료${kb}`, 'ok'); cupLog(`✅ 컴파일 완료${kb}`, 'ok');
_cupCompiledForCode = _cupCode;
_cupCompiledForFqbn = _cupGetEffectiveFqbn();
return data; return data;
} }
function _cupCacheHit() {
return _cupCompiledData && _cupCompiledForCode === _cupCode && _cupCompiledForFqbn === _cupGetEffectiveFqbn();
}
async function cupDoDownload() { async function cupDoDownload() {
cupTab('log'); cupTab('log');
const data = await _cupCompile(); if (!data) return; let data;
if (_cupCacheHit()) { data = _cupCompiledData; cupLog('캐시된 컴파일 결과 사용', 'info'); }
else { data = await _cupCompile(); if (!data) return; }
_cupCompiledData = data; _cupCompiledData = data;
const isHex = !!data.hex; const isHex = !!data.hex;
const content = isHex ? data.hex : _cupBase64ToBytes(data.bin || data.merged); const content = isHex ? data.hex : _cupBase64ToBytes(data.bin || data.merged);
@@ -6030,8 +6046,9 @@ async function cupDoUpload() {
document.getElementById('cup-tab-log').innerHTML = ''; document.getElementById('cup-tab-log').innerHTML = '';
_cupSetProgress(0); _cupSetProgress(0);
try { try {
const data = await _cupCompile(); if (!data) return; let data;
_cupCompiledData = data; if (_cupCacheHit()) { data = _cupCompiledData; cupLog('캐시된 컴파일 결과 사용', 'info'); }
else { data = await _cupCompile(); if (!data) return; _cupCompiledData = data; }
cupLog(`\n--- 업로드 시작 [${_cupBoardName}] ---`, 'prog'); _cupSetStatus('uploading', '업로드 중...'); _cupSetProgress(5); cupLog(`\n--- 업로드 시작 [${_cupBoardName}] ---`, 'prog'); _cupSetStatus('uploading', '업로드 중...'); _cupSetProgress(5);
if (method === 'avr-stk500') await _cupUploadAVR(data.hex); if (method === 'avr-stk500') await _cupUploadAVR(data.hex);
else if (method === 'stm32-uart') await _cupUploadSTM32(_cupBase64ToBytes(data.bin)); else if (method === 'stm32-uart') await _cupUploadSTM32(_cupBase64ToBytes(data.bin));
@@ -6047,8 +6064,9 @@ async function _cupUploadESP32() {
_cupSetProgress(0); _cupSetProgress(0);
let transport = null, success = false; let transport = null, success = false;
try { try {
const data = await _cupCompile(); if (!data) return; let data;
_cupCompiledData = data; if (_cupCacheHit()) { data = _cupCompiledData; cupLog('캐시된 컴파일 결과 사용', 'info'); }
else { data = await _cupCompile(); if (!data) return; _cupCompiledData = data; }
const b64 = data.merged || data.bin; const b64 = data.merged || data.bin;
if (!b64) throw new Error('컴파일 결과에 바이너리가 없습니다'); if (!b64) throw new Error('컴파일 결과에 바이너리가 없습니다');
cupLog('esptool-js 로딩 중...', 'prog'); cupLog('esptool-js 로딩 중...', 'prog');