const $ = id => document.getElementById(id); const runButton = $('run'); const status = $('status'); const verdict = $('verdict'); const cards = { published: $('card-published'), fixed: $('card-fixed') }; const fmt = ms => (ms >= 1000 ? `${(ms / 1000).toFixed(2)} s` : `${ms.toFixed(ms < 10 ? 1 : 0)} ms`); const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }); const live = { published: [], fixed: [] }; function resetCards() { for (const card of Object.values(cards)) { card.querySelector('[data-ms]').textContent = '…'; card.querySelector('[data-runs]').textContent = ''; card.querySelector('[data-sql]').textContent = ''; card.querySelector('[data-args]').textContent = ''; } live.published = []; live.fixed = []; verdict.hidden = true; } function renderCard(name, data) { const card = cards[name]; card.querySelector('[data-ms]').textContent = fmt(data.ms); card.querySelector('[data-runs]').textContent = `median of ${data.all.length}: ${data.all.map(fmt).join(' · ')}`; if (data.statement) { card.querySelector('[data-sql]').textContent = data.statement.sql; card.querySelector('[data-args]').textContent = `args: [${data.statement.args.join(', ')}]`; } } worker.onmessage = ({ data }) => { switch (data.type) { case 'ready': runButton.disabled = false; runButton.textContent = 'Run'; status.textContent = 'Ready. Everything runs locally in a Web Worker.'; break; case 'status': status.textContent = data.text; break; case 'seed': status.textContent = `Upserting vectors: ${data.done.toLocaleString('en-US')} / ${data.total.toLocaleString('en-US')}`; break; case 'tick': if (data.run >= 0) { live[data.name].push(data.ms); cards[data.name].querySelector('[data-runs]').textContent = live[data.name].map(fmt).join(' · '); } break; case 'done': { const r = data.result; renderCard('published', r.published); renderCard('fixed', r.fixed); const ratio = r.published.ms / r.fixed.ms; const branchOk = r.published.statement && !r.published.statement.usesTopK && r.fixed.statement && !r.fixed.statement.usesTopK; verdict.hidden = false; verdict.classList.toggle('bad', !r.identical || !branchOk); verdict.textContent = `${r.n.toLocaleString('en-US')} vectors × ${r.dim.toLocaleString('en-US')} dims${r.filter ? `, filter ${JSON.stringify(r.filter)}` : ''}: ` + `the fix is ×${ratio.toFixed(ratio < 10 ? 1 : 0)} faster. ` + (r.identical ? `Both return the same ${r.rows} results — same ids, order, scores and metadata.` : 'Results DIFFER between the two builds.') + (branchOk ? '' : ' (Unexpected: a store used vector_top_k.)'); status.textContent = `Done in ${fmt(r.totalMs)} (including seeding). Top result: ${r.top[0]?.id} (score ${r.top[0]?.score?.toFixed(6)}).`; runButton.disabled = false; runButton.textContent = 'Run again'; break; } case 'error': status.textContent = `Error: ${data.message}`; runButton.disabled = false; runButton.textContent = 'Run'; break; } }; worker.onerror = e => { status.textContent = `Worker failed to load: ${e.message ?? e}`; }; runButton.addEventListener('click', () => { resetCards(); runButton.disabled = true; runButton.textContent = 'Running…'; worker.postMessage({ n: Number($('n').value), dim: Number($('dim').value), topK: 10, runs: Number($('runs').value), filterMode: $('filter').value, }); });