import type { AnyEntity , Constructor , EntityMetadata } from '../typings' ; export class IdentityMap { private readonly registry = new Map < Constructor < AnyEntity > , Map < string , AnyEntity > > ( ) ; store < T extends AnyEntity < T > > ( item ) { this . getStore ( item . __meta ! . root ) . set ( this . getPkHash ( item ) , item ) ; } delete < T extends AnyEntity < T > > ( item ) { this . getStore ( item . __meta ! . root ) . delete ( this . getPkHash ( item ) ) ; } getByHash < T > ( meta , hash ) { const store = this . getStore ( meta ) ; return store . has ( hash ) ? store . get ( hash ) : undefined ; } getStore < T extends AnyEntity < T > > ( meta ) { const store = this . registry . get ( meta . class ) as Map < string , T > ; if ( store ) { return store ; } const newStore = new Map ( ) ; this . registry . set ( meta . class , newStore ) ; return newStore ; } clear ( ) { this . registry . clear ( ) ; } values ( ) { const ret = [ ] ; for ( const store of this . registry . values ( ) ) { ret . push ( ... store . values ( ) ) ; } return ret ; } * [ Symbol . iterator ] ( ) { for ( const store of this . registry . values ( ) ) { for ( const item of store . values ( ) ) { yield item ; } } } keys ( ) { const ret = [ ] ; for ( const [ cls , store ] of this . registry ) { ret . push ( ... [ ... store . keys ( ) ] . map ( hash => `${ cls . name }-${ hash }` ) ) ; } return ret ; } /**
     * For back compatibility only.
     */ get < T > ( hash ) { const [ name , id ] = hash . split ( '-' , 2 ) ; const cls = [ ... this . registry . keys ( ) ] . find ( k => k . name === name ) ; if ( ! cls ) { return undefined ; } const store = this . registry . get ( cls ) as Map < string , T > ; return store . has ( id ) ? store . get ( id ) : undefined ; } private getPkHash < T extends AnyEntity < T > > ( item ) { const pkHash = item . __helper ! . getSerializedPrimaryKey ( ) ; const schema = item . __helper ! . __schema || item . __meta ! . root . schema ; if ( schema ) { return schema + ':' + pkHash ; } return pkHash ; } }