filemail-sdk 10.0.0 → 10.2.1
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/dist/src/autoDownloader/autoDownloader.d.ts.map +1 -1
- package/dist/src/autoDownloader/autoDownloader.js +0 -1
- package/dist/src/autoDownloader/autoDownloader.js.map +1 -1
- package/dist/src/client/downloader/node/nodeTransferDownloader.d.ts.map +1 -1
- package/dist/src/client/downloader/node/nodeTransferDownloader.js +0 -2
- package/dist/src/client/downloader/node/nodeTransferDownloader.js.map +1 -1
- package/dist/src/client/uploader/transferUploaderBase.d.ts +1 -0
- package/dist/src/client/uploader/transferUploaderBase.d.ts.map +1 -1
- package/dist/src/client/uploader/transferUploaderBase.js +22 -3
- package/dist/src/client/uploader/transferUploaderBase.js.map +1 -1
- package/dist/src/downloader/api/node/nodeFileServerDownloadClient.d.ts.map +1 -1
- package/dist/src/downloader/api/node/nodeFileServerDownloadClient.js +6 -2
- package/dist/src/downloader/api/node/nodeFileServerDownloadClient.js.map +1 -1
- package/dist/src/downloader/chunkDownloader.d.ts.map +1 -1
- package/dist/src/downloader/chunkDownloader.js +0 -1
- package/dist/src/downloader/chunkDownloader.js.map +1 -1
- package/dist/src/downloader/downloadTracker.d.ts.map +1 -1
- package/dist/src/downloader/downloadTracker.js +0 -1
- package/dist/src/downloader/downloadTracker.js.map +1 -1
- package/dist/src/downloader/filesDownloader.d.ts.map +1 -1
- package/dist/src/downloader/filesDownloader.js +0 -1
- package/dist/src/downloader/filesDownloader.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/uploader/eventArgs/filesRegistrationBatchFailedEventArgs.d.ts +6 -0
- package/dist/src/uploader/eventArgs/filesRegistrationBatchFailedEventArgs.d.ts.map +1 -0
- package/dist/src/uploader/eventArgs/filesRegistrationBatchFailedEventArgs.js +2 -0
- package/dist/src/uploader/eventArgs/filesRegistrationBatchFailedEventArgs.js.map +1 -0
- package/dist/src/uploader/export/transferUploadExportData.d.ts +4 -3
- package/dist/src/uploader/export/transferUploadExportData.d.ts.map +1 -1
- package/dist/src/uploader/export/transferUploadExportData.js.map +1 -1
- package/dist/src/uploader/export/transferUploadMetadata.d.ts +0 -2
- package/dist/src/uploader/export/transferUploadMetadata.d.ts.map +1 -1
- package/dist/src/uploader/export/transferUploadMetadata.js.map +1 -1
- package/dist/src/uploader/options/transferUploadAppendInfo.d.ts +1 -0
- package/dist/src/uploader/options/transferUploadAppendInfo.d.ts.map +1 -1
- package/dist/src/uploader/options/transferUploadAppendInfo.js.map +1 -1
- package/dist/src/uploader/state/continuousChunksCalculator.d.ts +1 -0
- package/dist/src/uploader/state/continuousChunksCalculator.d.ts.map +1 -1
- package/dist/src/uploader/state/continuousChunksCalculator.js +8 -2
- package/dist/src/uploader/state/continuousChunksCalculator.js.map +1 -1
- package/dist/src/uploader/state/transferUploadState.d.ts.map +1 -1
- package/dist/src/uploader/state/transferUploadState.js +3 -2
- package/dist/src/uploader/state/transferUploadState.js.map +1 -1
- package/dist/src/uploader/transferFilesRegistrar.d.ts +30 -0
- package/dist/src/uploader/transferFilesRegistrar.d.ts.map +1 -0
- package/dist/src/uploader/transferFilesRegistrar.js +160 -0
- package/dist/src/uploader/transferFilesRegistrar.js.map +1 -0
- package/dist/src/uploader/transferUpload.d.ts +7 -3
- package/dist/src/uploader/transferUpload.d.ts.map +1 -1
- package/dist/src/uploader/transferUpload.js +67 -73
- package/dist/src/uploader/transferUpload.js.map +1 -1
- package/dist/src/uploader/transferUploadAcker.d.ts +1 -2
- package/dist/src/uploader/transferUploadAcker.d.ts.map +1 -1
- package/dist/src/uploader/transferUploadAcker.js +12 -8
- package/dist/src/uploader/transferUploadAcker.js.map +1 -1
- package/dist/src/uploader/transferUploadEvent.d.ts +1 -0
- package/dist/src/uploader/transferUploadEvent.d.ts.map +1 -1
- package/dist/src/uploader/transferUploadEvent.js +1 -0
- package/dist/src/uploader/transferUploadEvent.js.map +1 -1
- package/dist/src/utils/api/dtos/registerTransferFilesRequest.d.ts +1 -0
- package/dist/src/utils/api/dtos/registerTransferFilesRequest.d.ts.map +1 -1
- package/dist/src/utils/api/dtos/registerTransferFilesRequest.js.map +1 -1
- package/dist/src/utils/api/dtos/registerTransferFilesResponse.d.ts +6 -2
- package/dist/src/utils/api/dtos/registerTransferFilesResponse.d.ts.map +1 -1
- package/dist/src/utils/api/dtos/registerTransferFilesResponse.js.map +1 -1
- package/dist/src/utils/api/node/nodeApiClient.d.ts.map +1 -1
- package/dist/src/utils/api/node/nodeApiClient.js +1 -0
- package/dist/src/utils/api/node/nodeApiClient.js.map +1 -1
- package/dist/src/utils/fileSystem/node/nodeFileSystemService.d.ts.map +1 -1
- package/dist/src/utils/fileSystem/node/nodeFileSystemService.js +0 -3
- package/dist/src/utils/fileSystem/node/nodeFileSystemService.js.map +1 -1
- package/dist/src/utils/mergeAbortAndPauseSignals.d.ts +6 -1
- package/dist/src/utils/mergeAbortAndPauseSignals.d.ts.map +1 -1
- package/dist/src/utils/mergeAbortAndPauseSignals.js +14 -7
- package/dist/src/utils/mergeAbortAndPauseSignals.js.map +1 -1
- package/dist/src/utils/promiseAll.d.ts.map +1 -1
- package/dist/src/utils/promiseAll.js +0 -1
- package/dist/src/utils/promiseAll.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunkDownloader.js","sourceRoot":"","sources":["../../../src/downloader/chunkDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-await-in-loop */\nimport { RequestError } from \"got\";\nimport sleep from \"abortable-sleep\";\n\nimport TransferStatus from \"../utils/types/transferStatus.js\";\nimport DownloadError from \"./dtos/downloadError.js\";\nimport TransferDownloadEvent from \"./dtos/downloadEvent.js\";\nimport DownloadErrorCode from \"./dtos/downloadErrorCode.js\";\nimport DownloadFileChunkProgress from \"./downloadStatus/downloadFileChunkProgress.js\";\nimport { isBaseResponse } from \"../utils/api/dtos/baseResponse.js\";\n\nimport type DownloadFileChunkInfo from \"./dtos/downloadFileChunkInfo.js\";\nimport type DownloadFileInfo from \"./dtos/downloadFileInfo.js\";\nimport type DownloadOptions from \"./downloadOptions.js\";\nimport type DownloadState from \"./downloadStatus/downloadState.js\";\nimport type FileServerClientFactory from \"../utils/api/fileServerClientFactory.js\";\nimport type ChunkStreamProviderFactory from \"../utils/fileSystem/chunkStreamProviderFactory.js\";\nimport type EventsEngine from \"../utils/events/eventsEngine.js\";\nimport type FileServerDownloadClient from \"./api/fileServerDownloadClient.js\";\nimport type ChunkProgressEvent from \"../utils/events/chunkProgressEvent.js\";\nimport type FileDownloadFailedEventArgs from \"./eventArgs/fileDownloadFailedEventArgs.js\";\nimport type DownloadLogger from \"./downloadLogger.js\";\nimport type { ChunkStreamProviderEncryptionData } from \"../utils/fileSystem/chunkStreamProvider.js\";\n\nexport default class ChunkDownloader {\n #logger: DownloadLogger;\n #transferId: string;\n #chunk: DownloadFileChunkInfo;\n #file: DownloadFileInfo;\n #downloadState: DownloadState;\n #options: DownloadOptions;\n #fileServerClientFactory: FileServerClientFactory;\n #chunkStreamProviderFactory: ChunkStreamProviderFactory<string>;\n #eventsEngine: EventsEngine;\n #chunkDownloadClient: FileServerDownloadClient;\n #encryptionData?: ChunkStreamProviderEncryptionData;\n #bytesTransferred = 0;\n #running = false;\n #consecutiveNetworkErrors = 0;\n\n constructor(\n transferId: string,\n file: DownloadFileInfo,\n chunk: DownloadFileChunkInfo,\n downloadState: DownloadState,\n options: DownloadOptions,\n fileServerClientFactory: FileServerClientFactory,\n chunkStreamProviderFactory: ChunkStreamProviderFactory<string>,\n eventsEngine: EventsEngine,\n logger: DownloadLogger,\n encryptionData?: ChunkStreamProviderEncryptionData,\n ) {\n this.#transferId = transferId;\n this.#options = options;\n this.#file = file;\n this.#chunk = chunk;\n this.#downloadState = downloadState;\n this.#fileServerClientFactory = fileServerClientFactory;\n this.#chunkStreamProviderFactory = chunkStreamProviderFactory;\n this.#eventsEngine = eventsEngine;\n this.#chunkDownloadClient = this.#fileServerClientFactory.createFileServerDownloadClient(this.#file.url, this.#chunk.start, this.#chunk.end, this.#transferId, this.#file.name, this.#options);\n this.#logger = logger;\n this.#encryptionData = encryptionData;\n }\n\n async download(): Promise<void> {\n this.#throwIfRunning();\n this.#throwIfMissingDownloadPath();\n\n this.#running = true;\n\n let writtenCorrectly = false;\n let attempts = 0;\n let writeErrors = 0;\n let networkErrors = 0;\n let apiReturnedNotOkResponseStatus: boolean = false;\n let lastError: Error | null = null;\n let unhandledError: Error | null = null;\n\n try {\n this.#downloadState.chunkDownloadStarted(this.#file, this.#chunk);\n\n this.#addEventListeners();\n\n let fileserverMd5Promise: Promise<string> | null = this.#options.checkChunksMd5\n ? this.#chunkDownloadClient.getMd5Checksum()\n : null;\n\n while (writtenCorrectly === false && this.#canRetry(lastError as Error, writeErrors, networkErrors, apiReturnedNotOkResponseStatus)) {\n attempts += 1;\n\n this.#bytesTransferred = 0;\n\n if (this.#isDownloadClientRecreateNeeded()) {\n this.#recreateDownloadClient();\n\n fileserverMd5Promise = this.#options.checkChunksMd5\n ? this.#chunkDownloadClient.getMd5Checksum()\n : null;\n }\n\n const chunkWriter = this.#chunkStreamProviderFactory.provide(this.#file.temporaryDownloadPath!, this.#chunk.start ?? 0, this.#chunk.chunkSize, this.#encryptionData);\n\n try {\n await this.#chunkDownloadClient.download(chunkWriter, this.#encryptionData);\n\n if (this.#bytesTransferred !== this.#chunk.chunkSize) {\n if (this.#bytesTransferred > this.#chunk.chunkSize)\n this.#downloadState.possibleSupersizedFile(this.#file);\n\n throw new DownloadError(`Download request returned incorrect amount of data. Expected=${this.#chunk.chunkSize} Received=${this.#bytesTransferred}`, undefined, DownloadErrorCode.FileserverResponseWrongSize);\n }\n\n this.#consecutiveNetworkErrors = 0;\n networkErrors = 0;\n this.#downloadState.networkOk();\n\n if (this.#downloadState.status !== TransferStatus.Aborting) {\n if (fileserverMd5Promise !== null) {\n const remoteMd5 = await fileserverMd5Promise;\n const localMd5 = await chunkWriter.getMd5Checksum(`hex`);\n if (remoteMd5.toLowerCase() === localMd5.toLowerCase())\n writtenCorrectly = true;\n else {\n writeErrors += 1;\n lastError = new DownloadError(`MD5 checksum incorrect: fileserver=${remoteMd5} local=${localMd5}`);\n }\n }\n else\n writtenCorrectly = true;\n }\n }\n catch (error) {\n // note: getting an exception here may be caused by abort or stop operations\n // both operations immediately interrupt HTTP download request by calling chunkDownloadClient.release()\n if (this.#downloadState.pauseImmediately || this.#downloadState.status === TransferStatus.Aborting)\n lastError = null;\n else {\n lastError = error as Error;\n\n if (lastError instanceof RequestError) {\n if (this.#isApiNotOkResponseStatusResponse(lastError))\n apiReturnedNotOkResponseStatus = true;\n else {\n this.#consecutiveNetworkErrors += 1;\n networkErrors += 1;\n this.#downloadState.networkFailure();\n }\n }\n else\n writeErrors += 1;\n\n this.#logger.logError(lastError, `[CHUNK_DOWNLOADER_ERROR] Error in retry loop when downloading chunk attempt=${attempts} writeerrors=${writeErrors} networkerrors=${networkErrors}`, this.#errorInfoDump());\n }\n }\n finally {\n await chunkWriter?.release();\n this.#chunkDownloadClient?.release();\n\n let sleepTime = 0;\n if (this.#downloadState.isThereNetworkProblem)\n sleepTime = this.#options.fileserverOfflineCheckIntervalMillis;\n else if (networkErrors > 0) {\n const pow = Math.min(networkErrors, this.#options.fileserverOfflineAfterConsecutiveAttempts);\n sleepTime = this.#options.fileserverOfflineCheckIntervalMillis * (2 ** (pow - this.#options.fileserverOfflineAfterConsecutiveAttempts));\n }\n\n if (sleepTime > 0)\n await sleep(sleepTime);\n }\n }\n }\n catch (error) {\n unhandledError = error as Error;\n this.#logger.logError(unhandledError, `[CHUNK_DOWNLOADER_ERROR] Unhandled error when downloading chunk`, this.#errorInfoDump());\n }\n finally {\n this.#removeEventListeners();\n }\n\n if (writtenCorrectly)\n this.#downloadState.chunkDownloadCompleted(this.#file, this.#chunk);\n else {\n let downloadError: DownloadError | null = null;\n const failureCode = this.#toFailureCode(unhandledError ?? lastError);\n\n if (unhandledError)\n downloadError = new DownloadError(`Unhandled chunk download error for file ${this.#file.url} chunk ${this.#chunk.chunkNumber}`, { cause: unhandledError as Error }, failureCode);\n else if (lastError)\n downloadError = new DownloadError(`Chunk download failed for file ${this.#file.url} chunk ${this.#chunk.chunkNumber} attempt ${attempts}.`, { cause: lastError as Error }, failureCode);\n\n if (downloadError !== null) {\n this.#downloadState.chunkDownloadFailed(\n this.#file,\n this.#chunk,\n downloadError,\n );\n }\n }\n\n this.#running = false;\n }\n\n #isDownloadClientRecreateNeeded(): boolean {\n return this.#consecutiveNetworkErrors > 0 && this.#consecutiveNetworkErrors % this.#options.fileserverOfflineAfterConsecutiveAttempts === 0;\n }\n\n #recreateDownloadClient() {\n this.#chunkDownloadClient.removeEventListener(`progress`, this.#onProgress);\n\n this.#chunkDownloadClient = this.#fileServerClientFactory.createFileServerDownloadClient(this.#file.url, this.#chunk.start, this.#chunk.end, this.#transferId, this.#file.name, this.#options);\n\n this.#chunkDownloadClient.addEventListener(`progress`, this.#onProgress);\n }\n\n #throwIfRunning() {\n if (this.#running)\n throw new DownloadError(`This instance of chunk downloader is already in use. Please create a new one.`);\n }\n\n #throwIfMissingDownloadPath() {\n if (!this.#file.temporaryDownloadPath)\n throw new DownloadError(`Download file ${this.#file.externalId}/${this.#file.name}/${this.#file.downloadPath} is missing the required \"temporaryDownloadPath\"`);\n }\n\n #addEventListeners() {\n this.#eventsEngine.addEventListener(TransferDownloadEvent.Aborting, this.#onAbortRequested);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.Pausing, this.#onPauseRequested);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#chunkDownloadClient.addEventListener(`progress`, this.#onProgress);\n }\n\n #removeEventListeners() {\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.Aborting, this.#onAbortRequested);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.Pausing, this.#onPauseRequested);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#chunkDownloadClient.removeEventListener(`progress`, this.#onProgress);\n }\n\n #canRetry(error: Error | null, writeErrors: number, networkErrors: number, apiReturnedNotOkResponseStatus: boolean) {\n if (this.#downloadState.status === TransferStatus.Aborting || this.#downloadState.status === TransferStatus.Pausing)\n return false;\n\n if (this.#file.isFailed)\n return false;\n\n if (apiReturnedNotOkResponseStatus)\n return false;\n\n if (this.#isDiskFullError(error))\n return false;\n\n if (error && error instanceof RequestError)\n return this.#options.fileserverAttemptLimit <= 0 || networkErrors < this.#options.fileserverAttemptLimit!;\n\n return this.#options.maxWriteAttempts! < 0 || writeErrors < this.#options.maxWriteAttempts!;\n }\n\n #isApiNotOkResponseStatusResponse(error: RequestError): boolean {\n try {\n if (typeof error.response?.body !== `string`)\n return false;\n\n const response = JSON.parse(error.response?.body);\n\n if (!isBaseResponse(response))\n return false;\n\n return response.responsestatus !== `OK`;\n }\n catch {\n return false;\n }\n }\n\n /**\n * This method aborts pending download - it can be achieved only by destroying the download client\n * (which in turn destroys the underlying download HTTP request). This operation\n * will throw an expected exception inside download method (in main while loop). See {@link download} method.\n */\n #interruptDownload = () => {\n this.#chunkDownloadClient?.release();\n };\n\n #onAbortRequested = () => {\n this.#interruptDownload();\n };\n\n #onPauseRequested = () => {\n if (this.#downloadState.pauseImmediately)\n this.#interruptDownload();\n };\n\n #onFileFailed = (args: FileDownloadFailedEventArgs) => {\n if (this.#file.externalId === args.file.id)\n this.#chunkDownloadClient?.release();\n };\n\n #onProgress = (args: ChunkProgressEvent) => {\n this.#bytesTransferred = args.transferredBytesTotal;\n this.#downloadState.chunkDownloadProgressed(this.#file, this.#chunk, args);\n };\n\n #errorInfoDump() {\n return {\n fileid: this.#file.externalId,\n filename: this.#file.name,\n chunk: DownloadFileChunkProgress.FromChunkInfo(this.#chunk),\n };\n }\n\n #toFailureCode(error: Error | null): DownloadErrorCode | undefined {\n if (this.#isDiskFullError(error))\n return DownloadErrorCode.DiskFull;\n\n return undefined;\n }\n\n #isDiskFullError(error: unknown): boolean {\n if (!error)\n return false;\n\n let current = error as { message?: string, code?: string, cause?: unknown } | undefined;\n for (let depth = 0; depth < 8 && current; depth++) {\n if (current.code === `ENOSPC`)\n return true;\n\n if (typeof current.message === `string` && current.message.includes(`ENOSPC`))\n return true;\n\n current = current.cause as { message?: string, code?: string, cause?: unknown } | undefined;\n }\n\n return false;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chunkDownloader.js","sourceRoot":"","sources":["../../../src/downloader/chunkDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["import { RequestError } from \"got\";\nimport sleep from \"abortable-sleep\";\n\nimport TransferStatus from \"../utils/types/transferStatus.js\";\nimport DownloadError from \"./dtos/downloadError.js\";\nimport TransferDownloadEvent from \"./dtos/downloadEvent.js\";\nimport DownloadErrorCode from \"./dtos/downloadErrorCode.js\";\nimport DownloadFileChunkProgress from \"./downloadStatus/downloadFileChunkProgress.js\";\nimport { isBaseResponse } from \"../utils/api/dtos/baseResponse.js\";\n\nimport type DownloadFileChunkInfo from \"./dtos/downloadFileChunkInfo.js\";\nimport type DownloadFileInfo from \"./dtos/downloadFileInfo.js\";\nimport type DownloadOptions from \"./downloadOptions.js\";\nimport type DownloadState from \"./downloadStatus/downloadState.js\";\nimport type FileServerClientFactory from \"../utils/api/fileServerClientFactory.js\";\nimport type ChunkStreamProviderFactory from \"../utils/fileSystem/chunkStreamProviderFactory.js\";\nimport type EventsEngine from \"../utils/events/eventsEngine.js\";\nimport type FileServerDownloadClient from \"./api/fileServerDownloadClient.js\";\nimport type ChunkProgressEvent from \"../utils/events/chunkProgressEvent.js\";\nimport type FileDownloadFailedEventArgs from \"./eventArgs/fileDownloadFailedEventArgs.js\";\nimport type DownloadLogger from \"./downloadLogger.js\";\nimport type { ChunkStreamProviderEncryptionData } from \"../utils/fileSystem/chunkStreamProvider.js\";\n\nexport default class ChunkDownloader {\n #logger: DownloadLogger;\n #transferId: string;\n #chunk: DownloadFileChunkInfo;\n #file: DownloadFileInfo;\n #downloadState: DownloadState;\n #options: DownloadOptions;\n #fileServerClientFactory: FileServerClientFactory;\n #chunkStreamProviderFactory: ChunkStreamProviderFactory<string>;\n #eventsEngine: EventsEngine;\n #chunkDownloadClient: FileServerDownloadClient;\n #encryptionData?: ChunkStreamProviderEncryptionData;\n #bytesTransferred = 0;\n #running = false;\n #consecutiveNetworkErrors = 0;\n\n constructor(\n transferId: string,\n file: DownloadFileInfo,\n chunk: DownloadFileChunkInfo,\n downloadState: DownloadState,\n options: DownloadOptions,\n fileServerClientFactory: FileServerClientFactory,\n chunkStreamProviderFactory: ChunkStreamProviderFactory<string>,\n eventsEngine: EventsEngine,\n logger: DownloadLogger,\n encryptionData?: ChunkStreamProviderEncryptionData,\n ) {\n this.#transferId = transferId;\n this.#options = options;\n this.#file = file;\n this.#chunk = chunk;\n this.#downloadState = downloadState;\n this.#fileServerClientFactory = fileServerClientFactory;\n this.#chunkStreamProviderFactory = chunkStreamProviderFactory;\n this.#eventsEngine = eventsEngine;\n this.#chunkDownloadClient = this.#fileServerClientFactory.createFileServerDownloadClient(this.#file.url, this.#chunk.start, this.#chunk.end, this.#transferId, this.#file.name, this.#options);\n this.#logger = logger;\n this.#encryptionData = encryptionData;\n }\n\n async download(): Promise<void> {\n this.#throwIfRunning();\n this.#throwIfMissingDownloadPath();\n\n this.#running = true;\n\n let writtenCorrectly = false;\n let attempts = 0;\n let writeErrors = 0;\n let networkErrors = 0;\n let apiReturnedNotOkResponseStatus: boolean = false;\n let lastError: Error | null = null;\n let unhandledError: Error | null = null;\n\n try {\n this.#downloadState.chunkDownloadStarted(this.#file, this.#chunk);\n\n this.#addEventListeners();\n\n let fileserverMd5Promise: Promise<string> | null = this.#options.checkChunksMd5\n ? this.#chunkDownloadClient.getMd5Checksum()\n : null;\n\n while (writtenCorrectly === false && this.#canRetry(lastError as Error, writeErrors, networkErrors, apiReturnedNotOkResponseStatus)) {\n attempts += 1;\n\n this.#bytesTransferred = 0;\n\n if (this.#isDownloadClientRecreateNeeded()) {\n this.#recreateDownloadClient();\n\n fileserverMd5Promise = this.#options.checkChunksMd5\n ? this.#chunkDownloadClient.getMd5Checksum()\n : null;\n }\n\n const chunkWriter = this.#chunkStreamProviderFactory.provide(this.#file.temporaryDownloadPath!, this.#chunk.start ?? 0, this.#chunk.chunkSize, this.#encryptionData);\n\n try {\n await this.#chunkDownloadClient.download(chunkWriter, this.#encryptionData);\n\n if (this.#bytesTransferred !== this.#chunk.chunkSize) {\n if (this.#bytesTransferred > this.#chunk.chunkSize)\n this.#downloadState.possibleSupersizedFile(this.#file);\n\n throw new DownloadError(`Download request returned incorrect amount of data. Expected=${this.#chunk.chunkSize} Received=${this.#bytesTransferred}`, undefined, DownloadErrorCode.FileserverResponseWrongSize);\n }\n\n this.#consecutiveNetworkErrors = 0;\n networkErrors = 0;\n this.#downloadState.networkOk();\n\n if (this.#downloadState.status !== TransferStatus.Aborting) {\n if (fileserverMd5Promise !== null) {\n const remoteMd5 = await fileserverMd5Promise;\n const localMd5 = await chunkWriter.getMd5Checksum(`hex`);\n if (remoteMd5.toLowerCase() === localMd5.toLowerCase())\n writtenCorrectly = true;\n else {\n writeErrors += 1;\n lastError = new DownloadError(`MD5 checksum incorrect: fileserver=${remoteMd5} local=${localMd5}`);\n }\n }\n else\n writtenCorrectly = true;\n }\n }\n catch (error) {\n // note: getting an exception here may be caused by abort or stop operations\n // both operations immediately interrupt HTTP download request by calling chunkDownloadClient.release()\n if (this.#downloadState.pauseImmediately || this.#downloadState.status === TransferStatus.Aborting)\n lastError = null;\n else {\n lastError = error as Error;\n\n if (lastError instanceof RequestError) {\n if (this.#isApiNotOkResponseStatusResponse(lastError))\n apiReturnedNotOkResponseStatus = true;\n else {\n this.#consecutiveNetworkErrors += 1;\n networkErrors += 1;\n this.#downloadState.networkFailure();\n }\n }\n else\n writeErrors += 1;\n\n this.#logger.logError(lastError, `[CHUNK_DOWNLOADER_ERROR] Error in retry loop when downloading chunk attempt=${attempts} writeerrors=${writeErrors} networkerrors=${networkErrors}`, this.#errorInfoDump());\n }\n }\n finally {\n await chunkWriter?.release();\n this.#chunkDownloadClient?.release();\n\n let sleepTime = 0;\n if (this.#downloadState.isThereNetworkProblem)\n sleepTime = this.#options.fileserverOfflineCheckIntervalMillis;\n else if (networkErrors > 0) {\n const pow = Math.min(networkErrors, this.#options.fileserverOfflineAfterConsecutiveAttempts);\n sleepTime = this.#options.fileserverOfflineCheckIntervalMillis * (2 ** (pow - this.#options.fileserverOfflineAfterConsecutiveAttempts));\n }\n\n if (sleepTime > 0)\n await sleep(sleepTime);\n }\n }\n }\n catch (error) {\n unhandledError = error as Error;\n this.#logger.logError(unhandledError, `[CHUNK_DOWNLOADER_ERROR] Unhandled error when downloading chunk`, this.#errorInfoDump());\n }\n finally {\n this.#removeEventListeners();\n }\n\n if (writtenCorrectly)\n this.#downloadState.chunkDownloadCompleted(this.#file, this.#chunk);\n else {\n let downloadError: DownloadError | null = null;\n const failureCode = this.#toFailureCode(unhandledError ?? lastError);\n\n if (unhandledError)\n downloadError = new DownloadError(`Unhandled chunk download error for file ${this.#file.url} chunk ${this.#chunk.chunkNumber}`, { cause: unhandledError as Error }, failureCode);\n else if (lastError)\n downloadError = new DownloadError(`Chunk download failed for file ${this.#file.url} chunk ${this.#chunk.chunkNumber} attempt ${attempts}.`, { cause: lastError as Error }, failureCode);\n\n if (downloadError !== null) {\n this.#downloadState.chunkDownloadFailed(\n this.#file,\n this.#chunk,\n downloadError,\n );\n }\n }\n\n this.#running = false;\n }\n\n #isDownloadClientRecreateNeeded(): boolean {\n return this.#consecutiveNetworkErrors > 0 && this.#consecutiveNetworkErrors % this.#options.fileserverOfflineAfterConsecutiveAttempts === 0;\n }\n\n #recreateDownloadClient() {\n this.#chunkDownloadClient.removeEventListener(`progress`, this.#onProgress);\n\n this.#chunkDownloadClient = this.#fileServerClientFactory.createFileServerDownloadClient(this.#file.url, this.#chunk.start, this.#chunk.end, this.#transferId, this.#file.name, this.#options);\n\n this.#chunkDownloadClient.addEventListener(`progress`, this.#onProgress);\n }\n\n #throwIfRunning() {\n if (this.#running)\n throw new DownloadError(`This instance of chunk downloader is already in use. Please create a new one.`);\n }\n\n #throwIfMissingDownloadPath() {\n if (!this.#file.temporaryDownloadPath)\n throw new DownloadError(`Download file ${this.#file.externalId}/${this.#file.name}/${this.#file.downloadPath} is missing the required \"temporaryDownloadPath\"`);\n }\n\n #addEventListeners() {\n this.#eventsEngine.addEventListener(TransferDownloadEvent.Aborting, this.#onAbortRequested);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.Pausing, this.#onPauseRequested);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#chunkDownloadClient.addEventListener(`progress`, this.#onProgress);\n }\n\n #removeEventListeners() {\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.Aborting, this.#onAbortRequested);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.Pausing, this.#onPauseRequested);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#chunkDownloadClient.removeEventListener(`progress`, this.#onProgress);\n }\n\n #canRetry(error: Error | null, writeErrors: number, networkErrors: number, apiReturnedNotOkResponseStatus: boolean) {\n if (this.#downloadState.status === TransferStatus.Aborting || this.#downloadState.status === TransferStatus.Pausing)\n return false;\n\n if (this.#file.isFailed)\n return false;\n\n if (apiReturnedNotOkResponseStatus)\n return false;\n\n if (this.#isDiskFullError(error))\n return false;\n\n if (error && error instanceof RequestError)\n return this.#options.fileserverAttemptLimit <= 0 || networkErrors < this.#options.fileserverAttemptLimit!;\n\n return this.#options.maxWriteAttempts! < 0 || writeErrors < this.#options.maxWriteAttempts!;\n }\n\n #isApiNotOkResponseStatusResponse(error: RequestError): boolean {\n try {\n if (typeof error.response?.body !== `string`)\n return false;\n\n const response = JSON.parse(error.response?.body);\n\n if (!isBaseResponse(response))\n return false;\n\n return response.responsestatus !== `OK`;\n }\n catch {\n return false;\n }\n }\n\n /**\n * This method aborts pending download - it can be achieved only by destroying the download client\n * (which in turn destroys the underlying download HTTP request). This operation\n * will throw an expected exception inside download method (in main while loop). See {@link download} method.\n */\n #interruptDownload = () => {\n this.#chunkDownloadClient?.release();\n };\n\n #onAbortRequested = () => {\n this.#interruptDownload();\n };\n\n #onPauseRequested = () => {\n if (this.#downloadState.pauseImmediately)\n this.#interruptDownload();\n };\n\n #onFileFailed = (args: FileDownloadFailedEventArgs) => {\n if (this.#file.externalId === args.file.id)\n this.#chunkDownloadClient?.release();\n };\n\n #onProgress = (args: ChunkProgressEvent) => {\n this.#bytesTransferred = args.transferredBytesTotal;\n this.#downloadState.chunkDownloadProgressed(this.#file, this.#chunk, args);\n };\n\n #errorInfoDump() {\n return {\n fileid: this.#file.externalId,\n filename: this.#file.name,\n chunk: DownloadFileChunkProgress.FromChunkInfo(this.#chunk),\n };\n }\n\n #toFailureCode(error: Error | null): DownloadErrorCode | undefined {\n if (this.#isDiskFullError(error))\n return DownloadErrorCode.DiskFull;\n\n return undefined;\n }\n\n #isDiskFullError(error: unknown): boolean {\n if (!error)\n return false;\n\n let current = error as { message?: string, code?: string, cause?: unknown } | undefined;\n for (let depth = 0; depth < 8 && current; depth++) {\n if (current.code === `ENOSPC`)\n return true;\n\n if (typeof current.message === `string` && current.message.includes(`ENOSPC`))\n return true;\n\n current = current.cause as { message?: string, code?: string, cause?: unknown } | undefined;\n }\n\n return false;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"downloadTracker.d.ts","sourceRoot":"","sources":["../../../src/downloader/downloadTracker.ts"],"names":[],"mappings":"AAMA,OAAO,gBAAgB,MAAM,4BAA4B,CAAC;AAG1D,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,iBAAiB,MAAM,0CAA0C,CAAC;AAC9E,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,uBAAuB,MAAM,mCAAmC,CAAC;AAU7E,OAAO,KAAK,wBAAwB,MAAM,oCAAoC,CAAC;AAC/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEzE,MAAM,CAAC,OAAO,OAAO,eAAe;;gBAkBpB,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,uBAAuB,EAAE,MAAM,CAAC,EAAE,MAAM;IAaxK,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,MAAM,CAAC,eAAe;IAgB9B,OAAO,CAAC,MAAM,CAAC,mBAAmB;mBA8Kb,sBAAsB;IAyGrC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,gBAAgB,CAAC;IA8CvC,sBAAsB;WAYf,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAcxJ,sBAAsB,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,uBAAuB,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"downloadTracker.d.ts","sourceRoot":"","sources":["../../../src/downloader/downloadTracker.ts"],"names":[],"mappings":"AAMA,OAAO,gBAAgB,MAAM,4BAA4B,CAAC;AAG1D,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,iBAAiB,MAAM,0CAA0C,CAAC;AAC9E,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,uBAAuB,MAAM,mCAAmC,CAAC;AAU7E,OAAO,KAAK,wBAAwB,MAAM,oCAAoC,CAAC;AAC/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEzE,MAAM,CAAC,OAAO,OAAO,eAAe;;gBAkBpB,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,uBAAuB,EAAE,MAAM,CAAC,EAAE,MAAM;IAaxK,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,MAAM,CAAC,eAAe;IAgB9B,OAAO,CAAC,MAAM,CAAC,mBAAmB;mBA8Kb,sBAAsB;IAyGrC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,gBAAgB,CAAC;IA8CvC,sBAAsB;WAYf,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAcxJ,sBAAsB,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,uBAAuB,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAA;KAAE,CAAC;WAqD9F,4BAA4B,CAAC,UAAU,EAAE,MAAM,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB;IAczH,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAGnC"}
|
|
@@ -366,7 +366,6 @@ class DownloadTracker {
|
|
|
366
366
|
let repeatProgressDump = false;
|
|
367
367
|
const files = [];
|
|
368
368
|
for (const [restoredFileId, restoredFile] of Object.entries(this.#allFiles)) {
|
|
369
|
-
// eslint-disable-next-line no-await-in-loop
|
|
370
369
|
const { file, fileWasReset } = await this.#restoreSingleFile(restoredFileId, restoredFile);
|
|
371
370
|
if (fileWasReset)
|
|
372
371
|
repeatProgressDump = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"downloadTracker.js","sourceRoot":"","sources":["../../../src/downloader/downloadTracker.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,aAAa,MAAM,yBAAyB,CAAC;AACpD,OAAO,iBAAiB,MAAM,6BAA6B,CAAC;AAC5D,OAAO,qBAAqB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,qBAAqB,MAAM,iCAAiC,CAAC;AACpE,OAAO,gBAAgB,MAAM,4BAA4B,CAAC;AAC1D,OAAO,cAAc,MAAM,kCAAkC,CAAC;AAkB9D,MAAqB,eAAe;IACvB,WAAW,CAAS;IACpB,WAAW,CAAoB;IAC/B,aAAa,CAAS;IACtB,aAAa,CAAe;IAC5B,QAAQ,CAAkB;IAC1B,SAAS,CAA2B;IACpC,WAAW,CAAQ;IAE5B,sBAAsB,GAA0C,IAAI,CAAC;IACrE,SAAS,GAA4C,EAAE,CAAC;IACxD,SAAS,GAAgC,EAAE,UAAU,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IAC7E,QAAQ,GAAG,KAAK,CAAC;IACjB,SAAS,GAAG,KAAK,CAAC;IAClB,aAAa,GAAG,KAAK,CAAC;IACtB,gBAAgB,GAAG,KAAK,CAAC;IACzB,SAAS,GAAG,KAAK,CAAC;IAElB,YAAY,UAAkB,EAAE,OAAwB,EAAE,UAA6B,EAAE,YAA0B,EAAE,QAAkC,EAAE,MAAe;QACpK,IAAI,CAAC,OAAO,CAAC,0BAA0B;YACnC,MAAM,IAAI,aAAa,CAAC,uEAAuE,CAAC,CAAC;QAErG,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACvD,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAC9B,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,aAAa,GAAG,EAAe,CAAC,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAC;QACjH,IAAI,CAAC,WAAW,GAAG,IAAI,KAAK,EAAE,CAAC;IACnC,CAAC;IAEO,cAAc,CAAC,MAA0B,EAAE,QAAkC;QACjF,IAAI,CAAC,QAAQ;YACT,OAAO,EAAE,MAAM,EAAE,CAAC;QAEtB,OAAO;YACH,MAAM;YACN,QAAQ,EACR;gBACI,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACpC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;aACzC;SACJ,CAAC;IACN,CAAC;IAEO,MAAM,CAAC,eAAe,CAAC,UAAkB,EAAE,0BAAkC,EAAE,UAA6B;QAChH,OAAO,UAAU,CAAC,QAAQ,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,cAAc;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,gBAAgB;QAChB,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IACzE,CAAC;IAEO,MAAM,CAAC,mBAAmB,CAAC,UAAkB,EAAE,0BAAkC,EAAE,UAA6B;QACpH,MAAM,YAAY,GAAG,EAAe,CAAC,eAAe,CAAC,UAAU,EAAE,0BAA0B,EAAE,UAAU,CAAC,CAAC;QACzG,OAAO,UAAU,CAAC,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,iBAAiB;QACjB,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,aAAa;QACb,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,iBAAiB;QACjB,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IACzE,CAAC;IAED,kBAAkB;QACd,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5F,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,oBAAoB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QACtG,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,qBAAqB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACxG,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAClG,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,sBAAsB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC1G,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAClF,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpF,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACpG,CAAC;IAED,qBAAqB;QACjB,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/F,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,oBAAoB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QACzG,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,qBAAqB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC3G,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACrG,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,sBAAsB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7G,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACrF,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACvF,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACvG,CAAC;IAED,cAAc,GAAG,KAAK,EAAE,IAA2B,EAAE,EAAE;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC;QAC3C,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC;YAC3C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC9B,CAAC;IACL,CAAC,CAAC;IAEF,eAAe,GAAG,KAAK,EAAE,IAA2B,EAAE,EAAE;QACpD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC;QAC/D,IAAI,WAAW,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;YAC3B,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;YAC5C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QACjC,CAAC;IACL,CAAC,CAAC;IAEF,gBAAgB,GAAG,KAAK,EAAE,IAA2B,EAAE,EAAE;QACrD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC;QAC/D,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACpC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAClC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QACvC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAC5C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAE7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC;QAC3C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACrC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;YACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC9B,CAAC;IACL,CAAC,CAAC;IAEF,aAAa,GAAG,KAAK,EAAE,IAAiC,EAAE,EAAE;QACxD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC;QAC/D,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACpC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAClC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QACvC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAC5C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC,CAAC;IAEF,iBAAiB,GAAG,KAAK,EAAE,IAA4B,EAAE,EAAE;QACvD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC;QAC/D,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACpC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAClC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;QACvC,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAC5C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC,CAAC;IAEF,SAAS,GAAG,KAAK,EAAE,IAA4B,EAAE,EAAE;QAC/C,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAClD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IACjC,CAAC,CAAC;IAEF,UAAU,GAAG,KAAK,IAAI,EAAE;QACpB,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,YAAY,GAAG,KAAK,EAAE,IAAgC,EAAE,EAAE;QACtD,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,KAAK,cAAc,CAAC,SAAS,CAAC;QAEhE,IAAI,CAAC,cAAc;YACf,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAElC,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC,CAAC;IAEF,qBAAqB,CAAC,KAAoB;QACtC,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI;YACxB,OAAO,KAAK,CAAC,SAAS,CAAC;QAE3B,IAAI,EAAe,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,QAAQ;YACrD,OAAO,iBAAiB,CAAC,QAAQ,CAAC;QAEtC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,KAAc;QACnC,IAAI,OAAO,GAAG,KAAuD,CAAC;QAEtE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;YAChD,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;gBAChC,OAAO,OAAO,CAAC,IAAI,CAAC;YAExB,OAAO,GAAG,OAAO,CAAC,KAAuD,CAAC;QAC9E,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,cAAuB;QAClC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,IAAI,CAAC,sBAAsB,KAAK,IAAI,EAAE,CAAC;YACvC,aAAa,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YAC3C,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;QAErD,IAAI,cAAc;YACd,MAAM,EAAe,CAAC,4BAA4B,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,0BAA2B,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1I,CAAC;IAED,KAAK,CAAC,YAAY;QACd,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3F,CAAC;IAED,KAAK,CAAC,aAAa;QACf,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7F,CAAC;IAED,KAAK,CAAC,oBAAoB;QACtB,gKAAgK;QAChK,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACtF,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,uBAAuB;QACzB,gKAAgK;QAChK,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACzF,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAClF,CAAC;IAED,eAAe;QACX,IAAI,IAAI,CAAC,QAAQ;YACb,MAAM,IAAI,aAAa,CAAC,oEAAoE,CAAC,CAAC;IACtG,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,IAAY,EAAE,MAAc,EAAE,SAA4B,EAAE,UAA6B;QACjI,IAAI,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK;YAC7C,MAAM,IAAI,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAC3C,IAAI,CAAC;gBACD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;oBAC9B,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;gBACzC,CAAC;gBACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;oBACrB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;oBAC3B,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBACtC,CAAC;YACL,CAAC;YACD,OAAO,GAAG,EAAE,CAAC;gBACT,sHAAsH;gBACtH,sGAAsG;gBACtG,qDAAqD;gBACrD,wIAAwI;gBACxI,MAAM,IAAI,GAAoC;oBAC1C,MAAM,EAAE,mGAAmG,IAAI,CAAC,WAAW,MAAM,IAAI,CAAC,aAAa,EAAE;oBACrJ,KAAK,EAAE,GAAY;oBACnB,SAAS,EAAE,iBAAiB,CAAC,oBAAoB;oBACjD,UAAU,EAAE,IAAI,CAAC,WAAW;iBAC/B,CAAC;gBACF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,qBAAqB,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;YAChF,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,mBAAmB;QACf,IAAI,CAAC,sBAAsB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YACjD,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAClC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,6BAA6B,CAAC,IAAsB;QACtD,OAAO,IAAI,CAAC,cAAc;eACnB,CAAC,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,qBAAsB,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;IACvH,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,cAAsB,EAAE,YAAqC;QAClF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,cAAc,CAAE,CAAC;QAC/D,MAAM,IAAI,GAAG,IAAI,gBAAgB,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,EAAE,YAAY,CAAC,EAAE,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC;QACtJ,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,yBAAyB,GAAG,SAAS,CAAC,EAAE,CAAC;QAE9C,IAAI,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,SAAS,CAAC,EAAE,GAAG,KAAK,CAAC;YACrB,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,YAAY,GAAG,IAAI,CAAC;QACxB,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ;YACjC,gGAAgG;YAChG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,WAAW,CAAC;aAC5C,CAAC;YACF,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,CAAC;YAEzE,IAAI,iBAAiB,EAAE,CAAC;gBACpB,uHAAuH;gBACvH,mDAAmD;gBACnD,SAAS,CAAC,EAAE,GAAG,KAAK,CAAC;gBACrB,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;gBACpB,YAAY,GAAG,IAAI,CAAC;gBAEpB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;gBAC5B,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC;YAC1C,CAAC;YAED,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,CAAC;gBAClE,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;gBACxE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACxB,IAAI,KAAK,CAAC,WAAW;oBACjB,IAAI,CAAC,oBAAoB,IAAI,KAAK,CAAC,SAAS,CAAC;YACrD,CAAC;QACL,CAAC;QAED,2FAA2F;QAC3F,kHAAkH;QAClH,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAClC,CAAC;IAED,uBAAuB,CAAC,IAAsB,EAAE,UAAkB,EAAE,SAA0C;QAC1G,MAAM,KAAK,GAAG,IAAI,qBAAqB,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC;QAC9F,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,KAAK,IAAI,IAAI,UAAU,IAAI,SAAS,CAAC,EAAE,CAAC;QACxE,IAAI,KAAK,CAAC,WAAW;YACjB,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,sBAAsB,CAAC,SAA0C;QAC7D,OAAO,SAAS,CAAC,EAAE,KAAK,IAAI,IAAI,SAAS,CAAC,CAAC,KAAK,KAAK,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAiC;QACzC,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAC3B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC1B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG;oBAC3C,CAAC,EAAE,IAAI,CAAC,WAAW;oBACnB,EAAE,EAAE,IAAI,CAAC,QAAQ;oBACjB,EAAE,EAAE,IAAI,CAAC,yBAAyB;oBAClC,EAAE,EAAE,IAAI,CAAC,cAAc;oBACvB,EAAE,EAAE,IAAI;iBACX,CAAC;gBACF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG;oBAC9B,CAAC,EAAE,IAAI,CAAC,GAAG;oBACX,CAAC,EAAE,IAAI,CAAC,WAAW;oBACnB,CAAC,EAAE,IAAI,CAAC,IAAI;oBACZ,EAAE,EAAE,IAAI,CAAC,YAAY;oBACrB,GAAG,EAAE,IAAI,CAAC,qBAAqB;oBAC/B,EAAE,EAAE,IAAI,CAAC,UAAU;iBACtB,CAAC;YACN,CAAC;YACD,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;gBAC3C,IAAI,CAAC;oBACD,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;oBACxD,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;oBAC1B,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;oBAC3B,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;oBAClC,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;oBACrC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBAC1B,CAAC;gBACD,OAAO,GAAG,EAAE,CAAC;oBACT,MAAM,IAAI,aAAa,CAAC,oFAAoF,IAAI,CAAC,WAAW,MAAM,IAAI,CAAC,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,EAAE,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;gBAC7N,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC;;YAEG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAE1B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC/B,CAAC;IACL,CAAC;IAED,KAAK,CAAC,sBAAsB;QACxB,MAAM,EAAe,CAAC,sBAAsB,CAAC,IAAI,CAAC,gBAAgB,EAAE,iBAAiB,IAAI,CAAC,gBAAgB,kBAAkB,EAAE,iBAAiB,CAAC,wBAAwB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5L,IAAI,CAAC;YACD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACnF,MAAM,OAAO,GAAoB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACzD,OAAO,OAAO,CAAC;QACnB,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,aAAa,CAAC,+CAA+C,IAAI,CAAC,WAAW,MAAM,IAAI,CAAC,gBAAgB,EAAE,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,EAAE,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;QAC/L,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,UAAkB,EAAE,0BAAkC,EAAE,UAA6B;QACtH,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,EAAE,0BAA0B,EAAE,UAAU,CAAC,CAAC;QAEtG,MAAM,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,EAAE,kBAAkB,gBAAgB,kBAAkB,EAAE,iBAAiB,CAAC,wBAAwB,EAAE,UAAU,CAAC,CAAC;QAElK,IAAI,CAAC;YACD,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,aAAa,CAAC,gDAAgD,UAAU,MAAM,gBAAgB,EAAE,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,EAAE,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;QACrL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,sBAAsB;QACxB,MAAM,EAAe,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,IAAI,CAAC,UAAU,kBAAkB,EAAE,iBAAiB,CAAC,wBAAwB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClL,MAAM,EAAe,CAAC,sBAAsB,CAAC,IAAI,CAAC,aAAa,EAAE,kBAAkB,IAAI,CAAC,aAAa,kBAAkB,EAAE,iBAAiB,CAAC,wBAAwB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAEvL,IAAI,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YACtF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;YACzF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YAEtB,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,eAAe,GAAG,CAAC,CAAC;YACxB,IAAI,mBAAmB,GAAG,CAAC,CAAC;YAC5B,IAAI,kBAAkB,GAAG,KAAK,CAAC;YAC/B,MAAM,KAAK,GAA4B,EAAE,CAAC;YAE1C,KAAK,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1E,4CAA4C;gBAC5C,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;gBAE3F,IAAI,YAAY;oBACZ,kBAAkB,GAAG,IAAI,CAAC;gBAE9B,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC;gBAExC,IAAI,IAAI,CAAC,WAAW;oBAChB,mBAAmB,IAAI,IAAI,CAAC,WAAW,CAAC;gBAE5C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjB,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC;YAClC,CAAC;YAED,IAAI,kBAAkB,EAAE,CAAC;gBACrB,uEAAuE;gBACvE,sFAAsF;gBACtF,2EAA2E;gBAC3E,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACzC,CAAC;YAED,OAAO;gBACH,KAAK;gBACL,KAAK,EAAE;oBACH,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU;oBACrC,eAAe;oBACf,mBAAmB;oBACnB,SAAS;oBACT,OAAO,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,eAAe,CAAC,GAAG,SAAS,CAAC;iBACzE;aACJ,CAAC;QACN,CAAC;QACD,OAAO,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,aAAa,CAAC,gDAAgD,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,EAAE,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;QACrK,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,UAAkB,EAAE,0BAAkC,EAAE,UAA6B;QAC3H,MAAM,UAAU,GAAG,IAAI,KAAK,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,EAAe,CAAC,eAAe,CAAC,UAAU,EAAE,0BAA0B,EAAE,UAAU,CAAC,CAAC;QAEzG,MAAM,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YACrC,IAAI,CAAC;gBACD,MAAM,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAChD,CAAC;YACD,OAAO,GAAG,EAAE,CAAC;gBACT,MAAM,IAAI,aAAa,CAAC,sCAAsC,UAAU,MAAM,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,GAAY,EAAE,EAAE,iBAAiB,CAAC,qBAAqB,CAAC,CAAC;YACpK,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,SAAS;QACX,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAClC,CAAC;CACJ;;eAneoB,eAAe","sourcesContent":["import { Mutex } from \"async-mutex\";\n\nimport DownloadError from \"./dtos/downloadError.js\";\nimport DownloadErrorCode from \"./dtos/downloadErrorCode.js\";\nimport TransferDownloadEvent from \"./dtos/downloadEvent.js\";\nimport DownloadFileChunkInfo from \"./dtos/downloadFileChunkInfo.js\";\nimport DownloadFileInfo from \"./dtos/downloadFileInfo.js\";\nimport TransferStatus from \"../utils/types/transferStatus.js\";\n\nimport type EventsEngine from \"../utils/events/eventsEngine.js\";\nimport type FileSystemService from \"../utils/fileSystem/fileSystemService.js\";\nimport type DownloadOptions from \"./downloadOptions.js\";\nimport type DownloaderRestoredState from \"./dtos/downloaderRestoredState.js\";\nimport type DownloadTrackerFileInfo from \"./dtos/downloadTrackerFileInfo.js\";\nimport type DownloadTrackerProgressInfo from \"./dtos/downloadTrackerProgressInfo.js\";\nimport type ChunkDownloadEventArgs from \"./eventArgs/chunkDownloadEventArgs.js\";\nimport type DownloadPauseEventArgs from \"./eventArgs/downloadPauseEventArgs.js\";\nimport type FileDownloadEventArgs from \"./eventArgs/fileDownloadEventArgs.js\";\nimport type FileDownloadFailedEventArgs from \"./eventArgs/fileDownloadFailedEventArgs.js\";\nimport type DownloadTrackingFailedEventArgs from \"./eventArgs/downloadTrackingFailedEventArgs.js\";\nimport type DownloadCompletedEventArgs from \"./eventArgs/downloadCompletedEventArgs.js\";\nimport type DownloadTrackerFileProgressInfo from \"./dtos/downloadTrackerFileProgressInfo.js\";\nimport type DownloadTrackingMetadata from \"./dtos/downloadTrackingMetadata.js\";\nimport type { DownloadCommandE2eeData } from \"./dtos/downloadCommand.js\";\n\nexport default class DownloadTracker {\n readonly #downloadId: string;\n readonly #fileSystem: FileSystemService;\n readonly #trackingPath: string;\n readonly #eventsEngine: EventsEngine;\n readonly #options: DownloadOptions;\n readonly #metadata: DownloadTrackingMetadata;\n readonly #filesMutex: Mutex;\n\n #progressIntervalTimer: ReturnType<typeof setInterval> | null = null;\n #allFiles: Record<string, DownloadTrackerFileInfo> = {};\n #progress: DownloadTrackerProgressInfo = { activeTime: 0, trackedFiles: {} };\n #running = false;\n #restored = false;\n #filesChanged = false;\n #progressChanged = false;\n #canTrack = false;\n\n constructor(downloadId: string, options: DownloadOptions, fileSystem: FileSystemService, eventsEngine: EventsEngine, e2eeData?: DownloadCommandE2eeData, region?: string) {\n if (!options.downloadTrackingBaseFolder)\n throw new DownloadError(`Download tracker cannot be created - tracking folder is not specified`);\n\n this.#downloadId = downloadId;\n this.#options = options;\n this.#metadata = this.createMetadata(region, e2eeData);\n this.#fileSystem = fileSystem;\n this.#eventsEngine = eventsEngine;\n this.#trackingPath = DownloadTracker.getTrackingPath(downloadId, options.downloadTrackingBaseFolder, fileSystem);\n this.#filesMutex = new Mutex();\n }\n\n private createMetadata(region: string | undefined, e2eeData?: DownloadCommandE2eeData): DownloadTrackingMetadata {\n if (!e2eeData)\n return { region };\n\n return {\n region,\n e2eeData:\n {\n ivAsHex: e2eeData.iv.toString(`hex`),\n keyAsHex: e2eeData.key.toString(`hex`),\n },\n };\n }\n\n private static getTrackingPath(downloadId: string, downloadTrackingBaseFolder: string, fileSystem: FileSystemService) {\n return fileSystem.pathJoin(downloadTrackingBaseFolder, downloadId);\n }\n\n get #filesPath(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `files.json`);\n }\n\n get #filesPathTemp(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `files.tmp`);\n }\n\n get #optionsFilePath(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `options.json`);\n }\n\n private static getMetadataFilePath(downloadId: string, downloadTrackingBaseFolder: string, fileSystem: FileSystemService): string {\n const trackingPath = DownloadTracker.getTrackingPath(downloadId, downloadTrackingBaseFolder, fileSystem);\n return fileSystem.pathJoin(trackingPath, `metadata.json`);\n }\n\n get #metadataFilePath(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `metadata.json`);\n }\n\n get #progressPath(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `progress.json`);\n }\n\n get #progressPathTemp(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `progress.tmp`);\n }\n\n #addEventListeners() {\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileCreated, this.#onFileCreated);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadStarting, this.#onFileStarting);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.ChunkDownloadCompleted, this.#onChunkCompleted);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.Paused, this.#onPaused);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.Aborted, this.#onAborted);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.DownloadCompleted, this.#onCompleted);\n }\n\n #removeEventListeners() {\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileCreated, this.#onFileCreated);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadStarting, this.#onFileStarting);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.ChunkDownloadCompleted, this.#onChunkCompleted);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.Paused, this.#onPaused);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.Aborted, this.#onAborted);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.DownloadCompleted, this.#onCompleted);\n }\n\n #onFileCreated = async (args: FileDownloadEventArgs) => {\n const file = this.#allFiles[args.file.id]!;\n if (file.tdp !== args.file.temporaryDownloadPath) {\n file.tdp = args.file.temporaryDownloadPath;\n this.#filesChanged = true;\n }\n };\n\n #onFileStarting = async (args: FileDownloadEventArgs) => {\n const pendingFile = this.#progress.trackedFiles[args.file.id]!;\n if (pendingFile.wr === false) {\n pendingFile.wr = true;\n this.#progress.activeTime = args.activeTime;\n this.#progressChanged = true;\n }\n };\n\n #onFileCompleted = async (args: FileDownloadEventArgs) => {\n const pendingFile = this.#progress.trackedFiles[args.file.id]!;\n pendingFile.c = args.file.completed;\n pendingFile.er = args.file.failed;\n pendingFile.ok = args.file.lastOkChunk;\n pendingFile.ec = null;\n this.#progress.activeTime = args.activeTime;\n this.#progressChanged = true;\n\n const file = this.#allFiles[args.file.id]!;\n if (file.dp !== args.file.downloadPath) {\n file.dp = args.file.downloadPath;\n this.#filesChanged = true;\n }\n };\n\n #onFileFailed = async (args: FileDownloadFailedEventArgs) => {\n const pendingFile = this.#progress.trackedFiles[args.file.id]!;\n pendingFile.c = args.file.completed;\n pendingFile.er = args.file.failed;\n pendingFile.ok = args.file.lastOkChunk;\n pendingFile.ec = this.#toTrackedFailureCode(args.reason);\n this.#progress.activeTime = args.activeTime;\n this.#progressChanged = true;\n };\n\n #onChunkCompleted = async (args: ChunkDownloadEventArgs) => {\n const pendingFile = this.#progress.trackedFiles[args.file.id]!;\n pendingFile.c = args.file.completed;\n pendingFile.er = args.file.failed;\n pendingFile.ok = args.file.lastOkChunk;\n pendingFile.ec = null;\n this.#progress.activeTime = args.activeTime;\n this.#progressChanged = true;\n };\n\n #onPaused = async (args: DownloadPauseEventArgs) => {\n this.#progress.activeTime = args.activeTimeMillis;\n this.#progressChanged = true;\n };\n\n #onAborted = async () => {\n await this.#cleanUp(true);\n };\n\n #onCompleted = async (args: DownloadCompletedEventArgs) => {\n const removeTracking = args.status === TransferStatus.Completed;\n\n if (!removeTracking)\n await this.#dumpAllProgress();\n\n await this.#cleanUp(removeTracking);\n };\n\n #toTrackedFailureCode(error: DownloadError): DownloadErrorCode | null {\n if (error.errorCode !== null)\n return error.errorCode;\n\n if (DownloadTracker.#extractErrorCode(error) === `ENOSPC`)\n return DownloadErrorCode.DiskFull;\n\n return null;\n }\n\n static #extractErrorCode(error: unknown): string | undefined {\n let current = error as { code?: string, cause?: unknown } | undefined;\n\n for (let depth = 0; depth < 8 && current; depth++) {\n if (typeof current.code === `string`)\n return current.code;\n\n current = current.cause as { code?: string, cause?: unknown } | undefined;\n }\n\n return undefined;\n }\n\n async #cleanUp(removeTracking: boolean) {\n this.#running = false;\n this.#progressChanged = false;\n this.#filesChanged = false;\n if (this.#progressIntervalTimer !== null) {\n clearInterval(this.#progressIntervalTimer);\n this.#progressIntervalTimer = null;\n }\n this.#removeEventListeners();\n this.#allFiles = {};\n this.#progress = { activeTime: 0, trackedFiles: {} };\n\n if (removeTracking)\n await DownloadTracker.removeDownloadTrackingFolder(this.#downloadId, this.#options.downloadTrackingBaseFolder!, this.#fileSystem);\n }\n\n async #dumpOptions() {\n await this.#fileSystem.writeFile(this.#optionsFilePath, JSON.stringify(this.#options));\n }\n\n async #dumpMetadata() {\n await this.#fileSystem.writeFile(this.#metadataFilePath, JSON.stringify(this.#metadata));\n }\n\n async #dumpDownloaderFiles() {\n // write to disk - then rename: rename will be much faster than write (potentially few/few dozens MB) - minimizing risk of getting corrupt progress file on disk\n await this.#fileSystem.writeFile(this.#filesPathTemp, JSON.stringify(this.#allFiles));\n await this.#fileSystem.renameFile(this.#filesPathTemp, this.#filesPath);\n }\n\n async #dumpDownloaderProgress() {\n // write to disk - then rename: rename will be much faster than write (potentially few/few dozens MB) - minimizing risk of getting corrupt progress file on disk\n await this.#fileSystem.writeFile(this.#progressPathTemp, JSON.stringify(this.#progress));\n await this.#fileSystem.renameFile(this.#progressPathTemp, this.#progressPath);\n }\n\n #throwIfRunning() {\n if (this.#running)\n throw new DownloadError(`This download tracker is already running. Please create a new one.`);\n }\n\n private static async throwIfPathDoesntExist(path: string, reason: string, errorCode: DownloadErrorCode, fileSystem: FileSystemService) {\n if ((await fileSystem.pathExists(path)) === false)\n throw new DownloadError(reason, undefined, errorCode);\n }\n\n async #dumpAllProgress(): Promise<void> {\n await this.#filesMutex.runExclusive(async () => {\n try {\n if (this.#progressChanged) {\n this.#progressChanged = false;\n await this.#dumpDownloaderProgress();\n }\n if (this.#filesChanged) {\n this.#filesChanged = false;\n await this.#dumpDownloaderFiles();\n }\n }\n catch (err) {\n // When this event is emitted it means for the the caller that restoring interrupted download won't be able to recover\n // all downloaded data - but only some part of it. In general it is safe to continue after this event,\n // just keep in mind tracking data is not up-to-date.\n // Also note: in many cases tracking data will not be used at all (only when download was interrupted - by app restart, pc reboot etc.).\n const args: DownloadTrackingFailedEventArgs = {\n reason: `Could not update tracking data - recovering this transfer may re-download more data than needed ${this.#downloadId} @ ${this.#trackingPath}`,\n error: err as Error,\n errorCode: DownloadErrorCode.TrackingDataOutdated,\n downloadId: this.#downloadId,\n };\n this.#eventsEngine.emit(TransferDownloadEvent.DownloadTrackingFailed, args);\n }\n });\n }\n\n #setupProgressTimer() {\n this.#progressIntervalTimer = setInterval(async () => {\n await this.#dumpAllProgress();\n }, this.#options.downloadTrackingIntervalMillis);\n }\n\n async #shouldPendingFileBeRestarted(file: DownloadFileInfo) {\n return file.wasEverWritten\n && (!file.temporaryDownloadPath || (await this.#fileSystem.pathExists(file.temporaryDownloadPath!)) === false);\n }\n\n async #restoreSingleFile(restoredFileId: string, restoredFile: DownloadTrackerFileInfo) {\n const fileTrack = this.#progress.trackedFiles[restoredFileId]!;\n const file = new DownloadFileInfo(restoredFileId, restoredFile.u, restoredFile.n, restoredFile.s, restoredFile.dp, restoredFile.cc, restoredFile.tdp);\n let fileWasReset = false;\n\n file.wasEverWritten = fileTrack.wr;\n file.isCompleted = fileTrack.c;\n file.isFailed = fileTrack.er;\n file.lastSuccessfulChunkNumber = fileTrack.ok;\n\n if (this.#shouldRetryFailedFile(fileTrack)) {\n fileTrack.er = false;\n fileTrack.ec = null;\n file.isFailed = false;\n fileWasReset = true;\n }\n\n if (file.isCompleted || file.isFailed)\n // let's save some cpu time on restoring chunk collection for file which will never be picked up\n file.downloadedBytes_bank = file.sizeInBytes;\n else {\n const shouldFileBeReset = await this.#shouldPendingFileBeRestarted(file);\n\n if (shouldFileBeReset) {\n // it maye happen that disk state is de-synced from the progress tracking file (the file.temporaryDownloadPath is gone)\n // in this case we want to simply re-start the file\n fileTrack.wr = false;\n fileTrack.ok = null;\n fileWasReset = true;\n\n file.wasEverWritten = false;\n file.lastSuccessfulChunkNumber = null;\n }\n\n for (let chunkIndex = 0; chunkIndex < file.chunkCount; chunkIndex++) {\n const chunk = this.#restoreSingleChunkInfo(file, chunkIndex, fileTrack);\n file.chunks.push(chunk);\n if (chunk.isCompleted)\n file.downloadedBytes_bank += chunk.chunkSize;\n }\n }\n\n // this method will update file.downloadedBytes properly based on file.downloadedBytes_bank\n // (and theoretically also based on file.#pendingChunks - but when restoring state #pendingChunks is always empty)\n file.updateProgress();\n\n return { file, fileWasReset };\n }\n\n #restoreSingleChunkInfo(file: DownloadFileInfo, chunkIndex: number, fileTrack: DownloadTrackerFileProgressInfo) {\n const chunk = new DownloadFileChunkInfo(file, chunkIndex, this.#options.maxChunkSize ?? null);\n chunk.isCompleted = fileTrack.ok !== null && chunkIndex <= fileTrack.ok;\n if (chunk.isCompleted)\n chunk.setProgress(chunk.chunkSize);\n return chunk;\n }\n\n #shouldRetryFailedFile(fileTrack: DownloadTrackerFileProgressInfo): boolean {\n return fileTrack.er === true && fileTrack.c === false;\n }\n\n async start(allFiles: Array<DownloadFileInfo>) {\n this.#throwIfRunning();\n\n this.#running = true;\n\n if (this.#restored === false) {\n for (const file of allFiles) {\n this.#progress.trackedFiles[file.externalId] = {\n c: file.isCompleted,\n er: file.isFailed,\n ok: file.lastSuccessfulChunkNumber,\n wr: file.wasEverWritten,\n ec: null,\n };\n this.#allFiles[file.externalId] = {\n u: file.url,\n s: file.sizeInBytes,\n n: file.name,\n dp: file.downloadPath,\n tdp: file.temporaryDownloadPath,\n cc: file.chunkCount,\n };\n }\n await this.#filesMutex.runExclusive(async () => {\n try {\n await this.#fileSystem.createFolder(this.#trackingPath);\n await this.#dumpOptions();\n await this.#dumpMetadata();\n await this.#dumpDownloaderFiles();\n await this.#dumpDownloaderProgress();\n this.#canTrack = true;\n }\n catch (err) {\n throw new DownloadError(`Could not create tracking folder - recovering this transfer will not be possible ${this.#downloadId} @ ${this.#trackingPath}`, { cause: err as Error }, DownloadErrorCode.TrackingNotAvailable);\n }\n });\n }\n else\n this.#canTrack = true;\n\n if (this.#canTrack) {\n this.#addEventListeners();\n this.#setupProgressTimer();\n }\n }\n\n async restoreDownloadOptions() {\n await DownloadTracker.throwIfPathDoesntExist(this.#optionsFilePath, `Options file \"${this.#optionsFilePath}\" does not exist`, DownloadErrorCode.TrackingDataParsingError, this.#fileSystem);\n try {\n const optionsFile = await this.#fileSystem.readFileAsString(this.#optionsFilePath);\n const options: DownloadOptions = JSON.parse(optionsFile);\n return options;\n }\n catch (err) {\n throw new DownloadError(`Could not read download options information ${this.#downloadId} @ ${this.#optionsFilePath}`, { cause: err as Error }, DownloadErrorCode.TrackingDataParsingError);\n }\n }\n\n static async restoreDownloadMetadata(downloadId: string, downloadTrackingBaseFolder: string, fileSystem: FileSystemService): Promise<DownloadTrackingMetadata> {\n const metadataFilePath = this.getMetadataFilePath(downloadId, downloadTrackingBaseFolder, fileSystem);\n\n await this.throwIfPathDoesntExist(metadataFilePath, `Metadata file \"${metadataFilePath}\" does not exist`, DownloadErrorCode.TrackingDataParsingError, fileSystem);\n\n try {\n const metadataFile = await fileSystem.readFileAsString(metadataFilePath);\n return JSON.parse(metadataFile);\n }\n catch (err) {\n throw new DownloadError(`Could not read download metadata information ${downloadId} @ ${metadataFilePath}`, { cause: err as Error }, DownloadErrorCode.TrackingDataParsingError);\n }\n }\n\n async restoreDownloaderState(): Promise<{ state: DownloaderRestoredState, files: Array<DownloadFileInfo> }> {\n await DownloadTracker.throwIfPathDoesntExist(this.#filesPath, `Filesinfo file \"${this.#filesPath}\" does not exist`, DownloadErrorCode.TrackingDataParsingError, this.#fileSystem);\n await DownloadTracker.throwIfPathDoesntExist(this.#progressPath, `Tracking file \"${this.#progressPath}\" does not exist`, DownloadErrorCode.TrackingDataParsingError, this.#fileSystem);\n\n try {\n this.#allFiles = JSON.parse(await this.#fileSystem.readFileAsString(this.#filesPath));\n this.#progress = JSON.parse(await this.#fileSystem.readFileAsString(this.#progressPath));\n this.#restored = true;\n\n let totalSize = 0;\n let downloadedBytes = 0;\n let downloadedBytesBank = 0;\n let repeatProgressDump = false;\n const files: Array<DownloadFileInfo> = [];\n\n for (const [restoredFileId, restoredFile] of Object.entries(this.#allFiles)) {\n // eslint-disable-next-line no-await-in-loop\n const { file, fileWasReset } = await this.#restoreSingleFile(restoredFileId, restoredFile);\n\n if (fileWasReset)\n repeatProgressDump = true;\n\n downloadedBytes += file.downloadedBytes;\n\n if (file.isCompleted)\n downloadedBytesBank += file.sizeInBytes;\n\n files.push(file);\n totalSize += file.sizeInBytes;\n }\n\n if (repeatProgressDump) {\n // some tracking info might have been updated (corrected) in above loop\n // persisting this makes sure we have most correct state in the progress tracking file\n // (e.g. some unconfirmed pending files might be deleted by end users etc.)\n await this.#dumpDownloaderProgress();\n }\n\n return {\n files,\n state: {\n activeTime: this.#progress.activeTime,\n downloadedBytes,\n downloadedBytesBank,\n totalSize,\n percent: totalSize === 0 ? 100 : ((100 * downloadedBytes) / totalSize),\n },\n };\n }\n catch (err) {\n throw new DownloadError(`Could not read download tracking information ${this.#downloadId}`, { cause: err as Error }, DownloadErrorCode.TrackingDataParsingError);\n }\n }\n\n static async removeDownloadTrackingFolder(downloadId: string, downloadTrackingBaseFolder: string, fileSystem: FileSystemService) {\n const filesMutex = new Mutex();\n const trackingPath = DownloadTracker.getTrackingPath(downloadId, downloadTrackingBaseFolder, fileSystem);\n\n await filesMutex.runExclusive(async () => {\n try {\n await fileSystem.deleteFolder(trackingPath);\n }\n catch (err) {\n throw new DownloadError(`Could not remove tracking folder - ${downloadId} @ ${trackingPath}`, { cause: err as Error }, DownloadErrorCode.TrackingCleanupFailed);\n }\n });\n }\n\n async saveState(): Promise<void> {\n await this.#dumpAllProgress();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"downloadTracker.js","sourceRoot":"","sources":["../../../src/downloader/downloadTracker.ts"],"names":[],"mappings":"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","sourcesContent":["import { Mutex } from \"async-mutex\";\n\nimport DownloadError from \"./dtos/downloadError.js\";\nimport DownloadErrorCode from \"./dtos/downloadErrorCode.js\";\nimport TransferDownloadEvent from \"./dtos/downloadEvent.js\";\nimport DownloadFileChunkInfo from \"./dtos/downloadFileChunkInfo.js\";\nimport DownloadFileInfo from \"./dtos/downloadFileInfo.js\";\nimport TransferStatus from \"../utils/types/transferStatus.js\";\n\nimport type EventsEngine from \"../utils/events/eventsEngine.js\";\nimport type FileSystemService from \"../utils/fileSystem/fileSystemService.js\";\nimport type DownloadOptions from \"./downloadOptions.js\";\nimport type DownloaderRestoredState from \"./dtos/downloaderRestoredState.js\";\nimport type DownloadTrackerFileInfo from \"./dtos/downloadTrackerFileInfo.js\";\nimport type DownloadTrackerProgressInfo from \"./dtos/downloadTrackerProgressInfo.js\";\nimport type ChunkDownloadEventArgs from \"./eventArgs/chunkDownloadEventArgs.js\";\nimport type DownloadPauseEventArgs from \"./eventArgs/downloadPauseEventArgs.js\";\nimport type FileDownloadEventArgs from \"./eventArgs/fileDownloadEventArgs.js\";\nimport type FileDownloadFailedEventArgs from \"./eventArgs/fileDownloadFailedEventArgs.js\";\nimport type DownloadTrackingFailedEventArgs from \"./eventArgs/downloadTrackingFailedEventArgs.js\";\nimport type DownloadCompletedEventArgs from \"./eventArgs/downloadCompletedEventArgs.js\";\nimport type DownloadTrackerFileProgressInfo from \"./dtos/downloadTrackerFileProgressInfo.js\";\nimport type DownloadTrackingMetadata from \"./dtos/downloadTrackingMetadata.js\";\nimport type { DownloadCommandE2eeData } from \"./dtos/downloadCommand.js\";\n\nexport default class DownloadTracker {\n readonly #downloadId: string;\n readonly #fileSystem: FileSystemService;\n readonly #trackingPath: string;\n readonly #eventsEngine: EventsEngine;\n readonly #options: DownloadOptions;\n readonly #metadata: DownloadTrackingMetadata;\n readonly #filesMutex: Mutex;\n\n #progressIntervalTimer: ReturnType<typeof setInterval> | null = null;\n #allFiles: Record<string, DownloadTrackerFileInfo> = {};\n #progress: DownloadTrackerProgressInfo = { activeTime: 0, trackedFiles: {} };\n #running = false;\n #restored = false;\n #filesChanged = false;\n #progressChanged = false;\n #canTrack = false;\n\n constructor(downloadId: string, options: DownloadOptions, fileSystem: FileSystemService, eventsEngine: EventsEngine, e2eeData?: DownloadCommandE2eeData, region?: string) {\n if (!options.downloadTrackingBaseFolder)\n throw new DownloadError(`Download tracker cannot be created - tracking folder is not specified`);\n\n this.#downloadId = downloadId;\n this.#options = options;\n this.#metadata = this.createMetadata(region, e2eeData);\n this.#fileSystem = fileSystem;\n this.#eventsEngine = eventsEngine;\n this.#trackingPath = DownloadTracker.getTrackingPath(downloadId, options.downloadTrackingBaseFolder, fileSystem);\n this.#filesMutex = new Mutex();\n }\n\n private createMetadata(region: string | undefined, e2eeData?: DownloadCommandE2eeData): DownloadTrackingMetadata {\n if (!e2eeData)\n return { region };\n\n return {\n region,\n e2eeData:\n {\n ivAsHex: e2eeData.iv.toString(`hex`),\n keyAsHex: e2eeData.key.toString(`hex`),\n },\n };\n }\n\n private static getTrackingPath(downloadId: string, downloadTrackingBaseFolder: string, fileSystem: FileSystemService) {\n return fileSystem.pathJoin(downloadTrackingBaseFolder, downloadId);\n }\n\n get #filesPath(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `files.json`);\n }\n\n get #filesPathTemp(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `files.tmp`);\n }\n\n get #optionsFilePath(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `options.json`);\n }\n\n private static getMetadataFilePath(downloadId: string, downloadTrackingBaseFolder: string, fileSystem: FileSystemService): string {\n const trackingPath = DownloadTracker.getTrackingPath(downloadId, downloadTrackingBaseFolder, fileSystem);\n return fileSystem.pathJoin(trackingPath, `metadata.json`);\n }\n\n get #metadataFilePath(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `metadata.json`);\n }\n\n get #progressPath(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `progress.json`);\n }\n\n get #progressPathTemp(): string {\n return this.#fileSystem.pathJoin(this.#trackingPath, `progress.tmp`);\n }\n\n #addEventListeners() {\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileCreated, this.#onFileCreated);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadStarting, this.#onFileStarting);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.ChunkDownloadCompleted, this.#onChunkCompleted);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.Paused, this.#onPaused);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.Aborted, this.#onAborted);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.DownloadCompleted, this.#onCompleted);\n }\n\n #removeEventListeners() {\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileCreated, this.#onFileCreated);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadStarting, this.#onFileStarting);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.ChunkDownloadCompleted, this.#onChunkCompleted);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.Paused, this.#onPaused);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.Aborted, this.#onAborted);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.DownloadCompleted, this.#onCompleted);\n }\n\n #onFileCreated = async (args: FileDownloadEventArgs) => {\n const file = this.#allFiles[args.file.id]!;\n if (file.tdp !== args.file.temporaryDownloadPath) {\n file.tdp = args.file.temporaryDownloadPath;\n this.#filesChanged = true;\n }\n };\n\n #onFileStarting = async (args: FileDownloadEventArgs) => {\n const pendingFile = this.#progress.trackedFiles[args.file.id]!;\n if (pendingFile.wr === false) {\n pendingFile.wr = true;\n this.#progress.activeTime = args.activeTime;\n this.#progressChanged = true;\n }\n };\n\n #onFileCompleted = async (args: FileDownloadEventArgs) => {\n const pendingFile = this.#progress.trackedFiles[args.file.id]!;\n pendingFile.c = args.file.completed;\n pendingFile.er = args.file.failed;\n pendingFile.ok = args.file.lastOkChunk;\n pendingFile.ec = null;\n this.#progress.activeTime = args.activeTime;\n this.#progressChanged = true;\n\n const file = this.#allFiles[args.file.id]!;\n if (file.dp !== args.file.downloadPath) {\n file.dp = args.file.downloadPath;\n this.#filesChanged = true;\n }\n };\n\n #onFileFailed = async (args: FileDownloadFailedEventArgs) => {\n const pendingFile = this.#progress.trackedFiles[args.file.id]!;\n pendingFile.c = args.file.completed;\n pendingFile.er = args.file.failed;\n pendingFile.ok = args.file.lastOkChunk;\n pendingFile.ec = this.#toTrackedFailureCode(args.reason);\n this.#progress.activeTime = args.activeTime;\n this.#progressChanged = true;\n };\n\n #onChunkCompleted = async (args: ChunkDownloadEventArgs) => {\n const pendingFile = this.#progress.trackedFiles[args.file.id]!;\n pendingFile.c = args.file.completed;\n pendingFile.er = args.file.failed;\n pendingFile.ok = args.file.lastOkChunk;\n pendingFile.ec = null;\n this.#progress.activeTime = args.activeTime;\n this.#progressChanged = true;\n };\n\n #onPaused = async (args: DownloadPauseEventArgs) => {\n this.#progress.activeTime = args.activeTimeMillis;\n this.#progressChanged = true;\n };\n\n #onAborted = async () => {\n await this.#cleanUp(true);\n };\n\n #onCompleted = async (args: DownloadCompletedEventArgs) => {\n const removeTracking = args.status === TransferStatus.Completed;\n\n if (!removeTracking)\n await this.#dumpAllProgress();\n\n await this.#cleanUp(removeTracking);\n };\n\n #toTrackedFailureCode(error: DownloadError): DownloadErrorCode | null {\n if (error.errorCode !== null)\n return error.errorCode;\n\n if (DownloadTracker.#extractErrorCode(error) === `ENOSPC`)\n return DownloadErrorCode.DiskFull;\n\n return null;\n }\n\n static #extractErrorCode(error: unknown): string | undefined {\n let current = error as { code?: string, cause?: unknown } | undefined;\n\n for (let depth = 0; depth < 8 && current; depth++) {\n if (typeof current.code === `string`)\n return current.code;\n\n current = current.cause as { code?: string, cause?: unknown } | undefined;\n }\n\n return undefined;\n }\n\n async #cleanUp(removeTracking: boolean) {\n this.#running = false;\n this.#progressChanged = false;\n this.#filesChanged = false;\n if (this.#progressIntervalTimer !== null) {\n clearInterval(this.#progressIntervalTimer);\n this.#progressIntervalTimer = null;\n }\n this.#removeEventListeners();\n this.#allFiles = {};\n this.#progress = { activeTime: 0, trackedFiles: {} };\n\n if (removeTracking)\n await DownloadTracker.removeDownloadTrackingFolder(this.#downloadId, this.#options.downloadTrackingBaseFolder!, this.#fileSystem);\n }\n\n async #dumpOptions() {\n await this.#fileSystem.writeFile(this.#optionsFilePath, JSON.stringify(this.#options));\n }\n\n async #dumpMetadata() {\n await this.#fileSystem.writeFile(this.#metadataFilePath, JSON.stringify(this.#metadata));\n }\n\n async #dumpDownloaderFiles() {\n // write to disk - then rename: rename will be much faster than write (potentially few/few dozens MB) - minimizing risk of getting corrupt progress file on disk\n await this.#fileSystem.writeFile(this.#filesPathTemp, JSON.stringify(this.#allFiles));\n await this.#fileSystem.renameFile(this.#filesPathTemp, this.#filesPath);\n }\n\n async #dumpDownloaderProgress() {\n // write to disk - then rename: rename will be much faster than write (potentially few/few dozens MB) - minimizing risk of getting corrupt progress file on disk\n await this.#fileSystem.writeFile(this.#progressPathTemp, JSON.stringify(this.#progress));\n await this.#fileSystem.renameFile(this.#progressPathTemp, this.#progressPath);\n }\n\n #throwIfRunning() {\n if (this.#running)\n throw new DownloadError(`This download tracker is already running. Please create a new one.`);\n }\n\n private static async throwIfPathDoesntExist(path: string, reason: string, errorCode: DownloadErrorCode, fileSystem: FileSystemService) {\n if ((await fileSystem.pathExists(path)) === false)\n throw new DownloadError(reason, undefined, errorCode);\n }\n\n async #dumpAllProgress(): Promise<void> {\n await this.#filesMutex.runExclusive(async () => {\n try {\n if (this.#progressChanged) {\n this.#progressChanged = false;\n await this.#dumpDownloaderProgress();\n }\n if (this.#filesChanged) {\n this.#filesChanged = false;\n await this.#dumpDownloaderFiles();\n }\n }\n catch (err) {\n // When this event is emitted it means for the the caller that restoring interrupted download won't be able to recover\n // all downloaded data - but only some part of it. In general it is safe to continue after this event,\n // just keep in mind tracking data is not up-to-date.\n // Also note: in many cases tracking data will not be used at all (only when download was interrupted - by app restart, pc reboot etc.).\n const args: DownloadTrackingFailedEventArgs = {\n reason: `Could not update tracking data - recovering this transfer may re-download more data than needed ${this.#downloadId} @ ${this.#trackingPath}`,\n error: err as Error,\n errorCode: DownloadErrorCode.TrackingDataOutdated,\n downloadId: this.#downloadId,\n };\n this.#eventsEngine.emit(TransferDownloadEvent.DownloadTrackingFailed, args);\n }\n });\n }\n\n #setupProgressTimer() {\n this.#progressIntervalTimer = setInterval(async () => {\n await this.#dumpAllProgress();\n }, this.#options.downloadTrackingIntervalMillis);\n }\n\n async #shouldPendingFileBeRestarted(file: DownloadFileInfo) {\n return file.wasEverWritten\n && (!file.temporaryDownloadPath || (await this.#fileSystem.pathExists(file.temporaryDownloadPath!)) === false);\n }\n\n async #restoreSingleFile(restoredFileId: string, restoredFile: DownloadTrackerFileInfo) {\n const fileTrack = this.#progress.trackedFiles[restoredFileId]!;\n const file = new DownloadFileInfo(restoredFileId, restoredFile.u, restoredFile.n, restoredFile.s, restoredFile.dp, restoredFile.cc, restoredFile.tdp);\n let fileWasReset = false;\n\n file.wasEverWritten = fileTrack.wr;\n file.isCompleted = fileTrack.c;\n file.isFailed = fileTrack.er;\n file.lastSuccessfulChunkNumber = fileTrack.ok;\n\n if (this.#shouldRetryFailedFile(fileTrack)) {\n fileTrack.er = false;\n fileTrack.ec = null;\n file.isFailed = false;\n fileWasReset = true;\n }\n\n if (file.isCompleted || file.isFailed)\n // let's save some cpu time on restoring chunk collection for file which will never be picked up\n file.downloadedBytes_bank = file.sizeInBytes;\n else {\n const shouldFileBeReset = await this.#shouldPendingFileBeRestarted(file);\n\n if (shouldFileBeReset) {\n // it maye happen that disk state is de-synced from the progress tracking file (the file.temporaryDownloadPath is gone)\n // in this case we want to simply re-start the file\n fileTrack.wr = false;\n fileTrack.ok = null;\n fileWasReset = true;\n\n file.wasEverWritten = false;\n file.lastSuccessfulChunkNumber = null;\n }\n\n for (let chunkIndex = 0; chunkIndex < file.chunkCount; chunkIndex++) {\n const chunk = this.#restoreSingleChunkInfo(file, chunkIndex, fileTrack);\n file.chunks.push(chunk);\n if (chunk.isCompleted)\n file.downloadedBytes_bank += chunk.chunkSize;\n }\n }\n\n // this method will update file.downloadedBytes properly based on file.downloadedBytes_bank\n // (and theoretically also based on file.#pendingChunks - but when restoring state #pendingChunks is always empty)\n file.updateProgress();\n\n return { file, fileWasReset };\n }\n\n #restoreSingleChunkInfo(file: DownloadFileInfo, chunkIndex: number, fileTrack: DownloadTrackerFileProgressInfo) {\n const chunk = new DownloadFileChunkInfo(file, chunkIndex, this.#options.maxChunkSize ?? null);\n chunk.isCompleted = fileTrack.ok !== null && chunkIndex <= fileTrack.ok;\n if (chunk.isCompleted)\n chunk.setProgress(chunk.chunkSize);\n return chunk;\n }\n\n #shouldRetryFailedFile(fileTrack: DownloadTrackerFileProgressInfo): boolean {\n return fileTrack.er === true && fileTrack.c === false;\n }\n\n async start(allFiles: Array<DownloadFileInfo>) {\n this.#throwIfRunning();\n\n this.#running = true;\n\n if (this.#restored === false) {\n for (const file of allFiles) {\n this.#progress.trackedFiles[file.externalId] = {\n c: file.isCompleted,\n er: file.isFailed,\n ok: file.lastSuccessfulChunkNumber,\n wr: file.wasEverWritten,\n ec: null,\n };\n this.#allFiles[file.externalId] = {\n u: file.url,\n s: file.sizeInBytes,\n n: file.name,\n dp: file.downloadPath,\n tdp: file.temporaryDownloadPath,\n cc: file.chunkCount,\n };\n }\n await this.#filesMutex.runExclusive(async () => {\n try {\n await this.#fileSystem.createFolder(this.#trackingPath);\n await this.#dumpOptions();\n await this.#dumpMetadata();\n await this.#dumpDownloaderFiles();\n await this.#dumpDownloaderProgress();\n this.#canTrack = true;\n }\n catch (err) {\n throw new DownloadError(`Could not create tracking folder - recovering this transfer will not be possible ${this.#downloadId} @ ${this.#trackingPath}`, { cause: err as Error }, DownloadErrorCode.TrackingNotAvailable);\n }\n });\n }\n else\n this.#canTrack = true;\n\n if (this.#canTrack) {\n this.#addEventListeners();\n this.#setupProgressTimer();\n }\n }\n\n async restoreDownloadOptions() {\n await DownloadTracker.throwIfPathDoesntExist(this.#optionsFilePath, `Options file \"${this.#optionsFilePath}\" does not exist`, DownloadErrorCode.TrackingDataParsingError, this.#fileSystem);\n try {\n const optionsFile = await this.#fileSystem.readFileAsString(this.#optionsFilePath);\n const options: DownloadOptions = JSON.parse(optionsFile);\n return options;\n }\n catch (err) {\n throw new DownloadError(`Could not read download options information ${this.#downloadId} @ ${this.#optionsFilePath}`, { cause: err as Error }, DownloadErrorCode.TrackingDataParsingError);\n }\n }\n\n static async restoreDownloadMetadata(downloadId: string, downloadTrackingBaseFolder: string, fileSystem: FileSystemService): Promise<DownloadTrackingMetadata> {\n const metadataFilePath = this.getMetadataFilePath(downloadId, downloadTrackingBaseFolder, fileSystem);\n\n await this.throwIfPathDoesntExist(metadataFilePath, `Metadata file \"${metadataFilePath}\" does not exist`, DownloadErrorCode.TrackingDataParsingError, fileSystem);\n\n try {\n const metadataFile = await fileSystem.readFileAsString(metadataFilePath);\n return JSON.parse(metadataFile);\n }\n catch (err) {\n throw new DownloadError(`Could not read download metadata information ${downloadId} @ ${metadataFilePath}`, { cause: err as Error }, DownloadErrorCode.TrackingDataParsingError);\n }\n }\n\n async restoreDownloaderState(): Promise<{ state: DownloaderRestoredState, files: Array<DownloadFileInfo> }> {\n await DownloadTracker.throwIfPathDoesntExist(this.#filesPath, `Filesinfo file \"${this.#filesPath}\" does not exist`, DownloadErrorCode.TrackingDataParsingError, this.#fileSystem);\n await DownloadTracker.throwIfPathDoesntExist(this.#progressPath, `Tracking file \"${this.#progressPath}\" does not exist`, DownloadErrorCode.TrackingDataParsingError, this.#fileSystem);\n\n try {\n this.#allFiles = JSON.parse(await this.#fileSystem.readFileAsString(this.#filesPath));\n this.#progress = JSON.parse(await this.#fileSystem.readFileAsString(this.#progressPath));\n this.#restored = true;\n\n let totalSize = 0;\n let downloadedBytes = 0;\n let downloadedBytesBank = 0;\n let repeatProgressDump = false;\n const files: Array<DownloadFileInfo> = [];\n\n for (const [restoredFileId, restoredFile] of Object.entries(this.#allFiles)) {\n const { file, fileWasReset } = await this.#restoreSingleFile(restoredFileId, restoredFile);\n\n if (fileWasReset)\n repeatProgressDump = true;\n\n downloadedBytes += file.downloadedBytes;\n\n if (file.isCompleted)\n downloadedBytesBank += file.sizeInBytes;\n\n files.push(file);\n totalSize += file.sizeInBytes;\n }\n\n if (repeatProgressDump) {\n // some tracking info might have been updated (corrected) in above loop\n // persisting this makes sure we have most correct state in the progress tracking file\n // (e.g. some unconfirmed pending files might be deleted by end users etc.)\n await this.#dumpDownloaderProgress();\n }\n\n return {\n files,\n state: {\n activeTime: this.#progress.activeTime,\n downloadedBytes,\n downloadedBytesBank,\n totalSize,\n percent: totalSize === 0 ? 100 : ((100 * downloadedBytes) / totalSize),\n },\n };\n }\n catch (err) {\n throw new DownloadError(`Could not read download tracking information ${this.#downloadId}`, { cause: err as Error }, DownloadErrorCode.TrackingDataParsingError);\n }\n }\n\n static async removeDownloadTrackingFolder(downloadId: string, downloadTrackingBaseFolder: string, fileSystem: FileSystemService) {\n const filesMutex = new Mutex();\n const trackingPath = DownloadTracker.getTrackingPath(downloadId, downloadTrackingBaseFolder, fileSystem);\n\n await filesMutex.runExclusive(async () => {\n try {\n await fileSystem.deleteFolder(trackingPath);\n }\n catch (err) {\n throw new DownloadError(`Could not remove tracking folder - ${downloadId} @ ${trackingPath}`, { cause: err as Error }, DownloadErrorCode.TrackingCleanupFailed);\n }\n });\n }\n\n async saveState(): Promise<void> {\n await this.#dumpAllProgress();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesDownloader.d.ts","sourceRoot":"","sources":["../../../src/downloader/filesDownloader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"filesDownloader.d.ts","sourceRoot":"","sources":["../../../src/downloader/filesDownloader.ts"],"names":[],"mappings":"AAEA,OAAO,gBAAgB,MAAM,4BAA4B,CAAC;AAK1D,OAAO,cAAc,MAAM,kCAAkC,CAAC;AAE9D,OAAO,wBAAwB,MAAM,oCAAoC,CAAC;AAG1E,OAAO,KAAK,iBAAiB,MAAM,0CAA0C,CAAC;AAC9E,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,qBAAqB,MAAM,yDAAyD,CAAC;AACjG,OAAO,KAAK,uBAAuB,MAAM,mCAAmC,CAAC;AAC7E,OAAO,KAAK,uBAAuB,MAAM,yCAAyC,CAAC;AACnF,OAAO,KAAK,0BAA0B,MAAM,mDAAmD,CAAC;AAChG,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,iBAAiB,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,SAAS,MAAM,2BAA2B,CAAC;AAIvD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,oBAAoB,MAAM,yCAAyC,CAAC;AAEhF,MAAM,CAAC,OAAO,OAAO,eAAe;;gBAsB5B,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC,EACjD,QAAQ,EAAE,uBAAuB,GAAG,SAAS,EAC7C,UAAU,EAAE,iBAAiB,EAC7B,qBAAqB,EAAE,qBAAqB,EAC5C,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,oBAAoB,EAClC,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,SAAS,EACpB,uBAAuB,EAAE,uBAAuB,EAChD,0BAA0B,EAAE,0BAA0B,CAAC,MAAM,CAAC,EAC9D,wBAAwB,EAAE,wBAAwB,EAClD,QAAQ,CAAC,EAAE,uBAAuB;IA2CtC,OAAO,CAAC,oBAAoB;IAOtB,KAAK,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAkLzC,YAAY,CAAC,OAAO,EAAE;QAAE,sBAAsB,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,GAAG,IAAI;IAK3G,MAAM,IAAI,OAAO;IAIjB,YAAY,IAAI,OAAO;IAKvB,eAAe,CAAC,SAAS,EAAE,OAAO,GAAG,iBAAiB;IAItD,IAAI,MAAM,IAAI,cAAc,CAE3B;CAuRJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesDownloader.js","sourceRoot":"","sources":["../../../src/downloader/filesDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-await-in-loop */\nimport DownloadState from \"./downloadStatus/downloadState.js\";\nimport DownloadFilePromise from \"./downloadStatus/downloadFilePromise.js\";\nimport DownloadFileInfo from \"./dtos/downloadFileInfo.js\";\nimport DownloadFileProgress from \"./downloadStatus/downloadFileProgress.js\";\nimport DownloadError from \"./dtos/downloadError.js\";\nimport TransferDownloadEvent from \"./dtos/downloadEvent.js\";\nimport ChunkDownloader from \"./chunkDownloader.js\";\nimport TransferStatus from \"../utils/types/transferStatus.js\";\nimport DownloadErrorCode from \"./dtos/downloadErrorCode.js\";\nimport DownloadRegistrationMode from \"./dtos/downloadRegistrationMode.js\";\nimport { promiseAllSettled } from \"../utils/promiseAll.js\";\n\nimport type FileSystemService from \"../utils/fileSystem/fileSystemService.js\";\nimport type DownloadOptions from \"./downloadOptions.js\";\nimport type ConcurrencyController from \"../utils/concurrencyController/concurrencyController.js\";\nimport type DownloaderRestoredState from \"./dtos/downloaderRestoredState.js\";\nimport type FileServerClientFactory from \"../utils/api/fileServerClientFactory.js\";\nimport type ChunkStreamProviderFactory from \"../utils/fileSystem/chunkStreamProviderFactory.js\";\nimport type EventsEngine from \"../utils/events/eventsEngine.js\";\nimport type DownloadEventArgs from \"./eventArgs/downloadEventArgs.js\";\nimport type ApiClient from \"../utils/api/apiClient.js\";\nimport type FileDownloadEventArgs from \"./eventArgs/fileDownloadEventArgs.js\";\nimport type FileDownloadFailedEventArgs from \"./eventArgs/fileDownloadFailedEventArgs.js\";\nimport type DownloadFileChunkInfo from \"./dtos/downloadFileChunkInfo.js\";\nimport type DownloadLogger from \"./downloadLogger.js\";\nimport type { ChunkStreamProviderEncryptionData } from \"../utils/fileSystem/chunkStreamProvider.js\";\nimport type { DownloadCommandE2eeData } from \"./dtos/downloadCommand.js\";\nimport type CryptographyProvider from \"../utils/crypto/cryptographyProvider.js\";\n\nexport default class FilesDownloader {\n readonly #logger: DownloadLogger;\n readonly #transferId: string;\n readonly #trackId: string | undefined;\n readonly #downloadId: string;\n readonly #region?: string;\n readonly #files: Array<DownloadFileInfo>;\n readonly #downloadState: DownloadState;\n readonly #options: DownloadOptions;\n readonly #concurrencyController: ConcurrencyController;\n readonly #fileSystem: FileSystemService;\n readonly #apiClient: ApiClient;\n readonly #fileserverClientFactory: FileServerClientFactory;\n readonly #chunkStreamProviderFactory: ChunkStreamProviderFactory<string>;\n readonly #downloadRegistrationMode: DownloadRegistrationMode;\n readonly #eventsEngine: EventsEngine;\n readonly #cryptography: CryptographyProvider;\n readonly #ongoingChunkDownloads: Record<string, Promise<void>>;\n readonly #ongoingFileDownloads: Record<string, DownloadFilePromise>;\n readonly #encryptionData?: ChunkStreamProviderEncryptionData;\n\n constructor(\n logger: DownloadLogger,\n transferId: string,\n trackId: string | undefined,\n downloadId: string,\n region: string | undefined,\n files: DownloadFileInfo | Array<DownloadFileInfo>,\n oldState: DownloaderRestoredState | undefined,\n fileSystem: FileSystemService,\n concurrencyController: ConcurrencyController,\n eventsEngine: EventsEngine,\n cryptography: CryptographyProvider,\n options: DownloadOptions,\n apiClient: ApiClient,\n fileserverClientFactory: FileServerClientFactory,\n chunkStreamProviderFactory: ChunkStreamProviderFactory<string>,\n downloadRegistrationMode: DownloadRegistrationMode,\n e2eeData?: DownloadCommandE2eeData,\n ) {\n if (!transferId)\n throw new DownloadError(`No transfer specified`);\n\n if (!files)\n throw new DownloadError(`No files added to downloader`);\n\n if (Array.isArray(files) && files.length === 0)\n throw new DownloadError(`No files added to downloader`);\n\n if (!options.downloadFolder)\n throw new DownloadError(`No downloadFolder specified`);\n\n if (e2eeData && e2eeData.iv.length !== 16)\n throw new DownloadError(`IV must be 16 bytes long`);\n\n if (e2eeData && e2eeData.key.length !== 32)\n throw new DownloadError(`Encryption key must be 32 bytes long`);\n\n this.#logger = logger;\n this.#downloadId = downloadId;\n this.#transferId = transferId;\n this.#trackId = trackId;\n this.#region = region;\n this.#fileSystem = fileSystem;\n this.#files = Array.isArray(files) ? files : [files];\n this.#options = options;\n this.#eventsEngine = eventsEngine;\n this.#cryptography = cryptography;\n this.#downloadState = new DownloadState(this.#downloadId, this.#transferId, this.#files, this.#options, eventsEngine, oldState);\n this.#concurrencyController = concurrencyController;\n this.#apiClient = apiClient;\n this.#fileserverClientFactory = fileserverClientFactory;\n this.#chunkStreamProviderFactory = chunkStreamProviderFactory;\n this.#downloadRegistrationMode = downloadRegistrationMode;\n this.#ongoingChunkDownloads = {};\n this.#ongoingFileDownloads = {};\n\n if (e2eeData)\n this.#encryptionData = this.createEncryptionData(e2eeData);\n }\n\n private createEncryptionData(e2eeData: DownloadCommandE2eeData): ChunkStreamProviderEncryptionData {\n return {\n iv: e2eeData.iv,\n key: e2eeData.key,\n };\n }\n\n async start(): Promise<DownloadEventArgs> {\n try {\n await this.#throwIfNotEnoughDiskSpaceBeforeStart();\n\n this.#addEventListeners();\n\n let isDownloaderRunning = true;\n\n while (isDownloaderRunning) {\n this.#downloadState.start();\n\n const fileServerUrl = new URL(this.#files[0].url).origin;\n this.#downloadState.notifyMetadataDetermined(fileServerUrl, this.#region);\n\n // MAIN FILE LOOP\n for (const file of this.#files) {\n if (file.isCompleted || file.isFailed)\n continue;\n\n if (this.#downloadState.isRunning === false)\n break;\n\n // figure out if we are downloading a new file or resuming a file that was interrupted\n if (file.wasEverWritten) {\n // this a resumed file (recreated from progress.json) - it must already exist under its temporary path\n if (!file.temporaryDownloadPath) {\n this.#downloadState.fileFailed(file, new DownloadError(`File ${file.downloadPath} was supposed to be resumed but its temporary path is not known.`, undefined, DownloadErrorCode.ResumedFilePathNotSpecified));\n continue;\n }\n\n if ((await this.#fileSystem.pathExists(file.temporaryDownloadPath!)) === false) {\n this.#downloadState.fileFailed(file, new DownloadError(`File ${file.downloadPath} was supposed to be resumed at ${file.temporaryDownloadPath}, but it does not exist on disk anymore.`, undefined, DownloadErrorCode.ResumedFileNotFound));\n continue;\n }\n }\n else {\n // in some edge cases the temporary file may exist and its name be persisted in the tracker file\n // but the wasEverWritten flag was not yet set - just abandon such temporary file (it will be 'empty' - null bytes only)\n if (file.temporaryDownloadPath) {\n this.#logDeletingFile(file, file.temporaryDownloadPath, `start`);\n this.#fileSystem.deleteFile(file.temporaryDownloadPath);\n }\n\n // this is a new file - create it\n await this.#createDownloadFile(file);\n }\n\n this.#ongoingFileDownloads[file.externalId] = new DownloadFilePromise(file.externalId);\n this.#ongoingFileDownloads[file.externalId]!.awaiter.then(id => {\n delete this.#ongoingFileDownloads[id];\n });\n\n this.#downloadState.fileStarting(file);\n\n // note: this call does not really wait for all chunks to be downloaded, but until all chunks of a file have been **scheduled**\n await this.#downloadAllChunksForFile(file);\n\n // so when we are here, the file is not complete\n // to track completeness of a file we look at events emitted by this.#downloadState\n }\n\n // when we got here it's either pause request, stop request (which is just like pause but without waiting for pending chunks), abort request (cancel the download entirely) or everything is complete;\n\n // wait for any remaining pending chunks\n await promiseAllSettled(Object.values(this.#ongoingChunkDownloads));\n\n // Wait for any remaining pending files\n // Note: we cannot rely just on chunk downloads being completed, because downloading chunks\n // doesn't mean that a file is complete; last phase of file completion is renaming the file\n // from a temporary name (unconfirmed_somefile.txt_qweasd1234.fmdownload) to its real name, which may need adjustments if a file with same name already exists.\n // When file already exists - a unique filename will be generated automatically e.g.: file.txt --> file (1).txt\n await promiseAllSettled(Object.values(this.#ongoingFileDownloads).map(x => x.awaiter));\n\n if (this.#downloadState.status === TransferStatus.Pausing) {\n // set status to paused and await until resume/abort\n await this.#downloadState.paused();\n }\n\n isDownloaderRunning = await this.#prepareDownloaderForAnotherIteration();\n }\n\n await this.#cleanupEmptyDownloadFolderIfConfigured();\n }\n catch (error) {\n this.#logger.logError(error as Error, `Unhandled downloader error occured.`);\n this.#downloadState.completed(error as Error);\n }\n finally {\n this.#removeEventListeners();\n }\n\n return this.#downloadState.getCurrentState(true);\n }\n\n async #throwIfNotEnoughDiskSpaceBeforeStart() {\n await this.#fileSystem.createFolder(this.#options.downloadFolder!);\n\n const requiredBytes = this.#getRemainingBytesToDownload();\n\n if (requiredBytes <= 0n)\n return;\n\n try {\n const availableBytes = await this.#fileSystem.getAvailableDiskSpace(this.#options.downloadFolder!);\n\n if (availableBytes < requiredBytes)\n throw new DownloadError(`ENOSPC: Not enough disk space. Required=${requiredBytes}B, available=${availableBytes}B`, undefined, DownloadErrorCode.DiskFull);\n }\n catch (error) {\n if (this.#shouldSkipFreeDiskSpaceCheck(error)) {\n this.#logger.logWarning(`Skipping free disk space check because filesystem does not support statfs`, { error });\n return;\n }\n\n throw this.#toDownloadError(error, `Checking free disk space before download failed for ${this.#options.downloadFolder!}`);\n }\n }\n\n #getRemainingBytesToDownload(): bigint {\n let requiredBytes = 0n;\n\n for (const file of this.#files) {\n if (file.isCompleted || file.isFailed)\n continue;\n\n const remaining = file.sizeInBytes - file.downloadedBytes;\n requiredBytes += BigInt(remaining);\n }\n\n return requiredBytes;\n }\n\n #shouldSkipFreeDiskSpaceCheck(error: unknown): boolean {\n const code = this.#extractErrorCode(error);\n if (code === `ENOSYS` || code === `ENOTSUP` || code === `EOPNOTSUPP`)\n return true;\n\n const message = this.#extractErrorMessage(error)?.toLowerCase() ?? ``;\n if (code === `ENOENT` && message.includes(`statfs`))\n return true;\n\n return false;\n }\n\n #extractErrorCode(error: unknown): string | undefined {\n let current = error as { code?: string, cause?: unknown } | undefined;\n\n for (let depth = 0; depth < 8 && current; depth++) {\n if (typeof current.code === `string`)\n return current.code;\n\n current = current.cause as { code?: string, cause?: unknown } | undefined;\n }\n\n return undefined;\n }\n\n #extractErrorMessage(error: unknown): string | undefined {\n let current = error as { message?: string, cause?: unknown } | undefined;\n\n for (let depth = 0; depth < 8 && current; depth++) {\n if (typeof current.message === `string`)\n return current.message;\n\n current = current.cause as { message?: string, cause?: unknown } | undefined;\n }\n\n return undefined;\n }\n\n #logDeletingFile(file: DownloadFileInfo | DownloadFileProgress, path: string, method: string) {\n let fileDataToLog = file;\n if (file instanceof DownloadFileInfo)\n fileDataToLog = DownloadFileProgress.FromFileDownloadInfo(file);\n\n this.#logger.logInfo(`[DELETE_TEMPFILE] Deleting temp file path=${path} method=${method}\\n\\n${JSON.stringify(fileDataToLog, null, 4)}\\n`);\n }\n\n requestPause(options: { interruptPendingChunks: boolean, pausedTrigger?: (paused: boolean) => void }): void {\n Object.values(this.#ongoingFileDownloads).forEach(filePromise => filePromise.complete());\n this.#downloadState.requestPause(options);\n }\n\n resume(): boolean {\n return this.#downloadState.resume();\n }\n\n requestAbort(): boolean {\n Object.values(this.#ongoingFileDownloads).forEach(filePromise => filePromise.complete());\n return this.#downloadState.requestAbort();\n }\n\n getCurrentState(withFiles: boolean): DownloadEventArgs {\n return this.#downloadState.getCurrentState(withFiles);\n }\n\n get status(): TransferStatus {\n return this.#downloadState.status;\n }\n\n async #deleteAllTemporaryAndCompletedFiles() {\n for (const file of this.#files) {\n if (file.temporaryDownloadPath) {\n this.#logDeletingFile(file, file.temporaryDownloadPath, `deleteAllTemporaryAndCompletedFiles`);\n await this.#fileSystem.deleteFile(file.temporaryDownloadPath);\n }\n\n if (file.isCompleted)\n await this.#fileSystem.deleteFile(file.downloadPath);\n }\n }\n\n async #registerTransferDownload() {\n this.#downloadState.registeringTransferDownload();\n await this.#apiClient.registerTransferDownload({\n transferid: this.#transferId,\n track: this.#trackId,\n bps: this.#downloadState.averageBytesPerSecond,\n browser: this.#options.userAgent,\n });\n }\n\n async #registerFileDownload(filename: string, filesize: number) {\n this.#downloadState.registeringFileDownload();\n await this.#apiClient.registerFileDownload({\n transferid: this.#transferId,\n track: this.#trackId,\n bps: this.#downloadState.averageBytesPerSecond,\n browser: this.#options.userAgent,\n filename,\n filesize,\n });\n }\n\n #addEventListeners() {\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleting, this.#onFileCompleting);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.PossibleSupersizedFile, this.#onFileSupersized);\n }\n\n #removeEventListeners() {\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleting, this.#onFileCompleting);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.PossibleSupersizedFile, this.#onFileSupersized);\n }\n\n #onFileCompleted = async (args: FileDownloadEventArgs) => {\n if (this.#downloadRegistrationMode === DownloadRegistrationMode.EverySingleFile && !this.#options.skipRegistration)\n await this.#registerFileDownload(args.file.name, args.file.size);\n\n this.#ongoingFileDownloads[args.file.id]?.complete();\n };\n\n #onFileCompleting = async (args: FileDownloadEventArgs) => {\n // note the args.file.downloadPath may not be final - if a file with this name eixsts the following method will generate new name e.g. \"file.txt\" --> \"file (1).txt\"\n try {\n const finalDownloadPath = await this.#doTheFinalFileRenameAfterFilesIsDownloaded(args.file);\n this.#downloadState.fileCompleted(args.file.id, finalDownloadPath);\n }\n catch (error) {\n this.#downloadState.fileFailedById(args.file.id, error as DownloadError);\n }\n };\n\n #onFileSupersized = async (fileArgs: FileDownloadEventArgs) => {\n if (fileArgs.file.temporaryDownloadPath && await this.#fileSystem.getFileSize(fileArgs.file.temporaryDownloadPath) > fileArgs.file.size)\n await this.#fileSystem.truncateFile(fileArgs.file.temporaryDownloadPath, fileArgs.file.size);\n };\n\n #onFileFailed = async (args: FileDownloadFailedEventArgs) => {\n this.#ongoingFileDownloads[args.file.id]?.complete();\n\n const shouldKeepTemporaryFile = this.#shouldKeepTemporaryFileOnFailure();\n\n if (this.#options.deleteFailedFilesFromDisk) {\n if (args.file.temporaryDownloadPath && !shouldKeepTemporaryFile) {\n this.#logDeletingFile(args.file, args.file.temporaryDownloadPath, `onFileFailed`);\n await this.#fileSystem.deleteFile(args.file.temporaryDownloadPath);\n }\n }\n };\n\n #shouldKeepTemporaryFileOnFailure(): boolean {\n // Resuming failed files requires tracking state + preserved temporary files.\n // If tracking is disabled there is no benefit in leaving temp files behind.\n return this.#options.downloadTrackingBaseFolder !== null;\n }\n\n async #createDownloadFile(file: DownloadFileInfo) {\n this.#downloadState.fileCreating(file);\n\n try {\n await this.#autoGenerateUniqueDownloadFile(file);\n this.#downloadState.fileCreated(file);\n }\n catch (error) {\n throw this.#toDownloadError(error, `Creating download file failed for ${file.downloadPath}`);\n }\n }\n\n async #autoGenerateUniqueDownloadFile(file: DownloadFileInfo) {\n let counter = 0;\n const fileLeafName = this.#fileSystem.parseFilePath(file.name).base;\n do {\n const newFileName = `unconfirmed_${fileLeafName}_${this.#cryptography.generateRandomString(10)}.fmdownload`;\n const newPath = this.#fileSystem.replaceFilenameInPath(file.downloadPath, newFileName);\n if (await this.#fileSystem.createFile(newPath, false)) {\n // eslint-disable-next-line no-param-reassign\n file.temporaryDownloadPath = newPath;\n return;\n }\n\n counter += 1;\n } while (counter < 10000);\n\n throw new DownloadError(`Downloader could not generate unique download path for ${file.downloadPath}. It tried until counter=${counter}`, undefined, DownloadErrorCode.TooManyFileRenameAttempts);\n }\n\n #toDownloadError(error: unknown, message: string): DownloadError {\n if (error instanceof DownloadError)\n return error;\n\n const wrappedError = error instanceof Error\n ? error\n : new Error(`${error}`);\n\n const code = this.#fileSystem.fileErrorToDownloadErrorCode(wrappedError);\n return new DownloadError(message, { cause: wrappedError }, code);\n }\n\n async #downloadAllChunksForFile(file: DownloadFileInfo) {\n if (file.chunks.length) {\n // MAIN CHUNK LOOP\n for (const chunk of file.chunks) {\n if (chunk.isCompleted || chunk.isFailed)\n continue;\n\n const downloadScheduled = await this.#downloadSingleChunk(file, chunk);\n if (downloadScheduled === false) {\n // downloader is not running or file is in failed state - stop the chunk loop\n break;\n }\n }\n\n // Restored files can have all chunks already completed (e.g. rename failed in a previous run).\n // In such case there is nothing to schedule, so we need to trigger finalization explicitly.\n if (!file.isFailed && file.chunks.every(chunk => chunk.isCompleted)) {\n this.#downloadState.ensureFileStarted(file);\n file.updateProgress();\n this.#downloadState.fileCompleting(file);\n }\n }\n else {\n // zerobyte file\n file.updateProgress();\n this.#downloadState.fileCompleting(file);\n }\n }\n\n async #downloadSingleChunk(file: DownloadFileInfo, chunk: DownloadFileChunkInfo): Promise<boolean> {\n const releaseSemaphore = await this.#concurrencyController.acquire();\n\n if (this.#downloadState.isRunning === false) {\n // downloader is not running - stop trying more chunks\n releaseSemaphore();\n return false;\n }\n\n if (file.isFailed) {\n // do not try to download more chunks if the file has failed\n releaseSemaphore();\n return false;\n }\n\n const chunkDownloader = new ChunkDownloader(this.#transferId, file, chunk, this.#downloadState, this.#options, this.#fileserverClientFactory, this.#chunkStreamProviderFactory, this.#eventsEngine, this.#logger, this.#encryptionData);\n const chunkPromise: Promise<void> = chunkDownloader.download();\n this.#ongoingChunkDownloads[chunk.id] = chunkPromise;\n\n chunkPromise.finally(() => {\n releaseSemaphore();\n delete this.#ongoingChunkDownloads[chunk.id];\n });\n\n return true;\n }\n\n /**\n * Prepares downloader for next loop iteration. Handles two main scenarios:\n * 1. Aborting - cleans up the disk state, calls downloadState to trigger Aborted event and returns a false flag (to break the loop).\n * 2. Completed - registers download to web api, calls downloadState to trigger Completed event and returns a false flag (to break the loop).\n * 3. For all other cases returns true - to continue the loop.\n */\n async #prepareDownloaderForAnotherIteration(): Promise<boolean> {\n let shouldDownloaderContinue = true;\n if (this.#downloadState.status === TransferStatus.Aborting) {\n shouldDownloaderContinue = false;\n if (this.#options.deleteAbortedDownloadsFromDisk)\n await this.#deleteAllTemporaryAndCompletedFiles();\n\n this.#downloadState.aborted();\n }\n else if (this.#downloadState.allFilesCompletedOrFailed) {\n shouldDownloaderContinue = false;\n if (this.#downloadRegistrationMode === DownloadRegistrationMode.Transfer && !this.#options.skipRegistration)\n await this.#registerTransferDownload();\n\n this.#downloadState.completed();\n }\n return shouldDownloaderContinue;\n }\n\n async #cleanupEmptyDownloadFolderIfConfigured() {\n try {\n if (this.#options.deleteEmptyDownloadFoldersAfterDownload && await this.#fileSystem.folderIsEmpty(this.#options.downloadFolder!))\n await this.#fileSystem.deleteFolder(this.#options.downloadFolder!);\n }\n catch (error) {\n this.#logger.logWarning(`cleanupEmptyDownloadFolderIfConfigured failed`, { error });\n }\n }\n\n async #doTheFinalFileRenameAfterFilesIsDownloaded(file: DownloadFileProgress) {\n let created = false;\n let createCounter = 0;\n const original = this.#fileSystem.parseFilePath(file.downloadPath);\n let newPathFormatted = file.downloadPath;\n do {\n // we do not want to re-reserve disk space when creating the target file (final name) - so file size is omitted\n created = await this.#fileSystem.createFile(newPathFormatted, false);\n if (!created) {\n createCounter += 1;\n const newPath = {\n dir: original.dir,\n name: `${original.name} (${createCounter})`,\n ext: original.ext,\n };\n newPathFormatted = this.#fileSystem.formatFilePath(newPath);\n }\n } while (created === false && createCounter < 10000);\n\n if (!created)\n throw new DownloadError(`Downloader could not rename temp file ${file.temporaryDownloadPath} to ${file.downloadPath}. It tried until counter=${createCounter}`, undefined, DownloadErrorCode.TooManyFileRenameAttempts);\n\n let renamed = false;\n let renameCounter = 0;\n let lastError: Error | undefined;\n while (!renamed && renameCounter < 5) {\n renameCounter += 1;\n try {\n await this.#fileSystem.renameFile(file.temporaryDownloadPath!, newPathFormatted);\n renamed = true;\n this.#logger.logInfo(`Downloader renamed ${file.temporaryDownloadPath} to ${newPathFormatted} at attempt ${renameCounter}`);\n }\n catch (error) {\n lastError = error as Error;\n this.#logger.logError(lastError, `Downloader could not rename ${file.temporaryDownloadPath} to ${newPathFormatted} attempt ${renameCounter}`);\n }\n }\n if (!renamed)\n await this.#cleanupFailedRenameTarget(newPathFormatted);\n\n if (!renamed)\n throw new DownloadError(`Downloader could not rename ${file.temporaryDownloadPath} to ${newPathFormatted} after ${renameCounter} attempts.`, { cause: lastError }, DownloadErrorCode.RenameFromTemporaryFilenameToFinalFailure);\n else\n return newPathFormatted;\n }\n\n async #cleanupFailedRenameTarget(pathToDelete: string) {\n try {\n await this.#fileSystem.deleteFile(pathToDelete);\n }\n catch (error) {\n this.#logger.logWarning(`Could not cleanup failed rename target ${pathToDelete}`, { error });\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"filesDownloader.js","sourceRoot":"","sources":["../../../src/downloader/filesDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["import DownloadState from \"./downloadStatus/downloadState.js\";\nimport DownloadFilePromise from \"./downloadStatus/downloadFilePromise.js\";\nimport DownloadFileInfo from \"./dtos/downloadFileInfo.js\";\nimport DownloadFileProgress from \"./downloadStatus/downloadFileProgress.js\";\nimport DownloadError from \"./dtos/downloadError.js\";\nimport TransferDownloadEvent from \"./dtos/downloadEvent.js\";\nimport ChunkDownloader from \"./chunkDownloader.js\";\nimport TransferStatus from \"../utils/types/transferStatus.js\";\nimport DownloadErrorCode from \"./dtos/downloadErrorCode.js\";\nimport DownloadRegistrationMode from \"./dtos/downloadRegistrationMode.js\";\nimport { promiseAllSettled } from \"../utils/promiseAll.js\";\n\nimport type FileSystemService from \"../utils/fileSystem/fileSystemService.js\";\nimport type DownloadOptions from \"./downloadOptions.js\";\nimport type ConcurrencyController from \"../utils/concurrencyController/concurrencyController.js\";\nimport type DownloaderRestoredState from \"./dtos/downloaderRestoredState.js\";\nimport type FileServerClientFactory from \"../utils/api/fileServerClientFactory.js\";\nimport type ChunkStreamProviderFactory from \"../utils/fileSystem/chunkStreamProviderFactory.js\";\nimport type EventsEngine from \"../utils/events/eventsEngine.js\";\nimport type DownloadEventArgs from \"./eventArgs/downloadEventArgs.js\";\nimport type ApiClient from \"../utils/api/apiClient.js\";\nimport type FileDownloadEventArgs from \"./eventArgs/fileDownloadEventArgs.js\";\nimport type FileDownloadFailedEventArgs from \"./eventArgs/fileDownloadFailedEventArgs.js\";\nimport type DownloadFileChunkInfo from \"./dtos/downloadFileChunkInfo.js\";\nimport type DownloadLogger from \"./downloadLogger.js\";\nimport type { ChunkStreamProviderEncryptionData } from \"../utils/fileSystem/chunkStreamProvider.js\";\nimport type { DownloadCommandE2eeData } from \"./dtos/downloadCommand.js\";\nimport type CryptographyProvider from \"../utils/crypto/cryptographyProvider.js\";\n\nexport default class FilesDownloader {\n readonly #logger: DownloadLogger;\n readonly #transferId: string;\n readonly #trackId: string | undefined;\n readonly #downloadId: string;\n readonly #region?: string;\n readonly #files: Array<DownloadFileInfo>;\n readonly #downloadState: DownloadState;\n readonly #options: DownloadOptions;\n readonly #concurrencyController: ConcurrencyController;\n readonly #fileSystem: FileSystemService;\n readonly #apiClient: ApiClient;\n readonly #fileserverClientFactory: FileServerClientFactory;\n readonly #chunkStreamProviderFactory: ChunkStreamProviderFactory<string>;\n readonly #downloadRegistrationMode: DownloadRegistrationMode;\n readonly #eventsEngine: EventsEngine;\n readonly #cryptography: CryptographyProvider;\n readonly #ongoingChunkDownloads: Record<string, Promise<void>>;\n readonly #ongoingFileDownloads: Record<string, DownloadFilePromise>;\n readonly #encryptionData?: ChunkStreamProviderEncryptionData;\n\n constructor(\n logger: DownloadLogger,\n transferId: string,\n trackId: string | undefined,\n downloadId: string,\n region: string | undefined,\n files: DownloadFileInfo | Array<DownloadFileInfo>,\n oldState: DownloaderRestoredState | undefined,\n fileSystem: FileSystemService,\n concurrencyController: ConcurrencyController,\n eventsEngine: EventsEngine,\n cryptography: CryptographyProvider,\n options: DownloadOptions,\n apiClient: ApiClient,\n fileserverClientFactory: FileServerClientFactory,\n chunkStreamProviderFactory: ChunkStreamProviderFactory<string>,\n downloadRegistrationMode: DownloadRegistrationMode,\n e2eeData?: DownloadCommandE2eeData,\n ) {\n if (!transferId)\n throw new DownloadError(`No transfer specified`);\n\n if (!files)\n throw new DownloadError(`No files added to downloader`);\n\n if (Array.isArray(files) && files.length === 0)\n throw new DownloadError(`No files added to downloader`);\n\n if (!options.downloadFolder)\n throw new DownloadError(`No downloadFolder specified`);\n\n if (e2eeData && e2eeData.iv.length !== 16)\n throw new DownloadError(`IV must be 16 bytes long`);\n\n if (e2eeData && e2eeData.key.length !== 32)\n throw new DownloadError(`Encryption key must be 32 bytes long`);\n\n this.#logger = logger;\n this.#downloadId = downloadId;\n this.#transferId = transferId;\n this.#trackId = trackId;\n this.#region = region;\n this.#fileSystem = fileSystem;\n this.#files = Array.isArray(files) ? files : [files];\n this.#options = options;\n this.#eventsEngine = eventsEngine;\n this.#cryptography = cryptography;\n this.#downloadState = new DownloadState(this.#downloadId, this.#transferId, this.#files, this.#options, eventsEngine, oldState);\n this.#concurrencyController = concurrencyController;\n this.#apiClient = apiClient;\n this.#fileserverClientFactory = fileserverClientFactory;\n this.#chunkStreamProviderFactory = chunkStreamProviderFactory;\n this.#downloadRegistrationMode = downloadRegistrationMode;\n this.#ongoingChunkDownloads = {};\n this.#ongoingFileDownloads = {};\n\n if (e2eeData)\n this.#encryptionData = this.createEncryptionData(e2eeData);\n }\n\n private createEncryptionData(e2eeData: DownloadCommandE2eeData): ChunkStreamProviderEncryptionData {\n return {\n iv: e2eeData.iv,\n key: e2eeData.key,\n };\n }\n\n async start(): Promise<DownloadEventArgs> {\n try {\n await this.#throwIfNotEnoughDiskSpaceBeforeStart();\n\n this.#addEventListeners();\n\n let isDownloaderRunning = true;\n\n while (isDownloaderRunning) {\n this.#downloadState.start();\n\n const fileServerUrl = new URL(this.#files[0].url).origin;\n this.#downloadState.notifyMetadataDetermined(fileServerUrl, this.#region);\n\n // MAIN FILE LOOP\n for (const file of this.#files) {\n if (file.isCompleted || file.isFailed)\n continue;\n\n if (this.#downloadState.isRunning === false)\n break;\n\n // figure out if we are downloading a new file or resuming a file that was interrupted\n if (file.wasEverWritten) {\n // this a resumed file (recreated from progress.json) - it must already exist under its temporary path\n if (!file.temporaryDownloadPath) {\n this.#downloadState.fileFailed(file, new DownloadError(`File ${file.downloadPath} was supposed to be resumed but its temporary path is not known.`, undefined, DownloadErrorCode.ResumedFilePathNotSpecified));\n continue;\n }\n\n if ((await this.#fileSystem.pathExists(file.temporaryDownloadPath!)) === false) {\n this.#downloadState.fileFailed(file, new DownloadError(`File ${file.downloadPath} was supposed to be resumed at ${file.temporaryDownloadPath}, but it does not exist on disk anymore.`, undefined, DownloadErrorCode.ResumedFileNotFound));\n continue;\n }\n }\n else {\n // in some edge cases the temporary file may exist and its name be persisted in the tracker file\n // but the wasEverWritten flag was not yet set - just abandon such temporary file (it will be 'empty' - null bytes only)\n if (file.temporaryDownloadPath) {\n this.#logDeletingFile(file, file.temporaryDownloadPath, `start`);\n this.#fileSystem.deleteFile(file.temporaryDownloadPath);\n }\n\n // this is a new file - create it\n await this.#createDownloadFile(file);\n }\n\n this.#ongoingFileDownloads[file.externalId] = new DownloadFilePromise(file.externalId);\n this.#ongoingFileDownloads[file.externalId]!.awaiter.then(id => {\n delete this.#ongoingFileDownloads[id];\n });\n\n this.#downloadState.fileStarting(file);\n\n // note: this call does not really wait for all chunks to be downloaded, but until all chunks of a file have been **scheduled**\n await this.#downloadAllChunksForFile(file);\n\n // so when we are here, the file is not complete\n // to track completeness of a file we look at events emitted by this.#downloadState\n }\n\n // when we got here it's either pause request, stop request (which is just like pause but without waiting for pending chunks), abort request (cancel the download entirely) or everything is complete;\n\n // wait for any remaining pending chunks\n await promiseAllSettled(Object.values(this.#ongoingChunkDownloads));\n\n // Wait for any remaining pending files\n // Note: we cannot rely just on chunk downloads being completed, because downloading chunks\n // doesn't mean that a file is complete; last phase of file completion is renaming the file\n // from a temporary name (unconfirmed_somefile.txt_qweasd1234.fmdownload) to its real name, which may need adjustments if a file with same name already exists.\n // When file already exists - a unique filename will be generated automatically e.g.: file.txt --> file (1).txt\n await promiseAllSettled(Object.values(this.#ongoingFileDownloads).map(x => x.awaiter));\n\n if (this.#downloadState.status === TransferStatus.Pausing) {\n // set status to paused and await until resume/abort\n await this.#downloadState.paused();\n }\n\n isDownloaderRunning = await this.#prepareDownloaderForAnotherIteration();\n }\n\n await this.#cleanupEmptyDownloadFolderIfConfigured();\n }\n catch (error) {\n this.#logger.logError(error as Error, `Unhandled downloader error occured.`);\n this.#downloadState.completed(error as Error);\n }\n finally {\n this.#removeEventListeners();\n }\n\n return this.#downloadState.getCurrentState(true);\n }\n\n async #throwIfNotEnoughDiskSpaceBeforeStart() {\n await this.#fileSystem.createFolder(this.#options.downloadFolder!);\n\n const requiredBytes = this.#getRemainingBytesToDownload();\n\n if (requiredBytes <= 0n)\n return;\n\n try {\n const availableBytes = await this.#fileSystem.getAvailableDiskSpace(this.#options.downloadFolder!);\n\n if (availableBytes < requiredBytes)\n throw new DownloadError(`ENOSPC: Not enough disk space. Required=${requiredBytes}B, available=${availableBytes}B`, undefined, DownloadErrorCode.DiskFull);\n }\n catch (error) {\n if (this.#shouldSkipFreeDiskSpaceCheck(error)) {\n this.#logger.logWarning(`Skipping free disk space check because filesystem does not support statfs`, { error });\n return;\n }\n\n throw this.#toDownloadError(error, `Checking free disk space before download failed for ${this.#options.downloadFolder!}`);\n }\n }\n\n #getRemainingBytesToDownload(): bigint {\n let requiredBytes = 0n;\n\n for (const file of this.#files) {\n if (file.isCompleted || file.isFailed)\n continue;\n\n const remaining = file.sizeInBytes - file.downloadedBytes;\n requiredBytes += BigInt(remaining);\n }\n\n return requiredBytes;\n }\n\n #shouldSkipFreeDiskSpaceCheck(error: unknown): boolean {\n const code = this.#extractErrorCode(error);\n if (code === `ENOSYS` || code === `ENOTSUP` || code === `EOPNOTSUPP`)\n return true;\n\n const message = this.#extractErrorMessage(error)?.toLowerCase() ?? ``;\n if (code === `ENOENT` && message.includes(`statfs`))\n return true;\n\n return false;\n }\n\n #extractErrorCode(error: unknown): string | undefined {\n let current = error as { code?: string, cause?: unknown } | undefined;\n\n for (let depth = 0; depth < 8 && current; depth++) {\n if (typeof current.code === `string`)\n return current.code;\n\n current = current.cause as { code?: string, cause?: unknown } | undefined;\n }\n\n return undefined;\n }\n\n #extractErrorMessage(error: unknown): string | undefined {\n let current = error as { message?: string, cause?: unknown } | undefined;\n\n for (let depth = 0; depth < 8 && current; depth++) {\n if (typeof current.message === `string`)\n return current.message;\n\n current = current.cause as { message?: string, cause?: unknown } | undefined;\n }\n\n return undefined;\n }\n\n #logDeletingFile(file: DownloadFileInfo | DownloadFileProgress, path: string, method: string) {\n let fileDataToLog = file;\n if (file instanceof DownloadFileInfo)\n fileDataToLog = DownloadFileProgress.FromFileDownloadInfo(file);\n\n this.#logger.logInfo(`[DELETE_TEMPFILE] Deleting temp file path=${path} method=${method}\\n\\n${JSON.stringify(fileDataToLog, null, 4)}\\n`);\n }\n\n requestPause(options: { interruptPendingChunks: boolean, pausedTrigger?: (paused: boolean) => void }): void {\n Object.values(this.#ongoingFileDownloads).forEach(filePromise => filePromise.complete());\n this.#downloadState.requestPause(options);\n }\n\n resume(): boolean {\n return this.#downloadState.resume();\n }\n\n requestAbort(): boolean {\n Object.values(this.#ongoingFileDownloads).forEach(filePromise => filePromise.complete());\n return this.#downloadState.requestAbort();\n }\n\n getCurrentState(withFiles: boolean): DownloadEventArgs {\n return this.#downloadState.getCurrentState(withFiles);\n }\n\n get status(): TransferStatus {\n return this.#downloadState.status;\n }\n\n async #deleteAllTemporaryAndCompletedFiles() {\n for (const file of this.#files) {\n if (file.temporaryDownloadPath) {\n this.#logDeletingFile(file, file.temporaryDownloadPath, `deleteAllTemporaryAndCompletedFiles`);\n await this.#fileSystem.deleteFile(file.temporaryDownloadPath);\n }\n\n if (file.isCompleted)\n await this.#fileSystem.deleteFile(file.downloadPath);\n }\n }\n\n async #registerTransferDownload() {\n this.#downloadState.registeringTransferDownload();\n await this.#apiClient.registerTransferDownload({\n transferid: this.#transferId,\n track: this.#trackId,\n bps: this.#downloadState.averageBytesPerSecond,\n browser: this.#options.userAgent,\n });\n }\n\n async #registerFileDownload(filename: string, filesize: number) {\n this.#downloadState.registeringFileDownload();\n await this.#apiClient.registerFileDownload({\n transferid: this.#transferId,\n track: this.#trackId,\n bps: this.#downloadState.averageBytesPerSecond,\n browser: this.#options.userAgent,\n filename,\n filesize,\n });\n }\n\n #addEventListeners() {\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadCompleting, this.#onFileCompleting);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.addEventListener(TransferDownloadEvent.PossibleSupersizedFile, this.#onFileSupersized);\n }\n\n #removeEventListeners() {\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleted, this.#onFileCompleted);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadCompleting, this.#onFileCompleting);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.FileDownloadFailed, this.#onFileFailed);\n this.#eventsEngine.removeEventListener(TransferDownloadEvent.PossibleSupersizedFile, this.#onFileSupersized);\n }\n\n #onFileCompleted = async (args: FileDownloadEventArgs) => {\n if (this.#downloadRegistrationMode === DownloadRegistrationMode.EverySingleFile && !this.#options.skipRegistration)\n await this.#registerFileDownload(args.file.name, args.file.size);\n\n this.#ongoingFileDownloads[args.file.id]?.complete();\n };\n\n #onFileCompleting = async (args: FileDownloadEventArgs) => {\n // note the args.file.downloadPath may not be final - if a file with this name eixsts the following method will generate new name e.g. \"file.txt\" --> \"file (1).txt\"\n try {\n const finalDownloadPath = await this.#doTheFinalFileRenameAfterFilesIsDownloaded(args.file);\n this.#downloadState.fileCompleted(args.file.id, finalDownloadPath);\n }\n catch (error) {\n this.#downloadState.fileFailedById(args.file.id, error as DownloadError);\n }\n };\n\n #onFileSupersized = async (fileArgs: FileDownloadEventArgs) => {\n if (fileArgs.file.temporaryDownloadPath && await this.#fileSystem.getFileSize(fileArgs.file.temporaryDownloadPath) > fileArgs.file.size)\n await this.#fileSystem.truncateFile(fileArgs.file.temporaryDownloadPath, fileArgs.file.size);\n };\n\n #onFileFailed = async (args: FileDownloadFailedEventArgs) => {\n this.#ongoingFileDownloads[args.file.id]?.complete();\n\n const shouldKeepTemporaryFile = this.#shouldKeepTemporaryFileOnFailure();\n\n if (this.#options.deleteFailedFilesFromDisk) {\n if (args.file.temporaryDownloadPath && !shouldKeepTemporaryFile) {\n this.#logDeletingFile(args.file, args.file.temporaryDownloadPath, `onFileFailed`);\n await this.#fileSystem.deleteFile(args.file.temporaryDownloadPath);\n }\n }\n };\n\n #shouldKeepTemporaryFileOnFailure(): boolean {\n // Resuming failed files requires tracking state + preserved temporary files.\n // If tracking is disabled there is no benefit in leaving temp files behind.\n return this.#options.downloadTrackingBaseFolder !== null;\n }\n\n async #createDownloadFile(file: DownloadFileInfo) {\n this.#downloadState.fileCreating(file);\n\n try {\n await this.#autoGenerateUniqueDownloadFile(file);\n this.#downloadState.fileCreated(file);\n }\n catch (error) {\n throw this.#toDownloadError(error, `Creating download file failed for ${file.downloadPath}`);\n }\n }\n\n async #autoGenerateUniqueDownloadFile(file: DownloadFileInfo) {\n let counter = 0;\n const fileLeafName = this.#fileSystem.parseFilePath(file.name).base;\n do {\n const newFileName = `unconfirmed_${fileLeafName}_${this.#cryptography.generateRandomString(10)}.fmdownload`;\n const newPath = this.#fileSystem.replaceFilenameInPath(file.downloadPath, newFileName);\n if (await this.#fileSystem.createFile(newPath, false)) {\n // eslint-disable-next-line no-param-reassign\n file.temporaryDownloadPath = newPath;\n return;\n }\n\n counter += 1;\n } while (counter < 10000);\n\n throw new DownloadError(`Downloader could not generate unique download path for ${file.downloadPath}. It tried until counter=${counter}`, undefined, DownloadErrorCode.TooManyFileRenameAttempts);\n }\n\n #toDownloadError(error: unknown, message: string): DownloadError {\n if (error instanceof DownloadError)\n return error;\n\n const wrappedError = error instanceof Error\n ? error\n : new Error(`${error}`);\n\n const code = this.#fileSystem.fileErrorToDownloadErrorCode(wrappedError);\n return new DownloadError(message, { cause: wrappedError }, code);\n }\n\n async #downloadAllChunksForFile(file: DownloadFileInfo) {\n if (file.chunks.length) {\n // MAIN CHUNK LOOP\n for (const chunk of file.chunks) {\n if (chunk.isCompleted || chunk.isFailed)\n continue;\n\n const downloadScheduled = await this.#downloadSingleChunk(file, chunk);\n if (downloadScheduled === false) {\n // downloader is not running or file is in failed state - stop the chunk loop\n break;\n }\n }\n\n // Restored files can have all chunks already completed (e.g. rename failed in a previous run).\n // In such case there is nothing to schedule, so we need to trigger finalization explicitly.\n if (!file.isFailed && file.chunks.every(chunk => chunk.isCompleted)) {\n this.#downloadState.ensureFileStarted(file);\n file.updateProgress();\n this.#downloadState.fileCompleting(file);\n }\n }\n else {\n // zerobyte file\n file.updateProgress();\n this.#downloadState.fileCompleting(file);\n }\n }\n\n async #downloadSingleChunk(file: DownloadFileInfo, chunk: DownloadFileChunkInfo): Promise<boolean> {\n const releaseSemaphore = await this.#concurrencyController.acquire();\n\n if (this.#downloadState.isRunning === false) {\n // downloader is not running - stop trying more chunks\n releaseSemaphore();\n return false;\n }\n\n if (file.isFailed) {\n // do not try to download more chunks if the file has failed\n releaseSemaphore();\n return false;\n }\n\n const chunkDownloader = new ChunkDownloader(this.#transferId, file, chunk, this.#downloadState, this.#options, this.#fileserverClientFactory, this.#chunkStreamProviderFactory, this.#eventsEngine, this.#logger, this.#encryptionData);\n const chunkPromise: Promise<void> = chunkDownloader.download();\n this.#ongoingChunkDownloads[chunk.id] = chunkPromise;\n\n chunkPromise.finally(() => {\n releaseSemaphore();\n delete this.#ongoingChunkDownloads[chunk.id];\n });\n\n return true;\n }\n\n /**\n * Prepares downloader for next loop iteration. Handles two main scenarios:\n * 1. Aborting - cleans up the disk state, calls downloadState to trigger Aborted event and returns a false flag (to break the loop).\n * 2. Completed - registers download to web api, calls downloadState to trigger Completed event and returns a false flag (to break the loop).\n * 3. For all other cases returns true - to continue the loop.\n */\n async #prepareDownloaderForAnotherIteration(): Promise<boolean> {\n let shouldDownloaderContinue = true;\n if (this.#downloadState.status === TransferStatus.Aborting) {\n shouldDownloaderContinue = false;\n if (this.#options.deleteAbortedDownloadsFromDisk)\n await this.#deleteAllTemporaryAndCompletedFiles();\n\n this.#downloadState.aborted();\n }\n else if (this.#downloadState.allFilesCompletedOrFailed) {\n shouldDownloaderContinue = false;\n if (this.#downloadRegistrationMode === DownloadRegistrationMode.Transfer && !this.#options.skipRegistration)\n await this.#registerTransferDownload();\n\n this.#downloadState.completed();\n }\n return shouldDownloaderContinue;\n }\n\n async #cleanupEmptyDownloadFolderIfConfigured() {\n try {\n if (this.#options.deleteEmptyDownloadFoldersAfterDownload && await this.#fileSystem.folderIsEmpty(this.#options.downloadFolder!))\n await this.#fileSystem.deleteFolder(this.#options.downloadFolder!);\n }\n catch (error) {\n this.#logger.logWarning(`cleanupEmptyDownloadFolderIfConfigured failed`, { error });\n }\n }\n\n async #doTheFinalFileRenameAfterFilesIsDownloaded(file: DownloadFileProgress) {\n let created = false;\n let createCounter = 0;\n const original = this.#fileSystem.parseFilePath(file.downloadPath);\n let newPathFormatted = file.downloadPath;\n do {\n // we do not want to re-reserve disk space when creating the target file (final name) - so file size is omitted\n created = await this.#fileSystem.createFile(newPathFormatted, false);\n if (!created) {\n createCounter += 1;\n const newPath = {\n dir: original.dir,\n name: `${original.name} (${createCounter})`,\n ext: original.ext,\n };\n newPathFormatted = this.#fileSystem.formatFilePath(newPath);\n }\n } while (created === false && createCounter < 10000);\n\n if (!created)\n throw new DownloadError(`Downloader could not rename temp file ${file.temporaryDownloadPath} to ${file.downloadPath}. It tried until counter=${createCounter}`, undefined, DownloadErrorCode.TooManyFileRenameAttempts);\n\n let renamed = false;\n let renameCounter = 0;\n let lastError: Error | undefined;\n while (!renamed && renameCounter < 5) {\n renameCounter += 1;\n try {\n await this.#fileSystem.renameFile(file.temporaryDownloadPath!, newPathFormatted);\n renamed = true;\n this.#logger.logInfo(`Downloader renamed ${file.temporaryDownloadPath} to ${newPathFormatted} at attempt ${renameCounter}`);\n }\n catch (error) {\n lastError = error as Error;\n this.#logger.logError(lastError, `Downloader could not rename ${file.temporaryDownloadPath} to ${newPathFormatted} attempt ${renameCounter}`);\n }\n }\n if (!renamed)\n await this.#cleanupFailedRenameTarget(newPathFormatted);\n\n if (!renamed)\n throw new DownloadError(`Downloader could not rename ${file.temporaryDownloadPath} to ${newPathFormatted} after ${renameCounter} attempts.`, { cause: lastError }, DownloadErrorCode.RenameFromTemporaryFilenameToFinalFailure);\n else\n return newPathFormatted;\n }\n\n async #cleanupFailedRenameTarget(pathToDelete: string) {\n try {\n await this.#fileSystem.deleteFile(pathToDelete);\n }\n catch (error) {\n this.#logger.logWarning(`Could not cleanup failed rename target ${pathToDelete}`, { error });\n }\n }\n}\n"]}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -29,9 +29,10 @@ export { default as FsError } from "./utils/fileSystem/fsError.js";
|
|
|
29
29
|
export { default as ConcurrencyController } from "./utils/concurrencyController/concurrencyController.js";
|
|
30
30
|
export { default as ConcurrencyReleaser } from "./utils/concurrencyController/concurrencyReleaser.js";
|
|
31
31
|
export { default as TransferConcurrencyController } from "./utils/concurrencyController/transferConcurrencyController.js";
|
|
32
|
-
export { TransferUploadExportData, TransferUploadExportDataMetadata } from "./uploader/export/transferUploadExportData.js";
|
|
32
|
+
export { TransferUploadExportData, TransferUploadExportDataAppendInfo, TransferUploadExportDataMetadata } from "./uploader/export/transferUploadExportData.js";
|
|
33
33
|
export { default as TransferUploadMetadata } from "./uploader/export/transferUploadMetadata.js";
|
|
34
34
|
export { default as TransferUploadExportState } from "./uploader/export/transferUploadExportState.js";
|
|
35
|
+
export { default as RegisteredTransferFile } from "./uploader/registeredTransferFile.js";
|
|
35
36
|
export { ContinuousChunksCalculatorState, ContinuousChunk } from "./uploader/state/continuousChunksCalculator.js";
|
|
36
37
|
export { default as FileChunkUploadFailedEventArgs } from "./uploader/eventArgs/fileChunkUploadFailedEventArgs.js";
|
|
37
38
|
export { default as FileChunkUploadCompletedPartiallyEventArgs } from "./uploader/eventArgs/fileChunkUploadCompletedPartiallyEventArgs.js";
|
|
@@ -41,6 +42,7 @@ export { default as FileChunkUploadProgressedEventArgs } from "./uploader/eventA
|
|
|
41
42
|
export { default as TransferUploadProgressedEventArgs } from "./uploader/eventArgs/transferUploadProgressedEventArgs.js";
|
|
42
43
|
export { default as FileUploadEventArgs } from "./uploader/eventArgs/fileUploadEventArgs.js";
|
|
43
44
|
export { default as FileUploadFailedEventArgs } from "./uploader/eventArgs/fileUploadFailedEventArgs.js";
|
|
45
|
+
export { default as FilesRegistrationBatchFailedEventArgs } from "./uploader/eventArgs/filesRegistrationBatchFailedEventArgs.js";
|
|
44
46
|
export { default as FileAckFailedEventArgs } from "./uploader/eventArgs/fileAckFailedEventArgs.js";
|
|
45
47
|
export { default as FilesBatchAckFailedEventArgs } from "./uploader/eventArgs/filesBatchAckFailedEventArgs.js";
|
|
46
48
|
export { default as TransferUploadCompletedEventArgs } from "./uploader/eventArgs/transferUploadCompletedEventArgs.js";
|