dev@74: import {Injectable, Inject} from '@angular/core'; dev@47: import { dev@226: ListResponse dev@236: } from 'piper'; dev@64: import { dev@226: SimpleRequest, dev@226: SimpleResponse dev@236: } from 'piper/HigherLevelUtilities'; dev@236: import {Subject} from 'rxjs/Subject'; dev@236: import {Observable} from 'rxjs/Observable'; dev@236: import {Http, Response} from '@angular/http'; dev@226: import { dev@226: countingIdProvider, dev@226: WebWorkerStreamingClient dev@236: } from 'piper/client-stubs/WebWorkerStreamingClient'; dev@236: import {RequestId} from 'piper/protocols/WebWorkerProtocol'; dev@40: dev@74: type RepoUri = string; dev@74: export interface AvailableLibraries { dev@74: [libraryKey: string]: RepoUri; dev@74: } dev@74: dev@226: export interface Progress { dev@226: id: RequestId; dev@226: value: number; // between 0 and 100, for material-ui dev@226: } dev@226: dev@40: @Injectable() dev@40: export class FeatureExtractionService { dev@40: dev@40: private worker: Worker; dev@64: private featuresExtracted: Subject; dev@64: featuresExtracted$: Observable; dev@74: private librariesUpdated: Subject; dev@74: librariesUpdated$: Observable; dev@226: private progressUpdated: Subject; dev@226: progressUpdated$: Observable; dev@226: private client: WebWorkerStreamingClient; dev@44: dev@236: constructor(private http: Http, dev@236: @Inject('PiperRepoUri') private repositoryUri: RepoUri) { dev@40: this.worker = new Worker('bootstrap-feature-extraction-worker.js'); dev@64: this.featuresExtracted = new Subject(); dev@51: this.featuresExtracted$ = this.featuresExtracted.asObservable(); dev@74: this.librariesUpdated = new Subject(); dev@74: this.librariesUpdated$ = this.librariesUpdated.asObservable(); dev@226: this.progressUpdated = new Subject(); dev@226: this.progressUpdated$ = this.progressUpdated.asObservable(); dev@74: this.worker.addEventListener('message', (ev: MessageEvent) => { dev@74: const isValidResponse = ev.data.method === 'import' dev@226: && ev.data.result && ev.data.result.available ; dev@74: if (isValidResponse) { dev@226: (ev as Event).stopImmediatePropagation(); dev@74: this.librariesUpdated.next(ev.data.result); dev@74: } dev@226: }, true); dev@226: dev@226: this.client = new WebWorkerStreamingClient( dev@226: this.worker, dev@226: countingIdProvider(0) dev@236: ); dev@40: } dev@40: dev@47: list(): Promise { dev@226: return this.client.list({}); dev@40: } dev@40: dev@226: extract(analysisItemId: string, request: SimpleRequest): Promise { dev@226: return this.client.collect(request) dev@226: .do(val => { dev@247: if (val.totalBlockCount > 0) { dev@247: this.progressUpdated.next({ dev@247: id: analysisItemId, dev@247: value: (val.processedBlockCount / val.totalBlockCount) * 100 dev@247: }); dev@247: } dev@226: }) dev@226: .toPromise() dev@226: .then((response) => { dev@226: this.featuresExtracted.next(response); dev@226: }); dev@62: } dev@62: dev@74: updateAvailableLibraries(): Observable { dev@74: return this.http.get(this.repositoryUri) dev@74: .map(res => { dev@74: const map = res.json(); dev@74: this.worker.postMessage({ dev@74: method: 'addRemoteLibraries', dev@74: params: map dev@74: }); dev@74: return map; dev@74: }) dev@74: .catch((error: Response | any) => { dev@74: console.error(error); dev@74: return Observable.throw(error); dev@74: }); dev@74: } dev@74: dev@74: load(libraryKey: string): void { dev@74: this.worker.postMessage({method: 'import', params: libraryKey}); dev@74: } dev@40: }