use binary upload

This commit is contained in:
SrGooglo 2025-03-28 22:05:22 +00:00
parent 6d678b5f00
commit 551dc9ced0

View File

@ -54,6 +54,8 @@ export default class ChunkedUpload {
splitChunkSize: splitChunkSize, splitChunkSize: splitChunkSize,
totalChunks: this.totalChunks, totalChunks: this.totalChunks,
totalSize: file.size, totalSize: file.size,
fileName: file.name,
fileType: file.type,
}) })
} }
@ -89,33 +91,32 @@ export default class ChunkedUpload {
const start = this.chunkCount * this.splitChunkSize const start = this.chunkCount * this.splitChunkSize
const end = Math.min(start + this.splitChunkSize, this.file.size) const end = Math.min(start + this.splitChunkSize, this.file.size)
this._reader.onload = () => this._reader.onload = () => {
resolve( resolve(
new Blob([this._reader.result], { new Blob([this._reader.result], {
type: "application/octet-stream", type: "application/octet-stream",
}), }),
) )
}
this._reader.readAsArrayBuffer(this.file.slice(start, end)) this._reader.readAsArrayBuffer(this.file.slice(start, end))
}) })
} }
async sendChunk() { async sendChunk() {
const form = new FormData()
form.append("file", this.chunk)
this.headers["uploader-chunk-number"] = this.chunkCount
console.log(`[UPLOADER] Sending chunk ${this.chunkCount}`, { console.log(`[UPLOADER] Sending chunk ${this.chunkCount}`, {
currentChunk: this.chunkCount, currentChunk: this.chunkCount,
totalChunks: this.totalChunks, totalChunks: this.totalChunks,
chunk: this.chunk,
}) })
try { try {
const res = await fetch(this.endpoint, { const res = await fetch(this.endpoint, {
method: "POST", method: "POST",
headers: this.headers, headers: {
body: form, ...this.headers,
"uploader-chunk-number": this.chunkCount,
},
body: this.chunk,
}) })
return res return res
@ -147,11 +148,16 @@ export default class ChunkedUpload {
this.chunk = await this.loadChunk() this.chunk = await this.loadChunk()
try {
const res = await this.sendChunk() const res = await this.sendChunk()
if (![200, 201, 204].includes(res.status)) {
// failed!!
return this.manageRetries()
}
const data = await res.json() const data = await res.json()
if ([200, 201, 204].includes(res.status)) {
console.log(`[UPLOADER] Chunk ${this.chunkCount} sent`) console.log(`[UPLOADER] Chunk ${this.chunkCount} sent`)
this.chunkCount = this.chunkCount + 1 this.chunkCount = this.chunkCount + 1
@ -162,7 +168,32 @@ export default class ChunkedUpload {
// check if is the last chunk, if so, handle sse events // check if is the last chunk, if so, handle sse events
if (this.chunkCount === this.totalChunks) { if (this.chunkCount === this.totalChunks) {
if (data.eventChannelURL) { if (data.sseChannelId || data.eventChannelURL) {
this.waitOnSSE(data)
} else {
this.events.emit("finish", data)
}
}
this.events.emit("progress", {
percentProgress: Math.round(
(100 / this.totalChunks) * this.chunkCount,
),
})
} catch (error) {
this.events.emit("error", error)
}
}
togglePause() {
this.paused = !this.paused
if (!this.paused) {
return this.nextSend()
}
}
waitOnSSE(data) {
console.log( console.log(
`[UPLOADER] Connecting to SSE channel >`, `[UPLOADER] Connecting to SSE channel >`,
data.eventChannelURL, data.eventChannelURL,
@ -172,6 +203,7 @@ export default class ChunkedUpload {
eventSource.onerror = (error) => { eventSource.onerror = (error) => {
this.events.emit("error", error) this.events.emit("error", error)
eventSource.close()
} }
eventSource.onopen = () => { eventSource.onopen = () => {
@ -191,6 +223,7 @@ export default class ChunkedUpload {
if (messageData.status === "error") { if (messageData.status === "error") {
this.events.emit("error", messageData.result) this.events.emit("error", messageData.result)
eventSource.close()
} }
if (messageData.status === "progress") { if (messageData.status === "progress") {
@ -199,30 +232,5 @@ export default class ChunkedUpload {
}) })
} }
} }
} else {
this.events.emit("finish", data)
}
}
this.events.emit("progress", {
percentProgress: Math.round(
(100 / this.totalChunks) * this.chunkCount,
),
})
} else if ([408, 502, 503, 504].includes(res.status)) {
this.manageRetries()
} else {
this.events.emit("error", {
message: `[${res.status}] ${data.error ?? data.message}`,
})
}
}
togglePause() {
this.paused = !this.paused
if (!this.paused) {
return this.nextSend()
}
} }
} }