idle-timer.js 1.48 KB
/**
 * IdleTimer - 通用空闲超时计时器
 *
 * 用于检测「长时间无活动」场景:
 * - ACP/Claude Stream 流式输出的空闲检测
 * - 任何需要 touch() 重置的看门狗场景
 *
 * 使用方式:
 *   const timer = new IdleTimer(timeoutMs, onTimeout);
 *   timer.start();
 *   // 每次有活动时调用 touch()
 *   timer.touch();
 *   // 结束时清理
 *   timer.cancel();
 */

class IdleTimer {
  /**
   * @param {number} timeoutMs - 空闲超时时间(毫秒)
   * @param {Function} onTimeout - 超时回调
   * @param {Object} [options]
   * @param {string} [options.label] - 标签(用于日志/错误消息)
   */
  constructor(timeoutMs, onTimeout, options = {}) {
    this.timeoutMs = timeoutMs;
    this.onTimeout = onTimeout;
    this.label = options.label || 'idle-timer';
    this._timer = null;
    this._fired = false;
  }

  /** 启动计时器 */
  start() {
    this._reset();
    return this;
  }

  /** 重置计时器(收到活动时调用) */
  touch() {
    if (!this._fired) {
      this._reset();
    }
  }

  /** 取消计时器 */
  cancel() {
    if (this._timer) {
      clearTimeout(this._timer);
      this._timer = null;
    }
  }

  /** 计时器是否已触发 */
  get fired() {
    return this._fired;
  }

  /** @private */
  _reset() {
    this.cancel();
    this._timer = setTimeout(() => {
      this._fired = true;
      this._timer = null;
      this.onTimeout();
    }, this.timeoutMs);
  }
}

module.exports = { IdleTimer };