perf(test): trim bundled channel bootstrap

This commit is contained in:
Peter Steinberger
2026-04-06 17:05:49 +01:00
parent 8b79cbcd06
commit 5d0e8336ab
4 changed files with 156 additions and 77 deletions

View File

@@ -3,7 +3,7 @@ import {
loadBundledEntryExportSync,
} from "openclaw/plugin-sdk/channel-entry-contract";
import type { PluginRuntime } from "./api.js";
import type { ResolvedNostrAccount } from "./src/types.js";
import type { ResolvedNostrAccount } from "./api.js";
function createNostrProfileHttpHandler() {
return loadBundledEntryExportSync<

View File

@@ -7,6 +7,7 @@ import { loadPluginManifestRegistry } from "../../plugins/manifest-registry.js";
afterEach(() => {
vi.resetModules();
vi.doUnmock("../../plugins/bundled-plugin-metadata.js");
vi.doUnmock("../../plugins/discovery.js");
vi.doUnmock("../../plugins/manifest-registry.js");
vi.doUnmock("../../infra/boundary-file-read.js");
@@ -19,18 +20,14 @@ describe("bundled channel entry shape guards", () => {
.map((plugin) => plugin.rootDir);
it("treats missing bundled discovery results as empty", async () => {
vi.doMock("../../plugins/discovery.js", () => ({
discoverOpenClawPlugins: () => ({
candidates: [],
diagnostics: [],
}),
}));
vi.doMock("../../plugins/manifest-registry.js", () => ({
loadPluginManifestRegistry: () => ({
plugins: [],
diagnostics: [],
}),
}));
vi.doMock("../../plugins/bundled-plugin-metadata.js", async (importOriginal) => {
const actual =
await importOriginal<typeof import("../../plugins/bundled-plugin-metadata.js")>();
return {
...actual,
listBundledPluginMetadata: () => [],
};
});
const bundled = await importFreshModule<typeof import("./bundled.js")>(
import.meta.url,
@@ -181,32 +178,28 @@ describe("bundled channel entry shape guards", () => {
const modulePath = path.join(pluginDir, "index.js");
fs.writeFileSync(modulePath, "export {};\n", "utf8");
vi.doMock("../../plugins/discovery.js", () => ({
discoverOpenClawPlugins: () => ({
candidates: [
vi.doMock("../../plugins/bundled-plugin-metadata.js", async (importOriginal) => {
const actual =
await importOriginal<typeof import("../../plugins/bundled-plugin-metadata.js")>();
return {
...actual,
listBundledPluginMetadata: () => [
{
rootDir: pluginDir,
source: modulePath,
packageManifest: { extensions: ["./index.js"] },
dirName: "alpha",
idHint: "alpha",
source: {
source: "./index.js",
built: "./index.js",
},
manifest: {
id: "alpha",
channels: ["alpha"],
},
},
],
diagnostics: [],
}),
}));
vi.doMock("../../plugins/manifest-registry.js", () => ({
loadPluginManifestRegistry: () => ({
plugins: [
{
id: "alpha",
rootDir: pluginDir,
origin: "bundled",
channels: ["alpha"],
source: modulePath,
},
],
diagnostics: [],
}),
}));
resolveBundledPluginGeneratedPath: () => modulePath,
};
});
vi.doMock("../../infra/boundary-file-read.js", () => ({
openBoundaryFileSync: ({ absolutePath }: { absolutePath: string }) => ({
ok: true,
@@ -214,6 +207,9 @@ describe("bundled channel entry shape guards", () => {
fd: fs.openSync(absolutePath, "r"),
}),
}));
vi.doMock("../../plugins/channel-catalog-registry.js", () => ({
listChannelCatalogEntries: () => [],
}));
let reentered = false;
vi.doMock("jiti", () => ({

View File

@@ -1,16 +1,17 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { createSubsystemLogger } from "../../logging/subsystem.js";
import type {
BundledChannelEntryContract,
BundledChannelSetupEntryContract,
} from "../../plugin-sdk/channel-entry-contract.js";
import { loadPluginManifestRegistry } from "../../plugins/manifest-registry.js";
import type { PluginRuntime } from "../../plugins/runtime/types.js";
import {
isJavaScriptModulePath,
loadChannelPluginModule,
resolveCompiledBundledModulePath,
} from "./module-loader.js";
listBundledPluginMetadata,
resolveBundledPluginGeneratedPath,
type BundledPluginMetadata,
} from "../../plugins/bundled-plugin-metadata.js";
import type { PluginRuntime } from "../../plugins/runtime/types.js";
import { isJavaScriptModulePath, loadChannelPluginModule } from "./module-loader.js";
import type { ChannelId, ChannelPlugin } from "./types.js";
type GeneratedBundledChannelEntry = {
@@ -20,6 +21,7 @@ type GeneratedBundledChannelEntry = {
};
const log = createSubsystemLogger("channels");
const OPENCLAW_PACKAGE_ROOT = path.resolve(fileURLToPath(new URL("../../..", import.meta.url)));
function resolveChannelPluginModuleEntry(
moduleExport: unknown,
@@ -71,53 +73,85 @@ function resolveChannelSetupModuleEntry(
return record as BundledChannelSetupEntryContract;
}
function resolveBundledChannelBoundaryRoot(params: {
metadata: BundledPluginMetadata;
modulePath: string;
}): string {
const distRoot = path.resolve(
OPENCLAW_PACKAGE_ROOT,
"dist",
"extensions",
params.metadata.dirName,
);
if (params.modulePath === distRoot || params.modulePath.startsWith(`${distRoot}${path.sep}`)) {
return distRoot;
}
return path.resolve(OPENCLAW_PACKAGE_ROOT, "extensions", params.metadata.dirName);
}
function loadGeneratedBundledChannelModule(params: {
metadata: BundledPluginMetadata;
entry: BundledPluginMetadata["source"] | BundledPluginMetadata["setupSource"];
}): unknown {
const modulePath = resolveBundledPluginGeneratedPath(OPENCLAW_PACKAGE_ROOT, params.entry);
if (!modulePath) {
throw new Error(`missing generated module for bundled channel ${params.metadata.manifest.id}`);
}
return loadChannelPluginModule({
modulePath,
rootDir: resolveBundledChannelBoundaryRoot({
metadata: params.metadata,
modulePath,
}),
boundaryRootDir: resolveBundledChannelBoundaryRoot({
metadata: params.metadata,
modulePath,
}),
shouldTryNativeRequire: (safePath) =>
safePath.includes(`${path.sep}dist${path.sep}`) && isJavaScriptModulePath(safePath),
});
}
function loadGeneratedBundledChannelEntries(): readonly GeneratedBundledChannelEntry[] {
const manifestRegistry = loadPluginManifestRegistry({ cache: false, config: {} });
const entries: GeneratedBundledChannelEntry[] = [];
for (const manifest of manifestRegistry.plugins) {
if (manifest.origin !== "bundled" || manifest.channels.length === 0) {
for (const metadata of listBundledPluginMetadata({
includeChannelConfigs: false,
includeSyntheticChannelConfigs: false,
})) {
if ((metadata.manifest.channels?.length ?? 0) === 0) {
continue;
}
try {
const sourcePath = resolveCompiledBundledModulePath(manifest.source);
const entry = resolveChannelPluginModuleEntry(
loadChannelPluginModule({
modulePath: sourcePath,
rootDir: manifest.rootDir,
boundaryRootDir: resolveCompiledBundledModulePath(manifest.rootDir),
shouldTryNativeRequire: (safePath) =>
safePath.includes(`${path.sep}dist${path.sep}`) && isJavaScriptModulePath(safePath),
loadGeneratedBundledChannelModule({
metadata,
entry: metadata.source,
}),
);
if (!entry) {
log.warn(
`[channels] bundled channel entry ${manifest.id} missing bundled-channel-entry contract from ${sourcePath}; skipping`,
`[channels] bundled channel entry ${metadata.manifest.id} missing bundled-channel-entry contract; skipping`,
);
continue;
}
const setupEntry = manifest.setupSource
const setupEntry = metadata.setupSource
? resolveChannelSetupModuleEntry(
loadChannelPluginModule({
modulePath: resolveCompiledBundledModulePath(manifest.setupSource),
rootDir: manifest.rootDir,
boundaryRootDir: resolveCompiledBundledModulePath(manifest.rootDir),
shouldTryNativeRequire: (safePath) =>
safePath.includes(`${path.sep}dist${path.sep}`) && isJavaScriptModulePath(safePath),
loadGeneratedBundledChannelModule({
metadata,
entry: metadata.setupSource,
}),
)
: null;
entries.push({
id: manifest.id,
id: metadata.manifest.id,
entry,
...(setupEntry ? { setupEntry } : {}),
});
} catch (error) {
const detail = error instanceof Error ? error.message : String(error);
log.warn(
`[channels] failed to load bundled channel ${manifest.id} from ${manifest.source}: ${detail}`,
);
log.warn(`[channels] failed to load bundled channel ${metadata.manifest.id}: ${detail}`);
}
}

View File

@@ -5,6 +5,7 @@ import { createJiti } from "jiti";
import JSON5 from "json5";
import { resolveConfigPath } from "../config/paths.js";
import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";
import { configMayNeedPluginAutoEnable } from "../config/plugin-auto-enable.shared.js";
import { getRuntimeConfigSnapshot } from "../config/runtime-snapshot.js";
import type { OpenClawConfig } from "../config/types.js";
import { openBoundaryFileSync } from "../infra/boundary-file-read.js";
@@ -45,6 +46,15 @@ const loadedFacadeModules = new Map<string, unknown>();
const loadedFacadePluginIds = new Set<string>();
const OPENCLAW_SOURCE_EXTENSIONS_ROOT = path.resolve(OPENCLAW_PACKAGE_ROOT, "extensions");
let cachedBoundaryRawConfig: OpenClawConfig | undefined;
let cachedBoundaryResolvedConfigKey: string | undefined;
let cachedBoundaryConfigFileState:
| {
configPath: string;
mtimeMs: number;
size: number;
rawConfig: OpenClawConfig;
}
| undefined;
let cachedBoundaryResolvedConfig:
| {
rawConfig: OpenClawConfig;
@@ -216,36 +226,72 @@ function getJiti(modulePath: string) {
return loader;
}
function readFacadeBoundaryConfigSafely(): OpenClawConfig {
function readFacadeBoundaryConfigSafely(): {
rawConfig: OpenClawConfig;
cacheKey?: string;
} {
try {
const runtimeSnapshot = getRuntimeConfigSnapshot();
if (runtimeSnapshot) {
return runtimeSnapshot;
return { rawConfig: runtimeSnapshot };
}
const configPath = resolveConfigPath();
if (!fs.existsSync(configPath)) {
return EMPTY_FACADE_BOUNDARY_CONFIG;
return { rawConfig: EMPTY_FACADE_BOUNDARY_CONFIG, cacheKey: `missing:${configPath}` };
}
const stat = fs.statSync(configPath);
if (
cachedBoundaryConfigFileState &&
cachedBoundaryConfigFileState.configPath === configPath &&
cachedBoundaryConfigFileState.mtimeMs === stat.mtimeMs &&
cachedBoundaryConfigFileState.size === stat.size
) {
return {
rawConfig: cachedBoundaryConfigFileState.rawConfig,
cacheKey: `file:${configPath}:${stat.mtimeMs}:${stat.size}`,
};
}
const raw = fs.readFileSync(configPath, "utf8");
const parsed = JSON5.parse(raw);
return parsed && typeof parsed === "object"
? (parsed as OpenClawConfig)
: EMPTY_FACADE_BOUNDARY_CONFIG;
const rawConfig =
parsed && typeof parsed === "object"
? (parsed as OpenClawConfig)
: EMPTY_FACADE_BOUNDARY_CONFIG;
cachedBoundaryConfigFileState = {
configPath,
mtimeMs: stat.mtimeMs,
size: stat.size,
rawConfig,
};
return {
rawConfig,
cacheKey: `file:${configPath}:${stat.mtimeMs}:${stat.size}`,
};
} catch {
return EMPTY_FACADE_BOUNDARY_CONFIG;
return { rawConfig: EMPTY_FACADE_BOUNDARY_CONFIG };
}
}
function getFacadeBoundaryResolvedConfig() {
const rawConfig = readFacadeBoundaryConfigSafely();
if (cachedBoundaryResolvedConfig && cachedBoundaryRawConfig === rawConfig) {
const readResult = readFacadeBoundaryConfigSafely();
const { rawConfig } = readResult;
if (
cachedBoundaryResolvedConfig &&
((readResult.cacheKey && cachedBoundaryResolvedConfigKey === readResult.cacheKey) ||
(!readResult.cacheKey && cachedBoundaryRawConfig === rawConfig))
) {
return cachedBoundaryResolvedConfig;
}
const autoEnabled = applyPluginAutoEnable({
config: rawConfig,
env: process.env,
});
const autoEnabled = configMayNeedPluginAutoEnable(rawConfig, process.env)
? applyPluginAutoEnable({
config: rawConfig,
env: process.env,
})
: {
config: rawConfig,
autoEnabledReasons: {} as Record<string, string[]>,
};
const config = autoEnabled.config;
const resolved = {
rawConfig,
@@ -255,6 +301,7 @@ function getFacadeBoundaryResolvedConfig() {
autoEnabledReasons: autoEnabled.autoEnabledReasons,
};
cachedBoundaryRawConfig = rawConfig;
cachedBoundaryResolvedConfigKey = readResult.cacheKey;
cachedBoundaryResolvedConfig = resolved;
return resolved;
}
@@ -569,6 +616,8 @@ export function resetFacadeRuntimeStateForTest(): void {
loadedFacadePluginIds.clear();
jitiLoaders.clear();
cachedBoundaryRawConfig = undefined;
cachedBoundaryResolvedConfigKey = undefined;
cachedBoundaryConfigFileState = undefined;
cachedBoundaryResolvedConfig = undefined;
cachedManifestRegistry = undefined;
cachedFacadeModuleLocationsByKey.clear();