1
0
silverbullet/plugs/core/item.ts

88 lines
2.3 KiB
TypeScript
Raw Normal View History

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";
2023-07-24 17:54:31 +00:00
import { extractAttributes } from "$sb/lib/attribute.ts";
2022-03-29 15:02:28 +00:00
export type Item = {
name: string;
2022-04-04 09:51:41 +00:00
nested?: string;
tags?: string[];
// Not stored in DB
page?: string;
pos?: number;
2023-07-24 17:54:31 +00:00
} & Record<string, any>;
2022-03-29 15:02:28 +00:00
export async function indexItems({ name, tree }: IndexTreeEvent) {
2022-10-14 13:11:33 +00:00
const items: { key: string; value: Item }[] = [];
removeQueries(tree);
2022-03-29 15:02:28 +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;
}
if (collectNodesOfType(n, "Task").length > 0) {
// This is a task item, skip it
return;
}
2023-07-24 17:54:31 +00:00
const item: Item = {
name: "", // to be replaced
};
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;
}
2023-07-24 17:54:31 +00:00
// Extract attributes and remove from tree
const extractedAttributes = extractAttributes(child, true);
for (const [key, value] of Object.entries(extractedAttributes)) {
item[key] = value;
}
2022-04-04 09:51:41 +00:00
textNodes.push(child);
}
2023-07-24 17:54:31 +00:00
item.name = textNodes.map(renderToText).join("").trim();
2022-04-04 09:51:41 +00:00
if (nested) {
item.nested = nested;
2022-03-29 15:02:28 +00:00
}
collectNodesOfType(n, "Hashtag").forEach((h) => {
if (!item.tags) {
item.tags = [];
}
2022-11-20 09:24:24 +00:00
// Push tag to the list, removinn the initial #
item.tags.push(h.children![0].text!.substring(1));
});
2022-03-29 15:02:28 +00:00
items.push({
2022-04-04 09:51:41 +00:00
key: `it:${n.from}`,
value: item,
2022-03-29 15:02:28 +00:00
});
2022-04-04 09:51:41 +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
}
export async function queryProvider({
query,
}: 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(":");
allItems.push({
...value,
page: page,
pos: +pos,
});
}
return applyQuery(query, allItems);
}