@itwin/ecschema-rpcinterface-tests 5.7.0-dev.13 → 5.7.0-dev.15

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.
@@ -22875,6 +22875,10 @@ class ObservableSet extends Set {
22875
22875
  onDeleted = new _BeEvent__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
22876
22876
  /** Emitted after this set's contents are cleared. */
22877
22877
  onCleared = new _BeEvent__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
22878
+ /** Emitted after multiple items are added to this set via [[addAll]]. */
22879
+ onBatchAdded = new _BeEvent__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
22880
+ /** Emitted after multiple items are deleted from this set via [[deleteAll]]. */
22881
+ onBatchDeleted = new _BeEvent__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
22878
22882
  /** Construct a new ObservableSet.
22879
22883
  * @param elements Optional elements with which to populate the new set.
22880
22884
  */
@@ -22907,6 +22911,32 @@ class ObservableSet extends Set {
22907
22911
  this.onCleared.raiseEvent();
22908
22912
  }
22909
22913
  }
22914
+ /** Add multiple items to the set, raising [[onBatchAdded]] only once after all items are added.
22915
+ * This is more efficient than calling [[add]] in a loop when listeners need not be notified of each individual addition.
22916
+ * @param items The items to add.
22917
+ * @returns The number of items that were actually added (i.e., were not already present).
22918
+ */
22919
+ addAll(items) {
22920
+ const prevSize = this.size;
22921
+ for (const item of items)
22922
+ super.add(item);
22923
+ if (this.size !== prevSize)
22924
+ this.onBatchAdded.raiseEvent();
22925
+ return this.size - prevSize;
22926
+ }
22927
+ /** Delete multiple items from the set, raising [[onBatchDeleted]] only once after all items are deleted.
22928
+ * This is more efficient than calling [[delete]] in a loop when listeners need not be notified of each individual deletion.
22929
+ * @param items The items to delete.
22930
+ * @returns The number of items that were actually deleted (i.e., were present in the set).
22931
+ */
22932
+ deleteAll(items) {
22933
+ const prevSize = this.size;
22934
+ for (const item of items)
22935
+ super.delete(item);
22936
+ if (this.size !== prevSize)
22937
+ this.onBatchDeleted.raiseEvent();
22938
+ return prevSize - this.size;
22939
+ }
22910
22940
  }
22911
22941
 
22912
22942
 
@@ -23015,11 +23045,15 @@ class OneAtATimeAction {
23015
23045
  return await promise;
23016
23046
  }
23017
23047
  finally {
23018
- // do all of this whether promise was fulfilled or rejected
23019
- this._active = this._pending; // see if there's a pending request waiting
23020
- this._pending = undefined; // clear pending
23021
- if (this._active)
23022
- this._active.start(); // eslint-disable-line @typescript-eslint/no-floating-promises
23048
+ // A replaced pending request can be abandoned before it ever becomes active.
23049
+ // Only the currently active entry is allowed to promote/start the next pending request.
23050
+ if (this._active === entry) {
23051
+ // do all of this whether promise was fulfilled or rejected
23052
+ this._active = this._pending; // see if there's a pending request waiting
23053
+ this._pending = undefined; // clear pending
23054
+ if (this._active)
23055
+ this._active.start(); // eslint-disable-line @typescript-eslint/no-floating-promises
23056
+ }
23023
23057
  }
23024
23058
  }
23025
23059
  }
@@ -66205,7 +66239,8 @@ class SchemaFormatsProvider {
66205
66239
  * @param contextOrLocater The SchemaContext or a different ISchemaLocater implementation used to retrieve the schema. The SchemaContext
66206
66240
  * class implements the ISchemaLocater interface. If the provided locater is not a SchemaContext instance a new SchemaContext will be
66207
66241
  * created and the locater will be added.
66208
- * @param unitSystem Used to lookup a default format through a schema specific algorithm, when the format retrieved is associated with a KindOfQuantity.
66242
+ * @param unitSystem Optional unit system used to lookup a default format through a schema specific algorithm, when the format retrieved is associated with a KindOfQuantity.
66243
+ * If not provided, the default presentation format will be used directly without matching unit systems.
66209
66244
  */
66210
66245
  constructor(contextOrLocater, unitSystem) {
66211
66246
  if (contextOrLocater instanceof _Context__WEBPACK_IMPORTED_MODULE_0__.SchemaContext) {
@@ -66254,39 +66289,44 @@ class SchemaFormatsProvider {
66254
66289
  if (!kindOfQuantity) {
66255
66290
  return undefined;
66256
66291
  }
66257
- // Find the first presentation format that matches the provided unit system.
66258
- const unitSystemMatchers = getUnitSystemGroupMatchers(this._unitSystem);
66259
- const presentationFormats = kindOfQuantity.presentationFormats;
66260
- for (const matcher of unitSystemMatchers) {
66261
- for (const lazyFormat of presentationFormats) {
66262
- const format = await lazyFormat;
66263
- const unit = await (format.units && format.units[0][0]);
66264
- if (!unit) {
66265
- continue;
66266
- }
66267
- const currentUnitSystem = await unit.unitSystem;
66268
- if (currentUnitSystem && matcher(currentUnitSystem)) {
66269
- this._formatsRetrieved.add(itemKey.fullName);
66270
- const props = (0,_Metadata_OverrideFormat__WEBPACK_IMPORTED_MODULE_6__.getFormatProps)(format);
66271
- return this.convertToFormatDefinition(props, kindOfQuantity);
66292
+ // If a unit system is provided, find the first presentation format that matches it.
66293
+ if (this._unitSystem) {
66294
+ const unitSystemMatchers = getUnitSystemGroupMatchers(this._unitSystem);
66295
+ const presentationFormats = kindOfQuantity.presentationFormats;
66296
+ for (const matcher of unitSystemMatchers) {
66297
+ for (const lazyFormat of presentationFormats) {
66298
+ const format = await lazyFormat;
66299
+ const unit = await (format.units && format.units[0][0]);
66300
+ if (!unit) {
66301
+ continue;
66302
+ }
66303
+ const currentUnitSystem = await unit.unitSystem;
66304
+ if (currentUnitSystem && matcher(currentUnitSystem)) {
66305
+ this._formatsRetrieved.add(itemKey.fullName);
66306
+ const props = (0,_Metadata_OverrideFormat__WEBPACK_IMPORTED_MODULE_6__.getFormatProps)(format);
66307
+ return this.convertToFormatDefinition(props, kindOfQuantity);
66308
+ }
66272
66309
  }
66273
66310
  }
66311
+ // If no matching presentation format was found, fall back to persistence unit format
66312
+ // only if it matches the requested unit system.
66313
+ const persistenceUnit = await kindOfQuantity.persistenceUnit;
66314
+ const persistenceUnitSystem = await persistenceUnit?.unitSystem;
66315
+ if (persistenceUnit && persistenceUnitSystem && unitSystemMatchers.some((matcher) => matcher(persistenceUnitSystem))) {
66316
+ this._formatsRetrieved.add(itemKey.fullName);
66317
+ const props = getPersistenceUnitFormatProps(persistenceUnit);
66318
+ return this.convertToFormatDefinition(props, kindOfQuantity);
66319
+ }
66274
66320
  }
66275
- // If no matching presentation format was found, use persistence unit format if it matches unit system.
66276
- const persistenceUnit = await kindOfQuantity.persistenceUnit;
66277
- const persistenceUnitSystem = await persistenceUnit?.unitSystem;
66278
- if (persistenceUnit && persistenceUnitSystem && unitSystemMatchers.some((matcher) => matcher(persistenceUnitSystem))) {
66279
- this._formatsRetrieved.add(itemKey.fullName);
66280
- const props = getPersistenceUnitFormatProps(persistenceUnit);
66281
- return this.convertToFormatDefinition(props, kindOfQuantity);
66282
- }
66321
+ // If no unit system was provided, or no matching format was found, use the default presentation format.
66322
+ // Unit conversion from persistence unit to presentation unit will be handled by FormatterSpec.
66283
66323
  const defaultFormat = kindOfQuantity.defaultPresentationFormat;
66284
- if (!defaultFormat) {
66285
- return undefined;
66324
+ if (defaultFormat) {
66325
+ this._formatsRetrieved.add(itemKey.fullName);
66326
+ const defaultProps = (0,_Metadata_OverrideFormat__WEBPACK_IMPORTED_MODULE_6__.getFormatProps)(await defaultFormat);
66327
+ return this.convertToFormatDefinition(defaultProps, kindOfQuantity);
66286
66328
  }
66287
- this._formatsRetrieved.add(itemKey.fullName);
66288
- const defaultProps = (0,_Metadata_OverrideFormat__WEBPACK_IMPORTED_MODULE_6__.getFormatProps)(await defaultFormat);
66289
- return this.convertToFormatDefinition(defaultProps, kindOfQuantity);
66329
+ return undefined;
66290
66330
  }
66291
66331
  /**
66292
66332
  * Retrieves a Format from a SchemaContext. If the format is part of a KindOfQuantity, the first presentation format in the KindOfQuantity that matches the current unit system will be retrieved.
@@ -83115,6 +83155,18 @@ class CategorySelectorState extends _EntityState__WEBPACK_IMPORTED_MODULE_1__.El
83115
83155
  for (const id of _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.iterable(arg))
83116
83156
  this.categories.delete(id);
83117
83157
  }
83158
+ /** Add one or more categories to this CategorySelector, raising a single batch event instead of one event per category.
83159
+ * This is more efficient than [[addCategories]] when adding many categories at once.
83160
+ */
83161
+ addCategoriesBatched(arg) {
83162
+ this._categories.addAll(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.iterable(arg));
83163
+ }
83164
+ /** Remove one or more categories from this CategorySelector, raising a single batch event instead of one event per category.
83165
+ * This is more efficient than [[dropCategories]] when dropping many categories at once.
83166
+ */
83167
+ dropCategoriesBatched(arg) {
83168
+ this._categories.deleteAll(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.iterable(arg));
83169
+ }
83118
83170
  /** Add or remove categories from this CategorySelector.
83119
83171
  * @param arg The categories to add or remove
83120
83172
  * @param add If true, categories will be added; otherwise they will be removed.
@@ -89585,72 +89637,7 @@ class SnapshotConnection extends IModelConnection {
89585
89637
  /** The collection of loaded ModelState objects for an [[IModelConnection]]. */
89586
89638
  class Models {
89587
89639
  _iModel;
89588
- _modelExtentsQuery = `
89589
- SELECT
89590
- Model.Id AS ECInstanceId,
89591
- iModel_bbox_union(
89592
- iModel_placement_aabb(
89593
- iModel_placement(
89594
- iModel_point(Origin.X, Origin.Y, 0),
89595
- iModel_angles(Rotation, 0, 0),
89596
- iModel_bbox(
89597
- BBoxLow.X, BBoxLow.Y, -1,
89598
- BBoxHigh.X, BBoxHigh.Y, 1
89599
- )
89600
- )
89601
- )
89602
- ) AS bbox
89603
- FROM bis.GeometricElement2d
89604
- WHERE InVirtualSet(:ids64, Model.Id) AND Origin.X IS NOT NULL
89605
- GROUP BY Model.Id
89606
- UNION
89607
- SELECT
89608
- ge.Model.Id AS ECInstanceId,
89609
- iModel_bbox(
89610
- min(i.MinX), min(i.MinY), min(i.MinZ),
89611
- max(i.MaxX), max(i.MaxY), max(i.MaxZ)
89612
- ) AS bbox
89613
- FROM bis.SpatialIndex AS i, bis.GeometricElement3d AS ge, bis.GeometricModel3d AS gm
89614
- WHERE InVirtualSet(:ids64, ge.Model.Id) AND ge.ECInstanceId=i.ECInstanceId AND InVirtualSet(:ids64, gm.ECInstanceId) AND (gm.$->isNotSpatiallyLocated?=false OR gm.$->isNotSpatiallyLocated? IS NULL)
89615
- GROUP BY ge.Model.Id
89616
- UNION
89617
- SELECT
89618
- ge.Model.Id AS ECInstanceId,
89619
- iModel_bbox_union(
89620
- iModel_placement_aabb(
89621
- iModel_placement(
89622
- iModel_point(ge.Origin.X, ge.Origin.Y, ge.Origin.Z),
89623
- iModel_angles(ge.Yaw, ge.Pitch, ge.Roll),
89624
- iModel_bbox(
89625
- ge.BBoxLow.X, ge.BBoxLow.Y, ge.BBoxLow.Z,
89626
- ge.BBoxHigh.X, ge.BBoxHigh.Y, ge.BBoxHigh.Z
89627
- )
89628
- )
89629
- )
89630
- ) AS bbox
89631
- FROM bis.GeometricElement3d AS ge, bis.GeometricModel3d as gm
89632
- WHERE InVirtualSet(:ids64, ge.Model.Id) AND ge.Origin.X IS NOT NULL AND InVirtualSet(:ids64, gm.ECInstanceId) AND gm.$->isNotSpatiallyLocated?=true
89633
- GROUP BY ge.Model.Id`;
89634
- _modelExistenceQuery = `
89635
- WITH
89636
- GeometricModels AS(
89637
- SELECT
89638
- ECInstanceId
89639
- FROM bis.GeometricModel
89640
- WHERE InVirtualSet(: ids64, ECInstanceId)
89641
- )
89642
- SELECT
89643
- ECInstanceId,
89644
- true AS isGeometricModel
89645
- FROM GeometricModels
89646
- UNION ALL
89647
- SELECT
89648
- ECInstanceId,
89649
- false AS isGeometricModel
89650
- FROM bis.Model
89651
- WHERE InVirtualSet(: ids64, ECInstanceId)
89652
- AND ECInstanceId NOT IN(SELECT ECInstanceId FROM GeometricModels)`;
89653
- _loadedExtents = [];
89640
+ _loadedExtents = new Map();
89654
89641
  _geometryChangedListener;
89655
89642
  _loaded = new Map();
89656
89643
  /** @internal */
@@ -89665,7 +89652,9 @@ class SnapshotConnection extends IModelConnection {
89665
89652
  IModelConnection.onOpen.addListener(() => {
89666
89653
  if (this._iModel.isBriefcaseConnection()) {
89667
89654
  this._geometryChangedListener = (changes) => {
89668
- this._loadedExtents = this._loadedExtents.filter((extent) => !changes.some((change) => change.id === extent.id));
89655
+ changes.forEach((change) => {
89656
+ this._loadedExtents.delete(change.id);
89657
+ });
89669
89658
  };
89670
89659
  this._iModel.txns.onModelGeometryChanged.addListener(this._geometryChangedListener);
89671
89660
  }
@@ -89769,64 +89758,132 @@ class SnapshotConnection extends IModelConnection {
89769
89758
  return [];
89770
89759
  if (typeof modelIds === "string")
89771
89760
  modelIds = [modelIds];
89772
- const modelExtents = [];
89761
+ const resolvedExtents = new Map();
89762
+ const uncachedModelIds = [];
89763
+ // Add the cached model ids and the invalid ids
89773
89764
  for (const modelId of modelIds) {
89774
- if (!_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.isValidId64(modelId)) {
89775
- modelExtents.push({ id: modelId, extents: _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.createNull(), status: _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.InvalidId });
89765
+ if (this._loadedExtents.has(modelId)) {
89766
+ resolvedExtents.set(modelId, this._loadedExtents.get(modelId));
89776
89767
  }
89777
- }
89778
- const getUnloadedModelIds = () => modelIds.filter((modelId) => !modelExtents.some((loadedExtent) => loadedExtent.id === modelId));
89779
- let remainingModelIds = getUnloadedModelIds();
89780
- for (const modelId of remainingModelIds) {
89781
- const modelExtent = this._loadedExtents.find((extent) => modelId === extent.id);
89782
- if (modelExtent) {
89783
- modelExtents.push(modelExtent);
89768
+ else if (!_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.isValidId64(modelId)) {
89769
+ resolvedExtents.set(modelId, { id: modelId, extents: _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.createNull(), status: _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.InvalidId });
89784
89770
  }
89785
- }
89786
- remainingModelIds = getUnloadedModelIds();
89787
- if (remainingModelIds.length > 0) {
89788
- const params = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QueryBinder();
89789
- params.bindIdSet("ids64", remainingModelIds);
89790
- const extentsQueryReader = this._iModel.createQueryReader(this._modelExtentsQuery, params, {
89771
+ else {
89772
+ uncachedModelIds.push(modelId);
89773
+ }
89774
+ }
89775
+ // Run the ECSql to get uncached model extents
89776
+ if (uncachedModelIds.length > 0) {
89777
+ const modelList = uncachedModelIds.join(",");
89778
+ const useSingleModelQuery = uncachedModelIds.length === 1;
89779
+ const modelExtentsQuery = `
89780
+ SELECT
89781
+ Model.Id AS ECInstanceId,
89782
+ iModel_bbox_union(
89783
+ iModel_placement_aabb(
89784
+ iModel_placement(
89785
+ iModel_point(Origin.X, Origin.Y, 0),
89786
+ iModel_angles(Rotation, 0, 0),
89787
+ iModel_bbox(
89788
+ BBoxLow.X, BBoxLow.Y, -1,
89789
+ BBoxHigh.X, BBoxHigh.Y, 1
89790
+ )
89791
+ )
89792
+ )
89793
+ ) AS bbox
89794
+ FROM bis.GeometricElement2d
89795
+ WHERE Model.Id ${useSingleModelQuery ? `= ${uncachedModelIds[0]}` : `IN (${modelList})`}
89796
+ AND Origin.X IS NOT NULL
89797
+ GROUP BY Model.Id
89798
+
89799
+ UNION
89800
+
89801
+ SELECT
89802
+ ge.Model.Id AS ECInstanceId,
89803
+ iModel_bbox(
89804
+ min(i.MinX), min(i.MinY), min(i.MinZ),
89805
+ max(i.MaxX), max(i.MaxY), max(i.MaxZ)
89806
+ ) AS bbox
89807
+ FROM bis.SpatialIndex AS i
89808
+ INNER JOIN bis.GeometricElement3d AS ge
89809
+ ON ge.ECInstanceId = i.ECInstanceId
89810
+ INNER JOIN bis.GeometricModel3d AS gm
89811
+ ON ge.Model.Id = gm.ECInstanceId
89812
+ WHERE ge.Model.Id ${useSingleModelQuery ? `= ${uncachedModelIds[0]}` : `IN (${modelList})`}
89813
+ AND (gm.$->IsNotSpatiallyLocated? IS NULL OR gm.$->IsNotSpatiallyLocated? IS FALSE)
89814
+ GROUP BY ge.Model.Id
89815
+
89816
+ UNION
89817
+
89818
+ SELECT
89819
+ ge.Model.Id AS ECInstanceId,
89820
+ iModel_bbox_union(
89821
+ iModel_placement_aabb(
89822
+ iModel_placement(
89823
+ iModel_point(ge.Origin.X, ge.Origin.Y, ge.Origin.Z),
89824
+ iModel_angles(ge.Yaw, ge.Pitch, ge.Roll),
89825
+ iModel_bbox(
89826
+ ge.BBoxLow.X, ge.BBoxLow.Y, ge.BBoxLow.Z,
89827
+ ge.BBoxHigh.X, ge.BBoxHigh.Y, ge.BBoxHigh.Z
89828
+ )
89829
+ )
89830
+ )
89831
+ ) AS bbox
89832
+ FROM bis.GeometricElement3d ge
89833
+ INNER JOIN bis.GeometricModel3d gm
89834
+ ON ge.Model.Id = gm.ECInstanceId
89835
+ WHERE ge.Model.Id ${useSingleModelQuery ? `= ${uncachedModelIds[0]}` : `IN (${modelList})`}
89836
+ AND gm.$->IsNotSpatiallyLocated? IS TRUE
89837
+ AND ge.Origin.X IS NOT NULL
89838
+ GROUP BY ge.Model.Id
89839
+ `;
89840
+ const extentsQueryReader = this._iModel.createQueryReader(modelExtentsQuery, undefined, {
89791
89841
  rowFormat: _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QueryRowFormat.UseECSqlPropertyNames,
89792
89842
  });
89793
89843
  for await (const row of extentsQueryReader) {
89794
89844
  const byteArray = new Uint8Array(Object.values(row.bbox));
89795
89845
  const extents = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.fromArrayBuffer(byteArray.buffer);
89796
89846
  const extent = { id: row.ECInstanceId, extents, status: _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.Success };
89797
- modelExtents.push(extent);
89798
- this._loadedExtents.push(extent);
89799
- }
89800
- }
89801
- remainingModelIds = getUnloadedModelIds();
89802
- if (remainingModelIds.length > 0) {
89803
- const params = new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QueryBinder();
89804
- params.bindIdSet("ids64", remainingModelIds);
89805
- const modelExistenceQueryReader = this._iModel.createQueryReader(this._modelExistenceQuery, params, {
89847
+ resolvedExtents.set(extent.id, extent);
89848
+ this._loadedExtents.set(extent.id, extent);
89849
+ }
89850
+ }
89851
+ // Check if there still are any unresolved model IDs
89852
+ const unresolvedModelIds = uncachedModelIds.filter((id) => !resolvedExtents.has(id));
89853
+ if (unresolvedModelIds.length > 0) {
89854
+ const modelList = unresolvedModelIds.join(",");
89855
+ const modelExistenceQuery = `
89856
+ SELECT
89857
+ m.ECInstanceId,
89858
+ CASE WHEN g.ECInstanceId IS NOT NULL THEN 1 ELSE 0 END AS isGeometricModel
89859
+ FROM bis.Model m
89860
+ LEFT JOIN bis.GeometricModel g
89861
+ ON m.ECInstanceId = g.ECInstanceId
89862
+ WHERE m.ECInstanceId ${unresolvedModelIds.length === 1 ? `= ${unresolvedModelIds[0]}` : `IN (${modelList})`}
89863
+ `;
89864
+ const modelExistenceQueryReader = this._iModel.createQueryReader(modelExistenceQuery, undefined, {
89806
89865
  rowFormat: _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.QueryRowFormat.UseECSqlPropertyNames,
89807
89866
  });
89808
89867
  for await (const row of modelExistenceQueryReader) {
89809
- let extent;
89810
- if (row.isGeometricModel) {
89811
- extent = { id: row.ECInstanceId, extents: _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.createNull(), status: _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.Success };
89812
- }
89813
- else {
89814
- extent = { id: row.ECInstanceId, extents: _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.createNull(), status: _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.WrongModel };
89815
- }
89816
- modelExtents.push(extent);
89817
- this._loadedExtents.push(extent);
89868
+ const extent = {
89869
+ id: row.ECInstanceId,
89870
+ extents: _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.createNull(),
89871
+ status: row.isGeometricModel ? _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.Success : _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.WrongModel,
89872
+ };
89873
+ resolvedExtents.set(extent.id, extent);
89874
+ this._loadedExtents.set(extent.id, extent);
89818
89875
  }
89819
89876
  }
89877
+ // Return the results while maintaining the same order
89820
89878
  return modelIds.map((modelId) => {
89821
- let extent = modelExtents.find((loadedExtent) => loadedExtent.id === modelId);
89879
+ const extent = resolvedExtents.get(modelId);
89822
89880
  if (extent === undefined) {
89823
- extent = { id: modelId, extents: _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.createNull(), status: _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.NotFound };
89824
- this._loadedExtents.push(extent);
89825
- return extent;
89881
+ const notFound = { id: modelId, extents: _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.createNull(), status: _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.NotFound };
89882
+ this._loadedExtents.set(notFound.id, notFound);
89883
+ return notFound;
89826
89884
  }
89827
- else if (extent.status === _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.InvalidId) {
89828
- extent.id = "0";
89829
- return extent;
89885
+ if (extent.status === _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.IModelStatus.InvalidId) {
89886
+ return { ...extent, id: "0" };
89830
89887
  }
89831
89888
  return extent;
89832
89889
  });
@@ -98780,6 +98837,8 @@ class ViewState extends _EntityState__WEBPACK_IMPORTED_MODULE_5__.ElementState {
98780
98837
  this._unregisterCategorySelectorListeners.push(cats.onAdded.addListener(event));
98781
98838
  this._unregisterCategorySelectorListeners.push(cats.onDeleted.addListener(event));
98782
98839
  this._unregisterCategorySelectorListeners.push(cats.onCleared.addListener(event));
98840
+ this._unregisterCategorySelectorListeners.push(cats.onBatchAdded.addListener(event));
98841
+ this._unregisterCategorySelectorListeners.push(cats.onBatchDeleted.addListener(event));
98783
98842
  }
98784
98843
  /** Invoked when this view, previously attached to the specified [[Viewport]] via [[attachToViewport]], is no longer the view displayed by that Viewport.
98785
98844
  * This method is invoked automatically by the viewport - there is generally no reason for applications to invoke it directly.
@@ -100806,13 +100865,20 @@ class Viewport {
100806
100865
  * @param categories The Id(s) of the categories to which the change should be applied. No other categories will be affected.
100807
100866
  * @param display Whether or not elements on the specified categories should be displayed in the viewport.
100808
100867
  * @param enableAllSubCategories Specifies that when enabling display for a category, all of its subcategories should also be displayed even if they are overridden to be invisible.
100868
+ * @param batchNotify If true, a single batch event is raised instead of one event per category. This is more efficient when changing many categories at once.
100809
100869
  */
100810
- changeCategoryDisplay(categories, display, enableAllSubCategories = false) {
100870
+ changeCategoryDisplay(categories, display, enableAllSubCategories = false, batchNotify = false) {
100811
100871
  if (!display) {
100812
- this.view.categorySelector.dropCategories(categories);
100872
+ if (batchNotify)
100873
+ this.view.categorySelector.dropCategoriesBatched(categories);
100874
+ else
100875
+ this.view.categorySelector.dropCategories(categories);
100813
100876
  return;
100814
100877
  }
100815
- this.view.categorySelector.addCategories(categories);
100878
+ if (batchNotify)
100879
+ this.view.categorySelector.addCategoriesBatched(categories);
100880
+ else
100881
+ this.view.categorySelector.addCategories(categories);
100816
100882
  const categoryIds = _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Id64.toIdSet(categories);
100817
100883
  this.updateSubCategories(categoryIds, enableAllSubCategories);
100818
100884
  }
@@ -321385,7 +321451,7 @@ var loadLanguages = instance.loadLanguages;
321385
321451
  /***/ ((module) => {
321386
321452
 
321387
321453
  "use strict";
321388
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.7.0-dev.13","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.31.0","glob":"^10.5.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","vitest":"^3.0.6","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"2.2.0","webpack":"^5.97.1"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^4.3.4","@loaders.gl/draco":"^4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
321454
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@itwin/core-frontend","version":"5.7.0-dev.15","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers && npm run -s copy:draco","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2022 --outDir lib/esm","clean":"rimraf -g lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","copy:draco":"cpx \\"./node_modules/@loaders.gl/draco/dist/libs/*\\" ./lib/public/scripts","docs":"betools docs --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-inline-config -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint \\"./src/**/*.ts\\" 1>&2","lint-fix":"eslint --fix -f visualstudio \\"./src/**/*.ts\\" 1>&2","lint-deprecation":"eslint --fix -f visualstudio --no-inline-config -c ../../common/config/eslint/eslint.config.deprecation-policy.js \\"./src/**/*.ts\\"","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run webpackTestWorker && vitest --run","cover":"npm run webpackTestWorker && vitest --run","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/ecschema-metadata":"workspace:*","@itwin/ecschema-rpcinterface-common":"workspace:*","@itwin/object-storage-core":"^3.0.4","@itwin/eslint-plugin":"^6.0.0","@types/chai-as-promised":"^7","@types/draco3d":"^1.4.10","@types/sinon":"^17.0.2","@vitest/browser":"^3.0.6","@vitest/coverage-v8":"^3.0.6","cpx2":"^8.0.0","eslint":"^9.31.0","glob":"^10.5.0","playwright":"~1.56.1","rimraf":"^6.0.1","sinon":"^17.0.2","source-map-loader":"^5.0.0","typescript":"~5.6.2","vitest":"^3.0.6","vite-multiple-assets":"^1.3.1","vite-plugin-static-copy":"2.2.0","webpack":"^5.97.1"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/core-i18n":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^4.3.4","@loaders.gl/draco":"^4.3.4","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"}}');
321389
321455
 
321390
321456
  /***/ })
321391
321457