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.
Files changed (81) hide show
  1. package/dist/src/autoDownloader/autoDownloader.d.ts.map +1 -1
  2. package/dist/src/autoDownloader/autoDownloader.js +0 -1
  3. package/dist/src/autoDownloader/autoDownloader.js.map +1 -1
  4. package/dist/src/client/downloader/node/nodeTransferDownloader.d.ts.map +1 -1
  5. package/dist/src/client/downloader/node/nodeTransferDownloader.js +0 -2
  6. package/dist/src/client/downloader/node/nodeTransferDownloader.js.map +1 -1
  7. package/dist/src/client/uploader/transferUploaderBase.d.ts +1 -0
  8. package/dist/src/client/uploader/transferUploaderBase.d.ts.map +1 -1
  9. package/dist/src/client/uploader/transferUploaderBase.js +22 -3
  10. package/dist/src/client/uploader/transferUploaderBase.js.map +1 -1
  11. package/dist/src/downloader/api/node/nodeFileServerDownloadClient.d.ts.map +1 -1
  12. package/dist/src/downloader/api/node/nodeFileServerDownloadClient.js +6 -2
  13. package/dist/src/downloader/api/node/nodeFileServerDownloadClient.js.map +1 -1
  14. package/dist/src/downloader/chunkDownloader.d.ts.map +1 -1
  15. package/dist/src/downloader/chunkDownloader.js +0 -1
  16. package/dist/src/downloader/chunkDownloader.js.map +1 -1
  17. package/dist/src/downloader/downloadTracker.d.ts.map +1 -1
  18. package/dist/src/downloader/downloadTracker.js +0 -1
  19. package/dist/src/downloader/downloadTracker.js.map +1 -1
  20. package/dist/src/downloader/filesDownloader.d.ts.map +1 -1
  21. package/dist/src/downloader/filesDownloader.js +0 -1
  22. package/dist/src/downloader/filesDownloader.js.map +1 -1
  23. package/dist/src/index.d.ts +3 -1
  24. package/dist/src/index.d.ts.map +1 -1
  25. package/dist/src/index.js.map +1 -1
  26. package/dist/src/uploader/eventArgs/filesRegistrationBatchFailedEventArgs.d.ts +6 -0
  27. package/dist/src/uploader/eventArgs/filesRegistrationBatchFailedEventArgs.d.ts.map +1 -0
  28. package/dist/src/uploader/eventArgs/filesRegistrationBatchFailedEventArgs.js +2 -0
  29. package/dist/src/uploader/eventArgs/filesRegistrationBatchFailedEventArgs.js.map +1 -0
  30. package/dist/src/uploader/export/transferUploadExportData.d.ts +4 -3
  31. package/dist/src/uploader/export/transferUploadExportData.d.ts.map +1 -1
  32. package/dist/src/uploader/export/transferUploadExportData.js.map +1 -1
  33. package/dist/src/uploader/export/transferUploadMetadata.d.ts +0 -2
  34. package/dist/src/uploader/export/transferUploadMetadata.d.ts.map +1 -1
  35. package/dist/src/uploader/export/transferUploadMetadata.js.map +1 -1
  36. package/dist/src/uploader/options/transferUploadAppendInfo.d.ts +1 -0
  37. package/dist/src/uploader/options/transferUploadAppendInfo.d.ts.map +1 -1
  38. package/dist/src/uploader/options/transferUploadAppendInfo.js.map +1 -1
  39. package/dist/src/uploader/state/continuousChunksCalculator.d.ts +1 -0
  40. package/dist/src/uploader/state/continuousChunksCalculator.d.ts.map +1 -1
  41. package/dist/src/uploader/state/continuousChunksCalculator.js +8 -2
  42. package/dist/src/uploader/state/continuousChunksCalculator.js.map +1 -1
  43. package/dist/src/uploader/state/transferUploadState.d.ts.map +1 -1
  44. package/dist/src/uploader/state/transferUploadState.js +3 -2
  45. package/dist/src/uploader/state/transferUploadState.js.map +1 -1
  46. package/dist/src/uploader/transferFilesRegistrar.d.ts +30 -0
  47. package/dist/src/uploader/transferFilesRegistrar.d.ts.map +1 -0
  48. package/dist/src/uploader/transferFilesRegistrar.js +160 -0
  49. package/dist/src/uploader/transferFilesRegistrar.js.map +1 -0
  50. package/dist/src/uploader/transferUpload.d.ts +7 -3
  51. package/dist/src/uploader/transferUpload.d.ts.map +1 -1
  52. package/dist/src/uploader/transferUpload.js +67 -73
  53. package/dist/src/uploader/transferUpload.js.map +1 -1
  54. package/dist/src/uploader/transferUploadAcker.d.ts +1 -2
  55. package/dist/src/uploader/transferUploadAcker.d.ts.map +1 -1
  56. package/dist/src/uploader/transferUploadAcker.js +12 -8
  57. package/dist/src/uploader/transferUploadAcker.js.map +1 -1
  58. package/dist/src/uploader/transferUploadEvent.d.ts +1 -0
  59. package/dist/src/uploader/transferUploadEvent.d.ts.map +1 -1
  60. package/dist/src/uploader/transferUploadEvent.js +1 -0
  61. package/dist/src/uploader/transferUploadEvent.js.map +1 -1
  62. package/dist/src/utils/api/dtos/registerTransferFilesRequest.d.ts +1 -0
  63. package/dist/src/utils/api/dtos/registerTransferFilesRequest.d.ts.map +1 -1
  64. package/dist/src/utils/api/dtos/registerTransferFilesRequest.js.map +1 -1
  65. package/dist/src/utils/api/dtos/registerTransferFilesResponse.d.ts +6 -2
  66. package/dist/src/utils/api/dtos/registerTransferFilesResponse.d.ts.map +1 -1
  67. package/dist/src/utils/api/dtos/registerTransferFilesResponse.js.map +1 -1
  68. package/dist/src/utils/api/node/nodeApiClient.d.ts.map +1 -1
  69. package/dist/src/utils/api/node/nodeApiClient.js +1 -0
  70. package/dist/src/utils/api/node/nodeApiClient.js.map +1 -1
  71. package/dist/src/utils/fileSystem/node/nodeFileSystemService.d.ts.map +1 -1
  72. package/dist/src/utils/fileSystem/node/nodeFileSystemService.js +0 -3
  73. package/dist/src/utils/fileSystem/node/nodeFileSystemService.js.map +1 -1
  74. package/dist/src/utils/mergeAbortAndPauseSignals.d.ts +6 -1
  75. package/dist/src/utils/mergeAbortAndPauseSignals.d.ts.map +1 -1
  76. package/dist/src/utils/mergeAbortAndPauseSignals.js +14 -7
  77. package/dist/src/utils/mergeAbortAndPauseSignals.js.map +1 -1
  78. package/dist/src/utils/promiseAll.d.ts.map +1 -1
  79. package/dist/src/utils/promiseAll.js +0 -1
  80. package/dist/src/utils/promiseAll.js.map +1 -1
  81. package/package.json +1 -1
@@ -0,0 +1,160 @@
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
+ clientItemId: String(file.externalId),
101
+ path: this.joinTransferPath(file.fileDestinationPathInTransfer, file.fileName),
102
+ type: `File`,
103
+ size: file.fileSizeInBytes,
104
+ })),
105
+ };
106
+ const response = await this.#apiClient.registerTransferFiles(this.#transferId, registerFilesRequest, this.#stopController?.signal);
107
+ return this.validateRegistrationBatchResponse(filesBatch, response);
108
+ }
109
+ notifyBatchFailed(filesBatch, error) {
110
+ const eventArgs = {
111
+ externalFileIds: filesBatch.map(file => file.externalId),
112
+ error: error,
113
+ };
114
+ this.#eventsEngine.emit(TransferUploadEvent.FilesRegistrationBatchFailed, eventArgs);
115
+ }
116
+ getFilesMissingRegistration() {
117
+ return this.#files.filter(file => !this.#registeredFiles.has(file.externalId));
118
+ }
119
+ validateRegistrationBatchResponse(filesBatch, response) {
120
+ if (response.items.length !== filesBatch.length)
121
+ throw new TransferUploadError(`Invalid register transfer files response`);
122
+ const filesByClientItemId = new Map(filesBatch.map(file => [String(file.externalId), file]));
123
+ return response.items.map((item) => {
124
+ const file = filesByClientItemId.get(item.clientItemId);
125
+ if (!file || !item.uploadItemId || !item.fileId)
126
+ throw new TransferUploadError(`Invalid register transfer files response`);
127
+ return [file.externalId, { uploadItemId: item.uploadItemId, fileId: item.fileId }];
128
+ });
129
+ }
130
+ joinTransferPath(directoryPath, fileName) {
131
+ const normalizedDirectoryPath = directoryPath.replace(/^\/+|\/+$/g, ``);
132
+ const normalizedFileName = fileName.replace(/^\/+/g, ``);
133
+ if (!normalizedDirectoryPath)
134
+ return normalizedFileName;
135
+ return `${normalizedDirectoryPath}/${normalizedFileName}`;
136
+ }
137
+ notifyObserver() {
138
+ if (!this.#currentObserver)
139
+ return;
140
+ const { wantedExternalFileId, resolve } = this.#currentObserver;
141
+ const isFileRegistered = this.#registeredFiles.has(wantedExternalFileId);
142
+ const isFileFailed = this.#failedRegistrations.has(wantedExternalFileId);
143
+ if (isFileRegistered)
144
+ resolve({ isRegisteredSuccessfully: true });
145
+ else if (isFileFailed)
146
+ resolve({ isRegisteredSuccessfully: false, error: this.#failedRegistrations.get(wantedExternalFileId) });
147
+ else if (this.#isRegisteringAllFilesDone)
148
+ resolve({ isRegisteredSuccessfully: false, error: new Error(`File has never been picked up for registration`) });
149
+ else
150
+ return; // continue waiting for new batch registrations
151
+ this.#currentObserver = undefined;
152
+ }
153
+ export() {
154
+ return this.#registeredFiles;
155
+ }
156
+ recoverFromExportedState(registeredFiles) {
157
+ this.#registeredFiles = new Map(registeredFiles);
158
+ }
159
+ }
160
+ //# 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 clientItemId: String(file.externalId),\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 const filesByClientItemId = new Map(\n filesBatch.map(file => [String(file.externalId), file] as const),\n );\n\n return response.items.map((item): [string | number, RegisteredTransferFile] => {\n const file = filesByClientItemId.get(item.clientItemId);\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":"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"}
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;AAW3D,OAAO,KAAK,SAAS,MAAM,2BAA2B,CAAC;AAGvD,OAAO,KAAK,uBAAuB,MAAM,yCAAyC,CAAC;AACnF,OAAO,KAAK,WAAW,MAAM,oCAAoC,CAAC;AAElE,OAAO,KAAK,kBAAkB,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AAEtF,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,wBAAwB,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,8BAA8B,MAAM,+CAA+C,CAAC;AAGhG,OAAO,KAAK,mBAAmB,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,gCAAgC,MAAM,iDAAiD,CAAC;AAGpG,OAAO,KAAK,yBAAyB,MAAM,0CAA0C,CAAC;AACtF,OAAO,KAAK,qCAAqC,MAAM,sDAAsD,CAAC;AAC9G,OAAO,KAAK,sBAAsB,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,4BAA4B,MAAM,6CAA6C,CAAC;AAC5F,OAAO,KAAK,mBAAmB,MAAM,0BAA0B,CAAC;AAEhE,OAAO,KAAK,iCAAiC,MAAM,kDAAkD,CAAC;AACtG,OAAO,KAAK,kCAAkC,MAAM,mDAAmD,CAAC;AACxG,OAAO,KAAK,kCAAkC,MAAM,oEAAoE,CAAC;AACzH,OAAO,KAAK,oBAAoB,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,KAAK,qBAAqB,MAAM,yDAAyD,CAAC;AACjG,OAAO,KAAK,0CAA0C,MAAM,2DAA2D,CAAC;AACxH,OAAO,KAAK,iCAAiC,MAAM,kDAAkD,CAAC;AACtG,OAAO,KAAK,mCAAmC,MAAM,oDAAoD,CAAC;AAC1G,OAAO,KAAK,oBAAoB,MAAM,yCAAyC,CAAC;AAChF,OAAO,KAAK,EAAE,wBAAwB,EAAwE,MAAM,sCAAsC,CAAC;AAE3J,MAAM,CAAC,OAAO,OAAO,cAAc,CAAC,CAAC,SAAS,WAAW;;IAyBrD,kBAAkB,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC7C,kBAAkB,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAI7C,IAAI,MAAM,IAAI,cAAc,CAE3B;IAED,IAAI,mBAAmB,IAAI,MAAM,CAEhC;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,oBAAoB,IAAI,MAAM,CAKjC;IAED,IAAI,KAAK,IAAI,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,CAElC;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAEnC;gBAEW,0BAA0B,EAAE,kCAAkC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,YAAY,EAAE,oBAAoB,EAAE,KAAK,EAAE,mBAAmB;IAmBxX,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,8BAA8B;IAehC,GAAG,CAAC,mBAAmB,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAoH5F,OAAO,CAAC,sBAAsB;YAQhB,qBAAqB;YAOrB,uBAAuB;IAOrC,OAAO,CAAC,wBAAwB;YAWlB,6BAA6B;YA8C7B,SAAS;IAevB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,uBAAuB;IAqB/B,OAAO,CAAC,wBAAwB;IAsBhC,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,uBAAuB;YAIjB,iCAAiC;IA0C/C,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,gBAAgB;YAIV,sCAAsC;YAoBtC,gBAAgB;YAShB,gBAAgB;YAahB,mBAAmB;IAmB3B,MAAM,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCtD,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,2BAA2B;YAWrB,iBAAiB;IAc/B,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,WAAW,GAAG,mBAAmB,CAAC,sBAAsB,GAAG,mBAAmB,CAAC,cAAc,GAAG,mBAAmB,CAAC,sBAAsB,GAAG,mBAAmB,CAAC,eAAe,GAAG,mBAAmB,CAAC,uBAAuB,GAAG,mBAAmB,CAAC,gBAAgB,GAAG,mBAAmB,CAAC,cAAc,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IACtX,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,iBAAiB,GAAG,mBAAmB,CAAC,mBAAmB,GAAG,mBAAmB,CAAC,aAAa,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GAAG,IAAI;IACrM,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,gBAAgB,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,GAAG,IAAI;IAC5H,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,4BAA4B,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,qCAAqC,KAAK,IAAI,GAAG,IAAI;IACpJ,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,aAAa,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,GAAG,IAAI;IACtH,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,mBAAmB,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,IAAI,GAAG,IAAI;IAClI,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,yBAAyB,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,kCAAkC,KAAK,IAAI,GAAG,IAAI;IAC9I,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,sBAAsB,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,GAAG,IAAI;IACjI,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,wBAAwB,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,iCAAiC,KAAK,IAAI,GAAG,IAAI;IAC5I,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,iCAAiC,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,0CAA0C,KAAK,IAAI,GAAG,IAAI;IAC9J,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,qBAAqB,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,8BAA8B,KAAK,IAAI,GAAG,IAAI;IACtI,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,kBAAkB,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,iCAAiC,KAAK,IAAI,GAAG,IAAI;IACtI,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,iBAAiB,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,gCAAgC,KAAK,IAAI,GAAG,IAAI;IACpI,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,0BAA0B,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,mCAAmC,KAAK,IAAI,GAAG,IAAI;IAChJ,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAKvE,cAAc,IAAI,MAAM;IAKxB,MAAM,IAAI,wBAAwB,CAAC,CAAC,CAAC;IAYrC,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,8BAA8B;IAetC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,WAAW,EAAE,kBAAkB,EAAE,wBAAwB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,kCAAkC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,YAAY,EAAE,oBAAoB,EAAE,KAAK,EAAE,mBAAmB,GAAG,cAAc,CAAC,CAAC,CAAC;IA2B7Z,OAAO,CAAC,MAAM,CAAC,wBAAwB;IAevC,OAAO,CAAC,MAAM,CAAC,sBAAsB;CAiBxC"}
@@ -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
- #mergedPauseAndAbortSignal;
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
- async registerFilesAndCreateTransferMetadataFromInfo() {
90
+ createTransferMetadataFromInfo() {
86
91
  if (!this.isUploadAppendInfo(this.#info))
87
92
  throw new TransferUploadError(`Options are not TransferUploadAppendOptions`);
88
- const registeredFiles = await this.registerTransferFilesWithValidation(this.#info.transferId, this.#info.transferKey);
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
- registeredFiles,
99
- transferRegion: info.transferRegion,
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.#mergedPauseAndAbortSignal = mergeAbortAndPauseSignals(transferPauseSignal, transferAbortSignal);
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
- await this.registerFilesAndCreateTransferMetadataFromInfo();
116
+ this.createTransferMetadataFromInfo();
118
117
  else if (!this.#transferMetadata)
119
118
  await this.startApiTransferAndCreateMetadata();
120
119
  this.notifyMetadataDetermined();
121
- this.#acker.start(this.#transferMetadata.transferId, this.#transferMetadata.transferKey, this.#transferState, transferPauseSignal, transferAbortSignal);
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.#acker.stop();
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.#mergedPauseAndAbortSignal);
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.#transferMetadata?.registeredFiles?.get(externalFileId);
352
+ return this.#filesRegistrar?.getRegisteredFile(externalFileId);
375
353
  }
376
354
  enqueueFileAck(file) {
377
- if (this.isLegacyTransfer()) { // Remove legacy mode after all our clients migrated to app version >= 4.22
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.#transferMetadata !== undefined && this.#transferMetadata.registeredFiles === undefined;
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.#mergedPauseAndAbortSignal);
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.#mergedPauseAndAbortSignal);
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.#info,
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, registeredFiles, ...rest } = this.#transferMetadata;
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, registeredFiles, ...rest } = transferMetadata;
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) {