Browse Source

Merge pull request #347 from goto-bus-stop/upload-fixes

upload resolution changes, followup to #323
Renée Kooi 7 years ago
parent
commit
d090f73352
6 changed files with 339 additions and 237 deletions
  1. 256 212
      package-lock.json
  2. 0 1
      package.json
  3. 31 1
      src/core/Utils.js
  4. 26 0
      src/core/Utils.test.js
  5. 13 7
      src/plugins/Tus10.js
  6. 13 16
      src/plugins/XHRUpload.js

File diff suppressed because it is too large
+ 256 - 212
package-lock.json


+ 0 - 1
package.json

@@ -89,7 +89,6 @@
     "nanoraf": "3.0.1",
     "on-load": "3.2.0",
     "prettier-bytes": "1.0.4",
-    "promise-settle": "^0.3.0",
     "prop-types": "^15.5.10",
     "socket.io-client": "2.0.1",
     "tus-js-client": "^1.4.4",

+ 31 - 1
src/core/Utils.js

@@ -487,6 +487,35 @@ function _emitSocketProgress (uploader, progressData, file) {
 
 const emitSocketProgress = throttle(_emitSocketProgress, 300, {leading: true, trailing: true})
 
+function settle (promises) {
+  const resolutions = []
+  const rejections = []
+  function resolved (value) {
+    resolutions.push(value)
+  }
+  function rejected (error) {
+    rejections.push(error)
+  }
+
+  const wait = Promise.all(
+    promises.map((promise) => promise.then(resolved, rejected))
+  )
+
+  return wait.then(() => {
+    if (rejections.length === promises.length) {
+      // Very ad-hoc multiple-error reporting, should wrap this in a
+      // CombinedError or whatever kind of error class instead.
+      const error = rejections[0]
+      error.errors = rejections
+      return Promise.reject(error)
+    }
+    return {
+      successful: resolutions,
+      failed: rejections
+    }
+  })
+}
+
 module.exports = {
   generateFileID,
   toArray,
@@ -512,5 +541,6 @@ module.exports = {
   findDOMElement,
   findAllDOMElements,
   getSocketHost,
-  emitSocketProgress
+  emitSocketProgress,
+  settle
 }

+ 26 - 0
src/core/Utils.test.js

@@ -362,4 +362,30 @@ describe('core/utils', () => {
       ).toEqual('ws://foo.bar/a/b/cd?e=fghi&l=k&m=n')
     })
   })
+
+  describe('settle', () => {
+    it('should reject if all input promises reject', () => {
+      return expect(
+        utils.settle([
+          Promise.reject(new Error('oops')),
+          Promise.reject(new Error('this went wrong'))
+        ])
+      ).rejects.toMatchObject({
+        message: 'oops'
+      })
+    })
+
+    it('should resolve with an object if some input promises resolve', () => {
+      return expect(
+        utils.settle([
+          Promise.reject(new Error('rejected')),
+          Promise.resolve('resolved'),
+          Promise.resolve('also-resolved')
+        ])
+      ).resolves.toMatchObject({
+        successful: ['resolved', 'also-resolved'],
+        failed: [{ message: 'rejected' }]
+      })
+    })
+  })
 })

+ 13 - 7
src/plugins/Tus10.js

@@ -1,8 +1,11 @@
 const Plugin = require('./Plugin')
 const tus = require('tus-js-client')
-const settle = require('promise-settle')
 const UppySocket = require('../core/UppySocket')
-const Utils = require('../core/Utils')
+const {
+  emitSocketProgress,
+  getSocketHost,
+  settle
+} = require('../core/Utils')
 require('whatwg-fetch')
 
 // Extracted from https://github.com/tus/tus-js-client/blob/master/lib/upload.js#L13
@@ -142,7 +145,8 @@ module.exports = class Tus10 extends Plugin {
       optsTus.onError = (err) => {
         this.core.log(err)
         this.core.emit('core:upload-error', file.id, err)
-        reject(new Error('Failed because: ' + err))
+        err.message = `Failed because: ${err.message}`
+        reject(err)
       }
 
       optsTus.onProgress = (bytesUploaded, bytesTotal) => {
@@ -249,7 +253,7 @@ module.exports = class Tus10 extends Plugin {
 
   connectToServerSocket (file) {
     const token = file.serverToken
-    const host = Utils.getSocketHost(file.remote.host)
+    const host = getSocketHost(file.remote.host)
     const socket = new UppySocket({ target: `${host}/api/${token}` })
 
     this.onFileRemove(file.id, () => socket.send('pause', {}))
@@ -261,7 +265,7 @@ module.exports = class Tus10 extends Plugin {
     this.onPauseAll(file.id, () => socket.send('pause', {}))
     this.onResumeAll(file.id, () => socket.send('resume', {}))
 
-    socket.on('progress', (progressData) => Utils.emitSocketProgress(this, progressData, file))
+    socket.on('progress', (progressData) => emitSocketProgress(this, progressData, file))
 
     socket.on('success', (data) => {
       this.core.emitter.emit('core:upload-success', file.id, data, data.url)
@@ -324,7 +328,7 @@ module.exports = class Tus10 extends Plugin {
   }
 
   uploadFiles (files) {
-    return settle(files.map((file, index) => {
+    const promises = files.map((file, index) => {
       const current = parseInt(index, 10) + 1
       const total = files.length
 
@@ -333,7 +337,9 @@ module.exports = class Tus10 extends Plugin {
       } else {
         return this.uploadRemote(file, current, total)
       }
-    }))
+    })
+
+    return settle(promises)
   }
 
   handleUpload (fileIDs) {

+ 13 - 16
src/plugins/XHRUpload.js

@@ -1,7 +1,10 @@
 const Plugin = require('./Plugin')
-const settle = require('promise-settle')
 const UppySocket = require('../core/UppySocket')
-const Utils = require('../core/Utils')
+const {
+  emitSocketProgress,
+  getSocketHost,
+  settle
+} = require('../core/Utils')
 
 module.exports = class XHRUpload extends Plugin {
   constructor (core, opts) {
@@ -161,10 +164,10 @@ module.exports = class XHRUpload extends Plugin {
 
         res.json().then((data) => {
           const token = data.token
-          const host = Utils.getSocketHost(file.remote.host)
+          const host = getSocketHost(file.remote.host)
           const socket = new UppySocket({ target: `${host}/api/${token}` })
 
-          socket.on('progress', (progressData) => Utils.emitSocketProgress(this, progressData, file))
+          socket.on('progress', (progressData) => emitSocketProgress(this, progressData, file))
 
           socket.on('success', (data) => {
             this.core.emit('core:upload-success', file.id, data, data.url)
@@ -176,8 +179,8 @@ module.exports = class XHRUpload extends Plugin {
     })
   }
 
-  selectForUpload (files) {
-    return settle(files.map((file, i) => {
+  uploadFiles (files) {
+    const promises = files.map((file, i) => {
       const current = parseInt(i, 10) + 1
       const total = files.length
 
@@ -186,15 +189,9 @@ module.exports = class XHRUpload extends Plugin {
       } else {
         return this.upload(file, current, total)
       }
-    }))
-
-    //   if (this.opts.bundle) {
-    //     uploaders.push(this.upload(files, 0, files.length))
-    //   } else {
-    //     for (let i in files) {
-    //       uploaders.push(this.upload(files, i, files.length))
-    //     }
-    //   }
+    })
+
+    return settle(promises)
   }
 
   handleUpload (fileIDs) {
@@ -209,7 +206,7 @@ module.exports = class XHRUpload extends Plugin {
       return this.core.state.files[fileID]
     }
 
-    return this.selectForUpload(files).then(() => null)
+    return this.uploadFiles(files).then(() => null)
   }
 
   install () {

Some files were not shown because too many files changed in this diff