Files
factorio-clusterio/packages/lib/src/loadPlugin.ts
T
7122cbccf8 Add typed hook system for plugins
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>
2026-09-11 22:49:09 +00:00

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>;
}