1*8a424bebSJames Ideimport { DevServerManager } from './DevServerManager'; 28d307f52SEvan Baconimport { AbortCommandError } from '../../utils/errors'; 38d307f52SEvan Baconimport { Options } from '../resolveOptions'; 48d307f52SEvan Bacon 58d307f52SEvan Bacon/** Launch the app on various platforms in parallel. */ 68d307f52SEvan Baconexport async function openPlatformsAsync( 78d307f52SEvan Bacon devServerManager: DevServerManager, 88d307f52SEvan Bacon options: Pick<Options, 'ios' | 'android' | 'web'> 98d307f52SEvan Bacon) { 108d307f52SEvan Bacon const results = await Promise.allSettled([ 118d307f52SEvan Bacon options.android ? devServerManager.getDefaultDevServer().openPlatformAsync('emulator') : null, 128d307f52SEvan Bacon options.ios ? devServerManager.getDefaultDevServer().openPlatformAsync('simulator') : null, 138d307f52SEvan Bacon options.web 148d307f52SEvan Bacon ? devServerManager 158d307f52SEvan Bacon .ensureWebDevServerRunningAsync() 1629975bfdSEvan Bacon .then(() => devServerManager.getWebDevServer()?.openPlatformAsync('desktop')) 178d307f52SEvan Bacon : null, 188d307f52SEvan Bacon ]); 198d307f52SEvan Bacon 208d307f52SEvan Bacon const errors = results 218d307f52SEvan Bacon .map((result) => (result.status === 'rejected' ? result.reason : null)) 228d307f52SEvan Bacon .filter(Boolean); 238d307f52SEvan Bacon 248d307f52SEvan Bacon if (errors.length) { 258d307f52SEvan Bacon // ctrl+c 268d307f52SEvan Bacon const isEscapedError = errors.some((error: any) => error.code === 'ABORTED'); 278d307f52SEvan Bacon if (isEscapedError) { 288d307f52SEvan Bacon throw new AbortCommandError(); 298d307f52SEvan Bacon } 308d307f52SEvan Bacon throw errors[0]; 318d307f52SEvan Bacon } 328d307f52SEvan Bacon 338d307f52SEvan Bacon return !!options.android || !!options.ios; 348d307f52SEvan Bacon} 35