async function refreshInternals() { let d; try { const r = await fetch('/api/internals'); d = await r.json(); } catch(e) { return; } setRows('tb-int-health', (d.st_health||[]).map(r => { const dot = r.is_populated ? '' : ''; const ts = r.last_refresh ? new Date(r.last_refresh).toLocaleTimeString() : '—'; const dur = r.duration_ms != null ? r.duration_ms + ' ms' : '—'; const rows = r.rows_affected != null ? fmt(r.rows_affected) : '—'; return ` ${esc(r.name)} ${esc(r.refresh_mode)} ${esc(r.schedule||'calc')} ${dot} ${ts} ${dur} ${rows} ${esc(r.status)} `; }).join('')); document.getElementById('pre-dep-tree').textContent = (d.dep_tree||[]).join('\n') || '(no dependency data)'; setRows('tb-int-history', (d.refresh_history||[]).map(r => { const fallback = r.was_full_fallback ? ' ' : ''; const statusCol = r.status === 'FAILED' ? 'color:var(--red)' : 'color:var(--muted)'; const ts = r.start_time ? new Date(r.start_time).toLocaleTimeString() : '—'; return ` ${esc(r.name)} ${esc(r.refresh_mode)}${fallback} ${ts} ${r.duration_ms != null ? r.duration_ms : '—'} ${r.rows_affected != null ? fmt(r.rows_affected) : '—'} ${esc(r.status)} `; }).join('')); setRows('tb-int-eff', (d.efficiency||[]).map(r => ` ${esc(r.name)} ${fmt(r.total_refreshes)} ${fmt(r.diff_count)} ${fmt(r.full_count)} ${r.avg_diff_ms != null ? Number(r.avg_diff_ms).toFixed(1) : '—'} ${r.avg_full_ms != null ? Number(r.avg_full_ms).toFixed(1) : '—'} ${esc(r.diff_speedup||'—')} ${r.avg_change_ratio != null ? Number(r.avg_change_ratio).toFixed(3) : '—'} `).join('')); setRows('tb-int-advisor', (d.opt_hints||[]).map(r => { const keep = r.recommended_mode === 'KEEP'; const recHtml = keep ? `✓ KEEP ${esc(r.current_mode)}` : `→ SWITCH TO ${esc(r.recommended_mode)}`; const confClass = r.confidence === 'high' ? 'conf-high' : r.confidence === 'medium' ? 'conf-medium' : 'conf-low'; return ` ${esc(r.name)} ${esc(r.current_mode)} ${esc(r.effective_mode||'—')} ${recHtml} ${esc(r.confidence||'—')} ${esc(r.reason||'')} `; }).join('')); } document.getElementById('tab-internals-btn') .addEventListener('shown.bs.tab', refreshInternals); document.getElementById('tab-internals-btn') .addEventListener('shown.bs.tab', refreshInternals); setInterval(refreshInternals, 5000);