namespace ts . server { export interface PackageJsonCache { addOrUpdate ( fileName ) : void ; forEach ( action ) : void ; delete ( fileName ) : void ; get ( fileName ) : PackageJsonInfo | false | undefined ; getInDirectory ( directory ) : PackageJsonInfo | undefined ; directoryHasPackageJson ( directory ) : Ternary ; searchDirectoryAndAncestors ( directory ) : void ; } export function createPackageJsonCache ( host ) { const packageJsons = new Map < string , PackageJsonInfo > ( ) ; const directoriesWithoutPackageJson = new Map < string , true > ( ) ; return { addOrUpdate , forEach : packageJsons . forEach . bind ( packageJsons ) , get : packageJsons . get . bind ( packageJsons ) , delete : fileName => { packageJsons . delete ( fileName ) ; directoriesWithoutPackageJson . set ( getDirectoryPath ( fileName ) , true ) ; } , getInDirectory : directory => { return packageJsons . get ( combinePaths ( directory , "package.json" ) ) || undefined ; } , directoryHasPackageJson , searchDirectoryAndAncestors : directory => { forEachAncestorDirectory ( directory , ancestor => { if ( directoryHasPackageJson ( ancestor ) !== Ternary . Maybe ) { return true ; } const packageJsonFileName = host . toPath ( combinePaths ( ancestor , "package.json" ) ) ; if ( tryFileExists ( host , packageJsonFileName ) ) { addOrUpdate ( packageJsonFileName ) ; } else { directoriesWithoutPackageJson . set ( ancestor , true ) ; } } ) ; } , } ; function addOrUpdate ( fileName ) { const packageJsonInfo = Debug . checkDefined ( createPackageJsonInfo ( fileName , host . host ) ) ; packageJsons . set ( fileName , packageJsonInfo ) ; directoriesWithoutPackageJson . delete ( getDirectoryPath ( fileName ) ) ; } function directoryHasPackageJson ( directory ) { return packageJsons . has ( combinePaths ( directory , "package.json" ) ) ? Ternary . True : directoriesWithoutPackageJson . has ( directory ) ? Ternary . False : Ternary . Maybe ; } } }