Lots of tweaks
parent
35dc75d94e
commit
f6758dbbaf
|
@ -46,24 +46,36 @@ export function filterBox(
|
||||||
return syscall("editor.filterBox", label, options, helpText, placeHolder);
|
return syscall("editor.filterBox", label, options, helpText, placeHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showRhs(html: string, flex = 1): Promise<void> {
|
export function showRhs(
|
||||||
return syscall("editor.showRhs", html, flex);
|
html: string,
|
||||||
|
script?: string,
|
||||||
|
flex = 1
|
||||||
|
): Promise<void> {
|
||||||
|
return syscall("editor.showRhs", html, script, flex);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hideRhs(): Promise<void> {
|
export function hideRhs(): Promise<void> {
|
||||||
return syscall("editor.hideRhs");
|
return syscall("editor.hideRhs");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showLhs(html: string, flex = 1): Promise<void> {
|
export function showLhs(
|
||||||
return syscall("editor.showLhs", html, flex);
|
html: string,
|
||||||
|
script?: string,
|
||||||
|
flex = 1
|
||||||
|
): Promise<void> {
|
||||||
|
return syscall("editor.showLhs", html, script, flex);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hideLhs(): Promise<void> {
|
export function hideLhs(): Promise<void> {
|
||||||
return syscall("editor.hideLhs");
|
return syscall("editor.hideLhs");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showBhs(html: string, flex = 1): Promise<void> {
|
export function showBhs(
|
||||||
return syscall("editor.showBhs", html, flex);
|
html: string,
|
||||||
|
script?: string,
|
||||||
|
flex = 1
|
||||||
|
): Promise<void> {
|
||||||
|
return syscall("editor.showBhs", html, script, flex);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hideBhs(): Promise<void> {
|
export function hideBhs(): Promise<void> {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { LogEntry } from "@plugos/plugos/sandbox";
|
||||||
|
|
||||||
|
export async function getServerLogs(): Promise<LogEntry[]> {
|
||||||
|
return syscall("sandbox.getServerLogs");
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import type { LogEntry } from "@plugos/plugos/sandbox";
|
||||||
|
|
||||||
|
export async function getLogs(): Promise<LogEntry[]> {
|
||||||
|
return syscall("sandbox.getLogs");
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
export type LogLevel = "info" | "warn" | "error" | "log";
|
||||||
|
|
||||||
|
export class ConsoleLogger {
|
||||||
|
print: boolean;
|
||||||
|
callback: (level: LogLevel, entry: string) => void;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
callback: (level: LogLevel, entry: string) => void,
|
||||||
|
print: boolean = true
|
||||||
|
) {
|
||||||
|
this.print = print;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(...args: any[]): void {
|
||||||
|
this.push("log", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
warn(...args: any[]): void {
|
||||||
|
this.push("warn", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
error(...args: any[]): void {
|
||||||
|
this.push("error", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
info(...args: any[]): void {
|
||||||
|
this.push("info", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
push(level: LogLevel, args: any[]) {
|
||||||
|
this.callback(level, this.logMessage(args));
|
||||||
|
if (this.print) {
|
||||||
|
console[level](...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logMessage(values: any[]): string {
|
||||||
|
let pieces: string[] = [];
|
||||||
|
for (let val of values) {
|
||||||
|
switch (typeof val) {
|
||||||
|
case "string":
|
||||||
|
case "number":
|
||||||
|
pieces.push("" + val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
try {
|
||||||
|
let s = JSON.stringify(val, null, 2);
|
||||||
|
if (s.length > 500) {
|
||||||
|
s = s.substring(0, 500) + "...";
|
||||||
|
}
|
||||||
|
pieces.push(s);
|
||||||
|
} catch {
|
||||||
|
// May be cyclical reference
|
||||||
|
pieces.push("[circular object]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pieces.join(" ");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { ConsoleLogger } from "./custom_logger";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
parentPort,
|
parentPort,
|
||||||
workerData: { preloadedModules, nodeModulesPath },
|
workerData: { preloadedModules, nodeModulesPath },
|
||||||
|
@ -16,10 +18,18 @@ let pendingRequests = new Map<
|
||||||
|
|
||||||
let syscallReqId = 0;
|
let syscallReqId = 0;
|
||||||
|
|
||||||
|
let consoleLogger = new ConsoleLogger((level, message) => {
|
||||||
|
parentPort.postMessage({
|
||||||
|
type: "log",
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
}, false);
|
||||||
|
|
||||||
let vm = new VM({
|
let vm = new VM({
|
||||||
sandbox: {
|
sandbox: {
|
||||||
// Exposing some "safe" APIs
|
// Exposing some "safe" APIs
|
||||||
console,
|
console: consoleLogger,
|
||||||
setTimeout,
|
setTimeout,
|
||||||
clearTimeout,
|
clearTimeout,
|
||||||
setInterval,
|
setInterval,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { safeRun } from "../util";
|
import { safeRun } from "../util";
|
||||||
|
import { ConsoleLogger } from "./custom_logger";
|
||||||
import { ControllerMessage, WorkerMessage } from "./worker";
|
import { ControllerMessage, WorkerMessage } from "./worker";
|
||||||
|
|
||||||
let loadedFunctions = new Map<string, Function>();
|
let loadedFunctions = new Map<string, Function>();
|
||||||
|
@ -53,6 +54,11 @@ self.require = (moduleName: string): any => {
|
||||||
return preloadedModules[moduleName];
|
return preloadedModules[moduleName];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
self.console = new ConsoleLogger((level, message) => {
|
||||||
|
workerPostMessage({ type: "log", level, message });
|
||||||
|
}, false);
|
||||||
|
|
||||||
function wrapScript(code: string) {
|
function wrapScript(code: string) {
|
||||||
return `return (${code})["default"]`;
|
return `return (${code})["default"]`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
export type ControllerMessageType = "inited" | "result" | "syscall";
|
import type { LogLevel } from "./custom_logger";
|
||||||
|
|
||||||
|
export type ControllerMessageType = "inited" | "result" | "syscall" | "log";
|
||||||
export type ControllerMessage = {
|
export type ControllerMessage = {
|
||||||
type: ControllerMessageType;
|
type: ControllerMessageType;
|
||||||
id?: number;
|
id?: number;
|
||||||
name?: string;
|
name?: string;
|
||||||
args?: any[];
|
args?: any[];
|
||||||
error?: string;
|
error?: string;
|
||||||
|
level?: LogLevel;
|
||||||
|
message?: string;
|
||||||
result?: any;
|
result?: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,19 @@
|
||||||
import { ControllerMessage, WorkerLike, WorkerMessage } from "./environments/worker";
|
import type { LogLevel } from "./environments/custom_logger";
|
||||||
|
import {
|
||||||
|
ControllerMessage,
|
||||||
|
WorkerLike,
|
||||||
|
WorkerMessage,
|
||||||
|
} from "./environments/worker";
|
||||||
import { Plug } from "./plug";
|
import { Plug } from "./plug";
|
||||||
|
|
||||||
export type SandboxFactory<HookT> = (plug: Plug<HookT>) => Sandbox;
|
export type SandboxFactory<HookT> = (plug: Plug<HookT>) => Sandbox;
|
||||||
|
|
||||||
|
export type LogEntry = {
|
||||||
|
level: LogLevel;
|
||||||
|
message: string;
|
||||||
|
date: number;
|
||||||
|
};
|
||||||
|
|
||||||
export class Sandbox {
|
export class Sandbox {
|
||||||
protected worker: WorkerLike;
|
protected worker: WorkerLike;
|
||||||
protected reqId = 0;
|
protected reqId = 0;
|
||||||
|
@ -13,6 +24,8 @@ export class Sandbox {
|
||||||
>();
|
>();
|
||||||
protected loadedFunctions = new Set<string>();
|
protected loadedFunctions = new Set<string>();
|
||||||
protected plug: Plug<any>;
|
protected plug: Plug<any>;
|
||||||
|
public logBuffer: LogEntry[] = [];
|
||||||
|
public maxLogBufferSize = 100;
|
||||||
|
|
||||||
constructor(plug: Plug<any>, worker: WorkerLike) {
|
constructor(plug: Plug<any>, worker: WorkerLike) {
|
||||||
worker.onMessage = this.onMessage.bind(this);
|
worker.onMessage = this.onMessage.bind(this);
|
||||||
|
@ -84,6 +97,17 @@ export class Sandbox {
|
||||||
resultCbs && resultCbs.resolve(data.result);
|
resultCbs && resultCbs.resolve(data.result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "log":
|
||||||
|
this.logBuffer.push({
|
||||||
|
level: data.level!,
|
||||||
|
message: data.message!,
|
||||||
|
date: Date.now(),
|
||||||
|
});
|
||||||
|
if (this.logBuffer.length > this.maxLogBufferSize) {
|
||||||
|
this.logBuffer.shift();
|
||||||
|
}
|
||||||
|
console.log(`[Sandbox ${data.level}]`, data.message);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.error("Unknown message type", data);
|
console.error("Unknown message type", data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { LogEntry } from "../sandbox";
|
||||||
|
import { SysCallMapping, System } from "../system";
|
||||||
|
|
||||||
|
export default function sandboxSyscalls(system: System<any>): SysCallMapping {
|
||||||
|
return {
|
||||||
|
"sandbox.getLogs": async (ctx): Promise<LogEntry[]> => {
|
||||||
|
let allLogs: LogEntry[] = [];
|
||||||
|
for (let plug of system.loadedPlugs.values()) {
|
||||||
|
allLogs = allLogs.concat(plug.sandbox.logBuffer);
|
||||||
|
}
|
||||||
|
allLogs = allLogs.sort((a, b) => a.date - b.date);
|
||||||
|
return allLogs;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
|
@ -232,20 +232,20 @@ function $11a7e2bff790f35a$export$4f02334034b5dd8c(message) {
|
||||||
function $11a7e2bff790f35a$export$83b9d7a71bc0a208(label, options, helpText = "", placeHolder = "") {
|
function $11a7e2bff790f35a$export$83b9d7a71bc0a208(label, options, helpText = "", placeHolder = "") {
|
||||||
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.filterBox", label, options, helpText, placeHolder);
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.filterBox", label, options, helpText, placeHolder);
|
||||||
}
|
}
|
||||||
function $11a7e2bff790f35a$export$53ed0b99a5f8822e(html, flex = 1) {
|
function $11a7e2bff790f35a$export$53ed0b99a5f8822e(html, script, flex = 1) {
|
||||||
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.showRhs", html, flex);
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.showRhs", html, script, flex);
|
||||||
}
|
}
|
||||||
function $11a7e2bff790f35a$export$f19f28e8a128fabe() {
|
function $11a7e2bff790f35a$export$f19f28e8a128fabe() {
|
||||||
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.hideRhs");
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.hideRhs");
|
||||||
}
|
}
|
||||||
function $11a7e2bff790f35a$export$dcf0ace441f4b3a4(html, flex = 1) {
|
function $11a7e2bff790f35a$export$dcf0ace441f4b3a4(html, script, flex = 1) {
|
||||||
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.showLhs", html, flex);
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.showLhs", html, script, flex);
|
||||||
}
|
}
|
||||||
function $11a7e2bff790f35a$export$1be2ad20c6324dcf() {
|
function $11a7e2bff790f35a$export$1be2ad20c6324dcf() {
|
||||||
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.hideLhs");
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.hideLhs");
|
||||||
}
|
}
|
||||||
function $11a7e2bff790f35a$export$6ebe231c70cc6efb(html, flex = 1) {
|
function $11a7e2bff790f35a$export$6ebe231c70cc6efb(html, script, flex = 1) {
|
||||||
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.showBhs", html, flex);
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.showBhs", html, script, flex);
|
||||||
}
|
}
|
||||||
function $11a7e2bff790f35a$export$a7a5aa8ba1cd9dc3() {
|
function $11a7e2bff790f35a$export$a7a5aa8ba1cd9dc3() {
|
||||||
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.hideBhs");
|
return $4ba3510c824e3aea$export$c5be9092dbf465c("editor.hideBhs");
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -67,9 +67,6 @@ functions:
|
||||||
name: "Page: Rename"
|
name: "Page: Rename"
|
||||||
mac: Cmd-Alt-r
|
mac: Cmd-Alt-r
|
||||||
key: Ctrl-Alt-r
|
key: Ctrl-Alt-r
|
||||||
button:
|
|
||||||
label: "📝"
|
|
||||||
tooltip: "Rename page"
|
|
||||||
pageComplete:
|
pageComplete:
|
||||||
path: "./page.ts:pageComplete"
|
path: "./page.ts:pageComplete"
|
||||||
events:
|
events:
|
||||||
|
@ -93,15 +90,27 @@ functions:
|
||||||
slashCommand:
|
slashCommand:
|
||||||
name: tomorrow
|
name: tomorrow
|
||||||
parseServerCommand:
|
parseServerCommand:
|
||||||
path: ./page.ts:parseServerPageCommand
|
path: ./debug.ts:parseServerPageCommand
|
||||||
command:
|
command:
|
||||||
name: "Debug: Parse Document on Server"
|
name: "Debug: Parse Document on Server"
|
||||||
parsePage:
|
parsePage:
|
||||||
path: ./page.ts:parsePage
|
path: ./debug.ts:parsePage
|
||||||
parseCommand:
|
parseCommand:
|
||||||
path: ./page.ts:parsePageCommand
|
path: ./debug.ts:parsePageCommand
|
||||||
command:
|
command:
|
||||||
name: "Debug: Parse Document"
|
name: "Debug: Parse Document"
|
||||||
|
showLogsCommand:
|
||||||
|
path: ./debug.ts:showLogsCommand
|
||||||
|
command:
|
||||||
|
name: "Debug: Show Logs"
|
||||||
|
key: "Ctrl-Alt-l"
|
||||||
|
mac: "Cmd-Alt-l"
|
||||||
|
hideBhsCommand:
|
||||||
|
path: ./debug.ts:hideBhsCommand
|
||||||
|
command:
|
||||||
|
name: "UI: Hide BHS"
|
||||||
|
key: "Ctrl-Alt-b"
|
||||||
|
mac: "Cmd-Alt-b"
|
||||||
insertPageMeta:
|
insertPageMeta:
|
||||||
path: "./page.ts:insertPageMeta"
|
path: "./page.ts:insertPageMeta"
|
||||||
slashCommand:
|
slashCommand:
|
||||||
|
@ -111,6 +120,8 @@ functions:
|
||||||
command:
|
command:
|
||||||
name: "Template: Quick Note"
|
name: "Template: Quick Note"
|
||||||
key: "Alt-Shift-n"
|
key: "Alt-Shift-n"
|
||||||
|
button:
|
||||||
|
label: "🗒"
|
||||||
quickTaskCommand:
|
quickTaskCommand:
|
||||||
path: ./template.ts:quickTaskCommand
|
path: ./template.ts:quickTaskCommand
|
||||||
command:
|
command:
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
import { getLogs } from "@plugos/plugos-syscall/sandbox";
|
||||||
|
import { LogEntry } from "@plugos/plugos/sandbox";
|
||||||
|
import {
|
||||||
|
getText,
|
||||||
|
hideBhs,
|
||||||
|
showBhs,
|
||||||
|
} from "@silverbulletmd/plugos-silverbullet-syscall/editor";
|
||||||
|
import { parseMarkdown } from "@silverbulletmd/plugos-silverbullet-syscall/markdown";
|
||||||
|
import { getServerLogs } from "@silverbulletmd/plugos-silverbullet-syscall/sandbox";
|
||||||
|
import { invokeFunction } from "@silverbulletmd/plugos-silverbullet-syscall/system";
|
||||||
|
|
||||||
|
export async function parseServerPageCommand() {
|
||||||
|
console.log(await invokeFunction("server", "parsePage", await getText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function parsePageCommand() {
|
||||||
|
parsePage(await getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function parsePage(text: string) {
|
||||||
|
console.log("AST", JSON.stringify(await parseMarkdown(text), null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function showLogsCommand() {
|
||||||
|
let clientLogs = await getLogs();
|
||||||
|
let serverLogs = await getServerLogs();
|
||||||
|
|
||||||
|
await showBhs(
|
||||||
|
`
|
||||||
|
<style>
|
||||||
|
#client-log-header {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
#server-log-header {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 5px;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
#client-log {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 30px;
|
||||||
|
bottom: 0;
|
||||||
|
width: 50%;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
#server-log {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 30px;
|
||||||
|
bottom: 0;
|
||||||
|
width: 50%;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div id="client-log-header">Client logs (max 100)</div>
|
||||||
|
<div id="client-log">
|
||||||
|
<pre>${clientLogs
|
||||||
|
.map((le) => `[${le.level}] ${le.message}`)
|
||||||
|
.join("\n")}</pre>
|
||||||
|
</div>
|
||||||
|
<div id="server-log-header">Server logs (max 100)</div>
|
||||||
|
<div id="server-log">
|
||||||
|
<pre>${serverLogs
|
||||||
|
.map((le) => `[${le.level}] ${le.message}`)
|
||||||
|
.join("\n")}</pre>
|
||||||
|
</div>`,
|
||||||
|
`
|
||||||
|
var clientDiv = document.getElementById("client-log");
|
||||||
|
clientDiv.scrollTop = clientDiv.scrollHeight;
|
||||||
|
var serverDiv = document.getElementById("server-log");
|
||||||
|
serverDiv.scrollTop = serverDiv.scrollHeight;
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function hideBhsCommand() {
|
||||||
|
await hideBhs();
|
||||||
|
}
|
|
@ -239,18 +239,6 @@ export async function parseIndexTextRepublish({ name, text }: IndexEvent) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseServerPageCommand() {
|
|
||||||
console.log(await invokeFunction("server", "parsePage", await getText()));
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function parsePageCommand() {
|
|
||||||
parsePage(await getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function parsePage(text: string) {
|
|
||||||
console.log("AST", JSON.stringify(await parseMarkdown(text), null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function insertPageMeta() {
|
export async function insertPageMeta() {
|
||||||
let cursorPos = await getCursor();
|
let cursorPos = await getCursor();
|
||||||
await insertAtCursor("```meta\n\n```");
|
await insertAtCursor("```meta\n\n```");
|
||||||
|
|
|
@ -78,6 +78,7 @@ export async function updateMarkdownPreview() {
|
||||||
let cleanMd = await cleanMarkdown(text);
|
let cleanMd = await cleanMarkdown(text);
|
||||||
await showRhs(
|
await showRhs(
|
||||||
`<html><head>${css}</head><body>${md.render(cleanMd)}</body></html>`,
|
`<html><head>${css}</head><body>${md.render(cleanMd)}</body></html>`,
|
||||||
|
undefined,
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ export async function updateMaterializedQueriesCommand() {
|
||||||
currentPage
|
currentPage
|
||||||
);
|
);
|
||||||
await reloadPage();
|
await reloadPage();
|
||||||
await flashNotification("Updated materialized queries");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function whiteOutQueriesCommand() {
|
export async function whiteOutQueriesCommand() {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import { plugPrefix } from "@silverbulletmd/common/spaces/constants";
|
||||||
|
|
||||||
import { Authenticator } from "./auth";
|
import { Authenticator } from "./auth";
|
||||||
import { nextTick } from "process";
|
import { nextTick } from "process";
|
||||||
|
import sandboxSyscalls from "@plugos/plugos/syscalls/sandbox";
|
||||||
|
|
||||||
const safeFilename = /^[a-zA-Z0-9_\-\.]+$/;
|
const safeFilename = /^[a-zA-Z0-9_\-\.]+$/;
|
||||||
|
|
||||||
|
@ -90,6 +91,7 @@ export class ExpressServer {
|
||||||
markdownSyscalls(buildMarkdown([])),
|
markdownSyscalls(buildMarkdown([])),
|
||||||
esbuildSyscalls(),
|
esbuildSyscalls(),
|
||||||
systemSyscalls(this),
|
systemSyscalls(this),
|
||||||
|
sandboxSyscalls(this.system),
|
||||||
jwtSyscalls()
|
jwtSyscalls()
|
||||||
);
|
);
|
||||||
this.system.addHook(new EndpointHook(this.app, "/_/"));
|
this.system.addHook(new EndpointHook(this.app, "/_/"));
|
||||||
|
|
|
@ -2,7 +2,15 @@ import { useEffect, useRef } from "react";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import iframeHtml from "bundle-text:./panel.html";
|
import iframeHtml from "bundle-text:./panel.html";
|
||||||
|
|
||||||
export function Panel({ html, flex }: { html: string; flex: number }) {
|
export function Panel({
|
||||||
|
html,
|
||||||
|
script,
|
||||||
|
flex,
|
||||||
|
}: {
|
||||||
|
html: string;
|
||||||
|
script?: string;
|
||||||
|
flex: number;
|
||||||
|
}) {
|
||||||
const iFrameRef = useRef<HTMLIFrameElement>(null);
|
const iFrameRef = useRef<HTMLIFrameElement>(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function loadContent() {
|
function loadContent() {
|
||||||
|
@ -10,6 +18,7 @@ export function Panel({ html, flex }: { html: string; flex: number }) {
|
||||||
iFrameRef.current.contentWindow.postMessage({
|
iFrameRef.current.contentWindow.postMessage({
|
||||||
type: "html",
|
type: "html",
|
||||||
html: html,
|
html: html,
|
||||||
|
script: script,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,13 @@ window.addEventListener("message", (message) => {
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case "html":
|
case "html":
|
||||||
document.body.innerHTML = data.html;
|
document.body.innerHTML = data.html;
|
||||||
|
if (data.script) {
|
||||||
|
try {
|
||||||
|
eval(data.script);
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error("Error evaling script", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,6 +58,7 @@ import {
|
||||||
import { FilterList } from "./components/filter";
|
import { FilterList } from "./components/filter";
|
||||||
import { FilterOption } from "@silverbulletmd/common/types";
|
import { FilterOption } from "@silverbulletmd/common/types";
|
||||||
import { syntaxTree } from "@codemirror/language";
|
import { syntaxTree } from "@codemirror/language";
|
||||||
|
import sandboxSyscalls from "@plugos/plugos/syscalls/sandbox";
|
||||||
|
|
||||||
class PageState {
|
class PageState {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -120,15 +121,16 @@ export class Editor {
|
||||||
});
|
});
|
||||||
this.pageNavigator = new PathPageNavigator();
|
this.pageNavigator = new PathPageNavigator();
|
||||||
|
|
||||||
this.system.registerSyscalls([], editorSyscalls(this));
|
|
||||||
this.system.registerSyscalls([], spaceSyscalls(this));
|
|
||||||
this.system.registerSyscalls([], indexerSyscalls(this.space));
|
|
||||||
this.system.registerSyscalls([], systemSyscalls(this));
|
|
||||||
this.system.registerSyscalls(
|
this.system.registerSyscalls(
|
||||||
[],
|
[],
|
||||||
markdownSyscalls(buildMarkdown(this.mdExtensions))
|
editorSyscalls(this),
|
||||||
|
spaceSyscalls(this),
|
||||||
|
indexerSyscalls(this.space),
|
||||||
|
systemSyscalls(this),
|
||||||
|
markdownSyscalls(buildMarkdown(this.mdExtensions)),
|
||||||
|
clientStoreSyscalls(),
|
||||||
|
sandboxSyscalls(this.system)
|
||||||
);
|
);
|
||||||
this.system.registerSyscalls([], clientStoreSyscalls());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentPage(): string | undefined {
|
get currentPage(): string | undefined {
|
||||||
|
@ -636,16 +638,28 @@ export class Editor {
|
||||||
/>
|
/>
|
||||||
<div id="main">
|
<div id="main">
|
||||||
{!!viewState.showLHS && (
|
{!!viewState.showLHS && (
|
||||||
<Panel html={viewState.lhsHTML} flex={viewState.showLHS} />
|
<Panel
|
||||||
|
html={viewState.lhsHTML}
|
||||||
|
script={viewState.lhsScript}
|
||||||
|
flex={viewState.showLHS}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
<div id="editor" />
|
<div id="editor" />
|
||||||
{!!viewState.showRHS && (
|
{!!viewState.showRHS && (
|
||||||
<Panel html={viewState.rhsHTML} flex={viewState.showRHS} />
|
<Panel
|
||||||
|
html={viewState.rhsHTML}
|
||||||
|
script={viewState.rhsScript}
|
||||||
|
flex={viewState.showRHS}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!!viewState.showBHS && (
|
{!!viewState.showBHS && (
|
||||||
<div id="bhs">
|
<div id="bhs">
|
||||||
<Panel html={viewState.bhsHTML} flex={1} />
|
<Panel
|
||||||
|
html={viewState.bhsHTML}
|
||||||
|
script={viewState.bhsScript}
|
||||||
|
flex={1}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<StatusBar editorView={editor.editorView} />
|
<StatusBar editorView={editor.editorView} />
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default function reducer(
|
||||||
case "show-notification":
|
case "show-notification":
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
notifications: [action.notification, ...state.notifications],
|
notifications: [...state.notifications, action.notification],
|
||||||
};
|
};
|
||||||
case "dismiss-notification":
|
case "dismiss-notification":
|
||||||
return {
|
return {
|
||||||
|
@ -84,36 +84,42 @@ export default function reducer(
|
||||||
...state,
|
...state,
|
||||||
showRHS: action.flex,
|
showRHS: action.flex,
|
||||||
rhsHTML: action.html,
|
rhsHTML: action.html,
|
||||||
|
rhsScript: action.script,
|
||||||
};
|
};
|
||||||
case "hide-rhs":
|
case "hide-rhs":
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
showRHS: 0,
|
showRHS: 0,
|
||||||
rhsHTML: "",
|
rhsHTML: "",
|
||||||
|
rhsScript: undefined,
|
||||||
};
|
};
|
||||||
case "show-lhs":
|
case "show-lhs":
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
showLHS: action.flex,
|
showLHS: action.flex,
|
||||||
lhsHTML: action.html,
|
lhsHTML: action.html,
|
||||||
|
lhsScript: action.script,
|
||||||
};
|
};
|
||||||
case "hide-lhs":
|
case "hide-lhs":
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
showLHS: 0,
|
showLHS: 0,
|
||||||
lhsHTML: "",
|
lhsHTML: "",
|
||||||
|
lhsScript: undefined,
|
||||||
};
|
};
|
||||||
case "show-bhs":
|
case "show-bhs":
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
showBHS: action.flex,
|
showBHS: action.flex,
|
||||||
bhsHTML: action.html,
|
bhsHTML: action.html,
|
||||||
|
bhsScript: action.script,
|
||||||
};
|
};
|
||||||
case "hide-bhs":
|
case "hide-bhs":
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
showBHS: 0,
|
showBHS: 0,
|
||||||
bhsHTML: "",
|
bhsHTML: "",
|
||||||
|
bhsScript: undefined,
|
||||||
};
|
};
|
||||||
case "show-filterbox":
|
case "show-filterbox":
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -73,13 +73,18 @@ body {
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
|
|
||||||
|
|
||||||
.status {
|
.status {
|
||||||
float: right;
|
position: absolute;
|
||||||
|
font-family: "iA-Mono";
|
||||||
|
bottom: 45px;
|
||||||
|
left: 5px;
|
||||||
|
right: 5px;
|
||||||
|
background-color: rgb(187, 221, 247);
|
||||||
border: rgb(41, 41, 41) 1px solid;
|
border: rgb(41, 41, 41) 1px solid;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
font-size: 14px;
|
font-size: 15px;
|
||||||
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-page {
|
.current-page {
|
||||||
|
@ -113,13 +118,10 @@ body {
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.panel {
|
.panel {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,10 +143,8 @@ body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#editor {
|
#editor {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
flex: 2;
|
flex: 2;
|
||||||
|
@ -152,10 +152,13 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#bhs {
|
#bhs {
|
||||||
height: 200px;
|
height: 300px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
border-top: rgb(193, 193, 193) 1px solid;
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
.panel {
|
|
||||||
iframe {
|
iframe {
|
||||||
border: 0;
|
border: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -173,4 +176,5 @@ body {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
background-color: rgb(213, 213, 213);
|
background-color: rgb(213, 213, 213);
|
||||||
border-top: rgb(193, 193, 193) 1px solid;
|
border-top: rgb(193, 193, 193) 1px solid;
|
||||||
|
font-family: "iA-Mono";
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,11 +71,12 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
|
||||||
): Promise<FilterOption | undefined> => {
|
): Promise<FilterOption | undefined> => {
|
||||||
return editor.filterBox(label, options, helpText, placeHolder);
|
return editor.filterBox(label, options, helpText, placeHolder);
|
||||||
},
|
},
|
||||||
"editor.showRhs": (ctx, html: string, flex: number) => {
|
"editor.showRhs": (ctx, html: string, script: string, flex: number) => {
|
||||||
editor.viewDispatch({
|
editor.viewDispatch({
|
||||||
type: "show-rhs",
|
type: "show-rhs",
|
||||||
flex,
|
flex,
|
||||||
html,
|
html,
|
||||||
|
script,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"editor.hideRhs": (ctx) => {
|
"editor.hideRhs": (ctx) => {
|
||||||
|
@ -83,11 +84,12 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
|
||||||
type: "hide-rhs",
|
type: "hide-rhs",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"editor.showLhs": (ctx, html: string, flex: number) => {
|
"editor.showLhs": (ctx, html: string, script: string, flex: number) => {
|
||||||
editor.viewDispatch({
|
editor.viewDispatch({
|
||||||
type: "show-lhs",
|
type: "show-lhs",
|
||||||
flex,
|
flex,
|
||||||
html,
|
html,
|
||||||
|
script,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"editor.hideLhs": (ctx) => {
|
"editor.hideLhs": (ctx) => {
|
||||||
|
@ -95,11 +97,12 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
|
||||||
type: "hide-lhs",
|
type: "hide-lhs",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"editor.showBhs": (ctx, html: string, flex: number) => {
|
"editor.showBhs": (ctx, html: string, script: string, flex: number) => {
|
||||||
editor.viewDispatch({
|
editor.viewDispatch({
|
||||||
type: "show-bhs",
|
type: "show-bhs",
|
||||||
flex,
|
flex,
|
||||||
html,
|
html,
|
||||||
|
script,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
"editor.hideBhs": (ctx) => {
|
"editor.hideBhs": (ctx) => {
|
||||||
|
|
|
@ -22,5 +22,9 @@ export function systemSyscalls(editor: Editor): SysCallMapping {
|
||||||
"system.reloadPlugs": async () => {
|
"system.reloadPlugs": async () => {
|
||||||
return editor.reloadPlugs();
|
return editor.reloadPlugs();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"sandbox.getServerLogs": async (ctx) => {
|
||||||
|
return editor.space.proxySyscall(ctx.plug, "sandbox.getLogs", []);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@ export type AppViewState = {
|
||||||
rhsHTML: string;
|
rhsHTML: string;
|
||||||
lhsHTML: string;
|
lhsHTML: string;
|
||||||
bhsHTML: string;
|
bhsHTML: string;
|
||||||
|
rhsScript?: string;
|
||||||
|
lhsScript?: string;
|
||||||
|
bhsScript?: string;
|
||||||
allPages: Set<PageMeta>;
|
allPages: Set<PageMeta>;
|
||||||
commands: Map<string, AppCommand>;
|
commands: Map<string, AppCommand>;
|
||||||
notifications: Notification[];
|
notifications: Notification[];
|
||||||
|
@ -78,11 +81,11 @@ export type Action =
|
||||||
| { type: "hide-palette" }
|
| { type: "hide-palette" }
|
||||||
| { type: "show-notification"; notification: Notification }
|
| { type: "show-notification"; notification: Notification }
|
||||||
| { type: "dismiss-notification"; id: number }
|
| { type: "dismiss-notification"; id: number }
|
||||||
| { type: "show-rhs"; html: string; flex: number }
|
| { type: "show-rhs"; html: string; flex: number; script?: string }
|
||||||
| { type: "hide-rhs" }
|
| { type: "hide-rhs" }
|
||||||
| { type: "show-lhs"; html: string; flex: number }
|
| { type: "show-lhs"; html: string; flex: number; script?: string }
|
||||||
| { type: "hide-lhs" }
|
| { type: "hide-lhs" }
|
||||||
| { type: "show-bhs"; html: string; flex: number }
|
| { type: "show-bhs"; html: string; flex: number; script?: string }
|
||||||
| { type: "hide-bhs" }
|
| { type: "hide-bhs" }
|
||||||
| {
|
| {
|
||||||
type: "show-filterbox";
|
type: "show-filterbox";
|
||||||
|
|
Loading…
Reference in New Issue