mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-03 15:10:23 +00:00
refactor: share bundled loader Jiti config helpers
This commit is contained in:
@@ -4,9 +4,8 @@ import path from "node:path";
|
||||
import { createJiti } from "jiti";
|
||||
import { openBoundaryFileSync } from "../../infra/boundary-file-read.js";
|
||||
import {
|
||||
buildPluginLoaderAliasMap,
|
||||
buildPluginLoaderJitiOptions,
|
||||
resolvePluginLoaderJitiTryNative,
|
||||
resolvePluginLoaderJitiConfig,
|
||||
} from "../../plugins/sdk-alias.js";
|
||||
|
||||
const nodeRequire = createRequire(import.meta.url);
|
||||
@@ -15,14 +14,12 @@ function createModuleLoader() {
|
||||
const jitiLoaders = new Map<string, ReturnType<typeof createJiti>>();
|
||||
|
||||
return (modulePath: string) => {
|
||||
const tryNative = resolvePluginLoaderJitiTryNative(modulePath, {
|
||||
const { tryNative, aliasMap, cacheKey } = resolvePluginLoaderJitiConfig({
|
||||
modulePath,
|
||||
argv1: process.argv[1],
|
||||
moduleUrl: import.meta.url,
|
||||
preferBuiltDist: true,
|
||||
});
|
||||
const aliasMap = buildPluginLoaderAliasMap(modulePath, process.argv[1], import.meta.url);
|
||||
const cacheKey = JSON.stringify({
|
||||
tryNative,
|
||||
aliasMap: Object.entries(aliasMap).toSorted(([left], [right]) => left.localeCompare(right)),
|
||||
});
|
||||
const cached = jitiLoaders.get(cacheKey);
|
||||
if (cached) {
|
||||
return cached;
|
||||
|
||||
@@ -8,10 +8,9 @@ import type { ChannelConfigSchema, ChannelPlugin } from "../channels/plugins/typ
|
||||
import { openBoundaryFileSync } from "../infra/boundary-file-read.js";
|
||||
import type { PluginRuntime } from "../plugins/runtime/types.js";
|
||||
import {
|
||||
buildPluginLoaderAliasMap,
|
||||
buildPluginLoaderJitiOptions,
|
||||
resolveLoaderPackageRoot,
|
||||
resolvePluginLoaderJitiTryNative,
|
||||
resolvePluginLoaderJitiConfig,
|
||||
} from "../plugins/sdk-alias.js";
|
||||
import type { AnyAgentTool, OpenClawPluginApi, PluginCommandContext } from "../plugins/types.js";
|
||||
|
||||
@@ -252,14 +251,12 @@ function resolveBundledEntryModulePath(importMetaUrl: string, specifier: string)
|
||||
}
|
||||
|
||||
function getJiti(modulePath: string) {
|
||||
const tryNative = resolvePluginLoaderJitiTryNative(modulePath, {
|
||||
const { tryNative, aliasMap, cacheKey } = resolvePluginLoaderJitiConfig({
|
||||
modulePath,
|
||||
argv1: process.argv[1],
|
||||
moduleUrl: import.meta.url,
|
||||
preferBuiltDist: true,
|
||||
});
|
||||
const aliasMap = buildPluginLoaderAliasMap(modulePath, process.argv[1], import.meta.url);
|
||||
const cacheKey = JSON.stringify({
|
||||
tryNative,
|
||||
aliasMap: Object.entries(aliasMap).toSorted(([left], [right]) => left.localeCompare(right)),
|
||||
});
|
||||
const cached = jitiLoaders.get(cacheKey);
|
||||
if (cached) {
|
||||
return cached;
|
||||
|
||||
@@ -6,9 +6,8 @@ import { openBoundaryFileSync } from "../infra/boundary-file-read.js";
|
||||
import { resolveBundledPluginsDir } from "../plugins/bundled-dir.js";
|
||||
import { resolveBundledPluginPublicSurfacePath } from "../plugins/public-surface-runtime.js";
|
||||
import {
|
||||
buildPluginLoaderAliasMap,
|
||||
buildPluginLoaderJitiOptions,
|
||||
resolvePluginLoaderJitiTryNative,
|
||||
resolvePluginLoaderJitiConfig,
|
||||
resolveLoaderPackageRoot,
|
||||
} from "../plugins/sdk-alias.js";
|
||||
|
||||
@@ -137,14 +136,12 @@ function resolveFacadeModuleLocation(params: {
|
||||
}
|
||||
|
||||
function getJiti(modulePath: string) {
|
||||
const tryNative = resolvePluginLoaderJitiTryNative(modulePath, {
|
||||
const { tryNative, aliasMap, cacheKey } = resolvePluginLoaderJitiConfig({
|
||||
modulePath,
|
||||
argv1: process.argv[1],
|
||||
moduleUrl: import.meta.url,
|
||||
preferBuiltDist: true,
|
||||
});
|
||||
const aliasMap = buildPluginLoaderAliasMap(modulePath, process.argv[1], import.meta.url);
|
||||
const cacheKey = JSON.stringify({
|
||||
tryNative,
|
||||
aliasMap: Object.entries(aliasMap).toSorted(([left], [right]) => left.localeCompare(right)),
|
||||
});
|
||||
const cached = jitiLoaders.get(cacheKey);
|
||||
if (cached) {
|
||||
return cached;
|
||||
|
||||
@@ -12,11 +12,7 @@ import type {
|
||||
PluginManifest,
|
||||
PluginManifestChannelConfig,
|
||||
} from "./manifest.js";
|
||||
import {
|
||||
buildPluginLoaderAliasMap,
|
||||
buildPluginLoaderJitiOptions,
|
||||
resolvePluginLoaderJitiTryNative,
|
||||
} from "./sdk-alias.js";
|
||||
import { buildPluginLoaderJitiOptions, resolvePluginLoaderJitiConfig } from "./sdk-alias.js";
|
||||
import type { PluginConfigUiHint } from "./types.js";
|
||||
|
||||
const PUBLIC_SURFACE_SOURCE_EXTENSIONS = [".ts", ".mts", ".js", ".mjs", ".cts", ".cjs"] as const;
|
||||
@@ -75,14 +71,12 @@ function resolveConfigSchemaExport(imported: Record<string, unknown>): ChannelCo
|
||||
}
|
||||
|
||||
function getJiti(modulePath: string) {
|
||||
const tryNative = resolvePluginLoaderJitiTryNative(modulePath, {
|
||||
const { tryNative, aliasMap, cacheKey } = resolvePluginLoaderJitiConfig({
|
||||
modulePath,
|
||||
argv1: process.argv[1],
|
||||
moduleUrl: import.meta.url,
|
||||
preferBuiltDist: true,
|
||||
});
|
||||
const aliasMap = buildPluginLoaderAliasMap(modulePath, process.argv[1], import.meta.url);
|
||||
const cacheKey = JSON.stringify({
|
||||
tryNative,
|
||||
aliasMap: Object.entries(aliasMap).toSorted(([left], [right]) => left.localeCompare(right)),
|
||||
});
|
||||
const cached = jitiLoaders.get(cacheKey);
|
||||
if (cached) {
|
||||
return cached;
|
||||
|
||||
@@ -8,7 +8,8 @@ import { resolveBundledPluginPublicSurfacePath } from "./public-surface-runtime.
|
||||
import {
|
||||
buildPluginLoaderAliasMap,
|
||||
buildPluginLoaderJitiOptions,
|
||||
resolvePluginLoaderJitiTryNative,
|
||||
isBundledPluginExtensionPath,
|
||||
resolvePluginLoaderJitiConfig,
|
||||
resolveLoaderPackageRoot,
|
||||
} from "./sdk-alias.js";
|
||||
|
||||
@@ -70,18 +71,16 @@ function resolvePublicSurfaceLocation(params: {
|
||||
}
|
||||
|
||||
function getJiti(modulePath: string) {
|
||||
const tryNative = resolvePluginLoaderJitiTryNative(modulePath, {
|
||||
const { tryNative, aliasMap, cacheKey } = resolvePluginLoaderJitiConfig({
|
||||
modulePath,
|
||||
argv1: process.argv[1],
|
||||
moduleUrl: import.meta.url,
|
||||
preferBuiltDist: true,
|
||||
});
|
||||
const sharedLoader = getSharedBundledPublicSurfaceJiti(modulePath, tryNative);
|
||||
if (sharedLoader) {
|
||||
return sharedLoader;
|
||||
}
|
||||
const aliasMap = buildPluginLoaderAliasMap(modulePath, process.argv[1], import.meta.url);
|
||||
const cacheKey = JSON.stringify({
|
||||
tryNative,
|
||||
aliasMap: Object.entries(aliasMap).toSorted(([left], [right]) => left.localeCompare(right)),
|
||||
});
|
||||
const cached = jitiLoaders.get(cacheKey);
|
||||
if (cached) {
|
||||
return cached;
|
||||
@@ -99,18 +98,13 @@ function getSharedBundledPublicSurfaceJiti(
|
||||
tryNative: boolean,
|
||||
): ReturnType<typeof createJiti> | null {
|
||||
const bundledPluginsDir = resolveBundledPluginsDir();
|
||||
const normalizedModulePath = path.resolve(modulePath);
|
||||
const sharedRoots = [
|
||||
bundledPluginsDir ? path.resolve(bundledPluginsDir) : null,
|
||||
path.join(OPENCLAW_PACKAGE_ROOT, "extensions"),
|
||||
path.join(OPENCLAW_PACKAGE_ROOT, "dist", "extensions"),
|
||||
path.join(OPENCLAW_PACKAGE_ROOT, "dist-runtime", "extensions"),
|
||||
].filter((root): root is string => typeof root === "string");
|
||||
const isBundledPublicSurface = sharedRoots.some(
|
||||
(root) =>
|
||||
normalizedModulePath === root || normalizedModulePath.startsWith(`${root}${path.sep}`),
|
||||
);
|
||||
if (!isBundledPublicSurface) {
|
||||
if (
|
||||
!isBundledPluginExtensionPath({
|
||||
modulePath,
|
||||
openClawPackageRoot: OPENCLAW_PACKAGE_ROOT,
|
||||
...(bundledPluginsDir ? { bundledPluginsDir } : {}),
|
||||
})
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const cacheKey = tryNative ? "bundled:native" : "bundled:source";
|
||||
|
||||
@@ -10,10 +10,13 @@ import {
|
||||
import { withEnv } from "../test-utils/env.js";
|
||||
import {
|
||||
buildPluginLoaderAliasMap,
|
||||
createPluginLoaderJitiCacheKey,
|
||||
buildPluginLoaderJitiOptions,
|
||||
isBundledPluginExtensionPath,
|
||||
listPluginSdkAliasCandidates,
|
||||
listPluginSdkExportedSubpaths,
|
||||
normalizeJitiAliasTargetPath,
|
||||
resolvePluginLoaderJitiConfig,
|
||||
resolvePluginLoaderJitiTryNative,
|
||||
resolveExtensionApiAlias,
|
||||
resolvePluginRuntimeModulePath,
|
||||
@@ -732,6 +735,64 @@ describe("plugin sdk alias helpers", () => {
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps plugin loader Jiti cache keys stable across alias insertion order", () => {
|
||||
expect(
|
||||
createPluginLoaderJitiCacheKey({
|
||||
tryNative: true,
|
||||
aliasMap: {
|
||||
zeta: "/repo/zeta.js",
|
||||
alpha: "/repo/alpha.js",
|
||||
},
|
||||
}),
|
||||
).toBe(
|
||||
createPluginLoaderJitiCacheKey({
|
||||
tryNative: true,
|
||||
aliasMap: {
|
||||
alpha: "/repo/alpha.js",
|
||||
zeta: "/repo/zeta.js",
|
||||
},
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("returns plugin loader Jiti config with stable cache keys", () => {
|
||||
const first = resolvePluginLoaderJitiConfig({
|
||||
modulePath: `/repo/${bundledDistPluginFile("browser", "index.js")}`,
|
||||
argv1: "/repo/openclaw.mjs",
|
||||
moduleUrl: "file:///repo/src/plugins/public-surface-loader.ts",
|
||||
preferBuiltDist: true,
|
||||
});
|
||||
const second = resolvePluginLoaderJitiConfig({
|
||||
modulePath: `/repo/${bundledDistPluginFile("browser", "index.js")}`,
|
||||
argv1: "/repo/openclaw.mjs",
|
||||
moduleUrl: "file:///repo/src/plugins/public-surface-loader.ts",
|
||||
preferBuiltDist: true,
|
||||
});
|
||||
|
||||
expect(second).toEqual(first);
|
||||
});
|
||||
|
||||
it("detects bundled plugin extension paths across source and dist roots", () => {
|
||||
expect(
|
||||
isBundledPluginExtensionPath({
|
||||
modulePath: "/repo/extensions/demo/api.js",
|
||||
openClawPackageRoot: "/repo",
|
||||
}),
|
||||
).toBe(true);
|
||||
expect(
|
||||
isBundledPluginExtensionPath({
|
||||
modulePath: "/repo/dist/extensions/demo/api.js",
|
||||
openClawPackageRoot: "/repo",
|
||||
}),
|
||||
).toBe(true);
|
||||
expect(
|
||||
isBundledPluginExtensionPath({
|
||||
modulePath: "/repo/vendor/demo/api.js",
|
||||
openClawPackageRoot: "/repo",
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("normalizes Windows alias targets before handing them to Jiti", () => {
|
||||
const originalPlatform = process.platform;
|
||||
Object.defineProperty(process, "platform", {
|
||||
|
||||
@@ -441,13 +441,13 @@ export function buildPluginLoaderJitiOptions(aliasMap: Record<string, string>) {
|
||||
};
|
||||
}
|
||||
|
||||
function isNativeJitiDisabledByRuntime(): boolean {
|
||||
function supportsNativeJitiRuntime(): boolean {
|
||||
const versions = process.versions as { bun?: string };
|
||||
return typeof versions.bun === "string" || process.platform === "win32";
|
||||
return typeof versions.bun !== "string" && process.platform !== "win32";
|
||||
}
|
||||
|
||||
export function shouldPreferNativeJiti(modulePath: string): boolean {
|
||||
if (isNativeJitiDisabledByRuntime()) {
|
||||
if (!supportsNativeJitiRuntime()) {
|
||||
return false;
|
||||
}
|
||||
switch (path.extname(modulePath).toLowerCase()) {
|
||||
@@ -467,11 +467,65 @@ export function resolvePluginLoaderJitiTryNative(
|
||||
preferBuiltDist?: boolean;
|
||||
},
|
||||
): boolean {
|
||||
if (isNativeJitiDisabledByRuntime()) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
shouldPreferNativeJiti(modulePath) ||
|
||||
(options?.preferBuiltDist === true && modulePath.includes(`${path.sep}dist${path.sep}`))
|
||||
(supportsNativeJitiRuntime() &&
|
||||
options?.preferBuiltDist === true &&
|
||||
modulePath.includes(`${path.sep}dist${path.sep}`))
|
||||
);
|
||||
}
|
||||
|
||||
export function createPluginLoaderJitiCacheKey(params: {
|
||||
tryNative: boolean;
|
||||
aliasMap: Record<string, string>;
|
||||
}): string {
|
||||
return JSON.stringify({
|
||||
tryNative: params.tryNative,
|
||||
aliasMap: Object.entries(params.aliasMap).toSorted(([left], [right]) =>
|
||||
left.localeCompare(right),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
export function resolvePluginLoaderJitiConfig(params: {
|
||||
modulePath: string;
|
||||
argv1?: string;
|
||||
moduleUrl: string;
|
||||
preferBuiltDist?: boolean;
|
||||
}): {
|
||||
tryNative: boolean;
|
||||
aliasMap: Record<string, string>;
|
||||
cacheKey: string;
|
||||
} {
|
||||
const tryNative = resolvePluginLoaderJitiTryNative(
|
||||
params.modulePath,
|
||||
params.preferBuiltDist ? { preferBuiltDist: true } : {},
|
||||
);
|
||||
const aliasMap = buildPluginLoaderAliasMap(params.modulePath, params.argv1, params.moduleUrl);
|
||||
return {
|
||||
tryNative,
|
||||
aliasMap,
|
||||
cacheKey: createPluginLoaderJitiCacheKey({
|
||||
tryNative,
|
||||
aliasMap,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export function isBundledPluginExtensionPath(params: {
|
||||
modulePath: string;
|
||||
openClawPackageRoot: string;
|
||||
bundledPluginsDir?: string;
|
||||
}): boolean {
|
||||
const normalizedModulePath = path.resolve(params.modulePath);
|
||||
const roots = [
|
||||
params.bundledPluginsDir ? path.resolve(params.bundledPluginsDir) : null,
|
||||
path.join(params.openClawPackageRoot, "extensions"),
|
||||
path.join(params.openClawPackageRoot, "dist", "extensions"),
|
||||
path.join(params.openClawPackageRoot, "dist-runtime", "extensions"),
|
||||
].filter((root): root is string => typeof root === "string");
|
||||
return roots.some(
|
||||
(root) =>
|
||||
normalizedModulePath === root || normalizedModulePath.startsWith(`${root}${path.sep}`),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user