Files
ThreadNet-Web/packages/module-api/src/loader.ts
T

56 lines
1.6 KiB
TypeScript
Raw Normal View History

2025-01-27 10:07:35 +00:00
/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { satisfies } from "semver";
2025-11-12 12:16:31 +00:00
import { type Api, isModule, type Module, type ModuleExport } from "./api";
2025-01-27 10:07:35 +00:00
2025-01-29 10:48:35 +00:00
/**
* Error thrown when a module is incompatible with the engine version.
* @public
*/
2025-01-27 10:07:35 +00:00
export class ModuleIncompatibleError extends Error {
2025-01-28 11:27:53 +00:00
public constructor(pluginVersion: string) {
2025-01-27 10:07:35 +00:00
super(`Plugin version ${pluginVersion} is incompatible with engine version ${__VERSION__}`);
}
}
2025-01-29 10:48:35 +00:00
/**
* A module loader for loading and starting modules.
* @public
*/
2025-01-27 10:07:35 +00:00
export class ModuleLoader {
2025-01-29 10:50:56 +00:00
private modules: Module[] = [];
private started = false;
2025-01-27 10:07:35 +00:00
public constructor(private api: Api) {}
public async load(moduleExport: ModuleExport): Promise<void> {
2025-01-29 10:50:56 +00:00
if (this.started) {
2025-01-27 10:07:35 +00:00
throw new Error("PluginEngine.start() has already been called");
}
if (!isModule(moduleExport)) {
throw new Error("Invalid plugin");
}
if (!satisfies(__VERSION__, moduleExport.default.moduleApiVersion)) {
throw new ModuleIncompatibleError(moduleExport.default.moduleApiVersion);
}
2025-01-28 11:27:53 +00:00
const { default: Module } = moduleExport;
2025-01-29 10:50:56 +00:00
this.modules.push(new Module(this.api));
2025-01-27 10:07:35 +00:00
}
public async start(): Promise<void> {
2025-01-29 10:50:56 +00:00
if (this.started) {
2025-01-27 10:07:35 +00:00
throw new Error("PluginEngine.start() has already been called");
}
2025-01-29 10:50:56 +00:00
this.started = true;
2025-01-27 10:07:35 +00:00
2025-01-29 10:50:56 +00:00
await Promise.all(this.modules.map((plugin) => plugin.load()));
2025-01-27 10:07:35 +00:00
}
}