mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 23:04:52 +09:00
Replace invokeHook and the per plugin on* methods with AsyncHook collections on the controller, host, instance, clusterioctl and web control objects. Plugin entrypoints export a default function that receives a load context and attaches handlers to the hooks it needs. Class exports still load through fromContext with a deprecation warning. The create templates and docs use the entrypoint function. This is clusterio/clusterio#921 recreated on top of master after the ESM migration and the PluginDeclaration permissions change. Closes #730 Co-Authored-By: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
55 lines
1.4 KiB
TypeScript
55 lines
1.4 KiB
TypeScript
// Contained in its own file to allow use within web build
|
|
import type { PluginDeclaration, PluginType, PluginLoadContext, PluginClass } from "./plugin.js";
|
|
|
|
|
|
export async function loadPluginEntrypoint<
|
|
Context extends object,
|
|
Info extends PluginDeclaration
|
|
>(
|
|
pluginInfo: Info,
|
|
pluginType: PluginType,
|
|
context: PluginLoadContext<Context, Info>,
|
|
module: Record<string, unknown>
|
|
) {
|
|
const init = module.default;
|
|
|
|
if (typeof init !== "function") {
|
|
throw new Error(`Expected ${pluginType} plugin ${pluginInfo.name} to export a default function`);
|
|
}
|
|
|
|
await init(context);
|
|
}
|
|
|
|
export async function loadPluginClass<
|
|
Context extends object,
|
|
Class extends PluginClass<Context, Info>,
|
|
Info extends PluginDeclaration
|
|
>(
|
|
pluginInfo: Info,
|
|
pluginType: PluginType,
|
|
context: PluginLoadContext<Context, Info>,
|
|
module: Record<string, unknown>,
|
|
exportName: string,
|
|
baseClass: Class
|
|
) {
|
|
const pluginClass = module[exportName];
|
|
|
|
if (typeof pluginClass !== "function") {
|
|
throw new Error(`Expected ${pluginType} plugin ${pluginInfo.name} to export a class named ${exportName}`);
|
|
}
|
|
|
|
if (!(pluginClass.prototype instanceof baseClass)) {
|
|
throw new Error(`Expected ${exportName} exported from ${pluginInfo.name} to extend ${baseClass.name}`);
|
|
}
|
|
|
|
const plugin = (pluginClass as Class).fromContext(context);
|
|
try {
|
|
await plugin.init();
|
|
} catch (err) {
|
|
plugin.detachHooks();
|
|
throw err;
|
|
}
|
|
|
|
return plugin as InstanceType<Class>;
|
|
}
|