/** * 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 };