// End-to-end: same DB, same queries — published @mastra/libsql 1.25.1 vs the patched build. // Usage: PATCHED=/path/to/mastra/stores/libsql/dist/index.js N=5000 RUNS=3 node compare-patched.mjs import { mkdtempSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { createClient } from '@libsql/client'; import { LibSQLVector as Published } from '@mastra/libsql'; const { LibSQLVector: Patched } = await import(process.env.PATCHED); const N = Number(process.env.N ?? 5000); const RUNS = Number(process.env.RUNS ?? 3); const DIM = 2560; const TOPK = 10; function mulberry32(seed) { return () => { seed |= 0; seed = (seed + 0x6d2b79f5) | 0; let t = Math.imul(seed ^ (seed >>> 15), 1 | seed); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; } const rnd = mulberry32(7); const randomVector = () => Array.from({ length: DIM }, () => rnd() * 2 - 1); const dir = mkdtempSync(join(tmpdir(), 'mastra-libsql-compare-')); const url = `file:${join(dir, 'compare.db')}`; const indexName = 'chunks'; { const setup = new Published({ url, id: 'setup' }); await setup.createIndex({ indexName, dimension: DIM }); const raw = createClient({ url }); await raw.execute(`DROP INDEX IF EXISTS ${indexName}_vector_idx`); // force the brute-force path raw.close(); for (let off = 0; off < N; off += 250) { const n = Math.min(250, N - off); const vectors = Array.from({ length: n }, randomVector); await setup.upsert({ indexName, vectors, metadata: vectors.map((_, j) => ({ i: off + j, bucket: (off + j) % 10 })), ids: vectors.map((_, j) => `v${off + j}`), }); } await setup.close(); } const published = new Published({ url, id: 'published' }); const patched = new Patched({ url, id: 'patched' }); const median = xs => [...xs].sort((a, b) => a - b)[Math.floor(xs.length / 2)]; async function time(fn) { await fn(); const ts = []; let out; for (let r = 0; r < RUNS; r++) { const t0 = performance.now(); out = await fn(); ts.push(performance.now() - t0); } return { ms: median(ts), out }; } console.log(`N=${N} dim=${DIM} topK=${TOPK} runs=${RUNS} (median), no DiskANN index`); const cases = [ ['no filter', {}], ['filter {bucket: 3}', { filter: { bucket: 3 } }], ['filter {bucket: {$in: [1,2]}} + minScore 0.02', { filter: { bucket: { $in: [1, 2] } }, minScore: 0.02 }], ['includeVector', { includeVector: true }], ]; for (const [label, params] of cases) { const queryVector = randomVector(); const a = await time(() => published.query({ indexName, queryVector, topK: TOPK, ...params })); const b = await time(() => patched.query({ indexName, queryVector, topK: TOPK, ...params })); const identical = JSON.stringify(a.out) === JSON.stringify(b.out); console.log( `${label.padEnd(46)} 1.25.1 ${a.ms.toFixed(1).padStart(8)} ms | patched ${b.ms.toFixed(1).padStart(7)} ms | ` + `x${(a.ms / b.ms).toFixed(0)} | ${a.out.length} results, identical (ids, scores, metadata, vectors): ${identical}`, ); } await published.close(); await patched.close();