| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-08-15 16:34:22 +09:00
										 |  |  | import {patchMethod} from './utils'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | Zone.__load_patch('ZoneAwarePromise', (global: any, Zone: ZoneType, api: _ZonePrivate) => { | 
					
						
							|  |  |  |   const ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; | 
					
						
							|  |  |  |   const ObjectDefineProperty = Object.defineProperty; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function readableObjectToString(obj: any) { | 
					
						
							|  |  |  |     if (obj && obj.toString === Object.prototype.toString) { | 
					
						
							|  |  |  |       const className = obj.constructor && obj.constructor.name; | 
					
						
							|  |  |  |       return (className ? className : '') + ': ' + JSON.stringify(obj); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return obj ? obj.toString() : Object.prototype.toString.call(obj); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const __symbol__ = api.symbol; | 
					
						
							|  |  |  |   const _uncaughtPromiseErrors: UncaughtPromiseError[] = []; | 
					
						
							| 
									
										
										
										
											2020-03-09 20:01:50 +09:00
										 |  |  |   const isDisableWrappingUncaughtPromiseRejection = | 
					
						
							|  |  |  |       global[__symbol__('DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION')] === true; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   const symbolPromise = __symbol__('Promise'); | 
					
						
							|  |  |  |   const symbolThen = __symbol__('then'); | 
					
						
							|  |  |  |   const creationTrace = '__creationTrace__'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   api.onUnhandledError = (e: any) => { | 
					
						
							|  |  |  |     if (api.showUncaughtError()) { | 
					
						
							|  |  |  |       const rejection = e && e.rejection; | 
					
						
							|  |  |  |       if (rejection) { | 
					
						
							|  |  |  |         console.error( | 
					
						
							|  |  |  |             'Unhandled Promise rejection:', | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |             rejection instanceof Error ? rejection.message : rejection, | 
					
						
							|  |  |  |             '; Zone:', (<Zone>e.zone).name, '; Task:', e.task && (<Task>e.task).source, | 
					
						
							|  |  |  |             '; Value:', rejection, rejection instanceof Error ? rejection.stack : undefined); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       } else { | 
					
						
							|  |  |  |         console.error(e); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   api.microtaskDrainDone = () => { | 
					
						
							|  |  |  |     while (_uncaughtPromiseErrors.length) { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |       const uncaughtPromiseError: UncaughtPromiseError = _uncaughtPromiseErrors.shift()!; | 
					
						
							| 
									
										
										
										
											2020-03-09 20:01:50 +09:00
										 |  |  |       try { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |         uncaughtPromiseError.zone.runGuarded(() => { | 
					
						
							| 
									
										
										
										
											2020-08-15 16:34:22 +09:00
										 |  |  |           if (uncaughtPromiseError.throwOriginal) { | 
					
						
							|  |  |  |             throw uncaughtPromiseError.rejection; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |           throw uncaughtPromiseError; | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2020-03-09 20:01:50 +09:00
										 |  |  |       } catch (error) { | 
					
						
							|  |  |  |         handleUnhandledRejection(error); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL = __symbol__('unhandledPromiseRejectionHandler'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-26 10:33:02 +02:00
										 |  |  |   function handleUnhandledRejection(this: unknown, e: any) { | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     api.onUnhandledError(e); | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       const handler = (Zone as any)[UNHANDLED_PROMISE_REJECTION_HANDLER_SYMBOL]; | 
					
						
							| 
									
										
										
										
											2020-03-09 20:01:50 +09:00
										 |  |  |       if (typeof handler === 'function') { | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         handler.call(this, e); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } catch (err) { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |   function isThenable(value: any): boolean { | 
					
						
							|  |  |  |     return value && value.then; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |   function forwardResolution(value: any): any { | 
					
						
							|  |  |  |     return value; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |   function forwardRejection(rejection: any): any { | 
					
						
							|  |  |  |     return ZoneAwarePromise.reject(rejection); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const symbolState: string = __symbol__('state'); | 
					
						
							|  |  |  |   const symbolValue: string = __symbol__('value'); | 
					
						
							|  |  |  |   const symbolFinally: string = __symbol__('finally'); | 
					
						
							|  |  |  |   const symbolParentPromiseValue: string = __symbol__('parentPromiseValue'); | 
					
						
							|  |  |  |   const symbolParentPromiseState: string = __symbol__('parentPromiseState'); | 
					
						
							|  |  |  |   const source: string = 'Promise.then'; | 
					
						
							|  |  |  |   const UNRESOLVED: null = null; | 
					
						
							|  |  |  |   const RESOLVED = true; | 
					
						
							|  |  |  |   const REJECTED = false; | 
					
						
							|  |  |  |   const REJECTED_NO_CATCH = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function makeResolver(promise: ZoneAwarePromise<any>, state: boolean): (value: any) => void { | 
					
						
							|  |  |  |     return (v) => { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         resolvePromise(promise, state, v); | 
					
						
							|  |  |  |       } catch (err) { | 
					
						
							|  |  |  |         resolvePromise(promise, false, err); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       // Do not return value or you will break the Promise spec.
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const once = function() { | 
					
						
							|  |  |  |     let wasCalled = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return function wrapper(wrappedFunction: Function) { | 
					
						
							|  |  |  |       return function() { | 
					
						
							|  |  |  |         if (wasCalled) { | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         wasCalled = true; | 
					
						
							|  |  |  |         wrappedFunction.apply(null, arguments); | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const TYPE_ERROR = 'Promise resolved with itself'; | 
					
						
							|  |  |  |   const CURRENT_TASK_TRACE_SYMBOL = __symbol__('currentTaskTrace'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Promise Resolution
 | 
					
						
							|  |  |  |   function resolvePromise( | 
					
						
							|  |  |  |       promise: ZoneAwarePromise<any>, state: boolean, value: any): ZoneAwarePromise<any> { | 
					
						
							|  |  |  |     const onceWrapper = once(); | 
					
						
							|  |  |  |     if (promise === value) { | 
					
						
							|  |  |  |       throw new TypeError(TYPE_ERROR); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((promise as any)[symbolState] === UNRESOLVED) { | 
					
						
							|  |  |  |       // should only get value.then once based on promise spec.
 | 
					
						
							|  |  |  |       let then: any = null; | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         if (typeof value === 'object' || typeof value === 'function') { | 
					
						
							|  |  |  |           then = value && value.then; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } catch (err) { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |         onceWrapper(() => { | 
					
						
							|  |  |  |           resolvePromise(promise, false, err); | 
					
						
							|  |  |  |         })(); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         return promise; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       // if (value instanceof ZoneAwarePromise) {
 | 
					
						
							|  |  |  |       if (state !== REJECTED && value instanceof ZoneAwarePromise && | 
					
						
							|  |  |  |           value.hasOwnProperty(symbolState) && value.hasOwnProperty(symbolValue) && | 
					
						
							|  |  |  |           (value as any)[symbolState] !== UNRESOLVED) { | 
					
						
							| 
									
										
										
										
											2019-10-09 17:17:52 +02:00
										 |  |  |         clearRejectedNoCatch(value); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         resolvePromise(promise, (value as any)[symbolState], (value as any)[symbolValue]); | 
					
						
							|  |  |  |       } else if (state !== REJECTED && typeof then === 'function') { | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |           then.call( | 
					
						
							|  |  |  |               value, onceWrapper(makeResolver(promise, state)), | 
					
						
							|  |  |  |               onceWrapper(makeResolver(promise, false))); | 
					
						
							|  |  |  |         } catch (err) { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |           onceWrapper(() => { | 
					
						
							|  |  |  |             resolvePromise(promise, false, err); | 
					
						
							|  |  |  |           })(); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         } | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         (promise as any)[symbolState] = state; | 
					
						
							|  |  |  |         const queue = (promise as any)[symbolValue]; | 
					
						
							|  |  |  |         (promise as any)[symbolValue] = value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if ((promise as any)[symbolFinally] === symbolFinally) { | 
					
						
							|  |  |  |           // the promise is generated by Promise.prototype.finally
 | 
					
						
							|  |  |  |           if (state === RESOLVED) { | 
					
						
							|  |  |  |             // the state is resolved, should ignore the value
 | 
					
						
							|  |  |  |             // and use parent promise value
 | 
					
						
							|  |  |  |             (promise as any)[symbolState] = (promise as any)[symbolParentPromiseState]; | 
					
						
							|  |  |  |             (promise as any)[symbolValue] = (promise as any)[symbolParentPromiseValue]; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // record task information in value when error occurs, so we can
 | 
					
						
							|  |  |  |         // do some additional work such as render longStackTrace
 | 
					
						
							|  |  |  |         if (state === REJECTED && value instanceof Error) { | 
					
						
							|  |  |  |           // check if longStackTraceZone is here
 | 
					
						
							|  |  |  |           const trace = Zone.currentTask && Zone.currentTask.data && | 
					
						
							|  |  |  |               (Zone.currentTask.data as any)[creationTrace]; | 
					
						
							|  |  |  |           if (trace) { | 
					
						
							|  |  |  |             // only keep the long stack trace into error when in longStackTraceZone
 | 
					
						
							|  |  |  |             ObjectDefineProperty( | 
					
						
							|  |  |  |                 value, CURRENT_TASK_TRACE_SYMBOL, | 
					
						
							|  |  |  |                 {configurable: true, enumerable: false, writable: true, value: trace}); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (let i = 0; i < queue.length;) { | 
					
						
							|  |  |  |           scheduleResolveOrReject(promise, queue[i++], queue[i++], queue[i++], queue[i++]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (queue.length == 0 && state == REJECTED) { | 
					
						
							|  |  |  |           (promise as any)[symbolState] = REJECTED_NO_CATCH; | 
					
						
							| 
									
										
										
										
											2020-03-09 20:01:50 +09:00
										 |  |  |           let uncaughtPromiseError = value; | 
					
						
							| 
									
										
										
										
											2020-08-15 16:34:22 +09:00
										 |  |  |           try { | 
					
						
							|  |  |  |             // Here we throws a new Error to print more readable error log
 | 
					
						
							|  |  |  |             // and if the value is not an error, zone.js builds an `Error`
 | 
					
						
							|  |  |  |             // Object here to attach the stack information.
 | 
					
						
							|  |  |  |             throw new Error( | 
					
						
							|  |  |  |                 'Uncaught (in promise): ' + readableObjectToString(value) + | 
					
						
							|  |  |  |                 (value && value.stack ? '\n' + value.stack : '')); | 
					
						
							|  |  |  |           } catch (err) { | 
					
						
							|  |  |  |             uncaughtPromiseError = err; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           if (isDisableWrappingUncaughtPromiseRejection) { | 
					
						
							| 
									
										
										
										
											2020-03-09 20:01:50 +09:00
										 |  |  |             // If disable wrapping uncaught promise reject
 | 
					
						
							|  |  |  |             // use the value instead of wrapping it.
 | 
					
						
							| 
									
										
										
										
											2020-08-15 16:34:22 +09:00
										 |  |  |             uncaughtPromiseError.throwOriginal = true; | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2020-03-09 20:01:50 +09:00
										 |  |  |           uncaughtPromiseError.rejection = value; | 
					
						
							|  |  |  |           uncaughtPromiseError.promise = promise; | 
					
						
							|  |  |  |           uncaughtPromiseError.zone = Zone.current; | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |           uncaughtPromiseError.task = Zone.currentTask!; | 
					
						
							| 
									
										
										
										
											2020-03-09 20:01:50 +09:00
										 |  |  |           _uncaughtPromiseErrors.push(uncaughtPromiseError); | 
					
						
							|  |  |  |           api.scheduleMicroTask();  // to make sure that it is running
 | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Resolving an already resolved promise is a noop.
 | 
					
						
							|  |  |  |     return promise; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const REJECTION_HANDLED_HANDLER = __symbol__('rejectionHandledHandler'); | 
					
						
							| 
									
										
										
										
											2019-06-26 10:33:02 +02:00
										 |  |  |   function clearRejectedNoCatch(this: unknown, promise: ZoneAwarePromise<any>): void { | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     if ((promise as any)[symbolState] === REJECTED_NO_CATCH) { | 
					
						
							|  |  |  |       // if the promise is rejected no catch status
 | 
					
						
							|  |  |  |       // and queue.length > 0, means there is a error handler
 | 
					
						
							|  |  |  |       // here to handle the rejected promise, we should trigger
 | 
					
						
							|  |  |  |       // windows.rejectionhandled eventHandler or nodejs rejectionHandled
 | 
					
						
							|  |  |  |       // eventHandler
 | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         const handler = (Zone as any)[REJECTION_HANDLED_HANDLER]; | 
					
						
							|  |  |  |         if (handler && typeof handler === 'function') { | 
					
						
							|  |  |  |           handler.call(this, {rejection: (promise as any)[symbolValue], promise: promise}); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } catch (err) { | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       (promise as any)[symbolState] = REJECTED; | 
					
						
							|  |  |  |       for (let i = 0; i < _uncaughtPromiseErrors.length; i++) { | 
					
						
							|  |  |  |         if (promise === _uncaughtPromiseErrors[i].promise) { | 
					
						
							|  |  |  |           _uncaughtPromiseErrors.splice(i, 1); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function scheduleResolveOrReject<R, U1, U2>( | 
					
						
							| 
									
										
										
										
											2019-10-06 12:06:53 +09:00
										 |  |  |       promise: ZoneAwarePromise<any>, zone: Zone, chainPromise: ZoneAwarePromise<any>, | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |       onFulfilled?: ((value: R) => U1)|null|undefined, | 
					
						
							|  |  |  |       onRejected?: ((error: any) => U2)|null|undefined): void { | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     clearRejectedNoCatch(promise); | 
					
						
							|  |  |  |     const promiseState = (promise as any)[symbolState]; | 
					
						
							|  |  |  |     const delegate = promiseState ? | 
					
						
							|  |  |  |         (typeof onFulfilled === 'function') ? onFulfilled : forwardResolution : | 
					
						
							|  |  |  |         (typeof onRejected === 'function') ? onRejected : forwardRejection; | 
					
						
							|  |  |  |     zone.scheduleMicroTask(source, () => { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         const parentPromiseValue = (promise as any)[symbolValue]; | 
					
						
							|  |  |  |         const isFinallyPromise = | 
					
						
							|  |  |  |             !!chainPromise && symbolFinally === (chainPromise as any)[symbolFinally]; | 
					
						
							|  |  |  |         if (isFinallyPromise) { | 
					
						
							|  |  |  |           // if the promise is generated from finally call, keep parent promise's state and value
 | 
					
						
							|  |  |  |           (chainPromise as any)[symbolParentPromiseValue] = parentPromiseValue; | 
					
						
							|  |  |  |           (chainPromise as any)[symbolParentPromiseState] = promiseState; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // should not pass value to finally callback
 | 
					
						
							|  |  |  |         const value = zone.run( | 
					
						
							|  |  |  |             delegate, undefined, | 
					
						
							|  |  |  |             isFinallyPromise && delegate !== forwardRejection && delegate !== forwardResolution ? | 
					
						
							|  |  |  |                 [] : | 
					
						
							|  |  |  |                 [parentPromiseValue]); | 
					
						
							|  |  |  |         resolvePromise(chainPromise, true, value); | 
					
						
							|  |  |  |       } catch (error) { | 
					
						
							|  |  |  |         // if error occurs, should always return this error
 | 
					
						
							|  |  |  |         resolvePromise(chainPromise, false, error); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, chainPromise as TaskData); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const ZONE_AWARE_PROMISE_TO_STRING = 'function ZoneAwarePromise() { [native code] }'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-01 12:27:33 +09:00
										 |  |  |   const noop = function() {}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   class ZoneAwarePromise<R> implements Promise<R> { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |     static toString() { | 
					
						
							|  |  |  |       return ZONE_AWARE_PROMISE_TO_STRING; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     static resolve<R>(value: R): Promise<R> { | 
					
						
							|  |  |  |       return resolvePromise(<ZoneAwarePromise<R>>new this(null as any), RESOLVED, value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static reject<U>(error: U): Promise<U> { | 
					
						
							|  |  |  |       return resolvePromise(<ZoneAwarePromise<U>>new this(null as any), REJECTED, error); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static race<R>(values: PromiseLike<any>[]): Promise<R> { | 
					
						
							|  |  |  |       let resolve: (v: any) => void; | 
					
						
							|  |  |  |       let reject: (v: any) => void; | 
					
						
							|  |  |  |       let promise: any = new this((res, rej) => { | 
					
						
							|  |  |  |         resolve = res; | 
					
						
							|  |  |  |         reject = rej; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |       function onResolve(value: any) { | 
					
						
							|  |  |  |         resolve(value); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       function onReject(error: any) { | 
					
						
							|  |  |  |         reject(error); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |       for (let value of values) { | 
					
						
							|  |  |  |         if (!isThenable(value)) { | 
					
						
							|  |  |  |           value = this.resolve(value); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         value.then(onResolve, onReject); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return promise; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |     static all<R>(values: any): Promise<R> { | 
					
						
							|  |  |  |       return ZoneAwarePromise.allWithCallback(values); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-07-25 23:13:05 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     static allSettled<R>(values: any): Promise<R> { | 
					
						
							|  |  |  |       const P = this && this.prototype instanceof ZoneAwarePromise ? this : ZoneAwarePromise; | 
					
						
							|  |  |  |       return P.allWithCallback(values, { | 
					
						
							|  |  |  |         thenCallback: (value: any) => ({status: 'fulfilled', value}), | 
					
						
							|  |  |  |         errorCallback: (err: any) => ({status: 'rejected', reason: err}) | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static allWithCallback<R>(values: any, callback?: { | 
					
						
							|  |  |  |       thenCallback: (value: any) => any, | 
					
						
							|  |  |  |       errorCallback: (err: any) => any | 
					
						
							|  |  |  |     }): Promise<R> { | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       let resolve: (v: any) => void; | 
					
						
							|  |  |  |       let reject: (v: any) => void; | 
					
						
							|  |  |  |       let promise = new this<R>((res, rej) => { | 
					
						
							|  |  |  |         resolve = res; | 
					
						
							|  |  |  |         reject = rej; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Start at 2 to prevent prematurely resolving if .then is called immediately.
 | 
					
						
							|  |  |  |       let unresolvedCount = 2; | 
					
						
							|  |  |  |       let valueIndex = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const resolvedValues: any[] = []; | 
					
						
							|  |  |  |       for (let value of values) { | 
					
						
							|  |  |  |         if (!isThenable(value)) { | 
					
						
							|  |  |  |           value = this.resolve(value); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const curValueIndex = valueIndex; | 
					
						
							| 
									
										
										
										
											2019-07-25 23:13:05 +09:00
										 |  |  |         try { | 
					
						
							|  |  |  |           value.then( | 
					
						
							|  |  |  |               (value: any) => { | 
					
						
							|  |  |  |                 resolvedValues[curValueIndex] = callback ? callback.thenCallback(value) : value; | 
					
						
							|  |  |  |                 unresolvedCount--; | 
					
						
							|  |  |  |                 if (unresolvedCount === 0) { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |                   resolve!(resolvedValues); | 
					
						
							| 
									
										
										
										
											2019-07-25 23:13:05 +09:00
										 |  |  |                 } | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |               (err: any) => { | 
					
						
							|  |  |  |                 if (!callback) { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |                   reject!(err); | 
					
						
							| 
									
										
										
										
											2019-07-25 23:13:05 +09:00
										 |  |  |                 } else { | 
					
						
							|  |  |  |                   resolvedValues[curValueIndex] = callback.errorCallback(err); | 
					
						
							|  |  |  |                   unresolvedCount--; | 
					
						
							|  |  |  |                   if (unresolvedCount === 0) { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |                     resolve!(resolvedValues); | 
					
						
							| 
									
										
										
										
											2019-07-25 23:13:05 +09:00
										 |  |  |                   } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               }); | 
					
						
							|  |  |  |         } catch (thenErr) { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |           reject!(thenErr); | 
					
						
							| 
									
										
										
										
											2019-07-25 23:13:05 +09:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |         unresolvedCount++; | 
					
						
							|  |  |  |         valueIndex++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Make the unresolvedCount zero-based again.
 | 
					
						
							|  |  |  |       unresolvedCount -= 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (unresolvedCount === 0) { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |         resolve!(resolvedValues); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return promise; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor( | 
					
						
							|  |  |  |         executor: | 
					
						
							|  |  |  |             (resolve: (value?: R|PromiseLike<R>) => void, reject: (error?: any) => void) => void) { | 
					
						
							|  |  |  |       const promise: ZoneAwarePromise<R> = this; | 
					
						
							|  |  |  |       if (!(promise instanceof ZoneAwarePromise)) { | 
					
						
							|  |  |  |         throw new Error('Must be an instanceof Promise.'); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       (promise as any)[symbolState] = UNRESOLVED; | 
					
						
							|  |  |  |       (promise as any)[symbolValue] = [];  // queue;
 | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         executor && executor(makeResolver(promise, RESOLVED), makeResolver(promise, REJECTED)); | 
					
						
							|  |  |  |       } catch (error) { | 
					
						
							|  |  |  |         resolvePromise(promise, false, error); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |     get[Symbol.toStringTag]() { | 
					
						
							|  |  |  |       return 'Promise' as any; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |     get[Symbol.species]() { | 
					
						
							|  |  |  |       return ZoneAwarePromise; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-01 12:27:33 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |     then<TResult1 = R, TResult2 = never>( | 
					
						
							|  |  |  |         onFulfilled?: ((value: R) => TResult1 | PromiseLike<TResult1>)|undefined|null, | 
					
						
							|  |  |  |         onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>)|undefined| | 
					
						
							|  |  |  |         null): Promise<TResult1|TResult2> { | 
					
						
							| 
									
										
										
										
											2019-12-01 12:27:33 +09:00
										 |  |  |       let C = (this.constructor as any)[Symbol.species]; | 
					
						
							|  |  |  |       if (!C || typeof C !== 'function') { | 
					
						
							| 
									
										
										
										
											2019-12-22 13:15:08 +09:00
										 |  |  |         C = this.constructor || ZoneAwarePromise; | 
					
						
							| 
									
										
										
										
											2019-12-01 12:27:33 +09:00
										 |  |  |       } | 
					
						
							|  |  |  |       const chainPromise: Promise<TResult1|TResult2> = new (C as typeof ZoneAwarePromise)(noop); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       const zone = Zone.current; | 
					
						
							|  |  |  |       if ((this as any)[symbolState] == UNRESOLVED) { | 
					
						
							|  |  |  |         (<any[]>(this as any)[symbolValue]).push(zone, chainPromise, onFulfilled, onRejected); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         scheduleResolveOrReject(this, zone, chainPromise as any, onFulfilled, onRejected); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return chainPromise; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     catch<TResult = never>(onRejected?: ((reason: any) => TResult | PromiseLike<TResult>)|undefined| | 
					
						
							|  |  |  |                            null): Promise<R|TResult> { | 
					
						
							|  |  |  |       return this.then(null, onRejected); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     finally<U>(onFinally?: () => U | PromiseLike<U>): Promise<R> { | 
					
						
							| 
									
										
										
										
											2019-12-01 12:27:33 +09:00
										 |  |  |       let C = (this.constructor as any)[Symbol.species]; | 
					
						
							|  |  |  |       if (!C || typeof C !== 'function') { | 
					
						
							|  |  |  |         C = ZoneAwarePromise; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       const chainPromise: Promise<R|never> = new (C as typeof ZoneAwarePromise)(noop); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       (chainPromise as any)[symbolFinally] = symbolFinally; | 
					
						
							|  |  |  |       const zone = Zone.current; | 
					
						
							|  |  |  |       if ((this as any)[symbolState] == UNRESOLVED) { | 
					
						
							|  |  |  |         (<any[]>(this as any)[symbolValue]).push(zone, chainPromise, onFinally, onFinally); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         scheduleResolveOrReject(this, zone, chainPromise as any, onFinally, onFinally); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return chainPromise; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // Protect against aggressive optimizers dropping seemingly unused properties.
 | 
					
						
							|  |  |  |   // E.g. Closure Compiler in advanced mode.
 | 
					
						
							|  |  |  |   ZoneAwarePromise['resolve'] = ZoneAwarePromise.resolve; | 
					
						
							|  |  |  |   ZoneAwarePromise['reject'] = ZoneAwarePromise.reject; | 
					
						
							|  |  |  |   ZoneAwarePromise['race'] = ZoneAwarePromise.race; | 
					
						
							|  |  |  |   ZoneAwarePromise['all'] = ZoneAwarePromise.all; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const NativePromise = global[symbolPromise] = global['Promise']; | 
					
						
							|  |  |  |   global['Promise'] = ZoneAwarePromise; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const symbolThenPatched = __symbol__('thenPatched'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function patchThen(Ctor: Function) { | 
					
						
							|  |  |  |     const proto = Ctor.prototype; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const prop = ObjectGetOwnPropertyDescriptor(proto, 'then'); | 
					
						
							|  |  |  |     if (prop && (prop.writable === false || !prop.configurable)) { | 
					
						
							|  |  |  |       // check Ctor.prototype.then propertyDescriptor is writable or not
 | 
					
						
							|  |  |  |       // in meteor env, writable is false, we should ignore such case
 | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const originalThen = proto.then; | 
					
						
							|  |  |  |     // Keep a reference to the original method.
 | 
					
						
							|  |  |  |     proto[symbolThen] = originalThen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Ctor.prototype.then = function(onResolve: any, onReject: any) { | 
					
						
							| 
									
										
										
										
											2020-04-07 09:59:25 -07:00
										 |  |  |       const wrapped = new ZoneAwarePromise((resolve, reject) => { | 
					
						
							|  |  |  |         originalThen.call(this, resolve, reject); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       return wrapped.then(onResolve, onReject); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     (Ctor as any)[symbolThenPatched] = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   api.patchThen = patchThen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function zoneify(fn: Function) { | 
					
						
							| 
									
										
										
										
											2020-03-30 09:14:02 +09:00
										 |  |  |     return function(self: any, args: any[]) { | 
					
						
							|  |  |  |       let resultPromise = fn.apply(self, args); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |       if (resultPromise instanceof ZoneAwarePromise) { | 
					
						
							|  |  |  |         return resultPromise; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       let ctor = resultPromise.constructor; | 
					
						
							|  |  |  |       if (!ctor[symbolThenPatched]) { | 
					
						
							|  |  |  |         patchThen(ctor); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return resultPromise; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (NativePromise) { | 
					
						
							|  |  |  |     patchThen(NativePromise); | 
					
						
							| 
									
										
										
										
											2020-03-30 09:14:02 +09:00
										 |  |  |     patchMethod(global, 'fetch', delegate => zoneify(delegate)); | 
					
						
							| 
									
										
										
										
											2019-06-01 00:56:07 +09:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // This is not part of public API, but it is useful for tests, so we expose it.
 | 
					
						
							|  |  |  |   (Promise as any)[Zone.__symbol__('uncaughtPromiseErrors')] = _uncaughtPromiseErrors; | 
					
						
							|  |  |  |   return ZoneAwarePromise; | 
					
						
							|  |  |  | }); |