1
0
silverbullet/plugs/query/materialized_queries.ts

128 lines
4.3 KiB
TypeScript
Raw Normal View History

2022-04-05 15:02:17 +00:00
import { flashNotification, getCurrentPage, reloadPage, save } from "plugos-silverbullet-syscall/editor";
2022-04-01 15:07:08 +00:00
2022-04-05 15:02:17 +00:00
import { listPages, readPage, writePage } from "plugos-silverbullet-syscall/space";
import { invokeFunction } from "plugos-silverbullet-syscall/system";
import { scanPrefixGlobal } from "plugos-silverbullet-syscall";
import { applyQuery, parseQuery } from "./engine";
import { PageMeta } from "../../common/types";
import type { Task } from "../tasks/task";
import { Item } from "../core/item";
import YAML from "yaml";
import { replaceTemplateVars } from "../core/template";
import { queryRegex } from "./util";
2022-03-29 15:02:28 +00:00
async function replaceAsync(
str: string,
regex: RegExp,
asyncFn: (match: string, ...args: any[]) => Promise<string>
) {
const promises: Promise<string>[] = [];
str.replace(regex, (match: string, ...args: any[]): string => {
const promise = asyncFn(match, ...args);
promises.push(promise);
return "";
});
const data = await Promise.all(promises);
return str.replace(regex, () => data.shift()!);
}
export async function updateMaterializedQueriesCommand() {
2022-04-01 15:07:08 +00:00
const currentPage = await getCurrentPage();
await save();
2022-04-05 15:02:17 +00:00
await invokeFunction(
"server",
"updateMaterializedQueriesOnPage",
currentPage
);
2022-04-01 15:07:08 +00:00
await reloadPage();
await flashNotification("Updated materialized queries");
2022-03-29 15:02:28 +00:00
}
// Called from client, running on server
export async function updateMaterializedQueriesOnPage(pageName: string) {
2022-04-01 15:07:08 +00:00
let { text } = await readPage(pageName);
text = await replaceAsync(
text,
queryRegex,
async (fullMatch, startQuery, query, body, endQuery) => {
let parsedQuery = parseQuery(replaceTemplateVars(query));
console.log("Parsed query", parsedQuery);
switch (parsedQuery.table) {
case "page":
let allPages = await listPages();
let markdownPages = applyQuery(parsedQuery, allPages).map(
(pageMeta: PageMeta) => `* [[${pageMeta.name}]]`
);
return `${startQuery}\n${markdownPages.join("\n")}\n${endQuery}`;
case "task":
let allTasks: Task[] = [];
for (let { key, page, value } of await scanPrefixGlobal("task:")) {
let [, pos] = key.split(":");
allTasks.push({
...value,
page: page,
pos: pos,
});
2022-03-29 15:02:28 +00:00
}
let markdownTasks = applyQuery(parsedQuery, allTasks).map(
(t) =>
`* [${t.done ? "x" : " "}] [[${t.page}@${t.pos}]] ${t.name}` +
(t.nested ? "\n " + t.nested : "")
);
return `${startQuery}\n${markdownTasks.join("\n")}\n${endQuery}`;
case "link":
let uniqueLinks = new Set<string>();
for (let { value: name } of await scanPrefixGlobal(
`pl:${pageName}:`
)) {
2022-03-31 15:25:34 +00:00
uniqueLinks.add(name);
}
let markdownLinks = applyQuery(
parsedQuery,
[...uniqueLinks].map((l) => ({ name: l }))
).map((pageMeta) => `* [[${pageMeta.name}]]`);
return `${startQuery}\n${markdownLinks.join("\n")}\n${endQuery}`;
case "item":
let allItems: Item[] = [];
for (let { key, page, value } of await scanPrefixGlobal("it:")) {
let [, pos] = key.split(":");
allItems.push({
...value,
page: page,
pos: +pos,
});
2022-03-29 15:02:28 +00:00
}
let markdownItems = applyQuery(parsedQuery, allItems).map(
(item) =>
`* [[${item.page}@${item.pos}]] ${item.name}` +
(item.nested ? "\n " + item.nested : "")
);
return `${startQuery}\n${markdownItems.join("\n")}\n${endQuery}`;
case "data":
let allData: Object[] = [];
for (let { key, page, value } of await scanPrefixGlobal("data:")) {
let [, pos] = key.split("@");
allData.push({
...value,
page: page,
pos: +pos,
});
}
let markdownData = applyQuery(parsedQuery, allData).map((item) =>
YAML.stringify(item)
);
return `${startQuery}\n\`\`\`data\n${markdownData.join(
"---\n"
)}\`\`\`\n${endQuery}`;
default:
return fullMatch;
}
2022-03-29 15:02:28 +00:00
}
);
2022-03-29 15:02:28 +00:00
// console.log("New text", text);
2022-04-01 15:07:08 +00:00
await writePage(pageName, text);
2022-03-29 15:02:28 +00:00
}