export interface PromiseWithResolvers { promise: Promise; resolve: (value: T | PromiseLike) => void; reject: (reason?: any) => void; } export function promiseWithResolvers(): PromiseWithResolvers { let resolve: (value: T | PromiseLike) => void; let reject: (reason?: any) => void; const promise = new Promise((_resolve, _reject) => { resolve = _resolve; reject = _reject; }); return { promise, resolve: resolve!, reject: reject! }; } export type PackedPromise = () => Promise; export function packPromise(promise: Promise): PackedPromise { const packed: Promise> = promise.then( (value) => ({ status: "fulfilled", value }), (reason) => ({ status: "rejected", reason }), ); return function unpackPromise() { return packed.then((result) => result.status === "fulfilled" ? result.value : Promise.reject(result.reason), ); }; }