mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-16 14:51:39 +00:00
improve(control-ui): compress and cache bundled assets (#105890)
* perf(control-ui): compress bundled assets * chore(control-ui): remove release-owned changelog edit * fix(control-ui): release assets before compression * refactor(control-ui): split static response helpers * perf(control-ui): precompress bundled assets * refactor(control-ui): keep encoding internals private * chore(control-ui): refresh LOC baseline
This commit is contained in:
committed by
GitHub
parent
70b3467484
commit
16fa19cd72
43
scripts/check-control-ui-precompressed-assets.mjs
Normal file
43
scripts/check-control-ui-precompressed-assets.mjs
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env node
|
||||
// Verifies each generated Control UI sidecar encodes the final emitted asset bytes.
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { brotliDecompressSync, gunzipSync } from "node:zlib";
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const assetsDir = path.join(repoRoot, "dist", "control-ui", "assets");
|
||||
const errors = [];
|
||||
let checked = 0;
|
||||
|
||||
for (const entry of fs.readdirSync(assetsDir, { withFileTypes: true })) {
|
||||
if (!entry.isFile()) {
|
||||
continue;
|
||||
}
|
||||
const suffix = entry.name.endsWith(".br") ? ".br" : entry.name.endsWith(".gz") ? ".gz" : null;
|
||||
if (!suffix) {
|
||||
continue;
|
||||
}
|
||||
const sidecarPath = path.join(assetsDir, entry.name);
|
||||
const sourcePath = sidecarPath.slice(0, -suffix.length);
|
||||
try {
|
||||
const encoded = fs.readFileSync(sidecarPath);
|
||||
const decoded = suffix === ".br" ? brotliDecompressSync(encoded) : gunzipSync(encoded);
|
||||
const source = fs.readFileSync(sourcePath);
|
||||
if (!decoded.equals(source)) {
|
||||
errors.push(`${entry.name}: decoded bytes differ from ${path.basename(sourcePath)}`);
|
||||
}
|
||||
} catch (error) {
|
||||
errors.push(`${entry.name}: ${error instanceof Error ? error.message : String(error)}`);
|
||||
}
|
||||
checked += 1;
|
||||
}
|
||||
|
||||
if (checked === 0) {
|
||||
errors.push("no precompressed Control UI assets found");
|
||||
}
|
||||
if (errors.length > 0) {
|
||||
throw new Error(`Control UI precompressed asset verification failed:\n${errors.join("\n")}`);
|
||||
}
|
||||
|
||||
process.stdout.write(`verified ${checked} finalized Control UI sidecars\n`);
|
||||
@@ -14,6 +14,7 @@ const requiredPreparedPathGroups = [
|
||||
["dist/control-ui/index.html"],
|
||||
];
|
||||
const requiredControlUiAssetPrefix = "dist/control-ui/assets/";
|
||||
const requiredControlUiCompressionSuffixes = [".br", ".gz"] as const;
|
||||
const DEFAULT_PREPACK_COMMAND_TIMEOUT_MS = 30 * 60 * 1000;
|
||||
const ALLOW_UNRELEASED_CHANGELOG_ENV = "OPENCLAW_PREPACK_ALLOW_UNRELEASED_CHANGELOG";
|
||||
|
||||
@@ -42,6 +43,13 @@ export function collectPreparedPrepackErrors(
|
||||
}
|
||||
|
||||
if (!normalizedAssets.values().next().done) {
|
||||
for (const suffix of requiredControlUiCompressionSuffixes) {
|
||||
if (!Array.from(normalizedAssets).some((assetPath) => assetPath.endsWith(suffix))) {
|
||||
errors.push(
|
||||
`missing prepared Control UI ${suffix} asset under ${requiredControlUiAssetPrefix}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
@@ -878,7 +878,7 @@
|
||||
"src/gateway/cli-session-history.claude.ts": 602,
|
||||
"src/gateway/config-reload.ts": 1022,
|
||||
"src/gateway/control-ui-session-prs.ts": 648,
|
||||
"src/gateway/control-ui.ts": 1189,
|
||||
"src/gateway/control-ui.ts": 1152,
|
||||
"src/gateway/exec-approval-manager.ts": 1141,
|
||||
"src/gateway/gateway-cli-backend.live-helpers.ts": 648,
|
||||
"src/gateway/gateway-cli-backend.live-probe-helpers.ts": 513,
|
||||
|
||||
Reference in New Issue
Block a user