2022-10-14 13:11:33 +00:00
|
|
|
import type { IndexTreeEvent, QueryProviderEvent } from "$sb/app_event.ts";
|
2022-04-01 15:07:08 +00:00
|
|
|
|
2022-10-14 13:11:33 +00:00
|
|
|
import { index } from "$sb/silverbullet-syscall/mod.ts";
|
|
|
|
import { collectNodesOfType, ParseTree, renderToText } from "$sb/lib/tree.ts";
|
|
|
|
import { applyQuery, removeQueries } from "$sb/lib/query.ts";
|
2022-03-29 15:02:28 +00:00
|
|
|
|
2022-04-12 11:33:07 +00:00
|
|
|
export type Item = {
|
|
|
|
name: string;
|
2022-04-04 09:51:41 +00:00
|
|
|
nested?: string;
|
2022-07-08 07:50:26 +00:00
|
|
|
tags?: string[];
|
2022-04-12 11:33:07 +00:00
|
|
|
// Not stored in DB
|
|
|
|
page?: string;
|
|
|
|
pos?: number;
|
2022-03-29 15:02:28 +00:00
|
|
|
};
|
|
|
|
|
2022-04-20 08:56:43 +00:00
|
|
|
export async function indexItems({ name, tree }: IndexTreeEvent) {
|
2022-10-14 13:11:33 +00:00
|
|
|
const items: { key: string; value: Item }[] = [];
|
2022-04-20 08:56:43 +00:00
|
|
|
removeQueries(tree);
|
2022-03-29 15:02:28 +00:00
|
|
|
|
2022-10-21 08:00:43 +00:00
|
|
|
// console.log("Indexing items", name);
|
2022-04-04 09:51:41 +00:00
|
|
|
|
2022-10-14 13:11:33 +00:00
|
|
|
const coll = collectNodesOfType(tree, "ListItem");
|
2022-04-04 09:51:41 +00:00
|
|
|
|
|
|
|
coll.forEach((n) => {
|
|
|
|
if (!n.children) {
|
|
|
|
return;
|
|
|
|
}
|
2022-07-08 07:50:26 +00:00
|
|
|
if (collectNodesOfType(n, "Task").length > 0) {
|
|
|
|
// This is a task item, skip it
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-10-14 13:11:33 +00:00
|
|
|
const textNodes: ParseTree[] = [];
|
2022-04-04 09:51:41 +00:00
|
|
|
let nested: string | undefined;
|
2022-10-14 13:11:33 +00:00
|
|
|
for (const child of n.children!.slice(1)) {
|
2022-04-04 09:51:41 +00:00
|
|
|
if (child.type === "OrderedList" || child.type === "BulletList") {
|
2022-04-11 18:34:09 +00:00
|
|
|
nested = renderToText(child);
|
2022-04-04 09:51:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
textNodes.push(child);
|
|
|
|
}
|
2022-07-08 07:50:26 +00:00
|
|
|
|
2022-10-14 13:11:33 +00:00
|
|
|
const itemText = textNodes.map(renderToText).join("").trim();
|
|
|
|
const item: Item = {
|
2022-07-08 07:50:26 +00:00
|
|
|
name: itemText,
|
2022-03-29 15:02:28 +00:00
|
|
|
};
|
2022-04-04 09:51:41 +00:00
|
|
|
if (nested) {
|
2022-07-08 07:50:26 +00:00
|
|
|
item.nested = nested;
|
2022-03-29 15:02:28 +00:00
|
|
|
}
|
2022-07-08 07:50:26 +00:00
|
|
|
collectNodesOfType(n, "Hashtag").forEach((h) => {
|
|
|
|
if (!item.tags) {
|
|
|
|
item.tags = [];
|
|
|
|
}
|
|
|
|
item.tags.push(h.children![0].text!);
|
|
|
|
});
|
|
|
|
|
2022-03-29 15:02:28 +00:00
|
|
|
items.push({
|
2022-04-04 09:51:41 +00:00
|
|
|
key: `it:${n.from}`,
|
2022-07-08 07:50:26 +00:00
|
|
|
value: item,
|
2022-03-29 15:02:28 +00:00
|
|
|
});
|
2022-04-04 09:51:41 +00:00
|
|
|
});
|
2022-10-21 08:00:43 +00:00
|
|
|
// console.log("Found", items.length, "item(s)");
|
2022-10-14 13:11:33 +00:00
|
|
|
await index.batchSet(name, items);
|
2022-03-29 15:02:28 +00:00
|
|
|
}
|
2022-04-19 14:54:47 +00:00
|
|
|
|
|
|
|
export async function queryProvider({
|
|
|
|
query,
|
2022-04-28 09:55:38 +00:00
|
|
|
}: QueryProviderEvent): Promise<any[]> {
|
2022-10-14 13:11:33 +00:00
|
|
|
const allItems: Item[] = [];
|
|
|
|
for (const { key, page, value } of await index.queryPrefix("it:")) {
|
|
|
|
const [, pos] = key.split(":");
|
2022-04-19 14:54:47 +00:00
|
|
|
allItems.push({
|
|
|
|
...value,
|
|
|
|
page: page,
|
|
|
|
pos: +pos,
|
|
|
|
});
|
|
|
|
}
|
2022-04-28 09:55:38 +00:00
|
|
|
return applyQuery(query, allItems);
|
2022-04-19 14:54:47 +00:00
|
|
|
}
|