2022-06-28 12:14:15 +00:00
|
|
|
import {
|
|
|
|
fullTextDelete,
|
|
|
|
fullTextIndex,
|
|
|
|
fullTextSearch,
|
2022-10-10 12:50:21 +00:00
|
|
|
} from "../../syscall/plugos-syscall/fulltext.ts";
|
|
|
|
import { renderToText } from "../../common/tree.ts";
|
|
|
|
import { PageMeta } from "../../common/types.ts";
|
|
|
|
import { queryPrefix } from "../../syscall/silverbullet-syscall/index.ts";
|
|
|
|
import { navigate, prompt } from "../../syscall/silverbullet-syscall/editor.ts";
|
|
|
|
import { IndexTreeEvent } from "../../web/app_event.ts";
|
|
|
|
import { applyQuery, QueryProviderEvent } from "../query/engine.ts";
|
|
|
|
import { removeQueries } from "../query/util.ts";
|
2022-05-16 13:09:36 +00:00
|
|
|
|
2022-09-02 13:41:40 +00:00
|
|
|
const searchPrefix = "🔍 ";
|
|
|
|
|
2022-05-16 13:09:36 +00:00
|
|
|
export async function index(data: IndexTreeEvent) {
|
|
|
|
removeQueries(data.tree);
|
|
|
|
let cleanText = renderToText(data.tree);
|
|
|
|
await fullTextIndex(data.name, cleanText);
|
|
|
|
}
|
|
|
|
|
2022-06-28 12:14:15 +00:00
|
|
|
export async function unindex(pageName: string) {
|
|
|
|
await fullTextDelete(pageName);
|
|
|
|
}
|
|
|
|
|
2022-05-16 13:09:36 +00:00
|
|
|
export async function queryProvider({
|
|
|
|
query,
|
|
|
|
}: QueryProviderEvent): Promise<any[]> {
|
|
|
|
let phraseFilter = query.filter.find((f) => f.prop === "phrase");
|
|
|
|
if (!phraseFilter) {
|
|
|
|
throw Error("No 'phrase' filter specified, this is mandatory");
|
|
|
|
}
|
|
|
|
let results = await fullTextSearch(phraseFilter.value, 100);
|
|
|
|
|
2022-05-17 06:32:33 +00:00
|
|
|
let allPageMap: Map<string, any> = new Map(
|
|
|
|
results.map((r: any) => [r.name, r])
|
|
|
|
);
|
2022-05-17 13:54:55 +00:00
|
|
|
for (let { page, value } of await queryPrefix("meta:")) {
|
2022-05-16 13:09:36 +00:00
|
|
|
let p = allPageMap.get(page);
|
|
|
|
if (p) {
|
|
|
|
for (let [k, v] of Object.entries(value)) {
|
|
|
|
p[k] = v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the "phrase" filter
|
|
|
|
query.filter.splice(query.filter.indexOf(phraseFilter), 1);
|
|
|
|
|
|
|
|
results = applyQuery(query, results);
|
|
|
|
return results;
|
|
|
|
}
|
2022-05-17 09:53:17 +00:00
|
|
|
|
|
|
|
export async function searchCommand() {
|
|
|
|
let phrase = await prompt("Search for: ");
|
|
|
|
if (phrase) {
|
2022-09-02 13:41:40 +00:00
|
|
|
await navigate(`${searchPrefix}${phrase}`);
|
2022-05-17 09:53:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function readPageSearch(
|
|
|
|
name: string
|
|
|
|
): Promise<{ text: string; meta: PageMeta }> {
|
2022-09-02 13:41:40 +00:00
|
|
|
let phrase = name.substring(searchPrefix.length);
|
2022-05-17 09:53:17 +00:00
|
|
|
let results = await fullTextSearch(phrase, 100);
|
|
|
|
const text = `# Search results for "${phrase}"\n${results
|
|
|
|
.map((r: any) => `* [[${r.name}]] (score: ${r.rank})`)
|
|
|
|
.join("\n")}
|
|
|
|
`;
|
|
|
|
return {
|
|
|
|
text: text,
|
|
|
|
meta: {
|
|
|
|
name,
|
|
|
|
lastModified: 0,
|
|
|
|
perm: "ro",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function getPageMetaSearch(name: string): Promise<PageMeta> {
|
|
|
|
return {
|
|
|
|
name,
|
|
|
|
lastModified: 0,
|
|
|
|
perm: "ro",
|
|
|
|
};
|
|
|
|
}
|