@fluid-experimental/property-common 2.0.0-dev.2.3.0.115467 → 2.0.0-dev.4.1.0.148229

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 (127) hide show
  1. package/.eslintrc.js +9 -11
  2. package/.mocharc.json +6 -6
  3. package/README.md +1 -0
  4. package/api-extractor.json +2 -2
  5. package/dist/chronometer.d.ts.map +1 -1
  6. package/dist/chronometer.js.map +1 -1
  7. package/dist/consoleUtils.d.ts.map +1 -1
  8. package/dist/consoleUtils.js +4 -1
  9. package/dist/consoleUtils.js.map +1 -1
  10. package/dist/constants.d.ts +6 -6
  11. package/dist/constants.d.ts.map +1 -1
  12. package/dist/constants.js +16 -26
  13. package/dist/constants.js.map +1 -1
  14. package/dist/datastructures/collection.d.ts.map +1 -1
  15. package/dist/datastructures/collection.js +5 -4
  16. package/dist/datastructures/collection.js.map +1 -1
  17. package/dist/datastructures/dataArray.d.ts.map +1 -1
  18. package/dist/datastructures/dataArray.js +18 -9
  19. package/dist/datastructures/dataArray.js.map +1 -1
  20. package/dist/datastructures/integer64.d.ts.map +1 -1
  21. package/dist/datastructures/integer64.js +1 -1
  22. package/dist/datastructures/integer64.js.map +1 -1
  23. package/dist/datastructures/sortedCollection.d.ts.map +1 -1
  24. package/dist/datastructures/sortedCollection.js +3 -1
  25. package/dist/datastructures/sortedCollection.js.map +1 -1
  26. package/dist/deferredPromise.d.ts +1 -1
  27. package/dist/deferredPromise.d.ts.map +1 -1
  28. package/dist/deferredPromise.js +9 -3
  29. package/dist/deferredPromise.js.map +1 -1
  30. package/dist/deterministicRandomGenerator.d.ts.map +1 -1
  31. package/dist/deterministicRandomGenerator.js +6 -6
  32. package/dist/deterministicRandomGenerator.js.map +1 -1
  33. package/dist/error_objects/flaggedError.d.ts.map +1 -1
  34. package/dist/error_objects/flaggedError.js.map +1 -1
  35. package/dist/error_objects/httpError.d.ts.map +1 -1
  36. package/dist/error_objects/httpError.js +9 -9
  37. package/dist/error_objects/httpError.js.map +1 -1
  38. package/dist/error_objects/httpErrorNoStack.d.ts.map +1 -1
  39. package/dist/error_objects/httpErrorNoStack.js.map +1 -1
  40. package/dist/error_objects/operationError.d.ts +7 -7
  41. package/dist/error_objects/operationError.d.ts.map +1 -1
  42. package/dist/error_objects/operationError.js +7 -7
  43. package/dist/error_objects/operationError.js.map +1 -1
  44. package/dist/guidUtils.d.ts.map +1 -1
  45. package/dist/guidUtils.js +10 -9
  46. package/dist/guidUtils.js.map +1 -1
  47. package/dist/hashCalculator.d.ts.map +1 -1
  48. package/dist/hashCalculator.js.map +1 -1
  49. package/dist/joinPaths.d.ts.map +1 -1
  50. package/dist/joinPaths.js.map +1 -1
  51. package/dist/packageVersion.d.ts +1 -1
  52. package/dist/packageVersion.js +1 -1
  53. package/dist/packageVersion.js.map +1 -1
  54. package/lib/chronometer.d.ts.map +1 -1
  55. package/lib/chronometer.js.map +1 -1
  56. package/lib/consoleUtils.d.ts.map +1 -1
  57. package/lib/consoleUtils.js +4 -1
  58. package/lib/consoleUtils.js.map +1 -1
  59. package/lib/constants.d.ts +6 -6
  60. package/lib/constants.d.ts.map +1 -1
  61. package/lib/constants.js +16 -26
  62. package/lib/constants.js.map +1 -1
  63. package/lib/datastructures/collection.d.ts.map +1 -1
  64. package/lib/datastructures/collection.js +5 -4
  65. package/lib/datastructures/collection.js.map +1 -1
  66. package/lib/datastructures/dataArray.d.ts.map +1 -1
  67. package/lib/datastructures/dataArray.js +18 -9
  68. package/lib/datastructures/dataArray.js.map +1 -1
  69. package/lib/datastructures/integer64.d.ts.map +1 -1
  70. package/lib/datastructures/integer64.js +1 -1
  71. package/lib/datastructures/integer64.js.map +1 -1
  72. package/lib/datastructures/sortedCollection.d.ts.map +1 -1
  73. package/lib/datastructures/sortedCollection.js +3 -1
  74. package/lib/datastructures/sortedCollection.js.map +1 -1
  75. package/lib/deferredPromise.d.ts +1 -1
  76. package/lib/deferredPromise.d.ts.map +1 -1
  77. package/lib/deferredPromise.js +9 -3
  78. package/lib/deferredPromise.js.map +1 -1
  79. package/lib/deterministicRandomGenerator.d.ts.map +1 -1
  80. package/lib/deterministicRandomGenerator.js +6 -6
  81. package/lib/deterministicRandomGenerator.js.map +1 -1
  82. package/lib/error_objects/flaggedError.d.ts.map +1 -1
  83. package/lib/error_objects/flaggedError.js.map +1 -1
  84. package/lib/error_objects/httpError.d.ts.map +1 -1
  85. package/lib/error_objects/httpError.js +9 -9
  86. package/lib/error_objects/httpError.js.map +1 -1
  87. package/lib/error_objects/httpErrorNoStack.d.ts.map +1 -1
  88. package/lib/error_objects/httpErrorNoStack.js.map +1 -1
  89. package/lib/error_objects/operationError.d.ts +7 -7
  90. package/lib/error_objects/operationError.d.ts.map +1 -1
  91. package/lib/error_objects/operationError.js +7 -7
  92. package/lib/error_objects/operationError.js.map +1 -1
  93. package/lib/guidUtils.d.ts.map +1 -1
  94. package/lib/guidUtils.js +10 -9
  95. package/lib/guidUtils.js.map +1 -1
  96. package/lib/hashCalculator.d.ts.map +1 -1
  97. package/lib/hashCalculator.js.map +1 -1
  98. package/lib/joinPaths.d.ts.map +1 -1
  99. package/lib/joinPaths.js.map +1 -1
  100. package/lib/packageVersion.d.ts +1 -1
  101. package/lib/packageVersion.js +1 -1
  102. package/lib/packageVersion.js.map +1 -1
  103. package/package.json +42 -40
  104. package/platform-dependent/README.md +1 -0
  105. package/platform-dependent/browser.js +5 -5
  106. package/platform-dependent/package.json +14 -14
  107. package/platform-dependent/server.js +5 -5
  108. package/prettier.config.cjs +1 -1
  109. package/src/chronometer.ts +174 -169
  110. package/src/consoleUtils.ts +16 -11
  111. package/src/constants.ts +1683 -1640
  112. package/src/datastructures/collection.ts +417 -416
  113. package/src/datastructures/dataArray.ts +516 -492
  114. package/src/datastructures/integer64.ts +102 -99
  115. package/src/datastructures/sortedCollection.ts +155 -145
  116. package/src/deferredPromise.ts +43 -42
  117. package/src/deterministicRandomGenerator.ts +59 -59
  118. package/src/error_objects/flaggedError.ts +29 -29
  119. package/src/error_objects/httpError.ts +45 -42
  120. package/src/error_objects/httpErrorNoStack.ts +17 -17
  121. package/src/error_objects/operationError.ts +62 -62
  122. package/src/guidUtils.ts +182 -171
  123. package/src/hashCalculator.ts +5 -2
  124. package/src/joinPaths.ts +15 -9
  125. package/src/packageVersion.ts +1 -1
  126. package/tsconfig.esnext.json +6 -6
  127. package/tsconfig.json +9 -13
@@ -26,43 +26,46 @@ const { MSG } = constants;
26
26
  * @param high - Higher 32 bit
27
27
  */
28
28
  export class Integer64 {
29
- constructor(protected low = 0, protected high = 0) { }
30
-
31
- /**
32
- * @returns The higher 32 bit integer part
33
- */
34
- getValueHigh() {
35
- return this.high;
36
- }
37
-
38
- /**
39
- * @returns The lower 32 bit integer part
40
- */
41
- getValueLow() {
42
- return this.low;
43
- }
44
-
45
- protected _int64toString(isSigned: boolean, in_radix = 10): string {
46
- ConsoleUtils.assert(_.isNumber(in_radix), `${MSG.IN_RADIX_MUST_BE_NUMBER} ${in_radix}`);
47
- ConsoleUtils.assert(in_radix >= 2 && 36 >= in_radix, `${MSG.BASE_OUT_OF_RANGE} ${in_radix}`);
48
-
49
- let high = this.getValueHigh();
50
- let low = this.getValueLow();
51
- let result = "";
52
- const sign = !!(isSigned && (high & 0x80000000)); // eslint-disable-line no-bitwise
53
- if (sign) {
54
- high = ~high; // eslint-disable-line no-bitwise
55
- low = BIT32 - low;
56
- }
57
- do {
58
- const mod = (high % in_radix) * BIT32 + low;
59
- high = Math.floor(high / in_radix);
60
- low = Math.floor(mod / in_radix);
61
- result = (mod % in_radix).toString(in_radix) + result;
62
- } while (high || low);
63
-
64
- return sign ? `-${result}` : result;
65
- }
29
+ constructor(protected low = 0, protected high = 0) {}
30
+
31
+ /**
32
+ * @returns The higher 32 bit integer part
33
+ */
34
+ getValueHigh() {
35
+ return this.high;
36
+ }
37
+
38
+ /**
39
+ * @returns The lower 32 bit integer part
40
+ */
41
+ getValueLow() {
42
+ return this.low;
43
+ }
44
+
45
+ protected _int64toString(isSigned: boolean, in_radix = 10): string {
46
+ ConsoleUtils.assert(_.isNumber(in_radix), `${MSG.IN_RADIX_MUST_BE_NUMBER} ${in_radix}`);
47
+ ConsoleUtils.assert(
48
+ in_radix >= 2 && 36 >= in_radix,
49
+ `${MSG.BASE_OUT_OF_RANGE} ${in_radix}`,
50
+ );
51
+
52
+ let high = this.getValueHigh();
53
+ let low = this.getValueLow();
54
+ let result = "";
55
+ const sign = !!(isSigned && high & 0x80000000); // eslint-disable-line no-bitwise
56
+ if (sign) {
57
+ high = ~high; // eslint-disable-line no-bitwise
58
+ low = BIT32 - low;
59
+ }
60
+ do {
61
+ const mod = (high % in_radix) * BIT32 + low;
62
+ high = Math.floor(high / in_radix);
63
+ low = Math.floor(mod / in_radix);
64
+ result = (mod % in_radix).toString(in_radix) + result;
65
+ } while (high || low);
66
+
67
+ return sign ? `-${result}` : result;
68
+ }
66
69
  }
67
70
 
68
71
  /**
@@ -81,78 +84,78 @@ export class Integer64 {
81
84
  * @returns Low and high bits of `Int64`.
82
85
  */
83
86
  function _stringToInt64(in_signed: boolean, in_string: string, in_radix = 10): number[] {
84
- ConsoleUtils.assert(_.isString(in_string), MSG.IN_STRING_MUST_BE_STRING + in_string);
85
- const string = in_string.trim();
86
-
87
- ConsoleUtils.assert(_.isNumber(in_radix), `${MSG.IN_RADIX_BETWEEN_2_36} ${in_radix}`);
88
- ConsoleUtils.assert(in_radix >= 2 && 36 >= in_radix, `${MSG.BASE_OUT_OF_RANGE} ${in_radix}`);
89
-
90
- let position = 0;
91
- let negative = false;
92
- let high = 0;
93
- let low = 0;
94
- if (string[0] === "-") {
95
- negative = true;
96
- position += 1;
97
- }
98
-
99
- ConsoleUtils.assert(!negative || in_signed, MSG.CANNOT_UPDATE_TO_NEGATIVE + string);
100
-
101
- while (position < string.length) {
102
- const digit = parseInt(string[position++], in_radix);
103
- if (isNaN(digit)) {
104
- throw new TypeError(MSG.CANNOT_PARSE_INVALID_CHARACTERS + string);
105
- }
106
- low = low * in_radix + digit;
107
- high = high * in_radix + Math.floor(low / BIT32);
108
- low %= BIT32;
109
- }
110
-
111
- if (negative) {
112
- // eslint-disable-next-line no-bitwise
113
- high = ~high;
114
- if (low) {
115
- low = BIT32 - low;
116
- } else {
117
- high += 1;
118
- }
119
- }
120
-
121
- return [low, high];
87
+ ConsoleUtils.assert(_.isString(in_string), MSG.IN_STRING_MUST_BE_STRING + in_string);
88
+ const string = in_string.trim();
89
+
90
+ ConsoleUtils.assert(_.isNumber(in_radix), `${MSG.IN_RADIX_BETWEEN_2_36} ${in_radix}`);
91
+ ConsoleUtils.assert(in_radix >= 2 && 36 >= in_radix, `${MSG.BASE_OUT_OF_RANGE} ${in_radix}`);
92
+
93
+ let position = 0;
94
+ let negative = false;
95
+ let high = 0;
96
+ let low = 0;
97
+ if (string[0] === "-") {
98
+ negative = true;
99
+ position += 1;
100
+ }
101
+
102
+ ConsoleUtils.assert(!negative || in_signed, MSG.CANNOT_UPDATE_TO_NEGATIVE + string);
103
+
104
+ while (position < string.length) {
105
+ const digit = parseInt(string[position++], in_radix);
106
+ if (isNaN(digit)) {
107
+ throw new TypeError(MSG.CANNOT_PARSE_INVALID_CHARACTERS + string);
108
+ }
109
+ low = low * in_radix + digit;
110
+ high = high * in_radix + Math.floor(low / BIT32);
111
+ low %= BIT32;
112
+ }
113
+
114
+ if (negative) {
115
+ // eslint-disable-next-line no-bitwise
116
+ high = ~high;
117
+ if (low) {
118
+ low = BIT32 - low;
119
+ } else {
120
+ high += 1;
121
+ }
122
+ }
123
+
124
+ return [low, high];
122
125
  }
123
126
 
124
127
  /**
125
128
  * A data representation class for the signed 64 bit integer type
126
129
  */
127
130
  export class Int64 extends Integer64 {
128
- static fromString = function(in_string: string, radix = 10) {
129
- const [low, high] = _stringToInt64(true, in_string, radix);
130
- return new Int64(low, high);
131
- };
132
-
133
- clone() {
134
- return new Int64(this.low, this.high);
135
- }
136
-
137
- toString(radix = 10) {
138
- return this._int64toString(true, radix);
139
- }
131
+ static fromString = function (in_string: string, radix = 10) {
132
+ const [low, high] = _stringToInt64(true, in_string, radix);
133
+ return new Int64(low, high);
134
+ };
135
+
136
+ clone() {
137
+ return new Int64(this.low, this.high);
138
+ }
139
+
140
+ toString(radix = 10) {
141
+ return this._int64toString(true, radix);
142
+ }
140
143
  }
141
144
 
142
145
  /**
143
146
  * A data representation class for the unsigned 64 bit integer type
144
147
  */
145
148
  export class Uint64 extends Integer64 {
146
- static fromString(in_string: string, in_radix = 10) {
147
- const [low, high] = _stringToInt64.call(this, false, in_string, in_radix);
148
- return new Uint64(low, high);
149
- }
150
-
151
- clone() {
152
- return new Uint64(this.low, this.high);
153
- }
154
-
155
- toString(radix) {
156
- return this._int64toString(false, radix);
157
- }
149
+ static fromString(in_string: string, in_radix = 10) {
150
+ const [low, high] = _stringToInt64.call(this, false, in_string, in_radix);
151
+ return new Uint64(low, high);
152
+ }
153
+
154
+ clone() {
155
+ return new Uint64(this.low, this.high);
156
+ }
157
+
158
+ toString(radix) {
159
+ return this._int64toString(false, radix);
160
+ }
158
161
  }
@@ -12,149 +12,159 @@ import _ from "lodash";
12
12
  import { Collection } from "./collection";
13
13
 
14
14
  export class SortedCollection<T> extends Collection<T> {
15
- private _sortedKeys: string[] = [];
16
- private _comparisonFunction?: (x: string, y: string) => number = undefined;
17
-
18
- /**
19
- * A sorted collection class.
20
- * @param in_name - a friendly name to describe this collection. If undefined
21
- * the collection will have a default "Untitled Collection" assigned to its name.
22
- * @param in_type - optional parameter pointing to the constructor
23
- * of a type this Collection will host.
24
- */
25
- constructor(in_name?: string, in_type?) {
26
- super(in_name, in_type);
27
- }
28
-
29
- /**
30
- * Set the comparison function. By default the keys will be sorted wrt their ASCII code.
31
- *
32
- * @param in_fn - The function to compare two entries.
33
- * The return value of this function must convey to the following cases:
34
- *
35
- * - if a \> b, then the return value must be greater than 0.
36
- *
37
- * - if a \< b, then the return value must be less than 0.
38
- *
39
- * - if a == b, then the return value must be 0.
40
- */
41
- setComparisonFunction(in_fn?: (x: string, y: string) => number) {
42
- console.assert(_.isFunction(in_fn), "Must provide a function");
43
- this._comparisonFunction = in_fn;
44
- }
45
-
46
- /**
47
- * Add an item to the collection. Sort the list of keys in an ascending order.
48
- *
49
- * @param in_key - Key to store the value under.
50
- * @param in_value - Value to store in the collection.
51
- *
52
- * @returns The value passed in.
53
- */
54
- add(in_key: string | number, in_value: T) {
55
- const toReturn = super.add(in_key, in_value);
56
-
57
- this._sortedKeys.push(in_key.toString());
58
- this._sortedKeys.sort(this._comparisonFunction);
59
-
60
- return toReturn;
61
- }
62
-
63
- /**
64
- * Remove an item from this Collection. This method returns a Boolean indicating
65
- * the success or failure of the removal. This is practical because if we were
66
- * to throw an error when the key doesn't exist, it would require additional
67
- * checks by the caller to make sure this key exists prior to removal. Which
68
- * would make the attempt of removal more verbose and also costly because the
69
- * caller would have to keep a list – somewhere else – of the things he can
70
- * and cannot remove.
71
- *
72
- * @param in_key - the key we wish to remove
73
- * @returns true if the key exists and was removed, false otherwise.
74
- */
75
- remove(in_key: string) {
76
- const toReturn = super.remove(in_key);
77
- this._sortedKeys = _.without(this._sortedKeys, in_key);
78
- return toReturn;
79
- }
80
-
81
- /**
82
- * Copy the items of in_collection to this collection.
83
- * @returns cloned SortedCollection
84
- */
85
- clone(): SortedCollection<T> {
86
- const newCol = new SortedCollection<T>(this._name, this._type);
87
- newCol.setComparisonFunction(this._comparisonFunction);
88
- newCol.bulkAdd(this._items);
89
- return newCol;
90
- }
91
-
92
- /**
93
- * Internal function use to search (binary search) for the nearest index that
94
- * the given key would be inserted.
95
- * i.e. given the array [10, 20, 30, 40, 50] the index that 35 should be inserted at is 3
96
- * @param in_array - Target array
97
- * @param in_key - Key to check against
98
- * @returns The index at which the key would be inserted in
99
- */
100
- private _binarySearchNearestIndex(in_array: string[], in_key: string): number {
101
- if (this._comparisonFunction === undefined) {
102
- return _.sortedIndex(in_array, in_key);
103
- } else {
104
- const middleIndex = Math.floor((in_array.length - 1) / 2);
105
-
106
- if (middleIndex < 0) {
107
- return 0;
108
- }
109
-
110
- if (this._comparisonFunction(in_array[middleIndex], in_key) > 0) {
111
- if (in_array.length === 1) {
112
- return 0;
113
- }
114
-
115
- return this._binarySearchNearestIndex(in_array.slice(0, middleIndex), in_key);
116
- }
117
-
118
- if (this._comparisonFunction(in_array[middleIndex], in_key) < 0) {
119
- if (in_array.length === 1) {
120
- return 1;
121
- }
122
-
123
- return (middleIndex + 1) + this._binarySearchNearestIndex(
124
- in_array.slice(middleIndex + 1, in_array.length),
125
- in_key,
126
- );
127
- }
128
-
129
- return middleIndex;
130
- }
131
- }
132
-
133
- /**
134
- * Return the nearest next item to the given key i.e.
135
- * For the given list of keys ['1.0.1', '2.0.0', '2.2.0', '7.0.1'] the nearest next item to 6.0.1 is
136
- * the item mapped by '7.0.1'
137
- * @param in_key - The key to check against in order to get the nearest next item
138
- * @returns The nearest next item
139
- */
140
- getNearestNextItem(in_key: string) {
141
- const closestNextIndex = this._binarySearchNearestIndex(this._sortedKeys, in_key.toString());
142
- return closestNextIndex === this.getCount()
143
- ? undefined
144
- : this.item(this._sortedKeys[closestNextIndex]);
145
- }
146
-
147
- /**
148
- * Return the nearest previous item to the given key i.e.
149
- * For the given list of keys ['1.0.1', '2.0.0', '2.2.0', '7.0.1'] the nearest previous item to 6.0.1 is
150
- * the item mapped by '7.0.1'
151
- * @param in_key - The key to check against in order to get the nearest previous item
152
- * @returns The nearest previous item
153
- */
154
- getNearestPreviousItem(in_key: string | number) {
155
- const closestPreviousIndex = this._binarySearchNearestIndex(this._sortedKeys, in_key.toString());
156
- return closestPreviousIndex === 0
157
- ? undefined
158
- : this.item(this._sortedKeys[closestPreviousIndex - 1]);
159
- }
15
+ private _sortedKeys: string[] = [];
16
+ private _comparisonFunction?: (x: string, y: string) => number = undefined;
17
+
18
+ /**
19
+ * A sorted collection class.
20
+ * @param in_name - a friendly name to describe this collection. If undefined
21
+ * the collection will have a default "Untitled Collection" assigned to its name.
22
+ * @param in_type - optional parameter pointing to the constructor
23
+ * of a type this Collection will host.
24
+ */
25
+ constructor(in_name?: string, in_type?) {
26
+ super(in_name, in_type);
27
+ }
28
+
29
+ /**
30
+ * Set the comparison function. By default the keys will be sorted wrt their ASCII code.
31
+ *
32
+ * @param in_fn - The function to compare two entries.
33
+ * The return value of this function must convey to the following cases:
34
+ *
35
+ * - if a \> b, then the return value must be greater than 0.
36
+ *
37
+ * - if a \< b, then the return value must be less than 0.
38
+ *
39
+ * - if a == b, then the return value must be 0.
40
+ */
41
+ setComparisonFunction(in_fn?: (x: string, y: string) => number) {
42
+ console.assert(_.isFunction(in_fn), "Must provide a function");
43
+ this._comparisonFunction = in_fn;
44
+ }
45
+
46
+ /**
47
+ * Add an item to the collection. Sort the list of keys in an ascending order.
48
+ *
49
+ * @param in_key - Key to store the value under.
50
+ * @param in_value - Value to store in the collection.
51
+ *
52
+ * @returns The value passed in.
53
+ */
54
+ add(in_key: string | number, in_value: T) {
55
+ const toReturn = super.add(in_key, in_value);
56
+
57
+ this._sortedKeys.push(in_key.toString());
58
+ this._sortedKeys.sort(this._comparisonFunction);
59
+
60
+ return toReturn;
61
+ }
62
+
63
+ /**
64
+ * Remove an item from this Collection. This method returns a Boolean indicating
65
+ * the success or failure of the removal. This is practical because if we were
66
+ * to throw an error when the key doesn't exist, it would require additional
67
+ * checks by the caller to make sure this key exists prior to removal. Which
68
+ * would make the attempt of removal more verbose and also costly because the
69
+ * caller would have to keep a list – somewhere else – of the things he can
70
+ * and cannot remove.
71
+ *
72
+ * @param in_key - the key we wish to remove
73
+ * @returns true if the key exists and was removed, false otherwise.
74
+ */
75
+ remove(in_key: string) {
76
+ const toReturn = super.remove(in_key);
77
+ this._sortedKeys = _.without(this._sortedKeys, in_key);
78
+ return toReturn;
79
+ }
80
+
81
+ /**
82
+ * Copy the items of in_collection to this collection.
83
+ * @returns cloned SortedCollection
84
+ */
85
+ clone(): SortedCollection<T> {
86
+ const newCol = new SortedCollection<T>(this._name, this._type);
87
+ newCol.setComparisonFunction(this._comparisonFunction);
88
+ newCol.bulkAdd(this._items);
89
+ return newCol;
90
+ }
91
+
92
+ /**
93
+ * Internal function use to search (binary search) for the nearest index that
94
+ * the given key would be inserted.
95
+ * i.e. given the array [10, 20, 30, 40, 50] the index that 35 should be inserted at is 3
96
+ * @param in_array - Target array
97
+ * @param in_key - Key to check against
98
+ * @returns The index at which the key would be inserted in
99
+ */
100
+ private _binarySearchNearestIndex(in_array: string[], in_key: string): number {
101
+ if (this._comparisonFunction === undefined) {
102
+ return _.sortedIndex(in_array, in_key);
103
+ } else {
104
+ const middleIndex = Math.floor((in_array.length - 1) / 2);
105
+
106
+ if (middleIndex < 0) {
107
+ return 0;
108
+ }
109
+
110
+ if (this._comparisonFunction(in_array[middleIndex], in_key) > 0) {
111
+ if (in_array.length === 1) {
112
+ return 0;
113
+ }
114
+
115
+ return this._binarySearchNearestIndex(in_array.slice(0, middleIndex), in_key);
116
+ }
117
+
118
+ if (this._comparisonFunction(in_array[middleIndex], in_key) < 0) {
119
+ if (in_array.length === 1) {
120
+ return 1;
121
+ }
122
+
123
+ return (
124
+ middleIndex +
125
+ 1 +
126
+ this._binarySearchNearestIndex(
127
+ in_array.slice(middleIndex + 1, in_array.length),
128
+ in_key,
129
+ )
130
+ );
131
+ }
132
+
133
+ return middleIndex;
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Return the nearest next item to the given key i.e.
139
+ * For the given list of keys ['1.0.1', '2.0.0', '2.2.0', '7.0.1'] the nearest next item to 6.0.1 is
140
+ * the item mapped by '7.0.1'
141
+ * @param in_key - The key to check against in order to get the nearest next item
142
+ * @returns The nearest next item
143
+ */
144
+ getNearestNextItem(in_key: string) {
145
+ const closestNextIndex = this._binarySearchNearestIndex(
146
+ this._sortedKeys,
147
+ in_key.toString(),
148
+ );
149
+ return closestNextIndex === this.getCount()
150
+ ? undefined
151
+ : this.item(this._sortedKeys[closestNextIndex]);
152
+ }
153
+
154
+ /**
155
+ * Return the nearest previous item to the given key i.e.
156
+ * For the given list of keys ['1.0.1', '2.0.0', '2.2.0', '7.0.1'] the nearest previous item to 6.0.1 is
157
+ * the item mapped by '7.0.1'
158
+ * @param in_key - The key to check against in order to get the nearest previous item
159
+ * @returns The nearest previous item
160
+ */
161
+ getNearestPreviousItem(in_key: string | number) {
162
+ const closestPreviousIndex = this._binarySearchNearestIndex(
163
+ this._sortedKeys,
164
+ in_key.toString(),
165
+ );
166
+ return closestPreviousIndex === 0
167
+ ? undefined
168
+ : this.item(this._sortedKeys[closestPreviousIndex - 1]);
169
+ }
160
170
  }
@@ -10,52 +10,53 @@
10
10
  * tasks to terminate. This class becomes useful when combining classic async calls with promises.
11
11
  */
12
12
  export class DeferredPromise<T> implements Promise<T> {
13
- private _resolveSelf;
14
- private _rejectSelf;
15
- private readonly promise: Promise<T>;
13
+ private _resolveSelf;
14
+ private _rejectSelf;
15
+ private readonly promise: Promise<T>;
16
16
 
17
- constructor() {
18
- this.promise = new Promise((resolve, reject) => {
19
- this._resolveSelf = resolve;
20
- this._rejectSelf = reject;
21
- });
22
- }
23
- [Symbol.toStringTag]: string;
17
+ constructor() {
18
+ this.promise = new Promise((resolve, reject) => {
19
+ this._resolveSelf = resolve;
20
+ this._rejectSelf = reject;
21
+ });
22
+ }
23
+ readonly [Symbol.toStringTag]: string = "DeferredPromise";
24
24
 
25
- public async finally(onfinally?: () => void): Promise<T> {
26
- throw new Error("Method not implemented.");
27
- }
25
+ public async finally(onfinally?: () => void): Promise<T> {
26
+ throw new Error("Method not implemented.");
27
+ }
28
28
 
29
- /**
30
- * Fetches a node style callback that fulfills the promise when called.
31
- * @returns A node style callback that fulfills the promise when called.
32
- */
33
- getCb() {
34
- return (error, result) => {
35
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
36
- if (error) {
37
- return this.reject(error);
38
- }
39
- return this.resolve(result);
40
- };
41
- }
29
+ /**
30
+ * Fetches a node style callback that fulfills the promise when called.
31
+ * @returns A node style callback that fulfills the promise when called.
32
+ */
33
+ getCb() {
34
+ return (error, result) => {
35
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
36
+ if (error) {
37
+ return this.reject(error);
38
+ }
39
+ return this.resolve(result);
40
+ };
41
+ }
42
42
 
43
- public async then<TResult1 = T, TResult2 = never>(
44
- onfulfilled?: ((value: T) =>
45
- TResult1 | PromiseLike<TResult1>) | undefined | null,
46
- onrejected?: ((reason: any) =>
47
- TResult2 | PromiseLike<TResult2>) | undefined | null,
48
- ): Promise<TResult1 | TResult2> {
49
- return this.promise.then(onfulfilled, onrejected);
50
- }
43
+ public async then<TResult1 = T, TResult2 = never>(
44
+ onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
45
+ onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
46
+ ): Promise<TResult1 | TResult2> {
47
+ return this.promise.then(onfulfilled, onrejected);
48
+ }
51
49
 
52
- public async catch<TResult = never>(
53
- onrejected?: ((reason: any) =>
54
- TResult | PromiseLike<TResult>) | undefined | null,
55
- ): Promise<T | TResult> {
56
- return this.promise.then(onrejected);
57
- }
50
+ public async catch<TResult = never>(
51
+ onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
52
+ ): Promise<T | TResult> {
53
+ return this.promise.then(onrejected);
54
+ }
58
55
 
59
- public resolve(val: T) { this._resolveSelf(val); }
60
- public reject(reason: any) { this._rejectSelf(reason); }
56
+ public resolve(val: T) {
57
+ this._resolveSelf(val);
58
+ }
59
+ public reject(reason: any) {
60
+ this._rejectSelf(reason);
61
+ }
61
62
  }