const ensurePromise = (maybePromise: T | PromiseLike): Promise => typeof maybePromise === 'object' && maybePromise !== null && 'then' in maybePromise && typeof maybePromise.then === 'function' && 'catch' in maybePromise && typeof maybePromise.catch === 'function' && 'finally' in maybePromise && typeof maybePromise.finally === 'function' ? (maybePromise as Promise) : Promise.resolve(maybePromise); /** Returns a function that caches successful promises until time runs out, and throws away unsuccessful ones */ export const oncePromise = ( create: () => Promise, retries = true, timeout = -1 ) => { let getPromise = (): Promise => { const oldGetPromise = getPromise, promise = retries ? ensurePromise(create()).catch((e) => { getPromise = oldGetPromise; throw e; }) : ensurePromise(create()), expires = timeout > 0 ? performance.now() + timeout : 0; return (getPromise = expires ? ((() => performance.now() > expires ? oldGetPromise() : promise) as () => Promise) : () => promise)(); }; return () => getPromise(); }; export default oncePromise;