faster serving on huge folders
Massimo Melina committed
Feb 6, 2025 at 19:47 UTC
ac99bcc31d7f5bdbeb4d4058861701ed508249dc
1 file changed
+9
-9
src/walkDir.ts
+9
-9
@@ -1,5 +1,5 @@
1
import { makeQ } from './makeQ'
2
-import { stat, readdir } from 'fs/promises'
2
+import { stat, opendir } from 'fs/promises'
3
import { IS_WINDOWS } from './const'
4
import { join } from 'path'
5
import { pendingPromise, Promisable } from './cross'
@@ -38,25 +38,25 @@ export function walkDir(path: string, { depth = 0, hidden = true }: {
38
let n = 0
39
let last: DirStreamEntry | undefined
40
if (IS_WINDOWS) { // use native apis to read 'hidden' attribute
41
- const entries = await new Promise<fswin.Find.File[]>(res => fswin.find(base + '\\*', res))
42
- const methods = {
41
+ const direntMethods = {
42
isDir: false,
43
isFile(){ return !this.isDir },
44
isDirectory(){ return this.isDir },
45
isBlockDevice(){ return false },
46
isCharacterDevice() { return false },
47
}
49
- for (const f of entries) {
50
- if (stopped) break
51
- if (!hidden && f.IS_HIDDEN) continue
52
- await work(Object.assign(Object.create(methods), {
48
+ await new Promise<void>(res => fswin.find(base + '\\*', (event, f) => {
49
+ if (event !== 'FOUND') return res()
50
+ if (stopped) return true // stop signal
51
+ if (!hidden && f.IS_HIDDEN) return
52
+ work(Object.assign(Object.create(direntMethods), {
53
isDir: f.IS_DIRECTORY,
54
name: f.LONG_NAME,
55
stats: { size: f.SIZE, birthtime: f.CREATION_TIME, mtime: f.LAST_WRITE_TIME } as Stats
56
}))
57
- }
57
+ }, true))
58
}
59
- else for await (let entry of await readdir(base, { withFileTypes: true })) {
59
+ else for await (let entry of await opendir(base)) {
60
if (stopped) break
61
if (!hidden && entry.name[0] === '.')
62
continue