@itwin/presentation-hierarchies-react
Version:
React components based on `@itwin/presentation-hierarchies`
94 lines • 4.29 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { catchError, expand, from, map, mergeMap, of, toArray } from "rxjs";
import { isTreeModelHierarchyNode } from "./TreeModel.js";
import { createNodeId } from "./Utils.js";
/** @internal */
export class TreeLoader {
_hierarchyProvider;
_onHierarchyLimitExceeded;
_onHierarchyLoadError;
_treeNodeIdFactory;
constructor(_hierarchyProvider, _onHierarchyLimitExceeded, _onHierarchyLoadError, treeNodeIdFactory) {
this._hierarchyProvider = _hierarchyProvider;
this._onHierarchyLimitExceeded = _onHierarchyLimitExceeded;
this._onHierarchyLoadError = _onHierarchyLoadError;
this._treeNodeIdFactory = treeNodeIdFactory ?? /* c8 ignore next */ createNodeId;
}
loadChildren({ parent, getHierarchyLevelOptions, buildNode, ignoreCache }) {
const { instanceFilter, hierarchyLevelSizeLimit } = getHierarchyLevelOptions(parent);
const infoNodeIdBase = `${parent.id ?? "<root>"}`;
const treeModelNodesFactory = createTreeModelNodesFactory({ buildNode, treeNodeIdFactory: this._treeNodeIdFactory });
return from(this._hierarchyProvider.getNodes({
parentNode: parent.nodeData,
hierarchyLevelSizeLimit,
instanceFilter,
ignoreCache,
})).pipe(toArray(), catchError((err) => {
const nodeProps = {
id: `${infoNodeIdBase}-Unknown`,
parentId: parent.id,
};
let hierarchyLoadErrorType = "unknown";
if (err instanceof Error) {
nodeProps.id = `${infoNodeIdBase}-${err.message}`;
if (isRowsLimitError(err)) {
this._onHierarchyLimitExceeded({ parentId: parent.id, filter: instanceFilter, limit: err.limit });
return of([{ ...nodeProps, type: "ResultSetTooLarge", resultSetSizeLimit: err.limit }]);
}
if (isTimeoutError(err)) {
hierarchyLoadErrorType = "timeout";
}
}
this._onHierarchyLoadError({ parentId: parent.id, type: hierarchyLoadErrorType, error: err });
return of([
{
...nodeProps,
type: "Unknown",
message: "Failed to create hierarchy level",
},
]);
}), map((childNodes) => ({
parentId: parent.id,
loadedNodes: instanceFilter && childNodes.length === 0
? [
{
id: `${infoNodeIdBase}-no-filter-matches`,
parentId: parent.id,
type: "NoFilterMatches",
},
]
: childNodes.map(treeModelNodesFactory),
})));
}
loadNodes({ shouldLoadChildren, ...options }) {
return this.loadChildren(options).pipe(expand((loadedPart) => from(loadedPart.loadedNodes.filter((node) => isTreeModelHierarchyNode(node) && shouldLoadChildren(node))).pipe(mergeMap((node) => this.loadChildren({ ...options, parent: node })))));
}
}
function createTreeModelNodesFactory({ buildNode, treeNodeIdFactory, }) {
return (node) => {
if (!isHierarchyNode(node)) {
return node;
}
const modelNode = {
id: treeNodeIdFactory(node),
children: node.children,
label: node.label,
nodeData: node,
};
return buildNode ? buildNode(modelNode) : modelNode;
};
}
function isHierarchyNode(node) {
return "key" in node && node.key !== undefined;
}
function isRowsLimitError(error) {
const asRowsError = error;
return asRowsError.limit !== undefined && asRowsError.message.includes("Query rows limit of");
}
function isTimeoutError(error) {
return error.message.includes("query too long to execute or server is too busy");
}
//# sourceMappingURL=TreeLoader.js.map