From 6ae23c67253cfb1839a948e107f276a4998bfe8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 8 Sep 2021 17:44:02 -0300 Subject: [PATCH 1/2] status: When a chunk abort(), eg when parent's FlowFile.pause(), set its status back to pending (and pendingRetry === true) since it's actually not "uploading" anymore --- src/FlowChunk.js | 4 ++-- src/FlowFile.js | 6 +++--- test/uploadSpec.js | 4 +++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/FlowChunk.js b/src/FlowChunk.js index c3b2013..ece7f06 100644 --- a/src/FlowChunk.js +++ b/src/FlowChunk.js @@ -444,11 +444,11 @@ export default class FlowChunk { status(isTest) { if (this.readState === 1) { return 'reading'; - } else if (this.pendingRetry || this.preprocessState === 1) { + } else if (this.preprocessState === 1) { // if pending retry then that's effectively the same as actively uploading, // there might just be a slight delay before the retry starts return 'uploading'; - } else if (!this.xhr) { + } else if (!this.xhr || this.pendingRetry) { return 'pending'; } else if (this.xhr.readyState < 4) { // Status is really 'OPENED', 'HEADERS_RECEIVED' diff --git a/src/FlowFile.js b/src/FlowFile.js index 9e1a8f2..46b99b9 100644 --- a/src/FlowFile.js +++ b/src/FlowFile.js @@ -196,16 +196,16 @@ export default class FlowFile { abort(reset) { this.currentSpeed = 0; this.averageSpeed = 0; - var chunks = this.chunks; if (reset) { this.chunks = []; } - each(chunks, function (c) { + for (let c of this.chunks) { if (c.status() === 'uploading') { c.abort(); + c.pendingRetry = true; this.flowObj.uploadNextChunk(); } - }, this); + } } /** diff --git a/test/uploadSpec.js b/test/uploadSpec.js index a36b6f2..b6a6927 100644 --- a/test/uploadSpec.js +++ b/test/uploadSpec.js @@ -127,6 +127,7 @@ describe('upload file', function() { it('should pause and resume file', function () { flow.opts.chunkSize = 1; flow.opts.simultaneousUploads = 2; + flow.opts.testChunks = false; flow.addFile(new Blob(['1234'])); flow.addFile(new Blob(['56'])); var files = flow.files; @@ -271,6 +272,7 @@ describe('upload file', function() { flow.addFile(new Blob(['12'])); var file = flow.files[0]; flow.upload(); + expect(file.chunks[0].status()).toBe('uploading'); expect(xhr.requests.length).toBe(1); xhr.requests[0].respond(400); @@ -278,7 +280,7 @@ describe('upload file', function() { expect(error).not.toHaveBeenCalled(); expect(success).not.toHaveBeenCalled(); expect(retry).toHaveBeenCalled(); - expect(file.chunks[0].status()).toBe('uploading'); + expect(file.chunks[0].status()).toBe('pending'); jasmine.clock().tick(100); expect(xhr.requests.length).toBe(2); From 9c8d3ce697ddd3ca26046255ac8e854736acd103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 8 Sep 2021 17:55:13 -0300 Subject: [PATCH 2/2] update bulds --- dist/flow.js | 29 ++++++++++++++++++++--------- dist/flow.min.js | 2 +- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/dist/flow.js b/dist/flow.js index bad3d7b..e101a12 100644 --- a/dist/flow.js +++ b/dist/flow.js @@ -6121,11 +6121,11 @@ value: function status(isTest) { if (this.readState === 1) { return 'reading'; - } else if (this.pendingRetry || this.preprocessState === 1) { + } else if (this.preprocessState === 1) { // if pending retry then that's effectively the same as actively uploading, // there might just be a slight delay before the retry starts return 'uploading'; - } else if (!this.xhr) { + } else if (!this.xhr || this.pendingRetry) { return 'pending'; } else if (this.xhr.readyState < 4) { // Status is really 'OPENED', 'HEADERS_RECEIVED' @@ -6464,18 +6464,29 @@ value: function abort(reset) { this.currentSpeed = 0; this.averageSpeed = 0; - var chunks = this.chunks; if (reset) { this.chunks = []; } - each(chunks, function (c) { - if (c.status() === 'uploading') { - c.abort(); - this.flowObj.uploadNextChunk(); + var _iterator = _createForOfIteratorHelper(this.chunks), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var c = _step.value; + + if (c.status() === 'uploading') { + c.abort(); + c.pendingRetry = true; + this.flowObj.uploadNextChunk(); + } } - }, this); + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } } /** * Cancel current upload and remove from a list @@ -7132,7 +7143,7 @@ if (!_file2.isComplete()) { outstanding = true; - return false; + break; } } } catch (err) { diff --git a/dist/flow.min.js b/dist/flow.min.js index 83c37ec..a46266b 100644 --- a/dist/flow.min.js +++ b/dist/flow.min.js @@ -1,3 +1,3 @@ /*! @flowjs/flow.js 3.0.0-alpha.0 */ -function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}function e(t,e,r,n,i,o,a){try{var s=t[o](a),u=s.value}catch(t){return void r(t)}s.done?e(u):Promise.resolve(u).then(n,i)}function r(t){return function(){var r=this,n=arguments;return new Promise((function(i,o){var a=t.apply(r,n);function s(t){e(a,i,o,s,u,"next",t)}function u(t){e(a,i,o,s,u,"throw",t)}s(void 0)}))}}function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){for(var r=0;rt.length)&&(e=t.length);for(var r=0,n=new Array(e);r=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,a=!0,s=!1;return{s:function(){r=t[Symbol.iterator]()},n:function(){var t=r.next();return a=t.done,t},e:function(t){s=!0,o=t},f:function(){try{a||null==r.return||r.return()}finally{if(s)throw o}}}}var k="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function S(t){var e={exports:{}};return t(e,e.exports),e.exports}var O=function(t){return t&&t.Math==Math&&t},x=O("object"==("undefined"==typeof globalThis?"undefined":t(globalThis))&&globalThis)||O("object"==("undefined"==typeof window?"undefined":t(window))&&window)||O("object"==("undefined"==typeof self?"undefined":t(self))&&self)||O("object"==t(k)&&k)||function(){return this}()||Function("return this")(),E=function(t){try{return!!t()}catch(t){return!0}},j=!E((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),_={}.propertyIsEnumerable,P=Object.getOwnPropertyDescriptor,A={f:P&&!_.call({1:2},1)?function(t){var e=P(this,t);return!!e&&e.enumerable}:_},R=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},I={}.toString,T=function(t){return I.call(t).slice(8,-1)},C="".split,L=E((function(){return!Object("z").propertyIsEnumerable(0)}))?function(t){return"String"==T(t)?C.call(t,""):Object(t)}:Object,F=function(t){if(null==t)throw TypeError("Can't call method on "+t);return t},N=function(t){return L(F(t))},z=function(e){return"object"===t(e)?null!==e:"function"==typeof e},M=function(t,e){if(!z(t))return t;var r,n;if(e&&"function"==typeof(r=t.toString)&&!z(n=r.call(t)))return n;if("function"==typeof(r=t.valueOf)&&!z(n=r.call(t)))return n;if(!e&&"function"==typeof(r=t.toString)&&!z(n=r.call(t)))return n;throw TypeError("Can't convert object to primitive value")},D={}.hasOwnProperty,U=function(t,e){return D.call(t,e)},H=x.document,B=z(H)&&z(H.createElement),G=function(t){return B?H.createElement(t):{}},q=!j&&!E((function(){return 7!=Object.defineProperty(G("div"),"a",{get:function(){return 7}}).a})),$=Object.getOwnPropertyDescriptor,V={f:j?$:function(t,e){if(t=N(t),e=M(e,!0),q)try{return $(t,e)}catch(t){}if(U(t,e))return R(!A.f.call(t,e),t[e])}},Y=function(t){if(!z(t))throw TypeError(String(t)+" is not an object");return t},X=Object.defineProperty,K={f:j?X:function(t,e,r){if(Y(t),e=M(e,!0),Y(r),q)try{return X(t,e,r)}catch(t){}if("get"in r||"set"in r)throw TypeError("Accessors not supported");return"value"in r&&(t[e]=r.value),t}},W=j?function(t,e,r){return K.f(t,e,R(1,r))}:function(t,e,r){return t[e]=r,t},J=function(t,e){try{W(x,t,e)}catch(r){x[t]=e}return e},Z=x["__core-js_shared__"]||J("__core-js_shared__",{}),Q=Function.toString;"function"!=typeof Z.inspectSource&&(Z.inspectSource=function(t){return Q.call(t)});var tt,et,rt,nt=Z.inspectSource,it=x.WeakMap,ot="function"==typeof it&&/native code/.test(nt(it)),at=S((function(t){(t.exports=function(t,e){return Z[t]||(Z[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.8.3",mode:"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"})})),st=0,ut=Math.random(),ct=function(t){return"Symbol("+String(void 0===t?"":t)+")_"+(++st+ut).toString(36)},lt=at("keys"),ft=function(t){return lt[t]||(lt[t]=ct(t))},ht={},pt=x.WeakMap;if(ot){var dt=Z.state||(Z.state=new pt),vt=dt.get,yt=dt.has,gt=dt.set;tt=function(t,e){return e.facade=t,gt.call(dt,t,e),e},et=function(t){return vt.call(dt,t)||{}},rt=function(t){return yt.call(dt,t)}}else{var mt=ft("state");ht[mt]=!0,tt=function(t,e){return e.facade=t,W(t,mt,e),e},et=function(t){return U(t,mt)?t[mt]:{}},rt=function(t){return U(t,mt)}}var bt,wt,kt={set:tt,get:et,has:rt,enforce:function(t){return rt(t)?et(t):tt(t,{})},getterFor:function(t){return function(e){var r;if(!z(e)||(r=et(e)).type!==t)throw TypeError("Incompatible receiver, "+t+" required");return r}}},St=S((function(t){var e=kt.get,r=kt.enforce,n=String(String).split("String");(t.exports=function(t,e,i,o){var a,s=!!o&&!!o.unsafe,u=!!o&&!!o.enumerable,c=!!o&&!!o.noTargetGet;"function"==typeof i&&("string"!=typeof e||U(i,"name")||W(i,"name",e),(a=r(i)).source||(a.source=n.join("string"==typeof e?e:""))),t!==x?(s?!c&&t[e]&&(u=!0):delete t[e],u?t[e]=i:W(t,e,i)):u?t[e]=i:J(e,i)})(Function.prototype,"toString",(function(){return"function"==typeof this&&e(this).source||nt(this)}))})),Ot=x,xt=function(t){return"function"==typeof t?t:void 0},Et=function(t,e){return arguments.length<2?xt(Ot[t])||xt(x[t]):Ot[t]&&Ot[t][e]||x[t]&&x[t][e]},jt=Math.ceil,_t=Math.floor,Pt=function(t){return isNaN(t=+t)?0:(t>0?_t:jt)(t)},At=Math.min,Rt=function(t){return t>0?At(Pt(t),9007199254740991):0},It=Math.max,Tt=Math.min,Ct=function(t,e){var r=Pt(t);return r<0?It(r+e,0):Tt(r,e)},Lt=function(t){return function(e,r,n){var i,o=N(e),a=Rt(o.length),s=Ct(n,a);if(t&&r!=r){for(;a>s;)if((i=o[s++])!=i)return!0}else for(;a>s;s++)if((t||s in o)&&o[s]===r)return t||s||0;return!t&&-1}},Ft={includes:Lt(!0),indexOf:Lt(!1)},Nt=Ft.indexOf,zt=function(t,e){var r,n=N(t),i=0,o=[];for(r in n)!U(ht,r)&&U(n,r)&&o.push(r);for(;e.length>i;)U(n,r=e[i++])&&(~Nt(o,r)||o.push(r));return o},Mt=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],Dt=Mt.concat("length","prototype"),Ut={f:Object.getOwnPropertyNames||function(t){return zt(t,Dt)}},Ht={f:Object.getOwnPropertySymbols},Bt=Et("Reflect","ownKeys")||function(t){var e=Ut.f(Y(t)),r=Ht.f;return r?e.concat(r(t)):e},Gt=function(t,e){for(var r=Bt(e),n=K.f,i=V.f,o=0;o=74)&&(bt=le.match(/Chrome\/(\d+)/))&&(wt=bt[1]);var de=wt&&+wt,ve=se("species"),ye=function(t){return de>=51||!E((function(){var e=[];return(e.constructor={})[ve]=function(){return{foo:1}},1!==e[t](Boolean).foo}))},ge=se("isConcatSpreadable"),me=de>=51||!E((function(){var t=[];return t[ge]=!1,t.concat()[0]!==t})),be=ye("concat"),we=function(t){if(!z(t))return!1;var e=t[ge];return void 0!==e?!!e:Qt(t)};Zt({target:"Array",proto:!0,forced:!me||!be},{concat:function(t){var e,r,n,i,o,a=te(this),s=ce(a,0),u=0;for(e=-1,n=arguments.length;e9007199254740991)throw TypeError("Maximum allowed index exceeded");for(r=0;r=9007199254740991)throw TypeError("Maximum allowed index exceeded");ee(s,u++,o)}return s.length=u,s}});var ke=function(t){if("function"!=typeof t)throw TypeError(String(t)+" is not a function");return t},Se=function(t,e,r){if(ke(t),void 0===e)return t;switch(r){case 0:return function(){return t.call(e)};case 1:return function(r){return t.call(e,r)};case 2:return function(r,n){return t.call(e,r,n)};case 3:return function(r,n,i){return t.call(e,r,n,i)}}return function(){return t.apply(e,arguments)}},Oe=[].push,xe=function(t){var e=1==t,r=2==t,n=3==t,i=4==t,o=6==t,a=7==t,s=5==t||o;return function(u,c,l,f){for(var h,p,d=te(u),v=L(d),y=Se(c,l,3),g=Rt(v.length),m=0,b=f||ce,w=e?b(u,g):r||a?b(u,0):void 0;g>m;m++)if((s||m in v)&&(p=y(h=v[m],m,d),t))if(e)w[m]=p;else if(p)switch(t){case 3:return!0;case 5:return h;case 6:return m;case 2:Oe.call(w,h)}else switch(t){case 4:return!1;case 7:Oe.call(w,h)}return o?-1:n||i?i:w}},Ee={forEach:xe(0),map:xe(1),filter:xe(2),some:xe(3),every:xe(4),find:xe(5),findIndex:xe(6),filterOut:xe(7)},je=Object.defineProperty,_e={},Pe=function(t){throw t},Ae=function(t,e){if(U(_e,t))return _e[t];e||(e={});var r=[][t],n=!!U(e,"ACCESSORS")&&e.ACCESSORS,i=U(e,0)?e[0]:Pe,o=U(e,1)?e[1]:void 0;return _e[t]=!!r&&!E((function(){if(n&&!j)return!0;var t={length:-1};n?je(t,1,{enumerable:!0,get:Pe}):t[1]=1,r.call(t,i,o)}))},Re=Ee.filter,Ie=ye("filter"),Te=Ae("filter");Zt({target:"Array",proto:!0,forced:!Ie||!Te},{filter:function(t){return Re(this,t,arguments.length>1?arguments[1]:void 0)}});var Ce,Le=Object.keys||function(t){return zt(t,Mt)},Fe=j?Object.defineProperties:function(t,e){Y(t);for(var r,n=Le(e),i=n.length,o=0;i>o;)K.f(t,r=n[o++],e[r]);return t},Ne=Et("document","documentElement"),ze=ft("IE_PROTO"),Me=function(){},De=function(t){return"