bruce-models 5.8.7 → 5.8.8

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.
@@ -8293,20 +8293,51 @@
8293
8293
  if (!api) {
8294
8294
  api = exports.ENVIRONMENT.Api().GetBruceApi();
8295
8295
  }
8296
- const FILE_PORTION_SIZE = 50000000; // 50MB.
8296
+ const getOptimalConcurrency = (fileSize) => {
8297
+ // < 50MB
8298
+ if (fileSize < 50 * 1024 * 1024) {
8299
+ return 2;
8300
+ }
8301
+ // < 200MB
8302
+ if (fileSize < 200 * 1024 * 1024) {
8303
+ return 3;
8304
+ }
8305
+ // >= 200MB
8306
+ return 4;
8307
+ };
8308
+ const concurrentUploads = getOptimalConcurrency(file.size);
8309
+ const FILE_PORTION_SIZE = 35000000; // 35MB.
8297
8310
  let fileSize = file.size;
8298
- let fileOffset = 0;
8299
- let filePartsCount = fileSize / FILE_PORTION_SIZE;
8311
+ let filePartsCount = Math.ceil(fileSize / FILE_PORTION_SIZE);
8300
8312
  let t = Math.trunc(filePartsCount);
8301
8313
  filePartsCount = filePartsCount > t ? t + 1 : t;
8302
- let filePartIndex = 1;
8303
- let uploadToken = exports.ObjectUtils.UId();
8304
- let data;
8305
- while (fileOffset < fileSize) {
8306
- let partSize = Math.min(FILE_PORTION_SIZE, fileSize - fileOffset);
8307
- let retryCount = 5;
8308
- let retryWait = 1000;
8314
+ // Uploaded number of bytes so far.
8315
+ let uploaded = 0;
8316
+ // Part index -> uploaded amount.
8317
+ // When the part finishes uploading, we remove from here and add to uploaded.
8318
+ let uploadedPending = new Map();
8319
+ const updateProgress = () => {
8320
+ let total = uploaded;
8321
+ uploadedPending.forEach((value) => {
8322
+ total += (value || 0);
8323
+ });
8324
+ const percent = Math.round((total / fileSize) * 100);
8325
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress({
8326
+ percent: percent,
8327
+ uploaded: false
8328
+ });
8329
+ };
8330
+ const uploadToken = exports.ObjectUtils.UId();
8331
+ const uploadPart = (filePartIndex) => __awaiter(this, void 0, void 0, function* () {
8332
+ const fileOffset = filePartIndex * FILE_PORTION_SIZE;
8333
+ const partSize = Math.min(FILE_PORTION_SIZE, fileSize - fileOffset);
8334
+ let retryCount = 3;
8335
+ let retryWait = 3000;
8336
+ let data = null;
8309
8337
  while (retryCount > 0) {
8338
+ // Reset pending loaded in case this is a retry.
8339
+ uploadedPending.set(filePartIndex, 0);
8340
+ updateProgress();
8310
8341
  try {
8311
8342
  const blob = file.slice(fileOffset, fileOffset + partSize);
8312
8343
  const partialFile = new File([blob], file.name, { type: file.type });
@@ -8314,20 +8345,26 @@
8314
8345
  formData.append("originalFileName", file.name);
8315
8346
  formData.append("token", uploadToken);
8316
8347
  formData.append("count", "" + filePartsCount);
8317
- formData.append("part", "" + filePartIndex);
8348
+ // Not 0-based.
8349
+ formData.append("part", "" + (filePartIndex + 1));
8318
8350
  formData.append("file", partialFile);
8319
8351
  const reqParams = exports.Api.PrepReqParams(req);
8320
8352
  reqParams.formData = formData;
8321
8353
  reqParams.onProgress = (progress) => {
8322
- const sofar = fileOffset + progress.loaded;
8323
- const percent = Math.round((sofar / file.size) * 100);
8324
- onProgress === null || onProgress === void 0 ? void 0 : onProgress({
8325
- percent: percent,
8326
- uploaded: false
8327
- });
8354
+ const loaded = progress.loaded;
8355
+ uploadedPending.set(filePartIndex, loaded);
8356
+ updateProgress();
8328
8357
  };
8329
8358
  data = yield api.UPLOAD(url, partialFile, reqParams);
8330
8359
  retryCount = 0;
8360
+ uploaded += partSize;
8361
+ // Flush the pending upload.
8362
+ const pendingLoaded = uploadedPending.get(filePartIndex) || 0;
8363
+ uploaded += pendingLoaded;
8364
+ uploadedPending.delete(filePartIndex);
8365
+ // Call onProgress since we completed a portion.
8366
+ // This helps us know progress even when the request callback isn't working properly.
8367
+ updateProgress();
8331
8368
  }
8332
8369
  catch (up) {
8333
8370
  retryCount -= 1;
@@ -8338,20 +8375,34 @@
8338
8375
  retryWait = retryWait * 2;
8339
8376
  }
8340
8377
  }
8341
- fileOffset += partSize;
8342
- filePartIndex++;
8343
- // Call onProgress since we completed a portion.
8344
- // This helps us know progress even when the request callback isn't working properly.
8345
- onProgress === null || onProgress === void 0 ? void 0 : onProgress({
8346
- percent: Math.round((fileOffset / fileSize) * 100),
8347
- uploaded: false
8348
- });
8378
+ return { index: filePartIndex, data };
8379
+ });
8380
+ let results = [];
8381
+ for (let i = 0; i < filePartsCount; i += concurrentUploads) {
8382
+ const uploadPromises = [];
8383
+ for (let j = 0; j < concurrentUploads && (i + j) < filePartsCount; j++) {
8384
+ uploadPromises.push(uploadPart(i + j));
8385
+ }
8386
+ const batchResults = yield Promise.all(uploadPromises);
8387
+ // Sorting to maintain promise order.
8388
+ // Helps determine what the last part was.
8389
+ results.push(...batchResults.sort((a, b) => a.index - b.index).map(r => r.data));
8349
8390
  }
8350
8391
  onProgress === null || onProgress === void 0 ? void 0 : onProgress({
8351
8392
  percent: 100,
8352
8393
  uploaded: true
8353
8394
  });
8354
- return data;
8395
+ // Look for the explicitly stated final part.
8396
+ const final = results.find(x => x.RemainingParts == 0);
8397
+ if (final) {
8398
+ return final;
8399
+ }
8400
+ // Look for the last part.
8401
+ else if (results.length) {
8402
+ return results[results.length - 1];
8403
+ }
8404
+ // :(
8405
+ return null;
8355
8406
  });
8356
8407
  }
8357
8408
  Uploader.DoMultiPartUpload = DoMultiPartUpload;
@@ -15055,7 +15106,7 @@
15055
15106
  })(exports.Scenario || (exports.Scenario = {}));
15056
15107
 
15057
15108
  // This is updated with the package.json version on build.
15058
- const VERSION = "5.8.7";
15109
+ const VERSION = "5.8.8";
15059
15110
 
15060
15111
  exports.VERSION = VERSION;
15061
15112
  exports.AbstractApi = AbstractApi;