88 lines
2.5 KiB
JavaScript
88 lines
2.5 KiB
JavaScript
//@ts-check
|
|
// Helpers for a tracked promise land
|
|
// Traps regular promise as well as promise by fetch
|
|
// by Humans for All
|
|
//
|
|
|
|
|
|
/**
|
|
* @typedef {(resolve: (value: any) => void, reject: (reason?: any) => void) => void} PromiseExecutor
|
|
*/
|
|
|
|
|
|
/**
|
|
* Eval which allows promises generated by the evald code to be tracked.
|
|
* @param {string} codeToEval
|
|
*/
|
|
export async function evalWithPromiseTracking(codeToEval) {
|
|
const _Promise = globalThis.Promise;
|
|
const _fetch = globalThis.fetch
|
|
|
|
/** @type {any[]} */
|
|
const trackedPromises = [];
|
|
|
|
const Promise = function ( /** @type {PromiseExecutor} */ executor) {
|
|
console.info("WW:PT:Promise")
|
|
const promise = new _Promise(executor);
|
|
trackedPromises.push(promise);
|
|
|
|
// @ts-ignore
|
|
promise.then = function (...args) {
|
|
console.info("WW:PT:Then")
|
|
const newPromise = _Promise.prototype.then.apply(this, args);
|
|
trackedPromises.push(newPromise);
|
|
return newPromise;
|
|
};
|
|
|
|
promise.catch = function (...args) {
|
|
console.info("WW:PT:Catch")
|
|
const newPromise = _Promise.prototype.catch.apply(this, args);
|
|
trackedPromises.push(newPromise);
|
|
return newPromise;
|
|
};
|
|
|
|
return promise;
|
|
};
|
|
|
|
Promise.prototype = _Promise.prototype;
|
|
Object.assign(Promise, _Promise);
|
|
|
|
const fetch = function(/** @type {any[]} */ ...args) {
|
|
console.info("WW:PT:Fetch")
|
|
// @ts-ignore
|
|
const fpromise = _fetch(args);
|
|
trackedPromises.push(fpromise)
|
|
|
|
// @ts-ignore
|
|
fpromise.then = function (...args) {
|
|
console.info("WW:PT:FThen")
|
|
const newPromise = _Promise.prototype.then.apply(this, args);
|
|
trackedPromises.push(newPromise);
|
|
return newPromise;
|
|
};
|
|
|
|
fpromise.catch = function (...args) {
|
|
console.info("WW:PT:FCatch")
|
|
const newPromise = _Promise.prototype.catch.apply(this, args);
|
|
trackedPromises.push(newPromise);
|
|
return newPromise;
|
|
};
|
|
|
|
return fpromise;
|
|
}
|
|
|
|
fetch.prototype = _fetch.prototype;
|
|
Object.assign(fetch, _fetch);
|
|
|
|
//let tf = new Function(codeToEval);
|
|
//await tf()
|
|
await eval(`(async () => { ${codeToEval} })()`);
|
|
|
|
// Should I allow things to go back to related event loop once
|
|
//await Promise(resolve=>setTimeout(resolve, 0));
|
|
|
|
// Need and prefer promise failures to be trapped using reject/catch logic
|
|
// so using all instead of allSettled.
|
|
return _Promise.all(trackedPromises);
|
|
}
|