SilverBullet pivot to become an offline-first PWA (#403)
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { proxySyscalls } from "../../plugos/syscalls/transport.ts";
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { storeSyscalls } from "../../plugos/syscalls/store.dexie_browser.ts";
|
||||
|
||||
export function clientStoreSyscalls(): SysCallMapping {
|
||||
const storeCalls = storeSyscalls("local", "localData");
|
||||
// DEPRECATED, use store directly
|
||||
export function clientStoreSyscalls(
|
||||
storeCalls: SysCallMapping,
|
||||
): SysCallMapping {
|
||||
return proxySyscalls(
|
||||
["clientStore.get", "clientStore.set", "clientStore.delete"],
|
||||
(ctx, name, ...args) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Editor } from "../editor.tsx";
|
||||
import { EditorView, Transaction, Vim, vimGetCm } from "../deps.ts";
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { FilterOption } from "../../common/types.ts";
|
||||
import type { FilterOption } from "../types.ts";
|
||||
|
||||
export function editorSyscalls(editor: Editor): SysCallMapping {
|
||||
const syscalls: SysCallMapping = {
|
||||
|
||||
+34
-9
@@ -1,12 +1,37 @@
|
||||
import type { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { proxySyscalls } from "../../plugos/syscalls/transport.ts";
|
||||
import type { Space } from "../../common/spaces/space.ts";
|
||||
import type { HttpSpacePrimitives } from "../../common/spaces/http_space_primitives.ts";
|
||||
import {
|
||||
performLocalFetch,
|
||||
ProxyFetchRequest,
|
||||
ProxyFetchResponse,
|
||||
} from "../../common/proxy_fetch.ts";
|
||||
|
||||
export function sandboxFetchSyscalls(space: Space): SysCallMapping {
|
||||
return proxySyscalls(
|
||||
[
|
||||
"sandboxFetch.fetch",
|
||||
],
|
||||
(ctx, name, ...args) => space.proxySyscall(ctx.plug, name, args),
|
||||
);
|
||||
export function sandboxFetchSyscalls(
|
||||
httpSpacePrimitives?: HttpSpacePrimitives,
|
||||
): SysCallMapping {
|
||||
return {
|
||||
"sandboxFetch.fetch": async (
|
||||
_ctx,
|
||||
url: string,
|
||||
options: ProxyFetchRequest,
|
||||
): Promise<ProxyFetchResponse> => {
|
||||
// console.log("Got sandbox fetch ", url);
|
||||
if (!httpSpacePrimitives) {
|
||||
// No SB server to proxy the fetch available so let's execute the request directly
|
||||
return performLocalFetch(url, options);
|
||||
}
|
||||
const resp = httpSpacePrimitives.authenticatedFetch(
|
||||
httpSpacePrimitives.url,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
operation: "fetch",
|
||||
url,
|
||||
options,
|
||||
}),
|
||||
},
|
||||
);
|
||||
return (await resp).json();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { proxySyscalls } from "../../plugos/syscalls/transport.ts";
|
||||
import { Space } from "../../common/spaces/space.ts";
|
||||
|
||||
export function fulltextSyscalls(space: Space): SysCallMapping {
|
||||
return proxySyscalls(
|
||||
["fulltext.search", "fulltext.delete", "fulltext.index"],
|
||||
(ctx, name, ...args) => space.proxySyscall(ctx.plug, name, args),
|
||||
);
|
||||
}
|
||||
+61
-14
@@ -1,16 +1,63 @@
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { proxySyscalls } from "../../plugos/syscalls/transport.ts";
|
||||
import { Space } from "../../common/spaces/space.ts";
|
||||
import type { SysCallMapping } from "../../plugos/system.ts";
|
||||
import Dexie from "dexie";
|
||||
|
||||
export function indexerSyscalls(space: Space): SysCallMapping {
|
||||
return proxySyscalls(
|
||||
[
|
||||
"index.queryPrefix",
|
||||
"index.get",
|
||||
"index.set",
|
||||
"index.batchSet",
|
||||
"index.delete",
|
||||
],
|
||||
(ctx, name, ...args) => space.proxySyscall(ctx.plug, name, args),
|
||||
);
|
||||
type Item = {
|
||||
page: string;
|
||||
key: string;
|
||||
value: any;
|
||||
};
|
||||
|
||||
export type KV = {
|
||||
key: string;
|
||||
value: any;
|
||||
};
|
||||
|
||||
export function pageIndexSyscalls(
|
||||
dbName: string,
|
||||
indexedDB?: any,
|
||||
): SysCallMapping {
|
||||
const db = new Dexie(dbName, {
|
||||
indexedDB,
|
||||
});
|
||||
db.version(1).stores({
|
||||
"index": "[page+key], page, key",
|
||||
});
|
||||
const items = db.table<Item, { key: string; page: string }>("index");
|
||||
const apiObj: SysCallMapping = {
|
||||
"index.set": (_ctx, page: string, key: string, value: any) => {
|
||||
return items.put({ page, key, value });
|
||||
},
|
||||
"index.batchSet": async (_ctx, page: string, kvs: KV[]) => {
|
||||
// await items.bulkPut(kvs);
|
||||
if (kvs.length === 0) {
|
||||
return;
|
||||
}
|
||||
const values = kvs.flatMap((kv) => ({
|
||||
page,
|
||||
key: kv.key,
|
||||
value: kv.value,
|
||||
}));
|
||||
await items.bulkPut(values);
|
||||
},
|
||||
"index.delete": (_ctx, page: string, key: string) => {
|
||||
return items.delete({ page, key });
|
||||
},
|
||||
"index.get": async (_ctx, page: string, key: string) => {
|
||||
return (await items.get({ page, key }))?.value;
|
||||
},
|
||||
"index.queryPrefix": (_ctx, prefix: string) => {
|
||||
return items.where("key").startsWith(prefix).toArray();
|
||||
},
|
||||
"index.clearPageIndexForPage": async (ctx, page: string) => {
|
||||
await apiObj["index.deletePrefixForPage"](ctx, page, "");
|
||||
},
|
||||
"index.deletePrefixForPage": (_ctx, page: string, prefix: string) => {
|
||||
return items.where({ page }).and((it) => it.key.startsWith(prefix))
|
||||
.delete();
|
||||
},
|
||||
"index.clearPageIndex": () => {
|
||||
return items.clear();
|
||||
},
|
||||
};
|
||||
return apiObj;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { parse } from "../../common/markdown_parser/parse_tree.ts";
|
||||
import { Language } from "../deps.ts";
|
||||
import type { ParseTree } from "$sb/lib/tree.ts";
|
||||
|
||||
export function markdownSyscalls(lang: Language): SysCallMapping {
|
||||
return {
|
||||
"markdown.parseMarkdown": (_ctx, text: string): ParseTree => {
|
||||
return parse(lang, text);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { HttpSpacePrimitives } from "../../common/spaces/http_space_primitives.ts";
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
|
||||
export function shellSyscalls(
|
||||
httpSpacePrimitives?: HttpSpacePrimitives,
|
||||
): SysCallMapping {
|
||||
return {
|
||||
"shell.run": async (
|
||||
_ctx,
|
||||
cmd: string,
|
||||
args: string[],
|
||||
): Promise<{ stdout: string; stderr: string; code: number }> => {
|
||||
if (!httpSpacePrimitives) {
|
||||
throw new Error("Not supported in fully local mode");
|
||||
}
|
||||
const resp = httpSpacePrimitives.authenticatedFetch(
|
||||
httpSpacePrimitives.url,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
operation: "shell",
|
||||
cmd,
|
||||
args,
|
||||
}),
|
||||
},
|
||||
);
|
||||
const { code, stderr, stdout } = await (await resp).json();
|
||||
if (code !== 0) {
|
||||
throw new Error(stderr);
|
||||
}
|
||||
return { code, stderr, stdout };
|
||||
},
|
||||
};
|
||||
}
|
||||
+62
-13
@@ -1,19 +1,68 @@
|
||||
import { Editor } from "../editor.tsx";
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
|
||||
import commonSpaceSyscalls from "../../common/syscalls/space.ts";
|
||||
import { AttachmentMeta, PageMeta } from "../types.ts";
|
||||
import { FileData, FileEncoding } from "../space.ts";
|
||||
|
||||
export function spaceSyscalls(editor: Editor): SysCallMapping {
|
||||
const syscalls = commonSpaceSyscalls(editor.space);
|
||||
syscalls["space.deletePage"] = async (_ctx, name: string) => {
|
||||
// If we're deleting the current page, navigate to the index page
|
||||
if (editor.currentPage === name) {
|
||||
await editor.navigate("");
|
||||
}
|
||||
// Remove page from open pages in editor
|
||||
editor.openPages.delete(name);
|
||||
console.log("Deleting page");
|
||||
await editor.space.deletePage(name);
|
||||
const space = editor.space;
|
||||
return {
|
||||
"space.listPages": (): Promise<PageMeta[]> => {
|
||||
return space.fetchPageList();
|
||||
},
|
||||
"space.readPage": async (
|
||||
_ctx,
|
||||
name: string,
|
||||
): Promise<string> => {
|
||||
return (await space.readPage(name)).text;
|
||||
},
|
||||
"space.getPageMeta": (_ctx, name: string): Promise<PageMeta> => {
|
||||
return space.getPageMeta(name);
|
||||
},
|
||||
"space.writePage": (
|
||||
_ctx,
|
||||
name: string,
|
||||
text: string,
|
||||
): Promise<PageMeta> => {
|
||||
return space.writePage(name, text);
|
||||
},
|
||||
"space.deletePage": async (_ctx, name: string) => {
|
||||
// If we're deleting the current page, navigate to the index page
|
||||
if (editor.currentPage === name) {
|
||||
await editor.navigate("");
|
||||
}
|
||||
// Remove page from open pages in editor
|
||||
editor.openPages.delete(name);
|
||||
console.log("Deleting page");
|
||||
await editor.space.deletePage(name);
|
||||
},
|
||||
"space.listPlugs": (): Promise<string[]> => {
|
||||
return space.listPlugs();
|
||||
},
|
||||
"space.listAttachments": async (): Promise<AttachmentMeta[]> => {
|
||||
return await space.fetchAttachmentList();
|
||||
},
|
||||
"space.readAttachment": async (
|
||||
_ctx,
|
||||
name: string,
|
||||
): Promise<FileData> => {
|
||||
return (await space.readAttachment(name, "dataurl")).data;
|
||||
},
|
||||
"space.getAttachmentMeta": async (
|
||||
_ctx,
|
||||
name: string,
|
||||
): Promise<AttachmentMeta> => {
|
||||
return await space.getAttachmentMeta(name);
|
||||
},
|
||||
"space.writeAttachment": async (
|
||||
_ctx,
|
||||
name: string,
|
||||
encoding: FileEncoding,
|
||||
data: string,
|
||||
): Promise<AttachmentMeta> => {
|
||||
return await space.writeAttachment(name, encoding, data);
|
||||
},
|
||||
"space.deleteAttachment": async (_ctx, name: string) => {
|
||||
await space.deleteAttachment(name);
|
||||
},
|
||||
};
|
||||
return syscalls;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { proxySyscalls } from "../../plugos/syscalls/transport.ts";
|
||||
import { Space } from "../../common/spaces/space.ts";
|
||||
|
||||
export function storeSyscalls(space: Space): SysCallMapping {
|
||||
return proxySyscalls(
|
||||
[
|
||||
"store.queryPrefix",
|
||||
"store.get",
|
||||
"store.has",
|
||||
"store.set",
|
||||
"store.batchSet",
|
||||
"store.delete",
|
||||
"store.deletePrefix",
|
||||
],
|
||||
(ctx, name, ...args) => space.proxySyscall(ctx.plug, name, args),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { SyncService } from "../sync_service.ts";
|
||||
|
||||
export function syncSyscalls(syncService: SyncService): SysCallMapping {
|
||||
return {
|
||||
"sync.isSyncing": (): Promise<boolean> => {
|
||||
return syncService.isSyncing();
|
||||
},
|
||||
"sync.hasInitialSyncCompleted": (): Promise<boolean> => {
|
||||
return syncService.hasInitialSyncCompleted();
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -28,13 +28,9 @@ export function systemSyscalls(
|
||||
}
|
||||
name = functionName;
|
||||
}
|
||||
if (env === "client") {
|
||||
return plug.invoke(name, args);
|
||||
}
|
||||
|
||||
return editor.space.invokeFunction(plug, env, name, args);
|
||||
return plug.invoke(name, args);
|
||||
},
|
||||
"system.invokeCommand": (ctx, name: string) => {
|
||||
"system.invokeCommand": (_ctx, name: string) => {
|
||||
return editor.runCommandByName(name);
|
||||
},
|
||||
"system.listCommands": (): { [key: string]: CommandDef } => {
|
||||
@@ -47,9 +43,6 @@ export function systemSyscalls(
|
||||
"system.reloadPlugs": () => {
|
||||
return editor.reloadPlugs();
|
||||
},
|
||||
"sandbox.getServerLogs": (ctx) => {
|
||||
return editor.space.proxySyscall(ctx.plug, "sandbox.getLogs", []);
|
||||
},
|
||||
"system.getEnv": () => {
|
||||
return system.env;
|
||||
},
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { SysCallMapping } from "../../plugos/system.ts";
|
||||
import { YAML } from "../deps.ts";
|
||||
|
||||
export function yamlSyscalls(): SysCallMapping {
|
||||
return {
|
||||
"yaml.parse": (_ctx, text: string): any => {
|
||||
return YAML.parse(text);
|
||||
},
|
||||
"yaml.stringify": (_ctx, obj: any): string => {
|
||||
return YAML.stringify(obj);
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user