@webex/plugin-meetings 3.12.0-next.9 → 3.12.0-task-refactor.1

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 (201) hide show
  1. package/dist/annotation/index.js +5 -14
  2. package/dist/annotation/index.js.map +1 -1
  3. package/dist/breakouts/breakout.js +1 -1
  4. package/dist/breakouts/index.js +1 -1
  5. package/dist/config.js +2 -8
  6. package/dist/config.js.map +1 -1
  7. package/dist/constants.js +6 -29
  8. package/dist/constants.js.map +1 -1
  9. package/dist/hashTree/hashTreeParser.js +29 -1563
  10. package/dist/hashTree/hashTreeParser.js.map +1 -1
  11. package/dist/hashTree/types.js +3 -13
  12. package/dist/hashTree/types.js.map +1 -1
  13. package/dist/index.js +2 -11
  14. package/dist/index.js.map +1 -1
  15. package/dist/interceptors/index.js +0 -7
  16. package/dist/interceptors/index.js.map +1 -1
  17. package/dist/interceptors/locusRouteToken.js +5 -27
  18. package/dist/interceptors/locusRouteToken.js.map +1 -1
  19. package/dist/interpretation/index.js +2 -2
  20. package/dist/interpretation/index.js.map +1 -1
  21. package/dist/interpretation/siLanguage.js +1 -1
  22. package/dist/locus-info/controlsUtils.js +3 -7
  23. package/dist/locus-info/controlsUtils.js.map +1 -1
  24. package/dist/locus-info/index.js +247 -642
  25. package/dist/locus-info/index.js.map +1 -1
  26. package/dist/locus-info/selfUtils.js +0 -1
  27. package/dist/locus-info/selfUtils.js.map +1 -1
  28. package/dist/locus-info/types.js.map +1 -1
  29. package/dist/media/MediaConnectionAwaiter.js +1 -57
  30. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  31. package/dist/media/properties.js +2 -4
  32. package/dist/media/properties.js.map +1 -1
  33. package/dist/meeting/in-meeting-actions.js +1 -7
  34. package/dist/meeting/in-meeting-actions.js.map +1 -1
  35. package/dist/meeting/index.js +1036 -1481
  36. package/dist/meeting/index.js.map +1 -1
  37. package/dist/meeting/request.js +0 -50
  38. package/dist/meeting/request.js.map +1 -1
  39. package/dist/meeting/request.type.js.map +1 -1
  40. package/dist/meeting/util.js +3 -133
  41. package/dist/meeting/util.js.map +1 -1
  42. package/dist/meetings/index.js +59 -142
  43. package/dist/meetings/index.js.map +1 -1
  44. package/dist/meetings/util.js +7 -11
  45. package/dist/meetings/util.js.map +1 -1
  46. package/dist/member/index.js +0 -10
  47. package/dist/member/index.js.map +1 -1
  48. package/dist/member/util.js +0 -10
  49. package/dist/member/util.js.map +1 -1
  50. package/dist/metrics/constants.js +1 -7
  51. package/dist/metrics/constants.js.map +1 -1
  52. package/dist/multistream/mediaRequestManager.js +60 -9
  53. package/dist/multistream/mediaRequestManager.js.map +1 -1
  54. package/dist/multistream/remoteMediaManager.js +0 -11
  55. package/dist/multistream/remoteMediaManager.js.map +1 -1
  56. package/dist/multistream/sendSlotManager.js +2 -116
  57. package/dist/multistream/sendSlotManager.js.map +1 -1
  58. package/dist/reachability/clusterReachability.js +18 -171
  59. package/dist/reachability/clusterReachability.js.map +1 -1
  60. package/dist/reachability/index.js +11 -21
  61. package/dist/reachability/index.js.map +1 -1
  62. package/dist/reachability/reachabilityPeerConnection.js +1 -1
  63. package/dist/reachability/reachabilityPeerConnection.js.map +1 -1
  64. package/dist/reactions/reactions.type.js.map +1 -1
  65. package/dist/reconnection-manager/index.js +1 -0
  66. package/dist/reconnection-manager/index.js.map +1 -1
  67. package/dist/types/common/browser-detection.d.ts +0 -1
  68. package/dist/types/common/events/events-scope.d.ts +0 -1
  69. package/dist/types/common/events/events.d.ts +0 -1
  70. package/dist/types/config.d.ts +0 -5
  71. package/dist/types/constants.d.ts +1 -24
  72. package/dist/types/hashTree/hashTreeParser.d.ts +11 -260
  73. package/dist/types/hashTree/types.d.ts +0 -20
  74. package/dist/types/index.d.ts +0 -1
  75. package/dist/types/interceptors/index.d.ts +1 -2
  76. package/dist/types/interceptors/locusRouteToken.d.ts +0 -2
  77. package/dist/types/locus-info/index.d.ts +47 -68
  78. package/dist/types/locus-info/types.d.ts +12 -28
  79. package/dist/types/media/MediaConnectionAwaiter.d.ts +1 -10
  80. package/dist/types/media/properties.d.ts +1 -2
  81. package/dist/types/meeting/in-meeting-actions.d.ts +0 -6
  82. package/dist/types/meeting/index.d.ts +7 -86
  83. package/dist/types/meeting/request.d.ts +1 -16
  84. package/dist/types/meeting/request.type.d.ts +0 -5
  85. package/dist/types/meeting/util.d.ts +0 -31
  86. package/dist/types/meeting-info/util.d.ts +0 -1
  87. package/dist/types/meeting-info/utilv2.d.ts +0 -1
  88. package/dist/types/meetings/index.d.ts +2 -4
  89. package/dist/types/member/index.d.ts +0 -1
  90. package/dist/types/member/types.d.ts +4 -4
  91. package/dist/types/member/util.d.ts +0 -5
  92. package/dist/types/metrics/constants.d.ts +0 -6
  93. package/dist/types/multistream/mediaRequestManager.d.ts +23 -0
  94. package/dist/types/multistream/sendSlotManager.d.ts +1 -23
  95. package/dist/types/reachability/clusterReachability.d.ts +3 -30
  96. package/dist/types/reactions/reactions.type.d.ts +0 -1
  97. package/dist/types/recording-controller/util.d.ts +5 -5
  98. package/dist/types/roap/index.d.ts +1 -1
  99. package/dist/webinar/index.js +163 -438
  100. package/dist/webinar/index.js.map +1 -1
  101. package/package.json +24 -26
  102. package/src/annotation/index.ts +7 -27
  103. package/src/config.ts +0 -5
  104. package/src/constants.ts +1 -30
  105. package/src/hashTree/hashTreeParser.ts +25 -1523
  106. package/src/hashTree/types.ts +1 -24
  107. package/src/index.ts +1 -8
  108. package/src/interceptors/index.ts +1 -2
  109. package/src/interceptors/locusRouteToken.ts +5 -22
  110. package/src/interpretation/index.ts +2 -2
  111. package/src/locus-info/controlsUtils.ts +0 -17
  112. package/src/locus-info/index.ts +213 -707
  113. package/src/locus-info/selfUtils.ts +0 -1
  114. package/src/locus-info/types.ts +12 -27
  115. package/src/media/MediaConnectionAwaiter.ts +1 -41
  116. package/src/media/properties.ts +1 -3
  117. package/src/meeting/in-meeting-actions.ts +0 -12
  118. package/src/meeting/index.ts +84 -461
  119. package/src/meeting/request.ts +0 -42
  120. package/src/meeting/request.type.ts +0 -6
  121. package/src/meeting/util.ts +2 -160
  122. package/src/meetings/index.ts +60 -180
  123. package/src/meetings/util.ts +9 -10
  124. package/src/member/index.ts +0 -10
  125. package/src/member/util.ts +0 -12
  126. package/src/metrics/constants.ts +0 -7
  127. package/src/multistream/mediaRequestManager.ts +54 -4
  128. package/src/multistream/remoteMediaManager.ts +0 -13
  129. package/src/multistream/sendSlotManager.ts +3 -97
  130. package/src/reachability/clusterReachability.ts +27 -153
  131. package/src/reachability/index.ts +1 -15
  132. package/src/reachability/reachabilityPeerConnection.ts +1 -3
  133. package/src/reactions/reactions.type.ts +0 -1
  134. package/src/reconnection-manager/index.ts +1 -0
  135. package/src/webinar/index.ts +6 -265
  136. package/test/unit/spec/annotation/index.ts +7 -69
  137. package/test/unit/spec/interceptors/locusRouteToken.ts +0 -44
  138. package/test/unit/spec/locus-info/controlsUtils.js +1 -56
  139. package/test/unit/spec/locus-info/index.js +90 -1457
  140. package/test/unit/spec/media/MediaConnectionAwaiter.ts +1 -41
  141. package/test/unit/spec/media/properties.ts +3 -12
  142. package/test/unit/spec/meeting/in-meeting-actions.ts +2 -8
  143. package/test/unit/spec/meeting/index.js +128 -981
  144. package/test/unit/spec/meeting/request.js +0 -70
  145. package/test/unit/spec/meeting/utils.js +26 -438
  146. package/test/unit/spec/meetings/index.js +33 -845
  147. package/test/unit/spec/meetings/utils.js +1 -51
  148. package/test/unit/spec/member/index.js +4 -28
  149. package/test/unit/spec/member/util.js +27 -65
  150. package/test/unit/spec/multistream/mediaRequestManager.ts +85 -2
  151. package/test/unit/spec/multistream/remoteMediaManager.ts +0 -30
  152. package/test/unit/spec/multistream/sendSlotManager.ts +36 -135
  153. package/test/unit/spec/reachability/clusterReachability.ts +1 -125
  154. package/test/unit/spec/reachability/index.ts +3 -26
  155. package/test/unit/spec/reconnection-manager/index.js +8 -4
  156. package/test/unit/spec/webinar/index.ts +37 -534
  157. package/dist/aiEnableRequest/index.js +0 -184
  158. package/dist/aiEnableRequest/index.js.map +0 -1
  159. package/dist/aiEnableRequest/utils.js +0 -36
  160. package/dist/aiEnableRequest/utils.js.map +0 -1
  161. package/dist/hashTree/constants.js +0 -22
  162. package/dist/hashTree/constants.js.map +0 -1
  163. package/dist/hashTree/hashTree.js +0 -533
  164. package/dist/hashTree/hashTree.js.map +0 -1
  165. package/dist/hashTree/utils.js +0 -69
  166. package/dist/hashTree/utils.js.map +0 -1
  167. package/dist/interceptors/constant.js +0 -12
  168. package/dist/interceptors/constant.js.map +0 -1
  169. package/dist/interceptors/dataChannelAuthToken.js +0 -290
  170. package/dist/interceptors/dataChannelAuthToken.js.map +0 -1
  171. package/dist/interceptors/utils.js +0 -27
  172. package/dist/interceptors/utils.js.map +0 -1
  173. package/dist/types/aiEnableRequest/index.d.ts +0 -5
  174. package/dist/types/aiEnableRequest/utils.d.ts +0 -2
  175. package/dist/types/hashTree/constants.d.ts +0 -9
  176. package/dist/types/hashTree/hashTree.d.ts +0 -136
  177. package/dist/types/hashTree/utils.d.ts +0 -22
  178. package/dist/types/interceptors/constant.d.ts +0 -5
  179. package/dist/types/interceptors/dataChannelAuthToken.d.ts +0 -43
  180. package/dist/types/interceptors/utils.d.ts +0 -1
  181. package/dist/types/webinar/utils.d.ts +0 -6
  182. package/dist/webinar/utils.js +0 -25
  183. package/dist/webinar/utils.js.map +0 -1
  184. package/src/aiEnableRequest/README.md +0 -84
  185. package/src/aiEnableRequest/index.ts +0 -170
  186. package/src/aiEnableRequest/utils.ts +0 -25
  187. package/src/hashTree/constants.ts +0 -10
  188. package/src/hashTree/hashTree.ts +0 -480
  189. package/src/hashTree/utils.ts +0 -62
  190. package/src/interceptors/constant.ts +0 -6
  191. package/src/interceptors/dataChannelAuthToken.ts +0 -170
  192. package/src/interceptors/utils.ts +0 -16
  193. package/src/webinar/utils.ts +0 -16
  194. package/test/unit/spec/aiEnableRequest/index.ts +0 -981
  195. package/test/unit/spec/aiEnableRequest/utils.ts +0 -130
  196. package/test/unit/spec/hashTree/hashTree.ts +0 -721
  197. package/test/unit/spec/hashTree/hashTreeParser.ts +0 -3670
  198. package/test/unit/spec/hashTree/utils.ts +0 -140
  199. package/test/unit/spec/interceptors/dataChannelAuthToken.ts +0 -210
  200. package/test/unit/spec/interceptors/utils.ts +0 -75
  201. package/test/unit/spec/webinar/utils.ts +0 -39
@@ -1,480 +0,0 @@
1
- import {XXH3_128} from 'xxh3-ts/xxh3';
2
- import {EMPTY_HASH} from './constants';
3
- import {ObjectType} from './types';
4
-
5
- export type LeafDataItem = {
6
- type: ObjectType;
7
- id: number;
8
- version: number;
9
- };
10
-
11
- /**
12
- * HashTree is a data structure that organizes items into leaves based on their IDs,
13
- */
14
- class HashTree {
15
- leaves: Array<Record<string, Record<number, LeafDataItem>>>;
16
-
17
- leafHashes: Array<string>;
18
- readonly numLeaves: number;
19
-
20
- /**
21
- * Constructs a new HashTree.
22
- * @param {LeafDataItem[]} leafData Initial data to populate the tree.
23
- * @param {number} numLeaves The number of leaf nodes in the tree. Must be 0 or a power of 2.
24
- * @throws {Error} If numLeaves is not 0 or a power of 2.
25
- */
26
- constructor(leafData: LeafDataItem[], numLeaves: number) {
27
- // eslint-disable-next-line no-bitwise
28
- if ((numLeaves & (numLeaves - 1)) !== 0) {
29
- throw new Error(`Number of leaves must be a power of 2, saw ${numLeaves}`);
30
- }
31
-
32
- this.numLeaves = numLeaves;
33
- this.leafHashes = new Array(numLeaves).fill(EMPTY_HASH);
34
-
35
- this.leaves = new Array(numLeaves).fill(null).map(() => {
36
- return {};
37
- });
38
-
39
- if (leafData) {
40
- this.putItems(leafData);
41
- }
42
- }
43
-
44
- /**
45
- * Internal logic for adding or updating an item, without computing the leaf hash.
46
- * @param {LeafDataItem} item The item to add or update.
47
- * @returns {{put: boolean, index: (number|null)}} Object indicating if put and the leaf index.
48
- * @private
49
- */
50
- private _putItemInternal(item: LeafDataItem): {put: boolean; index: number | null} {
51
- if (this.numLeaves === 0) {
52
- return {put: false, index: null}; // Cannot add to a tree with 0 leaves
53
- }
54
-
55
- const index = item.id % this.numLeaves;
56
-
57
- if (!this.leaves[index][item.type]) {
58
- this.leaves[index][item.type] = {};
59
- }
60
-
61
- const existingItem = this.leaves[index][item.type][item.id];
62
-
63
- if (!existingItem || existingItem.version < item.version) {
64
- this.leaves[index][item.type][item.id] = item;
65
-
66
- return {put: true, index};
67
- }
68
-
69
- return {put: false, index: null};
70
- }
71
-
72
- /**
73
- * Adds or updates a single item in the hash tree.
74
- * @param {LeafDataItem} item The item to add or update.
75
- * @returns {boolean} True if the item was added or updated, false otherwise (e.g., older version or tree has 0 leaves).
76
- */
77
- putItem(item: LeafDataItem): boolean {
78
- const {put, index} = this._putItemInternal(item);
79
-
80
- if (put && index !== null) {
81
- this.computeLeafHash(index);
82
- }
83
-
84
- return put;
85
- }
86
-
87
- /**
88
- * Adds or updates multiple items in the hash tree.
89
- * @param {LeafDataItem[]} items The array of items to add or update.
90
- * @returns {boolean[]} An array of booleans indicating success for each item.
91
- */
92
- putItems(items: LeafDataItem[]): boolean[] {
93
- if (this.numLeaves === 0 && items.length > 0) {
94
- // Cannot add items to a tree with 0 leaves.
95
- return items.map(() => false);
96
- }
97
- const results: boolean[] = [];
98
- const changedLeafIndexes = new Set<number>();
99
-
100
- items.forEach((item) => {
101
- const {put, index} = this._putItemInternal(item);
102
- results.push(put);
103
- if (put && index !== null) {
104
- changedLeafIndexes.add(index);
105
- }
106
- });
107
-
108
- changedLeafIndexes.forEach((index) => {
109
- this.computeLeafHash(index);
110
- });
111
-
112
- return results;
113
- }
114
-
115
- /**
116
- * Internal logic for removing an item, without computing the leaf hash.
117
- * @param {LeafDataItem} item The item to remove.
118
- * @returns {{removed: boolean, index: (number|null)}} Object indicating if removed and the leaf index.
119
- * @private
120
- */
121
- private _removeItemInternal(item: LeafDataItem): {removed: boolean; index: number | null} {
122
- if (this.numLeaves === 0) {
123
- return {removed: false, index: null};
124
- }
125
-
126
- const index = item.id % this.numLeaves;
127
-
128
- if (
129
- this.leaves[index] &&
130
- this.leaves[index][item.type] &&
131
- this.leaves[index][item.type][item.id]
132
- ) {
133
- const existingItem = this.leaves[index][item.type][item.id];
134
- if (
135
- existingItem.id === item.id &&
136
- existingItem.type === item.type &&
137
- existingItem.version <= item.version
138
- ) {
139
- delete this.leaves[index][item.type][item.id];
140
- if (Object.keys(this.leaves[index][item.type]).length === 0) {
141
- delete this.leaves[index][item.type];
142
- }
143
-
144
- return {removed: true, index};
145
- }
146
- }
147
-
148
- return {removed: false, index: null};
149
- }
150
-
151
- /**
152
- * Removes a single item from the hash tree.
153
- * The removal is based on matching type, id, and the provided item's version
154
- * being greater than or equal to the existing item's version.
155
- * @param {LeafDataItem} item The item to remove.
156
- * @returns {boolean} True if the item was removed, false otherwise.
157
- */
158
- removeItem(item: LeafDataItem): boolean {
159
- const {removed, index} = this._removeItemInternal(item);
160
-
161
- if (removed && index !== null) {
162
- this.computeLeafHash(index);
163
- }
164
-
165
- return removed;
166
- }
167
-
168
- /**
169
- * Removes multiple items from the hash tree.
170
- * @param {LeafDataItem[]} items The array of items to remove.
171
- * @returns {boolean[]} An array of booleans indicating success for each item.
172
- */
173
- removeItems(items: LeafDataItem[]): boolean[] {
174
- if (this.numLeaves === 0 && items.length > 0) {
175
- return items.map(() => false);
176
- }
177
-
178
- const results: boolean[] = [];
179
- const changedLeafIndexes = new Set<number>();
180
-
181
- items.forEach((item) => {
182
- const {removed, index} = this._removeItemInternal(item);
183
- results.push(removed);
184
- if (removed && index !== null) {
185
- changedLeafIndexes.add(index);
186
- }
187
- });
188
-
189
- changedLeafIndexes.forEach((index) => {
190
- this.computeLeafHash(index);
191
- });
192
-
193
- return results;
194
- }
195
-
196
- /**
197
- * Updates multiple items in the hash tree.
198
- * This method can handle both updating and removing items based on the `operation` flag.
199
- *
200
- * @param {object[]} itemUpdates An array of objects containing `operation` flag and the `item` to update.
201
- * @returns {boolean[]} An array of booleans indicating success for each operation.
202
- */
203
- updateItems(itemUpdates: {operation: 'update' | 'remove'; item: LeafDataItem}[]): boolean[] {
204
- if (this.numLeaves === 0 && itemUpdates.length > 0) {
205
- return itemUpdates.map(() => false);
206
- }
207
-
208
- const results: boolean[] = [];
209
- const changedLeafIndexes = new Set<number>();
210
-
211
- itemUpdates.forEach(({operation, item}) => {
212
- if (operation === 'remove') {
213
- const {removed, index} = this._removeItemInternal(item);
214
- results.push(removed);
215
- if (removed && index !== null) {
216
- changedLeafIndexes.add(index);
217
- }
218
- } else {
219
- const {put, index} = this._putItemInternal(item);
220
- results.push(put);
221
- if (put && index !== null) {
222
- changedLeafIndexes.add(index);
223
- }
224
- }
225
- });
226
-
227
- changedLeafIndexes.forEach((index) => {
228
- this.computeLeafHash(index);
229
- });
230
-
231
- return results;
232
- }
233
-
234
- /**
235
- * Computes the hash for a specific leaf.
236
- * The hash is based on the sorted items within the leaf.
237
- * @param {number} index The index of the leaf to compute the hash for.
238
- * @returns {void}
239
- */
240
- computeLeafHash(index: number) {
241
- if (index < 0 || index >= this.numLeaves) {
242
- // nothing to do
243
- return;
244
- }
245
- const leafContent = this.leaves[index];
246
-
247
- const totalItemsCount = Object.keys(leafContent).reduce((count, type) => {
248
- return count + Object.keys(leafContent[type]).length;
249
- }, 0);
250
- const buffer = Buffer.alloc(totalItemsCount * 16);
251
-
252
- let offset = 0;
253
-
254
- // iterate through the item types lexicographically
255
- const itemTypes = Object.keys(leafContent).sort();
256
- itemTypes.forEach((type) => {
257
- // iterate through the items of this type in ascending order of ID
258
- const items = Object.values(leafContent[type]).sort(
259
- (a: LeafDataItem, b: LeafDataItem) => a.id - b.id
260
- );
261
-
262
- // add all the items id and version to the hasher
263
- items.forEach((item: LeafDataItem) => {
264
- buffer.writeBigInt64LE(BigInt(item.id), offset);
265
- buffer.writeBigInt64LE(BigInt(item.version), offset + 8);
266
-
267
- offset += 16;
268
- });
269
- });
270
-
271
- this.leafHashes[index] = XXH3_128(buffer, BigInt(0)).toString(16).padStart(32, '0');
272
- }
273
-
274
- /**
275
- * Computes all internal and leaf node hashes of the tree.
276
- * Internal node hashes are computed bottom-up from the leaf hashes.
277
- * @returns {string[]} An array of hash strings, with internal node hashes first, followed by leaf hashes.
278
- * Returns `[EMPTY_HASH]` if the tree has 0 leaves.
279
- */
280
- computeTreeHashes(): string[] {
281
- if (this.numLeaves === 0) {
282
- return [EMPTY_HASH];
283
- }
284
-
285
- let currentLevelHashes = [...this.leafHashes];
286
- const allHashes = [];
287
-
288
- while (currentLevelHashes.length > 1) {
289
- const nextLevelHashes: string[] = [];
290
- for (let i = 0; i < currentLevelHashes.length; i += 2) {
291
- const leftHash = currentLevelHashes[i];
292
- const rightHash = i + 1 < currentLevelHashes.length ? currentLevelHashes[i + 1] : leftHash;
293
-
294
- const input = Buffer.concat([
295
- Buffer.from(leftHash, 'hex').subarray(0, 8).reverse(),
296
- Buffer.from(leftHash, 'hex').subarray(8, 16).reverse(),
297
- Buffer.from(rightHash, 'hex').subarray(0, 8).reverse(),
298
- Buffer.from(rightHash, 'hex').subarray(8, 16).reverse(),
299
- ]);
300
-
301
- nextLevelHashes.push(XXH3_128(input, BigInt(0)).toString(16).padStart(32, '0'));
302
- }
303
- currentLevelHashes = nextLevelHashes;
304
- allHashes.unshift(...currentLevelHashes);
305
- }
306
-
307
- return [...allHashes, ...this.leafHashes];
308
- }
309
-
310
- /**
311
- * Returns all hashes in the tree (internal nodes then leaf nodes).
312
- * @returns {string[]} An array of hash strings.
313
- */
314
- getHashes(): string[] {
315
- return this.computeTreeHashes();
316
- }
317
-
318
- /**
319
- * Computes and returns the hash value of the root node.
320
- * @returns {string} The root hash of the entire tree. Returns `EMPTY_HASH` if the tree has 0 leaves.
321
- */
322
- getRootHash(): string {
323
- if (this.numLeaves === 0) {
324
- return EMPTY_HASH;
325
- }
326
-
327
- return this.computeTreeHashes()[0];
328
- }
329
-
330
- /**
331
- * Gets the number of leaves in the tree.
332
- * @returns {number} The number of leaves.
333
- */
334
- getLeafCount(): number {
335
- return this.numLeaves;
336
- }
337
-
338
- /**
339
- * Calculates the total number of items stored in the tree.
340
- * @returns {number} The total number of items.
341
- */
342
- getTotalItemCount(): number {
343
- let count = 0;
344
- for (const leaf of this.leaves) {
345
- for (const type of Object.keys(leaf)) {
346
- count += Object.keys(leaf[type]).length;
347
- }
348
- }
349
-
350
- return count;
351
- }
352
-
353
- /**
354
- * Retrieves all data items from a specific leaf.
355
- * @param {number} leafIndex The index of the leaf.
356
- * @returns {LeafDataItem[]} An array of LeafDataItem in the specified leaf, sorted by ID,
357
- * or an empty array if the index is invalid or leaf is empty.
358
- */
359
- getLeafData(leafIndex: number): LeafDataItem[] {
360
- if (leafIndex < 0 || leafIndex >= this.numLeaves) {
361
- return [];
362
- }
363
- const leafContent = this.leaves[leafIndex];
364
- const items: LeafDataItem[] = [];
365
- for (const type of Object.keys(leafContent)) {
366
- items.push(...Object.values(leafContent[type]));
367
- }
368
- // Optionally sort them if a specific order is required, e.g., by ID
369
- items.sort((a, b) => a.id - b.id);
370
-
371
- return items;
372
- }
373
-
374
- /**
375
- * Retrieves the version of a specific item by its id and type.
376
- * @param {number} id The ID of the item.
377
- * @param {ObjectType} type The type of the item.
378
- * @returns {number | undefined} The version of the item if found, undefined otherwise.
379
- */
380
- getItemVersion(id: number, type: ObjectType): number | undefined {
381
- if (this.numLeaves === 0) {
382
- return undefined;
383
- }
384
-
385
- const index = id % this.numLeaves;
386
- const item = this.leaves[index]?.[type]?.[id];
387
-
388
- return item?.version;
389
- }
390
-
391
- /**
392
- * Resizes the HashTree to have a new number of leaf nodes, redistributing all existing items.
393
- * @param {number} newNumLeaves The new number of leaf nodes (must be 0 or a power of 2).
394
- * @returns {boolean} true if the tree was resized, false if the size didn't change.
395
- * @throws {Error} if newNumLeaves is not 0 or a power of 2.
396
- */
397
- resize(newNumLeaves: number): boolean {
398
- // eslint-disable-next-line no-bitwise
399
- if (newNumLeaves < 0 || (newNumLeaves !== 0 && (newNumLeaves & (newNumLeaves - 1)) !== 0)) {
400
- throw new Error('New number of leaves must be 0 or a power of 2');
401
- }
402
-
403
- if (newNumLeaves === this.numLeaves) {
404
- return false;
405
- }
406
-
407
- const allItems: LeafDataItem[] = [];
408
- for (const leaf of this.leaves) {
409
- for (const type of Object.keys(leaf)) {
410
- allItems.push(...Object.values(leaf[type]));
411
- }
412
- }
413
-
414
- // Re-initialize
415
- // eslint-disable-next-line no-extra-semi
416
- (this as any).numLeaves = newNumLeaves; // Type assertion to update readonly property
417
- this.leafHashes = new Array(newNumLeaves).fill(EMPTY_HASH);
418
- this.leaves = new Array(newNumLeaves).fill(null).map(() => ({}));
419
-
420
- if (newNumLeaves > 0) {
421
- this.putItems(allItems); // Re-add items which will be re-assigned to leaves and re-hashed
422
- }
423
-
424
- return true;
425
- }
426
-
427
- /**
428
- * Compares the tree's leaf hashes with an external set of hashes and returns the indices of differing leaf nodes.
429
- * The externalHashes array is expected to contain all node hashes (internal followed by leaves),
430
- * similar to the output of getHashes().
431
- * @param {string[]} externalHashes An array of hash strings (internal node hashes then leaf hashes).
432
- * @returns {number[]} An array of indices of the leaf nodes that have different hashes.
433
- */
434
- diffHashes(externalHashes: string[]): number[] {
435
- if (this.numLeaves === 0) {
436
- // If this tree is empty, its hash is EMPTY_HASH.
437
- // It differs if externalHashes is not a single EMPTY_HASH.
438
- if (externalHashes && externalHashes.length === 1 && externalHashes[0] === EMPTY_HASH) {
439
- return []; // No differences
440
- }
441
- // An empty tree has no leaves to differ, so return an empty array
442
- // as no specific leaf indexes are different.
443
-
444
- return [];
445
- }
446
-
447
- // We are interested in comparing the leaf hashes part.
448
- // The externalHashes array should also have its leaf hashes at the end.
449
- const differingLeafIndexes: number[] = [];
450
- // Calculate where the leaf hashes would start in the externalHashes array,
451
- // assuming it has the same number of leaves as this tree.
452
- const externalLeafHashesStart = externalHashes.length - this.numLeaves;
453
-
454
- if (externalLeafHashesStart < 0) {
455
- // externalHashes is too short to contain a complete set of leaf hashes
456
- // corresponding to this tree's numLeaves.
457
- // In this case, consider all of this tree's leaves as "different".
458
- for (let i = 0; i < this.numLeaves; i += 1) {
459
- differingLeafIndexes.push(i);
460
- }
461
-
462
- return differingLeafIndexes;
463
- }
464
-
465
- // Compare each leaf hash
466
- for (let i = 0; i < this.numLeaves; i += 1) {
467
- const ownLeafHash = this.leafHashes[i];
468
- // externalLeafHash might be undefined if externalHashes is shorter than expected
469
- // but externalLeafHashesStart was non-negative, implying a structural mismatch.
470
- const externalLeafHash = externalHashes[externalLeafHashesStart + i];
471
- if (ownLeafHash !== externalLeafHash) {
472
- differingLeafIndexes.push(i);
473
- }
474
- }
475
-
476
- return differingLeafIndexes;
477
- }
478
- }
479
-
480
- export default HashTree;
@@ -1,62 +0,0 @@
1
- /* eslint-disable import/prefer-default-export */
2
-
3
- import {ObjectType, HashTreeObject} from './types';
4
-
5
- /**
6
- * Checks if the given hash tree object is of type "self"
7
- * @param {HashTreeObject} object object to check
8
- * @returns {boolean} True if the object is of type "self", false otherwise
9
- */
10
- export function isSelf(object: HashTreeObject) {
11
- return object.htMeta.elementId.type.toLowerCase() === ObjectType.self;
12
- }
13
-
14
- /**
15
- * Checks if the given hash tree object is of type "Metadata"
16
- * @param {HashTreeObject} object object to check
17
- * @returns {boolean} True if the object is of type "Metadata", false otherwise
18
- */
19
- export function isMetadata(object: HashTreeObject) {
20
- return object.htMeta.elementId.type.toLowerCase() === ObjectType.metadata;
21
- }
22
-
23
- /**
24
- * Analyzes given part of Locus DTO recursively and delete any nested objects that have their own htMeta
25
- *
26
- * @param {Object} currentLocusPart part of locus DTO to analyze
27
- * @param {Object} parent parent object
28
- * @param {string|number} currentKey key of the parent object that currentLocusPart is
29
- * @returns {void}
30
- */
31
- export const deleteNestedObjectsWithHtMeta = (
32
- currentLocusPart: any,
33
- parent?: any,
34
- currentKey?: string | number
35
- ) => {
36
- if (typeof currentLocusPart !== 'object' || currentLocusPart === null) {
37
- return;
38
- }
39
-
40
- if (parent && currentKey !== undefined && currentLocusPart.htMeta) {
41
- if (Array.isArray(parent)) {
42
- parent.splice(Number(currentKey), 1);
43
- } else {
44
- delete parent[currentKey];
45
- }
46
-
47
- return;
48
- }
49
-
50
- if (Array.isArray(currentLocusPart)) {
51
- // iterate array in reverse, so that indexes remain valid when deleting elements
52
- for (let i = currentLocusPart.length - 1; i >= 0; i -= 1) {
53
- deleteNestedObjectsWithHtMeta(currentLocusPart[i], currentLocusPart, i);
54
- }
55
- } else {
56
- for (const key of Object.keys(currentLocusPart)) {
57
- if (Object.prototype.hasOwnProperty.call(currentLocusPart, key)) {
58
- deleteNestedObjectsWithHtMeta(currentLocusPart[key], currentLocusPart, key);
59
- }
60
- }
61
- }
62
- };
@@ -1,6 +0,0 @@
1
- const DATA_CHANNEL_AUTH_HEADER = 'Data-Channel-Auth-Token';
2
- const MAX_RETRY = 1;
3
- const RETRY_INTERVAL = 2000;
4
- const RETRY_KEY = '_dcRetryKey';
5
-
6
- export {DATA_CHANNEL_AUTH_HEADER, MAX_RETRY, RETRY_INTERVAL, RETRY_KEY};