//@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); }