feat(webterm): 配置浏览器性能策略
This commit is contained in:
@@ -25,6 +25,7 @@ interface WebtermConfig {
|
||||
autoResumePrompt: AutoResumePrompt;
|
||||
browserTerminalHistory: BrowserTerminalHistory;
|
||||
browserOutputPolicy: BrowserOutputPolicy;
|
||||
browserPerformance: BrowserPerformance;
|
||||
targets: WebtermTarget[];
|
||||
}
|
||||
|
||||
@@ -52,6 +53,15 @@ interface BrowserOutputPolicy {
|
||||
maxFrameBytes: number;
|
||||
}
|
||||
|
||||
interface BrowserPerformance {
|
||||
animationsEnabled: boolean;
|
||||
defaultBackgroundMode: "disconnect" | "receive-only" | "live";
|
||||
backgroundModes: Array<{ id: "disconnect" | "receive-only" | "live"; label: string }>;
|
||||
deferredOutputMaxBytes: number;
|
||||
dashboardSampleWindowSeconds: number;
|
||||
dashboardRefreshIntervalMs: number;
|
||||
}
|
||||
|
||||
interface WebtermTarget {
|
||||
id: string;
|
||||
enabled: boolean;
|
||||
@@ -74,6 +84,7 @@ interface WebtermTarget {
|
||||
autoResumePrompt: AutoResumePrompt;
|
||||
browserTerminalHistory: BrowserTerminalHistory;
|
||||
browserOutputPolicy: BrowserOutputPolicy;
|
||||
browserPerformance: BrowserPerformance;
|
||||
environment: Record<string, string>;
|
||||
};
|
||||
publicExposure: {
|
||||
@@ -301,6 +312,7 @@ function readWebtermConfig(): WebtermConfig {
|
||||
const autoResumePrompt = parseAutoResumePrompt(recordField(yaml, "autoResumePrompt", "webterm"), "webterm.autoResumePrompt");
|
||||
const browserTerminalHistory = parseBrowserTerminalHistory(recordField(yaml, "browserTerminalHistory", "webterm"), "webterm.browserTerminalHistory");
|
||||
const browserOutputPolicy = parseBrowserOutputPolicy(recordField(yaml, "browserOutputPolicy", "webterm"), "webterm.browserOutputPolicy");
|
||||
const browserPerformance = parseBrowserPerformance(recordField(yaml, "browserPerformance", "webterm"), "webterm.browserPerformance");
|
||||
const targetsRaw = yaml.targets;
|
||||
if (!Array.isArray(targetsRaw)) throw new Error("webterm.targets must be an array");
|
||||
return {
|
||||
@@ -309,6 +321,7 @@ function readWebtermConfig(): WebtermConfig {
|
||||
autoResumePrompt,
|
||||
browserTerminalHistory,
|
||||
browserOutputPolicy,
|
||||
browserPerformance,
|
||||
targets: targetsRaw.map((item, index) => parseTarget(
|
||||
asRecord(item, `webterm.targets[${index}]`),
|
||||
`webterm.targets[${index}]`,
|
||||
@@ -316,6 +329,7 @@ function readWebtermConfig(): WebtermConfig {
|
||||
autoResumePrompt,
|
||||
browserTerminalHistory,
|
||||
browserOutputPolicy,
|
||||
browserPerformance,
|
||||
)),
|
||||
};
|
||||
}
|
||||
@@ -327,6 +341,7 @@ function parseTarget(
|
||||
autoResumePrompt: AutoResumePrompt,
|
||||
browserTerminalHistory: BrowserTerminalHistory,
|
||||
browserOutputPolicy: BrowserOutputPolicy,
|
||||
browserPerformance: BrowserPerformance,
|
||||
): WebtermTarget {
|
||||
const runtime = recordField(record, "runtime", path);
|
||||
const exposure = recordField(record, "publicExposure", path);
|
||||
@@ -358,6 +373,7 @@ function parseTarget(
|
||||
autoResumePrompt,
|
||||
browserTerminalHistory,
|
||||
browserOutputPolicy,
|
||||
browserPerformance,
|
||||
environment,
|
||||
},
|
||||
publicExposure: {
|
||||
@@ -404,6 +420,7 @@ function renderCompose(target: WebtermTarget): string {
|
||||
AUTO_RESUME_PROMPT_JSON: JSON.stringify(target.runtime.autoResumePrompt),
|
||||
BROWSER_TERMINAL_HISTORY_JSON: JSON.stringify(target.runtime.browserTerminalHistory),
|
||||
BROWSER_OUTPUT_POLICY_JSON: JSON.stringify(target.runtime.browserOutputPolicy),
|
||||
BROWSER_PERFORMANCE_JSON: JSON.stringify(target.runtime.browserPerformance),
|
||||
};
|
||||
const envLines = Object.entries(environment)
|
||||
.map(([key, value]) => ` ${key}: ${quoteYaml(value)}`)
|
||||
@@ -509,6 +526,7 @@ function targetSummary(target: WebtermTarget): Record<string, unknown> {
|
||||
},
|
||||
browserTerminalHistory: target.runtime.browserTerminalHistory,
|
||||
browserOutputPolicy: target.runtime.browserOutputPolicy,
|
||||
browserPerformance: target.runtime.browserPerformance,
|
||||
sourceMounts: target.runtime.sourceMounts.map((mount) => `${mount.source}->${mount.target}${mount.readOnly ? ":ro" : ""}`),
|
||||
hostPort: target.runtime.hostPort,
|
||||
containerPort: target.runtime.containerPort,
|
||||
@@ -710,6 +728,29 @@ function parseBrowserOutputPolicy(record: Record<string, unknown>, path: string)
|
||||
};
|
||||
}
|
||||
|
||||
function parseBrowserPerformance(record: Record<string, unknown>, path: string): BrowserPerformance {
|
||||
const allowedModes = ["disconnect", "receive-only", "live"] as const;
|
||||
const defaultBackgroundMode = stringField(record, "defaultBackgroundMode", path);
|
||||
if (!allowedModes.includes(defaultBackgroundMode as typeof allowedModes[number])) {
|
||||
throw new Error(`${path}.defaultBackgroundMode must be disconnect, receive-only or live`);
|
||||
}
|
||||
const modesRecord = recordField(record, "backgroundModes", path);
|
||||
const backgroundModes = allowedModes.map((id) => ({
|
||||
id,
|
||||
label: stringField(recordField(modesRecord, id, `${path}.backgroundModes`), "label", `${path}.backgroundModes.${id}`),
|
||||
}));
|
||||
const unknownModes = Object.keys(modesRecord).filter((id) => !allowedModes.includes(id as typeof allowedModes[number]));
|
||||
if (unknownModes.length > 0) throw new Error(`${path}.backgroundModes contains unsupported modes: ${unknownModes.join(", ")}`);
|
||||
return {
|
||||
animationsEnabled: booleanField(record, "animationsEnabled", path),
|
||||
defaultBackgroundMode: defaultBackgroundMode as BrowserPerformance["defaultBackgroundMode"],
|
||||
backgroundModes,
|
||||
deferredOutputMaxBytes: positiveIntegerField(record, "deferredOutputMaxBytes", path),
|
||||
dashboardSampleWindowSeconds: positiveIntegerField(record, "dashboardSampleWindowSeconds", path),
|
||||
dashboardRefreshIntervalMs: positiveIntegerField(record, "dashboardRefreshIntervalMs", path),
|
||||
};
|
||||
}
|
||||
|
||||
function positiveIntegerField(record: Record<string, unknown>, key: string, path: string): number {
|
||||
const value = integerField(record, key, path);
|
||||
if (value <= 0) throw new Error(`${path}.${key} must be positive`);
|
||||
|
||||
Reference in New Issue
Block a user