ClojureScript micro-library that helps you make the process of uploading large files easier for users. It splits file in chunks and uploads them sequentially with retries (and timeouts between them) on failure. Falls back to normal upload if blob slicing isn't supported by user's browser.
(ns myns.files
(:require-macros [cljs.core.async.macros :refer [go-loop]])
(:require [ostronom.uploader :as up]
[cljs.core.async :refer [<!]]))
(defn i-want-to-upload [file]
(let [uploader (up/get-uploader)
ch (up/upload uploader "/files" file {"form-field" "value"})]
(go-loop []
(when-let [[evt data] (<! ch)]
(cond evt
:progress
(do
(js/console.log "UPLOADED" (:loaded data) "OUT OF" (:total evt))
(recur))
:complete
(js/console.log "DONE")
:error
(js/console.log ":(")))))))get-uploader returns IUploader instance with upload method with two arities: [this target file form-data] and [u target file form-data file-name]
where:
targetis URL where file should be submittedfileis FormData file instanceform-datahash-map of additional form data to be sent with a filefile-nameoverrides file name offile
You can provide configuration options to get-uploader like this (get-uploader opts), where opts is a hash with some options:
:file-fieldform field which should contain file (default:"file"):chunk-sizesize of each chunk in bytes (default:524288):timeout-fntimeout function which should take number of upload attempt and return number of ms to sleep before another attempt (defaults to constantly 3000 ms):total-fieldform field which should contain total file size of uploaded file (default:"total"):offset-fieldform field which should contain offset of current chunk from the beginning (default:"offset"):max-retriesnumber of retries on chunk upload error.nilvalue means infinite retries (default:nil)
upload method returns core.async channel with following messages:
[:complete]-- when upload is complete[:error]-- when there was an error after all of the retries[:progress {:total N :loaded M}]-- informs you that M out of N bytes are uploaded
Obviously, your server should support "gluing" of those chunks together.