18d307f52SEvan Baconimport { FetchLike } from './client.types';
2*8a424bebSJames Ideimport * as Log from '../../log';
382f3de79SEvan Baconconst debug = require('debug')('expo:api:fetch:progress') as typeof console.log;
48d307f52SEvan Bacon
58d307f52SEvan Baconexport function wrapFetchWithProgress(fetch: FetchLike): FetchLike {
682f3de79SEvan Bacon  return (url, init) => {
782f3de79SEvan Bacon    return fetch(url, init).then((res) => {
88d307f52SEvan Bacon      if (res.ok && init?.onProgress) {
98d307f52SEvan Bacon        const totalDownloadSize = res.headers.get('Content-Length');
108d307f52SEvan Bacon        const total = Number(totalDownloadSize);
118d307f52SEvan Bacon
1282f3de79SEvan Bacon        debug(`Download size: ${totalDownloadSize}`);
138d307f52SEvan Bacon        if (!totalDownloadSize || isNaN(total) || total < 0) {
148d307f52SEvan Bacon          Log.warn(
158d307f52SEvan Bacon            'Progress callback not supported for network request because "Content-Length" header missing or invalid in response from URL:',
168d307f52SEvan Bacon            url.toString()
178d307f52SEvan Bacon          );
188d307f52SEvan Bacon          return res;
198d307f52SEvan Bacon        }
208d307f52SEvan Bacon
218d307f52SEvan Bacon        let length = 0;
228d307f52SEvan Bacon
2382f3de79SEvan Bacon        debug(`Starting progress animation for ${url}`);
248d307f52SEvan Bacon        res.body.on('data', (chunk) => {
2582f3de79SEvan Bacon          length += Buffer.byteLength(chunk);
268d307f52SEvan Bacon          onProgress();
278d307f52SEvan Bacon        });
288d307f52SEvan Bacon
298d307f52SEvan Bacon        res.body.on('end', () => {
3082f3de79SEvan Bacon          debug(`Finished progress animation for ${url}`);
318d307f52SEvan Bacon          onProgress();
328d307f52SEvan Bacon        });
338d307f52SEvan Bacon
348d307f52SEvan Bacon        const onProgress = () => {
3582f3de79SEvan Bacon          const progress = length / total || 0;
3629975bfdSEvan Bacon          init.onProgress?.({
378d307f52SEvan Bacon            progress,
388d307f52SEvan Bacon            total,
398d307f52SEvan Bacon            loaded: length,
408d307f52SEvan Bacon          });
418d307f52SEvan Bacon        };
428d307f52SEvan Bacon      }
438d307f52SEvan Bacon      return res;
4482f3de79SEvan Bacon    });
458d307f52SEvan Bacon  };
468d307f52SEvan Bacon}
47