llama.cpp/tools/server/public_simplechat/xpromise.mjs

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