packageDocumentation module import { Patch , produce } from "immer" ; import { BeUiEvent } from "@itwin/core-bentley" ; import { MutableTreeModel , TreeModel } from "./TreeModel" ; public export interface TreeModelChanges { addedNodeIds : string [ ] ; modifiedNodeIds : string [ ] ; removedNodeIds : string [ ] ; } public export class TreeModelSource { /** Event that is emitted every time tree model is changed. */ public onModelChanged = new BeUiEvent < [ TreeModel , TreeModelChanges ] > ( ) ; constructor ( private _model = new MutableTreeModel ( ) ) { } /**
     * Modifies tree model using provided callback.
     * If changes to tree model is detected then onModelChanged event is emitted.
     */ public modifyModel ( callback ) { let changes = { addedNodeIds : [ ] , modifiedNodeIds : [ ] , removedNodeIds : [ ] } ; const newModel = produce ( this . _model , ( draft ) => callback ( draft ) , ( patches ) => { changes = this . collectModelChanges ( patches ) ; } ) ; if ( newModel !== this . _model ) { this . _model = newModel ; this . onModelChanged . emit ( [ this . _model , changes ] ) ; } } /** Returns tree model. */ public getModel ( ) { return this . _model ; } private collectModelChanges ( modelPatches ) { const addedNodeIds = [ ] ; const modifiedNodeIds = new Set < string > ( ) ; const removedNodeIds = [ ] ; for ( const patch of modelPatches ) { if ( patch . path . length >= 3 && patch . path [ 0 ] === "_tree" && patch . path [ 1 ] === "_idToNode" ) { const nodeId = patch . path [ 2 ] as string ; if ( patch . path . length > 3 ) { modifiedNodeIds . add ( nodeId ) ; continue ; } switch ( patch . op ) { case "add" : addedNodeIds . push ( nodeId ) ; break ; case "remove" : removedNodeIds . push ( nodeId ) ; break ; case "replace" : modifiedNodeIds . add ( nodeId ) ; break ; } } } return { addedNodeIds , modifiedNodeIds : [ ... modifiedNodeIds ] , removedNodeIds } ; } }