import { ElementRef , Injectable } from '@angular/core' ; import { Observable } from 'rxjs/Observable' ; import { ConfigService , ConfigServiceFactory } from './config.service' ; import { GatewayService , GatewayServiceFactory , RequestOptions } from './gateway.service' ; import { RefreshService } from './refresh.service' ; import { RunService } from './run.service' ; import { StorageService } from './storage.service' ; import { SubscriptionService } from './subscription.service' ; import { WaiterService , WaiterServiceFactory } from './waiter.service' ; /**
 * Service aggregator
 */ @ Injectable ( ) export class DvServiceFactory { constructor ( private readonly gsf , private readonly wsf , private readonly csf , private readonly run , private readonly storage , private readonly sub , private readonly refresh ) { } forComponent ( component ) { return new DvServiceBuilder ( component , this . gsf , this . wsf , this . csf , this . run , this . storage , this . sub , this . refresh ) ; } } export class DvServiceBuilder { private defaultWaiter = false ; private refreshCallback : ( ( ) => void ) | undefined ; constructor ( private readonly component , private readonly gsf , private readonly wsf , private readonly csf , private readonly run , private readonly storage , private readonly sub , private readonly refresh ) { } withDefaultWaiter ( ) { this . defaultWaiter = true ; return this ; } withRefreshCallback ( refreshFn ) { this . refreshCallback = refreshFn ; return this ; } build ( ) { const elem = this . component . elem ; if ( elem === undefined ) { throw new Error ( 'Missing elem: add `elem: ElementRef` to your constructor' ) ; } const gateway = this . gsf . for ( elem ) ; const waiter = this . defaultWaiter ? this . wsf . for ( this . component , this . component . waitOn ) : undefined ; const config = this . csf . createConfigService ( elem ) ; this . run . register ( elem , this . component ) ; const destroyFn = this . refreshCallback ? this . refresh . register ( this . refreshCallback ) : undefined ; return new DvService ( gateway , waiter , config , this . sub , elem , this . run , this . storage , destroyFn ) ; } } export class DvService { constructor ( public readonly gateway , public readonly waiter , public readonly config , public readonly sub , private readonly elem , private readonly run , private readonly storage , private readonly destroyFn ) { } onDestroy ( ) { if ( this . destroyFn ) { this . destroyFn ( ) ; } } exec ( ) { this . run . exec ( this . elem ) ; } eval ( ) { this . run . eval ( this . elem ) ; } setItem ( key , value ) { this . storage . setItem ( this . elem , key , value ) ; } getItem ( key ) { return this . storage . getItem ( this . elem , key ) ; } removeItem ( key ) { this . storage . removeItem ( this . elem , key ) ; } removeItems ( ... keys ) { for ( const key of keys ) { this . storage . removeItem ( this . elem , key ) ; } } async waitAndGet < T > ( path ? , optionsFn ? ) { if ( this . waiter === undefined ) { throw new Error ( `You called waitAndGet but there's no waiter.` + `You must add withDefaultWaiter to the dv service` ) ; } await this . waiter . maybeWait ( ) ; const options = optionsFn ? optionsFn ( ) : undefined ; return await this . gateway . get < T > ( path , options ) . toPromise ( ) ; } async waitAndPost < T > ( path ? , bodyFn ? , optionsFn ? ) { if ( this . waiter === undefined ) { throw new Error ( `You called waitAndPost but there's no waiter.` + `You must add withDefaultWaiter to the dv service` ) ; } await this . waiter . maybeWait ( ) ; const body = bodyFn ? bodyFn ( ) : undefined ; const options = optionsFn ? optionsFn ( ) : undefined ; return await this . gateway . post < T > ( path , body , options ) . toPromise ( ) ; } async get < T > ( path ? , options ? ) { return await this . gateway . get < T > ( path , options ) . toPromise ( ) ; } async post < T > ( path ? , body ? , options ? ) { return await this . gateway . post < T > ( path , body , options ) . toPromise ( ) ; } noRequest ( ) { this . gateway . noRequest ( ) ; } subscribe < T > ( path ? , request = { } ) { return this . gateway . subscribe ( path , request ) ; } }