Skip to content

Commit b70c19d

Browse files
feat: limit plugin installation load (#1951)
* feat: limit plugin installation load * reduce limit
1 parent 6bf123b commit b70c19d

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

src/lib/installPlugin.js

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -176,36 +176,35 @@ export default async function installPlugin(
176176
// Track unsafe absolute entries to skip
177177
const ignoredUnsafeEntries = new Set();
178178

179-
const promises = Object.keys(zip.files).map(async (file) => {
179+
const files = Object.keys(zip.files);
180+
const limit = 2;
181+
182+
async function processFile(file) {
180183
try {
181-
let correctFile = file;
182-
if (/\\/.test(correctFile)) {
183-
correctFile = correctFile.replace(/\\/g, "/");
184-
}
184+
const entry = zip.files[file];
185185

186-
// Determine if the zip entry is a directory from JSZip metadata
187-
const isDirEntry = !!zip.files[file].dir || /\/$/.test(correctFile);
186+
let correctFile = file.replace(/\\/g, "/");
187+
const isDirEntry = entry.dir || correctFile.endsWith("/");
188188

189-
// If the original path is absolute or otherwise unsafe, skip it and warn later
190189
if (isUnsafeAbsolutePath(file)) {
191190
ignoredUnsafeEntries.add(file);
192191
return;
193192
}
194193

195-
// Sanitize path so it cannot escape pluginDir or start with '/'
196194
correctFile = sanitizeZipPath(correctFile, isDirEntry);
197-
if (!correctFile) return; // nothing to do
195+
if (!correctFile) return;
196+
198197
const fileUrl = Url.join(pluginDir, correctFile);
199198

200-
// Always ensure directories exist for dir entries
199+
// Handle directory entries
201200
if (isDirEntry) {
202201
await createFileRecursive(pluginDir, correctFile, true);
203202
return;
204203
}
205204

206-
// For files, ensure parent directory exists even if state claims it exists
205+
// Ensure parent directory exists
207206
const lastSlash = correctFile.lastIndexOf("/");
208-
if (lastSlash >= 0) {
207+
if (lastSlash !== -1) {
209208
const parentRel = correctFile.slice(0, lastSlash + 1);
210209
await createFileRecursive(pluginDir, parentRel, true);
211210
}
@@ -214,23 +213,28 @@ export default async function installPlugin(
214213
await createFileRecursive(pluginDir, correctFile, false);
215214
}
216215

217-
let data = await zip.files[file].async("ArrayBuffer");
216+
let data = await entry.async("ArrayBuffer");
218217

219218
if (file === "plugin.json") {
220219
data = JSON.stringify(pluginJson);
221220
}
222221

223222
if (!(await state.isUpdated(correctFile, data))) return;
223+
224224
await fsOperation(fileUrl).writeFile(data);
225-
return;
226225
} catch (error) {
227226
console.error(`Error processing file ${file}:`, error);
228227
}
229-
});
228+
}
230229

231-
// Wait for all files to be processed
232-
await Promise.allSettled(promises);
230+
// Process in batches
231+
for (let i = 0; i < files.length; i += limit) {
232+
const batch = files.slice(i, i + limit);
233+
await Promise.allSettled(batch.map(processFile));
233234

235+
// Allow UI thread to breathe
236+
await new Promise((r) => setTimeout(r, 0));
237+
}
234238
// Emit a non-blocking warning if any unsafe entries were skipped
235239
if (!isDependency && ignoredUnsafeEntries.size) {
236240
const sample = Array.from(ignoredUnsafeEntries).slice(0, 3).join(", ");

0 commit comments

Comments
 (0)