1*26ad19fcSEvan Bacon/**
2*26ad19fcSEvan Bacon * Copyright (c) 650 Industries.
3*26ad19fcSEvan Bacon * Copyright (c) Facebook, Inc. and its affiliates.
4*26ad19fcSEvan Bacon *
5*26ad19fcSEvan Bacon * This source code is licensed under the MIT license found in the
6*26ad19fcSEvan Bacon * LICENSE file in the root directory of this source tree.
7*26ad19fcSEvan Bacon */
8*26ad19fcSEvan Bacon
9*26ad19fcSEvan Baconimport { Platform } from 'react-native';
10*26ad19fcSEvan Bacon// @ts-expect-error
11*26ad19fcSEvan Baconimport Networking from 'react-native/Libraries/Network/RCTNetworking';
12*26ad19fcSEvan Bacon
13*26ad19fcSEvan Bacontype Subscriber = { remove: () => void };
14*26ad19fcSEvan Bacon
15*26ad19fcSEvan Baconexport function fetchAsync(
16*26ad19fcSEvan Bacon  url: string
17*26ad19fcSEvan Bacon): Promise<{ body: string; headers: Record<string, string> }> {
18*26ad19fcSEvan Bacon  let id: string | null = null;
19*26ad19fcSEvan Bacon  let responseText: string | null = null;
20*26ad19fcSEvan Bacon  let headers: Record<string, string> = {};
21*26ad19fcSEvan Bacon  let dataListener: Subscriber | null = null;
22*26ad19fcSEvan Bacon  let completeListener: Subscriber | null = null;
23*26ad19fcSEvan Bacon  let responseListener: Subscriber | null = null;
24*26ad19fcSEvan Bacon  return new Promise<{ body: string; headers: Record<string, string> }>((resolve, reject) => {
25*26ad19fcSEvan Bacon    const addListener = Networking.addListener as (
26*26ad19fcSEvan Bacon      event: string,
27*26ad19fcSEvan Bacon      callback: (props: [string, any, any]) => any
28*26ad19fcSEvan Bacon    ) => Subscriber;
29*26ad19fcSEvan Bacon    dataListener = addListener('didReceiveNetworkData', ([requestId, response]) => {
30*26ad19fcSEvan Bacon      if (requestId === id) {
31*26ad19fcSEvan Bacon        responseText = response;
32*26ad19fcSEvan Bacon      }
33*26ad19fcSEvan Bacon    });
34*26ad19fcSEvan Bacon    responseListener = addListener(
35*26ad19fcSEvan Bacon      'didReceiveNetworkResponse',
36*26ad19fcSEvan Bacon      ([requestId, status, responseHeaders]) => {
37*26ad19fcSEvan Bacon        if (requestId === id) {
38*26ad19fcSEvan Bacon          headers = responseHeaders;
39*26ad19fcSEvan Bacon        }
40*26ad19fcSEvan Bacon      }
41*26ad19fcSEvan Bacon    );
42*26ad19fcSEvan Bacon    completeListener = addListener('didCompleteNetworkResponse', ([requestId, error]) => {
43*26ad19fcSEvan Bacon      if (requestId === id) {
44*26ad19fcSEvan Bacon        if (error) {
45*26ad19fcSEvan Bacon          reject(error);
46*26ad19fcSEvan Bacon        } else {
47*26ad19fcSEvan Bacon          resolve({ body: responseText!, headers });
48*26ad19fcSEvan Bacon        }
49*26ad19fcSEvan Bacon      }
50*26ad19fcSEvan Bacon    });
51*26ad19fcSEvan Bacon    (Networking.sendRequest as any)(
52*26ad19fcSEvan Bacon      'GET',
53*26ad19fcSEvan Bacon      'asyncRequest',
54*26ad19fcSEvan Bacon      url,
55*26ad19fcSEvan Bacon      {
56*26ad19fcSEvan Bacon        'expo-platform': Platform.OS,
57*26ad19fcSEvan Bacon      },
58*26ad19fcSEvan Bacon      '',
59*26ad19fcSEvan Bacon      'text',
60*26ad19fcSEvan Bacon      false,
61*26ad19fcSEvan Bacon      0,
62*26ad19fcSEvan Bacon      (requestId: string) => {
63*26ad19fcSEvan Bacon        id = requestId;
64*26ad19fcSEvan Bacon      },
65*26ad19fcSEvan Bacon      true
66*26ad19fcSEvan Bacon    );
67*26ad19fcSEvan Bacon  }).finally(() => {
68*26ad19fcSEvan Bacon    dataListener?.remove();
69*26ad19fcSEvan Bacon    completeListener?.remove();
70*26ad19fcSEvan Bacon    responseListener?.remove();
71*26ad19fcSEvan Bacon  });
72*26ad19fcSEvan Bacon}
73