//#region src/infra/debounce.ts
function createInboundDebouncer(options) {
	const { debounceMs: defaultDebounceMs, buildKey, shouldDebounce, resolveDebounceMs, onFlush, onError } = options;
	const buffers = /* @__PURE__ */ new Map();
	function resolveMs(item) {
		const resolved = resolveDebounceMs?.(item);
		if (typeof resolved === "number" && Number.isFinite(resolved)) return Math.max(0, Math.trunc(resolved));
		return Math.max(0, Math.trunc(defaultDebounceMs));
	}
	async function flushBuffer(key, buffer) {
		buffers.delete(key);
		if (buffer.timeout) {
			clearTimeout(buffer.timeout);
			buffer.timeout = null;
		}
		if (buffer.items.length === 0) return;
		try {
			await onFlush(buffer.items);
		} catch (err) {
			onError?.(err, buffer.items);
		}
	}
	async function flushKey(key) {
		const buffer = buffers.get(key);
		if (!buffer) return;
		await flushBuffer(key, buffer);
	}
	function scheduleFlush(key, buffer) {
		if (buffer.timeout) clearTimeout(buffer.timeout);
		buffer.timeout = setTimeout(() => {
			flushBuffer(key, buffer);
		}, buffer.debounceMs);
		buffer.timeout.unref?.();
	}
	async function enqueue(item) {
		const key = buildKey(item);
		const debounceMs = resolveMs(item);
		if (!(debounceMs > 0 && (shouldDebounce?.(item) ?? true))) {
			if (key && buffers.has(key)) await flushKey(key);
			try {
				await onFlush([item]);
			} catch (err) {
				onError?.(err, [item]);
			}
			return;
		}
		if (!key) {
			try {
				await onFlush([item]);
			} catch (err) {
				onError?.(err, [item]);
			}
			return;
		}
		const existing = buffers.get(key);
		if (existing) {
			existing.items.push(item);
			existing.debounceMs = debounceMs;
			scheduleFlush(key, existing);
		} else {
			const buffer = {
				items: [item],
				timeout: null,
				debounceMs
			};
			buffers.set(key, buffer);
			scheduleFlush(key, buffer);
		}
	}
	async function flushAll() {
		const keys = Array.from(buffers.keys());
		await Promise.all(keys.map((key) => flushKey(key)));
	}
	function getBufferCount() {
		return buffers.size;
	}
	return {
		enqueue,
		flushKey,
		flushAll,
		getBufferCount
	};
}
function hasControlCommand(text) {
	return text.trim().startsWith("/");
}
//#endregion
export { createInboundDebouncer, hasControlCommand };

//# sourceMappingURL=debounce.js.map