1/**
2 * Copyright © 2022 650 Industries.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7import { fetchAsync } from './fetchAsync';
8
9declare let global: {
10  globalEvalWithSourceUrl?: any;
11};
12
13/**
14 * Load a bundle for a URL using fetch + eval on native and script tag injection on web.
15 *
16 * @param bundlePath Given a statement like `import('./Bacon')` `bundlePath` would be `Bacon`.
17 */
18export function fetchThenEvalAsync(url: string): Promise<void> {
19  return fetchAsync(url).then(({ body, headers }) => {
20    if (
21      headers?.has?.('Content-Type') != null &&
22      headers.get('Content-Type')!.includes('application/json')
23    ) {
24      // Errors are returned as JSON.
25      throw new Error(JSON.parse(body).message || `Unknown error fetching '${url}'`);
26    }
27
28    // NOTE(EvanBacon): All of this code is ignored in development mode at the root.
29
30    // Some engines do not support `sourceURL` as a comment. We expose a
31    // `globalEvalWithSourceUrl` function to handle updates in that case.
32    if (global.globalEvalWithSourceUrl) {
33      global.globalEvalWithSourceUrl(body, url);
34    } else {
35      // eslint-disable-next-line no-eval
36      eval(body);
37    }
38  });
39}
40