()
| 41 | // ===== SSE ===== |
| 42 | let es; |
| 43 | function connectSSE(){ |
| 44 | if(es)try{es.close()}catch{} |
| 45 | es=new EventSource(authQ('/api/logs/stream')); |
| 46 | es.addEventListener('log',e=>{ |
| 47 | const en=JSON.parse(e.data);logs.push(en); |
| 48 | if(logs.length>5000)logs=logs.slice(-3000); |
| 49 | if(!selId||selId===en.requestId){if(curTab==='logs')appendLog(en)} |
| 50 | }); |
| 51 | es.addEventListener('summary',e=>{ |
| 52 | const s=JSON.parse(e.data);rmap[s.requestId]=s; |
| 53 | const i=reqs.findIndex(r=>r.requestId===s.requestId); |
| 54 | if(i>=0)reqs[i]=s;else reqs.unshift(s); |
| 55 | renderRL();updCnt(); |
| 56 | if(selId===s.requestId)renderSCard(s); |
| 57 | }); |
| 58 | es.addEventListener('stats',e=>{applyStats(JSON.parse(e.data))}); |
| 59 | es.onopen=()=>{const c=document.getElementById('conn');c.className='conn on';c.querySelector('span').textContent='已连接'}; |
| 60 | es.onerror=()=>{const c=document.getElementById('conn');c.className='conn off';c.querySelector('span').textContent='重连中...';setTimeout(connectSSE,3000)}; |
| 61 | } |
| 62 | |
| 63 | // ===== Stats ===== |
| 64 | function updStats(){fetch(authQ('/api/stats')).then(r=>r.json()).then(applyStats).catch(()=>{})} |
no test coverage detected