// SPDX-License-Identifier: Apache-2.0
// Copyright 2024-2026 Vorion LLC
/**
 * Promise timeout utility
 *
 * Provides a mechanism to wrap promises with timeout behavior
 * to prevent indefinite hangs during health checks.
 */
import { createLogger } from './logger.js';
const timeoutLogger = createLogger({ component: 'timeout' });
/**
 * Wraps a promise with a timeout, rejecting if the operation
 * takes longer than the specified duration.
 *
 * @param promise - The promise to wrap with timeout
 * @param timeoutMs - Timeout duration in milliseconds
 * @param errorMessage - Custom error message for timeout
 * @returns The result of the promise if it resolves before timeout
 * @throws Error if the operation times out
 */
export async function withTimeout(promise, timeoutMs, errorMessage = 'Operation timed out') {
    let timeoutId;
    const timeoutPromise = new Promise((_, reject) => {
        timeoutId = setTimeout(() => {
            timeoutLogger.warn({ timeoutMs, errorMessage }, 'Operation timed out');
            reject(new Error(errorMessage));
        }, timeoutMs);
    });
    try {
        const result = await Promise.race([promise, timeoutPromise]);
        clearTimeout(timeoutId);
        return result;
    }
    catch (error) {
        clearTimeout(timeoutId);
        throw error;
    }
}
/**
 * TimeoutError class for type checking timeout errors
 */
export class TimeoutError extends Error {
    timeoutMs;
    constructor(message, timeoutMs) {
        super(message);
        this.timeoutMs = timeoutMs;
        this.name = 'TimeoutError';
    }
}
/**
 * Wraps a promise with a timeout, returning a TimeoutError instance
 * for easier type checking.
 *
 * @param promise - The promise to wrap with timeout
 * @param timeoutMs - Timeout duration in milliseconds
 * @param errorMessage - Custom error message for timeout
 * @returns The result of the promise if it resolves before timeout
 * @throws TimeoutError if the operation times out
 */
export async function withTimeoutTyped(promise, timeoutMs, errorMessage = 'Operation timed out') {
    let timeoutId;
    const timeoutPromise = new Promise((_, reject) => {
        timeoutId = setTimeout(() => {
            timeoutLogger.warn({ timeoutMs, errorMessage }, 'Operation timed out');
            reject(new TimeoutError(errorMessage, timeoutMs));
        }, timeoutMs);
    });
    try {
        const result = await Promise.race([promise, timeoutPromise]);
        clearTimeout(timeoutId);
        return result;
    }
    catch (error) {
        clearTimeout(timeoutId);
        throw error;
    }
}
/**
 * Check if an error is a timeout error
 */
export function isTimeoutError(error) {
    return error instanceof TimeoutError;
}
//# sourceMappingURL=timeout.js.map