naive-upload
Version:
<p align="left"> <a href="https://www.npmjs.org/package/naive-upload"> <img src="https://img.shields.io/npm/v/naive-upload.svg"> </a> <a href="https://bundlephobia.com/package/naive-upload@latest"> <img src="https://img.shields.io/bundl
350 lines (349 loc) • 13 kB
JavaScript
var B = Object.defineProperty;
var U = (f, e, a) => e in f ? B(f, e, { enumerable: !0, configurable: !0, writable: !0, value: a }) : f[e] = a;
var h = (f, e, a) => (U(f, typeof e != "symbol" ? e + "" : e, a), a);
import F from "./UploadError.js";
import { UploadWorkerMessageType as c } from "../Model/UploadWorkerMessageType.js";
import { PreUploadChunkFileState as b } from "../Model/PreUploadChunkFileState.js";
import { UploadWorkerScript as E } from "./UploadWorkerScript.js";
import A from "./FileReadHelper.js";
class m {
constructor(e, a, t) {
h(this, "enableWorker");
h(this, "workerSupported");
h(this, "debug");
h(this, "apiService");
h(this, "cancelTokenList", /* @__PURE__ */ new Map());
h(this, "workerUnits", []);
h(this, "chunkHandlerQueue", []);
h(this, "chunkHandler", []);
h(this, "delayTimes", 0);
h(this, "finished", !1);
h(this, "canceled", !1);
h(this, "paused", !1);
h(this, "waitToContinue", []);
h(this, "fileReaders", []);
this.debug = t, this.enableWorker = e, this.workerSupported = typeof Worker < "u", this.apiService = a, this.enableWorker && this.debug && console.debug(`UploadHelper > WebWoeker ${this.workerSupported ? "\u5DF2\u542F\u7528" : "\u672A\u542F\u7528\uFF08\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\uFF09"}`);
}
async uploadFile(e, a) {
const t = await this.apiService.singleFile(e.configCode, e.file, e.name, a, (d) => {
this.cancelTokenList.set(e.md5, d);
});
return this.cancelTokenList.delete(e.md5), t;
}
async uploadChunkFile(e, a, t, d) {
await this.apiService.singleChunkFile(a.key, t.md5, t.blob, d, (r) => {
this.cancelTokenList.set(t.md5, r);
}), this.cancelTokenList.delete(t.md5);
}
async useWorkerUploadFile(e, a) {
return new Promise(async (t, d) => {
let r;
try {
r = await this.fileReaders[0].readAsArrayBuffer(e.file);
} catch (u) {
d(u);
return;
}
try {
const u = this.apiService.getSingleFileByArrayBufferRequestParams(e.configCode, e.file.type, e.extension, e.name), s = await this.workerPostMessage(0, {
type: c.\u4E0B\u884C_\u4E0A\u4F20,
data: {
url: u.urlWithParams,
headers: u.headers,
buffer: r
}
}, a, !1);
t(s);
return;
} catch (u) {
d(u);
return;
}
});
}
async useWorkerUploadChunkFile(e, a, t, d) {
return new Promise(async (r, u) => {
let s;
try {
s = await this.fileReaders[e].readAsArrayBuffer(t.blob);
} catch (i) {
u(i);
return;
}
try {
const i = this.apiService.getSingleChunkFileByArrayBufferRequestParams(a.key, t.md5);
await this.workerPostMessage(
e,
{
type: c.\u4E0B\u884C_\u4E0A\u4F20,
data: {
url: i.urlWithParams,
headers: i.headers,
buffer: s
}
},
d,
!0
);
} catch (i) {
u(i);
return;
}
r();
});
}
async workerPostMessage(e, a, t, d) {
let r = this.workerUnits[e];
return r.used = !0, new Promise((u, s) => {
r.worker.onmessage = (i) => {
switch (i.data.type) {
case c.\u4E0A\u884C_\u8FDB\u5EA6:
const w = i.data.data;
t && t({
preLoaded: w.preLoaded,
total: w.total,
loaded: w.loaded
});
break;
case c.\u4E0A\u884C_\u53D6\u6D88:
const o = i.data.data;
t && t({
preLoaded: o.preLoaded,
total: o.total,
loaded: o.loaded
}), r.used = !1, s(new F("\u4E0A\u4F20\u64CD\u4F5C\u5DF2\u53D6\u6D88"));
break;
case c.\u4E0A\u884C_\u5B8C\u6210:
r.used = !1;
try {
const p = d ? this.apiService.getUserFileInfoFromSingleChunkFileByArrayBufferResponse(i.data.data) : this.apiService.getUserFileInfoFromSingleFileByArrayBufferResponse(i.data.data);
u(p);
} catch (p) {
s(new F("\u4E0A\u4F20\u5931\u8D25", p));
}
break;
case c.\u4E0A\u884C_\u5931\u8D25:
const k = i.data.data;
t && t({
preLoaded: k.preLoaded,
total: k.total,
loaded: k.loaded
}), r.used = !1, s(new F("\u4E0A\u4F20\u5931\u8D25"));
break;
case c.\u4E0A\u884C_\u8D85\u65F6:
const n = i.data.data;
t && t({
preLoaded: n.preLoaded,
total: n.total,
loaded: n.loaded
}), r.used = !1, s(new F("\u4E0A\u4F20\u64CD\u4F5C\u5904\u7406\u8D85\u65F6"));
break;
default:
s(new F(`\u672A\u77E5\u7684UploadWorkerMessageType: ${i.data.type}.`));
}
}, r.worker.onerror = (i) => {
r.used = !1, s(new F("WebWorker\u53D1\u751F\u9519\u8BEF", i.error));
}, r.worker.onmessageerror = (i) => {
r.used = !1, s(new F(`WebWorker\u901A\u8BAF\u9519\u8BEF\uFF0C${i.data}`));
}, a.type === c.\u4E0B\u884C_\u4E0A\u4F20 ? r.worker.postMessage(a, [a.data.buffer]) : r.worker.postMessage(JSON.parse(JSON.stringify(a)));
});
}
async closeByIndex(e) {
this.fileReaders[e].close(), this.debug && console.debug("UploadHelper > FileReadHelper \u5DF2\u5173\u95ED", Object.assign({}, this.fileReaders[e])), this.enableWorker && this.workerSupported && (await this.workerPostMessage(e, { type: c.\u4E0B\u884C_\u5173\u95ED }), this.debug && console.debug("UploadHelper > WebWoeker\u5B50\u7EBF\u7A0B\u8BA1\u7B97\u5355\u5143 \u5DF2\u5173\u95ED", Object.assign({}, this.workerUnits[e].worker)));
}
static async getInstance(e, a = !0, t, d = !1) {
return new Promise((r) => {
let u = new m(a, t, d);
for (; u.fileReaders.length < e; )
u.fileReaders.push(new A()), u.chunkHandler.push(!1), u.waitToContinue.push(null), u.debug && console.debug("UploadHelper > FileReadHelper \u5DF2\u521B\u5EFA", Object.assign({}, u.fileReaders[u.fileReaders.length - 1]));
if (u.enableWorker && u.workerSupported) {
window.URL = window.URL || window.webkitURL;
for (let s = 0; s < e; s++)
u.workerUnits.push({
worker: new Worker(window.URL.createObjectURL(E)),
used: !1
}), u.debug && console.debug("UploadHelper > WebWoeker\u5B50\u7EBF\u7A0B\u8BA1\u7B97\u5355\u5143 \u5DF2\u521B\u5EFA", Object.assign({}, u.workerUnits[s].worker));
}
r(u);
});
}
async handler(e, a) {
return new Promise(async (t, d) => {
this.debug && console.debug("UploadHelper \u5F00\u59CB\u5904\u7406", Object.assign({}, e));
const r = () => {
this.finished = !0, this.debug && console.debug("UploadHelper \u5904\u7406\u7ED3\u675F", Object.assign({}, e)), t();
};
let u;
try {
e.needSection ? u = await this.apiService.preUploadFile(
e.configCode,
e.md5,
e.file.type,
e.extension,
e.file.size.toString(),
e.name,
!0,
e.specs,
e.chunks.length
) : u = await this.apiService.preUploadFile(
e.configCode,
e.md5,
e.file.type,
e.extension,
e.file.size.toString(),
e.name,
!1
);
} catch (s) {
d(s);
return;
}
if (u.uploaded) {
this.debug && console.debug("UploadHelper \u5FFD\u7565\u5DF2\u4E0A\u4F20\u8FC7\u7684\u6587\u4EF6", Object.assign({}, e)), e.userFileInfo = u.userFileInfo, r();
return;
}
if (e.needSection) {
let s = { preLoaded: 0, loaded: 0, total: e.size };
const i = async () => {
if (this.finished)
return;
if (this.chunkHandlerQueue.length === 0) {
for (let l = 0; l < this.chunkHandler.length; l++)
if (this.chunkHandler[l])
return;
try {
e.userFileInfo = await this.apiService.uploadChunkFileFinished(
e.configCode,
e.md5,
e.specs,
e.chunks.length,
e.file.type,
e.extension,
e.name
), r();
} catch (l) {
d(l);
}
return;
}
let o = null;
for (let l = 0; l < this.chunkHandler.length; l++)
if (!this.chunkHandler[l]) {
o = l;
break;
}
if (o == null) {
this.debug && console.debug(`HashHelper \u5DF2\u8FBE\u5230\u6700\u5927\u5E76\u53D1\u6570\uFF1A${this.chunkHandler.length}\uFF0C\u5F53\u524D\u961F\u5217\u957F\u5EA6\uFF1A${this.chunkHandlerQueue.length}`, Object.assign({}, e));
return;
}
this.chunkHandler[o] = !0;
const k = () => {
if (a(s), this.canceled) {
t();
return;
}
if (this.paused) {
const l = async () => new Promise((D, H) => {
this.waitToContinue[o] = D;
});
this.debug && console.debug("UploadHelper > \u5DF2\u6682\u505C", o), l().then((D) => {
if (this.waitToContinue[o] = null, this.debug && console.debug("UploadHelper > \u5DF2\u6062\u590D", o), !D) {
t();
return;
}
this.chunkHandler[o] = !1, i();
});
} else
this.chunkHandler[o] = !1, i();
}, n = this.chunkHandlerQueue.shift();
if (n.uploaded) {
s.preLoaded += n.size, s.loaded += n.size, a(s), k();
return;
}
let p = { preLoaded: n.size, loaded: 0, total: n.size };
const y = (l) => {
s.loaded += l.loaded - p.loaded, p.loaded = l.loaded, a(s);
};
let g;
try {
g = await this.apiService.preUploadChunkFile(
e.md5,
n.md5,
n.index,
e.specs,
n.forced
);
} catch (l) {
d(l);
return;
}
s.preLoaded += p.preLoaded, a(s);
const C = async () => {
this.workerSupported ? await this.useWorkerUploadChunkFile(o, g, n, y) : await this.uploadChunkFile(o, g, n, y);
};
switch (g.state) {
case b.\u5141\u8BB8\u4E0A\u4F20:
await C();
break;
case b.\u5168\u90E8\u8DF3\u8FC7:
this.chunkHandlerQueue.length = 0;
return;
case b.\u63A8\u8FDF\u4E0A\u4F20:
this.chunkHandlerQueue.push(n), this.delayTimes++, this.delayTimes >= this.chunkHandlerQueue.length && (this.delayTimes = 0, n.forced = !0);
break;
case b.\u8DF3\u8FC7:
y({ preLoaded: n.size, loaded: n.size, total: n.size });
break;
}
k();
}, w = (o) => {
this.chunkHandlerQueue.push(o), i();
};
for (let o of e.chunks)
w(o);
} else
try {
this.workerSupported ? e.userFileInfo = await this.useWorkerUploadFile(e, a) : e.userFileInfo = await this.uploadFile(e, a), r();
} catch (s) {
d(s);
}
});
}
async cancel() {
if (this.canceled = !0, this.paused) {
this.paused = !1;
for (const e of this.waitToContinue)
e && e(!1);
}
if (this.enableWorker && this.workerSupported)
for (let e = 0; e < this.workerUnits.length; e++)
!this.workerUnits[e].used || (await this.workerPostMessage(e, { type: c.\u4E0B\u884C_\u53D6\u6D88 }), this.debug && console.debug("UploadHelper > WebWoeker\u5B50\u7EBF\u7A0B\u8BA1\u7B97\u5355\u5143 \u5DF2\u53D6\u6D88", Object.assign({}, this.workerUnits[e].worker)));
else
this.cancelTokenList.forEach((e) => {
e();
});
this.debug && console.debug("UploadHelper \u5DF2\u53D6\u6D88");
}
async pause() {
this.paused = !0, this.debug && console.debug("UploadHelper \u5DF2\u6682\u505C");
}
async continue() {
this.paused = !1;
for (const e of this.waitToContinue)
e && e(!0);
this.debug && console.debug("UploadHelper \u5DF2\u6062\u590D");
}
async close() {
if (this.enableWorker && this.workerSupported)
for (let e = 0; e < this.workerUnits.length; e++)
await this.closeByIndex(e);
else
for (let e = 0; e < this.fileReaders.length; e++)
await this.closeByIndex(e);
this.debug && console.debug("UploadHelper \u5DF2\u5173\u95ED");
}
}
export {
m as default
};
//# sourceMappingURL=UploadHelper.js.map