SilverBullet pivot to become an offline-first PWA (#403)

This commit is contained in:
Zef Hemel
2023-05-23 20:53:53 +02:00
committed by GitHub
parent b256269897
commit 5f484bed57
389 changed files with 4484 additions and 291129 deletions
+4 -3
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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();
},
};
}
-10
View File
@@ -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
View File
@@ -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;
}
+12
View File
@@ -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);
},
};
}
+34
View File
@@ -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
View File
@@ -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;
}
-18
View File
@@ -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),
);
}
+13
View File
@@ -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();
},
};
}
+2 -9
View File
@@ -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;
},
+13
View File
@@ -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);
},
};
}