Fix some nasty bug

pull/3/head
Zef Hemel 2022-03-31 17:25:34 +02:00
parent 859657f8b8
commit 4d201efdbb
10 changed files with 82 additions and 46 deletions

View File

@ -44,6 +44,7 @@ class IFrameWrapper implements WorkerLike {
} }
terminate() { terminate() {
console.log("Terminating iframe sandbox");
window.removeEventListener("message", this.messageListener); window.removeEventListener("message", this.messageListener);
return this.iframe.remove(); return this.iframe.remove();
} }

View File

@ -87,6 +87,7 @@ export class System<HookT> extends EventEmitter<SystemEvents<HookT>> {
sandboxFactory: SandboxFactory<HookT> sandboxFactory: SandboxFactory<HookT>
): Promise<Plug<HookT>> { ): Promise<Plug<HookT>> {
if (this.plugs.has(name)) { if (this.plugs.has(name)) {
console.log("Unloading", name);
await this.unload(name); await this.unload(name);
} }
// Validate // Validate

View File

@ -30,7 +30,8 @@ export async function updateMaterializedQueriesCommand() {
"updateMaterializedQueriesOnPage", "updateMaterializedQueriesOnPage",
await syscall("editor.getCurrentPage") await syscall("editor.getCurrentPage")
); );
syscall("editor.flashNotification", "Updated materialized queries"); await syscall("editor.reloadPage");
await syscall("editor.flashNotification", "Updated materialized queries");
} }
// Called from client, running on server // Called from client, running on server
@ -51,7 +52,7 @@ export async function updateMaterializedQueriesOnPage(pageName: string) {
let [, pos] = key.split(":"); let [, pos] = key.split(":");
if (!filter || (filter && task.includes(filter))) { if (!filter || (filter && task.includes(filter))) {
results.push( results.push(
`* [${complete ? "x" : " "}] [[${page}@${pos}]] ${task}` `* [${complete ? "x" : " "}] [[${page}@${pos}]] ${task}`
); );
if (children) { if (children) {
results.push(children.join("\n")); results.push(children.join("\n"));
@ -59,11 +60,26 @@ export async function updateMaterializedQueriesOnPage(pageName: string) {
} }
} }
return `${startQuery}\n${results.join("\n")}\n${endQuery}`; return `${startQuery}\n${results.join("\n")}\n${endQuery}`;
case "link":
let uniqueLinks = new Set<string>();
for (let {key, page, value: name} of await syscall(
"index.scanPrefixGlobal",
`pl:${pageName}:`
)) {
let [, pos] = key.split(":");
if (!filter || (filter && name.includes(filter))) {
uniqueLinks.add(name);
}
}
for (const uniqueResult of uniqueLinks) {
results.push(`* [[${uniqueResult}]]`);
}
return `${startQuery}\n${results.sort().join("\n")}\n${endQuery}`;
case "item": case "item":
for (let { for (let {
key, key,
page, page,
value: { item, children }, value: {item, children},
} of await syscall("index.scanPrefixGlobal", "it:")) { } of await syscall("index.scanPrefixGlobal", "it:")) {
let [, pos] = key.split(":"); let [, pos] = key.split(":");
if (!filter || (filter && item.includes(filter))) { if (!filter || (filter && item.includes(filter))) {

View File

@ -12,6 +12,8 @@ import spaceSyscalls from "./syscalls/space";
import { eventSyscalls } from "../plugos/syscalls/event"; import { eventSyscalls } from "../plugos/syscalls/event";
import { pageIndexSyscalls } from "./syscalls"; import { pageIndexSyscalls } from "./syscalls";
import knex, { Knex } from "knex"; import knex, { Knex } from "knex";
import shellSyscalls from "../plugos/syscalls/shell.node";
import { NodeCronHook } from "../plugos/hooks/node_cron";
export class ExpressServer { export class ExpressServer {
app: Express; app: Express;
@ -47,6 +49,10 @@ export class ExpressServer {
}, },
useNullAsDefault: true, useNullAsDefault: true,
}); });
system.registerSyscalls("shell", ["shell"], shellSyscalls(rootPath));
system.addHook(new NodeCronHook());
system.registerSyscalls("index", [], pageIndexSyscalls(this.db)); system.registerSyscalls("index", [], pageIndexSyscalls(this.db));
system.registerSyscalls("space", [], spaceSyscalls(this.storage)); system.registerSyscalls("space", [], spaceSyscalls(this.storage));
system.registerSyscalls("event", [], eventSyscalls(this.eventHook)); system.registerSyscalls("event", [], eventSyscalls(this.eventHook));
@ -69,7 +75,7 @@ export class ExpressServer {
.route(/\/(.+)/) .route(/\/(.+)/)
.get(async (req, res) => { .get(async (req, res) => {
let pageName = req.params[0]; let pageName = req.params[0];
console.log("Getting", pageName); // console.log("Getting", pageName);
try { try {
let pageData = await this.storage.readPage(pageName); let pageData = await this.storage.readPage(pageName);
res.status(200); res.status(200);
@ -80,7 +86,7 @@ export class ExpressServer {
res.status(200); res.status(200);
res.send(""); res.send("");
} }
}) };)
.put(bodyParser.text({ type: "*/*" }), async (req, res) => { .put(bodyParser.text({ type: "*/*" }), async (req, res) => {
let pageName = req.params[0]; let pageName = req.params[0];
console.log("Saving", pageName); console.log("Saving", pageName);

View File

@ -5,10 +5,8 @@ import http from "http";
import yargs from "yargs"; import yargs from "yargs";
import {hideBin} from "yargs/helpers"; import {hideBin} from "yargs/helpers";
import {SilverBulletHooks} from "../common/manifest"; import {SilverBulletHooks} from "../common/manifest";
import {ExpressServer} from "./express_server"; import {ExpressServer} from "./api_server";
import {DiskPlugLoader} from "../plugos/plug_loader"; import {DiskPlugLoader} from "../plugos/plug_loader";
import {NodeCronHook} from "../plugos/hooks/node_cron";
import shellSyscalls from "../plugos/syscalls/shell.node";
import {System} from "../plugos/system"; import {System} from "../plugos/system";
let args = yargs(hideBin(process.argv)) let args = yargs(hideBin(process.argv))
@ -19,7 +17,7 @@ let args = yargs(hideBin(process.argv))
.parse(); .parse();
if (!args._.length) { if (!args._.length) {
console.error("Usage: silverbullet <path-to-pages>"); console.error("Usage: silverbullet <path-to-pages>");
process.exit(1); process.exit(1);
} }
@ -44,8 +42,6 @@ expressServer
); );
await plugLoader.loadPlugs(); await plugLoader.loadPlugs();
plugLoader.watcher(); plugLoader.watcher();
system.registerSyscalls("shell", ["shell"], shellSyscalls(pagesPath));
system.addHook(new NodeCronHook());
server.listen(port, () => { server.listen(port, () => {
console.log(`Server listening on port ${port}`); console.log(`Server listening on port ${port}`);
}); });

View File

@ -36,7 +36,7 @@ import indexerSyscalls from "./syscalls/indexer";
import spaceSyscalls from "./syscalls/space"; import spaceSyscalls from "./syscalls/space";
import { Action, AppViewState, initialViewState } from "./types"; import { Action, AppViewState, initialViewState } from "./types";
import { SilverBulletHooks } from "../common/manifest"; import { SilverBulletHooks } from "../common/manifest";
import { safeRun } from "./util"; import { safeRun, throttle } from "./util";
import { System } from "../plugos/system"; import { System } from "../plugos/system";
import { EventHook } from "../plugos/hooks/event"; import { EventHook } from "../plugos/hooks/event";
import { systemSyscalls } from "./syscalls/system"; import { systemSyscalls } from "./syscalls/system";
@ -132,6 +132,10 @@ export class Editor implements AppEventDispatcher {
} }
}); });
let throttledRebuildEditorState = throttle(() => {
this.rebuildEditorState();
}, 100);
this.space.on({ this.space.on({
pageCreated: (meta) => { pageCreated: (meta) => {
console.log("Page created", meta); console.log("Page created", meta);
@ -156,12 +160,14 @@ export class Editor implements AppEventDispatcher {
safeRun(async () => { safeRun(async () => {
console.log("Plug load", plugName); console.log("Plug load", plugName);
await this.system.load(plugName, plug, createIFrameSandbox); await this.system.load(plugName, plug, createIFrameSandbox);
throttledRebuildEditorState();
}); });
}, },
plugUnloaded: (plugName) => { plugUnloaded: (plugName) => {
safeRun(async () => { safeRun(async () => {
console.log("Plug unload", plugName); console.log("Plug unload", plugName);
await this.system.unload(plugName); await this.system.unload(plugName);
throttledRebuildEditorState();
}); });
}, },
}); });
@ -364,6 +370,15 @@ export class Editor implements AppEventDispatcher {
}); });
} }
rebuildEditorState() {
const editorView = this.editorView;
if (editorView && this.currentPage) {
editorView.setState(
this.createEditorState(this.currentPage, editorView.state.sliceDoc())
);
}
}
reloadPage() { reloadPage() {
console.log("Reloading page"); console.log("Reloading page");
safeRun(async () => { safeRun(async () => {

View File

@ -35,40 +35,40 @@ const htmlNoMatch = html({ matchClosingTags: false });
/// Markdown language support. /// Markdown language support.
export function markdown( export function markdown(
config: { config: {
/// When given, this language will be used by default to parse code /// When given, this language will be used by default to parse code
/// blocks. /// blocks.
defaultCodeLanguage?: Language | LanguageSupport; defaultCodeLanguage?: Language | LanguageSupport;
/// A collection of language descriptions to search through for a /// A collection of language descriptions to search through for a
/// matching language (with /// matching language (with
/// [`LanguageDescription.matchLanguageName`](#language.LanguageDescription^matchLanguageName)) /// [`LanguageDescription.matchLanguageName`](#language.LanguageDescription^matchLanguageName))
/// when a fenced code block has an info string. /// when a fenced code block has an info string.
codeLanguages?: readonly LanguageDescription[]; codeLanguages?: readonly LanguageDescription[];
/// Set this to false to disable installation of the Markdown /// Set this to false to disable installation of the Markdown
/// [keymap](#lang-markdown.markdownKeymap). /// [keymap](#lang-markdown.markdownKeymap).
addKeymap?: boolean; addKeymap?: boolean;
/// Markdown parser /// Markdown parser
/// [extensions](https://github.com/lezer-parser/markdown#user-content-markdownextension) /// [extensions](https://github.com/lezer-parser/markdown#user-content-markdownextension)
/// to add to the parser. /// to add to the parser.
extensions?: MarkdownExtension; extensions?: MarkdownExtension;
/// The base language to use. Defaults to /// The base language to use. Defaults to
/// [`commonmarkLanguage`](#lang-markdown.commonmarkLanguage). /// [`commonmarkLanguage`](#lang-markdown.commonmarkLanguage).
base?: Language; base?: Language;
} = {} } = {}
) { ) {
let { let {
codeLanguages, codeLanguages,
defaultCodeLanguage, defaultCodeLanguage,
addKeymap = true, addKeymap = true,
base: {parser} = commonmarkLanguage, base: { parser } = commonmarkLanguage,
} = config; } = config;
if (!(parser instanceof MarkdownParser)) if (!(parser instanceof MarkdownParser))
throw new RangeError( throw new RangeError(
"Base parser provided to `markdown` should be a Markdown parser" "Base parser provided to `markdown` should be a Markdown parser"
); );
let extensions = config.extensions ? [config.extensions] : []; let extensions = config.extensions ? [config.extensions] : [];
let support = [htmlNoMatch.support], let support = [htmlNoMatch.support],
defaultCode; defaultCode;
if (defaultCodeLanguage instanceof LanguageSupport) { if (defaultCodeLanguage instanceof LanguageSupport) {
support.push(defaultCodeLanguage.support); support.push(defaultCodeLanguage.support);
defaultCode = defaultCodeLanguage.language; defaultCode = defaultCodeLanguage.language;
@ -76,11 +76,11 @@ export function markdown(
defaultCode = defaultCodeLanguage; defaultCode = defaultCodeLanguage;
} }
let codeParser = let codeParser =
codeLanguages || defaultCode codeLanguages || defaultCode
? getCodeParser(codeLanguages || [], defaultCode) ? getCodeParser(codeLanguages || [], defaultCode)
: undefined; : undefined;
extensions.push( extensions.push(
parseCode({codeParser, htmlParser: htmlNoMatch.language.parser}) parseCode({ codeParser, htmlParser: htmlNoMatch.language.parser })
); );
if (addKeymap) support.push(Prec.high(keymap.of(markdownKeymap))); if (addKeymap) support.push(Prec.high(keymap.of(markdownKeymap)));
return new LanguageSupport(mkLang(parser.configure(extensions)), support); return new LanguageSupport(mkLang(parser.configure(extensions)), support);

View File

@ -10,11 +10,11 @@ export default function reducer(
return { return {
...state, ...state,
allPages: new Set( allPages: new Set(
[...state.allPages].map((pageMeta) => [...state.allPages].map((pageMeta) =>
pageMeta.name === action.name pageMeta.name === action.name
? {...pageMeta, lastOpened: Date.now()} ? { ...pageMeta, lastOpened: Date.now() }
: pageMeta : pageMeta
) )
), ),
currentPage: action.name, currentPage: action.name,
}; };

View File

@ -185,7 +185,6 @@ export class Space extends EventEmitter<SpaceEvents> {
name: string, name: string,
args: any[] args: any[]
): Promise<any> { ): Promise<any> {
console.log("Making a remote syscall", name, args);
let req = await fetch(`${this.plugUrl}/${plug.name}/syscall/${name}`, { let req = await fetch(`${this.plugUrl}/${plug.name}/syscall/${name}`, {
method: "POST", method: "POST",
headers: { headers: {
@ -204,7 +203,6 @@ export class Space extends EventEmitter<SpaceEvents> {
} }
async remoteInvoke(plug: Plug<any>, name: string, args: any[]): Promise<any> { async remoteInvoke(plug: Plug<any>, name: string, args: any[]): Promise<any> {
console.log("Making a remote syscall", name, JSON.stringify(args));
let req = await fetch(`${this.plugUrl}/${plug.name}/function/${name}`, { let req = await fetch(`${this.plugUrl}/${plug.name}/function/${name}`, {
method: "POST", method: "POST",
headers: { headers: {

View File

@ -39,6 +39,9 @@ export default (editor: Editor): SysCallMapping => ({
navigate: async (ctx, name: string, pos: number) => { navigate: async (ctx, name: string, pos: number) => {
await editor.navigate(name, pos); await editor.navigate(name, pos);
}, },
reloadPage: async (ctx) => {
await editor.reloadPage();
},
openUrl: async (ctx, url: string) => { openUrl: async (ctx, url: string) => {
window.open(url, "_blank")!.focus(); window.open(url, "_blank")!.focus();
}, },