import { hashValuesToArray , collectFromHash } from './object' ; export class RefMap < RefType > { public currentMap : { [ key ] : RefType ; } = { } ; private depths : { [ key ] : number ; } = { } ; private callbackMap : { [ key ] : ( val : RefType | null ) => void ; } = { } ; constructor ( public masterCallback ? ) { } createRef ( key ) { let refCallback = this . callbackMap [ key ] ; if ( ! refCallback ) { refCallback = this . callbackMap [ key ] = ( val ) => { this . handleValue ( val , String ( key ) ) ; } ; } return refCallback ; } handleValue = ( val , key ) => { let { depths , currentMap } = this ; let removed = false ; let added = false ; if ( val !== null ) { removed = ( key in currentMap ) ; currentMap [ key ] = val ; depths [ key ] = ( depths [ key ] || 0 ) + 1 ; added = true ; } else { depths [ key ] -= 1 ; if ( ! depths [ key ] ) { delete currentMap [ key ] ; delete this . callbackMap [ key ] ; removed = true ; } } if ( this . masterCallback ) { if ( removed ) { this . masterCallback ( null , String ( key ) ) ; } if ( added ) { this . masterCallback ( val , String ( key ) ) ; } } } ; collect ( startIndex ? , endIndex ? , step ? ) { return collectFromHash ( this . currentMap , startIndex , endIndex , step ) ; } getAll ( ) { return hashValuesToArray ( this . currentMap ) ; } }