mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 21:21:10 +00:00
Place a sentinel object in the loadedFacadeModules cache before the Jiti sync load begins. Re-entrant calls (caused by circular facade references from constant exports evaluated at module-evaluation time) now receive the sentinel instead of recursing infinitely. Once the real module finishes loading, Object.assign() back-fills the sentinel so any references captured during the circular load phase see the final exports. The Jiti load is wrapped in try/catch: on failure the sentinel is removed from the cache so that subsequent retry attempts re-execute the load instead of silently returning an empty object. The function returns the sentinel (not the raw loaded module) to guarantee a single object identity for all callers, including those that captured a reference during the circular load phase. Also tightens the generic constraint from <T> to <T extends object> so Object.assign() is type-safe, and propagates the constraint to the test-utils callers in bundled-plugin-public-surface.ts. Fixes #57394
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { loadBundledPluginPublicSurfaceModuleSync } from "../plugin-sdk/facade-runtime.js";
|
|
import {
|
|
findBundledPluginMetadataById,
|
|
type BundledPluginMetadata,
|
|
} from "../plugins/bundled-plugin-metadata.js";
|
|
import { resolveLoaderPackageRoot } from "../plugins/sdk-alias.js";
|
|
|
|
const OPENCLAW_PACKAGE_ROOT =
|
|
resolveLoaderPackageRoot({
|
|
modulePath: fileURLToPath(import.meta.url),
|
|
moduleUrl: import.meta.url,
|
|
}) ?? fileURLToPath(new URL("../..", import.meta.url));
|
|
|
|
function findBundledPluginMetadata(pluginId: string): BundledPluginMetadata {
|
|
const metadata = findBundledPluginMetadataById(pluginId);
|
|
if (!metadata) {
|
|
throw new Error(`Unknown bundled plugin id: ${pluginId}`);
|
|
}
|
|
return metadata;
|
|
}
|
|
|
|
export function loadBundledPluginPublicSurfaceSync<T extends object>(params: {
|
|
pluginId: string;
|
|
artifactBasename: string;
|
|
}): T {
|
|
const metadata = findBundledPluginMetadata(params.pluginId);
|
|
return loadBundledPluginPublicSurfaceModuleSync<T>({
|
|
dirName: metadata.dirName,
|
|
artifactBasename: params.artifactBasename,
|
|
});
|
|
}
|
|
|
|
export function loadBundledPluginTestApiSync<T extends object>(pluginId: string): T {
|
|
return loadBundledPluginPublicSurfaceSync<T>({
|
|
pluginId,
|
|
artifactBasename: "test-api.js",
|
|
});
|
|
}
|
|
|
|
export function resolveRelativeBundledPluginPublicModuleId(params: {
|
|
fromModuleUrl: string;
|
|
pluginId: string;
|
|
artifactBasename: string;
|
|
}): string {
|
|
const metadata = findBundledPluginMetadata(params.pluginId);
|
|
const fromFilePath = fileURLToPath(params.fromModuleUrl);
|
|
const targetPath = path.resolve(
|
|
OPENCLAW_PACKAGE_ROOT,
|
|
"extensions",
|
|
metadata.dirName,
|
|
params.artifactBasename,
|
|
);
|
|
const relativePath = path
|
|
.relative(path.dirname(fromFilePath), targetPath)
|
|
.replaceAll(path.sep, "/");
|
|
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
}
|