vecfinder

Document searching tool based on embedding vectors
git clone git://git.finwo.net/app/vecfinder
Log | Files | Refs

commit 56f7e19439a079a67c5d5c873a7353945f0771a2
parent 11ac9246196ae3b3c68a367fdc91afc2b8ef522a
Author: finwo <finwo@pm.me>
Date:   Sat, 21 Mar 2026 04:10:41 +0100

Fix cache format and location

Diffstat:
Mvecfinder.js | 32++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/vecfinder.js b/vecfinder.js @@ -10,7 +10,7 @@ const EventEmitter = require('node:events'); // Configuration const CONFIG_DIR = path.join(process.env.HOME || process.env.USERPROFILE, '.config', 'vecfinder'); const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json'); -const CACHE_DIR = path.join(CONFIG_DIR, 'cache'); +const CACHE_DIR = path.join(process.env.HOME || process.env.USERPROFILE, '.cache', 'vecfinder'); const ONE_GIB = 1073741824; let config = { endpoint: 'http://localhost:1234/v1/embeddings', @@ -37,8 +37,8 @@ async function getCachedVector(filePath) { const cp = cachePath(filePath); const [cacheStat, fileStat] = await Promise.all([fs.stat(cp), fs.stat(filePath)]); if (fileStat.mtimeMs >= cacheStat.mtimeMs) return null; - const data = await fs.readFile(cp, 'utf8'); - return JSON.parse(data); + const buf = await fs.readFile(cp); + return Array.from(new Float64Array(buf.buffer, buf.byteOffset, buf.byteLength / 8)); } catch { return null; } @@ -48,7 +48,7 @@ async function setCachedVector(filePath, vector) { try { const cp = cachePath(filePath); await fs.mkdir(path.dirname(cp), { recursive: true }); - await fs.writeFile(cp, JSON.stringify(vector)); + await fs.writeFile(cp, Buffer.from(new Float64Array(vector).buffer)); enforceCacheLimit(); } catch {} } @@ -258,6 +258,9 @@ class UI { this.selectedIndex = 0; this.previewOffset = 0; this.rl = null; + this._previewWrapped = null; + this._previewFileId = null; + this._previewWidth = null; this.store.on('documentAdded', () => this.render()); this.store.on('queryUpdated', () => { @@ -385,8 +388,22 @@ class UI { let right = ''; const selectedResult = results[this.selectedIndex]; if (selectedResult) { - const lines = selectedResult.content.split('\n'); - right = lines[row + this.previewOffset] || ''; + if (!this._previewWrapped || this._previewFileId !== selectedResult.id || this._previewWidth !== rightWidth) { + const lines = selectedResult.content.split('\n'); + this._previewWrapped = []; + for (const line of lines) { + if (line.length === 0) { + this._previewWrapped.push(''); + } else { + for (let i = 0; i < line.length; i += rightWidth) { + this._previewWrapped.push(line.slice(i, i + rightWidth)); + } + } + } + this._previewFileId = selectedResult.id; + this._previewWidth = rightWidth; + } + right = this._previewWrapped[row + this.previewOffset] || ''; } right = right.padEnd(rightWidth, ' ').slice(0, rightWidth); @@ -421,4 +438,4 @@ async function main() { main().catch(err => { console.error(`Fatal error: ${err.message}`); process.exit(1); -}); -\ No newline at end of file +});