first-npm-package-nicule
Version:
This isi first npm package
85 lines (71 loc) • 3.06 kB
text/typescript
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];
})
)
}
}