import { EventEmitter } from "events" ; export default class Dictionary extends EventEmitter { byId : { [ key ] : any ; } ; refCountById : { [ key ] : number ; } ; unloadDelaySeconds : number ; unloadTimeoutsById : { [ id ] : NodeJS . Timer ; } = { } ; constructor ( unloadDelaySeconds = 60 ) { super ( ) ; this . byId = { } ; this . refCountById = { } ; this . unloadDelaySeconds = unloadDelaySeconds ; } acquire ( id , owner , callback ) { if ( this . refCountById [ id ] == null ) this . refCountById [ id ] = 0 ; this . refCountById [ id ] ++ ; const timeout = this . unloadTimeoutsById [ id ] ; if ( timeout != null ) { clearTimeout ( timeout ) ; delete this . unloadTimeoutsById [ id ] ; } let item = this . byId [ id ] ; if ( item == null ) { try { item = this . _load ( id ) ; } catch ( e ) { callback ( e , null ) ; return ; } this . byId [ id ] = item ; item . on ( "load" , ( ) => { if ( this . byId [ id ] == null ) return ; this . emit ( "itemLoad" , id , item ) ; } ) ; } if ( item . pub != null ) callback ( null , item ) ; else item . on ( "load" , ( ) => { if ( this . byId [ id ] == null ) return ; callback ( null , item ) ; return ; } ) ; } release ( id , owner , options ? ) { if ( this . refCountById [ id ] == null ) { console . log ( `Can't release ${ id }, ref count is null` ) ; return ; } this . refCountById [ id ] -- ; if ( this . refCountById [ id ] === 0 ) { delete this . refCountById [ id ] ; if ( options != null && options . skipUnloadDelay ) this . _unload ( id ) ; else this . unloadTimeoutsById [ id ] = setTimeout ( ( ) => { this . _unload ( id ) ; } , this . unloadDelaySeconds * 1000 ) ; } } _load ( id ) { throw new Error ( "This method must be overridden by derived classes" ) ; } _unload ( id ) { this . byId [ id ] . unload ( ) ; delete this . byId [ id ] ; delete this . unloadTimeoutsById [ id ] ; } releaseAll ( id ) { const timeout = this . unloadTimeoutsById [ id ] ; if ( timeout != null ) { clearTimeout ( timeout ) ; delete this . unloadTimeoutsById [ id ] ; } delete this . refCountById [ id ] ; delete this . byId [ id ] ; } }