import { StorageStrategy } from '../core/interfaces/storageStrategy' ; import { Subject } from 'rxjs' ; import { Inject , Injectable , Optional } from '@angular/core' ; import { STORAGE_STRATEGIES } from '../strategies' ; import { StorageStrategies } from '../constants/strategy' ; export const InvalidStrategyError = 'invalid_strategy' ; @ Injectable ( { providedIn : 'root' } ) export class StrategyIndex { static index : { [ name ] : StorageStrategy < any > ; } = { } ; readonly registration$ : Subject < string > = new Subject ( ) ; constructor ( @ Optional ( ) @ Inject ( STORAGE_STRATEGIES ) protected strategies ) { if ( ! strategies ) strategies = [ ] ; this . strategies = strategies . reverse ( ) . map ( ( strategy , index , arr ) => strategy . name ) . map ( ( name , index , arr ) => arr . indexOf ( name ) === index ? index : null ) . filter ( ( index ) => index !== null ) . map ( ( index ) => strategies [ index ] ) ; } static get ( name ) { if ( ! this . isStrategyRegistered ( name ) ) throw Error ( InvalidStrategyError ) ; let strategy = this . index [ name ] ; if ( ! strategy . isAvailable ) { strategy = this . index [ StorageStrategies . InMemory ] ; } return strategy ; } static set ( name , strategy ) { this . index [ name ] = strategy ; } static clear ( name ? ) { if ( name !== undefined ) delete this . index [ name ] ; else this . index = { } ; } static isStrategyRegistered ( name ) { return name in this . index ; } static hasRegistredStrategies ( ) { return Object . keys ( this . index ) . length > 0 ; } public getStrategy ( name ) { return StrategyIndex . get ( name ) ; } public indexStrategies ( ) { this . strategies . forEach ( ( strategy ) => this . register ( strategy . name , strategy ) ) ; } public indexStrategy ( name , overrideIfExists = false ) { if ( StrategyIndex . isStrategyRegistered ( name ) && ! overrideIfExists ) return StrategyIndex . get ( name ) ; const strategy = this . strategies . find ( ( strategy ) => strategy . name === name ) ; if ( ! strategy ) throw new Error ( InvalidStrategyError ) ; this . register ( name , strategy , overrideIfExists ) ; return strategy ; } public register ( name , strategy , overrideIfExists = false ) { if ( ! StrategyIndex . isStrategyRegistered ( name ) || overrideIfExists ) { StrategyIndex . set ( name , strategy ) ; this . registration$ . next ( name ) ; } } }