*Heavily refactor plugin api, remove most methods for now
*Introduce event emitter2 which will be used as part of api *Use a proxy class to create a custom PluginAPI.registerMethod which will pass the lexical scoped plugin name
This commit is contained in:
parent
523fe07028
commit
2b5d3ef646
|
@ -38,6 +38,7 @@
|
||||||
"date-fns": "^2.28.0",
|
"date-fns": "^2.28.0",
|
||||||
"dotenv": "^16.0.1",
|
"dotenv": "^16.0.1",
|
||||||
"ethers": "^5.6.9",
|
"ethers": "^5.6.9",
|
||||||
|
"eventemitter2": "^6.4.9",
|
||||||
"express": "^4.18.1",
|
"express": "^4.18.1",
|
||||||
"fetch-blob": "https://github.com/LumeWeb/fetch-blob.git",
|
"fetch-blob": "https://github.com/LumeWeb/fetch-blob.git",
|
||||||
"hyperswarm": "^3.0.4",
|
"hyperswarm": "^3.0.4",
|
||||||
|
|
|
@ -1,36 +1,87 @@
|
||||||
import config from "../config.js";
|
import config from "../config.js";
|
||||||
|
import type { RPCServer } from "./rpc/server.js";
|
||||||
import { getRpcServer } from "./rpc/server.js";
|
import { getRpcServer } from "./rpc/server.js";
|
||||||
import type { PluginAPI, RPCMethod, Plugin } from "@lumeweb/relay-types";
|
import type { Plugin, RPCMethod } from "@lumeweb/relay-types";
|
||||||
import slugify from "slugify";
|
import slugify from "slugify";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import {
|
import type { Logger } from "loglevel";
|
||||||
getSavedSsl,
|
|
||||||
getSsl,
|
|
||||||
getSslContext,
|
|
||||||
saveSSl,
|
|
||||||
setSsl,
|
|
||||||
setSSlCheck,
|
|
||||||
setSslContext,
|
|
||||||
} from "./ssl.js";
|
|
||||||
import log from "loglevel";
|
|
||||||
import { getSeed } from "../lib/util.js";
|
import { getSeed } from "../lib/util.js";
|
||||||
import { getRouter, resetRouter, setRouter } from "./app.js";
|
|
||||||
import {
|
|
||||||
createIndependentFileSmall,
|
|
||||||
openIndependentFileSmall,
|
|
||||||
overwriteIndependentFileSmall,
|
|
||||||
} from "../lib/file";
|
|
||||||
import { setDnsProvider } from "./dns";
|
|
||||||
import pluginRpc from "./plugins/rpc";
|
import pluginRpc from "./plugins/rpc";
|
||||||
import pluginCore from "./plugins/core";
|
import pluginCore from "./plugins/core";
|
||||||
|
import type Config from "@lumeweb/cfg";
|
||||||
|
import EventEmitter2 from "eventemitter2";
|
||||||
|
import log from "loglevel";
|
||||||
|
|
||||||
let pluginApi: PluginApiManager;
|
let pluginAPIManager: PluginAPIManager;
|
||||||
|
let pluginAPI: PluginAPI;
|
||||||
|
|
||||||
const sanitizeName = (name: string) =>
|
const sanitizeName = (name: string) =>
|
||||||
slugify(name, { lower: true, strict: true });
|
slugify(name, { lower: true, strict: true });
|
||||||
|
|
||||||
export class PluginApiManager {
|
class PluginAPI extends EventEmitter2 {
|
||||||
|
private _server: RPCServer;
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
config,
|
||||||
|
logger,
|
||||||
|
server,
|
||||||
|
}: {
|
||||||
|
config: Config;
|
||||||
|
logger: Logger;
|
||||||
|
server: RPCServer;
|
||||||
|
}) {
|
||||||
|
super({
|
||||||
|
wildcard: true,
|
||||||
|
verboseMemoryLeak: true,
|
||||||
|
maxListeners: 0,
|
||||||
|
});
|
||||||
|
this._config = config;
|
||||||
|
this._logger = logger;
|
||||||
|
this._server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _config: Config;
|
||||||
|
|
||||||
|
get config(): Config {
|
||||||
|
return this._config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _logger: Logger;
|
||||||
|
|
||||||
|
get logger(): Logger {
|
||||||
|
return this._logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
get rpcServer(): RPCServer {
|
||||||
|
return this._server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public loadPlugin(
|
||||||
|
moduleName: string
|
||||||
|
): (moduleName: string) => Promise<Plugin> {
|
||||||
|
return getPluginAPIManager().loadPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
get seed(): Uint8Array {
|
||||||
|
return getSeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
registerMethod(methodName: string, method: RPCMethod): void {
|
||||||
|
throw new Error("not implemented and should not be called");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPluginAPI(): PluginAPI {
|
||||||
|
if (!pluginAPI) {
|
||||||
|
pluginAPI = new PluginAPI({ config, logger: log, server: getRpcServer() });
|
||||||
|
}
|
||||||
|
|
||||||
|
return pluginAPI as PluginAPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PluginAPIManager {
|
||||||
private registeredPlugins: Map<string, Plugin> = new Map<string, Plugin>();
|
private registeredPlugins: Map<string, Plugin> = new Map<string, Plugin>();
|
||||||
|
|
||||||
public async loadPlugin(moduleName: string): Promise<Plugin> {
|
public async loadPlugin(moduleName: string): Promise<Plugin> {
|
||||||
|
@ -73,60 +124,42 @@ export class PluginApiManager {
|
||||||
this.registeredPlugins.set(plugin.name, plugin);
|
this.registeredPlugins.set(plugin.name, plugin);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
plugin.plugin(this.getPluginAPI(plugin.name));
|
plugin.plugin(
|
||||||
|
// @ts-ignore
|
||||||
|
new Proxy<PluginAPI>(getPluginAPI(), {
|
||||||
|
get(target: PluginAPI, prop: string): any {
|
||||||
|
if (prop === "registerMethod") {
|
||||||
|
return (methodName: string, method: RPCMethod): void => {
|
||||||
|
return getRpcServer().registerMethod(
|
||||||
|
plugin.name,
|
||||||
|
methodName,
|
||||||
|
method
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return (target as any)[prop];
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPluginAPI(pluginName: string): PluginAPI {
|
|
||||||
return {
|
|
||||||
config,
|
|
||||||
registerMethod: (methodName: string, method: RPCMethod): void => {
|
|
||||||
getRpcServer().registerMethod(pluginName, methodName, method);
|
|
||||||
},
|
|
||||||
loadPlugin: getPluginAPI().loadPlugin.bind(getPluginAPI()),
|
|
||||||
getRpcServer,
|
|
||||||
ssl: {
|
|
||||||
setContext: setSslContext,
|
|
||||||
getContext: getSslContext,
|
|
||||||
getSaved: getSavedSsl,
|
|
||||||
set: setSsl,
|
|
||||||
get: getSsl,
|
|
||||||
save: saveSSl,
|
|
||||||
setCheck: setSSlCheck,
|
|
||||||
},
|
|
||||||
files: {
|
|
||||||
createIndependentFileSmall,
|
|
||||||
openIndependentFileSmall,
|
|
||||||
overwriteIndependentFileSmall,
|
|
||||||
},
|
|
||||||
dns: {
|
|
||||||
setProvider: setDnsProvider,
|
|
||||||
},
|
|
||||||
logger: log,
|
|
||||||
getSeed,
|
|
||||||
appRouter: {
|
|
||||||
get: getRouter,
|
|
||||||
set: setRouter,
|
|
||||||
reset: resetRouter,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPluginAPI(): PluginApiManager {
|
export function getPluginAPIManager(): PluginAPIManager {
|
||||||
if (!pluginApi) {
|
if (!pluginAPIManager) {
|
||||||
pluginApi = new PluginApiManager();
|
pluginAPIManager = new PluginAPIManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
return pluginApi as PluginApiManager;
|
return pluginAPIManager as PluginAPIManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadPlugins() {
|
export async function loadPlugins() {
|
||||||
const api = await getPluginAPI();
|
const api = getPluginAPIManager();
|
||||||
|
|
||||||
api.loadPluginInstance(pluginCore);
|
api.loadPluginInstance(pluginCore);
|
||||||
api.loadPluginInstance(pluginRpc);
|
api.loadPluginInstance(pluginRpc);
|
||||||
|
|
|
@ -674,6 +674,7 @@ __metadata:
|
||||||
date-fns: "npm:^2.28.0"
|
date-fns: "npm:^2.28.0"
|
||||||
dotenv: "npm:^16.0.1"
|
dotenv: "npm:^16.0.1"
|
||||||
ethers: "npm:^5.6.9"
|
ethers: "npm:^5.6.9"
|
||||||
|
eventemitter2: "npm:^6.4.9"
|
||||||
express: "npm:^4.18.1"
|
express: "npm:^4.18.1"
|
||||||
fetch-blob: "https://github.com/LumeWeb/fetch-blob.git"
|
fetch-blob: "https://github.com/LumeWeb/fetch-blob.git"
|
||||||
hyper-typings: "npm:^1.0.0"
|
hyper-typings: "npm:^1.0.0"
|
||||||
|
@ -2115,6 +2116,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"eventemitter2@npm:^6.4.9":
|
||||||
|
version: 6.4.9
|
||||||
|
resolution: "eventemitter2@npm:6.4.9"
|
||||||
|
checksum: c180cc0012389f2cd564cdfba949807175dd309b1d7f0900cfdfc5a97436a867a30964b94f86613ab237d960d52f7e4c85098c9c8ef6dc8ed29bbf4e79465d8b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"eventemitter3@npm:^4.0.7":
|
"eventemitter3@npm:^4.0.7":
|
||||||
version: 4.0.7
|
version: 4.0.7
|
||||||
resolution: "eventemitter3@npm:4.0.7"
|
resolution: "eventemitter3@npm:4.0.7"
|
||||||
|
|
Loading…
Reference in New Issue