@@ -2,6 +2,47 @@ import { Dirent } from 'node:fs';
22import * as fs from 'node:fs/promises' ;
33import * as path from 'node:path' ;
44
5+ /**
6+ * Default concurrency limit for file operations.
7+ * Set conservatively to avoid EMFILE errors on Windows.
8+ */
9+ const DEFAULT_CONCURRENCY = 50 ;
10+
11+ /**
12+ * Process items with limited concurrency to avoid EMFILE errors.
13+ * Uses a semaphore pattern to limit parallel file operations.
14+ */
15+ async function processWithConcurrency < T , R > (
16+ items : T [ ] ,
17+ processor : ( item : T ) => Promise < R > ,
18+ concurrency : number = DEFAULT_CONCURRENCY ,
19+ ) : Promise < R [ ] > {
20+ const results : R [ ] = [ ] ;
21+ let index = 0 ;
22+
23+ async function worker ( ) : Promise < void > {
24+ while ( index < items . length ) {
25+ const currentIndex = index ++ ;
26+ const item = items [ currentIndex ] ;
27+ try {
28+ const result = await processor ( item ) ;
29+ results [ currentIndex ] = result ;
30+ } catch {
31+ // Errors are handled by the processor or ignored
32+ results [ currentIndex ] = undefined as R ;
33+ }
34+ }
35+ }
36+
37+ // Create worker pool
38+ const workers = Array ( Math . min ( concurrency , items . length ) )
39+ . fill ( null )
40+ . map ( ( ) => worker ( ) ) ;
41+
42+ await Promise . all ( workers ) ;
43+ return results ;
44+ }
45+
546/**
647 * Searches for `.ts` files containing the search pattern.
748 * @param {string } baseDir - The directory to search. Should be absolute or resolved by the caller.
@@ -21,18 +62,21 @@ export async function findFilesWithPattern(
2162 tsFiles . push ( file ) ;
2263 }
2364
24- const results : SourceLocation [ ] = [ ] ;
25- for ( const file of tsFiles ) {
26- try {
27- const hits = await findInFile ( file , searchPattern ) ;
28- if ( hits . length > 0 ) {
29- results . push ( ...hits ) ;
65+ // Process files with limited concurrency to avoid EMFILE errors
66+ const searchResults = await processWithConcurrency (
67+ tsFiles ,
68+ async ( file ) => {
69+ try {
70+ return await findInFile ( file , searchPattern ) ;
71+ } catch ( ctx ) {
72+ console . error ( `Error searching file ${ file } :` , ctx ) ;
73+ return [ ] ;
3074 }
31- } catch ( ctx ) {
32- console . error ( `Error searching file ${ file } :` , ctx ) ;
33- }
34- }
75+ } ,
76+ DEFAULT_CONCURRENCY ,
77+ ) ;
3578
79+ const results : SourceLocation [ ] = searchResults . flat ( ) ;
3680 return results . map ( ( r : SourceLocation ) => r . file ) ;
3781}
3882
0 commit comments