@itwin/unified-selection 0.2.0 → 0.4.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 +169 -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 +91 -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 +174 -131
  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 +91 -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 +174 -131
  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
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnableUnifiedSelectionSyncWithIModel.js","sourceRoot":"","sources":["../../../src/unified-selection/EnableUnifiedSelectionSyncWithIModel.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,+BAAgD;AAChD,sDAA6D;AAE7D,yEAAsG;AACtG,2DAA4F;AAG5F,qDAA2E;AAE3E,2CAAqI;AAqDrI;;;;GAIG;AACH,SAAgB,oCAAoC,CAAC,KAAgD;IACnG,MAAM,gBAAgB,GAAG,IAAI,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC3D,OAAO,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;AAC1C,CAAC;AAHD,oFAGC;AAED;;;;GAIG;AACH,MAAa,sBAAsB;IACzB,oBAAoB,GAAG,MAAM,CAAC;IAE9B,aAAa,CAA4D;IACzE,iBAAiB,CAAmB;IACpC,kBAAkB,CAAoB;IACtC,yBAAyB,CAA2B;IACpD,oBAAoB,CAAuC;IAE3D,YAAY,CAAU;IACtB,qBAAqB,GAAG,IAAI,cAAO,EAAQ,CAAC;IAC5C,oCAAoC,CAAa;IACjD,0BAA0B,CAAa;IACvC,kCAAkC,CAAU;IAEpD,YAAmB,KAAgD;QACjE,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,gBAAgB,CAAC;QAChD,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC,mBAAmB,CAAC;QACtD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,IAAI,CAAC,kCAAkC,GAAG,CAAC,CAAC,KAAK,CAAC,wBAAwB,CAAC;QAE3E,IAAI,CAAC,yBAAyB;YAC5B,KAAK,CAAC,wBAAwB;gBAC9B,IAAA,yDAA8B,EAAC;oBAC7B,gBAAgB,EAAE,IAAI,CAAC,iBAAiB;oBACxC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa;iBACzC,CAAC,CAAC;QAEL,IAAI,CAAC,kBAAkB,GAAG,IAAA,2CAAuB,EAAC,EAAE,YAAY,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACvH,IAAI,CAAC,oCAAoC,GAAG,IAAI,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,WAAW,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAEpI,gGAAgG;QAChG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,wBAAwB,GAAG,KAAK,CAAC;QAC9D,IAAI,CAAC,qBAAqB,CAAC,EAAE,qBAAqB,EAAE,UAAU,EAAE,CAAC,CAAC;IACpE,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAClC,IAAI,CAAC,oCAAoC,EAAE,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,kCAAkC,EAAE,CAAC;YAC7C,IAAI,CAAC,yBAAyB,CAAC,OAAO,EAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,wGAAwG;IACjG,8BAA8B;QACnC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACvC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,OAAO;YACL,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;SAClD,CAAC;IACJ,CAAC;IAEO,4BAA4B,CAAC,UAAsC,EAAE,WAAwB,EAAE,MAAc;QACnH,IAAI,UAAU,KAAK,OAAO,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YACvD,IAAI,CAAC,qBAAqB,CAAC,EAAE,qBAAqB,EAAE,UAAU,KAAK,SAAS,IAAI,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;YACnI,OAAO;QACT,CAAC;QAED,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;YACzB,IAAA,WAAI,EAAC,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;iBACxD,IAAI,CAAC,IAAA,gBAAS,EAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;iBAC3C,SAAS,CAAC;gBACT,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;oBACZ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;gBACzB,CAAC;aACF,CAAC,CAAC;YACL,OAAO;QACT,CAAC;QAED,IAAA,WAAI,EAAC,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;aACxD,IAAI,CAAC,IAAA,gBAAS,EAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;aAC3C,SAAS,CAAC;YACT,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;gBACZ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;YACD,QAAQ,EAAE,GAAG,EAAE;gBACb,IAAI,CAAC,qBAAqB,CAAC,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC,CAAC;YAChE,CAAC;SACF,CAAC,CAAC;IACP,CAAC;IAEO,yBAAyB,GAAG,CAAC,IAAqC,EAAE,EAAE;QAC5E,6DAA6D;QAC7D,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YAClE,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;YACjE,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACpF,CAAC,CAAC;IAEM,qBAAqB,CAAC,EAAE,qBAAqB,EAAmE;QACtH,IAAI,qBAAqB,KAAK,MAAM,EAAE,CAAC;YACrC,IAAA,oBAAK,EAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE;gBACjD,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;gBACrC,IAAI,qBAAqB,KAAK,UAAU,EAAE,CAAC;oBACzC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;gBAC7C,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAA,WAAI,EAAC,IAAI,CAAC,yBAAyB,CAAC,YAAY,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC;aACrF,IAAI,CAAC,IAAA,gBAAS,EAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;aAC3C,SAAS,CAAC;YACT,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;gBACZ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;SACF,CAAC,CAAC;IACP,CAAC;IAEO,YAAY,CAAC,GAAc;QACjC,IAAA,oBAAK,EAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE;YACjD,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACpC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzD,CAAC;YACD,IAAI,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;gBAClD,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACvE,CAAC;YACD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACxC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAC3D,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACpD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,GAAc;QACpC,IAAA,oBAAK,EAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE;YACjD,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACtB,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;gBAC7B,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC1E,CAAC;YACD,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACxB,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAC9D,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,wBAAwB,GAAG,KAAK,EAAE,KAAmC,EAAiB,EAAE;QAC9F,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,IAAI,kCAAyB,CAAC,KAAK,KAAK,KAAM,CAAC,IAAI,EAAE,CAAC;YACpD,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;YAChH,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,wBAAwB,CAAC,KAAM,CAAC,CAAC;QACzD,MAAM,eAAe,GAAG,IAAA,iCAAgB,EAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;QAChI,MAAM,IAAI,CAAC,2BAA2B,CAAC,KAAM,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACvE,CAAC,CAAC;IAEM,KAAK,CAAC,2BAA2B,CAAC,IAA+B,EAAE,QAAsD;QAC/H,IAAI,IAAI,KAAK,kCAAyB,CAAC,MAAM,EAAE,CAAC;YAC9C,IAAI,KAAK,EAAE,MAAM,UAAU,IAAI,QAAQ,EAAE,CAAC;gBACxC,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,WAAW,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAClJ,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,IAAI,KAAK,kCAAyB,CAAC,OAAO,EAAE,CAAC;YAC/C,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;QAClH,CAAC;QAED,IAAI,KAAK,EAAE,MAAM,UAAU,IAAI,QAAQ,EAAE,CAAC;YACxC,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,WAAW,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC7I,CAAC;IACH,CAAC;IAEO,wBAAwB,CAAC,KAAkC;QACjE,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,kCAAyB,CAAC,GAAG,CAAC;YACnC,KAAK,kCAAyB,CAAC,OAAO;gBACpC,IAAA,qBAAM,EAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACtB,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACtC;gBACE,IAAA,qBAAM,EAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACxB,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,GAAY;QAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;QACD,IAAI,GAAG,YAAY,GAAG,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAvMD,wDAuMC","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, Subject, takeUntil } from \"rxjs\";\nimport { assert, Id64Arg, using } from \"@itwin/core-bentley\";\nimport { ECClassHierarchyInspector, ECSqlQueryExecutor } from \"@itwin/presentation-shared\";\nimport { CachingHiliteSetProvider, createCachingHiliteSetProvider } from \"./CachingHiliteSetProvider\";\nimport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./HiliteSetProvider\";\nimport { SelectableInstanceKey, Selectables } from \"./Selectable\";\nimport { StorageSelectionChangeEventArgs, StorageSelectionChangeType } from \"./SelectionChangeEvent\";\nimport { computeSelection, ComputeSelectionProps } from \"./SelectionScope\";\nimport { SelectionStorage } from \"./SelectionStorage\";\nimport { CoreIModelHiliteSet, CoreIModelSelectionSet, CoreSelectionSetEventType, CoreSelectionSetEventUnsafe } from \"./types/IModel\";\n\n/**\n * Props for `enableUnifiedSelectionSyncWithIModel`.\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 EnableUnifiedSelectionSyncWithIModelProps {\n /**\n * Provides access to different iModel's features: query executing, class hierarchy, selection and hilite sets.\n * It's recommended to use `@itwin/presentation-core-interop` to create `ECSqlQueryExecutor` and `ECSchemaProvider` from\n * [IModelConnection](https://www.itwinjs.org/reference/core-frontend/imodelconnection/imodelconnection/) and map its `key`,\n * `hilited` and `selectionSet` attributes like this:\n *\n * ```ts\n * import { createECSqlQueryExecutor, createECSchemaProvider } from \"@itwin/presentation-core-interop\";\n * import { createCachingECClassHierarchyInspector } from \"@itwin/presentation-shared\";\n * import { IModelConnection } from \"@itwin/core-frontend\";\n *\n * const imodel: IModelConnection = ...\n * const imodelAccess = {\n * ...createECSqlQueryExecutor(imodel),\n * ...createCachingECClassHierarchyInspector({ schemaProvider: createECSchemaProvider(MyAppFrontend.getSchemaContext(imodel)) }),\n * key: imodel.key,\n * hiliteSet: imodel.hilited,\n * selectionSet: imodel.selectionSet,\n * };\n * ```.\n */\n imodelAccess: ECSqlQueryExecutor &\n ECClassHierarchyInspector & {\n /** Key of the iModel. Generally taken from `IModelConnection.key`. */\n readonly key: string;\n /** The set of currently hilited elements taken from `IModelConnection.hilited`. */\n readonly hiliteSet: CoreIModelHiliteSet;\n /** The set of currently selected elements taken from `IModelConnection.selectionSet`. */\n readonly selectionSet: CoreIModelSelectionSet;\n };\n\n /** Selection storage to synchronize IModel's tool selection with. */\n selectionStorage: SelectionStorage;\n\n /** Active scope provider. */\n activeScopeProvider: () => ComputeSelectionProps[\"scope\"];\n\n /**\n * A caching hilite set provider used to retrieve hilite sets for an iModel. If not provided, a new `CachingHiliteSetProvider`\n * will be created for the given iModel using the provided `imodelAccess`.\n * If the consuming application already has a `CachingHiliteSetProvider` defined, it should be provided instead\n * to reuse the cache and avoid creating new providers for each iModel.\n */\n cachingHiliteSetProvider?: CachingHiliteSetProvider;\n}\n\n/**\n * Enables synchronization between iModel selection and unified selection.\n * @returns function for disposing the synchronization.\n * @beta\n */\nexport function enableUnifiedSelectionSyncWithIModel(props: EnableUnifiedSelectionSyncWithIModelProps): () => void {\n const selectionHandler = new IModelSelectionHandler(props);\n return () => selectionHandler.dispose();\n}\n\n/**\n * A handler that syncs selection between unified selection storage\n * (`SelectionStorage`) and an iModel (`iModel.selectionSet`, `iModel.hilited`).\n * @internal\n */\nexport class IModelSelectionHandler {\n private _selectionSourceName = \"Tool\";\n\n private _imodelAccess: EnableUnifiedSelectionSyncWithIModelProps[\"imodelAccess\"];\n private _selectionStorage: SelectionStorage;\n private _hiliteSetProvider: HiliteSetProvider;\n private _cachingHiliteSetProvider: CachingHiliteSetProvider;\n private _activeScopeProvider: () => ComputeSelectionProps[\"scope\"];\n\n private _isSuspended: boolean;\n private _cancelOngoingChanges = new Subject<void>();\n private _unifiedSelectionListenerDisposeFunc: () => void;\n private _imodelListenerDisposeFunc: () => void;\n private _hasCustomCachingHiliteSetProvider: boolean;\n\n public constructor(props: EnableUnifiedSelectionSyncWithIModelProps) {\n this._imodelAccess = props.imodelAccess;\n this._selectionStorage = props.selectionStorage;\n this._activeScopeProvider = props.activeScopeProvider;\n this._isSuspended = false;\n this._hasCustomCachingHiliteSetProvider = !!props.cachingHiliteSetProvider;\n\n this._cachingHiliteSetProvider =\n props.cachingHiliteSetProvider ??\n createCachingHiliteSetProvider({\n selectionStorage: this._selectionStorage,\n imodelProvider: () => this._imodelAccess,\n });\n\n this._hiliteSetProvider = createHiliteSetProvider({ imodelAccess: this._imodelAccess });\n this._imodelListenerDisposeFunc = this._imodelAccess.selectionSet.onChanged.addListener(this.onIModelSelectionChanged);\n this._unifiedSelectionListenerDisposeFunc = this._selectionStorage.selectionChangeEvent.addListener(this.onUnifiedSelectionChanged);\n\n // stop imodel from syncing tool selection with hilited list - we want to override that behavior\n this._imodelAccess.hiliteSet.wantSyncWithSelectionSet = false;\n this.applyCurrentHiliteSet({ activeSelectionAction: \"clearAll\" });\n }\n\n public dispose() {\n this._cancelOngoingChanges.next();\n this._imodelListenerDisposeFunc();\n this._unifiedSelectionListenerDisposeFunc();\n if (!this._hasCustomCachingHiliteSetProvider) {\n this._cachingHiliteSetProvider.dispose();\n }\n }\n\n /** Temporarily suspends tool selection synchronization until the returned `IDisposable` is disposed. */\n public suspendIModelToolSelectionSync() {\n const wasSuspended = this._isSuspended;\n this._isSuspended = true;\n return {\n dispose: () => (this._isSuspended = wasSuspended),\n };\n }\n\n private handleUnifiedSelectionChange(changeType: StorageSelectionChangeType, selectables: Selectables, source: string) {\n if (changeType === \"clear\" || changeType === \"replace\") {\n this.applyCurrentHiliteSet({ activeSelectionAction: changeType === \"replace\" && source === \"Tool\" ? \"clearHilited\" : \"clearAll\" });\n return;\n }\n\n if (changeType === \"add\") {\n from(this._hiliteSetProvider.getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.addHiliteSet(set);\n },\n });\n return;\n }\n\n from(this._hiliteSetProvider.getHiliteSet({ selectables }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (set) => {\n this.removeHiliteSet(set);\n },\n complete: () => {\n this.applyCurrentHiliteSet({ activeSelectionAction: \"keep\" });\n },\n });\n }\n\n private onUnifiedSelectionChanged = (args: StorageSelectionChangeEventArgs) => {\n // iModels are only interested in top-level selection changes\n if (args.imodelKey !== this._imodelAccess.key || args.level !== 0) {\n return;\n }\n\n if (args.changeType === \"replace\" || args.changeType === \"clear\") {\n this._cancelOngoingChanges.next();\n }\n this.handleUnifiedSelectionChange(args.changeType, args.selectables, args.source);\n };\n\n private applyCurrentHiliteSet({ activeSelectionAction }: { activeSelectionAction: \"clearAll\" | \"clearHilited\" | \"keep\" }) {\n if (activeSelectionAction !== \"keep\") {\n using(this.suspendIModelToolSelectionSync(), (_) => {\n this._imodelAccess.hiliteSet.clear();\n if (activeSelectionAction === \"clearAll\") {\n this._imodelAccess.selectionSet.emptyAll();\n }\n });\n }\n\n from(this._cachingHiliteSetProvider.getHiliteSet({ imodelKey: this._imodelAccess.key }))\n .pipe(takeUntil(this._cancelOngoingChanges))\n .subscribe({\n next: (ids) => {\n this.addHiliteSet(ids);\n },\n });\n }\n\n private addHiliteSet(set: HiliteSet) {\n using(this.suspendIModelToolSelectionSync(), (_) => {\n if (set.models && set.models.length) {\n this._imodelAccess.hiliteSet.models.addIds(set.models);\n }\n if (set.subCategories && set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.addIds(set.subCategories);\n }\n if (set.elements && set.elements.length) {\n this._imodelAccess.hiliteSet.elements.addIds(set.elements);\n this._imodelAccess.selectionSet.add(set.elements);\n }\n });\n }\n\n private removeHiliteSet(set: HiliteSet) {\n using(this.suspendIModelToolSelectionSync(), (_) => {\n if (set.models.length) {\n this._imodelAccess.hiliteSet.models.deleteIds(set.models);\n }\n if (set.subCategories.length) {\n this._imodelAccess.hiliteSet.subcategories.deleteIds(set.subCategories);\n }\n if (set.elements.length) {\n this._imodelAccess.hiliteSet.elements.deleteIds(set.elements);\n this._imodelAccess.selectionSet.remove(set.elements);\n }\n });\n }\n\n private onIModelSelectionChanged = async (event?: CoreSelectionSetEventUnsafe): Promise<void> => {\n if (this._isSuspended) {\n return;\n }\n\n if (CoreSelectionSetEventType.Clear === event!.type) {\n this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });\n return;\n }\n\n const elementIds = this.getSelectionSetChangeIds(event!);\n const scopedSelection = computeSelection({ queryExecutor: this._imodelAccess, elementIds, scope: this._activeScopeProvider() });\n await this.handleIModelSelectionChange(event!.type, scopedSelection);\n };\n\n private async handleIModelSelectionChange(type: CoreSelectionSetEventType, iterator: AsyncIterableIterator<SelectableInstanceKey>) {\n if (type === CoreSelectionSetEventType.Remove) {\n for await (const selectable of iterator) {\n this._selectionStorage.removeFromSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName, selectables: [selectable] });\n }\n return;\n }\n\n if (type === CoreSelectionSetEventType.Replace) {\n this._selectionStorage.clearSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName });\n }\n\n for await (const selectable of iterator) {\n this._selectionStorage.addToSelection({ imodelKey: this._imodelAccess.key, source: this._selectionSourceName, selectables: [selectable] });\n }\n }\n\n private getSelectionSetChangeIds(event: CoreSelectionSetEventUnsafe): string[] {\n switch (event.type) {\n case CoreSelectionSetEventType.Add:\n case CoreSelectionSetEventType.Replace:\n assert(!!event.added);\n return this.idArgToIds(event.added);\n default:\n assert(!!event.removed);\n return this.idArgToIds(event.removed);\n }\n }\n\n private idArgToIds(ids: Id64Arg): string[] {\n if (typeof ids === \"string\") {\n return [ids];\n }\n if (ids instanceof Set) {\n return [...ids];\n }\n return ids;\n }\n}\n"]}
@@ -1,5 +1,4 @@
1
- import { IMetadataProvider } from "./queries/ECMetadata";
2
- import { IECSqlQueryExecutor } from "./queries/ECSqlCore";
1
+ import { ECClassHierarchyInspector, ECSqlQueryExecutor } from "@itwin/presentation-shared";
3
2
  import { Selectables } from "./Selectable";
4
3
  /**
5
4
  * A set of model, subcategory and element ids that can be used for specifying hilite.
@@ -16,8 +15,7 @@ export interface HiliteSet {
16
15
  * @internal Not exported through barrel, but used in public API as an argument. May be supplemented with optional attributes any time.
17
16
  */
18
17
  export interface HiliteSetProviderProps {
19
- queryExecutor: IECSqlQueryExecutor;
20
- metadataProvider: IMetadataProvider;
18
+ imodelAccess: ECClassHierarchyInspector & ECSqlQueryExecutor;
21
19
  }
22
20
  /**
23
21
  * Defines return value of `createHiliteSetProvider`.
@@ -1 +1 @@
1
- {"version":3,"file":"HiliteSetProvider.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/HiliteSetProvider.ts"],"names":[],"mappings":"AAWA,OAAO,EAAW,iBAAiB,EAAsB,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAgC,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAyB,WAAW,EAAE,MAAM,cAAc,CAAC;AAIlE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,mBAAmB,CAAC;IACnC,gBAAgB,EAAE,iBAAiB,CAAC;CACrC;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,YAAY,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,WAAW,CAAA;KAAE,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;CACrF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,iBAAiB,CAExF"}
1
+ {"version":3,"file":"HiliteSetProvider.d.ts","sourceRoot":"","sources":["../../../src/unified-selection/HiliteSetProvider.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,yBAAyB,EAAgB,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACzG,OAAO,EAAyB,WAAW,EAAE,MAAM,cAAc,CAAC;AAKlE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,yBAAyB,GAAG,kBAAkB,CAAC;CAC9D;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,YAAY,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE,WAAW,CAAA;KAAE,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;CACrF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,iBAAiB,CAExF"}
@@ -5,13 +5,9 @@
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.createHiliteSetProvider = 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
- const ECMetadata_1 = require("./queries/ECMetadata");
14
- const ECSqlCore_1 = require("./queries/ECSqlCore");
10
+ const Utils_1 = require("./Utils");
15
11
  const HILITE_SET_EMIT_FREQUENCY = 20;
16
12
  /**
17
13
  * Creates a hilite set provider that returns a `HiliteSet` for given selectables.
@@ -22,13 +18,11 @@ function createHiliteSetProvider(props) {
22
18
  }
23
19
  exports.createHiliteSetProvider = createHiliteSetProvider;
24
20
  class HiliteSetProviderImpl {
25
- _queryExecutor;
26
- _metadataProvider;
21
+ _imodelAccess;
27
22
  // Map between a class name and its type
28
23
  _classRelationCache;
29
24
  constructor(props) {
30
- this._queryExecutor = props.queryExecutor;
31
- this._metadataProvider = props.metadataProvider;
25
+ this._imodelAccess = props.imodelAccess;
32
26
  this._classRelationCache = new Map();
33
27
  }
34
28
  /**
@@ -95,20 +89,30 @@ class HiliteSetProviderImpl {
95
89
  return promise;
96
90
  }
97
91
  async getTypeImpl(key) {
98
- const keyClass = await this.getClass(key.className);
99
- return ((keyClass &&
100
- ((await this.checkType(keyClass, "BisCore", "Subject", "subject")) ??
101
- (await this.checkType(keyClass, "BisCore", "Model", "model")) ??
102
- (await this.checkType(keyClass, "BisCore", "Category", "category")) ??
103
- (await this.checkType(keyClass, "BisCore", "SubCategory", "subCategory")) ??
104
- (await this.checkType(keyClass, "Functional", "FunctionalElement", "functionalElement")) ??
105
- (await this.checkType(keyClass, "BisCore", "GroupInformationElement", "groupInformationElement")) ??
106
- (await this.checkType(keyClass, "BisCore", "GeometricElement", "geometricElement")) ??
107
- (await this.checkType(keyClass, "BisCore", "Element", "element")))) ??
92
+ return ((await this.checkType(key.className, "BisCore.Subject", "subject")) ??
93
+ (await this.checkType(key.className, "BisCore.Model", "model")) ??
94
+ (await this.checkType(key.className, "BisCore.Category", "category")) ??
95
+ (await this.checkType(key.className, "BisCore.SubCategory", "subCategory")) ??
96
+ (await this.checkType(key.className, "Functional.FunctionalElement", "functionalElement")) ??
97
+ (await this.checkType(key.className, "BisCore.GroupInformationElement", "groupInformationElement")) ??
98
+ (await this.checkType(key.className, "BisCore.GeometricElement", "geometricElement")) ??
99
+ (await this.checkType(key.className, "BisCore.Element", "element")) ??
108
100
  "unknown");
109
101
  }
110
- async checkType(keyClass, schemaName, className, type) {
111
- return (await keyClass.is(className, schemaName)) ? type : undefined;
102
+ async checkType(keyClassName, checkClassName, type) {
103
+ try {
104
+ const res = this._imodelAccess.classDerivesFrom(keyClassName, checkClassName);
105
+ const isOfType = typeof res === "boolean" ? res : await res;
106
+ return isOfType ? type : undefined;
107
+ }
108
+ catch (e) {
109
+ // we may be checking against a non-existing schema (e.g. Functional), in which case we should
110
+ // return undefined instead of throwing an error
111
+ if (e instanceof Error && e.message.match(/Schema "[\w\d_]+" not found/)) {
112
+ return undefined;
113
+ }
114
+ throw e;
115
+ }
112
116
  }
113
117
  getInstancesByType(selectables) {
114
118
  const keyTypeObs = (0, rxjs_1.merge)((0, rxjs_1.from)(selectables.custom.values()).pipe((0, rxjs_1.mergeMap)((selectable) => selectable.loadInstanceKeys())), (0, rxjs_1.from)(selectables.instanceKeys).pipe((0, rxjs_1.mergeMap)(([className, idSet]) => (0, rxjs_1.from)(idSet).pipe((0, rxjs_1.map)((id) => ({ className, id })))))).pipe(
@@ -130,24 +134,37 @@ class HiliteSetProviderImpl {
130
134
  return rxjs_1.EMPTY;
131
135
  }
132
136
  const bindings = [];
133
- const query = `WITH RECURSIVE
134
- ChildSubjects (ECInstanceId, JsonProperties) AS (
135
- SELECT ECInstanceId, JsonProperties FROM BisCore.Subject WHERE ${(0, ECSqlCore_1.formIdBindings)("ECInstanceId", subjectKeys, bindings)}
136
- UNION ALL
137
- SELECT r.ECInstanceId, r.JsonProperties FROM ChildSubjects s
138
- JOIN BisCore.Subject r ON r.Parent.Id = s.ECInstanceId
139
- ),
140
- Models (ECInstanceId) AS (
141
- SELECT s.ECInstanceId as \`ECInstanceId\` FROM BisCore.Model s
142
- WHERE ${(0, ECSqlCore_1.formIdBindings)("ECInstanceId", modelKeys, bindings)}
143
- )
144
- SELECT r.ECInstanceId as \`ECInstanceId\` FROM ChildSubjects s
145
- JOIN BisCore.PhysicalPartition r
146
- ON r.Parent.Id = s.ECInstanceId
147
- OR json_extract(s.JsonProperties,'$.Subject.Model.TargetPartition') = printf('0x%x', r.ECInstanceId)
148
- UNION
149
- SELECT ECInstanceId FROM Models;`;
150
- return (0, rxjs_1.from)(this._queryExecutor.createQueryReader(query, bindings));
137
+ const ctes = [
138
+ `
139
+ ChildSubjects(ECInstanceId, JsonProperties) AS (
140
+ SELECT ECInstanceId, JsonProperties
141
+ FROM BisCore.Subject
142
+ WHERE ${(0, Utils_1.formIdBindings)("ECInstanceId", subjectKeys, bindings)}
143
+ UNION ALL
144
+ SELECT r.ECInstanceId, r.JsonProperties
145
+ FROM ChildSubjects s
146
+ JOIN BisCore.Subject r ON r.Parent.Id = s.ECInstanceId
147
+ )
148
+ `,
149
+ `
150
+ Models(ECInstanceId) AS (
151
+ SELECT s.ECInstanceId AS ECInstanceId
152
+ FROM BisCore.Model s
153
+ WHERE ${(0, Utils_1.formIdBindings)("ECInstanceId", modelKeys, bindings)}
154
+ )
155
+ `,
156
+ ];
157
+ const ecsql = [
158
+ `
159
+ SELECT r.ECInstanceId AS ECInstanceId
160
+ FROM ChildSubjects s
161
+ JOIN BisCore.PhysicalPartition r ON r.Parent.Id = s.ECInstanceId OR json_extract(s.JsonProperties,'$.Subject.Model.TargetPartition') = printf('0x%x', r.ECInstanceId)
162
+ `,
163
+ `
164
+ SELECT ECInstanceId FROM Models
165
+ `,
166
+ ].join(" UNION ");
167
+ return (0, rxjs_1.from)(this._imodelAccess.createQueryReader({ ctes, ecsql, bindings }));
151
168
  }), (0, rxjs_1.map)((row) => row.ECInstanceId));
152
169
  }
153
170
  getHilitedSubCategories(instancesByType) {
@@ -159,20 +176,25 @@ class HiliteSetProviderImpl {
159
176
  return rxjs_1.EMPTY;
160
177
  }
161
178
  const bindings = [];
162
- const query = `WITH
163
- CategorySubCategories (ECInstanceId) AS (
164
- SELECT r.ECInstanceId as \`ECInstanceId\` FROM BisCore.Category s
165
- JOIN BisCore.SubCategory r ON r.Parent.Id = s.ECInstanceId
166
- WHERE ${(0, ECSqlCore_1.formIdBindings)("s.ECInstanceId", categoryKeys, bindings)}
167
- ),
168
- SubCategories (ECInstanceId) AS (
169
- SELECT s.ECInstanceId as \`ECInstanceId\` FROM BisCore.SubCategory s
170
- WHERE ${(0, ECSqlCore_1.formIdBindings)("s.ECInstanceId", subCategoryKeys, bindings)}
171
- )
172
- SELECT ECInstanceId FROM CategorySubCategories
173
- UNION
174
- SELECT ECInstanceId FROM SubCategories;`;
175
- return (0, rxjs_1.from)(this._queryExecutor.createQueryReader(query, bindings));
179
+ const ctes = [
180
+ `
181
+ CategorySubCategories(ECInstanceId) AS (
182
+ SELECT r.ECInstanceId AS ECInstanceId
183
+ FROM BisCore.Category s
184
+ JOIN BisCore.SubCategory r ON r.Parent.Id = s.ECInstanceId
185
+ WHERE ${(0, Utils_1.formIdBindings)("s.ECInstanceId", categoryKeys, bindings)}
186
+ )
187
+ `,
188
+ `
189
+ SubCategories(ECInstanceId) AS (
190
+ SELECT s.ECInstanceId AS ECInstanceId
191
+ FROM BisCore.SubCategory s
192
+ WHERE ${(0, Utils_1.formIdBindings)("s.ECInstanceId", subCategoryKeys, bindings)}
193
+ )
194
+ `,
195
+ ];
196
+ const ecsql = [`SELECT ECInstanceId FROM CategorySubCategories`, `SELECT ECInstanceId FROM SubCategories`].join(" UNION ");
197
+ return (0, rxjs_1.from)(this._imodelAccess.createQueryReader({ ctes, ecsql, bindings }));
176
198
  }), (0, rxjs_1.map)((row) => row.ECInstanceId));
177
199
  }
178
200
  getHilitedElements(instancesByType) {
@@ -187,88 +209,109 @@ class HiliteSetProviderImpl {
187
209
  return rxjs_1.EMPTY;
188
210
  }
189
211
  const bindings = [];
190
- const query = `WITH RECURSIVE
191
- ${hasFunctionalElements ? this.getHilitedFunctionalElementsQuery(functionalElements, bindings) : ""}
192
- GroupMembers (ECInstanceId, ECClassId) AS (
193
- SELECT TargetECInstanceId, TargetECClassId FROM BisCore.ElementGroupsMembers
194
- WHERE ${(0, ECSqlCore_1.formIdBindings)("SourceECInstanceId", groupInformationElementKeys, bindings)}
195
- ),
196
- GroupGeometricElements (ECInstanceId, ECClassId) AS (
197
- SELECT ECInstanceId, ECClassId FROM GroupMembers
198
- UNION ALL
199
- SELECT r.ECInstanceId, r.ECClassId FROM GroupGeometricElements s
200
- JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
201
- ),
202
- ElementGeometricElements (ECInstanceId, ECClassId) AS (
203
- SELECT ECInstanceId, ECClassId FROM BisCore.Element WHERE ${(0, ECSqlCore_1.formIdBindings)("ECInstanceId", elementKeys, bindings)}
204
- UNION ALL
205
- SELECT r.ECInstanceId, r.ECClassId FROM ElementGeometricElements s
206
- JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
207
- ),
208
- GeometricElementGeometricElements (ECInstanceId, ECClassId) AS (
209
- SELECT ECInstanceId, ECClassId FROM BisCore.GeometricElement WHERE ${(0, ECSqlCore_1.formIdBindings)("ECInstanceId", geometricElementKeys, bindings)}
210
- UNION ALL
211
- SELECT r.ECInstanceId, r.ECClassId FROM GeometricElementGeometricElements s
212
- JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
213
- )
214
- ${hasFunctionalElements
215
- ? `
216
- SELECT ECInstanceId FROM FunctionalElementChildGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)
217
- UNION
218
- `
219
- : ``}
220
- SELECT ECInstanceId FROM GeometricElementGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)
221
- UNION
222
- SELECT ECInstanceId FROM GroupGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)
223
- UNION
224
- SELECT ECInstanceId FROM ElementGeometricElements WHERE ECClassId IS (BisCore.GeometricElement);`;
225
- return (0, rxjs_1.from)(this._queryExecutor.createQueryReader(query, bindings));
226
- }), (0, rxjs_1.map)((row) => row.ECInstanceId));
227
- }
228
- getHilitedFunctionalElementsQuery(functionalElements, bindings) {
229
- return `ChildFunctionalElements (ECInstanceId, ECClassId) AS (
230
- SELECT ECInstanceId, ECClassId FROM Functional.FunctionalElement WHERE ${(0, ECSqlCore_1.formIdBindings)("ECInstanceId", functionalElements, bindings)}
212
+ const ctes = [
213
+ ...(hasFunctionalElements ? this.getHilitedFunctionalElementsQueryCTEs(functionalElements, bindings) : []),
214
+ `
215
+ GroupMembers(ECInstanceId, ECClassId) AS (
216
+ SELECT TargetECInstanceId, TargetECClassId
217
+ FROM BisCore.ElementGroupsMembers
218
+ WHERE ${(0, Utils_1.formIdBindings)("SourceECInstanceId", groupInformationElementKeys, bindings)}
219
+ )
220
+ `,
221
+ `
222
+ GroupGeometricElements(ECInstanceId, ECClassId) AS (
223
+ SELECT ECInstanceId, ECClassId FROM GroupMembers
231
224
  UNION ALL
232
- SELECT r.ECInstanceId, r.ECClassId FROM ChildFunctionalElements s
233
- JOIN Functional.FunctionalElement r ON r.Parent.Id = s.ECInstanceId
234
- ),
235
- PhysicalElements (ECInstanceId, ECClassId) AS (
236
- SELECT r.SourceECInstanceId, r.SourceECClassId FROM ChildFunctionalElements s
237
- JOIN Functional.PhysicalElementFulfillsFunction r ON r.TargetECInstanceId = s.ECInstanceId
238
- ),
239
- DrawingGraphicElements (ECInstanceId, ECClassId) AS (
240
- SELECT r.SourceECInstanceId, r.SourceECClassId FROM ChildFunctionalElements s
241
- JOIN Functional.DrawingGraphicRepresentsFunctionalElement r ON r.TargetECInstanceId = s.ECInstanceId
242
- ),
243
- PhysicalElementGeometricElements (ECInstanceId, ECClassId) AS (
244
- SELECT ECInstanceId, ECClassId FROM PhysicalElements
225
+ SELECT r.ECInstanceId, r.ECClassId
226
+ FROM GroupGeometricElements s
227
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
228
+ )
229
+ `,
230
+ `
231
+ ElementGeometricElements(ECInstanceId, ECClassId) AS (
232
+ SELECT ECInstanceId, ECClassId
233
+ FROM BisCore.Element
234
+ WHERE ${(0, Utils_1.formIdBindings)("ECInstanceId", elementKeys, bindings)}
245
235
  UNION ALL
246
- SELECT r.ECInstanceId, r.ECClassId FROM PhysicalElementGeometricElements s
247
- JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
248
- ),
249
- DrawingGraphicElementGeometricElements (ECInstanceId, ECClassId) AS (
250
- SELECT ECInstanceId, ECClassId FROM DrawingGraphicElements
236
+ SELECT r.ECInstanceId, r.ECClassId
237
+ FROM ElementGeometricElements s
238
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
239
+ )
240
+ `,
241
+ `
242
+ GeometricElementGeometricElements(ECInstanceId, ECClassId) AS (
243
+ SELECT ECInstanceId, ECClassId
244
+ FROM BisCore.GeometricElement
245
+ WHERE ${(0, Utils_1.formIdBindings)("ECInstanceId", geometricElementKeys, bindings)}
251
246
  UNION ALL
252
- SELECT r.ECInstanceId, r.ECClassId FROM DrawingGraphicElementGeometricElements s
253
- JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
254
- ),
255
- FunctionalElementChildGeometricElements (ECInstanceId, ECClassId) AS (
256
- SELECT ECInstanceId, ECClassId FROM PhysicalElementGeometricElements
257
- UNION
258
- SELECT ECInstanceId, ECClassId FROM DrawingGraphicElementGeometricElements
259
- ),`;
247
+ SELECT r.ECInstanceId, r.ECClassId
248
+ FROM GeometricElementGeometricElements s
249
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
250
+ )
251
+ `,
252
+ ];
253
+ const ecsql = [
254
+ ...(hasFunctionalElements ? ["SELECT ECInstanceId FROM FunctionalElementChildGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)"] : []),
255
+ "SELECT ECInstanceId FROM GeometricElementGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)",
256
+ "SELECT ECInstanceId FROM GroupGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)",
257
+ "SELECT ECInstanceId FROM ElementGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)",
258
+ ].join(" UNION ");
259
+ return (0, rxjs_1.from)(this._imodelAccess.createQueryReader({ ctes, ecsql, bindings }));
260
+ }), (0, rxjs_1.map)((row) => row.ECInstanceId));
260
261
  }
261
- async getClass(fullClassName) {
262
- const { schemaName, className } = (0, ECMetadata_1.parseFullClassName)(fullClassName);
263
- const schema = await this._metadataProvider.getSchema(schemaName);
264
- if (!schema) {
265
- return undefined;
266
- }
267
- const schemaClass = await schema.getClass(className);
268
- if (!schemaClass) {
269
- return undefined;
270
- }
271
- return schemaClass;
262
+ getHilitedFunctionalElementsQueryCTEs(functionalElements, bindings) {
263
+ return [
264
+ `
265
+ ChildFunctionalElements(ECInstanceId, ECClassId) AS (
266
+ SELECT ECInstanceId, ECClassId
267
+ FROM Functional.FunctionalElement
268
+ WHERE ${(0, Utils_1.formIdBindings)("ECInstanceId", functionalElements, bindings)}
269
+ UNION ALL
270
+ SELECT r.ECInstanceId, r.ECClassId
271
+ FROM ChildFunctionalElements s
272
+ JOIN Functional.FunctionalElement r ON r.Parent.Id = s.ECInstanceId
273
+ )
274
+ `,
275
+ `
276
+ PhysicalElements(ECInstanceId, ECClassId) AS (
277
+ SELECT r.SourceECInstanceId, r.SourceECClassId
278
+ FROM ChildFunctionalElements s
279
+ JOIN Functional.PhysicalElementFulfillsFunction r ON r.TargetECInstanceId = s.ECInstanceId
280
+ )
281
+ `,
282
+ `
283
+ DrawingGraphicElements(ECInstanceId, ECClassId) AS (
284
+ SELECT r.SourceECInstanceId, r.SourceECClassId
285
+ FROM ChildFunctionalElements s
286
+ JOIN Functional.DrawingGraphicRepresentsFunctionalElement r ON r.TargetECInstanceId = s.ECInstanceId
287
+ )
288
+ `,
289
+ `
290
+ PhysicalElementGeometricElements(ECInstanceId, ECClassId) AS (
291
+ SELECT ECInstanceId, ECClassId FROM PhysicalElements
292
+ UNION ALL
293
+ SELECT r.ECInstanceId, r.ECClassId
294
+ FROM PhysicalElementGeometricElements s
295
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
296
+ )
297
+ `,
298
+ `
299
+ DrawingGraphicElementGeometricElements(ECInstanceId, ECClassId) AS (
300
+ SELECT ECInstanceId, ECClassId FROM DrawingGraphicElements
301
+ UNION ALL
302
+ SELECT r.ECInstanceId, r.ECClassId
303
+ FROM DrawingGraphicElementGeometricElements s
304
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
305
+ )
306
+ `,
307
+ `
308
+ FunctionalElementChildGeometricElements(ECInstanceId, ECClassId) AS (
309
+ SELECT ECInstanceId, ECClassId FROM PhysicalElementGeometricElements
310
+ UNION
311
+ SELECT ECInstanceId, ECClassId FROM DrawingGraphicElementGeometricElements
312
+ )
313
+ `,
314
+ ];
272
315
  }
273
316
  }
274
317
  const INSTANCE_TYPES = [