1import chalk from 'chalk'; 2 3/** 4 * Wrap a method and profile the time it takes to execute the method using `EXPO_PROFILE`. 5 * Works best with named functions (i.e. not arrow functions). 6 * 7 * @param fn function to profile. 8 * @param functionName optional name of the function to display in the profile output. 9 */ 10export function profile<IArgs extends any[], T extends (...args: IArgs) => any>( 11 fn: T, 12 functionName: string = fn.name 13): T { 14 if (!process.env['DEBUG']) { 15 return fn; 16 } 17 18 const name = chalk.dim(`⏱ [profile] ${functionName ?? 'unknown'}`); 19 20 return ((...args: IArgs) => { 21 // Start the timer. 22 console.time(name); 23 24 // Invoke the method. 25 const results = fn(...args); 26 27 // If non-promise then return as-is. 28 if (!(results instanceof Promise)) { 29 console.timeEnd(name); 30 return results; 31 } 32 33 // Otherwise await to profile after the promise resolves. 34 return new Promise<Awaited<ReturnType<T>>>((resolve, reject) => { 35 results.then( 36 (results) => { 37 resolve(results); 38 console.timeEnd(name); 39 }, 40 (reason) => { 41 reject(reason); 42 console.timeEnd(name); 43 } 44 ); 45 }); 46 }) as T; 47} 48