tri-cli 0.0.53 → 0.0.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +28 -77
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -73,33 +73,19 @@ const getDirSizeAsync = async dirPath => {
|
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
-
// Fast file counting
|
|
76
|
+
// Fast file counting using shell command
|
|
77
77
|
const countFilesAsync = async dirPath => {
|
|
78
78
|
try {
|
|
79
79
|
const stats = fs.statSync(dirPath);
|
|
80
80
|
if (!stats.isDirectory()) return 1;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (entry.name.startsWith('.')) continue;
|
|
90
|
-
const fullPath = path.join(dir, entry.name);
|
|
91
|
-
if (entry.isFile()) {
|
|
92
|
-
count++;
|
|
93
|
-
} else if (entry.isDirectory()) {
|
|
94
|
-
await countRecursive(fullPath);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
} catch {
|
|
98
|
-
// Skip directories we can't read
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
await countRecursive(dirPath);
|
|
102
|
-
return count;
|
|
81
|
+
|
|
82
|
+
// Use find command for fast counting, excluding hidden files
|
|
83
|
+
const escapedPath = dirPath.replace(/"/g, '\\"');
|
|
84
|
+
const {
|
|
85
|
+
stdout
|
|
86
|
+
} = await execAsync(`find "${escapedPath}" -type f ! -path '*/.*' 2>/dev/null | wc -l`);
|
|
87
|
+
const count = parseInt(stdout.trim(), 10);
|
|
88
|
+
return isNaN(count) ? 0 : count;
|
|
103
89
|
} catch {
|
|
104
90
|
return 0;
|
|
105
91
|
}
|
|
@@ -451,64 +437,29 @@ const TreeVisualization = ({
|
|
|
451
437
|
collectNodes(node);
|
|
452
438
|
if (nodesToCount.length === 0) return; // Nothing to count
|
|
453
439
|
|
|
440
|
+
// Sort nodes by depth (shallowest first) for top-down display
|
|
441
|
+
nodesToCount.sort((a, b) => a.depth - b.depth);
|
|
442
|
+
|
|
454
443
|
// Mark all nodes as loading
|
|
455
|
-
const
|
|
456
|
-
setLoadingPaths(
|
|
444
|
+
const loadingSet = new Set(nodesToCount.map(n => n.data.path));
|
|
445
|
+
setLoadingPaths(loadingSet);
|
|
457
446
|
const newMap = new Map(calculatedCounts);
|
|
458
447
|
|
|
459
|
-
//
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
if (!targetNode.data.isFile) {
|
|
463
|
-
let runningCount = 0;
|
|
464
|
-
let updateCounter = 0;
|
|
465
|
-
const countRecursive = async dir => {
|
|
466
|
-
try {
|
|
467
|
-
const entries = fs.readdirSync(dir, {
|
|
468
|
-
withFileTypes: true
|
|
469
|
-
});
|
|
470
|
-
for (const entry of entries) {
|
|
471
|
-
// Skip hidden files
|
|
472
|
-
if (entry.name.startsWith('.')) continue;
|
|
473
|
-
const fullPath = path.join(dir, entry.name);
|
|
474
|
-
if (entry.isFile()) {
|
|
475
|
-
runningCount++;
|
|
476
|
-
updateCounter++;
|
|
477
|
-
// Stream update every 100 files for better performance
|
|
478
|
-
if (updateCounter >= 100) {
|
|
479
|
-
updateCounter = 0;
|
|
480
|
-
newMap.set(targetNode.data.path, runningCount);
|
|
481
|
-
React.startTransition(() => {
|
|
482
|
-
setCalculatedCounts(new Map(newMap));
|
|
483
|
-
});
|
|
484
|
-
await new Promise(r => setTimeout(r, 0));
|
|
485
|
-
}
|
|
486
|
-
} else if (entry.isDirectory()) {
|
|
487
|
-
await countRecursive(fullPath);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
} catch {
|
|
491
|
-
// Skip directories we can't read
|
|
492
|
-
}
|
|
493
|
-
};
|
|
494
|
-
await countRecursive(targetNode.data.path);
|
|
495
|
-
newMap.set(targetNode.data.path, runningCount);
|
|
496
|
-
} else {
|
|
497
|
-
// Files are always 1
|
|
498
|
-
newMap.set(targetNode.data.path, 1);
|
|
499
|
-
}
|
|
448
|
+
// Process all nodes in parallel, but update UI as each completes
|
|
449
|
+
const promises = nodesToCount.map(async targetNode => {
|
|
450
|
+
const count = await countFilesAsync(targetNode.data.path);
|
|
500
451
|
|
|
501
|
-
//
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
452
|
+
// Update immediately when this specific node completes
|
|
453
|
+
newMap.set(targetNode.data.path, count);
|
|
454
|
+
loadingSet.delete(targetNode.data.path);
|
|
455
|
+
|
|
456
|
+
// Trigger UI update
|
|
457
|
+
setCalculatedCounts(new Map(newMap));
|
|
458
|
+
setLoadingPaths(new Set(loadingSet));
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// Wait for all counts to complete
|
|
462
|
+
await Promise.all(promises);
|
|
512
463
|
};
|
|
513
464
|
const getLastModifiedAsync = async node => {
|
|
514
465
|
// Collect node and all its descendants
|