Register plugin UI exports eagerly

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
CodexCoderandPaperclip committed 2026-05-22 15:24:38 +00:00
1 parent 3af8b7f88b
commit c064507bd3
2 files changed
+50 -1

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
import { describe, expect, it } from "vitest";
import { _collectRegisterableExportNamesForTests } from "./slots";
describe("plugin slot export registration", () => {
it("keeps declared missing exports visible for diagnostics", () => {
const exports = _collectRegisterableExportNamesForTests(
{ Page: () => null },
new Set(["Page", "MissingRouteSidebar"]),
);
expect([...exports]).toEqual(["Page", "MissingRouteSidebar"]);
});
it("registers component-like module exports even when the current contribution did not declare them", () => {
const exports = _collectRegisterableExportNamesForTests(
{
Page: () => null,
RouteSidebar: () => null,
webComponentTag: "paperclip-widget",
metadata: { ignored: true },
count: 1,
default: () => null,
},
new Set(["Page"]),
);
expect(exports).toEqual(new Set(["Page", "RouteSidebar", "webComponentTag"]));
});
});
+21 -1
View File
@@ -177,6 +177,24 @@ export function resolveRegisteredPluginComponent(
return registry.get(buildRegistryKey(pluginKey, exportName)) ?? null;
}
function isRegisterablePluginExport(exported: unknown): boolean {
return typeof exported === "function" || typeof exported === "string";
}
function collectRegisterableExportNames(
mod: Record<string, unknown>,
declaredExports: Set<string>,
): Set<string> {
const exportNames = new Set(declaredExports);
for (const [exportName, exported] of Object.entries(mod)) {
if (exportName === "default") continue;
if (isRegisterablePluginExport(exported)) {
exportNames.add(exportName);
}
}
return exportNames;
}
// ---------------------------------------------------------------------------
// Plugin module dynamic import loader
// ---------------------------------------------------------------------------
@@ -471,7 +489,8 @@ async function loadPluginModule(contribution: PluginUiContribution): Promise<voi
}
}
for (const exportName of declaredExports) {
const exportNames = collectRegisterableExportNames(mod, declaredExports);
for (const exportName of exportNames) {
const exported = mod[exportName];
if (exported === undefined) {
console.warn(
@@ -910,3 +929,4 @@ export function _resetPluginModuleLoader(): void {
export const _applyJsxRuntimeKeyForTests = applyJsxRuntimeKey;
export const _createReactShimSourceForTests = createReactShimSource;
export const _rewriteBareSpecifiersForTests = rewriteBareSpecifiers;
export const _collectRegisterableExportNamesForTests = collectRegisterableExportNames;