551 lines
16 KiB
HTML
551 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Midstream WASM Demo</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: #333;
|
|
line-height: 1.6;
|
|
padding: 20px;
|
|
}
|
|
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
background: white;
|
|
border-radius: 12px;
|
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
overflow: hidden;
|
|
}
|
|
|
|
header {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
padding: 30px;
|
|
text-align: center;
|
|
}
|
|
|
|
h1 {
|
|
font-size: 2.5em;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.subtitle {
|
|
font-size: 1.1em;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.content {
|
|
padding: 30px;
|
|
}
|
|
|
|
.demo-section {
|
|
margin-bottom: 40px;
|
|
padding: 25px;
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
border-left: 4px solid #667eea;
|
|
}
|
|
|
|
h2 {
|
|
color: #667eea;
|
|
margin-bottom: 15px;
|
|
font-size: 1.8em;
|
|
}
|
|
|
|
button {
|
|
background: #667eea;
|
|
color: white;
|
|
border: none;
|
|
padding: 12px 24px;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
margin-right: 10px;
|
|
margin-bottom: 10px;
|
|
transition: background 0.3s;
|
|
}
|
|
|
|
button:hover {
|
|
background: #5568d3;
|
|
}
|
|
|
|
button:active {
|
|
transform: scale(0.98);
|
|
}
|
|
|
|
.output {
|
|
background: #2d3748;
|
|
color: #e2e8f0;
|
|
padding: 20px;
|
|
border-radius: 6px;
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 14px;
|
|
margin-top: 15px;
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.canvas-container {
|
|
margin-top: 20px;
|
|
background: white;
|
|
padding: 20px;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
canvas {
|
|
border: 1px solid #cbd5e0;
|
|
border-radius: 4px;
|
|
width: 100%;
|
|
max-width: 800px;
|
|
}
|
|
|
|
.metric {
|
|
display: inline-block;
|
|
background: white;
|
|
padding: 15px 20px;
|
|
border-radius: 6px;
|
|
margin-right: 15px;
|
|
margin-bottom: 15px;
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.metric-label {
|
|
font-size: 12px;
|
|
color: #718096;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.metric-value {
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
color: #667eea;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
.status {
|
|
padding: 8px 16px;
|
|
border-radius: 4px;
|
|
display: inline-block;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.status.success {
|
|
background: #c6f6d5;
|
|
color: #2f855a;
|
|
}
|
|
|
|
.status.running {
|
|
background: #bee3f8;
|
|
color: #2c5282;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.5; }
|
|
}
|
|
|
|
.loading {
|
|
animation: pulse 2s ease-in-out infinite;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<header>
|
|
<h1>🚀 Midstream WASM</h1>
|
|
<p class="subtitle">High-Performance Browser Computing</p>
|
|
<div style="margin-top: 15px;">
|
|
<span class="status success" id="wasmStatus">Initializing...</span>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="content">
|
|
<!-- Temporal Comparison Demo -->
|
|
<div class="demo-section">
|
|
<h2>📊 Temporal Comparison</h2>
|
|
<p>Dynamic Time Warping, LCS, and Edit Distance algorithms running in WebAssembly.</p>
|
|
|
|
<div style="margin-top: 20px;">
|
|
<button onclick="runTemporalDemo()">Run Analysis</button>
|
|
<button onclick="benchmarkDTW()">Benchmark DTW</button>
|
|
</div>
|
|
|
|
<div id="temporalMetrics"></div>
|
|
<div class="output" id="temporalOutput">Click "Run Analysis" to start...</div>
|
|
<div class="canvas-container">
|
|
<canvas id="temporalCanvas" width="800" height="300"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Nanosecond Scheduler Demo -->
|
|
<div class="demo-section">
|
|
<h2>⏱️ Nanosecond Scheduler</h2>
|
|
<p>High-precision task scheduling with microsecond accuracy.</p>
|
|
|
|
<div style="margin-top: 20px;">
|
|
<button onclick="startScheduler()">Start Scheduler</button>
|
|
<button onclick="stopScheduler()">Stop Scheduler</button>
|
|
<button onclick="scheduleTask()">Schedule Task</button>
|
|
</div>
|
|
|
|
<div id="schedulerMetrics"></div>
|
|
<div class="output" id="schedulerOutput">Scheduler ready...</div>
|
|
</div>
|
|
|
|
<!-- Meta-Learning Demo -->
|
|
<div class="demo-section">
|
|
<h2>🧠 Strange Loop Meta-Learning</h2>
|
|
<p>Self-improving pattern recognition and meta-cognition.</p>
|
|
|
|
<div style="margin-top: 20px;">
|
|
<button onclick="trainMetaLearning()">Train Patterns</button>
|
|
<button onclick="reflectMetaLearning()">Reflect</button>
|
|
<button onclick="resetMetaLearning()">Reset</button>
|
|
</div>
|
|
|
|
<div id="metaMetrics"></div>
|
|
<div class="output" id="metaOutput">Ready to learn...</div>
|
|
<div class="canvas-container">
|
|
<canvas id="metaCanvas" width="800" height="300"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- QUIC Multistream Demo -->
|
|
<div class="demo-section">
|
|
<h2>🌐 QUIC Multistream</h2>
|
|
<p>WebTransport-compatible multiplexed streaming.</p>
|
|
|
|
<div style="margin-top: 20px;">
|
|
<button onclick="openStreams()">Open Streams</button>
|
|
<button onclick="sendData()">Send Data</button>
|
|
<button onclick="closeAllStreams()">Close All</button>
|
|
</div>
|
|
|
|
<div id="quicMetrics"></div>
|
|
<div class="output" id="quicOutput">Ready for streaming...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="module">
|
|
import { init, TemporalCompare, NanoScheduler, StrangeLoop, QuicMultistream, version, benchmarkDtw as wasmBenchmark } from '../index.js';
|
|
|
|
// Global instances
|
|
let temporal, scheduler, strangeLoop, quic;
|
|
let schedulerRunning = false;
|
|
let schedulerTasks = [];
|
|
|
|
// Initialize WASM
|
|
async function initWasm() {
|
|
try {
|
|
await init();
|
|
document.getElementById('wasmStatus').textContent = `Ready • v${version()}`;
|
|
|
|
// Create instances
|
|
temporal = new TemporalCompare(100);
|
|
scheduler = new NanoScheduler();
|
|
strangeLoop = new StrangeLoop(0.1);
|
|
quic = new QuicMultistream();
|
|
|
|
console.log('✅ WASM initialized successfully');
|
|
console.log('Version:', version());
|
|
} catch (error) {
|
|
document.getElementById('wasmStatus').textContent = 'Error';
|
|
document.getElementById('wasmStatus').className = 'status';
|
|
document.getElementById('wasmStatus').style.background = '#fed7d7';
|
|
document.getElementById('wasmStatus').style.color = '#c53030';
|
|
console.error('Failed to initialize WASM:', error);
|
|
}
|
|
}
|
|
|
|
// Temporal Comparison Demo
|
|
window.runTemporalDemo = function() {
|
|
const output = document.getElementById('temporalOutput');
|
|
output.textContent = 'Running analysis...\n';
|
|
|
|
// Generate sample time series
|
|
const seq1 = Array.from({ length: 100 }, (_, i) => Math.sin(i / 10) + Math.random() * 0.1);
|
|
const seq2 = Array.from({ length: 100 }, (_, i) => Math.sin(i / 10 + 0.5) + Math.random() * 0.1);
|
|
|
|
const metrics = temporal.analyze(seq1, seq2);
|
|
|
|
output.textContent += `DTW Distance: ${metrics.dtwDistance.toFixed(2)}\n`;
|
|
output.textContent += `LCS Length: ${metrics.lcsLength}\n`;
|
|
output.textContent += `Edit Distance: ${metrics.editDistance}\n`;
|
|
output.textContent += `Similarity Score: ${(metrics.similarityScore * 100).toFixed(1)}%\n`;
|
|
|
|
// Display metrics
|
|
document.getElementById('temporalMetrics').innerHTML = `
|
|
<div class="metric">
|
|
<div class="metric-label">Similarity</div>
|
|
<div class="metric-value">${(metrics.similarityScore * 100).toFixed(1)}%</div>
|
|
</div>
|
|
<div class="metric">
|
|
<div class="metric-label">DTW Distance</div>
|
|
<div class="metric-value">${metrics.dtwDistance.toFixed(1)}</div>
|
|
</div>
|
|
`;
|
|
|
|
// Visualize sequences
|
|
visualizeSequences(seq1, seq2);
|
|
};
|
|
|
|
window.benchmarkDTW = function() {
|
|
const output = document.getElementById('temporalOutput');
|
|
output.textContent = 'Running benchmark...\n';
|
|
|
|
const avgTime = wasmBenchmark(100, 100);
|
|
output.textContent += `\nAverage time per DTW (100 elements): ${avgTime.toFixed(3)}ms\n`;
|
|
output.textContent += `Throughput: ${(1000 / avgTime).toFixed(0)} ops/sec\n`;
|
|
};
|
|
|
|
function visualizeSequences(seq1, seq2) {
|
|
const canvas = document.getElementById('temporalCanvas');
|
|
const ctx = canvas.getContext('2d');
|
|
const width = canvas.width;
|
|
const height = canvas.height;
|
|
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// Draw background
|
|
ctx.fillStyle = '#f7fafc';
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
|
// Draw grid
|
|
ctx.strokeStyle = '#e2e8f0';
|
|
ctx.lineWidth = 1;
|
|
for (let i = 0; i <= 10; i++) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(0, (height / 10) * i);
|
|
ctx.lineTo(width, (height / 10) * i);
|
|
ctx.stroke();
|
|
}
|
|
|
|
// Draw seq1
|
|
ctx.strokeStyle = '#667eea';
|
|
ctx.lineWidth = 2;
|
|
ctx.beginPath();
|
|
seq1.forEach((val, i) => {
|
|
const x = (i / seq1.length) * width;
|
|
const y = height / 2 - (val * height / 4);
|
|
if (i === 0) ctx.moveTo(x, y);
|
|
else ctx.lineTo(x, y);
|
|
});
|
|
ctx.stroke();
|
|
|
|
// Draw seq2
|
|
ctx.strokeStyle = '#f56565';
|
|
ctx.lineWidth = 2;
|
|
ctx.beginPath();
|
|
seq2.forEach((val, i) => {
|
|
const x = (i / seq2.length) * width;
|
|
const y = height / 2 - (val * height / 4);
|
|
if (i === 0) ctx.moveTo(x, y);
|
|
else ctx.lineTo(x, y);
|
|
});
|
|
ctx.stroke();
|
|
}
|
|
|
|
// Scheduler Demo
|
|
window.startScheduler = function() {
|
|
if (schedulerRunning) return;
|
|
schedulerRunning = true;
|
|
scheduler.start();
|
|
|
|
const output = document.getElementById('schedulerOutput');
|
|
output.textContent = 'Scheduler started...\n';
|
|
|
|
updateSchedulerMetrics();
|
|
};
|
|
|
|
window.stopScheduler = function() {
|
|
scheduler.stop();
|
|
schedulerRunning = false;
|
|
|
|
const output = document.getElementById('schedulerOutput');
|
|
output.textContent += 'Scheduler stopped.\n';
|
|
};
|
|
|
|
window.scheduleTask = function() {
|
|
const delay = Math.random() * 2000000000; // 0-2 seconds in ns
|
|
const output = document.getElementById('schedulerOutput');
|
|
|
|
const taskId = scheduler.schedule(() => {
|
|
output.textContent += `Task ${taskId} executed at ${scheduler.nowNs().toFixed(0)}ns\n`;
|
|
updateSchedulerMetrics();
|
|
}, delay);
|
|
|
|
output.textContent += `Task ${taskId} scheduled for ${(delay / 1000000).toFixed(0)}ms\n`;
|
|
updateSchedulerMetrics();
|
|
};
|
|
|
|
function updateSchedulerMetrics() {
|
|
document.getElementById('schedulerMetrics').innerHTML = `
|
|
<div class="metric">
|
|
<div class="metric-label">Pending Tasks</div>
|
|
<div class="metric-value">${scheduler.pendingCount}</div>
|
|
</div>
|
|
<div class="metric">
|
|
<div class="metric-label">Status</div>
|
|
<div class="metric-value">${schedulerRunning ? '▶️' : '⏸️'}</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// Meta-Learning Demo
|
|
window.trainMetaLearning = function() {
|
|
const output = document.getElementById('metaOutput');
|
|
output.textContent = 'Training patterns...\n';
|
|
|
|
const patterns = ['fast-path', 'slow-path', 'cached', 'optimized', 'baseline'];
|
|
|
|
for (let i = 0; i < 50; i++) {
|
|
const pattern = patterns[Math.floor(Math.random() * patterns.length)];
|
|
const performance = Math.random();
|
|
strangeLoop.observe(pattern, performance);
|
|
}
|
|
|
|
const best = strangeLoop.bestPattern();
|
|
output.textContent += `\nBest Pattern: ${best.patternId}\n`;
|
|
output.textContent += `Confidence: ${(best.confidence * 100).toFixed(1)}%\n`;
|
|
output.textContent += `Iterations: ${strangeLoop.iterationCount}\n`;
|
|
|
|
updateMetaMetrics();
|
|
visualizeMetaLearning();
|
|
};
|
|
|
|
window.reflectMetaLearning = function() {
|
|
const reflection = strangeLoop.reflect();
|
|
const output = document.getElementById('metaOutput');
|
|
|
|
output.textContent = 'Meta-cognition reflection:\n\n';
|
|
output.textContent += JSON.stringify(reflection, null, 2);
|
|
};
|
|
|
|
window.resetMetaLearning = function() {
|
|
strangeLoop = new StrangeLoop(0.1);
|
|
document.getElementById('metaOutput').textContent = 'Reset complete. Ready to learn...\n';
|
|
updateMetaMetrics();
|
|
};
|
|
|
|
function updateMetaMetrics() {
|
|
const best = strangeLoop.bestPattern();
|
|
document.getElementById('metaMetrics').innerHTML = `
|
|
<div class="metric">
|
|
<div class="metric-label">Patterns</div>
|
|
<div class="metric-value">${strangeLoop.patternCount}</div>
|
|
</div>
|
|
<div class="metric">
|
|
<div class="metric-label">Iterations</div>
|
|
<div class="metric-value">${strangeLoop.iterationCount}</div>
|
|
</div>
|
|
${best ? `
|
|
<div class="metric">
|
|
<div class="metric-label">Best Confidence</div>
|
|
<div class="metric-value">${(best.confidence * 100).toFixed(0)}%</div>
|
|
</div>
|
|
` : ''}
|
|
`;
|
|
}
|
|
|
|
function visualizeMetaLearning() {
|
|
const canvas = document.getElementById('metaCanvas');
|
|
const ctx = canvas.getContext('2d');
|
|
const width = canvas.width;
|
|
const height = canvas.height;
|
|
|
|
ctx.clearRect(0, 0, width, height);
|
|
ctx.fillStyle = '#f7fafc';
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
|
const reflection = strangeLoop.reflect();
|
|
const patterns = Object.values(reflection);
|
|
|
|
patterns.forEach((pattern, i) => {
|
|
const x = 50 + (i * 150);
|
|
const barHeight = pattern.confidence * 200;
|
|
const y = height - 50 - barHeight;
|
|
|
|
ctx.fillStyle = '#667eea';
|
|
ctx.fillRect(x, y, 100, barHeight);
|
|
|
|
ctx.fillStyle = '#2d3748';
|
|
ctx.font = '12px sans-serif';
|
|
ctx.fillText(pattern.patternId.substring(0, 10), x, height - 30);
|
|
ctx.fillText(`${(pattern.confidence * 100).toFixed(0)}%`, x + 30, y - 5);
|
|
});
|
|
}
|
|
|
|
// QUIC Demo
|
|
window.openStreams = function() {
|
|
const output = document.getElementById('quicOutput');
|
|
output.textContent = 'Opening streams...\n';
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
const priority = Math.floor(Math.random() * 256);
|
|
const streamId = quic.openStream(priority);
|
|
output.textContent += `Stream ${streamId} opened (priority: ${priority})\n`;
|
|
}
|
|
|
|
updateQuicMetrics();
|
|
};
|
|
|
|
window.sendData = function() {
|
|
const output = document.getElementById('quicOutput');
|
|
|
|
for (let i = 0; i < quic.streamCount; i++) {
|
|
const data = new Uint8Array(1024);
|
|
crypto.getRandomValues(data);
|
|
|
|
try {
|
|
const sent = quic.send(i, data);
|
|
output.textContent += `Stream ${i}: sent ${sent} bytes\n`;
|
|
} catch (e) {
|
|
// Stream might not exist
|
|
}
|
|
}
|
|
|
|
updateQuicMetrics();
|
|
};
|
|
|
|
window.closeAllStreams = function() {
|
|
const output = document.getElementById('quicOutput');
|
|
const count = quic.streamCount;
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
quic.closeStream(i);
|
|
}
|
|
|
|
output.textContent += `Closed ${count} streams\n`;
|
|
updateQuicMetrics();
|
|
};
|
|
|
|
function updateQuicMetrics() {
|
|
document.getElementById('quicMetrics').innerHTML = `
|
|
<div class="metric">
|
|
<div class="metric-label">Active Streams</div>
|
|
<div class="metric-value">${quic.streamCount}</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// Initialize on page load
|
|
initWasm();
|
|
</script>
|
|
</body>
|
|
</html>
|