@itwin/unified-selection 0.2.0 → 0.3.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 (94) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/README.md +34 -14
  3. package/lib/cjs/unified-selection/CachingHiliteSetProvider.d.ts +3 -7
  4. package/lib/cjs/unified-selection/CachingHiliteSetProvider.d.ts.map +1 -1
  5. package/lib/cjs/unified-selection/CachingHiliteSetProvider.js +14 -17
  6. package/lib/cjs/unified-selection/CachingHiliteSetProvider.js.map +1 -1
  7. package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts +90 -0
  8. package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts.map +1 -0
  9. package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.js +205 -0
  10. package/lib/cjs/unified-selection/EnableUnifiedSelectionSyncWithIModel.js.map +1 -0
  11. package/lib/cjs/unified-selection/HiliteSetProvider.d.ts +2 -4
  12. package/lib/cjs/unified-selection/HiliteSetProvider.d.ts.map +1 -1
  13. package/lib/cjs/unified-selection/HiliteSetProvider.js +156 -110
  14. package/lib/cjs/unified-selection/HiliteSetProvider.js.map +1 -1
  15. package/lib/cjs/unified-selection/Selectable.d.ts +0 -3
  16. package/lib/cjs/unified-selection/Selectable.d.ts.map +1 -1
  17. package/lib/cjs/unified-selection/Selectable.js +2 -2
  18. package/lib/cjs/unified-selection/Selectable.js.map +1 -1
  19. package/lib/cjs/unified-selection/SelectionChangeEvent.d.ts +5 -3
  20. package/lib/cjs/unified-selection/SelectionChangeEvent.d.ts.map +1 -1
  21. package/lib/cjs/unified-selection/SelectionChangeEvent.js.map +1 -1
  22. package/lib/cjs/unified-selection/SelectionScope.d.ts +2 -2
  23. package/lib/cjs/unified-selection/SelectionScope.d.ts.map +1 -1
  24. package/lib/cjs/unified-selection/SelectionScope.js +87 -54
  25. package/lib/cjs/unified-selection/SelectionScope.js.map +1 -1
  26. package/lib/cjs/unified-selection/SelectionStorage.d.ts +20 -28
  27. package/lib/cjs/unified-selection/SelectionStorage.d.ts.map +1 -1
  28. package/lib/cjs/unified-selection/SelectionStorage.js +21 -18
  29. package/lib/cjs/unified-selection/SelectionStorage.js.map +1 -1
  30. package/lib/cjs/unified-selection/Utils.d.ts +7 -0
  31. package/lib/cjs/unified-selection/Utils.d.ts.map +1 -0
  32. package/lib/cjs/unified-selection/{queries/ECSqlCore.js → Utils.js} +2 -1
  33. package/lib/cjs/unified-selection/Utils.js.map +1 -0
  34. package/lib/cjs/unified-selection/types/IModel.d.ts +84 -0
  35. package/lib/cjs/unified-selection/types/IModel.d.ts.map +1 -0
  36. package/lib/cjs/unified-selection/types/IModel.js +24 -0
  37. package/lib/cjs/unified-selection/types/IModel.js.map +1 -0
  38. package/lib/cjs/unified-selection.d.ts +1 -6
  39. package/lib/cjs/unified-selection.d.ts.map +1 -1
  40. package/lib/cjs/unified-selection.js +3 -7
  41. package/lib/cjs/unified-selection.js.map +1 -1
  42. package/lib/esm/unified-selection/CachingHiliteSetProvider.d.ts +3 -7
  43. package/lib/esm/unified-selection/CachingHiliteSetProvider.d.ts.map +1 -1
  44. package/lib/esm/unified-selection/CachingHiliteSetProvider.js +14 -17
  45. package/lib/esm/unified-selection/CachingHiliteSetProvider.js.map +1 -1
  46. package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts +90 -0
  47. package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.d.ts.map +1 -0
  48. package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.js +200 -0
  49. package/lib/esm/unified-selection/EnableUnifiedSelectionSyncWithIModel.js.map +1 -0
  50. package/lib/esm/unified-selection/HiliteSetProvider.d.ts +2 -4
  51. package/lib/esm/unified-selection/HiliteSetProvider.d.ts.map +1 -1
  52. package/lib/esm/unified-selection/HiliteSetProvider.js +155 -109
  53. package/lib/esm/unified-selection/HiliteSetProvider.js.map +1 -1
  54. package/lib/esm/unified-selection/Selectable.d.ts +0 -3
  55. package/lib/esm/unified-selection/Selectable.d.ts.map +1 -1
  56. package/lib/esm/unified-selection/Selectable.js.map +1 -1
  57. package/lib/esm/unified-selection/SelectionChangeEvent.d.ts +5 -3
  58. package/lib/esm/unified-selection/SelectionChangeEvent.d.ts.map +1 -1
  59. package/lib/esm/unified-selection/SelectionChangeEvent.js.map +1 -1
  60. package/lib/esm/unified-selection/SelectionScope.d.ts +2 -2
  61. package/lib/esm/unified-selection/SelectionScope.d.ts.map +1 -1
  62. package/lib/esm/unified-selection/SelectionScope.js +84 -51
  63. package/lib/esm/unified-selection/SelectionScope.js.map +1 -1
  64. package/lib/esm/unified-selection/SelectionStorage.d.ts +20 -28
  65. package/lib/esm/unified-selection/SelectionStorage.d.ts.map +1 -1
  66. package/lib/esm/unified-selection/SelectionStorage.js +21 -18
  67. package/lib/esm/unified-selection/SelectionStorage.js.map +1 -1
  68. package/lib/esm/unified-selection/Utils.d.ts +7 -0
  69. package/lib/esm/unified-selection/Utils.d.ts.map +1 -0
  70. package/lib/esm/unified-selection/{queries/ECSqlCore.js → Utils.js} +2 -1
  71. package/lib/esm/unified-selection/Utils.js.map +1 -0
  72. package/lib/esm/unified-selection/types/IModel.d.ts +84 -0
  73. package/lib/esm/unified-selection/types/IModel.d.ts.map +1 -0
  74. package/lib/esm/unified-selection/types/IModel.js +21 -0
  75. package/lib/esm/unified-selection/types/IModel.js.map +1 -0
  76. package/lib/esm/unified-selection.d.ts +1 -6
  77. package/lib/esm/unified-selection.d.ts.map +1 -1
  78. package/lib/esm/unified-selection.js +1 -6
  79. package/lib/esm/unified-selection.js.map +1 -1
  80. package/package.json +23 -16
  81. package/lib/cjs/unified-selection/queries/ECMetadata.d.ts +0 -44
  82. package/lib/cjs/unified-selection/queries/ECMetadata.d.ts.map +0 -1
  83. package/lib/cjs/unified-selection/queries/ECMetadata.js +0 -17
  84. package/lib/cjs/unified-selection/queries/ECMetadata.js.map +0 -1
  85. package/lib/cjs/unified-selection/queries/ECSqlCore.d.ts +0 -69
  86. package/lib/cjs/unified-selection/queries/ECSqlCore.d.ts.map +0 -1
  87. package/lib/cjs/unified-selection/queries/ECSqlCore.js.map +0 -1
  88. package/lib/esm/unified-selection/queries/ECMetadata.d.ts +0 -44
  89. package/lib/esm/unified-selection/queries/ECMetadata.d.ts.map +0 -1
  90. package/lib/esm/unified-selection/queries/ECMetadata.js +0 -13
  91. package/lib/esm/unified-selection/queries/ECMetadata.js.map +0 -1
  92. package/lib/esm/unified-selection/queries/ECSqlCore.d.ts +0 -69
  93. package/lib/esm/unified-selection/queries/ECSqlCore.d.ts.map +0 -1
  94. package/lib/esm/unified-selection/queries/ECSqlCore.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,124 @@
1
1
  # @itwin/unified-selection
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#530](https://github.com/iTwin/presentation/pull/530): Added `enableUnifiedSelectionSyncWithIModel` for enabling synchronization between iModel's tool selection and unified selection storage.
8
+ - [#544](https://github.com/iTwin/presentation/pull/544): Breaking API changes
9
+
10
+ - The type of ECSQL query executor's `createQueryReader` function was changed from:
11
+
12
+ ```ts
13
+ // createQueryReader(ecsql: string, bindings?: ECSqlBinding[], config?: ECSqlQueryReaderOptions): ECSqlQueryReader;
14
+ // usage:
15
+ const reader = executor.createQueryReader(
16
+ `
17
+ WITH RECURSIVE
18
+ ChildElements(ECInstanceId) AS (
19
+ SELECT ECInstanceId FROM bis.Element WHERE Parent.Id = ?
20
+ UNION ALL
21
+ SELECT c.ECInstanceId FROM bis.Element c JOIN ChildElements p ON c.Parent.Id = p.ECInstanceId
22
+ )
23
+ SELECT * FROM ChildElements
24
+ `,
25
+ [{ type: "id", value: "0x1" }],
26
+ { rowFormat: "Indexes" },
27
+ );
28
+ ```
29
+
30
+ to:
31
+
32
+ ```ts
33
+ // createQueryReader(query: { ctes?: string; ecsql: string; bindings?: ECSqlBinding[] }, config?: ECSqlQueryReaderOptions): ECSqlQueryReader;
34
+ // usage:
35
+ const reader = executor.createQueryReader(
36
+ {
37
+ ctes: [
38
+ `
39
+ ChildElements(ECInstanceId) AS (
40
+ SELECT ECInstanceId FROM bis.Element WHERE Parent.Id = ?
41
+ UNION ALL
42
+ SELECT c.ECInstanceId FROM bis.Element c JOIN ChildElements p ON c.Parent.Id = p.ECInstanceId
43
+ )
44
+ `,
45
+ ],
46
+ ecsql: "SELECT * FROM ChildElements",
47
+ bindings: [{ type: "id", value: "0x1" }],
48
+ },
49
+ { rowFormat: "Indexes" },
50
+ );
51
+ ```
52
+
53
+ This makes the API consistent with other Presentation packages and allows additional manipulation on ECSQL, which was not possible previously when ECSQL contained CTEs.
54
+
55
+ The change affects the following public APIs:
56
+
57
+ - `computeSelection` (`queryExecutor` prop),
58
+ - `createHiliteSetProvider` (previously `queryExecutor` prop, now `imodelAccess` prop),
59
+ - `createCachingHiliteSetProvider` (`iModelProvider` prop).
60
+
61
+ - `createHiliteSetProvider` function props `queryExecutor` and `schemaProvider` were merged into a single `imodelAccess` prop with merged type.
62
+
63
+ Previously:
64
+
65
+ ```ts
66
+ createHiliteSetProvider({
67
+ queryExecutor: createECSqlQueryExecutor(iModel),
68
+ schemaProvider: createECSchemaProvider(iModel),
69
+ });
70
+ ```
71
+
72
+ Now:
73
+
74
+ ```ts
75
+ createHiliteSetProvider({
76
+ imodelAccess: {
77
+ ...createECSqlQueryExecutor(iModel),
78
+ ...createECSchemaProvider(iModel),
79
+ },
80
+ });
81
+ ```
82
+
83
+ - `createCachingHiliteSetProvider` function prop `iModelProvider` was changed to return an object of merged type `ECSchemaProvider & ECSqlQueryExecutor` rather than `{ queryExecutor: ECSqlQueryExecutor; schemaProvider: ECSchemaProvider }`.
84
+
85
+ Previously:
86
+
87
+ ```ts
88
+ createCachingHiliteSetProvider({
89
+ selectionStorage,
90
+ iModelProvider: (key) => ({
91
+ queryExecutor: createECSqlQueryExecutor(iModel),
92
+ schemaProvider: createECSchemaProvider(iModel),
93
+ }),
94
+ });
95
+ ```
96
+
97
+ Now:
98
+
99
+ ```ts
100
+ createCachingHiliteSetProvider({
101
+ selectionStorage,
102
+ iModelProvider: (key) => ({
103
+ ...createECSqlQueryExecutor(iModel),
104
+ ...createECSchemaProvider(iModel),
105
+ }),
106
+ });
107
+ ```
108
+
109
+ - [#551](https://github.com/iTwin/presentation/pull/551): Changed `iModel` in attribute names to `imodel`. The change was made to be consistent with other Presentation packages and affects the following APIs:
110
+
111
+ - `SelectionStorage` methods now accept `imodelKey` prop rather than `iModelKey`. It's `selectionChangeEvent` is also now raised with `imodelKey` prop in `StorageSelectionChangeEventArgs`.
112
+ - `CachingHiliteSetProvider.getHiliteSet` now accepts an `imodelKey` prop rather than `iModelKey`.
113
+ - `createCachingHiliteSetProvider` props now accept `imodelProvider` callback rather than `iModelProvider`.
114
+
115
+ - [#553](https://github.com/iTwin/presentation/pull/553): Expose types from `@itwin/presentation-shared` rather than having our own copies.
116
+
117
+ ### Patch Changes
118
+
119
+ - Updated dependencies:
120
+ - @itwin/presentation-shared@0.1.0
121
+
3
122
  ## 0.2.0
4
123
 
5
124
  ### Minor Changes
package/README.md CHANGED
@@ -32,14 +32,14 @@ const unifiedSelection = createStore();
32
32
 
33
33
  // the store should to be cleaned up when iModels are closed to free up memory, e.g.:
34
34
  import { IModelConnection } from "@itwin/core-frontend";
35
- IModelConnection.onClose.addListener((iModel) => {
36
- unifiedSelection.clearStorage(iModel.key);
35
+ IModelConnection.onClose.addListener((imodel) => {
36
+ unifiedSelection.clearStorage(imodel.key);
37
37
  });
38
38
 
39
39
  // add a demo selection listener
40
40
  import { Selectables } from "@itwin/unified-selection";
41
- unifiedSelection.selectionChangeEvent.addListener(({ iModelKey, source, changeType, selectables }) => {
42
- const suffix = `in ${iModelKey} iModel from ${source} component`;
41
+ unifiedSelection.selectionChangeEvent.addListener(({ imodelKey, source, changeType, selectables }) => {
42
+ const suffix = `in ${imodelKey} iModel from ${source} component`;
43
43
  const numSelectables = Selectables.size(selectables);
44
44
  switch (changeType) {
45
45
  case "add":
@@ -58,8 +58,8 @@ unifiedSelection.selectionChangeEvent.addListener(({ iModelKey, source, changeTy
58
58
  });
59
59
 
60
60
  // in some component
61
- MyComponent.onECInstanceSelected((iModel: IModelConnection, key: { className: string; id: Id64String }) => {
62
- unifiedSelection.addToSelection({ iModelKey: iModel.key, source: "MyComponent", selectables: [key] });
61
+ MyComponent.onECInstanceSelected((imodel: IModelConnection, key: { className: string; id: Id64String }) => {
62
+ unifiedSelection.addToSelection({ imodelKey: imodel.key, source: "MyComponent", selectables: [key] });
63
63
  });
64
64
  ```
65
65
 
@@ -109,11 +109,13 @@ The `@itwin/unified-selection` package delivers APIs for creating a `HiliteSet`
109
109
  ```ts
110
110
  // Components may want to get a hilite set for arbitrary set of Selectables - use `createHiliteSetProvider` for that.
111
111
  import { IModelConnection } from "@itwin/core-frontend";
112
- import { createECSqlQueryExecutor, createMetadataProvider } from "@itwin/presentation-core-interop";
112
+ import { createECSqlQueryExecutor, createECSchemaProvider } from "@itwin/presentation-core-interop";
113
113
  import { createHiliteSetProvider } from "@itwin/unified-selection";
114
114
  const hiliteProvider = createHiliteSetProvider({
115
- metadataProvider: createMetadataProvider(imodel),
116
- queryExecutor: createECSqlQueryExecutor(imodel),
115
+ imodelAccess: {
116
+ ...createECSchemaProvider(imodel),
117
+ ...createECSqlQueryExecutor(imodel),
118
+ },
117
119
  });
118
120
  const hiliteSet = await hiliteProvider.getHiliteSet({ selectables });
119
121
 
@@ -121,11 +123,8 @@ const hiliteSet = await hiliteProvider.getHiliteSet({ selectables });
121
123
  // recommended to keep a single instance of this provider per application as it caches hilite sets per each iModel's selection.
122
124
  import { createCachingHiliteSetProvider } from "@itwin/unified-selection";
123
125
  const selectionHiliteProvider = createCachingHiliteSetProvider({
124
- selectionStorage,
125
- iModelProvider: (iModelKey: string) => {
126
- queryExecutor: IECSqlQueryExecutor;
127
- metadataProvider: IMetadataProvider;
128
- },
126
+ selectionStorage,
127
+ imodelProvider: (imodelKey: string) => getIModelByKey(imodelKey),
129
128
  });
130
129
  const selectionHiliteSet = await selectionHiliteProvider.getHiliteSet({ imodel.key });
131
130
  // The caching provider registers a selection change listener and should be disposed, in case its lifetime
@@ -166,3 +165,24 @@ const queryExecutor = createECSqlQueryExecutor(imodel);
166
165
  // Returns the parent element, or the element itself if it does not have a parent, for each element specified in `elementIds` argument.
167
166
  const selection = computeSelection({ queryExecutor, elementIds, scope: { id: "element", ancestorLevel: 1 } });
168
167
  ```
168
+
169
+ ## iModel selection synchronization with unified selection
170
+
171
+ The `@itwin/unified-selection` package delivers a `enableUnifiedSelectionSyncWithIModel` function to enable selection synchronization between an iModel and a `SelectionStorage`. When called, it returns a cleanup function that should be used to disable the synchronization. There should only be one active synchronization between a single iModel and a `SelectionStorage` at a given time. For example, this function could be used inside a `useEffect` hook in a component that holds an iModel:
172
+
173
+ ```ts
174
+ import { createECSqlQueryExecutor, createECSchemaProvider } from "@itwin/presentation-core-interop";
175
+ useEffect(() => {
176
+ return enableUnifiedSelectionSyncWithIModel({
177
+ imodelAccess: {
178
+ ...createECSqlQueryExecutor(imodel),
179
+ ...createECSchemaProvider(imodel),
180
+ key: imodel.key,
181
+ hiliteSet: imodel.hilited,
182
+ selectionSet: imodel.selectionSet,
183
+ },
184
+ selectionStorage,
185
+ activeScopeProvider: () => "element",
186
+ });
187
+ }, [imodel]);
188
+ ```
@@ -1,6 +1,5 @@
1
+ import { ECSchemaProvider, ECSqlQueryExecutor } from "@itwin/presentation-shared";
1
2
  import { HiliteSet } from "./HiliteSetProvider";
2
- import { IMetadataProvider } from "./queries/ECMetadata";
3
- import { IECSqlQueryExecutor } from "./queries/ECSqlCore";
4
3
  import { SelectionStorage } from "./SelectionStorage";
5
4
  /**
6
5
  * Props for creating a `CachingHiliteSetProvider` instance.
@@ -8,10 +7,7 @@ import { SelectionStorage } from "./SelectionStorage";
8
7
  */
9
8
  export interface CachingHiliteSetProviderProps {
10
9
  selectionStorage: SelectionStorage;
11
- iModelProvider: (iModelKey: string) => {
12
- queryExecutor: IECSqlQueryExecutor;
13
- metadataProvider: IMetadataProvider;
14
- };
10
+ imodelProvider: (imodelKey: string) => ECSchemaProvider & ECSqlQueryExecutor;
15
11
  }
16
12
  /**
17
13
  * Defines return value of `createCachingHiliteSetProvider`.
@@ -23,7 +19,7 @@ export interface CachingHiliteSetProvider {
23
19
  /** Get the current hilite set iterator for the specified imodel */
24
20
  getHiliteSet(props: {
25
21
  /** iModel to get hilite set for */
26
- iModelKey: string;
22
+ imodelKey: string;
27
23
  }): AsyncIterableIterator<HiliteSet>;
28
24
  /** Disposes the cache. */
29
25
  dispose(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"CachingHiliteSetProvider.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/CachingHiliteSetProvider.ts"],"names":[],"mappings":"AAWA,OAAO,EAA2B,SAAS,EAAqB,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EAAuC,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3F;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK;QAAE,aAAa,EAAE,mBAAmB,CAAC;QAAC,gBAAgB,EAAE,iBAAiB,CAAA;KAAE,CAAC;CACpH;AAED;;;;;GAKG;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,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EAA2B,SAAS,EAAqB,MAAM,qBAAqB,CAAC;AAE5F,OAAO,EAAuC,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3F;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,gBAAgB,GAAG,kBAAkB,CAAC;CAC9E;AAED;;;;;GAKG;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"}
@@ -5,9 +5,6 @@
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.createCachingHiliteSetProvider = void 0;
8
- /** @packageDocumentation
9
- * @module UnifiedSelection
10
- */
11
8
  const rxjs_1 = require("rxjs");
12
9
  const rxjs_for_await_1 = require("rxjs-for-await");
13
10
  const HiliteSetProvider_1 = require("./HiliteSetProvider");
@@ -26,25 +23,25 @@ class CachingHiliteSetProviderImpl {
26
23
  _hiliteSetProviders = new Map();
27
24
  _cache = new Map();
28
25
  _removeListener;
29
- _iModelProvider;
26
+ _imodelProvider;
30
27
  constructor(props) {
31
28
  this._selectionStorage = props.selectionStorage;
32
- this._iModelProvider = props.iModelProvider;
29
+ this._imodelProvider = props.imodelProvider;
33
30
  this._removeListener = this._selectionStorage.selectionChangeEvent.addListener((args) => {
34
- this._cache.delete(args.iModelKey);
31
+ this._cache.delete(args.imodelKey);
35
32
  if (args.changeType === "clear" && args.source === SelectionStorage_1.IMODEL_CLOSE_SELECTION_CLEAR_SOURCE) {
36
- this._hiliteSetProviders.delete(args.iModelKey);
33
+ this._hiliteSetProviders.delete(args.imodelKey);
37
34
  }
38
35
  });
39
36
  }
40
- getHiliteSet({ iModelKey }) {
41
- const { queryExecutor, metadataProvider } = this._iModelProvider(iModelKey);
42
- const provider = this.getHiliteSetProvider(iModelKey, queryExecutor, metadataProvider);
43
- let hiliteSet = this._cache.get(iModelKey);
37
+ getHiliteSet({ imodelKey }) {
38
+ const imodelAccess = this._imodelProvider(imodelKey);
39
+ const provider = this.getHiliteSetProvider(imodelKey, imodelAccess);
40
+ let hiliteSet = this._cache.get(imodelKey);
44
41
  if (!hiliteSet) {
45
- const selectables = this._selectionStorage.getSelection({ iModelKey });
42
+ const selectables = this._selectionStorage.getSelection({ imodelKey });
46
43
  hiliteSet = (0, rxjs_1.from)(provider.getHiliteSet({ selectables })).pipe((0, rxjs_1.shareReplay)({ refCount: true }));
47
- this._cache.set(iModelKey, hiliteSet);
44
+ this._cache.set(imodelKey, hiliteSet);
48
45
  }
49
46
  return (0, rxjs_for_await_1.eachValueFrom)(hiliteSet);
50
47
  }
@@ -53,11 +50,11 @@ class CachingHiliteSetProviderImpl {
53
50
  this._hiliteSetProviders = new Map();
54
51
  this._cache = new Map();
55
52
  }
56
- getHiliteSetProvider(iModelKey, queryExecutor, metadataProvider) {
57
- let provider = this._hiliteSetProviders.get(iModelKey);
53
+ getHiliteSetProvider(imodelKey, imodelAccess) {
54
+ let provider = this._hiliteSetProviders.get(imodelKey);
58
55
  if (!provider) {
59
- provider = (0, HiliteSetProvider_1.createHiliteSetProvider)({ queryExecutor, metadataProvider });
60
- this._hiliteSetProviders.set(iModelKey, provider);
56
+ provider = (0, HiliteSetProvider_1.createHiliteSetProvider)({ imodelAccess });
57
+ this._hiliteSetProviders.set(imodelKey, provider);
61
58
  }
62
59
  return provider;
63
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CachingHiliteSetProvider.js","sourceRoot":"","sources":["../../../src/unified-selection/CachingHiliteSetProvider.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG;;GAEG;AAEH,+BAAqD;AACrD,mDAA+C;AAC/C,2DAA4F;AAI5F,yDAA2F;AA4B3F;;;;GAIG;AACH,SAAgB,8BAA8B,CAAC,KAAoC;IACjF,OAAO,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAFD,wEAEC;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,CAAqG;IAE5H,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,sDAAmC,EAAE;gBACtF,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aACjD;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,YAAY,CAAC,EAAE,SAAS,EAAyB;QACtD,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,aAAa,EAAE,gBAAgB,CAAC,CAAC;QACvF,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC,SAAS,EAAE;YACd,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;SACvC;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,aAAkC,EAAE,gBAAmC;QACrH,IAAI,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ,EAAE;YACb,QAAQ,GAAG,IAAA,2CAAuB,EAAC,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;SACnD;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\n/** @packageDocumentation\n * @module UnifiedSelection\n */\n\nimport { from, Observable, shareReplay } from \"rxjs\";\nimport { eachValueFrom } from \"rxjs-for-await\";\nimport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./HiliteSetProvider\";\nimport { IMetadataProvider } from \"./queries/ECMetadata\";\nimport { IECSqlQueryExecutor } from \"./queries/ECSqlCore\";\nimport { StorageSelectionChangeEventArgs } from \"./SelectionChangeEvent\";\nimport { IMODEL_CLOSE_SELECTION_CLEAR_SOURCE, SelectionStorage } from \"./SelectionStorage\";\n\n/**\n * Props for creating a `CachingHiliteSetProvider` instance.\n * @internal Not exported through barrel, but used in public API as an argument. May be supplemented with optional attributes any time.\n */\nexport interface CachingHiliteSetProviderProps {\n selectionStorage: SelectionStorage;\n iModelProvider: (iModelKey: string) => { queryExecutor: IECSqlQueryExecutor; metadataProvider: IMetadataProvider };\n}\n\n/**\n * Defines return value of `createCachingHiliteSetProvider`.\n *\n * @beta 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 */\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 * @beta\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) => { queryExecutor: IECSqlQueryExecutor; metadataProvider: IMetadataProvider };\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 { queryExecutor, metadataProvider } = this._iModelProvider(iModelKey);\n const provider = this.getHiliteSetProvider(iModelKey, queryExecutor, metadataProvider);\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, queryExecutor: IECSqlQueryExecutor, metadataProvider: IMetadataProvider) {\n let provider = this._hiliteSetProviders.get(iModelKey);\n if (!provider) {\n provider = createHiliteSetProvider({ queryExecutor, metadataProvider });\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;;;AAEhG,+BAAqD;AACrD,mDAA+C;AAE/C,2DAA4F;AAE5F,yDAA2F;AA4B3F;;;;GAIG;AACH,SAAgB,8BAA8B,CAAC,KAAoC;IACjF,OAAO,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAFD,wEAEC;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,CAA+D;IAEtF,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,sDAAmC,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,YAAmD;QACjG,IAAI,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAA,2CAAuB,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 { ECSchemaProvider, ECSqlQueryExecutor } from \"@itwin/presentation-shared\";\nimport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./HiliteSetProvider\";\nimport { StorageSelectionChangeEventArgs } from \"./SelectionChangeEvent\";\nimport { IMODEL_CLOSE_SELECTION_CLEAR_SOURCE, SelectionStorage } from \"./SelectionStorage\";\n\n/**\n * Props for creating a `CachingHiliteSetProvider` instance.\n * @internal Not exported through barrel, but used in public API as an argument. May be supplemented with optional attributes any time.\n */\nexport interface CachingHiliteSetProviderProps {\n selectionStorage: SelectionStorage;\n imodelProvider: (imodelKey: string) => ECSchemaProvider & ECSqlQueryExecutor;\n}\n\n/**\n * Defines return value of `createCachingHiliteSetProvider`.\n *\n * @beta 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 */\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 * @beta\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) => ECSchemaProvider & 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: ECSchemaProvider & 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"]}
@@ -0,0 +1,90 @@
1
+ import { ECSchemaProvider, ECSqlQueryExecutor } from "@itwin/presentation-shared";
2
+ import { CachingHiliteSetProvider } from "./CachingHiliteSetProvider";
3
+ import { ComputeSelectionProps } from "./SelectionScope";
4
+ import { SelectionStorage } from "./SelectionStorage";
5
+ import { CoreIModelHiliteSet, CoreIModelSelectionSet } from "./types/IModel";
6
+ /**
7
+ * Props for `enableUnifiedSelectionSyncWithIModel`.
8
+ * @internal Not exported through barrel, but used in public API as an argument. May be supplemented with optional attributes any time.
9
+ */
10
+ export interface EnableUnifiedSelectionSyncWithIModelProps {
11
+ /**
12
+ * Provides access to different iModel's features: query executing, metadata access, selection and hilite sets.
13
+ * It's recommended to use `@itwin/presentation-core-interop` to create `ECSqlQueryExecutor` and `ECSchemaProvider` from
14
+ * [IModelConnection](https://www.itwinjs.org/reference/core-frontend/imodelconnection/imodelconnection/) and map its `key`,
15
+ * `hilited` and `selectionSet` attributes like this:
16
+ *
17
+ * ```ts
18
+ * import { createECSqlQueryExecutor, createECSchemaProvider } from "@itwin/presentation-core-interop";
19
+ * import { IModelConnection } from "@itwin/core-frontend";
20
+ *
21
+ * const imodel: IModelConnection = ...
22
+ * const imodelAccess = {
23
+ * ...createECSqlQueryExecutor(imodel),
24
+ * ...createECSchemaProvider(MyAppFrontend.getSchemaContext(imodel)),
25
+ * key: imodel.key,
26
+ * hiliteSet: imodel.hilited,
27
+ * selectionSet: imodel.selectionSet,
28
+ * };
29
+ * ```.
30
+ */
31
+ imodelAccess: ECSqlQueryExecutor & ECSchemaProvider & {
32
+ /** Key of the iModel. Generally taken from `IModelConnection.key`. */
33
+ readonly key: string;
34
+ /** The set of currently hilited elements taken from `IModelConnection.hilited`. */
35
+ readonly hiliteSet: CoreIModelHiliteSet;
36
+ /** The set of currently selected elements taken from `IModelConnection.selectionSet`. */
37
+ readonly selectionSet: CoreIModelSelectionSet;
38
+ };
39
+ /** Selection storage to synchronize IModel's tool selection with. */
40
+ selectionStorage: SelectionStorage;
41
+ /** Active scope provider. */
42
+ activeScopeProvider: () => ComputeSelectionProps["scope"];
43
+ /**
44
+ * A caching hilite set provider used to retrieve hilite sets for an iModel. If not provided, a new `CachingHiliteSetProvider`
45
+ * will be created for the given iModel using the provided `imodelAccess`.
46
+ * If the consuming application already has a `CachingHiliteSetProvider` defined, it should be provided instead
47
+ * to reuse the cache and avoid creating new providers for each iModel.
48
+ */
49
+ cachingHiliteSetProvider?: CachingHiliteSetProvider;
50
+ }
51
+ /**
52
+ * Enables synchronization between iModel selection and unified selection.
53
+ * @returns function for disposing the synchronization.
54
+ * @beta
55
+ */
56
+ export declare function enableUnifiedSelectionSyncWithIModel(props: EnableUnifiedSelectionSyncWithIModelProps): () => void;
57
+ /**
58
+ * A handler that syncs selection between unified selection storage
59
+ * (`SelectionStorage`) and an iModel (`iModel.selectionSet`, `iModel.hilited`).
60
+ * @internal
61
+ */
62
+ export declare class IModelSelectionHandler {
63
+ private _selectionSourceName;
64
+ private _imodelAccess;
65
+ private _selectionStorage;
66
+ private _hiliteSetProvider;
67
+ private _cachingHiliteSetProvider;
68
+ private _activeScopeProvider;
69
+ private _isSuspended;
70
+ private _cancelOngoingChanges;
71
+ private _unifiedSelectionListenerDisposeFunc;
72
+ private _imodelListenerDisposeFunc;
73
+ private _hasCustomCachingHiliteSetProvider;
74
+ constructor(props: EnableUnifiedSelectionSyncWithIModelProps);
75
+ dispose(): void;
76
+ /** Temporarily suspends tool selection synchronization until the returned `IDisposable` is disposed. */
77
+ suspendIModelToolSelectionSync(): {
78
+ dispose: () => boolean;
79
+ };
80
+ private handleUnifiedSelectionChange;
81
+ private onUnifiedSelectionChanged;
82
+ private applyCurrentHiliteSet;
83
+ private addHiliteSet;
84
+ private removeHiliteSet;
85
+ private onIModelSelectionChanged;
86
+ private handleIModelSelectionChange;
87
+ private getSelectionSetChangeIds;
88
+ private idArgToIds;
89
+ }
90
+ //# sourceMappingURL=EnableUnifiedSelectionSyncWithIModel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAkC,MAAM,4BAA4B,CAAC;AAItG,OAAO,EAAoB,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAA0D,MAAM,gBAAgB,CAAC;AAErI;;;GAGG;AACH,MAAM,WAAW,yCAAyC;IACxD;;;;;;;;;;;;;;;;;;;OAmBG;IACH,YAAY,EAAE,kBAAkB,GAC9B,gBAAgB,GAAG;QACjB,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;IAiBzC,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,UAAU;CASnB"}
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.IModelSelectionHandler = exports.enableUnifiedSelectionSyncWithIModel = void 0;
8
+ const rxjs_1 = require("rxjs");
9
+ const core_bentley_1 = require("@itwin/core-bentley");
10
+ const CachingHiliteSetProvider_1 = require("./CachingHiliteSetProvider");
11
+ const HiliteSetProvider_1 = require("./HiliteSetProvider");
12
+ const SelectionScope_1 = require("./SelectionScope");
13
+ const IModel_1 = require("./types/IModel");
14
+ /**
15
+ * Enables synchronization between iModel selection and unified selection.
16
+ * @returns function for disposing the synchronization.
17
+ * @beta
18
+ */
19
+ function enableUnifiedSelectionSyncWithIModel(props) {
20
+ const selectionHandler = new IModelSelectionHandler(props);
21
+ return () => selectionHandler.dispose();
22
+ }
23
+ exports.enableUnifiedSelectionSyncWithIModel = enableUnifiedSelectionSyncWithIModel;
24
+ /**
25
+ * A handler that syncs selection between unified selection storage
26
+ * (`SelectionStorage`) and an iModel (`iModel.selectionSet`, `iModel.hilited`).
27
+ * @internal
28
+ */
29
+ class IModelSelectionHandler {
30
+ _selectionSourceName = "Tool";
31
+ _imodelAccess;
32
+ _selectionStorage;
33
+ _hiliteSetProvider;
34
+ _cachingHiliteSetProvider;
35
+ _activeScopeProvider;
36
+ _isSuspended;
37
+ _cancelOngoingChanges = new rxjs_1.Subject();
38
+ _unifiedSelectionListenerDisposeFunc;
39
+ _imodelListenerDisposeFunc;
40
+ _hasCustomCachingHiliteSetProvider;
41
+ constructor(props) {
42
+ this._imodelAccess = props.imodelAccess;
43
+ this._selectionStorage = props.selectionStorage;
44
+ this._activeScopeProvider = props.activeScopeProvider;
45
+ this._isSuspended = false;
46
+ this._hasCustomCachingHiliteSetProvider = !!props.cachingHiliteSetProvider;
47
+ this._cachingHiliteSetProvider =
48
+ props.cachingHiliteSetProvider ??
49
+ (0, CachingHiliteSetProvider_1.createCachingHiliteSetProvider)({
50
+ selectionStorage: this._selectionStorage,
51
+ imodelProvider: () => this._imodelAccess,
52
+ });
53
+ this._hiliteSetProvider = (0, HiliteSetProvider_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" });
59
+ }
60
+ dispose() {
61
+ this._cancelOngoingChanges.next();
62
+ this._imodelListenerDisposeFunc();
63
+ this._unifiedSelectionListenerDisposeFunc();
64
+ if (!this._hasCustomCachingHiliteSetProvider) {
65
+ this._cachingHiliteSetProvider.dispose();
66
+ }
67
+ }
68
+ /** Temporarily suspends tool selection synchronization until the returned `IDisposable` is disposed. */
69
+ suspendIModelToolSelectionSync() {
70
+ const wasSuspended = this._isSuspended;
71
+ this._isSuspended = true;
72
+ return {
73
+ dispose: () => (this._isSuspended = wasSuspended),
74
+ };
75
+ }
76
+ 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;
90
+ }
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
+ }
102
+ onUnifiedSelectionChanged = (args) => {
103
+ // iModels are only interested in top-level selection changes
104
+ if (args.imodelKey !== this._imodelAccess.key || args.level !== 0) {
105
+ return;
106
+ }
107
+ if (args.changeType === "replace" || args.changeType === "clear") {
108
+ this._cancelOngoingChanges.next();
109
+ }
110
+ this.handleUnifiedSelectionChange(args.changeType, args.selectables, args.source);
111
+ };
112
+ applyCurrentHiliteSet({ activeSelectionAction }) {
113
+ if (activeSelectionAction !== "keep") {
114
+ (0, core_bentley_1.using)(this.suspendIModelToolSelectionSync(), (_) => {
115
+ this._imodelAccess.hiliteSet.clear();
116
+ if (activeSelectionAction === "clearAll") {
117
+ this._imodelAccess.selectionSet.emptyAll();
118
+ }
119
+ });
120
+ }
121
+ (0, rxjs_1.from)(this._cachingHiliteSetProvider.getHiliteSet({ imodelKey: this._imodelAccess.key }))
122
+ .pipe((0, rxjs_1.takeUntil)(this._cancelOngoingChanges))
123
+ .subscribe({
124
+ next: (ids) => {
125
+ this.addHiliteSet(ids);
126
+ },
127
+ });
128
+ }
129
+ 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);
136
+ }
137
+ if (set.elements && set.elements.length) {
138
+ this._imodelAccess.hiliteSet.elements.addIds(set.elements);
139
+ this._imodelAccess.selectionSet.add(set.elements);
140
+ }
141
+ });
142
+ }
143
+ 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);
150
+ }
151
+ if (set.elements.length) {
152
+ this._imodelAccess.hiliteSet.elements.deleteIds(set.elements);
153
+ this._imodelAccess.selectionSet.remove(set.elements);
154
+ }
155
+ });
156
+ }
157
+ onIModelSelectionChanged = async (event) => {
158
+ if (this._isSuspended) {
159
+ return;
160
+ }
161
+ if (IModel_1.CoreSelectionSetEventType.Clear === event.type) {
162
+ this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });
163
+ return;
164
+ }
165
+ const elementIds = this.getSelectionSetChangeIds(event);
166
+ const scopedSelection = (0, SelectionScope_1.computeSelection)({ queryExecutor: this._imodelAccess, elementIds, scope: this._activeScopeProvider() });
167
+ await this.handleIModelSelectionChange(event.type, scopedSelection);
168
+ };
169
+ async handleIModelSelectionChange(type, iterator) {
170
+ if (type === IModel_1.CoreSelectionSetEventType.Remove) {
171
+ for await (const selectable of iterator) {
172
+ this._selectionStorage.removeFromSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName, selectables: [selectable] });
173
+ }
174
+ return;
175
+ }
176
+ if (type === IModel_1.CoreSelectionSetEventType.Replace) {
177
+ this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });
178
+ }
179
+ for await (const selectable of iterator) {
180
+ this._selectionStorage.addToSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName, selectables: [selectable] });
181
+ }
182
+ }
183
+ getSelectionSetChangeIds(event) {
184
+ switch (event.type) {
185
+ case IModel_1.CoreSelectionSetEventType.Add:
186
+ case IModel_1.CoreSelectionSetEventType.Replace:
187
+ (0, core_bentley_1.assert)(!!event.added);
188
+ return this.idArgToIds(event.added);
189
+ default:
190
+ (0, core_bentley_1.assert)(!!event.removed);
191
+ return this.idArgToIds(event.removed);
192
+ }
193
+ }
194
+ idArgToIds(ids) {
195
+ if (typeof ids === "string") {
196
+ return [ids];
197
+ }
198
+ if (ids instanceof Set) {
199
+ return [...ids];
200
+ }
201
+ return ids;
202
+ }
203
+ }
204
+ exports.IModelSelectionHandler = IModelSelectionHandler;
205
+ //# sourceMappingURL=EnableUnifiedSelectionSyncWithIModel.js.map