github.com/argoproj/argo-cd/v2@v2.10.9/ui/src/app/shared/services/requests.ts (about) 1 import * as path from 'path'; 2 import * as agent from 'superagent'; 3 4 import {BehaviorSubject, Observable, Observer} from 'rxjs'; 5 import {filter} from 'rxjs/operators'; 6 7 type Callback = (data: any) => void; 8 9 declare class EventSource { 10 public onopen: Callback; 11 public onmessage: Callback; 12 public onerror: Callback; 13 public readyState: number; 14 constructor(url: string); 15 public close(): void; 16 } 17 18 enum ReadyState { 19 CONNECTING = 0, 20 OPEN = 1, 21 CLOSED = 2, 22 DONE = 4 23 } 24 25 let baseHRef = '/'; 26 27 const onError = new BehaviorSubject<agent.ResponseError>(null); 28 29 function toAbsURL(val: string): string { 30 return path.join(baseHRef, val); 31 } 32 33 function apiRoot(): string { 34 return toAbsURL('/api/v1'); 35 } 36 37 function initHandlers(req: agent.Request) { 38 req.on('error', err => onError.next(err)); 39 return req; 40 } 41 42 export default { 43 setBaseHRef(val: string) { 44 baseHRef = val; 45 }, 46 agent, 47 toAbsURL, 48 onError: onError.asObservable().pipe(filter(err => err != null)), 49 get(url: string) { 50 return initHandlers(agent.get(`${apiRoot()}${url}`)); 51 }, 52 53 post(url: string) { 54 return initHandlers(agent.post(`${apiRoot()}${url}`)).set('Content-Type', 'application/json'); 55 }, 56 57 put(url: string) { 58 return initHandlers(agent.put(`${apiRoot()}${url}`)).set('Content-Type', 'application/json'); 59 }, 60 61 patch(url: string) { 62 return initHandlers(agent.patch(`${apiRoot()}${url}`)).set('Content-Type', 'application/json'); 63 }, 64 65 delete(url: string) { 66 return initHandlers(agent.del(`${apiRoot()}${url}`)).set('Content-Type', 'application/json'); 67 }, 68 69 loadEventSource(url: string): Observable<string> { 70 return Observable.create((observer: Observer<any>) => { 71 let eventSource = new EventSource(`${apiRoot()}${url}`); 72 eventSource.onmessage = msg => observer.next(msg.data); 73 eventSource.onerror = e => () => { 74 observer.error(e); 75 onError.next(e); 76 }; 77 78 // EventSource does not provide easy way to get notification when connection closed. 79 // check readyState periodically instead. 80 const interval = setInterval(() => { 81 if (eventSource && eventSource.readyState === ReadyState.CLOSED) { 82 observer.error('connection got closed unexpectedly'); 83 } 84 }, 500); 85 return () => { 86 clearInterval(interval); 87 eventSource.close(); 88 eventSource = null; 89 }; 90 }); 91 } 92 };