52 lines
2.0 KiB
JavaScript
52 lines
2.0 KiB
JavaScript
/* net.js — WebSocket sync client + dev-mode error pipeline. */
|
|
export class ExhibitNet {
|
|
constructor() {
|
|
this.handlers = new Map();
|
|
this.ws = null;
|
|
this.retry = 1000;
|
|
}
|
|
on(type, fn) { this.handlers.set(type, fn); return this; }
|
|
connect() {
|
|
const proto = location.protocol === 'https:' ? 'wss' : 'ws';
|
|
this.ws = new WebSocket(`${proto}://${location.host}/ws`);
|
|
this.ws.onopen = () => { this.retry = 1000; };
|
|
this.ws.onmessage = (ev) => {
|
|
let m; try { m = JSON.parse(ev.data); } catch { return; }
|
|
const h = this.handlers.get(m.type);
|
|
if (h) h(m);
|
|
};
|
|
this.ws.onclose = () => {
|
|
setTimeout(() => this.connect(), this.retry);
|
|
this.retry = Math.min(this.retry * 2, 15000);
|
|
};
|
|
}
|
|
}
|
|
|
|
/* Dev-mode error checking: capture JS errors + unhandled rejections, show an
|
|
* on-screen overlay, and report to the server for the admin error log. */
|
|
export function installErrorReporter(devMode) {
|
|
const report = (payload) => {
|
|
fetch('/api/client-error', {
|
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ ua: navigator.userAgent, page: location.pathname, ...payload }),
|
|
}).catch(() => {});
|
|
if (devMode) showOverlay(payload);
|
|
};
|
|
window.addEventListener('error', (e) =>
|
|
report({ kind: 'error', msg: String(e.message), src: e.filename, line: e.lineno }));
|
|
window.addEventListener('unhandledrejection', (e) =>
|
|
report({ kind: 'rejection', msg: String(e.reason && e.reason.message || e.reason) }));
|
|
return report;
|
|
}
|
|
|
|
let overlayEl = null;
|
|
function showOverlay(p) {
|
|
if (!overlayEl) {
|
|
overlayEl = document.createElement('div');
|
|
overlayEl.style.cssText = 'position:fixed;bottom:0;left:0;right:0;max-height:35vh;overflow:auto;' +
|
|
'background:rgba(120,0,0,.88);color:#fff;font:12px monospace;padding:8px;z-index:99999;white-space:pre-wrap';
|
|
document.body.appendChild(overlayEl);
|
|
}
|
|
overlayEl.textContent += `[${p.kind}] ${p.msg}${p.src ? ` (${p.src}:${p.line})` : ''}\n`;
|
|
}
|