{"version":3,"file":"index-Bd7dlzi9.cjs","sources":["../src/errors/index.ts","../src/utils/index.ts","../src/client/index.ts"],"sourcesContent":["/**\r\n * Error system for AI Assistant Core\r\n *\r\n * All error codes with retriability classification.\r\n */\r\n\r\nexport const ErrorCodes = {\r\n  NETWORK: 'NETWORK',\r\n  TIMEOUT: 'TIMEOUT',\r\n  AUTH: 'AUTH',\r\n  FORBIDDEN: 'FORBIDDEN',\r\n  RATE_LIMIT: 'RATE_LIMIT',\r\n  MODEL_UNAVAILABLE: 'MODEL_UNAVAILABLE',\r\n  TOOL_FAILED: 'TOOL_FAILED',\r\n  PARSE: 'PARSE',\r\n  ABORTED: 'ABORTED',\r\n  UNKNOWN: 'UNKNOWN',\r\n} as const\r\n\r\nexport type ErrorCode = keyof typeof ErrorCodes\r\n\r\n/**\r\n * Map of error codes to their default retriability.\r\n * Retriable errors: transient network / server issues.\r\n * Non-retriable errors: auth, permission, parse, user-cancel.\r\n */\r\nconst DEFAULT_RETRIABILITY: Record<ErrorCode, boolean> = {\r\n  NETWORK: true,\r\n  TIMEOUT: true,\r\n  AUTH: false,\r\n  FORBIDDEN: false,\r\n  RATE_LIMIT: true,\r\n  MODEL_UNAVAILABLE: true,\r\n  TOOL_FAILED: false,\r\n  PARSE: false,\r\n  ABORTED: false,\r\n  UNKNOWN: false,\r\n}\r\n\r\nexport interface AiAssistantError extends Error {\r\n  code: ErrorCode\r\n  retriable: boolean\r\n  details?: unknown\r\n}\r\n\r\n/**\r\n * Create a typed AI Assistant error.\r\n *\r\n * @param code      — error code from ErrorCodes\r\n * @param message   — human-readable message\r\n * @param retriable — override default retriability (optional)\r\n * @param details   — extra context for debugging\r\n */\r\nexport function createError(\r\n  code: ErrorCode,\r\n  message: string,\r\n  retriable?: boolean,\r\n  details?: unknown\r\n): AiAssistantError {\r\n  const error = new Error(message) as AiAssistantError\r\n  error.code = code\r\n  error.retriable = retriable ?? DEFAULT_RETRIABILITY[code] ?? false\r\n  error.details = details\r\n  return error\r\n}\r\n\r\n/**\r\n * Check whether an error is retriable.\r\n */\r\nexport function isRetriable(error: unknown): boolean {\r\n  if (error instanceof Error && 'retriable' in error) {\r\n    return Boolean((error as AiAssistantError).retriable)\r\n  }\r\n  return false\r\n}\r\n\r\n/**\r\n * Check whether an error represents a user abort.\r\n */\r\nexport function isAborted(error: unknown): boolean {\r\n  if (error instanceof Error && 'code' in error) {\r\n    return (error as AiAssistantError).code === 'ABORTED'\r\n  }\r\n  return false\r\n}\r\n","/**\r\n * Utility functions for AI Assistant Core\r\n *\r\n * Pure TypeScript — no framework dependencies.\r\n */\r\n\r\n/** Generate a short unique id with an optional prefix. */\r\nexport function generateId(prefix: string = ''): string {\r\n  return `${prefix}${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`\r\n}\r\n\r\n/** Promise-based sleep. */\r\nexport function delay(ms: number): Promise<void> {\r\n  return new Promise(resolve => setTimeout(resolve, ms))\r\n}\r\n\r\n/** Clamp a number between min and max (inclusive). */\r\nexport function clamp(value: number, min: number, max: number): number {\r\n  return Math.min(Math.max(value, min), max)\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Type guards\r\n// ---------------------------------------------------------------------------\r\n\r\nexport function isObject(value: unknown): value is Record<string, unknown> {\r\n  return value !== null && typeof value === 'object' && !Array.isArray(value)\r\n}\r\n\r\nexport function isArray<T = unknown>(value: unknown): value is T[] {\r\n  return Array.isArray(value)\r\n}\r\n\r\nexport function isString(value: unknown): value is string {\r\n  return typeof value === 'string'\r\n}\r\n\r\nexport function isNumber(value: unknown): value is number {\r\n  return typeof value === 'number' && !Number.isNaN(value)\r\n}\r\n\r\nexport function isFunction(value: unknown): value is (...args: unknown[]) => unknown {\r\n  return typeof value === 'function'\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Debounce / Throttle\r\n// ---------------------------------------------------------------------------\r\n\r\nexport interface DebouncedFunction<T extends (...args: unknown[]) => unknown> {\r\n  (...args: Parameters<T>): ReturnType<T> | undefined\r\n  cancel: () => void\r\n  flush: () => ReturnType<T> | undefined\r\n}\r\n\r\nexport function debounce<T extends (...args: unknown[]) => unknown>(\r\n  fn: T,\r\n  waitMs: number,\r\n  immediate: boolean = false\r\n): DebouncedFunction<T> {\r\n  let timeoutId: ReturnType<typeof setTimeout> | null = null\r\n  let lastArgs: Parameters<T> | null = null\r\n  let lastResult: ReturnType<T> | undefined\r\n\r\n  const invoke = (): ReturnType<T> | undefined => {\r\n    timeoutId = null\r\n    if (lastArgs) {\r\n      lastResult = fn(...lastArgs) as ReturnType<T>\r\n      lastArgs = null\r\n    }\r\n    return lastResult\r\n  }\r\n\r\n  const debounced = (...args: Parameters<T>): ReturnType<T> | undefined => {\r\n    lastArgs = args\r\n    if (timeoutId) clearTimeout(timeoutId)\r\n    if (immediate && !timeoutId) {\r\n      lastResult = fn(...args) as ReturnType<T>\r\n      timeoutId = setTimeout(() => { timeoutId = null }, waitMs)\r\n      return lastResult\r\n    }\r\n    timeoutId = setTimeout(invoke, waitMs)\r\n    return undefined\r\n  }\r\n\r\n  debounced.cancel = () => {\r\n    if (timeoutId) {\r\n      clearTimeout(timeoutId)\r\n      timeoutId = null\r\n    }\r\n    lastArgs = null\r\n  }\r\n\r\n  debounced.flush = () => {\r\n    if (timeoutId) {\r\n      clearTimeout(timeoutId)\r\n      return invoke()\r\n    }\r\n    return lastResult\r\n  }\r\n\r\n  return debounced as DebouncedFunction<T>\r\n}\r\n\r\nexport interface ThrottledFunction<T extends (...args: unknown[]) => unknown> {\r\n  (...args: Parameters<T>): ReturnType<T> | undefined\r\n  cancel: () => void\r\n}\r\n\r\nexport function throttle<T extends (...args: unknown[]) => unknown>(\r\n  fn: T,\r\n  waitMs: number,\r\n  options: { leading?: boolean; trailing?: boolean } = {}\r\n): ThrottledFunction<T> {\r\n  const { leading = true, trailing = true } = options\r\n  let timeoutId: ReturnType<typeof setTimeout> | null = null\r\n  let lastArgs: Parameters<T> | null = null\r\n  let lastResult: ReturnType<T> | undefined\r\n  let lastCallTime = 0\r\n\r\n  const invoke = (): void => {\r\n    timeoutId = null\r\n    if (lastArgs && trailing) {\r\n      lastResult = fn(...lastArgs) as ReturnType<T>\r\n      lastArgs = null\r\n      lastCallTime = Date.now()\r\n    }\r\n  }\r\n\r\n  const throttled = (...args: Parameters<T>): ReturnType<T> | undefined => {\r\n    const now = Date.now()\r\n    const remaining = waitMs - (now - lastCallTime)\r\n    lastArgs = args\r\n\r\n    if (remaining <= 0 || remaining > waitMs) {\r\n      if (timeoutId) {\r\n        clearTimeout(timeoutId)\r\n        timeoutId = null\r\n      }\r\n      if (leading) {\r\n        lastResult = fn(...args) as ReturnType<T>\r\n        lastCallTime = now\r\n      } else {\r\n        lastCallTime = now\r\n        if (trailing) {\r\n          timeoutId = setTimeout(invoke, waitMs)\r\n        }\r\n      }\r\n      return lastResult\r\n    }\r\n\r\n    if (!timeoutId && trailing) {\r\n      timeoutId = setTimeout(invoke, remaining)\r\n    }\r\n    return lastResult\r\n  }\r\n\r\n  throttled.cancel = () => {\r\n    if (timeoutId) {\r\n      clearTimeout(timeoutId)\r\n      timeoutId = null\r\n    }\r\n    lastArgs = null\r\n    lastCallTime = 0\r\n  }\r\n\r\n  return throttled as ThrottledFunction<T>\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Deep clone\r\n// ---------------------------------------------------------------------------\r\n\r\nexport function deepClone<T>(value: T): T {\r\n  if (value === null || typeof value !== 'object') return value\r\n  if (value instanceof Date) return new Date(value.getTime()) as unknown as T\r\n  if (value instanceof RegExp) return new RegExp(value.source, value.flags) as unknown as T\r\n  if (Array.isArray(value)) {\r\n    return value.map(item => deepClone(item)) as unknown as T\r\n  }\r\n  const cloned = {} as Record<string, unknown>\r\n  for (const key of Object.keys(value as Record<string, unknown>)) {\r\n    cloned[key] = deepClone((value as Record<string, unknown>)[key])\r\n  }\r\n  return cloned as T\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Date / Duration formatting\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Format a Date or timestamp to locale string. */\r\nexport function formatDate(\r\n  input: Date | number | string,\r\n  options?: Intl.DateTimeFormatOptions\r\n): string {\r\n  const d = input instanceof Date ? input : new Date(input)\r\n  if (Number.isNaN(d.getTime())) return String(input)\r\n  return d.toLocaleString('zh-CN', {\r\n    year: 'numeric',\r\n    month: '2-digit',\r\n    day: '2-digit',\r\n    hour: '2-digit',\r\n    minute: '2-digit',\r\n    second: '2-digit',\r\n    ...options,\r\n  })\r\n}\r\n\r\n/** Format a duration in milliseconds to human-readable string. */\r\nexport function formatDuration(ms: number): string {\r\n  if (ms < 0) ms = 0\r\n  const seconds = Math.floor(ms / 1000)\r\n  const minutes = Math.floor(seconds / 60)\r\n  const hours = Math.floor(minutes / 60)\r\n\r\n  if (hours > 0) {\r\n    return `${hours}h ${minutes % 60}m ${seconds % 60}s`\r\n  }\r\n  if (minutes > 0) {\r\n    return `${minutes}m ${seconds % 60}s`\r\n  }\r\n  if (seconds > 0) {\r\n    return `${seconds}s`\r\n  }\r\n  return `${ms}ms`\r\n}\r\n","/**\r\n * SSE Client for AI Assistant Core\r\n *\r\n * Uses fetch + ReadableStream (not EventSource) to support:\r\n * - POST requests with custom headers\r\n * - AbortController cancellation\r\n * - Custom event parsing and heartbeat handling\r\n * - Sequence-based ack / resume protocol\r\n * - Exponential backoff reconnection\r\n */\r\n\r\nimport { createError } from '../errors'\r\nimport { clamp } from '../utils'\r\n\r\n// ---------------------------------------------------------------------------\r\n// Types\r\n// ---------------------------------------------------------------------------\r\n\r\nexport type SseConnectionStatus =\r\n  | 'idle'\r\n  | 'connecting'\r\n  | 'streaming'\r\n  | 'reconnecting'\r\n  | 'closed'\r\n  | 'error'\r\n\r\nexport interface SseClientOptions {\r\n  /** Target URL */\r\n  url: string\r\n  /** POST body */\r\n  body: unknown\r\n  /** Request headers */\r\n  headers: Record<string, string>\r\n  /** Abort signal for cancellation */\r\n  signal?: AbortSignal\r\n  /** Called for every parsed stream event */\r\n  onEvent?: (event: unknown) => void\r\n  /** Called on unrecoverable errors */\r\n  onError?: (error: Error) => void\r\n  /** Called when connection status changes */\r\n  onStatusChange?: (status: SseConnectionStatus) => void\r\n  /** Heartbeat timeout in ms (default 15000) */\r\n  heartbeatMs?: number\r\n  /** Request timeout in ms (default 180000) */\r\n  timeoutMs?: number\r\n  /** Reconnect config */\r\n  reconnect?: {\r\n    max: number\r\n    baseMs: number\r\n    maxMs?: number\r\n    resetOnSuccessMs?: number\r\n  }\r\n  /** Last acknowledged sequence number (for resume) */\r\n  lastSeq?: number\r\n  /**\r\n   * Resume hook, consulted ONLY when re-establishing a dropped stream (i.e. on a\r\n   * reconnect attempt, never the initial connect). Returns the additive body\r\n   * fields that let the backend replay from where the client left off —\r\n   * typically `{ conversationId, messageId, lastSeq }`. These are merged over the\r\n   * base body so the same `/chat/stream` endpoint serves both fresh sends and\r\n   * resumes (the 14-endpoint contract stays frozen). Any `lastSeq` returned here\r\n   * takes precedence over the client's internally tracked seq.\r\n   */\r\n  resume?: () => Record<string, unknown> | undefined\r\n}\r\ninterface ReconnectState {\r\n  attempt: number\r\n  timer: ReturnType<typeof setTimeout> | null\r\n}\r\n\r\nfunction normalizeSeq(value: unknown): number | null {\r\n  if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) {\r\n    return value\r\n  }\r\n  if (typeof value === 'string' && value.trim() !== '') {\r\n    const parsed = Number(value)\r\n    return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : null\r\n  }\r\n  return null\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// SseClient\r\n// ---------------------------------------------------------------------------\r\n\r\nexport class SseClient {\r\n  private reader: ReadableStreamDefaultReader<Uint8Array> | null = null\r\n  private abortCtrl: AbortController | null = null\r\n  private heartbeatTimer: ReturnType<typeof setTimeout> | null = null\r\n  private timeoutTimer: ReturnType<typeof setTimeout> | null = null\r\n  private reconnect: ReconnectState = { attempt: 0, timer: null }\r\n  private lastSeq = 0\r\n  private buffer = ''\r\n  private status: SseConnectionStatus = 'idle'\r\n  private options: SseClientOptions | null = null\r\n  private destroyed = false\r\n\r\n  /** Current connection status */\r\n  get connectionStatus(): SseConnectionStatus {\r\n    return this.status\r\n  }\r\n\r\n  /** Current reconnect attempt count */\r\n  get reconnectAttempt(): number {\r\n    return this.reconnect.attempt\r\n  }\r\n\r\n  /** Last acknowledged sequence number */\r\n  get currentSeq(): number {\r\n    return this.lastSeq\r\n  }\r\n\r\n  // -------------------------------------------------------------------------\r\n  // Lifecycle\r\n  // -------------------------------------------------------------------------\r\n\r\n  async start(options: SseClientOptions): Promise<void> {\r\n    if (this.destroyed) {\r\n      throw createError('UNKNOWN', 'SseClient has been destroyed', false)\r\n    }\r\n\r\n    this.options = options\r\n    this.lastSeq = options.lastSeq ?? 0\r\n    this._setStatus('connecting')\r\n    await this._connect()\r\n  }\r\n\r\n  /** Abort the current connection (does not destroy). */\r\n  abort(): void {\r\n    this._clearTimers()\r\n    this._cancelReader()\r\n    this._setStatus('closed')\r\n  }\r\n\r\n  /** Permanently destroy — no further connections allowed. */\r\n  destroy(): void {\r\n    this.destroyed = true\r\n    this.abort()\r\n    this._clearReconnectTimer()\r\n  }\r\n\r\n  // -------------------------------------------------------------------------\r\n  // Connection\r\n  // -------------------------------------------------------------------------\r\n\r\n  private async _connect(): Promise<void> {\r\n    const opts = this.options\r\n    if (!opts || this.destroyed) return\r\n\r\n    this._clearReconnectTimer()\r\n\r\n    // Build abort controller (merge external signal)\r\n    this.abortCtrl = new AbortController()\r\n    if (opts.signal) {\r\n      const onAbort = () => this.abortCtrl?.abort()\r\n      if (opts.signal.aborted) {\r\n        onAbort()\r\n        return\r\n      }\r\n      opts.signal.addEventListener('abort', onAbort, { once: true })\r\n    }\r\n\r\n    // Timeout guard\r\n    const timeoutMs = opts.timeoutMs ?? 180000\r\n    this.timeoutTimer = setTimeout(() => {\r\n      this._handleError(createError('TIMEOUT', `Request timed out after ${timeoutMs}ms`, true))\r\n    }, timeoutMs)\r\n\r\n    // `reconnect.attempt` is incremented before a reconnect is scheduled, so a\r\n    // value > 0 here means this `_connect` is re-establishing a dropped stream.\r\n    const isReconnect = this.reconnect.attempt > 0\r\n    // Additive resume fields (conversationId / messageId / authoritative lastSeq)\r\n    // are sent ONLY on reconnect so a fresh send's body is untouched.\r\n    const resumeFields = isReconnect ? (opts.resume?.() ?? {}) : {}\r\n    const resumeSeq = normalizeSeq(resumeFields.lastSeq) ?? this.lastSeq\r\n\r\n    try {\r\n      const res = await fetch(opts.url, {\r\n        method: 'POST',\r\n        headers: {\r\n          'Content-Type': 'application/json',\r\n          Accept: 'text/event-stream',\r\n          ...opts.headers,\r\n        },\r\n        body: JSON.stringify({\r\n          ...(typeof opts.body === 'object' && opts.body !== null ? opts.body : {}),\r\n          ...resumeFields,\r\n          lastSeq: resumeSeq,\r\n        }),\r\n        signal: this.abortCtrl.signal,\r\n      })\r\n\r\n      if (!res.ok) {\r\n        const status = res.status\r\n        if (status === 401 || status === 403) {\r\n          throw createError('AUTH', `Authentication failed (${status})`, false)\r\n        }\r\n        if (status === 429) {\r\n          throw createError('RATE_LIMIT', 'Rate limit exceeded', true)\r\n        }\r\n        throw createError('NETWORK', `HTTP ${status}: ${res.statusText}`, status >= 500)\r\n      }\r\n\r\n      if (!res.body) {\r\n        throw createError('NETWORK', 'Response body is empty', true)\r\n      }\r\n\r\n      this._setStatus('streaming')\r\n      this._resetReconnect()\r\n      this._startHeartbeat(opts.heartbeatMs ?? 15000)\r\n\r\n      this.reader = res.body.getReader()\r\n      const decoder = new TextDecoder()\r\n\r\n      while (true) {\r\n        const { done, value } = await this.reader.read()\r\n        if (done) break\r\n        this._processChunk(decoder.decode(value, { stream: true }))\r\n      }\r\n\r\n      // Stream ended gracefully\r\n      this._setStatus('closed')\r\n    } catch (err) {\r\n      if (this.destroyed) return\r\n\r\n      if (err instanceof Error && err.name === 'AbortError') {\r\n        this._setStatus('closed')\r\n        return\r\n      }\r\n\r\n      this._handleError(err instanceof Error ? err : new Error(String(err)))\r\n    } finally {\r\n      this._clearTimers()\r\n      this._cancelReader()\r\n    }\r\n  }\r\n\r\n  // -------------------------------------------------------------------------\r\n  // Stream parsing\r\n  // -------------------------------------------------------------------------\r\n\r\n  private _processChunk(chunk: string): void {\r\n    this.buffer += chunk\r\n    const lines = this.buffer.split('\\n')\r\n    // Keep the last partial line in the buffer\r\n    this.buffer = lines.pop() ?? ''\r\n\r\n    for (const line of lines) {\r\n      this._processLine(line)\r\n    }\r\n  }\r\n\r\n  private _processLine(line: string): void {\r\n    const trimmed = line.trim()\r\n\r\n    // Empty line — event boundary (SSE spec)\r\n    if (!trimmed) return\r\n\r\n    // Heartbeat / comment line (starts with ':')\r\n    if (trimmed.startsWith(':')) {\r\n      this._handleHeartbeat()\r\n      return\r\n    }\r\n\r\n    // Data line (starts with 'data:')\r\n    if (trimmed.startsWith('data:')) {\r\n      const payload = trimmed.slice(5).trim()\r\n      if (!payload) return\r\n      this._parseEvent(payload)\r\n      return\r\n    }\r\n\r\n    // Ignore other SSE fields (event:, id:, retry:) for simplicity\r\n  }\r\n\r\n  private _parseEvent(payload: string): void {\r\n    try {\r\n      const event = JSON.parse(payload) as Record<string, unknown>\r\n\r\n      // Sequence tracking\r\n      const seq = normalizeSeq(event.seq)\r\n      if (seq !== null) {\r\n        this.lastSeq = seq\r\n        event.seq = seq\r\n      }\r\n\r\n      // Heartbeat event\r\n      if (event.type === 'heartbeat') {\r\n        this._handleHeartbeat()\r\n        return\r\n      }\r\n\r\n      this.options?.onEvent?.(event)\r\n    } catch (err) {\r\n      this.options?.onError?.(\r\n        createError('PARSE', `Failed to parse SSE payload: ${payload.slice(0, 200)}`, false, err)\r\n      )\r\n    }\r\n  }\r\n\r\n  // -------------------------------------------------------------------------\r\n  // Heartbeat\r\n  // -------------------------------------------------------------------------\r\n\r\n  private _startHeartbeat(ms: number): void {\r\n    this._clearHeartbeat()\r\n    this.heartbeatTimer = setTimeout(() => {\r\n      this._handleError(createError('TIMEOUT', 'Heartbeat timeout — no data received', true))\r\n    }, ms * 2) // allow 2x interval before treating as timeout\r\n  }\r\n\r\n  private _handleHeartbeat(): void {\r\n    this._startHeartbeat(this.options?.heartbeatMs ?? 15000)\r\n    this.options?.onEvent?.({ type: 'heartbeat', ts: Date.now() })\r\n  }\r\n\r\n  // -------------------------------------------------------------------------\r\n  // Error & Reconnect\r\n  // -------------------------------------------------------------------------\r\n\r\n  private _handleError(error: Error): void {\r\n    this._setStatus('error')\r\n    this.options?.onError?.(error)\r\n\r\n    const cfg = this.options?.reconnect\r\n    if (!cfg) return\r\n\r\n    if (this.reconnect.attempt >= cfg.max) {\r\n      this._setStatus('error')\r\n      this.options?.onError?.(\r\n        createError('NETWORK', `Max reconnect attempts (${cfg.max}) exceeded`, false)\r\n      )\r\n      return\r\n    }\r\n\r\n    this._scheduleReconnect(cfg)\r\n  }\r\n\r\n  private _scheduleReconnect(cfg: NonNullable<SseClientOptions['reconnect']>): void {\r\n    this._setStatus('reconnecting')\r\n\r\n    const base = cfg.baseMs ?? 1000\r\n    const maxMs = cfg.maxMs ?? 30000\r\n    // Exponential backoff: 1s, 2s, 4s, 8s, 16s, 30s, 30s, 30s...\r\n    const delayMs = clamp(base * 2 ** this.reconnect.attempt, base, maxMs)\r\n    // Add jitter (±25%) to prevent thundering herd\r\n    const jitter = delayMs * 0.25 * (Math.random() * 2 - 1)\r\n    const finalDelay = Math.max(0, Math.floor(delayMs + jitter))\r\n\r\n    this.reconnect.attempt++\r\n    this.reconnect.timer = setTimeout(() => {\r\n      if (!this.destroyed) {\r\n        this._connect()\r\n      }\r\n    }, finalDelay)\r\n  }\r\n\r\n  private _resetReconnect(): void {\r\n    this.reconnect.attempt = 0\r\n    this._clearReconnectTimer()\r\n  }\r\n\r\n  // -------------------------------------------------------------------------\r\n  // Helpers\r\n  // -------------------------------------------------------------------------\r\n\r\n  private _setStatus(next: SseConnectionStatus): void {\r\n    if (this.status === next) return\r\n    this.status = next\r\n    this.options?.onStatusChange?.(next)\r\n  }\r\n\r\n  private _cancelReader(): void {\r\n    if (this.reader) {\r\n      this.reader.cancel().catch(() => {\r\n        /* ignore */\r\n      })\r\n      this.reader = null\r\n    }\r\n    if (this.abortCtrl) {\r\n      try {\r\n        this.abortCtrl.abort()\r\n      } catch {\r\n        /* ignore */\r\n      }\r\n      this.abortCtrl = null\r\n    }\r\n  }\r\n\r\n  private _clearTimers(): void {\r\n    if (this.timeoutTimer) {\r\n      clearTimeout(this.timeoutTimer)\r\n      this.timeoutTimer = null\r\n    }\r\n    this._clearHeartbeat()\r\n  }\r\n\r\n  private _clearHeartbeat(): void {\r\n    if (this.heartbeatTimer) {\r\n      clearTimeout(this.heartbeatTimer)\r\n      this.heartbeatTimer = null\r\n    }\r\n  }\r\n\r\n  private _clearReconnectTimer(): void {\r\n    if (this.reconnect.timer) {\r\n      clearTimeout(this.reconnect.timer)\r\n      this.reconnect.timer = null\r\n    }\r\n  }\r\n}\r\n"],"names":["_a"],"mappings":"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"}