First upload version 0.0.1
This commit is contained in:
50
node_modules/ipull/dist/download/download-engine/engine/base-download-engine.d.ts
generated
vendored
Normal file
50
node_modules/ipull/dist/download/download-engine/engine/base-download-engine.d.ts
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import { DownloadFile, SaveProgressInfo } from "../types.js";
|
||||
import DownloadEngineFile, { DownloadEngineFileOptions } from "../download-file/download-engine-file.js";
|
||||
import BaseDownloadEngineFetchStream, { BaseDownloadEngineFetchStreamOptions } from "../streams/download-engine-fetch-stream/base-download-engine-fetch-stream.js";
|
||||
import { EventEmitter } from "eventemitter3";
|
||||
import ProgressStatisticsBuilder, { ProgressStatusWithIndex } from "../../transfer-visualize/progress-statistics-builder.js";
|
||||
import retry from "async-retry";
|
||||
import { AvailablePrograms } from "../download-file/download-programs/switch-program.js";
|
||||
export type InputURLOptions = {
|
||||
partURLs: string[];
|
||||
} | {
|
||||
url: string;
|
||||
};
|
||||
export type BaseDownloadEngineOptions = InputURLOptions & BaseDownloadEngineFetchStreamOptions & {
|
||||
chunkSize?: number;
|
||||
parallelStreams?: number;
|
||||
retry?: retry.Options;
|
||||
comment?: string;
|
||||
programType?: AvailablePrograms;
|
||||
};
|
||||
export type BaseDownloadEngineEvents = {
|
||||
start: () => void;
|
||||
paused: () => void;
|
||||
resumed: () => void;
|
||||
progress: (progress: ProgressStatusWithIndex) => void;
|
||||
save: (progress: SaveProgressInfo) => void;
|
||||
finished: () => void;
|
||||
closed: () => void;
|
||||
[key: string]: any;
|
||||
};
|
||||
export default class BaseDownloadEngine extends EventEmitter<BaseDownloadEngineEvents> {
|
||||
readonly options: DownloadEngineFileOptions;
|
||||
protected readonly _engine: DownloadEngineFile;
|
||||
protected _progressStatisticsBuilder: ProgressStatisticsBuilder;
|
||||
protected _downloadStarted: boolean;
|
||||
protected _latestStatus?: ProgressStatusWithIndex;
|
||||
protected constructor(engine: DownloadEngineFile, options: DownloadEngineFileOptions);
|
||||
get file(): DownloadFile;
|
||||
get downloadSize(): number;
|
||||
get fileName(): string;
|
||||
get status(): import("../../transfer-visualize/format-transfer-status.js").FormattedStatus;
|
||||
get downloadStatues(): import("../../transfer-visualize/format-transfer-status.js").FormattedStatus[];
|
||||
protected _initEvents(): void;
|
||||
download(): Promise<void>;
|
||||
pause(): void;
|
||||
resume(): void;
|
||||
close(): Promise<void>;
|
||||
protected static _createDownloadFile(parts: string[], fetchStream: BaseDownloadEngineFetchStream): Promise<DownloadFile>;
|
||||
protected static _validateURL(options: InputURLOptions): void;
|
||||
protected static _validateOptions(options: BaseDownloadEngineOptions): void;
|
||||
}
|
||||
140
node_modules/ipull/dist/download/download-engine/engine/base-download-engine.js
generated
vendored
Normal file
140
node_modules/ipull/dist/download/download-engine/engine/base-download-engine.js
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
import UrlInputError from "./error/url-input-error.js";
|
||||
import { EventEmitter } from "eventemitter3";
|
||||
import ProgressStatisticsBuilder from "../../transfer-visualize/progress-statistics-builder.js";
|
||||
import DownloadAlreadyStartedError from "./error/download-already-started-error.js";
|
||||
import StatusCodeError from "../streams/download-engine-fetch-stream/errors/status-code-error.js";
|
||||
import { InvalidOptionError } from "./error/InvalidOptionError.js";
|
||||
const IGNORE_HEAD_STATUS_CODES = [405, 501, 404];
|
||||
export default class BaseDownloadEngine extends EventEmitter {
|
||||
options;
|
||||
_engine;
|
||||
_progressStatisticsBuilder = new ProgressStatisticsBuilder();
|
||||
_downloadStarted = false;
|
||||
_latestStatus;
|
||||
constructor(engine, options) {
|
||||
super();
|
||||
this.options = options;
|
||||
this._engine = engine;
|
||||
this._progressStatisticsBuilder.add(engine);
|
||||
this._initEvents();
|
||||
}
|
||||
get file() {
|
||||
return this._engine.file;
|
||||
}
|
||||
get downloadSize() {
|
||||
return this._engine.downloadSize;
|
||||
}
|
||||
get fileName() {
|
||||
return this.file.localFileName;
|
||||
}
|
||||
get status() {
|
||||
return this._latestStatus ?? ProgressStatisticsBuilder.oneStatistics(this._engine);
|
||||
}
|
||||
get downloadStatues() {
|
||||
return [this.status];
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get _fileEngineOptions() {
|
||||
return this._engine.options;
|
||||
}
|
||||
_initEvents() {
|
||||
this._engine.on("start", () => {
|
||||
return this.emit("start");
|
||||
});
|
||||
this._engine.on("save", (info) => {
|
||||
return this.emit("save", info);
|
||||
});
|
||||
this._engine.on("finished", () => {
|
||||
return this.emit("finished");
|
||||
});
|
||||
this._engine.on("closed", () => {
|
||||
return this.emit("closed");
|
||||
});
|
||||
this._engine.on("paused", () => {
|
||||
return this.emit("paused");
|
||||
});
|
||||
this._engine.on("resumed", () => {
|
||||
return this.emit("resumed");
|
||||
});
|
||||
this._progressStatisticsBuilder.on("progress", (status) => {
|
||||
this._latestStatus = status;
|
||||
return this.emit("progress", status);
|
||||
});
|
||||
}
|
||||
async download() {
|
||||
if (this._downloadStarted) {
|
||||
throw new DownloadAlreadyStartedError();
|
||||
}
|
||||
try {
|
||||
this._downloadStarted = true;
|
||||
await this._engine.download();
|
||||
}
|
||||
finally {
|
||||
await this.close();
|
||||
}
|
||||
}
|
||||
pause() {
|
||||
return this._engine.pause();
|
||||
}
|
||||
resume() {
|
||||
return this._engine.resume();
|
||||
}
|
||||
close() {
|
||||
return this._engine.close();
|
||||
}
|
||||
static async _createDownloadFile(parts, fetchStream) {
|
||||
const localFileName = decodeURIComponent(new URL(parts[0], "https://example").pathname.split("/")
|
||||
.pop() || "");
|
||||
const downloadFile = {
|
||||
totalSize: 0,
|
||||
parts: [],
|
||||
localFileName
|
||||
};
|
||||
let counter = 0;
|
||||
for (const part of parts) {
|
||||
try {
|
||||
const { length, acceptRange, newURL, fileName } = await fetchStream.fetchDownloadInfo(part);
|
||||
const downloadURL = newURL ?? part;
|
||||
const size = length || 0;
|
||||
downloadFile.totalSize += size;
|
||||
downloadFile.parts.push({
|
||||
downloadURL,
|
||||
size,
|
||||
acceptRange: size > 0 && acceptRange
|
||||
});
|
||||
if (counter++ === 0 && fileName) {
|
||||
downloadFile.localFileName = fileName;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof StatusCodeError && IGNORE_HEAD_STATUS_CODES.includes(error.statusCode)) {
|
||||
// if the server does not support HEAD request, we will skip that step
|
||||
downloadFile.parts.push({
|
||||
downloadURL: part,
|
||||
size: 0,
|
||||
acceptRange: false
|
||||
});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return downloadFile;
|
||||
}
|
||||
static _validateURL(options) {
|
||||
if ("partURLs" in options && "url" in options) {
|
||||
throw new UrlInputError("Either `partURLs` or `url` should be provided, not both");
|
||||
}
|
||||
if (!("partURLs" in options) && !("url" in options)) {
|
||||
throw new UrlInputError("Either `partURLs` or `url` should be provided");
|
||||
}
|
||||
}
|
||||
static _validateOptions(options) {
|
||||
if ("tryHeaders" in options && options.tryHeaders?.length && "defaultFetchDownloadInfo" in options) {
|
||||
throw new InvalidOptionError("Cannot use `tryHeaders` with `defaultFetchDownloadInfo`");
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=base-download-engine.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/base-download-engine.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/base-download-engine.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"base-download-engine.js","sourceRoot":"","sources":["../../../../src/download/download-engine/engine/base-download-engine.ts"],"names":[],"mappings":"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"}
|
||||
32
node_modules/ipull/dist/download/download-engine/engine/download-engine-browser.d.ts
generated
vendored
Normal file
32
node_modules/ipull/dist/download/download-engine/engine/download-engine-browser.d.ts
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import { SaveProgressInfo } from "../types.js";
|
||||
import DownloadEngineFile from "../download-file/download-engine-file.js";
|
||||
import DownloadEngineWriteStreamBrowser, { DownloadEngineWriteStreamBrowserWriter } from "../streams/download-engine-write-stream/download-engine-write-stream-browser.js";
|
||||
import BaseDownloadEngine, { BaseDownloadEngineOptions } from "./base-download-engine.js";
|
||||
import BaseDownloadEngineWriteStream from "../streams/download-engine-write-stream/base-download-engine-write-stream.js";
|
||||
import BaseDownloadEngineFetchStream from "../streams/download-engine-fetch-stream/base-download-engine-fetch-stream.js";
|
||||
export type DownloadEngineOptionsBrowser = BaseDownloadEngineOptions & {
|
||||
onWrite?: DownloadEngineWriteStreamBrowserWriter;
|
||||
progress?: SaveProgressInfo;
|
||||
fetchStrategy?: "xhr" | "fetch";
|
||||
};
|
||||
export type DownloadEngineOptionsCustomFetchBrowser = DownloadEngineOptionsBrowser & {
|
||||
partURLs: string[];
|
||||
fetchStream: BaseDownloadEngineFetchStream;
|
||||
};
|
||||
export type DownloadEngineOptionsBrowserConstructor<WriteStream = DownloadEngineWriteStreamBrowser> = DownloadEngineOptionsCustomFetchBrowser & {
|
||||
writeStream: WriteStream;
|
||||
};
|
||||
/**
|
||||
* Download engine for browser
|
||||
*/
|
||||
export default class DownloadEngineBrowser<WriteStream extends BaseDownloadEngineWriteStream = BaseDownloadEngineWriteStream> extends BaseDownloadEngine {
|
||||
readonly options: DownloadEngineOptionsBrowserConstructor<WriteStream>;
|
||||
protected constructor(engine: DownloadEngineFile, _options: DownloadEngineOptionsBrowserConstructor<WriteStream>);
|
||||
get writeStream(): Omit<WriteStream, "write" | "close">;
|
||||
/**
|
||||
* Download file
|
||||
*/
|
||||
static createFromOptions(options: DownloadEngineOptionsBrowser): Promise<DownloadEngineBrowser<DownloadEngineWriteStreamBrowser>>;
|
||||
protected static _createFromOptionsWithCustomFetch(options: DownloadEngineOptionsCustomFetchBrowser): Promise<DownloadEngineBrowser<DownloadEngineWriteStreamBrowser>>;
|
||||
protected static _validateOptions(options: DownloadEngineOptionsBrowser): void;
|
||||
}
|
||||
52
node_modules/ipull/dist/download/download-engine/engine/download-engine-browser.js
generated
vendored
Normal file
52
node_modules/ipull/dist/download/download-engine/engine/download-engine-browser.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
import DownloadEngineFile from "../download-file/download-engine-file.js";
|
||||
import DownloadEngineFetchStreamFetch from "../streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js";
|
||||
import DownloadEngineFetchStreamXhr from "../streams/download-engine-fetch-stream/download-engine-fetch-stream-xhr.js";
|
||||
import DownloadEngineWriteStreamBrowser from "../streams/download-engine-write-stream/download-engine-write-stream-browser.js";
|
||||
import BaseDownloadEngine from "./base-download-engine.js";
|
||||
/**
|
||||
* Download engine for browser
|
||||
*/
|
||||
export default class DownloadEngineBrowser extends BaseDownloadEngine {
|
||||
options;
|
||||
constructor(engine, _options) {
|
||||
super(engine, _options);
|
||||
this.options = _options;
|
||||
}
|
||||
get writeStream() {
|
||||
return this.options.writeStream;
|
||||
}
|
||||
/**
|
||||
* Download file
|
||||
*/
|
||||
static async createFromOptions(options) {
|
||||
DownloadEngineBrowser._validateOptions(options);
|
||||
const partURLs = "partURLs" in options ? options.partURLs : [options.url];
|
||||
const fetchStream = options.fetchStrategy === "xhr" ?
|
||||
new DownloadEngineFetchStreamXhr(options) : new DownloadEngineFetchStreamFetch(options);
|
||||
return DownloadEngineBrowser._createFromOptionsWithCustomFetch({ ...options, partURLs, fetchStream });
|
||||
}
|
||||
static async _createFromOptionsWithCustomFetch(options) {
|
||||
const downloadFile = await DownloadEngineBrowser._createDownloadFile(options.partURLs, options.fetchStream);
|
||||
downloadFile.downloadProgress = options.progress;
|
||||
const writeStream = new DownloadEngineWriteStreamBrowser(options.onWrite, {
|
||||
...options,
|
||||
file: downloadFile
|
||||
});
|
||||
if (options.acceptRangeIsKnown == null) {
|
||||
const doesNotAcceptRange = downloadFile.parts.find(p => !p.acceptRange);
|
||||
if (doesNotAcceptRange) {
|
||||
console.warn(`Server does not accept range requests for "${doesNotAcceptRange.downloadURL}". Meaning fast-downloads/pausing/resuming will not work.
|
||||
This may be related to cors origin policy (range header is ignored in the browser).
|
||||
If you know the server accepts range requests, you can set "acceptRangeIsKnown" to true. To dismiss this warning, set "acceptRangeIsKnown" to false.`);
|
||||
}
|
||||
}
|
||||
const allOptions = { ...options, writeStream };
|
||||
const engine = new DownloadEngineFile(downloadFile, allOptions);
|
||||
return new DownloadEngineBrowser(engine, allOptions);
|
||||
}
|
||||
static _validateOptions(options) {
|
||||
super._validateOptions(options);
|
||||
DownloadEngineBrowser._validateURL(options);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=download-engine-browser.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/download-engine-browser.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/download-engine-browser.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"download-engine-browser.js","sourceRoot":"","sources":["../../../../src/download/download-engine/engine/download-engine-browser.ts"],"names":[],"mappings":"AACA,OAAO,kBAAkB,MAAM,0CAA0C,CAAC;AAC1E,OAAO,8BAA8B,MAAM,+EAA+E,CAAC;AAC3H,OAAO,4BAA4B,MAAM,6EAA6E,CAAC;AACvH,OAAO,gCAA0E,MAAM,iFAAiF,CAAC;AACzK,OAAO,kBAA+C,MAAM,2BAA2B,CAAC;AAsBxF;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAyG,SAAQ,kBAAkB;IAC3H,OAAO,CAAuD;IAEvF,YAAsB,MAA0B,EAAE,QAA8D;QAC5G,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,IAAW,WAAW;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;IACpC,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAqC;QACvE,qBAAqB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,UAAU,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAE1E,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC;YACjD,IAAI,4BAA4B,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,8BAA8B,CAAC,OAAO,CAAC,CAAC;QAE5F,OAAO,qBAAqB,CAAC,iCAAiC,CAAC,EAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAC,CAAC,CAAC;IACxG,CAAC;IAGS,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,OAAgD;QACrG,MAAM,YAAY,GAAG,MAAM,qBAAqB,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QAC5G,YAAY,CAAC,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;QAEjD,MAAM,WAAW,GAAG,IAAI,gCAAgC,CAAC,OAAO,CAAC,OAAO,EAAE;YACtE,GAAG,OAAO;YACV,IAAI,EAAE,YAAY;SACrB,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,kBAAkB,IAAI,IAAI,EAAE,CAAC;YACrC,MAAM,kBAAkB,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;YACxE,IAAI,kBAAkB,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,8CAA8C,kBAAkB,CAAC,WAAW;;qJAE4C,CAAC,CAAC;YAC3I,CAAC;QACL,CAAC;QAED,MAAM,UAAU,GAA4C,EAAC,GAAG,OAAO,EAAE,WAAW,EAAC,CAAC;QACtF,MAAM,MAAM,GAAG,IAAI,kBAAkB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAChE,OAAO,IAAI,qBAAqB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACzD,CAAC;IAES,MAAM,CAAU,gBAAgB,CAAC,OAAqC;QAC5E,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAChC,qBAAqB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;CACJ"}
|
||||
39
node_modules/ipull/dist/download/download-engine/engine/download-engine-multi-download.d.ts
generated
vendored
Normal file
39
node_modules/ipull/dist/download/download-engine/engine/download-engine-multi-download.d.ts
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { EventEmitter } from "eventemitter3";
|
||||
import { FormattedStatus } from "../../transfer-visualize/format-transfer-status.js";
|
||||
import ProgressStatisticsBuilder, { ProgressStatusWithIndex } from "../../transfer-visualize/progress-statistics-builder.js";
|
||||
import BaseDownloadEngine, { BaseDownloadEngineEvents } from "./base-download-engine.js";
|
||||
type DownloadEngineMultiAllowedEngines = BaseDownloadEngine;
|
||||
type DownloadEngineMultiDownloadEvents<Engine = DownloadEngineMultiAllowedEngines> = BaseDownloadEngineEvents & {
|
||||
childDownloadStarted: (engine: Engine) => void;
|
||||
childDownloadClosed: (engine: Engine) => void;
|
||||
};
|
||||
export type DownloadEngineMultiDownloadOptions = {
|
||||
parallelDownloads?: number;
|
||||
};
|
||||
export default class DownloadEngineMultiDownload<Engine extends DownloadEngineMultiAllowedEngines = DownloadEngineMultiAllowedEngines> extends EventEmitter<DownloadEngineMultiDownloadEvents> {
|
||||
readonly downloads: Engine[];
|
||||
readonly options: DownloadEngineMultiDownloadOptions;
|
||||
protected _aborted: boolean;
|
||||
protected _activeEngines: Set<Engine>;
|
||||
protected _progressStatisticsBuilder: ProgressStatisticsBuilder;
|
||||
protected _downloadStatues: (ProgressStatusWithIndex | FormattedStatus)[];
|
||||
protected _closeFiles: (() => Promise<void>)[];
|
||||
protected _lastStatus?: ProgressStatusWithIndex;
|
||||
protected _loadingDownloads: number;
|
||||
protected constructor(engines: (DownloadEngineMultiAllowedEngines | DownloadEngineMultiDownload)[], options: DownloadEngineMultiDownloadOptions);
|
||||
get downloadStatues(): (FormattedStatus | ProgressStatusWithIndex)[];
|
||||
get status(): ProgressStatusWithIndex;
|
||||
get downloadSize(): number;
|
||||
protected _init(): void;
|
||||
private _addEngine;
|
||||
addDownload(engine: Engine | DownloadEngineMultiDownload<any> | Promise<Engine | DownloadEngineMultiDownload<any>>): Promise<void>;
|
||||
download(): Promise<void>;
|
||||
private _changeEngineFinishDownload;
|
||||
private _finishEnginesDownload;
|
||||
pause(): void;
|
||||
resume(): void;
|
||||
close(): Promise<void>;
|
||||
protected static _extractEngines<Engine>(engines: Engine[]): any[];
|
||||
static fromEngines<Engine extends DownloadEngineMultiAllowedEngines>(engines: (Engine | Promise<Engine>)[], options?: DownloadEngineMultiDownloadOptions): Promise<DownloadEngineMultiDownload<BaseDownloadEngine>>;
|
||||
}
|
||||
export {};
|
||||
151
node_modules/ipull/dist/download/download-engine/engine/download-engine-multi-download.js
generated
vendored
Normal file
151
node_modules/ipull/dist/download/download-engine/engine/download-engine-multi-download.js
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
import { EventEmitter } from "eventemitter3";
|
||||
import ProgressStatisticsBuilder from "../../transfer-visualize/progress-statistics-builder.js";
|
||||
import DownloadAlreadyStartedError from "./error/download-already-started-error.js";
|
||||
import { concurrency } from "./utils/concurrency.js";
|
||||
import { DownloadFlags, DownloadStatus } from "../download-file/progress-status-file.js";
|
||||
import { NoDownloadEngineProvidedError } from "./error/no-download-engine-provided-error.js";
|
||||
const DEFAULT_PARALLEL_DOWNLOADS = 1;
|
||||
export default class DownloadEngineMultiDownload extends EventEmitter {
|
||||
downloads;
|
||||
options;
|
||||
_aborted = false;
|
||||
_activeEngines = new Set();
|
||||
_progressStatisticsBuilder = new ProgressStatisticsBuilder();
|
||||
_downloadStatues = [];
|
||||
_closeFiles = [];
|
||||
_lastStatus;
|
||||
_loadingDownloads = 0;
|
||||
constructor(engines, options) {
|
||||
super();
|
||||
this.downloads = DownloadEngineMultiDownload._extractEngines(engines);
|
||||
this.options = options;
|
||||
this._init();
|
||||
}
|
||||
get downloadStatues() {
|
||||
return this._downloadStatues;
|
||||
}
|
||||
get status() {
|
||||
if (!this._lastStatus) {
|
||||
throw new NoDownloadEngineProvidedError();
|
||||
}
|
||||
return this._lastStatus;
|
||||
}
|
||||
get downloadSize() {
|
||||
return this.downloads.reduce((acc, engine) => acc + engine.downloadSize, 0);
|
||||
}
|
||||
_init() {
|
||||
this._progressStatisticsBuilder.downloadStatus = DownloadStatus.NotStarted;
|
||||
this._progressStatisticsBuilder.on("progress", progress => {
|
||||
progress = {
|
||||
...progress,
|
||||
downloadFlags: progress.downloadFlags.concat([DownloadFlags.DownloadSequence])
|
||||
};
|
||||
this._lastStatus = progress;
|
||||
this.emit("progress", progress);
|
||||
});
|
||||
let index = 0;
|
||||
for (const engine of this.downloads) {
|
||||
this._addEngine(engine, index++);
|
||||
}
|
||||
// Prevent multiple progress events on adding engines
|
||||
this._progressStatisticsBuilder.add(...this.downloads);
|
||||
}
|
||||
_addEngine(engine, index) {
|
||||
this._downloadStatues[index] = engine.status;
|
||||
engine.on("progress", (progress) => {
|
||||
this._downloadStatues[index] = progress;
|
||||
});
|
||||
this._changeEngineFinishDownload(engine);
|
||||
}
|
||||
async addDownload(engine) {
|
||||
const index = this.downloads.length + this._loadingDownloads;
|
||||
this._downloadStatues[index] = ProgressStatisticsBuilder.loadingStatusEmptyStatistics();
|
||||
this._loadingDownloads++;
|
||||
this._progressStatisticsBuilder._totalDownloadParts++;
|
||||
const awaitEngine = engine instanceof Promise ? await engine : engine;
|
||||
this._progressStatisticsBuilder._totalDownloadParts--;
|
||||
this._loadingDownloads--;
|
||||
if (awaitEngine instanceof DownloadEngineMultiDownload) {
|
||||
let countEngines = 0;
|
||||
for (const subEngine of awaitEngine.downloads) {
|
||||
this._addEngine(subEngine, index + countEngines++);
|
||||
this.downloads.push(subEngine);
|
||||
}
|
||||
this._progressStatisticsBuilder.add(...awaitEngine.downloads);
|
||||
}
|
||||
else {
|
||||
this._addEngine(awaitEngine, index);
|
||||
this.downloads.push(awaitEngine);
|
||||
this._progressStatisticsBuilder.add(awaitEngine);
|
||||
}
|
||||
}
|
||||
async download() {
|
||||
if (this._activeEngines.size) {
|
||||
throw new DownloadAlreadyStartedError();
|
||||
}
|
||||
this._progressStatisticsBuilder.downloadStatus = DownloadStatus.Active;
|
||||
this.emit("start");
|
||||
const concurrencyCount = this.options.parallelDownloads ?? DEFAULT_PARALLEL_DOWNLOADS;
|
||||
await concurrency(this.downloads, concurrencyCount, async (engine) => {
|
||||
if (this._aborted)
|
||||
return;
|
||||
this._activeEngines.add(engine);
|
||||
this.emit("childDownloadStarted", engine);
|
||||
await engine.download();
|
||||
this.emit("childDownloadClosed", engine);
|
||||
this._activeEngines.delete(engine);
|
||||
});
|
||||
this._progressStatisticsBuilder.downloadStatus = DownloadStatus.Finished;
|
||||
this.emit("finished");
|
||||
await this._finishEnginesDownload();
|
||||
await this.close();
|
||||
}
|
||||
_changeEngineFinishDownload(engine) {
|
||||
const options = engine._fileEngineOptions;
|
||||
const onFinishAsync = options.onFinishAsync;
|
||||
const onCloseAsync = options.onCloseAsync;
|
||||
options.onFinishAsync = undefined;
|
||||
options.onCloseAsync = undefined;
|
||||
this._closeFiles.push(async () => {
|
||||
await onFinishAsync?.();
|
||||
await options.writeStream.close();
|
||||
await onCloseAsync?.();
|
||||
});
|
||||
}
|
||||
async _finishEnginesDownload() {
|
||||
await Promise.all(this._closeFiles.map(func => func()));
|
||||
}
|
||||
pause() {
|
||||
this._progressStatisticsBuilder.downloadStatus = DownloadStatus.Paused;
|
||||
this._activeEngines.forEach(engine => engine.pause());
|
||||
}
|
||||
resume() {
|
||||
this._progressStatisticsBuilder.downloadStatus = DownloadStatus.Active;
|
||||
this._activeEngines.forEach(engine => engine.resume());
|
||||
}
|
||||
async close() {
|
||||
if (this._aborted)
|
||||
return;
|
||||
this._aborted = true;
|
||||
if (this._progressStatisticsBuilder.downloadStatus !== DownloadStatus.Finished) {
|
||||
this._progressStatisticsBuilder.downloadStatus = DownloadStatus.Cancelled;
|
||||
}
|
||||
const closePromises = Array.from(this._activeEngines)
|
||||
.map(engine => engine.close());
|
||||
await Promise.all(closePromises);
|
||||
this.emit("closed");
|
||||
}
|
||||
static _extractEngines(engines) {
|
||||
return engines.map(engine => {
|
||||
if (engine instanceof DownloadEngineMultiDownload) {
|
||||
return engine.downloads;
|
||||
}
|
||||
return engine;
|
||||
})
|
||||
.flat();
|
||||
}
|
||||
static async fromEngines(engines, options = {}) {
|
||||
return new DownloadEngineMultiDownload(await Promise.all(engines), options);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=download-engine-multi-download.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/download-engine-multi-download.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/download-engine-multi-download.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
67
node_modules/ipull/dist/download/download-engine/engine/download-engine-nodejs.d.ts
generated
vendored
Normal file
67
node_modules/ipull/dist/download/download-engine/engine/download-engine-nodejs.d.ts
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
import { DownloadFile } from "../types.js";
|
||||
import DownloadEngineFile from "../download-file/download-engine-file.js";
|
||||
import DownloadEngineWriteStreamNodejs from "../streams/download-engine-write-stream/download-engine-write-stream-nodejs.js";
|
||||
import BaseDownloadEngine, { BaseDownloadEngineOptions } from "./base-download-engine.js";
|
||||
import BaseDownloadEngineFetchStream from "../streams/download-engine-fetch-stream/base-download-engine-fetch-stream.js";
|
||||
export declare const PROGRESS_FILE_EXTENSION = ".ipull";
|
||||
type PathOptions = {
|
||||
directory: string;
|
||||
} | {
|
||||
savePath: string;
|
||||
};
|
||||
export type DownloadEngineOptionsNodejs = PathOptions & BaseDownloadEngineOptions & {
|
||||
fileName?: string;
|
||||
fetchStrategy?: "localFile" | "fetch";
|
||||
skipExisting?: boolean;
|
||||
};
|
||||
export type DownloadEngineOptionsNodejsCustomFetch = DownloadEngineOptionsNodejs & {
|
||||
partURLs: string[];
|
||||
fetchStream: BaseDownloadEngineFetchStream;
|
||||
};
|
||||
export type DownloadEngineOptionsNodejsConstructor<WriteStream = DownloadEngineWriteStreamNodejs> = DownloadEngineOptionsNodejsCustomFetch & {
|
||||
writeStream: WriteStream;
|
||||
};
|
||||
/**
|
||||
* Download engine for Node.js
|
||||
*/
|
||||
export default class DownloadEngineNodejs<T extends DownloadEngineWriteStreamNodejs = DownloadEngineWriteStreamNodejs> extends BaseDownloadEngine {
|
||||
readonly options: DownloadEngineOptionsNodejsConstructor<T>;
|
||||
protected constructor(engine: DownloadEngineFile, _options: DownloadEngineOptionsNodejsConstructor<T>);
|
||||
protected _initEvents(): void;
|
||||
/**
|
||||
* The file path with the progress extension or the final file path if the download is finished
|
||||
*/
|
||||
get fileAbsolutePath(): string;
|
||||
/**
|
||||
* The final file path (without the progress extension)
|
||||
*/
|
||||
get finalFileAbsolutePath(): string;
|
||||
/**
|
||||
* Abort the download & delete the file (**even if** the download is finished)
|
||||
* @deprecated use `close` with flag `deleteFile` instead
|
||||
*
|
||||
* TODO: remove in the next major version
|
||||
*/
|
||||
closeAndDeleteFile(): Promise<void>;
|
||||
/**
|
||||
* Close the download engine
|
||||
* @param deleteTempFile {boolean} - delete the temp file (when the download is **not finished**).
|
||||
* @param deleteFile {boolean} - delete the **temp** or **final file** (clean everything up).
|
||||
*/
|
||||
close({ deleteTempFile, deleteFile }?: {
|
||||
deleteTempFile?: boolean;
|
||||
deleteFile?: boolean;
|
||||
}): Promise<void>;
|
||||
/**
|
||||
* Download/copy a file
|
||||
*
|
||||
* if `fetchStrategy` is defined as "localFile" it will copy the file, otherwise it will download it
|
||||
* By default, it will guess the strategy based on the URL
|
||||
*/
|
||||
static createFromOptions(options: DownloadEngineOptionsNodejs): Promise<DownloadEngineNodejs<DownloadEngineWriteStreamNodejs>>;
|
||||
protected static _createFromOptionsWithCustomFetch(options: DownloadEngineOptionsNodejsCustomFetch): Promise<DownloadEngineNodejs<DownloadEngineWriteStreamNodejs>>;
|
||||
protected static _createDownloadLocation(download: DownloadFile, options: DownloadEngineOptionsNodejs): string;
|
||||
protected static _validateOptions(options: DownloadEngineOptionsNodejs): void;
|
||||
protected static _guessFetchStrategy(url: string): "localFile" | "fetch";
|
||||
}
|
||||
export {};
|
||||
154
node_modules/ipull/dist/download/download-engine/engine/download-engine-nodejs.js
generated
vendored
Normal file
154
node_modules/ipull/dist/download/download-engine/engine/download-engine-nodejs.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
import path from "path";
|
||||
import DownloadEngineFile from "../download-file/download-engine-file.js";
|
||||
import DownloadEngineFetchStreamFetch from "../streams/download-engine-fetch-stream/download-engine-fetch-stream-fetch.js";
|
||||
import DownloadEngineWriteStreamNodejs from "../streams/download-engine-write-stream/download-engine-write-stream-nodejs.js";
|
||||
import DownloadEngineFetchStreamLocalFile from "../streams/download-engine-fetch-stream/download-engine-fetch-stream-local-file.js";
|
||||
import BaseDownloadEngine from "./base-download-engine.js";
|
||||
import SavePathError from "./error/save-path-error.js";
|
||||
import fs from "fs-extra";
|
||||
import filenamify from "filenamify";
|
||||
import { DownloadStatus } from "../download-file/progress-status-file.js";
|
||||
export const PROGRESS_FILE_EXTENSION = ".ipull";
|
||||
/**
|
||||
* Download engine for Node.js
|
||||
*/
|
||||
export default class DownloadEngineNodejs extends BaseDownloadEngine {
|
||||
options;
|
||||
constructor(engine, _options) {
|
||||
super(engine, _options);
|
||||
this.options = _options;
|
||||
}
|
||||
_initEvents() {
|
||||
super._initEvents();
|
||||
this._engine.options.onSaveProgressAsync = async (progress) => {
|
||||
if (this.options.skipExisting)
|
||||
return;
|
||||
await this.options.writeStream.saveMedataAfterFile(progress);
|
||||
};
|
||||
// Try to clone the file if it's a single part download
|
||||
this._engine.options.onStartedAsync = async () => {
|
||||
if (this.options.skipExisting || this.options.fetchStrategy !== "localFile" || this.options.partURLs.length !== 1)
|
||||
return;
|
||||
try {
|
||||
const { reflinkFile } = await import("@reflink/reflink");
|
||||
await fs.remove(this.options.writeStream.path);
|
||||
await reflinkFile(this.options.partURLs[0], this.options.writeStream.path);
|
||||
this._engine.finished("cloned");
|
||||
}
|
||||
catch { }
|
||||
};
|
||||
this._engine.options.onFinishAsync = async () => {
|
||||
if (this.options.skipExisting)
|
||||
return;
|
||||
await this.options.writeStream.ftruncate(this.downloadSize);
|
||||
};
|
||||
this._engine.options.onCloseAsync = async () => {
|
||||
if (this.status.ended && this.options.writeStream.path != this.options.writeStream.finalPath) {
|
||||
await fs.rename(this.options.writeStream.path, this.options.writeStream.finalPath);
|
||||
this.options.writeStream.path = this.options.writeStream.finalPath;
|
||||
}
|
||||
};
|
||||
if (this.options.skipExisting) {
|
||||
this.options.writeStream.path = this.options.writeStream.finalPath;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The file path with the progress extension or the final file path if the download is finished
|
||||
*/
|
||||
get fileAbsolutePath() {
|
||||
return path.resolve(this.options.writeStream.path);
|
||||
}
|
||||
/**
|
||||
* The final file path (without the progress extension)
|
||||
*/
|
||||
get finalFileAbsolutePath() {
|
||||
return path.resolve(this.options.writeStream.finalPath);
|
||||
}
|
||||
/**
|
||||
* Abort the download & delete the file (**even if** the download is finished)
|
||||
* @deprecated use `close` with flag `deleteFile` instead
|
||||
*
|
||||
* TODO: remove in the next major version
|
||||
*/
|
||||
async closeAndDeleteFile() {
|
||||
await this.close({ deleteFile: true });
|
||||
}
|
||||
/**
|
||||
* Close the download engine
|
||||
* @param deleteTempFile {boolean} - delete the temp file (when the download is **not finished**).
|
||||
* @param deleteFile {boolean} - delete the **temp** or **final file** (clean everything up).
|
||||
*/
|
||||
async close({ deleteTempFile, deleteFile } = {}) {
|
||||
await super.close();
|
||||
if (deleteFile || deleteTempFile && this.status.downloadStatus != DownloadStatus.Finished) {
|
||||
try {
|
||||
await fs.unlink(this.fileAbsolutePath);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Download/copy a file
|
||||
*
|
||||
* if `fetchStrategy` is defined as "localFile" it will copy the file, otherwise it will download it
|
||||
* By default, it will guess the strategy based on the URL
|
||||
*/
|
||||
static async createFromOptions(options) {
|
||||
DownloadEngineNodejs._validateOptions(options);
|
||||
const partURLs = "partURLs" in options ? options.partURLs : [options.url];
|
||||
options.fetchStrategy ??= DownloadEngineNodejs._guessFetchStrategy(partURLs[0]);
|
||||
const fetchStream = options.fetchStrategy === "localFile" ?
|
||||
new DownloadEngineFetchStreamLocalFile(options) :
|
||||
new DownloadEngineFetchStreamFetch(options);
|
||||
return DownloadEngineNodejs._createFromOptionsWithCustomFetch({ ...options, partURLs, fetchStream });
|
||||
}
|
||||
static async _createFromOptionsWithCustomFetch(options) {
|
||||
const downloadFile = await DownloadEngineNodejs._createDownloadFile(options.partURLs, options.fetchStream);
|
||||
const downloadLocation = DownloadEngineNodejs._createDownloadLocation(downloadFile, options);
|
||||
downloadFile.localFileName = path.basename(downloadLocation);
|
||||
const writeStream = new DownloadEngineWriteStreamNodejs(downloadLocation + PROGRESS_FILE_EXTENSION, downloadLocation, options);
|
||||
writeStream.fileSize = downloadFile.totalSize;
|
||||
downloadFile.downloadProgress = await writeStream.loadMetadataAfterFileWithoutRetry();
|
||||
if (options.skipExisting) {
|
||||
options.skipExisting = false;
|
||||
if (downloadFile.totalSize > 0 && !downloadFile.downloadProgress) {
|
||||
try {
|
||||
const stat = await fs.stat(downloadLocation);
|
||||
if (stat.isFile() && stat.size === downloadFile.totalSize) {
|
||||
options.skipExisting = true;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
const allOptions = { ...options, writeStream };
|
||||
const engine = new DownloadEngineFile(downloadFile, allOptions);
|
||||
return new DownloadEngineNodejs(engine, allOptions);
|
||||
}
|
||||
static _createDownloadLocation(download, options) {
|
||||
if ("savePath" in options) {
|
||||
return options.savePath;
|
||||
}
|
||||
const fileName = options.fileName || download.localFileName;
|
||||
return path.join(options.directory, filenamify(fileName));
|
||||
}
|
||||
static _validateOptions(options) {
|
||||
super._validateOptions(options);
|
||||
if (!("directory" in options) && !("savePath" in options)) {
|
||||
throw new SavePathError("Either `directory` or `savePath` must be provided");
|
||||
}
|
||||
if ("directory" in options && "savePath" in options) {
|
||||
throw new SavePathError("Both `directory` and `savePath` cannot be provided");
|
||||
}
|
||||
DownloadEngineNodejs._validateURL(options);
|
||||
}
|
||||
static _guessFetchStrategy(url) {
|
||||
try {
|
||||
new URL(url);
|
||||
return "fetch";
|
||||
}
|
||||
catch { }
|
||||
return "localFile";
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=download-engine-nodejs.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/download-engine-nodejs.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/download-engine-nodejs.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4
node_modules/ipull/dist/download/download-engine/engine/error/InvalidOptionError.d.ts
generated
vendored
Normal file
4
node_modules/ipull/dist/download/download-engine/engine/error/InvalidOptionError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export declare class InvalidOptionError extends EngineError {
|
||||
constructor(message: string);
|
||||
}
|
||||
7
node_modules/ipull/dist/download/download-engine/engine/error/InvalidOptionError.js
generated
vendored
Normal file
7
node_modules/ipull/dist/download/download-engine/engine/error/InvalidOptionError.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export class InvalidOptionError extends EngineError {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=InvalidOptionError.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/error/InvalidOptionError.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/error/InvalidOptionError.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"InvalidOptionError.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/engine/error/InvalidOptionError.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAE5C,MAAM,OAAO,kBAAmB,SAAQ,WAAW;IAC/C,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;CACJ"}
|
||||
4
node_modules/ipull/dist/download/download-engine/engine/error/download-already-started-error.d.ts
generated
vendored
Normal file
4
node_modules/ipull/dist/download/download-engine/engine/error/download-already-started-error.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export default class DownloadAlreadyStartedError extends EngineError {
|
||||
constructor();
|
||||
}
|
||||
7
node_modules/ipull/dist/download/download-engine/engine/error/download-already-started-error.js
generated
vendored
Normal file
7
node_modules/ipull/dist/download/download-engine/engine/error/download-already-started-error.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export default class DownloadAlreadyStartedError extends EngineError {
|
||||
constructor() {
|
||||
super("Download already started");
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=download-already-started-error.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/error/download-already-started-error.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/error/download-already-started-error.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"download-already-started-error.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/engine/error/download-already-started-error.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAE5C,MAAM,CAAC,OAAO,OAAO,2BAA4B,SAAQ,WAAW;IAChE;QACI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACtC,CAAC;CACJ"}
|
||||
3
node_modules/ipull/dist/download/download-engine/engine/error/engine-error.d.ts
generated
vendored
Normal file
3
node_modules/ipull/dist/download/download-engine/engine/error/engine-error.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import IpullError from "../../../../errors/ipull-error.js";
|
||||
export default class EngineError extends IpullError {
|
||||
}
|
||||
4
node_modules/ipull/dist/download/download-engine/engine/error/engine-error.js
generated
vendored
Normal file
4
node_modules/ipull/dist/download/download-engine/engine/error/engine-error.js
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import IpullError from "../../../../errors/ipull-error.js";
|
||||
export default class EngineError extends IpullError {
|
||||
}
|
||||
//# sourceMappingURL=engine-error.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/error/engine-error.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/error/engine-error.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"engine-error.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/engine/error/engine-error.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,mCAAmC,CAAC;AAE3D,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,UAAU;CAAG"}
|
||||
4
node_modules/ipull/dist/download/download-engine/engine/error/invalid-content-length-error.d.ts
generated
vendored
Normal file
4
node_modules/ipull/dist/download/download-engine/engine/error/invalid-content-length-error.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export default class InvalidContentLengthError extends EngineError {
|
||||
constructor(url: string);
|
||||
}
|
||||
7
node_modules/ipull/dist/download/download-engine/engine/error/invalid-content-length-error.js
generated
vendored
Normal file
7
node_modules/ipull/dist/download/download-engine/engine/error/invalid-content-length-error.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export default class InvalidContentLengthError extends EngineError {
|
||||
constructor(url) {
|
||||
super(`Invalid content length, for request URL: ${url}`);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=invalid-content-length-error.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/error/invalid-content-length-error.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/error/invalid-content-length-error.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"invalid-content-length-error.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/engine/error/invalid-content-length-error.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAE5C,MAAM,CAAC,OAAO,OAAO,yBAA0B,SAAQ,WAAW;IAC9D,YAAY,GAAW;QACnB,KAAK,CAAC,4CAA4C,GAAG,EAAE,CAAC,CAAC;IAC7D,CAAC;CACJ"}
|
||||
3
node_modules/ipull/dist/download/download-engine/engine/error/missing-event-error.d.ts
generated
vendored
Normal file
3
node_modules/ipull/dist/download/download-engine/engine/error/missing-event-error.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export default class MissingEventError extends EngineError {
|
||||
}
|
||||
4
node_modules/ipull/dist/download/download-engine/engine/error/missing-event-error.js
generated
vendored
Normal file
4
node_modules/ipull/dist/download/download-engine/engine/error/missing-event-error.js
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export default class MissingEventError extends EngineError {
|
||||
}
|
||||
//# sourceMappingURL=missing-event-error.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/error/missing-event-error.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/error/missing-event-error.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"missing-event-error.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/engine/error/missing-event-error.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAE5C,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,WAAW;CAAG"}
|
||||
4
node_modules/ipull/dist/download/download-engine/engine/error/no-download-engine-provided-error.d.ts
generated
vendored
Normal file
4
node_modules/ipull/dist/download/download-engine/engine/error/no-download-engine-provided-error.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export declare class NoDownloadEngineProvidedError extends EngineError {
|
||||
constructor(error?: string);
|
||||
}
|
||||
7
node_modules/ipull/dist/download/download-engine/engine/error/no-download-engine-provided-error.js
generated
vendored
Normal file
7
node_modules/ipull/dist/download/download-engine/engine/error/no-download-engine-provided-error.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import EngineError from "./engine-error.js";
|
||||
export class NoDownloadEngineProvidedError extends EngineError {
|
||||
constructor(error = "No download engine provided for download sequence") {
|
||||
super(error);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=no-download-engine-provided-error.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/error/no-download-engine-provided-error.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/error/no-download-engine-provided-error.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"no-download-engine-provided-error.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/engine/error/no-download-engine-provided-error.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAE5C,MAAM,OAAO,6BAA8B,SAAQ,WAAW;IAC1D,YAAY,KAAK,GAAG,mDAAmD;QACnE,KAAK,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;CACJ"}
|
||||
4
node_modules/ipull/dist/download/download-engine/engine/error/save-path-error.d.ts
generated
vendored
Normal file
4
node_modules/ipull/dist/download/download-engine/engine/error/save-path-error.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { InvalidOptionError } from "./InvalidOptionError.js";
|
||||
export default class SavePathError extends InvalidOptionError {
|
||||
constructor(message: string);
|
||||
}
|
||||
7
node_modules/ipull/dist/download/download-engine/engine/error/save-path-error.js
generated
vendored
Normal file
7
node_modules/ipull/dist/download/download-engine/engine/error/save-path-error.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { InvalidOptionError } from "./InvalidOptionError.js";
|
||||
export default class SavePathError extends InvalidOptionError {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=save-path-error.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/error/save-path-error.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/error/save-path-error.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"save-path-error.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/engine/error/save-path-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,yBAAyB,CAAC;AAE3D,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,kBAAkB;IACzD,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;CACJ"}
|
||||
4
node_modules/ipull/dist/download/download-engine/engine/error/url-input-error.d.ts
generated
vendored
Normal file
4
node_modules/ipull/dist/download/download-engine/engine/error/url-input-error.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { InvalidOptionError } from "./InvalidOptionError.js";
|
||||
export default class UrlInputError extends InvalidOptionError {
|
||||
constructor(message: string);
|
||||
}
|
||||
7
node_modules/ipull/dist/download/download-engine/engine/error/url-input-error.js
generated
vendored
Normal file
7
node_modules/ipull/dist/download/download-engine/engine/error/url-input-error.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { InvalidOptionError } from "./InvalidOptionError.js";
|
||||
export default class UrlInputError extends InvalidOptionError {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=url-input-error.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/error/url-input-error.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/error/url-input-error.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"url-input-error.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/engine/error/url-input-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,yBAAyB,CAAC;AAE3D,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,kBAAkB;IACzD,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;CACJ"}
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/utils/concurrency.d.ts
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/utils/concurrency.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare function concurrency<Value>(array: Value[], concurrencyCount: number, callback: (value: Value) => Promise<void>): Promise<void>;
|
||||
22
node_modules/ipull/dist/download/download-engine/engine/utils/concurrency.js
generated
vendored
Normal file
22
node_modules/ipull/dist/download/download-engine/engine/utils/concurrency.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
export function concurrency(array, concurrencyCount, callback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let index = 0;
|
||||
let activeCount = 0;
|
||||
function next() {
|
||||
if (index === array.length && activeCount === 0) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
while (activeCount < concurrencyCount && index < array.length) {
|
||||
activeCount++;
|
||||
callback(array[index++])
|
||||
.then(() => {
|
||||
activeCount--;
|
||||
next();
|
||||
}, reject);
|
||||
}
|
||||
}
|
||||
next();
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=concurrency.js.map
|
||||
1
node_modules/ipull/dist/download/download-engine/engine/utils/concurrency.js.map
generated
vendored
Normal file
1
node_modules/ipull/dist/download/download-engine/engine/utils/concurrency.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/engine/utils/concurrency.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAQ,KAAc,EAAE,gBAAwB,EAAE,QAAyC;IAClH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,SAAS,IAAI;YACT,IAAI,KAAK,KAAK,KAAK,CAAC,MAAM,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;gBAC9C,OAAO,EAAE,CAAC;gBACV,OAAO;YACX,CAAC;YAED,OAAO,WAAW,GAAG,gBAAgB,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC5D,WAAW,EAAE,CAAC;gBACd,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;qBACnB,IAAI,CAAC,GAAG,EAAE;oBACP,WAAW,EAAE,CAAC;oBACd,IAAI,EAAE,CAAC;gBACX,CAAC,EAAE,MAAM,CAAC,CAAC;YACnB,CAAC;QACL,CAAC;QAED,IAAI,EAAE,CAAC;IACX,CAAC,CAAC,CAAC;AACP,CAAC"}
|
||||
Reference in New Issue
Block a user