filemail-sdk 10.0.0 → 10.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +158 -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/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
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import TransferUploadError from "./transferUploadError.js";
|
|
2
|
+
import TransferUploadEvent from "./transferUploadEvent.js";
|
|
3
|
+
const REGISTER_ITEMS_BATCH_SIZE = 250;
|
|
4
|
+
export default class TransferFilesRegistrar {
|
|
5
|
+
#apiClient;
|
|
6
|
+
#eventsEngine;
|
|
7
|
+
#files;
|
|
8
|
+
#registeredFiles = new Map();
|
|
9
|
+
#failedRegistrations = new Map();
|
|
10
|
+
#currentObserver;
|
|
11
|
+
#transferId;
|
|
12
|
+
#transferKey;
|
|
13
|
+
#stopController;
|
|
14
|
+
#removeExternalAbortListener;
|
|
15
|
+
#isRegisteringAllFilesDone = true;
|
|
16
|
+
#runningPromise;
|
|
17
|
+
constructor(apiClient, eventsEngine, files) {
|
|
18
|
+
this.#apiClient = apiClient;
|
|
19
|
+
this.#eventsEngine = eventsEngine;
|
|
20
|
+
this.#files = files;
|
|
21
|
+
}
|
|
22
|
+
getRegisteredFile(externalFileId) {
|
|
23
|
+
return this.#registeredFiles.get(externalFileId);
|
|
24
|
+
}
|
|
25
|
+
start(transferId, transferKey, pauseAndAbortSignal) {
|
|
26
|
+
if (!transferId || !transferKey)
|
|
27
|
+
throw new TransferUploadError(`TransferId and TransferKey are required`);
|
|
28
|
+
if (this.#runningPromise)
|
|
29
|
+
throw new TransferUploadError(`Registrar is already running`);
|
|
30
|
+
if (pauseAndAbortSignal?.aborted)
|
|
31
|
+
return;
|
|
32
|
+
this.#transferId = transferId;
|
|
33
|
+
this.#transferKey = transferKey;
|
|
34
|
+
this.#isRegisteringAllFilesDone = false;
|
|
35
|
+
this.#failedRegistrations.clear();
|
|
36
|
+
this.createStopController(pauseAndAbortSignal);
|
|
37
|
+
this.#runningPromise = this.runRegistration();
|
|
38
|
+
}
|
|
39
|
+
createStopController(pauseAndAbortSignal) {
|
|
40
|
+
const stopController = new AbortController();
|
|
41
|
+
this.#stopController = stopController;
|
|
42
|
+
const abortRegistration = () => stopController.abort(pauseAndAbortSignal?.reason);
|
|
43
|
+
pauseAndAbortSignal?.addEventListener(`abort`, abortRegistration, { once: true });
|
|
44
|
+
this.#removeExternalAbortListener = () => pauseAndAbortSignal?.removeEventListener(`abort`, abortRegistration);
|
|
45
|
+
}
|
|
46
|
+
async stop() {
|
|
47
|
+
if (!this.#runningPromise)
|
|
48
|
+
return;
|
|
49
|
+
this.#stopController?.abort();
|
|
50
|
+
await this.#runningPromise;
|
|
51
|
+
}
|
|
52
|
+
async waitUntilFileRegistered(wantedExternalFileId) {
|
|
53
|
+
if (this.#currentObserver)
|
|
54
|
+
throw new TransferUploadError(`Current implementation allows only one observer`);
|
|
55
|
+
return new Promise(resolve => {
|
|
56
|
+
this.#currentObserver = { wantedExternalFileId, resolve };
|
|
57
|
+
this.notifyObserver();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async runRegistration() {
|
|
61
|
+
try {
|
|
62
|
+
await this.registerMissingFiles();
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
this.#isRegisteringAllFilesDone = true;
|
|
66
|
+
this.notifyObserver();
|
|
67
|
+
this.#removeExternalAbortListener?.();
|
|
68
|
+
this.#removeExternalAbortListener = undefined;
|
|
69
|
+
this.#stopController = undefined;
|
|
70
|
+
this.#runningPromise = undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async registerMissingFiles() {
|
|
74
|
+
const filesToRegister = this.getFilesMissingRegistration();
|
|
75
|
+
for (let start = 0; start < filesToRegister.length; start += REGISTER_ITEMS_BATCH_SIZE) {
|
|
76
|
+
if (this.#stopController.signal.aborted)
|
|
77
|
+
break;
|
|
78
|
+
const filesBatch = filesToRegister.slice(start, start + REGISTER_ITEMS_BATCH_SIZE);
|
|
79
|
+
try {
|
|
80
|
+
const registeredBatchEntries = await this.registerSingleBatch(filesBatch);
|
|
81
|
+
for (const [externalFileId, registeredFile] of registeredBatchEntries)
|
|
82
|
+
this.#registeredFiles.set(externalFileId, registeredFile);
|
|
83
|
+
this.#eventsEngine.emit(TransferUploadEvent.RecreateDataUpdated);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
for (const file of filesBatch)
|
|
87
|
+
this.#failedRegistrations.set(file.externalId, error);
|
|
88
|
+
if (!this.#stopController?.signal.aborted)
|
|
89
|
+
this.notifyBatchFailed(filesBatch, error);
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
this.notifyObserver();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async registerSingleBatch(filesBatch) {
|
|
97
|
+
const registerFilesRequest = {
|
|
98
|
+
transferkey: this.#transferKey,
|
|
99
|
+
items: filesBatch.map(file => ({
|
|
100
|
+
path: this.joinTransferPath(file.fileDestinationPathInTransfer, file.fileName),
|
|
101
|
+
type: `File`,
|
|
102
|
+
size: file.fileSizeInBytes,
|
|
103
|
+
})),
|
|
104
|
+
};
|
|
105
|
+
const response = await this.#apiClient.registerTransferFiles(this.#transferId, registerFilesRequest, this.#stopController?.signal);
|
|
106
|
+
return this.validateRegistrationBatchResponse(filesBatch, response);
|
|
107
|
+
}
|
|
108
|
+
notifyBatchFailed(filesBatch, error) {
|
|
109
|
+
const eventArgs = {
|
|
110
|
+
externalFileIds: filesBatch.map(file => file.externalId),
|
|
111
|
+
error: error,
|
|
112
|
+
};
|
|
113
|
+
this.#eventsEngine.emit(TransferUploadEvent.FilesRegistrationBatchFailed, eventArgs);
|
|
114
|
+
}
|
|
115
|
+
getFilesMissingRegistration() {
|
|
116
|
+
return this.#files.filter(file => !this.#registeredFiles.has(file.externalId));
|
|
117
|
+
}
|
|
118
|
+
validateRegistrationBatchResponse(filesBatch, response) {
|
|
119
|
+
if (response.items.length !== filesBatch.length)
|
|
120
|
+
throw new TransferUploadError(`Invalid register transfer files response`);
|
|
121
|
+
return response.items.map((item, index) => {
|
|
122
|
+
const file = filesBatch[index];
|
|
123
|
+
if (!file || !item.uploadItemId || !item.fileId)
|
|
124
|
+
throw new TransferUploadError(`Invalid register transfer files response`);
|
|
125
|
+
return [file.externalId, { uploadItemId: item.uploadItemId, fileId: item.fileId }];
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
joinTransferPath(directoryPath, fileName) {
|
|
129
|
+
const normalizedDirectoryPath = directoryPath.replace(/^\/+|\/+$/g, ``);
|
|
130
|
+
const normalizedFileName = fileName.replace(/^\/+/g, ``);
|
|
131
|
+
if (!normalizedDirectoryPath)
|
|
132
|
+
return normalizedFileName;
|
|
133
|
+
return `${normalizedDirectoryPath}/${normalizedFileName}`;
|
|
134
|
+
}
|
|
135
|
+
notifyObserver() {
|
|
136
|
+
if (!this.#currentObserver)
|
|
137
|
+
return;
|
|
138
|
+
const { wantedExternalFileId, resolve } = this.#currentObserver;
|
|
139
|
+
const isFileRegistered = this.#registeredFiles.has(wantedExternalFileId);
|
|
140
|
+
const isFileFailed = this.#failedRegistrations.has(wantedExternalFileId);
|
|
141
|
+
if (isFileRegistered)
|
|
142
|
+
resolve({ isRegisteredSuccessfully: true });
|
|
143
|
+
else if (isFileFailed)
|
|
144
|
+
resolve({ isRegisteredSuccessfully: false, error: this.#failedRegistrations.get(wantedExternalFileId) });
|
|
145
|
+
else if (this.#isRegisteringAllFilesDone)
|
|
146
|
+
resolve({ isRegisteredSuccessfully: false, error: new Error(`File has never been picked up for registration`) });
|
|
147
|
+
else
|
|
148
|
+
return; // continue waiting for new batch registrations
|
|
149
|
+
this.#currentObserver = undefined;
|
|
150
|
+
}
|
|
151
|
+
export() {
|
|
152
|
+
return this.#registeredFiles;
|
|
153
|
+
}
|
|
154
|
+
recoverFromExportedState(registeredFiles) {
|
|
155
|
+
this.#registeredFiles = new Map(registeredFiles);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=transferFilesRegistrar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transferFilesRegistrar.js","sourceRoot":"","sources":["../../../src/uploader/transferFilesRegistrar.ts"],"names":[],"mappings":"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","sourcesContent":["import TransferUploadError from \"./transferUploadError.js\";\nimport TransferUploadEvent from \"./transferUploadEvent.js\";\n\nimport type ApiClient from \"../utils/api/apiClient.js\";\nimport type EventsEngine from \"../utils/events/eventsEngine.js\";\nimport type FileDetails from \"../utils/fileSystem/fileDetails.js\";\nimport type RegisteredTransferFile from \"./registeredTransferFile.js\";\nimport type FilesRegistrationBatchFailedEventArgs from \"./eventArgs/filesRegistrationBatchFailedEventArgs.js\";\nimport type { RegisterTransferFilesRequest } from \"../utils/api/dtos/registerTransferFilesRequest.js\";\nimport type { RegisterTransferFilesResponse } from \"../utils/api/dtos/registerTransferFilesResponse.js\";\n\nconst REGISTER_ITEMS_BATCH_SIZE = 250;\nexport default class TransferFilesRegistrar {\n #apiClient: ApiClient;\n #eventsEngine: EventsEngine;\n #files: readonly Readonly<FileDetails>[];\n\n #registeredFiles = new Map<string | number, RegisteredTransferFile>();\n #failedRegistrations = new Map<string | number, Error>();\n #currentObserver: { wantedExternalFileId: string | number, resolve: (value: RegistrationResult) => void } | undefined;\n\n #transferId: string | undefined;\n #transferKey: string | undefined;\n\n #stopController: AbortController | undefined;\n #removeExternalAbortListener: (() => void) | undefined;\n\n #isRegisteringAllFilesDone = true;\n\n #runningPromise: Promise<void> | undefined;\n\n constructor(apiClient: ApiClient, eventsEngine: EventsEngine, files: readonly Readonly<FileDetails>[]) {\n this.#apiClient = apiClient;\n this.#eventsEngine = eventsEngine;\n this.#files = files;\n }\n\n getRegisteredFile(externalFileId: string | number): RegisteredTransferFile | undefined {\n return this.#registeredFiles.get(externalFileId);\n }\n\n start(transferId: string, transferKey: string, pauseAndAbortSignal?: AbortSignal): void {\n if (!transferId || !transferKey)\n throw new TransferUploadError(`TransferId and TransferKey are required`);\n\n if (this.#runningPromise)\n throw new TransferUploadError(`Registrar is already running`);\n\n if (pauseAndAbortSignal?.aborted)\n return;\n\n this.#transferId = transferId;\n this.#transferKey = transferKey;\n\n this.#isRegisteringAllFilesDone = false;\n\n this.#failedRegistrations.clear();\n\n this.createStopController(pauseAndAbortSignal);\n\n this.#runningPromise = this.runRegistration();\n }\n\n private createStopController(pauseAndAbortSignal: AbortSignal | undefined) {\n const stopController = new AbortController();\n\n this.#stopController = stopController;\n\n const abortRegistration = () => stopController.abort(pauseAndAbortSignal?.reason);\n\n pauseAndAbortSignal?.addEventListener(`abort`, abortRegistration, { once: true });\n\n this.#removeExternalAbortListener = () => pauseAndAbortSignal?.removeEventListener(`abort`, abortRegistration);\n }\n\n async stop(): Promise<void> {\n if (!this.#runningPromise)\n return;\n\n this.#stopController?.abort();\n\n await this.#runningPromise;\n }\n\n async waitUntilFileRegistered(wantedExternalFileId: string | number): Promise<RegistrationResult> {\n if (this.#currentObserver)\n throw new TransferUploadError(`Current implementation allows only one observer`);\n\n return new Promise(resolve => {\n this.#currentObserver = { wantedExternalFileId, resolve };\n this.notifyObserver();\n });\n }\n\n private async runRegistration(): Promise<void> {\n try {\n await this.registerMissingFiles();\n }\n finally {\n this.#isRegisteringAllFilesDone = true;\n this.notifyObserver();\n this.#removeExternalAbortListener?.();\n\n this.#removeExternalAbortListener = undefined;\n this.#stopController = undefined;\n this.#runningPromise = undefined;\n }\n }\n\n private async registerMissingFiles(): Promise<void> {\n const filesToRegister = this.getFilesMissingRegistration();\n\n for (let start = 0; start < filesToRegister.length; start += REGISTER_ITEMS_BATCH_SIZE) {\n if (this.#stopController!.signal.aborted)\n break;\n\n const filesBatch = filesToRegister.slice(start, start + REGISTER_ITEMS_BATCH_SIZE);\n\n try {\n const registeredBatchEntries = await this.registerSingleBatch(filesBatch);\n\n for (const [externalFileId, registeredFile] of registeredBatchEntries)\n this.#registeredFiles.set(externalFileId, registeredFile);\n\n this.#eventsEngine.emit(TransferUploadEvent.RecreateDataUpdated);\n }\n catch (error) {\n for (const file of filesBatch)\n this.#failedRegistrations.set(file.externalId, error as Error);\n\n if (!this.#stopController?.signal.aborted)\n this.notifyBatchFailed(filesBatch, error);\n }\n finally {\n this.notifyObserver();\n }\n }\n }\n\n private async registerSingleBatch(filesBatch: readonly Readonly<FileDetails>[]): Promise<Array<[string | number, RegisteredTransferFile]>> {\n const registerFilesRequest: RegisterTransferFilesRequest = {\n transferkey: this.#transferKey!,\n items: filesBatch.map(file => ({\n path: this.joinTransferPath(file.fileDestinationPathInTransfer, file.fileName),\n type: `File`,\n size: file.fileSizeInBytes,\n })),\n };\n\n const response = await this.#apiClient.registerTransferFiles(this.#transferId!, registerFilesRequest, this.#stopController?.signal);\n return this.validateRegistrationBatchResponse(filesBatch, response);\n }\n\n private notifyBatchFailed(filesBatch: Readonly<FileDetails>[], error: unknown) {\n const eventArgs: FilesRegistrationBatchFailedEventArgs = {\n externalFileIds: filesBatch.map(file => file.externalId),\n error: error as Error,\n };\n\n this.#eventsEngine.emit(TransferUploadEvent.FilesRegistrationBatchFailed, eventArgs);\n }\n\n private getFilesMissingRegistration(): readonly Readonly<FileDetails>[] {\n return this.#files.filter(file => !this.#registeredFiles.has(file.externalId));\n }\n\n private validateRegistrationBatchResponse(filesBatch: readonly Readonly<FileDetails>[], response: RegisterTransferFilesResponse): Array<[string | number, RegisteredTransferFile]> {\n if (response.items.length !== filesBatch.length)\n throw new TransferUploadError(`Invalid register transfer files response`);\n\n return response.items.map((item, index): [string | number, RegisteredTransferFile] => {\n const file = filesBatch[index];\n\n if (!file || !item.uploadItemId || !item.fileId)\n throw new TransferUploadError(`Invalid register transfer files response`);\n\n return [file.externalId, { uploadItemId: item.uploadItemId, fileId: item.fileId }];\n });\n }\n\n private joinTransferPath(directoryPath: string, fileName: string): string {\n const normalizedDirectoryPath = directoryPath.replace(/^\\/+|\\/+$/g, ``);\n const normalizedFileName = fileName.replace(/^\\/+/g, ``);\n\n if (!normalizedDirectoryPath)\n return normalizedFileName;\n\n return `${normalizedDirectoryPath}/${normalizedFileName}`;\n }\n\n private notifyObserver(): void {\n if (!this.#currentObserver)\n return;\n\n const { wantedExternalFileId, resolve } = this.#currentObserver;\n const isFileRegistered = this.#registeredFiles.has(wantedExternalFileId);\n const isFileFailed = this.#failedRegistrations.has(wantedExternalFileId);\n\n if (isFileRegistered)\n resolve({ isRegisteredSuccessfully: true });\n else if (isFileFailed)\n resolve({ isRegisteredSuccessfully: false, error: this.#failedRegistrations.get(wantedExternalFileId)! });\n else if (this.#isRegisteringAllFilesDone)\n resolve({ isRegisteredSuccessfully: false, error: new Error(`File has never been picked up for registration`) });\n else\n return; // continue waiting for new batch registrations\n\n this.#currentObserver = undefined;\n }\n\n export(): ReadonlyMap<string | number, RegisteredTransferFile> {\n return this.#registeredFiles;\n }\n\n recoverFromExportedState(registeredFiles: readonly (readonly [string | number, RegisteredTransferFile])[]): void {\n this.#registeredFiles = new Map(registeredFiles);\n }\n}\n\nexport type RegistrationResult = { isRegisteredSuccessfully: true; } | { isRegisteredSuccessfully: false; error: Error; };"]}
|
|
@@ -11,6 +11,7 @@ import type FileChunkUploadFailedEventArgs from './eventArgs/fileChunkUploadFail
|
|
|
11
11
|
import type FileUploadEventArgs from './eventArgs/fileUploadEventArgs.js';
|
|
12
12
|
import type TransferUploadCompletedEventArgs from './eventArgs/transferUploadCompletedEventArgs.js';
|
|
13
13
|
import type FileUploadFailedEventArgs from './eventArgs/fileUploadFailedEventArgs.js';
|
|
14
|
+
import type FilesRegistrationBatchFailedEventArgs from './eventArgs/filesRegistrationBatchFailedEventArgs.js';
|
|
14
15
|
import type FileAckFailedEventArgs from './eventArgs/fileAckFailedEventArgs.js';
|
|
15
16
|
import type FilesBatchAckFailedEventArgs from './eventArgs/filesBatchAckFailedEventArgs.js';
|
|
16
17
|
import type TransferUploadAcker from './transferUploadAcker.js';
|
|
@@ -39,11 +40,14 @@ export default class TransferUpload<T extends FileDetails> {
|
|
|
39
40
|
get totalSizeInBytes(): number;
|
|
40
41
|
get transferId(): string | undefined;
|
|
41
42
|
constructor(chunkStreamProviderFactory: UploaderChunkStreamProviderFactory<T>, apiClient: ApiClient, fileServerClientFactory: FileServerClientFactory, eventsEngine: EventsEngine, info: TransferUploadInfo<T> | TransferUploadAppendInfo<T>, config: TransferUploadConfig, concurrencyController: ConcurrencyController, cryptography: CryptographyProvider, acker: TransferUploadAcker);
|
|
43
|
+
private isLegacyTransferAppend;
|
|
42
44
|
private isUploadAppend;
|
|
43
45
|
private isUploadAppendInfo;
|
|
44
|
-
private registerFilesAndCreateTransferMetadataFromInfo;
|
|
45
46
|
private createTransferMetadataFromInfo;
|
|
46
47
|
run(transferPauseSignal: PauseSignal, transferAbortSignal: AbortSignal): Promise<void>;
|
|
48
|
+
private startBackgroundWorkers;
|
|
49
|
+
private stopBackgroundWorkers;
|
|
50
|
+
private waitUntilFileRegistered;
|
|
47
51
|
private notifyMetadataDetermined;
|
|
48
52
|
private sendChunkAndKeepUpdatingState;
|
|
49
53
|
private sendChunk;
|
|
@@ -54,8 +58,6 @@ export default class TransferUpload<T extends FileDetails> {
|
|
|
54
58
|
private shouldStopProcessing;
|
|
55
59
|
private isFailureAbortRequested;
|
|
56
60
|
private startApiTransferAndCreateMetadata;
|
|
57
|
-
private registerTransferFilesWithValidation;
|
|
58
|
-
private joinTransferPath;
|
|
59
61
|
private getRegisteredFile;
|
|
60
62
|
private enqueueFileAck;
|
|
61
63
|
private hasUnackedFiles;
|
|
@@ -71,6 +73,7 @@ export default class TransferUpload<T extends FileDetails> {
|
|
|
71
73
|
addEventListener(eventName: TransferUploadEvent.TransferRun | TransferUploadEvent.TransferPauseRequested | TransferUploadEvent.TransferPaused | TransferUploadEvent.TransferAbortRequested | TransferUploadEvent.TransferAborted | TransferUploadEvent.TransferCancelRequested | TransferUploadEvent.TransferCanceled | TransferUploadEvent.TransferFailed, handler: () => void): void;
|
|
72
74
|
addEventListener(eventName: TransferUploadEvent.FileUploadStarted | TransferUploadEvent.FileUploadCompleted | TransferUploadEvent.FileCompleted, handler: (event: FileUploadEventArgs) => void): void;
|
|
73
75
|
addEventListener(eventName: TransferUploadEvent.FileUploadFailed, handler: (event: FileUploadFailedEventArgs) => void): void;
|
|
76
|
+
addEventListener(eventName: TransferUploadEvent.FilesRegistrationBatchFailed, handler: (event: FilesRegistrationBatchFailedEventArgs) => void): void;
|
|
74
77
|
addEventListener(eventName: TransferUploadEvent.FileAckFailed, handler: (event: FileAckFailedEventArgs) => void): void;
|
|
75
78
|
addEventListener(eventName: TransferUploadEvent.FilesBatchAckFailed, handler: (event: FilesBatchAckFailedEventArgs) => void): void;
|
|
76
79
|
addEventListener(eventName: TransferUploadEvent.FileChunkUploadProgressed, handler: (event: FileChunkUploadProgressedEventArgs) => void): void;
|
|
@@ -84,6 +87,7 @@ export default class TransferUpload<T extends FileDetails> {
|
|
|
84
87
|
addEventListener(eventName: string, handler: (arg?: any) => void): void;
|
|
85
88
|
exportAsString(): string;
|
|
86
89
|
export(): TransferUploadExportData<T>;
|
|
90
|
+
private getInfoExportValue;
|
|
87
91
|
private getTransferMetadataExportValue;
|
|
88
92
|
static recreate<T extends FileDetails>(transferExportData: TransferUploadExportData<T>, config: TransferUploadConfig, chunkStreamProviderFactory: UploaderChunkStreamProviderFactory<T>, apiClient: ApiClient, fileServerClientFactory: FileServerClientFactory, eventsEngine: EventsEngine, concurrencyController: ConcurrencyController, cryptography: CryptographyProvider, acker: TransferUploadAcker): TransferUpload<T>;
|
|
89
93
|
private static recreateTransferMetadata;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transferUpload.d.ts","sourceRoot":"","sources":["../../../src/uploader/transferUpload.ts"],"names":[],"mappings":"AAEA,OAAO,cAAc,MAAM,kCAAkC,CAAC;AAC9D,OAAO,mBAAmB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"transferUpload.d.ts","sourceRoot":"","sources":["../../../src/uploader/transferUpload.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import TransferUploadError from "./transferUploadError.js";
|
|
|
3
3
|
import TransferStatus from "../utils/types/transferStatus.js";
|
|
4
4
|
import TransferUploadEvent from './transferUploadEvent.js';
|
|
5
5
|
import ChunksIterator from './chunksIterator/chunksIterator.js';
|
|
6
|
+
import TransferFilesRegistrar from './transferFilesRegistrar.js';
|
|
6
7
|
import mergeAbortAndPauseSignals from '../utils/mergeAbortAndPauseSignals.js';
|
|
7
8
|
import ApiError from '../utils/api/apiError.js';
|
|
8
9
|
import FsError from '../utils/fileSystem/fsError.js';
|
|
@@ -10,7 +11,6 @@ import ApiFilemail449Error from '../utils/api/apiFilemail449Error.js';
|
|
|
10
11
|
import { promiseAllSettled } from '../utils/promiseAll.js';
|
|
11
12
|
import { isTransferFailureAbortReason } from './transferFailureAbortReason.js';
|
|
12
13
|
import { concatUint8Arrays, hexToUint8Array, uint8ArrayToHex } from '../utils/uint8ArrayUtils.js';
|
|
13
|
-
const REGISTER_ITEMS_BATCH_SIZE = 250;
|
|
14
14
|
export default class TransferUpload {
|
|
15
15
|
#totalSizeInBytes;
|
|
16
16
|
#chunkStreamProviderFactory;
|
|
@@ -29,7 +29,8 @@ export default class TransferUpload {
|
|
|
29
29
|
#transferRecipientTrackingLinks;
|
|
30
30
|
#pauseSignal;
|
|
31
31
|
#abortSignal;
|
|
32
|
-
#
|
|
32
|
+
#mergedPauseAndAbortController;
|
|
33
|
+
#filesRegistrar;
|
|
33
34
|
pauseEventListener;
|
|
34
35
|
abortEventListener;
|
|
35
36
|
#isRunMethodRunning = false;
|
|
@@ -75,6 +76,10 @@ export default class TransferUpload {
|
|
|
75
76
|
this.#concurrencyController = concurrencyController;
|
|
76
77
|
this.#cryptography = cryptography;
|
|
77
78
|
this.#acker = acker;
|
|
79
|
+
this.#filesRegistrar = this.isLegacyTransferAppend() ? undefined : new TransferFilesRegistrar(apiClient, eventsEngine, info.files);
|
|
80
|
+
}
|
|
81
|
+
isLegacyTransferAppend() {
|
|
82
|
+
return this.isUploadAppendInfo(this.#info) && (this.#info.isLegacyTransfer === undefined || this.#info.isLegacyTransfer === true);
|
|
78
83
|
}
|
|
79
84
|
isUploadAppend() {
|
|
80
85
|
return this.isUploadAppendInfo(this.#info);
|
|
@@ -82,22 +87,16 @@ export default class TransferUpload {
|
|
|
82
87
|
isUploadAppendInfo(info) {
|
|
83
88
|
return info.transferKey !== undefined;
|
|
84
89
|
}
|
|
85
|
-
|
|
90
|
+
createTransferMetadataFromInfo() {
|
|
86
91
|
if (!this.isUploadAppendInfo(this.#info))
|
|
87
92
|
throw new TransferUploadError(`Options are not TransferUploadAppendOptions`);
|
|
88
|
-
|
|
89
|
-
this.createTransferMetadataFromInfo(this.#info, registeredFiles);
|
|
90
|
-
this.#eventsEngine.emit(TransferUploadEvent.RecreateDataUpdated);
|
|
91
|
-
}
|
|
92
|
-
createTransferMetadataFromInfo(info, registeredFiles) {
|
|
93
|
-
this.#transferDownloadUrl = info.transferDownloadUrl;
|
|
93
|
+
this.#transferDownloadUrl = this.#info.transferDownloadUrl;
|
|
94
94
|
this.#transferMetadata = {
|
|
95
|
-
transferId: info.transferId,
|
|
96
|
-
transferKey: info.transferKey,
|
|
97
|
-
transferFileServerUrl: info.transferFileServerUrl,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
encryptionData: info.e2eeData,
|
|
95
|
+
transferId: this.#info.transferId,
|
|
96
|
+
transferKey: this.#info.transferKey,
|
|
97
|
+
transferFileServerUrl: this.#info.transferFileServerUrl,
|
|
98
|
+
transferRegion: this.#info.transferRegion,
|
|
99
|
+
encryptionData: this.#info.e2eeData,
|
|
101
100
|
};
|
|
102
101
|
}
|
|
103
102
|
async run(transferPauseSignal, transferAbortSignal) {
|
|
@@ -106,7 +105,7 @@ export default class TransferUpload {
|
|
|
106
105
|
try {
|
|
107
106
|
this.#pauseSignal = transferPauseSignal;
|
|
108
107
|
this.#abortSignal = transferAbortSignal;
|
|
109
|
-
this.#
|
|
108
|
+
this.#mergedPauseAndAbortController = mergeAbortAndPauseSignals(transferPauseSignal, transferAbortSignal);
|
|
110
109
|
if (!this.#transferState)
|
|
111
110
|
this.#transferState = new TransferUploadState(this.files, this.#eventsEngine, this.#config.currentRatesTimespanInMs, this.#config.progressEventThrottlingInMs);
|
|
112
111
|
else
|
|
@@ -114,16 +113,19 @@ export default class TransferUpload {
|
|
|
114
113
|
this.#transferState.transferRun();
|
|
115
114
|
this.addPauseAndStopListeners();
|
|
116
115
|
if (this.isUploadAppend() && !this.#transferMetadata)
|
|
117
|
-
|
|
116
|
+
this.createTransferMetadataFromInfo();
|
|
118
117
|
else if (!this.#transferMetadata)
|
|
119
118
|
await this.startApiTransferAndCreateMetadata();
|
|
120
119
|
this.notifyMetadataDetermined();
|
|
121
|
-
this
|
|
120
|
+
this.startBackgroundWorkers(transferPauseSignal, transferAbortSignal);
|
|
122
121
|
const ongoingChunkUploads = new Set();
|
|
123
122
|
for (const file of this.files) {
|
|
124
123
|
const fileStatus = this.#transferState.getFile(file.externalId);
|
|
125
124
|
if (fileStatus.isCompleted)
|
|
126
125
|
continue;
|
|
126
|
+
const registrationResult = await this.waitUntilFileRegistered(file);
|
|
127
|
+
if (!registrationResult.isRegisteredSuccessfully)
|
|
128
|
+
continue;
|
|
127
129
|
if (fileStatus.isUploadCompleted) {
|
|
128
130
|
this.enqueueFileAck(file);
|
|
129
131
|
continue;
|
|
@@ -131,7 +133,6 @@ export default class TransferUpload {
|
|
|
131
133
|
const alreadySentChunks = this.#transferState.getChunksForFile(file.externalId);
|
|
132
134
|
const chunksIterator = new ChunksIterator(alreadySentChunks, file.fileSizeInBytes, this.#config.chunkSizeInBytes);
|
|
133
135
|
for (const chunk of chunksIterator.getChunksIterator()) {
|
|
134
|
-
// eslint-disable-next-line no-await-in-loop
|
|
135
136
|
const releaseSemaphore = await this.#concurrencyController.acquire();
|
|
136
137
|
if (this.shouldStopProcessing()) {
|
|
137
138
|
releaseSemaphore();
|
|
@@ -154,8 +155,6 @@ export default class TransferUpload {
|
|
|
154
155
|
this.#transferState.transferPaused();
|
|
155
156
|
else if (this.#transferState.status === TransferStatus.Aborting)
|
|
156
157
|
this.#transferState.transferAborted();
|
|
157
|
-
// else if (this.isFailureAbortRequested())
|
|
158
|
-
// this.#transferState.transferFailed();
|
|
159
158
|
else if (this.uploadedBytesCount !== this.totalSizeInBytes || this.hasUnackedFiles())
|
|
160
159
|
this.#transferState.transferFailed();
|
|
161
160
|
else {
|
|
@@ -167,10 +166,6 @@ export default class TransferUpload {
|
|
|
167
166
|
// We can get here with pausing or aborting status if any API call fails (e.g., finalizeTransfer) so we need to check the status again
|
|
168
167
|
if (!this.#transferState)
|
|
169
168
|
this.#eventsEngine.emit(TransferUploadEvent.TransferFailed);
|
|
170
|
-
// else if (this.isFailureAbortRequested()) {
|
|
171
|
-
// this.#transferState.transferFailed();
|
|
172
|
-
// return;
|
|
173
|
-
// }
|
|
174
169
|
else if (this.#transferState.status === TransferStatus.Pausing) {
|
|
175
170
|
this.#transferState.transferPaused();
|
|
176
171
|
return;
|
|
@@ -187,20 +182,36 @@ export default class TransferUpload {
|
|
|
187
182
|
throw new TransferUploadError(`Unhandled error occured. See 'cause' for more details`, { cause: error });
|
|
188
183
|
}
|
|
189
184
|
finally {
|
|
190
|
-
await this
|
|
185
|
+
await this.stopBackgroundWorkers();
|
|
191
186
|
this.removePauseAndStopListeners();
|
|
192
187
|
this.#isRunMethodRunning = false;
|
|
193
188
|
}
|
|
194
189
|
}
|
|
190
|
+
startBackgroundWorkers(transferPauseSignal, transferAbortSignal) {
|
|
191
|
+
const fileAckSuccessfullCallback = (externalFileId, uploadItemId) => this.#transferState.fileCompleted(externalFileId, uploadItemId);
|
|
192
|
+
const fileAckFailedCallback = (externalFileId, uploadItemId, reason, error) => this.#transferState.fileAckFailed(externalFileId, uploadItemId, reason, error);
|
|
193
|
+
this.#acker.start(this.#transferMetadata.transferId, this.#transferMetadata.transferKey, fileAckSuccessfullCallback, fileAckFailedCallback, transferPauseSignal, transferAbortSignal);
|
|
194
|
+
this.#filesRegistrar?.start(this.#transferMetadata.transferId, this.#transferMetadata.transferKey, this.#mergedPauseAndAbortController?.signal);
|
|
195
|
+
}
|
|
196
|
+
async stopBackgroundWorkers() {
|
|
197
|
+
await Promise.allSettled([
|
|
198
|
+
this.#filesRegistrar?.stop(),
|
|
199
|
+
this.#acker.stop(),
|
|
200
|
+
]);
|
|
201
|
+
}
|
|
202
|
+
async waitUntilFileRegistered(file) {
|
|
203
|
+
if (this.isLegacyTransfer())
|
|
204
|
+
return { isRegisteredSuccessfully: true };
|
|
205
|
+
return await this.#filesRegistrar.waitUntilFileRegistered(file.externalId);
|
|
206
|
+
}
|
|
195
207
|
notifyMetadataDetermined() {
|
|
196
|
-
if (!this.#transferMetadata)
|
|
197
|
-
return;
|
|
198
208
|
const eventArgs = {
|
|
199
209
|
transferId: this.#transferMetadata.transferId,
|
|
200
210
|
fileServerUrl: this.#transferMetadata.transferFileServerUrl,
|
|
201
211
|
region: this.#transferMetadata.transferRegion,
|
|
202
212
|
};
|
|
203
213
|
this.#eventsEngine.emit(TransferUploadEvent.TransferMetadataDetermined, eventArgs);
|
|
214
|
+
this.#eventsEngine.emit(TransferUploadEvent.RecreateDataUpdated);
|
|
204
215
|
}
|
|
205
216
|
async sendChunkAndKeepUpdatingState(file, chunkStartPosition, chunkSizeInBytes, releaseSemaphore) {
|
|
206
217
|
let uploadedBytesCount = 0;
|
|
@@ -292,6 +303,7 @@ export default class TransferUpload {
|
|
|
292
303
|
removePauseAndStopListeners() {
|
|
293
304
|
this.#pauseSignal.removeEventListener(`pause`, this.pauseEventListener);
|
|
294
305
|
this.#abortSignal.removeEventListener(`abort`, this.abortEventListener);
|
|
306
|
+
this.#mergedPauseAndAbortController?.dispose();
|
|
295
307
|
}
|
|
296
308
|
shouldStopProcessing() {
|
|
297
309
|
return this.#transferState.status !== TransferStatus.Running || this.#abortSignal?.aborted === true || this.#pauseSignal?.paused === true;
|
|
@@ -323,58 +335,24 @@ export default class TransferUpload {
|
|
|
323
335
|
filerequestshareid: this.#info.fileRequestShareId,
|
|
324
336
|
customfields: this.#info.customFields,
|
|
325
337
|
};
|
|
326
|
-
const response = await this.#apiClient.initializeTransfer(request, this.#
|
|
327
|
-
const registeredFiles = await this.registerTransferFilesWithValidation(response.transferId, response.transferKey);
|
|
338
|
+
const response = await this.#apiClient.initializeTransfer(request, this.#mergedPauseAndAbortController?.signal);
|
|
328
339
|
this.#transferMetadata = {
|
|
329
340
|
transferId: response.transferId,
|
|
330
341
|
transferKey: response.transferKey,
|
|
331
342
|
transferFileServerUrl: response.transferUrl,
|
|
332
|
-
registeredFiles,
|
|
333
343
|
transferRegion: response.transferRegion,
|
|
334
344
|
encryptionData: encryptionDataAndIvSaltHex?.encryptionData,
|
|
335
345
|
};
|
|
336
|
-
this.#eventsEngine.emit(TransferUploadEvent.RecreateDataUpdated);
|
|
337
346
|
}
|
|
338
347
|
catch (error) {
|
|
339
348
|
throw new TransferUploadError(`Error initializing transfer through the API`, { cause: error });
|
|
340
349
|
}
|
|
341
350
|
}
|
|
342
|
-
async registerTransferFilesWithValidation(transferId, transferKey) {
|
|
343
|
-
const registeredFiles = new Map();
|
|
344
|
-
for (let start = 0; start < this.files.length; start += REGISTER_ITEMS_BATCH_SIZE) {
|
|
345
|
-
const filesBatch = this.files.slice(start, start + REGISTER_ITEMS_BATCH_SIZE);
|
|
346
|
-
// eslint-disable-next-line no-await-in-loop
|
|
347
|
-
const response = await this.#apiClient.registerTransferFiles(transferId, {
|
|
348
|
-
transferkey: transferKey,
|
|
349
|
-
items: filesBatch.map(file => ({
|
|
350
|
-
path: this.joinTransferPath(file.fileDestinationPathInTransfer, file.fileName),
|
|
351
|
-
type: `File`,
|
|
352
|
-
size: file.fileSizeInBytes,
|
|
353
|
-
})),
|
|
354
|
-
}, this.#mergedPauseAndAbortSignal);
|
|
355
|
-
if (response.items.length !== filesBatch.length)
|
|
356
|
-
throw new TransferUploadError(`Invalid register transfer files response`);
|
|
357
|
-
response.items.forEach((item, index) => {
|
|
358
|
-
const file = filesBatch[index];
|
|
359
|
-
if (!file || !item.uploadItemId || !item.fileId)
|
|
360
|
-
throw new TransferUploadError(`Invalid register transfer files response`);
|
|
361
|
-
registeredFiles.set(file.externalId, { uploadItemId: item.uploadItemId, fileId: item.fileId });
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
return registeredFiles;
|
|
365
|
-
}
|
|
366
|
-
joinTransferPath(directoryPath, fileName) {
|
|
367
|
-
const normalizedDirectoryPath = directoryPath.replace(/^\/+|\/+$/g, ``);
|
|
368
|
-
const normalizedFileName = fileName.replace(/^\/+/g, ``);
|
|
369
|
-
if (!normalizedDirectoryPath)
|
|
370
|
-
return normalizedFileName;
|
|
371
|
-
return `${normalizedDirectoryPath}/${normalizedFileName}`;
|
|
372
|
-
}
|
|
373
351
|
getRegisteredFile(externalFileId) {
|
|
374
|
-
return this.#
|
|
352
|
+
return this.#filesRegistrar?.getRegisteredFile(externalFileId);
|
|
375
353
|
}
|
|
376
354
|
enqueueFileAck(file) {
|
|
377
|
-
if (this.isLegacyTransfer()) {
|
|
355
|
+
if (this.isLegacyTransfer()) {
|
|
378
356
|
this.#transferState.fileCompleted(file.externalId, undefined);
|
|
379
357
|
return;
|
|
380
358
|
}
|
|
@@ -389,7 +367,7 @@ export default class TransferUpload {
|
|
|
389
367
|
return this.files.some(file => !this.#transferState.getFile(file.externalId).isCompleted);
|
|
390
368
|
}
|
|
391
369
|
isLegacyTransfer() {
|
|
392
|
-
return this.#
|
|
370
|
+
return this.#filesRegistrar === undefined;
|
|
393
371
|
}
|
|
394
372
|
async generateEncryptionDataAndIvSaltHmacHex(e2eeKey) {
|
|
395
373
|
if (!e2eeKey)
|
|
@@ -419,7 +397,7 @@ export default class TransferUpload {
|
|
|
419
397
|
const request = {
|
|
420
398
|
transferid: this.#transferMetadata.transferId,
|
|
421
399
|
};
|
|
422
|
-
await this.#apiClient.resetTransfer(request, this.#
|
|
400
|
+
await this.#apiClient.resetTransfer(request, this.#mergedPauseAndAbortController?.signal);
|
|
423
401
|
}
|
|
424
402
|
catch (error) {
|
|
425
403
|
throw new TransferUploadError(`Error resetting transfer through the API`, { cause: error });
|
|
@@ -432,7 +410,7 @@ export default class TransferUpload {
|
|
|
432
410
|
transferkey: this.#transferMetadata.transferKey,
|
|
433
411
|
protocol: `tcp`,
|
|
434
412
|
};
|
|
435
|
-
const response = await this.#apiClient.finalizeTransfer(request, this.#
|
|
413
|
+
const response = await this.#apiClient.finalizeTransfer(request, this.#mergedPauseAndAbortController?.signal);
|
|
436
414
|
this.#transferDownloadUrl = response.downloadUrl;
|
|
437
415
|
this.#transferConfirmationUrl = response.confirmationUrl;
|
|
438
416
|
this.#transferRecipientTrackingLinks = response.recipientTrackingLinks;
|
|
@@ -507,21 +485,32 @@ export default class TransferUpload {
|
|
|
507
485
|
throw new TransferUploadError(`Can't export not started Transfer`); // fileStatuses are not created yet and it really doesn't make any sens to export not started transfer
|
|
508
486
|
return {
|
|
509
487
|
transferMetadata: this.getTransferMetadataExportValue(),
|
|
510
|
-
info: this
|
|
488
|
+
info: this.getInfoExportValue(),
|
|
511
489
|
state: this.#transferState.export(),
|
|
490
|
+
registeredFiles: this.#filesRegistrar ? Array.from(this.#filesRegistrar.export().entries()) : undefined,
|
|
512
491
|
};
|
|
513
492
|
}
|
|
493
|
+
getInfoExportValue() {
|
|
494
|
+
if (this.isUploadAppendInfo(this.#info)) {
|
|
495
|
+
const { e2eeData, ...appendInfoWithoutE2eeData } = this.#info;
|
|
496
|
+
return appendInfoWithoutE2eeData;
|
|
497
|
+
}
|
|
498
|
+
// Until the transfer is initialized the key is still needed - a resumed run re-initializes from the info.
|
|
499
|
+
if (!this.#transferMetadata)
|
|
500
|
+
return this.#info;
|
|
501
|
+
const { e2eeKey, ...infoWithoutE2eeKey } = this.#info;
|
|
502
|
+
return infoWithoutE2eeKey;
|
|
503
|
+
}
|
|
514
504
|
getTransferMetadataExportValue() {
|
|
515
505
|
if (!this.#transferMetadata)
|
|
516
506
|
return undefined;
|
|
517
|
-
const { encryptionData,
|
|
507
|
+
const { encryptionData, ...rest } = this.#transferMetadata;
|
|
518
508
|
return {
|
|
519
509
|
...rest,
|
|
520
510
|
encryptionData: !encryptionData ? undefined : {
|
|
521
511
|
ivHex: uint8ArrayToHex(encryptionData.iv),
|
|
522
512
|
keyHex: uint8ArrayToHex(encryptionData.key),
|
|
523
513
|
},
|
|
524
|
-
registeredFiles: this.isLegacyTransfer() ? undefined : Array.from(registeredFiles.entries()),
|
|
525
514
|
};
|
|
526
515
|
}
|
|
527
516
|
static recreate(transferExportData, config, chunkStreamProviderFactory, apiClient, fileServerClientFactory, eventsEngine, concurrencyController, cryptography, acker) {
|
|
@@ -530,6 +519,12 @@ export default class TransferUpload {
|
|
|
530
519
|
const transfer = new TransferUpload(chunkStreamProviderFactory, apiClient, fileServerClientFactory, eventsEngine, transferExportData.info, config, concurrencyController, cryptography, acker);
|
|
531
520
|
transfer.#transferMetadata = this.recreateTransferMetadata(transferExportData.transferMetadata);
|
|
532
521
|
transfer.#transferState = new TransferUploadState(transferExportData.info.files, eventsEngine, config.currentRatesTimespanInMs, config.progressEventThrottlingInMs, transferExportData.state);
|
|
522
|
+
if (transfer.isUploadAppendInfo(transferExportData.info))
|
|
523
|
+
transfer.#transferDownloadUrl = transferExportData.info.transferDownloadUrl;
|
|
524
|
+
if (transferExportData.registeredFiles)
|
|
525
|
+
transfer.#filesRegistrar.recoverFromExportedState(transferExportData.registeredFiles);
|
|
526
|
+
else
|
|
527
|
+
transfer.#filesRegistrar = undefined;
|
|
533
528
|
return transfer;
|
|
534
529
|
}
|
|
535
530
|
catch (error) {
|
|
@@ -542,14 +537,13 @@ export default class TransferUpload {
|
|
|
542
537
|
static recreateTransferMetadata(transferMetadata) {
|
|
543
538
|
if (!transferMetadata)
|
|
544
539
|
return undefined;
|
|
545
|
-
const { encryptionData,
|
|
540
|
+
const { encryptionData, ...rest } = transferMetadata;
|
|
546
541
|
return {
|
|
547
542
|
...rest,
|
|
548
543
|
encryptionData: !encryptionData ? undefined : {
|
|
549
544
|
iv: hexToUint8Array(encryptionData.ivHex),
|
|
550
545
|
key: hexToUint8Array(encryptionData.keyHex),
|
|
551
546
|
},
|
|
552
|
-
registeredFiles: registeredFiles ? new Map(registeredFiles) : undefined,
|
|
553
547
|
};
|
|
554
548
|
}
|
|
555
549
|
static validateRecreateParams(transferExportData) {
|