@itwin/unified-selection 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +78 -0
  3. package/lib/cjs/unified-selection/CachingHiliteSetProvider.d.ts +37 -0
  4. package/lib/cjs/unified-selection/CachingHiliteSetProvider.d.ts.map +1 -0
  5. package/lib/cjs/unified-selection/CachingHiliteSetProvider.js +65 -0
  6. package/lib/cjs/unified-selection/CachingHiliteSetProvider.js.map +1 -0
  7. package/lib/cjs/unified-selection/HiliteSetProvider.d.ts +39 -0
  8. package/lib/cjs/unified-selection/HiliteSetProvider.d.ts.map +1 -0
  9. package/lib/cjs/unified-selection/HiliteSetProvider.js +298 -0
  10. package/lib/cjs/unified-selection/HiliteSetProvider.js.map +1 -0
  11. package/lib/cjs/unified-selection/SelectionChangeEvent.d.ts +6 -4
  12. package/lib/cjs/unified-selection/SelectionChangeEvent.d.ts.map +1 -1
  13. package/lib/cjs/unified-selection/SelectionChangeEvent.js +1 -1
  14. package/lib/cjs/unified-selection/SelectionChangeEvent.js.map +1 -1
  15. package/lib/cjs/unified-selection/SelectionScope.d.ts +44 -0
  16. package/lib/cjs/unified-selection/SelectionScope.d.ts.map +1 -0
  17. package/lib/cjs/unified-selection/SelectionScope.js +160 -0
  18. package/lib/cjs/unified-selection/SelectionScope.js.map +1 -0
  19. package/lib/cjs/unified-selection/SelectionStorage.d.ts +16 -3
  20. package/lib/cjs/unified-selection/SelectionStorage.d.ts.map +1 -1
  21. package/lib/cjs/unified-selection/SelectionStorage.js +14 -3
  22. package/lib/cjs/unified-selection/SelectionStorage.js.map +1 -1
  23. package/lib/cjs/unified-selection/queries/ECMetadata.d.ts +44 -0
  24. package/lib/cjs/unified-selection/queries/ECMetadata.d.ts.map +1 -0
  25. package/lib/cjs/unified-selection/queries/ECMetadata.js +17 -0
  26. package/lib/cjs/unified-selection/queries/ECMetadata.js.map +1 -0
  27. package/lib/cjs/unified-selection/queries/ECSqlCore.d.ts +69 -0
  28. package/lib/cjs/unified-selection/queries/ECSqlCore.d.ts.map +1 -0
  29. package/lib/cjs/unified-selection/queries/ECSqlCore.js +23 -0
  30. package/lib/cjs/unified-selection/queries/ECSqlCore.js.map +1 -0
  31. package/lib/cjs/unified-selection.d.ts +4 -1
  32. package/lib/cjs/unified-selection.d.ts.map +1 -1
  33. package/lib/cjs/unified-selection.js +9 -1
  34. package/lib/cjs/unified-selection.js.map +1 -1
  35. package/lib/esm/unified-selection/CachingHiliteSetProvider.d.ts +37 -0
  36. package/lib/esm/unified-selection/CachingHiliteSetProvider.d.ts.map +1 -0
  37. package/lib/esm/unified-selection/CachingHiliteSetProvider.js +61 -0
  38. package/lib/esm/unified-selection/CachingHiliteSetProvider.js.map +1 -0
  39. package/lib/esm/unified-selection/HiliteSetProvider.d.ts +39 -0
  40. package/lib/esm/unified-selection/HiliteSetProvider.d.ts.map +1 -0
  41. package/lib/esm/unified-selection/HiliteSetProvider.js +294 -0
  42. package/lib/esm/unified-selection/HiliteSetProvider.js.map +1 -0
  43. package/lib/esm/unified-selection/SelectionChangeEvent.d.ts +6 -4
  44. package/lib/esm/unified-selection/SelectionChangeEvent.d.ts.map +1 -1
  45. package/lib/esm/unified-selection/SelectionChangeEvent.js +1 -1
  46. package/lib/esm/unified-selection/SelectionChangeEvent.js.map +1 -1
  47. package/lib/esm/unified-selection/SelectionScope.d.ts +44 -0
  48. package/lib/esm/unified-selection/SelectionScope.d.ts.map +1 -0
  49. package/lib/esm/unified-selection/SelectionScope.js +156 -0
  50. package/lib/esm/unified-selection/SelectionScope.js.map +1 -0
  51. package/lib/esm/unified-selection/SelectionStorage.d.ts +16 -3
  52. package/lib/esm/unified-selection/SelectionStorage.d.ts.map +1 -1
  53. package/lib/esm/unified-selection/SelectionStorage.js +13 -2
  54. package/lib/esm/unified-selection/SelectionStorage.js.map +1 -1
  55. package/lib/esm/unified-selection/queries/ECMetadata.d.ts +44 -0
  56. package/lib/esm/unified-selection/queries/ECMetadata.d.ts.map +1 -0
  57. package/lib/esm/unified-selection/queries/ECMetadata.js +13 -0
  58. package/lib/esm/unified-selection/queries/ECMetadata.js.map +1 -0
  59. package/lib/esm/unified-selection/queries/ECSqlCore.d.ts +69 -0
  60. package/lib/esm/unified-selection/queries/ECSqlCore.d.ts.map +1 -0
  61. package/lib/esm/unified-selection/queries/ECSqlCore.js +19 -0
  62. package/lib/esm/unified-selection/queries/ECSqlCore.js.map +1 -0
  63. package/lib/esm/unified-selection.d.ts +4 -1
  64. package/lib/esm/unified-selection.d.ts.map +1 -1
  65. package/lib/esm/unified-selection.js +4 -1
  66. package/lib/esm/unified-selection.js.map +1 -1
  67. package/package.json +9 -3
@@ -0,0 +1,23 @@
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.formIdBindings = void 0;
8
+ /**
9
+ * Forms ECSql bindings from given ID's.
10
+ */
11
+ function formIdBindings(property, ids, bindings) {
12
+ if (ids.length > 1000) {
13
+ bindings.push({ type: "idset", value: ids });
14
+ return `InVirtualSet(?, ${property})`;
15
+ }
16
+ if (ids.length === 0) {
17
+ return `FALSE`;
18
+ }
19
+ ids.forEach((id) => bindings.push({ type: "id", value: id }));
20
+ return `${property} IN (${ids.map(() => "?").join(",")})`;
21
+ }
22
+ exports.formIdBindings = formIdBindings;
23
+ //# sourceMappingURL=ECSqlCore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ECSqlCore.js","sourceRoot":"","sources":["../../../../src/unified-selection/queries/ECSqlCore.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAyEhG;;GAEG;AACH,SAAgB,cAAc,CAAC,QAAgB,EAAE,GAAa,EAAE,QAAwB;IACtF,IAAI,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE;QACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7C,OAAO,mBAAmB,QAAQ,GAAG,CAAC;KACvC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE;QACpB,OAAO,OAAO,CAAC;KAChB;IAED,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9D,OAAO,GAAG,QAAQ,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAC5D,CAAC;AAZD,wCAYC","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/**\n * Types of values that can be bound to an ECSql query.\n */\nexport type ECSqlBindingType = \"boolean\" | \"double\" | \"id\" | \"idset\" | \"int\" | \"long\" | \"string\" | \"point2d\" | \"point3d\";\n\n/**\n * Defines an ECSql binding consisting of a value and its type. Necessary to differentiate between numeric\n * types and `Id64String` vs `string`.\n */\nexport type ECSqlBinding =\n | {\n type: \"boolean\";\n value?: boolean;\n }\n | {\n type: \"double\" | \"int\" | \"long\";\n value?: number;\n }\n | {\n type: \"id\";\n value?: string;\n }\n | {\n type: \"idset\";\n value?: string[];\n }\n | {\n type: \"string\";\n value?: string;\n }\n | {\n type: \"point2d\";\n value?: { x: number; y: number };\n }\n | {\n type: \"point3d\";\n value?: { x: number; y: number; z: number };\n };\n\n/**\n * Defines requested ECSQL result row format.\n */\nexport type ECSqlQueryRowFormat = \"ECSqlPropertyNames\" | \"Indexes\";\n\n/**\n * Defines options for ECSQL query reader.\n */\nexport interface ECSqlQueryReaderOptions {\n rowFormat?: ECSqlQueryRowFormat;\n}\n\n/**\n * Represents a single row of an ECSQL query result.\n */\nexport interface ECSqlQueryRow {\n [propertyName: string]: any;\n [propertyIndex: number]: any;\n}\n\n/**\n * Represents ECSQL query results reader.\n */\nexport type ECSqlQueryReader = AsyncIterableIterator<ECSqlQueryRow>;\n\n/**\n * An interface for something that knows how to create an ECSQL query reader.\n */\nexport interface IECSqlQueryExecutor {\n createQueryReader(ecsql: string, bindings?: ECSqlBinding[], config?: ECSqlQueryReaderOptions): ECSqlQueryReader;\n}\n\n/**\n * Forms ECSql bindings from given ID's.\n */\nexport function formIdBindings(property: string, ids: string[], bindings: ECSqlBinding[]): string {\n if (ids.length > 1000) {\n bindings.push({ type: \"idset\", value: ids });\n return `InVirtualSet(?, ${property})`;\n }\n\n if (ids.length === 0) {\n return `FALSE`;\n }\n\n ids.forEach((id) => bindings.push({ type: \"id\", value: id }));\n return `${property} IN (${ids.map(() => \"?\").join(\",\")})`;\n}\n"]}
@@ -5,6 +5,9 @@
5
5
  * API for working with unified selection.
6
6
  */
7
7
  export * from "./unified-selection/Selectable";
8
- export * from "./unified-selection/SelectionStorage";
8
+ export { SelectionStorage, createStorage } from "./unified-selection/SelectionStorage";
9
+ export { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from "./unified-selection/HiliteSetProvider";
10
+ export { createCachingHiliteSetProvider, CachingHiliteSetProvider } from "./unified-selection/CachingHiliteSetProvider";
11
+ export { computeSelection } from "./unified-selection/SelectionScope";
9
12
  export { StorageSelectionChangeType, StorageSelectionChangeEventArgs, StorageSelectionChangesListener, SelectionChangeEvent, } from "./unified-selection/SelectionChangeEvent";
10
13
  //# sourceMappingURL=unified-selection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"unified-selection.d.ts","sourceRoot":"","sources":["../../src/unified-selection.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sCAAsC,CAAC;AACrD,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,+BAA+B,EAC/B,oBAAoB,GACrB,MAAM,0CAA0C,CAAC"}
1
+ {"version":3,"file":"unified-selection.d.ts","sourceRoot":"","sources":["../../src/unified-selection.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,cAAc,gCAAgC,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC9G,OAAO,EAAE,8BAA8B,EAAE,wBAAwB,EAAE,MAAM,8CAA8C,CAAC;AACxH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,+BAA+B,EAC/B,oBAAoB,GACrB,MAAM,0CAA0C,CAAC"}
@@ -18,6 +18,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
18
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.computeSelection = exports.createCachingHiliteSetProvider = exports.createHiliteSetProvider = exports.createStorage = void 0;
21
22
  /**
22
23
  * @module UnifiedSelection
23
24
  *
@@ -25,5 +26,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
26
  * API for working with unified selection.
26
27
  */
27
28
  __exportStar(require("./unified-selection/Selectable"), exports);
28
- __exportStar(require("./unified-selection/SelectionStorage"), exports);
29
+ var SelectionStorage_1 = require("./unified-selection/SelectionStorage");
30
+ Object.defineProperty(exports, "createStorage", { enumerable: true, get: function () { return SelectionStorage_1.createStorage; } });
31
+ var HiliteSetProvider_1 = require("./unified-selection/HiliteSetProvider");
32
+ Object.defineProperty(exports, "createHiliteSetProvider", { enumerable: true, get: function () { return HiliteSetProvider_1.createHiliteSetProvider; } });
33
+ var CachingHiliteSetProvider_1 = require("./unified-selection/CachingHiliteSetProvider");
34
+ Object.defineProperty(exports, "createCachingHiliteSetProvider", { enumerable: true, get: function () { return CachingHiliteSetProvider_1.createCachingHiliteSetProvider; } });
35
+ var SelectionScope_1 = require("./unified-selection/SelectionScope");
36
+ Object.defineProperty(exports, "computeSelection", { enumerable: true, get: function () { return SelectionScope_1.computeSelection; } });
29
37
  //# sourceMappingURL=unified-selection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"unified-selection.js","sourceRoot":"","sources":["../../src/unified-selection.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;;;;;;;;;;;;;AAEhG;;;;;GAKG;AACH,iEAA+C;AAC/C,uEAAqD","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/**\n * @module UnifiedSelection\n *\n * @docs-group-description UnifiedSelection\n * API for working with unified selection.\n */\nexport * from \"./unified-selection/Selectable\";\nexport * from \"./unified-selection/SelectionStorage\";\nexport {\n StorageSelectionChangeType,\n StorageSelectionChangeEventArgs,\n StorageSelectionChangesListener,\n SelectionChangeEvent,\n} from \"./unified-selection/SelectionChangeEvent\";\n"]}
1
+ {"version":3,"file":"unified-selection.js","sourceRoot":"","sources":["../../src/unified-selection.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;;;;;;;;;;;;;;AAEhG;;;;;GAKG;AACH,iEAA+C;AAC/C,yEAAuF;AAA5D,iHAAA,aAAa,OAAA;AACxC,2EAA8G;AAArG,4HAAA,uBAAuB,OAAA;AAChC,yFAAwH;AAA/G,0IAAA,8BAA8B,OAAA;AACvC,qEAAsE;AAA7D,kHAAA,gBAAgB,OAAA","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/**\n * @module UnifiedSelection\n *\n * @docs-group-description UnifiedSelection\n * API for working with unified selection.\n */\nexport * from \"./unified-selection/Selectable\";\nexport { SelectionStorage, createStorage } from \"./unified-selection/SelectionStorage\";\nexport { createHiliteSetProvider, HiliteSet, HiliteSetProvider } from \"./unified-selection/HiliteSetProvider\";\nexport { createCachingHiliteSetProvider, CachingHiliteSetProvider } from \"./unified-selection/CachingHiliteSetProvider\";\nexport { computeSelection } from \"./unified-selection/SelectionScope\";\nexport {\n StorageSelectionChangeType,\n StorageSelectionChangeEventArgs,\n StorageSelectionChangesListener,\n SelectionChangeEvent,\n} from \"./unified-selection/SelectionChangeEvent\";\n"]}
@@ -0,0 +1,37 @@
1
+ import { HiliteSet } from "./HiliteSetProvider";
2
+ import { IMetadataProvider } from "./queries/ECMetadata";
3
+ import { IECSqlQueryExecutor } from "./queries/ECSqlCore";
4
+ import { SelectionStorage } from "./SelectionStorage";
5
+ /**
6
+ * Props for creating a `CachingHiliteSetProvider` instance.
7
+ * @internal Not exported through barrel, but used in public API as an argument. May be supplemented with optional attributes any time.
8
+ */
9
+ export interface CachingHiliteSetProviderProps {
10
+ selectionStorage: SelectionStorage;
11
+ iModelProvider: (iModelKey: string) => {
12
+ queryExecutor: IECSqlQueryExecutor;
13
+ metadataProvider: IMetadataProvider;
14
+ };
15
+ }
16
+ /**
17
+ * Defines return value of `createCachingHiliteSetProvider`.
18
+ *
19
+ * @beta Used in public API as a return value. Not expected to be created / extended by package
20
+ * consumers, may be supplemented with required attributes any time.
21
+ */
22
+ export interface CachingHiliteSetProvider {
23
+ /** Get the current hilite set iterator for the specified imodel */
24
+ getHiliteSet(props: {
25
+ /** iModel to get hilite set for */
26
+ iModelKey: string;
27
+ }): AsyncIterableIterator<HiliteSet>;
28
+ /** Disposes the cache. */
29
+ dispose(): void;
30
+ }
31
+ /**
32
+ * Creates a hilite set provider that caches hilite set for current selection for given iModel so any subsequent
33
+ * hilite set requests for the same iModel don't cost until selection in given selection storage changes.
34
+ * @beta
35
+ */
36
+ export declare function createCachingHiliteSetProvider(props: CachingHiliteSetProviderProps): CachingHiliteSetProvider;
37
+ //# sourceMappingURL=CachingHiliteSetProvider.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,61 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /** @packageDocumentation
6
+ * @module UnifiedSelection
7
+ */
8
+ import { from, shareReplay } from "rxjs";
9
+ import { eachValueFrom } from "rxjs-for-await";
10
+ import { createHiliteSetProvider } from "./HiliteSetProvider";
11
+ import { IMODEL_CLOSE_SELECTION_CLEAR_SOURCE } from "./SelectionStorage";
12
+ /**
13
+ * Creates a hilite set provider that caches hilite set for current selection for given iModel so any subsequent
14
+ * hilite set requests for the same iModel don't cost until selection in given selection storage changes.
15
+ * @beta
16
+ */
17
+ export function createCachingHiliteSetProvider(props) {
18
+ return new CachingHiliteSetProviderImpl(props);
19
+ }
20
+ class CachingHiliteSetProviderImpl {
21
+ _selectionStorage;
22
+ _hiliteSetProviders = new Map();
23
+ _cache = new Map();
24
+ _removeListener;
25
+ _iModelProvider;
26
+ constructor(props) {
27
+ this._selectionStorage = props.selectionStorage;
28
+ this._iModelProvider = props.iModelProvider;
29
+ this._removeListener = this._selectionStorage.selectionChangeEvent.addListener((args) => {
30
+ this._cache.delete(args.iModelKey);
31
+ if (args.changeType === "clear" && args.source === IMODEL_CLOSE_SELECTION_CLEAR_SOURCE) {
32
+ this._hiliteSetProviders.delete(args.iModelKey);
33
+ }
34
+ });
35
+ }
36
+ getHiliteSet({ iModelKey }) {
37
+ const { queryExecutor, metadataProvider } = this._iModelProvider(iModelKey);
38
+ const provider = this.getHiliteSetProvider(iModelKey, queryExecutor, metadataProvider);
39
+ let hiliteSet = this._cache.get(iModelKey);
40
+ if (!hiliteSet) {
41
+ const selectables = this._selectionStorage.getSelection({ iModelKey });
42
+ hiliteSet = from(provider.getHiliteSet({ selectables })).pipe(shareReplay({ refCount: true }));
43
+ this._cache.set(iModelKey, hiliteSet);
44
+ }
45
+ return eachValueFrom(hiliteSet);
46
+ }
47
+ dispose() {
48
+ this._removeListener();
49
+ this._hiliteSetProviders = new Map();
50
+ this._cache = new Map();
51
+ }
52
+ getHiliteSetProvider(iModelKey, queryExecutor, metadataProvider) {
53
+ let provider = this._hiliteSetProviders.get(iModelKey);
54
+ if (!provider) {
55
+ provider = createHiliteSetProvider({ queryExecutor, metadataProvider });
56
+ this._hiliteSetProviders.set(iModelKey, provider);
57
+ }
58
+ return provider;
59
+ }
60
+ }
61
+ //# sourceMappingURL=CachingHiliteSetProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CachingHiliteSetProvider.js","sourceRoot":"","sources":["../../../src/unified-selection/CachingHiliteSetProvider.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAc,WAAW,EAAE,MAAM,MAAM,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAgC,MAAM,qBAAqB,CAAC;AAI5F,OAAO,EAAE,mCAAmC,EAAoB,MAAM,oBAAoB,CAAC;AA4B3F;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAAC,KAAoC;IACjF,OAAO,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,4BAA4B;IACxB,iBAAiB,CAAmB;IACpC,mBAAmB,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC3D,MAAM,GAAG,IAAI,GAAG,EAAiC,CAAC;IAClD,eAAe,CAAa;IAC5B,eAAe,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,mCAAmC,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,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/F,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;SACvC;QAED,OAAO,aAAa,CAAC,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,uBAAuB,CAAC,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"]}
@@ -0,0 +1,39 @@
1
+ import { IMetadataProvider } from "./queries/ECMetadata";
2
+ import { IECSqlQueryExecutor } from "./queries/ECSqlCore";
3
+ import { Selectables } from "./Selectable";
4
+ /**
5
+ * A set of model, subcategory and element ids that can be used for specifying hilite.
6
+ * @see https://www.itwinjs.org/reference/core-frontend/selectionset/hiliteset/
7
+ * @beta
8
+ */
9
+ export interface HiliteSet {
10
+ models: string[];
11
+ subCategories: string[];
12
+ elements: string[];
13
+ }
14
+ /**
15
+ * Props for creating a `HiliteSetProvider` instance.
16
+ * @internal Not exported through barrel, but used in public API as an argument. May be supplemented with optional attributes any time.
17
+ */
18
+ export interface HiliteSetProviderProps {
19
+ queryExecutor: IECSqlQueryExecutor;
20
+ metadataProvider: IMetadataProvider;
21
+ }
22
+ /**
23
+ * Defines return value of `createHiliteSetProvider`.
24
+ *
25
+ * @beta Used in public API as a return value. Not expected to be created / extended by package
26
+ * consumers, may be supplemented with required attributes any time.
27
+ */
28
+ export interface HiliteSetProvider {
29
+ /** Get the current hilite set iterator for the specified imodel */
30
+ getHiliteSet(props: {
31
+ selectables: Selectables;
32
+ }): AsyncIterableIterator<HiliteSet>;
33
+ }
34
+ /**
35
+ * Creates a hilite set provider that returns a `HiliteSet` for given selectables.
36
+ * @beta
37
+ */
38
+ export declare function createHiliteSetProvider(props: HiliteSetProviderProps): HiliteSetProvider;
39
+ //# sourceMappingURL=HiliteSetProvider.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,294 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ /** @packageDocumentation
6
+ * @module UnifiedSelection
7
+ */
8
+ import { EMPTY, filter, forkJoin, from, map, merge, mergeMap, scan, shareReplay, Subject, toArray } from "rxjs";
9
+ import { eachValueFrom } from "rxjs-for-await";
10
+ import { parseFullClassName } from "./queries/ECMetadata";
11
+ import { formIdBindings } from "./queries/ECSqlCore";
12
+ const HILITE_SET_EMIT_FREQUENCY = 20;
13
+ /**
14
+ * Creates a hilite set provider that returns a `HiliteSet` for given selectables.
15
+ * @beta
16
+ */
17
+ export function createHiliteSetProvider(props) {
18
+ return new HiliteSetProviderImpl(props);
19
+ }
20
+ class HiliteSetProviderImpl {
21
+ _queryExecutor;
22
+ _metadataProvider;
23
+ // Map between a class name and its type
24
+ _classRelationCache;
25
+ constructor(props) {
26
+ this._queryExecutor = props.queryExecutor;
27
+ this._metadataProvider = props.metadataProvider;
28
+ this._classRelationCache = new Map();
29
+ }
30
+ /**
31
+ * Get hilite set iterator for supplied `Selectables`.
32
+ */
33
+ getHiliteSet(props) {
34
+ const obs = this.getHiliteSetObservable(props);
35
+ return eachValueFrom(obs);
36
+ }
37
+ /**
38
+ * Returns a "hot" observable of hilite sets.
39
+ */
40
+ getHiliteSetObservable({ selectables }) {
41
+ const instancesByType = this.getInstancesByType(selectables);
42
+ const observables = {
43
+ models: this.getHilitedModels(instancesByType),
44
+ subCategories: this.getHilitedSubCategories(instancesByType),
45
+ elements: this.getHilitedElements(instancesByType),
46
+ };
47
+ let hiliteSet = { models: [], subCategories: [], elements: [] };
48
+ let lastEmitTime = performance.now();
49
+ const subject = new Subject();
50
+ const subscriptions = ["models", "subCategories", "elements"].map((key) => observables[key].subscribe({
51
+ next(val) {
52
+ hiliteSet[key].push(val);
53
+ if (performance.now() - lastEmitTime < HILITE_SET_EMIT_FREQUENCY) {
54
+ return;
55
+ }
56
+ subject.next(hiliteSet);
57
+ hiliteSet = { models: [], subCategories: [], elements: [] };
58
+ lastEmitTime = performance.now();
59
+ },
60
+ complete() {
61
+ observables[key] = undefined;
62
+ if (observables.models || observables.subCategories || observables.elements) {
63
+ return;
64
+ }
65
+ // Emit last batch before completing the observable.
66
+ if (hiliteSet.elements.length || hiliteSet.models.length || hiliteSet.subCategories.length) {
67
+ subject.next(hiliteSet);
68
+ }
69
+ subject.complete();
70
+ },
71
+ error(err) {
72
+ subscriptions.forEach((x) => x.unsubscribe());
73
+ subscriptions.length = 0;
74
+ subject.error(err);
75
+ },
76
+ }));
77
+ return subject;
78
+ }
79
+ async getType(key) {
80
+ const cachedType = this._classRelationCache.get(key.className.replace(".", ":"));
81
+ if (cachedType) {
82
+ return cachedType;
83
+ }
84
+ const promise = this.getTypeImpl(key).then((res) => {
85
+ // Update the cache with the result of the promise.
86
+ this._classRelationCache.set(key.className, res);
87
+ return res;
88
+ });
89
+ // Add the promise to cache to prevent `getTypeImpl` being called multiple times.
90
+ this._classRelationCache.set(key.className, promise);
91
+ return promise;
92
+ }
93
+ async getTypeImpl(key) {
94
+ const keyClass = await this.getClass(key.className);
95
+ return ((keyClass &&
96
+ ((await this.checkType(keyClass, "BisCore", "Subject", "subject")) ??
97
+ (await this.checkType(keyClass, "BisCore", "Model", "model")) ??
98
+ (await this.checkType(keyClass, "BisCore", "Category", "category")) ??
99
+ (await this.checkType(keyClass, "BisCore", "SubCategory", "subCategory")) ??
100
+ (await this.checkType(keyClass, "Functional", "FunctionalElement", "functionalElement")) ??
101
+ (await this.checkType(keyClass, "BisCore", "GroupInformationElement", "groupInformationElement")) ??
102
+ (await this.checkType(keyClass, "BisCore", "GeometricElement", "geometricElement")) ??
103
+ (await this.checkType(keyClass, "BisCore", "Element", "element")))) ??
104
+ "unknown");
105
+ }
106
+ async checkType(keyClass, schemaName, className, type) {
107
+ return (await keyClass.is(className, schemaName)) ? type : undefined;
108
+ }
109
+ getInstancesByType(selectables) {
110
+ const keyTypeObs = merge(from(selectables.custom.values()).pipe(mergeMap((selectable) => selectable.loadInstanceKeys())), from(selectables.instanceKeys).pipe(mergeMap(([className, idSet]) => from(idSet).pipe(map((id) => ({ className, id })))))).pipe(
111
+ // Get types for each instance key
112
+ mergeMap((instanceKey) => from(this.getType(instanceKey)).pipe(map((instanceIdType) => ({ instanceId: instanceKey.id, instanceIdType })))),
113
+ // Cache the results
114
+ shareReplay());
115
+ return Object.fromEntries(INSTANCE_TYPES.map((type) => [
116
+ type,
117
+ keyTypeObs.pipe(filter(({ instanceIdType }) => instanceIdType === type), map(({ instanceId }) => instanceId), unique()),
118
+ ]));
119
+ }
120
+ getHilitedModels(instancesByType) {
121
+ return forkJoin({
122
+ modelKeys: instancesByType.model.pipe(toArray()),
123
+ subjectKeys: instancesByType.subject.pipe(toArray()),
124
+ }).pipe(mergeMap(({ modelKeys, subjectKeys }) => {
125
+ if (!modelKeys.length && !subjectKeys.length) {
126
+ return EMPTY;
127
+ }
128
+ const bindings = [];
129
+ const query = `WITH RECURSIVE
130
+ ChildSubjects (ECInstanceId, JsonProperties) AS (
131
+ SELECT ECInstanceId, JsonProperties FROM BisCore.Subject WHERE ${formIdBindings("ECInstanceId", subjectKeys, bindings)}
132
+ UNION ALL
133
+ SELECT r.ECInstanceId, r.JsonProperties FROM ChildSubjects s
134
+ JOIN BisCore.Subject r ON r.Parent.Id = s.ECInstanceId
135
+ ),
136
+ Models (ECInstanceId) AS (
137
+ SELECT s.ECInstanceId as \`ECInstanceId\` FROM BisCore.Model s
138
+ WHERE ${formIdBindings("ECInstanceId", modelKeys, bindings)}
139
+ )
140
+ SELECT r.ECInstanceId as \`ECInstanceId\` FROM ChildSubjects s
141
+ JOIN BisCore.PhysicalPartition r
142
+ ON r.Parent.Id = s.ECInstanceId
143
+ OR json_extract(s.JsonProperties,'$.Subject.Model.TargetPartition') = printf('0x%x', r.ECInstanceId)
144
+ UNION
145
+ SELECT ECInstanceId FROM Models;`;
146
+ return from(this._queryExecutor.createQueryReader(query, bindings));
147
+ }), map((row) => row.ECInstanceId));
148
+ }
149
+ getHilitedSubCategories(instancesByType) {
150
+ return forkJoin({
151
+ subCategoryKeys: instancesByType.subCategory.pipe(toArray()),
152
+ categoryKeys: instancesByType.category.pipe(toArray()),
153
+ }).pipe(mergeMap(({ subCategoryKeys, categoryKeys }) => {
154
+ if (!subCategoryKeys.length && !categoryKeys.length) {
155
+ return EMPTY;
156
+ }
157
+ const bindings = [];
158
+ const query = `WITH
159
+ CategorySubCategories (ECInstanceId) AS (
160
+ SELECT r.ECInstanceId as \`ECInstanceId\` FROM BisCore.Category s
161
+ JOIN BisCore.SubCategory r ON r.Parent.Id = s.ECInstanceId
162
+ WHERE ${formIdBindings("s.ECInstanceId", categoryKeys, bindings)}
163
+ ),
164
+ SubCategories (ECInstanceId) AS (
165
+ SELECT s.ECInstanceId as \`ECInstanceId\` FROM BisCore.SubCategory s
166
+ WHERE ${formIdBindings("s.ECInstanceId", subCategoryKeys, bindings)}
167
+ )
168
+ SELECT ECInstanceId FROM CategorySubCategories
169
+ UNION
170
+ SELECT ECInstanceId FROM SubCategories;`;
171
+ return from(this._queryExecutor.createQueryReader(query, bindings));
172
+ }), map((row) => row.ECInstanceId));
173
+ }
174
+ getHilitedElements(instancesByType) {
175
+ return forkJoin({
176
+ groupInformationElementKeys: instancesByType.groupInformationElement.pipe(toArray()),
177
+ geometricElementKeys: instancesByType.geometricElement.pipe(toArray()),
178
+ functionalElements: instancesByType.functionalElement.pipe(toArray()),
179
+ elementKeys: instancesByType.element.pipe(toArray()),
180
+ }).pipe(mergeMap(({ groupInformationElementKeys, geometricElementKeys, functionalElements, elementKeys }) => {
181
+ const hasFunctionalElements = !!functionalElements.length;
182
+ if (!groupInformationElementKeys.length && !geometricElementKeys.length && !elementKeys.length && !hasFunctionalElements) {
183
+ return EMPTY;
184
+ }
185
+ const bindings = [];
186
+ const query = `WITH RECURSIVE
187
+ ${hasFunctionalElements ? this.getHilitedFunctionalElementsQuery(functionalElements, bindings) : ""}
188
+ GroupMembers (ECInstanceId, ECClassId) AS (
189
+ SELECT TargetECInstanceId, TargetECClassId FROM BisCore.ElementGroupsMembers
190
+ WHERE ${formIdBindings("SourceECInstanceId", groupInformationElementKeys, bindings)}
191
+ ),
192
+ GroupGeometricElements (ECInstanceId, ECClassId) AS (
193
+ SELECT ECInstanceId, ECClassId FROM GroupMembers
194
+ UNION ALL
195
+ SELECT r.ECInstanceId, r.ECClassId FROM GroupGeometricElements s
196
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
197
+ ),
198
+ ElementGeometricElements (ECInstanceId, ECClassId) AS (
199
+ SELECT ECInstanceId, ECClassId FROM BisCore.Element WHERE ${formIdBindings("ECInstanceId", elementKeys, bindings)}
200
+ UNION ALL
201
+ SELECT r.ECInstanceId, r.ECClassId FROM ElementGeometricElements s
202
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
203
+ ),
204
+ GeometricElementGeometricElements (ECInstanceId, ECClassId) AS (
205
+ SELECT ECInstanceId, ECClassId FROM BisCore.GeometricElement WHERE ${formIdBindings("ECInstanceId", geometricElementKeys, bindings)}
206
+ UNION ALL
207
+ SELECT r.ECInstanceId, r.ECClassId FROM GeometricElementGeometricElements s
208
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
209
+ )
210
+ ${hasFunctionalElements
211
+ ? `
212
+ SELECT ECInstanceId FROM FunctionalElementChildGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)
213
+ UNION
214
+ `
215
+ : ``}
216
+ SELECT ECInstanceId FROM GeometricElementGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)
217
+ UNION
218
+ SELECT ECInstanceId FROM GroupGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)
219
+ UNION
220
+ SELECT ECInstanceId FROM ElementGeometricElements WHERE ECClassId IS (BisCore.GeometricElement);`;
221
+ return from(this._queryExecutor.createQueryReader(query, bindings));
222
+ }), map((row) => row.ECInstanceId));
223
+ }
224
+ getHilitedFunctionalElementsQuery(functionalElements, bindings) {
225
+ return `ChildFunctionalElements (ECInstanceId, ECClassId) AS (
226
+ SELECT ECInstanceId, ECClassId FROM Functional.FunctionalElement WHERE ${formIdBindings("ECInstanceId", functionalElements, bindings)}
227
+ UNION ALL
228
+ SELECT r.ECInstanceId, r.ECClassId FROM ChildFunctionalElements s
229
+ JOIN Functional.FunctionalElement r ON r.Parent.Id = s.ECInstanceId
230
+ ),
231
+ PhysicalElements (ECInstanceId, ECClassId) AS (
232
+ SELECT r.SourceECInstanceId, r.SourceECClassId FROM ChildFunctionalElements s
233
+ JOIN Functional.PhysicalElementFulfillsFunction r ON r.TargetECInstanceId = s.ECInstanceId
234
+ ),
235
+ DrawingGraphicElements (ECInstanceId, ECClassId) AS (
236
+ SELECT r.SourceECInstanceId, r.SourceECClassId FROM ChildFunctionalElements s
237
+ JOIN Functional.DrawingGraphicRepresentsFunctionalElement r ON r.TargetECInstanceId = s.ECInstanceId
238
+ ),
239
+ PhysicalElementGeometricElements (ECInstanceId, ECClassId) AS (
240
+ SELECT ECInstanceId, ECClassId FROM PhysicalElements
241
+ UNION ALL
242
+ SELECT r.ECInstanceId, r.ECClassId FROM PhysicalElementGeometricElements s
243
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
244
+ ),
245
+ DrawingGraphicElementGeometricElements (ECInstanceId, ECClassId) AS (
246
+ SELECT ECInstanceId, ECClassId FROM DrawingGraphicElements
247
+ UNION ALL
248
+ SELECT r.ECInstanceId, r.ECClassId FROM DrawingGraphicElementGeometricElements s
249
+ JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId
250
+ ),
251
+ FunctionalElementChildGeometricElements (ECInstanceId, ECClassId) AS (
252
+ SELECT ECInstanceId, ECClassId FROM PhysicalElementGeometricElements
253
+ UNION
254
+ SELECT ECInstanceId, ECClassId FROM DrawingGraphicElementGeometricElements
255
+ ),`;
256
+ }
257
+ async getClass(fullClassName) {
258
+ const { schemaName, className } = parseFullClassName(fullClassName);
259
+ const schema = await this._metadataProvider.getSchema(schemaName);
260
+ if (!schema) {
261
+ return undefined;
262
+ }
263
+ const schemaClass = await schema.getClass(className);
264
+ if (!schemaClass) {
265
+ return undefined;
266
+ }
267
+ return schemaClass;
268
+ }
269
+ }
270
+ const INSTANCE_TYPES = [
271
+ "subject",
272
+ "model",
273
+ "category",
274
+ "subCategory",
275
+ "functionalElement",
276
+ "groupInformationElement",
277
+ "geometricElement",
278
+ "element",
279
+ "unknown",
280
+ ];
281
+ function unique() {
282
+ return function (obs) {
283
+ return obs.pipe(scan((acc, val) => {
284
+ if (acc.set.has(val)) {
285
+ delete acc.val;
286
+ return acc;
287
+ }
288
+ acc.set.add(val);
289
+ acc.val = val;
290
+ return acc;
291
+ }, { set: new Set() }), map(({ val }) => val), filter((x) => !!x));
292
+ };
293
+ }
294
+ //# sourceMappingURL=HiliteSetProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HiliteSetProvider.js","sourceRoot":"","sources":["../../../src/unified-selection/HiliteSetProvider.ts"],"names":[],"mappings":"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","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 { EMPTY, filter, forkJoin, from, map, merge, mergeMap, Observable, scan, shareReplay, Subject, toArray } from \"rxjs\";\nimport { eachValueFrom } from \"rxjs-for-await\";\nimport { ECClass, IMetadataProvider, parseFullClassName } from \"./queries/ECMetadata\";\nimport { ECSqlBinding, formIdBindings, IECSqlQueryExecutor } from \"./queries/ECSqlCore\";\nimport { SelectableInstanceKey, Selectables } from \"./Selectable\";\n\nconst HILITE_SET_EMIT_FREQUENCY = 20;\n\n/**\n * A set of model, subcategory and element ids that can be used for specifying hilite.\n * @see https://www.itwinjs.org/reference/core-frontend/selectionset/hiliteset/\n * @beta\n */\nexport interface HiliteSet {\n models: string[];\n subCategories: string[];\n elements: string[];\n}\n\n/**\n * Props for creating a `HiliteSetProvider` 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 HiliteSetProviderProps {\n queryExecutor: IECSqlQueryExecutor;\n metadataProvider: IMetadataProvider;\n}\n\n/**\n * Defines return value of `createHiliteSetProvider`.\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 HiliteSetProvider {\n /** Get the current hilite set iterator for the specified imodel */\n getHiliteSet(props: { selectables: Selectables }): AsyncIterableIterator<HiliteSet>;\n}\n\n/**\n * Creates a hilite set provider that returns a `HiliteSet` for given selectables.\n * @beta\n */\nexport function createHiliteSetProvider(props: HiliteSetProviderProps): HiliteSetProvider {\n return new HiliteSetProviderImpl(props);\n}\n\nclass HiliteSetProviderImpl implements HiliteSetProvider {\n private _queryExecutor: IECSqlQueryExecutor;\n private _metadataProvider: IMetadataProvider;\n // Map between a class name and its type\n private _classRelationCache: Map<string, InstanceIdType | Promise<InstanceIdType>>;\n\n constructor(props: HiliteSetProviderProps) {\n this._queryExecutor = props.queryExecutor;\n this._metadataProvider = props.metadataProvider;\n this._classRelationCache = new Map();\n }\n\n /**\n * Get hilite set iterator for supplied `Selectables`.\n */\n public getHiliteSet(props: { selectables: Selectables }): AsyncIterableIterator<HiliteSet> {\n const obs = this.getHiliteSetObservable(props);\n return eachValueFrom(obs);\n }\n\n /**\n * Returns a \"hot\" observable of hilite sets.\n */\n private getHiliteSetObservable({ selectables }: { selectables: Selectables }): Subject<HiliteSet> {\n const instancesByType = this.getInstancesByType(selectables);\n const observables: { [key in keyof HiliteSet]?: Observable<string> } = {\n models: this.getHilitedModels(instancesByType),\n subCategories: this.getHilitedSubCategories(instancesByType),\n elements: this.getHilitedElements(instancesByType),\n };\n\n let hiliteSet: HiliteSet = { models: [], subCategories: [], elements: [] };\n let lastEmitTime = performance.now();\n const subject = new Subject<HiliteSet>();\n const subscriptions = ([\"models\", \"subCategories\", \"elements\"] as const).map((key) =>\n observables[key]!.subscribe({\n next(val) {\n hiliteSet[key].push(val);\n if (performance.now() - lastEmitTime < HILITE_SET_EMIT_FREQUENCY) {\n return;\n }\n subject.next(hiliteSet);\n hiliteSet = { models: [], subCategories: [], elements: [] };\n lastEmitTime = performance.now();\n },\n complete() {\n observables[key] = undefined;\n if (observables.models || observables.subCategories || observables.elements) {\n return;\n }\n // Emit last batch before completing the observable.\n if (hiliteSet.elements.length || hiliteSet.models.length || hiliteSet.subCategories.length) {\n subject.next(hiliteSet);\n }\n subject.complete();\n },\n error(err) {\n subscriptions.forEach((x) => x.unsubscribe());\n subscriptions.length = 0;\n subject.error(err);\n },\n }),\n );\n\n return subject;\n }\n\n private async getType(key: SelectableInstanceKey): Promise<InstanceIdType> {\n const cachedType = this._classRelationCache.get(key.className.replace(\".\", \":\"));\n if (cachedType) {\n return cachedType;\n }\n\n const promise = this.getTypeImpl(key).then((res) => {\n // Update the cache with the result of the promise.\n this._classRelationCache.set(key.className, res);\n return res;\n });\n\n // Add the promise to cache to prevent `getTypeImpl` being called multiple times.\n this._classRelationCache.set(key.className, promise);\n return promise;\n }\n\n private async getTypeImpl(key: SelectableInstanceKey): Promise<InstanceIdType> {\n const keyClass = await this.getClass(key.className);\n return (\n (keyClass &&\n ((await this.checkType(keyClass, \"BisCore\", \"Subject\", \"subject\")) ??\n (await this.checkType(keyClass, \"BisCore\", \"Model\", \"model\")) ??\n (await this.checkType(keyClass, \"BisCore\", \"Category\", \"category\")) ??\n (await this.checkType(keyClass, \"BisCore\", \"SubCategory\", \"subCategory\")) ??\n (await this.checkType(keyClass, \"Functional\", \"FunctionalElement\", \"functionalElement\")) ??\n (await this.checkType(keyClass, \"BisCore\", \"GroupInformationElement\", \"groupInformationElement\")) ??\n (await this.checkType(keyClass, \"BisCore\", \"GeometricElement\", \"geometricElement\")) ??\n (await this.checkType(keyClass, \"BisCore\", \"Element\", \"element\")))) ??\n \"unknown\"\n );\n }\n\n private async checkType(keyClass: ECClass, schemaName: string, className: string, type: InstanceIdType) {\n return (await keyClass.is(className, schemaName)) ? type : undefined;\n }\n\n private getInstancesByType(selectables: Selectables): InstancesByType {\n const keyTypeObs = merge(\n from(selectables.custom.values()).pipe(mergeMap((selectable) => selectable.loadInstanceKeys())),\n from(selectables.instanceKeys).pipe(mergeMap(([className, idSet]) => from(idSet).pipe(map((id) => ({ className, id }))))),\n ).pipe(\n // Get types for each instance key\n mergeMap((instanceKey) => from(this.getType(instanceKey)).pipe(map((instanceIdType) => ({ instanceId: instanceKey.id, instanceIdType })))),\n // Cache the results\n shareReplay(),\n );\n\n return Object.fromEntries(\n INSTANCE_TYPES.map((type) => [\n type,\n keyTypeObs.pipe(\n filter(({ instanceIdType }) => instanceIdType === type),\n map(({ instanceId }) => instanceId),\n unique(),\n ),\n ]),\n ) as InstancesByType;\n }\n\n private getHilitedModels(instancesByType: InstancesByType): Observable<string> {\n return forkJoin({\n modelKeys: instancesByType.model.pipe(toArray()),\n subjectKeys: instancesByType.subject.pipe(toArray()),\n }).pipe(\n mergeMap(({ modelKeys, subjectKeys }) => {\n if (!modelKeys.length && !subjectKeys.length) {\n return EMPTY;\n }\n\n const bindings: ECSqlBinding[] = [];\n const query = `WITH RECURSIVE\n ChildSubjects (ECInstanceId, JsonProperties) AS (\n SELECT ECInstanceId, JsonProperties FROM BisCore.Subject WHERE ${formIdBindings(\"ECInstanceId\", subjectKeys, bindings)}\n UNION ALL\n SELECT r.ECInstanceId, r.JsonProperties FROM ChildSubjects s\n JOIN BisCore.Subject r ON r.Parent.Id = s.ECInstanceId\n ),\n Models (ECInstanceId) AS (\n SELECT s.ECInstanceId as \\`ECInstanceId\\` FROM BisCore.Model s\n WHERE ${formIdBindings(\"ECInstanceId\", modelKeys, bindings)}\n )\n SELECT r.ECInstanceId as \\`ECInstanceId\\` FROM ChildSubjects s\n JOIN BisCore.PhysicalPartition r\n ON r.Parent.Id = s.ECInstanceId\n OR json_extract(s.JsonProperties,'$.Subject.Model.TargetPartition') = printf('0x%x', r.ECInstanceId)\n UNION\n SELECT ECInstanceId FROM Models;`;\n return from(this._queryExecutor.createQueryReader(query, bindings));\n }),\n map((row) => row.ECInstanceId),\n );\n }\n\n private getHilitedSubCategories(instancesByType: InstancesByType): Observable<string> {\n return forkJoin({\n subCategoryKeys: instancesByType.subCategory.pipe(toArray()),\n categoryKeys: instancesByType.category.pipe(toArray()),\n }).pipe(\n mergeMap(({ subCategoryKeys, categoryKeys }) => {\n if (!subCategoryKeys.length && !categoryKeys.length) {\n return EMPTY;\n }\n\n const bindings: ECSqlBinding[] = [];\n const query = `WITH\n CategorySubCategories (ECInstanceId) AS (\n SELECT r.ECInstanceId as \\`ECInstanceId\\` FROM BisCore.Category s\n JOIN BisCore.SubCategory r ON r.Parent.Id = s.ECInstanceId\n WHERE ${formIdBindings(\"s.ECInstanceId\", categoryKeys, bindings)}\n ),\n SubCategories (ECInstanceId) AS (\n SELECT s.ECInstanceId as \\`ECInstanceId\\` FROM BisCore.SubCategory s\n WHERE ${formIdBindings(\"s.ECInstanceId\", subCategoryKeys, bindings)}\n )\n SELECT ECInstanceId FROM CategorySubCategories\n UNION\n SELECT ECInstanceId FROM SubCategories;`;\n return from(this._queryExecutor.createQueryReader(query, bindings));\n }),\n map((row) => row.ECInstanceId),\n );\n }\n\n private getHilitedElements(instancesByType: InstancesByType): Observable<string> {\n return forkJoin({\n groupInformationElementKeys: instancesByType.groupInformationElement.pipe(toArray()),\n geometricElementKeys: instancesByType.geometricElement.pipe(toArray()),\n functionalElements: instancesByType.functionalElement.pipe(toArray()),\n elementKeys: instancesByType.element.pipe(toArray()),\n }).pipe(\n mergeMap(({ groupInformationElementKeys, geometricElementKeys, functionalElements, elementKeys }) => {\n const hasFunctionalElements = !!functionalElements.length;\n if (!groupInformationElementKeys.length && !geometricElementKeys.length && !elementKeys.length && !hasFunctionalElements) {\n return EMPTY;\n }\n\n const bindings: ECSqlBinding[] = [];\n const query = `WITH RECURSIVE\n ${hasFunctionalElements ? this.getHilitedFunctionalElementsQuery(functionalElements, bindings) : \"\"}\n GroupMembers (ECInstanceId, ECClassId) AS (\n SELECT TargetECInstanceId, TargetECClassId FROM BisCore.ElementGroupsMembers\n WHERE ${formIdBindings(\"SourceECInstanceId\", groupInformationElementKeys, bindings)}\n ),\n GroupGeometricElements (ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM GroupMembers\n UNION ALL\n SELECT r.ECInstanceId, r.ECClassId FROM GroupGeometricElements s\n JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId\n ),\n ElementGeometricElements (ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM BisCore.Element WHERE ${formIdBindings(\"ECInstanceId\", elementKeys, bindings)}\n UNION ALL\n SELECT r.ECInstanceId, r.ECClassId FROM ElementGeometricElements s\n JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId\n ),\n GeometricElementGeometricElements (ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM BisCore.GeometricElement WHERE ${formIdBindings(\"ECInstanceId\", geometricElementKeys, bindings)}\n UNION ALL\n SELECT r.ECInstanceId, r.ECClassId FROM GeometricElementGeometricElements s\n JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId\n )\n ${\n hasFunctionalElements\n ? `\n SELECT ECInstanceId FROM FunctionalElementChildGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)\n UNION\n `\n : ``\n }\n SELECT ECInstanceId FROM GeometricElementGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)\n UNION\n SELECT ECInstanceId FROM GroupGeometricElements WHERE ECClassId IS (BisCore.GeometricElement)\n UNION\n SELECT ECInstanceId FROM ElementGeometricElements WHERE ECClassId IS (BisCore.GeometricElement);`;\n return from(this._queryExecutor.createQueryReader(query, bindings));\n }),\n map((row) => row.ECInstanceId as string),\n );\n }\n\n private getHilitedFunctionalElementsQuery(functionalElements: string[], bindings: ECSqlBinding[]): string {\n return `ChildFunctionalElements (ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM Functional.FunctionalElement WHERE ${formIdBindings(\"ECInstanceId\", functionalElements, bindings)}\n UNION ALL\n SELECT r.ECInstanceId, r.ECClassId FROM ChildFunctionalElements s\n JOIN Functional.FunctionalElement r ON r.Parent.Id = s.ECInstanceId\n ),\n PhysicalElements (ECInstanceId, ECClassId) AS (\n SELECT r.SourceECInstanceId, r.SourceECClassId FROM ChildFunctionalElements s\n JOIN Functional.PhysicalElementFulfillsFunction r ON r.TargetECInstanceId = s.ECInstanceId\n ),\n DrawingGraphicElements (ECInstanceId, ECClassId) AS (\n SELECT r.SourceECInstanceId, r.SourceECClassId FROM ChildFunctionalElements s\n JOIN Functional.DrawingGraphicRepresentsFunctionalElement r ON r.TargetECInstanceId = s.ECInstanceId\n ),\n PhysicalElementGeometricElements (ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM PhysicalElements\n UNION ALL\n SELECT r.ECInstanceId, r.ECClassId FROM PhysicalElementGeometricElements s\n JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId\n ),\n DrawingGraphicElementGeometricElements (ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM DrawingGraphicElements\n UNION ALL\n SELECT r.ECInstanceId, r.ECClassId FROM DrawingGraphicElementGeometricElements s\n JOIN BisCore.Element r ON r.Parent.Id = s.ECInstanceId\n ),\n FunctionalElementChildGeometricElements (ECInstanceId, ECClassId) AS (\n SELECT ECInstanceId, ECClassId FROM PhysicalElementGeometricElements\n UNION\n SELECT ECInstanceId, ECClassId FROM DrawingGraphicElementGeometricElements\n ),`;\n }\n\n private async getClass(fullClassName: string): Promise<ECClass | undefined> {\n const { schemaName, className } = parseFullClassName(fullClassName);\n const schema = await this._metadataProvider.getSchema(schemaName);\n if (!schema) {\n return undefined;\n }\n const schemaClass = await schema.getClass(className);\n if (!schemaClass) {\n return undefined;\n }\n return schemaClass;\n }\n}\n\nconst INSTANCE_TYPES = [\n \"subject\",\n \"model\",\n \"category\",\n \"subCategory\",\n \"functionalElement\",\n \"groupInformationElement\",\n \"geometricElement\",\n \"element\",\n \"unknown\",\n] as const;\n\ntype InstanceIdType = (typeof INSTANCE_TYPES)[number];\n\ntype InstancesByType = {\n [idType in InstanceIdType]: Observable<string>;\n};\n\nfunction unique<T>() {\n return function (obs: Observable<T>): Observable<T> {\n return obs.pipe(\n scan(\n (acc, val) => {\n if (acc.set.has(val)) {\n delete acc.val;\n return acc;\n }\n\n acc.set.add(val);\n acc.val = val;\n return acc;\n },\n { set: new Set<T>() } as { set: Set<T>; val?: T },\n ),\n map(({ val }) => val),\n filter((x): x is T => !!x),\n );\n };\n}\n"]}