import { Definition , NodeId } from './Identifiers' ; import { ChangeNode , Payload , TraitMap , TreeNode } from './generic' ; import { Snapshot } from './Snapshot' ; import { memoizeGetter } from './Common' ; import { getChangeNodeFromSnapshot } from './SnapshotUtilities' ; public export class TreeNodeHandle implements TreeNode < TreeNodeHandle > { private readonly snapshot : Snapshot ; private readonly nodeId : NodeId ; /** Construct a handle which references the node with the given id in the given `Snapshot` */ public constructor ( snapshot , nodeId ) { this . snapshot = snapshot ; this . nodeId = nodeId ; } public get payload ( ) : Payload | undefined { return this . node . payload ; } public get definition ( ) : Definition { return this . node . definition ; } public get identifier ( ) : NodeId { return this . node . identifier ; } public get traits ( ) : TraitMap < TreeNodeHandle > { const traitMap = { } ; const { snapshot } = this ; for ( const [ label , trait ] of Object . entries ( this . node . traits ) ) { Object . defineProperty ( traitMap , label , { get ( ) { const handleTrait = trait . map ( ( node ) => new TreeNodeHandle ( snapshot , node . identifier ) ) ; return memoizeGetter ( this as TraitMap < TreeNodeHandle > , label , handleTrait ) ; } , configurable : true , enumerable : true } ) ; } return memoizeGetter ( this , 'traits' , traitMap ) ; } /**
     * Get a `ChangeNode` for the snapshot node that this handle references
     */ public get node ( ) : ChangeNode { return memoizeGetter ( this , 'node' , getChangeNodeFromSnapshot ( this . snapshot , this . nodeId , true ) ) ; } /**
     * Generate a new `ChangeNode` for the snapshot node that this handle references. The returned node will be fully
     * demanded, i.e. will contain no lazy/virtualized subtrees.
     */ public demandTree ( ) { return getChangeNodeFromSnapshot ( this . snapshot , this . nodeId , false ) ; } public toString ( ) { return JSON . stringify ( this . demandTree ( ) ) ; } }