This repository has been archived by the owner on Jun 11, 2023. It is now read-only.
forked from backblaze-b2-samples/multithreaded-downloader-js
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Chunk.js
95 lines (85 loc) · 2.6 KB
/
Chunk.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class Chunk {
constructor (options) {
Object.assign(this, options)
this.onStart = this.onStart ? this.onStart.bind(this) : () => {}
this.onFinish = this.onFinish ? this.onFinish.bind(this) : () => {}
this.onProgress = this.onProgress ? this.onProgress.bind(this) : () => {}
this.onError = this.onError ? this.onError.bind(this) : () => {}
// Passthrough this.headers to each range request (for Google Drive auth)
this.headers = new Headers(this.headers)
this.headers.set('Range', `bytes=${this.startByte}-${this.endByte}`)
this.url = new URL(this.url)
this.retryRequested = false
this.done = false
this.written = 0
}
start () {
this.onStart({id: this.id})
return window.fetch(this.url, {
mode: 'cors',
method: 'GET',
headers: this.headers,
signal: this.controller.signal
})
.then(response => {
this.response = response
this.retryRequested = false
this.contentLength = parseInt(response.headers.get('Content-Length') || response.headers.get('content-length'))
this.loaded = 0
this.monitor()
return response
})
}
monitor () {
// Clone the response so the original won't be locked to a reader
this.monitorReader = this.response.clone().body.getReader()
const pump = () => {
this.monitorReader.read()
.then(({done, value}) => {
this.done = done
if (!done) {
if (this.retryRequested) {
this.monitorReader.releaseLock()
this.onProgress({
id: this.id,
loaded: -this.loaded,
byteLength: -this.loaded,
contentLength: this.contentLength
})
this.start()
} else {
this.loaded += value.byteLength
this.onProgress({
id: this.id,
loaded: this.loaded,
byteLength: value.byteLength,
contentLength: this.contentLength
})
pump()
}
} else {
this.monitorReader.releaseLock()
this.onFinish({id: this.id})
}
})
.catch(error => {
this.onError({error: error, id: this.id})
if (!this.done) {
this.retry()
}
})
}
pump()
}
retry () {
this.retryRequested = true
// this.onProgress({
// id: this.id,
// loaded: -this.loaded,
// byteLength: -this.loaded,
// contentLength: this.contentLength
// })
// this.start()
}
}
// module.exports = Chunk