bruce-models 5.8.7 → 5.8.9

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.
@@ -8446,20 +8446,51 @@ var Uploader;
8446
8446
  if (!api) {
8447
8447
  api = ENVIRONMENT.Api().GetBruceApi();
8448
8448
  }
8449
- const FILE_PORTION_SIZE = 50000000; // 50MB.
8449
+ const getOptimalConcurrency = (fileSize) => {
8450
+ // < 50MB
8451
+ if (fileSize < 50 * 1024 * 1024) {
8452
+ return 2;
8453
+ }
8454
+ // < 200MB
8455
+ if (fileSize < 200 * 1024 * 1024) {
8456
+ return 3;
8457
+ }
8458
+ // >= 200MB
8459
+ return 4;
8460
+ };
8461
+ const concurrentUploads = getOptimalConcurrency(file.size);
8462
+ const FILE_PORTION_SIZE = 35000000; // 35MB.
8450
8463
  let fileSize = file.size;
8451
- let fileOffset = 0;
8452
- let filePartsCount = fileSize / FILE_PORTION_SIZE;
8464
+ let filePartsCount = Math.ceil(fileSize / FILE_PORTION_SIZE);
8453
8465
  let t = Math.trunc(filePartsCount);
8454
8466
  filePartsCount = filePartsCount > t ? t + 1 : t;
8455
- let filePartIndex = 1;
8456
- let uploadToken = ObjectUtils.UId();
8457
- let data;
8458
- while (fileOffset < fileSize) {
8459
- let partSize = Math.min(FILE_PORTION_SIZE, fileSize - fileOffset);
8460
- let retryCount = 5;
8461
- let retryWait = 1000;
8467
+ // Uploaded number of bytes so far.
8468
+ let uploaded = 0;
8469
+ // Part index -> uploaded amount.
8470
+ // When the part finishes uploading, we remove from here and add to uploaded.
8471
+ let uploadedPending = new Map();
8472
+ const updateProgress = () => {
8473
+ let total = uploaded;
8474
+ uploadedPending.forEach((value) => {
8475
+ total += (value || 0);
8476
+ });
8477
+ const percent = Math.round((total / fileSize) * 100);
8478
+ onProgress === null || onProgress === void 0 ? void 0 : onProgress({
8479
+ percent: percent,
8480
+ uploaded: false
8481
+ });
8482
+ };
8483
+ const uploadToken = ObjectUtils.UId();
8484
+ const uploadPart = (filePartIndex) => __awaiter(this, void 0, void 0, function* () {
8485
+ const fileOffset = filePartIndex * FILE_PORTION_SIZE;
8486
+ const partSize = Math.min(FILE_PORTION_SIZE, fileSize - fileOffset);
8487
+ let retryCount = 3;
8488
+ let retryWait = 3000;
8489
+ let data = null;
8462
8490
  while (retryCount > 0) {
8491
+ // Reset pending loaded in case this is a retry.
8492
+ uploadedPending.set(filePartIndex, 0);
8493
+ updateProgress();
8463
8494
  try {
8464
8495
  const blob = file.slice(fileOffset, fileOffset + partSize);
8465
8496
  const partialFile = new File([blob], file.name, { type: file.type });
@@ -8467,20 +8498,26 @@ var Uploader;
8467
8498
  formData.append("originalFileName", file.name);
8468
8499
  formData.append("token", uploadToken);
8469
8500
  formData.append("count", "" + filePartsCount);
8470
- formData.append("part", "" + filePartIndex);
8501
+ // Not 0-based.
8502
+ formData.append("part", "" + (filePartIndex + 1));
8471
8503
  formData.append("file", partialFile);
8472
8504
  const reqParams = Api.PrepReqParams(req);
8473
8505
  reqParams.formData = formData;
8474
8506
  reqParams.onProgress = (progress) => {
8475
- const sofar = fileOffset + progress.loaded;
8476
- const percent = Math.round((sofar / file.size) * 100);
8477
- onProgress === null || onProgress === void 0 ? void 0 : onProgress({
8478
- percent: percent,
8479
- uploaded: false
8480
- });
8507
+ const loaded = progress.loaded;
8508
+ uploadedPending.set(filePartIndex, loaded);
8509
+ updateProgress();
8481
8510
  };
8482
8511
  data = yield api.UPLOAD(url, partialFile, reqParams);
8483
8512
  retryCount = 0;
8513
+ uploaded += partSize;
8514
+ // Flush the pending upload.
8515
+ const pendingLoaded = uploadedPending.get(filePartIndex) || 0;
8516
+ uploaded += pendingLoaded;
8517
+ uploadedPending.delete(filePartIndex);
8518
+ // Call onProgress since we completed a portion.
8519
+ // This helps us know progress even when the request callback isn't working properly.
8520
+ updateProgress();
8484
8521
  }
8485
8522
  catch (up) {
8486
8523
  retryCount -= 1;
@@ -8491,20 +8528,34 @@ var Uploader;
8491
8528
  retryWait = retryWait * 2;
8492
8529
  }
8493
8530
  }
8494
- fileOffset += partSize;
8495
- filePartIndex++;
8496
- // Call onProgress since we completed a portion.
8497
- // This helps us know progress even when the request callback isn't working properly.
8498
- onProgress === null || onProgress === void 0 ? void 0 : onProgress({
8499
- percent: Math.round((fileOffset / fileSize) * 100),
8500
- uploaded: false
8501
- });
8531
+ return { index: filePartIndex, data };
8532
+ });
8533
+ let results = [];
8534
+ for (let i = 0; i < filePartsCount; i += concurrentUploads) {
8535
+ const uploadPromises = [];
8536
+ for (let j = 0; j < concurrentUploads && (i + j) < filePartsCount; j++) {
8537
+ uploadPromises.push(uploadPart(i + j));
8538
+ }
8539
+ const batchResults = yield Promise.all(uploadPromises);
8540
+ // Sorting to maintain promise order.
8541
+ // Helps determine what the last part was.
8542
+ results.push(...batchResults.sort((a, b) => a.index - b.index).map(r => r.data));
8502
8543
  }
8503
8544
  onProgress === null || onProgress === void 0 ? void 0 : onProgress({
8504
8545
  percent: 100,
8505
8546
  uploaded: true
8506
8547
  });
8507
- return data;
8548
+ // Look for the explicitly stated final part.
8549
+ const final = results.find(x => x.RemainingParts == 0);
8550
+ if (final) {
8551
+ return final;
8552
+ }
8553
+ // Look for the last part.
8554
+ else if (results.length) {
8555
+ return results[results.length - 1];
8556
+ }
8557
+ // :(
8558
+ return null;
8508
8559
  });
8509
8560
  }
8510
8561
  Uploader.DoMultiPartUpload = DoMultiPartUpload;
@@ -15358,7 +15409,7 @@ var Scenario;
15358
15409
  })(Scenario || (Scenario = {}));
15359
15410
 
15360
15411
  // This is updated with the package.json version on build.
15361
- const VERSION = "5.8.7";
15412
+ const VERSION = "5.8.9";
15362
15413
 
15363
15414
  export { VERSION, AnnDocument, CustomForm, AbstractApi, Api, BruceApi, GlobalApi, GuardianApi, ApiGetters, Calculator, Bounds, BruceEvent, CacheControl, Camera, Cartes, Carto, Color, DelayQueue, Geometry, UTC, BruceVariable, LRUCache, GeoJson, EntityAttachmentType, EntityAttachment, EntityComment, EntityLink, EntityLod, EntityLodCategory, EntityRelationType, EntityRelation, EntitySource, EntityTag, EntityType, Entity, EntityCoords, EntityAttribute, EntityHistoricData, EntityTableView, Comment, ClientFile, ProgramKey, ZoomControl, MenuItem, ProjectViewBookmark, ProjectView, ProjectViewLegacyTile, ProjectViewTile, ProjectViewLegacy, ProjectViewLegacyBookmark, ProjectViewBookmarkGroup, PendingAction, MessageBroker, HostingLocation, Style, Tileset, Permission, Session, UserGroup, User, Account, AccountInvite, AccountFeatures, AccountLimits, AccountTemplate, AccountType, EncryptUtils, MathUtils, ObjectUtils, PathUtils, UrlUtils, DataLab, DataLabGroup, ImportAssembly, ImportCad, ImportCsv, ImportJson, ImportGeoJson, ImportKml, ImportedFile, ExportBrz, ExportUsd, Markup, Uploader, Plugin, ENVIRONMENT, DataSource, Scenario };
15364
15415
  //# sourceMappingURL=bruce-models.es5.js.map