refactor: unify lazy import loaders

This commit is contained in:
Peter Steinberger
2026-05-02 10:55:52 +01:00
parent 2dcc13d685
commit 59fb9e5ca7
66 changed files with 642 additions and 616 deletions

View File

@@ -2,6 +2,7 @@ import type { Command } from "commander";
import { danger } from "../globals.js";
import { listBundledPackageChannelMetadata } from "../plugins/bundled-package-channel-metadata.js";
import { defaultRuntime } from "../runtime.js";
import { createLazyImportLoader } from "../shared/lazy-promise.js";
import { formatDocsLink } from "../terminal/links.js";
import { theme } from "../terminal/theme.js";
import { runChannelLogin, runChannelLogout } from "./channel-auth.js";
@@ -15,11 +16,12 @@ type ChannelsCommandsModule = typeof import("../commands/channels.js");
const optionNamesRemove = ["channel", "account", "delete"] as const;
let channelsCommandsPromise: Promise<ChannelsCommandsModule> | undefined;
const channelsCommandsLoader = createLazyImportLoader<ChannelsCommandsModule>(
() => import("../commands/channels.js"),
);
function loadChannelsCommands(): Promise<ChannelsCommandsModule> {
channelsCommandsPromise ??= import("../commands/channels.js");
return channelsCommandsPromise;
return channelsCommandsLoader.load();
}
function runChannelsCommand(action: () => Promise<void>) {

View File

@@ -1,13 +1,13 @@
import type { RuntimeEnv } from "../runtime.js";
import { createLazyImportLoader } from "../shared/lazy-promise.js";
import type { CliPluginRegistryPolicy } from "./command-catalog.js";
import { resolveCliCommandPathPolicy } from "./command-path-policy.js";
import { ensureCliPluginRegistryLoaded } from "./plugin-registry-loader.js";
let configGuardModulePromise: Promise<typeof import("./program/config-guard.js")> | undefined;
const configGuardModuleLoader = createLazyImportLoader(() => import("./program/config-guard.js"));
function loadConfigGuardModule() {
configGuardModulePromise ??= import("./program/config-guard.js");
return configGuardModulePromise;
return configGuardModuleLoader.load();
}
export async function ensureCliCommandBootstrap(params: {

View File

@@ -1,14 +1,14 @@
import type { OpenClawConfig } from "../../config/types.js";
import { formatErrorMessage } from "../../infra/errors.js";
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
import { withProgress } from "../progress.js";
type GatewayStatusProbeKind = "connect" | "read";
let probeGatewayModulePromise: Promise<typeof import("../../gateway/probe.js")> | undefined;
const probeGatewayModuleLoader = createLazyImportLoader(() => import("../../gateway/probe.js"));
async function loadProbeGatewayModule(): Promise<typeof import("../../gateway/probe.js")> {
probeGatewayModulePromise ??= import("../../gateway/probe.js");
return await probeGatewayModulePromise;
return await probeGatewayModuleLoader.load();
}
function resolveProbeFailureMessage(result: {

View File

@@ -1,24 +1,22 @@
import type { Command } from "commander";
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
import { inheritOptionFromParent } from "../command-options.js";
import type { DaemonInstallOptions, GatewayRpcOpts } from "./types.js";
let daemonInstallModulePromise: Promise<typeof import("./install.runtime.js")> | undefined;
let daemonLifecycleModulePromise: Promise<typeof import("./lifecycle.runtime.js")> | undefined;
let daemonStatusModulePromise: Promise<typeof import("./status.runtime.js")> | undefined;
const daemonInstallModuleLoader = createLazyImportLoader(() => import("./install.runtime.js"));
const daemonLifecycleModuleLoader = createLazyImportLoader(() => import("./lifecycle.runtime.js"));
const daemonStatusModuleLoader = createLazyImportLoader(() => import("./status.runtime.js"));
function loadDaemonInstallModule() {
daemonInstallModulePromise ??= import("./install.runtime.js");
return daemonInstallModulePromise;
return daemonInstallModuleLoader.load();
}
function loadDaemonLifecycleModule() {
daemonLifecycleModulePromise ??= import("./lifecycle.runtime.js");
return daemonLifecycleModulePromise;
return daemonLifecycleModuleLoader.load();
}
function loadDaemonStatusModule() {
daemonStatusModulePromise ??= import("./status.runtime.js");
return daemonStatusModulePromise;
return daemonStatusModuleLoader.load();
}
function resolveInstallOptions(

View File

@@ -30,6 +30,7 @@ import {
type PortUsageStatus,
} from "../../infra/ports.js";
import { resolveConfiguredLogFilePath } from "../../logging/log-file-path.js";
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
import { normalizeListenerAddress, parsePortFromArgs, pickProbeHostForBind } from "./shared.js";
import type { GatewayRpcOpts } from "./types.js";
@@ -81,43 +82,39 @@ type ResolvedGatewayStatus = {
probeUrlOverride: string | null;
};
let gatewayProbeAuthModulePromise:
| Promise<typeof import("../../gateway/probe-auth.js")>
| undefined;
let daemonInspectModulePromise: Promise<typeof import("../../daemon/inspect.js")> | undefined;
let serviceAuditModulePromise: Promise<typeof import("../../daemon/service-audit.js")> | undefined;
let gatewayTlsModulePromise: Promise<typeof import("../../infra/tls/gateway.js")> | undefined;
let daemonProbeModulePromise: Promise<typeof import("./probe.js")> | undefined;
let restartHealthModulePromise: Promise<typeof import("./restart-health.js")> | undefined;
const gatewayProbeAuthModuleLoader = createLazyImportLoader(
() => import("../../gateway/probe-auth.js"),
);
const daemonInspectModuleLoader = createLazyImportLoader(() => import("../../daemon/inspect.js"));
const serviceAuditModuleLoader = createLazyImportLoader(
() => import("../../daemon/service-audit.js"),
);
const gatewayTlsModuleLoader = createLazyImportLoader(() => import("../../infra/tls/gateway.js"));
const daemonProbeModuleLoader = createLazyImportLoader(() => import("./probe.js"));
const restartHealthModuleLoader = createLazyImportLoader(() => import("./restart-health.js"));
function loadGatewayProbeAuthModule() {
gatewayProbeAuthModulePromise ??= import("../../gateway/probe-auth.js");
return gatewayProbeAuthModulePromise;
return gatewayProbeAuthModuleLoader.load();
}
function loadDaemonInspectModule() {
daemonInspectModulePromise ??= import("../../daemon/inspect.js");
return daemonInspectModulePromise;
return daemonInspectModuleLoader.load();
}
function loadServiceAuditModule() {
serviceAuditModulePromise ??= import("../../daemon/service-audit.js");
return serviceAuditModulePromise;
return serviceAuditModuleLoader.load();
}
function loadGatewayTlsModule() {
gatewayTlsModulePromise ??= import("../../infra/tls/gateway.js");
return gatewayTlsModulePromise;
return gatewayTlsModuleLoader.load();
}
function loadDaemonProbeModule() {
daemonProbeModulePromise ??= import("./probe.js");
return daemonProbeModulePromise;
return daemonProbeModuleLoader.load();
}
function loadRestartHealthModule() {
restartHealthModulePromise ??= import("./restart-health.js");
return restartHealthModulePromise;
return restartHealthModuleLoader.load();
}
function resolveSnapshotRuntimeConfig(snapshot: ConfigFileSnapshot | null): OpenClawConfig | null {

View File

@@ -13,6 +13,7 @@ import {
} from "../../logging/diagnostic-stability.js";
import type { WriteDiagnosticSupportExportResult } from "../../logging/diagnostic-support-export.js";
import { defaultRuntime } from "../../runtime.js";
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
import { formatDocsLink } from "../../terminal/links.js";
import { colorize, isRich, theme } from "../../terminal/theme.js";
import { runCommandWithRuntime } from "../cli-utils.js";
@@ -31,77 +32,69 @@ import {
} from "./discover.js";
import { addGatewayRunCommand } from "./run.js";
let configModulePromise:
| Promise<typeof import("../../config/read-best-effort-config.runtime.js")>
| undefined;
let gatewayStatusModulePromise:
| Promise<typeof import("../../commands/gateway-status.js")>
| undefined;
let gatewayHealthModulePromise: Promise<typeof import("../../commands/health.js")> | undefined;
let bonjourDiscoveryModulePromise:
| Promise<typeof import("../../infra/bonjour-discovery.js")>
| undefined;
let wideAreaDnsModulePromise: Promise<typeof import("../../infra/widearea-dns.js")> | undefined;
let healthStyleModulePromise: Promise<typeof import("../../terminal/health-style.js")> | undefined;
let usageFormatModulePromise: Promise<typeof import("../../utils/usage-format.js")> | undefined;
let stabilityBundleModulePromise:
| Promise<typeof import("../../logging/diagnostic-stability-bundle.js")>
| undefined;
let supportExportModulePromise:
| Promise<typeof import("../../logging/diagnostic-support-export.js")>
| undefined;
let daemonStatusGatherModulePromise:
| Promise<typeof import("../daemon-cli/status.gather.js")>
| undefined;
const configModuleLoader = createLazyImportLoader(
() => import("../../config/read-best-effort-config.runtime.js"),
);
const gatewayStatusModuleLoader = createLazyImportLoader(
() => import("../../commands/gateway-status.js"),
);
const gatewayHealthModuleLoader = createLazyImportLoader(() => import("../../commands/health.js"));
const bonjourDiscoveryModuleLoader = createLazyImportLoader(
() => import("../../infra/bonjour-discovery.js"),
);
const wideAreaDnsModuleLoader = createLazyImportLoader(() => import("../../infra/widearea-dns.js"));
const healthStyleModuleLoader = createLazyImportLoader(
() => import("../../terminal/health-style.js"),
);
const usageFormatModuleLoader = createLazyImportLoader(() => import("../../utils/usage-format.js"));
const stabilityBundleModuleLoader = createLazyImportLoader(
() => import("../../logging/diagnostic-stability-bundle.js"),
);
const supportExportModuleLoader = createLazyImportLoader(
() => import("../../logging/diagnostic-support-export.js"),
);
const daemonStatusGatherModuleLoader = createLazyImportLoader(
() => import("../daemon-cli/status.gather.js"),
);
function loadConfigModule() {
configModulePromise ??= import("../../config/read-best-effort-config.runtime.js");
return configModulePromise;
return configModuleLoader.load();
}
function loadGatewayStatusModule() {
gatewayStatusModulePromise ??= import("../../commands/gateway-status.js");
return gatewayStatusModulePromise;
return gatewayStatusModuleLoader.load();
}
function loadGatewayHealthModule() {
gatewayHealthModulePromise ??= import("../../commands/health.js");
return gatewayHealthModulePromise;
return gatewayHealthModuleLoader.load();
}
function loadBonjourDiscoveryModule() {
bonjourDiscoveryModulePromise ??= import("../../infra/bonjour-discovery.js");
return bonjourDiscoveryModulePromise;
return bonjourDiscoveryModuleLoader.load();
}
function loadWideAreaDnsModule() {
wideAreaDnsModulePromise ??= import("../../infra/widearea-dns.js");
return wideAreaDnsModulePromise;
return wideAreaDnsModuleLoader.load();
}
function loadHealthStyleModule() {
healthStyleModulePromise ??= import("../../terminal/health-style.js");
return healthStyleModulePromise;
return healthStyleModuleLoader.load();
}
function loadUsageFormatModule() {
usageFormatModulePromise ??= import("../../utils/usage-format.js");
return usageFormatModulePromise;
return usageFormatModuleLoader.load();
}
function loadStabilityBundleModule() {
stabilityBundleModulePromise ??= import("../../logging/diagnostic-stability-bundle.js");
return stabilityBundleModulePromise;
return stabilityBundleModuleLoader.load();
}
function loadSupportExportModule() {
supportExportModulePromise ??= import("../../logging/diagnostic-support-export.js");
return supportExportModulePromise;
return supportExportModuleLoader.load();
}
function loadDaemonStatusGatherModule() {
daemonStatusGatherModulePromise ??= import("../daemon-cli/status.gather.js");
return daemonStatusGatherModulePromise;
return daemonStatusGatherModuleLoader.load();
}
function runGatewayCommand(action: () => Promise<void>, label?: string) {

View File

@@ -4,6 +4,7 @@ import { formatErrorMessage } from "../../infra/errors.js";
import { acquireGatewayLock } from "../../infra/gateway-lock.js";
import { createSubsystemLogger } from "../../logging/subsystem.js";
import type { RuntimeEnv } from "../../runtime.js";
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
const gatewayLog = createSubsystemLogger("gateway");
const LAUNCHD_SUPERVISED_RESTART_EXIT_DELAY_MS = 1500;
@@ -17,10 +18,11 @@ type RestartDrainTimeoutMs = number | undefined;
type GatewayLifecycleRuntimeModule = typeof import("./lifecycle.runtime.js");
let gatewayLifecycleRuntimeModule: Promise<GatewayLifecycleRuntimeModule> | undefined;
const gatewayLifecycleRuntimeLoader = createLazyImportLoader<GatewayLifecycleRuntimeModule>(
() => import("./lifecycle.runtime.js"),
);
const loadGatewayLifecycleRuntimeModule = () =>
(gatewayLifecycleRuntimeModule ??= import("./lifecycle.runtime.js"));
const loadGatewayLifecycleRuntimeModule = () => gatewayLifecycleRuntimeLoader.load();
function createRestartIterationHook(onRestart: () => Promise<void> | void): () => Promise<boolean> {
let isFirstIteration = true;

View File

@@ -2,16 +2,18 @@ import type { Command } from "commander";
import type { OperatorScope } from "../gateway/operator-scopes.js";
import type { GatewayClientMode, GatewayClientName } from "../gateway/protocol/client-info.js";
import type { DeviceIdentity } from "../infra/device-identity.js";
import { createLazyImportLoader } from "../shared/lazy-promise.js";
import type { GatewayRpcOpts } from "./gateway-rpc.types.js";
export type { GatewayRpcOpts } from "./gateway-rpc.types.js";
type GatewayRpcRuntimeModule = typeof import("./gateway-rpc.runtime.js");
let gatewayRpcRuntimePromise: Promise<GatewayRpcRuntimeModule> | undefined;
const gatewayRpcRuntimeLoader = createLazyImportLoader<GatewayRpcRuntimeModule>(
() => import("./gateway-rpc.runtime.js"),
);
async function loadGatewayRpcRuntime(): Promise<GatewayRpcRuntimeModule> {
gatewayRpcRuntimePromise ??= import("./gateway-rpc.runtime.js");
return gatewayRpcRuntimePromise;
return gatewayRpcRuntimeLoader.load();
}
export function addGatewayClientOptions(cmd: Command) {

View File

@@ -11,6 +11,7 @@ import { formatErrorMessage } from "../infra/errors.js";
import { readConfiguredLogTail } from "../logging/log-tail.js";
import { parseLogLine } from "../logging/parse-log-line.js";
import { formatTimestamp, isValidTimeZone } from "../logging/timestamps.js";
import { createLazyImportLoader } from "../shared/lazy-promise.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { formatDocsLink } from "../terminal/links.js";
import { clearActiveProgressLine } from "../terminal/progress-line.js";
@@ -21,11 +22,12 @@ import { addGatewayClientOptions, callGatewayFromCli } from "./gateway-rpc.js";
type LogsCliRuntimeModule = typeof import("./logs-cli.runtime.js");
let logsCliRuntimePromise: Promise<LogsCliRuntimeModule> | undefined;
const logsCliRuntimeLoader = createLazyImportLoader<LogsCliRuntimeModule>(
() => import("./logs-cli.runtime.js"),
);
async function loadLogsCliRuntime(): Promise<LogsCliRuntimeModule> {
logsCliRuntimePromise ??= import("./logs-cli.runtime.js");
return logsCliRuntimePromise;
return logsCliRuntimeLoader.load();
}
type LogsTailPayload = {

View File

@@ -1,5 +1,6 @@
import { randomUUID } from "node:crypto";
import type { Command } from "commander";
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
import { resolveNodeFromNodeList } from "../../shared/node-resolve.js";
import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js";
import { parseNodeList, parsePairingList } from "./format.js";
@@ -7,11 +8,12 @@ import type { NodeListNode, NodesRpcOpts } from "./types.js";
type NodesCliRpcRuntimeModule = typeof import("./rpc.runtime.js");
let nodesCliRpcRuntimePromise: Promise<NodesCliRpcRuntimeModule> | undefined;
const nodesCliRpcRuntimeLoader = createLazyImportLoader<NodesCliRpcRuntimeModule>(
() => import("./rpc.runtime.js"),
);
async function loadNodesCliRpcRuntime(): Promise<NodesCliRpcRuntimeModule> {
nodesCliRpcRuntimePromise ??= import("./rpc.runtime.js");
return nodesCliRpcRuntimePromise;
return nodesCliRpcRuntimeLoader.load();
}
export const nodesCallOpts = (cmd: Command, defaults?: { timeoutMs?: number }) =>

View File

@@ -1,12 +1,12 @@
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { loggingState } from "../logging/state.js";
import { createLazyImportLoader } from "../shared/lazy-promise.js";
import type { CliPluginRegistryScope } from "./command-catalog.js";
let pluginRegistryModulePromise: Promise<typeof import("./plugin-registry.js")> | undefined;
const pluginRegistryModuleLoader = createLazyImportLoader(() => import("./plugin-registry.js"));
function loadPluginRegistryModule() {
pluginRegistryModulePromise ??= import("./plugin-registry.js");
return pluginRegistryModulePromise;
return pluginRegistryModuleLoader.load();
}
export type CliPluginRegistryLoadPolicy = {

View File

@@ -1,4 +1,5 @@
import { defaultRuntime } from "../../runtime.js";
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
import {
parseAgentsListRouteArgs,
parseChannelsListRouteArgs,
@@ -38,23 +39,24 @@ function defineRoutedCommand<TParse extends RouteArgParser<unknown>>(
return definition;
}
let configCliPromise: Promise<ConfigCliModule> | undefined;
let modelsListCommandPromise: Promise<ModelsListCommandModule> | undefined;
let modelsStatusCommandPromise: Promise<ModelsStatusCommandModule> | undefined;
const configCliLoader = createLazyImportLoader<ConfigCliModule>(() => import("../config-cli.js"));
const modelsListCommandLoader = createLazyImportLoader<ModelsListCommandModule>(
() => import("../../commands/models/list.list-command.js"),
);
const modelsStatusCommandLoader = createLazyImportLoader<ModelsStatusCommandModule>(
() => import("../../commands/models/list.status-command.js"),
);
function loadConfigCli(): Promise<ConfigCliModule> {
configCliPromise ??= import("../config-cli.js");
return configCliPromise;
return configCliLoader.load();
}
function loadModelsListCommand(): Promise<ModelsListCommandModule> {
modelsListCommandPromise ??= import("../../commands/models/list.list-command.js");
return modelsListCommandPromise;
return modelsListCommandLoader.load();
}
function loadModelsStatusCommand(): Promise<ModelsStatusCommandModule> {
modelsStatusCommandPromise ??= import("../../commands/models/list.status-command.js");
return modelsStatusCommandPromise;
return modelsStatusCommandLoader.load();
}
export const routedCommandDefinitions = {

View File

@@ -1,13 +1,15 @@
import type { Command } from "commander";
import type { CaptureQueryPreset } from "../proxy-capture/types.js";
import { createLazyImportLoader } from "../shared/lazy-promise.js";
type ProxyCliRuntime = typeof import("./proxy-cli.runtime.js");
let proxyCliRuntimePromise: Promise<ProxyCliRuntime> | undefined;
const proxyCliRuntimeLoader = createLazyImportLoader<ProxyCliRuntime>(
() => import("./proxy-cli.runtime.js"),
);
async function loadProxyCliRuntime(): Promise<ProxyCliRuntime> {
proxyCliRuntimePromise ??= import("./proxy-cli.runtime.js");
return await proxyCliRuntimePromise;
return await proxyCliRuntimeLoader.load();
}
function parseOptionalNumber(value: string | undefined): number | undefined {