@itwin/presentation-frontend 4.5.0-dev.9 → 4.6.0-dev.1

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 (124) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/LICENSE.md +1 -1
  3. package/README.md +1 -1
  4. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.d.ts.map +1 -1
  5. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js +10 -6
  6. package/lib/cjs/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
  7. package/lib/cjs/presentation-frontend/Diagnostics.d.ts.map +1 -1
  8. package/lib/cjs/presentation-frontend/Diagnostics.js +18 -13
  9. package/lib/cjs/presentation-frontend/Diagnostics.js.map +1 -1
  10. package/lib/cjs/presentation-frontend/FrontendLoggerCategory.js +3 -3
  11. package/lib/cjs/presentation-frontend/FrontendLoggerCategory.js.map +1 -1
  12. package/lib/cjs/presentation-frontend/IpcRequestsHandler.d.ts.map +1 -1
  13. package/lib/cjs/presentation-frontend/IpcRequestsHandler.js +3 -3
  14. package/lib/cjs/presentation-frontend/IpcRequestsHandler.js.map +1 -1
  15. package/lib/cjs/presentation-frontend/LocalizationHelper.js +3 -3
  16. package/lib/cjs/presentation-frontend/LocalizationHelper.js.map +1 -1
  17. package/lib/cjs/presentation-frontend/Presentation.d.ts.map +1 -1
  18. package/lib/cjs/presentation-frontend/Presentation.js +26 -16
  19. package/lib/cjs/presentation-frontend/Presentation.js.map +1 -1
  20. package/lib/cjs/presentation-frontend/PresentationManager.d.ts +84 -21
  21. package/lib/cjs/presentation-frontend/PresentationManager.d.ts.map +1 -1
  22. package/lib/cjs/presentation-frontend/PresentationManager.js +245 -154
  23. package/lib/cjs/presentation-frontend/PresentationManager.js.map +1 -1
  24. package/lib/cjs/presentation-frontend/RulesetManager.d.ts.map +1 -1
  25. package/lib/cjs/presentation-frontend/RulesetManager.js +11 -7
  26. package/lib/cjs/presentation-frontend/RulesetManager.js.map +1 -1
  27. package/lib/cjs/presentation-frontend/RulesetVariablesManager.d.ts.map +1 -1
  28. package/lib/cjs/presentation-frontend/RulesetVariablesManager.js +53 -31
  29. package/lib/cjs/presentation-frontend/RulesetVariablesManager.js.map +1 -1
  30. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.d.ts +30 -0
  31. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.d.ts.map +1 -0
  32. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.js +117 -0
  33. package/lib/cjs/presentation-frontend/StreamedResponseGenerator.js.map +1 -0
  34. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts +33 -4
  35. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
  36. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +179 -74
  37. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
  38. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts.map +1 -1
  39. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +54 -25
  40. package/lib/cjs/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
  41. package/lib/cjs/presentation-frontend/selection/HiliteRules.json +172 -172
  42. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.d.ts.map +1 -1
  43. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.js +23 -13
  44. package/lib/cjs/presentation-frontend/selection/HiliteSetProvider.js.map +1 -1
  45. package/lib/cjs/presentation-frontend/selection/ISelectionProvider.js +3 -3
  46. package/lib/cjs/presentation-frontend/selection/ISelectionProvider.js.map +1 -1
  47. package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.d.ts.map +1 -1
  48. package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.js +3 -3
  49. package/lib/cjs/presentation-frontend/selection/SelectionChangeEvent.js.map +1 -1
  50. package/lib/cjs/presentation-frontend/selection/SelectionHandler.d.ts.map +1 -1
  51. package/lib/cjs/presentation-frontend/selection/SelectionHandler.js +15 -9
  52. package/lib/cjs/presentation-frontend/selection/SelectionHandler.js.map +1 -1
  53. package/lib/cjs/presentation-frontend/selection/SelectionHelper.d.ts.map +1 -1
  54. package/lib/cjs/presentation-frontend/selection/SelectionHelper.js +7 -5
  55. package/lib/cjs/presentation-frontend/selection/SelectionHelper.js.map +1 -1
  56. package/lib/cjs/presentation-frontend/selection/SelectionManager.d.ts.map +1 -1
  57. package/lib/cjs/presentation-frontend/selection/SelectionManager.js +31 -16
  58. package/lib/cjs/presentation-frontend/selection/SelectionManager.js.map +1 -1
  59. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.d.ts.map +1 -1
  60. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js +25 -14
  61. package/lib/cjs/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
  62. package/lib/cjs/presentation-frontend.js +3 -3
  63. package/lib/cjs/presentation-frontend.js.map +1 -1
  64. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.d.ts.map +1 -1
  65. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js +10 -6
  66. package/lib/esm/presentation-frontend/ConnectivityInformationProvider.js.map +1 -1
  67. package/lib/esm/presentation-frontend/Diagnostics.d.ts.map +1 -1
  68. package/lib/esm/presentation-frontend/Diagnostics.js +18 -13
  69. package/lib/esm/presentation-frontend/Diagnostics.js.map +1 -1
  70. package/lib/esm/presentation-frontend/FrontendLoggerCategory.js +3 -3
  71. package/lib/esm/presentation-frontend/FrontendLoggerCategory.js.map +1 -1
  72. package/lib/esm/presentation-frontend/IpcRequestsHandler.d.ts.map +1 -1
  73. package/lib/esm/presentation-frontend/IpcRequestsHandler.js +3 -3
  74. package/lib/esm/presentation-frontend/IpcRequestsHandler.js.map +1 -1
  75. package/lib/esm/presentation-frontend/LocalizationHelper.js +3 -3
  76. package/lib/esm/presentation-frontend/LocalizationHelper.js.map +1 -1
  77. package/lib/esm/presentation-frontend/Presentation.d.ts.map +1 -1
  78. package/lib/esm/presentation-frontend/Presentation.js +26 -16
  79. package/lib/esm/presentation-frontend/Presentation.js.map +1 -1
  80. package/lib/esm/presentation-frontend/PresentationManager.d.ts +84 -21
  81. package/lib/esm/presentation-frontend/PresentationManager.d.ts.map +1 -1
  82. package/lib/esm/presentation-frontend/PresentationManager.js +244 -152
  83. package/lib/esm/presentation-frontend/PresentationManager.js.map +1 -1
  84. package/lib/esm/presentation-frontend/RulesetManager.d.ts.map +1 -1
  85. package/lib/esm/presentation-frontend/RulesetManager.js +11 -7
  86. package/lib/esm/presentation-frontend/RulesetManager.js.map +1 -1
  87. package/lib/esm/presentation-frontend/RulesetVariablesManager.d.ts.map +1 -1
  88. package/lib/esm/presentation-frontend/RulesetVariablesManager.js +53 -31
  89. package/lib/esm/presentation-frontend/RulesetVariablesManager.js.map +1 -1
  90. package/lib/esm/presentation-frontend/StreamedResponseGenerator.d.ts +30 -0
  91. package/lib/esm/presentation-frontend/StreamedResponseGenerator.d.ts.map +1 -0
  92. package/lib/esm/presentation-frontend/StreamedResponseGenerator.js +113 -0
  93. package/lib/esm/presentation-frontend/StreamedResponseGenerator.js.map +1 -0
  94. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts +33 -4
  95. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.d.ts.map +1 -1
  96. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js +179 -74
  97. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesManager.js.map +1 -1
  98. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.d.ts.map +1 -1
  99. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js +54 -25
  100. package/lib/esm/presentation-frontend/favorite-properties/FavoritePropertiesStorage.js.map +1 -1
  101. package/lib/esm/presentation-frontend/selection/HiliteRules.json +172 -172
  102. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.d.ts.map +1 -1
  103. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.js +24 -14
  104. package/lib/esm/presentation-frontend/selection/HiliteSetProvider.js.map +1 -1
  105. package/lib/esm/presentation-frontend/selection/ISelectionProvider.js +3 -3
  106. package/lib/esm/presentation-frontend/selection/ISelectionProvider.js.map +1 -1
  107. package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.d.ts.map +1 -1
  108. package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.js +3 -3
  109. package/lib/esm/presentation-frontend/selection/SelectionChangeEvent.js.map +1 -1
  110. package/lib/esm/presentation-frontend/selection/SelectionHandler.d.ts.map +1 -1
  111. package/lib/esm/presentation-frontend/selection/SelectionHandler.js +15 -9
  112. package/lib/esm/presentation-frontend/selection/SelectionHandler.js.map +1 -1
  113. package/lib/esm/presentation-frontend/selection/SelectionHelper.d.ts.map +1 -1
  114. package/lib/esm/presentation-frontend/selection/SelectionHelper.js +7 -5
  115. package/lib/esm/presentation-frontend/selection/SelectionHelper.js.map +1 -1
  116. package/lib/esm/presentation-frontend/selection/SelectionManager.d.ts.map +1 -1
  117. package/lib/esm/presentation-frontend/selection/SelectionManager.js +31 -16
  118. package/lib/esm/presentation-frontend/selection/SelectionManager.js.map +1 -1
  119. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.d.ts.map +1 -1
  120. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js +25 -14
  121. package/lib/esm/presentation-frontend/selection/SelectionScopesManager.js.map +1 -1
  122. package/lib/esm/presentation-frontend.js +3 -3
  123. package/lib/esm/presentation-frontend.js.map +1 -1
  124. package/package.json +19 -16
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
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
- *--------------------------------------------------------------------------------------------*/
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
6
  /** @packageDocumentation
7
7
  * @module Core
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.buildPagedArrayResponse = exports.PresentationManager = void 0;
10
+ exports.PresentationManager = void 0;
11
11
  const core_bentley_1 = require("@itwin/core-bentley");
12
12
  const core_frontend_1 = require("@itwin/core-frontend");
13
13
  const presentation_common_1 = require("@itwin/presentation-common");
@@ -16,6 +16,7 @@ const LocalizationHelper_1 = require("./LocalizationHelper");
16
16
  const RulesetManager_1 = require("./RulesetManager");
17
17
  const RulesetVariablesManager_1 = require("./RulesetVariablesManager");
18
18
  const SelectionManager_1 = require("./selection/SelectionManager");
19
+ const StreamedResponseGenerator_1 = require("./StreamedResponseGenerator");
19
20
  /**
20
21
  * Frontend Presentation manager which basically just forwards all calls to
21
22
  * the backend implementation.
@@ -33,7 +34,9 @@ class PresentationManager {
33
34
  get activeUnitSystem() {
34
35
  return this._explicitActiveUnitSystem ?? core_frontend_1.IModelApp.quantityFormatter.activeUnitSystem;
35
36
  }
36
- set activeUnitSystem(value) { this._explicitActiveUnitSystem = value; }
37
+ set activeUnitSystem(value) {
38
+ this._explicitActiveUnitSystem = value;
39
+ }
37
40
  constructor(props) {
38
41
  /**
39
42
  * An event raised when hierarchies created using specific ruleset change
@@ -54,11 +57,11 @@ class PresentationManager {
54
57
  // eslint-disable-next-line deprecation/deprecation
55
58
  this._explicitActiveUnitSystem = props.activeUnitSystem;
56
59
  }
57
- this._requestsHandler = props?.rpcRequestsHandler ?? new presentation_common_1.RpcRequestsHandler(props ? { clientId: props.clientId, timeout: props.requestTimeout } : undefined);
60
+ this._requestsHandler =
61
+ props?.rpcRequestsHandler ?? new presentation_common_1.RpcRequestsHandler(props ? { clientId: props.clientId, timeout: props.requestTimeout } : undefined);
58
62
  this._rulesetVars = new Map();
59
63
  this._rulesets = RulesetManager_1.RulesetManagerImpl.create();
60
64
  this._localizationHelper = new LocalizationHelper_1.FrontendLocalizationHelper(props?.activeLocale);
61
- this._connections = new Map();
62
65
  this._schemaContextProvider = props?.schemaContextProvider;
63
66
  this._defaultFormats = props?.defaultFormats;
64
67
  if (core_frontend_1.IpcApp.isValid) {
@@ -68,41 +71,38 @@ class PresentationManager {
68
71
  }
69
72
  }
70
73
  /** Get / set active locale used for localizing presentation data */
71
- get activeLocale() { return this._localizationHelper.locale; }
72
- set activeLocale(locale) { this._localizationHelper.locale = locale; }
74
+ get activeLocale() {
75
+ return this._localizationHelper.locale;
76
+ }
77
+ set activeLocale(locale) {
78
+ this._localizationHelper.locale = locale;
79
+ }
73
80
  dispose() {
74
81
  if (this._clearEventListener) {
75
82
  this._clearEventListener();
76
83
  this._clearEventListener = undefined;
77
84
  }
78
85
  }
79
- async onConnection(imodel) {
80
- if (!this._connections.has(imodel))
81
- this._connections.set(imodel, this.initializeIModel(imodel));
82
- await this._connections.get(imodel);
83
- }
84
- async initializeIModel(imodel) {
85
- imodel.onClose.addOnce(() => {
86
- this._connections.delete(imodel);
87
- });
88
- await this.onNewiModelConnection(imodel);
89
- }
90
86
  /** @note This is only called in native apps after changes in iModels */
91
87
  async handleUpdateAsync(report) {
92
88
  for (const imodelKey in report) {
93
89
  // istanbul ignore if
94
- if (!report.hasOwnProperty(imodelKey))
90
+ if (!report.hasOwnProperty(imodelKey)) {
95
91
  continue;
92
+ }
96
93
  const imodelReport = report[imodelKey];
97
94
  for (const rulesetId in imodelReport) {
98
95
  // istanbul ignore if
99
- if (!imodelReport.hasOwnProperty(rulesetId))
96
+ if (!imodelReport.hasOwnProperty(rulesetId)) {
100
97
  continue;
98
+ }
101
99
  const updateInfo = imodelReport[rulesetId];
102
- if (updateInfo.content)
100
+ if (updateInfo.content) {
103
101
  this.onIModelContentChanged.raiseEvent({ rulesetId, updateInfo: updateInfo.content, imodelKey });
104
- if (updateInfo.hierarchy)
102
+ }
103
+ if (updateInfo.hierarchy) {
105
104
  this.onIModelHierarchyChanged.raiseEvent({ rulesetId, updateInfo: updateInfo.hierarchy, imodelKey });
105
+ }
106
106
  }
107
107
  }
108
108
  }
@@ -110,7 +110,13 @@ class PresentationManager {
110
110
  * Function that is called when a new IModelConnection is used to retrieve data.
111
111
  * @internal
112
112
  */
113
- async onNewiModelConnection(_) { }
113
+ startIModelInitialization(_) { }
114
+ /**
115
+ * Function that should be called to finish initialization that was started at [[PresentationManager.startIModelInitialization]].
116
+ * Can be removed when [[FavoritePropertiesManager.has]] and [[FavoritePropertiesManager.sortFields]] are removed.
117
+ * @internal
118
+ */
119
+ async ensureIModelInitialized(_) { }
114
120
  /**
115
121
  * Create a new PresentationManager instance
116
122
  * @param props Optional properties used to configure the manager
@@ -119,13 +125,19 @@ class PresentationManager {
119
125
  return new PresentationManager(props);
120
126
  }
121
127
  /** @internal */
122
- get rpcRequestsHandler() { return this._requestsHandler; }
128
+ get rpcRequestsHandler() {
129
+ return this._requestsHandler;
130
+ }
123
131
  /** @internal */
124
- get ipcRequestsHandler() { return this._ipcRequestsHandler; }
132
+ get ipcRequestsHandler() {
133
+ return this._ipcRequestsHandler;
134
+ }
125
135
  /**
126
136
  * Get rulesets manager
127
137
  */
128
- rulesets() { return this._rulesets; }
138
+ rulesets() {
139
+ return this._rulesets;
140
+ }
129
141
  /**
130
142
  * Get ruleset variables manager for specific ruleset
131
143
  * @param rulesetId Id of the ruleset to get the vars manager for
@@ -142,8 +154,9 @@ class PresentationManager {
142
154
  // 2. put all `requestOptions` members (if `locale` or `unitSystem` are set, they'll override the defaults put at #1)
143
155
  // 3. put `imodel` of type `IModelRpcProps` which overwrites the `imodel` from `requestOptions` put at #2
144
156
  const defaultOptions = {};
145
- if (this.activeLocale)
157
+ if (this.activeLocale) {
146
158
  defaultOptions.locale = this.activeLocale;
159
+ }
147
160
  defaultOptions.unitSystem = this.activeUnitSystem; // eslint-disable-line deprecation/deprecation
148
161
  const { imodel, rulesetVariables, ...rpcRequestOptions } = requestOptions;
149
162
  return {
@@ -163,13 +176,14 @@ class PresentationManager {
163
176
  const foundRuleset = await this._rulesets.get(rulesetOrId);
164
177
  foundRulesetOrId = foundRuleset ? foundRuleset.toJSON() : rulesetOrId;
165
178
  }
166
- const rulesetId = (typeof foundRulesetOrId === "object") ? foundRulesetOrId.id : foundRulesetOrId;
179
+ const rulesetId = typeof foundRulesetOrId === "object" ? foundRulesetOrId.id : foundRulesetOrId;
167
180
  // All Id64Array variable values must be sorted for serialization to JSON to work. RulesetVariablesManager
168
181
  // sorts them before storing, so that part is taken care of, but we need to ensure that variables coming from
169
182
  // request options are also sorted.
170
183
  const variables = (rulesetVariables ?? []).map((variable) => {
171
- if (variable.type === presentation_common_1.VariableValueTypes.Id64Array)
184
+ if (variable.type === presentation_common_1.VariableValueTypes.Id64Array) {
172
185
  return { ...variable, value: core_bentley_1.OrderedId64Iterable.sortArray(variable.value) };
186
+ }
173
187
  return variable;
174
188
  });
175
189
  if (!this._ipcRequestsHandler) {
@@ -179,32 +193,48 @@ class PresentationManager {
179
193
  }
180
194
  return { ...options, rulesetOrId: foundRulesetOrId, rulesetVariables: variables };
181
195
  }
182
- /** Retrieves nodes */
183
- async getNodes(requestOptions) {
184
- await this.onConnection(requestOptions.imodel);
196
+ /** Returns an iterator that polls nodes asynchronously. */
197
+ async getNodesIterator(requestOptions) {
198
+ this.startIModelInitialization(requestOptions.imodel);
185
199
  const options = await this.addRulesetAndVariablesToOptions(requestOptions);
186
200
  const rpcOptions = this.toRpcTokenOptions({ ...options });
187
- const result = await (0, exports.buildPagedArrayResponse)(options.paging, async (partialPageOptions) => this._requestsHandler.getPagedNodes({ ...rpcOptions, paging: partialPageOptions }));
188
- // eslint-disable-next-line deprecation/deprecation
189
- return this._localizationHelper.getLocalizedNodes(result.items.map(presentation_common_1.Node.fromJSON));
201
+ const generator = new StreamedResponseGenerator_1.StreamedResponseGenerator({
202
+ ...requestOptions,
203
+ getBatch: async (paging) => {
204
+ const result = await this._requestsHandler.getPagedNodes({ ...rpcOptions, paging });
205
+ return {
206
+ total: result.total,
207
+ // eslint-disable-next-line deprecation/deprecation
208
+ items: this._localizationHelper.getLocalizedNodes(result.items.map(presentation_common_1.Node.fromJSON)),
209
+ };
210
+ },
211
+ });
212
+ return generator.createAsyncIteratorResponse();
213
+ }
214
+ /**
215
+ * Retrieves nodes
216
+ * @deprecated in 4.5. Use [[getNodesIterator]] instead.
217
+ */
218
+ async getNodes(requestOptions) {
219
+ const result = await this.getNodesIterator(requestOptions);
220
+ return collect(result.items);
190
221
  }
191
222
  /** Retrieves nodes count. */
192
223
  async getNodesCount(requestOptions) {
193
- await this.onConnection(requestOptions.imodel);
224
+ this.startIModelInitialization(requestOptions.imodel);
194
225
  const options = await this.addRulesetAndVariablesToOptions(requestOptions);
195
226
  const rpcOptions = this.toRpcTokenOptions({ ...options });
196
227
  return this._requestsHandler.getNodesCount(rpcOptions);
197
228
  }
198
- /** Retrieves total nodes count and a single page of nodes. */
229
+ /**
230
+ * Retrieves total nodes count and a single page of nodes.
231
+ * @deprecated in 4.5. Use [[getNodesIterator]] instead.
232
+ */
199
233
  async getNodesAndCount(requestOptions) {
200
- await this.onConnection(requestOptions.imodel);
201
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
202
- const rpcOptions = this.toRpcTokenOptions({ ...options });
203
- const result = await (0, exports.buildPagedArrayResponse)(options.paging, async (partialPageOptions) => this._requestsHandler.getPagedNodes({ ...rpcOptions, paging: partialPageOptions }));
234
+ const result = await this.getNodesIterator(requestOptions);
204
235
  return {
205
236
  count: result.total,
206
- // eslint-disable-next-line deprecation/deprecation
207
- nodes: this._localizationHelper.getLocalizedNodes(result.items.map(presentation_common_1.Node.fromJSON)),
237
+ nodes: await collect(result.items),
208
238
  };
209
239
  }
210
240
  /**
@@ -212,16 +242,21 @@ class PresentationManager {
212
242
  * @beta
213
243
  */
214
244
  async getNodesDescriptor(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.getNodesDescriptor(rpcOptions);
219
- const descriptor = presentation_common_1.Descriptor.fromJSON(result);
220
- return descriptor ? this._localizationHelper.getLocalizedContentDescriptor(descriptor) : undefined;
245
+ this.startIModelInitialization(requestOptions.imodel);
246
+ try {
247
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
248
+ const rpcOptions = this.toRpcTokenOptions({ ...options });
249
+ const result = await this._requestsHandler.getNodesDescriptor(rpcOptions);
250
+ const descriptor = presentation_common_1.Descriptor.fromJSON(result);
251
+ return descriptor ? this._localizationHelper.getLocalizedContentDescriptor(descriptor) : undefined;
252
+ }
253
+ finally {
254
+ await this.ensureIModelInitialized(requestOptions.imodel);
255
+ }
221
256
  }
222
257
  /** Retrieves paths from root nodes to children nodes according to specified keys. Intersecting paths will be merged. */
223
258
  async getNodePaths(requestOptions) {
224
- await this.onConnection(requestOptions.imodel);
259
+ this.startIModelInitialization(requestOptions.imodel);
225
260
  const options = await this.addRulesetAndVariablesToOptions(requestOptions);
226
261
  const rpcOptions = this.toRpcTokenOptions({ ...options });
227
262
  const result = await this._requestsHandler.getNodePaths(rpcOptions);
@@ -230,7 +265,7 @@ class PresentationManager {
230
265
  }
231
266
  /** Retrieves paths from root nodes to nodes containing filter text in their label. */
232
267
  async getFilteredNodePaths(requestOptions) {
233
- await this.onConnection(requestOptions.imodel);
268
+ this.startIModelInitialization(requestOptions.imodel);
234
269
  const options = await this.addRulesetAndVariablesToOptions(requestOptions);
235
270
  const result = await this._requestsHandler.getFilteredNodePaths(this.toRpcTokenOptions(options));
236
271
  // eslint-disable-next-line deprecation/deprecation
@@ -242,26 +277,31 @@ class PresentationManager {
242
277
  * @public
243
278
  */
244
279
  async getContentSources(requestOptions) {
245
- await this.onConnection(requestOptions.imodel);
280
+ this.startIModelInitialization(requestOptions.imodel);
246
281
  const rpcOptions = this.toRpcTokenOptions(requestOptions);
247
282
  const result = await this._requestsHandler.getContentSources(rpcOptions);
248
283
  return presentation_common_1.SelectClassInfo.listFromCompressedJSON(result.sources, result.classesMap);
249
284
  }
250
285
  /** Retrieves the content descriptor which describes the content and can be used to customize it. */
251
286
  async getContentDescriptor(requestOptions) {
252
- await this.onConnection(requestOptions.imodel);
253
- const options = await this.addRulesetAndVariablesToOptions(requestOptions);
254
- const rpcOptions = this.toRpcTokenOptions({
255
- ...options,
256
- keys: stripTransientElementKeys(options.keys).toJSON(),
257
- });
258
- const result = await this._requestsHandler.getContentDescriptor(rpcOptions);
259
- const descriptor = presentation_common_1.Descriptor.fromJSON(result);
260
- return descriptor ? this._localizationHelper.getLocalizedContentDescriptor(descriptor) : undefined;
287
+ this.startIModelInitialization(requestOptions.imodel);
288
+ try {
289
+ const options = await this.addRulesetAndVariablesToOptions(requestOptions);
290
+ const rpcOptions = this.toRpcTokenOptions({
291
+ ...options,
292
+ keys: stripTransientElementKeys(options.keys).toJSON(),
293
+ });
294
+ const result = await this._requestsHandler.getContentDescriptor(rpcOptions);
295
+ const descriptor = presentation_common_1.Descriptor.fromJSON(result);
296
+ return descriptor ? this._localizationHelper.getLocalizedContentDescriptor(descriptor) : undefined;
297
+ }
298
+ finally {
299
+ await this.ensureIModelInitialized(requestOptions.imodel);
300
+ }
261
301
  }
262
302
  /** Retrieves overall content set size. */
263
303
  async getContentSetSize(requestOptions) {
264
- await this.onConnection(requestOptions.imodel);
304
+ this.startIModelInitialization(requestOptions.imodel);
265
305
  const options = await this.addRulesetAndVariablesToOptions(requestOptions);
266
306
  const rpcOptions = this.toRpcTokenOptions({
267
307
  ...options,
@@ -270,13 +310,7 @@ class PresentationManager {
270
310
  });
271
311
  return this._requestsHandler.getContentSetSize(rpcOptions);
272
312
  }
273
- /** Retrieves content which consists of a content descriptor and a page of records. */
274
- async getContent(requestOptions) {
275
- return (await this.getContentAndSize(requestOptions))?.content;
276
- }
277
- /** Retrieves content set size and content which consists of a content descriptor and a page of records. */
278
- async getContentAndSize(requestOptions) {
279
- await this.onConnection(requestOptions.imodel);
313
+ async getContentIteratorInternal(requestOptions) {
280
314
  const options = await this.addRulesetAndVariablesToOptions(requestOptions);
281
315
  const rpcOptions = this.toRpcTokenOptions({
282
316
  ...options,
@@ -284,46 +318,113 @@ class PresentationManager {
284
318
  keys: stripTransientElementKeys(requestOptions.keys).toJSON(),
285
319
  ...(!requestOptions.omitFormattedValues && this._schemaContextProvider !== undefined ? { omitFormattedValues: true } : undefined),
286
320
  });
287
- let descriptor = (requestOptions.descriptor instanceof presentation_common_1.Descriptor) ? requestOptions.descriptor : undefined;
288
- const result = await (0, exports.buildPagedArrayResponse)(options.paging, async (partialPageOptions, requestIndex) => {
289
- if (0 === requestIndex && !descriptor) {
290
- const content = await this._requestsHandler.getPagedContent({ ...rpcOptions, paging: partialPageOptions });
291
- if (content) {
292
- descriptor = presentation_common_1.Descriptor.fromJSON(content.descriptor);
293
- return content.contentSet;
294
- }
295
- return { total: 0, items: [] };
321
+ let contentFormatter;
322
+ if (!requestOptions.omitFormattedValues && this._schemaContextProvider) {
323
+ const koqPropertyFormatter = new presentation_common_1.KoqPropertyValueFormatter(this._schemaContextProvider(requestOptions.imodel), this._defaultFormats);
324
+ contentFormatter = new presentation_common_1.ContentFormatter(new presentation_common_1.ContentPropertyValueFormatter(koqPropertyFormatter), requestOptions.unitSystem ?? this._explicitActiveUnitSystem ?? core_frontend_1.IModelApp.quantityFormatter.activeUnitSystem);
325
+ }
326
+ let descriptor = requestOptions.descriptor instanceof presentation_common_1.Descriptor ? requestOptions.descriptor : undefined;
327
+ let firstPage;
328
+ if (!descriptor) {
329
+ const firstPageResponse = await this._requestsHandler.getPagedContent(rpcOptions);
330
+ if (!firstPageResponse?.descriptor || !firstPageResponse.contentSet) {
331
+ return undefined;
296
332
  }
297
- return this._requestsHandler.getPagedContentSet({ ...rpcOptions, paging: partialPageOptions });
333
+ descriptor = presentation_common_1.Descriptor.fromJSON(firstPageResponse?.descriptor);
334
+ firstPage = firstPageResponse?.contentSet;
335
+ }
336
+ // istanbul ignore if
337
+ if (!descriptor) {
338
+ return undefined;
339
+ }
340
+ descriptor = this._localizationHelper.getLocalizedContentDescriptor(descriptor);
341
+ const getPage = async (paging, requestIndex) => {
342
+ let contentSet = requestIndex === 0 ? firstPage : undefined;
343
+ contentSet ??= await this._requestsHandler.getPagedContentSet({ ...rpcOptions, paging });
344
+ let items = contentSet.items.map((x) => presentation_common_1.Item.fromJSON(x)).filter((x) => x !== undefined);
345
+ if (contentFormatter) {
346
+ items = await contentFormatter.formatContentItems(items, descriptor);
347
+ }
348
+ items = this._localizationHelper.getLocalizedContentItems(items);
349
+ return {
350
+ total: contentSet.total,
351
+ items,
352
+ };
353
+ };
354
+ const generator = new StreamedResponseGenerator_1.StreamedResponseGenerator({
355
+ ...requestOptions,
356
+ getBatch: getPage,
298
357
  });
299
- if (!descriptor)
358
+ return {
359
+ ...(await generator.createAsyncIteratorResponse()),
360
+ descriptor,
361
+ };
362
+ }
363
+ /** Retrieves a content descriptor, item count and async generator for the items themselves. */
364
+ async getContentIterator(requestOptions) {
365
+ this.startIModelInitialization(requestOptions.imodel);
366
+ const response = await this.getContentIteratorInternal(requestOptions);
367
+ if (!response) {
368
+ return undefined;
369
+ }
370
+ await this.ensureIModelInitialized(requestOptions.imodel);
371
+ return response;
372
+ }
373
+ /**
374
+ * Retrieves content which consists of a content descriptor and a page of records.
375
+ * @deprecated in 4.5. Use [[getContentIterator]] instead.
376
+ */
377
+ async getContent(requestOptions) {
378
+ // eslint-disable-next-line deprecation/deprecation
379
+ return (await this.getContentAndSize(requestOptions))?.content;
380
+ }
381
+ /**
382
+ * Retrieves content set size and content which consists of a content descriptor and a page of records.
383
+ * @deprecated in 4.5. Use [[getContentIterator]] instead.
384
+ */
385
+ async getContentAndSize(requestOptions) {
386
+ const response = await this.getContentIterator(requestOptions);
387
+ if (!response) {
300
388
  return undefined;
301
- const items = result.items.map((itemJson) => presentation_common_1.Item.fromJSON(itemJson)).filter((item) => (item !== undefined));
302
- const resultContent = new presentation_common_1.Content(descriptor, items);
303
- if (!requestOptions.omitFormattedValues && this._schemaContextProvider) {
304
- const koqPropertyFormatter = new presentation_common_1.KoqPropertyValueFormatter(this._schemaContextProvider(requestOptions.imodel), this._defaultFormats);
305
- const contentFormatter = new presentation_common_1.ContentFormatter(new presentation_common_1.ContentPropertyValueFormatter(koqPropertyFormatter), requestOptions.unitSystem ?? this._explicitActiveUnitSystem ?? core_frontend_1.IModelApp.quantityFormatter.activeUnitSystem);
306
- await contentFormatter.formatContent(resultContent);
307
389
  }
390
+ const { descriptor, total } = response;
391
+ const items = await collect(response.items);
308
392
  return {
309
- size: result.total,
310
- content: this._localizationHelper.getLocalizedContent(resultContent),
393
+ content: new presentation_common_1.Content(descriptor, items),
394
+ size: total,
311
395
  };
312
396
  }
313
- /** Retrieves distinct values of specific field from the content. */
314
- async getPagedDistinctValues(requestOptions) {
315
- await this.onConnection(requestOptions.imodel);
397
+ /** Returns an iterator that asynchronously polls distinct values of specific field from the content. */
398
+ async getDistinctValuesIterator(requestOptions) {
399
+ this.startIModelInitialization(requestOptions.imodel);
316
400
  const options = await this.addRulesetAndVariablesToOptions(requestOptions);
317
401
  const rpcOptions = {
318
402
  ...this.toRpcTokenOptions(options),
319
403
  descriptor: getDescriptorOverrides(options.descriptor),
320
404
  keys: stripTransientElementKeys(options.keys).toJSON(),
321
405
  };
322
- const result = await (0, exports.buildPagedArrayResponse)(requestOptions.paging, async (partialPageOptions) => this._requestsHandler.getPagedDistinctValues({ ...rpcOptions, paging: partialPageOptions }));
406
+ const generator = new StreamedResponseGenerator_1.StreamedResponseGenerator({
407
+ ...requestOptions,
408
+ getBatch: async (paging) => {
409
+ const response = await this._requestsHandler.getPagedDistinctValues({ ...rpcOptions, paging });
410
+ return {
411
+ total: response.total,
412
+ // eslint-disable-next-line deprecation/deprecation
413
+ items: response.items.map((x) => this._localizationHelper.getLocalizedDisplayValueGroup(presentation_common_1.DisplayValueGroup.fromJSON(x))),
414
+ };
415
+ },
416
+ });
417
+ return generator.createAsyncIteratorResponse();
418
+ }
419
+ /**
420
+ * Retrieves distinct values of specific field from the content.
421
+ * @deprecated in 4.5. Use [[getDistinctValuesIterator]] instead.
422
+ */
423
+ async getPagedDistinctValues(requestOptions) {
424
+ const result = await this.getDistinctValuesIterator(requestOptions);
323
425
  return {
324
- ...result,
325
- // eslint-disable-next-line deprecation/deprecation
326
- items: result.items.map(presentation_common_1.DisplayValueGroup.fromJSON).map((g) => this._localizationHelper.getLocalizedDisplayValueGroup(g)),
426
+ total: result.total,
427
+ items: await collect(result.items),
327
428
  };
328
429
  }
329
430
  /**
@@ -331,11 +432,12 @@ class PresentationManager {
331
432
  * @public
332
433
  */
333
434
  async getElementProperties(requestOptions) {
334
- await this.onConnection(requestOptions.imodel);
435
+ this.startIModelInitialization(requestOptions.imodel);
335
436
  const results = await this._requestsHandler.getElementProperties(this.toRpcTokenOptions(requestOptions));
336
437
  // istanbul ignore if
337
- if (!results)
438
+ if (!results) {
338
439
  return undefined;
440
+ }
339
441
  return this._localizationHelper.getLocalizedElementProperties(results);
340
442
  }
341
443
  /**
@@ -343,15 +445,15 @@ class PresentationManager {
343
445
  * @public
344
446
  */
345
447
  async getContentInstanceKeys(requestOptions) {
346
- await this.onConnection(requestOptions.imodel);
448
+ this.startIModelInitialization(requestOptions.imodel);
347
449
  const options = await this.addRulesetAndVariablesToOptions(requestOptions);
348
450
  const rpcOptions = {
349
451
  ...this.toRpcTokenOptions(options),
350
452
  keys: stripTransientElementKeys(options.keys).toJSON(),
351
453
  };
352
- const props = {
353
- page: requestOptions.paging,
354
- get: async (page) => {
454
+ const generator = new StreamedResponseGenerator_1.StreamedResponseGenerator({
455
+ ...requestOptions,
456
+ getBatch: async (page) => {
355
457
  const keys = await this._requestsHandler.getContentInstanceKeys({ ...rpcOptions, paging: page });
356
458
  return {
357
459
  total: keys.total,
@@ -363,84 +465,73 @@ class PresentationManager {
363
465
  }, new Array()),
364
466
  };
365
467
  },
468
+ });
469
+ const { total, items } = await generator.createAsyncIteratorResponse();
470
+ return {
471
+ total,
472
+ async *items() {
473
+ yield* items;
474
+ },
366
475
  };
367
- return createPagedGeneratorResponse(props);
368
476
  }
369
477
  /** Retrieves display label definition of specific item. */
370
478
  async getDisplayLabelDefinition(requestOptions) {
371
- await this.onConnection(requestOptions.imodel);
479
+ this.startIModelInitialization(requestOptions.imodel);
372
480
  const rpcOptions = this.toRpcTokenOptions({ ...requestOptions });
373
481
  const result = await this._requestsHandler.getDisplayLabelDefinition(rpcOptions);
374
482
  return this._localizationHelper.getLocalizedLabelDefinition(result);
375
483
  }
376
484
  /** Retrieves display label definition of specific items. */
377
- async getDisplayLabelDefinitions(requestOptions) {
378
- await this.onConnection(requestOptions.imodel);
485
+ async getDisplayLabelDefinitionsIterator(requestOptions) {
486
+ this.startIModelInitialization(requestOptions.imodel);
379
487
  const rpcOptions = this.toRpcTokenOptions({ ...requestOptions });
380
- const result = await (0, exports.buildPagedArrayResponse)(undefined, async (partialPageOptions) => {
381
- const partialKeys = (!partialPageOptions.start) ? rpcOptions.keys : rpcOptions.keys.slice(partialPageOptions.start);
382
- return this._requestsHandler.getPagedDisplayLabelDefinitions({ ...rpcOptions, keys: partialKeys });
488
+ const generator = new StreamedResponseGenerator_1.StreamedResponseGenerator({
489
+ ...requestOptions,
490
+ getBatch: async (page) => {
491
+ const partialKeys = !page.start ? rpcOptions.keys : rpcOptions.keys.slice(page.start);
492
+ const result = await this._requestsHandler.getPagedDisplayLabelDefinitions({ ...rpcOptions, keys: partialKeys });
493
+ result.items = this._localizationHelper.getLocalizedLabelDefinitions(result.items);
494
+ return result;
495
+ },
383
496
  });
384
- return this._localizationHelper.getLocalizedLabelDefinitions(result.items);
497
+ return generator.createAsyncIteratorResponse();
498
+ }
499
+ /**
500
+ * Retrieves display label definition of specific items.
501
+ * @deprecated in 4.5. Use [[getDisplayLabelDefinitionsIterator]] instead.
502
+ */
503
+ async getDisplayLabelDefinitions(requestOptions) {
504
+ const { items } = await this.getDisplayLabelDefinitionsIterator(requestOptions);
505
+ return collect(items);
385
506
  }
386
507
  }
387
508
  exports.PresentationManager = PresentationManager;
388
509
  const getDescriptorOverrides = (descriptorOrOverrides) => {
389
- if (descriptorOrOverrides instanceof presentation_common_1.Descriptor)
510
+ if (descriptorOrOverrides instanceof presentation_common_1.Descriptor) {
390
511
  return descriptorOrOverrides.createDescriptorOverrides();
512
+ }
391
513
  return descriptorOrOverrides;
392
514
  };
393
- async function createPagedGeneratorResponse(props) {
394
- let pageStart = props.page?.start ?? 0;
395
- let pageSize = props.page?.size ?? 0;
396
- let requestIndex = 0;
397
- const firstPage = await props.get({ start: pageStart, size: pageSize }, requestIndex++);
398
- return {
399
- total: firstPage.total,
400
- async *items() {
401
- let partialResult = firstPage;
402
- while (true) {
403
- for (const item of partialResult.items) {
404
- yield item;
405
- }
406
- const receivedItemsCount = partialResult.items.length;
407
- if (partialResult.total !== 0 && receivedItemsCount === 0) {
408
- if (pageStart >= partialResult.total)
409
- throw new Error(`Requested page with start index ${pageStart} is out of bounds. Total number of items: ${partialResult.total}`);
410
- throw new Error("Paged request returned non zero total count but no items");
411
- }
412
- if (pageSize !== 0 && receivedItemsCount >= pageSize || receivedItemsCount >= (partialResult.total - pageStart))
413
- break;
414
- if (pageSize !== 0)
415
- pageSize -= receivedItemsCount;
416
- pageStart += receivedItemsCount;
417
- partialResult = await props.get({ start: pageStart, size: pageSize }, requestIndex++);
418
- }
419
- },
420
- };
421
- }
422
- /** @internal */
423
- const buildPagedArrayResponse = async (requestedPage, getter) => {
424
- const items = new Array();
425
- const gen = await createPagedGeneratorResponse({ page: requestedPage, get: getter });
426
- for await (const item of gen.items()) {
427
- items.push(item);
428
- }
429
- return { total: gen.total, items };
430
- };
431
- exports.buildPagedArrayResponse = buildPagedArrayResponse;
432
515
  const stripTransientElementKeys = (keys) => {
433
- if (!keys.some((key) => presentation_common_1.Key.isInstanceKey(key) && key.className === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME))
516
+ if (!keys.some((key) => presentation_common_1.Key.isInstanceKey(key) && key.className === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME)) {
434
517
  return keys;
518
+ }
435
519
  const copy = new presentation_common_1.KeySet();
436
520
  copy.add(keys, (key) => {
437
521
  // the callback is not going to be called with EntityProps as KeySet converts them
438
522
  // to InstanceKeys, but we want to keep the EntityProps case for correctness
439
523
  // istanbul ignore next
440
- const isTransient = presentation_common_1.Key.isInstanceKey(key) && key.className === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME
441
- || presentation_common_1.Key.isEntityProps(key) && key.classFullName === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME;
524
+ const isTransient = (presentation_common_1.Key.isInstanceKey(key) && key.className === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME) ||
525
+ (presentation_common_1.Key.isEntityProps(key) && key.classFullName === SelectionManager_1.TRANSIENT_ELEMENT_CLASSNAME);
442
526
  return !isTransient;
443
527
  });
444
528
  return copy;
445
529
  };
530
+ async function collect(iter) {
531
+ const result = new Array();
532
+ for await (const value of iter) {
533
+ result.push(value);
534
+ }
535
+ return result;
536
+ }
446
537
  //# sourceMappingURL=PresentationManager.js.map