First upload version 0.0.1

This commit is contained in:
Neyra
2026-02-05 15:27:49 +08:00
commit 8e9b7201ed
4182 changed files with 593136 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
import ProgressStatusFile, { DownloadStatus, ProgressStatus } from "./progress-status-file.js";
import { DownloadFile, SaveProgressInfo } from "../types.js";
import BaseDownloadEngineFetchStream from "../streams/download-engine-fetch-stream/base-download-engine-fetch-stream.js";
import BaseDownloadEngineWriteStream from "../streams/download-engine-write-stream/base-download-engine-write-stream.js";
import retry from "async-retry";
import { EventEmitter } from "eventemitter3";
import { AvailablePrograms } from "./download-programs/switch-program.js";
import BaseDownloadProgram from "./download-programs/base-download-program.js";
export type DownloadEngineFileOptions = {
chunkSize?: number;
parallelStreams?: number;
retry?: retry.Options;
comment?: string;
fetchStream: BaseDownloadEngineFetchStream;
writeStream: BaseDownloadEngineWriteStream;
onFinishAsync?: () => Promise<void>;
onStartedAsync?: () => Promise<void>;
onCloseAsync?: () => Promise<void>;
onSaveProgressAsync?: (progress: SaveProgressInfo) => Promise<void>;
programType?: AvailablePrograms;
};
export type DownloadEngineFileOptionsWithDefaults = DownloadEngineFileOptions & {
chunkSize: number;
parallelStreams: number;
};
export type DownloadEngineFileEvents = {
start: () => void;
paused: () => void;
resumed: () => void;
progress: (progress: ProgressStatus) => void;
save: (progress: SaveProgressInfo) => void;
finished: () => void;
closed: () => void;
[key: string]: any;
};
export default class DownloadEngineFile extends EventEmitter<DownloadEngineFileEvents> {
readonly file: DownloadFile;
options: DownloadEngineFileOptionsWithDefaults;
protected _progress: SaveProgressInfo;
protected _closed: boolean;
protected _progressStatus: ProgressStatusFile;
protected _activeStreamBytes: {
[key: number]: number;
};
protected _activeProgram?: BaseDownloadProgram;
protected _downloadStatus: DownloadStatus;
private _latestProgressDate;
constructor(file: DownloadFile, options: DownloadEngineFileOptions);
private _createProgressFlags;
get downloadSize(): number;
get fileName(): string;
get status(): ProgressStatus;
protected get _activePart(): import("../types.js").DownloadFilePart;
private get _downloadedPartsSize();
private get _activeDownloadedChunkSize();
get transferredBytes(): number;
protected _emptyChunksForPart(part: number): any[];
private _initEventReloadStatus;
private _initProgress;
download(): Promise<void>;
protected _downloadSlice(startChunk: number, endChunk: number): Promise<void>;
protected _saveProgress(): Promise<void> | undefined;
protected _sendProgressDownloadPart(): void;
pause(): void;
resume(): void;
close(): Promise<void>;
finished(comment?: string): void;
[Symbol.dispose](): Promise<void>;
}

View File

@@ -0,0 +1,261 @@
import ProgressStatusFile, { DownloadFlags, DownloadStatus } from "./progress-status-file.js";
import { ChunkStatus } from "../types.js";
import { EventEmitter } from "eventemitter3";
import { withLock } from "lifecycle-utils";
import switchProgram from "./download-programs/switch-program.js";
import { pushComment } from "./utils/push-comment.js";
const DEFAULT_OPTIONS = {
chunkSize: 1024 * 1024 * 5,
parallelStreams: 1
};
export default class DownloadEngineFile extends EventEmitter {
file;
options;
_progress = {
part: 0,
chunks: [],
chunkSize: 0,
parallelStreams: 0
};
_closed = false;
_progressStatus;
_activeStreamBytes = {};
_activeProgram;
_downloadStatus = DownloadStatus.NotStarted;
_latestProgressDate = 0;
constructor(file, options) {
super();
this.file = file;
this.options = { ...DEFAULT_OPTIONS, ...options };
this._progressStatus = new ProgressStatusFile(file.parts.length, file.localFileName, options.fetchStream.transferAction, this._createProgressFlags());
this._initProgress();
}
_createProgressFlags() {
const flags = [];
if (this.options.skipExisting) {
flags.push(DownloadFlags.Existing);
}
return flags;
}
get downloadSize() {
return this.file.parts.reduce((acc, part) => acc + part.size, 0);
}
get fileName() {
return this.file.localFileName;
}
get status() {
return this._progressStatus.createStatus(this._progress.part + 1, this.transferredBytes, this.downloadSize, this._downloadStatus, this.options.comment);
}
get _activePart() {
return this.file.parts[this._progress.part];
}
get _downloadedPartsSize() {
return this.file.parts.slice(0, this._progress.part)
.reduce((acc, part) => acc + part.size, 0);
}
get _activeDownloadedChunkSize() {
return this._progress.chunks.filter(c => c === ChunkStatus.COMPLETE).length * this._progress.chunkSize;
}
get transferredBytes() {
if (this._downloadStatus === DownloadStatus.Finished) {
return this.downloadSize;
}
const streamingBytes = Object.values(this._activeStreamBytes)
.reduce((acc, bytes) => acc + bytes, 0);
const streamBytes = this._activeDownloadedChunkSize + streamingBytes;
const streamBytesMin = Math.min(streamBytes, this._activePart.size || streamBytes);
const allBytes = streamBytesMin + this._downloadedPartsSize;
return Math.min(allBytes, this.downloadSize || allBytes);
}
_emptyChunksForPart(part) {
const partInfo = this.file.parts[part];
if (partInfo.size === 0) {
return [ChunkStatus.NOT_STARTED];
}
const chunksCount = Math.ceil(partInfo.size / this.options.chunkSize);
return new Array(chunksCount).fill(ChunkStatus.NOT_STARTED);
}
_initEventReloadStatus() {
if (this._progress.part === this.file.parts.length - 1 && this._progress.chunks.every(c => c === ChunkStatus.COMPLETE)) {
this._downloadStatus = DownloadStatus.Finished;
}
}
_initProgress() {
if (this.options.skipExisting) {
this._progress.part = this.file.parts.length - 1;
this._downloadStatus = DownloadStatus.Finished;
this.options.comment = pushComment("Skipping existing", this.options.comment);
}
else if (this.file.downloadProgress) {
this._progress = this.file.downloadProgress;
this._initEventReloadStatus();
}
else {
this._progress = {
part: 0,
chunks: this._emptyChunksForPart(0),
chunkSize: this.options.chunkSize,
parallelStreams: this.options.parallelStreams
};
}
}
async download() {
if (this._downloadStatus === DownloadStatus.NotStarted) {
this._downloadStatus = DownloadStatus.Active;
}
this._progressStatus.started();
this.emit("start");
await this.options.onStartedAsync?.();
for (let i = this._progress.part; i < this.file.parts.length && this._downloadStatus !== DownloadStatus.Finished; i++) {
if (this._closed)
return;
// If we are starting a new part, we need to reset the progress
if (i > this._progress.part || !this._activePart.acceptRange) {
this._progress.part = i;
this._progress.chunkSize = this.options.chunkSize;
this._progress.parallelStreams = this.options.parallelStreams;
this._progress.chunks = this._emptyChunksForPart(i);
}
// Reset in progress chunks
this._progress.chunks = this._progress.chunks.map(chunk => (chunk === ChunkStatus.COMPLETE ? ChunkStatus.COMPLETE : ChunkStatus.NOT_STARTED));
// Reset active stream progress
this._activeStreamBytes = {};
if (this._activePart.acceptRange) {
this._activeProgram = switchProgram(this._progress, this._downloadSlice.bind(this), this.options.fetchStream.programType || this.options.programType);
await this._activeProgram.download();
}
else {
const chunksToRead = this._activePart.size > 0 ? this._progress.chunks.length : Infinity;
await this._downloadSlice(0, chunksToRead);
}
}
// All parts are downloaded, we can clear the progress
this._activeStreamBytes = {};
this._latestProgressDate = 0;
if (this._closed)
return;
this._progressStatus.finished();
this._downloadStatus = DownloadStatus.Finished;
this._sendProgressDownloadPart();
this.emit("finished");
await this.options.onFinishAsync?.();
}
_downloadSlice(startChunk, endChunk) {
const fetchState = this.options.fetchStream.withSubState({
chunkSize: this._progress.chunkSize,
startChunk,
endChunk,
totalSize: this._activePart.size,
url: this._activePart.downloadURL,
rangeSupport: this._activePart.acceptRange,
onProgress: (length) => {
this._activeStreamBytes[startChunk] = length;
this._sendProgressDownloadPart();
}
});
const downloadedPartsSize = this._downloadedPartsSize;
this._progress.chunks[startChunk] = ChunkStatus.IN_PROGRESS;
return (async () => {
const allWrites = new Set();
let lastChunkSize = 0;
await fetchState.fetchChunks((chunks, writePosition, index) => {
if (this._closed || this._progress.chunks[index] != ChunkStatus.IN_PROGRESS) {
return;
}
for (const chunk of chunks) {
const writePromise = this.options.writeStream.write(downloadedPartsSize + writePosition, chunk);
writePosition += chunk.length;
if (writePromise) {
allWrites.add(writePromise);
writePromise.then(() => {
allWrites.delete(writePromise);
});
}
}
// if content length is 0, we do not know how many chunks we should have
if (this._activePart.size === 0) {
this._progress.chunks.push(ChunkStatus.NOT_STARTED);
}
this._progress.chunks[index] = ChunkStatus.COMPLETE;
lastChunkSize = chunks.reduce((last, current) => last + current.length, 0);
delete this._activeStreamBytes[startChunk];
void this._saveProgress();
const nextChunk = this._progress.chunks[index + 1];
const shouldReadNext = endChunk - index > 1; // grater than 1, meaning there is a next chunk
if (shouldReadNext) {
if (nextChunk == null || nextChunk != ChunkStatus.NOT_STARTED) {
return fetchState.close();
}
this._progress.chunks[index + 1] = ChunkStatus.IN_PROGRESS;
}
});
// On dynamic content length, we need to adjust the last chunk size
if (this._activePart.size === 0) {
this._activePart.size = this._activeDownloadedChunkSize - this.options.chunkSize + lastChunkSize;
this._progress.chunks = this._progress.chunks.filter(c => c === ChunkStatus.COMPLETE);
}
delete this._activeStreamBytes[startChunk];
await Promise.all(allWrites);
})();
}
_saveProgress() {
const thisProgress = this._latestProgressDate = Date.now();
this._sendProgressDownloadPart();
if (!this._activePart.acceptRange)
return;
this.emit("save", this._progress);
return withLock(this, "_saveLock", async () => {
if (thisProgress === this._latestProgressDate) {
await this.options.onSaveProgressAsync?.(this._progress);
}
});
}
_sendProgressDownloadPart() {
if (this._closed)
return;
this.emit("progress", this.status);
}
pause() {
if (this.options.fetchStream.paused) {
return;
}
this._downloadStatus = DownloadStatus.Paused;
this.options.fetchStream.emit("paused");
this.emit("paused");
this._sendProgressDownloadPart();
}
resume() {
if (!this.options.fetchStream.paused) {
return;
}
this._downloadStatus = DownloadStatus.Active;
this.options.fetchStream.emit("resumed");
this.emit("resumed");
this._sendProgressDownloadPart();
}
async close() {
if (this._closed)
return;
if (this._downloadStatus !== DownloadStatus.Finished) {
this._progressStatus.finished();
this._downloadStatus = DownloadStatus.Cancelled;
this._sendProgressDownloadPart();
}
this._closed = true;
this._activeProgram?.abort();
await this.options.onCloseAsync?.();
await this.options.writeStream.close();
await this.options.fetchStream.close();
this.emit("closed");
}
finished(comment) {
if (comment) {
this.options.comment = pushComment(comment, this.options.comment);
}
this._downloadStatus = DownloadStatus.Finished;
}
[Symbol.dispose]() {
return this.close();
}
}
//# sourceMappingURL=download-engine-file.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
import { SaveProgressInfo } from "../../types.js";
export type ProgramSlice = {
start: number;
end: number;
};
export type DownloadSlice = (startChunk: number, endChunk: number) => Promise<void>;
export default abstract class BaseDownloadProgram {
protected savedProgress: SaveProgressInfo;
protected readonly _downloadSlice: DownloadSlice;
protected _aborted: boolean;
protected constructor(_savedProgress: SaveProgressInfo, _downloadSlice: DownloadSlice);
download(): Promise<void>;
protected abstract _createOneSlice(): ProgramSlice | null;
abort(): void;
}

View File

@@ -0,0 +1,38 @@
export default class BaseDownloadProgram {
savedProgress;
_downloadSlice;
_aborted = false;
constructor(_savedProgress, _downloadSlice) {
this._downloadSlice = _downloadSlice;
this.savedProgress = _savedProgress;
}
async download() {
if (this.savedProgress.parallelStreams === 1) {
return await this._downloadSlice(0, this.savedProgress.chunks.length);
}
const activeDownloads = [];
// eslint-disable-next-line no-constant-condition
while (true) {
while (activeDownloads.length >= this.savedProgress.parallelStreams) {
if (this._aborted)
return;
await Promise.race(activeDownloads);
}
const slice = this._createOneSlice();
if (slice == null)
break;
if (this._aborted)
return;
const promise = this._downloadSlice(slice.start, slice.end);
activeDownloads.push(promise);
promise.then(() => {
activeDownloads.splice(activeDownloads.indexOf(promise), 1);
});
}
await Promise.all(activeDownloads);
}
abort() {
this._aborted = true;
}
}
//# sourceMappingURL=base-download-program.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"base-download-program.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/download-file/download-programs/base-download-program.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,OAAO,OAAgB,mBAAmB;IACnC,aAAa,CAAmB;IACvB,cAAc,CAAgB;IACvC,QAAQ,GAAG,KAAK,CAAC;IAE3B,YAAsB,cAAgC,EAAE,cAA6B;QACjF,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC;IACxC,CAAC;IAEM,KAAK,CAAC,QAAQ;QACjB,IAAI,IAAI,CAAC,aAAa,CAAC,eAAe,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,eAAe,GAAmB,EAAE,CAAC;QAE3C,iDAAiD;QACjD,OAAO,IAAI,EAAE,CAAC;YACV,OAAO,eAAe,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC;gBAClE,IAAI,IAAI,CAAC,QAAQ;oBAAE,OAAO;gBAC1B,MAAM,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACxC,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YACrC,IAAI,KAAK,IAAI,IAAI;gBAAE,MAAM;YAEzB,IAAI,IAAI,CAAC,QAAQ;gBAAE,OAAO;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5D,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;gBACd,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;QACP,CAAC;QAED,MAAM,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACvC,CAAC;IAIM,KAAK;QACR,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACzB,CAAC;CACJ"}

View File

@@ -0,0 +1,6 @@
import { SaveProgressInfo } from "../../types.js";
import BaseDownloadProgram, { DownloadSlice, ProgramSlice } from "./base-download-program.js";
export default class DownloadProgramChunks extends BaseDownloadProgram {
constructor(savedProgress: SaveProgressInfo, downloadSlice: DownloadSlice);
protected _createOneSlice(): ProgramSlice | null;
}

View File

@@ -0,0 +1,14 @@
import { ChunkStatus } from "../../types.js";
import BaseDownloadProgram from "./base-download-program.js";
export default class DownloadProgramChunks extends BaseDownloadProgram {
constructor(savedProgress, downloadSlice) {
super(savedProgress, downloadSlice);
}
_createOneSlice() {
const notDownloadedIndex = this.savedProgress.chunks.findIndex(c => c === ChunkStatus.NOT_STARTED);
if (notDownloadedIndex === -1)
return null;
return { start: notDownloadedIndex, end: notDownloadedIndex + 1 };
}
}
//# sourceMappingURL=download-program-chunks.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"download-program-chunks.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/download-file/download-programs/download-program-chunks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAmB,MAAM,gBAAgB,CAAC;AAC7D,OAAO,mBAAkD,MAAM,4BAA4B,CAAC;AAE5F,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,mBAAmB;IAClE,YAAmB,aAA+B,EAAE,aAA4B;QAC5E,KAAK,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACxC,CAAC;IAES,eAAe;QACrB,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,WAAW,CAAC,CAAC;QACnG,IAAI,kBAAkB,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,OAAO,EAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,kBAAkB,GAAG,CAAC,EAAC,CAAC;IACpE,CAAC;CACJ"}

View File

@@ -0,0 +1,7 @@
import { SaveProgressInfo } from "../../types.js";
import BaseDownloadProgram, { DownloadSlice, ProgramSlice } from "./base-download-program.js";
export default class DownloadProgramStream extends BaseDownloadProgram {
constructor(savedProgress: SaveProgressInfo, downloadSlice: DownloadSlice);
protected _createOneSlice(): ProgramSlice | null;
private _findChunksSlices;
}

View File

@@ -0,0 +1,36 @@
import { ChunkStatus } from "../../types.js";
import BaseDownloadProgram from "./base-download-program.js";
export default class DownloadProgramStream extends BaseDownloadProgram {
constructor(savedProgress, downloadSlice) {
super(savedProgress, downloadSlice);
}
_createOneSlice() {
const slice = this._findChunksSlices()[0];
if (!slice)
return null;
const length = slice.end - slice.start;
return { start: Math.floor(slice.start + length / 2), end: slice.end };
}
_findChunksSlices() {
const chunksSlices = [];
let start = 0;
let currentIndex = 0;
for (const chunk of this.savedProgress.chunks) {
if (chunk !== ChunkStatus.NOT_STARTED) {
if (start === currentIndex) {
start = ++currentIndex;
continue;
}
chunksSlices.push({ start, end: currentIndex });
start = ++currentIndex;
continue;
}
currentIndex++;
}
if (start !== currentIndex) {
chunksSlices.push({ start, end: currentIndex });
}
return chunksSlices.sort((a, b) => (b.end - b.start) - (a.end - a.start));
}
}
//# sourceMappingURL=download-program-stream.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"download-program-stream.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/download-file/download-programs/download-program-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAmB,MAAM,gBAAgB,CAAC;AAC7D,OAAO,mBAAkD,MAAM,4BAA4B,CAAC;AAG5F,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,mBAAmB;IAClE,YAAmB,aAA+B,EAAE,aAA4B;QAC5E,KAAK,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACxC,CAAC;IAES,eAAe;QACrB,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC;QACvC,OAAO,EAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAC,CAAC;IACzE,CAAC;IAEO,iBAAiB;QACrB,MAAM,YAAY,GAAmB,EAAE,CAAC;QAExC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YAC5C,IAAI,KAAK,KAAK,WAAW,CAAC,WAAW,EAAE,CAAC;gBACpC,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;oBACzB,KAAK,GAAG,EAAE,YAAY,CAAC;oBACvB,SAAS;gBACb,CAAC;gBACD,YAAY,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,GAAG,EAAE,YAAY,EAAC,CAAC,CAAC;gBAC9C,KAAK,GAAG,EAAE,YAAY,CAAC;gBACvB,SAAS;YACb,CAAC;YAED,YAAY,EAAE,CAAC;QACnB,CAAC;QAED,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,GAAG,EAAE,YAAY,EAAC,CAAC,CAAC;QAClD,CAAC;QAED,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9E,CAAC;CACJ"}

View File

@@ -0,0 +1,6 @@
import { SaveProgressInfo } from "../../types.js";
import { DownloadSlice } from "./base-download-program.js";
import DownloadProgramChunks from "./download-program-chunks.js";
import DownloadProgramStream from "./download-program-stream.js";
export type AvailablePrograms = "stream" | "chunks";
export default function switchProgram(savedProgress: SaveProgressInfo, downloadSlice: DownloadSlice, name?: AvailablePrograms): DownloadProgramChunks | DownloadProgramStream;

View File

@@ -0,0 +1,12 @@
import DownloadProgramChunks from "./download-program-chunks.js";
import DownloadProgramStream from "./download-program-stream.js";
export default function switchProgram(savedProgress, downloadSlice, name) {
switch (name) {
case "chunks":
return new DownloadProgramChunks(savedProgress, downloadSlice);
case "stream":
default:
return new DownloadProgramStream(savedProgress, downloadSlice);
}
}
//# sourceMappingURL=switch-program.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"switch-program.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/download-file/download-programs/switch-program.ts"],"names":[],"mappings":"AAEA,OAAO,qBAAqB,MAAM,8BAA8B,CAAC;AACjE,OAAO,qBAAqB,MAAM,8BAA8B,CAAC;AAIjE,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,aAA+B,EAAE,aAA4B,EAAE,IAAwB;IACzH,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,QAAQ;YACT,OAAO,IAAI,qBAAqB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;QACnE,KAAK,QAAQ,CAAC;QACd;YACI,OAAO,IAAI,qBAAqB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACvE,CAAC;AACL,CAAC"}

View File

@@ -0,0 +1,43 @@
export type ProgressStatus = {
totalBytes: number;
totalDownloadParts: number;
fileName: string;
comment?: string;
downloadPart: number;
transferredBytes: number;
startTime: number;
endTime: number;
transferAction: string;
downloadStatus: DownloadStatus;
downloadFlags: DownloadFlags[];
};
export declare enum DownloadStatus {
Loading = "Loading",
Active = "Active",
Paused = "Paused",
NotStarted = "NotStarted",
Finished = "Finished",
Cancelled = "Cancelled",
Error = "Error"
}
export declare enum DownloadFlags {
Existing = "Existing",
DownloadSequence = "DownloadSequence"
}
export default class ProgressStatusFile {
readonly totalDownloadParts: number;
readonly fileName: string;
readonly comment?: string;
readonly downloadPart: number;
readonly transferredBytes: number;
readonly transferAction: string;
downloadStatus: DownloadStatus;
downloadFlags: DownloadFlags[];
totalBytes: number;
startTime: number;
endTime: number;
constructor(totalDownloadParts: number, fileName: string, transferAction?: string, downloadFlags?: DownloadFlags[], comment?: string, downloadPart?: number, transferredBytes?: number, downloadStatus?: DownloadStatus);
started(): void;
finished(): void;
createStatus(downloadPart: number, transferredBytes: number, totalBytes?: number, downloadStatus?: DownloadStatus, comment?: string | undefined): ProgressStatusFile;
}

View File

@@ -0,0 +1,52 @@
export var DownloadStatus;
(function (DownloadStatus) {
DownloadStatus["Loading"] = "Loading";
DownloadStatus["Active"] = "Active";
DownloadStatus["Paused"] = "Paused";
DownloadStatus["NotStarted"] = "NotStarted";
DownloadStatus["Finished"] = "Finished";
DownloadStatus["Cancelled"] = "Cancelled";
DownloadStatus["Error"] = "Error";
})(DownloadStatus || (DownloadStatus = {}));
export var DownloadFlags;
(function (DownloadFlags) {
DownloadFlags["Existing"] = "Existing";
DownloadFlags["DownloadSequence"] = "DownloadSequence";
})(DownloadFlags || (DownloadFlags = {}));
export default class ProgressStatusFile {
totalDownloadParts;
fileName;
comment;
downloadPart;
transferredBytes;
transferAction;
downloadStatus = DownloadStatus.Active;
downloadFlags = [];
totalBytes = 0;
startTime = 0;
endTime = 0;
constructor(totalDownloadParts, fileName, transferAction = "Transferring", downloadFlags = [], comment, downloadPart = 0, transferredBytes = 0, downloadStatus = DownloadStatus.Active) {
this.transferAction = transferAction;
this.transferredBytes = transferredBytes;
this.downloadPart = downloadPart;
this.comment = comment;
this.fileName = fileName;
this.totalDownloadParts = totalDownloadParts;
this.downloadFlags = downloadFlags;
this.downloadStatus = downloadStatus;
}
started() {
this.startTime = Date.now();
}
finished() {
this.endTime = Date.now();
}
createStatus(downloadPart, transferredBytes, totalBytes = this.totalBytes, downloadStatus = DownloadStatus.Active, comment = this.comment) {
const newStatus = new ProgressStatusFile(this.totalDownloadParts, this.fileName, this.transferAction, this.downloadFlags, comment, downloadPart, transferredBytes, downloadStatus);
newStatus.totalBytes = totalBytes;
newStatus.startTime = this.startTime;
newStatus.endTime = this.endTime;
return newStatus;
}
}
//# sourceMappingURL=progress-status-file.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"progress-status-file.js","sourceRoot":"","sources":["../../../../src/download/download-engine/download-file/progress-status-file.ts"],"names":[],"mappings":"AAcA,MAAM,CAAN,IAAY,cAQX;AARD,WAAY,cAAc;IACtB,qCAAmB,CAAA;IACnB,mCAAiB,CAAA;IACjB,mCAAiB,CAAA;IACjB,2CAAyB,CAAA;IACzB,uCAAqB,CAAA;IACrB,yCAAuB,CAAA;IACvB,iCAAe,CAAA;AACnB,CAAC,EARW,cAAc,KAAd,cAAc,QAQzB;AAED,MAAM,CAAN,IAAY,aAGX;AAHD,WAAY,aAAa;IACrB,sCAAqB,CAAA;IACrB,sDAAqC,CAAA;AACzC,CAAC,EAHW,aAAa,KAAb,aAAa,QAGxB;AAED,MAAM,CAAC,OAAO,OAAO,kBAAkB;IACnB,kBAAkB,CAAS;IAC3B,QAAQ,CAAS;IACjB,OAAO,CAAU;IACjB,YAAY,CAAS;IACrB,gBAAgB,CAAS;IACzB,cAAc,CAAS;IAChC,cAAc,GAAmB,cAAc,CAAC,MAAM,CAAC;IACvD,aAAa,GAAoB,EAAE,CAAC;IACpC,UAAU,GAAW,CAAC,CAAC;IACvB,SAAS,GAAW,CAAC,CAAC;IACtB,OAAO,GAAW,CAAC,CAAC;IAE3B,YACI,kBAA0B,EAC1B,QAAgB,EAChB,cAAc,GAAG,cAAc,EAC/B,gBAAiC,EAAE,EACnC,OAAgB,EAChB,YAAY,GAAG,CAAC,EAChB,gBAAgB,GAAG,CAAC,EACpB,cAAc,GAAG,cAAc,CAAC,MAAM;QAEtC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;QAC7C,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACzC,CAAC;IAEM,OAAO;QACV,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAChC,CAAC;IAEM,QAAQ;QACX,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9B,CAAC;IAEM,YAAY,CAAC,YAAoB,EAAE,gBAAwB,EAAE,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,OAAO;QAC5J,MAAM,SAAS,GAAG,IAAI,kBAAkB,CACpC,IAAI,CAAC,kBAAkB,EACvB,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,aAAa,EAClB,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,cAAc,CACjB,CAAC;QAEF,SAAS,CAAC,UAAU,GAAG,UAAU,CAAC;QAClC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACrC,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAEjC,OAAO,SAAS,CAAC;IACrB,CAAC;CACJ"}

View File

@@ -0,0 +1 @@
export declare function pushComment(newComment: string, comment?: string): string;

View File

@@ -0,0 +1,7 @@
export function pushComment(newComment, comment = "") {
if (comment.length) {
return `${newComment}, ${comment}`;
}
return newComment;
}
//# sourceMappingURL=push-comment.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"push-comment.js","sourceRoot":"","sources":["../../../../../src/download/download-engine/download-file/utils/push-comment.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,UAAkB,EAAE,OAAO,GAAG,EAAE;IACxD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,GAAG,UAAU,KAAK,OAAO,EAAE,CAAC;IACvC,CAAC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC"}