@itwin/tree-widget-react 4.0.0-alpha.24 → 4.0.0-alpha.26

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 (205) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/lib/esm/tree-widget-react/components/TreeWidgetUiItemsProvider.js +2 -1
  3. package/lib/esm/tree-widget-react/components/TreeWidgetUiItemsProvider.js.map +1 -1
  4. package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.js +1 -1
  5. package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.js.map +1 -1
  6. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.d.ts +4 -1
  7. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.js +4 -1
  8. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.js.map +1 -1
  9. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.d.ts +1 -0
  10. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.js +36 -47
  11. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.js.map +1 -1
  12. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.d.ts +2 -0
  13. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.js +4 -1
  14. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.js.map +1 -1
  15. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.d.ts +4 -2
  16. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js +87 -38
  17. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js.map +1 -1
  18. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeNode.d.ts +86 -0
  19. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeNode.js +50 -0
  20. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeNode.js.map +1 -0
  21. package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.d.ts +4 -2
  22. package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js +38 -23
  23. package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js.map +1 -1
  24. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.d.ts +11 -21
  25. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js +16 -168
  26. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js.map +1 -1
  27. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNodeInternal.d.ts +65 -0
  28. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNodeInternal.js +22 -0
  29. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNodeInternal.js.map +1 -0
  30. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseSearchPaths.d.ts +2 -2
  31. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseSearchPaths.js +4 -4
  32. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseSearchPaths.js.map +1 -1
  33. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/visibility/CategoriesTreeVisibilityHandler.d.ts +6 -12
  34. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/visibility/CategoriesTreeVisibilityHandler.js +192 -127
  35. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/visibility/CategoriesTreeVisibilityHandler.js.map +1 -1
  36. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/visibility/CategoriesTreeVisibilityHelper.d.ts +14 -5
  37. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/visibility/CategoriesTreeVisibilityHelper.js +43 -24
  38. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/visibility/CategoriesTreeVisibilityHelper.js.map +1 -1
  39. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/visibility/SearchResultsTree.d.ts +3 -1
  40. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/visibility/SearchResultsTree.js +78 -17
  41. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/visibility/SearchResultsTree.js.map +1 -1
  42. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeComponent.d.ts +2 -0
  43. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeComponent.js +4 -1
  44. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeComponent.js.map +1 -1
  45. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeDefinition.js +91 -114
  46. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeDefinition.js.map +1 -1
  47. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeIcon.d.ts +2 -2
  48. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeIcon.js.map +1 -1
  49. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeNode.d.ts +32 -0
  50. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeNode.js +26 -0
  51. package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeNode.js.map +1 -0
  52. package/lib/esm/tree-widget-react/components/trees/classifications-tree/UseClassificationsTree.d.ts +13 -1
  53. package/lib/esm/tree-widget-react/components/trees/classifications-tree/UseClassificationsTree.js +62 -32
  54. package/lib/esm/tree-widget-react/components/trees/classifications-tree/UseClassificationsTree.js.map +1 -1
  55. package/lib/esm/tree-widget-react/components/trees/classifications-tree/UseClassificationsTreeDefinition.d.ts +12 -9
  56. package/lib/esm/tree-widget-react/components/trees/classifications-tree/UseClassificationsTreeDefinition.js +42 -38
  57. package/lib/esm/tree-widget-react/components/trees/classifications-tree/UseClassificationsTreeDefinition.js.map +1 -1
  58. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeIdsCache.d.ts +15 -38
  59. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeIdsCache.js +59 -242
  60. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeIdsCache.js.map +1 -1
  61. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeNodeInternal.d.ts +29 -0
  62. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeNodeInternal.js +19 -0
  63. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeNodeInternal.js.map +1 -0
  64. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/visibility/ClassificationsTreeVisibilityHandler.d.ts +5 -9
  65. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/visibility/ClassificationsTreeVisibilityHandler.js +155 -84
  66. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/visibility/ClassificationsTreeVisibilityHandler.js.map +1 -1
  67. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/visibility/ClassificationsTreeVisibilityHelper.js +20 -6
  68. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/visibility/ClassificationsTreeVisibilityHelper.js.map +1 -1
  69. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/visibility/SearchResultsTree.d.ts +6 -10
  70. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/visibility/SearchResultsTree.js +104 -63
  71. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/visibility/SearchResultsTree.js.map +1 -1
  72. package/lib/esm/tree-widget-react/components/trees/common/SharedTreeContextProvider.d.ts +7 -0
  73. package/lib/esm/tree-widget-react/components/trees/common/SharedTreeContextProvider.js +14 -0
  74. package/lib/esm/tree-widget-react/components/trees/common/SharedTreeContextProvider.js.map +1 -0
  75. package/lib/esm/tree-widget-react/components/trees/common/TreeWidgetViewport.js +1 -1
  76. package/lib/esm/tree-widget-react/components/trees/common/TreeWidgetViewport.js.map +1 -1
  77. package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyVisibility.js +2 -2
  78. package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyVisibility.js.map +1 -1
  79. package/lib/esm/tree-widget-react/components/trees/common/Utils.js +2 -2
  80. package/lib/esm/tree-widget-react/components/trees/common/Utils.js.map +1 -1
  81. package/lib/esm/tree-widget-react/components/trees/common/components/Tree.d.ts +4 -4
  82. package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js +1 -1
  83. package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js.map +1 -1
  84. package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeVisibilityButton.d.ts +4 -4
  85. package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeVisibilityButton.js.map +1 -1
  86. package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.js +7 -5
  87. package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.js.map +1 -1
  88. package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.d.ts +2 -2
  89. package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.js.map +1 -1
  90. package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.js +5 -5
  91. package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.js.map +1 -1
  92. package/lib/esm/tree-widget-react/components/trees/common/internal/SharedTreeContextProviderInternal.d.ts +20 -0
  93. package/lib/esm/tree-widget-react/components/trees/common/internal/SharedTreeContextProviderInternal.js +44 -0
  94. package/lib/esm/tree-widget-react/components/trees/common/internal/SharedTreeContextProviderInternal.js.map +1 -0
  95. package/lib/esm/tree-widget-react/components/trees/common/internal/Types.d.ts +4 -0
  96. package/lib/esm/tree-widget-react/components/trees/common/internal/Types.js.map +1 -1
  97. package/lib/esm/tree-widget-react/components/trees/common/internal/UseIModelAccess.d.ts +12 -0
  98. package/lib/esm/tree-widget-react/components/trees/common/internal/UseIModelAccess.js +2 -1
  99. package/lib/esm/tree-widget-react/components/trees/common/internal/UseIModelAccess.js.map +1 -1
  100. package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.d.ts +17 -6
  101. package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js +58 -29
  102. package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js.map +1 -1
  103. package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.d.ts +8 -14
  104. package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.js +22 -26
  105. package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.js.map +1 -1
  106. package/lib/esm/tree-widget-react/components/trees/common/internal/{AlwaysAndNeverDrawnElementInfo.d.ts → caches/AlwaysAndNeverDrawnElementInfoCache.d.ts} +15 -21
  107. package/lib/esm/tree-widget-react/components/trees/common/internal/{AlwaysAndNeverDrawnElementInfo.js → caches/AlwaysAndNeverDrawnElementInfoCache.js} +40 -38
  108. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/AlwaysAndNeverDrawnElementInfoCache.js.map +1 -0
  109. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/BaseIdsCache.d.ts +68 -0
  110. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/BaseIdsCache.js +148 -0
  111. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/BaseIdsCache.js.map +1 -0
  112. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ElementChildrenCache.d.ts +30 -0
  113. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ElementChildrenCache.js +151 -0
  114. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ElementChildrenCache.js.map +1 -0
  115. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ElementModelCategoriesCache.d.ts +32 -0
  116. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ElementModelCategoriesCache.js +106 -0
  117. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ElementModelCategoriesCache.js.map +1 -0
  118. package/lib/esm/tree-widget-react/components/trees/common/internal/{ModelCategoryElementsCountCache.d.ts → caches/ModelCategoryElementsCountCache.d.ts} +9 -2
  119. package/lib/esm/tree-widget-react/components/trees/common/internal/{ModelCategoryElementsCountCache.js → caches/ModelCategoryElementsCountCache.js} +17 -21
  120. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ModelCategoryElementsCountCache.js.map +1 -0
  121. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ModeledElementsCache.d.ts +27 -0
  122. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ModeledElementsCache.js +106 -0
  123. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/ModeledElementsCache.js.map +1 -0
  124. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/SubCategoriesCache.d.ts +23 -0
  125. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/SubCategoriesCache.js +56 -0
  126. package/lib/esm/tree-widget-react/components/trees/common/internal/caches/SubCategoriesCache.js.map +1 -0
  127. package/lib/esm/tree-widget-react/components/trees/common/internal/useTreeHooks/UseCachedVisibility.d.ts +6 -6
  128. package/lib/esm/tree-widget-react/components/trees/common/internal/useTreeHooks/UseCachedVisibility.js +27 -17
  129. package/lib/esm/tree-widget-react/components/trees/common/internal/useTreeHooks/UseCachedVisibility.js.map +1 -1
  130. package/lib/esm/tree-widget-react/components/trees/common/internal/useTreeHooks/UseIdsCache.d.ts +7 -13
  131. package/lib/esm/tree-widget-react/components/trees/common/internal/useTreeHooks/UseIdsCache.js +36 -35
  132. package/lib/esm/tree-widget-react/components/trees/common/internal/useTreeHooks/UseIdsCache.js.map +1 -1
  133. package/lib/esm/tree-widget-react/components/trees/common/internal/visibility/BaseSearchResultsTree.d.ts +18 -0
  134. package/lib/esm/tree-widget-react/components/trees/common/internal/visibility/BaseSearchResultsTree.js +14 -1
  135. package/lib/esm/tree-widget-react/components/trees/common/internal/visibility/BaseSearchResultsTree.js.map +1 -1
  136. package/lib/esm/tree-widget-react/components/trees/common/internal/visibility/BaseVisibilityHelper.d.ts +46 -70
  137. package/lib/esm/tree-widget-react/components/trees/common/internal/visibility/BaseVisibilityHelper.js +229 -361
  138. package/lib/esm/tree-widget-react/components/trees/common/internal/visibility/BaseVisibilityHelper.js.map +1 -1
  139. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +2 -2
  140. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
  141. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js.map +1 -1
  142. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.d.ts +2 -2
  143. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
  144. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeComponent.js.map +1 -1
  145. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js +1 -1
  146. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js.map +1 -1
  147. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js +32 -19
  148. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js.map +1 -1
  149. package/lib/esm/tree-widget-react/components/trees/index.d.ts +5 -1
  150. package/lib/esm/tree-widget-react/components/trees/index.js +5 -1
  151. package/lib/esm/tree-widget-react/components/trees/index.js.map +1 -1
  152. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.d.ts +4 -1
  153. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.js +4 -1
  154. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.js.map +1 -1
  155. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.d.ts +7 -3
  156. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js +36 -35
  157. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js.map +1 -1
  158. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeComponent.d.ts +1 -0
  159. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeComponent.js +3 -1
  160. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
  161. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.d.ts +3 -1
  162. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js +70 -26
  163. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js.map +1 -1
  164. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeNode.d.ts +63 -0
  165. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeNode.js +56 -0
  166. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeNode.js.map +1 -0
  167. package/lib/esm/tree-widget-react/components/trees/models-tree/UseModelsTree.d.ts +5 -3
  168. package/lib/esm/tree-widget-react/components/trees/models-tree/UseModelsTree.js +26 -13
  169. package/lib/esm/tree-widget-react/components/trees/models-tree/UseModelsTree.js.map +1 -1
  170. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts +11 -23
  171. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +56 -189
  172. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js.map +1 -1
  173. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeNodeInternal.d.ts +52 -0
  174. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeNodeInternal.js +22 -0
  175. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeNodeInternal.js.map +1 -0
  176. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseSearchPaths.d.ts +2 -2
  177. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseSearchPaths.js +8 -8
  178. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseSearchPaths.js.map +1 -1
  179. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/visibility/ModelsTreeVisibilityHandler.d.ts +6 -12
  180. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/visibility/ModelsTreeVisibilityHandler.js +190 -114
  181. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/visibility/ModelsTreeVisibilityHandler.js.map +1 -1
  182. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/visibility/ModelsTreeVisibilityHelper.d.ts +6 -0
  183. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/visibility/ModelsTreeVisibilityHelper.js +20 -8
  184. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/visibility/ModelsTreeVisibilityHelper.js.map +1 -1
  185. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/visibility/SearchResultsTree.d.ts +4 -2
  186. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/visibility/SearchResultsTree.js +73 -13
  187. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/visibility/SearchResultsTree.js.map +1 -1
  188. package/lib/esm/tree-widget-react-internal.d.ts +1 -1
  189. package/lib/esm/tree-widget-react-internal.js +1 -1
  190. package/lib/esm/tree-widget-react-internal.js.map +1 -1
  191. package/package.json +77 -82
  192. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNode.d.ts +0 -41
  193. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNode.js +0 -50
  194. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNode.js.map +0 -1
  195. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeNode.d.ts +0 -19
  196. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeNode.js +0 -32
  197. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeNode.js.map +0 -1
  198. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/UseSearchPaths.d.ts +0 -20
  199. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/UseSearchPaths.js +0 -53
  200. package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/UseSearchPaths.js.map +0 -1
  201. package/lib/esm/tree-widget-react/components/trees/common/internal/AlwaysAndNeverDrawnElementInfo.js.map +0 -1
  202. package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.js.map +0 -1
  203. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeNode.d.ts +0 -37
  204. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeNode.js +0 -54
  205. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeNode.js.map +0 -1
@@ -0,0 +1,151 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { defaultIfEmpty, defer, EMPTY, firstValueFrom, from, map, mergeMap, reduce, tap } from "rxjs";
6
+ import { Guid, Id64 } from "@itwin/core-bentley";
7
+ import { catchBeSQLiteInterrupts } from "../UseErrorState.js";
8
+ import { getOptimalBatchSize } from "../Utils.js";
9
+ /** @internal */
10
+ export class ElementChildrenCache {
11
+ #queryExecutor;
12
+ #elementClassName;
13
+ #componentId;
14
+ #componentName;
15
+ #childElementsMap;
16
+ /** Stores element ids which have children query scheduled to execute. */
17
+ #childElementsLoadingMap;
18
+ constructor(props) {
19
+ this.#queryExecutor = props.queryExecutor;
20
+ this.#elementClassName = props.elementClassName;
21
+ this.#componentId = props.componentId;
22
+ this.#componentName = "ElementChildrenCache";
23
+ this.#childElementsMap = new Map();
24
+ this.#childElementsLoadingMap = new Map();
25
+ }
26
+ queryChildren({ elementIds }) {
27
+ if (elementIds.length === 0) {
28
+ return EMPTY;
29
+ }
30
+ return defer(() => {
31
+ const ctes = [
32
+ `
33
+ ElementChildren(id, parentId) AS (
34
+ SELECT ECInstanceId id, Parent.Id parentId
35
+ FROM ${this.#elementClassName}
36
+ WHERE Parent.Id IN (${elementIds.join(", ")})
37
+ UNION ALL
38
+ SELECT c.ECInstanceId id, c.Parent.Id
39
+ FROM ${this.#elementClassName} c
40
+ JOIN ElementChildren p ON c.Parent.Id = p.id
41
+ )
42
+ `,
43
+ ];
44
+ const ecsql = `
45
+ SELECT id, parentId
46
+ FROM ElementChildren
47
+ `;
48
+ return this.#queryExecutor.createQueryReader({ ecsql, ctes }, { rowFormat: "ECSqlPropertyNames", limit: "unbounded", restartToken: `${this.#componentName}/${this.#componentId}/children/${Guid.createValue()}` });
49
+ }).pipe(catchBeSQLiteInterrupts, map((row) => {
50
+ return { id: row.id, parentId: row.parentId };
51
+ }));
52
+ }
53
+ getChildElementsTreeFromMap({ elementIds }) {
54
+ const result = new Map();
55
+ if (Id64.sizeOf(elementIds) === 0 || this.#childElementsMap.size === 0) {
56
+ return result;
57
+ }
58
+ for (const elementId of Id64.iterable(elementIds)) {
59
+ const entry = this.#childElementsMap.get(elementId);
60
+ if (!entry?.children) {
61
+ continue;
62
+ }
63
+ const elementChildrenTree = new Map();
64
+ result.set(elementId, { children: elementChildrenTree });
65
+ for (const childId of entry.children) {
66
+ const childrenTreeOfChild = this.getChildElementsTreeFromMap({ elementIds: childId });
67
+ // Need to add children tree created from childId. This tree includes childId as root element
68
+ // If child does not have children, children tree won't be created. Need to add childId with undefined children
69
+ elementChildrenTree.set(childId, { children: childrenTreeOfChild.size > 0 ? childrenTreeOfChild : undefined });
70
+ }
71
+ }
72
+ return result;
73
+ }
74
+ getChildElementsCountMap({ elementIds }) {
75
+ const result = new Map();
76
+ for (const elementId of Id64.iterable(elementIds)) {
77
+ const entry = this.#childElementsMap.get(elementId);
78
+ if (entry?.children) {
79
+ let totalChildrenCount = entry.children.length;
80
+ for (const childrenOfChildCount of this.getChildElementsCountMap({ elementIds: entry.children }).values()) {
81
+ totalChildrenCount += childrenOfChildCount;
82
+ }
83
+ result.set(elementId, totalChildrenCount);
84
+ }
85
+ }
86
+ return result;
87
+ }
88
+ /**
89
+ * Populates #childElementsLoadingMap with promises. When these promises resolve, they will populate #childElementsMap with values and delete entries from #childElementsLoadingMap.
90
+ */
91
+ createChildElementsLoadingMapEntries({ elementsToQuery }) {
92
+ const getElementsToQueryPromise = async (batchedElementsToQuery) => firstValueFrom(this.queryChildren({ elementIds: batchedElementsToQuery }).pipe(
93
+ // Want to have void at the end instead of void[], so using reduce
94
+ reduce((acc, { parentId, id }) => {
95
+ let entry = this.#childElementsMap.get(parentId);
96
+ if (!entry) {
97
+ entry = { children: [] };
98
+ this.#childElementsMap.set(parentId, entry);
99
+ }
100
+ if (!entry.children) {
101
+ entry.children = [];
102
+ }
103
+ // Add child to parent's entry and add child to children map
104
+ entry.children.push(id);
105
+ if (!this.#childElementsMap.has(id)) {
106
+ this.#childElementsMap.set(id, { children: undefined });
107
+ }
108
+ return acc;
109
+ }, (() => { })()), tap({ complete: () => batchedElementsToQuery.forEach((elementId) => this.#childElementsLoadingMap.delete(elementId)) }), defaultIfEmpty((() => { })())));
110
+ const maximumBatchSize = 1000;
111
+ const totalSize = elementsToQuery.length;
112
+ const optimalBatchSize = getOptimalBatchSize({ totalSize, maximumBatchSize });
113
+ const loadingMapEntries = new Array();
114
+ // Don't want to slice if its not necessary
115
+ if (totalSize <= maximumBatchSize) {
116
+ loadingMapEntries.push(getElementsToQueryPromise(elementsToQuery));
117
+ }
118
+ else {
119
+ for (let i = 0; i < elementsToQuery.length; i += optimalBatchSize) {
120
+ loadingMapEntries.push(getElementsToQueryPromise(elementsToQuery.slice(i, i + optimalBatchSize)));
121
+ }
122
+ }
123
+ elementsToQuery.forEach((elementId, index) => this.#childElementsLoadingMap.set(elementId, loadingMapEntries[Math.floor(index / optimalBatchSize)]));
124
+ return { loadingMapEntries: Promise.all(loadingMapEntries).then(() => { }) };
125
+ }
126
+ createChildElementsMapEntries({ elementIds }) {
127
+ return from(Id64.iterable(elementIds)).pipe(reduce((acc, elementId) => {
128
+ if (this.#childElementsMap.has(elementId)) {
129
+ return acc;
130
+ }
131
+ const loadingPromise = this.#childElementsLoadingMap.get(elementId);
132
+ if (loadingPromise) {
133
+ acc.existingPromises.push(loadingPromise);
134
+ }
135
+ else {
136
+ acc.elementsToQuery.push(elementId);
137
+ }
138
+ return acc;
139
+ }, { existingPromises: new Array(), elementsToQuery: new Array() }), mergeMap(async ({ elementsToQuery, existingPromises }) => {
140
+ existingPromises.push(this.createChildElementsLoadingMapEntries({ elementsToQuery }).loadingMapEntries);
141
+ return Promise.all(existingPromises);
142
+ }));
143
+ }
144
+ getChildElementsTree({ elementIds }) {
145
+ return this.createChildElementsMapEntries({ elementIds }).pipe(map(() => this.getChildElementsTreeFromMap({ elementIds })));
146
+ }
147
+ getAllChildElementsCount({ elementIds }) {
148
+ return this.createChildElementsMapEntries({ elementIds }).pipe(map(() => this.getChildElementsCountMap({ elementIds })));
149
+ }
150
+ }
151
+ //# sourceMappingURL=ElementChildrenCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementChildrenCache.js","sourceRoot":"","sources":["../../../../../../../../src/tree-widget-react/components/trees/common/internal/caches/ElementChildrenCache.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { defaultIfEmpty, defer, EMPTY, firstValueFrom, from, map, mergeMap, reduce, tap } from \"rxjs\";\nimport { Guid, Id64 } from \"@itwin/core-bentley\";\nimport { catchBeSQLiteInterrupts } from \"../UseErrorState.js\";\nimport { getOptimalBatchSize } from \"../Utils.js\";\n\nimport type { Observable } from \"rxjs\";\nimport type { GuidString, Id64Arg, Id64Array, Id64String } from \"@itwin/core-bentley\";\nimport type { LimitingECSqlQueryExecutor } from \"@itwin/presentation-hierarchies\";\nimport type { ChildrenTree } from \"../Utils.js\";\n\ntype ChildElementsMap = Map<Id64String, { children: Id64Array | undefined }>;\ntype ChildElementsLoadingMap = Map<Id64String, Promise<void>>;\n\ninterface ElementChildrenCacheProps {\n queryExecutor: LimitingECSqlQueryExecutor;\n elementClassName: string;\n componentId: GuidString;\n}\n\n/** @internal */\nexport class ElementChildrenCache {\n #queryExecutor: LimitingECSqlQueryExecutor;\n readonly #elementClassName: string;\n #componentId: GuidString;\n #componentName: string;\n #childElementsMap: ChildElementsMap;\n /** Stores element ids which have children query scheduled to execute. */\n #childElementsLoadingMap: ChildElementsLoadingMap;\n\n constructor(props: ElementChildrenCacheProps) {\n this.#queryExecutor = props.queryExecutor;\n this.#elementClassName = props.elementClassName;\n this.#componentId = props.componentId;\n this.#componentName = \"ElementChildrenCache\";\n this.#childElementsMap = new Map();\n this.#childElementsLoadingMap = new Map();\n }\n\n private queryChildren({ elementIds }: { elementIds: Id64Array }): Observable<{ id: Id64String; parentId: Id64String }> {\n if (elementIds.length === 0) {\n return EMPTY;\n }\n\n return defer(() => {\n const ctes = [\n `\n ElementChildren(id, parentId) AS (\n SELECT ECInstanceId id, Parent.Id parentId\n FROM ${this.#elementClassName}\n WHERE Parent.Id IN (${elementIds.join(\", \")})\n UNION ALL\n SELECT c.ECInstanceId id, c.Parent.Id\n FROM ${this.#elementClassName} c\n JOIN ElementChildren p ON c.Parent.Id = p.id\n )\n `,\n ];\n const ecsql = `\n SELECT id, parentId\n FROM ElementChildren\n `;\n return this.#queryExecutor.createQueryReader(\n { ecsql, ctes },\n { rowFormat: \"ECSqlPropertyNames\", limit: \"unbounded\", restartToken: `${this.#componentName}/${this.#componentId}/children/${Guid.createValue()}` },\n );\n }).pipe(\n catchBeSQLiteInterrupts,\n map((row) => {\n return { id: row.id, parentId: row.parentId };\n }),\n );\n }\n\n private getChildElementsTreeFromMap({ elementIds }: { elementIds: Id64Arg }): ChildrenTree {\n const result: ChildrenTree = new Map();\n if (Id64.sizeOf(elementIds) === 0 || this.#childElementsMap.size === 0) {\n return result;\n }\n for (const elementId of Id64.iterable(elementIds)) {\n const entry = this.#childElementsMap.get(elementId);\n if (!entry?.children) {\n continue;\n }\n const elementChildrenTree: ChildrenTree = new Map();\n result.set(elementId, { children: elementChildrenTree });\n for (const childId of entry.children) {\n const childrenTreeOfChild = this.getChildElementsTreeFromMap({ elementIds: childId });\n // Need to add children tree created from childId. This tree includes childId as root element\n // If child does not have children, children tree won't be created. Need to add childId with undefined children\n elementChildrenTree.set(childId, { children: childrenTreeOfChild.size > 0 ? childrenTreeOfChild : undefined });\n }\n }\n return result;\n }\n\n private getChildElementsCountMap({ elementIds }: { elementIds: Id64Arg }): Map<Id64String, number> {\n const result = new Map<Id64String, number>();\n for (const elementId of Id64.iterable(elementIds)) {\n const entry = this.#childElementsMap.get(elementId);\n if (entry?.children) {\n let totalChildrenCount = entry.children.length;\n for (const childrenOfChildCount of this.getChildElementsCountMap({ elementIds: entry.children }).values()) {\n totalChildrenCount += childrenOfChildCount;\n }\n result.set(elementId, totalChildrenCount);\n }\n }\n return result;\n }\n\n /**\n * Populates #childElementsLoadingMap with promises. When these promises resolve, they will populate #childElementsMap with values and delete entries from #childElementsLoadingMap.\n */\n private createChildElementsLoadingMapEntries({ elementsToQuery }: { elementsToQuery: Id64Array }): { loadingMapEntries: Promise<void> } {\n const getElementsToQueryPromise = async (batchedElementsToQuery: Id64Array) =>\n firstValueFrom(\n this.queryChildren({ elementIds: batchedElementsToQuery }).pipe(\n // Want to have void at the end instead of void[], so using reduce\n reduce(\n (acc, { parentId, id }) => {\n let entry = this.#childElementsMap.get(parentId);\n if (!entry) {\n entry = { children: [] };\n this.#childElementsMap.set(parentId, entry);\n }\n if (!entry.children) {\n entry.children = [];\n }\n // Add child to parent's entry and add child to children map\n entry.children.push(id);\n if (!this.#childElementsMap.has(id)) {\n this.#childElementsMap.set(id, { children: undefined });\n }\n return acc;\n },\n (() => {})(),\n ),\n tap({ complete: () => batchedElementsToQuery.forEach((elementId) => this.#childElementsLoadingMap.delete(elementId)) }),\n defaultIfEmpty((() => {})()),\n ),\n );\n const maximumBatchSize = 1000;\n const totalSize = elementsToQuery.length;\n const optimalBatchSize = getOptimalBatchSize({ totalSize, maximumBatchSize });\n const loadingMapEntries = new Array<Promise<void>>();\n // Don't want to slice if its not necessary\n if (totalSize <= maximumBatchSize) {\n loadingMapEntries.push(getElementsToQueryPromise(elementsToQuery));\n } else {\n for (let i = 0; i < elementsToQuery.length; i += optimalBatchSize) {\n loadingMapEntries.push(getElementsToQueryPromise(elementsToQuery.slice(i, i + optimalBatchSize)));\n }\n }\n\n elementsToQuery.forEach((elementId, index) => this.#childElementsLoadingMap.set(elementId, loadingMapEntries[Math.floor(index / optimalBatchSize)]));\n return { loadingMapEntries: Promise.all(loadingMapEntries).then(() => {}) };\n }\n\n private createChildElementsMapEntries({ elementIds }: { elementIds: Id64Arg }): Observable<void[]> {\n return from(Id64.iterable(elementIds)).pipe(\n reduce(\n (acc, elementId) => {\n if (this.#childElementsMap.has(elementId)) {\n return acc;\n }\n const loadingPromise = this.#childElementsLoadingMap.get(elementId);\n if (loadingPromise) {\n acc.existingPromises.push(loadingPromise);\n } else {\n acc.elementsToQuery.push(elementId);\n }\n return acc;\n },\n { existingPromises: new Array<Promise<void>>(), elementsToQuery: new Array<Id64String>() },\n ),\n mergeMap(async ({ elementsToQuery, existingPromises }) => {\n existingPromises.push(this.createChildElementsLoadingMapEntries({ elementsToQuery }).loadingMapEntries);\n return Promise.all(existingPromises);\n }),\n );\n }\n\n public getChildElementsTree({ elementIds }: { elementIds: Id64Arg }): Observable<ChildrenTree> {\n return this.createChildElementsMapEntries({ elementIds }).pipe(map(() => this.getChildElementsTreeFromMap({ elementIds })));\n }\n\n public getAllChildElementsCount({ elementIds }: { elementIds: Id64Arg }): Observable<Map<Id64String, number>> {\n return this.createChildElementsMapEntries({ elementIds }).pipe(map(() => this.getChildElementsCountMap({ elementIds })));\n }\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import type { Observable } from "rxjs";
2
+ import type { GuidString, Id64Array, Id64Set, Id64String } from "@itwin/core-bentley";
3
+ import type { LimitingECSqlQueryExecutor } from "@itwin/presentation-hierarchies";
4
+ import type { ModelId } from "../Types.js";
5
+ import type { ModeledElementsCache } from "./ModeledElementsCache.js";
6
+ interface ElementModelCategoriesCacheProps {
7
+ queryExecutor: LimitingECSqlQueryExecutor;
8
+ componentId: GuidString;
9
+ elementClassName: string;
10
+ modeledElementsCache: ModeledElementsCache;
11
+ }
12
+ /** @internal */
13
+ export declare class ElementModelCategoriesCache {
14
+ #private;
15
+ constructor(props: ElementModelCategoriesCacheProps);
16
+ private queryElementModelCategories;
17
+ private getModelsCategoriesInfo;
18
+ getCategoryElementModels(props: {
19
+ categoryId: Id64String;
20
+ includeSubModels?: boolean;
21
+ includeOnlyIfCategoryOfTopMostElement?: boolean;
22
+ }): Observable<Array<ModelId>>;
23
+ getModelCategoryIds({ modelId, includeOnlyIfCategoryOfTopMostElement, }: {
24
+ modelId: Id64String;
25
+ includeOnlyIfCategoryOfTopMostElement?: boolean;
26
+ }): Observable<Id64Set>;
27
+ getCategoriesOfModelsTopMostElements(modelIds: Id64Array): Observable<Id64Set>;
28
+ getAllCategoriesOfElements(): Observable<Id64Set>;
29
+ getAllModels(): Observable<Array<ModelId>>;
30
+ }
31
+ export {};
32
+ //# sourceMappingURL=ElementModelCategoriesCache.d.ts.map
@@ -0,0 +1,106 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { defer, forkJoin, from, map, mergeMap, reduce, shareReplay } from "rxjs";
6
+ import { CLASS_NAME_Model } from "../ClassNameDefinitions.js";
7
+ import { catchBeSQLiteInterrupts } from "../UseErrorState.js";
8
+ /** @internal */
9
+ export class ElementModelCategoriesCache {
10
+ #queryExecutor;
11
+ #componentId;
12
+ #componentName;
13
+ #elementClassName;
14
+ #modeledElementsCache;
15
+ #modelsCategoriesInfo;
16
+ constructor(props) {
17
+ this.#queryExecutor = props.queryExecutor;
18
+ this.#elementClassName = props.elementClassName;
19
+ this.#modeledElementsCache = props.modeledElementsCache;
20
+ this.#componentId = props.componentId;
21
+ this.#componentName = "ElementModelCategoriesCache";
22
+ }
23
+ queryElementModelCategories() {
24
+ return defer(() => {
25
+ const query = `
26
+ SELECT * FROM (
27
+ SELECT
28
+ this.Model.Id modelId,
29
+ this.Category.Id categoryId,
30
+ MAX(IIF(this.Parent.Id IS NULL, 1, 0)) isTopMostElementCategory
31
+ FROM ${CLASS_NAME_Model} m
32
+ JOIN ${this.#elementClassName} this ON m.ECInstanceId = this.Model.Id
33
+ WHERE m.IsPrivate = false
34
+ GROUP BY modelId, categoryId
35
+ )
36
+ `;
37
+ return this.#queryExecutor.createQueryReader({ ecsql: query }, { rowFormat: "ECSqlPropertyNames", limit: "unbounded", restartToken: `${this.#componentName}/${this.#componentId}/element-models-and-categories` });
38
+ }).pipe(catchBeSQLiteInterrupts, map((row) => {
39
+ return { modelId: row.modelId, categoryId: row.categoryId, isTopMostElementCategory: !!row.isTopMostElementCategory };
40
+ }));
41
+ }
42
+ getModelsCategoriesInfo() {
43
+ this.#modelsCategoriesInfo ??= forkJoin({
44
+ modelCategories: this.queryElementModelCategories().pipe(reduce((acc, queriedCategory) => {
45
+ let modelEntry = acc.get(queriedCategory.modelId);
46
+ if (modelEntry === undefined) {
47
+ modelEntry = { categoriesOfTopMostElements: new Set(), allCategories: new Set() };
48
+ acc.set(queriedCategory.modelId, modelEntry);
49
+ }
50
+ modelEntry.allCategories.add(queriedCategory.categoryId);
51
+ if (queriedCategory.isTopMostElementCategory) {
52
+ modelEntry.categoriesOfTopMostElements.add(queriedCategory.categoryId);
53
+ }
54
+ return acc;
55
+ }, new Map())),
56
+ allSubModels: this.#modeledElementsCache.getModeledElementsInfo().pipe(map(({ allSubModels }) => allSubModels)),
57
+ }).pipe(map(({ modelCategories, allSubModels }) => {
58
+ const result = new Map();
59
+ for (const [modelId, { categoriesOfTopMostElements, allCategories }] of modelCategories) {
60
+ const isSubModel = allSubModels.has(modelId);
61
+ result.set(modelId, {
62
+ categoriesOfTopMostElements,
63
+ allCategories,
64
+ isSubModel,
65
+ });
66
+ }
67
+ return result;
68
+ }), shareReplay());
69
+ return this.#modelsCategoriesInfo;
70
+ }
71
+ getCategoryElementModels(props) {
72
+ const { categoryId, includeSubModels } = props;
73
+ return this.getModelsCategoriesInfo().pipe(map((modelCategories) => {
74
+ const categoryModels = new Array();
75
+ for (const [modelId, { allCategories, categoriesOfTopMostElements, isSubModel }] of modelCategories) {
76
+ if ((includeSubModels || !isSubModel) &&
77
+ (props.includeOnlyIfCategoryOfTopMostElement ? categoriesOfTopMostElements.has(categoryId) : allCategories.has(categoryId))) {
78
+ categoryModels.push(modelId);
79
+ }
80
+ }
81
+ return categoryModels;
82
+ }));
83
+ }
84
+ getModelCategoryIds({ modelId, includeOnlyIfCategoryOfTopMostElement, }) {
85
+ return this.getModelsCategoriesInfo().pipe(map((modelCategories) => (includeOnlyIfCategoryOfTopMostElement ? modelCategories.get(modelId)?.categoriesOfTopMostElements : modelCategories.get(modelId)?.allCategories) ??
86
+ new Set()));
87
+ }
88
+ getCategoriesOfModelsTopMostElements(modelIds) {
89
+ return this.getModelsCategoriesInfo().pipe(mergeMap((modelCategories) => from(modelIds).pipe(mergeMap((modelId) => modelCategories.get(modelId)?.categoriesOfTopMostElements ?? []))), reduce((acc, categoryId) => {
90
+ acc.add(categoryId);
91
+ return acc;
92
+ }, new Set()));
93
+ }
94
+ getAllCategoriesOfElements() {
95
+ return this.getModelsCategoriesInfo().pipe(mergeMap((modelCategories) => modelCategories.values()), reduce((acc, { allCategories }) => {
96
+ for (const categoryId of allCategories) {
97
+ acc.add(categoryId);
98
+ }
99
+ return acc;
100
+ }, new Set()));
101
+ }
102
+ getAllModels() {
103
+ return this.getModelsCategoriesInfo().pipe(map((modelCategories) => [...modelCategories.keys()]));
104
+ }
105
+ }
106
+ //# sourceMappingURL=ElementModelCategoriesCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ElementModelCategoriesCache.js","sourceRoot":"","sources":["../../../../../../../../src/tree-widget-react/components/trees/common/internal/caches/ElementModelCategoriesCache.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { defer, forkJoin, from, map, mergeMap, reduce, shareReplay } from \"rxjs\";\nimport { CLASS_NAME_Model } from \"../ClassNameDefinitions.js\";\nimport { catchBeSQLiteInterrupts } from \"../UseErrorState.js\";\n\nimport type { Observable } from \"rxjs\";\nimport type { GuidString, Id64Array, Id64Set, Id64String } from \"@itwin/core-bentley\";\nimport type { LimitingECSqlQueryExecutor } from \"@itwin/presentation-hierarchies\";\nimport type { CategoryId, ModelId } from \"../Types.js\";\nimport type { ModeledElementsCache } from \"./ModeledElementsCache.js\";\n\ninterface ElementModelCategoriesCacheProps {\n queryExecutor: LimitingECSqlQueryExecutor;\n componentId: GuidString;\n elementClassName: string;\n modeledElementsCache: ModeledElementsCache;\n}\n\n/** @internal */\nexport class ElementModelCategoriesCache {\n #queryExecutor: LimitingECSqlQueryExecutor;\n #componentId: GuidString;\n #componentName: string;\n #elementClassName: string;\n #modeledElementsCache: ModeledElementsCache;\n #modelsCategoriesInfo:\n | Observable<Map<ModelId, { categoriesOfTopMostElements: Set<CategoryId>; allCategories: Set<CategoryId>; isSubModel: boolean }>>\n | undefined;\n\n constructor(props: ElementModelCategoriesCacheProps) {\n this.#queryExecutor = props.queryExecutor;\n this.#elementClassName = props.elementClassName;\n this.#modeledElementsCache = props.modeledElementsCache;\n this.#componentId = props.componentId;\n this.#componentName = \"ElementModelCategoriesCache\";\n }\n\n private queryElementModelCategories(): Observable<{\n modelId: Id64String;\n categoryId: Id64String;\n isTopMostElementCategory: boolean;\n }> {\n return defer(() => {\n const query = `\n SELECT * FROM (\n SELECT\n this.Model.Id modelId,\n this.Category.Id categoryId,\n MAX(IIF(this.Parent.Id IS NULL, 1, 0)) isTopMostElementCategory\n FROM ${CLASS_NAME_Model} m\n JOIN ${this.#elementClassName} this ON m.ECInstanceId = this.Model.Id\n WHERE m.IsPrivate = false\n GROUP BY modelId, categoryId\n )\n `;\n return this.#queryExecutor.createQueryReader(\n { ecsql: query },\n { rowFormat: \"ECSqlPropertyNames\", limit: \"unbounded\", restartToken: `${this.#componentName}/${this.#componentId}/element-models-and-categories` },\n );\n }).pipe(\n catchBeSQLiteInterrupts,\n map((row) => {\n return { modelId: row.modelId, categoryId: row.categoryId, isTopMostElementCategory: !!row.isTopMostElementCategory };\n }),\n );\n }\n\n private getModelsCategoriesInfo() {\n this.#modelsCategoriesInfo ??= forkJoin({\n modelCategories: this.queryElementModelCategories().pipe(\n reduce((acc, queriedCategory) => {\n let modelEntry = acc.get(queriedCategory.modelId);\n if (modelEntry === undefined) {\n modelEntry = { categoriesOfTopMostElements: new Set(), allCategories: new Set() };\n acc.set(queriedCategory.modelId, modelEntry);\n }\n modelEntry.allCategories.add(queriedCategory.categoryId);\n if (queriedCategory.isTopMostElementCategory) {\n modelEntry.categoriesOfTopMostElements.add(queriedCategory.categoryId);\n }\n return acc;\n }, new Map<ModelId, { categoriesOfTopMostElements: Set<CategoryId>; allCategories: Set<CategoryId> }>()),\n ),\n allSubModels: this.#modeledElementsCache.getModeledElementsInfo().pipe(map(({ allSubModels }) => allSubModels)),\n }).pipe(\n map(({ modelCategories, allSubModels }) => {\n const result = new Map<ModelId, { categoriesOfTopMostElements: Set<CategoryId>; allCategories: Set<CategoryId>; isSubModel: boolean }>();\n for (const [modelId, { categoriesOfTopMostElements, allCategories }] of modelCategories) {\n const isSubModel = allSubModels.has(modelId);\n result.set(modelId, {\n categoriesOfTopMostElements,\n allCategories,\n isSubModel,\n });\n }\n return result;\n }),\n shareReplay(),\n );\n return this.#modelsCategoriesInfo;\n }\n\n public getCategoryElementModels(props: {\n categoryId: Id64String;\n includeSubModels?: boolean;\n includeOnlyIfCategoryOfTopMostElement?: boolean;\n }): Observable<Array<ModelId>> {\n const { categoryId, includeSubModels } = props;\n return this.getModelsCategoriesInfo().pipe(\n map((modelCategories) => {\n const categoryModels = new Array<ModelId>();\n for (const [modelId, { allCategories, categoriesOfTopMostElements, isSubModel }] of modelCategories) {\n if (\n (includeSubModels || !isSubModel) &&\n (props.includeOnlyIfCategoryOfTopMostElement ? categoriesOfTopMostElements.has(categoryId) : allCategories.has(categoryId))\n ) {\n categoryModels.push(modelId);\n }\n }\n return categoryModels;\n }),\n );\n }\n\n public getModelCategoryIds({\n modelId,\n includeOnlyIfCategoryOfTopMostElement,\n }: {\n modelId: Id64String;\n includeOnlyIfCategoryOfTopMostElement?: boolean;\n }): Observable<Id64Set> {\n return this.getModelsCategoriesInfo().pipe(\n map(\n (modelCategories) =>\n (includeOnlyIfCategoryOfTopMostElement ? modelCategories.get(modelId)?.categoriesOfTopMostElements : modelCategories.get(modelId)?.allCategories) ??\n new Set(),\n ),\n );\n }\n\n public getCategoriesOfModelsTopMostElements(modelIds: Id64Array): Observable<Id64Set> {\n return this.getModelsCategoriesInfo().pipe(\n mergeMap((modelCategories) => from(modelIds).pipe(mergeMap((modelId) => modelCategories.get(modelId)?.categoriesOfTopMostElements ?? []))),\n reduce((acc, categoryId) => {\n acc.add(categoryId);\n return acc;\n }, new Set<Id64String>()),\n );\n }\n\n public getAllCategoriesOfElements(): Observable<Id64Set> {\n return this.getModelsCategoriesInfo().pipe(\n mergeMap((modelCategories) => modelCategories.values()),\n reduce((acc, { allCategories }) => {\n for (const categoryId of allCategories) {\n acc.add(categoryId);\n }\n return acc;\n }, new Set<CategoryId>()),\n );\n }\n\n public getAllModels(): Observable<Array<ModelId>> {\n return this.getModelsCategoriesInfo().pipe(map((modelCategories) => [...modelCategories.keys()]));\n }\n}\n"]}
@@ -4,9 +4,16 @@ import type { LimitingECSqlQueryExecutor } from "@itwin/presentation-hierarchies
4
4
  /** @internal */
5
5
  export declare class ModelCategoryElementsCountCache implements Disposable {
6
6
  #private;
7
- constructor(queryExecutor: LimitingECSqlQueryExecutor, elementsClassNames: string[], componentId: GuidString);
7
+ constructor(props: {
8
+ queryExecutor: LimitingECSqlQueryExecutor;
9
+ elementClassName: string;
10
+ componentId: GuidString;
11
+ });
8
12
  private queryCategoryElementCounts;
9
13
  [Symbol.dispose](): void;
10
- getCategoryElementsCount(modelId: Id64String, categoryId: Id64String): Observable<number>;
14
+ getCategoryElementsCount({ modelId, categoryId }: {
15
+ modelId: Id64String;
16
+ categoryId: Id64String;
17
+ }): Observable<number>;
11
18
  }
12
19
  //# sourceMappingURL=ModelCategoryElementsCountCache.d.ts.map
@@ -4,21 +4,21 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import { bufferCount, bufferTime, defer, filter, from, map, mergeAll, mergeMap, reduce, ReplaySubject, Subject, take, toArray } from "rxjs";
6
6
  import { assert, Guid } from "@itwin/core-bentley";
7
- import { catchBeSQLiteInterrupts } from "./UseErrorState.js";
8
- import { releaseMainThreadOnItemsCount } from "./Utils.js";
7
+ import { catchBeSQLiteInterrupts } from "../UseErrorState.js";
8
+ import { releaseMainThreadOnItemsCount } from "../Utils.js";
9
9
  /** @internal */
10
10
  export class ModelCategoryElementsCountCache {
11
11
  #cache = new Map();
12
12
  #requestsStream = new Subject();
13
13
  #subscription;
14
14
  #queryExecutor;
15
- #elementsClassNames;
15
+ #elementClassName;
16
16
  #componentId;
17
17
  #componentName;
18
- constructor(queryExecutor, elementsClassNames, componentId) {
19
- this.#componentId = componentId;
20
- this.#queryExecutor = queryExecutor;
21
- this.#elementsClassNames = elementsClassNames;
18
+ constructor(props) {
19
+ this.#componentId = props.componentId;
20
+ this.#queryExecutor = props.queryExecutor;
21
+ this.#elementClassName = props.elementClassName;
22
22
  this.#componentName = "ModelCategoryElementsCountCache";
23
23
  this.#subscription = this.#requestsStream
24
24
  .pipe(bufferTime(20), filter((requests) => requests.length > 0), mergeMap((requests) => this.queryCategoryElementCounts(requests)), mergeAll())
@@ -44,10 +44,11 @@ export class ModelCategoryElementsCountCache {
44
44
  // we may have thousands of where clauses here, and sending a single query with all of them could take a
45
45
  // long time - instead, split it into smaller chunks
46
46
  bufferCount(100), mergeMap((whereClauses) => defer(() => this.#queryExecutor.createQueryReader({
47
- ctes: this.#elementsClassNames.map((elementsClassName, index) => `
48
- CategoryElements${index}(id, modelId, categoryId) AS (
47
+ ctes: [
48
+ `
49
+ CategoryElements(id, modelId, categoryId) AS (
49
50
  SELECT ECInstanceId, Model.Id, Category.Id
50
- FROM ${elementsClassName}
51
+ FROM ${this.#elementClassName}
51
52
  WHERE
52
53
  Parent.Id IS NULL
53
54
  AND (
@@ -57,19 +58,14 @@ export class ModelCategoryElementsCountCache {
57
58
  UNION ALL
58
59
 
59
60
  SELECT c.ECInstanceId, p.modelId, p.categoryId
60
- FROM ${elementsClassName} c
61
- JOIN CategoryElements${index} p ON c.Parent.Id = p.id
61
+ FROM ${this.#elementClassName} c
62
+ JOIN CategoryElements p ON c.Parent.Id = p.id
62
63
  )
63
- `),
64
+ `,
65
+ ],
64
66
  ecsql: `
65
67
  SELECT modelId, categoryId, COUNT(id) elementsCount
66
- FROM (
67
- ${this.#elementsClassNames
68
- .map((_, index) => `
69
- SELECT * FROM CategoryElements${index}
70
- `)
71
- .join(" UNION ALL ")}
72
- )
68
+ FROM (SELECT * FROM CategoryElements)
73
69
  GROUP BY modelId, categoryId
74
70
  `,
75
71
  }, {
@@ -98,7 +94,7 @@ export class ModelCategoryElementsCountCache {
98
94
  [Symbol.dispose]() {
99
95
  this.#subscription.unsubscribe();
100
96
  }
101
- getCategoryElementsCount(modelId, categoryId) {
97
+ getCategoryElementsCount({ modelId, categoryId }) {
102
98
  const cacheKey = `${modelId}-${categoryId}`;
103
99
  let result = this.#cache.get(cacheKey);
104
100
  if (result !== undefined) {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelCategoryElementsCountCache.js","sourceRoot":"","sources":["../../../../../../../../src/tree-widget-react/components/trees/common/internal/caches/ModelCategoryElementsCountCache.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { bufferCount, bufferTime, defer, filter, from, map, mergeAll, mergeMap, reduce, ReplaySubject, Subject, take, toArray } from \"rxjs\";\nimport { assert, Guid } from \"@itwin/core-bentley\";\nimport { catchBeSQLiteInterrupts } from \"../UseErrorState.js\";\nimport { releaseMainThreadOnItemsCount } from \"../Utils.js\";\n\nimport type { Observable, Subscription } from \"rxjs\";\nimport type { GuidString, Id64Set, Id64String } from \"@itwin/core-bentley\";\nimport type { LimitingECSqlQueryExecutor } from \"@itwin/presentation-hierarchies\";\nimport type { CategoryId, ModelId } from \"../Types.js\";\n\ntype ModelCategoryKey = `${ModelId}-${CategoryId}`;\n\n/** @internal */\nexport class ModelCategoryElementsCountCache implements Disposable {\n #cache = new Map<ModelCategoryKey, Subject<number>>();\n #requestsStream = new Subject<{ modelId: Id64String; categoryId: Id64String }>();\n #subscription: Subscription;\n #queryExecutor: LimitingECSqlQueryExecutor;\n #elementClassName: string;\n #componentId: GuidString;\n #componentName: string;\n\n public constructor(props: { queryExecutor: LimitingECSqlQueryExecutor; elementClassName: string; componentId: GuidString }) {\n this.#componentId = props.componentId;\n this.#queryExecutor = props.queryExecutor;\n this.#elementClassName = props.elementClassName;\n this.#componentName = \"ModelCategoryElementsCountCache\";\n this.#subscription = this.#requestsStream\n .pipe(\n bufferTime(20),\n filter((requests) => requests.length > 0),\n mergeMap((requests) => this.queryCategoryElementCounts(requests)),\n mergeAll(),\n )\n .subscribe({\n next: ({ modelId, categoryId, elementsCount }) => {\n const subject = this.#cache.get(`${modelId}-${categoryId}`);\n assert(!!subject);\n subject.next(elementsCount);\n },\n });\n }\n\n private queryCategoryElementCounts(\n input: Array<{ modelId: Id64String; categoryId: Id64String }>,\n ): Observable<Array<{ modelId: Id64String; categoryId: Id64String; elementsCount: number }>> {\n return from(input).pipe(\n reduce((acc, { modelId, categoryId }) => {\n const entry = acc.get(modelId);\n if (!entry) {\n acc.set(modelId, new Set([categoryId]));\n } else {\n entry.add(categoryId);\n }\n return acc;\n }, new Map<Id64String, Id64Set>()),\n mergeMap((modelCategoryMap) => modelCategoryMap.entries()),\n map(([modelId, categoryIds]) => `Model.Id = ${modelId} AND Category.Id IN (${[...categoryIds].join(\", \")})`),\n // we may have thousands of where clauses here, and sending a single query with all of them could take a\n // long time - instead, split it into smaller chunks\n bufferCount(100),\n mergeMap((whereClauses) =>\n defer(() =>\n this.#queryExecutor.createQueryReader(\n {\n ctes: [\n `\n CategoryElements(id, modelId, categoryId) AS (\n SELECT ECInstanceId, Model.Id, Category.Id\n FROM ${this.#elementClassName}\n WHERE\n Parent.Id IS NULL\n AND (\n ${whereClauses.join(\" OR \")}\n )\n\n UNION ALL\n\n SELECT c.ECInstanceId, p.modelId, p.categoryId\n FROM ${this.#elementClassName} c\n JOIN CategoryElements p ON c.Parent.Id = p.id\n )\n `,\n ],\n ecsql: `\n SELECT modelId, categoryId, COUNT(id) elementsCount\n FROM (SELECT * FROM CategoryElements)\n GROUP BY modelId, categoryId\n `,\n },\n {\n rowFormat: \"ECSqlPropertyNames\",\n limit: \"unbounded\",\n restartToken: `${this.#componentName}/${this.#componentId}/category-element-counts/${Guid.createValue()}`,\n },\n ),\n ).pipe(catchBeSQLiteInterrupts),\n ),\n releaseMainThreadOnItemsCount(500),\n reduce(\n ({ acc, createKey }, row) => {\n acc.set(createKey({ modelId: row.modelId, categoryId: row.categoryId }), {\n modelId: row.modelId,\n categoryId: row.categoryId,\n elementsCount: row.elementsCount,\n });\n return { acc, createKey };\n },\n {\n acc: new Map<string, { modelId: Id64String; categoryId: Id64String; elementsCount: number }>(),\n createKey: (keyProps: { modelId: Id64String; categoryId: Id64String }) => `${keyProps.modelId}-${keyProps.categoryId}`,\n },\n ),\n mergeMap(({ acc: result, createKey }) => {\n input.forEach(({ modelId, categoryId }) => {\n if (!result.has(createKey({ modelId, categoryId }))) {\n result.set(createKey({ modelId, categoryId }), { categoryId, modelId, elementsCount: 0 });\n }\n });\n\n return from(result.values());\n }),\n toArray(),\n );\n }\n\n public [Symbol.dispose]() {\n this.#subscription.unsubscribe();\n }\n\n public getCategoryElementsCount({ modelId, categoryId }: { modelId: Id64String; categoryId: Id64String }): Observable<number> {\n const cacheKey: ModelCategoryKey = `${modelId}-${categoryId}`;\n let result = this.#cache.get(cacheKey);\n if (result !== undefined) {\n return from(result).pipe(take(1));\n }\n\n result = new ReplaySubject(1);\n this.#cache.set(cacheKey, result);\n this.#requestsStream.next({ modelId, categoryId });\n return from(result).pipe(take(1));\n }\n}\n"]}
@@ -0,0 +1,27 @@
1
+ import type { Observable } from "rxjs";
2
+ import type { GuidString, Id64Array, Id64String } from "@itwin/core-bentley";
3
+ import type { LimitingECSqlQueryExecutor } from "@itwin/presentation-hierarchies";
4
+ import type { CategoryId, ElementId, ModelId } from "../Types.js";
5
+ interface ModeledElementsCacheProps {
6
+ queryExecutor: LimitingECSqlQueryExecutor;
7
+ componentId: GuidString;
8
+ elementClassName: string;
9
+ }
10
+ /** @internal */
11
+ export declare class ModeledElementsCache {
12
+ #private;
13
+ constructor(props: ModeledElementsCacheProps);
14
+ private queryModeledElements;
15
+ getModeledElementsInfo(): Observable<{
16
+ modelWithCategoryModeledElements: Map<ModelId, Map<CategoryId, Set<ElementId>>>;
17
+ allSubModels: Set<ElementId>;
18
+ childSubModels: Map<ElementId, Set<ElementId>>;
19
+ }>;
20
+ getSubModelsUnderElement(elementId: Id64String): Observable<Id64Array>;
21
+ getCategoryModeledElements({ modelId, categoryId }: {
22
+ modelId: Id64String;
23
+ categoryId: Id64String;
24
+ }): Observable<Id64String>;
25
+ }
26
+ export {};
27
+ //# sourceMappingURL=ModeledElementsCache.d.ts.map
@@ -0,0 +1,106 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { defer, map, mergeMap, reduce, shareReplay } from "rxjs";
6
+ import { CLASS_NAME_Model } from "../ClassNameDefinitions.js";
7
+ import { catchBeSQLiteInterrupts } from "../UseErrorState.js";
8
+ /** @internal */
9
+ export class ModeledElementsCache {
10
+ #queryExecutor;
11
+ #componentId;
12
+ #componentName;
13
+ #elementClassName;
14
+ // ElementId here is also a ModelId, since those elements are sub models.
15
+ #modeledElementsInfo;
16
+ constructor(props) {
17
+ this.#queryExecutor = props.queryExecutor;
18
+ this.#componentId = props.componentId;
19
+ this.#elementClassName = props.elementClassName;
20
+ this.#componentName = "ModeledElementsCache";
21
+ }
22
+ queryModeledElements() {
23
+ return defer(() => {
24
+ const query = `
25
+ SELECT
26
+ me.ECInstanceId modeledElementId,
27
+ me.Category.Id categoryId,
28
+ me.Model.Id modelId,
29
+ IIF(me.Parent.Id IS NULL,
30
+ '',
31
+ (
32
+ WITH RECURSIVE ModeledElementParents(parentId, parentPath) AS (
33
+ SELECT p.Parent.Id, CAST(IdToHex(p.ECInstanceId) AS TEXT)
34
+ FROM ${this.#elementClassName} p
35
+ WHERE p.ECInstanceId = me.Parent.Id
36
+ UNION ALL
37
+ SELECT pOfp.Parent.Id, CAST(IdToHex(pOfp.ECInstanceId) AS TEXT) || ';' || c.parentPath
38
+ FROM ${this.#elementClassName} pOfp
39
+ JOIN ModeledElementParents c ON c.parentId = pOfp.ECInstanceId
40
+ )
41
+ SELECT parentPath
42
+ FROM ModeledElementParents
43
+ WHERE parentId IS NULL
44
+ )
45
+ ) parentElements
46
+ FROM ${CLASS_NAME_Model} m
47
+ JOIN ${this.#elementClassName} me ON me.ECInstanceId = m.ModeledElement.Id
48
+ WHERE
49
+ m.IsPrivate = false
50
+ AND m.ECInstanceId IN (SELECT Model.Id FROM ${this.#elementClassName})
51
+ `;
52
+ return this.#queryExecutor.createQueryReader({ ecsql: query }, { rowFormat: "ECSqlPropertyNames", limit: "unbounded", restartToken: `${this.#componentName}/${this.#componentId}/modeled-elements` });
53
+ }).pipe(catchBeSQLiteInterrupts, map((row) => {
54
+ return { modelId: row.modelId, categoryId: row.categoryId, modeledElementId: row.modeledElementId, parentElements: row.parentElements.split(";") };
55
+ }));
56
+ }
57
+ getModeledElementsInfo() {
58
+ this.#modeledElementsInfo ??= this.queryModeledElements().pipe(reduce((acc, { modelId, categoryId, modeledElementId, parentElements }) => {
59
+ let modelEntry = acc.modelWithCategoryModeledElements.get(modelId);
60
+ if (!modelEntry) {
61
+ modelEntry = new Map();
62
+ acc.modelWithCategoryModeledElements.set(modelId, modelEntry);
63
+ }
64
+ const categoryEntry = modelEntry.get(categoryId);
65
+ if (!categoryEntry) {
66
+ modelEntry.set(categoryId, new Set([modeledElementId]));
67
+ }
68
+ else {
69
+ categoryEntry.add(modeledElementId);
70
+ }
71
+ acc.allSubModels.add(modeledElementId);
72
+ parentElements.forEach((parentElementId) => {
73
+ const entry = acc.childSubModels.get(parentElementId);
74
+ if (!entry) {
75
+ acc.childSubModels.set(parentElementId, new Set([modeledElementId]));
76
+ }
77
+ else {
78
+ entry.add(modeledElementId);
79
+ }
80
+ });
81
+ return acc;
82
+ }, {
83
+ modelWithCategoryModeledElements: new Map(),
84
+ allSubModels: new Set(),
85
+ childSubModels: new Map(),
86
+ }), shareReplay());
87
+ return this.#modeledElementsInfo;
88
+ }
89
+ getSubModelsUnderElement(elementId) {
90
+ return this.getModeledElementsInfo().pipe(map(({ allSubModels, childSubModels }) => {
91
+ const subModels = new Array();
92
+ if (allSubModels.has(elementId)) {
93
+ subModels.push(elementId);
94
+ }
95
+ const elementEntry = childSubModels.get(elementId);
96
+ for (const childSubModelId of elementEntry ?? []) {
97
+ subModels.push(childSubModelId);
98
+ }
99
+ return subModels;
100
+ }));
101
+ }
102
+ getCategoryModeledElements({ modelId, categoryId }) {
103
+ return this.getModeledElementsInfo().pipe(mergeMap(({ modelWithCategoryModeledElements }) => modelWithCategoryModeledElements.get(modelId)?.get(categoryId) ?? new Set()));
104
+ }
105
+ }
106
+ //# sourceMappingURL=ModeledElementsCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModeledElementsCache.js","sourceRoot":"","sources":["../../../../../../../../src/tree-widget-react/components/trees/common/internal/caches/ModeledElementsCache.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAa9D,gBAAgB;AAChB,MAAM,OAAO,oBAAoB;IAC/B,cAAc,CAA6B;IAC3C,YAAY,CAAa;IACzB,cAAc,CAAS;IACvB,iBAAiB,CAAS;IAC1B,yEAAyE;IACzE,oBAAoB,CAMN;IAEd,YAAY,KAAgC;QAC1C,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC,aAAa,CAAC;QAC1C,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,gBAAgB,CAAC;QAChD,IAAI,CAAC,cAAc,GAAG,sBAAsB,CAAC;IAC/C,CAAC;IAEO,oBAAoB;QAM1B,OAAO,KAAK,CAAC,GAAG,EAAE;YAChB,MAAM,KAAK,GAAG;;;;;;;;;;uBAUG,IAAI,CAAC,iBAAiB;;;;uBAItB,IAAI,CAAC,iBAAiB;;;;;;;;eAQ9B,gBAAgB;eAChB,IAAI,CAAC,iBAAiB;;;wDAGmB,IAAI,CAAC,iBAAiB;OACvE,CAAC;YACF,OAAO,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAC1C,EAAE,KAAK,EAAE,KAAK,EAAE,EAChB,EAAE,SAAS,EAAE,oBAAoB,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,YAAY,mBAAmB,EAAE,CACtI,CAAC;QACJ,CAAC,CAAC,CAAC,IAAI,CACL,uBAAuB,EACvB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACV,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,gBAAgB,EAAE,GAAG,CAAC,gBAAgB,EAAE,cAAc,EAAE,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACrJ,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAEM,sBAAsB;QAC3B,IAAI,CAAC,oBAAoB,KAAK,IAAI,CAAC,oBAAoB,EAAE,CAAC,IAAI,CAC5D,MAAM,CACJ,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,EAAE,EAAE;YACjE,IAAI,UAAU,GAAG,GAAG,CAAC,gCAAgC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACnE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,UAAU,GAAG,IAAI,GAAG,EAAE,CAAC;gBACvB,GAAG,CAAC,gCAAgC,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAChE,CAAC;YACD,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACjD,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;YAC1D,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YACtC,CAAC;YACD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YACvC,cAAc,CAAC,OAAO,CAAC,CAAC,eAAe,EAAE,EAAE;gBACzC,MAAM,KAAK,GAAG,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;gBACtD,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;gBACvE,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC,CAAC,CAAC;YACH,OAAO,GAAG,CAAC;QACb,CAAC,EACD;YACE,gCAAgC,EAAE,IAAI,GAAG,EAA4C;YACrF,YAAY,EAAE,IAAI,GAAG,EAAa;YAClC,cAAc,EAAE,IAAI,GAAG,EAA6B;SACrD,CACF,EACD,WAAW,EAAE,CACd,CAAC;QACF,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IAEM,wBAAwB,CAAC,SAAqB;QACnD,OAAO,IAAI,CAAC,sBAAsB,EAAE,CAAC,IAAI,CACvC,GAAG,CAAC,CAAC,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,EAAE;YACvC,MAAM,SAAS,GAAG,IAAI,KAAK,EAAa,CAAC;YACzC,IAAI,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAChC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC5B,CAAC;YACD,MAAM,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACnD,KAAK,MAAM,eAAe,IAAI,YAAY,IAAI,EAAE,EAAE,CAAC;gBACjD,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAClC,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAEM,0BAA0B,CAAC,EAAE,OAAO,EAAE,UAAU,EAAmD;QACxG,OAAO,IAAI,CAAC,sBAAsB,EAAE,CAAC,IAAI,CACvC,QAAQ,CAAC,CAAC,EAAE,gCAAgC,EAAE,EAAE,EAAE,CAAC,gCAAgC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,GAAG,EAAc,CAAC,CAC5I,CAAC;IACJ,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { defer, map, mergeMap, reduce, shareReplay } from \"rxjs\";\nimport { CLASS_NAME_Model } from \"../ClassNameDefinitions.js\";\nimport { catchBeSQLiteInterrupts } from \"../UseErrorState.js\";\n\nimport type { Observable } from \"rxjs\";\nimport type { GuidString, Id64Array, Id64String } from \"@itwin/core-bentley\";\nimport type { LimitingECSqlQueryExecutor } from \"@itwin/presentation-hierarchies\";\nimport type { CategoryId, ElementId, ModelId } from \"../Types.js\";\n\ninterface ModeledElementsCacheProps {\n queryExecutor: LimitingECSqlQueryExecutor;\n componentId: GuidString;\n elementClassName: string;\n}\n\n/** @internal */\nexport class ModeledElementsCache {\n #queryExecutor: LimitingECSqlQueryExecutor;\n #componentId: GuidString;\n #componentName: string;\n #elementClassName: string;\n // ElementId here is also a ModelId, since those elements are sub models.\n #modeledElementsInfo:\n | Observable<{\n modelWithCategoryModeledElements: Map<ModelId, Map<CategoryId, Set<ElementId>>>;\n allSubModels: Set<ElementId>;\n childSubModels: Map<ElementId, Set<ElementId>>;\n }>\n | undefined;\n\n constructor(props: ModeledElementsCacheProps) {\n this.#queryExecutor = props.queryExecutor;\n this.#componentId = props.componentId;\n this.#elementClassName = props.elementClassName;\n this.#componentName = \"ModeledElementsCache\";\n }\n\n private queryModeledElements(): Observable<{\n modelId: Id64String;\n modeledElementId: Id64String;\n categoryId: Id64String;\n parentElements: Id64Array;\n }> {\n return defer(() => {\n const query = `\n SELECT\n me.ECInstanceId modeledElementId,\n me.Category.Id categoryId,\n me.Model.Id modelId,\n IIF(me.Parent.Id IS NULL,\n '',\n (\n WITH RECURSIVE ModeledElementParents(parentId, parentPath) AS (\n SELECT p.Parent.Id, CAST(IdToHex(p.ECInstanceId) AS TEXT)\n FROM ${this.#elementClassName} p\n WHERE p.ECInstanceId = me.Parent.Id\n UNION ALL\n SELECT pOfp.Parent.Id, CAST(IdToHex(pOfp.ECInstanceId) AS TEXT) || ';' || c.parentPath\n FROM ${this.#elementClassName} pOfp\n JOIN ModeledElementParents c ON c.parentId = pOfp.ECInstanceId\n )\n SELECT parentPath\n FROM ModeledElementParents\n WHERE parentId IS NULL\n )\n ) parentElements\n FROM ${CLASS_NAME_Model} m\n JOIN ${this.#elementClassName} me ON me.ECInstanceId = m.ModeledElement.Id\n WHERE\n m.IsPrivate = false\n AND m.ECInstanceId IN (SELECT Model.Id FROM ${this.#elementClassName})\n `;\n return this.#queryExecutor.createQueryReader(\n { ecsql: query },\n { rowFormat: \"ECSqlPropertyNames\", limit: \"unbounded\", restartToken: `${this.#componentName}/${this.#componentId}/modeled-elements` },\n );\n }).pipe(\n catchBeSQLiteInterrupts,\n map((row) => {\n return { modelId: row.modelId, categoryId: row.categoryId, modeledElementId: row.modeledElementId, parentElements: row.parentElements.split(\";\") };\n }),\n );\n }\n\n public getModeledElementsInfo() {\n this.#modeledElementsInfo ??= this.queryModeledElements().pipe(\n reduce(\n (acc, { modelId, categoryId, modeledElementId, parentElements }) => {\n let modelEntry = acc.modelWithCategoryModeledElements.get(modelId);\n if (!modelEntry) {\n modelEntry = new Map();\n acc.modelWithCategoryModeledElements.set(modelId, modelEntry);\n }\n const categoryEntry = modelEntry.get(categoryId);\n if (!categoryEntry) {\n modelEntry.set(categoryId, new Set([modeledElementId]));\n } else {\n categoryEntry.add(modeledElementId);\n }\n acc.allSubModels.add(modeledElementId);\n parentElements.forEach((parentElementId) => {\n const entry = acc.childSubModels.get(parentElementId);\n if (!entry) {\n acc.childSubModels.set(parentElementId, new Set([modeledElementId]));\n } else {\n entry.add(modeledElementId);\n }\n });\n return acc;\n },\n {\n modelWithCategoryModeledElements: new Map<ModelId, Map<CategoryId, Set<ElementId>>>(),\n allSubModels: new Set<ElementId>(),\n childSubModels: new Map<ElementId, Set<ElementId>>(),\n },\n ),\n shareReplay(),\n );\n return this.#modeledElementsInfo;\n }\n\n public getSubModelsUnderElement(elementId: Id64String): Observable<Id64Array> {\n return this.getModeledElementsInfo().pipe(\n map(({ allSubModels, childSubModels }) => {\n const subModels = new Array<ElementId>();\n if (allSubModels.has(elementId)) {\n subModels.push(elementId);\n }\n const elementEntry = childSubModels.get(elementId);\n for (const childSubModelId of elementEntry ?? []) {\n subModels.push(childSubModelId);\n }\n return subModels;\n }),\n );\n }\n\n public getCategoryModeledElements({ modelId, categoryId }: { modelId: Id64String; categoryId: Id64String }): Observable<Id64String> {\n return this.getModeledElementsInfo().pipe(\n mergeMap(({ modelWithCategoryModeledElements }) => modelWithCategoryModeledElements.get(modelId)?.get(categoryId) ?? new Set<Id64String>()),\n );\n }\n}\n"]}