export const delay = (ms: number) => new Promise(resolve => setTimeout(() => resolve(), ms)); export const makeCancellable = (promise: Promise) => { const cancellablePromise = Object.create(Promise.prototype); cancellablePromise.hasCanceled = false; const wrappedPromise = new Promise((resolve, reject) => { promise.then( val => (cancellablePromise.hasCanceled ? reject({ isCanceled: true }) : resolve(val)), error => (cancellablePromise.hasCanceled ? reject({ isCanceled: true }) : reject(error)), ); }); cancellablePromise.wrappedPromise = wrappedPromise; cancellablePromise.cancel = function () { this.hasCanceled = true; }; cancellablePromise.then = function (...args) { return this.wrappedPromise.then(...args); }; cancellablePromise.catch = function (...args) { return this.wrappedPromise.catch(...args); }; return cancellablePromise; }; export const makeTimeLimited = (promise: Promise, timeoutMs: number, reason?: any) => { return Promise.race([promise, delay(timeoutMs).then(() => Promise.reject(reason || new Error('Timeout')))]); };