@@ -29,6 +29,11 @@ interface ITokensContext {
29
29
seen : Set < string > ;
30
30
}
31
31
32
+ export type FileProcessorFn < T > = (
33
+ path : string ,
34
+ metadata : { siblings : readonly string [ ] ; mtime : number } ,
35
+ ) => Promise < T > ;
36
+
32
37
export interface ITurboGlobStreamOptions < E > {
33
38
/** Glob patterns */
34
39
pattern : string ;
@@ -41,7 +46,7 @@ export interface ITurboGlobStreamOptions<E> {
41
46
/** Cache state, will be updated. */
42
47
cache : CacheTree < IGlobCached < E > > ;
43
48
/** File to transform a path into extracted data emitted on onFile */
44
- fileProcessor : ( path : string ) => Promise < E > ;
49
+ fileProcessor : FileProcessorFn < E > ;
45
50
}
46
51
47
52
const forwardSlashRe = / \/ / g;
@@ -60,7 +65,7 @@ export class TurboGlobStream<E> {
60
65
61
66
private readonly filter ?: ( path : string , previousData ?: E ) => boolean ;
62
67
private readonly ignore : ( ( path : string ) => boolean ) [ ] ;
63
- private readonly processor : ( path : string ) => Promise < E > ;
68
+ private readonly processor : FileProcessorFn < E > ;
64
69
private readonly fileEmitter = new EventEmitter < E > ( ) ;
65
70
public readonly onFile = this . fileEmitter . event ;
66
71
private readonly errorEmitter = new EventEmitter < { path : string ; error : Error } > ( ) ;
@@ -121,7 +126,7 @@ export class TurboGlobStream<E> {
121
126
const depths = tokens [ 0 ] === '**' ? [ 0 , 1 ] : [ 0 ] ;
122
127
const cacheEntry = CacheTree . getPath ( opts . cache , opts . cwd ) ;
123
128
const ctx = { elements : tokens , seen : new Set < string > ( ) } ;
124
- return Promise . all ( depths . map ( d => this . readSomething ( ctx , d , opts . cwd , cacheEntry ) ) ) ;
129
+ return Promise . all ( depths . map ( d => this . readSomething ( ctx , d , opts . cwd , [ ] , cacheEntry ) ) ) ;
125
130
} ) ,
126
131
) . then ( ( ) => undefined ) ;
127
132
}
@@ -134,6 +139,7 @@ export class TurboGlobStream<E> {
134
139
ctx : ITokensContext ,
135
140
ti : number ,
136
141
path : string ,
142
+ siblings : readonly string [ ] ,
137
143
cache : CacheTree < IGlobCached < E > > ,
138
144
) {
139
145
// Skip already processed files, since we might see them twice during glob stars.
@@ -168,19 +174,32 @@ export class TurboGlobStream<E> {
168
174
// children added or removed.
169
175
if ( cd . type === CachedType . Directory ) {
170
176
const todo : unknown [ ] = [ ] ;
177
+ const entries = Object . entries ( cache . children ) ;
178
+ const siblings = entries
179
+ . filter ( ( [ , e ] ) => e . data ?. type !== CachedType . Directory )
180
+ . map ( ( [ n ] ) => n ) ;
181
+
171
182
for ( const [ name , child ] of Object . entries ( cache . children ) ) {
172
183
// for cached objects with a type, recurse normally. For ones without,
173
184
// try to stat them first (may have been interrupted before they were finished)
174
185
todo . push (
175
186
child . data !== undefined
176
- ? this . handleDirectoryEntry ( ctx , ti , path , { name, type : child . data . type } , cache )
187
+ ? this . handleDirectoryEntry (
188
+ ctx ,
189
+ ti ,
190
+ path ,
191
+ { name, type : child . data . type } ,
192
+ siblings ,
193
+ cache ,
194
+ )
177
195
: this . stat ( path ) . then (
178
196
stat =>
179
197
this . handleDirectoryEntry (
180
198
ctx ,
181
199
ti ,
182
200
path ,
183
201
{ name, type : stat . isFile ( ) ? CachedType . File : CachedType . Directory } ,
202
+ siblings ,
184
203
cache ,
185
204
) ,
186
205
( ) => undefined ,
@@ -200,7 +219,7 @@ export class TurboGlobStream<E> {
200
219
await this . handleDir ( ctx , ti , stat . mtimeMs , path , cache ) ;
201
220
} else {
202
221
this . alreadyProcessedFiles . add ( cache ) ;
203
- await this . handleFile ( stat . mtimeMs , path , cache ) ;
222
+ await this . handleFile ( stat . mtimeMs , path , siblings , cache ) ;
204
223
}
205
224
}
206
225
@@ -230,6 +249,7 @@ export class TurboGlobStream<E> {
230
249
ti : number ,
231
250
path : string ,
232
251
dirent : { name : string ; type : CachedType } ,
252
+ siblings : readonly string [ ] ,
233
253
cache : CacheTree < IGlobCached < E > > ,
234
254
) : unknown {
235
255
const nextPath = path + '/' + dirent . name ;
@@ -246,9 +266,11 @@ export class TurboGlobStream<E> {
246
266
}
247
267
248
268
if ( typeof descends === 'number' ) {
249
- return this . readSomething ( ctx , ti + descends , nextPath , nextChild ) ;
269
+ return this . readSomething ( ctx , ti + descends , nextPath , siblings , nextChild ) ;
250
270
} else {
251
- return Promise . all ( descends . map ( d => this . readSomething ( ctx , ti + d , nextPath , nextChild ) ) ) ;
271
+ return Promise . all (
272
+ descends . map ( d => this . readSomething ( ctx , ti + d , nextPath , siblings , nextChild ) ) ,
273
+ ) ;
252
274
}
253
275
}
254
276
@@ -295,11 +317,16 @@ export class TurboGlobStream<E> {
295
317
}
296
318
}
297
319
298
- private async handleFile ( mtime : number , path : string , cache : CacheTree < IGlobCached < E > > ) {
320
+ private async handleFile (
321
+ mtime : number ,
322
+ path : string ,
323
+ siblings : readonly string [ ] ,
324
+ cache : CacheTree < IGlobCached < E > > ,
325
+ ) {
299
326
const platformPath = sep === '/' ? path : path . replace ( forwardSlashRe , sep ) ;
300
327
let extracted : E ;
301
328
try {
302
- extracted = await this . processor ( platformPath ) ;
329
+ extracted = await this . processor ( platformPath , { siblings , mtime } ) ;
303
330
} catch ( error ) {
304
331
this . errorEmitter . fire ( { path : platformPath , error } ) ;
305
332
return ;
@@ -325,6 +352,7 @@ export class TurboGlobStream<E> {
325
352
}
326
353
327
354
const todo : unknown [ ] = [ ] ;
355
+ const siblings = files . filter ( f => f . isFile ( ) ) . map ( f => f . name ) ;
328
356
for ( const file of files ) {
329
357
if ( file . name . startsWith ( '.' ) ) {
330
358
continue ;
@@ -339,7 +367,9 @@ export class TurboGlobStream<E> {
339
367
continue ;
340
368
}
341
369
342
- todo . push ( this . handleDirectoryEntry ( ctx , ti , path , { name : file . name , type } , cache ) ) ;
370
+ todo . push (
371
+ this . handleDirectoryEntry ( ctx , ti , path , { name : file . name , type } , siblings , cache ) ,
372
+ ) ;
343
373
}
344
374
345
375
await Promise . all ( todo ) ;
0 commit comments