@itwin/core-bentley 4.0.0-dev.7 → 4.0.0-dev.72

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 (211) hide show
  1. package/CHANGELOG.md +50 -1
  2. package/lib/cjs/AccessToken.d.ts +10 -10
  3. package/lib/cjs/AccessToken.d.ts.map +1 -1
  4. package/lib/cjs/AccessToken.js +9 -9
  5. package/lib/cjs/Assert.d.ts +25 -25
  6. package/lib/cjs/Assert.js +45 -45
  7. package/lib/cjs/Assert.js.map +1 -1
  8. package/lib/cjs/BeEvent.d.ts +81 -81
  9. package/lib/cjs/BeEvent.d.ts.map +1 -1
  10. package/lib/cjs/BeEvent.js +156 -156
  11. package/lib/cjs/BeSQLite.d.ts +172 -170
  12. package/lib/cjs/BeSQLite.d.ts.map +1 -1
  13. package/lib/cjs/BeSQLite.js +185 -183
  14. package/lib/cjs/BeSQLite.js.map +1 -1
  15. package/lib/cjs/BentleyError.d.ts +378 -378
  16. package/lib/cjs/BentleyError.d.ts.map +1 -1
  17. package/lib/cjs/BentleyError.js +703 -702
  18. package/lib/cjs/BentleyError.js.map +1 -1
  19. package/lib/cjs/BentleyLoggerCategory.d.ts +11 -11
  20. package/lib/cjs/BentleyLoggerCategory.js +19 -19
  21. package/lib/cjs/ByteStream.d.ts +110 -110
  22. package/lib/cjs/ByteStream.js +159 -159
  23. package/lib/cjs/ClassUtils.d.ts +14 -14
  24. package/lib/cjs/ClassUtils.js +27 -27
  25. package/lib/cjs/Compare.d.ts +47 -47
  26. package/lib/cjs/Compare.d.ts.map +1 -1
  27. package/lib/cjs/Compare.js +75 -75
  28. package/lib/cjs/CompressedId64Set.d.ts +134 -134
  29. package/lib/cjs/CompressedId64Set.d.ts.map +1 -1
  30. package/lib/cjs/CompressedId64Set.js +428 -428
  31. package/lib/cjs/CompressedId64Set.js.map +1 -1
  32. package/lib/cjs/Dictionary.d.ts +125 -125
  33. package/lib/cjs/Dictionary.js +203 -203
  34. package/lib/cjs/Disposable.d.ts +80 -80
  35. package/lib/cjs/Disposable.d.ts.map +1 -1
  36. package/lib/cjs/Disposable.js +120 -120
  37. package/lib/cjs/Id.d.ts +285 -285
  38. package/lib/cjs/Id.d.ts.map +1 -1
  39. package/lib/cjs/Id.js +643 -643
  40. package/lib/cjs/IndexMap.d.ts +65 -65
  41. package/lib/cjs/IndexMap.js +91 -91
  42. package/lib/cjs/JsonSchema.d.ts +77 -77
  43. package/lib/cjs/JsonSchema.d.ts.map +1 -1
  44. package/lib/cjs/JsonSchema.js +9 -9
  45. package/lib/cjs/JsonUtils.d.ts +78 -78
  46. package/lib/cjs/JsonUtils.js +151 -151
  47. package/lib/cjs/LRUMap.d.ts +129 -129
  48. package/lib/cjs/LRUMap.js +333 -333
  49. package/lib/cjs/LRUMap.js.map +1 -1
  50. package/lib/cjs/Logger.d.ts +143 -143
  51. package/lib/cjs/Logger.d.ts.map +1 -1
  52. package/lib/cjs/Logger.js +256 -258
  53. package/lib/cjs/Logger.js.map +1 -1
  54. package/lib/cjs/ObservableSet.d.ts +23 -23
  55. package/lib/cjs/ObservableSet.js +51 -51
  56. package/lib/cjs/OneAtATimeAction.d.ts +31 -31
  57. package/lib/cjs/OneAtATimeAction.js +94 -94
  58. package/lib/cjs/OneAtATimeAction.js.map +1 -1
  59. package/lib/cjs/OrderedId64Iterable.d.ts +74 -74
  60. package/lib/cjs/OrderedId64Iterable.d.ts.map +1 -1
  61. package/lib/cjs/OrderedId64Iterable.js +235 -235
  62. package/lib/cjs/OrderedSet.d.ts +40 -40
  63. package/lib/cjs/OrderedSet.js +64 -64
  64. package/lib/cjs/PriorityQueue.d.ts +70 -70
  65. package/lib/cjs/PriorityQueue.d.ts.map +1 -1
  66. package/lib/cjs/PriorityQueue.js +140 -140
  67. package/lib/cjs/ProcessDetector.d.ts +59 -59
  68. package/lib/cjs/ProcessDetector.js +71 -71
  69. package/lib/cjs/SortedArray.d.ts +236 -232
  70. package/lib/cjs/SortedArray.d.ts.map +1 -1
  71. package/lib/cjs/SortedArray.js +315 -303
  72. package/lib/cjs/SortedArray.js.map +1 -1
  73. package/lib/cjs/StatusCategory.d.ts +30 -30
  74. package/lib/cjs/StatusCategory.d.ts.map +1 -1
  75. package/lib/cjs/StatusCategory.js +460 -460
  76. package/lib/cjs/StatusCategory.js.map +1 -1
  77. package/lib/cjs/StringUtils.d.ts +22 -22
  78. package/lib/cjs/StringUtils.js +148 -148
  79. package/lib/cjs/Time.d.ts +122 -122
  80. package/lib/cjs/Time.js +152 -152
  81. package/lib/cjs/Time.js.map +1 -1
  82. package/lib/cjs/Tracing.d.ts +43 -40
  83. package/lib/cjs/Tracing.d.ts.map +1 -1
  84. package/lib/cjs/Tracing.js +134 -130
  85. package/lib/cjs/Tracing.js.map +1 -1
  86. package/lib/cjs/TupleKeyedMap.d.ts +36 -36
  87. package/lib/cjs/TupleKeyedMap.js +102 -102
  88. package/lib/cjs/TypedArrayBuilder.d.ts +155 -155
  89. package/lib/cjs/TypedArrayBuilder.d.ts.map +1 -1
  90. package/lib/cjs/TypedArrayBuilder.js +206 -208
  91. package/lib/cjs/TypedArrayBuilder.js.map +1 -1
  92. package/lib/cjs/UnexpectedErrors.d.ts +43 -43
  93. package/lib/cjs/UnexpectedErrors.d.ts.map +1 -1
  94. package/lib/cjs/UnexpectedErrors.js +68 -68
  95. package/lib/cjs/UnexpectedErrors.js.map +1 -1
  96. package/lib/cjs/UtilityTypes.d.ts +112 -96
  97. package/lib/cjs/UtilityTypes.d.ts.map +1 -1
  98. package/lib/cjs/UtilityTypes.js +40 -40
  99. package/lib/cjs/UtilityTypes.js.map +1 -1
  100. package/lib/cjs/YieldManager.d.ts +18 -18
  101. package/lib/cjs/YieldManager.js +34 -34
  102. package/lib/cjs/core-bentley.d.ts +74 -74
  103. package/lib/cjs/core-bentley.js +94 -90
  104. package/lib/cjs/core-bentley.js.map +1 -1
  105. package/lib/cjs/partitionArray.d.ts +21 -21
  106. package/lib/cjs/partitionArray.js +43 -43
  107. package/lib/esm/AccessToken.d.ts +10 -10
  108. package/lib/esm/AccessToken.d.ts.map +1 -1
  109. package/lib/esm/AccessToken.js +8 -8
  110. package/lib/esm/Assert.d.ts +25 -25
  111. package/lib/esm/Assert.js +41 -41
  112. package/lib/esm/Assert.js.map +1 -1
  113. package/lib/esm/BeEvent.d.ts +81 -81
  114. package/lib/esm/BeEvent.d.ts.map +1 -1
  115. package/lib/esm/BeEvent.js +150 -150
  116. package/lib/esm/BeSQLite.d.ts +172 -170
  117. package/lib/esm/BeSQLite.d.ts.map +1 -1
  118. package/lib/esm/BeSQLite.js +182 -180
  119. package/lib/esm/BeSQLite.js.map +1 -1
  120. package/lib/esm/BentleyError.d.ts +378 -378
  121. package/lib/esm/BentleyError.d.ts.map +1 -1
  122. package/lib/esm/BentleyError.js +699 -698
  123. package/lib/esm/BentleyError.js.map +1 -1
  124. package/lib/esm/BentleyLoggerCategory.d.ts +11 -11
  125. package/lib/esm/BentleyLoggerCategory.js +16 -16
  126. package/lib/esm/ByteStream.d.ts +110 -110
  127. package/lib/esm/ByteStream.js +155 -155
  128. package/lib/esm/ClassUtils.d.ts +14 -14
  129. package/lib/esm/ClassUtils.js +22 -22
  130. package/lib/esm/Compare.d.ts +47 -47
  131. package/lib/esm/Compare.d.ts.map +1 -1
  132. package/lib/esm/Compare.js +63 -63
  133. package/lib/esm/CompressedId64Set.d.ts +134 -134
  134. package/lib/esm/CompressedId64Set.d.ts.map +1 -1
  135. package/lib/esm/CompressedId64Set.js +423 -423
  136. package/lib/esm/CompressedId64Set.js.map +1 -1
  137. package/lib/esm/Dictionary.d.ts +125 -125
  138. package/lib/esm/Dictionary.js +199 -199
  139. package/lib/esm/Disposable.d.ts +80 -80
  140. package/lib/esm/Disposable.d.ts.map +1 -1
  141. package/lib/esm/Disposable.js +112 -112
  142. package/lib/esm/Id.d.ts +285 -285
  143. package/lib/esm/Id.d.ts.map +1 -1
  144. package/lib/esm/Id.js +639 -639
  145. package/lib/esm/IndexMap.d.ts +65 -65
  146. package/lib/esm/IndexMap.js +86 -86
  147. package/lib/esm/JsonSchema.d.ts +77 -77
  148. package/lib/esm/JsonSchema.d.ts.map +1 -1
  149. package/lib/esm/JsonSchema.js +8 -8
  150. package/lib/esm/JsonUtils.d.ts +78 -78
  151. package/lib/esm/JsonUtils.js +148 -148
  152. package/lib/esm/LRUMap.d.ts +129 -129
  153. package/lib/esm/LRUMap.js +326 -326
  154. package/lib/esm/LRUMap.js.map +1 -1
  155. package/lib/esm/Logger.d.ts +143 -143
  156. package/lib/esm/Logger.d.ts.map +1 -1
  157. package/lib/esm/Logger.js +253 -253
  158. package/lib/esm/Logger.js.map +1 -1
  159. package/lib/esm/ObservableSet.d.ts +23 -23
  160. package/lib/esm/ObservableSet.js +47 -47
  161. package/lib/esm/OneAtATimeAction.d.ts +31 -31
  162. package/lib/esm/OneAtATimeAction.js +89 -89
  163. package/lib/esm/OneAtATimeAction.js.map +1 -1
  164. package/lib/esm/OrderedId64Iterable.d.ts +74 -74
  165. package/lib/esm/OrderedId64Iterable.d.ts.map +1 -1
  166. package/lib/esm/OrderedId64Iterable.js +232 -232
  167. package/lib/esm/OrderedSet.d.ts +40 -40
  168. package/lib/esm/OrderedSet.js +59 -59
  169. package/lib/esm/PriorityQueue.d.ts +70 -70
  170. package/lib/esm/PriorityQueue.d.ts.map +1 -1
  171. package/lib/esm/PriorityQueue.js +136 -136
  172. package/lib/esm/ProcessDetector.d.ts +59 -59
  173. package/lib/esm/ProcessDetector.js +67 -67
  174. package/lib/esm/SortedArray.d.ts +236 -232
  175. package/lib/esm/SortedArray.d.ts.map +1 -1
  176. package/lib/esm/SortedArray.js +308 -296
  177. package/lib/esm/SortedArray.js.map +1 -1
  178. package/lib/esm/StatusCategory.d.ts +30 -30
  179. package/lib/esm/StatusCategory.d.ts.map +1 -1
  180. package/lib/esm/StatusCategory.js +455 -454
  181. package/lib/esm/StatusCategory.js.map +1 -1
  182. package/lib/esm/StringUtils.d.ts +22 -22
  183. package/lib/esm/StringUtils.js +142 -142
  184. package/lib/esm/Time.d.ts +122 -122
  185. package/lib/esm/Time.js +146 -146
  186. package/lib/esm/Time.js.map +1 -1
  187. package/lib/esm/Tracing.d.ts +43 -40
  188. package/lib/esm/Tracing.d.ts.map +1 -1
  189. package/lib/esm/Tracing.js +130 -126
  190. package/lib/esm/Tracing.js.map +1 -1
  191. package/lib/esm/TupleKeyedMap.d.ts +36 -36
  192. package/lib/esm/TupleKeyedMap.js +98 -98
  193. package/lib/esm/TypedArrayBuilder.d.ts +155 -155
  194. package/lib/esm/TypedArrayBuilder.d.ts.map +1 -1
  195. package/lib/esm/TypedArrayBuilder.js +198 -200
  196. package/lib/esm/TypedArrayBuilder.js.map +1 -1
  197. package/lib/esm/UnexpectedErrors.d.ts +43 -43
  198. package/lib/esm/UnexpectedErrors.d.ts.map +1 -1
  199. package/lib/esm/UnexpectedErrors.js +65 -64
  200. package/lib/esm/UnexpectedErrors.js.map +1 -1
  201. package/lib/esm/UtilityTypes.d.ts +112 -96
  202. package/lib/esm/UtilityTypes.d.ts.map +1 -1
  203. package/lib/esm/UtilityTypes.js +34 -34
  204. package/lib/esm/UtilityTypes.js.map +1 -1
  205. package/lib/esm/YieldManager.d.ts +18 -18
  206. package/lib/esm/YieldManager.js +30 -30
  207. package/lib/esm/core-bentley.d.ts +74 -74
  208. package/lib/esm/core-bentley.js +78 -78
  209. package/lib/esm/partitionArray.d.ts +21 -21
  210. package/lib/esm/partitionArray.js +39 -39
  211. package/package.json +9 -9
package/lib/esm/Id.js CHANGED
@@ -1,640 +1,640 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
- * See LICENSE.md in the project root for license terms and full copyright notice.
4
- *--------------------------------------------------------------------------------------------*/
5
- /** @packageDocumentation
6
- * @module Ids
7
- */
8
- function toHex(str) {
9
- const v = parseInt(str, 16);
10
- return Number.isNaN(v) ? 0 : v;
11
- }
12
- function isLowerCaseNonZeroHexDigit(str, index) {
13
- return isLowerCaseHexDigit(str, index, false);
14
- }
15
- function isLowerCaseHexDigit(str, index, allowZero = true) {
16
- const charCode = str.charCodeAt(index);
17
- const minDecimalDigit = allowZero ? 0x30 : 0x31; // '0' or '1'...
18
- return (charCode >= minDecimalDigit && charCode <= 0x39) || (charCode >= 0x61 && charCode <= 0x66); // '0'-'9, 'a' -'f'
19
- }
20
- function isValidHexString(id, startIndex, len) {
21
- if (len === 0)
22
- return false;
23
- // No leading zeroes...
24
- if (!isLowerCaseNonZeroHexDigit(id, startIndex))
25
- return false;
26
- // ...followed by len-1 lowercase hexadecimal digits.
27
- for (let i = 1; i < len; i++)
28
- if (!isLowerCaseHexDigit(id, startIndex + i))
29
- return false;
30
- return true;
31
- }
32
- /**
33
- * The Id64 namespace provides facilities for working with 64-bit identifiers. These Ids are stored as 64-bit integers inside an [[IModelDb]], but must be represented
34
- * as strings in JavaScript because JavaScript does not intrinsically support 64-bit integers.
35
- *
36
- * The [[Id64String]] type alias is used to indicate function arguments, return types, and variables which are known to contain a well-formed representation of a 64-bit Id.
37
- *
38
- * See [Working with Ids]($docs/learning/common/Id64.md) for a detailed description and code examples.
39
- * @public
40
- */
41
- export var Id64;
42
- (function (Id64) {
43
- /** Extract the "local" Id portion of an Id64String, contained in the lower 40 bits of the 64-bit value. */
44
- function getLocalId(id) {
45
- if (isInvalid(id))
46
- return 0;
47
- const len = id.length;
48
- const start = (len > 12) ? (len - 10) : 2;
49
- return toHex(id.slice(start));
50
- }
51
- Id64.getLocalId = getLocalId;
52
- /** Extract the briefcase Id portion of an Id64String, contained in the upper 24 bits of the 64-bit value. */
53
- function getBriefcaseId(id) {
54
- if (isInvalid(id))
55
- return 0;
56
- const len = id.length;
57
- return (len <= 12) ? 0 : toHex(id.slice(2, len - 10));
58
- }
59
- Id64.getBriefcaseId = getBriefcaseId;
60
- /** Create an Id64String from its JSON representation.
61
- * @param prop The JSON representation of an Id.
62
- * @returns A well-formed Id string.
63
- * @note if the input is undefined, the result is "0", indicating an invalid Id.
64
- * @note if the input is not undefined, the result is the same as that of [[Id64.fromString]].
65
- */
66
- function fromJSON(prop) {
67
- return typeof prop === "string" ? Id64.fromString(prop) : Id64.invalid;
68
- }
69
- Id64.fromJSON = fromJSON;
70
- /** Given a string value, attempt to normalize it into a well-formed Id string.
71
- * If the input is already a well-formed Id string, it is returned unmodified.
72
- * Otherwise, the input is trimmed of leading and trailing whitespace, converted to lowercase, and an attempt is made to parse it as a 64-bit hexadecimal integer.
73
- * If parsing succeeds the normalized result is returned; otherwise the result is "0", indicating an invalid Id.
74
- *
75
- * For a description of "well-formed", see [Working with Ids]($docs/learning/common/Id64.md).
76
- */
77
- function fromString(val) {
78
- // NB: in case this is called from JavaScript, we must check the run-time type...
79
- if (typeof val !== "string")
80
- return Id64.invalid;
81
- // Skip the common case in which the input is already a well-formed Id string
82
- if (Id64.isId64(val))
83
- return val;
84
- // Attempt to normalize the input into a well-formed Id string
85
- val = val.toLowerCase().trim();
86
- const len = val.length;
87
- if (len < 2 || val[0] !== "0" || val[1] !== "x")
88
- return Id64.invalid;
89
- let low = 0;
90
- let high = 0;
91
- let start = 2;
92
- if (len > 12) {
93
- start = (len - 10);
94
- high = toHex(val.slice(2, start));
95
- }
96
- low = toHex(val.slice(start));
97
- return fromLocalAndBriefcaseIds(low, high);
98
- }
99
- Id64.fromString = fromString;
100
- // Used when constructing local ID portion of Id64String. Performance optimization.
101
- const _localIdPrefixByLocalIdLength = [
102
- "0000000000",
103
- "000000000",
104
- "00000000",
105
- "0000000",
106
- "000000",
107
- "00000",
108
- "0000",
109
- "000",
110
- "00",
111
- "0",
112
- "",
113
- ];
114
- /** Produce an Id string from a local and briefcase Id.
115
- * @param localId The non-zero local Id as an unsigned 40-bit integer.
116
- * @param briefcaseId The briefcase Id as an unsigned 24-bit integer.
117
- * @returns an Id64String containing the hexadecimal string representation of the unsigned 64-bit integer which would result from the
118
- * operation `localId | (briefcaseId << 40)`, or an invalid Id "0" if the inputs are invalid.
119
- */
120
- function fromLocalAndBriefcaseIds(localId, briefcaseId) {
121
- // NB: Yes, we must check the run-time type...
122
- if (typeof localId !== "number" || typeof briefcaseId !== "number")
123
- return Id64.invalid;
124
- localId = Math.floor(localId);
125
- if (0 === localId)
126
- return Id64.invalid;
127
- briefcaseId = Math.floor(briefcaseId);
128
- const lowStr = localId.toString(16);
129
- return `0x${(briefcaseId === 0) ? lowStr : (briefcaseId.toString(16) + (_localIdPrefixByLocalIdLength[lowStr.length] + lowStr))}`;
130
- }
131
- Id64.fromLocalAndBriefcaseIds = fromLocalAndBriefcaseIds;
132
- // Used as a buffer when converting a pair of 32-bit integers to an Id64String. Significant performance optimization.
133
- const scratchCharCodes = [
134
- 0x30,
135
- 0x78,
136
- 0x30,
137
- 0x30,
138
- 0x30,
139
- 0x30,
140
- 0x30,
141
- 0x30,
142
- 0x30,
143
- 0x30,
144
- 0x30,
145
- 0x30,
146
- 0x30,
147
- 0x30,
148
- 0x30,
149
- 0x30,
150
- 0x30,
151
- 0x30,
152
- ];
153
- // Convert 4-bit unsigned integer to char code representing lower-case hexadecimal digit.
154
- function uint4ToCharCode(uint4) {
155
- return uint4 + (uint4 < 10 ? 0x30 : 0x57);
156
- }
157
- // Convert char code representing lower-case hexadecimal digit to 4-bit unsigned integer.
158
- function charCodeToUint4(char) {
159
- return char - (char >= 0x57 ? 0x57 : 0x30);
160
- }
161
- // Convert a substring to a uint32. This is twice as fast as using Number.parseInt().
162
- function substringToUint32(id, start, end) {
163
- let uint32 = 0;
164
- for (let i = start; i < end; i++) {
165
- const uint4 = charCodeToUint4(id.charCodeAt(i));
166
- const shift = (end - i - 1) << 2;
167
- const mask = uint4 << shift;
168
- uint32 = (uint32 | mask) >>> 0; // >>> 0 to force unsigned because javascript
169
- }
170
- return uint32;
171
- }
172
- /** Create an Id64String from a pair of unsigned 32-bit integers.
173
- * @param lowBytes The lower 4 bytes of the Id
174
- * @param highBytes The upper 4 bytes of the Id
175
- * @returns an Id64String containing the hexadecimal string representation of the unsigned 64-bit integer which would result from the
176
- * operation `lowBytes | (highBytes << 32)`.
177
- * @see [[Id64.fromUint32PairObject]] if you have a [[Id64.Uint32Pair]] object.
178
- */
179
- function fromUint32Pair(lowBytes, highBytes) {
180
- const localIdLow = lowBytes >>> 0;
181
- const localIdHigh = (highBytes & 0x000000ff) * (0xffffffff + 1); // aka (highBytes & 0xff) << 32
182
- const localId = localIdLow + localIdHigh; // aka localIdLow | localIdHigh
183
- if (0 === localId)
184
- return Id64.invalid;
185
- // Need to omit or preserve leading zeroes...
186
- const buffer = scratchCharCodes;
187
- let index = 2;
188
- for (let i = 7; i >= 0; i--) {
189
- const shift = i << 2;
190
- const mask = 0xf << shift;
191
- const uint4 = (highBytes & mask) >>> shift;
192
- if (index > 2 || 0 !== uint4)
193
- buffer[index++] = uint4ToCharCode(uint4);
194
- }
195
- for (let i = 7; i >= 0; i--) {
196
- const shift = i << 2;
197
- const mask = 0xf << shift;
198
- const uint4 = (lowBytes & mask) >>> shift;
199
- if (index > 2 || 0 !== uint4)
200
- buffer[index++] = uint4ToCharCode(uint4);
201
- }
202
- if (buffer.length !== index)
203
- buffer.length = index;
204
- return String.fromCharCode(...scratchCharCodes);
205
- }
206
- Id64.fromUint32Pair = fromUint32Pair;
207
- /** Create an Id64String from a [[Id64.Uint32Pair]].
208
- * @see [[Id64.fromUint32Pair]].
209
- */
210
- function fromUint32PairObject(pair) {
211
- return fromUint32Pair(pair.lower, pair.upper);
212
- }
213
- Id64.fromUint32PairObject = fromUint32PairObject;
214
- /** Returns true if the inputs represent two halves of a valid 64-bit Id.
215
- * @see [[Id64.Uint32Pair]].
216
- */
217
- function isValidUint32Pair(lowBytes, highBytes) {
218
- // Detect local ID of zero
219
- return 0 !== lowBytes || 0 !== (highBytes & 0x000000ff);
220
- }
221
- Id64.isValidUint32Pair = isValidUint32Pair;
222
- /** Convert an Id64String to a 64-bit unsigned integer represented as a pair of unsigned 32-bit integers.
223
- * @param id The well-formed string representation of a 64-bit Id.
224
- * @param out Used as the return value if supplied; otherwise a new object is returned.
225
- * @returns An object containing the parsed lower and upper 32-bit integers comprising the 64-bit Id.
226
- */
227
- function getUint32Pair(id, out) {
228
- if (!out)
229
- out = { lower: 0, upper: 0 };
230
- out.lower = getLowerUint32(id);
231
- out.upper = getUpperUint32(id);
232
- return out;
233
- }
234
- Id64.getUint32Pair = getUint32Pair;
235
- /** Extract an unsigned 32-bit integer from the lower 4 bytes of an Id64String. */
236
- function getLowerUint32(id) {
237
- if (isInvalid(id))
238
- return 0;
239
- const end = id.length;
240
- const start = end > 10 ? end - 8 : 2;
241
- return substringToUint32(id, start, end);
242
- }
243
- Id64.getLowerUint32 = getLowerUint32;
244
- /** Extract an unsigned 32-bit integer from the upper 4 bytes of an Id64String. */
245
- function getUpperUint32(id) {
246
- const len = id.length;
247
- if (len <= 10 || isInvalid(id))
248
- return 0;
249
- return substringToUint32(id, 2, len - 8);
250
- }
251
- Id64.getUpperUint32 = getUpperUint32;
252
- /** Convert an [[Id64Arg]] into an [[Id64Set]].
253
- *
254
- * This method can be used by functions that accept an Id64Arg to conveniently process the value(s). For example:
255
- * ```ts
256
- * public addCategories(arg: Id64Arg) { Id64.toIdSet(arg).forEach((id) => this.categories.add(id)); }
257
- * ```
258
- *
259
- * Alternatively, to avoid allocating a new Id64Set, use [[Id64.iterable]].
260
- *
261
- * @param arg The Ids to convert to an Id64Set.
262
- * @param makeCopy If true, and the input is already an Id64Set, returns a deep copy of the input.
263
- * @returns An Id64Set containing the set of [[Id64String]]s represented by the Id64Arg.
264
- */
265
- function toIdSet(arg, makeCopy = false) {
266
- if (arg instanceof Set)
267
- return makeCopy ? new Set(arg) : arg;
268
- const ids = new Set();
269
- if (typeof arg === "string")
270
- ids.add(arg);
271
- else if (Array.isArray(arg)) {
272
- arg.forEach((id) => {
273
- if (typeof id === "string")
274
- ids.add(id);
275
- });
276
- }
277
- return ids;
278
- }
279
- Id64.toIdSet = toIdSet;
280
- /** Obtain iterator over the specified Ids.
281
- * @see [[Id64.iterable]].
282
- */
283
- function* iterator(ids) {
284
- if (typeof ids === "string") {
285
- yield ids;
286
- }
287
- else {
288
- for (const id of ids)
289
- yield id;
290
- }
291
- }
292
- Id64.iterator = iterator;
293
- /** Obtain an iterable over the specified Ids. Example usage:
294
- * ```ts
295
- * const ids = ["0x123", "0xfed"];
296
- * for (const id of Id64.iterable(ids))
297
- * console.log(id);
298
- * ```
299
- */
300
- function iterable(ids) {
301
- return {
302
- [Symbol.iterator]: () => iterator(ids),
303
- };
304
- }
305
- Id64.iterable = iterable;
306
- /** Return the first [[Id64String]] of an [[Id64Arg]]. */
307
- function getFirst(arg) {
308
- return typeof arg === "string" ? arg : (Array.isArray(arg) ? arg[0] : arg.values().next().value);
309
- }
310
- Id64.getFirst = getFirst;
311
- /** Return the number of [[Id64String]]s represented by an [[Id64Arg]]. */
312
- function sizeOf(arg) {
313
- return typeof arg === "string" ? 1 : (Array.isArray(arg) ? arg.length : arg.size);
314
- }
315
- Id64.sizeOf = sizeOf;
316
- /** Returns true if the [[Id64Arg]] contains the specified Id. */
317
- function has(arg, id) {
318
- if (typeof arg === "string")
319
- return arg === id;
320
- if (Array.isArray(arg))
321
- return -1 !== arg.indexOf(id);
322
- return arg.has(id);
323
- }
324
- Id64.has = has;
325
- /** The string representation of an invalid Id. */
326
- Id64.invalid = "0";
327
- /** Determine if the supplied id string represents a transient Id.
328
- * @param id A well-formed Id string.
329
- * @returns true if the Id represents a transient Id.
330
- * @note This method assumes the input is a well-formed Id string.
331
- * @see [[Id64.isTransientId64]]
332
- * @see [[TransientIdSequence]]
333
- */
334
- function isTransient(id) {
335
- // A transient Id is of the format "0xffffffxxxxxxxxxx" where the leading 6 digits indicate an invalid briefcase Id.
336
- return 18 === id.length && id.startsWith("0xffffff");
337
- }
338
- Id64.isTransient = isTransient;
339
- /** Determine if the input is a well-formed [[Id64String]] and represents a transient Id.
340
- * @see [[Id64.isTransient]]
341
- * @see [[Id64.isId64]]
342
- * @see [[TransientIdSequence]]
343
- */
344
- function isTransientId64(id) {
345
- return isValidId64(id) && isTransient(id);
346
- }
347
- Id64.isTransientId64 = isTransientId64;
348
- /** Determine if the input is a well-formed [[Id64String]].
349
- *
350
- * For a description of "well-formed", see [Working with Ids]($docs/learning/common/Id64.md).
351
- * @see [[Id64.isValidId64]]
352
- */
353
- function isId64(id) {
354
- const len = id.length;
355
- if (0 === len || 18 < len)
356
- return false;
357
- if ("0" !== id[0])
358
- return false;
359
- // Well-formed invalid Id: "0"
360
- if (1 === len)
361
- return true;
362
- // Valid Ids begin with "0x" followed by at least one lower-case hexadecimal digit.
363
- if (2 === len || "x" !== id[1])
364
- return false;
365
- // If briefcase Id is present, it occupies at least one digit, followed by 10 digits for local Id
366
- let localIdStart = 2;
367
- if (len > 12) {
368
- localIdStart = len - 10;
369
- // Verify briefcase Id
370
- if (!isValidHexString(id, 2, localIdStart - 2))
371
- return false;
372
- // Skip leading zeroes in local Id
373
- for (let i = localIdStart; i < len; i++) {
374
- if (0x30 !== id.charCodeAt(i)) // '0'
375
- break;
376
- else
377
- localIdStart++;
378
- }
379
- if (localIdStart >= len)
380
- return false;
381
- }
382
- return isValidHexString(id, localIdStart, len - localIdStart);
383
- }
384
- Id64.isId64 = isId64;
385
- /** Returns true if the input is not equal to the representation of an invalid Id.
386
- * @note This method assumes the input is a well-formed Id string.
387
- * @see [[Id64.isInvalid]]
388
- * @see [[Id64.isValidId64]]
389
- */
390
- function isValid(id) {
391
- return Id64.invalid !== id;
392
- }
393
- Id64.isValid = isValid;
394
- /** Returns true if the input is a well-formed [[Id64String]] representing a valid Id.
395
- * @see [[Id64.isValid]]
396
- * @see [[Id64.isId64]]
397
- */
398
- function isValidId64(id) {
399
- return Id64.invalid !== id && Id64.isId64(id);
400
- }
401
- Id64.isValidId64 = isValidId64;
402
- /** Returns true if the input is a well-formed [[Id64String]] representing an invalid Id.
403
- * @see [[Id64.isValid]]
404
- */
405
- function isInvalid(id) {
406
- return Id64.invalid === id;
407
- }
408
- Id64.isInvalid = isInvalid;
409
- /** A specialized replacement for Set<Id64String> optimized for performance-critical code which represents large sets of [[Id64]]s as pairs of
410
- * 32-bit integers.
411
- * The internal representation is a Map<number, Set<number>> where the Map key is the upper 4 bytes of the IDs and the Set elements are the lower 4 bytes of the IDs.
412
- * Because the upper 4 bytes store the 24-bit briefcase ID plus the upper 8 bits of the local ID, there will be a very small distribution of unique Map keys.
413
- * To further optimize this data type, the following assumptions are made regarding the { lower, upper } inputs, and no validation is performed to confirm them:
414
- * - The inputs are unsigned 32-bit integers;
415
- * - The inputs represent a valid Id64String (e.g., local ID is not zero).
416
- * @see [[Id64.Uint32Map]] for a similarly-optimized replacement for Map<Id64String, T>
417
- * @public
418
- */
419
- class Uint32Set {
420
- /** Construct a new Uint32Set.
421
- * @param ids If supplied, all of the specified Ids will be added to the new set.
422
- */
423
- constructor(ids) {
424
- this._map = new Map();
425
- if (undefined !== ids)
426
- this.addIds(ids);
427
- }
428
- /** Remove all contents of this set. */
429
- clear() {
430
- this._map.clear();
431
- }
432
- /** Add an Id to the set. */
433
- addId(id) {
434
- this.add(Id64.getLowerUint32(id), Id64.getUpperUint32(id));
435
- }
436
- /** Add any number of Ids to the set. */
437
- addIds(ids) {
438
- for (const id of Id64.iterable(ids))
439
- this.addId(id);
440
- }
441
- /** Returns true if the set contains the specified Id. */
442
- hasId(id) { return this.has(Id64.getLowerUint32(id), Id64.getUpperUint32(id)); }
443
- /** Add an Id to the set. */
444
- add(low, high) {
445
- let set = this._map.get(high);
446
- if (undefined === set) {
447
- set = new Set();
448
- this._map.set(high, set);
449
- }
450
- set.add(low);
451
- }
452
- /** Remove an Id from the set. */
453
- deleteId(id) {
454
- this.delete(Id64.getLowerUint32(id), Id64.getUpperUint32(id));
455
- }
456
- /** Remove any number of Ids from the set. */
457
- deleteIds(ids) {
458
- for (const id of Id64.iterable(ids))
459
- this.deleteId(id);
460
- }
461
- /** Remove an Id from the set. */
462
- delete(low, high) {
463
- const set = this._map.get(high);
464
- if (undefined !== set)
465
- set.delete(low);
466
- }
467
- /** Returns true if the set contains the specified Id. */
468
- has(low, high) {
469
- const set = this._map.get(high);
470
- return undefined !== set && set.has(low);
471
- }
472
- /** Returns true if the set contains the Id specified by `pair`. */
473
- hasPair(pair) {
474
- return this.has(pair.lower, pair.upper);
475
- }
476
- /** Returns true if the set contains no Ids. */
477
- get isEmpty() { return 0 === this._map.size; }
478
- /** Returns the number of Ids contained in the set. */
479
- get size() {
480
- let size = 0;
481
- for (const entry of this._map)
482
- size += entry[1].size;
483
- return size;
484
- }
485
- /** Populates and returns an array of all Ids contained in the set. */
486
- toId64Array() {
487
- const ids = [];
488
- for (const entry of this._map)
489
- for (const low of entry[1])
490
- ids.push(Id64.fromUint32Pair(low, entry[0]));
491
- return ids;
492
- }
493
- /** Populates and returns a set of all Ids contained in the set. */
494
- toId64Set() {
495
- const ids = new Set();
496
- for (const entry of this._map)
497
- for (const low of entry[1])
498
- ids.add(Id64.fromUint32Pair(low, entry[0]));
499
- return ids;
500
- }
501
- /** Execute a function against each Id in this set. */
502
- forEach(func) {
503
- for (const entry of this._map)
504
- for (const lo of entry[1])
505
- func(lo, entry[0]);
506
- }
507
- }
508
- Id64.Uint32Set = Uint32Set;
509
- /** A specialized replacement for Map<Id64String, T> optimized for performance-critical code.
510
- * @see [[Id64.Uint32Set]] for implementation details.
511
- * @public
512
- */
513
- class Uint32Map {
514
- constructor() {
515
- this._map = new Map();
516
- }
517
- /** Remove all entries from the map. */
518
- clear() { this._map.clear(); }
519
- /** Find an entry in the map by Id. */
520
- getById(id) { return this.get(Id64.getLowerUint32(id), Id64.getUpperUint32(id)); }
521
- /** Set an entry in the map by Id. */
522
- setById(id, value) { this.set(Id64.getLowerUint32(id), Id64.getUpperUint32(id), value); }
523
- /** Set an entry in the map by Id components. */
524
- set(low, high, value) {
525
- let map = this._map.get(high);
526
- if (undefined === map) {
527
- map = new Map();
528
- this._map.set(high, map);
529
- }
530
- map.set(low, value);
531
- }
532
- /** Get an entry from the map by Id components. */
533
- get(low, high) {
534
- const map = this._map.get(high);
535
- return undefined !== map ? map.get(low) : undefined;
536
- }
537
- /** Returns true if the map contains no entries. */
538
- get isEmpty() { return 0 === this._map.size; }
539
- /** Returns the number of entries in the map. */
540
- get size() {
541
- let size = 0;
542
- for (const entry of this._map)
543
- size += entry[1].size;
544
- return size;
545
- }
546
- /** Execute a function against each entry in this map. */
547
- forEach(func) {
548
- for (const outerEntry of this._map)
549
- for (const innerEntry of outerEntry[1])
550
- func(innerEntry[0], outerEntry[0], innerEntry[1]);
551
- }
552
- }
553
- Id64.Uint32Map = Uint32Map;
554
- })(Id64 || (Id64 = {}));
555
- /**
556
- * Generates unique [[Id64String]] values in sequence, which are guaranteed not to conflict with Ids associated with persistent elements or models.
557
- * This is useful for associating stable, non-persistent identifiers with things like [Decorator]($frontend)s.
558
- * A TransientIdSequence can generate a maximum of (2^40)-2 unique Ids.
559
- * @public
560
- */
561
- export class TransientIdSequence {
562
- constructor() {
563
- this._localId = 0;
564
- }
565
- /** Generate and return the next transient Id64String in the sequence.
566
- * @deprecated in 3.x. Use [[getNext]].
567
- */
568
- get next() {
569
- return this.getNext();
570
- }
571
- /** Generate and return the next transient Id64String in the sequence. */
572
- getNext() {
573
- return Id64.fromLocalAndBriefcaseIds(++this._localId, 0xffffff);
574
- }
575
- /** Preview the transient Id64String that will be returned by the next call to [[getNext]].
576
- * This is primarily useful for tests.
577
- */
578
- peekNext() {
579
- return Id64.fromLocalAndBriefcaseIds(this._localId + 1, 0xffffff);
580
- }
581
- }
582
- /**
583
- * The Guid namespace provides facilities for working with GUID strings using the "8-4-4-4-12" pattern.
584
- *
585
- * The [[GuidString]] type alias is used to indicate function arguments, return types, and variables which are known to
586
- * be in the GUID format.
587
- * @public
588
- */
589
- export var Guid;
590
- (function (Guid) {
591
- const uuidPattern = new RegExp("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
592
- /** Represents the empty Guid 00000000-0000-0000-0000-000000000000 */
593
- Guid.empty = "00000000-0000-0000-0000-000000000000";
594
- /** Determine whether the input string is "guid-like". That is, it follows the 8-4-4-4-12 pattern. This does not enforce
595
- * that the string is actually in valid UUID format.
596
- */
597
- function isGuid(value) {
598
- return uuidPattern.test(value);
599
- }
600
- Guid.isGuid = isGuid;
601
- /** Determine whether the input string is a valid V4 Guid string */
602
- function isV4Guid(value) {
603
- return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/.test(value);
604
- }
605
- Guid.isV4Guid = isV4Guid;
606
- /** Create a new V4 Guid value */
607
- function createValue() {
608
- // https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
609
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
610
- const r = Math.random() * 16 | 0;
611
- const v = c === "x" ? r : (r & 0x3 | 0x8);
612
- return v.toString(16);
613
- });
614
- }
615
- Guid.createValue = createValue;
616
- /**
617
- * Normalize a Guid string if possible. Normalization consists of:
618
- * - Convert all characters to lower case
619
- * - Trim any leading or trailing whitespace
620
- * - Convert to the standard Guid format "8-4-4-4-12", repositioning the '-' characters as necessary, presuming there are exactly 32 hexadecimal digits.
621
- * @param value Input value that represents a Guid
622
- * @returns Normalized representation of the Guid string. If the normalization fails, return the *original* value unmodified (Note: it is *not* a valid Guid)
623
- */
624
- function normalize(value) {
625
- const lowerValue = value.toLowerCase().trim();
626
- // Return if it's already formatted to be a Guid
627
- if (isGuid(lowerValue))
628
- return lowerValue;
629
- // Remove any existing "-" characters and position them properly, if there remains exactly 32 hexadecimal digits
630
- const noDashValue = lowerValue.replace(/-/g, "");
631
- const noDashPattern = /^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/;
632
- if (noDashPattern.test(noDashValue)) {
633
- return noDashValue.replace(noDashPattern, (_match, p1, p2, p3, p4, p5) => `${p1}-${p2}-${p3}-${p4}-${p5}`);
634
- }
635
- // Return unmodified string - (note: it is *not* a valid Guid)
636
- return value;
637
- }
638
- Guid.normalize = normalize;
639
- })(Guid || (Guid = {}));
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /** @packageDocumentation
6
+ * @module Ids
7
+ */
8
+ function toHex(str) {
9
+ const v = parseInt(str, 16);
10
+ return Number.isNaN(v) ? 0 : v;
11
+ }
12
+ function isLowerCaseNonZeroHexDigit(str, index) {
13
+ return isLowerCaseHexDigit(str, index, false);
14
+ }
15
+ function isLowerCaseHexDigit(str, index, allowZero = true) {
16
+ const charCode = str.charCodeAt(index);
17
+ const minDecimalDigit = allowZero ? 0x30 : 0x31; // '0' or '1'...
18
+ return (charCode >= minDecimalDigit && charCode <= 0x39) || (charCode >= 0x61 && charCode <= 0x66); // '0'-'9, 'a' -'f'
19
+ }
20
+ function isValidHexString(id, startIndex, len) {
21
+ if (len === 0)
22
+ return false;
23
+ // No leading zeroes...
24
+ if (!isLowerCaseNonZeroHexDigit(id, startIndex))
25
+ return false;
26
+ // ...followed by len-1 lowercase hexadecimal digits.
27
+ for (let i = 1; i < len; i++)
28
+ if (!isLowerCaseHexDigit(id, startIndex + i))
29
+ return false;
30
+ return true;
31
+ }
32
+ /**
33
+ * The Id64 namespace provides facilities for working with 64-bit identifiers. These Ids are stored as 64-bit integers inside an [[IModelDb]], but must be represented
34
+ * as strings in JavaScript because JavaScript does not intrinsically support 64-bit integers.
35
+ *
36
+ * The [[Id64String]] type alias is used to indicate function arguments, return types, and variables which are known to contain a well-formed representation of a 64-bit Id.
37
+ *
38
+ * See [Working with Ids]($docs/learning/common/Id64.md) for a detailed description and code examples.
39
+ * @public
40
+ */
41
+ export var Id64;
42
+ (function (Id64) {
43
+ /** Extract the "local" Id portion of an Id64String, contained in the lower 40 bits of the 64-bit value. */
44
+ function getLocalId(id) {
45
+ if (isInvalid(id))
46
+ return 0;
47
+ const len = id.length;
48
+ const start = (len > 12) ? (len - 10) : 2;
49
+ return toHex(id.slice(start));
50
+ }
51
+ Id64.getLocalId = getLocalId;
52
+ /** Extract the briefcase Id portion of an Id64String, contained in the upper 24 bits of the 64-bit value. */
53
+ function getBriefcaseId(id) {
54
+ if (isInvalid(id))
55
+ return 0;
56
+ const len = id.length;
57
+ return (len <= 12) ? 0 : toHex(id.slice(2, len - 10));
58
+ }
59
+ Id64.getBriefcaseId = getBriefcaseId;
60
+ /** Create an Id64String from its JSON representation.
61
+ * @param prop The JSON representation of an Id.
62
+ * @returns A well-formed Id string.
63
+ * @note if the input is undefined, the result is "0", indicating an invalid Id.
64
+ * @note if the input is not undefined, the result is the same as that of [[Id64.fromString]].
65
+ */
66
+ function fromJSON(prop) {
67
+ return typeof prop === "string" ? Id64.fromString(prop) : Id64.invalid;
68
+ }
69
+ Id64.fromJSON = fromJSON;
70
+ /** Given a string value, attempt to normalize it into a well-formed Id string.
71
+ * If the input is already a well-formed Id string, it is returned unmodified.
72
+ * Otherwise, the input is trimmed of leading and trailing whitespace, converted to lowercase, and an attempt is made to parse it as a 64-bit hexadecimal integer.
73
+ * If parsing succeeds the normalized result is returned; otherwise the result is "0", indicating an invalid Id.
74
+ *
75
+ * For a description of "well-formed", see [Working with Ids]($docs/learning/common/Id64.md).
76
+ */
77
+ function fromString(val) {
78
+ // NB: in case this is called from JavaScript, we must check the run-time type...
79
+ if (typeof val !== "string")
80
+ return Id64.invalid;
81
+ // Skip the common case in which the input is already a well-formed Id string
82
+ if (Id64.isId64(val))
83
+ return val;
84
+ // Attempt to normalize the input into a well-formed Id string
85
+ val = val.toLowerCase().trim();
86
+ const len = val.length;
87
+ if (len < 2 || val[0] !== "0" || val[1] !== "x")
88
+ return Id64.invalid;
89
+ let low = 0;
90
+ let high = 0;
91
+ let start = 2;
92
+ if (len > 12) {
93
+ start = (len - 10);
94
+ high = toHex(val.slice(2, start));
95
+ }
96
+ low = toHex(val.slice(start));
97
+ return fromLocalAndBriefcaseIds(low, high);
98
+ }
99
+ Id64.fromString = fromString;
100
+ // Used when constructing local ID portion of Id64String. Performance optimization.
101
+ const _localIdPrefixByLocalIdLength = [
102
+ "0000000000",
103
+ "000000000",
104
+ "00000000",
105
+ "0000000",
106
+ "000000",
107
+ "00000",
108
+ "0000",
109
+ "000",
110
+ "00",
111
+ "0",
112
+ "",
113
+ ];
114
+ /** Produce an Id string from a local and briefcase Id.
115
+ * @param localId The non-zero local Id as an unsigned 40-bit integer.
116
+ * @param briefcaseId The briefcase Id as an unsigned 24-bit integer.
117
+ * @returns an Id64String containing the hexadecimal string representation of the unsigned 64-bit integer which would result from the
118
+ * operation `localId | (briefcaseId << 40)`, or an invalid Id "0" if the inputs are invalid.
119
+ */
120
+ function fromLocalAndBriefcaseIds(localId, briefcaseId) {
121
+ // NB: Yes, we must check the run-time type...
122
+ if (typeof localId !== "number" || typeof briefcaseId !== "number")
123
+ return Id64.invalid;
124
+ localId = Math.floor(localId);
125
+ if (0 === localId)
126
+ return Id64.invalid;
127
+ briefcaseId = Math.floor(briefcaseId);
128
+ const lowStr = localId.toString(16);
129
+ return `0x${(briefcaseId === 0) ? lowStr : (briefcaseId.toString(16) + (_localIdPrefixByLocalIdLength[lowStr.length] + lowStr))}`;
130
+ }
131
+ Id64.fromLocalAndBriefcaseIds = fromLocalAndBriefcaseIds;
132
+ // Used as a buffer when converting a pair of 32-bit integers to an Id64String. Significant performance optimization.
133
+ const scratchCharCodes = [
134
+ 0x30,
135
+ 0x78,
136
+ 0x30,
137
+ 0x30,
138
+ 0x30,
139
+ 0x30,
140
+ 0x30,
141
+ 0x30,
142
+ 0x30,
143
+ 0x30,
144
+ 0x30,
145
+ 0x30,
146
+ 0x30,
147
+ 0x30,
148
+ 0x30,
149
+ 0x30,
150
+ 0x30,
151
+ 0x30,
152
+ ];
153
+ // Convert 4-bit unsigned integer to char code representing lower-case hexadecimal digit.
154
+ function uint4ToCharCode(uint4) {
155
+ return uint4 + (uint4 < 10 ? 0x30 : 0x57);
156
+ }
157
+ // Convert char code representing lower-case hexadecimal digit to 4-bit unsigned integer.
158
+ function charCodeToUint4(char) {
159
+ return char - (char >= 0x57 ? 0x57 : 0x30);
160
+ }
161
+ // Convert a substring to a uint32. This is twice as fast as using Number.parseInt().
162
+ function substringToUint32(id, start, end) {
163
+ let uint32 = 0;
164
+ for (let i = start; i < end; i++) {
165
+ const uint4 = charCodeToUint4(id.charCodeAt(i));
166
+ const shift = (end - i - 1) << 2;
167
+ const mask = uint4 << shift;
168
+ uint32 = (uint32 | mask) >>> 0; // >>> 0 to force unsigned because javascript
169
+ }
170
+ return uint32;
171
+ }
172
+ /** Create an Id64String from a pair of unsigned 32-bit integers.
173
+ * @param lowBytes The lower 4 bytes of the Id
174
+ * @param highBytes The upper 4 bytes of the Id
175
+ * @returns an Id64String containing the hexadecimal string representation of the unsigned 64-bit integer which would result from the
176
+ * operation `lowBytes | (highBytes << 32)`.
177
+ * @see [[Id64.fromUint32PairObject]] if you have a [[Id64.Uint32Pair]] object.
178
+ */
179
+ function fromUint32Pair(lowBytes, highBytes) {
180
+ const localIdLow = lowBytes >>> 0;
181
+ const localIdHigh = (highBytes & 0x000000ff) * (0xffffffff + 1); // aka (highBytes & 0xff) << 32
182
+ const localId = localIdLow + localIdHigh; // aka localIdLow | localIdHigh
183
+ if (0 === localId)
184
+ return Id64.invalid;
185
+ // Need to omit or preserve leading zeroes...
186
+ const buffer = scratchCharCodes;
187
+ let index = 2;
188
+ for (let i = 7; i >= 0; i--) {
189
+ const shift = i << 2;
190
+ const mask = 0xf << shift;
191
+ const uint4 = (highBytes & mask) >>> shift;
192
+ if (index > 2 || 0 !== uint4)
193
+ buffer[index++] = uint4ToCharCode(uint4);
194
+ }
195
+ for (let i = 7; i >= 0; i--) {
196
+ const shift = i << 2;
197
+ const mask = 0xf << shift;
198
+ const uint4 = (lowBytes & mask) >>> shift;
199
+ if (index > 2 || 0 !== uint4)
200
+ buffer[index++] = uint4ToCharCode(uint4);
201
+ }
202
+ if (buffer.length !== index)
203
+ buffer.length = index;
204
+ return String.fromCharCode(...scratchCharCodes);
205
+ }
206
+ Id64.fromUint32Pair = fromUint32Pair;
207
+ /** Create an Id64String from a [[Id64.Uint32Pair]].
208
+ * @see [[Id64.fromUint32Pair]].
209
+ */
210
+ function fromUint32PairObject(pair) {
211
+ return fromUint32Pair(pair.lower, pair.upper);
212
+ }
213
+ Id64.fromUint32PairObject = fromUint32PairObject;
214
+ /** Returns true if the inputs represent two halves of a valid 64-bit Id.
215
+ * @see [[Id64.Uint32Pair]].
216
+ */
217
+ function isValidUint32Pair(lowBytes, highBytes) {
218
+ // Detect local ID of zero
219
+ return 0 !== lowBytes || 0 !== (highBytes & 0x000000ff);
220
+ }
221
+ Id64.isValidUint32Pair = isValidUint32Pair;
222
+ /** Convert an Id64String to a 64-bit unsigned integer represented as a pair of unsigned 32-bit integers.
223
+ * @param id The well-formed string representation of a 64-bit Id.
224
+ * @param out Used as the return value if supplied; otherwise a new object is returned.
225
+ * @returns An object containing the parsed lower and upper 32-bit integers comprising the 64-bit Id.
226
+ */
227
+ function getUint32Pair(id, out) {
228
+ if (!out)
229
+ out = { lower: 0, upper: 0 };
230
+ out.lower = getLowerUint32(id);
231
+ out.upper = getUpperUint32(id);
232
+ return out;
233
+ }
234
+ Id64.getUint32Pair = getUint32Pair;
235
+ /** Extract an unsigned 32-bit integer from the lower 4 bytes of an Id64String. */
236
+ function getLowerUint32(id) {
237
+ if (isInvalid(id))
238
+ return 0;
239
+ const end = id.length;
240
+ const start = end > 10 ? end - 8 : 2;
241
+ return substringToUint32(id, start, end);
242
+ }
243
+ Id64.getLowerUint32 = getLowerUint32;
244
+ /** Extract an unsigned 32-bit integer from the upper 4 bytes of an Id64String. */
245
+ function getUpperUint32(id) {
246
+ const len = id.length;
247
+ if (len <= 10 || isInvalid(id))
248
+ return 0;
249
+ return substringToUint32(id, 2, len - 8);
250
+ }
251
+ Id64.getUpperUint32 = getUpperUint32;
252
+ /** Convert an [[Id64Arg]] into an [[Id64Set]].
253
+ *
254
+ * This method can be used by functions that accept an Id64Arg to conveniently process the value(s). For example:
255
+ * ```ts
256
+ * public addCategories(arg: Id64Arg) { Id64.toIdSet(arg).forEach((id) => this.categories.add(id)); }
257
+ * ```
258
+ *
259
+ * Alternatively, to avoid allocating a new Id64Set, use [[Id64.iterable]].
260
+ *
261
+ * @param arg The Ids to convert to an Id64Set.
262
+ * @param makeCopy If true, and the input is already an Id64Set, returns a deep copy of the input.
263
+ * @returns An Id64Set containing the set of [[Id64String]]s represented by the Id64Arg.
264
+ */
265
+ function toIdSet(arg, makeCopy = false) {
266
+ if (arg instanceof Set)
267
+ return makeCopy ? new Set(arg) : arg;
268
+ const ids = new Set();
269
+ if (typeof arg === "string")
270
+ ids.add(arg);
271
+ else if (Array.isArray(arg)) {
272
+ arg.forEach((id) => {
273
+ if (typeof id === "string")
274
+ ids.add(id);
275
+ });
276
+ }
277
+ return ids;
278
+ }
279
+ Id64.toIdSet = toIdSet;
280
+ /** Obtain iterator over the specified Ids.
281
+ * @see [[Id64.iterable]].
282
+ */
283
+ function* iterator(ids) {
284
+ if (typeof ids === "string") {
285
+ yield ids;
286
+ }
287
+ else {
288
+ for (const id of ids)
289
+ yield id;
290
+ }
291
+ }
292
+ Id64.iterator = iterator;
293
+ /** Obtain an iterable over the specified Ids. Example usage:
294
+ * ```ts
295
+ * const ids = ["0x123", "0xfed"];
296
+ * for (const id of Id64.iterable(ids))
297
+ * console.log(id);
298
+ * ```
299
+ */
300
+ function iterable(ids) {
301
+ return {
302
+ [Symbol.iterator]: () => iterator(ids),
303
+ };
304
+ }
305
+ Id64.iterable = iterable;
306
+ /** Return the first [[Id64String]] of an [[Id64Arg]]. */
307
+ function getFirst(arg) {
308
+ return typeof arg === "string" ? arg : (Array.isArray(arg) ? arg[0] : arg.values().next().value);
309
+ }
310
+ Id64.getFirst = getFirst;
311
+ /** Return the number of [[Id64String]]s represented by an [[Id64Arg]]. */
312
+ function sizeOf(arg) {
313
+ return typeof arg === "string" ? 1 : (Array.isArray(arg) ? arg.length : arg.size);
314
+ }
315
+ Id64.sizeOf = sizeOf;
316
+ /** Returns true if the [[Id64Arg]] contains the specified Id. */
317
+ function has(arg, id) {
318
+ if (typeof arg === "string")
319
+ return arg === id;
320
+ if (Array.isArray(arg))
321
+ return -1 !== arg.indexOf(id);
322
+ return arg.has(id);
323
+ }
324
+ Id64.has = has;
325
+ /** The string representation of an invalid Id. */
326
+ Id64.invalid = "0";
327
+ /** Determine if the supplied id string represents a transient Id.
328
+ * @param id A well-formed Id string.
329
+ * @returns true if the Id represents a transient Id.
330
+ * @note This method assumes the input is a well-formed Id string.
331
+ * @see [[Id64.isTransientId64]]
332
+ * @see [[TransientIdSequence]]
333
+ */
334
+ function isTransient(id) {
335
+ // A transient Id is of the format "0xffffffxxxxxxxxxx" where the leading 6 digits indicate an invalid briefcase Id.
336
+ return 18 === id.length && id.startsWith("0xffffff");
337
+ }
338
+ Id64.isTransient = isTransient;
339
+ /** Determine if the input is a well-formed [[Id64String]] and represents a transient Id.
340
+ * @see [[Id64.isTransient]]
341
+ * @see [[Id64.isId64]]
342
+ * @see [[TransientIdSequence]]
343
+ */
344
+ function isTransientId64(id) {
345
+ return isValidId64(id) && isTransient(id);
346
+ }
347
+ Id64.isTransientId64 = isTransientId64;
348
+ /** Determine if the input is a well-formed [[Id64String]].
349
+ *
350
+ * For a description of "well-formed", see [Working with Ids]($docs/learning/common/Id64.md).
351
+ * @see [[Id64.isValidId64]]
352
+ */
353
+ function isId64(id) {
354
+ const len = id.length;
355
+ if (0 === len || 18 < len)
356
+ return false;
357
+ if ("0" !== id[0])
358
+ return false;
359
+ // Well-formed invalid Id: "0"
360
+ if (1 === len)
361
+ return true;
362
+ // Valid Ids begin with "0x" followed by at least one lower-case hexadecimal digit.
363
+ if (2 === len || "x" !== id[1])
364
+ return false;
365
+ // If briefcase Id is present, it occupies at least one digit, followed by 10 digits for local Id
366
+ let localIdStart = 2;
367
+ if (len > 12) {
368
+ localIdStart = len - 10;
369
+ // Verify briefcase Id
370
+ if (!isValidHexString(id, 2, localIdStart - 2))
371
+ return false;
372
+ // Skip leading zeroes in local Id
373
+ for (let i = localIdStart; i < len; i++) {
374
+ if (0x30 !== id.charCodeAt(i)) // '0'
375
+ break;
376
+ else
377
+ localIdStart++;
378
+ }
379
+ if (localIdStart >= len)
380
+ return false;
381
+ }
382
+ return isValidHexString(id, localIdStart, len - localIdStart);
383
+ }
384
+ Id64.isId64 = isId64;
385
+ /** Returns true if the input is not equal to the representation of an invalid Id.
386
+ * @note This method assumes the input is a well-formed Id string.
387
+ * @see [[Id64.isInvalid]]
388
+ * @see [[Id64.isValidId64]]
389
+ */
390
+ function isValid(id) {
391
+ return Id64.invalid !== id;
392
+ }
393
+ Id64.isValid = isValid;
394
+ /** Returns true if the input is a well-formed [[Id64String]] representing a valid Id.
395
+ * @see [[Id64.isValid]]
396
+ * @see [[Id64.isId64]]
397
+ */
398
+ function isValidId64(id) {
399
+ return Id64.invalid !== id && Id64.isId64(id);
400
+ }
401
+ Id64.isValidId64 = isValidId64;
402
+ /** Returns true if the input is a well-formed [[Id64String]] representing an invalid Id.
403
+ * @see [[Id64.isValid]]
404
+ */
405
+ function isInvalid(id) {
406
+ return Id64.invalid === id;
407
+ }
408
+ Id64.isInvalid = isInvalid;
409
+ /** A specialized replacement for Set<Id64String> optimized for performance-critical code which represents large sets of [[Id64]]s as pairs of
410
+ * 32-bit integers.
411
+ * The internal representation is a Map<number, Set<number>> where the Map key is the upper 4 bytes of the IDs and the Set elements are the lower 4 bytes of the IDs.
412
+ * Because the upper 4 bytes store the 24-bit briefcase ID plus the upper 8 bits of the local ID, there will be a very small distribution of unique Map keys.
413
+ * To further optimize this data type, the following assumptions are made regarding the { lower, upper } inputs, and no validation is performed to confirm them:
414
+ * - The inputs are unsigned 32-bit integers;
415
+ * - The inputs represent a valid Id64String (e.g., local ID is not zero).
416
+ * @see [[Id64.Uint32Map]] for a similarly-optimized replacement for Map<Id64String, T>
417
+ * @public
418
+ */
419
+ class Uint32Set {
420
+ /** Construct a new Uint32Set.
421
+ * @param ids If supplied, all of the specified Ids will be added to the new set.
422
+ */
423
+ constructor(ids) {
424
+ this._map = new Map();
425
+ if (undefined !== ids)
426
+ this.addIds(ids);
427
+ }
428
+ /** Remove all contents of this set. */
429
+ clear() {
430
+ this._map.clear();
431
+ }
432
+ /** Add an Id to the set. */
433
+ addId(id) {
434
+ this.add(Id64.getLowerUint32(id), Id64.getUpperUint32(id));
435
+ }
436
+ /** Add any number of Ids to the set. */
437
+ addIds(ids) {
438
+ for (const id of Id64.iterable(ids))
439
+ this.addId(id);
440
+ }
441
+ /** Returns true if the set contains the specified Id. */
442
+ hasId(id) { return this.has(Id64.getLowerUint32(id), Id64.getUpperUint32(id)); }
443
+ /** Add an Id to the set. */
444
+ add(low, high) {
445
+ let set = this._map.get(high);
446
+ if (undefined === set) {
447
+ set = new Set();
448
+ this._map.set(high, set);
449
+ }
450
+ set.add(low);
451
+ }
452
+ /** Remove an Id from the set. */
453
+ deleteId(id) {
454
+ this.delete(Id64.getLowerUint32(id), Id64.getUpperUint32(id));
455
+ }
456
+ /** Remove any number of Ids from the set. */
457
+ deleteIds(ids) {
458
+ for (const id of Id64.iterable(ids))
459
+ this.deleteId(id);
460
+ }
461
+ /** Remove an Id from the set. */
462
+ delete(low, high) {
463
+ const set = this._map.get(high);
464
+ if (undefined !== set)
465
+ set.delete(low);
466
+ }
467
+ /** Returns true if the set contains the specified Id. */
468
+ has(low, high) {
469
+ const set = this._map.get(high);
470
+ return undefined !== set && set.has(low);
471
+ }
472
+ /** Returns true if the set contains the Id specified by `pair`. */
473
+ hasPair(pair) {
474
+ return this.has(pair.lower, pair.upper);
475
+ }
476
+ /** Returns true if the set contains no Ids. */
477
+ get isEmpty() { return 0 === this._map.size; }
478
+ /** Returns the number of Ids contained in the set. */
479
+ get size() {
480
+ let size = 0;
481
+ for (const entry of this._map)
482
+ size += entry[1].size;
483
+ return size;
484
+ }
485
+ /** Populates and returns an array of all Ids contained in the set. */
486
+ toId64Array() {
487
+ const ids = [];
488
+ for (const entry of this._map)
489
+ for (const low of entry[1])
490
+ ids.push(Id64.fromUint32Pair(low, entry[0]));
491
+ return ids;
492
+ }
493
+ /** Populates and returns a set of all Ids contained in the set. */
494
+ toId64Set() {
495
+ const ids = new Set();
496
+ for (const entry of this._map)
497
+ for (const low of entry[1])
498
+ ids.add(Id64.fromUint32Pair(low, entry[0]));
499
+ return ids;
500
+ }
501
+ /** Execute a function against each Id in this set. */
502
+ forEach(func) {
503
+ for (const entry of this._map)
504
+ for (const lo of entry[1])
505
+ func(lo, entry[0]);
506
+ }
507
+ }
508
+ Id64.Uint32Set = Uint32Set;
509
+ /** A specialized replacement for Map<Id64String, T> optimized for performance-critical code.
510
+ * @see [[Id64.Uint32Set]] for implementation details.
511
+ * @public
512
+ */
513
+ class Uint32Map {
514
+ constructor() {
515
+ this._map = new Map();
516
+ }
517
+ /** Remove all entries from the map. */
518
+ clear() { this._map.clear(); }
519
+ /** Find an entry in the map by Id. */
520
+ getById(id) { return this.get(Id64.getLowerUint32(id), Id64.getUpperUint32(id)); }
521
+ /** Set an entry in the map by Id. */
522
+ setById(id, value) { this.set(Id64.getLowerUint32(id), Id64.getUpperUint32(id), value); }
523
+ /** Set an entry in the map by Id components. */
524
+ set(low, high, value) {
525
+ let map = this._map.get(high);
526
+ if (undefined === map) {
527
+ map = new Map();
528
+ this._map.set(high, map);
529
+ }
530
+ map.set(low, value);
531
+ }
532
+ /** Get an entry from the map by Id components. */
533
+ get(low, high) {
534
+ const map = this._map.get(high);
535
+ return undefined !== map ? map.get(low) : undefined;
536
+ }
537
+ /** Returns true if the map contains no entries. */
538
+ get isEmpty() { return 0 === this._map.size; }
539
+ /** Returns the number of entries in the map. */
540
+ get size() {
541
+ let size = 0;
542
+ for (const entry of this._map)
543
+ size += entry[1].size;
544
+ return size;
545
+ }
546
+ /** Execute a function against each entry in this map. */
547
+ forEach(func) {
548
+ for (const outerEntry of this._map)
549
+ for (const innerEntry of outerEntry[1])
550
+ func(innerEntry[0], outerEntry[0], innerEntry[1]);
551
+ }
552
+ }
553
+ Id64.Uint32Map = Uint32Map;
554
+ })(Id64 || (Id64 = {}));
555
+ /**
556
+ * Generates unique [[Id64String]] values in sequence, which are guaranteed not to conflict with Ids associated with persistent elements or models.
557
+ * This is useful for associating stable, non-persistent identifiers with things like [Decorator]($frontend)s.
558
+ * A TransientIdSequence can generate a maximum of (2^40)-2 unique Ids.
559
+ * @public
560
+ */
561
+ export class TransientIdSequence {
562
+ constructor() {
563
+ this._localId = 0;
564
+ }
565
+ /** Generate and return the next transient Id64String in the sequence.
566
+ * @deprecated in 3.x. Use [[getNext]].
567
+ */
568
+ get next() {
569
+ return this.getNext();
570
+ }
571
+ /** Generate and return the next transient Id64String in the sequence. */
572
+ getNext() {
573
+ return Id64.fromLocalAndBriefcaseIds(++this._localId, 0xffffff);
574
+ }
575
+ /** Preview the transient Id64String that will be returned by the next call to [[getNext]].
576
+ * This is primarily useful for tests.
577
+ */
578
+ peekNext() {
579
+ return Id64.fromLocalAndBriefcaseIds(this._localId + 1, 0xffffff);
580
+ }
581
+ }
582
+ /**
583
+ * The Guid namespace provides facilities for working with GUID strings using the "8-4-4-4-12" pattern.
584
+ *
585
+ * The [[GuidString]] type alias is used to indicate function arguments, return types, and variables which are known to
586
+ * be in the GUID format.
587
+ * @public
588
+ */
589
+ export var Guid;
590
+ (function (Guid) {
591
+ const uuidPattern = new RegExp("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
592
+ /** Represents the empty Guid 00000000-0000-0000-0000-000000000000 */
593
+ Guid.empty = "00000000-0000-0000-0000-000000000000";
594
+ /** Determine whether the input string is "guid-like". That is, it follows the 8-4-4-4-12 pattern. This does not enforce
595
+ * that the string is actually in valid UUID format.
596
+ */
597
+ function isGuid(value) {
598
+ return uuidPattern.test(value);
599
+ }
600
+ Guid.isGuid = isGuid;
601
+ /** Determine whether the input string is a valid V4 Guid string */
602
+ function isV4Guid(value) {
603
+ return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/.test(value);
604
+ }
605
+ Guid.isV4Guid = isV4Guid;
606
+ /** Create a new V4 Guid value */
607
+ function createValue() {
608
+ // https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
609
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
610
+ const r = Math.random() * 16 | 0;
611
+ const v = c === "x" ? r : (r & 0x3 | 0x8);
612
+ return v.toString(16);
613
+ });
614
+ }
615
+ Guid.createValue = createValue;
616
+ /**
617
+ * Normalize a Guid string if possible. Normalization consists of:
618
+ * - Convert all characters to lower case
619
+ * - Trim any leading or trailing whitespace
620
+ * - Convert to the standard Guid format "8-4-4-4-12", repositioning the '-' characters as necessary, presuming there are exactly 32 hexadecimal digits.
621
+ * @param value Input value that represents a Guid
622
+ * @returns Normalized representation of the Guid string. If the normalization fails, return the *original* value unmodified (Note: it is *not* a valid Guid)
623
+ */
624
+ function normalize(value) {
625
+ const lowerValue = value.toLowerCase().trim();
626
+ // Return if it's already formatted to be a Guid
627
+ if (isGuid(lowerValue))
628
+ return lowerValue;
629
+ // Remove any existing "-" characters and position them properly, if there remains exactly 32 hexadecimal digits
630
+ const noDashValue = lowerValue.replace(/-/g, "");
631
+ const noDashPattern = /^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/;
632
+ if (noDashPattern.test(noDashValue)) {
633
+ return noDashValue.replace(noDashPattern, (_match, p1, p2, p3, p4, p5) => `${p1}-${p2}-${p3}-${p4}-${p5}`);
634
+ }
635
+ // Return unmodified string - (note: it is *not* a valid Guid)
636
+ return value;
637
+ }
638
+ Guid.normalize = normalize;
639
+ })(Guid || (Guid = {}));
640
640
  //# sourceMappingURL=Id.js.map