@itwin/presentation-components
Version:
React components based on iTwin.js Presentation library
67 lines • 2.69 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Tree
*/
import { share, Subject, tap } from "rxjs";
import { PagedTreeNodeLoader } from "@itwin/components-react";
import { toRxjsObservable } from "./Utils.js";
/**
* Wrapper for `PagedTreeNodeLoader` that reports load times of nodes.
* @internal
*/
export class ReportingTreeNodeLoader extends PagedTreeNodeLoader {
_nodeLoader;
_onNodeLoaded;
_trackedRequests;
constructor(nodeLoader, onNodeLoaded) {
super(nodeLoader.dataProvider, nodeLoader.modelSource, nodeLoader.pageSize);
this._nodeLoader = nodeLoader;
this._onNodeLoaded = onNodeLoaded;
this._trackedRequests = new Map();
}
loadNode(parent, childIndex) {
const observable = this._nodeLoader.loadNode(parent, childIndex);
const parentId = parent.id ?? "root";
if (childIndex !== 0) {
return observable;
}
let tracked = this._trackedRequests.get(parentId);
if (!tracked) {
let time;
tracked = toRxjsObservable(observable).pipe(tap({
subscribe: () => {
time = performance.now();
},
unsubscribe: () => {
this._trackedRequests.delete(parentId);
},
error: () => {
this._trackedRequests.delete(parentId);
},
next: () => {
this._onNodeLoaded({ node: parentId, duration: performance.now() - time });
},
complete: () => {
this._trackedRequests.delete(parentId);
},
}), share({ resetOnRefCountZero: true }));
this._trackedRequests.set(parentId, tracked);
}
if (parent.id !== undefined) {
return tracked;
}
// workaround ControlledTree unsubscribing from the observable after nodes are loaded into a tree model
// but not emitted from observable yet.
const subject = new Subject();
const source = tracked; // reference docs generation fails if `tracked` is used directly.
return subject.pipe(tap({
subscribe: () => {
source.subscribe(subject);
},
}));
}
}
//# sourceMappingURL=ReportingTreeNodeLoader.js.map