Cleanup
This commit is contained in:
+2
-2
@@ -7,8 +7,8 @@
|
||||
"license": "MIT",
|
||||
"browserslist": "> 0.5%, last 2 versions, not dead",
|
||||
"scripts": {
|
||||
"start": "mkdir -p dist && cp src/function_worker.js dist/ && parcel",
|
||||
"build": "parcel build && cp src/function_worker.js dist/",
|
||||
"start": "parcel",
|
||||
"build": "parcel build",
|
||||
"clean": "rm -rf dist",
|
||||
"check-watch": "tsc --noEmit --watch"
|
||||
},
|
||||
|
||||
@@ -37,7 +37,7 @@ import { lineWrapper } from "./lineWrapper";
|
||||
import { markdown } from "./markdown";
|
||||
import { IPageNavigator, PathPageNavigator } from "./navigator";
|
||||
import customMarkDown from "./parser";
|
||||
import { BrowserSystem } from "./plugbox_browser/browser_system";
|
||||
import { System } from "../../plugbox/src/runtime";
|
||||
import { Plug } from "../../plugbox/src/runtime";
|
||||
import { slashCommandRegexp } from "./types";
|
||||
|
||||
@@ -124,7 +124,7 @@ export class Editor implements AppEventDispatcher {
|
||||
}
|
||||
|
||||
async loadPlugs() {
|
||||
const system = new BrowserSystem<NuggetHook>("/plug");
|
||||
const system = new System<NuggetHook>();
|
||||
system.registerSyscalls(
|
||||
dbSyscalls,
|
||||
editorSyscalls(this),
|
||||
@@ -132,7 +132,6 @@ export class Editor implements AppEventDispatcher {
|
||||
indexerSyscalls(this.indexer)
|
||||
);
|
||||
|
||||
await system.bootServiceWorker();
|
||||
console.log("Now loading core plug");
|
||||
let mainPlug = await system.load("core", coreManifest);
|
||||
this.plugs.push(mainPlug);
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
// Page: this file is not built by Parcel, it's simply copied to the distribution
|
||||
// The reason is that somehow Parcel cannot accept using importScripts otherwise
|
||||
function safeRun(fn) {
|
||||
fn().catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
|
||||
let func = null;
|
||||
let pendingRequests = {};
|
||||
|
||||
self.addEventListener("syscall", (event) => {
|
||||
let customEvent = event;
|
||||
let detail = customEvent.detail;
|
||||
pendingRequests[detail.id] = detail.callback;
|
||||
self.postMessage({
|
||||
type: "syscall",
|
||||
id: detail.id,
|
||||
name: detail.name,
|
||||
args: detail.args,
|
||||
});
|
||||
});
|
||||
|
||||
self.addEventListener("result", (event) => {
|
||||
let customEvent = event;
|
||||
self.postMessage({
|
||||
type: "result",
|
||||
result: customEvent.detail,
|
||||
});
|
||||
});
|
||||
|
||||
self.addEventListener("app-error", (event) => {
|
||||
let customEvent = event;
|
||||
self.postMessage({
|
||||
type: "error",
|
||||
reason: customEvent.detail,
|
||||
});
|
||||
});
|
||||
|
||||
self.addEventListener("message", (event) => {
|
||||
safeRun(async () => {
|
||||
let messageEvent = event;
|
||||
let data = messageEvent.data;
|
||||
switch (data.type) {
|
||||
case "boot":
|
||||
console.log("Booting", `${data.prefix}/function/${data.name}`);
|
||||
importScripts(`${data.prefix}/function/${data.name}`);
|
||||
self.postMessage({
|
||||
type: "inited",
|
||||
});
|
||||
break;
|
||||
case "invoke":
|
||||
self.dispatchEvent(
|
||||
new CustomEvent("invoke-function", {
|
||||
detail: {
|
||||
args: data.args || [],
|
||||
},
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "syscall-response":
|
||||
let id = data.id;
|
||||
const lookup = pendingRequests[id];
|
||||
if (!lookup) {
|
||||
console.log(
|
||||
"Current outstanding requests",
|
||||
pendingRequests,
|
||||
"looking up",
|
||||
id
|
||||
);
|
||||
throw Error("Invalid request id");
|
||||
}
|
||||
return await lookup(data.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,57 +0,0 @@
|
||||
import { PlugLoader, System } from "../../../plugbox/src/runtime";
|
||||
import { Manifest } from "../../../plugbox/src/types";
|
||||
import { sleep } from "../util";
|
||||
|
||||
export class BrowserLoader<HookT> implements PlugLoader<HookT> {
|
||||
readonly pathPrefix: string;
|
||||
|
||||
constructor(pathPrefix: string) {
|
||||
this.pathPrefix = pathPrefix;
|
||||
}
|
||||
|
||||
async load(name: string, manifest: Manifest<HookT>): Promise<void> {
|
||||
await fetch(`${this.pathPrefix}/${name}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(manifest),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class BrowserSystem<HookT> extends System<HookT> {
|
||||
constructor(pathPrefix: string) {
|
||||
super(new BrowserLoader(pathPrefix), pathPrefix);
|
||||
}
|
||||
// Service worker stuff
|
||||
async pollServiceWorkerActive() {
|
||||
for (let i = 0; i < 25; i++) {
|
||||
try {
|
||||
console.log("Pinging...", `${this.pathPrefix}/$ping`);
|
||||
let ping = await fetch(`${this.pathPrefix}/$ping`);
|
||||
let text = await ping.text();
|
||||
if (ping.status === 200 && text === "ok") {
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Not yet");
|
||||
}
|
||||
await sleep(100);
|
||||
}
|
||||
// Alright, something's messed up
|
||||
throw new Error("Worker not successfully activated");
|
||||
}
|
||||
|
||||
async bootServiceWorker() {
|
||||
// @ts-ignore
|
||||
let reg = navigator.serviceWorker.register(
|
||||
new URL("../plugbox_sw.ts", import.meta.url),
|
||||
{
|
||||
type: "module",
|
||||
scope: "/",
|
||||
}
|
||||
);
|
||||
|
||||
console.log("Service worker registered successfully");
|
||||
|
||||
await this.pollServiceWorkerActive();
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
import { Manifest } from "./types";
|
||||
|
||||
import { openDB } from "idb";
|
||||
|
||||
const rootUrl = location.origin + "/plug";
|
||||
|
||||
// Storing manifests in IndexedDB, y'all
|
||||
const db = openDB("manifests-store", undefined, {
|
||||
upgrade(db) {
|
||||
db.createObjectStore("manifests");
|
||||
},
|
||||
});
|
||||
|
||||
async function saveManifest(name: string, manifest: Manifest) {
|
||||
await (await db).put("manifests", manifest, name);
|
||||
}
|
||||
|
||||
async function getManifest(name: string): Promise<Manifest | undefined> {
|
||||
return (await (await db).get("manifests", name)) as Manifest | undefined;
|
||||
}
|
||||
|
||||
self.addEventListener("install", (event) => {
|
||||
console.log("Installing");
|
||||
// @ts-ignore
|
||||
self.skipWaiting();
|
||||
});
|
||||
|
||||
async function handlePut(req: Request, path: string) {
|
||||
console.log("Got manifest load for", path);
|
||||
let manifest = (await req.json()) as Manifest;
|
||||
await saveManifest(path, manifest);
|
||||
// loadedBundles.set(path, manifest);
|
||||
return new Response("ok");
|
||||
}
|
||||
|
||||
function wrapScript(functionName: string, code: string): string {
|
||||
return `const mod = ${code}
|
||||
|
||||
self.addEventListener('invoke-function', async e => {
|
||||
try {
|
||||
let result = await mod['${functionName}'](...e.detail.args);
|
||||
self.dispatchEvent(new CustomEvent('result', {detail: result}));
|
||||
} catch(e) {
|
||||
console.error(\`Error while running ${functionName}\`, e);
|
||||
self.dispatchEvent(new CustomEvent('app-error', {detail: e.message}));
|
||||
}
|
||||
});
|
||||
`;
|
||||
}
|
||||
|
||||
self.addEventListener("fetch", (event: any) => {
|
||||
const req = event.request;
|
||||
if (req.url.startsWith(rootUrl)) {
|
||||
let path = req.url.substring(rootUrl.length + 1);
|
||||
event.respondWith(
|
||||
(async () => {
|
||||
// console.log("Service worker is serving", path);
|
||||
if (path === `$ping`) {
|
||||
// console.log("Got ping");
|
||||
return new Response("ok");
|
||||
}
|
||||
|
||||
if (req.method === "PUT") {
|
||||
return await handlePut(req, path);
|
||||
}
|
||||
|
||||
let [plugName, resourceType, functionName] = path.split("/");
|
||||
|
||||
let manifest = await getManifest(plugName);
|
||||
|
||||
if (!manifest) {
|
||||
// console.log("Ain't got", plugName);
|
||||
return new Response(`Plug not loaded: ${plugName}`, {
|
||||
status: 404,
|
||||
});
|
||||
}
|
||||
|
||||
if (resourceType === "$manifest") {
|
||||
return new Response(JSON.stringify(manifest));
|
||||
}
|
||||
|
||||
if (resourceType === "function") {
|
||||
let func = manifest.functions[functionName];
|
||||
// console.log("Serving function", functionName, func);
|
||||
if (!func) {
|
||||
return new Response("Not found", {
|
||||
status: 404,
|
||||
});
|
||||
}
|
||||
return new Response(wrapScript(func.functionName!, func.code!), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-type": "application/javascript",
|
||||
},
|
||||
});
|
||||
}
|
||||
})()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener("activate", (event) => {
|
||||
// console.log("Now ready to pick up fetches");
|
||||
// @ts-ignore
|
||||
event.waitUntil(self.clients.claim());
|
||||
});
|
||||
|
||||
// console.log("I'm a service worker, look at me!", location.href);
|
||||
+8
-8
@@ -13,15 +13,15 @@ export interface Space {
|
||||
|
||||
export class HttpRemoteSpace implements Space {
|
||||
url: string;
|
||||
socket: Socket;
|
||||
socket?: Socket;
|
||||
|
||||
constructor(url: string, socket: Socket) {
|
||||
constructor(url: string, socket: Socket | null) {
|
||||
this.url = url;
|
||||
this.socket = socket;
|
||||
// this.socket = socket;
|
||||
|
||||
socket.on("connect", () => {
|
||||
console.log("connected via SocketIO", serverEvents.pageText);
|
||||
});
|
||||
// socket.on("connect", () => {
|
||||
// console.log("connected via SocketIO", serverEvents.pageText);
|
||||
// });
|
||||
}
|
||||
|
||||
async listPages(): Promise<PageMeta[]> {
|
||||
@@ -36,10 +36,10 @@ export class HttpRemoteSpace implements Space {
|
||||
}
|
||||
|
||||
async openPage(name: string) {
|
||||
this.socket.on(serverEvents.pageText, (pageName, text) => {
|
||||
this.socket!.on(serverEvents.pageText, (pageName, text) => {
|
||||
console.log("Got this", pageName, text);
|
||||
});
|
||||
this.socket.emit(serverEvents.openPage, "start");
|
||||
this.socket!.emit(serverEvents.openPage, "start");
|
||||
}
|
||||
|
||||
async readPage(name: string): Promise<{ text: string; meta: PageMeta }> {
|
||||
|
||||
@@ -14,14 +14,6 @@ export function safeRun(fn: () => Promise<void>) {
|
||||
});
|
||||
}
|
||||
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, ms);
|
||||
});
|
||||
}
|
||||
|
||||
export function isMacLike() {
|
||||
return /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user