js-uploader
Version:
A JavaScript library for file upload
608 lines • 31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Uploader = void 0;
var tslib_1 = require("tslib");
var interface_1 = require("../interface");
var modules_1 = require("./modules");
var handlers_1 = require("./handlers");
var operators_1 = require("rxjs/operators");
var rxjs_1 = require("rxjs");
var Base_1 = require("./Base");
var utils_1 = require("../utils");
var helpers_1 = require("./helpers");
var shared_1 = require("../shared");
// import * as packageJson from '../../package.json'
var defaultOptions = {
requestOptions: {
url: '/',
timeout: 0,
},
autoUpload: false,
computeFileHash: false,
computeChunkHash: false,
maxRetryTimes: 3,
retryInterval: 5000,
chunked: true,
chunkSize: 1024 * 1024 * 4,
chunkConcurrency: 1,
taskConcurrency: 1,
resumable: true,
};
var Uploader = /** @class */ (function (_super) {
tslib_1.__extends(Uploader, _super);
// static readonly version = (packageJson as any).version
function Uploader(options) {
var _this = _super.call(this, options === null || options === void 0 ? void 0 : options.id) || this;
_this.taskQueue = [];
_this.filePickers = [];
_this.fileDraggers = [];
_this.taskHandlerMap = new Map();
_this.upload$ = null;
_this.subscription = new rxjs_1.Subscription();
_this.uploadSubscription = null;
_this.taskSubject = new rxjs_1.Subject();
_this.action = new rxjs_1.Subject();
_this.pause$ = _this.action.pipe(operators_1.filter(function (v) { return v === 'pause'; }));
_this.clear$ = _this.action.pipe(operators_1.filter(function (v) { return v === 'clear'; }));
var opt = _this.mergeOptions(options);
_this.validateOptions(opt);
_this.options = opt;
_this.id = _this.options.id;
_this.initFilePickersAndDraggers();
_this.initEventHandler();
_this.options.resumable && _this.restoreTask();
return _this;
}
Uploader.create = function (options) {
return new Uploader(options);
};
Uploader.prototype.mergeOptions = function (options) {
var opt = Object.assign({}, defaultOptions, options);
Object.keys(defaultOptions).forEach(function (key) {
var _a;
var k = key;
if (typeof defaultOptions[k] === 'object') {
Object.assign(defaultOptions[k], opt[k]);
var val = Object.assign({}, defaultOptions[k], opt[k]);
Object.assign(opt, (_a = {}, _a[k] = val, _a));
}
});
return opt;
};
Uploader.prototype.validateOptions = function (options) {
shared_1.Logger.info('🚀 ~ file: Uploader.ts ~ line 84 ~ Uploader ~ validateOptions ~ options', options);
// TODO
if (typeof options !== 'object') {
throw new Error('');
}
};
Uploader.prototype.upload = function (task, action) {
var _this = this;
var _a, _b;
if (!this.uploadSubscription || ((_a = this.uploadSubscription) === null || _a === void 0 ? void 0 : _a.closed)) {
var filteredTaskStatus_1 = [interface_1.StatusCode.Waiting, interface_1.StatusCode.Uploading, interface_1.StatusCode.Complete];
this.upload$ = this.taskSubject.pipe(operators_1.filter(function (task) {
return !filteredTaskStatus_1.includes(task.status);
}), operators_1.tap(function (task) {
shared_1.Logger.info('🚀 ~ file: 等待上传', task);
_this.changeUploadTaskStatus(task, interface_1.StatusCode.Waiting);
_this.emit(interface_1.EventType.TaskWaiting, task);
}), operators_1.mergeMap(function (task) {
return _this.executeForResult(task, action);
}, this.options.taskConcurrency || 1));
(_b = this.uploadSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
this.uploadSubscription = this.upload$.subscribe({
next: function (v) {
shared_1.Logger.info('任务结束', v);
_this.checkComplete();
},
error: function (e) {
shared_1.Logger.info('任务出错', e);
},
complete: function () {
shared_1.Logger.info('所有任务完成');
},
});
this.subscription.add(this.uploadSubscription);
}
this.putNextTask(task);
};
Uploader.prototype.checkComplete = function () {
if (this.isComplete()) {
this.emit(interface_1.EventType.Complete);
}
};
Uploader.prototype.executeForResult = function (task, action) {
var _this = this;
return rxjs_1.of(task).pipe(operators_1.filter(function (task) { return task.status === interface_1.StatusCode.Waiting; }), operators_1.concatMap(function () { return _this.getTaskHandler(task); }), operators_1.tap(function (handler) {
handler = _this.rebindTaskHandlerEvent(handler);
action === 'resume' ? handler.resume() : action === 'retry' ? handler.retry() : handler.handle();
}), operators_1.concatMap(function (handler) {
return rxjs_1.race(rxjs_1.fromEvent(handler, interface_1.EventType.TaskPause).pipe(operators_1.tap(function () {
// 暂停
shared_1.Logger.info('任务暂停');
})), rxjs_1.fromEvent(handler, interface_1.EventType.TaskCancel).pipe(operators_1.tap(function () {
// 取消
_this.freeHandler(task);
})), rxjs_1.fromEvent(handler, interface_1.EventType.TaskComplete).pipe(operators_1.tap(function () {
// 完成
_this.freeHandler(task);
})), rxjs_1.fromEvent(handler, interface_1.EventType.TaskError).pipe(operators_1.switchMap(function (err) {
// 出错 跳过错误的任务?
if (_this.options.skipTaskWhenUploadError) {
_this.freeHandler(task);
return rxjs_1.of(null);
}
return rxjs_1.throwError(err);
}))).pipe(operators_1.mapTo(task), operators_1.first());
}));
};
Uploader.prototype.resume = function (task) {
this.upload(task, 'resume');
};
Uploader.prototype.retry = function (task) {
this.upload(task, 'retry');
};
Uploader.prototype.pause = function (task) {
var _this = this;
this.action.next('pause');
var fn = function (task) {
var _a;
var handler = (_a = _this.taskHandlerMap.get(task.id)) === null || _a === void 0 ? void 0 : _a.pause();
if (!handler) {
task.status = interface_1.StatusCode.Pause;
// 任务暂停事件
_this.emit(interface_1.EventType.TaskPause, task);
}
};
var tasks = task ? [task] : this.taskQueue;
var filteredStatus = [interface_1.StatusCode.Pause, interface_1.StatusCode.Complete, interface_1.StatusCode.Error];
rxjs_1.from(tasks)
.pipe(operators_1.filter(function (tsk) { return !filteredStatus.includes(tsk.status); }), operators_1.tap(function (tsk) { return fn(tsk); }))
.subscribe({
complete: function () {
_this.emit(interface_1.EventType.TasksPause);
},
});
};
Uploader.prototype.cancel = function (task) {
if (task) {
this.action.next('cancel');
return this.removeTask(task);
}
else {
return this.clear();
}
};
Uploader.prototype.clear = function () {
var _this = this;
return new Promise(function (resolve) {
_this.action.next('clear');
var unsubscribe = function () {
var _a;
(_a = _this.uploadSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
_this.uploadSubscription = null;
_this.upload$ = null;
};
unsubscribe();
if (_this.taskQueue.length === 0) {
return resolve();
}
rxjs_1.of(_this.taskQueue.splice(0, _this.taskQueue.length))
.pipe(operators_1.tap(function () { return _this.emit(interface_1.EventType.Clear); }), operators_1.concatMap(function (list) { return _this.removeTask(list, true); }), operators_1.concatMap(function () { return _this.clearStorage(_this.id); }), operators_1.tap(function () { return modules_1.FileStore.clear(); }))
.subscribe({
complete: function () {
unsubscribe();
resolve();
},
});
});
};
Uploader.prototype.cancelFile = function (item) {
var _this = this;
var _a;
var task = item.task, files = item.files;
var handler = (_a = this.taskHandlerMap.get(task.id)) === null || _a === void 0 ? void 0 : _a.abortFile.apply(_a, tslib_1.__spread(files));
var rawTask = this.taskQueue.find(function (i) { return i.id === task.id; });
if (!handler && rawTask) {
files.forEach(function (file) {
var idIndex = rawTask === null || rawTask === void 0 ? void 0 : rawTask.fileIDList.indexOf(file.id);
if (idIndex > -1) {
rawTask === null || rawTask === void 0 ? void 0 : rawTask.fileIDList.splice(idIndex, 1);
rawTask.fileSize -= file.size;
_this.emit(interface_1.EventType.FileCancel, rawTask, modules_1.FileStore.get(file.id));
}
var fileIndex = rawTask === null || rawTask === void 0 ? void 0 : rawTask.fileList.findIndex(function (i) { return i.id === file.id; });
if (fileIndex !== -1) {
rawTask === null || rawTask === void 0 ? void 0 : rawTask.fileList.splice(fileIndex, 1);
}
_this.emit(interface_1.EventType.TaskUpdate, rawTask);
});
this.emit(interface_1.EventType.FilesCancel, rawTask, files);
}
this.once(interface_1.EventType.FilesCancel, function () {
if (_this.options.resumable) {
_this.presistTaskOnly(task);
_this.removeFileFromStroage.apply(_this, tslib_1.__spread(files));
_this.removeChunkFromStroage.apply(_this, tslib_1.__spread(files.reduce(function (arr, i) { return arr.concat(i.chunkIDList); }, [])));
}
_this.removeFileFromFileStore.apply(_this, tslib_1.__spread(files.map(function (i) { return i.id; })));
});
};
Uploader.prototype.isUploading = function () {
var _a;
if ((_a = this.uploadSubscription) === null || _a === void 0 ? void 0 : _a.closed) {
return false;
}
return this.taskQueue.some(function (task) { return task.status === interface_1.StatusCode.Uploading || task.status === interface_1.StatusCode.Waiting; });
};
Uploader.prototype.hasError = function () {
return this.taskQueue.some(function (task) { return task.status === interface_1.StatusCode.Error; });
};
Uploader.prototype.getErrorTasks = function () {
return this.taskQueue.filter(function (task) { return task.status === interface_1.StatusCode.Error; });
};
Uploader.prototype.isComplete = function () {
var status = [interface_1.StatusCode.Uploading, interface_1.StatusCode.Waiting, interface_1.StatusCode.Pause];
return !this.taskQueue.some(function (task) { return status.includes(task.status); });
};
Uploader.prototype.destory = function () {
this.subscription.unsubscribe();
};
Uploader.prototype.removeTask = function (tasks, clear) {
var _this = this;
if (!Array.isArray(tasks)) {
tasks = [tasks];
}
return rxjs_1.scheduled(tasks || [], rxjs_1.asyncScheduler)
.pipe(operators_1.tap(function (task) {
var _a;
var index = _this.taskQueue.findIndex(function (i) { return i.id === (task === null || task === void 0 ? void 0 : task.id); });
index > -1 && _this.taskQueue.splice(index, 1);
(_a = _this.taskHandlerMap.get(task.id)) === null || _a === void 0 ? void 0 : _a.abort();
_this.taskHandlerMap.delete(task.id);
!clear && _this.removeTaskFromStroage(task);
// 任务取消事件
_this.emit(interface_1.EventType.TaskCancel, task);
}))
.toPromise();
};
Uploader.prototype.rebindTaskHandlerEvent = function (handler) {
var _this = this;
var e = [];
for (var _i = 1; _i < arguments.length; _i++) {
e[_i - 1] = arguments[_i];
}
var events = (e === null || e === void 0 ? void 0 : e.length) ? e : Object.values(interface_1.EventType);
events.forEach(function (e) {
handler === null || handler === void 0 ? void 0 : handler.off(e);
handler === null || handler === void 0 ? void 0 : handler.on(e, function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return _this.taskHandlerEventCallback.apply(_this, tslib_1.__spread([e], args));
});
});
return handler;
};
Uploader.prototype.getTaskHandler = function (task) {
var _this = this;
return rxjs_1.iif(function () { return _this.taskHandlerMap.has(task.id); }, rxjs_1.of(this.taskHandlerMap.get(task.id)), handlers_1.handle(task, this.options)).pipe(operators_1.tap(function (handler) {
_this.taskHandlerMap.set(task.id, handler);
}));
};
Uploader.prototype.freeHandler = function (task) {
var id = task.id;
var handler = this.taskHandlerMap.get(id) || null;
if (handler) {
Object.values(interface_1.EventType).forEach(function (e) { return handler.off(e); });
this.taskHandlerMap.delete(id);
handler = null;
}
};
Uploader.prototype.putNextTask = function (task) {
var _this = this;
if (task) {
if (typeof task === 'object') {
this.taskSubject.next(task);
}
else {
var tsk = this.taskQueue.find(function (tsk) { return tsk.id === task; });
tsk && this.taskSubject.next(tsk);
}
}
else {
var sub_1 = rxjs_1.scheduled(this.taskQueue, rxjs_1.asapScheduler)
.pipe(operators_1.filter(function (tsk) { return tsk.status !== interface_1.StatusCode.Complete; }), operators_1.takeUntil(this.pause$))
.subscribe({
next: function (tsk) { return _this.taskSubject.next(tsk); },
complete: function () {
sub_1 === null || sub_1 === void 0 ? void 0 : sub_1.unsubscribe();
sub_1 = null;
},
});
}
};
Uploader.prototype.taskHandlerEventCallback = function (e) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
this.emit.apply(this, tslib_1.__spread([e], args));
};
Uploader.prototype.changeUploadTaskStatus = function (task, status) {
task.status = status;
};
Uploader.prototype.restoreTask = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var taskList, recoverableTaskStatus;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, modules_1.getStorage(this.id).UploadTask.values().toPromise()];
case 1:
taskList = _a.sent();
recoverableTaskStatus = this.options.recoverableTaskStatus;
if (!(taskList === null || taskList === void 0 ? void 0 : taskList.length)) {
return [2 /*return*/, []];
}
return [2 /*return*/, rxjs_1.scheduled(taskList || [], rxjs_1.asyncScheduler)
.pipe(operators_1.filter(function (task) {
if (recoverableTaskStatus === null || recoverableTaskStatus === void 0 ? void 0 : recoverableTaskStatus.length) {
return recoverableTaskStatus.includes(task.status);
}
return true;
}), operators_1.tap(function (task) {
if (task.status !== interface_1.StatusCode.Complete) {
task.status = task.status === interface_1.StatusCode.Error ? task.status : interface_1.StatusCode.Pause;
task.progress = task.progress >= 100 ? 99 : task.progress;
}
_this.taskQueue.push(task);
if (_this.options.autoUpload && task.status === interface_1.StatusCode.Pause) {
_this.upload(task);
}
// 任务恢复事件
_this.emit(interface_1.EventType.TaskRestore, task);
}), operators_1.last(), operators_1.mapTo(taskList), operators_1.takeUntil(this.clear$))
.toPromise()
// return new Promise((resolve, reject) => {
// Storage.UploadTask.list()
// .then((list: unknown[]) => {
// Logger.info('Uploader -> restoreTask -> list', list)
// const taskList: UploadTask[] = []
// const fn = (timeRemaining?: () => number) => {
// while (list.length) {
// const arr = list.splice(0, 20) as UploadTask[]
// arr.forEach((task) => {
// if (task.status === StatusCode.Complete) {
// return this.removeTaskFromStroage(task)
// }
// task.status = StatusCode.Pause
// task.progress = task.progress >= 100 ? 99 : task.progress
// this.taskQueue.push(task)
// taskList.push(task)
// this.options.autoUpload && this.upload(task)
// // 任务恢复事件
// this.emit(EventType.TaskRestore, task)
// })
// if (!timeRemaining || !timeRemaining?.()) {
// break
// }
// }
// list.length ? scheduleWork(fn) : resolve(taskList)
// }
// scheduleWork(fn)
// })
// .catch((e) => reject(e))
// })
];
}
});
});
};
Uploader.prototype.initFilePickersAndDraggers = function () {
var _this = this;
var _a = this.options, filePicker = _a.filePicker, fileDragger = _a.fileDragger;
var filePickers = Array.isArray(filePicker) ? filePicker : filePicker ? [filePicker] : null;
var fileDraggers = Array.isArray(fileDragger) ? fileDragger : fileDragger ? [fileDragger] : null;
var obs = [];
if (filePickers === null || filePickers === void 0 ? void 0 : filePickers.length) {
obs.push.apply(obs, tslib_1.__spread(filePickers.map(function (opts) {
var picker = new modules_1.FilePicker(opts);
_this.filePickers.push(picker);
return picker.file$;
})));
}
if (fileDraggers === null || fileDraggers === void 0 ? void 0 : fileDraggers.length) {
obs.push.apply(obs, tslib_1.__spread(fileDraggers.map(function (opts) {
var dragger = new modules_1.FileDragger(opts, _this.options);
_this.fileDraggers.push(dragger);
return dragger.file$;
})));
}
if (obs.length) {
this.subscription.add(rxjs_1.merge.apply(void 0, tslib_1.__spread(obs)).pipe(operators_1.concatMap(function (files) { return _this.add(files); }))
.subscribe());
}
};
Uploader.prototype.initEventHandler = function () {
var _this = this;
this.on(interface_1.EventType.TaskCreated, function (task) {
_this.options.autoUpload && _this.upload(task);
});
};
Uploader.prototype.add = function (files) {
var _this = this;
return rxjs_1.of(files).pipe(operators_1.concatMap(function (files) {
var _a, _b;
// 选择文件后添加文件前hook
var beforeAdd = _this.hookWrap((_b = (_a = _this.options).beforeFilesAdd) === null || _b === void 0 ? void 0 : _b.call(_a, files));
return rxjs_1.from(beforeAdd).pipe(operators_1.mapTo(files));
}), operators_1.concatMap(function (files) {
return rxjs_1.from(_this.addFilesAsync.apply(_this, tslib_1.__spread(files))).pipe(operators_1.map(function (tasks) { return ({ files: files, tasks: tasks }); }));
}), operators_1.takeUntil(this.clear$));
};
Uploader.prototype.addFilesAsync = function () {
var _this = this;
var files = [];
for (var _i = 0; _i < arguments.length; _i++) {
files[_i] = arguments[_i];
}
return new Promise(function (resolve, reject) {
shared_1.Logger.info('Uploader -> addFile -> files', files);
var resolveTasks = function (tasks) {
resolve(tasks);
_this.emit(interface_1.EventType.TasksAdded, tasks);
};
var finish = function (tasks) {
if (_this.options.resumable) {
var ob$ = utils_1.isElectron()
? _this.presistTaskWithoutBlob(tasks, _this.clear$)
: _this.presistTask(tasks, _this.clear$);
var sub_2 = ob$.pipe(operators_1.takeUntil(_this.clear$)).subscribe({
error: function (e) { return reject(e); },
complete: function () {
// 任务持久化事件
_this.emit(interface_1.EventType.TasksPresist, tasks);
sub_2 === null || sub_2 === void 0 ? void 0 : sub_2.unsubscribe();
sub_2 = null;
resolveTasks(tasks);
console.timeEnd('addFilesAsync');
},
});
}
else {
resolveTasks(tasks);
console.timeEnd('addFilesAsync');
}
};
if (!files.length) {
resolveTasks([]);
return;
}
console.time('addFilesAsync');
var fileFilter = _this.options.fileFilter;
var tasks = new Set();
rxjs_1.scheduled(files || [], rxjs_1.asapScheduler)
.pipe(operators_1.filter(function (file) {
var accept = true;
if (fileFilter instanceof RegExp) {
accept = fileFilter.test(file.name);
}
else if (typeof fileFilter === 'function') {
accept = fileFilter(file.name, file);
}
return !!accept;
}), operators_1.bufferCount(1000), operators_1.map(function (files) {
return files.map(helpers_1.fileFactory);
}), operators_1.concatMap(function (files) { return _this.generateTask.apply(_this, tslib_1.__spread(files)); }), operators_1.tap(function (data) { return data === null || data === void 0 ? void 0 : data.forEach(function (i) { return i && tasks.add(i); }); }))
.subscribe({
complete: function () { return finish(tslib_1.__spread(tasks)); },
});
// const scheduleWork = (cb: Noop, timeout?: number) => cb()
// const fn = async (timeRemaining?: () => number) => {
// while (files.length) {
// Logger.info(files.length)
// const filelist: UploadFile[] = []
// files.splice(0, 100).forEach((file) => {
// let ignored = false
// if (fileFilter instanceof RegExp) {
// ignored = !fileFilter.test(file.name)
// } else if (typeof fileFilter === 'function') {
// ignored = !fileFilter(file.name, file)
// }
// if (!ignored) {
// filelist.push(fileFactory(file))
// }
// })
// const currentTasks: UploadTask[] = await this.generateTask(...filelist).toPromise()
// currentTasks.map((i) => tasks.add(i))
// // if (!timeRemaining?.()) {
// // break
// // }
// }
// files.length ? scheduleWork(fn, 1000) : finish([...tasks])
// }
// scheduleWork(fn)
});
};
Uploader.prototype.generateTask = function () {
var _this = this;
var fileList = [];
for (var _i = 0; _i < arguments.length; _i++) {
fileList[_i] = arguments[_i];
}
return new rxjs_1.Observable(function (subscriber) {
console.time('generateTask');
var _a = _this.options, ossOptions = _a.ossOptions, singleFileTask = _a.singleFileTask;
var updateTasks = new Set();
var newTasks = [];
var notifier = new rxjs_1.Subject();
var existsTaskMap = new Map();
var sub = rxjs_1.from(fileList)
.pipe(operators_1.tap(function (file) {
var pos = file.relativePath.indexOf('/');
var newTask = null;
var inFolder = !singleFileTask && pos !== -1;
if (!inFolder) {
newTask = helpers_1.taskFactory(file, singleFileTask);
}
else {
var parentPath_1 = file.relativePath.substring(0, pos + 1);
var existsTask = existsTaskMap.get(parentPath_1);
if (!existsTask) {
existsTask = _this.taskQueue.concat(newTasks).find(function (tsk) {
return tsk.fileIDList.some(function (id) { var _a; return (_a = modules_1.FileStore.get(id)) === null || _a === void 0 ? void 0 : _a.relativePath.startsWith(parentPath_1); });
});
existsTask && existsTaskMap.set(parentPath_1, existsTask);
}
if (existsTask) {
var existsFile = existsTask.fileIDList.find(function (id) { var _a; return ((_a = modules_1.FileStore.get(id)) === null || _a === void 0 ? void 0 : _a.relativePath) === file.relativePath; });
if (!existsFile) {
existsTask.fileIDList.push(file.id);
existsTask.fileList.push(file);
existsTask.fileSize += file.size;
updateTasks.add(existsTask);
}
else {
shared_1.Logger.info('existsTask:', existsTask, 'existsFile:', existsFile);
}
}
else {
newTask = helpers_1.taskFactory(file, singleFileTask);
}
}
if (newTask) {
newTask.oss = (ossOptions === null || ossOptions === void 0 ? void 0 : ossOptions.enable) ? ossOptions === null || ossOptions === void 0 ? void 0 : ossOptions.provider : newTask.oss;
newTask.type = singleFileTask ? 'file' : newTask.type;
newTasks.push(newTask);
}
}), operators_1.last(), operators_1.concatMap(function () { var _a, _b; return (fileList.length ? rxjs_1.from(_this.hookWrap((_b = (_a = _this.options).filesAdded) === null || _b === void 0 ? void 0 : _b.call(_a, fileList))) : rxjs_1.of(null)); }), operators_1.concatMap(function () { var _a, _b; return (newTasks.length ? rxjs_1.from(_this.hookWrap((_b = (_a = _this.options).beforeTasksAdd) === null || _b === void 0 ? void 0 : _b.call(_a, newTasks))) : rxjs_1.of(null)); }), operators_1.tap(function () {
// 任务创建事件
newTasks.forEach(function (task) {
_this.emit(interface_1.EventType.TaskCreated, task);
_this.taskQueue.push(task);
});
// 任务更新事件
updateTasks.forEach(function (task) { return _this.emit(interface_1.EventType.TaskUpdate, task); });
}), operators_1.takeUntil(notifier))
.subscribe({
complete: function () {
subscriber.next(newTasks);
subscriber.complete();
console.timeEnd('generateTask');
},
error: function (e) { return subscriber.error(e); },
});
return function () {
notifier === null || notifier === void 0 ? void 0 : notifier.next();
notifier === null || notifier === void 0 ? void 0 : notifier.unsubscribe();
sub === null || sub === void 0 ? void 0 : sub.unsubscribe();
};
});
};
return Uploader;
}(Base_1.default));
exports.Uploader = Uploader;
//# sourceMappingURL=Uploader.js.map