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