import { Observable , Subject } from 'rxjs' ; import { FilterRequest , IFilterUpdateEvent , IFlags as IFilterFlags , IDesc as IFilterDesc , IDescOptional as IFilterDescOptional , IDescUpdating as IFilterDescUpdating , } from './controller.session.tab.search.filters.request' ; import { IStore , EStoreKeys , IStoreData , } from '../../dependencies/store/controller.session.tab.search.store.support' ; import * as Toolkit from 'chipmunk.client.toolkit' ; export interface IUpdateEvent { requests : FilterRequest [ ] ; updated ? : FilterRequest ; added ? : FilterRequest | FilterRequest [ ] ; removed ? : FilterRequest ; } export interface IReorderParams { prev : number ; curt : number ; } export { FilterRequest , IUpdateEvent as IFiltersStorageUpdated , IFilterUpdateEvent , IFilterFlags , IFilterDesc , IFilterDescOptional , IFilterDescUpdating , } ; export class FiltersStorage implements IStore < IFilterDesc [ ] > { private _logger : Toolkit . Logger ; private _guid : string ; private _stored : FilterRequest [ ] = [ ] ; private _subjects : { updated : Subject < IUpdateEvent > ; changed : Subject < IFilterUpdateEvent > ; } = { updated : new Subject < IUpdateEvent > ( ) , changed : new Subject < IFilterUpdateEvent > ( ) , } ; constructor ( session ) { this . _guid = session ; this . _logger = new Toolkit . Logger ( `FiltersStorage: ${ session }` ) ; } public destroy ( ) { return new Promise ( ( resolve ) => { this . _clear ( ) ; resolve ( ) ; } ) ; } public getObservable ( ) { return { updated : this . _subjects . updated . asObservable ( ) , changed : this . _subjects . changed . asObservable ( ) , } ; } public has ( request ) { return ( this . _stored . find ( ( stored ) => { return request . getHash ( ) === stored . getHash ( ) ; } ) !== undefined ) ; } public add ( descs , from ? ) { if ( ! ( descs instanceof Array ) ) { descs = [ descs ] ; } const prevCount = this . _stored . length ; const added = [ ] ; try { descs . forEach ( ( desc ) => { const srchRqst = desc instanceof FilterRequest ? new FilterRequest ( desc . asDesc ( ) ) : new FilterRequest ( desc ) ; if ( this . has ( srchRqst ) ) { this . _logger . warn ( `Request "${ srchRqst . asDesc ( ) . request }" already exist` ) ; return ; } if ( typeof from === 'number' && from < this . _stored . length ) { this . _stored . splice ( from , 0 , srchRqst ) ; } else { this . _stored . push ( srchRqst ) ; } added . push ( srchRqst ) ; srchRqst . onUpdated ( this . _onRequestUpdated . bind ( this ) ) ; } ) ; } catch ( err ) { return new Error ( `Fail add request(s) due error: ${ err instanceof Error ? err . message : err }` ) ; } if ( this . _stored . length === prevCount ) { return undefined ; } this . _subjects . updated . next ( { requests : this . _stored , added : added . length === 1 ? added [ 0 ] : added , } ) ; return undefined ; } public remove ( request ) { const prevCount = this . _stored . length ; this . _stored = this . _stored . filter ( ( stored ) => { return request . getHash ( ) !== stored . getHash ( ) ; } ) ; request . destroy ( ) ; if ( this . _stored . length === prevCount ) { return ; } this . _subjects . updated . next ( { requests : this . _stored , removed : request } ) ; } public clear ( ) { if ( this . _stored . length === 0 ) { return ; } this . _clear ( ) ; this . _subjects . updated . next ( { requests : this . _stored } ) ; } public get ( ) { return this . _stored ; } public getStoredCount ( ) { return this . _stored . length ; } public getAsDesc ( ) { return this . _stored . map ( ( filter ) => { return filter . asDesc ( ) ; } ) ; } public getActive ( ) { return this . _stored . filter ( ( request ) => request . getState ( ) ) ; } public reorder ( params ) { const filter = this . _stored [ params . prev ] ; this . _stored = this . _stored . filter ( ( i , index ) => { return index !== params . prev ; } ) ; this . _stored . splice ( params . curt , 0 , filter ) ; this . _subjects . updated . next ( { requests : this . _stored , updated : undefined } ) ; } public getBySource ( source ) { return this . _stored . find ( ( filter ) => { return filter . asRegExp ( ) . source === source ; } ) ; } public store ( ) { const self = this ; return { key ( ) { return EStoreKeys . filters ; } , extract ( ) { return self . _stored . map ( ( filter ) => { return filter . asDesc ( ) ; } ) ; } , upload ( filters , append ) { if ( ! append ) { self . clear ( ) ; } return self . add ( filters . map ( ( desc ) => new FilterRequest ( desc ) ) ) ; } , getItemsCount ( ) { return self . _stored . length ; } , } ; } private _onRequestUpdated ( event ) { this . _subjects . changed . next ( event ) ; } private _clear ( ) { this . _stored . forEach ( ( request ) => { request . destroy ( ) ; } ) ; this . _stored = [ ] ; } }