UNPKG

ai-patterns

Version:

Production-ready TypeScript patterns to build solid and robust AI applications. Retry logic, circuit breakers, rate limiting, human-in-the-loop escalation, prompt versioning, response validation, context window management, and more—all with complete type

94 lines 3.29 kB
"use strict"; /** * Timeout Pattern - Limit execution time of operations */ Object.defineProperty(exports, "__esModule", { value: true }); exports.TimeoutDurations = void 0; exports.timeout = timeout; exports.createTimeoutSignal = createTimeoutSignal; exports.combineSignals = combineSignals; const common_1 = require("../types/common"); const errors_1 = require("../types/errors"); const timeout_1 = require("../types/timeout"); Object.defineProperty(exports, "TimeoutDurations", { enumerable: true, get: function () { return timeout_1.TimeoutDurations; } }); /** * Timeout Pattern - Execute function with time limit */ async function timeout(options) { const { execute: fn, timeoutMs, message = `Operation cancelled after ${timeoutMs}ms`, logger = common_1.defaultLogger, onTimeout, signal: externalSignal, } = options; // Validation if (timeoutMs <= 0) { throw new errors_1.PatternError(`timeoutMs must be > 0, received: ${timeoutMs}`, errors_1.ErrorCode.INVALID_TIMEOUT); } const startTime = Date.now(); const controller = new AbortController(); const { signal: internalSignal } = controller; // If external signal provided, combine with internal signal if (externalSignal) { if (externalSignal.aborted) { throw new errors_1.PatternError("Operation cancelled before start", errors_1.ErrorCode.ABORTED); } externalSignal.addEventListener("abort", () => { controller.abort(); }); } // Create timeout timer const timer = setTimeout(() => { logger.warn(`Timeout after ${timeoutMs}ms`); if (onTimeout) { onTimeout(); } controller.abort(); }, timeoutMs); try { // Execute function with signal const value = await Promise.race([ fn(), new Promise((_, reject) => { internalSignal.addEventListener("abort", () => { const duration = Date.now() - startTime; const error = new errors_1.PatternError(message, errors_1.ErrorCode.TIMEOUT, undefined, { duration, timeoutMs }); error.duration = duration; error.timedOut = true; reject(error); }); }), ]); const duration = Date.now() - startTime; logger.debug(`Operation completed in ${duration}ms`); return { value, duration, timedOut: false, }; } finally { clearTimeout(timer); } } /** * Create an AbortSignal that aborts after a delay */ function createTimeoutSignal(timeoutMs) { const controller = new AbortController(); setTimeout(() => controller.abort(), timeoutMs); return controller.signal; } /** * Combine multiple AbortSignals into one * The combined signal aborts when any input signal aborts */ function combineSignals(...signals) { const controller = new AbortController(); for (const signal of signals) { if (signal.aborted) { controller.abort(); break; } signal.addEventListener("abort", () => { controller.abort(); }); } return controller.signal; } //# sourceMappingURL=timeout.js.map