/**
 * Envuelve una promesa y la rechaza si no se completa en el tiempo especificado.
 * @param promise La promesa a envolver.
 * @param ms Tiempo límite en milisegundos.
 * @param error Opcional. Error con el que se rechaza en caso de timeout.
 */
export function withTimeout<T>(
  promise: Promise<T>,
  ms: number,
  error?: Error
): Promise<T> {
  let timeoutId: ReturnType<typeof setTimeout>;

  const timeoutPromise = new Promise<never>((_, reject) => {
    timeoutId = setTimeout(() => {
      reject(error || new Error(`Operation timed out after ${ms}ms`));
    }, ms);
  });

  return Promise.race([
    promise.finally(() => clearTimeout(timeoutId!)),
    timeoutPromise,
  ]) as Promise<T>;
}
