fix(plugin-sdk): lazily load legacy root alias

This commit is contained in:
Gustavo Madeira Santana
2026-03-08 17:13:46 -04:00
parent 09acbe6528
commit 5889a2e98e
2 changed files with 174 additions and 12 deletions

View File

@@ -108,26 +108,94 @@ const fastExports = {
resolveControlCommandGate,
};
const monolithic = tryLoadMonolithicSdk();
const rootExports =
monolithic && typeof monolithic === "object"
? {
...monolithic,
...fastExports,
}
: { ...fastExports };
const target = { ...fastExports };
let rootExports = null;
Object.defineProperty(rootExports, "__esModule", {
function getMonolithicSdk() {
const loaded = tryLoadMonolithicSdk();
if (loaded && typeof loaded === "object") {
return loaded;
}
return null;
}
function getExportValue(prop) {
if (Reflect.has(target, prop)) {
return Reflect.get(target, prop);
}
const monolithic = getMonolithicSdk();
if (!monolithic) {
return undefined;
}
return Reflect.get(monolithic, prop);
}
function getExportDescriptor(prop) {
const ownDescriptor = Reflect.getOwnPropertyDescriptor(target, prop);
if (ownDescriptor) {
return ownDescriptor;
}
const monolithic = getMonolithicSdk();
if (!monolithic) {
return undefined;
}
const descriptor = Reflect.getOwnPropertyDescriptor(monolithic, prop);
if (!descriptor) {
return undefined;
}
// Proxy invariants require descriptors returned for dynamic properties to be configurable.
return {
...descriptor,
configurable: true,
};
}
rootExports = new Proxy(target, {
get(_target, prop, receiver) {
if (Reflect.has(target, prop)) {
return Reflect.get(target, prop, receiver);
}
return getExportValue(prop);
},
has(_target, prop) {
if (Reflect.has(target, prop)) {
return true;
}
const monolithic = getMonolithicSdk();
return monolithic ? Reflect.has(monolithic, prop) : false;
},
ownKeys() {
const keys = new Set(Reflect.ownKeys(target));
const monolithic = getMonolithicSdk();
if (monolithic) {
for (const key of Reflect.ownKeys(monolithic)) {
if (!keys.has(key)) {
keys.add(key);
}
}
}
return [...keys];
},
getOwnPropertyDescriptor(_target, prop) {
return getExportDescriptor(prop);
},
});
Object.defineProperty(target, "__esModule", {
configurable: true,
enumerable: false,
writable: false,
value: true,
});
Object.defineProperty(rootExports, "default", {
Object.defineProperty(target, "default", {
configurable: true,
enumerable: false,
writable: false,
value: rootExports,
get() {
return rootExports;
},
});
module.exports = rootExports;

View File

@@ -1,8 +1,14 @@
import fs from "node:fs";
import { createRequire } from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
import vm from "node:vm";
import { describe, expect, it } from "vitest";
const require = createRequire(import.meta.url);
const rootSdk = require("./root-alias.cjs") as Record<string, unknown>;
const rootAliasPath = fileURLToPath(new URL("./root-alias.cjs", import.meta.url));
const rootAliasSource = fs.readFileSync(rootAliasPath, "utf-8");
type EmptySchema = {
safeParse: (value: unknown) =>
@@ -13,6 +19,64 @@ type EmptySchema = {
};
};
function loadRootAliasWithStubs(options?: {
distExists?: boolean;
monolithicExports?: Record<string | symbol, unknown>;
}) {
let createJitiCalls = 0;
let jitiLoadCalls = 0;
const loadedSpecifiers: string[] = [];
const monolithicExports = options?.monolithicExports ?? {
slowHelper: () => "loaded",
};
const wrapper = vm.runInNewContext(
`(function (exports, require, module, __filename, __dirname) {${rootAliasSource}\n})`,
{},
{ filename: rootAliasPath },
) as (
exports: Record<string, unknown>,
require: NodeJS.Require,
module: { exports: Record<string, unknown> },
__filename: string,
__dirname: string,
) => void;
const module = { exports: {} as Record<string, unknown> };
const localRequire = ((id: string) => {
if (id === "node:path") {
return path;
}
if (id === "node:fs") {
return {
existsSync: () => options?.distExists ?? false,
};
}
if (id === "jiti") {
return {
createJiti() {
createJitiCalls += 1;
return (specifier: string) => {
jitiLoadCalls += 1;
loadedSpecifiers.push(specifier);
return monolithicExports;
};
},
};
}
throw new Error(`unexpected require: ${id}`);
}) as NodeJS.Require;
wrapper(module.exports, localRequire, module, rootAliasPath, path.dirname(rootAliasPath));
return {
moduleExports: module.exports,
get createJitiCalls() {
return createJitiCalls;
},
get jitiLoadCalls() {
return jitiLoadCalls;
},
loadedSpecifiers,
};
}
describe("plugin-sdk root alias", () => {
it("exposes the fast empty config schema helper", () => {
const factory = rootSdk.emptyPluginConfigSchema as (() => EmptySchema) | undefined;
@@ -27,6 +91,36 @@ describe("plugin-sdk root alias", () => {
expect(parsed.success).toBe(false);
});
it("does not load the monolithic sdk for fast helpers", () => {
const lazyModule = loadRootAliasWithStubs();
const lazyRootSdk = lazyModule.moduleExports;
const factory = lazyRootSdk.emptyPluginConfigSchema as (() => EmptySchema) | undefined;
expect(lazyModule.createJitiCalls).toBe(0);
expect(lazyModule.jitiLoadCalls).toBe(0);
expect(typeof factory).toBe("function");
expect(factory?.().safeParse({})).toEqual({ success: true, data: {} });
expect(lazyModule.createJitiCalls).toBe(0);
expect(lazyModule.jitiLoadCalls).toBe(0);
});
it("loads legacy root exports on demand and preserves reflection", () => {
const lazyModule = loadRootAliasWithStubs({
monolithicExports: {
slowHelper: () => "loaded",
},
});
const lazyRootSdk = lazyModule.moduleExports;
expect(lazyModule.createJitiCalls).toBe(0);
expect("slowHelper" in lazyRootSdk).toBe(true);
expect(lazyModule.createJitiCalls).toBe(1);
expect(lazyModule.jitiLoadCalls).toBe(1);
expect((lazyRootSdk.slowHelper as () => string)()).toBe("loaded");
expect(Object.keys(lazyRootSdk)).toContain("slowHelper");
expect(Object.getOwnPropertyDescriptor(lazyRootSdk, "slowHelper")).toBeDefined();
});
it("loads legacy root exports through the merged root wrapper", { timeout: 240_000 }, () => {
expect(typeof rootSdk.resolveControlCommandGate).toBe("function");
expect(typeof rootSdk.default).toBe("object");