fix(library): resolve main-thread UI freeze and process kill data loss via OPFS payload capping, yield throttling, and UI batching

This commit is contained in:
2026-10-05 12:13:45 +07:00
parent 1e93c8484b
commit 140b4f88b2
4 changed files with 24 additions and 9 deletions
+5 -3
View File
@@ -45,7 +45,7 @@ const LANES = 4;
// How often the walk's position is written down, in the same seconds as the
// catalogue is read back on: the position is the whole of what the walk has found
// and not read, and writing it is a string of a few megabytes on a long roll.
const WALK_MS = 2000;
const WALK_MS = 5000;
// How often the screen is told how far the reading has come: the column is
// rebuilt out of the count, and a rebuild a frame is a reading that spends its
// time drawing itself. Five times a second is a counter that moves to the eye
@@ -834,11 +834,12 @@ export async function scanFolder(
if (at - wroteAt < WALK_MS) return;
wroteAt = at;
const held = [...inHand, ...batch.map(pathOf)];
const savedEntries = entries.slice(0, 500).map((e) => e.rel);
await saveWalk(
folder.name,
[...tree.walked],
tree.pending.map((p) => p.rel),
[...held, ...entries.map((e) => e.rel)],
[...held, ...savedEntries],
held.length,
progress
);
@@ -962,11 +963,12 @@ export async function scanFolder(
// Micro-yield to the browser main thread event loop so scanning never blocks UI rendering or user interactions
processed++;
if (processed % 12 === 0) {
if (processed % 3 === 0) {
await new Promise((resolve) => setTimeout(resolve, 0));
}
}
await Promise.all(lanes);
await flush();
};
// How many of the frames in hand were counted by the reading that handed them