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