| 
									
										
										
										
											2023-04-04 20:22:57 +02:00
										 |  |  | export interface IResolve<T> { | 
					
						
							|  |  |  |   (value?: T | PromiseLike<T>): void; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export interface IReject { | 
					
						
							|  |  |  |   (reason?: any): void; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export type TDeferredStatus = 'pending' | 'fulfilled' | 'rejected'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class Deferred<T> { | 
					
						
							|  |  |  |   public promise: Promise<T>; | 
					
						
							|  |  |  |   public resolve: IResolve<T>; | 
					
						
							|  |  |  |   public reject: IReject; | 
					
						
							|  |  |  |   public status: TDeferredStatus; | 
					
						
							| 
									
										
										
										
											2023-04-17 21:00:25 +02:00
										 |  |  |   public claimed = false; | 
					
						
							| 
									
										
										
										
											2023-04-17 21:01:18 +02:00
										 |  |  |   public claim() { | 
					
						
							|  |  |  |     if (this.claimed) { | 
					
						
							|  |  |  |       throw new Error('Deferred already claimed'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     this.claimed = true; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-04-04 20:22:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   public startedAt: number; | 
					
						
							|  |  |  |   public stoppedAt: number; | 
					
						
							|  |  |  |   public get duration(): number { | 
					
						
							|  |  |  |     if (this.stoppedAt) { | 
					
						
							|  |  |  |       return this.stoppedAt - this.startedAt; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return Date.now() - this.startedAt; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor() { | 
					
						
							|  |  |  |     this.promise = new Promise<T>((resolve, reject) => { | 
					
						
							|  |  |  |       this.resolve = (valueArg: T | PromiseLike<T>) => { | 
					
						
							|  |  |  |         this.status = 'fulfilled'; | 
					
						
							|  |  |  |         this.stoppedAt = Date.now(); | 
					
						
							|  |  |  |         resolve(valueArg); | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       this.reject = (reason: any) => { | 
					
						
							|  |  |  |         this.status = 'rejected'; | 
					
						
							|  |  |  |         this.stoppedAt = Date.now(); | 
					
						
							|  |  |  |         reject(reason); | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |       this.startedAt = Date.now(); | 
					
						
							|  |  |  |       this.status = 'pending'; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const defer = <T>() => { | 
					
						
							|  |  |  |   return new Deferred<T>(); | 
					
						
							|  |  |  | }; |