/** Объединяет несколько AbortSignal: один abort отменяет общий контроллер. */
export function mergeAbortSignals(...signals: AbortSignal[]): AbortSignal {
  const c = new AbortController()
  const forward = () => {
    c.abort()
  }
  for (const s of signals) {
    if (s.aborted) {
      forward()
      return c.signal
    }
    s.addEventListener("abort", forward, { once: true })
  }
  return c.signal
}

/** Отмена через `ms` миллисекунд (таймер не снимается при другой отмене — ок для короткоживущих запросов). */
export function abortAfterMs(ms: number): AbortSignal {
  const c = new AbortController()
  setTimeout(() => c.abort(), ms)
  return c.signal
}
