From 7d28b53b7506fe4e88384a37c1698f6346b7970f Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Fri, 14 Oct 2022 15:11:33 +0200 Subject: [PATCH] Massive restructure of plugin API --- common/parse_tree.ts | 2 +- common/syscalls/markdown.ts | 2 +- import_map.json | 2 +- {web => plug-api}/app_event.ts | 8 +- {plugs/core => plug-api/lib}/dates.ts | 0 plug-api/lib/query.ts | 168 ++++++++++++++++++ {plugs => plug-api}/lib/secrets_page.ts | 0 {plugs => plug-api}/lib/settings_page.ts | 12 +- {common => plug-api/lib}/tree.test.ts | 7 +- {common => plug-api/lib}/tree.ts | 0 {plugs => plug-api}/lib/util.ts | 6 +- {plugs => plug-api}/lib/yaml_page.ts | 20 +-- plug-api/plugos-syscall/asset.ts | 15 ++ {syscall => plug-api}/plugos-syscall/event.ts | 2 +- {syscall => plug-api}/plugos-syscall/fs.ts | 2 +- .../plugos-syscall/fulltext.ts | 0 plug-api/plugos-syscall/mod.ts | 8 + .../plugos-syscall/sandbox.ts | 0 {syscall => plug-api}/plugos-syscall/shell.ts | 0 {syscall => plug-api}/plugos-syscall/store.ts | 0 .../plugos-syscall/syscall.ts | 0 .../silverbullet-syscall/clientStore.ts | 0 .../silverbullet-syscall/editor.ts | 40 ----- .../silverbullet-syscall/index.ts | 0 .../silverbullet-syscall/markdown.ts | 2 +- plug-api/silverbullet-syscall/mod.ts | 7 + .../silverbullet-syscall/sandbox.ts | 0 .../silverbullet-syscall/space.ts | 4 +- .../silverbullet-syscall/syscall.ts | 0 .../silverbullet-syscall/system.ts | 0 plugos/syscalls/fs.deno.ts | 14 +- plugs/core/anchor.ts | 27 ++- plugs/core/cloud.ts | 12 +- plugs/core/command.ts | 7 +- plugs/core/core.plug.yaml | 4 +- plugs/core/debug.ts | 26 +-- plugs/core/editor.ts | 9 +- plugs/core/item.ts | 36 ++-- plugs/core/link.ts | 48 +++-- plugs/core/navigate.ts | 35 ++-- plugs/core/page.ts | 141 +++++++-------- plugs/core/plugmanager.ts | 67 +++---- plugs/core/search.ts | 48 +++-- plugs/core/stats.ts | 12 +- plugs/core/tags.ts | 25 ++- plugs/core/template.ts | 110 ++++++------ plugs/core/text.ts | 55 +++--- plugs/emoji/emoji.ts | 4 +- plugs/markdown/markdown.plug.yaml | 2 + plugs/markdown/markdown.ts | 12 +- plugs/markdown/preview.ts | 78 ++------ plugs/markdown/styles.css | 51 ++++++ plugs/markdown/util.ts | 6 +- plugs/plugmd/plugmd.ts | 68 +++---- plugs/query/complete.ts | 8 +- plugs/query/data.ts | 50 +++--- plugs/query/engine.test.ts | 14 +- plugs/query/engine.ts | 137 ++------------ plugs/query/materialized_queries.ts | 66 ++++--- plugs/query/parser.ts | 53 ++---- plugs/query/util.ts | 54 +----- plugs/tasks/task.ts | 94 +++++----- server/hooks/plug_space_primitives.ts | 2 +- server/syscalls/space.ts | 34 ++-- syscall/plugos-syscall/asset.ts | 22 --- web/editor.tsx | 2 +- web/syscalls/editor.ts | 21 +-- web/syscalls/space.ts | 8 +- web/syscalls/system.ts | 15 +- website/CHANGELOG.md | 11 +- 70 files changed, 826 insertions(+), 969 deletions(-) rename {web => plug-api}/app_event.ts (67%) rename {plugs/core => plug-api/lib}/dates.ts (100%) create mode 100644 plug-api/lib/query.ts rename {plugs => plug-api}/lib/secrets_page.ts (100%) rename {plugs => plug-api}/lib/settings_page.ts (86%) rename {common => plug-api/lib}/tree.test.ts (87%) rename {common => plug-api/lib}/tree.ts (100%) rename {plugs => plug-api}/lib/util.ts (81%) rename {plugs => plug-api}/lib/yaml_page.ts (61%) create mode 100644 plug-api/plugos-syscall/asset.ts rename {syscall => plug-api}/plugos-syscall/event.ts (95%) rename {syscall => plug-api}/plugos-syscall/fs.ts (94%) rename {syscall => plug-api}/plugos-syscall/fulltext.ts (100%) create mode 100644 plug-api/plugos-syscall/mod.ts rename {syscall => plug-api}/plugos-syscall/sandbox.ts (100%) rename {syscall => plug-api}/plugos-syscall/shell.ts (100%) rename {syscall => plug-api}/plugos-syscall/store.ts (100%) rename {syscall => plug-api}/plugos-syscall/syscall.ts (100%) rename {syscall => plug-api}/silverbullet-syscall/clientStore.ts (100%) rename {syscall => plug-api}/silverbullet-syscall/editor.ts (79%) rename {syscall => plug-api}/silverbullet-syscall/index.ts (100%) rename {syscall => plug-api}/silverbullet-syscall/markdown.ts (74%) create mode 100644 plug-api/silverbullet-syscall/mod.ts rename {syscall => plug-api}/silverbullet-syscall/sandbox.ts (100%) rename {syscall => plug-api}/silverbullet-syscall/space.ts (93%) rename {syscall => plug-api}/silverbullet-syscall/syscall.ts (100%) rename {syscall => plug-api}/silverbullet-syscall/system.ts (100%) create mode 100644 plugs/markdown/styles.css delete mode 100644 syscall/plugos-syscall/asset.ts diff --git a/common/parse_tree.ts b/common/parse_tree.ts index da1f630..188f07d 100644 --- a/common/parse_tree.ts +++ b/common/parse_tree.ts @@ -1,4 +1,4 @@ -import { ParseTree } from "./tree.ts"; +import { ParseTree } from "$sb/lib/tree.ts"; import type { SyntaxNode } from "./deps.ts"; import type { Language } from "./deps.ts"; diff --git a/common/syscalls/markdown.ts b/common/syscalls/markdown.ts index 9809369..27a1da6 100644 --- a/common/syscalls/markdown.ts +++ b/common/syscalls/markdown.ts @@ -1,7 +1,7 @@ import { SysCallMapping } from "../../plugos/system.ts"; import { parse } from "../parse_tree.ts"; import { Language } from "../deps.ts"; -import type { ParseTree } from "../tree.ts"; +import type { ParseTree } from "$sb/lib/tree.ts"; export function markdownSyscalls(lang: Language): SysCallMapping { return { diff --git a/import_map.json b/import_map.json index 8ad4b5f..ab1dd43 100644 --- a/import_map.json +++ b/import_map.json @@ -10,7 +10,7 @@ "@lezer/highlight": "https://esm.sh/@lezer/highlight@1.1.1?external=@lezer/common", "@codemirror/autocomplete": "https://esm.sh/@codemirror/autocomplete@6.3.0?external=@codemirror/state,@lezer/common", "@codemirror/lint": "https://esm.sh/@codemirror/lint@6.0.0?external=@codemirror/state,@lezer/common", - "$sb/": "./syscall/", + "$sb/": "./plug-api/", "handlebars": "https://esm.sh/handlebars", "@lezer/lr": "https://esm.sh/@lezer/lr", "yaml": "https://deno.land/std/encoding/yaml.ts" diff --git a/web/app_event.ts b/plug-api/app_event.ts similarity index 67% rename from web/app_event.ts rename to plug-api/app_event.ts index 85437b3..e3b5e5d 100644 --- a/web/app_event.ts +++ b/plug-api/app_event.ts @@ -1,4 +1,5 @@ -import type { ParseTree } from "../common/tree.ts"; +import type { ParseTree } from "./lib/tree.ts"; +import { ParsedQuery } from "./lib/query.ts"; export type AppEvent = | "page:click" @@ -7,6 +8,11 @@ export type AppEvent = | "editor:init" | "plugs:loaded"; +export type QueryProviderEvent = { + query: ParsedQuery; + pageName: string; +}; + export type ClickEvent = { page: string; pos: number; diff --git a/plugs/core/dates.ts b/plug-api/lib/dates.ts similarity index 100% rename from plugs/core/dates.ts rename to plug-api/lib/dates.ts diff --git a/plug-api/lib/query.ts b/plug-api/lib/query.ts new file mode 100644 index 0000000..32f22e8 --- /dev/null +++ b/plug-api/lib/query.ts @@ -0,0 +1,168 @@ +import { + addParentPointers, + collectNodesMatching, + ParseTree, + renderToText, +} from "./tree.ts"; + +export const queryRegex = + /()(.+?)()/gs; + +export const directiveStartRegex = //s; + +export const directiveEndRegex = //s; + +export type QueryFilter = { + op: string; + prop: string; + value: any; +}; + +export type ParsedQuery = { + table: string; + orderBy?: string; + orderDesc?: boolean; + limit?: number; + filter: QueryFilter[]; + select?: string[]; + render?: string; +}; + +export function applyQuery(parsedQuery: ParsedQuery, records: T[]): T[] { + let resultRecords: any[] = []; + if (parsedQuery.filter.length === 0) { + resultRecords = records.slice(); + } else { + recordLoop: + for (const record of records) { + const recordAny: any = record; + for (let { op, prop, value } of parsedQuery.filter) { + switch (op) { + case "=": { + const recordPropVal = recordAny[prop]; + if (Array.isArray(recordPropVal) && !Array.isArray(value)) { + // Record property is an array, and value is a scalar: find the value in the array + if (!recordPropVal.includes(value)) { + continue recordLoop; + } + } else if (Array.isArray(recordPropVal) && Array.isArray(value)) { + // Record property is an array, and value is an array: find the value in the array + if (!recordPropVal.some((v) => value.includes(v))) { + continue recordLoop; + } + } else if (!(recordPropVal == value)) { + // Both are scalars: exact value + continue recordLoop; + } + break; + } + case "!=": + if (!(recordAny[prop] != value)) { + continue recordLoop; + } + break; + case "<": + if (!(recordAny[prop] < value)) { + continue recordLoop; + } + break; + case "<=": + if (!(recordAny[prop] <= value)) { + continue recordLoop; + } + break; + case ">": + if (!(recordAny[prop] > value)) { + continue recordLoop; + } + break; + case ">=": + if (!(recordAny[prop] >= value)) { + continue recordLoop; + } + break; + case "=~": + // TODO: Cache regexps somehow + if (!new RegExp(value).exec(recordAny[prop])) { + continue recordLoop; + } + break; + case "!=~": + if (new RegExp(value).exec(recordAny[prop])) { + continue recordLoop; + } + break; + case "in": + if (!value.includes(recordAny[prop])) { + continue recordLoop; + } + break; + } + } + resultRecords.push(recordAny); + } + } + // Now the sorting + if (parsedQuery.orderBy) { + resultRecords = resultRecords.sort((a: any, b: any) => { + const orderBy = parsedQuery.orderBy!; + const orderDesc = parsedQuery.orderDesc!; + if (a[orderBy] === b[orderBy]) { + return 0; + } + + if (a[orderBy] < b[orderBy]) { + return orderDesc ? 1 : -1; + } else { + return orderDesc ? -1 : 1; + } + }); + } + if (parsedQuery.limit) { + resultRecords = resultRecords.slice(0, parsedQuery.limit); + } + if (parsedQuery.select) { + resultRecords = resultRecords.map((rec) => { + let newRec: any = {}; + for (let k of parsedQuery.select!) { + newRec[k] = rec[k]; + } + return newRec; + }); + } + return resultRecords; +} + +export function removeQueries(pt: ParseTree) { + addParentPointers(pt); + collectNodesMatching(pt, (t) => { + if (t.type !== "CommentBlock") { + return false; + } + let text = t.children![0].text!; + let match = directiveStartRegex.exec(text); + if (!match) { + return false; + } + let directiveType = match[1]; + let parentChildren = t.parent!.children!; + let index = parentChildren.indexOf(t); + let nodesToReplace: ParseTree[] = []; + for (let i = index + 1; i < parentChildren.length; i++) { + let n = parentChildren[i]; + if (n.type === "CommentBlock") { + let text = n.children![0].text!; + let match = directiveEndRegex.exec(text); + if (match && match[1] === directiveType) { + break; + } + } + nodesToReplace.push(n); + } + let renderedText = nodesToReplace.map(renderToText).join(""); + parentChildren.splice(index + 1, nodesToReplace.length, { + text: new Array(renderedText.length + 1).join(" "), + }); + return true; + }); +} diff --git a/plugs/lib/secrets_page.ts b/plug-api/lib/secrets_page.ts similarity index 100% rename from plugs/lib/secrets_page.ts rename to plug-api/lib/secrets_page.ts diff --git a/plugs/lib/settings_page.ts b/plug-api/lib/settings_page.ts similarity index 86% rename from plugs/lib/settings_page.ts rename to plug-api/lib/settings_page.ts index a243f51..9bb5dbf 100644 --- a/plugs/lib/settings_page.ts +++ b/plug-api/lib/settings_page.ts @@ -2,7 +2,7 @@ import { readYamlPage } from "./yaml_page.ts"; import { notifyUser } from "./util.ts"; import * as YAML from "yaml"; -import { writePage } from "../../syscall/silverbullet-syscall/space.ts"; +import { space } from "$sb/silverbullet-syscall/mod.ts"; /** * Convenience function to read a specific set of settings from the `SETTINGS` page as well as default values @@ -18,9 +18,9 @@ const SETTINGS_PAGE = "SETTINGS"; export async function readSettings(settings: T): Promise { try { - let allSettings = (await readYamlPage(SETTINGS_PAGE, ["yaml"])) || {}; + const allSettings = (await readYamlPage(SETTINGS_PAGE, ["yaml"])) || {}; // TODO: I'm sure there's a better way to type this than "any" - let collectedSettings: any = {}; + const collectedSettings: any = {}; for (let [key, defaultVal] of Object.entries(settings)) { if (key in allSettings) { collectedSettings[key] = allSettings[key]; @@ -47,10 +47,10 @@ export async function writeSettings(settings: T) { let readSettings = {}; try { readSettings = (await readYamlPage(SETTINGS_PAGE, ["yaml"])) || {}; - } catch (e: any) { + } catch { await notifyUser("Creating a new SETTINGS page...", "info"); } - const writeSettings = { ...readSettings, ...settings }; + const writeSettings: any = { ...readSettings, ...settings }; // const doc = new YAML.Document(); // doc.contents = writeSettings; const contents = @@ -59,5 +59,5 @@ export async function writeSettings(settings: T) { writeSettings, ) }\n\`\`\``; // might need \r\n for windows? - await writePage(SETTINGS_PAGE, contents); + await space.writePage(SETTINGS_PAGE, contents); } diff --git a/common/tree.test.ts b/plug-api/lib/tree.test.ts similarity index 87% rename from common/tree.test.ts rename to plug-api/lib/tree.test.ts index bab9675..7685c87 100644 --- a/common/tree.test.ts +++ b/plug-api/lib/tree.test.ts @@ -1,4 +1,4 @@ -import { parse } from "./parse_tree.ts"; +// import { parse } from "./parse_tree.ts"; import { addParentPointers, collectNodesMatching, @@ -8,8 +8,9 @@ import { renderToText, replaceNodesMatching, } from "./tree.ts"; -import wikiMarkdownLang from "./parser.ts"; -import { assertEquals, assertNotEquals } from "../test_deps.ts"; +import wikiMarkdownLang from "../../common/parser.ts"; +import { assertEquals, assertNotEquals } from "../../test_deps.ts"; +import { parse } from "../../common/parse_tree.ts"; const mdTest1 = ` # Heading diff --git a/common/tree.ts b/plug-api/lib/tree.ts similarity index 100% rename from common/tree.ts rename to plug-api/lib/tree.ts diff --git a/plugs/lib/util.ts b/plug-api/lib/util.ts similarity index 81% rename from plugs/lib/util.ts rename to plug-api/lib/util.ts index f0908f9..32d4974 100644 --- a/plugs/lib/util.ts +++ b/plug-api/lib/util.ts @@ -1,4 +1,4 @@ -import { flashNotification } from "../../syscall/silverbullet-syscall/editor.ts"; +import { editor } from "$sb/silverbullet-syscall/mod.ts"; export async function replaceAsync( str: string, @@ -26,9 +26,9 @@ export function isBrowser() { return !isServer(); } -export async function notifyUser(message: string, type?: "info" | "error") { +export function notifyUser(message: string, type?: "info" | "error") { if (isBrowser()) { - return flashNotification(message, type); + return editor.flashNotification(message, type); } const log = type === "error" ? console.error : console.log; log(message); // we should end up sending the message to the user, users dont read logs. diff --git a/plugs/lib/yaml_page.ts b/plug-api/lib/yaml_page.ts similarity index 61% rename from plugs/lib/yaml_page.ts rename to plug-api/lib/yaml_page.ts index 8d739f6..0cdc8e1 100644 --- a/plugs/lib/yaml_page.ts +++ b/plug-api/lib/yaml_page.ts @@ -1,17 +1,13 @@ -import { findNodeOfType, traverseTree } from "../../common/tree.ts"; -import { parseMarkdown } from "../../syscall/silverbullet-syscall/markdown.ts"; -import { - readPage, - writePage, -} from "../../syscall/silverbullet-syscall/space.ts"; +import { findNodeOfType, traverseTree } from "$sb/lib/tree.ts"; +import { markdown, space } from "$sb/silverbullet-syscall/mod.ts"; import * as YAML from "yaml"; export async function readYamlPage( pageName: string, allowedLanguages = ["yaml"], ): Promise { - const { text } = await readPage(pageName); - let tree = await parseMarkdown(text); + const text = await space.readPage(pageName); + const tree = await markdown.parseMarkdown(text); let data: any = {}; traverseTree(tree, (t): boolean => { @@ -19,19 +15,19 @@ export async function readYamlPage( if (t.type !== "FencedCode") { return false; } - let codeInfoNode = findNodeOfType(t, "CodeInfo"); + const codeInfoNode = findNodeOfType(t, "CodeInfo"); if (!codeInfoNode) { return false; } if (!allowedLanguages.includes(codeInfoNode.children![0].text!)) { return false; } - let codeTextNode = findNodeOfType(t, "CodeText"); + const codeTextNode = findNodeOfType(t, "CodeText"); if (!codeTextNode) { // Honestly, this shouldn't happen return false; } - let codeText = codeTextNode.children![0].text!; + const codeText = codeTextNode.children![0].text!; try { data = YAML.parse(codeText); } catch (e: any) { @@ -49,5 +45,5 @@ export async function writeYamlPage( data: any, ): Promise { const text = YAML.stringify(data); - await writePage(pageName, "```yaml\n" + text + "\n```"); + await space.writePage(pageName, "```yaml\n" + text + "\n```"); } diff --git a/plug-api/plugos-syscall/asset.ts b/plug-api/plugos-syscall/asset.ts new file mode 100644 index 0000000..a709989 --- /dev/null +++ b/plug-api/plugos-syscall/asset.ts @@ -0,0 +1,15 @@ +import { base64Decode } from "../../plugos/asset_bundle/base64.ts"; +import { syscall } from "./syscall.ts"; + +export async function readAsset( + name: string, + encoding: "utf8" | "dataurl" = "utf8", +): Promise { + const data = await syscall("asset.readAsset", name); + switch (encoding) { + case "utf8": + return new TextDecoder().decode(base64Decode(data)); + case "dataurl": + return "data:application/octet-stream," + data; + } +} diff --git a/syscall/plugos-syscall/event.ts b/plug-api/plugos-syscall/event.ts similarity index 95% rename from syscall/plugos-syscall/event.ts rename to plug-api/plugos-syscall/event.ts index 6d50182..a2a3065 100644 --- a/syscall/plugos-syscall/event.ts +++ b/plug-api/plugos-syscall/event.ts @@ -1,6 +1,6 @@ import { syscall } from "./syscall.ts"; -export function dispatch( +export function dispatchEvent( eventName: string, data: any, timeout?: number, diff --git a/syscall/plugos-syscall/fs.ts b/plug-api/plugos-syscall/fs.ts similarity index 94% rename from syscall/plugos-syscall/fs.ts rename to plug-api/plugos-syscall/fs.ts index 6649a3c..6602e63 100644 --- a/syscall/plugos-syscall/fs.ts +++ b/plug-api/plugos-syscall/fs.ts @@ -8,7 +8,7 @@ export type FileMeta = { export function readFile( path: string, encoding: "utf8" | "dataurl" = "utf8", -): Promise<{ text: string; meta: FileMeta }> { +): Promise { return syscall("fs.readFile", path, encoding); } diff --git a/syscall/plugos-syscall/fulltext.ts b/plug-api/plugos-syscall/fulltext.ts similarity index 100% rename from syscall/plugos-syscall/fulltext.ts rename to plug-api/plugos-syscall/fulltext.ts diff --git a/plug-api/plugos-syscall/mod.ts b/plug-api/plugos-syscall/mod.ts new file mode 100644 index 0000000..cf1fa24 --- /dev/null +++ b/plug-api/plugos-syscall/mod.ts @@ -0,0 +1,8 @@ +export * as asset from "./asset.ts"; +export * as events from "./event.ts"; +export * as fs from "./fs.ts"; +export * as sandbox from "./sandbox.ts"; +export * as fulltext from "./fulltext.ts"; +export * as shell from "./shell.ts"; +export * as store from "./store.ts"; +export * from "./syscall.ts"; diff --git a/syscall/plugos-syscall/sandbox.ts b/plug-api/plugos-syscall/sandbox.ts similarity index 100% rename from syscall/plugos-syscall/sandbox.ts rename to plug-api/plugos-syscall/sandbox.ts diff --git a/syscall/plugos-syscall/shell.ts b/plug-api/plugos-syscall/shell.ts similarity index 100% rename from syscall/plugos-syscall/shell.ts rename to plug-api/plugos-syscall/shell.ts diff --git a/syscall/plugos-syscall/store.ts b/plug-api/plugos-syscall/store.ts similarity index 100% rename from syscall/plugos-syscall/store.ts rename to plug-api/plugos-syscall/store.ts diff --git a/syscall/plugos-syscall/syscall.ts b/plug-api/plugos-syscall/syscall.ts similarity index 100% rename from syscall/plugos-syscall/syscall.ts rename to plug-api/plugos-syscall/syscall.ts diff --git a/syscall/silverbullet-syscall/clientStore.ts b/plug-api/silverbullet-syscall/clientStore.ts similarity index 100% rename from syscall/silverbullet-syscall/clientStore.ts rename to plug-api/silverbullet-syscall/clientStore.ts diff --git a/syscall/silverbullet-syscall/editor.ts b/plug-api/silverbullet-syscall/editor.ts similarity index 79% rename from syscall/silverbullet-syscall/editor.ts rename to plug-api/silverbullet-syscall/editor.ts index fa68b4d..ebbb117 100644 --- a/syscall/silverbullet-syscall/editor.ts +++ b/plug-api/silverbullet-syscall/editor.ts @@ -114,43 +114,3 @@ export function prompt( export function enableReadOnlyMode(enabled: boolean) { return syscall("editor.enableReadOnlyMode", enabled); } - -// DEPRECATED in favor of showPanel and hidePanel - -export function showRhs( - html: string, - script?: string, - flex = 1, -): Promise { - return syscall("editor.showRhs", html, script, flex); -} - -export function hideRhs(): Promise { - return syscall("editor.hideRhs"); -} - -export function showLhs( - html: string, - script?: string, - flex = 1, -): Promise { - return syscall("editor.showLhs", html, script, flex); -} - -export function hideLhs(): Promise { - return syscall("editor.hideLhs"); -} - -export function showBhs( - html: string, - script?: string, - flex = 1, -): Promise { - return syscall("editor.showBhs", html, script, flex); -} - -export function hideBhs(): Promise { - return syscall("editor.hideBhs"); -} - -// End deprecation diff --git a/syscall/silverbullet-syscall/index.ts b/plug-api/silverbullet-syscall/index.ts similarity index 100% rename from syscall/silverbullet-syscall/index.ts rename to plug-api/silverbullet-syscall/index.ts diff --git a/syscall/silverbullet-syscall/markdown.ts b/plug-api/silverbullet-syscall/markdown.ts similarity index 74% rename from syscall/silverbullet-syscall/markdown.ts rename to plug-api/silverbullet-syscall/markdown.ts index 4894516..50642ff 100644 --- a/syscall/silverbullet-syscall/markdown.ts +++ b/plug-api/silverbullet-syscall/markdown.ts @@ -1,6 +1,6 @@ import { syscall } from "./syscall.ts"; -import type { ParseTree } from "../../common/tree.ts"; +import type { ParseTree } from "$sb/lib/tree.ts"; export function parseMarkdown(text: string): Promise { return syscall("markdown.parseMarkdown", text); diff --git a/plug-api/silverbullet-syscall/mod.ts b/plug-api/silverbullet-syscall/mod.ts new file mode 100644 index 0000000..e54f5e9 --- /dev/null +++ b/plug-api/silverbullet-syscall/mod.ts @@ -0,0 +1,7 @@ +export * as clientStore from "./clientStore.ts"; +export * as editor from "./editor.ts"; +export * as index from "./index.ts"; +export * as markdown from "./markdown.ts"; +export * as sandbox from "./sandbox.ts"; +export * as space from "./space.ts"; +export * as system from "./system.ts"; diff --git a/syscall/silverbullet-syscall/sandbox.ts b/plug-api/silverbullet-syscall/sandbox.ts similarity index 100% rename from syscall/silverbullet-syscall/sandbox.ts rename to plug-api/silverbullet-syscall/sandbox.ts diff --git a/syscall/silverbullet-syscall/space.ts b/plug-api/silverbullet-syscall/space.ts similarity index 93% rename from syscall/silverbullet-syscall/space.ts rename to plug-api/silverbullet-syscall/space.ts index 8daf921..2c1ddd0 100644 --- a/syscall/silverbullet-syscall/space.ts +++ b/plug-api/silverbullet-syscall/space.ts @@ -11,7 +11,7 @@ export function getPageMeta(name: string): Promise { export function readPage( name: string, -): Promise<{ text: string; meta: PageMeta }> { +): Promise { return syscall("space.readPage", name); } @@ -37,7 +37,7 @@ export function getAttachmentMeta(name: string): Promise { export function readAttachment( name: string, -): Promise<{ data: string; meta: AttachmentMeta }> { +): Promise { return syscall("space.readAttachment", name); } diff --git a/syscall/silverbullet-syscall/syscall.ts b/plug-api/silverbullet-syscall/syscall.ts similarity index 100% rename from syscall/silverbullet-syscall/syscall.ts rename to plug-api/silverbullet-syscall/syscall.ts diff --git a/syscall/silverbullet-syscall/system.ts b/plug-api/silverbullet-syscall/system.ts similarity index 100% rename from syscall/silverbullet-syscall/system.ts rename to plug-api/silverbullet-syscall/system.ts diff --git a/plugos/syscalls/fs.deno.ts b/plugos/syscalls/fs.deno.ts index 8d71cf8..eb2ad49 100644 --- a/plugos/syscalls/fs.deno.ts +++ b/plugos/syscalls/fs.deno.ts @@ -17,7 +17,7 @@ export default function fileSystemSyscalls(root = "/"): SysCallMapping { _ctx, filePath: string, encoding: "utf8" | "dataurl" = "utf8", - ): Promise<{ text: string; meta: FileMeta }> => { + ): Promise => { const p = resolvedPath(filePath); let text = ""; if (encoding === "utf8") { @@ -27,17 +27,7 @@ export default function fileSystemSyscalls(root = "/"): SysCallMapping { base64Encode(await Deno.readFile(p)) }`; } - const s = await Deno.stat(p); - return { - text, - meta: { - name: filePath, - lastModified: s.mtime!.getTime(), - contentType: mime.getType(filePath) || "application/octet-stream", - size: s.size, - perm: "rw", - }, - }; + return text; }, "fs.getFileMeta": async (_ctx, filePath: string): Promise => { const p = resolvedPath(filePath); diff --git a/plugs/core/anchor.ts b/plugs/core/anchor.ts index e154652..4af9120 100644 --- a/plugs/core/anchor.ts +++ b/plugs/core/anchor.ts @@ -1,44 +1,37 @@ -import { collectNodesOfType } from "../../common/tree.ts"; -import { - batchSet, - queryPrefix, -} from "../../syscall/silverbullet-syscall/index.ts"; -import { - getCurrentPage, - matchBefore, -} from "../../syscall/silverbullet-syscall/editor.ts"; -import type { IndexTreeEvent } from "../../web/app_event.ts"; -import { removeQueries } from "../query/util.ts"; +import { collectNodesOfType } from "$sb/lib/tree.ts"; +import { editor, index } from "$sb/silverbullet-syscall/mod.ts"; +import type { IndexTreeEvent } from "$sb/app_event.ts"; +import { removeQueries } from "$sb/lib/query.ts"; // Key space // a:pageName:anchorName => pos export async function indexAnchors({ name: pageName, tree }: IndexTreeEvent) { removeQueries(tree); - let anchors: { key: string; value: string }[] = []; + const anchors: { key: string; value: string }[] = []; collectNodesOfType(tree, "NamedAnchor").forEach((n) => { - let aName = n.children![0].text!; + const aName = n.children![0].text!; anchors.push({ key: `a:${pageName}:${aName}`, value: "" + n.from, }); }); console.log("Found", anchors.length, "anchors(s)"); - await batchSet(pageName, anchors); + await index.batchSet(pageName, anchors); } export async function anchorComplete() { - let prefix = await matchBefore("\\[\\[[^\\]@:]*@[\\w\\.\\-\\/]*"); + const prefix = await editor.matchBefore("\\[\\[[^\\]@:]*@[\\w\\.\\-\\/]*"); if (!prefix) { return null; } const [pageRefPrefix, anchorRef] = prefix.text.split("@"); let pageRef = pageRefPrefix.substring(2); if (!pageRef) { - pageRef = await getCurrentPage(); + pageRef = await editor.getCurrentPage(); } - let allAnchors = await queryPrefix(`a:${pageRef}:@${anchorRef}`); + const allAnchors = await index.queryPrefix(`a:${pageRef}:@${anchorRef}`); return { from: prefix.from + pageRefPrefix.length + 1, options: allAnchors.map((a) => ({ diff --git a/plugs/core/cloud.ts b/plugs/core/cloud.ts index 5e58b29..7acaf85 100644 --- a/plugs/core/cloud.ts +++ b/plugs/core/cloud.ts @@ -2,9 +2,9 @@ import type { FileData, FileEncoding, } from "../../common/spaces/space_primitives.ts"; -import { renderToText, replaceNodesMatching } from "../../common/tree.ts"; +import { renderToText, replaceNodesMatching } from "$sb/lib/tree.ts"; import type { FileMeta } from "../../common/types.ts"; -import { parseMarkdown } from "../../syscall/silverbullet-syscall/markdown.ts"; +import { parseMarkdown } from "$sb/silverbullet-syscall/markdown.ts"; const pagePrefix = "馃挱 "; @@ -55,7 +55,7 @@ async function translateLinksWithPrefix( text: string, prefix: string, ): Promise { - let tree = await parseMarkdown(text); + const tree = await parseMarkdown(text); replaceNodesMatching(tree, (tree) => { if (tree.type === "WikiLinkPage") { // Add the prefix in the link text @@ -67,12 +67,12 @@ async function translateLinksWithPrefix( return text; } -export async function getFileMetaCloud(name: string): Promise { - return { +export function getFileMetaCloud(name: string): Promise { + return Promise.resolve({ name, size: 0, contentType: "text/markdown", lastModified: 0, perm: "ro", - }; + }); } diff --git a/plugs/core/command.ts b/plugs/core/command.ts index e827d3a..82c5fe8 100644 --- a/plugs/core/command.ts +++ b/plugs/core/command.ts @@ -1,12 +1,11 @@ -import { matchBefore } from "../../syscall/silverbullet-syscall/editor.ts"; -import { listCommands } from "../../syscall/silverbullet-syscall/system.ts"; +import { editor, system } from "$sb/silverbullet-syscall/mod.ts"; export async function commandComplete() { - let prefix = await matchBefore("\\{\\[[^\\]]*"); + const prefix = await editor.matchBefore("\\{\\[[^\\]]*"); if (!prefix) { return null; } - let allCommands = await listCommands(); + const allCommands = await system.listCommands(); return { from: prefix.from + 2, diff --git a/plugs/core/core.plug.yaml b/plugs/core/core.plug.yaml index 9bd5454..75aa770 100644 --- a/plugs/core/core.plug.yaml +++ b/plugs/core/core.plug.yaml @@ -139,11 +139,11 @@ functions: # Full text search # searchIndex: - # path: ./search.ts:index + # path: ./search.ts:pageIndex # events: # - page:index # searchUnindex: - # path: "./search.ts:unindex" + # path: "./search.ts:pageUnindex" # env: server # events: # - page:deleted diff --git a/plugs/core/debug.ts b/plugs/core/debug.ts index a28ea35..806f0d6 100644 --- a/plugs/core/debug.ts +++ b/plugs/core/debug.ts @@ -1,24 +1,26 @@ -import { getLogs } from "../../syscall/plugos-syscall/sandbox.ts"; +import { sandbox } from "$sb/plugos-syscall/mod.ts"; import { - getText, - hidePanel, - showPanel, -} from "../../syscall/silverbullet-syscall/editor.ts"; -import { parseMarkdown } from "../../syscall/silverbullet-syscall/markdown.ts"; -import { getServerLogs } from "../../syscall/silverbullet-syscall/sandbox.ts"; + editor, + markdown, + sandbox as serverSandbox, +} from "$sb/silverbullet-syscall/mod.ts"; export async function parsePageCommand() { console.log( "AST", - JSON.stringify(await parseMarkdown(await getText()), null, 2), + JSON.stringify( + await markdown.parseMarkdown(await editor.getText()), + null, + 2, + ), ); } export async function showLogsCommand() { - let clientLogs = await getLogs(); - let serverLogs = await getServerLogs(); + const clientLogs = await sandbox.getLogs(); + const serverLogs = await serverSandbox.getServerLogs(); - await showPanel( + await editor.showPanel( "bhs", 1, ` @@ -83,5 +85,5 @@ export async function showLogsCommand() { } export async function hideBhsCommand() { - await hidePanel("bhs"); + await editor.hidePanel("bhs"); } diff --git a/plugs/core/editor.ts b/plugs/core/editor.ts index d68f000..3c9fb84 100644 --- a/plugs/core/editor.ts +++ b/plugs/core/editor.ts @@ -1,16 +1,15 @@ -import * as clientStore from "../../syscall/silverbullet-syscall/clientStore.ts"; -import { enableReadOnlyMode } from "../../syscall/silverbullet-syscall/editor.ts"; +import { clientStore, editor } from "$sb/silverbullet-syscall/mod.ts"; export async function editorLoad() { - let readOnlyMode = await clientStore.get("readOnlyMode"); + const readOnlyMode = await clientStore.get("readOnlyMode"); if (readOnlyMode) { - await enableReadOnlyMode(true); + await editor.enableReadOnlyMode(true); } } export async function toggleReadOnlyMode() { let readOnlyMode = await clientStore.get("readOnlyMode"); readOnlyMode = !readOnlyMode; - await enableReadOnlyMode(readOnlyMode); + await editor.enableReadOnlyMode(readOnlyMode); await clientStore.set("readOnlyMode", readOnlyMode); } diff --git a/plugs/core/item.ts b/plugs/core/item.ts index 984e5be..a5aa6c8 100644 --- a/plugs/core/item.ts +++ b/plugs/core/item.ts @@ -1,16 +1,8 @@ -import type { IndexTreeEvent } from "../../web/app_event.ts"; +import type { IndexTreeEvent, QueryProviderEvent } from "$sb/app_event.ts"; -import { - batchSet, - queryPrefix, -} from "../../syscall/silverbullet-syscall/index.ts"; -import { - collectNodesOfType, - ParseTree, - renderToText, -} from "../../common/tree.ts"; -import { removeQueries } from "../query/util.ts"; -import { applyQuery, QueryProviderEvent } from "../query/engine.ts"; +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"; export type Item = { name: string; @@ -22,12 +14,12 @@ export type Item = { }; export async function indexItems({ name, tree }: IndexTreeEvent) { - let items: { key: string; value: Item }[] = []; + const items: { key: string; value: Item }[] = []; removeQueries(tree); console.log("Indexing items", name); - let coll = collectNodesOfType(tree, "ListItem"); + const coll = collectNodesOfType(tree, "ListItem"); coll.forEach((n) => { if (!n.children) { @@ -38,9 +30,9 @@ export async function indexItems({ name, tree }: IndexTreeEvent) { return; } - let textNodes: ParseTree[] = []; + const textNodes: ParseTree[] = []; let nested: string | undefined; - for (let child of n.children!.slice(1)) { + for (const child of n.children!.slice(1)) { if (child.type === "OrderedList" || child.type === "BulletList") { nested = renderToText(child); break; @@ -48,8 +40,8 @@ export async function indexItems({ name, tree }: IndexTreeEvent) { textNodes.push(child); } - let itemText = textNodes.map(renderToText).join("").trim(); - let item: Item = { + const itemText = textNodes.map(renderToText).join("").trim(); + const item: Item = { name: itemText, }; if (nested) { @@ -68,15 +60,15 @@ export async function indexItems({ name, tree }: IndexTreeEvent) { }); }); console.log("Found", items.length, "item(s)"); - await batchSet(name, items); + await index.batchSet(name, items); } export async function queryProvider({ query, }: QueryProviderEvent): Promise { - let allItems: Item[] = []; - for (let { key, page, value } of await queryPrefix("it:")) { - let [, pos] = key.split(":"); + const allItems: Item[] = []; + for (const { key, page, value } of await index.queryPrefix("it:")) { + const [, pos] = key.split(":"); allItems.push({ ...value, page: page, diff --git a/plugs/core/link.ts b/plugs/core/link.ts index 306128d..506e262 100644 --- a/plugs/core/link.ts +++ b/plugs/core/link.ts @@ -1,14 +1,6 @@ -import { nodeAtPos } from "../../common/tree.ts"; -import { - filterBox, - flashNotification, - getCursor, - getText, - replaceRange, -} from "../../syscall/silverbullet-syscall/editor.ts"; -import { parseMarkdown } from "../../syscall/silverbullet-syscall/markdown.ts"; -import { dispatch as dispatchEvent } from "../../syscall/plugos-syscall/event.ts"; -import { invokeFunction } from "../../syscall/silverbullet-syscall/system.ts"; +import { nodeAtPos } from "$sb/lib/tree.ts"; +import { editor, markdown, system } from "$sb/silverbullet-syscall/mod.ts"; +import { events } from "$sb/plugos-syscall/mod.ts"; type UnfurlOption = { id: string; @@ -16,16 +8,16 @@ type UnfurlOption = { }; export async function unfurlCommand() { - let mdTree = await parseMarkdown(await getText()); - let nakedUrlNode = nodeAtPos(mdTree, await getCursor()); - let url = nakedUrlNode!.children![0].text!; + const mdTree = await markdown.parseMarkdown(await editor.getText()); + const nakedUrlNode = nodeAtPos(mdTree, await editor.getCursor()); + const url = nakedUrlNode!.children![0].text!; console.log("Got URL to unfurl", url); - let optionResponses = await dispatchEvent("unfurl:options", url); - let options: UnfurlOption[] = []; - for (let resp of optionResponses) { + const optionResponses = await events.dispatchEvent("unfurl:options", url); + const options: UnfurlOption[] = []; + for (const resp of optionResponses) { options.push(...resp); } - let selectedUnfurl: any = await filterBox( + const selectedUnfurl: any = await editor.filterBox( "Unfurl", options, "Select the unfurl strategy of your choice", @@ -34,19 +26,23 @@ export async function unfurlCommand() { return; } try { - let replacement = await invokeFunction( + const replacement = await system.invokeFunction( "server", "unfurlExec", selectedUnfurl.id, url, ); - await replaceRange(nakedUrlNode?.from!, nakedUrlNode?.to!, replacement); + await editor.replaceRange( + nakedUrlNode?.from!, + nakedUrlNode?.to!, + replacement, + ); } catch (e: any) { - await flashNotification(e.message, "error"); + await editor.flashNotification(e.message, "error"); } } -export async function titleUnfurlOptions(url: string): Promise { +export function titleUnfurlOptions(): UnfurlOption[] { return [ { id: "title-unfurl", @@ -57,7 +53,7 @@ export async function titleUnfurlOptions(url: string): Promise { // Run on the server because plugs will likely rely on fetch for this export async function unfurlExec(id: string, url: string): Promise { - let replacement = await dispatchEvent(`unfurl:${id}`, url); + const replacement = await events.dispatchEvent(`unfurl:${id}`, url); if (replacement.length === 0) { throw new Error("Unfurl failed"); } else { @@ -68,13 +64,13 @@ export async function unfurlExec(id: string, url: string): Promise { const titleRegex = /]*>\s*([^<]+)\s*<\/title\s*>/i; export async function titleUnfurl(url: string): Promise { - let response = await fetch(url); + const response = await fetch(url); if (response.status < 200 || response.status >= 300) { console.error("Unfurl failed", await response.text()); throw new Error(`Failed to fetch: ${await response.statusText}`); } - let body = await response.text(); - let match = titleRegex.exec(body); + const body = await response.text(); + const match = titleRegex.exec(body); if (match) { return `[${match[1]}](${url})`; } else { diff --git a/plugs/core/navigate.ts b/plugs/core/navigate.ts index 742e123..8eb32b0 100644 --- a/plugs/core/navigate.ts +++ b/plugs/core/navigate.ts @@ -1,15 +1,6 @@ -import type { ClickEvent } from "../../web/app_event.ts"; -import { - flashNotification, - getCurrentPage, - getCursor, - getText, - navigate as navigateTo, - openUrl, -} from "../../syscall/silverbullet-syscall/editor.ts"; -import { parseMarkdown } from "../../syscall/silverbullet-syscall/markdown.ts"; -import { nodeAtPos, ParseTree } from "../../common/tree.ts"; -import { invokeCommand } from "../../syscall/silverbullet-syscall/system.ts"; +import type { ClickEvent } from "$sb/app_event.ts"; +import { editor, markdown, system } from "$sb/silverbullet-syscall/mod.ts"; +import { nodeAtPos, ParseTree } from "$sb/lib/tree.ts"; // Checks if the URL contains a protocol, if so keeps it, otherwise assumes an attachment function patchUrl(url: string): string { @@ -35,21 +26,21 @@ async function actionClickOrActionEnter(mdTree: ParseTree | null) { } } if (!pageLink) { - pageLink = await getCurrentPage(); + pageLink = await editor.getCurrentPage(); } - await navigateTo(pageLink, pos); + await editor.navigate(pageLink, pos); break; } case "URL": case "NakedURL": - await openUrl(patchUrl(mdTree.children![0].text!)); + await editor.openUrl(patchUrl(mdTree.children![0].text!)); break; case "Link": { const url = patchUrl(mdTree.children![4].children![0].text!); if (url.length <= 1) { - return flashNotification("Empty link, ignoring", "error"); + return editor.flashNotification("Empty link, ignoring", "error"); } - await openUrl(url); + await editor.openUrl(url); break; } case "CommandLink": { @@ -57,15 +48,15 @@ async function actionClickOrActionEnter(mdTree: ParseTree | null) { .children![0].text!.substring(2, mdTree.children![0].text!.length - 2) .trim(); console.log("Got command link", command); - await invokeCommand(command); + await system.invokeCommand(command); break; } } } export async function linkNavigate() { - const mdTree = await parseMarkdown(await getText()); - const newNode = nodeAtPos(mdTree, await getCursor()); + const mdTree = await markdown.parseMarkdown(await editor.getText()); + const newNode = nodeAtPos(mdTree, await editor.getCursor()); await actionClickOrActionEnter(newNode); } @@ -74,11 +65,11 @@ export async function clickNavigate(event: ClickEvent) { if (event.ctrlKey || event.metaKey) { return; } - const mdTree = await parseMarkdown(await getText()); + const mdTree = await markdown.parseMarkdown(await editor.getText()); const newNode = nodeAtPos(mdTree, event.pos); await actionClickOrActionEnter(newNode); } export async function navigateCommand(cmdDef: any) { - await navigateTo(cmdDef.page); + await editor.navigate(cmdDef.page); } diff --git a/plugs/core/page.ts b/plugs/core/page.ts index 282a6c9..00115ae 100644 --- a/plugs/core/page.ts +++ b/plugs/core/page.ts @@ -1,39 +1,26 @@ -import type { IndexEvent, IndexTreeEvent } from "../../web/app_event.ts"; +import type { + IndexEvent, + IndexTreeEvent, + QueryProviderEvent, +} from "$sb/app_event.ts"; import { - batchSet, - clearPageIndex as clearPageIndexSyscall, - clearPageIndexForPage, - queryPrefix, - set, -} from "../../syscall/silverbullet-syscall/index.ts"; + editor, + index, + markdown, + space, + system, +} from "$sb/silverbullet-syscall/mod.ts"; -import { - flashNotification, - getCurrentPage, - getCursor, - getText, - matchBefore, - navigate, - prompt, -} from "../../syscall/silverbullet-syscall/editor.ts"; +import { events, store } from "$sb/plugos-syscall/mod.ts"; -import { dispatch } from "../../syscall/plugos-syscall/event.ts"; -import { - deletePage as deletePageSyscall, - listPages, - readPage, - writePage, -} from "../../syscall/silverbullet-syscall/space.ts"; -import { invokeFunction } from "../../syscall/silverbullet-syscall/system.ts"; -import { parseMarkdown } from "../../syscall/silverbullet-syscall/markdown.ts"; import { addParentPointers, collectNodesMatching, ParseTree, renderToText, replaceNodesMatching, -} from "../../common/tree.ts"; -import { applyQuery, QueryProviderEvent } from "../query/engine.ts"; +} from "$sb/lib/tree.ts"; +import { applyQuery } from "$sb/lib/query.ts"; import { extractMeta } from "../query/data.ts"; // Key space: @@ -41,19 +28,19 @@ import { extractMeta } from "../query/data.ts"; // meta => metaJson export async function indexLinks({ name, tree }: IndexTreeEvent) { - let backLinks: { key: string; value: string }[] = []; + const backLinks: { key: string; value: string }[] = []; // [[Style Links]] console.log("Now indexing", name); - let pageMeta = extractMeta(tree); + const pageMeta = extractMeta(tree); if (Object.keys(pageMeta).length > 0) { console.log("Extracted page meta data", pageMeta); // Don't index meta data starting with $ - for (let key in pageMeta) { + for (const key in pageMeta) { if (key.startsWith("$")) { delete pageMeta[key]; } } - await set(name, "meta:", pageMeta); + await index.set(name, "meta:", pageMeta); } collectNodesMatching(tree, (n) => n.type === "WikiLinkPage").forEach((n) => { @@ -67,18 +54,18 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) { }); }); console.log("Found", backLinks.length, "wiki link(s)"); - await batchSet(name, backLinks); + await index.batchSet(name, backLinks); } export async function pageQueryProvider({ query, }: QueryProviderEvent): Promise { - let allPages = await listPages(); - let allPageMap: Map = new Map( + let allPages = await space.listPages(); + const allPageMap: Map = new Map( allPages.map((pm) => [pm.name, pm]), ); - for (let { page, value } of await queryPrefix("meta:")) { - let p = allPageMap.get(page); + for (const { page, value } of await index.queryPrefix("meta:")) { + const p = allPageMap.get(page); if (p) { for (let [k, v] of Object.entries(value)) { p[k] = v; @@ -93,8 +80,10 @@ export async function linkQueryProvider({ query, pageName, }: QueryProviderEvent): Promise { - let links: any[] = []; - for (let { value: name, key } of await queryPrefix(`pl:${pageName}:`)) { + const links: any[] = []; + for ( + const { value: name, key } of await index.queryPrefix(`pl:${pageName}:`) + ) { const [, , pos] = key.split(":"); // Key: pl:page:pos links.push({ name, pos }); } @@ -102,18 +91,18 @@ export async function linkQueryProvider({ } export async function deletePage() { - let pageName = await getCurrentPage(); + const pageName = await editor.getCurrentPage(); console.log("Navigating to index page"); - await navigate(""); + await editor.navigate(""); console.log("Deleting page from space"); - await deletePageSyscall(pageName); + await space.deletePage(pageName); } export async function renamePage() { - const oldName = await getCurrentPage(); - const cursor = await getCursor(); + const oldName = await editor.getCurrentPage(); + const cursor = await editor.getCursor(); console.log("Old name is", oldName); - const newName = await prompt(`Rename ${oldName} to:`, oldName); + const newName = await editor.prompt(`Rename ${oldName} to:`, oldName); if (!newName) { return; } @@ -123,45 +112,45 @@ export async function renamePage() { } console.log("New name", newName); - let pagesToUpdate = await getBackLinks(oldName); + const pagesToUpdate = await getBackLinks(oldName); console.log("All pages containing backlinks", pagesToUpdate); - let text = await getText(); + const text = await editor.getText(); console.log("Writing new page to space"); - await writePage(newName, text); + await space.writePage(newName, text); console.log("Navigating to new page"); - await navigate(newName, cursor, true); + await editor.navigate(newName, cursor, true); console.log("Deleting page from space"); - await deletePageSyscall(oldName); + await space.deletePage(oldName); - let pageToUpdateSet = new Set(); - for (let pageToUpdate of pagesToUpdate) { + const pageToUpdateSet = new Set(); + for (const pageToUpdate of pagesToUpdate) { pageToUpdateSet.add(pageToUpdate.page); } - for (let pageToUpdate of pageToUpdateSet) { + for (const pageToUpdate of pageToUpdateSet) { if (pageToUpdate === oldName) { continue; } console.log("Now going to update links in", pageToUpdate); - let { text } = await readPage(pageToUpdate); + const text = await space.readPage(pageToUpdate); // console.log("Received text", text); if (!text) { // Page likely does not exist, but at least we can skip it continue; } - let mdTree = await parseMarkdown(text); + const mdTree = await markdown.parseMarkdown(text); addParentPointers(mdTree); replaceNodesMatching(mdTree, (n): ParseTree | undefined | null => { if (n.type === "WikiLinkPage") { - let pageName = n.children![0].text!; + const pageName = n.children![0].text!; if (pageName === oldName) { n.children![0].text = newName; return n; } // page name with @pos position if (pageName.startsWith(`${oldName}@`)) { - let [, pos] = pageName.split("@"); + const [, pos] = pageName.split("@"); n.children![0].text = `${newName}@${pos}`; return n; } @@ -169,10 +158,10 @@ export async function renamePage() { return; }); // let newText = text.replaceAll(`[[${oldName}]]`, `[[${newName}]]`); - let newText = renderToText(mdTree); + const newText = renderToText(mdTree); if (text !== newText) { console.log("Changes made, saving..."); - await writePage(pageToUpdate, newText); + await space.writePage(pageToUpdate, newText); } } } @@ -183,10 +172,10 @@ type BackLink = { }; async function getBackLinks(pageName: string): Promise { - let allBackLinks = await queryPrefix(`pl:${pageName}:`); - let pagesToUpdate: BackLink[] = []; - for (let { key, value } of allBackLinks) { - let keyParts = key.split(":"); + const allBackLinks = await index.queryPrefix(`pl:${pageName}:`); + const pagesToUpdate: BackLink[] = []; + for (const { key, value } of allBackLinks) { + const keyParts = key.split(":"); pagesToUpdate.push({ page: value, pos: +keyParts[keyParts.length - 1], @@ -196,18 +185,18 @@ async function getBackLinks(pageName: string): Promise { } export async function reindexCommand() { - await flashNotification("Reindexing..."); - await invokeFunction("server", "reindexSpace"); - await flashNotification("Reindexing done"); + await editor.flashNotification("Reindexing..."); + await system.invokeFunction("server", "reindexSpace"); + await editor.flashNotification("Reindexing done"); } // Completion export async function pageComplete() { - let prefix = await matchBefore("\\[\\[[^\\]@:]*"); + const prefix = await editor.matchBefore("\\[\\[[^\\]@:]*"); if (!prefix) { return null; } - let allPages = await listPages(); + const allPages = await space.listPages(); return { from: prefix.from + 2, options: allPages.map((pageMeta) => ({ @@ -220,14 +209,14 @@ export async function pageComplete() { // Server functions export async function reindexSpace() { console.log("Clearing page index..."); - await clearPageIndexSyscall(); + await index.clearPageIndex(); console.log("Listing all pages"); - let pages = await listPages(); - for (let { name } of pages) { + const pages = await space.listPages(); + for (const { name } of pages) { console.log("Indexing", name); - const { text } = await readPage(name); - let parsed = await parseMarkdown(text); - await dispatch("page:index", { + const text = await space.readPage(name); + const parsed = await markdown.parseMarkdown(text); + await events.dispatchEvent("page:index", { name, tree: parsed, }); @@ -237,12 +226,12 @@ export async function reindexSpace() { export async function clearPageIndex(page: string) { console.log("Clearing page index for page", page); - await clearPageIndexForPage(page); + await index.clearPageIndexForPage(page); } export async function parseIndexTextRepublish({ name, text }: IndexEvent) { - await dispatch("page:index", { + await events.dispatchEvent("page:index", { name, - tree: await parseMarkdown(text), + tree: await markdown.parseMarkdown(text), }); } diff --git a/plugs/core/plugmanager.ts b/plugs/core/plugmanager.ts index 4fee935..ef458b9 100644 --- a/plugs/core/plugmanager.ts +++ b/plugs/core/plugmanager.ts @@ -1,30 +1,18 @@ -import { dispatch } from "../../syscall/plugos-syscall/event.ts"; -import { Manifest } from "../../common/manifest.ts"; -import { - flashNotification, - save, -} from "../../syscall/silverbullet-syscall/editor.ts"; -import { - deleteAttachment, - listPlugs, - writeAttachment, -} from "../../syscall/silverbullet-syscall/space.ts"; -import { - invokeFunction, - reloadPlugs, -} from "../../syscall/silverbullet-syscall/system.ts"; +import { events } from "$sb/plugos-syscall/mod.ts"; +import type { Manifest } from "../../common/manifest.ts"; +import { editor, space, system } from "$sb/silverbullet-syscall/mod.ts"; -import { readYamlPage } from "../lib/yaml_page.ts"; +import { readYamlPage } from "$sb/lib/yaml_page.ts"; export async function updatePlugsCommand() { - await save(); - flashNotification("Updating plugs..."); + await editor.save(); + await editor.flashNotification("Updating plugs..."); try { - await invokeFunction("server", "updatePlugs"); - flashNotification("And... done!"); - await reloadPlugs(); + await system.invokeFunction("server", "updatePlugs"); + await editor.flashNotification("And... done!"); + system.reloadPlugs(); } catch (e: any) { - flashNotification("Error updating plugs: " + e.message, "error"); + editor.flashNotification("Error updating plugs: " + e.message, "error"); } } @@ -42,18 +30,21 @@ export async function updatePlugs() { throw new Error(`Error processing PLUGS: ${e.message}`); } console.log("Plug YAML", plugList); - let allPlugNames: string[] = []; - for (let plugUri of plugList) { - let [protocol, ...rest] = plugUri.split(":"); - let manifests = await dispatch(`get-plug:${protocol}`, rest.join(":")); + const allPlugNames: string[] = []; + for (const plugUri of plugList) { + const [protocol, ...rest] = plugUri.split(":"); + const manifests = await events.dispatchEvent( + `get-plug:${protocol}`, + rest.join(":"), + ); if (manifests.length === 0) { console.error("Could not resolve plug", plugUri); } // console.log("Got manifests", plugUri, protocol, manifests); - let manifest = manifests[0]; + const manifest = manifests[0]; allPlugNames.push(manifest.name); // console.log("Writing", `_plug/${manifest.name}`); - await writeAttachment( + await space.writeAttachment( `_plug/${manifest.name}.plug.json`, "string", JSON.stringify(manifest), @@ -61,34 +52,32 @@ export async function updatePlugs() { } // And delete extra ones - for (let existingPlug of await listPlugs()) { - let plugName = existingPlug.substring( + for (const existingPlug of await space.listPlugs()) { + const plugName = existingPlug.substring( "_plug/".length, existingPlug.length - ".plug.json".length, ); console.log("Considering", plugName); if (!allPlugNames.includes(plugName)) { console.log("Removing plug", plugName); - await deleteAttachment(existingPlug); + await space.deleteAttachment(existingPlug); } } - await reloadPlugs(); + await system.reloadPlugs(); } export async function getPlugHTTPS(url: string): Promise { - let fullUrl = `https:${url}`; + const fullUrl = `https:${url}`; console.log("Now fetching plug manifest from", fullUrl); - let req = await fetch(fullUrl); + const req = await fetch(fullUrl); if (req.status !== 200) { throw new Error(`Could not fetch plug manifest from ${fullUrl}`); } - let json = await req.json(); - - return json; + return req.json(); } -export async function getPlugGithub(identifier: string): Promise { - let [owner, repo, path] = identifier.split("/"); +export function getPlugGithub(identifier: string): Promise { + const [owner, repo, path] = identifier.split("/"); let [repoClean, branch] = repo.split("@"); if (!branch) { branch = "main"; // or "master"? diff --git a/plugs/core/search.ts b/plugs/core/search.ts index 214c744..a8d1550 100644 --- a/plugs/core/search.ts +++ b/plugs/core/search.ts @@ -1,42 +1,36 @@ -import { - fullTextDelete, - fullTextIndex, - fullTextSearch, -} 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"; +import { fulltext } from "$sb/plugos-syscall/mod.ts"; +import { renderToText } from "$sb/lib/tree.ts"; +import type { PageMeta } from "../../common/types.ts"; +import { editor, index } from "$sb/silverbullet-syscall/mod.ts"; +import { IndexTreeEvent, QueryProviderEvent } from "$sb/app_event.ts"; +import { applyQuery, removeQueries } from "$sb/lib/query.ts"; const searchPrefix = "馃攳 "; -export async function index(data: IndexTreeEvent) { +export async function pageIndex(data: IndexTreeEvent) { removeQueries(data.tree); - let cleanText = renderToText(data.tree); - await fullTextIndex(data.name, cleanText); + const cleanText = renderToText(data.tree); + await fulltext.fullTextIndex(data.name, cleanText); } -export async function unindex(pageName: string) { - await fullTextDelete(pageName); +export async function pageUnindex(pageName: string) { + await fulltext.fullTextDelete(pageName); } export async function queryProvider({ query, }: QueryProviderEvent): Promise { - let phraseFilter = query.filter.find((f) => f.prop === "phrase"); + const 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); + let results = await fulltext.fullTextSearch(phraseFilter.value, 100); - let allPageMap: Map = new Map( + const allPageMap: Map = new Map( results.map((r: any) => [r.name, r]), ); - for (let { page, value } of await queryPrefix("meta:")) { - let p = allPageMap.get(page); + for (const { page, value } of await index.queryPrefix("meta:")) { + const p = allPageMap.get(page); if (p) { for (let [k, v] of Object.entries(value)) { p[k] = v; @@ -52,17 +46,17 @@ export async function queryProvider({ } export async function searchCommand() { - let phrase = await prompt("Search for: "); + const phrase = await prompt("Search for: "); if (phrase) { - await navigate(`${searchPrefix}${phrase}`); + await editor.navigate(`${searchPrefix}${phrase}`); } } export async function readPageSearch( name: string, ): Promise<{ text: string; meta: PageMeta }> { - let phrase = name.substring(searchPrefix.length); - let results = await fullTextSearch(phrase, 100); + const phrase = name.substring(searchPrefix.length); + const results = await fulltext.fullTextSearch(phrase, 100); const text = `# Search results for "${phrase}"\n${ results .map((r: any) => `* [[${r.name}]] (score: ${r.rank})`) @@ -79,7 +73,7 @@ export async function readPageSearch( }; } -export async function getPageMetaSearch(name: string): Promise { +export function getPageMetaSearch(name: string): PageMeta { return { name, lastModified: 0, diff --git a/plugs/core/stats.ts b/plugs/core/stats.ts index 0cbd3c3..fb56176 100644 --- a/plugs/core/stats.ts +++ b/plugs/core/stats.ts @@ -1,8 +1,4 @@ -import { - flashNotification, - getText, -} from "../../syscall/silverbullet-syscall/editor.ts"; -import { listPages } from "../../syscall/silverbullet-syscall/space.ts"; +import { editor, space } from "$sb/silverbullet-syscall/mod.ts"; function countWords(str: string): number { const matches = str.match(/[\w\d\'-]+/gi); @@ -15,11 +11,11 @@ function readingTime(wordCount: number): number { } export async function statsCommand() { - const text = await getText(); - const allPages = await listPages(); + const text = await editor.getText(); + const allPages = await space.listPages(); const wordCount = countWords(text); const time = readingTime(wordCount); - await flashNotification( + await editor.flashNotification( `${wordCount} words; ${time} minutes read; ${allPages.length} total pages in space.`, ); } diff --git a/plugs/core/tags.ts b/plugs/core/tags.ts index dd97c2b..e23e322 100644 --- a/plugs/core/tags.ts +++ b/plugs/core/tags.ts @@ -1,35 +1,30 @@ -import { collectNodesOfType } from "../../common/tree.ts"; -import { - batchSet, - queryPrefix, -} from "../../syscall/silverbullet-syscall/index.ts"; -import { matchBefore } from "../../syscall/silverbullet-syscall/editor.ts"; -import type { IndexTreeEvent } from "../../web/app_event.ts"; -import { applyQuery, QueryProviderEvent } from "../query/engine.ts"; -import { removeQueries } from "../query/util.ts"; +import { collectNodesOfType } from "$sb/lib/tree.ts"; +import { editor, index } from "$sb/silverbullet-syscall/mod.ts"; +import type { IndexTreeEvent, QueryProviderEvent } from "$sb/app_event.ts"; +import { applyQuery, removeQueries } from "$sb/lib/query.ts"; // Key space // tag:TAG => true (for completion) export async function indexTags({ name, tree }: IndexTreeEvent) { removeQueries(tree); - let allTags = new Set(); + const allTags = new Set(); collectNodesOfType(tree, "Hashtag").forEach((n) => { allTags.add(n.children![0].text!); }); - batchSet( + await index.batchSet( name, [...allTags].map((t) => ({ key: `tag:${t}`, value: t })), ); } export async function tagComplete() { - let prefix = await matchBefore("#[^#\\s]+"); + const prefix = await editor.matchBefore("#[^#\\s]+"); // console.log("Running tag complete", prefix); if (!prefix) { return null; } - let allTags = await queryPrefix(`tag:${prefix.text}`); + const allTags = await index.queryPrefix(`tag:${prefix.text}`); return { from: prefix.from, options: allTags.map((tag) => ({ @@ -45,8 +40,8 @@ type Tag = { }; export async function tagProvider({ query }: QueryProviderEvent) { - let allTags = new Map(); - for (let { value } of await queryPrefix("tag:")) { + const allTags = new Map(); + for (const { value } of await index.queryPrefix("tag:")) { let currentFreq = allTags.get(value); if (!currentFreq) { currentFreq = 0; diff --git a/plugs/core/template.ts b/plugs/core/template.ts index 92b78f9..7f3f601 100644 --- a/plugs/core/template.ts +++ b/plugs/core/template.ts @@ -1,31 +1,16 @@ -import { - getPageMeta, - listPages, - readPage, - writePage, -} from "$sb/silverbullet-syscall/space.ts"; -import { - filterBox, - getCurrentPage, - getCursor, - insertAtCursor, - moveCursor, - navigate, - prompt, -} from "../../syscall/silverbullet-syscall/editor.ts"; -import { parseMarkdown } from "../../syscall/silverbullet-syscall/markdown.ts"; +import { editor, markdown, space } from "$sb/silverbullet-syscall/mod.ts"; import { extractMeta } from "../query/data.ts"; -import { renderToText } from "../../common/tree.ts"; -import { niceDate } from "./dates.ts"; -import { readSettings } from "../lib/settings_page.ts"; +import { renderToText } from "$sb/lib/tree.ts"; +import { niceDate } from "$sb/lib/dates.ts"; +import { readSettings } from "$sb/lib/settings_page.ts"; export async function instantiateTemplateCommand() { - const allPages = await listPages(); + const allPages = await space.listPages(); const { pageTemplatePrefix } = await readSettings({ pageTemplatePrefix: "template/page/", }); - const selectedTemplate = await filterBox( + const selectedTemplate = await editor.filterBox( "Template", allPages .filter((pageMeta) => pageMeta.name.startsWith(pageTemplatePrefix)) @@ -41,40 +26,43 @@ export async function instantiateTemplateCommand() { } console.log("Selected template", selectedTemplate); - const { text } = await readPage( + const text = await space.readPage( `${pageTemplatePrefix}${selectedTemplate.name}`, ); - const parseTree = await parseMarkdown(text); + const parseTree = await markdown.parseMarkdown(text); const additionalPageMeta = extractMeta(parseTree, [ "$name", "$disableDirectives", ]); - const pageName = await prompt("Name of new page", additionalPageMeta.$name); + const pageName = await editor.prompt( + "Name of new page", + additionalPageMeta.$name, + ); if (!pageName) { return; } const pageText = replaceTemplateVars(renderToText(parseTree), pageName); - await writePage(pageName, pageText); - await navigate(pageName); + await space.writePage(pageName, pageText); + await editor.navigate(pageName); } export async function insertSnippet() { - let allPages = await listPages(); - let { snippetPrefix } = await readSettings({ + const allPages = await space.listPages(); + const { snippetPrefix } = await readSettings({ snippetPrefix: "snippet/", }); - let cursorPos = await getCursor(); - let page = await getCurrentPage(); - let allSnippets = allPages + const cursorPos = await editor.getCursor(); + const page = await editor.getCurrentPage(); + const allSnippets = allPages .filter((pageMeta) => pageMeta.name.startsWith(snippetPrefix)) .map((pageMeta) => ({ ...pageMeta, name: pageMeta.name.slice(snippetPrefix.length), })); - let selectedSnippet = await filterBox( + const selectedSnippet = await editor.filterBox( "Snippet", allSnippets, `Select the snippet to insert (listing any page starting with ${snippetPrefix})`, @@ -83,15 +71,15 @@ export async function insertSnippet() { if (!selectedSnippet) { return; } - let { text } = await readPage(`${snippetPrefix}${selectedSnippet.name}`); + const text = await space.readPage(`${snippetPrefix}${selectedSnippet.name}`); let templateText = replaceTemplateVars(text, page); - let carretPos = templateText.indexOf("|^|"); + const carretPos = templateText.indexOf("|^|"); templateText = templateText.replace("|^|", ""); templateText = replaceTemplateVars(templateText, page); - await insertAtCursor(templateText); + await editor.insertAtCursor(templateText); if (carretPos !== -1) { - await moveCursor(cursorPos + carretPos); + await editor.moveCursor(cursorPos + carretPos); } } @@ -101,18 +89,22 @@ export function replaceTemplateVars(s: string, pageName: string): string { switch (v) { case "today": return niceDate(new Date()); - case "tomorrow": - let tomorrow = new Date(); + case "tomorrow": { + const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); return niceDate(tomorrow); - case "yesterday": - let yesterday = new Date(); + } + + case "yesterday": { + const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); return niceDate(yesterday); - case "lastWeek": - let lastWeek = new Date(); + } + case "lastWeek": { + const lastWeek = new Date(); lastWeek.setDate(lastWeek.getDate() - 7); return niceDate(lastWeek); + } case "page": return pageName; } @@ -121,55 +113,55 @@ export function replaceTemplateVars(s: string, pageName: string): string { } export async function quickNoteCommand() { - let { quickNotePrefix } = await readSettings({ + const { quickNotePrefix } = await readSettings({ quickNotePrefix: "馃摜 ", }); - let isoDate = new Date().toISOString(); + const isoDate = new Date().toISOString(); let [date, time] = isoDate.split("T"); time = time.split(".")[0]; - let pageName = `${quickNotePrefix}${date} ${time}`; - await navigate(pageName); + const pageName = `${quickNotePrefix}${date} ${time}`; + await editor.navigate(pageName); } export async function dailyNoteCommand() { - let { dailyNoteTemplate, dailyNotePrefix } = await readSettings({ + const { dailyNoteTemplate, dailyNotePrefix } = await readSettings({ dailyNoteTemplate: "template/page/Daily Note", dailyNotePrefix: "馃搮 ", }); let dailyNoteTemplateText = ""; try { - let { text } = await readPage(dailyNoteTemplate); + const text = await space.readPage(dailyNoteTemplate); dailyNoteTemplateText = text; } catch { console.warn(`No daily note template found at ${dailyNoteTemplate}`); } - let date = niceDate(new Date()); - let pageName = `${dailyNotePrefix}${date}`; + const date = niceDate(new Date()); + const pageName = `${dailyNotePrefix}${date}`; if (dailyNoteTemplateText) { try { - await getPageMeta(pageName); + await space.getPageMeta(pageName); } catch { // Doesn't exist, let's create - await writePage( + await space.writePage( pageName, replaceTemplateVars(dailyNoteTemplateText, pageName), ); } - await navigate(pageName); + await editor.navigate(pageName); } else { - await navigate(pageName); + await editor.navigate(pageName); } } export async function insertTemplateText(cmdDef: any) { - let cursorPos = await getCursor(); - let page = await getCurrentPage(); + const cursorPos = await editor.getCursor(); + const page = await editor.getCurrentPage(); let templateText: string = cmdDef.value; - let carretPos = templateText.indexOf("|^|"); + const carretPos = templateText.indexOf("|^|"); templateText = templateText.replace("|^|", ""); templateText = replaceTemplateVars(templateText, page); - await insertAtCursor(templateText); + await editor.insertAtCursor(templateText); if (carretPos !== -1) { - await moveCursor(cursorPos + carretPos); + await editor.moveCursor(cursorPos + carretPos); } } diff --git a/plugs/core/text.ts b/plugs/core/text.ts index 7ce6d7c..726af46 100644 --- a/plugs/core/text.ts +++ b/plugs/core/text.ts @@ -1,15 +1,8 @@ -import { - getSelection, - getText, - insertAtCursor, - moveCursor, - replaceRange, - setSelection, -} from "$sb/silverbullet-syscall/editor.ts"; +import { editor } from "$sb/silverbullet-syscall/mod.ts"; export async function quoteSelection() { - let text = await getText(); - const selection = await getSelection(); + let text = await editor.getText(); + const selection = await editor.getSelection(); let from = selection.from; while (from >= 0 && text[from] !== "\n") { from--; @@ -23,12 +16,12 @@ export async function quoteSelection() { text = text.slice(from, selection.to); text = `> ${text.replaceAll("\n", "\n> ")}`; } - await replaceRange(from, selection.to, text); + await editor.replaceRange(from, selection.to, text); } export async function listifySelection() { - let text = await getText(); - const selection = await getSelection(); + let text = await editor.getText(); + const selection = await editor.getSelection(); let from = selection.from; while (from >= 0 && text[from] !== "\n") { from--; @@ -36,12 +29,12 @@ export async function listifySelection() { from++; text = text.slice(from, selection.to); text = `* ${text.replaceAll(/\n(?!\n)/g, "\n* ")}`; - await replaceRange(from, selection.to, text); + await editor.replaceRange(from, selection.to, text); } export async function numberListifySelection() { - let text = await getText(); - const selection = await getSelection(); + let text = await editor.getText(); + const selection = await editor.getSelection(); let from = selection.from; while (from >= 0 && text[from] !== "\n") { from--; @@ -55,12 +48,12 @@ export async function numberListifySelection() { return `\n${counter}. `; }) }`; - await replaceRange(from, selection.to, text); + await editor.replaceRange(from, selection.to, text); } export async function linkSelection() { - const text = await getText(); - const selection = await getSelection(); + const text = await editor.getText(); + const selection = await editor.getSelection(); const textSelection = text.slice(selection.from, selection.to); let linkedText = `[]()`; let pos = 1; @@ -73,8 +66,8 @@ export async function linkSelection() { pos = linkedText.length - 1; } } - await replaceRange(selection.from, selection.to, linkedText); - await moveCursor(selection.from + pos); + await editor.replaceRange(selection.from, selection.to, linkedText); + await editor.moveCursor(selection.from + pos); } export function wrapSelection(cmdDef: any) { @@ -82,17 +75,17 @@ export function wrapSelection(cmdDef: any) { } async function insertMarker(marker: string) { - let text = await getText(); - const selection = await getSelection(); + const text = await editor.getText(); + const selection = await editor.getSelection(); if (selection.from === selection.to) { // empty selection if (markerAt(selection.from)) { // Already there, skipping ahead - await moveCursor(selection.from + marker.length); + await editor.moveCursor(selection.from + marker.length); } else { // Not there, inserting - await insertAtCursor(marker + marker); - await moveCursor(selection.from + marker.length); + await editor.insertAtCursor(marker + marker); + await editor.moveCursor(selection.from + marker.length); } } else { let from = selection.from; @@ -107,28 +100,28 @@ async function insertMarker(marker: string) { if (!hasMarker) { // Adding - await replaceRange( + await editor.replaceRange( selection.from, selection.to, marker + text.slice(selection.from, selection.to) + marker, ); - await setSelection( + await editor.setSelection( selection.from + marker.length, selection.to + marker.length, ); } else { // Removing - await replaceRange( + await editor.replaceRange( from, to, text.substring(from + marker.length, to - marker.length), ); - await setSelection(from, to - marker.length * 2); + await editor.setSelection(from, to - marker.length * 2); } } function markerAt(pos: number) { - for (var i = 0; i < marker.length; i++) { + for (let i = 0; i < marker.length; i++) { if (text[pos + i] !== marker[i]) { return false; } diff --git a/plugs/emoji/emoji.ts b/plugs/emoji/emoji.ts index 675fa7d..cf4f3c0 100644 --- a/plugs/emoji/emoji.ts +++ b/plugs/emoji/emoji.ts @@ -1,8 +1,8 @@ import emojis from "./emoji.json" assert { type: "json" }; -import { matchBefore } from "$sb/silverbullet-syscall/editor.ts"; +import { editor } from "$sb/silverbullet-syscall/mod.ts"; export async function emojiCompleter() { - const prefix = await matchBefore(":[\\w]+"); + const prefix = await editor.matchBefore(":[\\w]+"); if (!prefix) { return null; } diff --git a/plugs/markdown/markdown.plug.yaml b/plugs/markdown/markdown.plug.yaml index 1508070..b4fedd8 100644 --- a/plugs/markdown/markdown.plug.yaml +++ b/plugs/markdown/markdown.plug.yaml @@ -1,6 +1,8 @@ name: markdown imports: - https://get.silverbullet.md/global.plug.json +assets: + - styles.css functions: toggle: path: "./markdown.ts:togglePreview" diff --git a/plugs/markdown/markdown.ts b/plugs/markdown/markdown.ts index d523e10..e3cd7b0 100644 --- a/plugs/markdown/markdown.ts +++ b/plugs/markdown/markdown.ts @@ -1,13 +1,11 @@ -import { hideLhs, hideRhs } from "../../syscall/silverbullet-syscall/editor.ts"; -import { invokeFunction } from "../../syscall/silverbullet-syscall/system.ts"; -import * as clientStore from "../../syscall/silverbullet-syscall/clientStore.ts"; -import { readSettings } from "../lib/settings_page.ts"; +import { clientStore, editor, system } from "$sb/silverbullet-syscall/mod.ts"; +import { readSettings } from "$sb/lib/settings_page.ts"; export async function togglePreview() { - let currentValue = !!(await clientStore.get("enableMarkdownPreview")); + const currentValue = !!(await clientStore.get("enableMarkdownPreview")); await clientStore.set("enableMarkdownPreview", !currentValue); if (!currentValue) { - await invokeFunction("client", "preview"); + await system.invokeFunction("client", "preview"); } else { await hideMarkdownPreview(); } @@ -15,6 +13,6 @@ export async function togglePreview() { async function hideMarkdownPreview() { const setting = await readSettings({ previewOnRHS: true }); - const hide = setting.previewOnRHS ? hideRhs : hideLhs; + const hide = setting.previewOnRHS ? editor.hideRhs : editor.hideLhs; await hide(); } diff --git a/plugs/markdown/preview.ts b/plugs/markdown/preview.ts index a95ff0e..b6d1cd2 100644 --- a/plugs/markdown/preview.ts +++ b/plugs/markdown/preview.ts @@ -1,69 +1,10 @@ import MarkdownIt from "https://esm.sh/markdown-it@13.0.1"; -import { - getText, - showPanel, -} from "../../syscall/silverbullet-syscall/editor.ts"; -import * as clientStore from "../../syscall/silverbullet-syscall/clientStore.ts"; -import { cleanMarkdown } from "./util.ts"; - -const css = ` - -`; - import taskLists from "https://esm.sh/markdown-it-task-lists@2.1.1"; +import { clientStore, editor } from "$sb/silverbullet-syscall/mod.ts"; +import { asset } from "$sb/plugos-syscall/mod.ts"; +import { cleanMarkdown } from "./util.ts"; + const md = new MarkdownIt({ linkify: true, html: false, @@ -74,11 +15,14 @@ export async function updateMarkdownPreview() { if (!(await clientStore.get("enableMarkdownPreview"))) { return; } - let text = await getText(); - let cleanMd = await cleanMarkdown(text); - await showPanel( + const text = await editor.getText(); + const cleanMd = await cleanMarkdown(text); + const css = await asset.readAsset("styles.css"); + await editor.showPanel( "rhs", 2, - `${css}${md.render(cleanMd)}`, + `${ + md.render(cleanMd) + }`, ); } diff --git a/plugs/markdown/styles.css b/plugs/markdown/styles.css new file mode 100644 index 0000000..e4dd9c7 --- /dev/null +++ b/plugs/markdown/styles.css @@ -0,0 +1,51 @@ +