mirror of
https://github.com/adminlove520/AI-Account-Toolkit.git
synced 2026-05-14 09:17:38 +08:00
99 lines
2.5 KiB
JavaScript
99 lines
2.5 KiB
JavaScript
(function attachStepWaiterApi(globalScope) {
|
|
function normalizeError(error, fallbackMessage) {
|
|
if (error instanceof Error) {
|
|
return error;
|
|
}
|
|
if (typeof error === 'string' && error) {
|
|
return new Error(error);
|
|
}
|
|
return new Error(fallbackMessage);
|
|
}
|
|
|
|
function createStepWaiterRegistry(options = {}) {
|
|
const schedule = options.schedule || setTimeout;
|
|
const cancel = options.cancel || clearTimeout;
|
|
const waiters = new Map();
|
|
|
|
function clearOwnedWaiter(step, waiter) {
|
|
if (waiters.get(step) === waiter) {
|
|
waiters.delete(step);
|
|
}
|
|
}
|
|
|
|
function waitForStepComplete(step, timeoutMs = 120000) {
|
|
return new Promise((resolve, reject) => {
|
|
const existing = waiters.get(step);
|
|
if (existing) {
|
|
existing.reject(new Error(`Step ${step} waiter was replaced by a newer execution.`));
|
|
}
|
|
|
|
let settled = false;
|
|
const waiter = {
|
|
resolve: (payload) => {
|
|
if (settled) {
|
|
return;
|
|
}
|
|
settled = true;
|
|
cancel(waiter.timer);
|
|
clearOwnedWaiter(step, waiter);
|
|
resolve(payload);
|
|
},
|
|
reject: (error) => {
|
|
if (settled) {
|
|
return;
|
|
}
|
|
settled = true;
|
|
cancel(waiter.timer);
|
|
clearOwnedWaiter(step, waiter);
|
|
reject(normalizeError(error, `Step ${step} failed.`));
|
|
},
|
|
timer: null,
|
|
};
|
|
|
|
waiter.timer = schedule(() => {
|
|
waiter.reject(new Error(`Step ${step} timed out after ${timeoutMs / 1000}s.`));
|
|
}, timeoutMs);
|
|
|
|
waiters.set(step, waiter);
|
|
});
|
|
}
|
|
|
|
function notifyStepComplete(step, payload) {
|
|
const waiter = waiters.get(step);
|
|
if (waiter) {
|
|
waiter.resolve(payload);
|
|
}
|
|
}
|
|
|
|
function notifyStepError(step, error) {
|
|
const waiter = waiters.get(step);
|
|
if (waiter) {
|
|
waiter.reject(error);
|
|
}
|
|
}
|
|
|
|
function rejectAll(error) {
|
|
const pending = Array.from(waiters.values());
|
|
waiters.clear();
|
|
for (const waiter of pending) {
|
|
waiter.reject(error);
|
|
}
|
|
}
|
|
|
|
return {
|
|
waitForStepComplete,
|
|
notifyStepComplete,
|
|
notifyStepError,
|
|
rejectAll,
|
|
};
|
|
}
|
|
|
|
const api = { createStepWaiterRegistry };
|
|
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
module.exports = api;
|
|
}
|
|
|
|
Object.assign(globalScope, api);
|
|
})(typeof globalThis !== 'undefined' ? globalThis : self);
|