@itwin/presentation-frontend 4.0.0-dev.8 → 4.0.0-dev.81

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 (122) hide show
  1. package/CHANGELOG.md +45 -1
  2. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.d.ts +29 -29
  3. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js +47 -47
  4. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
  5. package/lib/cjs/presentation-frontend/Diagnostics.d.ts +14 -14
  6. package/lib/cjs/presentation-frontend/Diagnostics.js +61 -61
  7. package/lib/cjs/presentation-frontend/FrontendLoggerCategory.d.ts +12 -12
  8. package/lib/cjs/presentation-frontend/FrontendLoggerCategory.js +20 -20
  9. package/lib/cjs/presentation-frontend/IpcRequestsHandler.d.ts +9 -10
  10. package/lib/cjs/presentation-frontend/IpcRequestsHandler.d.ts.map +1 -1
  11. package/lib/cjs/presentation-frontend/IpcRequestsHandler.js +32 -41
  12. package/lib/cjs/presentation-frontend/IpcRequestsHandler.js.map +1 -1
  13. package/lib/cjs/presentation-frontend/LocalizationHelper.d.ts +10 -10
  14. package/lib/cjs/presentation-frontend/LocalizationHelper.js +31 -31
  15. package/lib/cjs/presentation-frontend/LocalizationHelper.js.map +1 -1
  16. package/lib/cjs/presentation-frontend/Presentation.d.ts +73 -75
  17. package/lib/cjs/presentation-frontend/Presentation.d.ts.map +1 -1
  18. package/lib/cjs/presentation-frontend/Presentation.js +159 -162
  19. package/lib/cjs/presentation-frontend/Presentation.js.map +1 -1
  20. package/lib/cjs/presentation-frontend/PresentationManager.d.ts +207 -186
  21. package/lib/cjs/presentation-frontend/PresentationManager.d.ts.map +1 -1
  22. package/lib/cjs/presentation-frontend/PresentationManager.js +442 -436
  23. package/lib/cjs/presentation-frontend/PresentationManager.js.map +1 -1
  24. package/lib/cjs/presentation-frontend/RulesetManager.d.ts +63 -63
  25. package/lib/cjs/presentation-frontend/RulesetManager.js +85 -85
  26. package/lib/cjs/presentation-frontend/RulesetVariablesManager.d.ts +143 -143
  27. package/lib/cjs/presentation-frontend/RulesetVariablesManager.js +195 -195
  28. package/lib/cjs/presentation-frontend/RulesetVariablesManager.js.map +1 -1
  29. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts +132 -132
  30. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
  31. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +520 -518
  32. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
  33. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts +111 -111
  34. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +290 -293
  35. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
  36. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.d.ts +52 -52
  37. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.js +97 -97
  38. package/lib/cjs/presentation-frontend/selection/ISelectionProvider.d.ts +19 -19
  39. package/lib/cjs/presentation-frontend/selection/ISelectionProvider.js +9 -9
  40. package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.d.ts +52 -52
  41. package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.js +33 -33
  42. package/lib/cjs/presentation-frontend/selection/SelectionHandler.d.ts +103 -103
  43. package/lib/cjs/presentation-frontend/selection/SelectionHandler.js +108 -108
  44. package/lib/cjs/presentation-frontend/selection/SelectionHelper.d.ts +17 -14
  45. package/lib/cjs/presentation-frontend/selection/SelectionHelper.d.ts.map +1 -1
  46. package/lib/cjs/presentation-frontend/selection/SelectionHelper.js +40 -37
  47. package/lib/cjs/presentation-frontend/selection/SelectionHelper.js.map +1 -1
  48. package/lib/cjs/presentation-frontend/selection/SelectionManager.d.ts +139 -139
  49. package/lib/cjs/presentation-frontend/selection/SelectionManager.js +414 -414
  50. package/lib/cjs/presentation-frontend/selection/SelectionManager.js.map +1 -1
  51. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.d.ts +59 -59
  52. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js +91 -91
  53. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
  54. package/lib/cjs/presentation-frontend.d.ts +33 -34
  55. package/lib/cjs/presentation-frontend.d.ts.map +1 -1
  56. package/lib/cjs/presentation-frontend.js +53 -50
  57. package/lib/cjs/presentation-frontend.js.map +1 -1
  58. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.d.ts +29 -29
  59. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js +43 -43
  60. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
  61. package/lib/esm/presentation-frontend/Diagnostics.d.ts +14 -14
  62. package/lib/esm/presentation-frontend/Diagnostics.js +56 -56
  63. package/lib/esm/presentation-frontend/FrontendLoggerCategory.d.ts +12 -12
  64. package/lib/esm/presentation-frontend/FrontendLoggerCategory.js +17 -17
  65. package/lib/esm/presentation-frontend/IpcRequestsHandler.d.ts +9 -10
  66. package/lib/esm/presentation-frontend/IpcRequestsHandler.d.ts.map +1 -1
  67. package/lib/esm/presentation-frontend/IpcRequestsHandler.js +28 -37
  68. package/lib/esm/presentation-frontend/IpcRequestsHandler.js.map +1 -1
  69. package/lib/esm/presentation-frontend/LocalizationHelper.d.ts +10 -10
  70. package/lib/esm/presentation-frontend/LocalizationHelper.js +27 -27
  71. package/lib/esm/presentation-frontend/LocalizationHelper.js.map +1 -1
  72. package/lib/esm/presentation-frontend/Presentation.d.ts +73 -75
  73. package/lib/esm/presentation-frontend/Presentation.d.ts.map +1 -1
  74. package/lib/esm/presentation-frontend/Presentation.js +155 -158
  75. package/lib/esm/presentation-frontend/Presentation.js.map +1 -1
  76. package/lib/esm/presentation-frontend/PresentationManager.d.ts +207 -186
  77. package/lib/esm/presentation-frontend/PresentationManager.d.ts.map +1 -1
  78. package/lib/esm/presentation-frontend/PresentationManager.js +437 -431
  79. package/lib/esm/presentation-frontend/PresentationManager.js.map +1 -1
  80. package/lib/esm/presentation-frontend/RulesetManager.d.ts +63 -63
  81. package/lib/esm/presentation-frontend/RulesetManager.js +81 -81
  82. package/lib/esm/presentation-frontend/RulesetVariablesManager.d.ts +143 -143
  83. package/lib/esm/presentation-frontend/RulesetVariablesManager.js +191 -191
  84. package/lib/esm/presentation-frontend/RulesetVariablesManager.js.map +1 -1
  85. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts +132 -132
  86. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
  87. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +515 -512
  88. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
  89. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts +111 -111
  90. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +282 -285
  91. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
  92. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.d.ts +52 -52
  93. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.js +93 -93
  94. package/lib/esm/presentation-frontend/selection/ISelectionProvider.d.ts +19 -19
  95. package/lib/esm/presentation-frontend/selection/ISelectionProvider.js +8 -8
  96. package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.d.ts +52 -52
  97. package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.js +29 -29
  98. package/lib/esm/presentation-frontend/selection/SelectionHandler.d.ts +103 -103
  99. package/lib/esm/presentation-frontend/selection/SelectionHandler.js +104 -104
  100. package/lib/esm/presentation-frontend/selection/SelectionHelper.d.ts +17 -14
  101. package/lib/esm/presentation-frontend/selection/SelectionHelper.d.ts.map +1 -1
  102. package/lib/esm/presentation-frontend/selection/SelectionHelper.js +36 -33
  103. package/lib/esm/presentation-frontend/selection/SelectionHelper.js.map +1 -1
  104. package/lib/esm/presentation-frontend/selection/SelectionManager.d.ts +139 -139
  105. package/lib/esm/presentation-frontend/selection/SelectionManager.js +409 -409
  106. package/lib/esm/presentation-frontend/selection/SelectionManager.js.map +1 -1
  107. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.d.ts +59 -59
  108. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js +85 -85
  109. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
  110. package/lib/esm/presentation-frontend.d.ts +33 -34
  111. package/lib/esm/presentation-frontend.d.ts.map +1 -1
  112. package/lib/esm/presentation-frontend.js +37 -38
  113. package/lib/esm/presentation-frontend.js.map +1 -1
  114. package/package.json +22 -20
  115. package/lib/cjs/presentation-frontend/StateTracker.d.ts +0 -39
  116. package/lib/cjs/presentation-frontend/StateTracker.d.ts.map +0 -1
  117. package/lib/cjs/presentation-frontend/StateTracker.js +0 -130
  118. package/lib/cjs/presentation-frontend/StateTracker.js.map +0 -1
  119. package/lib/esm/presentation-frontend/StateTracker.d.ts +0 -39
  120. package/lib/esm/presentation-frontend/StateTracker.d.ts.map +0 -1
  121. package/lib/esm/presentation-frontend/StateTracker.js +0 -126
  122. package/lib/esm/presentation-frontend/StateTracker.js.map +0 -1
@@ -1,437 +1,443 @@
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
- /** @packageDocumentation
7
- * @module Core
8
- */
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.buildPagedArrayResponse = exports.PresentationManager = void 0;
11
- const core_bentley_1 = require("@itwin/core-bentley");
12
- const core_frontend_1 = require("@itwin/core-frontend");
13
- const presentation_common_1 = require("@itwin/presentation-common");
14
- const IpcRequestsHandler_1 = require("./IpcRequestsHandler");
15
- const LocalizationHelper_1 = require("./LocalizationHelper");
16
- const RulesetManager_1 = require("./RulesetManager");
17
- const RulesetVariablesManager_1 = require("./RulesetVariablesManager");
18
- const SelectionManager_1 = require("./selection/SelectionManager");
19
- const StateTracker_1 = require("./StateTracker");
20
- /**
21
- * Frontend Presentation manager which basically just forwards all calls to
22
- * the backend implementation.
23
- *
24
- * @public
25
- */
26
- class PresentationManager {
27
- constructor(props) {
28
- var _a, _b, _c;
29
- /**
30
- * An event raised when hierarchies created using specific ruleset change
31
- * @alpha
32
- */
33
- this.onIModelHierarchyChanged = new core_bentley_1.BeEvent();
34
- /**
35
- * An event raised when content created using specific ruleset changes
36
- * @alpha
37
- */
38
- this.onIModelContentChanged = new core_bentley_1.BeEvent();
39
- // eslint-disable-next-line @typescript-eslint/naming-convention
40
- this.onUpdate = (_evt, report) => {
41
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
42
- this.handleUpdateAsync(presentation_common_1.UpdateInfo.fromJSON(report));
43
- };
44
- if (props) {
45
- this.activeUnitSystem = props.activeUnitSystem;
46
- }
47
- this._requestsHandler = (_a = props === null || props === void 0 ? void 0 : props.rpcRequestsHandler) !== null && _a !== void 0 ? _a : new presentation_common_1.RpcRequestsHandler(props ? { clientId: props.clientId } : undefined);
48
- this._rulesetVars = new Map();
49
- this._rulesets = RulesetManager_1.RulesetManagerImpl.create();
50
- this._localizationHelper = new LocalizationHelper_1.FrontendLocalizationHelper(props === null || props === void 0 ? void 0 : props.activeLocale);
51
- this._connections = new Map();
52
- if (core_frontend_1.IpcApp.isValid) {
53
- // Ipc only works in ipc apps, so the `onUpdate` callback will only be called there.
54
- this._clearEventListener = core_frontend_1.IpcApp.addListener(presentation_common_1.PresentationIpcEvents.Update, this.onUpdate);
55
- this._ipcRequestsHandler = (_b = props === null || props === void 0 ? void 0 : props.ipcRequestsHandler) !== null && _b !== void 0 ? _b : new IpcRequestsHandler_1.IpcRequestsHandler(this._requestsHandler.clientId);
56
- this._stateTracker = (_c = props === null || props === void 0 ? void 0 : props.stateTracker) !== null && _c !== void 0 ? _c : new StateTracker_1.StateTracker(this._ipcRequestsHandler);
57
- }
58
- }
59
- /** Get / set active locale used for localizing presentation data */
60
- get activeLocale() { return this._localizationHelper.locale; }
61
- set activeLocale(locale) { this._localizationHelper.locale = locale; }
62
- dispose() {
63
- this._requestsHandler.dispose();
64
- if (this._clearEventListener) {
65
- this._clearEventListener();
66
- this._clearEventListener = undefined;
67
- }
68
- }
69
- async onConnection(imodel) {
70
- if (!this._connections.has(imodel))
71
- this._connections.set(imodel, this.initializeIModel(imodel));
72
- await this._connections.get(imodel);
73
- }
74
- async initializeIModel(imodel) {
75
- imodel.onClose.addOnce(() => {
76
- this._connections.delete(imodel);
77
- });
78
- await this.onNewiModelConnection(imodel);
79
- }
80
- /** @note This is only called in native apps after changes in iModels */
81
- async handleUpdateAsync(report) {
82
- for (const imodelKey in report) {
83
- // istanbul ignore if
84
- if (!report.hasOwnProperty(imodelKey))
85
- continue;
86
- const imodelReport = report[imodelKey];
87
- for (const rulesetId in imodelReport) {
88
- // istanbul ignore if
89
- if (!imodelReport.hasOwnProperty(rulesetId))
90
- continue;
91
- const updateInfo = imodelReport[rulesetId];
92
- if (updateInfo.content)
93
- this.onIModelContentChanged.raiseEvent({ rulesetId, updateInfo: updateInfo.content, imodelKey });
94
- if (updateInfo.hierarchy)
95
- this.onIModelHierarchyChanged.raiseEvent({ rulesetId, updateInfo: updateInfo.hierarchy, imodelKey });
96
- }
97
- }
98
- }
99
- /** Function that is called when a new IModelConnection is used to retrieve data.
100
- * @internal
101
- */
102
- async onNewiModelConnection(_) { }
103
- /**
104
- * Create a new PresentationManager instance
105
- * @param props Optional properties used to configure the manager
106
- */
107
- static create(props) {
108
- return new PresentationManager(props);
109
- }
110
- /** @internal */
111
- get rpcRequestsHandler() { return this._requestsHandler; }
112
- /** @internal */
113
- get ipcRequestsHandler() { return this._ipcRequestsHandler; }
114
- /** @internal */
115
- get stateTracker() { return this._stateTracker; }
116
- /**
117
- * Get rulesets manager
118
- */
119
- rulesets() { return this._rulesets; }
120
- /**
121
- * Get ruleset variables manager for specific ruleset
122
- * @param rulesetId Id of the ruleset to get the vars manager for
123
- */
124
- vars(rulesetId) {
125
- if (!this._rulesetVars.has(rulesetId)) {
126
- const varsManager = new RulesetVariablesManager_1.RulesetVariablesManagerImpl(rulesetId, this._ipcRequestsHandler);
127
- this._rulesetVars.set(rulesetId, varsManager);
128
- }
129
- return this._rulesetVars.get(rulesetId);
130
- }
131
- toRpcTokenOptions(requestOptions) {
132
- // 1. put default `locale` and `unitSystem`
133
- // 2. put all `requestOptions` members (if `locale` or `unitSystem` are set, they'll override the defaults put at #1)
134
- // 3. put `imodel` of type `IModelRpcProps` which overwrites the `imodel` from `requestOptions` put at #2
135
- const defaultOptions = {};
136
- if (this.activeLocale)
137
- defaultOptions.locale = this.activeLocale;
138
- if (this.activeUnitSystem)
139
- defaultOptions.unitSystem = this.activeUnitSystem;
140
- const { imodel, rulesetVariables, ...rpcRequestOptions } = requestOptions;
141
- return {
142
- ...defaultOptions,
143
- ...rpcRequestOptions,
144
- ...(rulesetVariables ? { rulesetVariables: rulesetVariables.map(presentation_common_1.RulesetVariable.toJSON) } : {}),
145
- imodel: imodel.getRpcProps(),
146
- };
147
- }
148
- async addRulesetAndVariablesToOptions(options) {
149
- const { rulesetOrId, rulesetVariables } = options;
150
- let foundRulesetOrId;
151
- if (typeof rulesetOrId === "object") {
152
- foundRulesetOrId = rulesetOrId;
153
- }
154
- else {
155
- const foundRuleset = await this._rulesets.get(rulesetOrId);
156
- foundRulesetOrId = foundRuleset ? foundRuleset.toJSON() : rulesetOrId;
157
- }
158
- const rulesetId = (typeof foundRulesetOrId === "object") ? foundRulesetOrId.id : foundRulesetOrId;
159
- // All Id64Array variable values must be sorted for serialization to JSON to work. RulesetVariablesManager
160
- // sorts them before storing, so that part is taken care of, but we need to ensure that variables coming from
161
- // request options are also sorted.
162
- const variables = (rulesetVariables !== null && rulesetVariables !== void 0 ? rulesetVariables : []).map((variable) => {
163
- if (variable.type === presentation_common_1.VariableValueTypes.Id64Array)
164
- return { ...variable, value: core_bentley_1.OrderedId64Iterable.sortArray(variable.value) };
165
- return variable;
166
- });
167
- if (!this._ipcRequestsHandler) {
168
- // only need to add variables from variables manager if there's no IPC
169
- // handler - if there is one, the variables are already known by the backend
170
- variables.push(...this.vars(rulesetId).getAllVariables());
171
- }
172
- return { ...options, rulesetOrId: foundRulesetOrId, rulesetVariables: variables };
173
- }
174
- /** Retrieves nodes */
175
- async getNodes(requestOptions) {
176
- await this.onConnection(requestOptions.imodel);
177
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
178
- const rpcOptions = this.toRpcTokenOptions({ ...options });
179
- const result = await (0, exports.buildPagedArrayResponse)(options.paging, async (partialPageOptions) => this._requestsHandler.getPagedNodes({ ...rpcOptions, paging: partialPageOptions }));
180
- // eslint-disable-next-line deprecation/deprecation
181
- return this._localizationHelper.getLocalizedNodes(result.items.map(presentation_common_1.Node.fromJSON));
182
- }
183
- /** Retrieves nodes count. */
184
- async getNodesCount(requestOptions) {
185
- await this.onConnection(requestOptions.imodel);
186
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
187
- const rpcOptions = this.toRpcTokenOptions({ ...options });
188
- return this._requestsHandler.getNodesCount(rpcOptions);
189
- }
190
- /** Retrieves total nodes count and a single page of nodes. */
191
- async getNodesAndCount(requestOptions) {
192
- await this.onConnection(requestOptions.imodel);
193
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
194
- const rpcOptions = this.toRpcTokenOptions({ ...options });
195
- const result = await (0, exports.buildPagedArrayResponse)(options.paging, async (partialPageOptions) => this._requestsHandler.getPagedNodes({ ...rpcOptions, paging: partialPageOptions }));
196
- return {
197
- count: result.total,
198
- // eslint-disable-next-line deprecation/deprecation
199
- nodes: this._localizationHelper.getLocalizedNodes(result.items.map(presentation_common_1.Node.fromJSON)),
200
- };
201
- }
202
- /**
203
- * Retrieves hierarchy level descriptor.
204
- * @beta
205
- */
206
- async getNodesDescriptor(requestOptions) {
207
- await this.onConnection(requestOptions.imodel);
208
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
209
- const rpcOptions = this.toRpcTokenOptions({ ...options });
210
- const result = await this._requestsHandler.getNodesDescriptor(rpcOptions);
211
- return presentation_common_1.Descriptor.fromJSON(result);
212
- }
213
- /** Retrieves paths from root nodes to children nodes according to specified keys. Intersecting paths will be merged. */
214
- async getNodePaths(requestOptions) {
215
- await this.onConnection(requestOptions.imodel);
216
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
217
- const rpcOptions = this.toRpcTokenOptions({ ...options });
218
- const result = await this._requestsHandler.getNodePaths(rpcOptions);
219
- // eslint-disable-next-line deprecation/deprecation
220
- return result.map(presentation_common_1.NodePathElement.fromJSON);
221
- }
222
- /** Retrieves paths from root nodes to nodes containing filter text in their label. */
223
- async getFilteredNodePaths(requestOptions) {
224
- await this.onConnection(requestOptions.imodel);
225
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
226
- const result = await this._requestsHandler.getFilteredNodePaths(this.toRpcTokenOptions(options));
227
- // eslint-disable-next-line deprecation/deprecation
228
- return result.map(presentation_common_1.NodePathElement.fromJSON);
229
- }
230
- /**
231
- * Get information about the sources of content when building it for specific ECClasses. Sources involve classes of the primary select instance,
232
- * its related instances for loading related and navigation properties.
233
- * @public
234
- */
235
- async getContentSources(requestOptions) {
236
- await this.onConnection(requestOptions.imodel);
237
- const rpcOptions = this.toRpcTokenOptions(requestOptions);
238
- const result = await this._requestsHandler.getContentSources(rpcOptions);
239
- return presentation_common_1.SelectClassInfo.listFromCompressedJSON(result.sources, result.classesMap);
240
- }
241
- /** Retrieves the content descriptor which describes the content and can be used to customize it. */
242
- async getContentDescriptor(requestOptions) {
243
- await this.onConnection(requestOptions.imodel);
244
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
245
- const rpcOptions = this.toRpcTokenOptions({
246
- ...options,
247
- keys: stripTransientElementKeys(options.keys).toJSON(),
248
- });
249
- const result = await this._requestsHandler.getContentDescriptor(rpcOptions);
250
- return presentation_common_1.Descriptor.fromJSON(result);
251
- }
252
- /** Retrieves overall content set size. */
253
- async getContentSetSize(requestOptions) {
254
- await this.onConnection(requestOptions.imodel);
255
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
256
- const rpcOptions = this.toRpcTokenOptions({
257
- ...options,
258
- descriptor: getDescriptorOverrides(requestOptions.descriptor),
259
- keys: stripTransientElementKeys(requestOptions.keys).toJSON(),
260
- });
261
- return this._requestsHandler.getContentSetSize(rpcOptions);
262
- }
263
- /** Retrieves content which consists of a content descriptor and a page of records. */
264
- async getContent(requestOptions) {
265
- var _a;
266
- return (_a = (await this.getContentAndSize(requestOptions))) === null || _a === void 0 ? void 0 : _a.content;
267
- }
268
- /** Retrieves content set size and content which consists of a content descriptor and a page of records. */
269
- async getContentAndSize(requestOptions) {
270
- await this.onConnection(requestOptions.imodel);
271
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
272
- const rpcOptions = this.toRpcTokenOptions({
273
- ...options,
274
- descriptor: getDescriptorOverrides(requestOptions.descriptor),
275
- keys: stripTransientElementKeys(requestOptions.keys).toJSON(),
276
- });
277
- let descriptor = (requestOptions.descriptor instanceof presentation_common_1.Descriptor) ? requestOptions.descriptor : undefined;
278
- const result = await (0, exports.buildPagedArrayResponse)(options.paging, async (partialPageOptions, requestIndex) => {
279
- if (0 === requestIndex && !descriptor) {
280
- const content = await this._requestsHandler.getPagedContent({ ...rpcOptions, paging: partialPageOptions });
281
- if (content) {
282
- descriptor = presentation_common_1.Descriptor.fromJSON(content.descriptor);
283
- return content.contentSet;
284
- }
285
- return { total: 0, items: [] };
286
- }
287
- return this._requestsHandler.getPagedContentSet({ ...rpcOptions, paging: partialPageOptions });
288
- });
289
- if (!descriptor)
290
- return undefined;
291
- const items = result.items.map((itemJson) => presentation_common_1.Item.fromJSON(itemJson)).filter((item) => (item !== undefined));
292
- return {
293
- size: result.total,
294
- content: this._localizationHelper.getLocalizedContent(new presentation_common_1.Content(descriptor, items)),
295
- };
296
- }
297
- /** Retrieves distinct values of specific field from the content. */
298
- async getPagedDistinctValues(requestOptions) {
299
- await this.onConnection(requestOptions.imodel);
300
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
301
- const rpcOptions = {
302
- ...this.toRpcTokenOptions(options),
303
- descriptor: getDescriptorOverrides(options.descriptor),
304
- keys: stripTransientElementKeys(options.keys).toJSON(),
305
- };
306
- const result = await (0, exports.buildPagedArrayResponse)(requestOptions.paging, async (partialPageOptions) => this._requestsHandler.getPagedDistinctValues({ ...rpcOptions, paging: partialPageOptions }));
307
- return {
308
- ...result,
309
- // eslint-disable-next-line deprecation/deprecation
310
- items: result.items.map(presentation_common_1.DisplayValueGroup.fromJSON),
311
- };
312
- }
313
- /**
314
- * Retrieves property data in a simplified format for a single element specified by ID.
315
- * @public
316
- */
317
- async getElementProperties(requestOptions) {
318
- await this.onConnection(requestOptions.imodel);
319
- const results = await this._requestsHandler.getElementProperties(this.toRpcTokenOptions(requestOptions));
320
- // istanbul ignore if
321
- if (!results)
322
- return undefined;
323
- return this._localizationHelper.getLocalizedElementProperties(results);
324
- }
325
- /**
326
- * Retrieves content item instance keys.
327
- * @public
328
- */
329
- async getContentInstanceKeys(requestOptions) {
330
- await this.onConnection(requestOptions.imodel);
331
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
332
- const rpcOptions = {
333
- ...this.toRpcTokenOptions(options),
334
- keys: stripTransientElementKeys(options.keys).toJSON(),
335
- };
336
- const props = {
337
- page: requestOptions.paging,
338
- get: async (page) => {
339
- const keys = await this._requestsHandler.getContentInstanceKeys({ ...rpcOptions, paging: page });
340
- return {
341
- total: keys.total,
342
- items: keys.items.instanceKeys.reduce((instanceKeys, entry) => {
343
- for (const id of core_bentley_1.CompressedId64Set.iterable(entry[1])) {
344
- instanceKeys.push({ className: entry[0], id });
345
- }
346
- return instanceKeys;
347
- }, new Array()),
348
- };
349
- },
350
- };
351
- return createPagedGeneratorResponse(props);
352
- }
353
- /** Retrieves display label definition of specific item. */
354
- async getDisplayLabelDefinition(requestOptions) {
355
- await this.onConnection(requestOptions.imodel);
356
- const rpcOptions = this.toRpcTokenOptions({ ...requestOptions });
357
- const result = await this._requestsHandler.getDisplayLabelDefinition(rpcOptions);
358
- return this._localizationHelper.getLocalizedLabelDefinition(result);
359
- }
360
- /** Retrieves display label definition of specific items. */
361
- async getDisplayLabelDefinitions(requestOptions) {
362
- await this.onConnection(requestOptions.imodel);
363
- const rpcOptions = this.toRpcTokenOptions({ ...requestOptions });
364
- const result = await (0, exports.buildPagedArrayResponse)(undefined, async (partialPageOptions) => {
365
- const partialKeys = (!partialPageOptions.start) ? rpcOptions.keys : rpcOptions.keys.slice(partialPageOptions.start);
366
- return this._requestsHandler.getPagedDisplayLabelDefinitions({ ...rpcOptions, keys: partialKeys });
367
- });
368
- return this._localizationHelper.getLocalizedLabelDefinitions(result.items);
369
- }
370
- }
371
- exports.PresentationManager = PresentationManager;
372
- const getDescriptorOverrides = (descriptorOrOverrides) => {
373
- if (descriptorOrOverrides instanceof presentation_common_1.Descriptor)
374
- return descriptorOrOverrides.createDescriptorOverrides();
375
- return descriptorOrOverrides;
376
- };
377
- async function createPagedGeneratorResponse(props) {
378
- var _a, _b, _c, _d;
379
- let pageStart = (_b = (_a = props.page) === null || _a === void 0 ? void 0 : _a.start) !== null && _b !== void 0 ? _b : 0;
380
- let pageSize = (_d = (_c = props.page) === null || _c === void 0 ? void 0 : _c.size) !== null && _d !== void 0 ? _d : 0;
381
- let requestIndex = 0;
382
- const firstPage = await props.get({ start: pageStart, size: pageSize }, requestIndex++);
383
- return {
384
- total: firstPage.total,
385
- async *items() {
386
- let partialResult = firstPage;
387
- while (true) {
388
- for (const item of partialResult.items) {
389
- yield item;
390
- }
391
- const receivedItemsCount = partialResult.items.length;
392
- if (partialResult.total !== 0 && receivedItemsCount === 0) {
393
- if (pageStart >= partialResult.total)
394
- throw new Error(`Requested page with start index ${pageStart} is out of bounds. Total number of items: ${partialResult.total}`);
395
- throw new Error("Paged request returned non zero total count but no items");
396
- }
397
- if (pageSize !== 0 && receivedItemsCount >= pageSize || receivedItemsCount >= (partialResult.total - pageStart))
398
- break;
399
- if (pageSize !== 0)
400
- pageSize -= receivedItemsCount;
401
- pageStart += receivedItemsCount;
402
- partialResult = await props.get({ start: pageStart, size: pageSize }, requestIndex++);
403
- }
404
- },
405
- };
406
- }
407
- /** @internal */
408
- const buildPagedArrayResponse = async (requestedPage, getter) => {
409
- try {
410
- const items = new Array();
411
- const gen = await createPagedGeneratorResponse({ page: requestedPage, get: getter });
412
- for await (const item of gen.items()) {
413
- items.push(item);
414
- }
415
- return { total: gen.total, items };
416
- }
417
- catch {
418
- // FIXME: we should propagate the error...
419
- return { total: 0, items: [] };
420
- }
421
- };
422
- exports.buildPagedArrayResponse = buildPagedArrayResponse;
423
- const stripTransientElementKeys = (keys) => {
424
- if (!keys.some((key) => presentation_common_1.Key.isInstanceKey(key) && key.className === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME))
425
- return keys;
426
- const copy = new presentation_common_1.KeySet();
427
- copy.add(keys, (key) => {
428
- // the callback is not going to be called with EntityProps as KeySet converts them
429
- // to InstanceKeys, but we want to keep the EntityProps case for correctness
430
- // istanbul ignore next
431
- const isTransient = presentation_common_1.Key.isInstanceKey(key) && key.className === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME
432
- || presentation_common_1.Key.isEntityProps(key) && key.classFullName === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME;
433
- return !isTransient;
434
- });
435
- return copy;
436
- };
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
+ /** @packageDocumentation
7
+ * @module Core
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.buildPagedArrayResponse = exports.PresentationManager = void 0;
11
+ const core_bentley_1 = require("@itwin/core-bentley");
12
+ const core_frontend_1 = require("@itwin/core-frontend");
13
+ const presentation_common_1 = require("@itwin/presentation-common");
14
+ const IpcRequestsHandler_1 = require("./IpcRequestsHandler");
15
+ const LocalizationHelper_1 = require("./LocalizationHelper");
16
+ const RulesetManager_1 = require("./RulesetManager");
17
+ const RulesetVariablesManager_1 = require("./RulesetVariablesManager");
18
+ const SelectionManager_1 = require("./selection/SelectionManager");
19
+ /**
20
+ * Frontend Presentation manager which basically just forwards all calls to
21
+ * the backend implementation.
22
+ *
23
+ * @public
24
+ */
25
+ class PresentationManager {
26
+ /**
27
+ * Get / set active unit system used to format property values with units.
28
+ *
29
+ * @deprecated in 4.0. `IModelApp.quantityFormatter` should be used to get/set the active unit system. At the moment
30
+ * [[PresentationManager]] allows overriding it, but returns `IModelApp.quantityFormatter.activeUnitSystem` if override
31
+ * is not set.
32
+ */
33
+ get activeUnitSystem() {
34
+ return this._explicitActiveUnitSystem ?? core_frontend_1.IModelApp.quantityFormatter.activeUnitSystem;
35
+ }
36
+ set activeUnitSystem(value) { this._explicitActiveUnitSystem = value; }
37
+ constructor(props) {
38
+ /**
39
+ * An event raised when hierarchies created using specific ruleset change
40
+ * @alpha
41
+ */
42
+ this.onIModelHierarchyChanged = new core_bentley_1.BeEvent();
43
+ /**
44
+ * An event raised when content created using specific ruleset changes
45
+ * @alpha
46
+ */
47
+ this.onIModelContentChanged = new core_bentley_1.BeEvent();
48
+ // eslint-disable-next-line @typescript-eslint/naming-convention
49
+ this.onUpdate = (_evt, report) => {
50
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
51
+ this.handleUpdateAsync(report);
52
+ };
53
+ if (props) {
54
+ // eslint-disable-next-line deprecation/deprecation
55
+ this._explicitActiveUnitSystem = props.activeUnitSystem;
56
+ }
57
+ this._requestsHandler = props?.rpcRequestsHandler ?? new presentation_common_1.RpcRequestsHandler(props ? { clientId: props.clientId, timeout: props.requestTimeout } : undefined);
58
+ this._rulesetVars = new Map();
59
+ this._rulesets = RulesetManager_1.RulesetManagerImpl.create();
60
+ this._localizationHelper = new LocalizationHelper_1.FrontendLocalizationHelper(props?.activeLocale);
61
+ this._connections = new Map();
62
+ this._schemaContextProvider = props?.schemaContextProvider;
63
+ if (core_frontend_1.IpcApp.isValid) {
64
+ // Ipc only works in ipc apps, so the `onUpdate` callback will only be called there.
65
+ this._clearEventListener = core_frontend_1.IpcApp.addListener(presentation_common_1.PresentationIpcEvents.Update, this.onUpdate);
66
+ this._ipcRequestsHandler = props?.ipcRequestsHandler ?? new IpcRequestsHandler_1.IpcRequestsHandler(this._requestsHandler.clientId);
67
+ }
68
+ }
69
+ /** Get / set active locale used for localizing presentation data */
70
+ get activeLocale() { return this._localizationHelper.locale; }
71
+ set activeLocale(locale) { this._localizationHelper.locale = locale; }
72
+ dispose() {
73
+ if (this._clearEventListener) {
74
+ this._clearEventListener();
75
+ this._clearEventListener = undefined;
76
+ }
77
+ }
78
+ async onConnection(imodel) {
79
+ if (!this._connections.has(imodel))
80
+ this._connections.set(imodel, this.initializeIModel(imodel));
81
+ await this._connections.get(imodel);
82
+ }
83
+ async initializeIModel(imodel) {
84
+ imodel.onClose.addOnce(() => {
85
+ this._connections.delete(imodel);
86
+ });
87
+ await this.onNewiModelConnection(imodel);
88
+ }
89
+ /** @note This is only called in native apps after changes in iModels */
90
+ async handleUpdateAsync(report) {
91
+ for (const imodelKey in report) {
92
+ // istanbul ignore if
93
+ if (!report.hasOwnProperty(imodelKey))
94
+ continue;
95
+ const imodelReport = report[imodelKey];
96
+ for (const rulesetId in imodelReport) {
97
+ // istanbul ignore if
98
+ if (!imodelReport.hasOwnProperty(rulesetId))
99
+ continue;
100
+ const updateInfo = imodelReport[rulesetId];
101
+ if (updateInfo.content)
102
+ this.onIModelContentChanged.raiseEvent({ rulesetId, updateInfo: updateInfo.content, imodelKey });
103
+ if (updateInfo.hierarchy)
104
+ this.onIModelHierarchyChanged.raiseEvent({ rulesetId, updateInfo: updateInfo.hierarchy, imodelKey });
105
+ }
106
+ }
107
+ }
108
+ /**
109
+ * Function that is called when a new IModelConnection is used to retrieve data.
110
+ * @internal
111
+ */
112
+ async onNewiModelConnection(_) { }
113
+ /**
114
+ * Create a new PresentationManager instance
115
+ * @param props Optional properties used to configure the manager
116
+ */
117
+ static create(props) {
118
+ return new PresentationManager(props);
119
+ }
120
+ /** @internal */
121
+ get rpcRequestsHandler() { return this._requestsHandler; }
122
+ /** @internal */
123
+ get ipcRequestsHandler() { return this._ipcRequestsHandler; }
124
+ /**
125
+ * Get rulesets manager
126
+ */
127
+ rulesets() { return this._rulesets; }
128
+ /**
129
+ * Get ruleset variables manager for specific ruleset
130
+ * @param rulesetId Id of the ruleset to get the vars manager for
131
+ */
132
+ vars(rulesetId) {
133
+ if (!this._rulesetVars.has(rulesetId)) {
134
+ const varsManager = new RulesetVariablesManager_1.RulesetVariablesManagerImpl(rulesetId, this._ipcRequestsHandler);
135
+ this._rulesetVars.set(rulesetId, varsManager);
136
+ }
137
+ return this._rulesetVars.get(rulesetId);
138
+ }
139
+ toRpcTokenOptions(requestOptions) {
140
+ // 1. put default `locale` and `unitSystem`
141
+ // 2. put all `requestOptions` members (if `locale` or `unitSystem` are set, they'll override the defaults put at #1)
142
+ // 3. put `imodel` of type `IModelRpcProps` which overwrites the `imodel` from `requestOptions` put at #2
143
+ const defaultOptions = {};
144
+ if (this.activeLocale)
145
+ defaultOptions.locale = this.activeLocale;
146
+ defaultOptions.unitSystem = this.activeUnitSystem; // eslint-disable-line deprecation/deprecation
147
+ const { imodel, rulesetVariables, ...rpcRequestOptions } = requestOptions;
148
+ return {
149
+ ...defaultOptions,
150
+ ...rpcRequestOptions,
151
+ ...(rulesetVariables ? { rulesetVariables: rulesetVariables.map(presentation_common_1.RulesetVariable.toJSON) } : {}),
152
+ imodel: imodel.getRpcProps(),
153
+ };
154
+ }
155
+ async addRulesetAndVariablesToOptions(options) {
156
+ const { rulesetOrId, rulesetVariables } = options;
157
+ let foundRulesetOrId;
158
+ if (typeof rulesetOrId === "object") {
159
+ foundRulesetOrId = rulesetOrId;
160
+ }
161
+ else {
162
+ const foundRuleset = await this._rulesets.get(rulesetOrId);
163
+ foundRulesetOrId = foundRuleset ? foundRuleset.toJSON() : rulesetOrId;
164
+ }
165
+ const rulesetId = (typeof foundRulesetOrId === "object") ? foundRulesetOrId.id : foundRulesetOrId;
166
+ // All Id64Array variable values must be sorted for serialization to JSON to work. RulesetVariablesManager
167
+ // sorts them before storing, so that part is taken care of, but we need to ensure that variables coming from
168
+ // request options are also sorted.
169
+ const variables = (rulesetVariables ?? []).map((variable) => {
170
+ if (variable.type === presentation_common_1.VariableValueTypes.Id64Array)
171
+ return { ...variable, value: core_bentley_1.OrderedId64Iterable.sortArray(variable.value) };
172
+ return variable;
173
+ });
174
+ if (!this._ipcRequestsHandler) {
175
+ // only need to add variables from variables manager if there's no IPC
176
+ // handler - if there is one, the variables are already known by the backend
177
+ variables.push(...this.vars(rulesetId).getAllVariables());
178
+ }
179
+ return { ...options, rulesetOrId: foundRulesetOrId, rulesetVariables: variables };
180
+ }
181
+ /** Retrieves nodes */
182
+ async getNodes(requestOptions) {
183
+ await this.onConnection(requestOptions.imodel);
184
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
185
+ const rpcOptions = this.toRpcTokenOptions({ ...options });
186
+ const result = await (0, exports.buildPagedArrayResponse)(options.paging, async (partialPageOptions) => this._requestsHandler.getPagedNodes({ ...rpcOptions, paging: partialPageOptions }));
187
+ // eslint-disable-next-line deprecation/deprecation
188
+ return this._localizationHelper.getLocalizedNodes(result.items.map(presentation_common_1.Node.fromJSON));
189
+ }
190
+ /** Retrieves nodes count. */
191
+ async getNodesCount(requestOptions) {
192
+ await this.onConnection(requestOptions.imodel);
193
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
194
+ const rpcOptions = this.toRpcTokenOptions({ ...options });
195
+ return this._requestsHandler.getNodesCount(rpcOptions);
196
+ }
197
+ /** Retrieves total nodes count and a single page of nodes. */
198
+ async getNodesAndCount(requestOptions) {
199
+ await this.onConnection(requestOptions.imodel);
200
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
201
+ const rpcOptions = this.toRpcTokenOptions({ ...options });
202
+ const result = await (0, exports.buildPagedArrayResponse)(options.paging, async (partialPageOptions) => this._requestsHandler.getPagedNodes({ ...rpcOptions, paging: partialPageOptions }));
203
+ return {
204
+ count: result.total,
205
+ // eslint-disable-next-line deprecation/deprecation
206
+ nodes: this._localizationHelper.getLocalizedNodes(result.items.map(presentation_common_1.Node.fromJSON)),
207
+ };
208
+ }
209
+ /**
210
+ * Retrieves hierarchy level descriptor.
211
+ * @beta
212
+ */
213
+ async getNodesDescriptor(requestOptions) {
214
+ await this.onConnection(requestOptions.imodel);
215
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
216
+ const rpcOptions = this.toRpcTokenOptions({ ...options });
217
+ const result = await this._requestsHandler.getNodesDescriptor(rpcOptions);
218
+ return presentation_common_1.Descriptor.fromJSON(result);
219
+ }
220
+ /** Retrieves paths from root nodes to children nodes according to specified keys. Intersecting paths will be merged. */
221
+ async getNodePaths(requestOptions) {
222
+ await this.onConnection(requestOptions.imodel);
223
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
224
+ const rpcOptions = this.toRpcTokenOptions({ ...options });
225
+ const result = await this._requestsHandler.getNodePaths(rpcOptions);
226
+ // eslint-disable-next-line deprecation/deprecation
227
+ return result.map(presentation_common_1.NodePathElement.fromJSON);
228
+ }
229
+ /** Retrieves paths from root nodes to nodes containing filter text in their label. */
230
+ async getFilteredNodePaths(requestOptions) {
231
+ await this.onConnection(requestOptions.imodel);
232
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
233
+ const result = await this._requestsHandler.getFilteredNodePaths(this.toRpcTokenOptions(options));
234
+ // eslint-disable-next-line deprecation/deprecation
235
+ return result.map(presentation_common_1.NodePathElement.fromJSON);
236
+ }
237
+ /**
238
+ * Get information about the sources of content when building it for specific ECClasses. Sources involve classes of the primary select instance,
239
+ * its related instances for loading related and navigation properties.
240
+ * @public
241
+ */
242
+ async getContentSources(requestOptions) {
243
+ await this.onConnection(requestOptions.imodel);
244
+ const rpcOptions = this.toRpcTokenOptions(requestOptions);
245
+ const result = await this._requestsHandler.getContentSources(rpcOptions);
246
+ return presentation_common_1.SelectClassInfo.listFromCompressedJSON(result.sources, result.classesMap);
247
+ }
248
+ /** Retrieves the content descriptor which describes the content and can be used to customize it. */
249
+ async getContentDescriptor(requestOptions) {
250
+ await this.onConnection(requestOptions.imodel);
251
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
252
+ const rpcOptions = this.toRpcTokenOptions({
253
+ ...options,
254
+ keys: stripTransientElementKeys(options.keys).toJSON(),
255
+ });
256
+ const result = await this._requestsHandler.getContentDescriptor(rpcOptions);
257
+ return presentation_common_1.Descriptor.fromJSON(result);
258
+ }
259
+ /** Retrieves overall content set size. */
260
+ async getContentSetSize(requestOptions) {
261
+ await this.onConnection(requestOptions.imodel);
262
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
263
+ const rpcOptions = this.toRpcTokenOptions({
264
+ ...options,
265
+ descriptor: getDescriptorOverrides(requestOptions.descriptor),
266
+ keys: stripTransientElementKeys(requestOptions.keys).toJSON(),
267
+ });
268
+ return this._requestsHandler.getContentSetSize(rpcOptions);
269
+ }
270
+ /** Retrieves content which consists of a content descriptor and a page of records. */
271
+ async getContent(requestOptions) {
272
+ return (await this.getContentAndSize(requestOptions))?.content;
273
+ }
274
+ /** Retrieves content set size and content which consists of a content descriptor and a page of records. */
275
+ async getContentAndSize(requestOptions) {
276
+ await this.onConnection(requestOptions.imodel);
277
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
278
+ const rpcOptions = this.toRpcTokenOptions({
279
+ ...options,
280
+ descriptor: getDescriptorOverrides(requestOptions.descriptor),
281
+ keys: stripTransientElementKeys(requestOptions.keys).toJSON(),
282
+ ...(!requestOptions.omitFormattedValues && this._schemaContextProvider !== undefined ? { omitFormattedValues: true } : undefined),
283
+ });
284
+ let descriptor = (requestOptions.descriptor instanceof presentation_common_1.Descriptor) ? requestOptions.descriptor : undefined;
285
+ const result = await (0, exports.buildPagedArrayResponse)(options.paging, async (partialPageOptions, requestIndex) => {
286
+ if (0 === requestIndex && !descriptor) {
287
+ const content = await this._requestsHandler.getPagedContent({ ...rpcOptions, paging: partialPageOptions });
288
+ if (content) {
289
+ descriptor = presentation_common_1.Descriptor.fromJSON(content.descriptor);
290
+ return content.contentSet;
291
+ }
292
+ return { total: 0, items: [] };
293
+ }
294
+ return this._requestsHandler.getPagedContentSet({ ...rpcOptions, paging: partialPageOptions });
295
+ });
296
+ if (!descriptor)
297
+ return undefined;
298
+ const items = result.items.map((itemJson) => presentation_common_1.Item.fromJSON(itemJson)).filter((item) => (item !== undefined));
299
+ const resultContent = new presentation_common_1.Content(descriptor, items);
300
+ if (!requestOptions.omitFormattedValues && this._schemaContextProvider) {
301
+ const koqPropertyFormatter = new presentation_common_1.KoqPropertyValueFormatter(this._schemaContextProvider(requestOptions.imodel));
302
+ const contentFormatter = new presentation_common_1.ContentFormatter(new presentation_common_1.ContentPropertyValueFormatter(koqPropertyFormatter), core_frontend_1.IModelApp.quantityFormatter.activeUnitSystem);
303
+ await contentFormatter.formatContent(resultContent);
304
+ }
305
+ return {
306
+ size: result.total,
307
+ content: this._localizationHelper.getLocalizedContent(resultContent),
308
+ };
309
+ }
310
+ /** Retrieves distinct values of specific field from the content. */
311
+ async getPagedDistinctValues(requestOptions) {
312
+ await this.onConnection(requestOptions.imodel);
313
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
314
+ const rpcOptions = {
315
+ ...this.toRpcTokenOptions(options),
316
+ descriptor: getDescriptorOverrides(options.descriptor),
317
+ keys: stripTransientElementKeys(options.keys).toJSON(),
318
+ };
319
+ const result = await (0, exports.buildPagedArrayResponse)(requestOptions.paging, async (partialPageOptions) => this._requestsHandler.getPagedDistinctValues({ ...rpcOptions, paging: partialPageOptions }));
320
+ return {
321
+ ...result,
322
+ // eslint-disable-next-line deprecation/deprecation
323
+ items: result.items.map(presentation_common_1.DisplayValueGroup.fromJSON),
324
+ };
325
+ }
326
+ /**
327
+ * Retrieves property data in a simplified format for a single element specified by ID.
328
+ * @public
329
+ */
330
+ async getElementProperties(requestOptions) {
331
+ await this.onConnection(requestOptions.imodel);
332
+ const results = await this._requestsHandler.getElementProperties(this.toRpcTokenOptions(requestOptions));
333
+ // istanbul ignore if
334
+ if (!results)
335
+ return undefined;
336
+ return this._localizationHelper.getLocalizedElementProperties(results);
337
+ }
338
+ /**
339
+ * Retrieves content item instance keys.
340
+ * @public
341
+ */
342
+ async getContentInstanceKeys(requestOptions) {
343
+ await this.onConnection(requestOptions.imodel);
344
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
345
+ const rpcOptions = {
346
+ ...this.toRpcTokenOptions(options),
347
+ keys: stripTransientElementKeys(options.keys).toJSON(),
348
+ };
349
+ const props = {
350
+ page: requestOptions.paging,
351
+ get: async (page) => {
352
+ const keys = await this._requestsHandler.getContentInstanceKeys({ ...rpcOptions, paging: page });
353
+ return {
354
+ total: keys.total,
355
+ items: keys.items.instanceKeys.reduce((instanceKeys, entry) => {
356
+ for (const id of core_bentley_1.CompressedId64Set.iterable(entry[1])) {
357
+ instanceKeys.push({ className: entry[0], id });
358
+ }
359
+ return instanceKeys;
360
+ }, new Array()),
361
+ };
362
+ },
363
+ };
364
+ return createPagedGeneratorResponse(props);
365
+ }
366
+ /** Retrieves display label definition of specific item. */
367
+ async getDisplayLabelDefinition(requestOptions) {
368
+ await this.onConnection(requestOptions.imodel);
369
+ const rpcOptions = this.toRpcTokenOptions({ ...requestOptions });
370
+ const result = await this._requestsHandler.getDisplayLabelDefinition(rpcOptions);
371
+ return this._localizationHelper.getLocalizedLabelDefinition(result);
372
+ }
373
+ /** Retrieves display label definition of specific items. */
374
+ async getDisplayLabelDefinitions(requestOptions) {
375
+ await this.onConnection(requestOptions.imodel);
376
+ const rpcOptions = this.toRpcTokenOptions({ ...requestOptions });
377
+ const result = await (0, exports.buildPagedArrayResponse)(undefined, async (partialPageOptions) => {
378
+ const partialKeys = (!partialPageOptions.start) ? rpcOptions.keys : rpcOptions.keys.slice(partialPageOptions.start);
379
+ return this._requestsHandler.getPagedDisplayLabelDefinitions({ ...rpcOptions, keys: partialKeys });
380
+ });
381
+ return this._localizationHelper.getLocalizedLabelDefinitions(result.items);
382
+ }
383
+ }
384
+ exports.PresentationManager = PresentationManager;
385
+ const getDescriptorOverrides = (descriptorOrOverrides) => {
386
+ if (descriptorOrOverrides instanceof presentation_common_1.Descriptor)
387
+ return descriptorOrOverrides.createDescriptorOverrides();
388
+ return descriptorOrOverrides;
389
+ };
390
+ async function createPagedGeneratorResponse(props) {
391
+ let pageStart = props.page?.start ?? 0;
392
+ let pageSize = props.page?.size ?? 0;
393
+ let requestIndex = 0;
394
+ const firstPage = await props.get({ start: pageStart, size: pageSize }, requestIndex++);
395
+ return {
396
+ total: firstPage.total,
397
+ async *items() {
398
+ let partialResult = firstPage;
399
+ while (true) {
400
+ for (const item of partialResult.items) {
401
+ yield item;
402
+ }
403
+ const receivedItemsCount = partialResult.items.length;
404
+ if (partialResult.total !== 0 && receivedItemsCount === 0) {
405
+ if (pageStart >= partialResult.total)
406
+ throw new Error(`Requested page with start index ${pageStart} is out of bounds. Total number of items: ${partialResult.total}`);
407
+ throw new Error("Paged request returned non zero total count but no items");
408
+ }
409
+ if (pageSize !== 0 && receivedItemsCount >= pageSize || receivedItemsCount >= (partialResult.total - pageStart))
410
+ break;
411
+ if (pageSize !== 0)
412
+ pageSize -= receivedItemsCount;
413
+ pageStart += receivedItemsCount;
414
+ partialResult = await props.get({ start: pageStart, size: pageSize }, requestIndex++);
415
+ }
416
+ },
417
+ };
418
+ }
419
+ /** @internal */
420
+ const buildPagedArrayResponse = async (requestedPage, getter) => {
421
+ const items = new Array();
422
+ const gen = await createPagedGeneratorResponse({ page: requestedPage, get: getter });
423
+ for await (const item of gen.items()) {
424
+ items.push(item);
425
+ }
426
+ return { total: gen.total, items };
427
+ };
428
+ exports.buildPagedArrayResponse = buildPagedArrayResponse;
429
+ const stripTransientElementKeys = (keys) => {
430
+ if (!keys.some((key) => presentation_common_1.Key.isInstanceKey(key) && key.className === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME))
431
+ return keys;
432
+ const copy = new presentation_common_1.KeySet();
433
+ copy.add(keys, (key) => {
434
+ // the callback is not going to be called with EntityProps as KeySet converts them
435
+ // to InstanceKeys, but we want to keep the EntityProps case for correctness
436
+ // istanbul ignore next
437
+ const isTransient = presentation_common_1.Key.isInstanceKey(key) && key.className === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME
438
+ || presentation_common_1.Key.isEntityProps(key) && key.classFullName === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME;
439
+ return !isTransient;
440
+ });
441
+ return copy;
442
+ };
437
443
  //# sourceMappingURL=PresentationManager.js.map