import fs from 'fs-extra' ; import os from 'os' ; import path from 'path' ; class Cacher < T > { refresher : ( ) => Promise < T > ; filename : string ; bootstrapFile ? : string ; ttlMilliseconds : number ; readError ? : any ; writeError ? : any ; constructor ( refresher , filename , ttlMilliseconds ? , bootstrapFile ? ) { this . refresher = refresher ; this . filename = path . join ( getCacheDir ( ) , filename ) ; this . ttlMilliseconds = ttlMilliseconds || 0 ; this . bootstrapFile = bootstrapFile ; } async getAsync ( ) { if ( process . env . SKIP_CACHE ) { return await this . refresher ( ) ; } let mtime ; try { const stats = await fs . stat ( this . filename ) ; mtime = stats . mtime ; } catch ( e ) { try { await fs . mkdirp ( getCacheDir ( ) ) ; if ( this . bootstrapFile ) { const bootstrapContents = ( await fs . readFile ( this . bootstrapFile ) ) . toString ( ) ; await fs . writeFile ( this . filename , bootstrapContents , 'utf8' ) ; } } catch ( e ) { } mtime = new Date ( 1989 , 10 , 19 ) ; } let fromCache = null ; let failedRefresh = null ; if ( this . ttlMilliseconds === 0 || new Date ( ) . getTime ( ) - mtime . getTime ( ) > this . ttlMilliseconds ) { try { fromCache = await this . refresher ( ) ; try { await fs . writeFile ( this . filename , JSON . stringify ( fromCache ) , 'utf8' ) ; } catch ( e ) { this . writeError = e ; } } catch ( e ) { failedRefresh = e ; } } if ( ! fromCache ) { try { fromCache = JSON . parse ( await fs . readFile ( this . filename , 'utf8' ) ) ; } catch ( e ) { this . readError = e ; } } if ( fromCache ) { return fromCache ; } else { if ( failedRefresh ) { throw new Error ( `Unable to perform cache refresh for ${ this . filename }: ${ failedRefresh }` ) ; } else { throw new Error ( `Unable to read ${ this . filename }. ${ this . readError || '' }` ) ; } } } async clearAsync ( ) { try { await fs . unlink ( this . filename ) ; } catch ( e ) { this . writeError = e ; } } } function getCacheDir ( ) { const homeDir = os . homedir ( ) ; if ( process . env . XDG_CACHE_HOME ) { return process . env . XDG_CACHE_HOME ; } else if ( process . platform === 'win32' ) { return path . join ( homeDir , 'AppData' , 'Local' , 'Expo' ) ; } else if ( process . platform === 'darwin' ) { return path . join ( homeDir , '.expo' , 'cache' ) ; } else { return path . join ( homeDir , '.cache' , 'expo' ) ; } } export { Cacher , getCacheDir } ;