@whatwg-node/promise-helpers
Version:
Promise helpers
134 lines (133 loc) • 3.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.isPromise = isPromise;
exports.isPromiseLike = isPromiseLike;
exports.handleMaybePromiseLike = handleMaybePromiseLike;
exports.handleMaybePromise = handleMaybePromise;
exports.fakePromise = fakePromise;
exports.createDeferredPromise = createDeferredPromise;
exports.iterateAsyncVoid = iterateAsyncVoid;
exports.fakeRejectPromise = fakeRejectPromise;
function isPromise(value) {
return isPromiseLike(value);
}
function isPromiseLike(value) {
return value?.then != null;
}
function handleMaybePromiseLike(inputFactory, outputSuccessFactory, outputErrorFactory) {
function _handleMaybePromiseLike() {
const input$ = inputFactory();
if (isPromiseLike(input$)) {
return input$.then(outputSuccessFactory, outputErrorFactory);
}
return outputSuccessFactory(input$);
}
if (!outputErrorFactory) {
return _handleMaybePromiseLike();
}
try {
return _handleMaybePromiseLike();
}
catch (err) {
return outputErrorFactory(err);
}
}
function handleMaybePromise(inputFactory, outputSuccessFactory, outputErrorFactory) {
return handleMaybePromiseLike(inputFactory, outputSuccessFactory, outputErrorFactory);
}
function fakePromise(value) {
if (isPromise(value)) {
return value;
}
// Write a fake promise to avoid the promise constructor
// being called with `new Promise` in the browser.
return {
then(resolve) {
if (resolve) {
const callbackResult = resolve(value);
if (isPromise(callbackResult)) {
return callbackResult;
}
return fakePromise(callbackResult);
}
return this;
},
catch() {
return this;
},
finally(cb) {
if (cb) {
const callbackResult = cb();
if (isPromise(callbackResult)) {
return callbackResult.then(() => value, () => value);
}
return fakePromise(value);
}
return this;
},
[Symbol.toStringTag]: 'Promise',
};
}
function createDeferredPromise() {
if (Promise.withResolvers) {
return Promise.withResolvers();
}
let resolveFn;
let rejectFn;
const promise = new Promise(function deferredPromiseExecutor(resolve, reject) {
resolveFn = resolve;
rejectFn = reject;
});
return {
promise,
get resolve() {
return resolveFn;
},
get reject() {
return rejectFn;
},
};
}
function iterateAsyncVoid(iterable, callback) {
const iterator = iterable[Symbol.iterator]();
let stopEarlyFlag = false;
function stopEarlyFn() {
stopEarlyFlag = true;
}
function iterate() {
const { done: endOfIterator, value } = iterator.next();
if (endOfIterator) {
return;
}
return handleMaybePromise(() => callback(value, stopEarlyFn), () => {
if (stopEarlyFlag) {
return;
}
return iterate();
});
}
return iterate();
}
function fakeRejectPromise(error) {
if (isPromise(error)) {
return error;
}
return {
then() {
return this;
},
catch(reject) {
if (reject) {
return fakePromise(reject(error));
}
return this;
},
finally(cb) {
if (cb) {
cb();
}
return this;
},
[Symbol.toStringTag]: 'Promise',
};
}