simple-fs-server/search.ts
2023-01-06 18:24:27 +09:00

92 lines
2.8 KiB
TypeScript

import { Command } from "https://deno.land/x/cliffy@v0.25.6/mod.ts";
import { Index } from "./src/client_search.ts";
import { Doc, DocCollector, loadDocuments } from "./src/collect.ts";
export async function collectDocuments(path: string, out: string) {
const collector = new DocCollector({ summaryOnly: true, dropContent: true });
await collector.walkDir(path);
const docs = collector.getDocs();
await Deno.writeTextFile(out, JSON.stringify(docs));
}
export async function watchDocuments(doc: string, options?: {
abort?: AbortSignal;
}) {
const doc_dump = await loadDocuments(doc);
const collector = new DocCollector({ summaryOnly: true, dropContent: true });
collector.setDocs(doc_dump);
const index = Index.createIndex(doc_dump);
async function update() {
index.setDocs(collector.getDocs());
await Deno.writeTextFile(doc, JSON.stringify(collector.getDocs()));
}
collector.watchDir(".", {
async onAdd(doc) {
console.log("onAdd :", doc.path);
await update();
},
async onRemove(path) {
console.log("onRemove :", path);
await update();
},
async onChange(doc) {
console.log("onModify :", doc.path);
await update();
},
abort: options?.abort,
});
return index;
}
export const search = new Command();
search.name("search")
.description("Search for a document.")
.command("collect", "Collect a document.")
.description("Collect documents and index documents.")
.arguments("<path:string>")
.option("-o, --out <path:string>", "out file to write the index to.", {
default: "collected_docs.json",
})
.action(async ({ out }, path: string) => {
console.log("collecting", path);
await collectDocuments(path, out);
})
.command("search", "Search for a document.")
.description("Search for a document.")
.arguments("<query:string>")
.option("-d, --docs <path:string>", "collected document file to search", {
default: "collected_docs.json",
})
.action(async ({ docs }, query: string) => {
console.log("searching", query);
const doc_dump = await loadDocuments(docs);
const results = Index.createIndex(doc_dump).search(query);
console.log(results);
})
.command("interact", "watch the index and search for a document.")
.description("watch the index and search for a document.")
.option("-d, --doc <path:string>", "doc file to read the docs from.", {
default: "collected_docs.json",
})
.action(async ({ doc }) => {
console.log("interacting");
const index = await watchDocuments(doc);
// interact
while (true) {
const query = await prompt("query: ");
if (query === null) {
continue;
}
if (query === ":exit") {
break;
}
const results = index.search(query);
console.log(results);
}
});
if (import.meta.main) {
await search.parse(Deno.args);
}