

















@@ -7,6 +7,7 @@ import { readJsonIfExists, writeJson } from "./json-files.js";
77export { LOCAL_BUILD_METADATA_DIST_PATHS } from "../../scripts/lib/local-build-metadata-paths.mjs";
8899export const PACKAGE_DIST_INVENTORY_RELATIVE_PATH = "dist/postinstall-inventory.json";
10+const PACKAGE_DIST_INVENTORY_SCAN_CONCURRENCY = 32;
1011const LEGACY_QA_CHANNEL_DIR = ["qa", "channel"].join("-");
1112const LEGACY_QA_LAB_DIR = ["qa", "lab"].join("-");
1213const OMITTED_QA_EXTENSION_PREFIXES = [
@@ -42,6 +43,35 @@ const OMITTED_DIST_SUBTREE_PATTERNS = [
4243] as const;
4344const INSTALL_STAGE_DEBRIS_DIR_PATTERN = /^\.openclaw-install-stage(?:-[^/]+)?$/iu;
4445type ExternalizedBundledExtensionIds = ReadonlySet<string>;
46+type PackageDistInventoryScanContext = {
47+activeFsOps: number;
48+fsConcurrency: number;
49+waiters: Array<() => void>;
50+};
51+52+function createPackageDistInventoryScanContext(): PackageDistInventoryScanContext {
53+return {
54+activeFsOps: 0,
55+fsConcurrency: PACKAGE_DIST_INVENTORY_SCAN_CONCURRENCY,
56+waiters: [],
57+};
58+}
59+60+async function withPackageDistInventoryFsSlot<T>(
61+context: PackageDistInventoryScanContext,
62+task: () => Promise<T>,
63+): Promise<T> {
64+while (context.activeFsOps >= context.fsConcurrency) {
65+await new Promise<void>((resolve) => context.waiters.push(resolve));
66+}
67+context.activeFsOps += 1;
68+try {
69+return await task();
70+} finally {
71+context.activeFsOps -= 1;
72+context.waiters.shift()?.();
73+}
74+}
45754676function normalizeRelativePath(value: string): string {
4777return value.replace(/\\/g, "/");
@@ -175,19 +205,22 @@ async function collectRelativeFiles(
175205rootDir: string,
176206baseDir: string,
177207externalizedExtensionIds: ExternalizedBundledExtensionIds,
208+context: PackageDistInventoryScanContext,
178209): Promise<string[]> {
179210const rootRelativePath = normalizeRelativePath(path.relative(baseDir, rootDir));
180211if (rootRelativePath && isOmittedDistSubtree(rootRelativePath, externalizedExtensionIds)) {
181212return [];
182213}
183214try {
184-const rootStats = await fs.lstat(rootDir);
215+const rootStats = await withPackageDistInventoryFsSlot(context, () => fs.lstat(rootDir));
185216if (!rootStats.isDirectory() || rootStats.isSymbolicLink()) {
186217throw new Error(
187218`Unsafe package dist path: ${normalizeRelativePath(path.relative(baseDir, rootDir))}`,
188219);
189220}
190-const entries = await fs.readdir(rootDir, { withFileTypes: true });
221+const entries = await withPackageDistInventoryFsSlot(context, () =>
222+fs.readdir(rootDir, { withFileTypes: true }),
223+);
191224const files = await Promise.all(
192225entries.map(async (entry) => {
193226const entryPath = path.join(rootDir, entry.name);
@@ -196,7 +229,7 @@ async function collectRelativeFiles(
196229throw new Error(`Unsafe package dist path: ${relativePath}`);
197230}
198231if (entry.isDirectory()) {
199-return await collectRelativeFiles(entryPath, baseDir, externalizedExtensionIds);
232+return await collectRelativeFiles(entryPath, baseDir, externalizedExtensionIds, context);
200233}
201234if (entry.isFile()) {
202235return isPackagedDistPath(relativePath, externalizedExtensionIds) ? [relativePath] : [];
@@ -215,10 +248,12 @@ async function collectRelativeFiles(
215248216249export async function collectPackageDistInventory(packageRoot: string): Promise<string[]> {
217250const externalizedExtensionIds = await collectExternalizedBundledExtensionIds(packageRoot);
251+const scanContext = createPackageDistInventoryScanContext();
218252return await collectRelativeFiles(
219253path.join(packageRoot, "dist"),
220254packageRoot,
221255externalizedExtensionIds,
256+scanContext,
222257);
223258}
224259此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。