Plugins -> Plugs
This commit is contained in:
parent
e94d4d3253
commit
fd72374c7d
@ -11,9 +11,9 @@ export class FunctionWorker {
|
|||||||
private initCallback: any;
|
private initCallback: any;
|
||||||
private invokeResolve?: (result?: any) => void;
|
private invokeResolve?: (result?: any) => void;
|
||||||
private invokeReject?: (reason?: any) => void;
|
private invokeReject?: (reason?: any) => void;
|
||||||
private plugin: Plugin<any>;
|
private plug: Plug<any>;
|
||||||
|
|
||||||
constructor(plugin: Plugin<any>, pathPrefix: string, name: string) {
|
constructor(plug: Plug<any>, pathPrefix: string, name: string) {
|
||||||
let worker = window.Worker;
|
let worker = window.Worker;
|
||||||
this.worker = new worker("/function_worker.js");
|
this.worker = new worker("/function_worker.js");
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ export class FunctionWorker {
|
|||||||
this.inited = new Promise((resolve) => {
|
this.inited = new Promise((resolve) => {
|
||||||
this.initCallback = resolve;
|
this.initCallback = resolve;
|
||||||
});
|
});
|
||||||
this.plugin = plugin;
|
this.plug = plug;
|
||||||
}
|
}
|
||||||
|
|
||||||
async onmessage(evt: MessageEvent) {
|
async onmessage(evt: MessageEvent) {
|
||||||
@ -40,7 +40,7 @@ export class FunctionWorker {
|
|||||||
this.initCallback();
|
this.initCallback();
|
||||||
break;
|
break;
|
||||||
case "syscall":
|
case "syscall":
|
||||||
let result = await this.plugin.system.syscall(data.name, data.args);
|
let result = await this.plug.system.syscall(data.name, data.args);
|
||||||
|
|
||||||
this.worker.postMessage({
|
this.worker.postMessage({
|
||||||
type: "syscall-response",
|
type: "syscall-response",
|
||||||
@ -76,11 +76,11 @@ export class FunctionWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginLoader<HookT> {
|
export interface PlugLoader<HookT> {
|
||||||
load(name: string, manifest: Manifest<HookT>): Promise<void>;
|
load(name: string, manifest: Manifest<HookT>): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Plugin<HookT> {
|
export class Plug<HookT> {
|
||||||
pathPrefix: string;
|
pathPrefix: string;
|
||||||
system: System<HookT>;
|
system: System<HookT>;
|
||||||
private runningFunctions: Map<string, FunctionWorker>;
|
private runningFunctions: Map<string, FunctionWorker>;
|
||||||
@ -96,7 +96,7 @@ export class Plugin<HookT> {
|
|||||||
|
|
||||||
async load(manifest: Manifest<HookT>) {
|
async load(manifest: Manifest<HookT>) {
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
await this.system.pluginLoader.load(this.name, manifest);
|
await this.system.plugLoader.load(this.name, manifest);
|
||||||
await this.dispatchEvent("load");
|
await this.dispatchEvent("load");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,15 +136,15 @@ export class Plugin<HookT> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class System<HookT> {
|
export class System<HookT> {
|
||||||
protected plugins: Map<string, Plugin<HookT>>;
|
protected plugs: Map<string, Plug<HookT>>;
|
||||||
protected pathPrefix: string;
|
protected pathPrefix: string;
|
||||||
registeredSyscalls: SysCallMapping;
|
registeredSyscalls: SysCallMapping;
|
||||||
pluginLoader: PluginLoader<HookT>;
|
plugLoader: PlugLoader<HookT>;
|
||||||
|
|
||||||
constructor(PluginLoader: PluginLoader<HookT>, pathPrefix: string) {
|
constructor(plugLoader: PlugLoader<HookT>, pathPrefix: string) {
|
||||||
this.pluginLoader = PluginLoader;
|
this.plugLoader = plugLoader;
|
||||||
this.pathPrefix = pathPrefix;
|
this.pathPrefix = pathPrefix;
|
||||||
this.plugins = new Map<string, Plugin<HookT>>();
|
this.plugs = new Map<string, Plug<HookT>>();
|
||||||
this.registeredSyscalls = {};
|
this.registeredSyscalls = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,16 +167,16 @@ export class System<HookT> {
|
|||||||
return Promise.resolve(callback(...args));
|
return Promise.resolve(callback(...args));
|
||||||
}
|
}
|
||||||
|
|
||||||
async load(name: string, manifest: Manifest<HookT>): Promise<Plugin<HookT>> {
|
async load(name: string, manifest: Manifest<HookT>): Promise<Plug<HookT>> {
|
||||||
const plugin = new Plugin(this, this.pathPrefix, name);
|
const plug = new Plug(this, this.pathPrefix, name);
|
||||||
await plugin.load(manifest);
|
await plug.load(manifest);
|
||||||
this.plugins.set(name, plugin);
|
this.plugs.set(name, plug);
|
||||||
return plugin;
|
return plug;
|
||||||
}
|
}
|
||||||
|
|
||||||
async stop(): Promise<void[]> {
|
async stop(): Promise<void[]> {
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
Array.from(this.plugins.values()).map((plugin) => plugin.stop())
|
Array.from(this.plugs.values()).map((plug) => plug.stop())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ import { markdown } from "./markdown";
|
|||||||
import { IPageNavigator, PathPageNavigator } from "./navigator";
|
import { IPageNavigator, PathPageNavigator } from "./navigator";
|
||||||
import customMarkDown from "./parser";
|
import customMarkDown from "./parser";
|
||||||
import { BrowserSystem } from "./plugbox_browser/browser_system";
|
import { BrowserSystem } from "./plugbox_browser/browser_system";
|
||||||
import { Plugin } from "../../plugbox/src/runtime";
|
import { Plug } from "../../plugbox/src/runtime";
|
||||||
import { slashCommandRegexp } from "./types";
|
import { slashCommandRegexp } from "./types";
|
||||||
|
|
||||||
import reducer from "./reducer";
|
import reducer from "./reducer";
|
||||||
@ -80,7 +80,7 @@ export class Editor implements AppEventDispatcher {
|
|||||||
openPages: Map<string, PageState>;
|
openPages: Map<string, PageState>;
|
||||||
space: Space;
|
space: Space;
|
||||||
editorCommands: Map<string, AppCommand>;
|
editorCommands: Map<string, AppCommand>;
|
||||||
plugins: Plugin<NuggetHook>[];
|
plugs: Plug<NuggetHook>[];
|
||||||
indexer: Indexer;
|
indexer: Indexer;
|
||||||
navigationResolve?: (val: undefined) => void;
|
navigationResolve?: (val: undefined) => void;
|
||||||
pageNavigator: IPageNavigator;
|
pageNavigator: IPageNavigator;
|
||||||
@ -88,7 +88,7 @@ export class Editor implements AppEventDispatcher {
|
|||||||
constructor(space: Space, parent: Element) {
|
constructor(space: Space, parent: Element) {
|
||||||
this.editorCommands = new Map();
|
this.editorCommands = new Map();
|
||||||
this.openPages = new Map();
|
this.openPages = new Map();
|
||||||
this.plugins = [];
|
this.plugs = [];
|
||||||
this.space = space;
|
this.space = space;
|
||||||
this.viewState = initialViewState;
|
this.viewState = initialViewState;
|
||||||
this.viewDispatch = () => {};
|
this.viewDispatch = () => {};
|
||||||
@ -104,7 +104,7 @@ export class Editor implements AppEventDispatcher {
|
|||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
await this.loadPageList();
|
await this.loadPageList();
|
||||||
await this.loadPlugins();
|
await this.loadPlugs();
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|
||||||
this.pageNavigator.subscribe(async (pageName) => {
|
this.pageNavigator.subscribe(async (pageName) => {
|
||||||
@ -123,8 +123,8 @@ export class Editor implements AppEventDispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadPlugins() {
|
async loadPlugs() {
|
||||||
const system = new BrowserSystem<NuggetHook>("/plugin");
|
const system = new BrowserSystem<NuggetHook>("/plug");
|
||||||
system.registerSyscalls(
|
system.registerSyscalls(
|
||||||
dbSyscalls,
|
dbSyscalls,
|
||||||
editorSyscalls(this),
|
editorSyscalls(this),
|
||||||
@ -133,12 +133,12 @@ export class Editor implements AppEventDispatcher {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await system.bootServiceWorker();
|
await system.bootServiceWorker();
|
||||||
console.log("Now loading core plugin");
|
console.log("Now loading core plug");
|
||||||
let mainPlugin = await system.load("core", coreManifest);
|
let mainPlug = await system.load("core", coreManifest);
|
||||||
this.plugins.push(mainPlugin);
|
this.plugs.push(mainPlug);
|
||||||
this.editorCommands = new Map<string, AppCommand>();
|
this.editorCommands = new Map<string, AppCommand>();
|
||||||
for (let plugin of this.plugins) {
|
for (let plug of this.plugs) {
|
||||||
this.buildCommands(plugin);
|
this.buildCommands(plug);
|
||||||
}
|
}
|
||||||
this.viewDispatch({
|
this.viewDispatch({
|
||||||
type: "update-commands",
|
type: "update-commands",
|
||||||
@ -146,14 +146,14 @@ export class Editor implements AppEventDispatcher {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildCommands(plugin: Plugin<NuggetHook>) {
|
private buildCommands(plug: Plug<NuggetHook>) {
|
||||||
const cmds = plugin.manifest!.hooks.commands;
|
const cmds = plug.manifest!.hooks.commands;
|
||||||
for (let name in cmds) {
|
for (let name in cmds) {
|
||||||
let cmd = cmds[name];
|
let cmd = cmds[name];
|
||||||
this.editorCommands.set(name, {
|
this.editorCommands.set(name, {
|
||||||
command: cmd,
|
command: cmd,
|
||||||
run: async (arg): Promise<any> => {
|
run: async (arg): Promise<any> => {
|
||||||
return await plugin.invoke(cmd.invoke, [arg]);
|
return await plug.invoke(cmd.invoke, [arg]);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -162,10 +162,10 @@ export class Editor implements AppEventDispatcher {
|
|||||||
// TODO: Parallelize?
|
// TODO: Parallelize?
|
||||||
async dispatchAppEvent(name: AppEvent, data?: any): Promise<any[]> {
|
async dispatchAppEvent(name: AppEvent, data?: any): Promise<any[]> {
|
||||||
let results: any[] = [];
|
let results: any[] = [];
|
||||||
for (let plugin of this.plugins) {
|
for (let plug of this.plugs) {
|
||||||
let pluginResults = await plugin.dispatchEvent(name, data);
|
let plugResults = await plug.dispatchEvent(name, data);
|
||||||
if (pluginResults) {
|
if (plugResults) {
|
||||||
for (let result of pluginResults) {
|
for (let result of plugResults) {
|
||||||
results.push(result);
|
results.push(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ export class Editor implements AppEventDispatcher {
|
|||||||
closeBrackets(),
|
closeBrackets(),
|
||||||
autocompletion({
|
autocompletion({
|
||||||
override: [
|
override: [
|
||||||
this.pluginCompleter.bind(this),
|
this.plugCompleter.bind(this),
|
||||||
this.commandCompleter.bind(this),
|
this.commandCompleter.bind(this),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@ -304,7 +304,7 @@ export class Editor implements AppEventDispatcher {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async pluginCompleter(
|
async plugCompleter(
|
||||||
ctx: CompletionContext
|
ctx: CompletionContext
|
||||||
): Promise<CompletionResult | null> {
|
): Promise<CompletionResult | null> {
|
||||||
let allCompletionResults = await this.dispatchAppEvent("editor:complete");
|
let allCompletionResults = await this.dispatchAppEvent("editor:complete");
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { PluginLoader, System } from "../../../plugbox/src/runtime";
|
import { PlugLoader, System } from "../../../plugbox/src/runtime";
|
||||||
import { Manifest } from "../../../plugbox/src/types";
|
import { Manifest } from "../../../plugbox/src/types";
|
||||||
import { sleep } from "../util";
|
import { sleep } from "../util";
|
||||||
|
|
||||||
export class BrowserLoader<HookT> implements PluginLoader<HookT> {
|
export class BrowserLoader<HookT> implements PlugLoader<HookT> {
|
||||||
readonly pathPrefix: string;
|
readonly pathPrefix: string;
|
||||||
|
|
||||||
constructor(pathPrefix: string) {
|
constructor(pathPrefix: string) {
|
||||||
|
@ -2,7 +2,7 @@ import { Manifest } from "./types";
|
|||||||
|
|
||||||
import { openDB } from "idb";
|
import { openDB } from "idb";
|
||||||
|
|
||||||
const rootUrl = location.origin + "/plugin";
|
const rootUrl = location.origin + "/plug";
|
||||||
|
|
||||||
// Storing manifests in IndexedDB, y'all
|
// Storing manifests in IndexedDB, y'all
|
||||||
const db = openDB("manifests-store", undefined, {
|
const db = openDB("manifests-store", undefined, {
|
||||||
@ -64,13 +64,13 @@ self.addEventListener("fetch", (event: any) => {
|
|||||||
return await handlePut(req, path);
|
return await handlePut(req, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
let [pluginName, resourceType, functionName] = path.split("/");
|
let [plugName, resourceType, functionName] = path.split("/");
|
||||||
|
|
||||||
let manifest = await getManifest(pluginName);
|
let manifest = await getManifest(plugName);
|
||||||
|
|
||||||
if (!manifest) {
|
if (!manifest) {
|
||||||
// console.log("Ain't got", pluginName);
|
// console.log("Ain't got", plugName);
|
||||||
return new Response(`Plugin not loaded: ${pluginName}`, {
|
return new Response(`Plug not loaded: ${plugName}`, {
|
||||||
status: 404,
|
status: 404,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ window.addEventListener("message", async (event) => {
|
|||||||
let data = messageEvent.data;
|
let data = messageEvent.data;
|
||||||
if (data.type === "iframe_event") {
|
if (data.type === "iframe_event") {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.mainPlugin.dispatchEvent(data.data.event, data.data.data);
|
window.mainPlug.dispatchEvent(data.data.event, data.data.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user