import { channelProjection } from "./channel.js";
//#region src/stream/projections/channel-effect.ts
/**
* Acquire a side-effect subscription over one or more channels.
*
* @param registry - The stream's {@link ChannelRegistry}.
* @param channels - Channels to observe (e.g. `["lifecycle", "tools"]`).
* @param namespace - Resolved namespace (`[]` for the root).
* @param options - Callbacks plus projection (`bufferSize`/`replay`)
*   options.
* @returns A `dispose()` function that detaches the listener and
*   releases the ref-counted projection. Idempotent.
*/
function acquireChannelEffect(registry, channels, namespace, options) {
	const { onEvent, onError, ...projectionOptions } = options;
	const acquired = registry.acquire(channelProjection(channels, namespace, {
		replay: projectionOptions.replay ?? false,
		bufferSize: projectionOptions.bufferSize
	}));
	const { store } = acquired;
	const initial = store.getSnapshot();
	let lastDelivered = initial.length > 0 ? initial[initial.length - 1] : void 0;
	const deliver = () => {
		const snapshot = store.getSnapshot();
		let start = 0;
		if (lastDelivered !== void 0) {
			const index = snapshot.lastIndexOf(lastDelivered);
			start = index === -1 ? 0 : index + 1;
		}
		for (let i = start; i < snapshot.length; i += 1) {
			const event = snapshot[i];
			try {
				onEvent(event);
			} catch (error) {
				if (onError) onError(error);
			}
		}
		if (snapshot.length > 0) lastDelivered = snapshot[snapshot.length - 1];
	};
	const unsubscribe = store.subscribe(deliver);
	let released = false;
	return () => {
		if (released) return;
		released = true;
		unsubscribe();
		acquired.release();
	};
}
//#endregion
export { acquireChannelEffect };

//# sourceMappingURL=channel-effect.js.map