commit ed89e611e73ac0b342bb3485c0a6c26791a1486b
parent 5d1bf412d6266ccb37a618e30b7f3a0f7cc3bfa5
Author: finwo <finwo@pm.me>
Date: Tue, 24 Mar 2026 14:13:16 +0100
Wait for both consumers and walkers to be done in --query mode
Diffstat:
| M | vecfinder.js | | | 73 | +++++++++++++++++++++++++++++++++++++------------------------------------ |
1 file changed, 37 insertions(+), 36 deletions(-)
diff --git a/vecfinder.js b/vecfinder.js
@@ -256,10 +256,22 @@ async function walkDir(dirPath) {
async function indexDirectory(store, dirPath) {
const files = await walkDir(dirPath);
const queue = [];
+ let totalFiles = 0;
+ let completedFiles = 0;
+
+ for (const filePath of files) {
+ const stats = await fs.stat(filePath).catch(() => null);
+ if (!stats || stats.size > 1024 * 1024) continue;
+ const text = await isTextFile(filePath);
+ if (!text) continue;
+ queue.push(filePath);
+ totalFiles++;
+ }
function consumer() {
- if (queue.length === 0) return;
- if (store.consumersActive >= config.parallelism) return;
+ if (queue.length === 0 && store.consumersActive === 0) return;
+
+ if (store.consumersActive >= config.parallelism || queue.length === 0) return;
store.consumersActive++;
const filePath = queue.shift();
@@ -280,20 +292,29 @@ async function indexDirectory(store, dirPath) {
}
} catch {}
+ completedFiles++;
store.consumersActive--;
store.emit('documentAdded');
- setImmediate(consumer);
+ if (queue.length > 0 || store.consumersActive > 0) {
+ setImmediate(consumer);
+ }
})();
}
- for (const filePath of files) {
- const stats = await fs.stat(filePath).catch(() => null);
- if (!stats || stats.size > 1024 * 1024) continue;
- const text = await isTextFile(filePath);
- if (!text) continue;
- queue.push(filePath);
+ for (let i = 0; i < Math.min(config.parallelism, totalFiles); i++) {
setImmediate(consumer);
}
+
+ return new Promise(resolve => {
+ const checkComplete = () => {
+ if (completedFiles >= totalFiles && store.consumersActive === 0 && queue.length === 0) {
+ store.removeListener('documentAdded', checkComplete);
+ resolve();
+ }
+ };
+ store.on('documentAdded', checkComplete);
+ checkComplete();
+ });
}
// UI
@@ -623,19 +644,6 @@ class UI {
}
}
-function waitForIndexing(store) {
- return new Promise(resolve => {
- const check = () => {
- if (store.consumersActive === 0 && store.documents.size > 0) {
- store.removeListener('documentAdded', check);
- resolve();
- }
- };
- store.on('documentAdded', check);
- check();
- });
-}
-
function printUsage() {
stdout.write(`Usage: vecfinder [options]
vecfinder --query <text> [-k N]
@@ -675,21 +683,14 @@ async function main() {
process.exit(1);
}
- indexDirectory(store, process.cwd());
-
- try {
- await waitForIndexing(store);
- const raw = await fetchEmbedding(queryText);
- store.queryVec = normalize(raw);
- const results = store.getResults().slice(0, k);
- for (const r of results) {
- stdout.write(r.id + '\n');
- }
- process.exit(0);
- } catch (err) {
- stderr.write(`Error: ${err.message}\n`);
- process.exit(1);
+ await indexDirectory(store, process.cwd());
+ const raw = await fetchEmbedding(queryText);
+ store.queryVec = normalize(raw);
+ const results = store.getResults().slice(0, k);
+ for (const r of results) {
+ stdout.write(r.id + '\n');
}
+ process.exit(0);
}
const useBatFlag = args.includes('--no-bat') ? false : null;