wifi-densepose/vendor/midstream/wasm/www/index.js

312 lines
10 KiB
JavaScript

import * as wasm from 'lean-agentic-wasm';
// Global state
let wsClient = null;
let sseClient = null;
let httpClient = null;
let agenticClient = null;
let messageCount = 0;
let startTime = Date.now();
// Initialize WASM and agentic client
async function init() {
try {
agenticClient = new wasm.LeanAgenticClient('demo-session', null);
log('ws', 'WASM module loaded successfully', 'success');
updateStats();
} catch (err) {
log('ws', `Failed to initialize: ${err}`, 'error');
}
}
// Tab switching
window.switchTab = function(tab) {
const tabs = document.querySelectorAll('.tab');
const contents = document.querySelectorAll('.tab-content');
tabs.forEach(t => t.classList.remove('active'));
contents.forEach(c => c.classList.remove('active'));
document.querySelector(`.tab:nth-child(${getTabIndex(tab)})`).classList.add('active');
document.getElementById(`${tab}-tab`).classList.add('active');
};
function getTabIndex(tab) {
const tabs = ['websocket', 'sse', 'http', 'benchmark'];
return tabs.indexOf(tab) + 1;
}
// WebSocket functions
window.connectWebSocket = async function() {
const url = document.getElementById('ws-url').value;
try {
wsClient = new wasm.WebSocketClient(url);
wsClient.set_on_message((data) => {
const start = performance.now();
const result = agenticClient.process_message(data);
const latency = performance.now() - start;
log('ws', `Received: ${data} | Latency: ${latency.toFixed(2)}ms`, 'success');
messageCount++;
updateStats();
});
wsClient.set_on_error((error) => {
log('ws', `Error: ${error}`, 'error');
});
wsClient.set_on_close((code) => {
log('ws', `Connection closed: ${code}`, 'error');
document.getElementById('status').textContent = 'Disconnected';
});
// Wait for connection
await new Promise(resolve => setTimeout(resolve, 100));
if (wsClient.ready_state() === 1) {
log('ws', `Connected to ${url}`, 'success');
document.getElementById('status').textContent = 'Connected (WS)';
}
} catch (err) {
log('ws', `Connection failed: ${err}`, 'error');
}
};
window.disconnectWebSocket = function() {
if (wsClient) {
wsClient.close();
wsClient = null;
log('ws', 'Disconnected', 'success');
document.getElementById('status').textContent = 'Disconnected';
}
};
window.sendWebSocketMessage = function() {
const message = document.getElementById('ws-message').value;
if (wsClient && wsClient.ready_state() === 1) {
const start = performance.now();
wsClient.send(message);
const latency = performance.now() - start;
log('ws', `Sent: ${message} | Send latency: ${latency.toFixed(3)}ms`, 'success');
document.getElementById('ws-message').value = '';
} else {
log('ws', 'Not connected', 'error');
}
};
window.startWebSocketBurst = async function() {
if (!wsClient || wsClient.ready_state() !== 1) {
log('ws', 'Not connected', 'error');
return;
}
const count = 1000;
const start = performance.now();
for (let i = 0; i < count; i++) {
wsClient.send(`Message ${i}`);
}
const duration = performance.now() - start;
const throughput = (count / duration) * 1000;
log('ws', `Burst test: ${count} messages in ${duration.toFixed(2)}ms (${throughput.toFixed(0)} msg/s)`, 'success');
};
// SSE functions
window.connectSSE = function() {
const url = document.getElementById('sse-url').value;
try {
sseClient = new wasm.SSEClient(url);
sseClient.set_on_message((data) => {
const start = performance.now();
const result = agenticClient.process_message(data);
const latency = performance.now() - start;
log('sse', `Received: ${data} | Latency: ${latency.toFixed(2)}ms`, 'success');
messageCount++;
updateStats();
});
log('sse', `Connected to ${url}`, 'success');
document.getElementById('status').textContent = 'Connected (SSE)';
} catch (err) {
log('sse', `Connection failed: ${err}`, 'error');
}
};
window.disconnectSSE = function() {
if (sseClient) {
sseClient.close();
sseClient = null;
log('sse', 'Disconnected', 'success');
document.getElementById('status').textContent = 'Disconnected';
}
};
// HTTP Streaming
window.startHTTPStream = async function() {
const url = document.getElementById('http-url').value;
try {
httpClient = new wasm.StreamingHTTPClient(url);
log('http', `Starting stream from ${url}...`, 'success');
await httpClient.stream((data) => {
const start = performance.now();
const result = agenticClient.process_message(data);
const latency = performance.now() - start;
log('http', `Chunk: ${data.substring(0, 50)}... | Latency: ${latency.toFixed(2)}ms`, 'success');
messageCount++;
updateStats();
});
log('http', 'Stream completed', 'success');
} catch (err) {
log('http', `Stream error: ${err}`, 'error');
}
};
// Benchmark functions
window.runLatencyBenchmark = function() {
log('benchmark', 'Running latency benchmark...', 'success');
const iterations = 10000;
const latencies = [];
for (let i = 0; i < iterations; i++) {
const start = performance.now();
agenticClient.process_message(`Test message ${i}`);
const latency = performance.now() - start;
latencies.push(latency);
}
const avg = latencies.reduce((a, b) => a + b, 0) / iterations;
const sorted = latencies.sort((a, b) => a - b);
const p50 = sorted[Math.floor(iterations * 0.5)];
const p95 = sorted[Math.floor(iterations * 0.95)];
const p99 = sorted[Math.floor(iterations * 0.99)];
const min = sorted[0];
const max = sorted[iterations - 1];
log('benchmark', `Latency Statistics (${iterations} iterations):`, 'success');
log('benchmark', ` Min: ${min.toFixed(3)}ms`, 'success');
log('benchmark', ` P50: ${p50.toFixed(3)}ms`, 'success');
log('benchmark', ` P95: ${p95.toFixed(3)}ms`, 'success');
log('benchmark', ` P99: ${p99.toFixed(3)}ms`, 'success');
log('benchmark', ` Max: ${max.toFixed(3)}ms`, 'success');
log('benchmark', ` Avg: ${avg.toFixed(3)}ms`, 'success');
updateLatencyMeter(avg, p99);
};
window.runThroughputBenchmark = function() {
log('benchmark', 'Running throughput benchmark...', 'success');
const duration = 5000; // 5 seconds
const start = performance.now();
let count = 0;
while (performance.now() - start < duration) {
agenticClient.process_message(`Throughput test ${count}`);
count++;
}
const actualDuration = performance.now() - start;
const throughput = (count / actualDuration) * 1000;
log('benchmark', `Throughput: ${throughput.toFixed(0)} messages/second`, 'success');
log('benchmark', `Total processed: ${count} messages in ${actualDuration.toFixed(0)}ms`, 'success');
document.getElementById('throughput').textContent = `${throughput.toFixed(0)}/s`;
};
window.runConcurrentBenchmark = async function() {
log('benchmark', 'Running concurrent sessions benchmark...', 'success');
const sessions = 100;
const messagesPerSession = 10;
const clients = [];
for (let i = 0; i < sessions; i++) {
clients.push(new wasm.LeanAgenticClient(`session-${i}`, null));
}
const start = performance.now();
// Process messages concurrently
const promises = clients.map((client, i) => {
return new Promise(resolve => {
for (let j = 0; j < messagesPerSession; j++) {
client.process_message(`Session ${i} message ${j}`);
}
resolve();
});
});
await Promise.all(promises);
const duration = performance.now() - start;
const totalMessages = sessions * messagesPerSession;
const throughput = (totalMessages / duration) * 1000;
log('benchmark', `Concurrent test: ${sessions} sessions`, 'success');
log('benchmark', `Total messages: ${totalMessages}`, 'success');
log('benchmark', `Duration: ${duration.toFixed(2)}ms`, 'success');
log('benchmark', `Throughput: ${throughput.toFixed(0)} msg/s`, 'success');
log('benchmark', `Avg per session: ${(duration / sessions).toFixed(2)}ms`, 'success');
};
// Utility functions
function log(tab, message, type = 'info') {
const logDiv = document.getElementById(`${tab}-log`);
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
const entry = document.createElement('div');
entry.className = `log-entry ${type}`;
entry.textContent = `[${timestamp}] ${message}`;
logDiv.appendChild(entry);
logDiv.scrollTop = logDiv.scrollHeight;
}
function updateStats() {
if (agenticClient) {
const avgLatency = agenticClient.get_avg_latency_ms();
const msgCount = agenticClient.get_message_count();
const elapsed = (Date.now() - startTime) / 1000;
const throughput = msgCount / elapsed;
document.getElementById('avg-latency').textContent = `${avgLatency.toFixed(2)}ms`;
document.getElementById('msg-count').textContent = msgCount;
document.getElementById('throughput').textContent = `${throughput.toFixed(0)}/s`;
}
}
function updateLatencyMeter(avg, p99) {
const meter = document.getElementById('latency-bar');
const maxLatency = 10; // 10ms max for visualization
const percentage = Math.min((avg / maxLatency) * 100, 100);
meter.style.height = `${percentage}%`;
if (avg < 1) {
meter.style.background = 'linear-gradient(180deg, #2ecc71 0%, #27ae60 100%)';
} else if (avg < 5) {
meter.style.background = 'linear-gradient(180deg, #f39c12 0%, #e67e22 100%)';
} else {
meter.style.background = 'linear-gradient(180deg, #e74c3c 0%, #c0392b 100%)';
}
}
// Auto-update stats
setInterval(updateStats, 1000);
// Initialize on load
init();