Files
openclaw/src/plugins/jiti-loader-cache.ts
Effet 75c9b216e5 fixup! perf(plugins): native-require fast path respects tryNative=false
Review feedback from @chatgpt-codex-connector (P1): callers that pass
`tryNative: false` rely on jiti's alias rewriting (e.g.
`bundled-capability-runtime` in Vitest+dist mode narrows the SDK
slice through shim aliases). Route everything through the jiti
loader when `tryNative` is false so those rewrites still apply.

Review feedback from @greptile-apps (P2): forward the full argument
tuple through to the jiti fallback with `...rest` so any future
loader option argument is not silently dropped by the wrapper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 11:23:42 +01:00

107 lines
4.1 KiB
TypeScript

import { createJiti } from "jiti";
import { tryNativeRequireJavaScriptModule } from "./native-module-require.js";
import {
buildPluginLoaderJitiOptions,
createPluginLoaderJitiCacheKey,
resolvePluginLoaderJitiConfig,
type PluginSdkResolutionPreference,
} from "./sdk-alias.js";
export type PluginJitiLoader = ReturnType<typeof createJiti>;
export type PluginJitiLoaderFactory = typeof createJiti;
export type PluginJitiLoaderCache = Map<string, PluginJitiLoader>;
export function getCachedPluginJitiLoader(params: {
cache: PluginJitiLoaderCache;
modulePath: string;
importerUrl: string;
argvEntry?: string;
preferBuiltDist?: boolean;
jitiFilename?: string;
createLoader?: PluginJitiLoaderFactory;
aliasMap?: Record<string, string>;
tryNative?: boolean;
pluginSdkResolution?: PluginSdkResolutionPreference;
cacheScopeKey?: string;
}): PluginJitiLoader {
const jitiFilename = params.jitiFilename ?? params.modulePath;
if (params.cacheScopeKey) {
const scopedCacheKey = `${jitiFilename}::${params.cacheScopeKey}`;
const cached = params.cache.get(scopedCacheKey);
if (cached) {
return cached;
}
}
const hasAliasOverride = Boolean(params.aliasMap);
const hasTryNativeOverride = typeof params.tryNative === "boolean";
const defaultConfig =
hasAliasOverride || hasTryNativeOverride
? resolvePluginLoaderJitiConfig({
modulePath: params.modulePath,
argv1: params.argvEntry ?? process.argv[1],
moduleUrl: params.importerUrl,
...(params.preferBuiltDist ? { preferBuiltDist: true } : {}),
...(params.pluginSdkResolution
? { pluginSdkResolution: params.pluginSdkResolution }
: {}),
})
: null;
const canReuseDefaultCacheKey =
defaultConfig !== null &&
(!hasAliasOverride || params.aliasMap === defaultConfig.aliasMap) &&
(!hasTryNativeOverride || params.tryNative === defaultConfig.tryNative);
const resolved = defaultConfig
? {
tryNative: params.tryNative ?? defaultConfig.tryNative,
aliasMap: params.aliasMap ?? defaultConfig.aliasMap,
cacheKey: canReuseDefaultCacheKey ? defaultConfig.cacheKey : undefined,
}
: resolvePluginLoaderJitiConfig({
modulePath: params.modulePath,
argv1: params.argvEntry ?? process.argv[1],
moduleUrl: params.importerUrl,
...(params.preferBuiltDist ? { preferBuiltDist: true } : {}),
...(params.pluginSdkResolution ? { pluginSdkResolution: params.pluginSdkResolution } : {}),
});
const { tryNative, aliasMap } = resolved;
const cacheKey =
resolved.cacheKey ??
createPluginLoaderJitiCacheKey({
tryNative,
aliasMap,
});
const scopedCacheKey = `${jitiFilename}::${params.cacheScopeKey ?? cacheKey}`;
const cached = params.cache.get(scopedCacheKey);
if (cached) {
return cached;
}
const jitiLoader = (params.createLoader ?? createJiti)(jitiFilename, {
...buildPluginLoaderJitiOptions(aliasMap),
tryNative,
});
// When the caller has explicitly opted out of native loading (for example
// `bundled-capability-runtime` in Vitest+dist mode, which depends on
// jiti's alias rewriting to surface a narrow SDK slice), route every
// target through jiti so those alias rewrites still apply.
if (!tryNative) {
params.cache.set(scopedCacheKey, jitiLoader);
return jitiLoader;
}
// Otherwise prefer native require() for already-compiled JS artifacts
// (the bundled plugin public surfaces shipped in dist/). jiti's transform
// pipeline provides no value for output that is already plain JS and adds
// several seconds of per-load overhead on slower hosts. jiti still runs
// for TS / TSX sources and for the small set of require(esm) /
// async-module fallbacks `tryNativeRequireJavaScriptModule` declines to
// handle.
const loader = ((target: string, ...rest: unknown[]) => {
const native = tryNativeRequireJavaScriptModule(target);
if (native.ok) {
return native.moduleExport;
}
return (jitiLoader as (t: string, ...a: unknown[]) => unknown)(target, ...rest);
}) as PluginJitiLoader;
params.cache.set(scopedCacheKey, loader);
return loader;
}