fetch-api-progress
Version:
Upload and download progress for Fetch API
2 lines (1 loc) • 1.59 kB
JavaScript
function r(e){return e.lengthComputable?{get lengthComputable(){return!0},get loaded(){return e.loaded},get total(){return e.total}}:{get lengthComputable(){return!1},get loaded(){return e.loaded}}}function b(e,n){if(!n)return e;let a=(()=>{let t=!1,d=new Request("https://teil.one",{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!d})();if(!e.body||!a||/^get$/i.test(e.method??"")||/^head$/i.test(e.method??""))return e;if(!(e.body instanceof Blob))throw new Error("Request progress tracking is supported only for Blob and File");let l=e.body,o=l.size,s=0,u=new TransformStream({start(){let t=r({lengthComputable:a,loaded:0,total:o});n(t)},transform(t,d){d.enqueue(t),s+=t.byteLength;let c=r({lengthComputable:a,loaded:s,total:o});n(c)},flush(){let t=r({lengthComputable:a,loaded:o,total:o});n(t)}});return{...e,body:l.stream().pipeThrough(u),duplex:"half"}}function C(e,n){if(!n)return e;let a=typeof Response<"u"&&typeof ReadableStream<"u";if(!e.body||!a)return e;let l=e.body.getReader(),o=0,s=e.headers.get("content-length"),u=e.headers.get("content-encoding"),g=u&&!/^identity$/i.test(u),t=s&&!g?parseInt(s,10):void 0,d=new ReadableStream({start(c){n(r({lengthComputable:typeof t<"u",loaded:o,total:t})),async function f(){let{done:h,value:p}=await l.read();if(h){n(r({lengthComputable:typeof t<"u",loaded:o,total:t})),c.close();return}p&&(o+=p.length,n(r({lengthComputable:typeof t<"u",loaded:o,total:t}))),c.enqueue(p),f()}()}});return new Response(d,e)}export{b as trackRequestProgress,C as trackResponseProgress};