upload-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/client/index.cjs.js +335 -0
- package/client/index.cjs.js.map +1 -0
- package/client/index.d.ts +1 -0
- package/client/index.esm.js +333 -0
- package/client/index.esm.js.map +1 -0
- package/client/index.umd.js +338 -0
- package/client/index.umd.js.map +1 -0
- package/core/index.cjs.js +285 -0
- package/core/index.cjs.js.map +1 -0
- package/core/index.d.ts +32 -0
- package/core/index.esm.js +283 -0
- package/core/index.esm.js.map +1 -0
- package/index.cjs.js +9 -0
- package/index.d.ts +4 -0
- package/index.js +16 -0
- package/package.json +41 -0
- package/utils/index.cjs.js +583 -0
- package/utils/index.cjs.js.map +1 -0
- package/utils/index.d.ts +108 -0
- package/utils/index.esm.js +572 -0
- package/utils/index.esm.js.map +1 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var PQueue = require('p-queue');
|
|
4
|
+
var utils = require('@upload-sdk/utils');
|
|
5
|
+
|
|
6
|
+
const BaseUrl = '/api';
|
|
7
|
+
const uploadChunkUrl = `${BaseUrl}/upload/chunk`;
|
|
8
|
+
/**
|
|
9
|
+
* 大文件上传文件切片请求
|
|
10
|
+
* @param options
|
|
11
|
+
*/
|
|
12
|
+
const uploadBigFileChunkRequest = (options) => {
|
|
13
|
+
const url = uploadChunkUrl;
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const httpClient = utils.createHttpClient();
|
|
16
|
+
httpClient.post(url, options.data, options.config).then(res => {
|
|
17
|
+
resolve(res);
|
|
18
|
+
}).catch(err => {
|
|
19
|
+
reject(err);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* 大文件上传前置校验
|
|
25
|
+
* @param options
|
|
26
|
+
*/
|
|
27
|
+
const checkBigFileHashRequest = (options) => {
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
const httpClient = utils.createHttpClient();
|
|
30
|
+
httpClient.post(options.url, options.data, options.config).then(res => {
|
|
31
|
+
resolve(res);
|
|
32
|
+
}).catch(err => {
|
|
33
|
+
reject(err);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// 可以使用的 webWorker 数量
|
|
39
|
+
const CAN_USER_WORKERS = Math.min(navigator.hardwareConcurrency - 1 || 2);
|
|
40
|
+
function useUpload(options = {}) {
|
|
41
|
+
const getUrl = () => {
|
|
42
|
+
return options.url || '';
|
|
43
|
+
};
|
|
44
|
+
const createXHR = () => {
|
|
45
|
+
return new XMLHttpRequest();
|
|
46
|
+
};
|
|
47
|
+
const setHeaders = (xhrInstance, headers = {}) => {
|
|
48
|
+
const defaultHeaders = Object.assign({ 'Accept': 'application/json' }, headers);
|
|
49
|
+
Object.entries(defaultHeaders).forEach(([key, value]) => {
|
|
50
|
+
if (value) {
|
|
51
|
+
xhrInstance.setRequestHeader(key, value);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* 单文件上传
|
|
57
|
+
* @param file 文件
|
|
58
|
+
* @param fileOptions 其他参数
|
|
59
|
+
* @returns
|
|
60
|
+
*/
|
|
61
|
+
const uploadFile = (file, fileOptions = {}) => {
|
|
62
|
+
const formData = new FormData();
|
|
63
|
+
let uploadProgress = 0;
|
|
64
|
+
let onProgress;
|
|
65
|
+
const fieldName = fileOptions.fieldName || 'file';
|
|
66
|
+
formData.append(fieldName, file);
|
|
67
|
+
// 额外数据
|
|
68
|
+
const extraData = Object.assign(Object.assign({}, options.data), fileOptions.data);
|
|
69
|
+
if (extraData) {
|
|
70
|
+
Object.entries(extraData).forEach(([key, value]) => {
|
|
71
|
+
if (value !== undefined && value !== null) {
|
|
72
|
+
formData.append(key, value.toString());
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const xhr = createXHR();
|
|
77
|
+
const handleProgress = (event) => {
|
|
78
|
+
if (event.lengthComputable) {
|
|
79
|
+
uploadProgress = Math.round((event.loaded / event.total) * 100);
|
|
80
|
+
console.log('uploadProgress', uploadProgress);
|
|
81
|
+
if (onProgress) {
|
|
82
|
+
onProgress(uploadProgress, event);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const start = () => {
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
// 发送 请求
|
|
89
|
+
xhr.open('POST', getUrl(), true);
|
|
90
|
+
// 设置超时
|
|
91
|
+
if (options.timeout) {
|
|
92
|
+
xhr.timeout = options.timeout;
|
|
93
|
+
}
|
|
94
|
+
// 设置凭据
|
|
95
|
+
if (options.withCredentials) {
|
|
96
|
+
xhr.withCredentials = true;
|
|
97
|
+
}
|
|
98
|
+
// 设置请求头
|
|
99
|
+
setHeaders(xhr, options.headers);
|
|
100
|
+
// 进度事件
|
|
101
|
+
xhr.upload.addEventListener('progress', handleProgress);
|
|
102
|
+
// 请求完成
|
|
103
|
+
xhr.addEventListener('load', () => {
|
|
104
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
105
|
+
try {
|
|
106
|
+
const response = xhr.responseText ? JSON.parse(xhr.responseText) : {};
|
|
107
|
+
resolve(response);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
const errorMsg = `解析响应失败: ${error.message}`;
|
|
111
|
+
reject(new Error(errorMsg));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const error = new Error(`上传失败: ${xhr.statusText}`);
|
|
116
|
+
reject(error);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
// 请求错误
|
|
120
|
+
xhr.addEventListener('error', () => {
|
|
121
|
+
const error = new Error('网络错误,上传失败');
|
|
122
|
+
reject(error);
|
|
123
|
+
});
|
|
124
|
+
// 请求超时
|
|
125
|
+
xhr.addEventListener('timeout', () => {
|
|
126
|
+
const error = new Error(`请求超时 (${options.timeout}ms)`);
|
|
127
|
+
reject(error);
|
|
128
|
+
});
|
|
129
|
+
// 中止事件
|
|
130
|
+
xhr.addEventListener('abort', () => {
|
|
131
|
+
const error = new Error('上传已取消');
|
|
132
|
+
reject(error);
|
|
133
|
+
});
|
|
134
|
+
// 发送请求
|
|
135
|
+
try {
|
|
136
|
+
xhr.send(formData);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
const errorMsg = `发送请求失败: ${error.message}`;
|
|
140
|
+
reject(new Error(errorMsg));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
const pause = () => {
|
|
145
|
+
xhr.abort();
|
|
146
|
+
};
|
|
147
|
+
const resume = () => {
|
|
148
|
+
// upload();
|
|
149
|
+
};
|
|
150
|
+
const cancel = () => {
|
|
151
|
+
xhr.abort();
|
|
152
|
+
};
|
|
153
|
+
const setOnProgress = (callback) => {
|
|
154
|
+
onProgress = callback;
|
|
155
|
+
};
|
|
156
|
+
return {
|
|
157
|
+
start,
|
|
158
|
+
pause,
|
|
159
|
+
resume,
|
|
160
|
+
cancel,
|
|
161
|
+
setOnProgress
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* 多文件上传
|
|
166
|
+
* @param files 文件列表
|
|
167
|
+
* @param fileOptions 其他参数
|
|
168
|
+
* @returns
|
|
169
|
+
*/
|
|
170
|
+
const uploadFiles = (files, fileOptions = {}) => {
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* 大文件上传
|
|
174
|
+
* @param file 文件
|
|
175
|
+
* @param fileOptions 其他参数
|
|
176
|
+
* @returns
|
|
177
|
+
*/
|
|
178
|
+
const uploadBigFile = (file, fileOptions = {}) => {
|
|
179
|
+
// 1. 计算文件可以分成多少个分片
|
|
180
|
+
// 2. 创建 web worker 来计算每个分片的 hash
|
|
181
|
+
// 3. 得到分片和 hash 后就上传这个分片
|
|
182
|
+
// 4. 计算整个文件的 hash,得到这个 hash 后需要验证这个文件是否已经存在了,存在直接秒传
|
|
183
|
+
// 分片大小
|
|
184
|
+
const chunkSize = fileOptions.chunkSize || 1024 * 1024
|
|
185
|
+
* 5;
|
|
186
|
+
// 分片数量 = 文件大小 / 分片大小 (向上取整)
|
|
187
|
+
const chunkCount = Math.ceil(file.size / chunkSize);
|
|
188
|
+
const availableWorkers = CAN_USER_WORKERS;
|
|
189
|
+
// 1. TaskQueue 是一个任务队列,用于管理多个任务
|
|
190
|
+
// 2. 其中每个任务都是一个 Promise
|
|
191
|
+
// 3. 每完成一个任务,就从任务队列中取出下一个任务并执行
|
|
192
|
+
// 4. 若是队列中没有任务,则等待 任务进入队列
|
|
193
|
+
const taskQueue = new PQueue({ concurrency: availableWorkers });
|
|
194
|
+
const fileChunks = [];
|
|
195
|
+
// 已完成分片任务数量
|
|
196
|
+
let completedChunks = 0;
|
|
197
|
+
/**
|
|
198
|
+
* 分片上传进度回调函数
|
|
199
|
+
* @param progress
|
|
200
|
+
*/
|
|
201
|
+
const onProgress = (progress) => {
|
|
202
|
+
console.log('progress', progress);
|
|
203
|
+
};
|
|
204
|
+
const syncStartFileChunkUpload = () => {
|
|
205
|
+
const worker = new utils.FileHashWorker();
|
|
206
|
+
return new Promise((resolve, reject) => {
|
|
207
|
+
try {
|
|
208
|
+
let resultFileHash;
|
|
209
|
+
worker.onMessage((res) => {
|
|
210
|
+
const result = res.data;
|
|
211
|
+
resultFileHash = result.fileHash;
|
|
212
|
+
checkBigFileHashRequest({
|
|
213
|
+
data: {
|
|
214
|
+
resultFileHash
|
|
215
|
+
}
|
|
216
|
+
}).then((res) => {
|
|
217
|
+
resolve(res.successChunkHash);
|
|
218
|
+
}).finally(() => {
|
|
219
|
+
worker.close();
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
worker.send({
|
|
223
|
+
file,
|
|
224
|
+
chunkSize
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
reject(error);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
};
|
|
232
|
+
const start = () => {
|
|
233
|
+
const totalChunks = Math.ceil(file.size / chunkSize);
|
|
234
|
+
const workerPool = availableWorkers;
|
|
235
|
+
const successChunkHashList = [];
|
|
236
|
+
for (let i = 0; i < availableWorkers; i++) {
|
|
237
|
+
const worker = new utils.FileChunkHashWorker();
|
|
238
|
+
worker.send({
|
|
239
|
+
index: i,
|
|
240
|
+
file: file,
|
|
241
|
+
chunkSize,
|
|
242
|
+
startChunksIndex: i * workerPool,
|
|
243
|
+
endChunksIndex: Math.min(totalChunks, (i + 1) * workerPool)
|
|
244
|
+
});
|
|
245
|
+
worker.onMessage((event) => {
|
|
246
|
+
const { type, data } = event.data;
|
|
247
|
+
const { chunks = [] } = data;
|
|
248
|
+
fileChunks.push(...chunks);
|
|
249
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
250
|
+
const _chunkTarget = chunks[i];
|
|
251
|
+
// const fileChunk = new FileChunk()
|
|
252
|
+
taskQueue.add(() => {
|
|
253
|
+
return uploadBigFileChunkRequest(_chunkTarget);
|
|
254
|
+
}).then((result) => {
|
|
255
|
+
if (result.type === 'success') {
|
|
256
|
+
onProgress(completedChunks / chunkCount);
|
|
257
|
+
}
|
|
258
|
+
}).catch((err) => {
|
|
259
|
+
/*
|
|
260
|
+
TODO 这里可能需要尝试对 chunk 进行重试,重新上传这些没有上传成功的分片
|
|
261
|
+
*/
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
completedChunks++;
|
|
265
|
+
worker.close();
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
syncStartFileChunkUpload().then((successChunkHash) => {
|
|
269
|
+
successChunkHashList.push(...successChunkHash);
|
|
270
|
+
});
|
|
271
|
+
};
|
|
272
|
+
return {
|
|
273
|
+
start
|
|
274
|
+
};
|
|
275
|
+
};
|
|
276
|
+
return {
|
|
277
|
+
uploadFile,
|
|
278
|
+
uploadFiles,
|
|
279
|
+
uploadBigFile,
|
|
280
|
+
uploadLargeFile: uploadBigFile
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
exports.useUpload = useUpload;
|
|
285
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/api.ts","../src/index.ts"],"sourcesContent":[null,null],"names":["createHttpClient","FileHashWorker","FileChunkHashWorker"],"mappings":"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"}
|
package/core/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
interface UploadFileOptions {
|
|
2
|
+
fieldName?: string;
|
|
3
|
+
data?: Record<string, any>;
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
interface UploadOptions {
|
|
7
|
+
url?: string;
|
|
8
|
+
fieldName?: string;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
data?: Record<string, any>;
|
|
11
|
+
withCredentials?: boolean;
|
|
12
|
+
timeout?: number;
|
|
13
|
+
}
|
|
14
|
+
declare function useUpload(options?: UploadOptions): {
|
|
15
|
+
uploadFile: (file: File, fileOptions?: UploadFileOptions) => {
|
|
16
|
+
start: () => Promise<any>;
|
|
17
|
+
pause: () => void;
|
|
18
|
+
resume: () => void;
|
|
19
|
+
cancel: () => void;
|
|
20
|
+
setOnProgress: (callback: any) => void;
|
|
21
|
+
};
|
|
22
|
+
uploadFiles: (files: File[], fileOptions?: UploadFileOptions) => void;
|
|
23
|
+
uploadBigFile: (file: File, fileOptions?: UploadFileOptions) => {
|
|
24
|
+
start: () => void;
|
|
25
|
+
};
|
|
26
|
+
uploadLargeFile: (file: File, fileOptions?: UploadFileOptions) => {
|
|
27
|
+
start: () => void;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export { useUpload };
|
|
32
|
+
export type { UploadFileOptions, UploadOptions };
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import PQueue from 'p-queue';
|
|
2
|
+
import { createHttpClient, FileChunkHashWorker, FileHashWorker } from '@upload-sdk/utils';
|
|
3
|
+
|
|
4
|
+
const BaseUrl = '/api';
|
|
5
|
+
const uploadChunkUrl = `${BaseUrl}/upload/chunk`;
|
|
6
|
+
/**
|
|
7
|
+
* 大文件上传文件切片请求
|
|
8
|
+
* @param options
|
|
9
|
+
*/
|
|
10
|
+
const uploadBigFileChunkRequest = (options) => {
|
|
11
|
+
const url = uploadChunkUrl;
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const httpClient = createHttpClient();
|
|
14
|
+
httpClient.post(url, options.data, options.config).then(res => {
|
|
15
|
+
resolve(res);
|
|
16
|
+
}).catch(err => {
|
|
17
|
+
reject(err);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* 大文件上传前置校验
|
|
23
|
+
* @param options
|
|
24
|
+
*/
|
|
25
|
+
const checkBigFileHashRequest = (options) => {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const httpClient = createHttpClient();
|
|
28
|
+
httpClient.post(options.url, options.data, options.config).then(res => {
|
|
29
|
+
resolve(res);
|
|
30
|
+
}).catch(err => {
|
|
31
|
+
reject(err);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// 可以使用的 webWorker 数量
|
|
37
|
+
const CAN_USER_WORKERS = Math.min(navigator.hardwareConcurrency - 1 || 2);
|
|
38
|
+
function useUpload(options = {}) {
|
|
39
|
+
const getUrl = () => {
|
|
40
|
+
return options.url || '';
|
|
41
|
+
};
|
|
42
|
+
const createXHR = () => {
|
|
43
|
+
return new XMLHttpRequest();
|
|
44
|
+
};
|
|
45
|
+
const setHeaders = (xhrInstance, headers = {}) => {
|
|
46
|
+
const defaultHeaders = Object.assign({ 'Accept': 'application/json' }, headers);
|
|
47
|
+
Object.entries(defaultHeaders).forEach(([key, value]) => {
|
|
48
|
+
if (value) {
|
|
49
|
+
xhrInstance.setRequestHeader(key, value);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* 单文件上传
|
|
55
|
+
* @param file 文件
|
|
56
|
+
* @param fileOptions 其他参数
|
|
57
|
+
* @returns
|
|
58
|
+
*/
|
|
59
|
+
const uploadFile = (file, fileOptions = {}) => {
|
|
60
|
+
const formData = new FormData();
|
|
61
|
+
let uploadProgress = 0;
|
|
62
|
+
let onProgress;
|
|
63
|
+
const fieldName = fileOptions.fieldName || 'file';
|
|
64
|
+
formData.append(fieldName, file);
|
|
65
|
+
// 额外数据
|
|
66
|
+
const extraData = Object.assign(Object.assign({}, options.data), fileOptions.data);
|
|
67
|
+
if (extraData) {
|
|
68
|
+
Object.entries(extraData).forEach(([key, value]) => {
|
|
69
|
+
if (value !== undefined && value !== null) {
|
|
70
|
+
formData.append(key, value.toString());
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
const xhr = createXHR();
|
|
75
|
+
const handleProgress = (event) => {
|
|
76
|
+
if (event.lengthComputable) {
|
|
77
|
+
uploadProgress = Math.round((event.loaded / event.total) * 100);
|
|
78
|
+
console.log('uploadProgress', uploadProgress);
|
|
79
|
+
if (onProgress) {
|
|
80
|
+
onProgress(uploadProgress, event);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const start = () => {
|
|
85
|
+
return new Promise((resolve, reject) => {
|
|
86
|
+
// 发送 请求
|
|
87
|
+
xhr.open('POST', getUrl(), true);
|
|
88
|
+
// 设置超时
|
|
89
|
+
if (options.timeout) {
|
|
90
|
+
xhr.timeout = options.timeout;
|
|
91
|
+
}
|
|
92
|
+
// 设置凭据
|
|
93
|
+
if (options.withCredentials) {
|
|
94
|
+
xhr.withCredentials = true;
|
|
95
|
+
}
|
|
96
|
+
// 设置请求头
|
|
97
|
+
setHeaders(xhr, options.headers);
|
|
98
|
+
// 进度事件
|
|
99
|
+
xhr.upload.addEventListener('progress', handleProgress);
|
|
100
|
+
// 请求完成
|
|
101
|
+
xhr.addEventListener('load', () => {
|
|
102
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
103
|
+
try {
|
|
104
|
+
const response = xhr.responseText ? JSON.parse(xhr.responseText) : {};
|
|
105
|
+
resolve(response);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
const errorMsg = `解析响应失败: ${error.message}`;
|
|
109
|
+
reject(new Error(errorMsg));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
const error = new Error(`上传失败: ${xhr.statusText}`);
|
|
114
|
+
reject(error);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
// 请求错误
|
|
118
|
+
xhr.addEventListener('error', () => {
|
|
119
|
+
const error = new Error('网络错误,上传失败');
|
|
120
|
+
reject(error);
|
|
121
|
+
});
|
|
122
|
+
// 请求超时
|
|
123
|
+
xhr.addEventListener('timeout', () => {
|
|
124
|
+
const error = new Error(`请求超时 (${options.timeout}ms)`);
|
|
125
|
+
reject(error);
|
|
126
|
+
});
|
|
127
|
+
// 中止事件
|
|
128
|
+
xhr.addEventListener('abort', () => {
|
|
129
|
+
const error = new Error('上传已取消');
|
|
130
|
+
reject(error);
|
|
131
|
+
});
|
|
132
|
+
// 发送请求
|
|
133
|
+
try {
|
|
134
|
+
xhr.send(formData);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
const errorMsg = `发送请求失败: ${error.message}`;
|
|
138
|
+
reject(new Error(errorMsg));
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
const pause = () => {
|
|
143
|
+
xhr.abort();
|
|
144
|
+
};
|
|
145
|
+
const resume = () => {
|
|
146
|
+
// upload();
|
|
147
|
+
};
|
|
148
|
+
const cancel = () => {
|
|
149
|
+
xhr.abort();
|
|
150
|
+
};
|
|
151
|
+
const setOnProgress = (callback) => {
|
|
152
|
+
onProgress = callback;
|
|
153
|
+
};
|
|
154
|
+
return {
|
|
155
|
+
start,
|
|
156
|
+
pause,
|
|
157
|
+
resume,
|
|
158
|
+
cancel,
|
|
159
|
+
setOnProgress
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* 多文件上传
|
|
164
|
+
* @param files 文件列表
|
|
165
|
+
* @param fileOptions 其他参数
|
|
166
|
+
* @returns
|
|
167
|
+
*/
|
|
168
|
+
const uploadFiles = (files, fileOptions = {}) => {
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* 大文件上传
|
|
172
|
+
* @param file 文件
|
|
173
|
+
* @param fileOptions 其他参数
|
|
174
|
+
* @returns
|
|
175
|
+
*/
|
|
176
|
+
const uploadBigFile = (file, fileOptions = {}) => {
|
|
177
|
+
// 1. 计算文件可以分成多少个分片
|
|
178
|
+
// 2. 创建 web worker 来计算每个分片的 hash
|
|
179
|
+
// 3. 得到分片和 hash 后就上传这个分片
|
|
180
|
+
// 4. 计算整个文件的 hash,得到这个 hash 后需要验证这个文件是否已经存在了,存在直接秒传
|
|
181
|
+
// 分片大小
|
|
182
|
+
const chunkSize = fileOptions.chunkSize || 1024 * 1024
|
|
183
|
+
* 5;
|
|
184
|
+
// 分片数量 = 文件大小 / 分片大小 (向上取整)
|
|
185
|
+
const chunkCount = Math.ceil(file.size / chunkSize);
|
|
186
|
+
const availableWorkers = CAN_USER_WORKERS;
|
|
187
|
+
// 1. TaskQueue 是一个任务队列,用于管理多个任务
|
|
188
|
+
// 2. 其中每个任务都是一个 Promise
|
|
189
|
+
// 3. 每完成一个任务,就从任务队列中取出下一个任务并执行
|
|
190
|
+
// 4. 若是队列中没有任务,则等待 任务进入队列
|
|
191
|
+
const taskQueue = new PQueue({ concurrency: availableWorkers });
|
|
192
|
+
const fileChunks = [];
|
|
193
|
+
// 已完成分片任务数量
|
|
194
|
+
let completedChunks = 0;
|
|
195
|
+
/**
|
|
196
|
+
* 分片上传进度回调函数
|
|
197
|
+
* @param progress
|
|
198
|
+
*/
|
|
199
|
+
const onProgress = (progress) => {
|
|
200
|
+
console.log('progress', progress);
|
|
201
|
+
};
|
|
202
|
+
const syncStartFileChunkUpload = () => {
|
|
203
|
+
const worker = new FileHashWorker();
|
|
204
|
+
return new Promise((resolve, reject) => {
|
|
205
|
+
try {
|
|
206
|
+
let resultFileHash;
|
|
207
|
+
worker.onMessage((res) => {
|
|
208
|
+
const result = res.data;
|
|
209
|
+
resultFileHash = result.fileHash;
|
|
210
|
+
checkBigFileHashRequest({
|
|
211
|
+
data: {
|
|
212
|
+
resultFileHash
|
|
213
|
+
}
|
|
214
|
+
}).then((res) => {
|
|
215
|
+
resolve(res.successChunkHash);
|
|
216
|
+
}).finally(() => {
|
|
217
|
+
worker.close();
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
worker.send({
|
|
221
|
+
file,
|
|
222
|
+
chunkSize
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
reject(error);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
};
|
|
230
|
+
const start = () => {
|
|
231
|
+
const totalChunks = Math.ceil(file.size / chunkSize);
|
|
232
|
+
const workerPool = availableWorkers;
|
|
233
|
+
const successChunkHashList = [];
|
|
234
|
+
for (let i = 0; i < availableWorkers; i++) {
|
|
235
|
+
const worker = new FileChunkHashWorker();
|
|
236
|
+
worker.send({
|
|
237
|
+
index: i,
|
|
238
|
+
file: file,
|
|
239
|
+
chunkSize,
|
|
240
|
+
startChunksIndex: i * workerPool,
|
|
241
|
+
endChunksIndex: Math.min(totalChunks, (i + 1) * workerPool)
|
|
242
|
+
});
|
|
243
|
+
worker.onMessage((event) => {
|
|
244
|
+
const { type, data } = event.data;
|
|
245
|
+
const { chunks = [] } = data;
|
|
246
|
+
fileChunks.push(...chunks);
|
|
247
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
248
|
+
const _chunkTarget = chunks[i];
|
|
249
|
+
// const fileChunk = new FileChunk()
|
|
250
|
+
taskQueue.add(() => {
|
|
251
|
+
return uploadBigFileChunkRequest(_chunkTarget);
|
|
252
|
+
}).then((result) => {
|
|
253
|
+
if (result.type === 'success') {
|
|
254
|
+
onProgress(completedChunks / chunkCount);
|
|
255
|
+
}
|
|
256
|
+
}).catch((err) => {
|
|
257
|
+
/*
|
|
258
|
+
TODO 这里可能需要尝试对 chunk 进行重试,重新上传这些没有上传成功的分片
|
|
259
|
+
*/
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
completedChunks++;
|
|
263
|
+
worker.close();
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
syncStartFileChunkUpload().then((successChunkHash) => {
|
|
267
|
+
successChunkHashList.push(...successChunkHash);
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
return {
|
|
271
|
+
start
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
return {
|
|
275
|
+
uploadFile,
|
|
276
|
+
uploadFiles,
|
|
277
|
+
uploadBigFile,
|
|
278
|
+
uploadLargeFile: uploadBigFile
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export { useUpload };
|
|
283
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/api.ts","../src/index.ts"],"sourcesContent":[null,null],"names":[],"mappings":"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"}
|
package/index.cjs.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
// 主入口文件 - CommonJS 版本
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
|
|
5
|
+
const Client = require('./client/index.cjs.js');
|
|
6
|
+
const Core = require('./core/index.cjs.js');
|
|
7
|
+
const Utils = require('./utils/index.cjs.js');
|
|
8
|
+
|
|
9
|
+
Object.assign(exports, Client, Core, Utils);
|
package/index.d.ts
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
// 主入口文件 - 聚合所有子包导出
|
|
3
|
+
export * from './client/index.esm.js';
|
|
4
|
+
export * from './core/index.esm.js';
|
|
5
|
+
export * from './utils/index.esm.js';
|
|
6
|
+
|
|
7
|
+
// 默认导出所有内容
|
|
8
|
+
import * as Client from './client/index.esm.js';
|
|
9
|
+
import * as Core from './core/index.esm.js';
|
|
10
|
+
import * as Utils from './utils/index.esm.js';
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
...Client,
|
|
14
|
+
...Core,
|
|
15
|
+
...Utils
|
|
16
|
+
};
|