18d307f52SEvan Baconimport chalk from 'chalk'; 28d307f52SEvan Bacon 3814b6fafSEvan Baconimport { env } from './env'; 4*8a424bebSJames Ideimport * as Log from '../log'; 58d307f52SEvan Bacon 68d307f52SEvan Bacon/** 78d307f52SEvan Bacon * Wrap a method and profile the time it takes to execute the method using `EXPO_PROFILE`. 88d307f52SEvan Bacon * Works best with named functions (i.e. not arrow functions). 98d307f52SEvan Bacon * 108d307f52SEvan Bacon * @param fn function to profile. 118d307f52SEvan Bacon * @param functionName optional name of the function to display in the profile output. 128d307f52SEvan Bacon */ 138d307f52SEvan Baconexport function profile<IArgs extends any[], T extends (...args: IArgs) => any>( 148d307f52SEvan Bacon fn: T, 158d307f52SEvan Bacon functionName: string = fn.name 168d307f52SEvan Bacon): T { 17814b6fafSEvan Bacon if (!env.EXPO_PROFILE) { 188d307f52SEvan Bacon return fn; 198d307f52SEvan Bacon } 208d307f52SEvan Bacon 218d307f52SEvan Bacon const name = chalk.dim(`⏱ [profile] ${functionName ?? 'unknown'}`); 228d307f52SEvan Bacon 238d307f52SEvan Bacon return ((...args: IArgs) => { 248d307f52SEvan Bacon // Start the timer. 258d307f52SEvan Bacon Log.time(name); 268d307f52SEvan Bacon 278d307f52SEvan Bacon // Invoke the method. 288d307f52SEvan Bacon const results = fn(...args); 298d307f52SEvan Bacon 308d307f52SEvan Bacon // If non-promise then return as-is. 318d307f52SEvan Bacon if (!(results instanceof Promise)) { 328d307f52SEvan Bacon Log.timeEnd(name); 338d307f52SEvan Bacon return results; 348d307f52SEvan Bacon } 358d307f52SEvan Bacon 368d307f52SEvan Bacon // Otherwise await to profile after the promise resolves. 378d307f52SEvan Bacon return new Promise<Awaited<ReturnType<T>>>((resolve, reject) => { 388d307f52SEvan Bacon results.then( 398d307f52SEvan Bacon (results) => { 408d307f52SEvan Bacon resolve(results); 418d307f52SEvan Bacon Log.timeEnd(name); 428d307f52SEvan Bacon }, 438d307f52SEvan Bacon (reason) => { 448d307f52SEvan Bacon reject(reason); 458d307f52SEvan Bacon Log.timeEnd(name); 468d307f52SEvan Bacon } 478d307f52SEvan Bacon ); 488d307f52SEvan Bacon }); 498d307f52SEvan Bacon }) as T; 508d307f52SEvan Bacon} 51