// renderProcTable — 3-секционная таблица во время обработки // (готово / текущий / ожидают / пропущены сверх лимита). import { fmtSec } from './fmt_sec.js'; import { estForFile, DEFAULT_EST_MB_SEC } from './est_for_file.js'; import { procRow } from './proc_row.js'; export function renderProcTable(state, els, cfg) { const procState = state.proc.procState; const groups = { done: [], current: [], pending: [], over: [] }; for (let i = 0; i < state.files.length; i++) { if (state.overNames.has(state.files[i].name)) { groups.over.push(i); continue; } const st = procState[i] ? procState[i].st : 'pending'; if (st === 'done' || st === 'skipped') groups.done.push(i); else if (st === 'current') groups.current.push(i); else groups.pending.push(i); } // Оценка скорости из текущего файла (сек/символ) — для «ожидающих» let rate = null; for (const i of groups.current) { const p = procState[i]; const cur = (performance.now() - p.t0) / 1000; const total = cur + (p.eta != null ? p.eta : 0); if (p.chars > 0 && total > 0) rate = total / p.chars; } const rows = []; if (groups.done.length) { rows.push('✓ Обработанные (' + groups.done.length + ')'); for (const i of groups.done) { const p = procState[i]; const txt = p.st === 'skipped' ? 'не извлечён' : '✓ ' + (p.elapsed ? p.elapsed.toFixed(1) : '0.0') + 'с'; rows.push(procRow(state, i, txt)); } } if (groups.over.length) { rows.push('⛔ Пропущены (сверх лимита) (' + groups.over.length + ')'); for (const i of groups.over) { rows.push(procRow(state, i, 'пропущен (лимит)')); } } if (groups.current.length) { rows.push('▶ Текущий файл'); for (const i of groups.current) { const p = procState[i]; const cur = ((performance.now() - p.t0) / 1000).toFixed(1); const eta = (p.eta != null) ? ' / ~' + fmtSec(p.eta) : ''; rows.push(procRow(state, i, '⏳ ' + cur + 'с' + eta + '')); } } if (groups.pending.length) { rows.push('○ Ожидают обработки (' + groups.pending.length + ')'); for (const i of groups.pending) { const p = procState[i] || {}; // Оценка: LLM (chars x rate) если известна; иначе грубая по размеру/скорости извлечения if (rate && !p.est && p.chars > 0) p.est = p.chars * rate; if (!p.est) { const szMB = (state.files[i] ? state.files[i].size : 0) / 1048576; const k = (state.proc && state.proc.procExtractRate) || cfg.estMbSec || DEFAULT_EST_MB_SEC; // сек/МБ p.est = Math.max(1, Math.round(szMB * k)); } let txt; if (p.st === 'analyzed') txt = 'анализ ✓'; else if (p.st === 'current') txt = ''; else if (p.est != null) txt = '~' + fmtSec(p.est) + ''; else txt = ''; rows.push(procRow(state, i, txt)); } } els.tableBody.innerHTML = rows.join(''); const cntDone = groups.done.length; els.countEl.textContent = 'Готово ' + cntDone + ' / ' + state.files.length + ' файлов'; }