You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
demoncord-rewrite/src/api/plugin.ts

98 lines
3.1 KiB

//TODO: separate currently running status from enabled on reload
//ugh am i gonna remake the internal plugin format again? (yes)
/*[plugin name]: {
enabled: Bool, //doubles as our running status (my explanation is too complex to fit in this comment so get fucked)
iife: String, //we can't store functions in iDB? well fuck you, I'll make plugin devs package to an iife string
desc: String //self-descriptory
//TODO: should we be saving this in a separate metadata object?
}*/
import { idb, nests } from "./common";
import logger from "./utils/logger";
const ctxNest: Nest<any> = nests.make(); //Plugin context nest (I would create this in index, but it's not a good idea to expose that)
let pluginNest: Nest<{ plugins: any }>;
const pluginEval = (iife: string) => (0, eval)(iife); //defined as a separate function in case we want to do more things on plugin eval later
async function savePlugin(
eve: string,
{ path, value }: { path: string[] | string; value: any }
) {
logger.debug(
["Plugins"],
`Got ${eve} event for plugin manager's nest with path ${path} and val ${value}`
);
await idb.set("demon", {
plugins: pluginNest.ghost.plugins
});
}
async function init() {
pluginNest = demon.summon("internal/nest"); //we don't have access to the global yet outside of the function
if (!(await idb.get("demon"))) {
await idb.set("demon", {
plugins: {} //we need to pre-create this i guess?
});
}
pluginNest.store.plugins = (await idb.get("demon")).plugins; //we do this before we setup our hook to avoid any potential conflicts
pluginNest.on(nests.Events.SET, savePlugin);
pluginNest.on(nests.Events.DELETE, savePlugin);
Object.keys(pluginNest.ghost.plugins).forEach((ele) => {
if (pluginNest.ghost.plugins[ele].enabled) {
const exports = pluginEval(pluginNest.ghost.plugins[ele].iife);
const ctx = exports.onStart(); //actually starts plugin
ctxNest.store[ele] = ctx;
pluginNest.store.plugins[ele].enabled = true; //for clarity
} else {
pluginNest.store.plugins[ele].enabled = false; //for clarity
}
});
}
function add(iife: string) {
const exports = pluginEval(iife);
logger.debug(["Plugins"], `Adding ${exports.meta.name}`);
pluginNest.store.plugins[exports.meta.name] = {
iife,
enabled: false,
desc: exports.meta.desc
};
}
function del(name: string) {
if (!!pluginNest.ghost.plugins[name]) {
logger.debug(["Plugins"], `Removing ${name}`);
delete pluginNest.store.plugins[name];
} else {
throw new Error("Can't delete plugin that doesn't exist. lol");
}
}
function toggle(name: string) {
if (!!pluginNest.ghost.plugins[name]) {
if (pluginNest.ghost.plugins[name].enabled) {
logger.debug(["Plugins"], `Disabling ${name}`);
const exports = pluginEval(pluginNest.ghost.plugins[name].iife);
exports.onStop(ctxNest.store[name]);
pluginNest.store.plugins[name].enabled = false;
} else {
logger.debug(["Plugins"], `Enabling ${name}`);
const exports = pluginEval(pluginNest.ghost.plugins[name].iife);
const ctx = exports.onStart();
ctxNest.store[name] = ctx;
pluginNest.store.plugins[name].enabled = true;
}
}
}
export { init, add, del, toggle };
export default {
init,
add,
del,
toggle
};