1import { FetchLike } from './client.types'; 2import * as Log from '../../log'; 3const debug = require('debug')('expo:api:fetch:progress') as typeof console.log; 4 5export function wrapFetchWithProgress(fetch: FetchLike): FetchLike { 6 return (url, init) => { 7 return fetch(url, init).then((res) => { 8 if (res.ok && init?.onProgress) { 9 const totalDownloadSize = res.headers.get('Content-Length'); 10 const total = Number(totalDownloadSize); 11 12 debug(`Download size: ${totalDownloadSize}`); 13 if (!totalDownloadSize || isNaN(total) || total < 0) { 14 Log.warn( 15 'Progress callback not supported for network request because "Content-Length" header missing or invalid in response from URL:', 16 url.toString() 17 ); 18 return res; 19 } 20 21 let length = 0; 22 23 debug(`Starting progress animation for ${url}`); 24 res.body.on('data', (chunk) => { 25 length += Buffer.byteLength(chunk); 26 onProgress(); 27 }); 28 29 res.body.on('end', () => { 30 debug(`Finished progress animation for ${url}`); 31 onProgress(); 32 }); 33 34 const onProgress = () => { 35 const progress = length / total || 0; 36 init.onProgress?.({ 37 progress, 38 total, 39 loaded: length, 40 }); 41 }; 42 } 43 return res; 44 }); 45 }; 46} 47