patreon-dl 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 +422 -0
- package/bin/patreon-dl.js +5 -0
- package/dist/cli/CLIOptionValidator.d.ts +9 -0
- package/dist/cli/CLIOptionValidator.d.ts.map +1 -0
- package/dist/cli/CLIOptionValidator.js +85 -0
- package/dist/cli/CLIOptionValidator.js.map +1 -0
- package/dist/cli/CLIOptions.d.ts +20 -0
- package/dist/cli/CLIOptions.d.ts.map +1 -0
- package/dist/cli/CLIOptions.js +75 -0
- package/dist/cli/CLIOptions.js.map +1 -0
- package/dist/cli/CommandLineParser.d.ts +11 -0
- package/dist/cli/CommandLineParser.d.ts.map +1 -0
- package/dist/cli/CommandLineParser.js +212 -0
- package/dist/cli/CommandLineParser.js.map +1 -0
- package/dist/cli/ConfigFileParser.d.ts +9 -0
- package/dist/cli/ConfigFileParser.d.ts.map +1 -0
- package/dist/cli/ConfigFileParser.js +163 -0
- package/dist/cli/ConfigFileParser.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +162 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/downloaders/Bootstrap.d.ts +29 -0
- package/dist/downloaders/Bootstrap.d.ts.map +1 -0
- package/dist/downloaders/Bootstrap.js +51 -0
- package/dist/downloaders/Bootstrap.js.map +1 -0
- package/dist/downloaders/Downloader.d.ts +59 -0
- package/dist/downloaders/Downloader.d.ts.map +1 -0
- package/dist/downloaders/Downloader.js +357 -0
- package/dist/downloaders/Downloader.js.map +1 -0
- package/dist/downloaders/DownloaderEvent.d.ts +47 -0
- package/dist/downloaders/DownloaderEvent.d.ts.map +1 -0
- package/dist/downloaders/DownloaderEvent.js +6 -0
- package/dist/downloaders/DownloaderEvent.js.map +1 -0
- package/dist/downloaders/DownloaderOptions.d.ts +39 -0
- package/dist/downloaders/DownloaderOptions.d.ts.map +1 -0
- package/dist/downloaders/DownloaderOptions.js +69 -0
- package/dist/downloaders/DownloaderOptions.js.map +1 -0
- package/dist/downloaders/PostDownloader.d.ts +8 -0
- package/dist/downloaders/PostDownloader.d.ts.map +1 -0
- package/dist/downloaders/PostDownloader.js +428 -0
- package/dist/downloaders/PostDownloader.js.map +1 -0
- package/dist/downloaders/ProductDownloader.d.ts +8 -0
- package/dist/downloaders/ProductDownloader.d.ts.map +1 -0
- package/dist/downloaders/ProductDownloader.js +171 -0
- package/dist/downloaders/ProductDownloader.js.map +1 -0
- package/dist/downloaders/cache/StatusCache.d.ts +43 -0
- package/dist/downloaders/cache/StatusCache.d.ts.map +1 -0
- package/dist/downloaders/cache/StatusCache.js +206 -0
- package/dist/downloaders/cache/StatusCache.js.map +1 -0
- package/dist/downloaders/index.d.ts +7 -0
- package/dist/downloaders/index.d.ts.map +1 -0
- package/dist/downloaders/index.js +6 -0
- package/dist/downloaders/index.js.map +1 -0
- package/dist/downloaders/task/DownloadTask.d.ts +89 -0
- package/dist/downloaders/task/DownloadTask.d.ts.map +1 -0
- package/dist/downloaders/task/DownloadTask.js +240 -0
- package/dist/downloaders/task/DownloadTask.js.map +1 -0
- package/dist/downloaders/task/DownloadTaskBatch.d.ts +45 -0
- package/dist/downloaders/task/DownloadTaskBatch.d.ts.map +1 -0
- package/dist/downloaders/task/DownloadTaskBatch.js +195 -0
- package/dist/downloaders/task/DownloadTaskBatch.js.map +1 -0
- package/dist/downloaders/task/DownloadTaskBatchEvent.d.ts +32 -0
- package/dist/downloaders/task/DownloadTaskBatchEvent.d.ts.map +1 -0
- package/dist/downloaders/task/DownloadTaskBatchEvent.js +2 -0
- package/dist/downloaders/task/DownloadTaskBatchEvent.js.map +1 -0
- package/dist/downloaders/task/DownloadTaskFactory.d.ts +20 -0
- package/dist/downloaders/task/DownloadTaskFactory.d.ts.map +1 -0
- package/dist/downloaders/task/DownloadTaskFactory.js +177 -0
- package/dist/downloaders/task/DownloadTaskFactory.js.map +1 -0
- package/dist/downloaders/task/FFmpegDownloadTask.d.ts +27 -0
- package/dist/downloaders/task/FFmpegDownloadTask.d.ts.map +1 -0
- package/dist/downloaders/task/FFmpegDownloadTask.js +206 -0
- package/dist/downloaders/task/FFmpegDownloadTask.js.map +1 -0
- package/dist/downloaders/task/FetcherDownloadTask.d.ts +21 -0
- package/dist/downloaders/task/FetcherDownloadTask.d.ts.map +1 -0
- package/dist/downloaders/task/FetcherDownloadTask.js +213 -0
- package/dist/downloaders/task/FetcherDownloadTask.js.map +1 -0
- package/dist/downloaders/task/index.d.ts +4 -0
- package/dist/downloaders/task/index.d.ts.map +1 -0
- package/dist/downloaders/task/index.js +3 -0
- package/dist/downloaders/task/index.js.map +1 -0
- package/dist/downloaders/templates/CampaignInfo.d.ts +3 -0
- package/dist/downloaders/templates/CampaignInfo.d.ts.map +1 -0
- package/dist/downloaders/templates/CampaignInfo.js +58 -0
- package/dist/downloaders/templates/CampaignInfo.js.map +1 -0
- package/dist/downloaders/templates/PostInfo.d.ts +4 -0
- package/dist/downloaders/templates/PostInfo.d.ts.map +1 -0
- package/dist/downloaders/templates/PostInfo.js +45 -0
- package/dist/downloaders/templates/PostInfo.js.map +1 -0
- package/dist/downloaders/templates/ProductInfo.d.ts +3 -0
- package/dist/downloaders/templates/ProductInfo.d.ts.map +1 -0
- package/dist/downloaders/templates/ProductInfo.js +20 -0
- package/dist/downloaders/templates/ProductInfo.js.map +1 -0
- package/dist/entities/Attachment.d.ts +7 -0
- package/dist/entities/Attachment.d.ts.map +1 -0
- package/dist/entities/Attachment.js +2 -0
- package/dist/entities/Attachment.js.map +1 -0
- package/dist/entities/Campaign.d.ts +19 -0
- package/dist/entities/Campaign.d.ts.map +1 -0
- package/dist/entities/Campaign.js +2 -0
- package/dist/entities/Campaign.js.map +1 -0
- package/dist/entities/Downloadable.d.ts +6 -0
- package/dist/entities/Downloadable.d.ts.map +1 -0
- package/dist/entities/Downloadable.js +5 -0
- package/dist/entities/Downloadable.js.map +1 -0
- package/dist/entities/MediaItem.d.ts +95 -0
- package/dist/entities/MediaItem.d.ts.map +1 -0
- package/dist/entities/MediaItem.js +2 -0
- package/dist/entities/MediaItem.js.map +1 -0
- package/dist/entities/Post.d.ts +87 -0
- package/dist/entities/Post.d.ts.map +1 -0
- package/dist/entities/Post.js +2 -0
- package/dist/entities/Post.js.map +1 -0
- package/dist/entities/Product.d.ts +17 -0
- package/dist/entities/Product.d.ts.map +1 -0
- package/dist/entities/Product.js +2 -0
- package/dist/entities/Product.js.map +1 -0
- package/dist/entities/Reward.d.ts +14 -0
- package/dist/entities/Reward.d.ts.map +1 -0
- package/dist/entities/Reward.js +2 -0
- package/dist/entities/Reward.js.map +1 -0
- package/dist/entities/User.d.ts +15 -0
- package/dist/entities/User.d.ts.map +1 -0
- package/dist/entities/User.js +2 -0
- package/dist/entities/User.js.map +1 -0
- package/dist/entities/index.d.ts +9 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +6 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/PageParser.d.ts +6 -0
- package/dist/parsers/PageParser.d.ts.map +1 -0
- package/dist/parsers/PageParser.js +23 -0
- package/dist/parsers/PageParser.js.map +1 -0
- package/dist/parsers/Parser.d.ts +43 -0
- package/dist/parsers/Parser.d.ts.map +1 -0
- package/dist/parsers/Parser.js +439 -0
- package/dist/parsers/Parser.js.map +1 -0
- package/dist/parsers/PostParser.d.ts +7 -0
- package/dist/parsers/PostParser.d.ts.map +1 -0
- package/dist/parsers/PostParser.js +259 -0
- package/dist/parsers/PostParser.js.map +1 -0
- package/dist/parsers/ProductParser.d.ts +7 -0
- package/dist/parsers/ProductParser.d.ts.map +1 -0
- package/dist/parsers/ProductParser.js +70 -0
- package/dist/parsers/ProductParser.js.map +1 -0
- package/dist/utils/AttachmentFilenameResolver.d.ts +9 -0
- package/dist/utils/AttachmentFilenameResolver.d.ts.map +1 -0
- package/dist/utils/AttachmentFilenameResolver.js +73 -0
- package/dist/utils/AttachmentFilenameResolver.js.map +1 -0
- package/dist/utils/FSHelper.d.ts +57 -0
- package/dist/utils/FSHelper.d.ts.map +1 -0
- package/dist/utils/FSHelper.js +214 -0
- package/dist/utils/FSHelper.js.map +1 -0
- package/dist/utils/Fetcher.d.ts +45 -0
- package/dist/utils/Fetcher.d.ts.map +1 -0
- package/dist/utils/Fetcher.js +192 -0
- package/dist/utils/Fetcher.js.map +1 -0
- package/dist/utils/FetcherProgressMonitor.d.ts +18 -0
- package/dist/utils/FetcherProgressMonitor.d.ts.map +1 -0
- package/dist/utils/FetcherProgressMonitor.js +56 -0
- package/dist/utils/FetcherProgressMonitor.js.map +1 -0
- package/dist/utils/FilenameFormatHelper.d.ts +44 -0
- package/dist/utils/FilenameFormatHelper.d.ts.map +1 -0
- package/dist/utils/FilenameFormatHelper.js +98 -0
- package/dist/utils/FilenameFormatHelper.js.map +1 -0
- package/dist/utils/FllenameResolver.d.ts +20 -0
- package/dist/utils/FllenameResolver.d.ts.map +1 -0
- package/dist/utils/FllenameResolver.js +55 -0
- package/dist/utils/FllenameResolver.js.map +1 -0
- package/dist/utils/Formatter.d.ts +21 -0
- package/dist/utils/Formatter.d.ts.map +1 -0
- package/dist/utils/Formatter.js +112 -0
- package/dist/utils/Formatter.js.map +1 -0
- package/dist/utils/MediaFilenameResolver.d.ts +9 -0
- package/dist/utils/MediaFilenameResolver.d.ts.map +1 -0
- package/dist/utils/MediaFilenameResolver.js +90 -0
- package/dist/utils/MediaFilenameResolver.js.map +1 -0
- package/dist/utils/Misc.d.ts +14 -0
- package/dist/utils/Misc.d.ts.map +1 -0
- package/dist/utils/Misc.js +4 -0
- package/dist/utils/Misc.js.map +1 -0
- package/dist/utils/ObjectHelper.d.ts +4 -0
- package/dist/utils/ObjectHelper.d.ts.map +1 -0
- package/dist/utils/ObjectHelper.js +30 -0
- package/dist/utils/ObjectHelper.js.map +1 -0
- package/dist/utils/PackageInfo.d.ts +10 -0
- package/dist/utils/PackageInfo.d.ts.map +1 -0
- package/dist/utils/PackageInfo.js +33 -0
- package/dist/utils/PackageInfo.js.map +1 -0
- package/dist/utils/URLHelper.d.ts +40 -0
- package/dist/utils/URLHelper.d.ts.map +1 -0
- package/dist/utils/URLHelper.js +192 -0
- package/dist/utils/URLHelper.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logging/ChainLogger.d.ts +11 -0
- package/dist/utils/logging/ChainLogger.d.ts.map +1 -0
- package/dist/utils/logging/ChainLogger.js +50 -0
- package/dist/utils/logging/ChainLogger.js.map +1 -0
- package/dist/utils/logging/ConsoleLogger.d.ts +31 -0
- package/dist/utils/logging/ConsoleLogger.d.ts.map +1 -0
- package/dist/utils/logging/ConsoleLogger.js +126 -0
- package/dist/utils/logging/ConsoleLogger.js.map +1 -0
- package/dist/utils/logging/FileLogger.d.ts +26 -0
- package/dist/utils/logging/FileLogger.d.ts.map +1 -0
- package/dist/utils/logging/FileLogger.js +147 -0
- package/dist/utils/logging/FileLogger.js.map +1 -0
- package/dist/utils/logging/Logger.d.ts +12 -0
- package/dist/utils/logging/Logger.d.ts.map +1 -0
- package/dist/utils/logging/Logger.js +15 -0
- package/dist/utils/logging/Logger.js.map +1 -0
- package/dist/utils/logging/index.d.ts +7 -0
- package/dist/utils/logging/index.d.ts.map +1 -0
- package/dist/utils/logging/index.js +7 -0
- package/dist/utils/logging/index.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _DownloadTask_instances, _a, _DownloadTask_idCounter, _DownloadTask_id, _DownloadTask_src, _DownloadTask_maxRetries, _DownloadTask_retryCount, _DownloadTask_resolvedDestPath, _DownloadTask_srcEntity, _DownloadTask_callbacks, _DownloadTask_logger, _DownloadTask_lastProgress, _DownloadTask_status, _DownloadTask_startPromise, _DownloadTask_startingCallback, _DownloadTask_abortPromise, _DownloadTask_notifyEnd;
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import { commonLog } from '../../utils/logging/Logger.js';
|
|
15
|
+
export class DownloadTaskError extends Error {
|
|
16
|
+
constructor(message, task, cause) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'DownloadTaskError';
|
|
19
|
+
this.task = task;
|
|
20
|
+
this.cause = cause;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const ENDED_STATUSES = [
|
|
24
|
+
'error',
|
|
25
|
+
'completed',
|
|
26
|
+
'aborted',
|
|
27
|
+
'skipped'
|
|
28
|
+
];
|
|
29
|
+
export default class DownloadTask {
|
|
30
|
+
constructor(params) {
|
|
31
|
+
var _b, _c;
|
|
32
|
+
_DownloadTask_instances.add(this);
|
|
33
|
+
_DownloadTask_id.set(this, void 0);
|
|
34
|
+
_DownloadTask_src.set(this, void 0);
|
|
35
|
+
_DownloadTask_maxRetries.set(this, void 0);
|
|
36
|
+
_DownloadTask_retryCount.set(this, void 0);
|
|
37
|
+
_DownloadTask_resolvedDestPath.set(this, void 0);
|
|
38
|
+
_DownloadTask_srcEntity.set(this, void 0);
|
|
39
|
+
_DownloadTask_callbacks.set(this, void 0);
|
|
40
|
+
_DownloadTask_logger.set(this, void 0);
|
|
41
|
+
_DownloadTask_lastProgress.set(this, void 0);
|
|
42
|
+
_DownloadTask_status.set(this, void 0);
|
|
43
|
+
_DownloadTask_startPromise.set(this, void 0);
|
|
44
|
+
_DownloadTask_startingCallback.set(this, void 0);
|
|
45
|
+
_DownloadTask_abortPromise.set(this, void 0);
|
|
46
|
+
__classPrivateFieldSet(this, _DownloadTask_id, __classPrivateFieldGet(DownloadTask, _a, "f", _DownloadTask_idCounter), "f");
|
|
47
|
+
__classPrivateFieldSet(this, _DownloadTask_src, params.src, "f");
|
|
48
|
+
__classPrivateFieldSet(this, _DownloadTask_maxRetries, params.maxRetries, "f");
|
|
49
|
+
__classPrivateFieldSet(this, _DownloadTask_retryCount, 0, "f");
|
|
50
|
+
__classPrivateFieldSet(this, _DownloadTask_resolvedDestPath, null, "f");
|
|
51
|
+
__classPrivateFieldSet(this, _DownloadTask_srcEntity, params.srcEntity, "f");
|
|
52
|
+
__classPrivateFieldSet(this, _DownloadTask_callbacks, params.callbacks, "f");
|
|
53
|
+
__classPrivateFieldSet(this, _DownloadTask_logger, params.logger, "f");
|
|
54
|
+
__classPrivateFieldSet(this, _DownloadTask_lastProgress, null, "f");
|
|
55
|
+
__classPrivateFieldSet(this, _DownloadTask_status, 'pending', "f");
|
|
56
|
+
__classPrivateFieldSet(this, _DownloadTask_startPromise, null, "f");
|
|
57
|
+
__classPrivateFieldSet(this, _DownloadTask_startingCallback, null, "f");
|
|
58
|
+
__classPrivateFieldSet(this, _DownloadTask_abortPromise, null, "f");
|
|
59
|
+
__classPrivateFieldSet(_b = DownloadTask, _a, (_c = __classPrivateFieldGet(_b, _a, "f", _DownloadTask_idCounter), _c++, _c), "f", _DownloadTask_idCounter);
|
|
60
|
+
}
|
|
61
|
+
start() {
|
|
62
|
+
if (__classPrivateFieldGet(this, _DownloadTask_startPromise, "f")) {
|
|
63
|
+
return __classPrivateFieldGet(this, _DownloadTask_startPromise, "f");
|
|
64
|
+
}
|
|
65
|
+
if (this.hasEnded()) {
|
|
66
|
+
// Cannot start an ended task
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
__classPrivateFieldSet(this, _DownloadTask_startPromise, new Promise(async (resolve) => {
|
|
70
|
+
var _b;
|
|
71
|
+
__classPrivateFieldSet(this, _DownloadTask_startingCallback, () => {
|
|
72
|
+
__classPrivateFieldSet(this, _DownloadTask_startPromise, null, "f");
|
|
73
|
+
__classPrivateFieldSet(this, _DownloadTask_startingCallback, null, "f");
|
|
74
|
+
resolve();
|
|
75
|
+
}, "f");
|
|
76
|
+
await this.doStart();
|
|
77
|
+
// Retry on error, up to `maxRetries`
|
|
78
|
+
while (__classPrivateFieldGet(this, _DownloadTask_status, "f") === 'pending-retry' && __classPrivateFieldGet(this, _DownloadTask_retryCount, "f") < __classPrivateFieldGet(this, _DownloadTask_maxRetries, "f")) {
|
|
79
|
+
__classPrivateFieldSet(this, _DownloadTask_retryCount, (_b = __classPrivateFieldGet(this, _DownloadTask_retryCount, "f"), _b++, _b), "f");
|
|
80
|
+
await this.doStart();
|
|
81
|
+
}
|
|
82
|
+
}), "f");
|
|
83
|
+
return __classPrivateFieldGet(this, _DownloadTask_startPromise, "f");
|
|
84
|
+
}
|
|
85
|
+
abort() {
|
|
86
|
+
if (__classPrivateFieldGet(this, _DownloadTask_abortPromise, "f")) {
|
|
87
|
+
return __classPrivateFieldGet(this, _DownloadTask_abortPromise, "f");
|
|
88
|
+
}
|
|
89
|
+
__classPrivateFieldSet(this, _DownloadTask_abortPromise, new Promise(async (resolve) => {
|
|
90
|
+
if (this.isRunning()) {
|
|
91
|
+
await this.doAbort();
|
|
92
|
+
}
|
|
93
|
+
else if (__classPrivateFieldGet(this, _DownloadTask_status, "f") === 'pending' || __classPrivateFieldGet(this, _DownloadTask_status, "f") === 'pending-retry') {
|
|
94
|
+
this.notifyAbort();
|
|
95
|
+
}
|
|
96
|
+
resolve();
|
|
97
|
+
})
|
|
98
|
+
.finally(() => {
|
|
99
|
+
__classPrivateFieldSet(this, _DownloadTask_abortPromise, null, "f");
|
|
100
|
+
}), "f");
|
|
101
|
+
return __classPrivateFieldGet(this, _DownloadTask_abortPromise, "f");
|
|
102
|
+
}
|
|
103
|
+
getProgress() {
|
|
104
|
+
const progress = this.doGetProgress();
|
|
105
|
+
if (progress === undefined) {
|
|
106
|
+
return __classPrivateFieldGet(this, _DownloadTask_lastProgress, "f");
|
|
107
|
+
}
|
|
108
|
+
__classPrivateFieldSet(this, _DownloadTask_lastProgress, progress, "f");
|
|
109
|
+
return progress;
|
|
110
|
+
}
|
|
111
|
+
notifyStart() {
|
|
112
|
+
__classPrivateFieldSet(this, _DownloadTask_status, 'downloading', "f");
|
|
113
|
+
__classPrivateFieldSet(this, _DownloadTask_lastProgress, this.getProgress(), "f");
|
|
114
|
+
if (this.callbacks?.onStart) {
|
|
115
|
+
this.callbacks.onStart(this);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
notifyProgress(progress) {
|
|
119
|
+
__classPrivateFieldSet(this, _DownloadTask_lastProgress, progress, "f");
|
|
120
|
+
if (this.callbacks?.onProgress) {
|
|
121
|
+
this.callbacks.onProgress(this, progress);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
notifyComplete() {
|
|
125
|
+
__classPrivateFieldGet(this, _DownloadTask_instances, "m", _DownloadTask_notifyEnd).call(this, 'completed');
|
|
126
|
+
}
|
|
127
|
+
notifyAbort() {
|
|
128
|
+
__classPrivateFieldGet(this, _DownloadTask_instances, "m", _DownloadTask_notifyEnd).call(this, 'aborted');
|
|
129
|
+
}
|
|
130
|
+
notifySkip(reason) {
|
|
131
|
+
__classPrivateFieldGet(this, _DownloadTask_instances, "m", _DownloadTask_notifyEnd).call(this, 'skipped', reason);
|
|
132
|
+
}
|
|
133
|
+
notifyError(error) {
|
|
134
|
+
const msg = error instanceof Error ? error.message : error;
|
|
135
|
+
const err = new DownloadTaskError(msg, this);
|
|
136
|
+
if (error instanceof Error) {
|
|
137
|
+
err.cause = error;
|
|
138
|
+
}
|
|
139
|
+
const willRetry = __classPrivateFieldGet(this, _DownloadTask_retryCount, "f") < __classPrivateFieldGet(this, _DownloadTask_maxRetries, "f");
|
|
140
|
+
__classPrivateFieldGet(this, _DownloadTask_instances, "m", _DownloadTask_notifyEnd).call(this, 'error', err, willRetry);
|
|
141
|
+
}
|
|
142
|
+
isRunning() {
|
|
143
|
+
return this.status === 'downloading';
|
|
144
|
+
}
|
|
145
|
+
isAborting() {
|
|
146
|
+
return !!__classPrivateFieldGet(this, _DownloadTask_abortPromise, "f");
|
|
147
|
+
}
|
|
148
|
+
hasEnded() {
|
|
149
|
+
return ENDED_STATUSES.includes(__classPrivateFieldGet(this, _DownloadTask_status, "f"));
|
|
150
|
+
}
|
|
151
|
+
get id() {
|
|
152
|
+
return __classPrivateFieldGet(this, _DownloadTask_id, "f");
|
|
153
|
+
}
|
|
154
|
+
set id(value) {
|
|
155
|
+
__classPrivateFieldSet(this, _DownloadTask_id, value, "f");
|
|
156
|
+
}
|
|
157
|
+
get src() {
|
|
158
|
+
return __classPrivateFieldGet(this, _DownloadTask_src, "f");
|
|
159
|
+
}
|
|
160
|
+
get resolvedDestFilename() {
|
|
161
|
+
return __classPrivateFieldGet(this, _DownloadTask_resolvedDestPath, "f") ? path.basename(__classPrivateFieldGet(this, _DownloadTask_resolvedDestPath, "f")) : null;
|
|
162
|
+
}
|
|
163
|
+
get resolvedDestPath() {
|
|
164
|
+
return __classPrivateFieldGet(this, _DownloadTask_resolvedDestPath, "f");
|
|
165
|
+
}
|
|
166
|
+
set resolvedDestPath(value) {
|
|
167
|
+
__classPrivateFieldSet(this, _DownloadTask_resolvedDestPath, value, "f");
|
|
168
|
+
}
|
|
169
|
+
get srcEntity() {
|
|
170
|
+
return __classPrivateFieldGet(this, _DownloadTask_srcEntity, "f");
|
|
171
|
+
}
|
|
172
|
+
get maxRetries() {
|
|
173
|
+
return __classPrivateFieldGet(this, _DownloadTask_maxRetries, "f");
|
|
174
|
+
}
|
|
175
|
+
get retryCount() {
|
|
176
|
+
return __classPrivateFieldGet(this, _DownloadTask_retryCount, "f");
|
|
177
|
+
}
|
|
178
|
+
get status() {
|
|
179
|
+
return __classPrivateFieldGet(this, _DownloadTask_status, "f");
|
|
180
|
+
}
|
|
181
|
+
set status(value) {
|
|
182
|
+
__classPrivateFieldSet(this, _DownloadTask_status, value, "f");
|
|
183
|
+
}
|
|
184
|
+
get callbacks() {
|
|
185
|
+
return __classPrivateFieldGet(this, _DownloadTask_callbacks, "f");
|
|
186
|
+
}
|
|
187
|
+
setCallbacks(value) {
|
|
188
|
+
if (this.status !== 'pending') {
|
|
189
|
+
throw Error('You can only set callbacks of a pending task');
|
|
190
|
+
}
|
|
191
|
+
__classPrivateFieldSet(this, _DownloadTask_callbacks, value, "f");
|
|
192
|
+
}
|
|
193
|
+
log(level, ...msg) {
|
|
194
|
+
commonLog(__classPrivateFieldGet(this, _DownloadTask_logger, "f"), level, this.name, ...msg);
|
|
195
|
+
}
|
|
196
|
+
get logger() {
|
|
197
|
+
return __classPrivateFieldGet(this, _DownloadTask_logger, "f");
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
_a = DownloadTask, _DownloadTask_id = new WeakMap(), _DownloadTask_src = new WeakMap(), _DownloadTask_maxRetries = new WeakMap(), _DownloadTask_retryCount = new WeakMap(), _DownloadTask_resolvedDestPath = new WeakMap(), _DownloadTask_srcEntity = new WeakMap(), _DownloadTask_callbacks = new WeakMap(), _DownloadTask_logger = new WeakMap(), _DownloadTask_lastProgress = new WeakMap(), _DownloadTask_status = new WeakMap(), _DownloadTask_startPromise = new WeakMap(), _DownloadTask_startingCallback = new WeakMap(), _DownloadTask_abortPromise = new WeakMap(), _DownloadTask_instances = new WeakSet(), _DownloadTask_notifyEnd = function _DownloadTask_notifyEnd(status, ...cbPayload) {
|
|
201
|
+
__classPrivateFieldSet(this, _DownloadTask_status, status, "f");
|
|
202
|
+
let clearCallbacks = true;
|
|
203
|
+
let callStartingCallback = true;
|
|
204
|
+
switch (status) {
|
|
205
|
+
case 'completed':
|
|
206
|
+
if (this.callbacks?.onComplete) {
|
|
207
|
+
this.callbacks.onComplete(this);
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
case 'aborted':
|
|
211
|
+
if (this.callbacks?.onAbort) {
|
|
212
|
+
this.callbacks.onAbort(this);
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
case 'skipped':
|
|
216
|
+
if (this.callbacks?.onSkip) {
|
|
217
|
+
const [reason] = cbPayload;
|
|
218
|
+
this.callbacks.onSkip(this, reason);
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
221
|
+
case 'error':
|
|
222
|
+
const [err, willRetry] = cbPayload;
|
|
223
|
+
if (willRetry) {
|
|
224
|
+
__classPrivateFieldSet(this, _DownloadTask_status, 'pending-retry', "f");
|
|
225
|
+
clearCallbacks = false;
|
|
226
|
+
callStartingCallback = false;
|
|
227
|
+
}
|
|
228
|
+
if (this.callbacks?.onError) {
|
|
229
|
+
this.callbacks.onError(err, willRetry);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (__classPrivateFieldGet(this, _DownloadTask_startingCallback, "f") && callStartingCallback) {
|
|
233
|
+
__classPrivateFieldGet(this, _DownloadTask_startingCallback, "f").call(this);
|
|
234
|
+
}
|
|
235
|
+
if (clearCallbacks) {
|
|
236
|
+
__classPrivateFieldSet(this, _DownloadTask_callbacks, null, "f");
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
_DownloadTask_idCounter = { value: 0 };
|
|
240
|
+
//# sourceMappingURL=DownloadTask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DownloadTask.js","sourceRoot":"","sources":["../../../src/downloaders/task/DownloadTask.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\nimport { Downloadable } from '../../entities/Downloadable.js';\nimport Logger, { LogLevel, commonLog } from '../../utils/logging/Logger.js';\n\nexport class DownloadTaskError extends Error {\n task: IDownloadTask;\n cause?: Error;\n\n constructor(message: string, task: IDownloadTask, cause?: Error) {\n super(message);\n this.name = 'DownloadTaskError';\n this.task = task;\n this.cause = cause;\n }\n}\n\nexport type DownloadTaskSkipReason = {\n message: string;\n} & ({\n name: 'destFileExists';\n existingDestFilePath: string;\n} | {\n name: 'other';\n})\n\nexport interface DownloadProgress {\n destFilename: string;\n destFilePath: string;\n lengthUnit: string;\n length: number; // Measured in `lengthUnit`\n lengthDownloaded: number; // Measured in `lengthUnit`\n percent: number;\n sizeDownloaded: number; // Kb\n speed: number; // Kb/s\n}\n\nexport interface DownloadTaskParams<T extends Downloadable = Downloadable> {\n src: string;\n srcEntity: T,\n maxRetries: number;\n callbacks: DownloadTaskCallbacks | null;\n logger?: Logger | null;\n}\n\nexport interface DownloadTaskCallbacks {\n onStart: (task: DownloadTask) => void;\n onProgress: (task: DownloadTask, progress: DownloadProgress | null) => void;\n onComplete: (task: DownloadTask) => void;\n onAbort: (task: DownloadTask) => void;\n onSkip: (task: DownloadTask, reason: DownloadTaskSkipReason) => void;\n onError: (error: DownloadTaskError, willRetry: boolean) => void;\n onSpawn: (origin: DownloadTask, spawn: DownloadTask) => void;\n}\n\nexport type DownloadTaskStatus =\n 'pending' |\n 'pending-retry' | // Pending retry on error\n 'downloading' |\n 'error' |\n 'completed' |\n 'aborted' |\n 'skipped';\n\nconst ENDED_STATUSES: DownloadTaskStatus[] = [\n 'error',\n 'completed',\n 'aborted',\n 'skipped'\n];\n\nexport interface IDownloadTask {\n id: number;\n src: string;\n srcEntity: Downloadable;\n retryCount: number;\n resolvedDestFilename: string | null;\n resolvedDestPath: string | null;\n getProgress: () => DownloadProgress | null;\n}\n\nexport default abstract class DownloadTask<T extends Downloadable = Downloadable> implements IDownloadTask {\n\n protected abstract name: string;\n\n static #idCounter = 0;\n\n #id: number;\n #src: string;\n #maxRetries: number;\n #retryCount: number;\n #resolvedDestPath: string | null;\n #srcEntity: T;\n #callbacks: DownloadTaskCallbacks | null;\n #logger?: Logger | null;\n #lastProgress: DownloadProgress | null;\n #status: DownloadTaskStatus;\n\n #startPromise: Promise<void> | null;\n #startingCallback: (() => void) | null;\n #abortPromise: Promise<void> | null;\n\n constructor(params: DownloadTaskParams<T>) {\n this.#id = DownloadTask.#idCounter;\n this.#src = params.src;\n this.#maxRetries = params.maxRetries;\n this.#retryCount = 0;\n this.#resolvedDestPath = null;\n this.#srcEntity = params.srcEntity;\n this.#callbacks = params.callbacks;\n this.#logger = params.logger;\n this.#lastProgress = null;\n this.#status = 'pending';\n this.#startPromise = null;\n this.#startingCallback = null;\n this.#abortPromise = null;\n\n DownloadTask.#idCounter++;\n }\n\n protected abstract doStart(): Promise<void>;\n protected abstract doAbort(): Promise<void>;\n protected abstract doDestroy(): Promise<void>;\n protected abstract doGetProgress(): DownloadProgress | null | undefined;\n\n start() {\n if (this.#startPromise) {\n return this.#startPromise;\n }\n\n if (this.hasEnded()) {\n // Cannot start an ended task\n return Promise.resolve();\n }\n\n this.#startPromise = new Promise<void>(async (resolve) => {\n this.#startingCallback = () => {\n this.#startPromise = null;\n this.#startingCallback = null;\n resolve();\n };\n\n await this.doStart();\n\n // Retry on error, up to `maxRetries`\n while (this.#status === 'pending-retry' && this.#retryCount < this.#maxRetries) {\n this.#retryCount++;\n await this.doStart();\n }\n });\n\n return this.#startPromise;\n }\n\n abort() {\n if (this.#abortPromise) {\n return this.#abortPromise;\n }\n\n this.#abortPromise = new Promise<void>(async (resolve) => {\n if (this.isRunning()) {\n await this.doAbort();\n }\n else if (this.#status === 'pending' || this.#status === 'pending-retry') {\n this.notifyAbort();\n }\n resolve();\n })\n .finally(() => {\n this.#abortPromise = null;\n });\n\n return this.#abortPromise;\n }\n\n getProgress() {\n const progress = this.doGetProgress();\n if (progress === undefined) {\n return this.#lastProgress;\n }\n this.#lastProgress = progress;\n return progress;\n }\n\n protected notifyStart() {\n this.#status = 'downloading';\n this.#lastProgress = this.getProgress();\n if (this.callbacks?.onStart) {\n this.callbacks.onStart(this);\n }\n }\n\n protected notifyProgress(progress: DownloadProgress | null) {\n this.#lastProgress = progress;\n if (this.callbacks?.onProgress) {\n this.callbacks.onProgress(this, progress);\n }\n }\n\n protected notifyComplete() {\n this.#notifyEnd('completed');\n }\n\n protected notifyAbort() {\n this.#notifyEnd('aborted');\n }\n\n protected notifySkip(reason: DownloadTaskSkipReason) {\n this.#notifyEnd('skipped', reason);\n }\n\n protected notifyError(error: any) {\n const msg = error instanceof Error ? error.message : error;\n const err = new DownloadTaskError(msg, this);\n if (error instanceof Error) {\n err.cause = error;\n }\n const willRetry = this.#retryCount < this.#maxRetries;\n this.#notifyEnd('error', err, willRetry);\n }\n\n #notifyEnd(status: 'error', err: DownloadTaskError, willRetry: boolean): void;\n #notifyEnd(status: 'skipped', reason: DownloadTaskSkipReason): void;\n #notifyEnd(status: 'aborted'): void;\n #notifyEnd(status: 'completed'): void;\n #notifyEnd(status: 'completed' | 'aborted' | 'skipped' | 'error', ...cbPayload: any[]) {\n this.#status = status;\n let clearCallbacks = true;\n let callStartingCallback = true;\n switch (status) {\n case 'completed':\n if (this.callbacks?.onComplete) {\n this.callbacks.onComplete(this);\n }\n break;\n case 'aborted':\n if (this.callbacks?.onAbort) {\n this.callbacks.onAbort(this);\n }\n break;\n case 'skipped':\n if (this.callbacks?.onSkip) {\n const [ reason ] = cbPayload;\n this.callbacks.onSkip(this, reason);\n }\n break;\n case 'error':\n const [ err, willRetry ] = cbPayload;\n if (willRetry) {\n this.#status = 'pending-retry';\n clearCallbacks = false;\n callStartingCallback = false;\n }\n if (this.callbacks?.onError) {\n this.callbacks.onError(err, willRetry);\n }\n }\n\n if (this.#startingCallback && callStartingCallback) {\n this.#startingCallback();\n }\n\n if (clearCallbacks) {\n this.#callbacks = null;\n }\n }\n\n isRunning() {\n return this.status === 'downloading';\n }\n\n isAborting() {\n return !!this.#abortPromise;\n }\n\n hasEnded() {\n return ENDED_STATUSES.includes(this.#status);\n }\n\n get id() {\n return this.#id;\n }\n\n set id(value: number) {\n this.#id = value;\n }\n\n get src() {\n return this.#src;\n }\n\n get resolvedDestFilename() {\n return this.#resolvedDestPath ? path.basename(this.#resolvedDestPath) : null;\n }\n\n get resolvedDestPath() {\n return this.#resolvedDestPath;\n }\n\n protected set resolvedDestPath(value: string | null) {\n this.#resolvedDestPath = value;\n }\n\n get srcEntity() {\n return this.#srcEntity;\n }\n\n protected get maxRetries() {\n return this.#maxRetries;\n }\n\n get retryCount() {\n return this.#retryCount;\n }\n\n get status() {\n return this.#status;\n }\n\n protected set status(value: DownloadTaskStatus) {\n this.#status = value;\n }\n\n protected get callbacks() {\n return this.#callbacks;\n }\n\n setCallbacks(value: DownloadTaskCallbacks | null) {\n if (this.status !== 'pending') {\n throw Error('You can only set callbacks of a pending task');\n }\n this.#callbacks = value;\n }\n\n protected log(level: LogLevel, ...msg: Array<any>) {\n commonLog(this.#logger, level, this.name, ...msg);\n }\n\n protected get logger() {\n return this.#logger;\n }\n}\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import DownloadTask, { DownloadTaskStatus, IDownloadTask } from './DownloadTask.js';
|
|
3
|
+
import Fetcher from '../../utils/Fetcher.js';
|
|
4
|
+
import EventEmitter from 'events';
|
|
5
|
+
import { DownloadTaskBatchEvent, DownloadTaskBatchEventPayloadOf } from './DownloadTaskBatchEvent.js';
|
|
6
|
+
export interface DownloadTaskBatchParams {
|
|
7
|
+
name: string;
|
|
8
|
+
fetcher: Fetcher;
|
|
9
|
+
limiter: {
|
|
10
|
+
maxConcurrent: number;
|
|
11
|
+
minTime: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface IDownloadTaskBatch extends EventEmitter {
|
|
15
|
+
id: number;
|
|
16
|
+
name: string;
|
|
17
|
+
allTasksEnded: () => boolean;
|
|
18
|
+
hasErrors: () => boolean;
|
|
19
|
+
isDestroyed: () => boolean;
|
|
20
|
+
isAborted: () => boolean;
|
|
21
|
+
getTasks: (status?: DownloadTaskStatus) => IDownloadTask[];
|
|
22
|
+
on<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;
|
|
23
|
+
once<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;
|
|
24
|
+
off<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;
|
|
25
|
+
}
|
|
26
|
+
export default class DownloadTaskBatch extends EventEmitter implements IDownloadTaskBatch {
|
|
27
|
+
#private;
|
|
28
|
+
constructor(params: DownloadTaskBatchParams);
|
|
29
|
+
addTasks(tasks: DownloadTask[]): void;
|
|
30
|
+
start(): Promise<void>;
|
|
31
|
+
destroy(): Promise<void>;
|
|
32
|
+
allTasksEnded(): boolean;
|
|
33
|
+
hasErrors(): boolean;
|
|
34
|
+
isDestroyed(): boolean;
|
|
35
|
+
isAborted(): boolean;
|
|
36
|
+
getTasks(status?: DownloadTaskStatus): DownloadTask<import("../../index.js").Downloadable>[];
|
|
37
|
+
abort(): Promise<void>;
|
|
38
|
+
get id(): number;
|
|
39
|
+
get name(): string;
|
|
40
|
+
on<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;
|
|
41
|
+
once<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;
|
|
42
|
+
off<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;
|
|
43
|
+
emit<T extends DownloadTaskBatchEvent>(event: T, args: DownloadTaskBatchEventPayloadOf<T>): boolean;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=DownloadTaskBatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DownloadTaskBatch.d.ts","sourceRoot":"","sources":["../../../src/downloaders/task/DownloadTaskBatch.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,EAAE,EAAuC,kBAAkB,EAA0B,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACjJ,OAAO,OAAO,MAAM,wBAAwB,CAAC;AAC7C,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,EAAE,sBAAsB,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AAEtG,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAA;CACF;AAED,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,OAAO,CAAC;IAC7B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,WAAW,EAAE,MAAM,OAAO,CAAC;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,kBAAkB,KAAK,aAAa,EAAE,CAAC;IAC3D,EAAE,CAAC,CAAC,SAAS,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACnH,IAAI,CAAC,CAAC,SAAS,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACrH,GAAG,CAAC,CAAC,SAAS,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;CACrH;AAED,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,YAAa,YAAW,kBAAkB;;gBAgB3E,MAAM,EAAE,uBAAuB;IAwB3C,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE;IA2C9B,KAAK;IAyCC,OAAO;IAiBb,aAAa;IAIb,SAAS;IAIT,WAAW;IAIX,SAAS;IAIT,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB;IAO9B,KAAK;IAoBX,IAAI,EAAE,WAEL;IAED,IAAI,IAAI,WAEP;IAED,EAAE,CAAC,CAAC,SAAS,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAKlH,IAAI,CAAC,CAAC,SAAS,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAKpH,GAAG,CAAC,CAAC,SAAS,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAKnH,IAAI,CAAC,CAAC,SAAS,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,+BAA+B,CAAC,CAAC,CAAC,GAAG,OAAO;CAIpG"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _DownloadTaskBatch_instances, _a, _DownloadTaskBatch_idCounter, _DownloadTaskBatch_id, _DownloadTaskBatch_taskIdCounter, _DownloadTaskBatch_name, _DownloadTaskBatch_tasks, _DownloadTaskBatch_limiter, _DownloadTaskBatch_startPromise, _DownloadTaskBatch_startingCallback, _DownloadTaskBatch_abortPromise, _DownloadTaskBatch_destroyPromise, _DownloadTaskBatch_destroyed, _DownloadTaskBatch_aborted, _DownloadTaskBatch_reassignTaskId, _DownloadTaskBatch_checkAndCallbackBatchComplete;
|
|
13
|
+
import Bottleneck from 'bottleneck';
|
|
14
|
+
import EventEmitter from 'events';
|
|
15
|
+
export default class DownloadTaskBatch extends EventEmitter {
|
|
16
|
+
constructor(params) {
|
|
17
|
+
var _b, _c;
|
|
18
|
+
super();
|
|
19
|
+
_DownloadTaskBatch_instances.add(this);
|
|
20
|
+
_DownloadTaskBatch_id.set(this, void 0);
|
|
21
|
+
_DownloadTaskBatch_taskIdCounter.set(this, void 0);
|
|
22
|
+
_DownloadTaskBatch_name.set(this, void 0);
|
|
23
|
+
_DownloadTaskBatch_tasks.set(this, void 0);
|
|
24
|
+
_DownloadTaskBatch_limiter.set(this, void 0);
|
|
25
|
+
_DownloadTaskBatch_startPromise.set(this, void 0);
|
|
26
|
+
_DownloadTaskBatch_startingCallback.set(this, void 0);
|
|
27
|
+
_DownloadTaskBatch_abortPromise.set(this, void 0);
|
|
28
|
+
_DownloadTaskBatch_destroyPromise.set(this, void 0);
|
|
29
|
+
_DownloadTaskBatch_destroyed.set(this, void 0);
|
|
30
|
+
_DownloadTaskBatch_aborted.set(this, void 0);
|
|
31
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_limiter, new Bottleneck({
|
|
32
|
+
maxConcurrent: params.limiter.maxConcurrent,
|
|
33
|
+
minTime: params.limiter.minTime
|
|
34
|
+
}), "f");
|
|
35
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_id, __classPrivateFieldGet(DownloadTaskBatch, _a, "f", _DownloadTaskBatch_idCounter), "f");
|
|
36
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_taskIdCounter, 0, "f");
|
|
37
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_name, params.name, "f");
|
|
38
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_tasks, [], "f");
|
|
39
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_startPromise, null, "f");
|
|
40
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_startingCallback, null, "f");
|
|
41
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_abortPromise, null, "f");
|
|
42
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_destroyPromise, null, "f");
|
|
43
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_destroyed, false, "f");
|
|
44
|
+
__classPrivateFieldSet(_b = DownloadTaskBatch, _a, (_c = __classPrivateFieldGet(_b, _a, "f", _DownloadTaskBatch_idCounter), _c++, _c), "f", _DownloadTaskBatch_idCounter);
|
|
45
|
+
}
|
|
46
|
+
addTasks(tasks) {
|
|
47
|
+
for (const task of tasks) {
|
|
48
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_instances, "m", _DownloadTaskBatch_reassignTaskId).call(this, task);
|
|
49
|
+
task.setCallbacks({
|
|
50
|
+
onStart: (task) => {
|
|
51
|
+
this.emit('taskStart', { task });
|
|
52
|
+
},
|
|
53
|
+
onProgress: (task, progress) => {
|
|
54
|
+
this.emit('taskProgress', { task, progress });
|
|
55
|
+
},
|
|
56
|
+
onComplete: (task) => {
|
|
57
|
+
this.emit('taskComplete', { task });
|
|
58
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_instances, "m", _DownloadTaskBatch_checkAndCallbackBatchComplete).call(this);
|
|
59
|
+
},
|
|
60
|
+
onAbort: (task) => {
|
|
61
|
+
this.emit('taskAbort', { task });
|
|
62
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_instances, "m", _DownloadTaskBatch_checkAndCallbackBatchComplete).call(this);
|
|
63
|
+
},
|
|
64
|
+
onSkip: (task, reason) => {
|
|
65
|
+
this.emit('taskSkip', { task, reason });
|
|
66
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_instances, "m", _DownloadTaskBatch_checkAndCallbackBatchComplete).call(this);
|
|
67
|
+
},
|
|
68
|
+
onError: (error, willRetry) => {
|
|
69
|
+
this.emit('taskError', { error, willRetry });
|
|
70
|
+
if (!willRetry) {
|
|
71
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_instances, "m", _DownloadTaskBatch_checkAndCallbackBatchComplete).call(this);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
onSpawn: (origin, spawn) => {
|
|
75
|
+
if (!this.isAborted() && !this.isDestroyed()) {
|
|
76
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_instances, "m", _DownloadTaskBatch_reassignTaskId).call(this, spawn);
|
|
77
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_tasks, "f").push(spawn);
|
|
78
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_limiter, "f").schedule(() => spawn.start());
|
|
79
|
+
this.emit('taskSpawn', { origin, spawn });
|
|
80
|
+
spawn.start();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_tasks, "f").push(...tasks);
|
|
86
|
+
}
|
|
87
|
+
start() {
|
|
88
|
+
if (this.isAborted()) {
|
|
89
|
+
throw Error('Cannot start aborted task batch');
|
|
90
|
+
}
|
|
91
|
+
if (this.isDestroyed()) {
|
|
92
|
+
throw Error('Cannot start a destroyed task batch');
|
|
93
|
+
}
|
|
94
|
+
if (__classPrivateFieldGet(this, _DownloadTaskBatch_startPromise, "f")) {
|
|
95
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_startPromise, "f");
|
|
96
|
+
}
|
|
97
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_startPromise, new Promise((resolve) => {
|
|
98
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_startingCallback, () => {
|
|
99
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_startPromise, null, "f");
|
|
100
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_startingCallback, null, "f");
|
|
101
|
+
resolve();
|
|
102
|
+
}, "f");
|
|
103
|
+
if (__classPrivateFieldGet(this, _DownloadTaskBatch_tasks, "f").length > 0) {
|
|
104
|
+
for (const task of __classPrivateFieldGet(this, _DownloadTaskBatch_tasks, "f")) {
|
|
105
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_limiter, "f").schedule(() => task.start());
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// This will cause promise to resolve right away
|
|
110
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_instances, "m", _DownloadTaskBatch_checkAndCallbackBatchComplete).call(this);
|
|
111
|
+
}
|
|
112
|
+
}), "f");
|
|
113
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_startPromise, "f");
|
|
114
|
+
}
|
|
115
|
+
async destroy() {
|
|
116
|
+
if (__classPrivateFieldGet(this, _DownloadTaskBatch_destroyPromise, "f")) {
|
|
117
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_destroyPromise, "f");
|
|
118
|
+
}
|
|
119
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_destroyPromise, new Promise(async (resolve) => {
|
|
120
|
+
await this.abort();
|
|
121
|
+
this.removeAllListeners();
|
|
122
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_tasks, [], "f");
|
|
123
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_destroyPromise, null, "f");
|
|
124
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_destroyed, true, "f");
|
|
125
|
+
resolve();
|
|
126
|
+
}), "f");
|
|
127
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_destroyPromise, "f");
|
|
128
|
+
}
|
|
129
|
+
allTasksEnded() {
|
|
130
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_tasks, "f").every((task) => task.hasEnded());
|
|
131
|
+
}
|
|
132
|
+
hasErrors() {
|
|
133
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_tasks, "f").some((task) => task.status === 'error');
|
|
134
|
+
}
|
|
135
|
+
isDestroyed() {
|
|
136
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_destroyed, "f") || !!__classPrivateFieldGet(this, _DownloadTaskBatch_destroyPromise, "f");
|
|
137
|
+
}
|
|
138
|
+
isAborted() {
|
|
139
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_aborted, "f") || !!__classPrivateFieldGet(this, _DownloadTaskBatch_abortPromise, "f");
|
|
140
|
+
}
|
|
141
|
+
getTasks(status) {
|
|
142
|
+
if (!status) {
|
|
143
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_tasks, "f");
|
|
144
|
+
}
|
|
145
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_tasks, "f").filter((task) => task.status === status);
|
|
146
|
+
}
|
|
147
|
+
async abort() {
|
|
148
|
+
if (__classPrivateFieldGet(this, _DownloadTaskBatch_abortPromise, "f")) {
|
|
149
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_abortPromise, "f");
|
|
150
|
+
}
|
|
151
|
+
if (this.isAborted()) {
|
|
152
|
+
return Promise.resolve();
|
|
153
|
+
}
|
|
154
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_abortPromise, new Promise(async (resolve) => {
|
|
155
|
+
const abortPromises = __classPrivateFieldGet(this, _DownloadTaskBatch_tasks, "f").map((task) => task.abort());
|
|
156
|
+
await Promise.all(abortPromises);
|
|
157
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_aborted, true, "f");
|
|
158
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_abortPromise, null, "f");
|
|
159
|
+
resolve();
|
|
160
|
+
}), "f");
|
|
161
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_abortPromise, "f");
|
|
162
|
+
}
|
|
163
|
+
get id() {
|
|
164
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_id, "f");
|
|
165
|
+
}
|
|
166
|
+
get name() {
|
|
167
|
+
return __classPrivateFieldGet(this, _DownloadTaskBatch_name, "f");
|
|
168
|
+
}
|
|
169
|
+
on(event, listener) {
|
|
170
|
+
return super.on(event, listener);
|
|
171
|
+
}
|
|
172
|
+
once(event, listener) {
|
|
173
|
+
return super.on(event, listener);
|
|
174
|
+
}
|
|
175
|
+
off(event, listener) {
|
|
176
|
+
return super.off(event, listener);
|
|
177
|
+
}
|
|
178
|
+
emit(event, ...args) {
|
|
179
|
+
return super.emit(event, ...args);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
_a = DownloadTaskBatch, _DownloadTaskBatch_id = new WeakMap(), _DownloadTaskBatch_taskIdCounter = new WeakMap(), _DownloadTaskBatch_name = new WeakMap(), _DownloadTaskBatch_tasks = new WeakMap(), _DownloadTaskBatch_limiter = new WeakMap(), _DownloadTaskBatch_startPromise = new WeakMap(), _DownloadTaskBatch_startingCallback = new WeakMap(), _DownloadTaskBatch_abortPromise = new WeakMap(), _DownloadTaskBatch_destroyPromise = new WeakMap(), _DownloadTaskBatch_destroyed = new WeakMap(), _DownloadTaskBatch_aborted = new WeakMap(), _DownloadTaskBatch_instances = new WeakSet(), _DownloadTaskBatch_reassignTaskId = function _DownloadTaskBatch_reassignTaskId(task) {
|
|
183
|
+
var _b;
|
|
184
|
+
task.id = __classPrivateFieldGet(this, _DownloadTaskBatch_taskIdCounter, "f");
|
|
185
|
+
__classPrivateFieldSet(this, _DownloadTaskBatch_taskIdCounter, (_b = __classPrivateFieldGet(this, _DownloadTaskBatch_taskIdCounter, "f"), _b++, _b), "f");
|
|
186
|
+
}, _DownloadTaskBatch_checkAndCallbackBatchComplete = function _DownloadTaskBatch_checkAndCallbackBatchComplete() {
|
|
187
|
+
if (this.allTasksEnded()) {
|
|
188
|
+
if (__classPrivateFieldGet(this, _DownloadTaskBatch_startingCallback, "f")) {
|
|
189
|
+
__classPrivateFieldGet(this, _DownloadTaskBatch_startingCallback, "f").call(this);
|
|
190
|
+
}
|
|
191
|
+
this.emit('complete', {});
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
_DownloadTaskBatch_idCounter = { value: 0 };
|
|
195
|
+
//# sourceMappingURL=DownloadTaskBatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DownloadTaskBatch.js","sourceRoot":"","sources":["../../../src/downloaders/task/DownloadTaskBatch.ts"],"names":[],"mappings":"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","sourcesContent":["import Bottleneck from 'bottleneck';\nimport DownloadTask, { DownloadTaskError, DownloadProgress, DownloadTaskStatus, DownloadTaskSkipReason, IDownloadTask } from './DownloadTask.js';\nimport Fetcher from '../../utils/Fetcher.js';\nimport EventEmitter from 'events';\nimport { DownloadTaskBatchEvent, DownloadTaskBatchEventPayloadOf } from './DownloadTaskBatchEvent.js';\n\nexport interface DownloadTaskBatchParams {\n name: string;\n fetcher: Fetcher;\n limiter: {\n maxConcurrent: number;\n minTime: number;\n }\n}\n\nexport interface IDownloadTaskBatch extends EventEmitter {\n id: number;\n name: string;\n allTasksEnded: () => boolean;\n hasErrors: () => boolean;\n isDestroyed: () => boolean;\n isAborted: () => boolean;\n getTasks: (status?: DownloadTaskStatus) => IDownloadTask[];\n on<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;\n once<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;\n off<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;\n}\n\nexport default class DownloadTaskBatch extends EventEmitter implements IDownloadTaskBatch {\n\n static #idCounter = 0;\n\n #id: number;\n #taskIdCounter: number;\n #name: string;\n #tasks: DownloadTask[];\n #limiter: Bottleneck;\n #startPromise: Promise<void> | null;\n #startingCallback?: (() => void) | null;\n #abortPromise: Promise<void> | null;\n #destroyPromise: Promise<void> | null;\n #destroyed: boolean;\n #aborted: boolean;\n\n constructor(params: DownloadTaskBatchParams) {\n super();\n this.#limiter = new Bottleneck({\n maxConcurrent: params.limiter.maxConcurrent,\n minTime: params.limiter.minTime\n });\n this.#id = DownloadTaskBatch.#idCounter;\n this.#taskIdCounter = 0;\n this.#name = params.name;\n this.#tasks = [];\n this.#startPromise = null;\n this.#startingCallback = null;\n this.#abortPromise = null;\n this.#destroyPromise = null;\n this.#destroyed = false;\n\n DownloadTaskBatch.#idCounter++;\n }\n\n #reassignTaskId(task: DownloadTask) {\n task.id = this.#taskIdCounter;\n this.#taskIdCounter++;\n }\n\n addTasks(tasks: DownloadTask[]) {\n for (const task of tasks) {\n this.#reassignTaskId(task);\n\n task.setCallbacks({\n onStart: (task: DownloadTask) => {\n this.emit('taskStart', { task });\n },\n onProgress: (task: DownloadTask, progress: DownloadProgress | null) => {\n this.emit('taskProgress', { task, progress });\n },\n onComplete: (task: DownloadTask) => {\n this.emit('taskComplete', { task });\n this.#checkAndCallbackBatchComplete();\n },\n onAbort: (task: DownloadTask) => {\n this.emit('taskAbort', { task });\n this.#checkAndCallbackBatchComplete();\n },\n onSkip: (task: DownloadTask, reason: DownloadTaskSkipReason) => {\n this.emit('taskSkip', { task, reason });\n this.#checkAndCallbackBatchComplete();\n },\n onError: (error: DownloadTaskError, willRetry: boolean) => {\n this.emit('taskError', { error, willRetry });\n if (!willRetry) {\n this.#checkAndCallbackBatchComplete();\n }\n },\n onSpawn: (origin: DownloadTask, spawn: DownloadTask) => {\n if (!this.isAborted() && !this.isDestroyed()) {\n this.#reassignTaskId(spawn);\n this.#tasks.push(spawn);\n this.#limiter.schedule(() => spawn.start());\n this.emit('taskSpawn', { origin, spawn });\n spawn.start();\n }\n }\n });\n }\n this.#tasks.push(...tasks);\n }\n\n start() {\n if (this.isAborted()) {\n throw Error('Cannot start aborted task batch');\n }\n if (this.isDestroyed()) {\n throw Error('Cannot start a destroyed task batch');\n }\n\n if (this.#startPromise) {\n return this.#startPromise;\n }\n\n this.#startPromise = new Promise<void>((resolve) => {\n this.#startingCallback = () => {\n this.#startPromise = null;\n this.#startingCallback = null;\n resolve();\n };\n if (this.#tasks.length > 0) {\n for (const task of this.#tasks) {\n this.#limiter.schedule(() => task.start());\n }\n }\n else {\n // This will cause promise to resolve right away\n this.#checkAndCallbackBatchComplete();\n }\n });\n\n return this.#startPromise;\n }\n\n #checkAndCallbackBatchComplete() {\n if (this.allTasksEnded()) {\n if (this.#startingCallback) {\n this.#startingCallback();\n }\n this.emit('complete', {});\n }\n }\n\n async destroy() {\n if (this.#destroyPromise) {\n return this.#destroyPromise;\n }\n\n this.#destroyPromise = new Promise<void>(async (resolve) => {\n await this.abort();\n this.removeAllListeners();\n this.#tasks = [];\n this.#destroyPromise = null;\n this.#destroyed = true;\n resolve();\n });\n\n return this.#destroyPromise;\n }\n\n allTasksEnded() {\n return this.#tasks.every((task) => task.hasEnded());\n }\n\n hasErrors() {\n return this.#tasks.some((task) => task.status === 'error');\n }\n\n isDestroyed() {\n return this.#destroyed || !!this.#destroyPromise;\n }\n\n isAborted() {\n return this.#aborted || !!this.#abortPromise;\n }\n\n getTasks(status?: DownloadTaskStatus) {\n if (!status) {\n return this.#tasks;\n }\n return this.#tasks.filter((task) => task.status === status);\n }\n\n async abort() {\n if (this.#abortPromise) {\n return this.#abortPromise;\n }\n\n if (this.isAborted()) {\n return Promise.resolve();\n }\n\n this.#abortPromise = new Promise(async (resolve) => {\n const abortPromises = this.#tasks.map((task) => task.abort());\n await Promise.all(abortPromises);\n this.#aborted = true;\n this.#abortPromise = null;\n resolve();\n });\n\n return this.#abortPromise;\n }\n\n get id() {\n return this.#id;\n }\n\n get name() {\n return this.#name;\n }\n\n on<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;\n on(event: string | symbol, listener: (...args: any[]) => void): this {\n return super.on(event, listener);\n }\n\n once<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;\n once(event: string | symbol, listener: (...args: any[]) => void): this {\n return super.on(event, listener);\n }\n\n off<T extends DownloadTaskBatchEvent>(event: T, listener: (args: DownloadTaskBatchEventPayloadOf<T>) => void): this;\n off(event: string | symbol, listener: (...args: any[]) => void): this {\n return super.off(event, listener);\n }\n\n emit<T extends DownloadTaskBatchEvent>(event: T, args: DownloadTaskBatchEventPayloadOf<T>): boolean;\n emit(event: string | symbol, ...args: any[]): boolean {\n return super.emit(event, ...args);\n }\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DownloadProgress, DownloadTaskError, IDownloadTask, DownloadTaskSkipReason } from './DownloadTask.js';
|
|
2
|
+
export type DownloadTaskBatchEvent = 'taskStart' | 'taskProgress' | 'taskComplete' | 'taskError' | 'taskAbort' | 'taskSkip' | 'taskSpawn' | 'complete';
|
|
3
|
+
export interface DownloadTaskBatchEventPayload {
|
|
4
|
+
'taskStart': {
|
|
5
|
+
task: IDownloadTask;
|
|
6
|
+
};
|
|
7
|
+
'taskProgress': {
|
|
8
|
+
task: IDownloadTask;
|
|
9
|
+
progress: DownloadProgress | null;
|
|
10
|
+
};
|
|
11
|
+
'taskComplete': {
|
|
12
|
+
task: IDownloadTask;
|
|
13
|
+
};
|
|
14
|
+
'taskError': {
|
|
15
|
+
error: DownloadTaskError;
|
|
16
|
+
willRetry: boolean;
|
|
17
|
+
};
|
|
18
|
+
'taskAbort': {
|
|
19
|
+
task: IDownloadTask;
|
|
20
|
+
};
|
|
21
|
+
'taskSkip': {
|
|
22
|
+
task: IDownloadTask;
|
|
23
|
+
reason: DownloadTaskSkipReason;
|
|
24
|
+
};
|
|
25
|
+
'taskSpawn': {
|
|
26
|
+
origin: IDownloadTask;
|
|
27
|
+
spawn: IDownloadTask;
|
|
28
|
+
};
|
|
29
|
+
'complete': {};
|
|
30
|
+
}
|
|
31
|
+
export type DownloadTaskBatchEventPayloadOf<T extends DownloadTaskBatchEvent> = DownloadTaskBatchEventPayload[T];
|
|
32
|
+
//# sourceMappingURL=DownloadTaskBatchEvent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DownloadTaskBatchEvent.d.ts","sourceRoot":"","sources":["../../../src/downloaders/task/DownloadTaskBatchEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE/G,MAAM,MAAM,sBAAsB,GAChC,WAAW,GACX,cAAc,GACd,cAAc,GACd,WAAW,GACX,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,CAAC;AAEb,MAAM,WAAW,6BAA6B;IAE5C,WAAW,EAAE;QACX,IAAI,EAAE,aAAa,CAAC;KACrB,CAAC;IAEF,cAAc,EAAE;QACd,IAAI,EAAE,aAAa,CAAC;QACpB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;KACnC,CAAC;IAEF,cAAc,EAAE;QACd,IAAI,EAAE,aAAa,CAAC;KACrB,CAAC;IAEF,WAAW,EAAE;QACX,KAAK,EAAE,iBAAiB,CAAC;QACzB,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;IAEF,WAAW,EAAE;QACX,IAAI,EAAE,aAAa,CAAC;KACrB,CAAC;IAEF,UAAU,EAAE;QACV,IAAI,EAAE,aAAa,CAAC;QACpB,MAAM,EAAE,sBAAsB,CAAC;KAChC,CAAC;IAEF,WAAW,EAAE;QACX,MAAM,EAAE,aAAa,CAAC;QACtB,KAAK,EAAE,aAAa,CAAC;KACtB,CAAC;IAEF,UAAU,EAAE,EAAE,CAAC;CAChB;AAED,MAAM,MAAM,+BAA+B,CAAC,CAAC,SAAS,sBAAsB,IAAI,6BAA6B,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DownloadTaskBatchEvent.js","sourceRoot":"","sources":["../../../src/downloaders/task/DownloadTaskBatchEvent.ts"],"names":[],"mappings":"","sourcesContent":["import { DownloadProgress, DownloadTaskError, IDownloadTask, DownloadTaskSkipReason } from './DownloadTask.js';\n\nexport type DownloadTaskBatchEvent =\n 'taskStart' |\n 'taskProgress' |\n 'taskComplete' |\n 'taskError' |\n 'taskAbort' |\n 'taskSkip' |\n 'taskSpawn' |\n 'complete';\n\nexport interface DownloadTaskBatchEventPayload {\n\n 'taskStart': {\n task: IDownloadTask;\n };\n\n 'taskProgress': {\n task: IDownloadTask;\n progress: DownloadProgress | null;\n };\n\n 'taskComplete': {\n task: IDownloadTask;\n };\n\n 'taskError': {\n error: DownloadTaskError;\n willRetry: boolean;\n };\n\n 'taskAbort': {\n task: IDownloadTask;\n };\n\n 'taskSkip': {\n task: IDownloadTask;\n reason: DownloadTaskSkipReason;\n };\n\n 'taskSpawn': {\n origin: IDownloadTask;\n spawn: IDownloadTask;\n };\n\n 'complete': {};\n}\n\nexport type DownloadTaskBatchEventPayloadOf<T extends DownloadTaskBatchEvent> = DownloadTaskBatchEventPayload[T];\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Fetcher from '../../utils/Fetcher.js';
|
|
2
|
+
import DownloadTask, { DownloadTaskCallbacks } from './DownloadTask.js';
|
|
3
|
+
import { Downloadable } from '../../entities/Downloadable.js';
|
|
4
|
+
import { FileExistsAction } from '../DownloaderOptions.js';
|
|
5
|
+
import Logger from '../../utils/logging/Logger.js';
|
|
6
|
+
export default class DownloadTaskFactory {
|
|
7
|
+
#private;
|
|
8
|
+
static createFromDownloadable(params: {
|
|
9
|
+
item: Downloadable;
|
|
10
|
+
destDir: string;
|
|
11
|
+
fetcher: Fetcher;
|
|
12
|
+
destFilenameFormat: string;
|
|
13
|
+
fileExistsAction: FileExistsAction;
|
|
14
|
+
downloadAllVariants: boolean;
|
|
15
|
+
maxRetries: number;
|
|
16
|
+
callbacks?: DownloadTaskCallbacks | null;
|
|
17
|
+
logger?: Logger | null;
|
|
18
|
+
}): DownloadTask<Downloadable>[];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=DownloadTaskFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DownloadTaskFactory.d.ts","sourceRoot":"","sources":["../../../src/downloaders/task/DownloadTaskFactory.ts"],"names":[],"mappings":"AAEA,OAAO,OAAO,MAAM,wBAAwB,CAAC;AAE7C,OAAO,YAAY,EAAE,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,MAAM,MAAM,+BAA+B,CAAC;AAqCnD,MAAM,CAAC,OAAO,OAAO,mBAAmB;;IAEtC,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE;QACpC,IAAI,EAAE,YAAY,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,mBAAmB,EAAE,OAAO,CAAC;QAC7B,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;QACzC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB;CA8JF"}
|