@@ -10,6 +10,7 @@ export class HashReader {
1010 private readonly _selectivityHashesPath : string ;
1111 private readonly _compresion : SelectivityCompressionType ;
1212 private _hashFileContents : Promise < HashFileContents > | null = null ;
13+ private _fileStateCache = new Map < string , boolean > ( ) ;
1314
1415 constructor ( selectivityRootPath : string , compression : SelectivityCompressionType ) {
1516 this . _selectivityHashesPath = getSelectivityHashesPath ( selectivityRootPath ) ;
@@ -24,60 +25,64 @@ export class HashReader {
2425 return ( this . _hashFileContents = readHashFileContents ( this . _selectivityHashesPath , this . _compresion ) ) ;
2526 }
2627
27- private _readHashForFile ( filePath : string ) : Promise < string > {
28- return this . _getHashFileContents ( ) . then ( hashFileContents => hashFileContents . files [ filePath ] ) ;
29- }
30-
31- private _readHashForModule ( moduleName : string ) : Promise < string > {
32- return this . _getHashFileContents ( ) . then ( hashFileContents => hashFileContents . modules [ moduleName ] ) ;
33- }
34-
35- private _readHashForPattern ( pattern : string ) : Promise < string > {
36- return this . _getHashFileContents ( ) . then ( hashFileContents => hashFileContents . patterns [ pattern ] ) ;
37- }
38-
3928 async patternHasChanged ( pattern : string ) : Promise < boolean > {
40- const [ cachedPatternHash , calculatedPatternHash ] = await Promise . all ( [
41- this . _readHashForPattern ( pattern ) ,
42- this . _hashProvider . calculateForPattern ( pattern ) ,
43- ] ) ;
29+ const fileContents = await this . _getHashFileContents ( ) ;
30+ const cachedPatternHash = fileContents . patterns [ pattern ] ;
31+ const calculatedPatternHash = await this . _hashProvider . calculateForPattern ( pattern ) ;
4432
4533 return cachedPatternHash !== calculatedPatternHash ;
4634 }
4735
4836 /** @returns changed deps or null, if nothing changed */
4937 async getTestChangedDeps ( testDeps : NormalizedDependencies ) : Promise < NormalizedDependencies | null > {
5038 const depFileTypes : Array < keyof NormalizedDependencies > = [ "css" , "js" , "modules" ] as const ;
51- const result : NormalizedDependencies = { css : [ ] , js : [ ] , modules : [ ] } ;
39+ const fileContents = await this . _getHashFileContents ( ) ;
5240
53- let hasAnythingChanged = false ;
41+ let result : NormalizedDependencies | null = null ;
5442
5543 const checkForDepFileType = async ( depFileType : keyof NormalizedDependencies ) : Promise < void > => {
56- await Promise . all (
57- testDeps [ depFileType ] . map ( async filePath => {
58- const adjustedFilePath = depFileType === "modules" ? path . join ( filePath , "package.json" ) : filePath ;
59- const [ cachedFileHash , calculatedFileHash ] = await Promise . all ( [
60- depFileType === "modules" ? this . _readHashForModule ( filePath ) : this . _readHashForFile ( filePath ) ,
61- this . _hashProvider . calculateForFile ( adjustedFilePath ) . catch ( ( err : Error ) => err ) ,
62- ] ) ;
63-
64- if ( calculatedFileHash instanceof Error ) {
65- debugSelectivity (
66- `Couldn't calculate hash for ${ adjustedFilePath } : ${ calculatedFileHash . message } ` ,
67- ) ;
68- }
69-
70- if ( cachedFileHash !== calculatedFileHash ) {
71- hasAnythingChanged = true ;
72- result [ depFileType ] . push ( filePath ) ;
73- }
74- } ) ,
75- ) ;
44+ for ( const filePath of testDeps [ depFileType ] ) {
45+ const isChanged = this . _fileStateCache . get ( filePath ) ;
46+
47+ if ( isChanged === false ) {
48+ continue ;
49+ } else if ( isChanged === true ) {
50+ result ||= { css : [ ] , js : [ ] , modules : [ ] } ;
51+ result [ depFileType ] . push ( filePath ) ;
52+ continue ;
53+ }
54+
55+ const adjustedFilePath = depFileType === "modules" ? path . join ( filePath , "package.json" ) : filePath ;
56+ const cachedFileHash =
57+ depFileType === "modules" ? fileContents . modules [ filePath ] : fileContents . files [ filePath ] ;
58+
59+ const calculatedFileHash = await this . _hashProvider
60+ . calculateForFile ( adjustedFilePath )
61+ . catch ( ( err : Error ) => err ) ;
62+
63+ if ( calculatedFileHash instanceof Error ) {
64+ debugSelectivity ( `${ calculatedFileHash . message } : ${ calculatedFileHash . cause } ` ) ;
65+ }
66+
67+ if ( cachedFileHash !== calculatedFileHash ) {
68+ result ||= { css : [ ] , js : [ ] , modules : [ ] } ;
69+ result [ depFileType ] . push ( filePath ) ;
70+ this . _fileStateCache . set ( filePath , true ) ;
71+ } else {
72+ this . _fileStateCache . set ( filePath , false ) ;
73+ }
74+ }
7675 } ;
7776
78- await Promise . all ( depFileTypes . map ( depFileType => checkForDepFileType ( depFileType ) ) ) ;
77+ for ( const depFileType of depFileTypes ) {
78+ await checkForDepFileType ( depFileType ) ;
79+ }
80+
81+ return result ;
82+ }
7983
80- return hasAnythingChanged ? result : null ;
84+ clearCache ( ) : void {
85+ this . _fileStateCache . clear ( ) ;
8186 }
8287}
8388
0 commit comments