@itwin/unified-selection 1.1.1 → 1.2.0

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 (41) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +5 -5
  3. package/lib/cjs/unified-selection/CachingHiliteSetProvider.d.ts +14 -2
  4. package/lib/cjs/unified-selection/CachingHiliteSetProvider.d.ts.map +1 -1
  5. package/lib/cjs/unified-selection/CachingHiliteSetProvider.js +5 -1
  6. package/lib/cjs/unified-selection/CachingHiliteSetProvider.js.map +1 -1
  7. package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts +11 -7
  8. package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts.map +1 -1
  9. package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.js +172 -85
  10. package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.js.map +1 -1
  11. package/lib/cjs/unified-selection/SelectionScope.d.ts +2 -1
  12. package/lib/cjs/unified-selection/SelectionScope.d.ts.map +1 -1
  13. package/lib/cjs/unified-selection/SelectionScope.js +10 -5
  14. package/lib/cjs/unified-selection/SelectionScope.js.map +1 -1
  15. package/lib/cjs/unified-selection/Utils.d.ts +14 -0
  16. package/lib/cjs/unified-selection/Utils.d.ts.map +1 -1
  17. package/lib/cjs/unified-selection/Utils.js +18 -0
  18. package/lib/cjs/unified-selection/Utils.js.map +1 -1
  19. package/lib/cjs/unified-selection/types/IModel.d.ts +51 -3
  20. package/lib/cjs/unified-selection/types/IModel.d.ts.map +1 -1
  21. package/lib/cjs/unified-selection/types/IModel.js.map +1 -1
  22. package/lib/esm/unified-selection/CachingHiliteSetProvider.d.ts +14 -2
  23. package/lib/esm/unified-selection/CachingHiliteSetProvider.d.ts.map +1 -1
  24. package/lib/esm/unified-selection/CachingHiliteSetProvider.js +5 -1
  25. package/lib/esm/unified-selection/CachingHiliteSetProvider.js.map +1 -1
  26. package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts +11 -7
  27. package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts.map +1 -1
  28. package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.js +173 -86
  29. package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.js.map +1 -1
  30. package/lib/esm/unified-selection/SelectionScope.d.ts +2 -1
  31. package/lib/esm/unified-selection/SelectionScope.d.ts.map +1 -1
  32. package/lib/esm/unified-selection/SelectionScope.js +10 -5
  33. package/lib/esm/unified-selection/SelectionScope.js.map +1 -1
  34. package/lib/esm/unified-selection/Utils.d.ts +14 -0
  35. package/lib/esm/unified-selection/Utils.d.ts.map +1 -1
  36. package/lib/esm/unified-selection/Utils.js +17 -0
  37. package/lib/esm/unified-selection/Utils.js.map +1 -1
  38. package/lib/esm/unified-selection/types/IModel.d.ts +51 -3
  39. package/lib/esm/unified-selection/types/IModel.d.ts.map +1 -1
  40. package/lib/esm/unified-selection/types/IModel.js.map +1 -1
  41. package/package.json +6 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @itwin/unified-selection
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#800](https://github.com/iTwin/presentation/pull/800): Add support for Models and SubCategories selection that's going to be available in `@itwin/core-frontend` version `5`.
8
+
9
+ The changes in `@itwin/core-frontend` allow us to stop manually syncing `HiliteSet` with `SelectionSet` and rely on automatic syncing instead.
10
+
11
+ - [#800](https://github.com/iTwin/presentation/pull/800): `computeSelection`: Broadened the type of `elementIds` prop from `Id64String[]` to `Id64Arg`.
12
+ - [#802](https://github.com/iTwin/presentation/pull/802): Prefer `Symbol.dispose` over `dispose` for disposable objects.
13
+
14
+ The package contained a number of types for disposable objects, that had a requirement of `dispose` method being called on them after they are no longer needed. In conjunction with the `using` utility from `@itwin/core-bentley`, usage of such objects looked like this:
15
+
16
+ ```ts
17
+ class MyDisposable() {
18
+ dispose() {
19
+ // do some cleanup
20
+ }
21
+ }
22
+ using(new MyDisposable(), (obj) => {
23
+ // do something with obj, it'll get disposed when the callback returns
24
+ });
25
+ ```
26
+
27
+ In version `5.2`, TypeScript [introduced](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management) `Disposable` type and `using` declarations (from the upcoming [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management) feature in ECMAScript). Now we're making use of those new utilities in this package (while still supporting the old `dispose` method), which allows using `MyDisposable` from the above snippet like this:
28
+
29
+ ```ts
30
+ using obj = new MyDisposable();
31
+ // do something with obj, it'll get disposed when it goes out of scope
32
+ ```
33
+
34
+ ## 1.1.2
35
+
36
+ ### Patch Changes
37
+
38
+ - Updated dependencies:
39
+ - @itwin/presentation-shared@1.2.0
40
+
3
41
  ## 1.1.1
4
42
 
5
43
  ### Patch Changes
package/README.md CHANGED
@@ -122,17 +122,17 @@ const hiliteSet = await hiliteProvider.getHiliteSet({ selectables });
122
122
  // Some others may want to get a hilite set for _current_ selection in storage - use `createCachingHiliteSetProvider` for that. It's
123
123
  // recommended to keep a single instance of this provider per application as it caches hilite sets per each iModel's selection.
124
124
  import { createCachingHiliteSetProvider } from "@itwin/unified-selection";
125
- const selectionHiliteProvider = createCachingHiliteSetProvider({
125
+ // Note the use of `using` keyword here. The caching provider registers a selection change listener and should be disposed, in case
126
+ // its lifetime is shorter than that of `SelectionStorage`, to unregister the listener. The `using` keyword ensures that the provider
127
+ // is disposed when it goes out of scope.
128
+ using selectionHiliteProvider = createCachingHiliteSetProvider({
126
129
  selectionStorage,
127
130
  imodelProvider: (imodelKey: string) => getIModelByKey(imodelKey),
128
131
  });
129
132
  const selectionHiliteSet = await selectionHiliteProvider.getHiliteSet({ imodel.key });
130
- // The caching provider registers a selection change listener and should be disposed, in case its lifetime
131
- // is shorter than that of `SelectionStorage`, to unregister the listener.
132
- selectionHiliteProvider.dispose();
133
133
  ```
134
134
 
135
- #### Selection scopes
135
+ ### Selection scopes
136
136
 
137
137
  Selection scopes allow decoupling of what gets picked and what gets selected. Without selection scopes, whenever a user picks an element in the viewport, its ID goes straight into unified selection storage. With selection scopes we can modify that and add something different. The input to the selection scopes' processor is a query executor, element IDs, and the scope to apply, and the output is an iterator of `SelectableInstanceKey`. We get the input when the user picks some elements in the viewport, run that through the selection scope processor and put the output into unified selection storage.
138
138
 
@@ -26,7 +26,17 @@ export interface CachingHiliteSetProvider {
26
26
  /** iModel to get hilite set for */
27
27
  imodelKey: string;
28
28
  }): AsyncIterableIterator<HiliteSet>;
29
- /** Disposes the cache. */
29
+ /**
30
+ * Disposes the cache.
31
+ *
32
+ * Optional to avoid breaking the API. Will be made required when the deprecated
33
+ * `dispose` is removed.
34
+ */
35
+ [Symbol.dispose]?: () => void;
36
+ /**
37
+ * Disposes the cache.
38
+ * @deprecated in 1.2. Use `[Symbol.dispose]` instead.
39
+ */
30
40
  dispose(): void;
31
41
  }
32
42
  /**
@@ -34,5 +44,7 @@ export interface CachingHiliteSetProvider {
34
44
  * hilite set requests for the same iModel don't cost until selection in given selection storage changes.
35
45
  * @public
36
46
  */
37
- export declare function createCachingHiliteSetProvider(props: CachingHiliteSetProviderProps): CachingHiliteSetProvider;
47
+ export declare function createCachingHiliteSetProvider(props: CachingHiliteSetProviderProps): CachingHiliteSetProvider & {
48
+ [Symbol.dispose]: () => void;
49
+ };
38
50
  //# sourceMappingURL=CachingHiliteSetProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CachingHiliteSetProvider.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/CachingHiliteSetProvider.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAA2B,SAAS,EAAqB,MAAM,wBAAwB,CAAC;AAE/F,OAAO,EAAuC,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9F;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C,8DAA8D;IAC9D,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,iEAAiE;IACjE,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,yBAAyB,GAAG,kBAAkB,CAAC;CACvF;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,YAAY,CAAC,KAAK,EAAE;QAClB,mCAAmC;QACnC,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAErC,0BAA0B;IAC1B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,6BAA6B,GAAG,wBAAwB,CAE7G"}
1
+ {"version":3,"file":"CachingHiliteSetProvider.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/CachingHiliteSetProvider.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAA2B,SAAS,EAAqB,MAAM,wBAAwB,CAAC;AAE/F,OAAO,EAAuC,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9F;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C,8DAA8D;IAC9D,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,iEAAiE;IACjE,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,yBAAyB,GAAG,kBAAkB,CAAC;CACvF;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,wBAAwB;IACvC,mEAAmE;IACnE,YAAY,CAAC,KAAK,EAAE;QAClB,mCAAmC;QACnC,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAErC;;;;;OAKG;IACH,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC;IAE9B;;;OAGG;IACH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,6BAA6B,GAAG,wBAAwB,GAAG;IAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAEhJ"}
@@ -44,11 +44,15 @@ class CachingHiliteSetProviderImpl {
44
44
  }
45
45
  return (0, rxjs_for_await_1.eachValueFrom)(hiliteSet);
46
46
  }
47
- dispose() {
47
+ [Symbol.dispose]() {
48
48
  this._removeListener();
49
49
  this._hiliteSetProviders = new Map();
50
50
  this._cache = new Map();
51
51
  }
52
+ /* c8 ignore next 3 */
53
+ dispose() {
54
+ this[Symbol.dispose]();
55
+ }
52
56
  getHiliteSetProvider(imodelKey, imodelAccess) {
53
57
  let provider = this._hiliteSetProviders.get(imodelKey);
54
58
  if (!provider) {
@@ -1 +1 @@
1
- {"version":3,"file":"CachingHiliteSetProvider.js","sourceRoot":"","sources":["../../../src/unified-selection/CachingHiliteSetProvider.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;AA6ChG,wEAEC;AA7CD,+BAAqD;AACrD,mDAA+C;AAE/C,iEAA+F;AAE/F,+DAA8F;AAiC9F;;;;GAIG;AACH,SAAgB,8BAA8B,CAAC,KAAoC;IACjF,OAAO,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,4BAA4B;IACxB,iBAAiB,CAAmB;IACpC,mBAAmB,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC3D,MAAM,GAAG,IAAI,GAAG,EAAiC,CAAC;IAClD,eAAe,CAAa;IAC5B,eAAe,CAAwE;IAE/F,YAAY,KAAoC;QAC9C,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,gBAAgB,CAAC;QAChD,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC;QAC5C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,IAAqC,EAAE,EAAE;YACvH,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACnC,IAAI,IAAI,CAAC,UAAU,KAAK,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK,yDAAmC,EAAE,CAAC;gBACvF,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAClD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,YAAY,CAAC,EAAE,SAAS,EAAyB;QACtD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACpE,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;YACvE,SAAS,GAAG,IAAA,WAAI,EAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAA,kBAAW,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/F,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,IAAA,8BAAa,EAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,mBAAmB,GAAG,IAAI,GAAG,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;IAC1B,CAAC;IAEO,oBAAoB,CAAC,SAAiB,EAAE,YAA4D;QAC1G,IAAI,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAA,8CAAuB,EAAC,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { from, Observable, shareReplay } from \"rxjs\";\nimport { eachValueFrom } from \"rxjs-for-await\";\nimport { ECClassHierarchyInspector, ECSqlQueryExecutor } from \"@itwin/presentation-shared\";\nimport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./HiliteSetProvider.js\";\nimport { StorageSelectionChangeEventArgs } from \"./SelectionChangeEvent.js\";\nimport { IMODEL_CLOSE_SELECTION_CLEAR_SOURCE, SelectionStorage } from \"./SelectionStorage.js\";\n\n/**\n * Props for creating a `CachingHiliteSetProvider` instance.\n * @public\n */\nexport interface CachingHiliteSetProviderProps {\n /** Selection storage to use for retrieving the hilite set. */\n selectionStorage: SelectionStorage;\n /** A callback that should return iModel access by iModel key. */\n imodelProvider: (imodelKey: string) => ECClassHierarchyInspector & ECSqlQueryExecutor;\n}\n\n/**\n * Defines return value of `createCachingHiliteSetProvider`.\n *\n * **Warning:** Used in public API as a return value. Not expected to be created / extended by package\n * consumers, may be supplemented with required attributes any time.\n *\n * @see `createCachingHiliteSetProvider`\n * @public\n */\nexport interface CachingHiliteSetProvider {\n /** Get the current hilite set iterator for the specified imodel */\n getHiliteSet(props: {\n /** iModel to get hilite set for */\n imodelKey: string;\n }): AsyncIterableIterator<HiliteSet>;\n\n /** Disposes the cache. */\n dispose(): void;\n}\n\n/**\n * Creates a hilite set provider that caches hilite set for current selection for given iModel so any subsequent\n * hilite set requests for the same iModel don't cost until selection in given selection storage changes.\n * @public\n */\nexport function createCachingHiliteSetProvider(props: CachingHiliteSetProviderProps): CachingHiliteSetProvider {\n return new CachingHiliteSetProviderImpl(props);\n}\n\nclass CachingHiliteSetProviderImpl implements CachingHiliteSetProvider {\n private _selectionStorage: SelectionStorage;\n private _hiliteSetProviders = new Map<string, HiliteSetProvider>();\n private _cache = new Map<string, Observable<HiliteSet>>();\n private _removeListener: () => void;\n private _imodelProvider: (imodelKey: string) => ECClassHierarchyInspector & ECSqlQueryExecutor;\n\n constructor(props: CachingHiliteSetProviderProps) {\n this._selectionStorage = props.selectionStorage;\n this._imodelProvider = props.imodelProvider;\n this._removeListener = this._selectionStorage.selectionChangeEvent.addListener((args: StorageSelectionChangeEventArgs) => {\n this._cache.delete(args.imodelKey);\n if (args.changeType === \"clear\" && args.source === IMODEL_CLOSE_SELECTION_CLEAR_SOURCE) {\n this._hiliteSetProviders.delete(args.imodelKey);\n }\n });\n }\n\n public getHiliteSet({ imodelKey }: { imodelKey: string }): AsyncIterableIterator<HiliteSet> {\n const imodelAccess = this._imodelProvider(imodelKey);\n const provider = this.getHiliteSetProvider(imodelKey, imodelAccess);\n let hiliteSet = this._cache.get(imodelKey);\n\n if (!hiliteSet) {\n const selectables = this._selectionStorage.getSelection({ imodelKey });\n hiliteSet = from(provider.getHiliteSet({ selectables })).pipe(shareReplay({ refCount: true }));\n this._cache.set(imodelKey, hiliteSet);\n }\n\n return eachValueFrom(hiliteSet);\n }\n\n public dispose(): void {\n this._removeListener();\n this._hiliteSetProviders = new Map();\n this._cache = new Map();\n }\n\n private getHiliteSetProvider(imodelKey: string, imodelAccess: ECClassHierarchyInspector & ECSqlQueryExecutor) {\n let provider = this._hiliteSetProviders.get(imodelKey);\n if (!provider) {\n provider = createHiliteSetProvider({ imodelAccess });\n this._hiliteSetProviders.set(imodelKey, provider);\n }\n return provider;\n }\n}\n"]}
1
+ {"version":3,"file":"CachingHiliteSetProvider.js","sourceRoot":"","sources":["../../../src/unified-selection/CachingHiliteSetProvider.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;AAwDhG,wEAEC;AAxDD,+BAAqD;AACrD,mDAA+C;AAE/C,iEAA+F;AAE/F,+DAA8F;AA4C9F;;;;GAIG;AACH,SAAgB,8BAA8B,CAAC,KAAoC;IACjF,OAAO,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,4BAA4B;IACxB,iBAAiB,CAAmB;IACpC,mBAAmB,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC3D,MAAM,GAAG,IAAI,GAAG,EAAiC,CAAC;IAClD,eAAe,CAAa;IAC5B,eAAe,CAAwE;IAE/F,YAAY,KAAoC;QAC9C,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,gBAAgB,CAAC;QAChD,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,cAAc,CAAC;QAC5C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,IAAqC,EAAE,EAAE;YACvH,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACnC,IAAI,IAAI,CAAC,UAAU,KAAK,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK,yDAAmC,EAAE,CAAC;gBACvF,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAClD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,YAAY,CAAC,EAAE,SAAS,EAAyB;QACtD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACpE,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;YACvE,SAAS,GAAG,IAAA,WAAI,EAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAA,kBAAW,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/F,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,IAAA,8BAAa,EAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAEM,CAAC,MAAM,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,mBAAmB,GAAG,IAAI,GAAG,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;IAC1B,CAAC;IAED,sBAAsB;IACf,OAAO;QACZ,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IACzB,CAAC;IAEO,oBAAoB,CAAC,SAAiB,EAAE,YAA4D;QAC1G,IAAI,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAA,8CAAuB,EAAC,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { from, Observable, shareReplay } from \"rxjs\";\nimport { eachValueFrom } from \"rxjs-for-await\";\nimport { ECClassHierarchyInspector, ECSqlQueryExecutor } from \"@itwin/presentation-shared\";\nimport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./HiliteSetProvider.js\";\nimport { StorageSelectionChangeEventArgs } from \"./SelectionChangeEvent.js\";\nimport { IMODEL_CLOSE_SELECTION_CLEAR_SOURCE, SelectionStorage } from \"./SelectionStorage.js\";\n\n/**\n * Props for creating a `CachingHiliteSetProvider` instance.\n * @public\n */\nexport interface CachingHiliteSetProviderProps {\n /** Selection storage to use for retrieving the hilite set. */\n selectionStorage: SelectionStorage;\n /** A callback that should return iModel access by iModel key. */\n imodelProvider: (imodelKey: string) => ECClassHierarchyInspector & ECSqlQueryExecutor;\n}\n\n/**\n * Defines return value of `createCachingHiliteSetProvider`.\n *\n * **Warning:** Used in public API as a return value. Not expected to be created / extended by package\n * consumers, may be supplemented with required attributes any time.\n *\n * @see `createCachingHiliteSetProvider`\n * @public\n */\nexport interface CachingHiliteSetProvider {\n /** Get the current hilite set iterator for the specified imodel */\n getHiliteSet(props: {\n /** iModel to get hilite set for */\n imodelKey: string;\n }): AsyncIterableIterator<HiliteSet>;\n\n /**\n * Disposes the cache.\n *\n * Optional to avoid breaking the API. Will be made required when the deprecated\n * `dispose` is removed.\n */\n [Symbol.dispose]?: () => void;\n\n /**\n * Disposes the cache.\n * @deprecated in 1.2. Use `[Symbol.dispose]` instead.\n */\n dispose(): void;\n}\n\n/**\n * Creates a hilite set provider that caches hilite set for current selection for given iModel so any subsequent\n * hilite set requests for the same iModel don't cost until selection in given selection storage changes.\n * @public\n */\nexport function createCachingHiliteSetProvider(props: CachingHiliteSetProviderProps): CachingHiliteSetProvider & { [Symbol.dispose]: () => void } {\n return new CachingHiliteSetProviderImpl(props);\n}\n\nclass CachingHiliteSetProviderImpl implements CachingHiliteSetProvider {\n private _selectionStorage: SelectionStorage;\n private _hiliteSetProviders = new Map<string, HiliteSetProvider>();\n private _cache = new Map<string, Observable<HiliteSet>>();\n private _removeListener: () => void;\n private _imodelProvider: (imodelKey: string) => ECClassHierarchyInspector & ECSqlQueryExecutor;\n\n constructor(props: CachingHiliteSetProviderProps) {\n this._selectionStorage = props.selectionStorage;\n this._imodelProvider = props.imodelProvider;\n this._removeListener = this._selectionStorage.selectionChangeEvent.addListener((args: StorageSelectionChangeEventArgs) => {\n this._cache.delete(args.imodelKey);\n if (args.changeType === \"clear\" && args.source === IMODEL_CLOSE_SELECTION_CLEAR_SOURCE) {\n this._hiliteSetProviders.delete(args.imodelKey);\n }\n });\n }\n\n public getHiliteSet({ imodelKey }: { imodelKey: string }): AsyncIterableIterator<HiliteSet> {\n const imodelAccess = this._imodelProvider(imodelKey);\n const provider = this.getHiliteSetProvider(imodelKey, imodelAccess);\n let hiliteSet = this._cache.get(imodelKey);\n\n if (!hiliteSet) {\n const selectables = this._selectionStorage.getSelection({ imodelKey });\n hiliteSet = from(provider.getHiliteSet({ selectables })).pipe(shareReplay({ refCount: true }));\n this._cache.set(imodelKey, hiliteSet);\n }\n\n return eachValueFrom(hiliteSet);\n }\n\n public [Symbol.dispose](): void {\n this._removeListener();\n this._hiliteSetProviders = new Map();\n this._cache = new Map();\n }\n\n /* c8 ignore next 3 */\n public dispose(): void {\n this[Symbol.dispose]();\n }\n\n private getHiliteSetProvider(imodelKey: string, imodelAccess: ECClassHierarchyInspector & ECSqlQueryExecutor) {\n let provider = this._hiliteSetProviders.get(imodelKey);\n if (!provider) {\n provider = createHiliteSetProvider({ imodelAccess });\n this._hiliteSetProviders.set(imodelKey, provider);\n }\n return provider;\n }\n}\n"]}
@@ -46,8 +46,13 @@ export interface EnableUnifiedSelectionSyncWithIModelProps {
46
46
  * will be created for the given iModel using the provided `imodelAccess`.
47
47
  * If the consuming application already has a `CachingHiliteSetProvider` defined, it should be provided instead
48
48
  * to reuse the cache and avoid creating new providers for each iModel.
49
+ *
50
+ * The type is defined in a way that makes it required for provider to have either the deprecated `dispose` or the
51
+ * new `Symbol.dispose` method.
49
52
  */
50
- cachingHiliteSetProvider?: CachingHiliteSetProvider;
53
+ cachingHiliteSetProvider?: CachingHiliteSetProvider | (Omit<CachingHiliteSetProvider, "dispose"> & {
54
+ [Symbol.dispose]: () => void;
55
+ });
51
56
  }
52
57
  /**
53
58
  * Enables synchronization between iModel selection and unified selection.
@@ -69,14 +74,14 @@ export declare class IModelSelectionHandler {
69
74
  private _activeScopeProvider;
70
75
  private _isSuspended;
71
76
  private _cancelOngoingChanges;
72
- private _unifiedSelectionListenerDisposeFunc;
73
- private _imodelListenerDisposeFunc;
77
+ private _unregisterUnifiedSelectionListener;
78
+ private _unregisterIModelSelectionSetListener;
74
79
  private _hasCustomCachingHiliteSetProvider;
75
80
  constructor(props: EnableUnifiedSelectionSyncWithIModelProps);
76
- dispose(): void;
77
- /** Temporarily suspends tool selection synchronization until the returned `IDisposable` is disposed. */
81
+ [Symbol.dispose](): void;
82
+ /** Temporarily suspends tool selection synchronization until the returned disposable object is disposed. */
78
83
  suspendIModelToolSelectionSync(): {
79
- dispose: () => boolean;
84
+ [Symbol.dispose]: () => void;
80
85
  };
81
86
  private handleUnifiedSelectionChange;
82
87
  private onUnifiedSelectionChanged;
@@ -86,6 +91,5 @@ export declare class IModelSelectionHandler {
86
91
  private onIModelSelectionChanged;
87
92
  private handleIModelSelectionChange;
88
93
  private getSelectionSetChangeIds;
89
- private idArgToIds;
90
94
  }
91
95
  //# sourceMappingURL=EnableUnifiedSelectionSyncWithIModel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAAE,wBAAwB,EAAkC,MAAM,+BAA+B,CAAC;AAIzG,OAAO,EAAoB,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAA0D,MAAM,mBAAmB,CAAC;AAExI;;;GAGG;AACH,MAAM,WAAW,yCAAyC;IACxD;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,YAAY,EAAE,kBAAkB,GAC9B,yBAAyB,GAAG;QAC1B,sEAAsE;QACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,mFAAmF;QACnF,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;QACxC,yFAAyF;QACzF,QAAQ,CAAC,YAAY,EAAE,sBAAsB,CAAC;KAC/C,CAAC;IAEJ,qEAAqE;IACrE,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC,6BAA6B;IAC7B,mBAAmB,EAAE,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAE1D;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;CACrD;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,yCAAyC,GAAG,MAAM,IAAI,CAGjH;AAED;;;;GAIG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,oBAAoB,CAAU;IAEtC,OAAO,CAAC,aAAa,CAA4D;IACjF,OAAO,CAAC,iBAAiB,CAAmB;IAC5C,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,yBAAyB,CAA2B;IAC5D,OAAO,CAAC,oBAAoB,CAAuC;IAEnE,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,oCAAoC,CAAa;IACzD,OAAO,CAAC,0BAA0B,CAAa;IAC/C,OAAO,CAAC,kCAAkC,CAAU;gBAEjC,KAAK,EAAE,yCAAyC;IAuB5D,OAAO;IASd,wGAAwG;IACjG,8BAA8B;;;IAQrC,OAAO,CAAC,4BAA4B;IA6BpC,OAAO,CAAC,yBAAyB,CAU/B;IAEF,OAAO,CAAC,qBAAqB;IAmB7B,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,wBAAwB,CAa9B;YAEY,2BAA2B;IAoBzC,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,UAAU;CASnB"}
1
+ {"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAAE,wBAAwB,EAAkC,MAAM,+BAA+B,CAAC;AAIzG,OAAO,EAAoB,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAA6E,MAAM,mBAAmB,CAAC;AAG3J;;;GAGG;AACH,MAAM,WAAW,yCAAyC;IACxD;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,YAAY,EAAE,kBAAkB,GAC9B,yBAAyB,GAAG;QAC1B,sEAAsE;QACtE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,mFAAmF;QACnF,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;QACxC,yFAAyF;QACzF,QAAQ,CAAC,YAAY,EAAE,sBAAsB,CAAC;KAC/C,CAAC;IAEJ,qEAAqE;IACrE,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC,6BAA6B;IAC7B,mBAAmB,EAAE,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAE1D;;;;;;;;OAQG;IACH,wBAAwB,CAAC,EAAE,wBAAwB,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,SAAS,CAAC,GAAG;QAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;CACtI;AAED;;;;GAIG;AACH,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,yCAAyC,GAAG,MAAM,IAAI,CAGjH;AAED;;;;GAIG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,oBAAoB,CAAU;IAEtC,OAAO,CAAC,aAAa,CAA4D;IACjF,OAAO,CAAC,iBAAiB,CAAmB;IAC5C,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,yBAAyB,CAAqF;IACtH,OAAO,CAAC,oBAAoB,CAAuC;IAEnE,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,mCAAmC,CAAa;IACxD,OAAO,CAAC,qCAAqC,CAAa;IAC1D,OAAO,CAAC,kCAAkC,CAAU;gBAEjC,KAAK,EAAE,yCAAyC;IAqB5D,CAAC,MAAM,CAAC,OAAO,CAAC;IASvB,4GAA4G;IACrG,8BAA8B;;;IAUrC,OAAO,CAAC,4BAA4B;IA2BpC,OAAO,CAAC,yBAAyB,CAU/B;IAEF,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,wBAAwB,CAmB9B;YAEY,2BAA2B;IAiBzC,OAAO,CAAC,wBAAwB;CAcjC"}
@@ -3,15 +3,67 @@
3
3
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
4
  * See LICENSE.md in the project root for license terms and full copyright notice.
5
5
  *--------------------------------------------------------------------------------------------*/
6
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
7
+ if (value !== null && value !== void 0) {
8
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
9
+ var dispose, inner;
10
+ if (async) {
11
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
12
+ dispose = value[Symbol.asyncDispose];
13
+ }
14
+ if (dispose === void 0) {
15
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
16
+ dispose = value[Symbol.dispose];
17
+ if (async) inner = dispose;
18
+ }
19
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
20
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
21
+ env.stack.push({ value: value, dispose: dispose, async: async });
22
+ }
23
+ else if (async) {
24
+ env.stack.push({ async: true });
25
+ }
26
+ return value;
27
+ };
28
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
29
+ return function (env) {
30
+ function fail(e) {
31
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
32
+ env.hasError = true;
33
+ }
34
+ var r, s = 0;
35
+ function next() {
36
+ while (r = env.stack.pop()) {
37
+ try {
38
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
39
+ if (r.dispose) {
40
+ var result = r.dispose.call(r.value);
41
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
42
+ }
43
+ else s |= 1;
44
+ }
45
+ catch (e) {
46
+ fail(e);
47
+ }
48
+ }
49
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
50
+ if (env.hasError) throw env.error;
51
+ }
52
+ return next();
53
+ };
54
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
55
+ var e = new Error(message);
56
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
57
+ });
6
58
  Object.defineProperty(exports, "__esModule", { value: true });
7
59
  exports.IModelSelectionHandler = void 0;
8
60
  exports.enableUnifiedSelectionSyncWithIModel = enableUnifiedSelectionSyncWithIModel;
9
61
  const rxjs_1 = require("rxjs");
10
- const core_bentley_1 = require("@itwin/core-bentley");
11
62
  const CachingHiliteSetProvider_js_1 = require("./CachingHiliteSetProvider.js");
12
63
  const HiliteSetProvider_js_1 = require("./HiliteSetProvider.js");
13
64
  const SelectionScope_js_1 = require("./SelectionScope.js");
14
65
  const IModel_js_1 = require("./types/IModel.js");
66
+ const Utils_js_1 = require("./Utils.js");
15
67
  /**
16
68
  * Enables synchronization between iModel selection and unified selection.
17
69
  * @returns function for disposing the synchronization.
@@ -19,7 +71,7 @@ const IModel_js_1 = require("./types/IModel.js");
19
71
  */
20
72
  function enableUnifiedSelectionSyncWithIModel(props) {
21
73
  const selectionHandler = new IModelSelectionHandler(props);
22
- return () => selectionHandler.dispose();
74
+ return () => selectionHandler[Symbol.dispose]();
23
75
  }
24
76
  /**
25
77
  * A handler that syncs selection between unified selection storage
@@ -35,8 +87,8 @@ class IModelSelectionHandler {
35
87
  _activeScopeProvider;
36
88
  _isSuspended;
37
89
  _cancelOngoingChanges = new rxjs_1.Subject();
38
- _unifiedSelectionListenerDisposeFunc;
39
- _imodelListenerDisposeFunc;
90
+ _unregisterUnifiedSelectionListener;
91
+ _unregisterIModelSelectionSetListener;
40
92
  _hasCustomCachingHiliteSetProvider;
41
93
  constructor(props) {
42
94
  this._imodelAccess = props.imodelAccess;
@@ -51,53 +103,53 @@ class IModelSelectionHandler {
51
103
  imodelProvider: () => this._imodelAccess,
52
104
  });
53
105
  this._hiliteSetProvider = (0, HiliteSetProvider_js_1.createHiliteSetProvider)({ imodelAccess: this._imodelAccess });
54
- this._imodelListenerDisposeFunc = this._imodelAccess.selectionSet.onChanged.addListener(this.onIModelSelectionChanged);
55
- this._unifiedSelectionListenerDisposeFunc = this._selectionStorage.selectionChangeEvent.addListener(this.onUnifiedSelectionChanged);
56
- // stop imodel from syncing tool selection with hilited list - we want to override that behavior
57
- this._imodelAccess.hiliteSet.wantSyncWithSelectionSet = false;
58
- this.applyCurrentHiliteSet({ activeSelectionAction: "clearAll" });
106
+ this._unregisterIModelSelectionSetListener = this._imodelAccess.selectionSet.onChanged.addListener(this.onIModelSelectionChanged);
107
+ this._unregisterUnifiedSelectionListener = this._selectionStorage.selectionChangeEvent.addListener(this.onUnifiedSelectionChanged);
108
+ this.applyCurrentHiliteSet({ activeSelectionAction: "clear" });
59
109
  }
60
- dispose() {
110
+ [Symbol.dispose]() {
61
111
  this._cancelOngoingChanges.next();
62
- this._imodelListenerDisposeFunc();
63
- this._unifiedSelectionListenerDisposeFunc();
112
+ this._unregisterIModelSelectionSetListener();
113
+ this._unregisterUnifiedSelectionListener();
64
114
  if (!this._hasCustomCachingHiliteSetProvider) {
65
- this._cachingHiliteSetProvider.dispose();
115
+ (0, Utils_js_1.safeDispose)(this._cachingHiliteSetProvider);
66
116
  }
67
117
  }
68
- /** Temporarily suspends tool selection synchronization until the returned `IDisposable` is disposed. */
118
+ /** Temporarily suspends tool selection synchronization until the returned disposable object is disposed. */
69
119
  suspendIModelToolSelectionSync() {
70
120
  const wasSuspended = this._isSuspended;
71
121
  this._isSuspended = true;
72
122
  return {
73
- dispose: () => (this._isSuspended = wasSuspended),
123
+ [Symbol.dispose]: () => {
124
+ this._isSuspended = wasSuspended;
125
+ },
74
126
  };
75
127
  }
76
128
  handleUnifiedSelectionChange(changeType, selectables, source) {
77
- if (changeType === "clear" || changeType === "replace") {
78
- this.applyCurrentHiliteSet({ activeSelectionAction: changeType === "replace" && source === "Tool" ? "clearHilited" : "clearAll" });
79
- return;
80
- }
81
- if (changeType === "add") {
82
- (0, rxjs_1.from)(this._hiliteSetProvider.getHiliteSet({ selectables }))
83
- .pipe((0, rxjs_1.takeUntil)(this._cancelOngoingChanges))
84
- .subscribe({
85
- next: (set) => {
86
- this.addHiliteSet(set);
87
- },
88
- });
89
- return;
129
+ switch (changeType) {
130
+ case "clear":
131
+ case "replace":
132
+ return this.applyCurrentHiliteSet({ activeSelectionAction: source === "Tool" ? "keep" : "clear" });
133
+ case "add":
134
+ return void (0, rxjs_1.from)(this._hiliteSetProvider.getHiliteSet({ selectables }))
135
+ .pipe((0, rxjs_1.takeUntil)(this._cancelOngoingChanges))
136
+ .subscribe({
137
+ next: (set) => {
138
+ this.addHiliteSet(set);
139
+ },
140
+ });
141
+ case "remove":
142
+ return void (0, rxjs_1.from)(this._hiliteSetProvider.getHiliteSet({ selectables }))
143
+ .pipe((0, rxjs_1.takeUntil)(this._cancelOngoingChanges))
144
+ .subscribe({
145
+ next: (set) => {
146
+ this.removeHiliteSet(set);
147
+ },
148
+ complete: () => {
149
+ this.applyCurrentHiliteSet({ activeSelectionAction: "keep" });
150
+ },
151
+ });
90
152
  }
91
- (0, rxjs_1.from)(this._hiliteSetProvider.getHiliteSet({ selectables }))
92
- .pipe((0, rxjs_1.takeUntil)(this._cancelOngoingChanges))
93
- .subscribe({
94
- next: (set) => {
95
- this.removeHiliteSet(set);
96
- },
97
- complete: () => {
98
- this.applyCurrentHiliteSet({ activeSelectionAction: "keep" });
99
- },
100
- });
101
153
  }
102
154
  onUnifiedSelectionChanged = (args) => {
103
155
  // iModels are only interested in top-level selection changes
@@ -110,13 +162,20 @@ class IModelSelectionHandler {
110
162
  this.handleUnifiedSelectionChange(args.changeType, args.selectables, args.source);
111
163
  };
112
164
  applyCurrentHiliteSet({ activeSelectionAction }) {
113
- if (activeSelectionAction !== "keep") {
114
- (0, core_bentley_1.using)(this.suspendIModelToolSelectionSync(), (_) => {
165
+ if (activeSelectionAction === "clear") {
166
+ const env_1 = { stack: [], error: void 0, hasError: false };
167
+ try {
168
+ const _dispose = __addDisposableResource(env_1, this.suspendIModelToolSelectionSync(), false);
115
169
  this._imodelAccess.hiliteSet.clear();
116
- if (activeSelectionAction === "clearAll") {
117
- this._imodelAccess.selectionSet.emptyAll();
118
- }
119
- });
170
+ this._imodelAccess.selectionSet.emptyAll();
171
+ }
172
+ catch (e_1) {
173
+ env_1.error = e_1;
174
+ env_1.hasError = true;
175
+ }
176
+ finally {
177
+ __disposeResources(env_1);
178
+ }
120
179
  }
121
180
  (0, rxjs_1.from)(this._cachingHiliteSetProvider.getHiliteSet({ imodelKey: this._imodelAccess.key }))
122
181
  .pipe((0, rxjs_1.takeUntil)(this._cancelOngoingChanges))
@@ -127,32 +186,71 @@ class IModelSelectionHandler {
127
186
  });
128
187
  }
129
188
  addHiliteSet(set) {
130
- (0, core_bentley_1.using)(this.suspendIModelToolSelectionSync(), (_) => {
131
- if (set.models && set.models.length) {
132
- this._imodelAccess.hiliteSet.models.addIds(set.models);
133
- }
134
- if (set.subCategories && set.subCategories.length) {
135
- this._imodelAccess.hiliteSet.subcategories.addIds(set.subCategories);
189
+ const env_2 = { stack: [], error: void 0, hasError: false };
190
+ try {
191
+ const _dispose = __addDisposableResource(env_2, this.suspendIModelToolSelectionSync(), false);
192
+ if ("active" in this._imodelAccess.selectionSet) {
193
+ // the `active` property tells us we're using 5.0 core, which supports models and subcategories
194
+ // in selection set - we can simply add the set as a whole
195
+ this._imodelAccess.selectionSet.add({
196
+ models: set.models,
197
+ subcategories: set.subCategories,
198
+ elements: set.elements,
199
+ });
136
200
  }
137
- if (set.elements && set.elements.length) {
138
- this._imodelAccess.hiliteSet.elements.addIds(set.elements);
139
- this._imodelAccess.selectionSet.add(set.elements);
201
+ else {
202
+ // pre-5.0 core requires adding models and subcategories to hilite set separately
203
+ if (set.models.length) {
204
+ this._imodelAccess.hiliteSet.models.addIds(set.models);
205
+ }
206
+ if (set.subCategories.length) {
207
+ this._imodelAccess.hiliteSet.subcategories.addIds(set.subCategories);
208
+ }
209
+ if (set.elements.length) {
210
+ this._imodelAccess.selectionSet.add(set.elements);
211
+ }
140
212
  }
141
- });
213
+ }
214
+ catch (e_2) {
215
+ env_2.error = e_2;
216
+ env_2.hasError = true;
217
+ }
218
+ finally {
219
+ __disposeResources(env_2);
220
+ }
142
221
  }
143
222
  removeHiliteSet(set) {
144
- (0, core_bentley_1.using)(this.suspendIModelToolSelectionSync(), (_) => {
145
- if (set.models.length) {
146
- this._imodelAccess.hiliteSet.models.deleteIds(set.models);
147
- }
148
- if (set.subCategories.length) {
149
- this._imodelAccess.hiliteSet.subcategories.deleteIds(set.subCategories);
223
+ const env_3 = { stack: [], error: void 0, hasError: false };
224
+ try {
225
+ const _dispose = __addDisposableResource(env_3, this.suspendIModelToolSelectionSync(), false);
226
+ if ("active" in this._imodelAccess.selectionSet) {
227
+ // the `active` property tells us we're using 5.0 core, which supports models and subcategories
228
+ // in selection set - we can simply remove the set as a whole
229
+ this._imodelAccess.selectionSet.remove({
230
+ models: set.models,
231
+ subcategories: set.subCategories,
232
+ elements: set.elements,
233
+ });
150
234
  }
151
- if (set.elements.length) {
152
- this._imodelAccess.hiliteSet.elements.deleteIds(set.elements);
153
- this._imodelAccess.selectionSet.remove(set.elements);
235
+ else {
236
+ if (set.models.length) {
237
+ this._imodelAccess.hiliteSet.models.deleteIds(set.models);
238
+ }
239
+ if (set.subCategories.length) {
240
+ this._imodelAccess.hiliteSet.subcategories.deleteIds(set.subCategories);
241
+ }
242
+ if (set.elements.length) {
243
+ this._imodelAccess.selectionSet.remove(set.elements);
244
+ }
154
245
  }
155
- });
246
+ }
247
+ catch (e_3) {
248
+ env_3.error = e_3;
249
+ env_3.hasError = true;
250
+ }
251
+ finally {
252
+ __disposeResources(env_3);
253
+ }
156
254
  }
157
255
  onIModelSelectionChanged = async (event) => {
158
256
  if (this._isSuspended) {
@@ -162,15 +260,14 @@ class IModelSelectionHandler {
162
260
  this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });
163
261
  return;
164
262
  }
165
- const elementIds = this.getSelectionSetChangeIds(event);
166
- const scopedSelection = (0, SelectionScope_js_1.computeSelection)({ queryExecutor: this._imodelAccess, elementIds, scope: this._activeScopeProvider() });
263
+ const ids = this.getSelectionSetChangeIds(event);
264
+ const scopedSelection = (0, rxjs_1.merge)(ids.elements
265
+ ? (0, rxjs_1.from)((0, SelectionScope_js_1.computeSelection)({ queryExecutor: this._imodelAccess, elementIds: ids.elements, scope: this._activeScopeProvider() }))
266
+ : /* c8 ignore next */ rxjs_1.EMPTY, ids.models ? (0, rxjs_1.from)(ids.models).pipe((0, rxjs_1.map)((id) => ({ className: "BisCore.Model", id }))) : /* c8 ignore next */ rxjs_1.EMPTY, ids.subcategories ? (0, rxjs_1.from)(ids.subcategories).pipe((0, rxjs_1.map)((id) => ({ className: "BisCore.SubCategory", id }))) : /* c8 ignore next */ rxjs_1.EMPTY);
167
267
  await this.handleIModelSelectionChange(event.type, scopedSelection);
168
268
  };
169
- async handleIModelSelectionChange(type, iterator) {
170
- const selectables = [];
171
- for await (const selectable of iterator) {
172
- selectables.push(selectable);
173
- }
269
+ async handleIModelSelectionChange(type, keys) {
270
+ const selectables = await (0, rxjs_1.firstValueFrom)(keys.pipe((0, rxjs_1.toArray)()));
174
271
  const props = {
175
272
  imodelKey: this._imodelAccess.key,
176
273
  source: this._selectionSourceName,
@@ -188,22 +285,12 @@ class IModelSelectionHandler {
188
285
  getSelectionSetChangeIds(event) {
189
286
  switch (event.type) {
190
287
  case IModel_js_1.CoreSelectionSetEventType.Add:
288
+ return event.additions ?? (event.added ? { elements: event.added } : /* c8 ignore next */ {});
289
+ case IModel_js_1.CoreSelectionSetEventType.Remove:
290
+ return event.removals ?? (event.removed ? { elements: event.removed } : /* c8 ignore next */ {});
191
291
  case IModel_js_1.CoreSelectionSetEventType.Replace:
192
- (0, core_bentley_1.assert)(!!event.added);
193
- return this.idArgToIds(event.added);
194
- default:
195
- (0, core_bentley_1.assert)(!!event.removed);
196
- return this.idArgToIds(event.removed);
197
- }
198
- }
199
- idArgToIds(ids) {
200
- if (typeof ids === "string") {
201
- return [ids];
202
- }
203
- if (ids instanceof Set) {
204
- return [...ids];
292
+ return "active" in event.set ? event.set.active : { elements: event.set.elements };
205
293
  }
206
- return ids;
207
294
  }
208
295
  }
209
296
  exports.IModelSelectionHandler = IModelSelectionHandler;