@@ -16,7 +16,7 @@ module.exports = configure((api) => {
16
16
// allow aborting requests on body errors
17
17
const controller = new AbortController ( )
18
18
const signal = anySignal ( [ controller . signal , options . signal ] )
19
- const { headers, body, total, lengthComputable } =
19
+ const { headers, body, total, parts } =
20
20
await multipartRequest ( source , controller , options . headers )
21
21
22
22
// In browser response body only starts streaming once upload is
@@ -25,7 +25,7 @@ module.exports = configure((api) => {
25
25
// `{ total, loaded}` passed to `onUploadProgress` and `multipart.total`
26
26
// in which case we disable progress updates to be written out.
27
27
const [ progressFn , onUploadProgress ] = typeof options . progress === 'function'
28
- ? createProgressHandler ( lengthComputable , total , options . progress )
28
+ ? createProgressHandler ( total , parts , options . progress )
29
29
: [ null , null ]
30
30
31
31
const res = await api . post ( 'add' , {
@@ -58,27 +58,42 @@ module.exports = configure((api) => {
58
58
* Returns simple progress callback when content length isn't computable or a
59
59
* progress event handler that inerpolates progress from upload progress events.
60
60
*
61
- * @param {boolean } lengthComputable
62
61
* @param {number } total
63
- * @param {(n:number) => void } progress
62
+ * @param {{name:string, start:number, end:number}[]|null } parts
63
+ * @param {(n:number, name:string) => void } progress
64
64
*/
65
- const createProgressHandler = ( lengthComputable , total , progress ) =>
66
- lengthComputable ? [ null , createOnUploadPrgress ( total , progress ) ] : [ progress , null ]
65
+ const createProgressHandler = ( total , parts , progress ) =>
66
+ parts ? [ null , createOnUploadPrgress ( total , parts , progress ) ] : [ progress , null ]
67
67
68
68
/**
69
69
* Creates a progress handler that interpolates progress from upload progress
70
70
* events and total size of the content that is added.
71
71
*
72
72
* @param {number } size - actual content size
73
- * @param {(n:number) => void } progress
74
- * @returns {(event:{total:number, loaded: number}) => progress }
75
- */
76
- const createOnUploadPrgress = ( size , progress ) => ( { loaded, total } ) =>
77
- progress ( Math . floor ( loaded / total * size ) )
78
-
79
- /**
80
- * @typedef {import('../../ipfs/src/core/components/add-all').UnixFSEntry } UnixFSEntry
73
+ * @param {{name:string, start:number, end:number}[] } parts
74
+ * @param {(n:number, name:string) => void } progress
75
+ * @returns {(event:{total:number, loaded: number}) => void }
81
76
*/
77
+ const createOnUploadPrgress = ( size , parts , progress ) => {
78
+ let index = 0
79
+ return ( { loaded, total } ) => {
80
+ // Derive position from the current progress.
81
+ const position = Math . floor ( loaded / total * size )
82
+ while ( true ) {
83
+ const { start, end, name } = parts [ index ]
84
+ // If within current part range reporst progress and break the loop
85
+ if ( position < end ) {
86
+ progress ( position - start , name )
87
+ break
88
+ // If passed current part range report final byte for the chunk and
89
+ // move to next one.
90
+ } else {
91
+ progress ( end - start , name )
92
+ index += 1
93
+ }
94
+ }
95
+ }
96
+ }
82
97
83
98
/**
84
99
* @param {any } input
@@ -108,7 +123,4 @@ function toCoreInterface ({ name, hash, size, mode, mtime, mtimeNsecs }) {
108
123
109
124
/**
110
125
* @typedef {import('ipfs-core/src/components/add-all/index').UnixFSEntry } UnixFSEntry
111
- * @typedef {import('./index').HttpOptions } HttpOptions
112
- * @typedef {Object } HttpAddOptions
113
- * @property { }
114
126
*/
0 commit comments