@expo/metro-runtime 3.1.1 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"buildUrlForBundle.d.ts","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAI5D"}
1
+ {"version":3,"file":"buildUrlForBundle.d.ts","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAO5D"}
@@ -14,6 +14,9 @@ exports.buildUrlForBundle = void 0;
14
14
  * @returns a URL like "/foobar.bundle?platform=android&modulesOnly=true&runModule=false&runtimeBytecodeVersion=null"
15
15
  */
16
16
  function buildUrlForBundle(bundlePath) {
17
+ if (bundlePath.match(/^https?:\/\//)) {
18
+ return bundlePath;
19
+ }
17
20
  // NOTE(EvanBacon): This must come from the window origin (at least in dev mode).
18
21
  // Otherwise Metro will crash from attempting to load a bundle that doesn't exist.
19
22
  return '/' + bundlePath.replace(/^\/+/, '');
@@ -1 +1 @@
1
- {"version":3,"file":"buildUrlForBundle.js","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,UAAkB;IAClD,iFAAiF;IACjF,kFAAkF;IAClF,OAAO,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAJD,8CAIC","sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/**\n * Given a path and some optional additional query parameters, create the dev server bundle URL.\n * @param bundlePath like `/foobar`\n * @param params like `{ platform: \"web\" }`\n * @returns a URL like \"/foobar.bundle?platform=android&modulesOnly=true&runModule=false&runtimeBytecodeVersion=null\"\n */\nexport function buildUrlForBundle(bundlePath: string): string {\n // NOTE(EvanBacon): This must come from the window origin (at least in dev mode).\n // Otherwise Metro will crash from attempting to load a bundle that doesn't exist.\n return '/' + bundlePath.replace(/^\\/+/, '');\n}\n"]}
1
+ {"version":3,"file":"buildUrlForBundle.js","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH;;;;;GAKG;AACH,SAAgB,iBAAiB,CAAC,UAAkB;IAClD,IAAI,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;QACpC,OAAO,UAAU,CAAC;KACnB;IACD,iFAAiF;IACjF,kFAAkF;IAClF,OAAO,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAPD,8CAOC","sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/**\n * Given a path and some optional additional query parameters, create the dev server bundle URL.\n * @param bundlePath like `/foobar`\n * @param params like `{ platform: \"web\" }`\n * @returns a URL like \"/foobar.bundle?platform=android&modulesOnly=true&runModule=false&runtimeBytecodeVersion=null\"\n */\nexport function buildUrlForBundle(bundlePath: string): string {\n if (bundlePath.match(/^https?:\\/\\//)) {\n return bundlePath;\n }\n // NOTE(EvanBacon): This must come from the window origin (at least in dev mode).\n // Otherwise Metro will crash from attempting to load a bundle that doesn't exist.\n return '/' + bundlePath.replace(/^\\/+/, '');\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"buildUrlForBundle.native.d.ts","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.native.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAgB5D"}
1
+ {"version":3,"file":"buildUrlForBundle.native.d.ts","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.native.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAoB5D"}
@@ -8,6 +8,9 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.buildUrlForBundle = void 0;
10
10
  function buildUrlForBundle(bundlePath) {
11
+ if (bundlePath.match(/^https?:\/\//)) {
12
+ return bundlePath;
13
+ }
11
14
  if (process.env.NODE_ENV === 'production') {
12
15
  if (typeof location !== 'undefined') {
13
16
  return joinComponents(location.origin, bundlePath);
@@ -1 +1 @@
1
- {"version":3,"file":"buildUrlForBundle.native.js","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.native.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,SAAgB,iBAAiB,CAAC,UAAkB;IAClD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE;QACzC,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;YACnC,OAAO,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;SACpD;QACD,MAAM,IAAI,KAAK,CACb,6IAA6I,CAC9I,CAAC;KACH;SAAM;QACL,MAAM,YAAY,GAAG,OAAO,CAAC,iBAAiB,CAAC;aAC5C,OAAmD,CAAC;QAEvD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,YAAY,EAAE,CAAC;QAE1C,OAAO,cAAc,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;KAC9C;AACH,CAAC;AAhBD,8CAgBC;AAED,SAAS,cAAc,CAAC,MAAc,EAAE,MAAc;IACpD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACvE,CAAC","sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nexport function buildUrlForBundle(bundlePath: string): string {\n if (process.env.NODE_ENV === 'production') {\n if (typeof location !== 'undefined') {\n return joinComponents(location.origin, bundlePath);\n }\n throw new Error(\n 'Unable to determine the production URL where additional JavaScript chunks are hosted because the global \"location\" variable is not defined.'\n );\n } else {\n const getDevServer = require('../getDevServer')\n .default as typeof import('../getDevServer').default;\n\n const { url: serverUrl } = getDevServer();\n\n return joinComponents(serverUrl, bundlePath);\n }\n}\n\nfunction joinComponents(prefix: string, suffix: string): string {\n return prefix.replace(/\\/+$/, '') + '/' + suffix.replace(/^\\/+/, '');\n}\n"]}
1
+ {"version":3,"file":"buildUrlForBundle.native.js","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.native.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,SAAgB,iBAAiB,CAAC,UAAkB;IAClD,IAAI,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE;QACpC,OAAO,UAAU,CAAC;KACnB;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE;QACzC,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;YACnC,OAAO,cAAc,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;SACpD;QACD,MAAM,IAAI,KAAK,CACb,6IAA6I,CAC9I,CAAC;KACH;SAAM;QACL,MAAM,YAAY,GAAG,OAAO,CAAC,iBAAiB,CAAC;aAC5C,OAAmD,CAAC;QAEvD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,YAAY,EAAE,CAAC;QAE1C,OAAO,cAAc,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;KAC9C;AACH,CAAC;AApBD,8CAoBC;AAED,SAAS,cAAc,CAAC,MAAc,EAAE,MAAc;IACpD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACvE,CAAC","sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nexport function buildUrlForBundle(bundlePath: string): string {\n if (bundlePath.match(/^https?:\\/\\//)) {\n return bundlePath;\n }\n\n if (process.env.NODE_ENV === 'production') {\n if (typeof location !== 'undefined') {\n return joinComponents(location.origin, bundlePath);\n }\n throw new Error(\n 'Unable to determine the production URL where additional JavaScript chunks are hosted because the global \"location\" variable is not defined.'\n );\n } else {\n const getDevServer = require('../getDevServer')\n .default as typeof import('../getDevServer').default;\n\n const { url: serverUrl } = getDevServer();\n\n return joinComponents(serverUrl, bundlePath);\n }\n}\n\nfunction joinComponents(prefix: string, suffix: string): string {\n return prefix.replace(/\\/+$/, '') + '/' + suffix.replace(/^\\/+/, '');\n}\n"]}
@@ -6,6 +6,7 @@
6
6
  */
7
7
  export declare function fetchAsync(url: string): Promise<{
8
8
  body: string;
9
+ status: number;
9
10
  headers: Headers;
10
11
  }>;
11
12
  //# sourceMappingURL=fetchAsync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetchAsync.d.ts","sourceRoot":"","sources":["../../src/async-require/fetchAsync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAYzF"}
1
+ {"version":3,"file":"fetchAsync.d.ts","sourceRoot":"","sources":["../../src/async-require/fetchAsync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAa7D"}
@@ -17,6 +17,7 @@ async function fetchAsync(url) {
17
17
  });
18
18
  return {
19
19
  body: await response.text(),
20
+ status: response.status,
20
21
  headers: response.headers,
21
22
  };
22
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fetchAsync.js","sourceRoot":"","sources":["../../src/async-require/fetchAsync.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACI,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,wEAAwE;YACxE,eAAe,EAAE,KAAK;SACvB;KACF,CAAC,CAAC;IACH,OAAO;QACL,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE;QAC3B,OAAO,EAAE,QAAQ,CAAC,OAAO;KAC1B,CAAC;AACJ,CAAC;AAZD,gCAYC","sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nexport async function fetchAsync(url: string): Promise<{ body: string; headers: Headers }> {\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n // No real reason for this but we try to use this format for everything.\n 'expo-platform': 'web',\n },\n });\n return {\n body: await response.text(),\n headers: response.headers,\n };\n}\n"]}
1
+ {"version":3,"file":"fetchAsync.js","sourceRoot":"","sources":["../../src/async-require/fetchAsync.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACI,KAAK,UAAU,UAAU,CAC9B,GAAW;IAEX,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,wEAAwE;YACxE,eAAe,EAAE,KAAK;SACvB;KACF,CAAC,CAAC;IACH,OAAO;QACL,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE;QAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,OAAO,EAAE,QAAQ,CAAC,OAAO;KAC1B,CAAC;AACJ,CAAC;AAfD,gCAeC","sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nexport async function fetchAsync(\n url: string\n): Promise<{ body: string; status: number; headers: Headers }> {\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n // No real reason for this but we try to use this format for everything.\n 'expo-platform': 'web',\n },\n });\n return {\n body: await response.text(),\n status: response.status,\n headers: response.headers,\n };\n}\n"]}
@@ -7,6 +7,7 @@
7
7
  */
8
8
  export declare function fetchAsync(url: string): Promise<{
9
9
  body: string;
10
+ status: number;
10
11
  headers: Record<string, string>;
11
12
  }>;
12
13
  //# sourceMappingURL=fetchAsync.native.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetchAsync.native.d.ts","sourceRoot":"","sources":["../../src/async-require/fetchAsync.native.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAuD5D"}
1
+ {"version":3,"file":"fetchAsync.native.d.ts","sourceRoot":"","sources":["../../src/async-require/fetchAsync.native.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CA2D5E"}
@@ -16,6 +16,7 @@ const react_native_1 = require("react-native");
16
16
  const RCTNetworking_1 = __importDefault(require("react-native/Libraries/Network/RCTNetworking"));
17
17
  function fetchAsync(url) {
18
18
  let id = null;
19
+ let statusCode = null;
19
20
  let responseText = null;
20
21
  let headers = {};
21
22
  let dataListener = null;
@@ -30,6 +31,7 @@ function fetchAsync(url) {
30
31
  });
31
32
  responseListener = addListener('didReceiveNetworkResponse', ([requestId, status, responseHeaders]) => {
32
33
  if (requestId === id) {
34
+ statusCode = status;
33
35
  headers = responseHeaders;
34
36
  }
35
37
  });
@@ -39,7 +41,7 @@ function fetchAsync(url) {
39
41
  reject(error);
40
42
  }
41
43
  else {
42
- resolve({ body: responseText, headers });
44
+ resolve({ body: responseText, status: statusCode, headers });
43
45
  }
44
46
  }
45
47
  });
@@ -1 +1 @@
1
- {"version":3,"file":"fetchAsync.native.js","sourceRoot":"","sources":["../../src/async-require/fetchAsync.native.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;AAEH,+CAAwC;AACxC,mBAAmB;AACnB,iGAAsE;AAItE,SAAgB,UAAU,CACxB,GAAW;IAEX,IAAI,EAAE,GAAkB,IAAI,CAAC;IAC7B,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,IAAI,OAAO,GAA2B,EAAE,CAAC;IACzC,IAAI,YAAY,GAAsB,IAAI,CAAC;IAC3C,IAAI,gBAAgB,GAAsB,IAAI,CAAC;IAC/C,IAAI,gBAAgB,GAAsB,IAAI,CAAC;IAC/C,OAAO,IAAI,OAAO,CAAoD,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxF,MAAM,WAAW,GAAG,uBAAU,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAU,CAG3C,CAAC;QAChB,YAAY,GAAG,WAAW,CAAC,uBAAuB,EAAE,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE;YAC5E,IAAI,SAAS,KAAK,EAAE,EAAE;gBACpB,YAAY,GAAG,QAAQ,CAAC;aACzB;QACH,CAAC,CAAC,CAAC;QACH,gBAAgB,GAAG,WAAW,CAC5B,2BAA2B,EAC3B,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,EAAE;YACvC,IAAI,SAAS,KAAK,EAAE,EAAE;gBACpB,OAAO,GAAG,eAAe,CAAC;aAC3B;QACH,CAAC,CACF,CAAC;QACF,gBAAgB,GAAG,WAAW,CAAC,4BAA4B,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE;YAClF,IAAI,SAAS,KAAK,EAAE,EAAE;gBACpB,IAAI,KAAK,EAAE;oBACT,MAAM,CAAC,KAAK,CAAC,CAAC;iBACf;qBAAM;oBACL,OAAO,CAAC,EAAE,IAAI,EAAE,YAAa,EAAE,OAAO,EAAE,CAAC,CAAC;iBAC3C;aACF;QACH,CAAC,CAAC,CAAC;QACF,uBAAU,CAAC,WAAmB,CAC7B,KAAK,EACL,cAAc,EACd,GAAG,EACH;YACE,eAAe,EAAE,uBAAQ,CAAC,EAAE;SAC7B,EACD,EAAE,EACF,MAAM,EACN,KAAK,EACL,CAAC,EACD,CAAC,SAAiB,EAAE,EAAE;YACpB,EAAE,GAAG,SAAS,CAAC;QACjB,CAAC,EACD,IAAI,CACL,CAAC;IACJ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;QACd,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAzDD,gCAyDC","sourcesContent":["/**\n * Copyright (c) 650 Industries.\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { Platform } from 'react-native';\n// @ts-expect-error\nimport Networking from 'react-native/Libraries/Network/RCTNetworking';\n\ntype Subscriber = { remove: () => void };\n\nexport function fetchAsync(\n url: string\n): Promise<{ body: string; headers: Record<string, string> }> {\n let id: string | null = null;\n let responseText: string | null = null;\n let headers: Record<string, string> = {};\n let dataListener: Subscriber | null = null;\n let completeListener: Subscriber | null = null;\n let responseListener: Subscriber | null = null;\n return new Promise<{ body: string; headers: Record<string, string> }>((resolve, reject) => {\n const addListener = Networking.addListener.bind(Networking) as (\n event: string,\n callback: (props: [string, any, any]) => any\n ) => Subscriber;\n dataListener = addListener('didReceiveNetworkData', ([requestId, response]) => {\n if (requestId === id) {\n responseText = response;\n }\n });\n responseListener = addListener(\n 'didReceiveNetworkResponse',\n ([requestId, status, responseHeaders]) => {\n if (requestId === id) {\n headers = responseHeaders;\n }\n }\n );\n completeListener = addListener('didCompleteNetworkResponse', ([requestId, error]) => {\n if (requestId === id) {\n if (error) {\n reject(error);\n } else {\n resolve({ body: responseText!, headers });\n }\n }\n });\n (Networking.sendRequest as any)(\n 'GET',\n 'asyncRequest',\n url,\n {\n 'expo-platform': Platform.OS,\n },\n '',\n 'text',\n false,\n 0,\n (requestId: string) => {\n id = requestId;\n },\n true\n );\n }).finally(() => {\n dataListener?.remove();\n completeListener?.remove();\n responseListener?.remove();\n });\n}\n"]}
1
+ {"version":3,"file":"fetchAsync.native.js","sourceRoot":"","sources":["../../src/async-require/fetchAsync.native.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;AAEH,+CAAwC;AACxC,mBAAmB;AACnB,iGAAsE;AAItE,SAAgB,UAAU,CACxB,GAAW;IAEX,IAAI,EAAE,GAAkB,IAAI,CAAC;IAC7B,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,IAAI,OAAO,GAA2B,EAAE,CAAC;IACzC,IAAI,YAAY,GAAsB,IAAI,CAAC;IAC3C,IAAI,gBAAgB,GAAsB,IAAI,CAAC;IAC/C,IAAI,gBAAgB,GAAsB,IAAI,CAAC;IAC/C,OAAO,IAAI,OAAO,CAChB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAClB,MAAM,WAAW,GAAG,uBAAU,CAAC,WAAW,CAAC,IAAI,CAAC,uBAAU,CAG3C,CAAC;QAChB,YAAY,GAAG,WAAW,CAAC,uBAAuB,EAAE,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE;YAC5E,IAAI,SAAS,KAAK,EAAE,EAAE;gBACpB,YAAY,GAAG,QAAQ,CAAC;aACzB;QACH,CAAC,CAAC,CAAC;QACH,gBAAgB,GAAG,WAAW,CAC5B,2BAA2B,EAC3B,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,EAAE;YACvC,IAAI,SAAS,KAAK,EAAE,EAAE;gBACpB,UAAU,GAAG,MAAM,CAAC;gBACpB,OAAO,GAAG,eAAe,CAAC;aAC3B;QACH,CAAC,CACF,CAAC;QACF,gBAAgB,GAAG,WAAW,CAAC,4BAA4B,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE;YAClF,IAAI,SAAS,KAAK,EAAE,EAAE;gBACpB,IAAI,KAAK,EAAE;oBACT,MAAM,CAAC,KAAK,CAAC,CAAC;iBACf;qBAAM;oBACL,OAAO,CAAC,EAAE,IAAI,EAAE,YAAa,EAAE,MAAM,EAAE,UAAW,EAAE,OAAO,EAAE,CAAC,CAAC;iBAChE;aACF;QACH,CAAC,CAAC,CAAC;QACF,uBAAU,CAAC,WAAmB,CAC7B,KAAK,EACL,cAAc,EACd,GAAG,EACH;YACE,eAAe,EAAE,uBAAQ,CAAC,EAAE;SAC7B,EACD,EAAE,EACF,MAAM,EACN,KAAK,EACL,CAAC,EACD,CAAC,SAAiB,EAAE,EAAE;YACpB,EAAE,GAAG,SAAS,CAAC;QACjB,CAAC,EACD,IAAI,CACL,CAAC;IACJ,CAAC,CACF,CAAC,OAAO,CAAC,GAAG,EAAE;QACb,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AA7DD,gCA6DC","sourcesContent":["/**\n * Copyright (c) 650 Industries.\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { Platform } from 'react-native';\n// @ts-expect-error\nimport Networking from 'react-native/Libraries/Network/RCTNetworking';\n\ntype Subscriber = { remove: () => void };\n\nexport function fetchAsync(\n url: string\n): Promise<{ body: string; status: number; headers: Record<string, string> }> {\n let id: string | null = null;\n let statusCode: number | null = null;\n let responseText: string | null = null;\n let headers: Record<string, string> = {};\n let dataListener: Subscriber | null = null;\n let completeListener: Subscriber | null = null;\n let responseListener: Subscriber | null = null;\n return new Promise<{ body: string; status: number; headers: Record<string, string> }>(\n (resolve, reject) => {\n const addListener = Networking.addListener.bind(Networking) as (\n event: string,\n callback: (props: [string, any, any]) => any\n ) => Subscriber;\n dataListener = addListener('didReceiveNetworkData', ([requestId, response]) => {\n if (requestId === id) {\n responseText = response;\n }\n });\n responseListener = addListener(\n 'didReceiveNetworkResponse',\n ([requestId, status, responseHeaders]) => {\n if (requestId === id) {\n statusCode = status;\n headers = responseHeaders;\n }\n }\n );\n completeListener = addListener('didCompleteNetworkResponse', ([requestId, error]) => {\n if (requestId === id) {\n if (error) {\n reject(error);\n } else {\n resolve({ body: responseText!, status: statusCode!, headers });\n }\n }\n });\n (Networking.sendRequest as any)(\n 'GET',\n 'asyncRequest',\n url,\n {\n 'expo-platform': Platform.OS,\n },\n '',\n 'text',\n false,\n 0,\n (requestId: string) => {\n id = requestId;\n },\n true\n );\n }\n ).finally(() => {\n dataListener?.remove();\n completeListener?.remove();\n responseListener?.remove();\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"fetchThenEvalJs.d.ts","sourceRoot":"","sources":["../../src/async-require/fetchThenEvalJs.ts"],"names":[],"mappings":"AAYA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB7D"}
1
+ {"version":3,"file":"fetchThenEvalJs.d.ts","sourceRoot":"","sources":["../../src/async-require/fetchThenEvalJs.ts"],"names":[],"mappings":"AAYA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C7D"}
@@ -14,23 +14,52 @@ const fetchAsync_1 = require("./fetchAsync");
14
14
  * @param bundlePath Given a statement like `import('./Bacon')` `bundlePath` would be `Bacon`.
15
15
  */
16
16
  function fetchThenEvalAsync(url) {
17
- return (0, fetchAsync_1.fetchAsync)(url).then(({ body, headers }) => {
17
+ return (0, fetchAsync_1.fetchAsync)(url).then(({ body, status, headers }) => {
18
18
  if (headers?.has?.('Content-Type') != null &&
19
19
  headers.get('Content-Type').includes('application/json')) {
20
20
  // Errors are returned as JSON.
21
21
  throw new Error(JSON.parse(body).message || `Unknown error fetching '${url}'`);
22
22
  }
23
- // NOTE(EvanBacon): All of this code is ignored in development mode at the root.
24
- // Some engines do not support `sourceURL` as a comment. We expose a
25
- // `globalEvalWithSourceUrl` function to handle updates in that case.
26
- if (global.globalEvalWithSourceUrl) {
27
- global.globalEvalWithSourceUrl(body, url);
23
+ if (status === 200) {
24
+ // Some engines do not support `sourceURL` as a comment. We expose a
25
+ // `globalEvalWithSourceUrl` function to handle updates in that case.
26
+ if (global.globalEvalWithSourceUrl) {
27
+ return global.globalEvalWithSourceUrl(body, url);
28
+ }
29
+ else {
30
+ // eslint-disable-next-line no-eval
31
+ return eval(body);
32
+ }
28
33
  }
29
34
  else {
30
- // eslint-disable-next-line no-eval
31
- eval(body);
35
+ // Format Metro errors if possible.
36
+ if (process.env.NODE_ENV === 'development') {
37
+ // body can be an error from Metro if a module is missing.
38
+ // {"originModulePath":"/Users/evanbacon/Documents/GitHub/expo/.","targetModuleName":"./http://localhost:8081/node_modules/react-native/index.js","message":"..."}
39
+ const error = jsonParseOptional(body);
40
+ if (error) {
41
+ // TODO: This is essentially like the Metro native red box errors. We should do a better job formatting them so
42
+ // the user experience doesn't feel bad. This can be tested by loading a split bundle that results in a missing module error from Metro.
43
+ if ('message' in error) {
44
+ throw new Error('Failed to load split bundle from Metro ' +
45
+ url +
46
+ ' (check terminal for more info).\n(load: ' +
47
+ error.message +
48
+ ')');
49
+ }
50
+ }
51
+ }
52
+ throw new Error(`Failed to load split bundle from Metro ${url} (check terminal for more info).\n${body}`);
32
53
  }
33
54
  });
34
55
  }
35
56
  exports.fetchThenEvalAsync = fetchThenEvalAsync;
57
+ function jsonParseOptional(json) {
58
+ try {
59
+ return JSON.parse(json);
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
36
65
  //# sourceMappingURL=fetchThenEvalJs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetchThenEvalJs.js","sourceRoot":"","sources":["../../src/async-require/fetchThenEvalJs.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,6CAA0C;AAM1C;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,GAAW;IAC5C,OAAO,IAAA,uBAAU,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;QAChD,IACE,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,IAAI,IAAI;YACtC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EACzD;YACA,+BAA+B;YAC/B,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,2BAA2B,GAAG,GAAG,CAAC,CAAC;SAChF;QAED,gFAAgF;QAEhF,oEAAoE;QACpE,qEAAqE;QACrE,IAAI,MAAM,CAAC,uBAAuB,EAAE;YAClC,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;SAC3C;aAAM;YACL,mCAAmC;YACnC,IAAI,CAAC,IAAI,CAAC,CAAC;SACZ;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AArBD,gDAqBC","sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { fetchAsync } from './fetchAsync';\n\ndeclare let global: {\n globalEvalWithSourceUrl?: any;\n};\n\n/**\n * Load a bundle for a URL using fetch + eval on native and script tag injection on web.\n *\n * @param bundlePath Given a statement like `import('./Bacon')` `bundlePath` would be `Bacon`.\n */\nexport function fetchThenEvalAsync(url: string): Promise<void> {\n return fetchAsync(url).then(({ body, headers }) => {\n if (\n headers?.has?.('Content-Type') != null &&\n headers.get('Content-Type')!.includes('application/json')\n ) {\n // Errors are returned as JSON.\n throw new Error(JSON.parse(body).message || `Unknown error fetching '${url}'`);\n }\n\n // NOTE(EvanBacon): All of this code is ignored in development mode at the root.\n\n // Some engines do not support `sourceURL` as a comment. We expose a\n // `globalEvalWithSourceUrl` function to handle updates in that case.\n if (global.globalEvalWithSourceUrl) {\n global.globalEvalWithSourceUrl(body, url);\n } else {\n // eslint-disable-next-line no-eval\n eval(body);\n }\n });\n}\n"]}
1
+ {"version":3,"file":"fetchThenEvalJs.js","sourceRoot":"","sources":["../../src/async-require/fetchThenEvalJs.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,6CAA0C;AAM1C;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,GAAW;IAC5C,OAAO,IAAA,uBAAU,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACxD,IACE,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,IAAI,IAAI;YACtC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EACzD;YACA,+BAA+B;YAC/B,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,2BAA2B,GAAG,GAAG,CAAC,CAAC;SAChF;QAED,IAAI,MAAM,KAAK,GAAG,EAAE;YAClB,oEAAoE;YACpE,qEAAqE;YACrE,IAAI,MAAM,CAAC,uBAAuB,EAAE;gBAClC,OAAO,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;aAClD;iBAAM;gBACL,mCAAmC;gBACnC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;aACnB;SACF;aAAM;YACL,mCAAmC;YACnC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE;gBAC1C,0DAA0D;gBAC1D,kKAAkK;gBAClK,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBACtC,IAAI,KAAK,EAAE;oBACT,+GAA+G;oBAC/G,wIAAwI;oBACxI,IAAI,SAAS,IAAI,KAAK,EAAE;wBACtB,MAAM,IAAI,KAAK,CACb,yCAAyC;4BACvC,GAAG;4BACH,2CAA2C;4BAC3C,KAAK,CAAC,OAAO;4BACb,GAAG,CACN,CAAC;qBACH;iBACF;aACF;YAED,MAAM,IAAI,KAAK,CACb,0CAA0C,GAAG,qCAAqC,IAAI,EAAE,CACzF,CAAC;SACH;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AA7CD,gDA6CC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;KACzB;IAAC,MAAM;QACN,OAAO,IAAI,CAAC;KACb;AACH,CAAC","sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { fetchAsync } from './fetchAsync';\n\ndeclare let global: {\n globalEvalWithSourceUrl?: any;\n};\n\n/**\n * Load a bundle for a URL using fetch + eval on native and script tag injection on web.\n *\n * @param bundlePath Given a statement like `import('./Bacon')` `bundlePath` would be `Bacon`.\n */\nexport function fetchThenEvalAsync(url: string): Promise<void> {\n return fetchAsync(url).then(({ body, status, headers }) => {\n if (\n headers?.has?.('Content-Type') != null &&\n headers.get('Content-Type')!.includes('application/json')\n ) {\n // Errors are returned as JSON.\n throw new Error(JSON.parse(body).message || `Unknown error fetching '${url}'`);\n }\n\n if (status === 200) {\n // Some engines do not support `sourceURL` as a comment. We expose a\n // `globalEvalWithSourceUrl` function to handle updates in that case.\n if (global.globalEvalWithSourceUrl) {\n return global.globalEvalWithSourceUrl(body, url);\n } else {\n // eslint-disable-next-line no-eval\n return eval(body);\n }\n } else {\n // Format Metro errors if possible.\n if (process.env.NODE_ENV === 'development') {\n // body can be an error from Metro if a module is missing.\n // {\"originModulePath\":\"/Users/evanbacon/Documents/GitHub/expo/.\",\"targetModuleName\":\"./http://localhost:8081/node_modules/react-native/index.js\",\"message\":\"...\"}\n const error = jsonParseOptional(body);\n if (error) {\n // TODO: This is essentially like the Metro native red box errors. We should do a better job formatting them so\n // the user experience doesn't feel bad. This can be tested by loading a split bundle that results in a missing module error from Metro.\n if ('message' in error) {\n throw new Error(\n 'Failed to load split bundle from Metro ' +\n url +\n ' (check terminal for more info).\\n(load: ' +\n error.message +\n ')'\n );\n }\n }\n }\n\n throw new Error(\n `Failed to load split bundle from Metro ${url} (check terminal for more info).\\n${body}`\n );\n }\n });\n}\n\nfunction jsonParseOptional(json: string): any {\n try {\n return JSON.parse(json);\n } catch {\n return null;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/metro-runtime",
3
- "version": "3.1.1",
3
+ "version": "3.1.2",
4
4
  "description": "Tools for making advanced Metro bundler features work",
5
5
  "sideEffects": true,
6
6
  "types": "build",
@@ -36,5 +36,5 @@
36
36
  "peerDependencies": {
37
37
  "react-native": "*"
38
38
  },
39
- "gitHead": "102899632731658eecba006c0d1c79b98ba8f5f7"
39
+ "gitHead": "7fb94e3c0598d0e2d428184b16eec5ec67d80388"
40
40
  }
@@ -6,6 +6,10 @@
6
6
  */
7
7
 
8
8
  export function buildUrlForBundle(bundlePath: string): string {
9
+ if (bundlePath.match(/^https?:\/\//)) {
10
+ return bundlePath;
11
+ }
12
+
9
13
  if (process.env.NODE_ENV === 'production') {
10
14
  if (typeof location !== 'undefined') {
11
15
  return joinComponents(location.origin, bundlePath);
@@ -12,6 +12,9 @@
12
12
  * @returns a URL like "/foobar.bundle?platform=android&modulesOnly=true&runModule=false&runtimeBytecodeVersion=null"
13
13
  */
14
14
  export function buildUrlForBundle(bundlePath: string): string {
15
+ if (bundlePath.match(/^https?:\/\//)) {
16
+ return bundlePath;
17
+ }
15
18
  // NOTE(EvanBacon): This must come from the window origin (at least in dev mode).
16
19
  // Otherwise Metro will crash from attempting to load a bundle that doesn't exist.
17
20
  return '/' + bundlePath.replace(/^\/+/, '');
@@ -14,57 +14,61 @@ type Subscriber = { remove: () => void };
14
14
 
15
15
  export function fetchAsync(
16
16
  url: string
17
- ): Promise<{ body: string; headers: Record<string, string> }> {
17
+ ): Promise<{ body: string; status: number; headers: Record<string, string> }> {
18
18
  let id: string | null = null;
19
+ let statusCode: number | null = null;
19
20
  let responseText: string | null = null;
20
21
  let headers: Record<string, string> = {};
21
22
  let dataListener: Subscriber | null = null;
22
23
  let completeListener: Subscriber | null = null;
23
24
  let responseListener: Subscriber | null = null;
24
- return new Promise<{ body: string; headers: Record<string, string> }>((resolve, reject) => {
25
- const addListener = Networking.addListener.bind(Networking) as (
26
- event: string,
27
- callback: (props: [string, any, any]) => any
28
- ) => Subscriber;
29
- dataListener = addListener('didReceiveNetworkData', ([requestId, response]) => {
30
- if (requestId === id) {
31
- responseText = response;
32
- }
33
- });
34
- responseListener = addListener(
35
- 'didReceiveNetworkResponse',
36
- ([requestId, status, responseHeaders]) => {
25
+ return new Promise<{ body: string; status: number; headers: Record<string, string> }>(
26
+ (resolve, reject) => {
27
+ const addListener = Networking.addListener.bind(Networking) as (
28
+ event: string,
29
+ callback: (props: [string, any, any]) => any
30
+ ) => Subscriber;
31
+ dataListener = addListener('didReceiveNetworkData', ([requestId, response]) => {
37
32
  if (requestId === id) {
38
- headers = responseHeaders;
33
+ responseText = response;
39
34
  }
40
- }
41
- );
42
- completeListener = addListener('didCompleteNetworkResponse', ([requestId, error]) => {
43
- if (requestId === id) {
44
- if (error) {
45
- reject(error);
46
- } else {
47
- resolve({ body: responseText!, headers });
35
+ });
36
+ responseListener = addListener(
37
+ 'didReceiveNetworkResponse',
38
+ ([requestId, status, responseHeaders]) => {
39
+ if (requestId === id) {
40
+ statusCode = status;
41
+ headers = responseHeaders;
42
+ }
48
43
  }
49
- }
50
- });
51
- (Networking.sendRequest as any)(
52
- 'GET',
53
- 'asyncRequest',
54
- url,
55
- {
56
- 'expo-platform': Platform.OS,
57
- },
58
- '',
59
- 'text',
60
- false,
61
- 0,
62
- (requestId: string) => {
63
- id = requestId;
64
- },
65
- true
66
- );
67
- }).finally(() => {
44
+ );
45
+ completeListener = addListener('didCompleteNetworkResponse', ([requestId, error]) => {
46
+ if (requestId === id) {
47
+ if (error) {
48
+ reject(error);
49
+ } else {
50
+ resolve({ body: responseText!, status: statusCode!, headers });
51
+ }
52
+ }
53
+ });
54
+ (Networking.sendRequest as any)(
55
+ 'GET',
56
+ 'asyncRequest',
57
+ url,
58
+ {
59
+ 'expo-platform': Platform.OS,
60
+ },
61
+ '',
62
+ 'text',
63
+ false,
64
+ 0,
65
+ (requestId: string) => {
66
+ id = requestId;
67
+ },
68
+ true
69
+ );
70
+ }
71
+ ).finally(() => {
68
72
  dataListener?.remove();
69
73
  completeListener?.remove();
70
74
  responseListener?.remove();
@@ -4,7 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- export async function fetchAsync(url: string): Promise<{ body: string; headers: Headers }> {
7
+ export async function fetchAsync(
8
+ url: string
9
+ ): Promise<{ body: string; status: number; headers: Headers }> {
8
10
  const response = await fetch(url, {
9
11
  method: 'GET',
10
12
  headers: {
@@ -14,6 +16,7 @@ export async function fetchAsync(url: string): Promise<{ body: string; headers:
14
16
  });
15
17
  return {
16
18
  body: await response.text(),
19
+ status: response.status,
17
20
  headers: response.headers,
18
21
  };
19
22
  }
@@ -16,7 +16,7 @@ declare let global: {
16
16
  * @param bundlePath Given a statement like `import('./Bacon')` `bundlePath` would be `Bacon`.
17
17
  */
18
18
  export function fetchThenEvalAsync(url: string): Promise<void> {
19
- return fetchAsync(url).then(({ body, headers }) => {
19
+ return fetchAsync(url).then(({ body, status, headers }) => {
20
20
  if (
21
21
  headers?.has?.('Content-Type') != null &&
22
22
  headers.get('Content-Type')!.includes('application/json')
@@ -25,15 +25,47 @@ export function fetchThenEvalAsync(url: string): Promise<void> {
25
25
  throw new Error(JSON.parse(body).message || `Unknown error fetching '${url}'`);
26
26
  }
27
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);
28
+ if (status === 200) {
29
+ // Some engines do not support `sourceURL` as a comment. We expose a
30
+ // `globalEvalWithSourceUrl` function to handle updates in that case.
31
+ if (global.globalEvalWithSourceUrl) {
32
+ return global.globalEvalWithSourceUrl(body, url);
33
+ } else {
34
+ // eslint-disable-next-line no-eval
35
+ return eval(body);
36
+ }
34
37
  } else {
35
- // eslint-disable-next-line no-eval
36
- eval(body);
38
+ // Format Metro errors if possible.
39
+ if (process.env.NODE_ENV === 'development') {
40
+ // body can be an error from Metro if a module is missing.
41
+ // {"originModulePath":"/Users/evanbacon/Documents/GitHub/expo/.","targetModuleName":"./http://localhost:8081/node_modules/react-native/index.js","message":"..."}
42
+ const error = jsonParseOptional(body);
43
+ if (error) {
44
+ // TODO: This is essentially like the Metro native red box errors. We should do a better job formatting them so
45
+ // the user experience doesn't feel bad. This can be tested by loading a split bundle that results in a missing module error from Metro.
46
+ if ('message' in error) {
47
+ throw new Error(
48
+ 'Failed to load split bundle from Metro ' +
49
+ url +
50
+ ' (check terminal for more info).\n(load: ' +
51
+ error.message +
52
+ ')'
53
+ );
54
+ }
55
+ }
56
+ }
57
+
58
+ throw new Error(
59
+ `Failed to load split bundle from Metro ${url} (check terminal for more info).\n${body}`
60
+ );
37
61
  }
38
62
  });
39
63
  }
64
+
65
+ function jsonParseOptional(json: string): any {
66
+ try {
67
+ return JSON.parse(json);
68
+ } catch {
69
+ return null;
70
+ }
71
+ }