@@ -305,12 +305,31 @@ export type NodeMapper<T, TFilterData> = (node: ITreeNode<ICompressedTreeNode<T>
305305
306306export const DefaultElementMapper : ElementMapper < any > = elements => elements [ elements . length - 1 ] ;
307307
308- function mapNode < T , TFilterData > ( compressedNodeMapper : CompressedNodeMapper < T > , node : ITreeNode < ICompressedTreeNode < T > | null , TFilterData > ) : ITreeNode < T | null , TFilterData > {
309- return {
310- ...node ,
311- element : node . element === null ? null : compressedNodeMapper ( node . element ) ,
312- children : node . children . map ( child => mapNode ( compressedNodeMapper , child ) )
308+ function createNodeMapper < T , TFilterData > ( compressedNodeMapper : CompressedNodeMapper < T > ) : NodeMapper < T , TFilterData > {
309+ const map = new WeakMap < ITreeNode < ICompressedTreeNode < T > | null , TFilterData > , ITreeNode < T | null , TFilterData > > ( ) ;
310+ const nodeMapper : NodeMapper < T , TFilterData > = node => {
311+ let result = map . get ( node ) ;
312+
313+ if ( ! result ) {
314+ result = new Proxy ( node , {
315+ get ( obj , prop ) {
316+ if ( prop === 'element' ) {
317+ return node . element === null ? null : compressedNodeMapper ( node . element ) ;
318+ } else if ( prop === 'children' ) {
319+ return node . children . map ( nodeMapper ) ;
320+ }
321+
322+ return ( obj as any ) [ prop ] ;
323+ }
324+ } ) as ITreeNode < T | null , TFilterData > ;
325+
326+ map . set ( node , result ) ;
327+ }
328+
329+ return result ;
313330 } ;
331+
332+ return nodeMapper ;
314333}
315334
316335function mapList < T , TFilterData > ( nodeMapper : NodeMapper < T , TFilterData > , list : ISpliceable < ITreeNode < T , TFilterData > > ) : ISpliceable < ITreeNode < ICompressedTreeNode < T > , TFilterData > > {
@@ -379,7 +398,7 @@ export class CompressibleObjectTreeModel<T extends NonNullable<any>, TFilterData
379398 ) {
380399 this . elementMapper = options . elementMapper || DefaultElementMapper ;
381400 const compressedNodeMapper : CompressedNodeMapper < T > = node => this . elementMapper ( node . elements ) ;
382- this . nodeMapper = node => mapNode ( compressedNodeMapper , node ) ;
401+ this . nodeMapper = createNodeMapper ( compressedNodeMapper ) ;
383402
384403 this . model = new CompressedObjectTreeModel ( user , mapList ( this . nodeMapper , list ) , mapOptions ( compressedNodeMapper , options ) ) ;
385404 }
0 commit comments