pull/1017/head
Zef Hemel 2024-08-02 17:14:40 +02:00
parent 351c3c7088
commit 47f504f2ce
21 changed files with 153 additions and 117 deletions

View File

@ -1,10 +1,10 @@
import * as YAML from "js-yaml";
export async function hello() {
// @ts-ignore: syscall is a global function
const numbers = await syscall("addNumbers", 1, 2);
return {
yamlMessage: YAML.dump({ hello: "world" }),
addedNumbers: numbers,
};
// @ts-ignore: syscall is a global function
const numbers = await syscall("addNumbers", 1, 2);
return {
yamlMessage: YAML.dump({ hello: "world" }),
addedNumbers: numbers,
};
}

View File

@ -2,6 +2,6 @@ import { assertEquals } from "@std/assert";
import { parseExpression } from "$common/expression_parser.ts";
Deno.test("Test expression parser", () => {
// Just a sanity check here
assertEquals(parseExpression("1 + 2"), ["+", ["number", 1], ["number", 2]]);
// Just a sanity check here
assertEquals(parseExpression("1 + 2"), ["+", ["number", 1], ["number", 2]]);
});

View File

@ -5,8 +5,8 @@ import { expressionToKvQueryExpression } from "$sb/lib/parse-query.ts";
import { lezerToParseTree } from "$common/markdown_parser/parse_tree.ts";
export function parseExpression(s: string): QueryExpression {
const ast = parseTreeToAST(
lezerToParseTree(s, expressionLanguage.parser.parse(s).topNode),
);
return expressionToKvQueryExpression(ast[1]);
const ast = parseTreeToAST(
lezerToParseTree(s, expressionLanguage.parser.parse(s).topNode),
);
return expressionToKvQueryExpression(ast[1]);
}

View File

@ -1,5 +1,5 @@
export const wikiLinkRegex = /(!?\[\[)([^\]\|]+)(?:\|([^\]]+))?(\]\])/g; // [fullMatch, firstMark, url, alias, lastMark]
export const mdLinkRegex = /!?\[(?<title>[^\]]*)\]\((?<url>.+)\)/g; // [fullMatch, alias, url]
export const tagRegex =
/#[^\d\s!@#$%^&*(),.?":{}|<>\\][^\s!@#$%^&*(),.?":{}|<>\\]*/;
/#[^\d\s!@#$%^&*(),.?":{}|<>\\][^\s!@#$%^&*(),.?":{}|<>\\]*/;
export const pWikiLinkRegex = new RegExp("^" + wikiLinkRegex.source); // Modified regex used only in parser

View File

@ -4,21 +4,21 @@ import Ajv from "ajv";
const ajv = new Ajv();
export function jsonschemaSyscalls(): SysCallMapping {
return {
"jsonschema.validateObject": (
_ctx,
schema: any,
object: any,
): undefined | string => {
const validate = ajv.compile(schema);
if (validate(object)) {
return;
} else {
let text = ajv.errorsText(validate.errors);
text = text.replaceAll("/", ".");
text = text.replace(/^data\./, "");
return text;
}
},
};
return {
"jsonschema.validateObject": (
_ctx,
schema: any,
object: any,
): undefined | string => {
const validate = ajv.compile(schema);
if (validate(object)) {
return;
} else {
let text = ajv.errorsText(validate.errors);
text = text.replaceAll("/", ".");
text = text.replace(/^data\./, "");
return text;
}
},
};
}

View File

@ -18,6 +18,7 @@
"check": "find . -name '*.ts*' | xargs deno check",
"lint": "deno lint",
"fmt": "deno fmt",
"test": "deno test -A --unstable-kv --unstable-worker-options",
"bench": "deno bench",
@ -53,12 +54,13 @@
},
"fmt": {
"exclude": [
"dist",
"dist_bundle",
"dist*",
"website",
"website_build",
"test_space",
"README.md"
"**/*.md",
"**/*.js",
"**/*.json"
]
},
"compilerOptions": {

View File

@ -2,59 +2,59 @@ import { DataStore } from "$lib/data/datastore.ts";
import { MemoryKvPrimitives } from "$lib/data/memory_kv_primitives.ts";
Deno.bench("DataStore enrichment benchmark with match", (b) => {
// Dummy datastore with a single object enricher
const datastore = new DataStore(new MemoryKvPrimitives(), {});
// Dummy datastore with a single object enricher
const datastore = new DataStore(new MemoryKvPrimitives(), {});
datastore.objectDecorators = [
{
where: ["=", ["attr", "tags"], ["string", "person"]],
attributes: {
fullName: ["+", ["+", ["attr", "firstName"], ["string", " "]], [
"attr",
"lastName",
]],
},
},
];
datastore.objectDecorators = [
{
where: ["=", ["attr", "tags"], ["string", "person"]],
attributes: {
fullName: ["+", ["+", ["attr", "firstName"], ["string", " "]], [
"attr",
"lastName",
]],
},
},
];
b.start();
// Let's try with half a million entries
for (let i = 0; i < 500000; i++) {
const obj = {
firstName: "Pete",
lastName: "Smith",
tags: ["person"],
};
datastore.enrichObject(obj);
}
b.end();
b.start();
// Let's try with half a million entries
for (let i = 0; i < 500000; i++) {
const obj = {
firstName: "Pete",
lastName: "Smith",
tags: ["person"],
};
datastore.enrichObject(obj);
}
b.end();
});
Deno.bench("DataStore enrichment benchmark without match", (b) => {
// Dummy datastore with a single object enricher
const datastore = new DataStore(new MemoryKvPrimitives(), {});
// Dummy datastore with a single object enricher
const datastore = new DataStore(new MemoryKvPrimitives(), {});
datastore.objectDecorators = [
{
where: ["=", ["attr", "tags"], ["string", "person"]],
attributes: {
fullName: ["+", ["+", ["attr", "firstName"], ["string", " "]], [
"attr",
"lastName",
]],
},
},
];
datastore.objectDecorators = [
{
where: ["=", ["attr", "tags"], ["string", "person"]],
attributes: {
fullName: ["+", ["+", ["attr", "firstName"], ["string", " "]], [
"attr",
"lastName",
]],
},
},
];
b.start();
// Let's try with half a million entries
for (let i = 0; i < 500000; i++) {
const obj = {
firstName: "Pete",
lastName: "Smith",
tags: ["peson"],
};
datastore.enrichObject(obj);
}
b.end();
b.start();
// Let's try with half a million entries
for (let i = 0; i < 500000; i++) {
const obj = {
firstName: "Pete",
lastName: "Smith",
tags: ["peson"],
};
datastore.enrichObject(obj);
}
b.end();
});

View File

@ -2,19 +2,19 @@ import { assert, assertEquals } from "@std/assert";
import { federatedPathToLocalPath, wildcardPathToRegex } from "./util.ts";
Deno.test("Test wildcardPathToRegex", () => {
assert(wildcardPathToRegex("test").test("test"));
assert(wildcardPathToRegex("test").test("test.md"));
assert(wildcardPathToRegex("test*").test("test"));
assert(wildcardPathToRegex("test/*").test("test/bla"));
assert(wildcardPathToRegex("test/*").test("test/bla.md"));
assert(wildcardPathToRegex("test/*").test("test/bla/bla"));
assert(!wildcardPathToRegex("test/*").test("tests/bla/bla"));
assert(wildcardPathToRegex("test").test("test"));
assert(wildcardPathToRegex("test").test("test.md"));
assert(wildcardPathToRegex("test*").test("test"));
assert(wildcardPathToRegex("test/*").test("test/bla"));
assert(wildcardPathToRegex("test/*").test("test/bla.md"));
assert(wildcardPathToRegex("test/*").test("test/bla/bla"));
assert(!wildcardPathToRegex("test/*").test("tests/bla/bla"));
});
Deno.test("Test federatedPathToLocalPath", () => {
assertEquals(federatedPathToLocalPath("!silverbullet.md"), "");
assertEquals(
federatedPathToLocalPath("!silverbullet.md/Library/Core/test"),
"Library/Core/test",
);
assertEquals(federatedPathToLocalPath("!silverbullet.md"), "");
assertEquals(
federatedPathToLocalPath("!silverbullet.md/Library/Core/test"),
"Library/Core/test",
);
});

View File

@ -1,14 +1,14 @@
export function wildcardPathToRegex(pattern: string): RegExp {
// Escape special characters in the pattern except for the wildcard "*"
const escapedPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
// Escape special characters in the pattern except for the wildcard "*"
const escapedPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
// Replace the wildcard "*" with ".*" to match any character sequence
const regexPattern = escapedPattern.replace(/\*/g, ".*");
// Replace the wildcard "*" with ".*" to match any character sequence
const regexPattern = escapedPattern.replace(/\*/g, ".*");
// Create a new regular expression with the converted pattern
return new RegExp(`^${regexPattern}(\\.md)?$`);
// Create a new regular expression with the converted pattern
return new RegExp(`^${regexPattern}(\\.md)?$`);
}
export function federatedPathToLocalPath(path: string): string {
return path.split("/").slice(1).join("/");
return path.split("/").slice(1).join("/");
}

View File

@ -1,4 +1,7 @@
import type { IndexTreeEvent, QueryProviderEvent } from "../../plug-api/types.ts";
import type {
IndexTreeEvent,
QueryProviderEvent,
} from "../../plug-api/types.ts";
import { renderToText } from "$sb/lib/tree.ts";
import { applyQuery, liftAttributeFilter } from "$sb/lib/query.ts";
import { editor } from "$sb/syscalls.ts";

View File

@ -1,4 +1,8 @@
import type { AttachmentMeta, FileMeta, PageMeta } from "../../plug-api/types.ts";
import type {
AttachmentMeta,
FileMeta,
PageMeta,
} from "../../plug-api/types.ts";
import type { SysCallMapping } from "../../lib/plugos/system.ts";
import type { Space } from "../../common/space.ts";

View File

@ -1,4 +1,7 @@
import type { CodeWidgetCallback, WidgetContent } from "../../plug-api/types.ts";
import type {
CodeWidgetCallback,
WidgetContent,
} from "../../plug-api/types.ts";
import { WidgetType } from "@codemirror/view";
import type { Client } from "../client.ts";
import { createWidgetSandboxIFrame } from "../components/widget_sandbox_iframe.ts";

View File

@ -93,7 +93,7 @@ export class MarkdownWidget extends WidgetType {
extendedMarkdownLanguage,
trimmedMarkdown,
);
const html = renderMarkdownToHtml(mdTree, {
// Annotate every element with its position so we can use it to put
// the cursor there when the user clicks on the table.

View File

@ -1,7 +1,11 @@
// Forked from https://codeberg.org/retronav/ixora
// Original author: Pranav Karawale
// License: Apache License 2.0.
import { type EditorState, StateField, type Transaction } from "@codemirror/state";
import {
type EditorState,
StateField,
type Transaction,
} from "@codemirror/state";
import type { DecorationSet } from "@codemirror/view";
import { Decoration, EditorView, WidgetType } from "@codemirror/view";
type LinkOptions = {

View File

@ -1,4 +1,8 @@
import { EditorSelection, type StateCommand, Transaction } from "@codemirror/state";
import {
EditorSelection,
type StateCommand,
Transaction,
} from "@codemirror/state";
import { Text } from "@codemirror/state";
export function insertMarker(marker: string): StateCommand {

View File

@ -200,7 +200,9 @@ export function FilterList({
className={(selectedOption === idx
? "sb-option sb-selected-option"
: "sb-option") +
(option.cssClass ? " sb-decorated-object " + option.cssClass : "")}
(option.cssClass
? " sb-decorated-object " + option.cssClass
: "")}
onMouseMove={() => {
if (selectedOption !== idx) {
setSelectionOption(idx);

View File

@ -21,7 +21,7 @@ export function Panel({
type: "html",
html: config.html,
script: config.script,
theme: document.getElementsByTagName("html")[0].dataset.theme
theme: document.getElementsByTagName("html")[0].dataset.theme,
});
}
@ -31,7 +31,7 @@ export function Panel({
return;
}
iframe.addEventListener("load", updateContent)
iframe.addEventListener("load", updateContent);
updateContent();
return () => {
@ -89,7 +89,12 @@ export function Panel({
return (
<div className="sb-panel" style={{ flex: config.mode }}>
<iframe srcDoc={panelHtml} ref={iFrameRef} style={{ visibility: 'hidden' }} onLoad={() => iFrameRef.current!.style.visibility = "visible" }/>
<iframe
srcDoc={panelHtml}
ref={iFrameRef}
style={{ visibility: "hidden" }}
onLoad={() => iFrameRef.current!.style.visibility = "visible"}
/>
</div>
);
}

View File

@ -69,10 +69,8 @@ export function TopBar({
? "sb-loading"
: unsavedChanges
? "sb-unsaved"
: "sb-saved") +
(cssClass
? " sb-decorated-object " + cssClass
: "")}
: "sb-saved") +
(cssClass ? " sb-decorated-object " + cssClass : "")}
>
<MiniEditor
text={pageName ?? ""}

View File

@ -1,6 +1,10 @@
import { plugPrefix } from "$common/spaces/constants.ts";
import type { SpacePrimitives } from "$common/spaces/space_primitives.ts";
import { SpaceSync, type SyncStatus, type SyncStatusItem } from "$common/spaces/sync.ts";
import {
SpaceSync,
type SyncStatus,
type SyncStatusItem,
} from "$common/spaces/sync.ts";
import { sleep } from "$lib/async.ts";
import type { EventHook } from "../common/hooks/event.ts";
import type { DataStore } from "$lib/data/datastore.ts";

View File

@ -1,6 +1,10 @@
import type { Client } from "../client.ts";
import type { SysCallMapping } from "../../lib/plugos/system.ts";
import type { AttachmentMeta, FileMeta, PageMeta } from "../../plug-api/types.ts";
import type {
AttachmentMeta,
FileMeta,
PageMeta,
} from "../../plug-api/types.ts";
export function spaceReadSyscalls(editor: Client): SysCallMapping {
return {

View File

@ -1,5 +1,8 @@
import type { HttpSpacePrimitives } from "$common/spaces/http_space_primitives.ts";
import type { SyscallContext, SysCallMapping } from "../../lib/plugos/system.ts";
import type {
SyscallContext,
SysCallMapping,
} from "../../lib/plugos/system.ts";
import type { Client } from "../client.ts";
export function proxySyscalls(client: Client, names: string[]): SysCallMapping {