From 5a7c38b26de99c93eba8ffc065da3c379345633c Mon Sep 17 00:00:00 2001 From: kim Date: Fri, 19 Jun 2026 00:04:06 +0900 Subject: [PATCH] =?UTF-8?q?v3.0.4:=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=ED=8C=A8=EB=84=90=20=EC=BB=B4=ED=8C=8C=EC=9D=BC=20=EC=BA=90?= =?UTF-8?q?=EC=8B=9C=20=E2=80=94=20=EC=BB=B4=ED=8C=8C=EC=9D=BC=20=ED=9B=84?= =?UTF-8?q?=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EC=8B=9C=20=EC=9E=AC=EC=BB=B4?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EB=9E=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 컴파일 결과를 (code, fqbn) 키로 캐시 - 사이드바 🔨 컴파일 성공 시에도 캐시 저장 - 캐시 히트 시 업로드/다운로드에서 컴파일 단계 건너뜀 Co-Authored-By: Claude Sonnet 4.6 --- web-ui/code.js | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/web-ui/code.js b/web-ui/code.js index 4eba25f..680482a 100644 --- a/web-ui/code.js +++ b/web-ui/code.js @@ -1567,6 +1567,12 @@ async function csbCompileOnly() { const kb = data.size ? (data.size / 1024).toFixed(1) : null; const extra = data.autoInstalled?.length ? `\n자동 설치된 라이브러리: ${data.autoInstalled.join(', ')}` : ''; 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) { codeAiAppend('system', `컴파일 오류: ${e.message}`); @@ -5825,6 +5831,8 @@ let _cupPort = null; let _cupBusy = false; let _cupCode = '', _cupFqbn = '', _cupBoardName = '', _cupFname = ''; let _cupCompiledData = null; +let _cupCompiledForCode = ''; +let _cupCompiledForFqbn = ''; let _cupBoardOptions = []; let _cupSelOptions = {}; let _cupMonActive = false; @@ -5999,12 +6007,20 @@ async function _cupCompile() { if (data.error) { cupLog('컴파일 오류:\n' + data.error, 'err'); _cupSetStatus('error', '컴파일 실패'); return null; } const kb = data.size ? ` (${(data.size/1024).toFixed(1)} KB)` : ''; cupLog(`✅ 컴파일 완료${kb}`, 'ok'); + _cupCompiledForCode = _cupCode; + _cupCompiledForFqbn = _cupGetEffectiveFqbn(); return data; } +function _cupCacheHit() { + return _cupCompiledData && _cupCompiledForCode === _cupCode && _cupCompiledForFqbn === _cupGetEffectiveFqbn(); +} + async function cupDoDownload() { 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; const isHex = !!data.hex; const content = isHex ? data.hex : _cupBase64ToBytes(data.bin || data.merged); @@ -6030,8 +6046,9 @@ async function cupDoUpload() { document.getElementById('cup-tab-log').innerHTML = ''; _cupSetProgress(0); try { - const data = await _cupCompile(); if (!data) return; - _cupCompiledData = data; + let data; + if (_cupCacheHit()) { data = _cupCompiledData; cupLog('캐시된 컴파일 결과 사용', 'info'); } + else { data = await _cupCompile(); if (!data) return; _cupCompiledData = data; } cupLog(`\n--- 업로드 시작 [${_cupBoardName}] ---`, 'prog'); _cupSetStatus('uploading', '업로드 중...'); _cupSetProgress(5); if (method === 'avr-stk500') await _cupUploadAVR(data.hex); else if (method === 'stm32-uart') await _cupUploadSTM32(_cupBase64ToBytes(data.bin)); @@ -6047,8 +6064,9 @@ async function _cupUploadESP32() { _cupSetProgress(0); let transport = null, success = false; try { - const data = await _cupCompile(); if (!data) return; - _cupCompiledData = data; + let data; + if (_cupCacheHit()) { data = _cupCompiledData; cupLog('캐시된 컴파일 결과 사용', 'info'); } + else { data = await _cupCompile(); if (!data) return; _cupCompiledData = data; } const b64 = data.merged || data.bin; if (!b64) throw new Error('컴파일 결과에 바이너리가 없습니다'); cupLog('esptool-js 로딩 중...', 'prog');