import { MediaAssembler } from "../../client/stream/media.js";
import { isRootNamespace, namespaceKey } from "../namespace.js";
import { openProjectionSubscription } from "./runtime.js";
//#region src/stream/projections/media.ts
function createMediaProjection(kind, namespace, buildAssembler, options) {
	const ns = [...namespace];
	return {
		key: `${kind}|${namespaceKey(ns)}`,
		namespace: ns,
		initial: [],
		open({ thread, store, rootBus }) {
			const assembler = buildAssembler((media) => {
				store.setValue([...store.getSnapshot(), media]);
			}, options);
			if (isRootNamespace(ns) && rootBus.channels.includes("messages")) {
				const unsubscribe = rootBus.subscribe((event) => {
					if (event.method !== "messages") return;
					if (!isRootNamespace(event.params.namespace)) return;
					assembler.consume(event);
				});
				return { async dispose() {
					unsubscribe();
					for (const media of store.getSnapshot()) try {
						media.revoke();
					} catch {}
					assembler.close();
				} };
			}
			const runtime = openProjectionSubscription({
				thread,
				channels: ["messages"],
				namespace: ns,
				onEvent(event) {
					if (event.method !== "messages") return;
					assembler.consume(event);
				},
				onFinally() {
					assembler.close();
				}
			});
			return { async dispose() {
				for (const media of store.getSnapshot()) try {
					media.revoke();
				} catch {}
				assembler.close();
				await runtime.dispose();
			} };
		}
	};
}
function audioProjection(namespace, options) {
	return createMediaProjection("audio", namespace, (push, opts) => new MediaAssembler({
		fetch: opts?.fetch,
		onAudio: (m) => push(m)
	}), options);
}
function imagesProjection(namespace, options) {
	return createMediaProjection("images", namespace, (push, opts) => new MediaAssembler({
		fetch: opts?.fetch,
		onImage: (m) => push(m)
	}), options);
}
function videoProjection(namespace, options) {
	return createMediaProjection("video", namespace, (push, opts) => new MediaAssembler({
		fetch: opts?.fetch,
		onVideo: (m) => push(m)
	}), options);
}
function filesProjection(namespace, options) {
	return createMediaProjection("files", namespace, (push, opts) => new MediaAssembler({
		fetch: opts?.fetch,
		onFile: (m) => push(m)
	}), options);
}
//#endregion
export { audioProjection, filesProjection, imagesProjection, videoProjection };

//# sourceMappingURL=media.js.map