bruce-models 5.9.7 → 5.9.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.
Files changed (37) hide show
  1. package/dist/bruce-models.es5.js +128 -100
  2. package/dist/bruce-models.es5.js.map +1 -1
  3. package/dist/bruce-models.umd.js +128 -100
  4. package/dist/bruce-models.umd.js.map +1 -1
  5. package/dist/lib/api/api.js.map +1 -1
  6. package/dist/lib/bruce-models.js +1 -1
  7. package/dist/lib/calculator/calculator.js +25 -13
  8. package/dist/lib/calculator/calculator.js.map +1 -1
  9. package/dist/lib/common/bruce-event.js +8 -3
  10. package/dist/lib/common/bruce-event.js.map +1 -1
  11. package/dist/lib/common/bruce-variable.js +31 -38
  12. package/dist/lib/common/bruce-variable.js.map +1 -1
  13. package/dist/lib/common/cache.js +2 -3
  14. package/dist/lib/common/cache.js.map +1 -1
  15. package/dist/lib/common/delay-queue.js +6 -2
  16. package/dist/lib/common/delay-queue.js.map +1 -1
  17. package/dist/lib/common/geometry.js +17 -13
  18. package/dist/lib/common/geometry.js.map +1 -1
  19. package/dist/lib/common/lru-cache.js +7 -1
  20. package/dist/lib/common/lru-cache.js.map +1 -1
  21. package/dist/lib/common/utc.js +15 -7
  22. package/dist/lib/common/utc.js.map +1 -1
  23. package/dist/lib/entity/entity-attribute.js +4 -1
  24. package/dist/lib/entity/entity-attribute.js.map +1 -1
  25. package/dist/lib/entity/entity.js +1 -1
  26. package/dist/lib/entity/entity.js.map +1 -1
  27. package/dist/lib/util/math-utils.js +7 -7
  28. package/dist/lib/util/math-utils.js.map +1 -1
  29. package/dist/lib/util/path-utils.js +6 -5
  30. package/dist/lib/util/path-utils.js.map +1 -1
  31. package/dist/types/api/api.d.ts +2 -2
  32. package/dist/types/bruce-models.d.ts +1 -1
  33. package/dist/types/calculator/calculator.d.ts +1 -1
  34. package/dist/types/common/bruce-variable.d.ts +1 -0
  35. package/dist/types/common/delay-queue.d.ts +2 -1
  36. package/dist/types/util/math-utils.d.ts +1 -1
  37. package/package.json +1 -1
@@ -150,8 +150,6 @@ var Api;
150
150
  Api.PrepReqParams = PrepReqParams;
151
151
  })(Api || (Api = {}));
152
152
 
153
- // 1 minute.
154
- const DEFAULT_DURATION = 60 * 1000;
155
153
  class CacheControl {
156
154
  constructor(id) {
157
155
  this.memory = new Map();
@@ -172,7 +170,7 @@ class CacheControl {
172
170
  }
173
171
  let { id, data, duration } = params;
174
172
  if (!duration || duration < 0) {
175
- duration = DEFAULT_DURATION;
173
+ duration = Api.DEFAULT_CACHE_DURATION;
176
174
  }
177
175
  id = String(id);
178
176
  const expires = Date.now() + duration;
@@ -1653,6 +1651,10 @@ class BruceEvent {
1653
1651
  Unsubscribe(id) {
1654
1652
  let index = this.callbacks.findIndex(x => x._id == id);
1655
1653
  if (index > -1) {
1654
+ // Null the callback function to prevent it from being called.
1655
+ // This stops a trigger from calling it if it's currently looping.
1656
+ this.callbacks[index].callback = null;
1657
+ // Remove the callback from the list.
1656
1658
  this.callbacks.splice(index, 1);
1657
1659
  }
1658
1660
  }
@@ -1662,9 +1664,10 @@ class BruceEvent {
1662
1664
  * @param data
1663
1665
  */
1664
1666
  Trigger(data) {
1665
- let callbacks = this.callbacks;
1666
- for (let i = 0; i < callbacks.length; i++) {
1667
- let callback = callbacks[i];
1667
+ // We copy in case the callback modifies the list.
1668
+ const callbacksCopy = [...this.callbacks];
1669
+ for (let i = 0; i < callbacksCopy.length; i++) {
1670
+ const callback = callbacksCopy[i];
1668
1671
  if (callback.callback) {
1669
1672
  callback.callback(data);
1670
1673
  }
@@ -2579,7 +2582,10 @@ var EntityAttribute;
2579
2582
  }
2580
2583
  const key = path[0];
2581
2584
  const item = items.find((i) => i.Key === key);
2582
- if (!item || !item.Structure || !path.length) {
2585
+ if (!item) {
2586
+ return null;
2587
+ }
2588
+ if (path.length === 1) {
2583
2589
  return item;
2584
2590
  }
2585
2591
  return GetAttribute(item.Structure, path.slice(1));
@@ -3170,13 +3176,14 @@ var PathUtils;
3170
3176
  }
3171
3177
  const broken = str.split(".");
3172
3178
  for (let i = 0; i < broken.length; i++) {
3173
- let piece = broken[0];
3174
- if (piece.charAt(0) == "\"") {
3175
- piece = broken[0] = piece.substring(1);
3179
+ let piece = broken[i];
3180
+ if (piece.startsWith("\"")) {
3181
+ piece = piece.substring(1);
3176
3182
  }
3177
- if (piece.charAt(piece.length - 1) == "\"") {
3178
- broken[0] = piece.substring(0, piece.length - 1);
3183
+ if (piece.endsWith("\"")) {
3184
+ piece = piece.substring(0, piece.length - 1);
3179
3185
  }
3186
+ broken[i] = piece;
3180
3187
  }
3181
3188
  return broken;
3182
3189
  }
@@ -3841,7 +3848,7 @@ var Entity;
3841
3848
  function GetValue(params) {
3842
3849
  var _a;
3843
3850
  let { entity: data, path, handleLegacy: checkAgainstLegacy } = params;
3844
- if (checkAgainstLegacy == null) {
3851
+ if (checkAgainstLegacy == null || checkAgainstLegacy == undefined) {
3845
3852
  checkAgainstLegacy = true;
3846
3853
  }
3847
3854
  if (!path || !path.length) {
@@ -4386,25 +4393,6 @@ var Entity;
4386
4393
  Entity.GetHistoricContainsKey = GetHistoricContainsKey;
4387
4394
  })(Entity || (Entity = {}));
4388
4395
 
4389
- /**
4390
- * Gets the first Bruce variable in a string.
4391
- * @param str
4392
- * @returns
4393
- */
4394
- function getVariable(str) {
4395
- const start = str.indexOf("${");
4396
- if (start > -1) {
4397
- const end = str.indexOf("}");
4398
- if (end > -1) {
4399
- if (start < end) {
4400
- const path = str.substring(start + 2, end);
4401
- const txt = str.substring(start, end + 1);
4402
- return { path: path, text: txt };
4403
- }
4404
- }
4405
- }
4406
- return null;
4407
- }
4408
4396
  /**
4409
4397
  * Utilities for parsing "Bruce variables", typically within strings.
4410
4398
  *
@@ -4421,28 +4409,40 @@ var BruceVariable;
4421
4409
  * @returns
4422
4410
  */
4423
4411
  function SwapValues(params) {
4424
- let { str, entity: data, legacyParse } = params;
4425
- if (!legacyParse) {
4426
- legacyParse = false;
4427
- }
4428
- while (true) {
4429
- const variable = getVariable(str);
4430
- if (variable) {
4431
- const path = legacyParse ? PathUtils.ParseLegacy(variable.path) : PathUtils.Parse(variable.path);
4432
- let value = "";
4433
- if (path.length > 0) {
4434
- value = Entity.GetValue({
4435
- entity: data,
4436
- path: path
4437
- });
4438
- }
4439
- str = str.replace(variable.text, value);
4412
+ const { str, entity: data, legacyParse, retainType } = params;
4413
+ // If the input is just a path, return the value of the path.
4414
+ // We only do this for 'retainType=true' because all existing code expects a string result.
4415
+ if (retainType && str.startsWith("${") && str.endsWith("}")) {
4416
+ let pathStr = str.slice(2, -1);
4417
+ pathStr = pathStr.trim();
4418
+ const path = legacyParse ? PathUtils.ParseLegacy(pathStr) : PathUtils.Parse(pathStr);
4419
+ return Entity.GetValue({
4420
+ entity: data,
4421
+ path: path
4422
+ });
4423
+ }
4424
+ // Regex that will match all Bruce variables.
4425
+ // It looks for ${...} and captures the content inside the brackets.
4426
+ const variableRegex = /\${([^}]*)}/g;
4427
+ return str.replace(variableRegex, (match, pathStr) => {
4428
+ // If the path is empty or just whitespace, return empty string
4429
+ if (!pathStr || pathStr.trim().length === 0) {
4430
+ return "";
4440
4431
  }
4441
- else {
4442
- break;
4432
+ pathStr = pathStr.trim();
4433
+ const path = legacyParse ? PathUtils.ParseLegacy(pathStr) : PathUtils.Parse(pathStr);
4434
+ if (!path.length) {
4435
+ return "";
4443
4436
  }
4444
- }
4445
- return str;
4437
+ const value = Entity.GetValue({
4438
+ entity: data,
4439
+ path: path
4440
+ });
4441
+ if (value == null || value == undefined) {
4442
+ return "";
4443
+ }
4444
+ return String(value);
4445
+ });
4446
4446
  }
4447
4447
  BruceVariable.SwapValues = SwapValues;
4448
4448
  })(BruceVariable || (BruceVariable = {}));
@@ -4526,6 +4526,11 @@ var Calculator;
4526
4526
  */
4527
4527
  function Calculate(params) {
4528
4528
  let { fields, tags, data, defaultValue, type } = params;
4529
+ // If params doesn't include a defaultValue, use null.
4530
+ // Though passing in undefined is valid!
4531
+ if ("defaultValue" in params == false) {
4532
+ defaultValue = null;
4533
+ }
4529
4534
  if (fields == null) {
4530
4535
  return defaultValue;
4531
4536
  }
@@ -4576,11 +4581,6 @@ var Calculator;
4576
4581
  let value = null;
4577
4582
  for (let i = 0; i < fieldsArr.length; i++) {
4578
4583
  let field = fieldsArr[i];
4579
- if (field) {
4580
- // Dereference.
4581
- // We do this because we'll be modifying the field to fix bad data.
4582
- field = JSON.parse(JSON.stringify(field));
4583
- }
4584
4584
  // Bad data has it set to 'color' but expects the input to be a number.
4585
4585
  if (type == "number" && field.type == EValueType.Color) {
4586
4586
  field.type = EValueType.Input;
@@ -4937,20 +4937,26 @@ var Calculator;
4937
4937
  try {
4938
4938
  value = BruceVariable.SwapValues({
4939
4939
  str: value,
4940
- entity: entity
4940
+ entity: entity,
4941
+ retainType: true
4941
4942
  });
4942
- const isJsEval = value.startsWith("JS:");
4943
- const MATH_REGEX = /(\d+\.?\d*|\.\d+)([+\-*/])(\d+\.?\d*|\.\d+)/;
4944
- const isMathEval = isJsEval || MATH_REGEX.test(value);
4945
- if (isJsEval || isMathEval) {
4946
- if (isJsEval) {
4947
- value = value.replace("JS:", "");
4948
- value = value.trim();
4943
+ if (value == null || value == undefined) {
4944
+ return null;
4945
+ }
4946
+ if (typeof value === "string") {
4947
+ const isJsEval = value.startsWith("JS:");
4948
+ const MATH_REGEX = /(\d+\.?\d*|\.\d+)([+\-*/])(\d+\.?\d*|\.\d+)/;
4949
+ const isMathEval = isJsEval || MATH_REGEX.test(value);
4950
+ if (isJsEval || isMathEval) {
4951
+ if (isJsEval) {
4952
+ value = value.replace("JS:", "");
4953
+ value = value.trim();
4954
+ }
4955
+ // https://rollupjs.org/guide/en/#avoiding-eval
4956
+ // This stops eval warning.
4957
+ const eval2 = eval;
4958
+ return eval2(value);
4949
4959
  }
4950
- // https://rollupjs.org/guide/en/#avoiding-eval
4951
- // This stops eval warning.
4952
- const eval2 = eval;
4953
- return eval2(value);
4954
4960
  }
4955
4961
  }
4956
4962
  catch (exception) {
@@ -5009,13 +5015,7 @@ var Geometry;
5009
5015
  if (!points.length) {
5010
5016
  throw ("points is empty.");
5011
5017
  }
5012
- let carto = points[0];
5013
- let lineString = `${carto.longitude},${carto.latitude}` + (carto.altitude != null ? `,${carto.altitude}` : "");
5014
- for (let i = 1; i < points.length; i++) {
5015
- carto = points[i];
5016
- lineString += ` ${carto.longitude},${carto.latitude}` + (carto.altitude != null ? `,${carto.altitude}` : "");
5017
- }
5018
- return lineString;
5018
+ return points.map(carto => `${carto.longitude},${carto.latitude}` + (carto.altitude != null ? `,${carto.altitude}` : "")).join(' ');
5019
5019
  }
5020
5020
  Geometry.LineStrFromPoints = LineStrFromPoints;
5021
5021
  /**
@@ -5107,6 +5107,9 @@ var Geometry;
5107
5107
  }
5108
5108
  return newGeometry;
5109
5109
  }
5110
+ else if (!geometry) {
5111
+ return {};
5112
+ }
5110
5113
  return geometry;
5111
5114
  }
5112
5115
  Geometry.ParseGeometry = ParseGeometry;
@@ -5123,19 +5126,26 @@ var Geometry;
5123
5126
  const collection = [];
5124
5127
  // Returns if two coordinates are equal.
5125
5128
  const areCoordinatesEqual = (coord1, coord2) => {
5126
- return coord1[0] === coord2[0] && coord1[1] === coord2[1] && coord1[2] === coord2[2];
5129
+ return coord1[0] === coord2[0] && coord1[1] === coord2[1] &&
5130
+ (noAltitude || coord1[2] === coord2[2]);
5127
5131
  };
5128
5132
  // Removes consecutive duplicate coordinates.
5129
5133
  const removeConsecutiveDuplicates = (coordinates) => {
5130
- return coordinates.filter((coord, index) => {
5131
- return index === 0 || !areCoordinatesEqual(coord, coordinates[index - 1]);
5132
- });
5134
+ if (coordinates.length <= 1)
5135
+ return coordinates;
5136
+ const result = [coordinates[0]];
5137
+ for (let i = 1; i < coordinates.length; i++) {
5138
+ if (!areCoordinatesEqual(coordinates[i], coordinates[i - 1])) {
5139
+ result.push(coordinates[i]);
5140
+ }
5141
+ }
5142
+ return result;
5133
5143
  };
5134
5144
  // Ensures that the polygon is closed.
5135
5145
  const closePolygonCoordinates = (coordinates) => {
5136
5146
  return coordinates.map(ring => {
5137
- if (!areCoordinatesEqual(ring[0], ring[ring.length - 1])) {
5138
- ring.push(ring[0]);
5147
+ if (ring.length > 0 && !areCoordinatesEqual(ring[0], ring[ring.length - 1])) {
5148
+ return [...ring, ring[0]];
5139
5149
  }
5140
5150
  return ring;
5141
5151
  });
@@ -5729,13 +5739,14 @@ var Carto;
5729
5739
  * If you have a method that may be called often, but you don't want it to run often, use this.
5730
5740
  */
5731
5741
  class DelayQueue {
5732
- constructor(callback, delay = 200) {
5742
+ constructor(callback, delay = 200, startDelayed = false) {
5733
5743
  // Millisecond delay.
5734
5744
  this.delay = 200;
5735
5745
  // Date-time stamp for the last callback call.
5736
5746
  this.lastCallTime = null;
5737
5747
  this.callback = callback;
5738
5748
  this.delay = delay;
5749
+ this.startDelayed = startDelayed;
5739
5750
  }
5740
5751
  /**
5741
5752
  * Request a call on the callback.
@@ -5743,7 +5754,10 @@ class DelayQueue {
5743
5754
  */
5744
5755
  Call(force = false) {
5745
5756
  if (this.lastCallTime == null) {
5746
- force = true;
5757
+ this.lastCallTime = new Date().getTime();
5758
+ if (this.startDelayed) {
5759
+ force = false;
5760
+ }
5747
5761
  }
5748
5762
  if (force) {
5749
5763
  let endDate = new Date().getTime();
@@ -5848,28 +5862,36 @@ var UTC;
5848
5862
  * @param utc
5849
5863
  */
5850
5864
  function GetPassedTime(utc) {
5851
- const passedSeconds = GetPassedSeconds(utc);
5865
+ let tense = "ago";
5866
+ let passedSeconds = GetPassedSeconds(utc);
5867
+ if (passedSeconds < 0) {
5868
+ // Account for the time difference between the client and the server.
5869
+ if (passedSeconds < -(15 * 60)) {
5870
+ return "recently";
5871
+ }
5872
+ tense = "from now";
5873
+ }
5852
5874
  if (passedSeconds < 60) {
5853
- return `${passedSeconds} second${passedSeconds > 1 ? "s" : ""} ago`;
5875
+ return `${passedSeconds} second${passedSeconds > 1 ? "s" : ""} ${tense}`;
5854
5876
  }
5855
5877
  const passedMinutes = Math.floor(passedSeconds / 60);
5856
5878
  if (passedMinutes < 60) {
5857
- return `${passedMinutes} minute${passedMinutes > 1 ? "s" : ""} ago`;
5879
+ return `${passedMinutes} minute${passedMinutes > 1 ? "s" : ""} ${tense}`;
5858
5880
  }
5859
5881
  const passedHours = Math.floor(passedMinutes / 60);
5860
5882
  if (passedHours < 24) {
5861
- return `${passedHours} hour${passedHours > 1 ? "s" : ""} ago`;
5883
+ return `${passedHours} hour${passedHours > 1 ? "s" : ""} ${tense}`;
5862
5884
  }
5863
5885
  const passedDays = Math.floor(passedHours / 24);
5864
5886
  if (passedDays < 30) {
5865
- return `${passedDays} day${passedDays > 1 ? "s" : ""} ago`;
5887
+ return `${passedDays} day${passedDays > 1 ? "s" : ""} ${tense}`;
5866
5888
  }
5867
5889
  const passedMonths = Math.floor(passedDays / 30);
5868
5890
  if (passedMonths < 12) {
5869
- return `${passedMonths} month${passedMonths > 1 ? "s" : ""} ago`;
5891
+ return `${passedMonths} month${passedMonths > 1 ? "s" : ""} ${tense}`;
5870
5892
  }
5871
5893
  const passedYears = Math.floor(passedMonths / 12);
5872
- return `${passedYears} year${passedYears > 1 ? "s" : ""} ago`;
5894
+ return `${passedYears} year${passedYears > 1 ? "s" : ""} ${tense}`;
5873
5895
  }
5874
5896
  UTC.GetPassedTime = GetPassedTime;
5875
5897
  /**
@@ -5950,7 +5972,13 @@ class LRUCache {
5950
5972
  * @param value
5951
5973
  */
5952
5974
  Set(key, value) {
5953
- if (this.cache.size >= this.capacity) {
5975
+ if (this.capacity <= 0) {
5976
+ // Empty cache.
5977
+ // Means we were configured to not cache anything.
5978
+ this.cache.clear();
5979
+ return;
5980
+ }
5981
+ else if (this.cache.size >= this.capacity) {
5954
5982
  const leastRecentlyUsedKey = this.cache.keys().next().value;
5955
5983
  this.cache.delete(leastRecentlyUsedKey);
5956
5984
  }
@@ -7721,15 +7749,15 @@ var MathUtils;
7721
7749
  * @returns
7722
7750
  */
7723
7751
  function Round(num, decimals = 0) {
7724
- if (decimals <= 0) {
7725
- return Math.round(num);
7752
+ const n = typeof num === 'string' ? parseFloat(num) : num;
7753
+ if (isNaN(n)) {
7754
+ return 0;
7726
7755
  }
7727
- let tmp = "1";
7728
- for (let i = 0; i < decimals; i++) {
7729
- tmp += "0";
7756
+ if (decimals <= 0) {
7757
+ return Math.round(n);
7730
7758
  }
7731
- const d = parseFloat(tmp);
7732
- return Math.round((num + Number.EPSILON) * d) / d;
7759
+ const multiplier = Math.pow(10, decimals);
7760
+ return Math.round((n + Number.EPSILON) * multiplier) / multiplier;
7733
7761
  }
7734
7762
  MathUtils.Round = Round;
7735
7763
  /**
@@ -15649,7 +15677,7 @@ var Scenario;
15649
15677
  })(Scenario || (Scenario = {}));
15650
15678
 
15651
15679
  // This is updated with the package.json version on build.
15652
- const VERSION = "5.9.7";
15680
+ const VERSION = "5.9.8";
15653
15681
 
15654
15682
  export { VERSION, Assembly, 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 };
15655
15683
  //# sourceMappingURL=bruce-models.es5.js.map