Some checks are pending
build-and-push / image (push) Waiting to run
- Implemented demand pane for managing trend-driven design jobs. - Created diffusion pane for generating images via Stable Diffusion. - Added inbox pane for sweeping and routing artifacts through the CxAI inbox classifier. - Developed items pane for CRUD operations against /api/items. - Introduced lang pane for running language pipelines. - Established mac pane for macOS app distribution information. - Integrated slack pane for sending messages and displaying diagnostics. - Built system pane for process introspection and version information. - Launched tools pane for browsing and invoking MCP tools. - Set up websocket pane for connecting to the /ws/echo service.
67 lines
2.4 KiB
JavaScript
67 lines
2.4 KiB
JavaScript
// panes/websocket.js — /ws/echo console.
|
|
import { registerPane } from '../app.js';
|
|
|
|
const TPL = `
|
|
<div class="pane-head">
|
|
<div><div class="title">WebSocket</div><div class="sub">Connect to <code>/ws/echo</code>.</div></div>
|
|
<div class="grow"></div>
|
|
<span class="pill" id="ws-pill"><span class="dot"></span><span id="ws-state">idle</span></span>
|
|
</div>
|
|
<div class="card">
|
|
<div class="btn-row mb-3">
|
|
<button class="btn btn-primary" id="ws-connect">Connect</button>
|
|
<button class="btn btn-secondary" id="ws-disconnect">Disconnect</button>
|
|
</div>
|
|
<pre class="console h-64" id="ws-log"></pre>
|
|
<form id="ws-form" class="flex gap-2 mt-3">
|
|
<input class="input" id="ws-input" placeholder="message…" />
|
|
<button class="btn btn-primary" type="submit">Send</button>
|
|
</form>
|
|
</div>
|
|
`;
|
|
|
|
let ws = null;
|
|
|
|
function setState(host, state, klass) {
|
|
host.querySelector('#ws-state').textContent = state;
|
|
const p = host.querySelector('#ws-pill');
|
|
p.classList.remove('ok', 'err', 'warn', 'info');
|
|
if (klass) p.classList.add(klass);
|
|
}
|
|
|
|
function append(host, line) {
|
|
const pre = host.querySelector('#ws-log');
|
|
pre.textContent += line + '\n';
|
|
pre.scrollTop = pre.scrollHeight;
|
|
}
|
|
|
|
function connect(host) {
|
|
if (ws && ws.readyState <= 1) return;
|
|
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
const url = `${proto}//${location.host}/ws/echo`;
|
|
ws = new WebSocket(url);
|
|
setState(host, 'connecting…', 'warn');
|
|
ws.onopen = () => { setState(host, 'connected', 'ok'); append(host, `< connected ${url}`); };
|
|
ws.onclose = () => { setState(host, 'disconnected', 'err'); append(host, '< closed'); };
|
|
ws.onerror = () => append(host, '! error');
|
|
ws.onmessage = (e) => append(host, '< ' + e.data);
|
|
}
|
|
|
|
registerPane('websocket', {
|
|
label: 'WebSocket',
|
|
init(host) {
|
|
host.innerHTML = TPL;
|
|
host.querySelector('#ws-connect').addEventListener('click', () => connect(host));
|
|
host.querySelector('#ws-disconnect').addEventListener('click', () => ws && ws.close());
|
|
host.querySelector('#ws-form').addEventListener('submit', (e) => {
|
|
e.preventDefault();
|
|
const v = host.querySelector('#ws-input').value;
|
|
if (!v) return;
|
|
if (!ws || ws.readyState !== 1) { append(host, '! not connected'); return; }
|
|
ws.send(v);
|
|
append(host, '> ' + v);
|
|
host.querySelector('#ws-input').value = '';
|
|
});
|
|
},
|
|
});
|