feat: add Meilisearch backend integration with Docker Compose setup and Excalidraw support

This commit is contained in:
2025-10-14 10:41:15 -04:00
parent b359e8ab8e
commit 32a9998b40
71 changed files with 11544 additions and 435 deletions
+96
View File
@@ -0,0 +1,96 @@
#!/usr/bin/env node
import autocannon from 'autocannon';
const API_URL = process.env.API_URL || 'http://127.0.0.1:4000';
const QUERIES = [
'*',
'tag:work notes',
'path:Projects file:readme',
'obsidian search',
'tag:dev path:Projects'
];
console.log('🚀 Starting Meilisearch search benchmark...');
console.log(`API URL: ${API_URL}`);
console.log(`Queries to test: ${QUERIES.length}\n`);
async function benchQuery(query) {
const encodedQuery = encodeURIComponent(query);
const url = `${API_URL}/api/search?q=${encodedQuery}`;
console.log(`\n📊 Benchmarking: "${query}"`);
console.log(`URL: ${url}`);
return new Promise((resolve, reject) => {
autocannon(
{
url,
connections: 20,
duration: 10,
pipelining: 1
},
(err, result) => {
if (err) {
reject(err);
return;
}
console.log(`\n✅ Results for "${query}":`);
console.log(` Average: ${result.latency.mean.toFixed(2)} ms`);
console.log(` Median (P50): ${result.latency.p50.toFixed(2)} ms`);
console.log(` P95: ${result.latency.p95.toFixed(2)} ms`);
console.log(` P99: ${result.latency.p99.toFixed(2)} ms`);
console.log(` Requests/sec: ${result.requests.average.toFixed(2)}`);
console.log(` Total requests: ${result.requests.total}`);
resolve({
query,
latency: result.latency,
requests: result.requests
});
}
);
});
}
async function runBenchmarks() {
const results = [];
for (const query of QUERIES) {
try {
const result = await benchQuery(query);
results.push(result);
} catch (err) {
console.error(`\n❌ Failed to benchmark "${query}":`, err.message);
}
}
console.log('\n\n' + '='.repeat(60));
console.log('📈 SUMMARY');
console.log('='.repeat(60));
for (const result of results) {
console.log(`\n"${result.query}"`);
console.log(` P95: ${result.latency.p95.toFixed(2)} ms | Avg: ${result.latency.mean.toFixed(2)} ms`);
}
const allP95s = results.map(r => r.latency.p95);
const maxP95 = Math.max(...allP95s);
const avgP95 = allP95s.reduce((a, b) => a + b, 0) / allP95s.length;
console.log('\n' + '='.repeat(60));
console.log(`Overall P95: Avg ${avgP95.toFixed(2)} ms | Max ${maxP95.toFixed(2)} ms`);
console.log('='.repeat(60));
if (maxP95 < 150) {
console.log('\n✅ SUCCESS: P95 < 150ms target met!');
} else {
console.log('\n⚠️ WARNING: P95 exceeds 150ms target');
}
}
runBenchmarks().catch(err => {
console.error('\n💥 Benchmark suite failed:', err);
process.exit(1);
});