2024-02-29 22:23:05 +08:00
|
|
|
import { FunctionMap } from "../plug-api/types.ts";
|
2024-02-09 04:00:45 +08:00
|
|
|
import { builtinFunctions } from "../lib/builtin_query_functions.ts";
|
|
|
|
import { System } from "../lib/plugos/system.ts";
|
2024-02-29 22:23:05 +08:00
|
|
|
import { Query } from "../plug-api/types.ts";
|
2024-02-09 04:00:45 +08:00
|
|
|
import { LimitedMap } from "$lib/limited_map.ts";
|
2024-01-21 02:16:07 +08:00
|
|
|
|
2024-02-03 02:19:07 +08:00
|
|
|
const pageCacheTtl = 10 * 1000; // 10s
|
|
|
|
|
2024-02-07 21:50:01 +08:00
|
|
|
export function buildQueryFunctions(
|
2024-05-28 02:33:41 +08:00
|
|
|
allKnownFiles: Set<string>,
|
2024-02-03 02:19:07 +08:00
|
|
|
system: System<any>,
|
2024-02-07 21:50:01 +08:00
|
|
|
): FunctionMap {
|
2024-02-03 02:19:07 +08:00
|
|
|
const pageCache = new LimitedMap<string>(10);
|
2024-02-07 21:50:01 +08:00
|
|
|
|
2024-01-21 02:16:07 +08:00
|
|
|
return {
|
|
|
|
...builtinFunctions,
|
2024-02-03 02:19:07 +08:00
|
|
|
pageExists(name: string) {
|
2024-02-26 13:46:03 +08:00
|
|
|
if (typeof name !== "string") {
|
|
|
|
throw new Error("pageExists(): name is not a string");
|
|
|
|
}
|
|
|
|
|
2024-01-21 02:16:07 +08:00
|
|
|
if (name.startsWith("!") || name.startsWith("{{")) {
|
|
|
|
// Let's assume federated pages exist, and ignore template variable ones
|
|
|
|
return true;
|
|
|
|
}
|
2024-06-24 12:21:57 +08:00
|
|
|
|
|
|
|
const flattendFiles = new Set(
|
|
|
|
[...allKnownFiles].flatMap((file) =>
|
|
|
|
(file.endsWith(".md")) ? [file.slice(0, -3)] : []
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
return flattendFiles.has(name);
|
2024-01-21 02:16:07 +08:00
|
|
|
},
|
2024-02-26 13:46:03 +08:00
|
|
|
async template(template: unknown, obj: unknown) {
|
|
|
|
if (typeof template !== "string") {
|
|
|
|
throw new Error("template(): template is not a string");
|
|
|
|
}
|
|
|
|
|
2024-02-03 02:19:07 +08:00
|
|
|
return (await system.invokeFunction("template.renderTemplate", [
|
|
|
|
template,
|
|
|
|
obj,
|
|
|
|
])).text;
|
|
|
|
},
|
|
|
|
// INTERNAL: Used for implementing the { query } syntax in expressions
|
|
|
|
$query(query: Query, variables: Record<string, any>) {
|
|
|
|
return system.invokeFunction("query.renderQuery", [
|
|
|
|
query,
|
|
|
|
variables,
|
|
|
|
]);
|
|
|
|
},
|
|
|
|
// INTERNAL: Used to implement resolving [[links]] in expressions
|
2024-02-06 03:05:01 +08:00
|
|
|
readPage(name: string): Promise<string> | string {
|
2024-02-03 02:19:07 +08:00
|
|
|
const cachedPage = pageCache.get(name);
|
|
|
|
if (cachedPage) {
|
|
|
|
return cachedPage;
|
|
|
|
} else {
|
2024-02-07 21:50:01 +08:00
|
|
|
return system.localSyscall("space.readPage", [name]).then((page) => {
|
2024-02-03 02:19:07 +08:00
|
|
|
pageCache.set(name, page, pageCacheTtl);
|
|
|
|
return page;
|
|
|
|
}).catch((e: any) => {
|
|
|
|
if (e.message === "Not found") {
|
|
|
|
throw new Error(`Page not found: ${name}`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2024-01-21 02:16:07 +08:00
|
|
|
};
|
|
|
|
}
|