forked from sveltejs/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupload.js
52 lines (37 loc) · 1.22 KB
/
upload.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
import { writable } from 'svelte/store';
export function create_upload() {
const { subscribe, update } = writable({ status: 'idle', progress: 0 });
/** @type {XMLHttpRequest} */
let xhr;
return {
subscribe,
/** @param {{file: File, url: string, headers: Record<string, string>}} input */
start({ file, url, headers = {} }) {
return new Promise((resolve, reject) => {
xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (event) => {
/** @type {number} */
let progress = 0;
if (event.lengthComputable) {
progress = Math.round((event.loaded / event.total) * 100);
}
update((state) => ({ ...state, status: 'uploading', progress }));
});
xhr.addEventListener('loadend', () => {
const status = xhr.status > 0 && xhr.status < 400 ? 'completed' : 'error';
update((state) => ({ ...state, status }));
resolve(xhr);
});
xhr.upload.addEventListener('error', () => {
update((state) => ({ ...state, progress: 0, status: 'error' }));
});
xhr.open('POST', url);
for (const [name, value] of Object.entries(headers)) {
xhr.setRequestHeader(name, value);
}
xhr.send(file);
});
}
};
}
export default create_upload;