filemail-sdk 9.4.2 → 9.4.3

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.
@@ -6,6 +6,7 @@ export default class ChunksIterator {
6
6
  });
7
7
  private sanitizeChunks;
8
8
  private removeZeroByteChunks;
9
+ private createChunksByStartPositionMap;
9
10
  getChunksIterator(): IterableIterator<ContinuousChunk>;
10
11
  private isZeroBytesFilesCase;
11
12
  private getNextIteratorValueForZeroBytesFile;
@@ -1 +1 @@
1
- {"version":3,"file":"chunksIterator.d.ts","sourceRoot":"","sources":["../../../../src/uploader/chunksIterator/chunksIterator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAE9E,MAAM,CAAC,OAAO,OAAO,cAAc;;gBASnB,iBAAiB,EAAE,SAAS,QAAQ,CAAC,eAAe,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,wBAAwB,EAAE;QAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE;IAO7J,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,oBAAoB;IAI5B,iBAAiB,IAAI,gBAAgB,CAAC,eAAe,CAAC;IActD,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,oCAAoC;IAS5C,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,mBAAmB;CAgB9B"}
1
+ {"version":3,"file":"chunksIterator.d.ts","sourceRoot":"","sources":["../../../../src/uploader/chunksIterator/chunksIterator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAE9E,MAAM,CAAC,OAAO,OAAO,cAAc;;gBAUnB,iBAAiB,EAAE,SAAS,QAAQ,CAAC,eAAe,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE,wBAAwB,EAAE;QAAE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE;IAQ7J,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,8BAA8B;IAItC,iBAAiB,IAAI,gBAAgB,CAAC,eAAe,CAAC;IActD,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,oCAAoC;IAS5C,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,mBAAmB;CAgB9B"}
@@ -1,11 +1,13 @@
1
1
  export default class ChunksIterator {
2
2
  #alreadySentChunks;
3
+ #alreadySentChunksByStartPosition;
3
4
  #fileSizeInBytes;
4
5
  #currentChunkSizeProvider;
5
6
  #nextChunkStartPosition = 0;
6
7
  #isValueAlreadyReturnedForZeroBytesFile = false;
7
8
  constructor(alreadySentChunks, fileSizeInBytes, currentChunkSizeProvider) {
8
9
  this.#alreadySentChunks = this.sanitizeChunks(alreadySentChunks);
10
+ this.#alreadySentChunksByStartPosition = this.createChunksByStartPositionMap(this.#alreadySentChunks);
9
11
  this.#fileSizeInBytes = fileSizeInBytes;
10
12
  this.#currentChunkSizeProvider = currentChunkSizeProvider;
11
13
  }
@@ -16,6 +18,9 @@ export default class ChunksIterator {
16
18
  removeZeroByteChunks(alreadySentChunks) {
17
19
  return alreadySentChunks.filter(c => c.sizeInBytes > 0);
18
20
  }
21
+ createChunksByStartPositionMap(alreadySentChunks) {
22
+ return new Map(alreadySentChunks.map(chunk => [chunk.startPosition, chunk.sizeInBytes]));
23
+ }
19
24
  getChunksIterator() {
20
25
  return {
21
26
  [Symbol.iterator]() {
@@ -46,11 +51,13 @@ export default class ChunksIterator {
46
51
  return { value: { startPosition, sizeInBytes }, done: false };
47
52
  }
48
53
  getChunkStartPosition(nextChunkStartPosition) {
49
- const alreadySentChunkStartingHere = this.#alreadySentChunks.find(c => c.startPosition === nextChunkStartPosition);
50
- if (!alreadySentChunkStartingHere)
51
- return nextChunkStartPosition;
52
- const newNextChunkStartPosition = nextChunkStartPosition + alreadySentChunkStartingHere.sizeInBytes;
53
- return this.getChunkStartPosition(newNextChunkStartPosition);
54
+ let chunkStartPosition = nextChunkStartPosition;
55
+ while (true) {
56
+ const alreadySentChunkSize = this.#alreadySentChunksByStartPosition.get(chunkStartPosition);
57
+ if (!alreadySentChunkSize)
58
+ return chunkStartPosition;
59
+ chunkStartPosition += alreadySentChunkSize;
60
+ }
54
61
  }
55
62
  getChunkSizeInBytes(newChunkStartPosition) {
56
63
  const currentMaxChunkSize = this.#currentChunkSizeProvider.currentChunkSize;
@@ -1 +1 @@
1
- {"version":3,"file":"chunksIterator.js","sourceRoot":"","sources":["../../../../src/uploader/chunksIterator/chunksIterator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContinuousChunk } from \"../state/continuousChunksCalculator.js\";\n\nexport default class ChunksIterator {\n #alreadySentChunks: readonly Readonly<ContinuousChunk>[];\n #fileSizeInBytes: number;\n #currentChunkSizeProvider: { readonly currentChunkSize: number };\n\n #nextChunkStartPosition = 0;\n\n #isValueAlreadyReturnedForZeroBytesFile = false;\n\n constructor(alreadySentChunks: readonly Readonly<ContinuousChunk>[], fileSizeInBytes: number, currentChunkSizeProvider: { readonly currentChunkSize: number }) {\n this.#alreadySentChunks = this.sanitizeChunks(alreadySentChunks);\n this.#fileSizeInBytes = fileSizeInBytes;\n this.#currentChunkSizeProvider = currentChunkSizeProvider;\n }\n\n // This is an anti corruption layer that can be removed after everybody migrates to desktop > 4.8.2\n private sanitizeChunks(alreadySentChunks: readonly Readonly<ContinuousChunk>[]): readonly Readonly<ContinuousChunk>[] {\n return this.removeZeroByteChunks(alreadySentChunks);\n }\n\n private removeZeroByteChunks(alreadySentChunks: readonly Readonly<ContinuousChunk>[]): readonly Readonly<ContinuousChunk>[] {\n return alreadySentChunks.filter(c => c.sizeInBytes > 0);\n }\n\n getChunksIterator(): IterableIterator<ContinuousChunk> {\n return {\n [Symbol.iterator](): IterableIterator<ContinuousChunk> {\n return this;\n },\n next: (): IteratorResult<ContinuousChunk> => {\n if (this.isZeroBytesFilesCase())\n return this.getNextIteratorValueForZeroBytesFile();\n\n return this.getNextIteratorValue();\n },\n };\n }\n\n private isZeroBytesFilesCase(): boolean {\n return this.#fileSizeInBytes === 0;\n }\n\n private getNextIteratorValueForZeroBytesFile(): IteratorResult<ContinuousChunk> {\n if (this.#isValueAlreadyReturnedForZeroBytesFile)\n return { value: null, done: true };\n\n this.#isValueAlreadyReturnedForZeroBytesFile = true;\n\n return { value: { startPosition: 0, sizeInBytes: 0 }, done: false };\n }\n\n private getNextIteratorValue(): IteratorResult<ContinuousChunk> {\n const startPosition = this.getChunkStartPosition(this.#nextChunkStartPosition);\n\n if (startPosition === this.#fileSizeInBytes)\n return { value: null, done: true };\n\n const sizeInBytes = this.getChunkSizeInBytes(startPosition);\n\n this.#nextChunkStartPosition = startPosition + sizeInBytes;\n\n return { value: { startPosition, sizeInBytes }, done: false };\n }\n\n private getChunkStartPosition(nextChunkStartPosition: number): number {\n const alreadySentChunkStartingHere = this.#alreadySentChunks.find(c => c.startPosition === nextChunkStartPosition);\n\n if (!alreadySentChunkStartingHere)\n return nextChunkStartPosition;\n\n const newNextChunkStartPosition = nextChunkStartPosition + alreadySentChunkStartingHere.sizeInBytes;\n\n return this.getChunkStartPosition(newNextChunkStartPosition);\n }\n\n private getChunkSizeInBytes(newChunkStartPosition: number) {\n const currentMaxChunkSize = this.#currentChunkSizeProvider.currentChunkSize;\n const newChunkEndPosition = newChunkStartPosition + currentMaxChunkSize - 1;\n\n const alreadySentChunkStartingInTheMiddle = this.#alreadySentChunks.find(c => newChunkStartPosition < c.startPosition && c.startPosition <= newChunkEndPosition);\n\n if (alreadySentChunkStartingInTheMiddle)\n return alreadySentChunkStartingInTheMiddle.startPosition - newChunkStartPosition;\n\n const chunkEndsBeyondFile = newChunkEndPosition >= this.#fileSizeInBytes;\n\n if (chunkEndsBeyondFile)\n return this.#fileSizeInBytes - newChunkStartPosition;\n\n return currentMaxChunkSize;\n }\n}"]}
1
+ {"version":3,"file":"chunksIterator.js","sourceRoot":"","sources":["../../../../src/uploader/chunksIterator/chunksIterator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContinuousChunk } from \"../state/continuousChunksCalculator.js\";\n\nexport default class ChunksIterator {\n #alreadySentChunks: readonly Readonly<ContinuousChunk>[];\n #alreadySentChunksByStartPosition: ReadonlyMap<number, number>;\n #fileSizeInBytes: number;\n #currentChunkSizeProvider: { readonly currentChunkSize: number };\n\n #nextChunkStartPosition = 0;\n\n #isValueAlreadyReturnedForZeroBytesFile = false;\n\n constructor(alreadySentChunks: readonly Readonly<ContinuousChunk>[], fileSizeInBytes: number, currentChunkSizeProvider: { readonly currentChunkSize: number }) {\n this.#alreadySentChunks = this.sanitizeChunks(alreadySentChunks);\n this.#alreadySentChunksByStartPosition = this.createChunksByStartPositionMap(this.#alreadySentChunks);\n this.#fileSizeInBytes = fileSizeInBytes;\n this.#currentChunkSizeProvider = currentChunkSizeProvider;\n }\n\n // This is an anti corruption layer that can be removed after everybody migrates to desktop > 4.8.2\n private sanitizeChunks(alreadySentChunks: readonly Readonly<ContinuousChunk>[]): readonly Readonly<ContinuousChunk>[] {\n return this.removeZeroByteChunks(alreadySentChunks);\n }\n\n private removeZeroByteChunks(alreadySentChunks: readonly Readonly<ContinuousChunk>[]): readonly Readonly<ContinuousChunk>[] {\n return alreadySentChunks.filter(c => c.sizeInBytes > 0);\n }\n\n private createChunksByStartPositionMap(alreadySentChunks: readonly Readonly<ContinuousChunk>[]): ReadonlyMap<number, number> {\n return new Map(alreadySentChunks.map(chunk => [chunk.startPosition, chunk.sizeInBytes]));\n }\n\n getChunksIterator(): IterableIterator<ContinuousChunk> {\n return {\n [Symbol.iterator](): IterableIterator<ContinuousChunk> {\n return this;\n },\n next: (): IteratorResult<ContinuousChunk> => {\n if (this.isZeroBytesFilesCase())\n return this.getNextIteratorValueForZeroBytesFile();\n\n return this.getNextIteratorValue();\n },\n };\n }\n\n private isZeroBytesFilesCase(): boolean {\n return this.#fileSizeInBytes === 0;\n }\n\n private getNextIteratorValueForZeroBytesFile(): IteratorResult<ContinuousChunk> {\n if (this.#isValueAlreadyReturnedForZeroBytesFile)\n return { value: null, done: true };\n\n this.#isValueAlreadyReturnedForZeroBytesFile = true;\n\n return { value: { startPosition: 0, sizeInBytes: 0 }, done: false };\n }\n\n private getNextIteratorValue(): IteratorResult<ContinuousChunk> {\n const startPosition = this.getChunkStartPosition(this.#nextChunkStartPosition);\n\n if (startPosition === this.#fileSizeInBytes)\n return { value: null, done: true };\n\n const sizeInBytes = this.getChunkSizeInBytes(startPosition);\n\n this.#nextChunkStartPosition = startPosition + sizeInBytes;\n\n return { value: { startPosition, sizeInBytes }, done: false };\n }\n\n private getChunkStartPosition(nextChunkStartPosition: number): number {\n let chunkStartPosition = nextChunkStartPosition;\n\n while (true) {\n const alreadySentChunkSize = this.#alreadySentChunksByStartPosition.get(chunkStartPosition);\n\n if (!alreadySentChunkSize)\n return chunkStartPosition;\n\n chunkStartPosition += alreadySentChunkSize;\n }\n }\n\n private getChunkSizeInBytes(newChunkStartPosition: number) {\n const currentMaxChunkSize = this.#currentChunkSizeProvider.currentChunkSize;\n const newChunkEndPosition = newChunkStartPosition + currentMaxChunkSize - 1;\n\n const alreadySentChunkStartingInTheMiddle = this.#alreadySentChunks.find(c => newChunkStartPosition < c.startPosition && c.startPosition <= newChunkEndPosition);\n\n if (alreadySentChunkStartingInTheMiddle)\n return alreadySentChunkStartingInTheMiddle.startPosition - newChunkStartPosition;\n\n const chunkEndsBeyondFile = newChunkEndPosition >= this.#fileSizeInBytes;\n\n if (chunkEndsBeyondFile)\n return this.#fileSizeInBytes - newChunkStartPosition;\n\n return currentMaxChunkSize;\n }\n}"]}
@@ -21,6 +21,7 @@ export default class TransferUploadOptimizer implements UploadOptimizer {
21
21
  private isMsgSizeError;
22
22
  private isNoBufsError;
23
23
  private isErrorContainingErrorCode;
24
+ private trimHistoryArrayToMaxEntries;
24
25
  private optimize;
25
26
  }
26
27
  //# sourceMappingURL=transferUploadOptimizer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transferUploadOptimizer.d.ts","sourceRoot":"","sources":["../../../../src/uploader/optimizer/transferUploadOptimizer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,mBAAmB,MAAM,0DAA0D,CAAC;AAChG,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,YAAY,MAAM,oCAAoC,CAAC;AAInE,OAAO,KAAK,kCAAkC,MAAM,yCAAyC,CAAC;AAE9F,MAAM,CAAC,OAAO,OAAO,uBAAwB,YAAW,eAAe;;gBAoCvD,YAAY,EAAE,MAAM,EAAE,yBAAyB,EAAE,MAAM,EAAE,oBAAoB,EAAE,YAAY,EAAE,uBAAuB,EAAE,kCAAkC;IAOpK,IAAI,gBAAgB,IAAI,MAAM,CAI7B;IAED,IAAI,yBAAyB,IAAI,MAAM,CAItC;IAED,IAAI,oBAAoB,IAAI,MAAM,CAyBjC;IAEK,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAMtD,OAAO,CAAC,iBAAiB;IAKzB,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM;IA8B/C,IAAI;IASJ,OAAO,CAAC,yBAAyB;IAOjC,OAAO,CAAC,6BAA6B;IAOrC,OAAO,CAAC,kBAAkB,CAExB;IAEF,OAAO,CAAC,oBAAoB,CAE1B;IAEF,OAAO,CAAC,6BAA6B,CAEnC;IAEF,OAAO,CAAC,iBAAiB,CAiBvB;IAEF,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,QAAQ,CAed;CACL"}
1
+ {"version":3,"file":"transferUploadOptimizer.d.ts","sourceRoot":"","sources":["../../../../src/uploader/optimizer/transferUploadOptimizer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,mBAAmB,MAAM,0DAA0D,CAAC;AAChG,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,YAAY,MAAM,oCAAoC,CAAC;AAInE,OAAO,KAAK,kCAAkC,MAAM,yCAAyC,CAAC;AAK9F,MAAM,CAAC,OAAO,OAAO,uBAAwB,YAAW,eAAe;;gBAoCvD,YAAY,EAAE,MAAM,EAAE,yBAAyB,EAAE,MAAM,EAAE,oBAAoB,EAAE,YAAY,EAAE,uBAAuB,EAAE,kCAAkC;IAOpK,IAAI,gBAAgB,IAAI,MAAM,CAI7B;IAED,IAAI,yBAAyB,IAAI,MAAM,CAItC;IAED,IAAI,oBAAoB,IAAI,MAAM,CAyBjC;IAEK,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAMtD,OAAO,CAAC,iBAAiB;IAKzB,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM;IA8B/C,IAAI;IASJ,OAAO,CAAC,yBAAyB;IAOjC,OAAO,CAAC,6BAA6B;IAOrC,OAAO,CAAC,kBAAkB,CAGxB;IAEF,OAAO,CAAC,oBAAoB,CAG1B;IAEF,OAAO,CAAC,6BAA6B,CAGnC;IAEF,OAAO,CAAC,iBAAiB,CAkBvB;IAEF,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,QAAQ,CAed;CACL"}
@@ -2,6 +2,8 @@ import throttle from "lodash.throttle";
2
2
  import TransferConcurrencyController from "../../utils/concurrencyController/transferConcurrencyController.js";
3
3
  import TransferUploadEvent from "../transferUploadEvent.js";
4
4
  import FsError from "../../utils/fileSystem/fsError.js";
5
+ const MAX_OPTIMIZER_HISTORY_ENTRIES = 10_000;
6
+ const OPTIMIZER_HISTORY_TRIM_THRESHOLD = 12_000;
5
7
  export default class TransferUploadOptimizer {
6
8
  #tcpChunkSize;
7
9
  #tcpChunksUploadInParallel;
@@ -109,12 +111,15 @@ export default class TransferUploadOptimizer {
109
111
  }
110
112
  chunkUploadStarted = () => {
111
113
  this.#startedChunksTimeHistory.push(Date.now());
114
+ this.#startedChunksTimeHistory = this.trimHistoryArrayToMaxEntries(this.#startedChunksTimeHistory);
112
115
  };
113
116
  chunkUploadSucceeded = (eventArgs) => {
114
117
  this.#ackedChunksHistory.push({ time: Date.now(), latencyInMs: eventArgs.latencyInMsIfUdp });
118
+ this.#ackedChunksHistory = this.trimHistoryArrayToMaxEntries(this.#ackedChunksHistory);
115
119
  };
116
120
  chunkUploadSucceededPartially = (eventArgs) => {
117
121
  this.#ackedChunksHistory.push({ time: Date.now(), latencyInMs: eventArgs.latencyInMsIfUdp });
122
+ this.#ackedChunksHistory = this.trimHistoryArrayToMaxEntries(this.#ackedChunksHistory);
118
123
  };
119
124
  chunkUploadFailed = (eventArgs) => {
120
125
  const isFileAccessError = eventArgs.error.cause instanceof FsError;
@@ -129,6 +134,7 @@ export default class TransferUploadOptimizer {
129
134
  return;
130
135
  }
131
136
  this.#failedChunksTimeHistory.push(Date.now());
137
+ this.#failedChunksTimeHistory = this.trimHistoryArrayToMaxEntries(this.#failedChunksTimeHistory);
132
138
  };
133
139
  isMsgSizeError(error) {
134
140
  return this.isErrorContainingErrorCode(error, `EMSGSIZE`);
@@ -143,6 +149,11 @@ export default class TransferUploadOptimizer {
143
149
  return this.isErrorContainingErrorCode(error.cause, errorCode);
144
150
  return false;
145
151
  }
152
+ trimHistoryArrayToMaxEntries(history) {
153
+ if (history.length <= OPTIMIZER_HISTORY_TRIM_THRESHOLD)
154
+ return history;
155
+ return history.slice(history.length - MAX_OPTIMIZER_HISTORY_ENTRIES);
156
+ }
146
157
  optimize = async () => {
147
158
  const optimizationResult = this.#udpOptimizationStrategy.getOptimizedValues(this.#startedChunksTimeHistory, this.#ackedChunksHistory, this.#failedChunksTimeHistory, this.#currentOptimizationValues);
148
159
  this.#currentOptimizationValues = optimizationResult.optimizedValues;
@@ -1 +1 @@
1
- {"version":3,"file":"transferUploadOptimizer.js","sourceRoot":"","sources":["../../../../src/uploader/optimizer/transferUploadOptimizer.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AAEvC,OAAO,6BAA6B,MAAM,oEAAoE,CAAC;AAC/G,OAAO,mBAAmB,MAAM,2BAA2B,CAAC;AAC5D,OAAO,OAAO,MAAM,mCAAmC,CAAC;AAYxD,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAC/B,aAAa,CAAS;IACtB,0BAA0B,CAAS;IACnC,qBAAqB,CAAe;IACpC,wBAAwB,CAAqC;IAEtE,sBAAsB,CAAoC;IAE1D,MAAM,CAAsB;IAE5B,0BAA0B,CAAiC;IAC3D,0BAA0B,CAAiC;IAE3D,QAAQ,CAA6B;IAErC,yBAAyB,GAAa,EAAE,CAAC;IACzC,mBAAmB,GAA4C,EAAE,CAAC;IAClE,wBAAwB,GAAa,EAAE,CAAC;IAExC,sBAAsB,GAAG,CAAC,CAAC;IAE3B,mBAAmB,GAAG,QAAQ,CAAC,GAAG,EAAE;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,IAAI,CAAC,0BAA2B,CAAC,CAAC;QAElG,IAAI,CAAC,0BAA2B,CAAC,uBAAuB,GAAG,MAAM,CAAC,uBAAuB,CAAC;QAC1F,IAAI,CAAC,0BAA2B,CAAC,6BAA6B,GAAG,MAAM,CAAC,6BAA6B,CAAC;QAEtG,IAAI,CAAC,sBAAuB,CAAC,cAAc,GAAG,IAAI,CAAC,0BAA2B,CAAC,uBAAuB,CAAC;IAC3G,CAAC,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAE5C,oBAAoB,GAAG,QAAQ,CAAC,GAAG,EAAE;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,wBAAwB,CAAC,mBAAmB,CAAC,IAAI,CAAC,0BAA2B,CAAC,CAAC;QAEnG,IAAI,CAAC,0BAA2B,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAClE,CAAC,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAE5C,YAAY,YAAoB,EAAE,yBAAiC,EAAE,oBAAkC,EAAE,uBAA2D;QAChK,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,0BAA0B,GAAG,yBAAyB,CAAC;QAC5D,IAAI,CAAC,qBAAqB,GAAG,oBAAoB,CAAC;QAClD,IAAI,CAAC,wBAAwB,GAAG,uBAAuB,CAAC;IAC5D,CAAC;IAED,IAAI,gBAAgB;QAChB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,OAAO,IAAI,CAAC,0BAA2B,CAAC,SAAS,CAAC;IACtD,CAAC;IAED,IAAI,yBAAyB;QACzB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,OAAO,IAAI,CAAC,0BAA2B,CAAC,kBAAkB,CAAC;IAC/D,CAAC;IAED,IAAI,oBAAoB;QACpB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,IAAI,IAAI,CAAC,yBAAyB,CAAC,MAAM,KAAK,CAAC;YAC3C,OAAO,CAAC,CAAC;QAEb,IAAI,IAAI,CAAC,0BAA2B,CAAC,6BAA6B,GAAG,CAAC,EAAE,CAAC;YACrE,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,0BAA2B,CAAC,6BAA6B,CAAC,CAAC;YAEzG,IAAI,IAAI,CAAC,sBAAsB,GAAG,kBAAkB,EAAE,CAAC;gBACnD,IAAI,CAAC,sBAAsB,IAAI,CAAC,CAAC;gBACjC,OAAO,CAAC,CAAC;YACb,CAAC;YAED,IAAI,CAAC,sBAAsB,GAAG,CAAC,CAAC;YAChC,OAAO,CAAC,CAAC;QACb,CAAC;QAED,MAAM,kBAAkB,GAAG,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,yBAAyB,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;QACtG,MAAM,kBAAkB,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,kBAAkB,CAAC;QAErE,IAAI,kBAAkB,GAAG,IAAI,CAAC,0BAA2B,CAAC,6BAA6B;YACnF,OAAO,IAAI,CAAC,0BAA2B,CAAC,6BAA6B,GAAG,kBAAkB,CAAC;QAE/F,OAAO,CAAC,CAAC;IACb,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,OAAO,MAAM,IAAI,CAAC,sBAAuB,CAAC,OAAO,EAAE,CAAC;IACxD,CAAC;IAEO,iBAAiB;QACrB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YACzB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,KAAc,EAAE,iBAAyB;QAC3C,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QAEpB,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC,wBAAwB,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;YACpG,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC,0BAA0B,CAAC;YAElE,IAAI,CAAC,sBAAsB,GAAG,IAAI,6BAA6B,CAAC,IAAI,CAAC,0BAA0B,CAAC,uBAAuB,CAAC,CAAC;YAEzH,IAAI,CAAC,yBAAyB,EAAE,CAAC;YAEjC,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,0BAA0B,CAAC,wBAAwB,CAAC,CAAC;QAChH,CAAC;aACI,CAAC;YACF,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;YAE1B,IAAI,CAAC,0BAA0B,GAAG;gBAC9B,SAAS,EAAE,IAAI,CAAC,aAAa;gBAC7B,uBAAuB,EAAE,IAAI,CAAC,0BAA0B;gBACxD,6BAA6B,EAAE,CAAC;gBAChC,wBAAwB,EAAE,CAAC;gBAC3B,kBAAkB,EAAE,CAAC;aACxB,CAAC;YAEF,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC,0BAA0B,CAAC;YAElE,IAAI,CAAC,sBAAsB,GAAG,IAAI,6BAA6B,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACrG,CAAC;IACL,CAAC;IAED,IAAI;QACA,IAAI,CAAC,IAAI,CAAC,MAAM;YACZ,OAAO;QAEX,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE5B,IAAI,CAAC,6BAA6B,EAAE,CAAC;IACzC,CAAC;IAEO,yBAAyB;QAC7B,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,sBAAsB,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjH,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,wBAAwB,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACrH,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,iCAAiC,EAAE,IAAI,CAAC,6BAA6B,CAAC,CAAC;QACvI,IAAI,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,qBAAqB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACnH,CAAC;IAEO,6BAA6B;QACjC,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,sBAAsB,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACpH,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,wBAAwB,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACxH,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,iCAAiC,EAAE,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC1I,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,qBAAqB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACtH,CAAC;IAEO,kBAAkB,GAAG,GAAG,EAAE;QAC9B,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC;IAEM,oBAAoB,GAAG,CAAC,SAA4C,EAAE,EAAE;QAC5E,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,SAAS,CAAC,gBAAiB,EAAE,CAAC,CAAC;IAClG,CAAC,CAAC;IAEM,6BAA6B,GAAG,CAAC,SAAqD,EAAE,EAAE;QAC9F,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,SAAS,CAAC,gBAAiB,EAAE,CAAC,CAAC;IAClG,CAAC,CAAC;IAEM,iBAAiB,GAAG,CAAC,SAAyC,EAAE,EAAE;QACtE,MAAM,iBAAiB,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,YAAY,OAAO,CAAC;QAEnE,IAAI,iBAAiB;YACjB,OAAO;QAEX,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC5B,OAAO;QACX,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,OAAO;QACX,CAAC;QAED,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC;IAEM,cAAc,CAAC,KAAY;QAC/B,OAAO,IAAI,CAAC,0BAA0B,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC9D,CAAC;IAEO,aAAa,CAAC,KAAY;QAC9B,OAAO,IAAI,CAAC,0BAA0B,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC7D,CAAC;IAEO,0BAA0B,CAAC,KAAY,EAAE,SAAiB;QAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;YACjC,OAAO,IAAI,CAAC;QAEhB,IAAI,KAAK,CAAC,KAAK;YACX,OAAO,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAEnE,OAAO,KAAK,CAAC;IACjB,CAAC;IAEO,QAAQ,GAAG,KAAK,IAAmB,EAAE;QACzC,MAAM,kBAAkB,GAAG,IAAI,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC,0BAA2B,CAAC,CAAC;QAEvM,IAAI,CAAC,0BAA0B,GAAG,kBAAkB,CAAC,eAAe,CAAC;QAErE,IAAI,CAAC,sBAAuB,CAAC,cAAc,GAAG,IAAI,CAAC,0BAA0B,CAAC,uBAAuB,CAAC;QAEtG,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,kBAAkB,CAAC,eAAe,CAAC,wBAAwB,CAAC,CAAC;QAE/G,IAAI,kBAAkB,CAAC,kBAAkB,KAAK,KAAK;YAC/C,OAAO;QAEX,IAAI,CAAC,yBAAyB,GAAG,EAAE,CAAC;QACpC,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC;IACvC,CAAC,CAAC;CACL","sourcesContent":["import throttle from \"lodash.throttle\";\n\nimport TransferConcurrencyController from \"../../utils/concurrencyController/transferConcurrencyController.js\";\nimport TransferUploadEvent from \"../transferUploadEvent.js\";\nimport FsError from \"../../utils/fileSystem/fsError.js\";\n\nimport type OptimizationValues from \"./optimizationValues.js\";\nimport type ConcurrencyController from \"../../utils/concurrencyController/concurrencyController.js\";\nimport type ConcurrencyReleaser from \"../../utils/concurrencyController/concurrencyReleaser.js\";\nimport type UploadOptimizer from \"./uploadOptimizer.js\";\nimport type EventsEngine from \"../../utils/events/eventsEngine.js\";\nimport type FileChunkUploadFailedEventArgs from \"../eventArgs/fileChunkUploadFailedEventArgs.js\";\nimport type FileChunkUploadCompletedEventArgs from \"../eventArgs/fileChunkUploadCompletedEventArgs.js\";\nimport type FileChunkUploadCompletedPartiallyEventArgs from \"../eventArgs/fileChunkUploadCompletedPartiallyEventArgs.js\";\nimport type TransferUploadOptimizationStrategy from \"./transferUploadOptimizationStrategy.js\";\n\nexport default class TransferUploadOptimizer implements UploadOptimizer {\n readonly #tcpChunkSize: number;\n readonly #tcpChunksUploadInParallel: number;\n readonly #transferEventsEngine: EventsEngine;\n readonly #udpOptimizationStrategy: TransferUploadOptimizationStrategy;\n\n #concurrencyController: ConcurrencyController | undefined;\n\n #isUdp: boolean | undefined;\n\n #initialOptimizationValues: OptimizationValues | undefined;\n #currentOptimizationValues: OptimizationValues | undefined;\n\n #timeout: NodeJS.Timeout | undefined;\n\n #startedChunksTimeHistory: number[] = [];\n #ackedChunksHistory: { time: number, latencyInMs: number }[] = [];\n #failedChunksTimeHistory: number[] = [];\n\n #chunksStartedInThisMs = 0;\n\n #noBufsErrorHandler = throttle(() => {\n const result = this.#udpOptimizationStrategy.noBufsErrorHandler(this.#currentOptimizationValues!);\n\n this.#currentOptimizationValues!.maxParallelChunksAmount = result.maxParallelChunksAmount;\n this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs = result.minTimeBetweenChunksStartInMs;\n\n this.#concurrencyController!.maxConcurrency = this.#currentOptimizationValues!.maxParallelChunksAmount;\n }, 500, { leading: true, trailing: false });\n\n #msgSizeErrorHandler = throttle(() => {\n const result = this.#udpOptimizationStrategy.msgSizeErrorHandler(this.#currentOptimizationValues!);\n\n this.#currentOptimizationValues!.chunkSize = result.chunkSize;\n }, 500, { leading: true, trailing: false });\n\n constructor(tcpChunkSize: number, tcpChunksUploadInParallel: number, transferEventsEngine: EventsEngine, udpOptimizationStrategy: TransferUploadOptimizationStrategy) {\n this.#tcpChunkSize = tcpChunkSize;\n this.#tcpChunksUploadInParallel = tcpChunksUploadInParallel;\n this.#transferEventsEngine = transferEventsEngine;\n this.#udpOptimizationStrategy = udpOptimizationStrategy;\n }\n\n get currentChunkSize(): number {\n this.throwIfNotStarted();\n\n return this.#currentOptimizationValues!.chunkSize;\n }\n\n get currentRequestTimeoutInMs(): number {\n this.throwIfNotStarted();\n\n return this.#currentOptimizationValues!.requestTimeoutInMs;\n }\n\n get currentSleepTimeInMs(): number {\n this.throwIfNotStarted();\n\n if (this.#startedChunksTimeHistory.length === 0)\n return 0;\n\n if (this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs < 1) {\n const chunksToStartPerMs = Math.ceil(1 / this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs);\n\n if (this.#chunksStartedInThisMs < chunksToStartPerMs) {\n this.#chunksStartedInThisMs += 1;\n return 0;\n }\n\n this.#chunksStartedInThisMs = 0;\n return 1;\n }\n\n const lastChunkStartTime = this.#startedChunksTimeHistory[this.#startedChunksTimeHistory.length - 1]!;\n const timeSinceLastStart = new Date().getTime() - lastChunkStartTime;\n\n if (timeSinceLastStart < this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs)\n return this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs - timeSinceLastStart;\n\n return 0;\n }\n\n async semaphoreAcquire(): Promise<ConcurrencyReleaser> {\n this.throwIfNotStarted();\n\n return await this.#concurrencyController!.acquire();\n }\n\n private throwIfNotStarted() {\n if (this.#isUdp === undefined)\n throw new Error(`Optimizer hasn't been started`);\n }\n\n start(isUdp: boolean, serverLatencyInMs: number) {\n this.#isUdp = isUdp;\n\n if (isUdp) {\n this.#initialOptimizationValues = this.#udpOptimizationStrategy.getInitialValues(serverLatencyInMs);\n this.#currentOptimizationValues = this.#initialOptimizationValues;\n\n this.#concurrencyController = new TransferConcurrencyController(this.#initialOptimizationValues.maxParallelChunksAmount);\n\n this.subscribeToTransferEvents();\n\n this.#timeout = setTimeout(() => this.optimize(), this.#initialOptimizationValues.optimizationIntervalInMs);\n }\n else {\n this.#timeout = undefined;\n\n this.#initialOptimizationValues = {\n chunkSize: this.#tcpChunkSize,\n maxParallelChunksAmount: this.#tcpChunksUploadInParallel,\n minTimeBetweenChunksStartInMs: 0,\n optimizationIntervalInMs: 0,\n requestTimeoutInMs: 0,\n };\n\n this.#currentOptimizationValues = this.#initialOptimizationValues;\n\n this.#concurrencyController = new TransferConcurrencyController(this.#tcpChunksUploadInParallel);\n }\n }\n\n stop() {\n if (!this.#isUdp)\n return;\n\n clearTimeout(this.#timeout);\n\n this.unsubscribeFromTransferEvents();\n }\n\n private subscribeToTransferEvents() {\n this.#transferEventsEngine.addEventListener(TransferUploadEvent.FileChunkUploadStarted, this.chunkUploadStarted);\n this.#transferEventsEngine.addEventListener(TransferUploadEvent.FileChunkUploadCompleted, this.chunkUploadSucceeded);\n this.#transferEventsEngine.addEventListener(TransferUploadEvent.FileChunkUploadCompletedPartially, this.chunkUploadSucceededPartially);\n this.#transferEventsEngine.addEventListener(TransferUploadEvent.FileChunkUploadFailed, this.chunkUploadFailed);\n }\n\n private unsubscribeFromTransferEvents() {\n this.#transferEventsEngine.removeEventListener(TransferUploadEvent.FileChunkUploadStarted, this.chunkUploadStarted);\n this.#transferEventsEngine.removeEventListener(TransferUploadEvent.FileChunkUploadCompleted, this.chunkUploadSucceeded);\n this.#transferEventsEngine.removeEventListener(TransferUploadEvent.FileChunkUploadCompletedPartially, this.chunkUploadSucceededPartially);\n this.#transferEventsEngine.removeEventListener(TransferUploadEvent.FileChunkUploadFailed, this.chunkUploadFailed);\n }\n\n private chunkUploadStarted = () => {\n this.#startedChunksTimeHistory.push(Date.now());\n };\n\n private chunkUploadSucceeded = (eventArgs: FileChunkUploadCompletedEventArgs) => {\n this.#ackedChunksHistory.push({ time: Date.now(), latencyInMs: eventArgs.latencyInMsIfUdp! });\n };\n\n private chunkUploadSucceededPartially = (eventArgs: FileChunkUploadCompletedPartiallyEventArgs) => {\n this.#ackedChunksHistory.push({ time: Date.now(), latencyInMs: eventArgs.latencyInMsIfUdp! });\n };\n\n private chunkUploadFailed = (eventArgs: FileChunkUploadFailedEventArgs) => {\n const isFileAccessError = eventArgs.error.cause instanceof FsError;\n\n if (isFileAccessError)\n return;\n\n if (this.isMsgSizeError(eventArgs.error)) {\n this.#msgSizeErrorHandler();\n return;\n }\n\n if (this.isNoBufsError(eventArgs.error)) {\n this.#noBufsErrorHandler();\n return;\n }\n\n this.#failedChunksTimeHistory.push(Date.now());\n };\n\n private isMsgSizeError(error: Error) {\n return this.isErrorContainingErrorCode(error, `EMSGSIZE`);\n }\n\n private isNoBufsError(error: Error) {\n return this.isErrorContainingErrorCode(error, `ENOBUFS`);\n }\n\n private isErrorContainingErrorCode(error: Error, errorCode: string): boolean {\n if (error.message.includes(errorCode))\n return true;\n\n if (error.cause)\n return this.isErrorContainingErrorCode(error.cause, errorCode);\n\n return false;\n }\n\n private optimize = async (): Promise<void> => {\n const optimizationResult = this.#udpOptimizationStrategy.getOptimizedValues(this.#startedChunksTimeHistory, this.#ackedChunksHistory, this.#failedChunksTimeHistory, this.#currentOptimizationValues!);\n\n this.#currentOptimizationValues = optimizationResult.optimizedValues;\n\n this.#concurrencyController!.maxConcurrency = this.#currentOptimizationValues.maxParallelChunksAmount;\n\n this.#timeout = setTimeout(() => this.optimize(), optimizationResult.optimizedValues.optimizationIntervalInMs);\n\n if (optimizationResult.clearChunksHistory === false)\n return;\n\n this.#startedChunksTimeHistory = [];\n this.#ackedChunksHistory = [];\n this.#failedChunksTimeHistory = [];\n };\n}"]}
1
+ {"version":3,"file":"transferUploadOptimizer.js","sourceRoot":"","sources":["../../../../src/uploader/optimizer/transferUploadOptimizer.ts"],"names":[],"mappings":"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","sourcesContent":["import throttle from \"lodash.throttle\";\n\nimport TransferConcurrencyController from \"../../utils/concurrencyController/transferConcurrencyController.js\";\nimport TransferUploadEvent from \"../transferUploadEvent.js\";\nimport FsError from \"../../utils/fileSystem/fsError.js\";\n\nimport type OptimizationValues from \"./optimizationValues.js\";\nimport type ConcurrencyController from \"../../utils/concurrencyController/concurrencyController.js\";\nimport type ConcurrencyReleaser from \"../../utils/concurrencyController/concurrencyReleaser.js\";\nimport type UploadOptimizer from \"./uploadOptimizer.js\";\nimport type EventsEngine from \"../../utils/events/eventsEngine.js\";\nimport type FileChunkUploadFailedEventArgs from \"../eventArgs/fileChunkUploadFailedEventArgs.js\";\nimport type FileChunkUploadCompletedEventArgs from \"../eventArgs/fileChunkUploadCompletedEventArgs.js\";\nimport type FileChunkUploadCompletedPartiallyEventArgs from \"../eventArgs/fileChunkUploadCompletedPartiallyEventArgs.js\";\nimport type TransferUploadOptimizationStrategy from \"./transferUploadOptimizationStrategy.js\";\n\nconst MAX_OPTIMIZER_HISTORY_ENTRIES = 10_000;\nconst OPTIMIZER_HISTORY_TRIM_THRESHOLD = 12_000;\n\nexport default class TransferUploadOptimizer implements UploadOptimizer {\n readonly #tcpChunkSize: number;\n readonly #tcpChunksUploadInParallel: number;\n readonly #transferEventsEngine: EventsEngine;\n readonly #udpOptimizationStrategy: TransferUploadOptimizationStrategy;\n\n #concurrencyController: ConcurrencyController | undefined;\n\n #isUdp: boolean | undefined;\n\n #initialOptimizationValues: OptimizationValues | undefined;\n #currentOptimizationValues: OptimizationValues | undefined;\n\n #timeout: NodeJS.Timeout | undefined;\n\n #startedChunksTimeHistory: number[] = [];\n #ackedChunksHistory: { time: number, latencyInMs: number }[] = [];\n #failedChunksTimeHistory: number[] = [];\n\n #chunksStartedInThisMs = 0;\n\n #noBufsErrorHandler = throttle(() => {\n const result = this.#udpOptimizationStrategy.noBufsErrorHandler(this.#currentOptimizationValues!);\n\n this.#currentOptimizationValues!.maxParallelChunksAmount = result.maxParallelChunksAmount;\n this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs = result.minTimeBetweenChunksStartInMs;\n\n this.#concurrencyController!.maxConcurrency = this.#currentOptimizationValues!.maxParallelChunksAmount;\n }, 500, { leading: true, trailing: false });\n\n #msgSizeErrorHandler = throttle(() => {\n const result = this.#udpOptimizationStrategy.msgSizeErrorHandler(this.#currentOptimizationValues!);\n\n this.#currentOptimizationValues!.chunkSize = result.chunkSize;\n }, 500, { leading: true, trailing: false });\n\n constructor(tcpChunkSize: number, tcpChunksUploadInParallel: number, transferEventsEngine: EventsEngine, udpOptimizationStrategy: TransferUploadOptimizationStrategy) {\n this.#tcpChunkSize = tcpChunkSize;\n this.#tcpChunksUploadInParallel = tcpChunksUploadInParallel;\n this.#transferEventsEngine = transferEventsEngine;\n this.#udpOptimizationStrategy = udpOptimizationStrategy;\n }\n\n get currentChunkSize(): number {\n this.throwIfNotStarted();\n\n return this.#currentOptimizationValues!.chunkSize;\n }\n\n get currentRequestTimeoutInMs(): number {\n this.throwIfNotStarted();\n\n return this.#currentOptimizationValues!.requestTimeoutInMs;\n }\n\n get currentSleepTimeInMs(): number {\n this.throwIfNotStarted();\n\n if (this.#startedChunksTimeHistory.length === 0)\n return 0;\n\n if (this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs < 1) {\n const chunksToStartPerMs = Math.ceil(1 / this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs);\n\n if (this.#chunksStartedInThisMs < chunksToStartPerMs) {\n this.#chunksStartedInThisMs += 1;\n return 0;\n }\n\n this.#chunksStartedInThisMs = 0;\n return 1;\n }\n\n const lastChunkStartTime = this.#startedChunksTimeHistory[this.#startedChunksTimeHistory.length - 1]!;\n const timeSinceLastStart = new Date().getTime() - lastChunkStartTime;\n\n if (timeSinceLastStart < this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs)\n return this.#currentOptimizationValues!.minTimeBetweenChunksStartInMs - timeSinceLastStart;\n\n return 0;\n }\n\n async semaphoreAcquire(): Promise<ConcurrencyReleaser> {\n this.throwIfNotStarted();\n\n return await this.#concurrencyController!.acquire();\n }\n\n private throwIfNotStarted() {\n if (this.#isUdp === undefined)\n throw new Error(`Optimizer hasn't been started`);\n }\n\n start(isUdp: boolean, serverLatencyInMs: number) {\n this.#isUdp = isUdp;\n\n if (isUdp) {\n this.#initialOptimizationValues = this.#udpOptimizationStrategy.getInitialValues(serverLatencyInMs);\n this.#currentOptimizationValues = this.#initialOptimizationValues;\n\n this.#concurrencyController = new TransferConcurrencyController(this.#initialOptimizationValues.maxParallelChunksAmount);\n\n this.subscribeToTransferEvents();\n\n this.#timeout = setTimeout(() => this.optimize(), this.#initialOptimizationValues.optimizationIntervalInMs);\n }\n else {\n this.#timeout = undefined;\n\n this.#initialOptimizationValues = {\n chunkSize: this.#tcpChunkSize,\n maxParallelChunksAmount: this.#tcpChunksUploadInParallel,\n minTimeBetweenChunksStartInMs: 0,\n optimizationIntervalInMs: 0,\n requestTimeoutInMs: 0,\n };\n\n this.#currentOptimizationValues = this.#initialOptimizationValues;\n\n this.#concurrencyController = new TransferConcurrencyController(this.#tcpChunksUploadInParallel);\n }\n }\n\n stop() {\n if (!this.#isUdp)\n return;\n\n clearTimeout(this.#timeout);\n\n this.unsubscribeFromTransferEvents();\n }\n\n private subscribeToTransferEvents() {\n this.#transferEventsEngine.addEventListener(TransferUploadEvent.FileChunkUploadStarted, this.chunkUploadStarted);\n this.#transferEventsEngine.addEventListener(TransferUploadEvent.FileChunkUploadCompleted, this.chunkUploadSucceeded);\n this.#transferEventsEngine.addEventListener(TransferUploadEvent.FileChunkUploadCompletedPartially, this.chunkUploadSucceededPartially);\n this.#transferEventsEngine.addEventListener(TransferUploadEvent.FileChunkUploadFailed, this.chunkUploadFailed);\n }\n\n private unsubscribeFromTransferEvents() {\n this.#transferEventsEngine.removeEventListener(TransferUploadEvent.FileChunkUploadStarted, this.chunkUploadStarted);\n this.#transferEventsEngine.removeEventListener(TransferUploadEvent.FileChunkUploadCompleted, this.chunkUploadSucceeded);\n this.#transferEventsEngine.removeEventListener(TransferUploadEvent.FileChunkUploadCompletedPartially, this.chunkUploadSucceededPartially);\n this.#transferEventsEngine.removeEventListener(TransferUploadEvent.FileChunkUploadFailed, this.chunkUploadFailed);\n }\n\n private chunkUploadStarted = () => {\n this.#startedChunksTimeHistory.push(Date.now());\n this.#startedChunksTimeHistory = this.trimHistoryArrayToMaxEntries(this.#startedChunksTimeHistory);\n };\n\n private chunkUploadSucceeded = (eventArgs: FileChunkUploadCompletedEventArgs) => {\n this.#ackedChunksHistory.push({ time: Date.now(), latencyInMs: eventArgs.latencyInMsIfUdp! });\n this.#ackedChunksHistory = this.trimHistoryArrayToMaxEntries(this.#ackedChunksHistory);\n };\n\n private chunkUploadSucceededPartially = (eventArgs: FileChunkUploadCompletedPartiallyEventArgs) => {\n this.#ackedChunksHistory.push({ time: Date.now(), latencyInMs: eventArgs.latencyInMsIfUdp! });\n this.#ackedChunksHistory = this.trimHistoryArrayToMaxEntries(this.#ackedChunksHistory);\n };\n\n private chunkUploadFailed = (eventArgs: FileChunkUploadFailedEventArgs) => {\n const isFileAccessError = eventArgs.error.cause instanceof FsError;\n\n if (isFileAccessError)\n return;\n\n if (this.isMsgSizeError(eventArgs.error)) {\n this.#msgSizeErrorHandler();\n return;\n }\n\n if (this.isNoBufsError(eventArgs.error)) {\n this.#noBufsErrorHandler();\n return;\n }\n\n this.#failedChunksTimeHistory.push(Date.now());\n this.#failedChunksTimeHistory = this.trimHistoryArrayToMaxEntries(this.#failedChunksTimeHistory);\n };\n\n private isMsgSizeError(error: Error) {\n return this.isErrorContainingErrorCode(error, `EMSGSIZE`);\n }\n\n private isNoBufsError(error: Error) {\n return this.isErrorContainingErrorCode(error, `ENOBUFS`);\n }\n\n private isErrorContainingErrorCode(error: Error, errorCode: string): boolean {\n if (error.message.includes(errorCode))\n return true;\n\n if (error.cause)\n return this.isErrorContainingErrorCode(error.cause, errorCode);\n\n return false;\n }\n\n private trimHistoryArrayToMaxEntries<T>(history: T[]): T[] {\n if (history.length <= OPTIMIZER_HISTORY_TRIM_THRESHOLD)\n return history;\n\n return history.slice(history.length - MAX_OPTIMIZER_HISTORY_ENTRIES);\n }\n\n private optimize = async (): Promise<void> => {\n const optimizationResult = this.#udpOptimizationStrategy.getOptimizedValues(this.#startedChunksTimeHistory, this.#ackedChunksHistory, this.#failedChunksTimeHistory, this.#currentOptimizationValues!);\n\n this.#currentOptimizationValues = optimizationResult.optimizedValues;\n\n this.#concurrencyController!.maxConcurrency = this.#currentOptimizationValues.maxParallelChunksAmount;\n\n this.#timeout = setTimeout(() => this.optimize(), optimizationResult.optimizedValues.optimizationIntervalInMs);\n\n if (optimizationResult.clearChunksHistory === false)\n return;\n\n this.#startedChunksTimeHistory = [];\n this.#ackedChunksHistory = [];\n this.#failedChunksTimeHistory = [];\n };\n}"]}
@@ -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":"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"}
@@ -114,7 +114,7 @@ export default class TransferUpload {
114
114
  if (this.#isUdpUploadMode && !this.#transferMetadata.udpData.handshakeData)
115
115
  await this.serverUdpHandshake();
116
116
  this.#optimizer.start(this.#isUdpUploadMode, this.#serverLatencyInMs);
117
- const ongoingChunkUploads = [];
117
+ const ongoingChunkUploads = new Set();
118
118
  for (const file of this.files) {
119
119
  const fileStatus = this.#transferState.getFile(file.externalId);
120
120
  if (fileStatus.isCompleted)
@@ -131,15 +131,18 @@ export default class TransferUpload {
131
131
  releaseSemaphore();
132
132
  break;
133
133
  }
134
- const promise = this.sendChunkAndKeepUpdatingState(file, chunk.startPosition, chunk.sizeInBytes, releaseSemaphore);
135
- ongoingChunkUploads.push(promise);
134
+ const chunkUploadPromise = this.sendChunkAndKeepUpdatingState(file, chunk.startPosition, chunk.sizeInBytes, releaseSemaphore);
135
+ const trackedChunkUploadPromise = chunkUploadPromise.finally(() => {
136
+ ongoingChunkUploads.delete(trackedChunkUploadPromise);
137
+ });
138
+ ongoingChunkUploads.add(trackedChunkUploadPromise);
136
139
  if (this.#transferState.status !== TransferStatus.Running)
137
140
  break;
138
141
  }
139
142
  if (this.#transferState.status !== TransferStatus.Running)
140
143
  break;
141
144
  }
142
- await promiseAllSettled(ongoingChunkUploads);
145
+ await promiseAllSettled(Array.from(ongoingChunkUploads));
143
146
  this.#optimizer.stop();
144
147
  if (this.#transferState.status === TransferStatus.Pausing)
145
148
  this.#transferState.transferPaused();
@@ -1 +1 @@
1
- {"version":3,"file":"transferUpload.js","sourceRoot":"","sources":["../../../src/uploader/transferUpload.ts"],"names":[],"mappings":"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","sourcesContent":["import sleep from 'abortable-sleep';\n\nimport ApiError from '../utils/api/apiError.js';\nimport FsError from '../utils/fileSystem/fsError.js';\nimport TransferUploadState from \"./state/transferUploadState.js\";\nimport TransferUploadError from \"./transferUploadError.js\";\nimport TransferStatus from \"../utils/types/transferStatus.js\";\nimport TransferUploadEvent from './transferUploadEvent.js';\nimport ChunksIterator from './chunksIterator/chunksIterator.js';\nimport mergeAbortAndPauseSignals from '../utils/mergeAbortAndPauseSignals.js';\nimport ApiFilemail449Error from '../utils/api/apiFilemail449Error.js';\nimport { promiseAllSettled } from '../utils/promiseAll.js';\nimport { concatUint8Arrays, hexToUint8Array, uint8ArrayToHex } from '../utils/uint8ArrayUtils.js';\n\nimport type ApiClient from \"../utils/api/apiClient.js\";\nimport type { InitializeTransferRequest } from \"../utils/api/dtos/initializeTransferRequest.js\";\nimport type SendFileChunkRequest from '../utils/api/dtos/sendFileChunkRequest.js';\nimport type FileServerClientFactory from '../utils/api/fileServerClientFactory.js';\nimport type FileDetails from \"../utils/fileSystem/fileDetails.js\";\nimport type TransferUploadMetadata from \"./export/transferUploadMetadata.js\";\nimport type TransferUploadInfo from \"./options/transferUploadInfo.js\";\nimport type { TransferUploadAppendInfo } from './options/transferUploadAppendInfo.js';\nimport type ResetTransferRequest from '../utils/api/dtos/resetTransferRequest.js';\nimport type EventsEngine from '../utils/events/eventsEngine.js';\nimport type FileChunkUploadEventArgs from './eventArgs/fileChunkUploadEventArgs.js';\nimport type FileChunkUploadFailedEventArgs from './eventArgs/fileChunkUploadFailedEventArgs.js';\nimport type ChunkProgressEvent from '../utils/events/chunkProgressEvent.js';\nimport type FinalizeTransferRequest from '../utils/api/dtos/finalizeTransferRequest.js';\nimport type FileUploadEventArgs from './eventArgs/fileUploadEventArgs.js';\nimport type TransferUploadCompletedEventArgs from './eventArgs/transferUploadCompletedEventArgs.js';\nimport type CancelTransferRequest from '../utils/api/dtos/cancelTransferRequest.js';\nimport type ConcurrencyReleaser from \"../utils/concurrencyController/concurrencyReleaser.js\";\nimport type FileUploadFailedEventArgs from './eventArgs/fileUploadFailedEventArgs.js';\nimport type TransferUploadProgressedEventArgs from './eventArgs/transferUploadProgressedEventArgs.js';\nimport type FileChunkUploadProgressedEventArgs from './eventArgs/fileChunkUploadProgressedEventArgs.js';\nimport type UploaderChunkStreamProviderFactory from './chunkStreamProviderFactory/uploaderChunkStreamProviderFactory.js';\nimport type TransferUploadConfig from './options/transferUploadConfig.js';\nimport type { PauseSignal } from './pauseController.js';\nimport type InitializeTransferResponse from '../utils/api/dtos/initializeTransferResponse.js';\nimport type { InitializeTransferResponseUdpData } from '../utils/api/dtos/initializeTransferResponse.js';\nimport type TransferUploadModeChosenEventArgs from './eventArgs/transferUploadModeChosenEventArgs.js';\nimport type HandshakeRequest from './api/dtos/handshakeRequest.js';\nimport type ChunkStreamProvider from '../utils/fileSystem/chunkStreamProvider.js';\nimport type SendChunkRequest from './api/dtos/sendChunkRequest.js';\nimport type UploadOptimizer from './optimizer/uploadOptimizer.js';\nimport type FileChunkUploadCompletedPartiallyEventArgs from './eventArgs/fileChunkUploadCompletedPartiallyEventArgs.js';\nimport type FileChunkUploadCompletedEventArgs from './eventArgs/fileChunkUploadCompletedEventArgs.js';\nimport type TransferMetadataDeterminedEventArgs from './eventArgs/transferMetadataDeterminedEventArgs.js';\nimport type CryptographyProvider from '../utils/crypto/cryptographyProvider.js';\nimport type { TransferUploadExportData, TransferUploadExportDataMetadata } from './export/transferUploadExportData.js';\n\nexport default class TransferUpload<T extends FileDetails> {\n #totalSizeInBytes: number;\n\n #chunkStreamProviderFactory: UploaderChunkStreamProviderFactory<T>;\n #apiClient: ApiClient;\n #fileServerClientFactory: FileServerClientFactory;\n #eventsEngine: EventsEngine;\n #info: TransferUploadInfo<T> | TransferUploadAppendInfo<T>;\n #config: TransferUploadConfig;\n #optimizer: UploadOptimizer;\n #cryptography: CryptographyProvider;\n\n #transferState?: TransferUploadState;\n #transferMetadata?: TransferUploadMetadata;\n #transferDownloadUrl?: string;\n\n #pauseSignal: PauseSignal | undefined;\n #abortSignal: AbortSignal | undefined;\n #mergedPauseAndAbortSignal: AbortSignal | undefined;\n\n pauseEventListener: (() => void) | undefined;\n abortEventListener: (() => void) | undefined;\n\n #isUdpUploadMode: boolean;\n #serverLatencyInMs: number | undefined;\n\n #isRunMethodRunning = false;\n\n get status(): TransferStatus {\n return this.#transferState?.status ?? TransferStatus.Initialized;\n }\n\n get completedFilesCount(): number {\n return this.#transferState?.completedFilesCount ?? 0;\n }\n\n get failedFilesCount(): number {\n return this.#transferState?.failedFilesCount ?? 0;\n }\n\n get uploadedBytesCount(): number {\n return this.#transferState?.uploadedBytesCount ?? 0;\n }\n\n get failedBytesCount(): number {\n return this.#transferState?.failedBytesCount ?? 0;\n }\n\n get progressInPercentage(): number {\n if (this.totalSizeInBytes === 0)\n return 0;\n\n return (this.uploadedBytesCount * 100) / this.totalSizeInBytes;\n }\n\n get files(): readonly Readonly<T>[] {\n return this.#info.files;\n }\n\n get totalSizeInBytes(): number {\n return this.#totalSizeInBytes;\n }\n\n get transferId(): string | undefined {\n return this.#transferMetadata?.transferId;\n }\n\n constructor(chunkStreamProviderFactory: UploaderChunkStreamProviderFactory<T>, apiClient: ApiClient, fileServerClientFactory: FileServerClientFactory, eventsEngine: EventsEngine, info: TransferUploadInfo<T> | TransferUploadAppendInfo<T>, config: TransferUploadConfig, optimizer: UploadOptimizer, cryptography: CryptographyProvider) {\n if (info.files.length === 0)\n throw new TransferUploadError(`Files can't be empty`);\n\n this.#totalSizeInBytes = info.files.reduce((partialSum, file) => partialSum + file.fileSizeInBytes, 0);\n this.#isUdpUploadMode = false;\n\n this.#chunkStreamProviderFactory = chunkStreamProviderFactory;\n this.#apiClient = apiClient;\n this.#fileServerClientFactory = fileServerClientFactory;\n this.#eventsEngine = eventsEngine;\n this.#info = info;\n this.#config = config;\n this.#optimizer = optimizer;\n this.#cryptography = cryptography;\n\n if (this.isUploadAppendInfo(this.#info))\n this.createTransferMetadataFromInfo(this.#info);\n }\n\n private isUploadAppend(): boolean {\n return this.isUploadAppendInfo(this.#info);\n }\n\n private isUploadAppendInfo(info: TransferUploadInfo<T> | TransferUploadAppendInfo<T>): info is TransferUploadAppendInfo<T> {\n return (info as TransferUploadAppendInfo<T>).transferKey !== undefined;\n }\n\n private createTransferMetadataFromInfo(info: TransferUploadAppendInfo<T>) {\n if (!this.isUploadAppendInfo(info))\n throw new TransferUploadError(`Options are not TransferUploadAppendOptions`);\n\n this.#transferDownloadUrl = info.transferDownloadUrl;\n\n this.#transferMetadata = {\n transferId: info.transferId,\n transferKey: info.transferKey,\n transferFileServerUrl: info.transferFileServerUrl,\n transferRegion: info.transferRegion,\n encryptionData: info.e2eeData,\n };\n }\n\n async run(transferPauseSignal: PauseSignal, transferAbortSignal: AbortSignal): Promise<void> {\n this.throwIfNotPossibleToRun(transferPauseSignal, transferAbortSignal);\n\n this.#isRunMethodRunning = true;\n\n try {\n this.#pauseSignal = transferPauseSignal;\n this.#abortSignal = transferAbortSignal;\n this.#mergedPauseAndAbortSignal = mergeAbortAndPauseSignals(transferPauseSignal, transferAbortSignal);\n\n if (!this.#transferState)\n this.#transferState = new TransferUploadState(this.files, this.#eventsEngine, this.#config.currentRatesTimespanInMs, this.#config.progressEventThrottlingInMs);\n else\n this.#transferState.recover();\n\n this.#transferState.transferRun();\n\n this.addPauseAndStopListeners();\n\n if (!this.#transferMetadata)\n await this.startApiTransferAndCreateMetadata();\n\n this.notifyMetadataDetermined();\n\n await this.pingServerAndChooseUploadMode();\n\n if (this.#isUdpUploadMode && !this.#transferMetadata!.udpData!.handshakeData)\n await this.serverUdpHandshake();\n\n this.#optimizer.start(this.#isUdpUploadMode, this.#serverLatencyInMs!);\n\n const ongoingChunkUploads: Promise<void>[] = [];\n\n for (const file of this.files) {\n const fileStatus = this.#transferState.getFile(file.externalId);\n\n if (fileStatus.isCompleted)\n continue;\n\n const alreadySentChunks = this.#transferState.getChunksForFile(file.externalId);\n const chunksIterator = new ChunksIterator(alreadySentChunks, file.fileSizeInBytes, this.#optimizer);\n\n for (const chunk of chunksIterator.getChunksIterator()) {\n // eslint-disable-next-line no-await-in-loop\n const releaseSemaphore = await this.#optimizer.semaphoreAcquire();\n\n if (this.#optimizer.currentSleepTimeInMs >= 1)\n // eslint-disable-next-line no-await-in-loop\n await sleep(this.#optimizer.currentSleepTimeInMs, this.#mergedPauseAndAbortSignal);\n\n if (this.#transferState!.status !== TransferStatus.Running) {\n releaseSemaphore();\n break;\n }\n\n const promise: Promise<void> = this.sendChunkAndKeepUpdatingState(file, chunk.startPosition, chunk.sizeInBytes, releaseSemaphore);\n\n ongoingChunkUploads.push(promise);\n\n if (this.#transferState!.status !== TransferStatus.Running)\n break;\n }\n\n if (this.#transferState!.status !== TransferStatus.Running)\n break;\n }\n\n await promiseAllSettled(ongoingChunkUploads);\n\n this.#optimizer.stop();\n\n if (this.#transferState.status === TransferStatus.Pausing)\n this.#transferState.transferPaused();\n else if (this.#transferState.status === TransferStatus.Aborting)\n this.#transferState.transferAborted();\n else if (this.uploadedBytesCount !== this.totalSizeInBytes)\n this.#transferState.transferFailed();\n else {\n await this.finalizeTransfer();\n this.#transferState.transferCompleted(this.#transferMetadata!, this.#transferDownloadUrl!);\n }\n }\n catch (error) {\n // 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\n if (!this.#transferState)\n this.#eventsEngine.emit(TransferUploadEvent.TransferFailed);\n else if (this.#transferState.status === TransferStatus.Pausing) {\n this.#transferState.transferPaused();\n return;\n }\n else if (this.#transferState.status === TransferStatus.Aborting) {\n this.#transferState.transferAborted();\n return;\n }\n else\n this.#transferState.transferFailed();\n\n if (error instanceof TransferUploadError)\n throw error;\n else\n throw new TransferUploadError(`Unhandled error occured. See 'cause' for more details`, { cause: error as Error });\n }\n finally {\n this.removePauseAndStopListeners();\n this.#optimizer.stop();\n this.#isRunMethodRunning = false;\n }\n }\n\n private notifyMetadataDetermined() {\n if (!this.#transferMetadata)\n return;\n\n const eventArgs: TransferMetadataDeterminedEventArgs = {\n transferId: this.#transferMetadata.transferId,\n fileServerUrl: this.#transferMetadata.transferFileServerUrl,\n region: this.#transferMetadata.transferRegion,\n };\n\n this.#eventsEngine.emit(TransferUploadEvent.TransferMetadataDetermined, eventArgs);\n }\n\n private async pingServerAndChooseUploadMode(): Promise<void> {\n try {\n if (this.#config.turnOffUdp)\n throw new Error(`UDP is turned off`);\n\n const udpData = this.#transferMetadata?.udpData;\n\n if (!udpData)\n throw new Error(`No UDP data is available`);\n\n const requestTimeout = this.#config.forceUdp ? 3 * 1000 : this.getPingTimeout(udpData.threshold);\n const retryDelay = 1000;\n\n const udpClient = this.#fileServerClientFactory.createFileServerUdpUploadClient(udpData.ip, udpData.port, requestTimeout, this.#mergedPauseAndAbortSignal, undefined, retryDelay);\n\n await udpClient.connect();\n\n const pingResult = await udpClient.ping();\n\n udpClient.close().catch(() => { /* discard */ });\n\n this.#serverLatencyInMs = pingResult.latencyInMs;\n this.#isUdpUploadMode = pingResult.latencyInMs >= udpData.threshold;\n\n const eventArgs: TransferUploadModeChosenEventArgs = { isUdpMode: this.#isUdpUploadMode, latency: pingResult.latencyInMs };\n this.#eventsEngine.emit(TransferUploadEvent.TransferUploadModeChosen, eventArgs);\n }\n catch (error) {\n this.#isUdpUploadMode = false;\n\n const eventArgs: TransferUploadModeChosenEventArgs = { isUdpMode: this.#isUdpUploadMode, error: error as Error };\n this.#eventsEngine.emit(TransferUploadEvent.TransferUploadModeChosen, eventArgs);\n }\n }\n\n private getPingTimeout(udpPingThreshold: number) {\n const pingTimeout = Math.min(3 * 1000, udpPingThreshold * 20);\n return Math.max(500, pingTimeout);\n }\n\n private async serverUdpHandshake(): Promise<void> {\n const transferMetadata = this.#transferMetadata!;\n const udpData = transferMetadata.udpData!;\n\n const requestTimeout = this.getHandshakeTimeout();\n const retryDelay = 1000;\n\n const udpClient = this.#fileServerClientFactory.createFileServerUdpUploadClient(udpData.ip, udpData.port, requestTimeout, this.#mergedPauseAndAbortSignal, undefined, retryDelay);\n\n await udpClient.connect();\n\n const handshakeRequest: HandshakeRequest = { transferId: transferMetadata.transferId, transferKey: transferMetadata.transferKey };\n const handshakeResponse = await udpClient.handshake(handshakeRequest);\n\n udpClient.close().catch(() => { /* discard */ });\n\n this.#transferMetadata!.udpData!.handshakeData = handshakeResponse;\n }\n\n private getHandshakeTimeout() {\n const timeout = Math.min(this.#serverLatencyInMs! * 30, 30 * 1000);\n return Math.max(2000, timeout);\n }\n\n private async sendChunkAndKeepUpdatingState(file: T, chunkStartPosition: number, chunkSizeInBytes: number, releaseSemaphore: ConcurrencyReleaser): Promise<void> {\n let uploadedBytesCount = 0;\n\n try {\n this.#transferState!.chunkUploadStarted(file.externalId, chunkStartPosition, chunkSizeInBytes);\n\n const chunkStreamProvider = this.#chunkStreamProviderFactory.createChunkStreamProvider(file, chunkStartPosition, chunkSizeInBytes, this.#transferMetadata?.encryptionData);\n\n const progressEventHandler = (eventArgs: ChunkProgressEvent) => {\n uploadedBytesCount += eventArgs.transferredBytesSinceLastEvent;\n this.#transferState!.chunkUploadProgressed(file.externalId, chunkStartPosition, chunkSizeInBytes, eventArgs);\n };\n\n const response = await this.sendChunk(file, chunkStreamProvider, progressEventHandler);\n\n const latencyInMsIfUdp = this.#isUdpUploadMode ? (response as { latencyInMs: number }).latencyInMs : undefined;\n\n if (uploadedBytesCount === chunkSizeInBytes)\n this.#transferState!.chunkUploadCompleted(file.externalId, chunkStartPosition, chunkSizeInBytes, latencyInMsIfUdp);\n else\n this.#transferState!.chunkUploadCompletedPartially(file.externalId, chunkStartPosition, chunkSizeInBytes, uploadedBytesCount, this.#pauseSignal!.paused, latencyInMsIfUdp);\n }\n catch (error) {\n const chunkError = error as Error;\n\n const isTcpPausingError = chunkError.cause !== undefined\n && chunkError.cause instanceof ApiFilemail449Error\n && chunkError.cause.message === `Wrong md5 hash`\n && this.#pauseSignal?.paused === true;\n\n if (isTcpPausingError)\n this.#transferState!.chunkUploadCompletedPartially(file.externalId, chunkStartPosition, chunkSizeInBytes, uploadedBytesCount, this.#pauseSignal!.paused);\n else {\n const failedReason = this.getChunkFailedReason(error);\n this.#transferState!.chunkUploadFailed(file.externalId, chunkStartPosition, chunkSizeInBytes, uploadedBytesCount, failedReason, error as Error);\n }\n }\n finally {\n releaseSemaphore();\n }\n }\n\n private async sendChunk(file: T, chunkStreamProvider: ChunkStreamProvider, progressEventHandler: (eventArgs: ChunkProgressEvent) => void): Promise<{ latencyInMs: number } | void> {\n if (this.#isUdpUploadMode)\n return await this.sendChunkUsingUdp(file, chunkStreamProvider, progressEventHandler);\n\n return await this.sendChunkUsingTcp(file, chunkStreamProvider, progressEventHandler);\n }\n\n private async sendChunkUsingUdp(file: T, chunkStreamProvider: ChunkStreamProvider, progressEventHandler: (eventArgs: ChunkProgressEvent) => void): Promise<{ latencyInMs: number }> {\n const transferMetadata = this.#transferMetadata!;\n const udpData = transferMetadata.udpData!;\n\n const udpClient = this.#fileServerClientFactory.createFileServerUdpUploadClient(udpData.ip, udpData.port, this.#optimizer.currentRequestTimeoutInMs, this.#mergedPauseAndAbortSignal, 0);\n\n const sendChunkRequest: SendChunkRequest = {\n sessionGuid: this.#transferMetadata!.udpData!.handshakeData!.sessionGuid,\n aesKey: this.#transferMetadata!.udpData!.handshakeData!.aesKey,\n chunkStartPosition: chunkStreamProvider.chunkStartPosition,\n fileSizeInBytes: file.fileSizeInBytes,\n fileDestinationPathInTransfer: file.fileDestinationPathInTransfer,\n fileName: file.fileName,\n };\n\n await udpClient.connect();\n\n const result = await udpClient.sendChunk(sendChunkRequest, chunkStreamProvider);\n\n udpClient.close().catch(() => { /* discard */ });\n\n const chunkProgressEventArgs: ChunkProgressEvent = { transferredBytesTotal: chunkStreamProvider.chunkLengthInBytes, transferredBytesSinceLastEvent: chunkStreamProvider.chunkLengthInBytes };\n progressEventHandler(chunkProgressEventArgs);\n\n return result;\n }\n\n private async sendChunkUsingTcp(file: T, chunkStreamProvider: ChunkStreamProvider, progressEventHandler: (eventArgs: ChunkProgressEvent) => void): Promise<void> {\n const request: SendFileChunkRequest = {\n chunkLengthInBytes: chunkStreamProvider.chunkLengthInBytes,\n chunkStartPosition: chunkStreamProvider.chunkStartPosition,\n };\n\n const fileServerClient = this.#fileServerClientFactory.createFileServerTcpUploadClient(this.#transferMetadata!.transferFileServerUrl, this.#transferMetadata!.transferId, this.#transferMetadata!.transferKey, file.fileName, file.fileDestinationPathInTransfer, file.fileSizeInBytes);\n\n const ongoingRequestPromise = fileServerClient.sendFileChunk(request, chunkStreamProvider, this.#pauseSignal!, this.#abortSignal!);\n\n fileServerClient.addEventListener(`progress`, progressEventHandler);\n\n await ongoingRequestPromise;\n }\n\n private getChunkFailedReason(error: unknown) {\n if (error instanceof FsError)\n return `Can't read file. ${error.message}`;\n\n if (error instanceof ApiError)\n return error.cause?.message ? `${error.message}. ${error.cause.message}` : error.message;\n\n return (error as Error)?.message;\n }\n\n private throwIfNotPossibleToRun(pauseSignal: PauseSignal, abortSignal: AbortSignal) {\n if (this.#isRunMethodRunning)\n throw new TransferUploadError(`This transfer is running and cannot be run`);\n\n if (this.#transferState\n && this.#transferState.status !== TransferStatus.Failed\n && this.#transferState.status !== TransferStatus.Aborted\n && this.#transferState.status !== TransferStatus.Initialized\n && this.#transferState.status !== TransferStatus.Paused)\n throw new TransferUploadError(`Transfer is in ${TransferStatus[this.#transferState!.status]} state and cannot be run`);\n\n if (this.files.length === 0)\n throw new TransferUploadError(`There are no files passed to the transfer`);\n\n if (pauseSignal.paused)\n throw new TransferUploadError(`Can't run transfer with already paused PauseController`);\n\n if (abortSignal.aborted)\n throw new TransferUploadError(`Can't run transfer with already aborted AbortController`);\n }\n\n private addPauseAndStopListeners() {\n this.pauseEventListener = () => {\n if (this.#transferState!.status !== TransferStatus.Running)\n throw new TransferUploadError(`Transfer is in ${TransferStatus[this.#transferState!.status]} state and cannot be paused`);\n\n this.#transferState!.transferPauseRequested();\n };\n\n this.abortEventListener = () => {\n if (this.#transferState!.status !== TransferStatus.Running)\n throw new TransferUploadError(`Transfer is in ${TransferStatus[this.#transferState!.status]} state and cannot be stopped`);\n\n this.#transferState!.transferAbortRequested();\n };\n\n this.#pauseSignal!.addEventListener(`pause`, this.pauseEventListener);\n this.#abortSignal!.addEventListener(`abort`, this.abortEventListener);\n }\n\n private removePauseAndStopListeners() {\n this.#pauseSignal!.removeEventListener(`pause`, this.pauseEventListener!);\n this.#abortSignal!.removeEventListener(`abort`, this.abortEventListener!);\n }\n\n private async startApiTransferAndCreateMetadata() {\n if (this.isUploadAppendInfo(this.#info))\n throw new TransferUploadError(`Options are not TransferUploadOptions`);\n\n try {\n const encryptionDataAndIvSaltHex = await this.generateEncryptionDataAndIvSaltHmacHex(this.#info.e2eeKey);\n\n const request: InitializeTransferRequest = {\n e2ee: Boolean(encryptionDataAndIvSaltHex),\n e2ee_keyhash: encryptionDataAndIvSaltHex?.ivSaltHmacHex,\n transfersize: this.totalSizeInBytes,\n to: this.#info.to,\n from: this.#info.from,\n subject: this.#info.subject,\n message: this.#info.message,\n notify: this.#info.notify,\n confirmation: this.#info.confirmation,\n days: this.#info.days,\n password: this.#info.uploadPassword,\n companyid: this.#info.companyId,\n incominglogintoken: this.#info.incomingLoginToken,\n incomingpageid: this.#info.incomingPageId,\n filerequestid: this.#info.fileRequestId,\n filerequestshareid: this.#info.fileRequestShareId,\n customfields: this.#info.customFields,\n };\n\n const response = await this.#apiClient.initializeTransfer(request, this.#mergedPauseAndAbortSignal);\n\n this.#transferMetadata = {\n transferId: response.transferId,\n transferKey: response.transferKey,\n transferFileServerUrl: response.transferUrl,\n transferRegion: response.transferRegion,\n encryptionData: encryptionDataAndIvSaltHex?.encryptionData,\n udpData: this.getResponseOrForcedUdpData(response),\n };\n }\n catch (error) {\n throw new TransferUploadError(`Error initializing transfer through the API`, { cause: error as Error });\n }\n }\n\n private async generateEncryptionDataAndIvSaltHmacHex(e2eeKey?: string): Promise<{ encryptionData: { iv: Uint8Array, key: Uint8Array }, ivSaltHmacHex: string, salt: Uint8Array, hmac: Uint8Array } | undefined> {\n if (!e2eeKey)\n return undefined;\n\n const salt = this.#cryptography.generateRandomBytes(16);\n const key = await this.#cryptography.deriveKey(e2eeKey, salt);\n const hmac = await this.#cryptography.generateHmac(key);\n const iv = this.#cryptography.generateRandomBytes(16);\n\n const ivSaltHmac = concatUint8Arrays([iv, salt, hmac]);\n const ivSaltHmacHex = uint8ArrayToHex(ivSaltHmac);\n\n return {\n encryptionData: { iv, key },\n hmac,\n salt,\n ivSaltHmacHex,\n };\n }\n\n private getResponseOrForcedUdpData(response: InitializeTransferResponse): InitializeTransferResponseUdpData | undefined {\n if (!this.#config.forceUdp || !response.udp)\n return response.udp;\n\n return {\n ...response.udp,\n threshold: 0,\n };\n }\n\n private async finalizeTransfer(): Promise<void> {\n this.#eventsEngine.emit(TransferUploadEvent.TransferFinalizing);\n\n if (this.isUploadAppend())\n await this.resetApiTransfer();\n else\n await this.finalizeApiTransfer();\n }\n\n private async resetApiTransfer(): Promise<void> {\n try {\n const request: ResetTransferRequest = {\n transferid: this.#transferMetadata!.transferId,\n };\n\n await this.#apiClient.resetTransfer(request, this.#mergedPauseAndAbortSignal);\n }\n catch (error) {\n throw new TransferUploadError(`Error resetting transfer through the API`, { cause: error as Error });\n }\n }\n\n private async finalizeApiTransfer(): Promise<void> {\n try {\n const request: FinalizeTransferRequest = {\n transferid: this.#transferMetadata!.transferId,\n transferkey: this.#transferMetadata!.transferKey,\n protocol: this.#isUdpUploadMode ? `udp` : `tcp`,\n };\n\n const response = await this.#apiClient.finalizeTransfer(request, this.#mergedPauseAndAbortSignal);\n\n this.#transferDownloadUrl = response.downloadUrl;\n }\n catch (error) {\n throw new TransferUploadError(`Error finalizing transfer through the API`, { cause: error as Error });\n }\n }\n\n async cancel(abortSignal?: AbortSignal): Promise<void> {\n try {\n const isTransferApiInitialized = Boolean(this.#transferState) && Boolean(this.#transferMetadata);\n\n if (!isTransferApiInitialized) {\n this.emitCancelEvents();\n return;\n }\n\n this.throwIfInWrongStateToCancel();\n\n this.#transferState!.transferCancelRequested();\n\n if (this.isUploadAppend()) {\n // There is no possibility to cancel transfer upload append on API for now\n }\n else {\n try {\n await this.cancelApiTransfer(abortSignal);\n }\n catch {\n // If API cancel fails we still finalize local transfer state as canceled to avoid hanging in Canceling.\n }\n }\n\n this.#transferState!.transferCanceled();\n }\n catch (error) {\n if (error instanceof TransferUploadError)\n throw error;\n else\n throw new TransferUploadError(`Unhandled error occured. See 'cause' for more details`, { cause: error as Error });\n }\n }\n\n private emitCancelEvents() {\n this.#eventsEngine.emit(TransferUploadEvent.TransferCancelRequested);\n this.#eventsEngine.emit(TransferUploadEvent.TransferCanceled);\n }\n\n private throwIfInWrongStateToCancel() {\n if (!this.#transferState)\n return;\n\n if (this.#transferState.status !== TransferStatus.Failed\n && this.#transferState.status !== TransferStatus.Aborted\n && this.#transferState.status !== TransferStatus.Initialized\n && this.#transferState.status !== TransferStatus.Paused)\n throw new TransferUploadError(`Transfer is in ${TransferStatus[this.#transferState!.status]} state and cannot be canceled`);\n }\n\n private async cancelApiTransfer(abortSignal?: AbortSignal): Promise<void> {\n try {\n const request: CancelTransferRequest = {\n transferid: this.#transferMetadata!.transferId,\n transferkey: this.#transferMetadata!.transferKey,\n };\n\n await this.#apiClient.cancelTransfer(request, abortSignal);\n }\n catch (error) {\n throw new TransferUploadError(`Error canceling transfer through the API`, { cause: error as Error });\n }\n }\n\n addEventListener(eventName: TransferUploadEvent.TransferRun | TransferUploadEvent.TransferPauseRequested | TransferUploadEvent.TransferPaused | TransferUploadEvent.TransferAbortRequested | TransferUploadEvent.TransferAborted | TransferUploadEvent.TransferCancelRequested | TransferUploadEvent.TransferCanceled | TransferUploadEvent.TransferFailed, handler: () => void): void\n addEventListener(eventName: TransferUploadEvent.FileUploadStarted | TransferUploadEvent.FileUploadCompleted, handler: (event: FileUploadEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileUploadFailed, handler: (event: FileUploadFailedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadProgressed, handler: (event: FileChunkUploadProgressedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadStarted, handler: (event: FileChunkUploadEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadCompleted, handler: (event: FileChunkUploadCompletedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadCompletedPartially, handler: (event: FileChunkUploadCompletedPartiallyEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadFailed, handler: (event: FileChunkUploadFailedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.TransferProgressed, handler: (event: TransferUploadProgressedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.TransferCompleted, handler: (event: TransferUploadCompletedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.TransferUploadModeChosen, handler: (event: TransferUploadModeChosenEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.TransferMetadataDetermined, handler: (event: TransferMetadataDeterminedEventArgs) => void): void\n addEventListener(eventName: string, handler: (arg?: any) => void): void\n addEventListener(eventName: string, handler: (arg?: any) => void): void {\n this.#eventsEngine.addEventListener(eventName, handler);\n }\n\n exportAsString(): string {\n const exportData = this.export();\n return JSON.stringify(exportData);\n }\n\n export(): TransferUploadExportData<T> {\n if (!this.#transferState?.files)\n 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\n\n return {\n transferMetadata: this.getTransferMetadataExportValue(),\n info: this.#info,\n state: this.#transferState.export(),\n };\n }\n\n private getTransferMetadataExportValue(): TransferUploadExportDataMetadata | undefined {\n if (!this.#transferMetadata)\n return undefined;\n\n const { encryptionData, ...rest } = this.#transferMetadata;\n\n return {\n ...rest,\n encryptionData: !encryptionData ? undefined : {\n ivHex: uint8ArrayToHex(encryptionData.iv),\n keyHex: uint8ArrayToHex(encryptionData.key),\n },\n };\n }\n\n static recreate<T extends FileDetails>(transferExportData: TransferUploadExportData<T>, config: TransferUploadConfig, chunkStreamProviderFactory: UploaderChunkStreamProviderFactory<T>, apiClient: ApiClient, fileServerClientFactory: FileServerClientFactory, eventsEngine: EventsEngine, optimizer: UploadOptimizer, cryptography: CryptographyProvider): TransferUpload<T> {\n try {\n TransferUpload.validateRecreateParams(transferExportData);\n\n const transfer = new TransferUpload<T>(chunkStreamProviderFactory, apiClient, fileServerClientFactory, eventsEngine, transferExportData.info, config, optimizer, cryptography);\n\n transfer.#transferMetadata = this.recreateTransferMetadata(transferExportData.transferMetadata);\n transfer.#transferState = new TransferUploadState(transferExportData.info.files, eventsEngine, config.currentRatesTimespanInMs, config.progressEventThrottlingInMs, transferExportData.state);\n\n return transfer;\n }\n catch (error) {\n if (error instanceof TransferUploadError)\n throw error;\n else\n throw new TransferUploadError(`Unhandled error occured. See 'cause' for more details`, { cause: error as Error });\n }\n }\n\n private static recreateTransferMetadata(transferMetadata?: TransferUploadExportDataMetadata): TransferUploadMetadata | undefined {\n if (!transferMetadata)\n return undefined;\n\n const { encryptionData, ...rest } = transferMetadata;\n\n return {\n ...rest,\n encryptionData: !encryptionData ? undefined : {\n iv: hexToUint8Array(encryptionData.ivHex),\n key: hexToUint8Array(encryptionData.keyHex),\n },\n };\n }\n\n private static validateRecreateParams<T extends FileDetails>(transferExportData: TransferUploadExportData<T>) {\n if (!transferExportData.info)\n throw new TransferUploadError(`Info must be defined`);\n\n if (!transferExportData.state)\n throw new TransferUploadError(`State must be defined`);\n\n if (transferExportData.transferMetadata && (!transferExportData.transferMetadata.transferId || !transferExportData.transferMetadata.transferKey || !transferExportData.transferMetadata.transferFileServerUrl))\n throw new TransferUploadError(`Not all transfer metadata properties are defined`);\n\n if (transferExportData.transferMetadata?.encryptionData) {\n if (transferExportData.transferMetadata.encryptionData.ivHex.length !== 32)\n throw new TransferUploadError(`Encryption IV must be 16 bytes long`);\n if (transferExportData.transferMetadata.encryptionData.keyHex.length !== 64)\n throw new TransferUploadError(`Encryption key must be 32 bytes long`);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"transferUpload.js","sourceRoot":"","sources":["../../../src/uploader/transferUpload.ts"],"names":[],"mappings":"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","sourcesContent":["import sleep from 'abortable-sleep';\n\nimport ApiError from '../utils/api/apiError.js';\nimport FsError from '../utils/fileSystem/fsError.js';\nimport TransferUploadState from \"./state/transferUploadState.js\";\nimport TransferUploadError from \"./transferUploadError.js\";\nimport TransferStatus from \"../utils/types/transferStatus.js\";\nimport TransferUploadEvent from './transferUploadEvent.js';\nimport ChunksIterator from './chunksIterator/chunksIterator.js';\nimport mergeAbortAndPauseSignals from '../utils/mergeAbortAndPauseSignals.js';\nimport ApiFilemail449Error from '../utils/api/apiFilemail449Error.js';\nimport { promiseAllSettled } from '../utils/promiseAll.js';\nimport { concatUint8Arrays, hexToUint8Array, uint8ArrayToHex } from '../utils/uint8ArrayUtils.js';\n\nimport type ApiClient from \"../utils/api/apiClient.js\";\nimport type { InitializeTransferRequest } from \"../utils/api/dtos/initializeTransferRequest.js\";\nimport type SendFileChunkRequest from '../utils/api/dtos/sendFileChunkRequest.js';\nimport type FileServerClientFactory from '../utils/api/fileServerClientFactory.js';\nimport type FileDetails from \"../utils/fileSystem/fileDetails.js\";\nimport type TransferUploadMetadata from \"./export/transferUploadMetadata.js\";\nimport type TransferUploadInfo from \"./options/transferUploadInfo.js\";\nimport type { TransferUploadAppendInfo } from './options/transferUploadAppendInfo.js';\nimport type ResetTransferRequest from '../utils/api/dtos/resetTransferRequest.js';\nimport type EventsEngine from '../utils/events/eventsEngine.js';\nimport type FileChunkUploadEventArgs from './eventArgs/fileChunkUploadEventArgs.js';\nimport type FileChunkUploadFailedEventArgs from './eventArgs/fileChunkUploadFailedEventArgs.js';\nimport type ChunkProgressEvent from '../utils/events/chunkProgressEvent.js';\nimport type FinalizeTransferRequest from '../utils/api/dtos/finalizeTransferRequest.js';\nimport type FileUploadEventArgs from './eventArgs/fileUploadEventArgs.js';\nimport type TransferUploadCompletedEventArgs from './eventArgs/transferUploadCompletedEventArgs.js';\nimport type CancelTransferRequest from '../utils/api/dtos/cancelTransferRequest.js';\nimport type ConcurrencyReleaser from \"../utils/concurrencyController/concurrencyReleaser.js\";\nimport type FileUploadFailedEventArgs from './eventArgs/fileUploadFailedEventArgs.js';\nimport type TransferUploadProgressedEventArgs from './eventArgs/transferUploadProgressedEventArgs.js';\nimport type FileChunkUploadProgressedEventArgs from './eventArgs/fileChunkUploadProgressedEventArgs.js';\nimport type UploaderChunkStreamProviderFactory from './chunkStreamProviderFactory/uploaderChunkStreamProviderFactory.js';\nimport type TransferUploadConfig from './options/transferUploadConfig.js';\nimport type { PauseSignal } from './pauseController.js';\nimport type InitializeTransferResponse from '../utils/api/dtos/initializeTransferResponse.js';\nimport type { InitializeTransferResponseUdpData } from '../utils/api/dtos/initializeTransferResponse.js';\nimport type TransferUploadModeChosenEventArgs from './eventArgs/transferUploadModeChosenEventArgs.js';\nimport type HandshakeRequest from './api/dtos/handshakeRequest.js';\nimport type ChunkStreamProvider from '../utils/fileSystem/chunkStreamProvider.js';\nimport type SendChunkRequest from './api/dtos/sendChunkRequest.js';\nimport type UploadOptimizer from './optimizer/uploadOptimizer.js';\nimport type FileChunkUploadCompletedPartiallyEventArgs from './eventArgs/fileChunkUploadCompletedPartiallyEventArgs.js';\nimport type FileChunkUploadCompletedEventArgs from './eventArgs/fileChunkUploadCompletedEventArgs.js';\nimport type TransferMetadataDeterminedEventArgs from './eventArgs/transferMetadataDeterminedEventArgs.js';\nimport type CryptographyProvider from '../utils/crypto/cryptographyProvider.js';\nimport type { TransferUploadExportData, TransferUploadExportDataMetadata } from './export/transferUploadExportData.js';\n\nexport default class TransferUpload<T extends FileDetails> {\n #totalSizeInBytes: number;\n\n #chunkStreamProviderFactory: UploaderChunkStreamProviderFactory<T>;\n #apiClient: ApiClient;\n #fileServerClientFactory: FileServerClientFactory;\n #eventsEngine: EventsEngine;\n #info: TransferUploadInfo<T> | TransferUploadAppendInfo<T>;\n #config: TransferUploadConfig;\n #optimizer: UploadOptimizer;\n #cryptography: CryptographyProvider;\n\n #transferState?: TransferUploadState;\n #transferMetadata?: TransferUploadMetadata;\n #transferDownloadUrl?: string;\n\n #pauseSignal: PauseSignal | undefined;\n #abortSignal: AbortSignal | undefined;\n #mergedPauseAndAbortSignal: AbortSignal | undefined;\n\n pauseEventListener: (() => void) | undefined;\n abortEventListener: (() => void) | undefined;\n\n #isUdpUploadMode: boolean;\n #serverLatencyInMs: number | undefined;\n\n #isRunMethodRunning = false;\n\n get status(): TransferStatus {\n return this.#transferState?.status ?? TransferStatus.Initialized;\n }\n\n get completedFilesCount(): number {\n return this.#transferState?.completedFilesCount ?? 0;\n }\n\n get failedFilesCount(): number {\n return this.#transferState?.failedFilesCount ?? 0;\n }\n\n get uploadedBytesCount(): number {\n return this.#transferState?.uploadedBytesCount ?? 0;\n }\n\n get failedBytesCount(): number {\n return this.#transferState?.failedBytesCount ?? 0;\n }\n\n get progressInPercentage(): number {\n if (this.totalSizeInBytes === 0)\n return 0;\n\n return (this.uploadedBytesCount * 100) / this.totalSizeInBytes;\n }\n\n get files(): readonly Readonly<T>[] {\n return this.#info.files;\n }\n\n get totalSizeInBytes(): number {\n return this.#totalSizeInBytes;\n }\n\n get transferId(): string | undefined {\n return this.#transferMetadata?.transferId;\n }\n\n constructor(chunkStreamProviderFactory: UploaderChunkStreamProviderFactory<T>, apiClient: ApiClient, fileServerClientFactory: FileServerClientFactory, eventsEngine: EventsEngine, info: TransferUploadInfo<T> | TransferUploadAppendInfo<T>, config: TransferUploadConfig, optimizer: UploadOptimizer, cryptography: CryptographyProvider) {\n if (info.files.length === 0)\n throw new TransferUploadError(`Files can't be empty`);\n\n this.#totalSizeInBytes = info.files.reduce((partialSum, file) => partialSum + file.fileSizeInBytes, 0);\n this.#isUdpUploadMode = false;\n\n this.#chunkStreamProviderFactory = chunkStreamProviderFactory;\n this.#apiClient = apiClient;\n this.#fileServerClientFactory = fileServerClientFactory;\n this.#eventsEngine = eventsEngine;\n this.#info = info;\n this.#config = config;\n this.#optimizer = optimizer;\n this.#cryptography = cryptography;\n\n if (this.isUploadAppendInfo(this.#info))\n this.createTransferMetadataFromInfo(this.#info);\n }\n\n private isUploadAppend(): boolean {\n return this.isUploadAppendInfo(this.#info);\n }\n\n private isUploadAppendInfo(info: TransferUploadInfo<T> | TransferUploadAppendInfo<T>): info is TransferUploadAppendInfo<T> {\n return (info as TransferUploadAppendInfo<T>).transferKey !== undefined;\n }\n\n private createTransferMetadataFromInfo(info: TransferUploadAppendInfo<T>) {\n if (!this.isUploadAppendInfo(info))\n throw new TransferUploadError(`Options are not TransferUploadAppendOptions`);\n\n this.#transferDownloadUrl = info.transferDownloadUrl;\n\n this.#transferMetadata = {\n transferId: info.transferId,\n transferKey: info.transferKey,\n transferFileServerUrl: info.transferFileServerUrl,\n transferRegion: info.transferRegion,\n encryptionData: info.e2eeData,\n };\n }\n\n async run(transferPauseSignal: PauseSignal, transferAbortSignal: AbortSignal): Promise<void> {\n this.throwIfNotPossibleToRun(transferPauseSignal, transferAbortSignal);\n\n this.#isRunMethodRunning = true;\n\n try {\n this.#pauseSignal = transferPauseSignal;\n this.#abortSignal = transferAbortSignal;\n this.#mergedPauseAndAbortSignal = mergeAbortAndPauseSignals(transferPauseSignal, transferAbortSignal);\n\n if (!this.#transferState)\n this.#transferState = new TransferUploadState(this.files, this.#eventsEngine, this.#config.currentRatesTimespanInMs, this.#config.progressEventThrottlingInMs);\n else\n this.#transferState.recover();\n\n this.#transferState.transferRun();\n\n this.addPauseAndStopListeners();\n\n if (!this.#transferMetadata)\n await this.startApiTransferAndCreateMetadata();\n\n this.notifyMetadataDetermined();\n\n await this.pingServerAndChooseUploadMode();\n\n if (this.#isUdpUploadMode && !this.#transferMetadata!.udpData!.handshakeData)\n await this.serverUdpHandshake();\n\n this.#optimizer.start(this.#isUdpUploadMode, this.#serverLatencyInMs!);\n\n const ongoingChunkUploads = new Set<Promise<void>>();\n\n for (const file of this.files) {\n const fileStatus = this.#transferState.getFile(file.externalId);\n\n if (fileStatus.isCompleted)\n continue;\n\n const alreadySentChunks = this.#transferState.getChunksForFile(file.externalId);\n const chunksIterator = new ChunksIterator(alreadySentChunks, file.fileSizeInBytes, this.#optimizer);\n\n for (const chunk of chunksIterator.getChunksIterator()) {\n // eslint-disable-next-line no-await-in-loop\n const releaseSemaphore = await this.#optimizer.semaphoreAcquire();\n\n if (this.#optimizer.currentSleepTimeInMs >= 1)\n // eslint-disable-next-line no-await-in-loop\n await sleep(this.#optimizer.currentSleepTimeInMs, this.#mergedPauseAndAbortSignal);\n\n if (this.#transferState!.status !== TransferStatus.Running) {\n releaseSemaphore();\n break;\n }\n\n const chunkUploadPromise = this.sendChunkAndKeepUpdatingState(file, chunk.startPosition, chunk.sizeInBytes, releaseSemaphore);\n\n const trackedChunkUploadPromise = chunkUploadPromise.finally(() => {\n ongoingChunkUploads.delete(trackedChunkUploadPromise);\n });\n\n ongoingChunkUploads.add(trackedChunkUploadPromise);\n\n if (this.#transferState!.status !== TransferStatus.Running)\n break;\n }\n\n if (this.#transferState!.status !== TransferStatus.Running)\n break;\n }\n\n await promiseAllSettled(Array.from(ongoingChunkUploads));\n\n this.#optimizer.stop();\n\n if (this.#transferState.status === TransferStatus.Pausing)\n this.#transferState.transferPaused();\n else if (this.#transferState.status === TransferStatus.Aborting)\n this.#transferState.transferAborted();\n else if (this.uploadedBytesCount !== this.totalSizeInBytes)\n this.#transferState.transferFailed();\n else {\n await this.finalizeTransfer();\n this.#transferState.transferCompleted(this.#transferMetadata!, this.#transferDownloadUrl!);\n }\n }\n catch (error) {\n // 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\n if (!this.#transferState)\n this.#eventsEngine.emit(TransferUploadEvent.TransferFailed);\n else if (this.#transferState.status === TransferStatus.Pausing) {\n this.#transferState.transferPaused();\n return;\n }\n else if (this.#transferState.status === TransferStatus.Aborting) {\n this.#transferState.transferAborted();\n return;\n }\n else\n this.#transferState.transferFailed();\n\n if (error instanceof TransferUploadError)\n throw error;\n else\n throw new TransferUploadError(`Unhandled error occured. See 'cause' for more details`, { cause: error as Error });\n }\n finally {\n this.removePauseAndStopListeners();\n this.#optimizer.stop();\n this.#isRunMethodRunning = false;\n }\n }\n\n private notifyMetadataDetermined() {\n if (!this.#transferMetadata)\n return;\n\n const eventArgs: TransferMetadataDeterminedEventArgs = {\n transferId: this.#transferMetadata.transferId,\n fileServerUrl: this.#transferMetadata.transferFileServerUrl,\n region: this.#transferMetadata.transferRegion,\n };\n\n this.#eventsEngine.emit(TransferUploadEvent.TransferMetadataDetermined, eventArgs);\n }\n\n private async pingServerAndChooseUploadMode(): Promise<void> {\n try {\n if (this.#config.turnOffUdp)\n throw new Error(`UDP is turned off`);\n\n const udpData = this.#transferMetadata?.udpData;\n\n if (!udpData)\n throw new Error(`No UDP data is available`);\n\n const requestTimeout = this.#config.forceUdp ? 3 * 1000 : this.getPingTimeout(udpData.threshold);\n const retryDelay = 1000;\n\n const udpClient = this.#fileServerClientFactory.createFileServerUdpUploadClient(udpData.ip, udpData.port, requestTimeout, this.#mergedPauseAndAbortSignal, undefined, retryDelay);\n\n await udpClient.connect();\n\n const pingResult = await udpClient.ping();\n\n udpClient.close().catch(() => { /* discard */ });\n\n this.#serverLatencyInMs = pingResult.latencyInMs;\n this.#isUdpUploadMode = pingResult.latencyInMs >= udpData.threshold;\n\n const eventArgs: TransferUploadModeChosenEventArgs = { isUdpMode: this.#isUdpUploadMode, latency: pingResult.latencyInMs };\n this.#eventsEngine.emit(TransferUploadEvent.TransferUploadModeChosen, eventArgs);\n }\n catch (error) {\n this.#isUdpUploadMode = false;\n\n const eventArgs: TransferUploadModeChosenEventArgs = { isUdpMode: this.#isUdpUploadMode, error: error as Error };\n this.#eventsEngine.emit(TransferUploadEvent.TransferUploadModeChosen, eventArgs);\n }\n }\n\n private getPingTimeout(udpPingThreshold: number) {\n const pingTimeout = Math.min(3 * 1000, udpPingThreshold * 20);\n return Math.max(500, pingTimeout);\n }\n\n private async serverUdpHandshake(): Promise<void> {\n const transferMetadata = this.#transferMetadata!;\n const udpData = transferMetadata.udpData!;\n\n const requestTimeout = this.getHandshakeTimeout();\n const retryDelay = 1000;\n\n const udpClient = this.#fileServerClientFactory.createFileServerUdpUploadClient(udpData.ip, udpData.port, requestTimeout, this.#mergedPauseAndAbortSignal, undefined, retryDelay);\n\n await udpClient.connect();\n\n const handshakeRequest: HandshakeRequest = { transferId: transferMetadata.transferId, transferKey: transferMetadata.transferKey };\n const handshakeResponse = await udpClient.handshake(handshakeRequest);\n\n udpClient.close().catch(() => { /* discard */ });\n\n this.#transferMetadata!.udpData!.handshakeData = handshakeResponse;\n }\n\n private getHandshakeTimeout() {\n const timeout = Math.min(this.#serverLatencyInMs! * 30, 30 * 1000);\n return Math.max(2000, timeout);\n }\n\n private async sendChunkAndKeepUpdatingState(file: T, chunkStartPosition: number, chunkSizeInBytes: number, releaseSemaphore: ConcurrencyReleaser): Promise<void> {\n let uploadedBytesCount = 0;\n\n try {\n this.#transferState!.chunkUploadStarted(file.externalId, chunkStartPosition, chunkSizeInBytes);\n\n const chunkStreamProvider = this.#chunkStreamProviderFactory.createChunkStreamProvider(file, chunkStartPosition, chunkSizeInBytes, this.#transferMetadata?.encryptionData);\n\n const progressEventHandler = (eventArgs: ChunkProgressEvent) => {\n uploadedBytesCount += eventArgs.transferredBytesSinceLastEvent;\n this.#transferState!.chunkUploadProgressed(file.externalId, chunkStartPosition, chunkSizeInBytes, eventArgs);\n };\n\n const response = await this.sendChunk(file, chunkStreamProvider, progressEventHandler);\n\n const latencyInMsIfUdp = this.#isUdpUploadMode ? (response as { latencyInMs: number }).latencyInMs : undefined;\n\n if (uploadedBytesCount === chunkSizeInBytes)\n this.#transferState!.chunkUploadCompleted(file.externalId, chunkStartPosition, chunkSizeInBytes, latencyInMsIfUdp);\n else\n this.#transferState!.chunkUploadCompletedPartially(file.externalId, chunkStartPosition, chunkSizeInBytes, uploadedBytesCount, this.#pauseSignal!.paused, latencyInMsIfUdp);\n }\n catch (error) {\n const chunkError = error as Error;\n\n const isTcpPausingError = chunkError.cause !== undefined\n && chunkError.cause instanceof ApiFilemail449Error\n && chunkError.cause.message === `Wrong md5 hash`\n && this.#pauseSignal?.paused === true;\n\n if (isTcpPausingError)\n this.#transferState!.chunkUploadCompletedPartially(file.externalId, chunkStartPosition, chunkSizeInBytes, uploadedBytesCount, this.#pauseSignal!.paused);\n else {\n const failedReason = this.getChunkFailedReason(error);\n this.#transferState!.chunkUploadFailed(file.externalId, chunkStartPosition, chunkSizeInBytes, uploadedBytesCount, failedReason, error as Error);\n }\n }\n finally {\n releaseSemaphore();\n }\n }\n\n private async sendChunk(file: T, chunkStreamProvider: ChunkStreamProvider, progressEventHandler: (eventArgs: ChunkProgressEvent) => void): Promise<{ latencyInMs: number } | void> {\n if (this.#isUdpUploadMode)\n return await this.sendChunkUsingUdp(file, chunkStreamProvider, progressEventHandler);\n\n return await this.sendChunkUsingTcp(file, chunkStreamProvider, progressEventHandler);\n }\n\n private async sendChunkUsingUdp(file: T, chunkStreamProvider: ChunkStreamProvider, progressEventHandler: (eventArgs: ChunkProgressEvent) => void): Promise<{ latencyInMs: number }> {\n const transferMetadata = this.#transferMetadata!;\n const udpData = transferMetadata.udpData!;\n\n const udpClient = this.#fileServerClientFactory.createFileServerUdpUploadClient(udpData.ip, udpData.port, this.#optimizer.currentRequestTimeoutInMs, this.#mergedPauseAndAbortSignal, 0);\n\n const sendChunkRequest: SendChunkRequest = {\n sessionGuid: this.#transferMetadata!.udpData!.handshakeData!.sessionGuid,\n aesKey: this.#transferMetadata!.udpData!.handshakeData!.aesKey,\n chunkStartPosition: chunkStreamProvider.chunkStartPosition,\n fileSizeInBytes: file.fileSizeInBytes,\n fileDestinationPathInTransfer: file.fileDestinationPathInTransfer,\n fileName: file.fileName,\n };\n\n await udpClient.connect();\n\n const result = await udpClient.sendChunk(sendChunkRequest, chunkStreamProvider);\n\n udpClient.close().catch(() => { /* discard */ });\n\n const chunkProgressEventArgs: ChunkProgressEvent = { transferredBytesTotal: chunkStreamProvider.chunkLengthInBytes, transferredBytesSinceLastEvent: chunkStreamProvider.chunkLengthInBytes };\n progressEventHandler(chunkProgressEventArgs);\n\n return result;\n }\n\n private async sendChunkUsingTcp(file: T, chunkStreamProvider: ChunkStreamProvider, progressEventHandler: (eventArgs: ChunkProgressEvent) => void): Promise<void> {\n const request: SendFileChunkRequest = {\n chunkLengthInBytes: chunkStreamProvider.chunkLengthInBytes,\n chunkStartPosition: chunkStreamProvider.chunkStartPosition,\n };\n\n const fileServerClient = this.#fileServerClientFactory.createFileServerTcpUploadClient(this.#transferMetadata!.transferFileServerUrl, this.#transferMetadata!.transferId, this.#transferMetadata!.transferKey, file.fileName, file.fileDestinationPathInTransfer, file.fileSizeInBytes);\n\n const ongoingRequestPromise = fileServerClient.sendFileChunk(request, chunkStreamProvider, this.#pauseSignal!, this.#abortSignal!);\n\n fileServerClient.addEventListener(`progress`, progressEventHandler);\n\n await ongoingRequestPromise;\n }\n\n private getChunkFailedReason(error: unknown) {\n if (error instanceof FsError)\n return `Can't read file. ${error.message}`;\n\n if (error instanceof ApiError)\n return error.cause?.message ? `${error.message}. ${error.cause.message}` : error.message;\n\n return (error as Error)?.message;\n }\n\n private throwIfNotPossibleToRun(pauseSignal: PauseSignal, abortSignal: AbortSignal) {\n if (this.#isRunMethodRunning)\n throw new TransferUploadError(`This transfer is running and cannot be run`);\n\n if (this.#transferState\n && this.#transferState.status !== TransferStatus.Failed\n && this.#transferState.status !== TransferStatus.Aborted\n && this.#transferState.status !== TransferStatus.Initialized\n && this.#transferState.status !== TransferStatus.Paused)\n throw new TransferUploadError(`Transfer is in ${TransferStatus[this.#transferState!.status]} state and cannot be run`);\n\n if (this.files.length === 0)\n throw new TransferUploadError(`There are no files passed to the transfer`);\n\n if (pauseSignal.paused)\n throw new TransferUploadError(`Can't run transfer with already paused PauseController`);\n\n if (abortSignal.aborted)\n throw new TransferUploadError(`Can't run transfer with already aborted AbortController`);\n }\n\n private addPauseAndStopListeners() {\n this.pauseEventListener = () => {\n if (this.#transferState!.status !== TransferStatus.Running)\n throw new TransferUploadError(`Transfer is in ${TransferStatus[this.#transferState!.status]} state and cannot be paused`);\n\n this.#transferState!.transferPauseRequested();\n };\n\n this.abortEventListener = () => {\n if (this.#transferState!.status !== TransferStatus.Running)\n throw new TransferUploadError(`Transfer is in ${TransferStatus[this.#transferState!.status]} state and cannot be stopped`);\n\n this.#transferState!.transferAbortRequested();\n };\n\n this.#pauseSignal!.addEventListener(`pause`, this.pauseEventListener);\n this.#abortSignal!.addEventListener(`abort`, this.abortEventListener);\n }\n\n private removePauseAndStopListeners() {\n this.#pauseSignal!.removeEventListener(`pause`, this.pauseEventListener!);\n this.#abortSignal!.removeEventListener(`abort`, this.abortEventListener!);\n }\n\n private async startApiTransferAndCreateMetadata() {\n if (this.isUploadAppendInfo(this.#info))\n throw new TransferUploadError(`Options are not TransferUploadOptions`);\n\n try {\n const encryptionDataAndIvSaltHex = await this.generateEncryptionDataAndIvSaltHmacHex(this.#info.e2eeKey);\n\n const request: InitializeTransferRequest = {\n e2ee: Boolean(encryptionDataAndIvSaltHex),\n e2ee_keyhash: encryptionDataAndIvSaltHex?.ivSaltHmacHex,\n transfersize: this.totalSizeInBytes,\n to: this.#info.to,\n from: this.#info.from,\n subject: this.#info.subject,\n message: this.#info.message,\n notify: this.#info.notify,\n confirmation: this.#info.confirmation,\n days: this.#info.days,\n password: this.#info.uploadPassword,\n companyid: this.#info.companyId,\n incominglogintoken: this.#info.incomingLoginToken,\n incomingpageid: this.#info.incomingPageId,\n filerequestid: this.#info.fileRequestId,\n filerequestshareid: this.#info.fileRequestShareId,\n customfields: this.#info.customFields,\n };\n\n const response = await this.#apiClient.initializeTransfer(request, this.#mergedPauseAndAbortSignal);\n\n this.#transferMetadata = {\n transferId: response.transferId,\n transferKey: response.transferKey,\n transferFileServerUrl: response.transferUrl,\n transferRegion: response.transferRegion,\n encryptionData: encryptionDataAndIvSaltHex?.encryptionData,\n udpData: this.getResponseOrForcedUdpData(response),\n };\n }\n catch (error) {\n throw new TransferUploadError(`Error initializing transfer through the API`, { cause: error as Error });\n }\n }\n\n private async generateEncryptionDataAndIvSaltHmacHex(e2eeKey?: string): Promise<{ encryptionData: { iv: Uint8Array, key: Uint8Array }, ivSaltHmacHex: string, salt: Uint8Array, hmac: Uint8Array } | undefined> {\n if (!e2eeKey)\n return undefined;\n\n const salt = this.#cryptography.generateRandomBytes(16);\n const key = await this.#cryptography.deriveKey(e2eeKey, salt);\n const hmac = await this.#cryptography.generateHmac(key);\n const iv = this.#cryptography.generateRandomBytes(16);\n\n const ivSaltHmac = concatUint8Arrays([iv, salt, hmac]);\n const ivSaltHmacHex = uint8ArrayToHex(ivSaltHmac);\n\n return {\n encryptionData: { iv, key },\n hmac,\n salt,\n ivSaltHmacHex,\n };\n }\n\n private getResponseOrForcedUdpData(response: InitializeTransferResponse): InitializeTransferResponseUdpData | undefined {\n if (!this.#config.forceUdp || !response.udp)\n return response.udp;\n\n return {\n ...response.udp,\n threshold: 0,\n };\n }\n\n private async finalizeTransfer(): Promise<void> {\n this.#eventsEngine.emit(TransferUploadEvent.TransferFinalizing);\n\n if (this.isUploadAppend())\n await this.resetApiTransfer();\n else\n await this.finalizeApiTransfer();\n }\n\n private async resetApiTransfer(): Promise<void> {\n try {\n const request: ResetTransferRequest = {\n transferid: this.#transferMetadata!.transferId,\n };\n\n await this.#apiClient.resetTransfer(request, this.#mergedPauseAndAbortSignal);\n }\n catch (error) {\n throw new TransferUploadError(`Error resetting transfer through the API`, { cause: error as Error });\n }\n }\n\n private async finalizeApiTransfer(): Promise<void> {\n try {\n const request: FinalizeTransferRequest = {\n transferid: this.#transferMetadata!.transferId,\n transferkey: this.#transferMetadata!.transferKey,\n protocol: this.#isUdpUploadMode ? `udp` : `tcp`,\n };\n\n const response = await this.#apiClient.finalizeTransfer(request, this.#mergedPauseAndAbortSignal);\n\n this.#transferDownloadUrl = response.downloadUrl;\n }\n catch (error) {\n throw new TransferUploadError(`Error finalizing transfer through the API`, { cause: error as Error });\n }\n }\n\n async cancel(abortSignal?: AbortSignal): Promise<void> {\n try {\n const isTransferApiInitialized = Boolean(this.#transferState) && Boolean(this.#transferMetadata);\n\n if (!isTransferApiInitialized) {\n this.emitCancelEvents();\n return;\n }\n\n this.throwIfInWrongStateToCancel();\n\n this.#transferState!.transferCancelRequested();\n\n if (this.isUploadAppend()) {\n // There is no possibility to cancel transfer upload append on API for now\n }\n else {\n try {\n await this.cancelApiTransfer(abortSignal);\n }\n catch {\n // If API cancel fails we still finalize local transfer state as canceled to avoid hanging in Canceling.\n }\n }\n\n this.#transferState!.transferCanceled();\n }\n catch (error) {\n if (error instanceof TransferUploadError)\n throw error;\n else\n throw new TransferUploadError(`Unhandled error occured. See 'cause' for more details`, { cause: error as Error });\n }\n }\n\n private emitCancelEvents() {\n this.#eventsEngine.emit(TransferUploadEvent.TransferCancelRequested);\n this.#eventsEngine.emit(TransferUploadEvent.TransferCanceled);\n }\n\n private throwIfInWrongStateToCancel() {\n if (!this.#transferState)\n return;\n\n if (this.#transferState.status !== TransferStatus.Failed\n && this.#transferState.status !== TransferStatus.Aborted\n && this.#transferState.status !== TransferStatus.Initialized\n && this.#transferState.status !== TransferStatus.Paused)\n throw new TransferUploadError(`Transfer is in ${TransferStatus[this.#transferState!.status]} state and cannot be canceled`);\n }\n\n private async cancelApiTransfer(abortSignal?: AbortSignal): Promise<void> {\n try {\n const request: CancelTransferRequest = {\n transferid: this.#transferMetadata!.transferId,\n transferkey: this.#transferMetadata!.transferKey,\n };\n\n await this.#apiClient.cancelTransfer(request, abortSignal);\n }\n catch (error) {\n throw new TransferUploadError(`Error canceling transfer through the API`, { cause: error as Error });\n }\n }\n\n addEventListener(eventName: TransferUploadEvent.TransferRun | TransferUploadEvent.TransferPauseRequested | TransferUploadEvent.TransferPaused | TransferUploadEvent.TransferAbortRequested | TransferUploadEvent.TransferAborted | TransferUploadEvent.TransferCancelRequested | TransferUploadEvent.TransferCanceled | TransferUploadEvent.TransferFailed, handler: () => void): void\n addEventListener(eventName: TransferUploadEvent.FileUploadStarted | TransferUploadEvent.FileUploadCompleted, handler: (event: FileUploadEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileUploadFailed, handler: (event: FileUploadFailedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadProgressed, handler: (event: FileChunkUploadProgressedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadStarted, handler: (event: FileChunkUploadEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadCompleted, handler: (event: FileChunkUploadCompletedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadCompletedPartially, handler: (event: FileChunkUploadCompletedPartiallyEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.FileChunkUploadFailed, handler: (event: FileChunkUploadFailedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.TransferProgressed, handler: (event: TransferUploadProgressedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.TransferCompleted, handler: (event: TransferUploadCompletedEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.TransferUploadModeChosen, handler: (event: TransferUploadModeChosenEventArgs) => void): void\n addEventListener(eventName: TransferUploadEvent.TransferMetadataDetermined, handler: (event: TransferMetadataDeterminedEventArgs) => void): void\n addEventListener(eventName: string, handler: (arg?: any) => void): void\n addEventListener(eventName: string, handler: (arg?: any) => void): void {\n this.#eventsEngine.addEventListener(eventName, handler);\n }\n\n exportAsString(): string {\n const exportData = this.export();\n return JSON.stringify(exportData);\n }\n\n export(): TransferUploadExportData<T> {\n if (!this.#transferState?.files)\n 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\n\n return {\n transferMetadata: this.getTransferMetadataExportValue(),\n info: this.#info,\n state: this.#transferState.export(),\n };\n }\n\n private getTransferMetadataExportValue(): TransferUploadExportDataMetadata | undefined {\n if (!this.#transferMetadata)\n return undefined;\n\n const { encryptionData, ...rest } = this.#transferMetadata;\n\n return {\n ...rest,\n encryptionData: !encryptionData ? undefined : {\n ivHex: uint8ArrayToHex(encryptionData.iv),\n keyHex: uint8ArrayToHex(encryptionData.key),\n },\n };\n }\n\n static recreate<T extends FileDetails>(transferExportData: TransferUploadExportData<T>, config: TransferUploadConfig, chunkStreamProviderFactory: UploaderChunkStreamProviderFactory<T>, apiClient: ApiClient, fileServerClientFactory: FileServerClientFactory, eventsEngine: EventsEngine, optimizer: UploadOptimizer, cryptography: CryptographyProvider): TransferUpload<T> {\n try {\n TransferUpload.validateRecreateParams(transferExportData);\n\n const transfer = new TransferUpload<T>(chunkStreamProviderFactory, apiClient, fileServerClientFactory, eventsEngine, transferExportData.info, config, optimizer, cryptography);\n\n transfer.#transferMetadata = this.recreateTransferMetadata(transferExportData.transferMetadata);\n transfer.#transferState = new TransferUploadState(transferExportData.info.files, eventsEngine, config.currentRatesTimespanInMs, config.progressEventThrottlingInMs, transferExportData.state);\n\n return transfer;\n }\n catch (error) {\n if (error instanceof TransferUploadError)\n throw error;\n else\n throw new TransferUploadError(`Unhandled error occured. See 'cause' for more details`, { cause: error as Error });\n }\n }\n\n private static recreateTransferMetadata(transferMetadata?: TransferUploadExportDataMetadata): TransferUploadMetadata | undefined {\n if (!transferMetadata)\n return undefined;\n\n const { encryptionData, ...rest } = transferMetadata;\n\n return {\n ...rest,\n encryptionData: !encryptionData ? undefined : {\n iv: hexToUint8Array(encryptionData.ivHex),\n key: hexToUint8Array(encryptionData.keyHex),\n },\n };\n }\n\n private static validateRecreateParams<T extends FileDetails>(transferExportData: TransferUploadExportData<T>) {\n if (!transferExportData.info)\n throw new TransferUploadError(`Info must be defined`);\n\n if (!transferExportData.state)\n throw new TransferUploadError(`State must be defined`);\n\n if (transferExportData.transferMetadata && (!transferExportData.transferMetadata.transferId || !transferExportData.transferMetadata.transferKey || !transferExportData.transferMetadata.transferFileServerUrl))\n throw new TransferUploadError(`Not all transfer metadata properties are defined`);\n\n if (transferExportData.transferMetadata?.encryptionData) {\n if (transferExportData.transferMetadata.encryptionData.ivHex.length !== 32)\n throw new TransferUploadError(`Encryption IV must be 16 bytes long`);\n if (transferExportData.transferMetadata.encryptionData.keyHex.length !== 64)\n throw new TransferUploadError(`Encryption key must be 32 bytes long`);\n }\n }\n}\n"]}
@@ -19,6 +19,8 @@ export default class NodeChunkStreamProvider implements ChunkStreamProvider {
19
19
  decipherStream?: Writable;
20
20
  }>;
21
21
  release(): Promise<void>;
22
+ private registerPauseListener;
23
+ private cleanupPauseListener;
22
24
  private closeHandle;
23
25
  private destroyStream;
24
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"nodeChunkStreamProvider.d.ts","sourceRoot":"","sources":["../../../../../src/utils/fileSystem/node/nodeChunkStreamProvider.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAMvC,OAAO,KAAK,mBAAmB,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACxE,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AAEnF,MAAM,CAAC,OAAO,OAAO,uBAAwB,YAAW,mBAAmB;;IACvE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAapC,IAAI,UAAU,IAAI,OAAO,CAYxB;gBAEW,YAAY,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,cAAc,EAAE,iCAAiC,GAAG,SAAS;IAavJ,OAAO,CAAC,+BAA+B;IAUjC,cAAc,CAAC,MAAM,EAAE,KAAK,GAAG,QAAQ,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBpF,kBAAkB,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC;IAyC5E,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B,OAAO,CAAC,mBAAmB;IAOrB,mBAAmB,IAAI,OAAO,CAAC;QAAE,UAAU,EAAE,QAAQ,CAAC;QAAC,cAAc,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;IA8BnF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB9B,OAAO,CAAC,WAAW,CAQjB;IAEF,OAAO,CAAC,aAAa,CAQnB;CACL"}
1
+ {"version":3,"file":"nodeChunkStreamProvider.d.ts","sourceRoot":"","sources":["../../../../../src/utils/fileSystem/node/nodeChunkStreamProvider.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAMvC,OAAO,KAAK,mBAAmB,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACxE,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AAEnF,MAAM,CAAC,OAAO,OAAO,uBAAwB,YAAW,mBAAmB;;IACvE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAepC,IAAI,UAAU,IAAI,OAAO,CAYxB;gBAEW,YAAY,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,cAAc,EAAE,iCAAiC,GAAG,SAAS;IAavJ,OAAO,CAAC,+BAA+B;IAUjC,cAAc,CAAC,MAAM,EAAE,KAAK,GAAG,QAAQ,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBpF,kBAAkB,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC;IAqC5E,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B,OAAO,CAAC,mBAAmB;IAOrB,mBAAmB,IAAI,OAAO,CAAC;QAAE,UAAU,EAAE,QAAQ,CAAC;QAAC,cAAc,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;IA8BnF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB9B,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,WAAW,CAQjB;IAEF,OAAO,CAAC,aAAa,CAQnB;CACL"}
@@ -18,6 +18,8 @@ export default class NodeChunkStreamProvider {
18
18
  #fileWriteHandle = null;
19
19
  #fileWriteStream = null;
20
20
  #fileWriteDecipherStream = null;
21
+ #pauseSignal;
22
+ #pauseListener;
21
23
  get isReleased() {
22
24
  const isFileReadHandleReleased = this.#fileReadHandle === null;
23
25
  const isFileReadStreamReleased = this.#fileReadStream?.destroyed ?? true;
@@ -78,11 +80,7 @@ export default class NodeChunkStreamProvider {
78
80
  }
79
81
  else
80
82
  this.#fileReadStream.pipe(this.#fileReadPassThroughStream);
81
- pauseSignal?.addEventListener(`pause`, () => {
82
- this.#fileReadStream?.destroy();
83
- this.#fileReadCipherStream?.destroy();
84
- this.#fileReadPassThroughStream?.end();
85
- });
83
+ this.registerPauseListener(pauseSignal);
86
84
  return ReadableStream.from(this.#fileReadPassThroughStream);
87
85
  }
88
86
  catch (error) {
@@ -119,6 +117,7 @@ export default class NodeChunkStreamProvider {
119
117
  }
120
118
  }
121
119
  async release() {
120
+ this.cleanupPauseListener();
122
121
  await Promise.allSettled([
123
122
  this.closeHandle(this.#fileReadHandle),
124
123
  this.destroyStream(this.#fileReadStream),
@@ -136,6 +135,25 @@ export default class NodeChunkStreamProvider {
136
135
  this.#fileWriteStream = null;
137
136
  this.#fileWriteDecipherStream = null;
138
137
  }
138
+ registerPauseListener(pauseSignal) {
139
+ this.cleanupPauseListener();
140
+ if (!pauseSignal)
141
+ return;
142
+ this.#pauseSignal = pauseSignal;
143
+ this.#pauseListener = () => {
144
+ this.#fileReadStream?.destroy();
145
+ this.#fileReadCipherStream?.destroy();
146
+ this.#fileReadPassThroughStream?.end();
147
+ };
148
+ this.#pauseSignal.addEventListener(`pause`, this.#pauseListener);
149
+ }
150
+ cleanupPauseListener() {
151
+ if (!this.#pauseSignal || !this.#pauseListener)
152
+ return;
153
+ this.#pauseSignal.removeEventListener(`pause`, this.#pauseListener);
154
+ this.#pauseSignal = undefined;
155
+ this.#pauseListener = undefined;
156
+ }
139
157
  closeHandle = async (handle) => {
140
158
  if (!handle)
141
159
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"nodeChunkStreamProvider.js","sourceRoot":"","sources":["../../../../../src/utils/fileSystem/node/nodeChunkStreamProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs/promises\";\nimport { ReadStream, WriteStream, constants as fsConsts } from \"fs\";\nimport crypto from \"crypto\";\nimport { pipeline, finished } from \"stream/promises\";\nimport { PassThrough, Transform } from \"stream\";\n\nimport { ReadableStream } from \"stream/web\";\nimport type { Writable } from \"stream\";\n\nimport { createCipher, createDecipher } from 'aes-ctr-concurrent';\n\nimport FsError from '../fsError.js';\n\nimport type ChunkStreamProvider from \"../chunkStreamProvider.js\";\nimport type { PauseSignal } from \"../../../uploader/pauseController.js\";\nimport type { ChunkStreamProviderEncryptionData } from \"../chunkStreamProvider.js\";\n\nexport default class NodeChunkStreamProvider implements ChunkStreamProvider {\n readonly chunkStartPosition: number;\n readonly chunkLengthInBytes: number;\n\n readonly #encryptionData?: ChunkStreamProviderEncryptionData;\n readonly #fullFilePath: string;\n\n #fileReadHandle: fs.FileHandle | null = null;\n #fileReadStream: ReadStream | null = null;\n #fileReadCipherStream: Transform | null = null;\n #fileReadPassThroughStream: PassThrough | null = null;\n #fileWriteHandle: fs.FileHandle | null = null;\n #fileWriteStream: WriteStream | null = null;\n #fileWriteDecipherStream: Transform | null = null;\n\n get isReleased(): boolean {\n const isFileReadHandleReleased = this.#fileReadHandle === null;\n const isFileReadStreamReleased = this.#fileReadStream?.destroyed ?? true;\n const isFileReadCipherStreamReleased = this.#fileReadCipherStream?.destroyed ?? true;\n const isFileReadPassThroughStreamReleased = this.#fileReadPassThroughStream?.destroyed ?? true;\n const isFileWriteHandleReleased = this.#fileWriteHandle === null;\n const isFileWriteStreamReleased = this.#fileWriteStream?.destroyed ?? true;\n const isFileWriteDecipherStreamReleased = this.#fileWriteDecipherStream?.destroyed ?? true;\n\n return isFileReadHandleReleased && isFileReadStreamReleased && isFileReadCipherStreamReleased\n && isFileReadPassThroughStreamReleased && isFileWriteStreamReleased && isFileWriteDecipherStreamReleased\n && isFileWriteHandleReleased;\n }\n\n constructor(fullFilePath: string, chunkStartPosition: number, chunkLengthInBytes: number, encryptionData: ChunkStreamProviderEncryptionData | undefined) {\n this.throwIfEncryptionDataIsNotValid(encryptionData);\n\n this.#fullFilePath = fullFilePath;\n this.#encryptionData = encryptionData;\n this.chunkStartPosition = chunkStartPosition;\n\n if (chunkLengthInBytes < 0)\n throw new FsError(`chunkLengthInBytes can't be a negative value`);\n\n this.chunkLengthInBytes = chunkLengthInBytes;\n }\n\n private throwIfEncryptionDataIsNotValid(encryptionData: ChunkStreamProviderEncryptionData | undefined) {\n if (!encryptionData)\n return;\n\n if (encryptionData.iv.length !== 16)\n throw new FsError(`Encryption IV must be 16 bytes long`);\n if (encryptionData.key.length !== 32)\n throw new FsError(`Encryption key must be 32 bytes long`);\n }\n\n async getMd5Checksum(format: `hex` | `base64`, pauseSignal?: PauseSignal): Promise<string> {\n try {\n const fileStream = await this.getChunkReadStream(pauseSignal);\n\n const hash = crypto.createHash(`md5`);\n\n await pipeline(fileStream, hash);\n\n return hash.digest(format);\n }\n catch (error) {\n throw new FsError(`ComputingFileMd5ChecksumException`, { cause: error as Error });\n }\n finally {\n if (!this.isReleased)\n await this.release();\n }\n }\n\n async getChunkReadStream(pauseSignal?: PauseSignal): Promise<ReadableStream> {\n try {\n if (!this.isReleased)\n await this.release();\n\n this.#fileReadHandle = await fs.open(this.#fullFilePath, fsConsts.O_RDONLY);\n\n this.#fileReadStream = this.#fileReadHandle.createReadStream({\n start: this.chunkStartPosition,\n end: this.getChunkEndPosition(),\n });\n\n this.#fileReadPassThroughStream = new PassThrough();\n\n if (this.#encryptionData) {\n this.#fileReadCipherStream = createCipher(\n Buffer.from(this.#encryptionData.key),\n Buffer.from(this.#encryptionData.iv),\n this.chunkStartPosition,\n ) as Transform;\n this.#fileReadStream.pipe(this.#fileReadCipherStream).pipe(this.#fileReadPassThroughStream);\n }\n else\n this.#fileReadStream.pipe(this.#fileReadPassThroughStream);\n\n pauseSignal?.addEventListener(`pause`, () => {\n this.#fileReadStream?.destroy();\n this.#fileReadCipherStream?.destroy();\n this.#fileReadPassThroughStream?.end();\n });\n\n return ReadableStream.from(this.#fileReadPassThroughStream);\n }\n catch (error) {\n if (!this.isReleased)\n await this.release();\n\n throw new FsError(`CreatingFileReadStreamException`, { cause: error as Error });\n }\n }\n\n getChunkBlob(): Promise<Blob> {\n throw new Error(`Not implemented for NodeJS`);\n }\n\n private getChunkEndPosition() {\n if (this.chunkLengthInBytes === 0)\n return this.chunkStartPosition;\n\n return this.chunkStartPosition + this.chunkLengthInBytes - 1;\n }\n\n async getChunkWriteStream(): Promise<{ fileStream: Writable, decipherStream?: Writable }> {\n try {\n if (!this.isReleased)\n await this.release();\n\n this.#fileWriteHandle = await fs.open(this.#fullFilePath, fsConsts.O_WRONLY);\n\n this.#fileWriteStream = this.#fileWriteHandle.createWriteStream({\n start: this.chunkStartPosition,\n });\n\n if (!this.#encryptionData)\n return { fileStream: this.#fileWriteStream };\n\n this.#fileWriteDecipherStream = createDecipher(\n Buffer.from(this.#encryptionData.key),\n Buffer.from(this.#encryptionData.iv),\n this.chunkStartPosition,\n ) as Transform;\n\n return { fileStream: this.#fileWriteStream, decipherStream: this.#fileWriteDecipherStream };\n }\n catch (error) {\n if (!this.isReleased)\n await this.release();\n\n throw new FsError(`CreatingFileWriteStreamException`, { cause: error as Error });\n }\n }\n\n async release(): Promise<void> {\n await Promise.allSettled([\n this.closeHandle(this.#fileReadHandle),\n this.destroyStream(this.#fileReadStream),\n this.destroyStream(this.#fileReadCipherStream),\n this.destroyStream(this.#fileReadPassThroughStream),\n this.closeHandle(this.#fileWriteHandle),\n this.destroyStream(this.#fileWriteStream),\n this.destroyStream(this.#fileWriteDecipherStream),\n ]);\n\n this.#fileReadHandle = null;\n this.#fileReadStream = null;\n this.#fileReadCipherStream = null;\n this.#fileReadPassThroughStream = null;\n this.#fileWriteHandle = null;\n this.#fileWriteStream = null;\n this.#fileWriteDecipherStream = null;\n }\n\n private closeHandle = async (handle: fs.FileHandle | null): Promise<void> => {\n if (!handle)\n return;\n\n try {\n await handle.close();\n }\n catch { /* ignore errors during handle closing */ }\n };\n\n private destroyStream = async (stream: ReadStream | Writable | Transform | PassThrough | null): Promise<void> => {\n if (!stream || stream.destroyed)\n return;\n\n stream.once(`error`, () => { /* absorb premature close errors */ });\n const finishPromise = finished(stream).catch(() => { /* safely ignore */ });\n stream.destroy();\n await finishPromise;\n };\n}\n"]}
1
+ {"version":3,"file":"nodeChunkStreamProvider.js","sourceRoot":"","sources":["../../../../../src/utils/fileSystem/node/nodeChunkStreamProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"fs/promises\";\nimport { ReadStream, WriteStream, constants as fsConsts } from \"fs\";\nimport crypto from \"crypto\";\nimport { pipeline, finished } from \"stream/promises\";\nimport { PassThrough, Transform } from \"stream\";\n\nimport { ReadableStream } from \"stream/web\";\nimport type { Writable } from \"stream\";\n\nimport { createCipher, createDecipher } from 'aes-ctr-concurrent';\n\nimport FsError from '../fsError.js';\n\nimport type ChunkStreamProvider from \"../chunkStreamProvider.js\";\nimport type { PauseSignal } from \"../../../uploader/pauseController.js\";\nimport type { ChunkStreamProviderEncryptionData } from \"../chunkStreamProvider.js\";\n\nexport default class NodeChunkStreamProvider implements ChunkStreamProvider {\n readonly chunkStartPosition: number;\n readonly chunkLengthInBytes: number;\n\n readonly #encryptionData?: ChunkStreamProviderEncryptionData;\n readonly #fullFilePath: string;\n\n #fileReadHandle: fs.FileHandle | null = null;\n #fileReadStream: ReadStream | null = null;\n #fileReadCipherStream: Transform | null = null;\n #fileReadPassThroughStream: PassThrough | null = null;\n #fileWriteHandle: fs.FileHandle | null = null;\n #fileWriteStream: WriteStream | null = null;\n #fileWriteDecipherStream: Transform | null = null;\n #pauseSignal: PauseSignal | undefined;\n #pauseListener: (() => void) | undefined;\n\n get isReleased(): boolean {\n const isFileReadHandleReleased = this.#fileReadHandle === null;\n const isFileReadStreamReleased = this.#fileReadStream?.destroyed ?? true;\n const isFileReadCipherStreamReleased = this.#fileReadCipherStream?.destroyed ?? true;\n const isFileReadPassThroughStreamReleased = this.#fileReadPassThroughStream?.destroyed ?? true;\n const isFileWriteHandleReleased = this.#fileWriteHandle === null;\n const isFileWriteStreamReleased = this.#fileWriteStream?.destroyed ?? true;\n const isFileWriteDecipherStreamReleased = this.#fileWriteDecipherStream?.destroyed ?? true;\n\n return isFileReadHandleReleased && isFileReadStreamReleased && isFileReadCipherStreamReleased\n && isFileReadPassThroughStreamReleased && isFileWriteStreamReleased && isFileWriteDecipherStreamReleased\n && isFileWriteHandleReleased;\n }\n\n constructor(fullFilePath: string, chunkStartPosition: number, chunkLengthInBytes: number, encryptionData: ChunkStreamProviderEncryptionData | undefined) {\n this.throwIfEncryptionDataIsNotValid(encryptionData);\n\n this.#fullFilePath = fullFilePath;\n this.#encryptionData = encryptionData;\n this.chunkStartPosition = chunkStartPosition;\n\n if (chunkLengthInBytes < 0)\n throw new FsError(`chunkLengthInBytes can't be a negative value`);\n\n this.chunkLengthInBytes = chunkLengthInBytes;\n }\n\n private throwIfEncryptionDataIsNotValid(encryptionData: ChunkStreamProviderEncryptionData | undefined) {\n if (!encryptionData)\n return;\n\n if (encryptionData.iv.length !== 16)\n throw new FsError(`Encryption IV must be 16 bytes long`);\n if (encryptionData.key.length !== 32)\n throw new FsError(`Encryption key must be 32 bytes long`);\n }\n\n async getMd5Checksum(format: `hex` | `base64`, pauseSignal?: PauseSignal): Promise<string> {\n try {\n const fileStream = await this.getChunkReadStream(pauseSignal);\n\n const hash = crypto.createHash(`md5`);\n\n await pipeline(fileStream, hash);\n\n return hash.digest(format);\n }\n catch (error) {\n throw new FsError(`ComputingFileMd5ChecksumException`, { cause: error as Error });\n }\n finally {\n if (!this.isReleased)\n await this.release();\n }\n }\n\n async getChunkReadStream(pauseSignal?: PauseSignal): Promise<ReadableStream> {\n try {\n if (!this.isReleased)\n await this.release();\n\n this.#fileReadHandle = await fs.open(this.#fullFilePath, fsConsts.O_RDONLY);\n\n this.#fileReadStream = this.#fileReadHandle.createReadStream({\n start: this.chunkStartPosition,\n end: this.getChunkEndPosition(),\n });\n\n this.#fileReadPassThroughStream = new PassThrough();\n\n if (this.#encryptionData) {\n this.#fileReadCipherStream = createCipher(\n Buffer.from(this.#encryptionData.key),\n Buffer.from(this.#encryptionData.iv),\n this.chunkStartPosition,\n ) as Transform;\n this.#fileReadStream.pipe(this.#fileReadCipherStream).pipe(this.#fileReadPassThroughStream);\n }\n else\n this.#fileReadStream.pipe(this.#fileReadPassThroughStream);\n\n this.registerPauseListener(pauseSignal);\n\n return ReadableStream.from(this.#fileReadPassThroughStream);\n }\n catch (error) {\n if (!this.isReleased)\n await this.release();\n\n throw new FsError(`CreatingFileReadStreamException`, { cause: error as Error });\n }\n }\n\n getChunkBlob(): Promise<Blob> {\n throw new Error(`Not implemented for NodeJS`);\n }\n\n private getChunkEndPosition() {\n if (this.chunkLengthInBytes === 0)\n return this.chunkStartPosition;\n\n return this.chunkStartPosition + this.chunkLengthInBytes - 1;\n }\n\n async getChunkWriteStream(): Promise<{ fileStream: Writable, decipherStream?: Writable }> {\n try {\n if (!this.isReleased)\n await this.release();\n\n this.#fileWriteHandle = await fs.open(this.#fullFilePath, fsConsts.O_WRONLY);\n\n this.#fileWriteStream = this.#fileWriteHandle.createWriteStream({\n start: this.chunkStartPosition,\n });\n\n if (!this.#encryptionData)\n return { fileStream: this.#fileWriteStream };\n\n this.#fileWriteDecipherStream = createDecipher(\n Buffer.from(this.#encryptionData.key),\n Buffer.from(this.#encryptionData.iv),\n this.chunkStartPosition,\n ) as Transform;\n\n return { fileStream: this.#fileWriteStream, decipherStream: this.#fileWriteDecipherStream };\n }\n catch (error) {\n if (!this.isReleased)\n await this.release();\n\n throw new FsError(`CreatingFileWriteStreamException`, { cause: error as Error });\n }\n }\n\n async release(): Promise<void> {\n this.cleanupPauseListener();\n\n await Promise.allSettled([\n this.closeHandle(this.#fileReadHandle),\n this.destroyStream(this.#fileReadStream),\n this.destroyStream(this.#fileReadCipherStream),\n this.destroyStream(this.#fileReadPassThroughStream),\n this.closeHandle(this.#fileWriteHandle),\n this.destroyStream(this.#fileWriteStream),\n this.destroyStream(this.#fileWriteDecipherStream),\n ]);\n\n this.#fileReadHandle = null;\n this.#fileReadStream = null;\n this.#fileReadCipherStream = null;\n this.#fileReadPassThroughStream = null;\n this.#fileWriteHandle = null;\n this.#fileWriteStream = null;\n this.#fileWriteDecipherStream = null;\n }\n\n private registerPauseListener(pauseSignal?: PauseSignal) {\n this.cleanupPauseListener();\n\n if (!pauseSignal)\n return;\n\n this.#pauseSignal = pauseSignal;\n\n this.#pauseListener = () => {\n this.#fileReadStream?.destroy();\n this.#fileReadCipherStream?.destroy();\n this.#fileReadPassThroughStream?.end();\n };\n\n this.#pauseSignal.addEventListener(`pause`, this.#pauseListener);\n }\n\n private cleanupPauseListener() {\n if (!this.#pauseSignal || !this.#pauseListener)\n return;\n\n this.#pauseSignal.removeEventListener(`pause`, this.#pauseListener);\n\n this.#pauseSignal = undefined;\n this.#pauseListener = undefined;\n }\n\n private closeHandle = async (handle: fs.FileHandle | null): Promise<void> => {\n if (!handle)\n return;\n\n try {\n await handle.close();\n }\n catch { /* ignore errors during handle closing */ }\n };\n\n private destroyStream = async (stream: ReadStream | Writable | Transform | PassThrough | null): Promise<void> => {\n if (!stream || stream.destroyed)\n return;\n\n stream.once(`error`, () => { /* absorb premature close errors */ });\n const finishPromise = finished(stream).catch(() => { /* safely ignore */ });\n stream.destroy();\n await finishPromise;\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "filemail-sdk",
3
- "version": "9.4.2",
3
+ "version": "9.4.3",
4
4
  "description": "Library for transferring files to and from Filemail.com",
5
5
  "author": "Filemail AS",
6
6
  "license": "BSD-3-Clause",