@itwin/presentation-frontend 5.0.0-dev.6 → 5.0.0-dev.62

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 (98) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.d.ts +3 -3
  3. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.d.ts.map +1 -1
  4. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js +11 -9
  5. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
  6. package/lib/cjs/presentation-frontend/Diagnostics.js.map +1 -1
  7. package/lib/cjs/presentation-frontend/FrontendLoggerCategory.js.map +1 -1
  8. package/lib/cjs/presentation-frontend/IpcRequestsHandler.js +2 -1
  9. package/lib/cjs/presentation-frontend/IpcRequestsHandler.js.map +1 -1
  10. package/lib/cjs/presentation-frontend/LocalizationHelper.js +1 -0
  11. package/lib/cjs/presentation-frontend/LocalizationHelper.js.map +1 -1
  12. package/lib/cjs/presentation-frontend/Presentation.js +5 -5
  13. package/lib/cjs/presentation-frontend/Presentation.js.map +1 -1
  14. package/lib/cjs/presentation-frontend/PresentationManager.d.ts +4 -2
  15. package/lib/cjs/presentation-frontend/PresentationManager.d.ts.map +1 -1
  16. package/lib/cjs/presentation-frontend/PresentationManager.js +31 -21
  17. package/lib/cjs/presentation-frontend/PresentationManager.js.map +1 -1
  18. package/lib/cjs/presentation-frontend/RulesetManager.js +2 -4
  19. package/lib/cjs/presentation-frontend/RulesetManager.js.map +1 -1
  20. package/lib/cjs/presentation-frontend/RulesetVariablesManager.js +4 -2
  21. package/lib/cjs/presentation-frontend/RulesetVariablesManager.js.map +1 -1
  22. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.js +1 -0
  23. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.js.map +1 -1
  24. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts +4 -2
  25. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
  26. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +142 -126
  27. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
  28. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts +2 -3
  29. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts.map +1 -1
  30. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +21 -19
  31. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
  32. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.js +2 -0
  33. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.js.map +1 -1
  34. package/lib/cjs/presentation-frontend/selection/ISelectionProvider.js.map +1 -1
  35. package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.js.map +1 -1
  36. package/lib/cjs/presentation-frontend/selection/SelectionHandler.d.ts +3 -2
  37. package/lib/cjs/presentation-frontend/selection/SelectionHandler.d.ts.map +1 -1
  38. package/lib/cjs/presentation-frontend/selection/SelectionHandler.js +33 -13
  39. package/lib/cjs/presentation-frontend/selection/SelectionHandler.js.map +1 -1
  40. package/lib/cjs/presentation-frontend/selection/SelectionHelper.js.map +1 -1
  41. package/lib/cjs/presentation-frontend/selection/SelectionManager.d.ts +25 -7
  42. package/lib/cjs/presentation-frontend/selection/SelectionManager.d.ts.map +1 -1
  43. package/lib/cjs/presentation-frontend/selection/SelectionManager.js +190 -87
  44. package/lib/cjs/presentation-frontend/selection/SelectionManager.js.map +1 -1
  45. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.d.ts +0 -7
  46. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.d.ts.map +1 -1
  47. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js +3 -11
  48. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
  49. package/lib/cjs/presentation-frontend.js.map +1 -1
  50. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.d.ts +3 -3
  51. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.d.ts.map +1 -1
  52. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js +11 -9
  53. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
  54. package/lib/esm/presentation-frontend/Diagnostics.js.map +1 -1
  55. package/lib/esm/presentation-frontend/FrontendLoggerCategory.js.map +1 -1
  56. package/lib/esm/presentation-frontend/IpcRequestsHandler.js +2 -1
  57. package/lib/esm/presentation-frontend/IpcRequestsHandler.js.map +1 -1
  58. package/lib/esm/presentation-frontend/LocalizationHelper.js +1 -0
  59. package/lib/esm/presentation-frontend/LocalizationHelper.js.map +1 -1
  60. package/lib/esm/presentation-frontend/Presentation.js +5 -5
  61. package/lib/esm/presentation-frontend/Presentation.js.map +1 -1
  62. package/lib/esm/presentation-frontend/PresentationManager.d.ts +4 -2
  63. package/lib/esm/presentation-frontend/PresentationManager.d.ts.map +1 -1
  64. package/lib/esm/presentation-frontend/PresentationManager.js +32 -22
  65. package/lib/esm/presentation-frontend/PresentationManager.js.map +1 -1
  66. package/lib/esm/presentation-frontend/RulesetManager.js +2 -4
  67. package/lib/esm/presentation-frontend/RulesetManager.js.map +1 -1
  68. package/lib/esm/presentation-frontend/RulesetVariablesManager.js +4 -2
  69. package/lib/esm/presentation-frontend/RulesetVariablesManager.js.map +1 -1
  70. package/lib/esm/presentation-frontend/StreamedResponseGenerator.js +1 -0
  71. package/lib/esm/presentation-frontend/StreamedResponseGenerator.js.map +1 -1
  72. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts +4 -2
  73. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
  74. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +143 -127
  75. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
  76. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts +2 -3
  77. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts.map +1 -1
  78. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +22 -20
  79. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
  80. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.js +2 -0
  81. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.js.map +1 -1
  82. package/lib/esm/presentation-frontend/selection/ISelectionProvider.js.map +1 -1
  83. package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.js.map +1 -1
  84. package/lib/esm/presentation-frontend/selection/SelectionHandler.d.ts +3 -2
  85. package/lib/esm/presentation-frontend/selection/SelectionHandler.d.ts.map +1 -1
  86. package/lib/esm/presentation-frontend/selection/SelectionHandler.js +33 -13
  87. package/lib/esm/presentation-frontend/selection/SelectionHandler.js.map +1 -1
  88. package/lib/esm/presentation-frontend/selection/SelectionHelper.js.map +1 -1
  89. package/lib/esm/presentation-frontend/selection/SelectionManager.d.ts +25 -7
  90. package/lib/esm/presentation-frontend/selection/SelectionManager.d.ts.map +1 -1
  91. package/lib/esm/presentation-frontend/selection/SelectionManager.js +191 -88
  92. package/lib/esm/presentation-frontend/selection/SelectionManager.js.map +1 -1
  93. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.d.ts +0 -7
  94. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.d.ts.map +1 -1
  95. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js +3 -10
  96. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
  97. package/lib/esm/presentation-frontend.js.map +1 -1
  98. package/package.json +19 -18
@@ -5,8 +5,60 @@
5
5
  /** @packageDocumentation
6
6
  * @module UnifiedSelection
7
7
  */
8
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
9
+ if (value !== null && value !== void 0) {
10
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
11
+ var dispose, inner;
12
+ if (async) {
13
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
14
+ dispose = value[Symbol.asyncDispose];
15
+ }
16
+ if (dispose === void 0) {
17
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
18
+ dispose = value[Symbol.dispose];
19
+ if (async) inner = dispose;
20
+ }
21
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
22
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
23
+ env.stack.push({ value: value, dispose: dispose, async: async });
24
+ }
25
+ else if (async) {
26
+ env.stack.push({ async: true });
27
+ }
28
+ return value;
29
+ };
30
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
31
+ return function (env) {
32
+ function fail(e) {
33
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
34
+ env.hasError = true;
35
+ }
36
+ var r, s = 0;
37
+ function next() {
38
+ while (r = env.stack.pop()) {
39
+ try {
40
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
41
+ if (r.dispose) {
42
+ var result = r.dispose.call(r.value);
43
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
44
+ }
45
+ else s |= 1;
46
+ }
47
+ catch (e) {
48
+ fail(e);
49
+ }
50
+ }
51
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
52
+ if (env.hasError) throw env.error;
53
+ }
54
+ return next();
55
+ };
56
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
57
+ var e = new Error(message);
58
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
59
+ });
8
60
  import { defer, EMPTY, mergeMap, of, Subject, takeUntil, tap } from "rxjs";
9
- import { Id64, using } from "@itwin/core-bentley";
61
+ import { Id64 } from "@itwin/core-bentley";
10
62
  import { IModelConnection, SelectionSetEventType } from "@itwin/core-frontend";
11
63
  import { AsyncTasksTracker, KeySet, NodeKey } from "@itwin/presentation-common";
12
64
  import { createStorage, TRANSIENT_ELEMENT_CLASSNAME, } from "@itwin/unified-selection";
@@ -19,40 +71,59 @@ import { createSelectionScopeProps } from "./SelectionScopesManager";
19
71
  * @public
20
72
  */
21
73
  export class SelectionManager {
74
+ _imodelKeyFactory;
75
+ _imodelToolSelectionSyncHandlers = new Map();
76
+ _hiliteSetProviders = new Map();
77
+ _ownsStorage;
78
+ _knownIModels = new Set();
79
+ _currentSelection = new CurrentSelectionStorage();
80
+ _selectionChanges = new Subject();
81
+ _selectionEventsSubscription;
82
+ _listeners = [];
83
+ /**
84
+ * Underlying selection storage used by this selection manager. Ideally, consumers should use
85
+ * the storage directly instead of using this manager to manipulate selection.
86
+ */
87
+ selectionStorage;
88
+ /** An event which gets broadcasted on selection changes */
89
+ selectionChange;
90
+ /** Manager for [selection scopes]($docs/presentation/unified-selection/index#selection-scopes) */
91
+ scopes;
22
92
  /**
23
93
  * Creates an instance of SelectionManager.
24
94
  */
25
95
  constructor(props) {
26
- this._imodelToolSelectionSyncHandlers = new Map();
27
- this._hiliteSetProviders = new Map();
28
- this._knownIModels = new Map();
29
- this._currentSelection = new CurrentSelectionStorage();
30
- this._selectionChanges = new Subject();
31
- this._listeners = [];
32
96
  this.selectionChange = new SelectionChangeEvent();
33
97
  this.scopes = props.scopes;
34
- this._selectionStorage = props.selectionStorage ?? createStorage();
98
+ this.selectionStorage = props.selectionStorage ?? createStorage();
99
+ this._imodelKeyFactory = props.imodelKeyFactory ?? ((imodel) => (imodel.key.length ? imodel.key : imodel.name));
35
100
  this._ownsStorage = props.selectionStorage === undefined;
36
- this._selectionStorage.selectionChangeEvent.addListener((args) => this._selectionChanges.next(args));
101
+ this.selectionStorage.selectionChangeEvent.addListener((args) => this._selectionChanges.next(args));
37
102
  this._selectionEventsSubscription = this.streamSelectionEvents();
38
103
  this._listeners.push(IModelConnection.onOpen.addListener((imodel) => {
39
- this._knownIModels.set(imodel.key, imodel);
104
+ this._knownIModels.add(imodel);
40
105
  }));
41
106
  this._listeners.push(IModelConnection.onClose.addListener((imodel) => {
42
107
  this.onConnectionClose(imodel);
43
108
  }));
44
109
  }
45
- dispose() {
110
+ [Symbol.dispose]() {
46
111
  this._selectionEventsSubscription.unsubscribe();
47
112
  this._listeners.forEach((dispose) => dispose());
48
113
  }
114
+ /** @deprecated in 5.0. Use [Symbol.dispose] instead. */
115
+ // istanbul ignore next
116
+ dispose() {
117
+ this[Symbol.dispose]();
118
+ }
49
119
  onConnectionClose(imodel) {
120
+ const imodelKey = this._imodelKeyFactory(imodel);
50
121
  this._hiliteSetProviders.delete(imodel);
51
- this._knownIModels.delete(imodel.key);
52
- this._currentSelection.clear(imodel.key);
122
+ this._knownIModels.delete(imodel);
123
+ this._currentSelection.clear(imodelKey);
53
124
  if (this._ownsStorage) {
54
125
  this.clearSelection("Connection Close Event", imodel);
55
- this._selectionStorage.clearStorage({ iModelKey: imodel.key });
126
+ this.selectionStorage.clearStorage({ imodelKey });
56
127
  }
57
128
  }
58
129
  /** @internal */
@@ -81,27 +152,30 @@ export class SelectionManager {
81
152
  }
82
153
  else {
83
154
  this._imodelToolSelectionSyncHandlers.delete(imodel);
84
- registration.handler.dispose();
155
+ registration.handler[Symbol.dispose]();
85
156
  }
86
157
  }
87
158
  }
88
159
  }
89
160
  /**
90
- * Temporarily suspends tool selection synchronization until the returned `IDisposable`
161
+ * Temporarily suspends tool selection synchronization until the returned `Disposable`
91
162
  * is disposed.
92
163
  */
93
164
  suspendIModelToolSelectionSync(imodel) {
94
165
  const registration = this._imodelToolSelectionSyncHandlers.get(imodel);
95
166
  if (!registration) {
96
- return { dispose: () => { } };
167
+ const noop = () => { };
168
+ return { [Symbol.dispose]: noop, dispose: noop };
97
169
  }
98
170
  const wasSuspended = registration.handler.isSuspended;
99
171
  registration.handler.isSuspended = true;
100
- return { dispose: () => (registration.handler.isSuspended = wasSuspended) };
172
+ const doDispose = () => (registration.handler.isSuspended = wasSuspended);
173
+ return { [Symbol.dispose]: doDispose, dispose: doDispose };
101
174
  }
102
175
  /** Get the selection levels currently stored in this manager for the specified imodel */
103
176
  getSelectionLevels(imodel) {
104
- return this._selectionStorage.getSelectionLevels({ iModelKey: imodel.key });
177
+ const imodelKey = this._imodelKeyFactory(imodel);
178
+ return this.selectionStorage.getSelectionLevels({ imodelKey });
105
179
  }
106
180
  /**
107
181
  * Get the selection currently stored in this manager
@@ -111,39 +185,39 @@ export class SelectionManager {
111
185
  * latest selection after changes.
112
186
  */
113
187
  getSelection(imodel, level = 0) {
114
- return this._currentSelection.getSelection(imodel.key, level);
188
+ const imodelKey = this._imodelKeyFactory(imodel);
189
+ return this._currentSelection.getSelection(imodelKey, level);
115
190
  }
116
191
  handleEvent(evt) {
117
- if (!this._knownIModels.has(evt.imodel.key)) {
118
- this._knownIModels.set(evt.imodel.key, evt.imodel);
119
- }
192
+ const imodelKey = this._imodelKeyFactory(evt.imodel);
193
+ this._knownIModels.add(evt.imodel);
120
194
  switch (evt.changeType) {
121
195
  case SelectionChangeType.Add:
122
- this._selectionStorage.addToSelection({
123
- iModelKey: evt.imodel.key,
196
+ this.selectionStorage.addToSelection({
197
+ imodelKey,
124
198
  source: evt.source,
125
199
  level: evt.level,
126
200
  selectables: keysToSelectable(evt.imodel, evt.keys),
127
201
  });
128
202
  break;
129
203
  case SelectionChangeType.Remove:
130
- this._selectionStorage.removeFromSelection({
131
- iModelKey: evt.imodel.key,
204
+ this.selectionStorage.removeFromSelection({
205
+ imodelKey,
132
206
  source: evt.source,
133
207
  level: evt.level,
134
208
  selectables: keysToSelectable(evt.imodel, evt.keys),
135
209
  });
136
210
  break;
137
211
  case SelectionChangeType.Replace:
138
- this._selectionStorage.replaceSelection({
139
- iModelKey: evt.imodel.key,
212
+ this.selectionStorage.replaceSelection({
213
+ imodelKey,
140
214
  source: evt.source,
141
215
  level: evt.level,
142
216
  selectables: keysToSelectable(evt.imodel, evt.keys),
143
217
  });
144
218
  break;
145
219
  case SelectionChangeType.Clear:
146
- this._selectionStorage.clearSelection({ iModelKey: evt.imodel.key, source: evt.source, level: evt.level });
220
+ this.selectionStorage.clearSelection({ imodelKey, source: evt.source, level: evt.level });
147
221
  break;
148
222
  }
149
223
  }
@@ -290,9 +364,9 @@ export class SelectionManager {
290
364
  streamSelectionEvents() {
291
365
  return this._selectionChanges
292
366
  .pipe(mergeMap((args) => {
293
- const currentSelectables = this._selectionStorage.getSelection({ iModelKey: args.imodelKey, level: args.level });
367
+ const currentSelectables = this.selectionStorage.getSelection({ imodelKey: args.imodelKey, level: args.level });
294
368
  return this._currentSelection.computeSelection(args.imodelKey, args.level, currentSelectables, args.selectables).pipe(mergeMap(({ level, changedSelection }) => {
295
- const imodel = this._knownIModels.get(args.imodelKey);
369
+ const imodel = findIModel(this._knownIModels, this._imodelKeyFactory, args.imodelKey);
296
370
  // istanbul ignore if
297
371
  if (!imodel) {
298
372
  return EMPTY;
@@ -314,12 +388,37 @@ export class SelectionManager {
314
388
  });
315
389
  }
316
390
  }
391
+ function findIModel(set, imodelKeyFactory, key) {
392
+ for (const imodel of set) {
393
+ if (imodelKeyFactory(imodel) === key) {
394
+ return imodel;
395
+ }
396
+ }
397
+ return undefined;
398
+ }
317
399
  /** @internal */
318
400
  export class ToolSelectionSyncHandler {
401
+ _selectionSourceName = "Tool";
402
+ _logicalSelection;
403
+ _imodel;
404
+ _imodelToolSelectionListenerDisposeFunc;
405
+ _asyncsTracker = new AsyncTasksTracker();
406
+ isSuspended;
319
407
  constructor(imodel, logicalSelection) {
320
- this._selectionSourceName = "Tool";
321
- this._asyncsTracker = new AsyncTasksTracker();
322
- this.onToolSelectionChanged = async (ev) => {
408
+ this._imodel = imodel;
409
+ this._logicalSelection = logicalSelection;
410
+ this._imodelToolSelectionListenerDisposeFunc = imodel.selectionSet.onChanged.addListener(this.onToolSelectionChanged);
411
+ }
412
+ [Symbol.dispose]() {
413
+ this._imodelToolSelectionListenerDisposeFunc();
414
+ }
415
+ /** note: used only it tests */
416
+ get pendingAsyncs() {
417
+ return this._asyncsTracker.pendingAsyncs;
418
+ }
419
+ onToolSelectionChanged = async (ev) => {
420
+ const env_1 = { stack: [], error: void 0, hasError: false };
421
+ try {
323
422
  // ignore selection change event if the handler is suspended
324
423
  if (this.isSuspended) {
325
424
  return;
@@ -335,13 +434,13 @@ export class ToolSelectionSyncHandler {
335
434
  let ids;
336
435
  switch (ev.type) {
337
436
  case SelectionSetEventType.Add:
338
- ids = ev.added;
437
+ ids = ev.additions;
339
438
  break;
340
439
  case SelectionSetEventType.Replace:
341
- ids = ev.set.elements;
440
+ ids = ev.set.active;
342
441
  break;
343
442
  default:
344
- ids = ev.removed;
443
+ ids = ev.removals;
345
444
  break;
346
445
  }
347
446
  // we're always using scoped selection changer even if the scope is set to "element" - that
@@ -349,39 +448,32 @@ export class ToolSelectionSyncHandler {
349
448
  // we can't because otherwise our keys compare fails (presentation components load data with
350
449
  // concrete classes)
351
450
  const changer = new ScopedSelectionChanger(this._selectionSourceName, this._imodel, this._logicalSelection, createSelectionScopeProps(this._logicalSelection.scopes.activeScope));
352
- // we know what to do immediately on `clear` events
353
- if (SelectionSetEventType.Clear === ev.type) {
354
- await changer.clear(selectionLevel);
355
- return;
451
+ const _r = __addDisposableResource(env_1, this._asyncsTracker.trackAsyncTask(), false);
452
+ switch (ev.type) {
453
+ case SelectionSetEventType.Add:
454
+ await changer.add(ids, selectionLevel);
455
+ break;
456
+ case SelectionSetEventType.Replace:
457
+ await changer.replace(ids, selectionLevel);
458
+ break;
459
+ case SelectionSetEventType.Remove:
460
+ await changer.remove(ids, selectionLevel);
461
+ break;
462
+ case SelectionSetEventType.Clear:
463
+ await changer.clear(selectionLevel);
464
+ break;
356
465
  }
357
- const parsedIds = parseIds(ids);
358
- await using(this._asyncsTracker.trackAsyncTask(), async (_r) => {
359
- switch (ev.type) {
360
- case SelectionSetEventType.Add:
361
- await changer.add(parsedIds.transient, parsedIds.persistent, selectionLevel);
362
- break;
363
- case SelectionSetEventType.Replace:
364
- await changer.replace(parsedIds.transient, parsedIds.persistent, selectionLevel);
365
- break;
366
- case SelectionSetEventType.Remove:
367
- await changer.remove(parsedIds.transient, parsedIds.persistent, selectionLevel);
368
- break;
369
- }
370
- });
371
- };
372
- this._imodel = imodel;
373
- this._logicalSelection = logicalSelection;
374
- this._imodelToolSelectionListenerDisposeFunc = imodel.selectionSet.onChanged.addListener(this.onToolSelectionChanged);
375
- }
376
- dispose() {
377
- this._imodelToolSelectionListenerDisposeFunc();
378
- }
379
- /** note: used only it tests */
380
- get pendingAsyncs() {
381
- return this._asyncsTracker.pendingAsyncs;
382
- }
466
+ }
467
+ catch (e_1) {
468
+ env_1.error = e_1;
469
+ env_1.hasError = true;
470
+ }
471
+ finally {
472
+ __disposeResources(env_1);
473
+ }
474
+ };
383
475
  }
384
- const parseIds = (ids) => {
476
+ const parseElementIds = (ids) => {
385
477
  let allPersistent = true;
386
478
  let allTransient = true;
387
479
  for (const id of Id64.iterable(ids)) {
@@ -416,13 +508,16 @@ const parseIds = (ids) => {
416
508
  }
417
509
  return { persistent: persistentElementIds, transient: transientElementIds };
418
510
  };
419
- function addTransientKeys(transientIds, keys) {
420
- for (const id of Id64.iterable(transientIds)) {
421
- keys.add({ className: TRANSIENT_ELEMENT_CLASSNAME, id });
511
+ function addKeys(target, className, ids) {
512
+ for (const id of Id64.iterable(ids)) {
513
+ target.add({ className, id });
422
514
  }
423
515
  }
424
- /** @internal */
425
516
  class ScopedSelectionChanger {
517
+ name;
518
+ imodel;
519
+ manager;
520
+ scope;
426
521
  constructor(name, imodel, manager, scope) {
427
522
  this.name = name;
428
523
  this.imodel = imodel;
@@ -432,27 +527,37 @@ class ScopedSelectionChanger {
432
527
  async clear(level) {
433
528
  this.manager.clearSelection(this.name, this.imodel, level);
434
529
  }
435
- async add(transientIds, persistentIds, level) {
436
- const keys = await this.manager.scopes.computeSelection(this.imodel, persistentIds, this.scope);
437
- addTransientKeys(transientIds, keys);
530
+ async add(ids, level) {
531
+ const keys = await this.#computeSelection(ids);
438
532
  this.manager.addToSelection(this.name, this.imodel, keys, level);
439
533
  }
440
- async remove(transientIds, persistentIds, level) {
441
- const keys = await this.manager.scopes.computeSelection(this.imodel, persistentIds, this.scope);
442
- addTransientKeys(transientIds, keys);
534
+ async remove(ids, level) {
535
+ const keys = await this.#computeSelection(ids);
443
536
  this.manager.removeFromSelection(this.name, this.imodel, keys, level);
444
537
  }
445
- async replace(transientIds, persistentIds, level) {
446
- const keys = await this.manager.scopes.computeSelection(this.imodel, persistentIds, this.scope);
447
- addTransientKeys(transientIds, keys);
538
+ async replace(ids, level) {
539
+ const keys = await this.#computeSelection(ids);
448
540
  this.manager.replaceSelection(this.name, this.imodel, keys, level);
449
541
  }
542
+ async #computeSelection(ids) {
543
+ let keys = new KeySet();
544
+ if (ids.elements) {
545
+ const { persistent, transient } = parseElementIds(ids.elements);
546
+ keys = await this.manager.scopes.computeSelection(this.imodel, persistent, this.scope);
547
+ addKeys(keys, TRANSIENT_ELEMENT_CLASSNAME, transient);
548
+ }
549
+ if (ids.models) {
550
+ addKeys(keys, "BisCore.Model", ids.models);
551
+ }
552
+ if (ids.subcategories) {
553
+ addKeys(keys, "BisCore.SubCategory", ids.subcategories);
554
+ }
555
+ return keys;
556
+ }
450
557
  }
451
558
  /** Stores current selection in `KeySet` format per iModel. */
452
559
  class CurrentSelectionStorage {
453
- constructor() {
454
- this._currentSelection = new Map();
455
- }
560
+ _currentSelection = new Map();
456
561
  getCurrentSelectionStorage(imodelKey) {
457
562
  let storage = this._currentSelection.get(imodelKey);
458
563
  if (!storage) {
@@ -476,9 +581,7 @@ class CurrentSelectionStorage {
476
581
  * It always stores result of latest resolved call to `computeSelection`.
477
582
  */
478
583
  class IModelSelectionStorage {
479
- constructor() {
480
- this._currentSelection = new Map();
481
- }
584
+ _currentSelection = new Map();
482
585
  getSelection(level) {
483
586
  let entry = this._currentSelection.get(level);
484
587
  if (!entry) {