UNPKG

first-npm-package-nicule

Version:

This isi first npm package

85 lines (71 loc) 3.06 kB
import {filter, take, debounceTime, switchMap} from 'rxjs/operators'; import { Subject , Observable } from 'rxjs'; import { Type } from '@angular/core'; import { Store } from '@ngrx/store'; import { Hypermedia } from '../interfaces'; import { ReflectiveModelBinderFactory, ReflectiveQueryMatcherFactory } from 'first-npm-package-nicule/models'; import { HypermediaState } from '../reducers'; import { FetchHypermedia } from '../actions'; export class ResourceSelector { private refresh$: Subject<undefined> = new Subject(); private downloadProgress$: Observable<number>; private uploadProgress$: Observable<number>; private hypermedia$: Observable<Hypermedia>; private interceptors = {}; constructor(private path: string, private scope: string, private authorize: boolean, private tokenOverride: string, private store: Store<{ hypermedia: HypermediaState }>, private modelBinderFactory: ReflectiveModelBinderFactory, private queryMatcherFactory: ReflectiveQueryMatcherFactory ) { this.hypermedia$ = store.select('hypermedia', 'hypermedia', scope, path, 'data').pipe( filter(data => data !== undefined)); this.uploadProgress$ = store.select('hypermedia', 'hypermedia', scope, path, 'upload'); this.downloadProgress$ = store.select('hypermedia', 'hypermedia', scope, path, 'download'); } downloadProgress(): Observable<number> { return this.downloadProgress$; } uploadProgress(): Observable<number> { return this.uploadProgress$; } refresh(success: (response?: Hypermedia) => void = () => { }): void { const subscription = this.hypermedia$ .pipe(take(1)) .subscribe(response => success(response)); this.fetch(); } fetch(): void { this.store.dispatch(new FetchHypermedia({ path: this.path, scope: this.scope, authorize: this.authorize, tokenOverride: this.tokenOverride, interceptors: this.interceptors })); } intercept(statusCode: string | number, interceptor: (hypermedia: Hypermedia) => void): void { this.interceptors[statusCode] = interceptor; } as<T>(type: Type<T>, noFetch = false): Observable<T> { const modelBinder = this.modelBinderFactory.make(type); const queryMatcher = this.queryMatcherFactory.make(type); return this.hypermedia$ .onSubscribe(() => { if (!noFetch) { this.fetch(); } }) .pipe( debounceTime(100), switchMap(hypermedia => { if (queryMatcher.matches(hypermedia)) { return [modelBinder.bind(hypermedia)]; } return [undefined]; }) ) } }