import { r as __exportAll } from "./chunk-BSw8zbkd.mjs";
import { C as boolean, D as object, E as number, O as string, S as array, T as literal, _ as generateId, a as BaseDocumentHeaderSchema, c as baseCreateDocument, f as createAction, g as defaultBaseState, h as createState, j as datetime, l as baseLoadFromInput, m as createReducer, o as BaseDocumentStateSchema, s as baseActions, u as baseSaveToFileHandle, v as isDocumentAction, w as lazy, x as any } from "./dist-JCXjvFc8.mjs";
//#region document-models/voice/v1/gen/document-model.ts
const documentModel = {
	id: "powerchat/voice",
	name: "Voice",
	author: {
		name: "Powerhouse",
		website: "https://www.powerhouse.inc/"
	},
	extension: "pvc",
	description: "Voice channel state for PowerChat. Tracks active participants, mute/deafen states, and peer signaling.",
	specifications: [{
		state: {
			local: {
				schema: "",
				examples: [],
				initialValue: ""
			},
			global: {
				schema: "type VoiceParticipant {\n  id: OID!\n  name: String!\n  avatar: String\n  joinedAt: DateTime!\n  isMuted: Boolean!\n  isDeafened: Boolean!\n}\n\ntype VoiceState {\n  channelId: PHID\n  activeParticipants: [VoiceParticipant!]!\n  maxParticipants: Int\n}",
				examples: [],
				initialValue: "{\"channelId\": null, \"activeParticipants\": [], \"maxParticipants\": null}"
			}
		},
		modules: [{
			id: "mod-config",
			name: "config",
			description: "Voice channel configuration",
			operations: [{
				id: "op-set-channel-id",
				name: "SET_CHANNEL_ID",
				description: "Links this voice room to a channel",
				schema: "input SetChannelIdInput {\n  channelId: PHID!\n}",
				template: "Links this voice room to a channel",
				reducer: "state.channelId = action.input.channelId;",
				errors: [],
				examples: [],
				scope: "global"
			}, {
				id: "op-set-max-participants",
				name: "SET_MAX_PARTICIPANTS",
				description: "Sets the maximum number of participants",
				schema: "input SetMaxParticipantsInput {\n  maxParticipants: Int\n}",
				template: "Sets the maximum number of participants",
				reducer: "state.maxParticipants = action.input.maxParticipants || null;",
				errors: [],
				examples: [],
				scope: "global"
			}]
		}, {
			id: "mod-voice",
			name: "voice",
			description: "Voice channel participant operations",
			operations: [
				{
					id: "op-join-voice",
					name: "JOIN_VOICE",
					description: "Adds a participant to the voice channel",
					schema: "input JoinVoiceInput {\n  id: OID!\n  name: String!\n  avatar: String\n  joinedAt: DateTime!\n}",
					template: "Adds a participant to the voice channel",
					reducer: "if (state.maxParticipants && state.activeParticipants.length >= state.maxParticipants) {\n  throw new VoiceChannelFullError('Voice channel is full');\n}\nconst existing = state.activeParticipants.find(p => p.id === action.input.id);\nif (existing) {\n  throw new AlreadyInVoiceError('Already in voice channel');\n}\nstate.activeParticipants.push({\n  id: action.input.id,\n  name: action.input.name,\n  avatar: action.input.avatar || null,\n  joinedAt: action.input.joinedAt,\n  isMuted: false,\n  isDeafened: false,\n});",
					errors: [{
						id: "err-full",
						name: "VoiceChannelFullError",
						code: "VOICE_CHANNEL_FULL",
						description: "Voice channel is at max capacity",
						template: ""
					}, {
						id: "err-already-in",
						name: "AlreadyInVoiceError",
						code: "ALREADY_IN_VOICE",
						description: "Already in voice channel",
						template: ""
					}],
					examples: [],
					scope: "global"
				},
				{
					id: "op-leave-voice",
					name: "LEAVE_VOICE",
					description: "Removes a participant from the voice channel",
					schema: "input LeaveVoiceInput {\n  participantId: OID!\n}",
					template: "Removes a participant from the voice channel",
					reducer: "const index = state.activeParticipants.findIndex(p => p.id === action.input.participantId);\nif (index === -1) {\n  throw new NotInVoiceError('Not in voice channel');\n}\nstate.activeParticipants.splice(index, 1);",
					errors: [{
						id: "err-not-in-leave",
						name: "NotInVoiceError",
						code: "NOT_IN_VOICE",
						description: "Not in voice channel",
						template: ""
					}],
					examples: [],
					scope: "global"
				},
				{
					id: "op-mute",
					name: "MUTE",
					description: "Mutes a participant",
					schema: "input MuteInput {\n  participantId: OID!\n}",
					template: "Mutes a participant",
					reducer: "const participant = state.activeParticipants.find(p => p.id === action.input.participantId);\nif (!participant) {\n  throw new NotInVoiceError('Not in voice channel');\n}\nparticipant.isMuted = true;",
					errors: [{
						id: "err-not-in-mute",
						name: "NotInVoiceError",
						code: "NOT_IN_VOICE",
						description: "Not in voice channel",
						template: ""
					}],
					examples: [],
					scope: "global"
				},
				{
					id: "op-unmute",
					name: "UNMUTE",
					description: "Unmutes a participant",
					schema: "input UnmuteInput {\n  participantId: OID!\n}",
					template: "Unmutes a participant",
					reducer: "const participant = state.activeParticipants.find(p => p.id === action.input.participantId);\nif (!participant) {\n  throw new NotInVoiceError('Not in voice channel');\n}\nparticipant.isMuted = false;",
					errors: [{
						id: "err-not-in-unmute",
						name: "NotInVoiceError",
						code: "NOT_IN_VOICE",
						description: "Not in voice channel",
						template: ""
					}],
					examples: [],
					scope: "global"
				},
				{
					id: "op-deafen",
					name: "DEAFEN",
					description: "Deafens a participant",
					schema: "input DeafenInput {\n  participantId: OID!\n}",
					template: "Deafens a participant",
					reducer: "const participant = state.activeParticipants.find(p => p.id === action.input.participantId);\nif (!participant) {\n  throw new NotInVoiceError('Not in voice channel');\n}\nparticipant.isDeafened = true;\nparticipant.isMuted = true;",
					errors: [{
						id: "err-not-in-deafen",
						name: "NotInVoiceError",
						code: "NOT_IN_VOICE",
						description: "Not in voice channel",
						template: ""
					}],
					examples: [],
					scope: "global"
				},
				{
					id: "op-undeafen",
					name: "UNDEAFEN",
					description: "Undeafens a participant",
					schema: "input UndeafenInput {\n  participantId: OID!\n}",
					template: "Undeafens a participant",
					reducer: "const participant = state.activeParticipants.find(p => p.id === action.input.participantId);\nif (!participant) {\n  throw new NotInVoiceError('Not in voice channel');\n}\nparticipant.isDeafened = false;",
					errors: [{
						id: "err-not-in-undeafen",
						name: "NotInVoiceError",
						code: "NOT_IN_VOICE",
						description: "Not in voice channel",
						template: ""
					}],
					examples: [],
					scope: "global"
				}
			]
		}],
		version: 1,
		changeLog: []
	}]
};
//#endregion
//#region document-models/voice/v1/src/reducers/config.ts
const voiceConfigOperations = {
	setChannelIdOperation(state, action) {
		state.channelId = action.input.channelId;
	},
	setMaxParticipantsOperation(state, action) {
		state.maxParticipants = action.input.maxParticipants || null;
	}
};
//#endregion
//#region document-models/voice/v1/gen/voice/error.ts
var VoiceChannelFullError = class extends Error {
	errorCode = "VoiceChannelFullError";
	constructor(message = "VoiceChannelFullError") {
		super(message);
	}
};
var AlreadyInVoiceError = class extends Error {
	errorCode = "AlreadyInVoiceError";
	constructor(message = "AlreadyInVoiceError") {
		super(message);
	}
};
var NotInVoiceError = class extends Error {
	errorCode = "NotInVoiceError";
	constructor(message = "NotInVoiceError") {
		super(message);
	}
};
//#endregion
//#region document-models/voice/v1/src/reducers/voice.ts
const voiceVoiceOperations = {
	joinVoiceOperation(state, action) {
		if (state.maxParticipants && state.activeParticipants.length >= state.maxParticipants) throw new VoiceChannelFullError("Voice channel is full");
		if (state.activeParticipants.find((p) => p.id === action.input.id)) throw new AlreadyInVoiceError("Already in voice channel");
		state.activeParticipants.push({
			id: action.input.id,
			name: action.input.name,
			avatar: action.input.avatar || null,
			joinedAt: action.input.joinedAt,
			isMuted: false,
			isDeafened: false
		});
	},
	leaveVoiceOperation(state, action) {
		const index = state.activeParticipants.findIndex((p) => p.id === action.input.participantId);
		if (index === -1) throw new NotInVoiceError("Not in voice channel");
		state.activeParticipants.splice(index, 1);
	},
	muteOperation(state, action) {
		const participant = state.activeParticipants.find((p) => p.id === action.input.participantId);
		if (!participant) throw new NotInVoiceError("Not in voice channel");
		participant.isMuted = true;
	},
	unmuteOperation(state, action) {
		const participant = state.activeParticipants.find((p) => p.id === action.input.participantId);
		if (!participant) throw new NotInVoiceError("Not in voice channel");
		participant.isMuted = false;
	},
	deafenOperation(state, action) {
		const participant = state.activeParticipants.find((p) => p.id === action.input.participantId);
		if (!participant) throw new NotInVoiceError("Not in voice channel");
		participant.isDeafened = true;
		participant.isMuted = true;
	},
	undeafenOperation(state, action) {
		const participant = state.activeParticipants.find((p) => p.id === action.input.participantId);
		if (!participant) throw new NotInVoiceError("Not in voice channel");
		participant.isDeafened = false;
	}
};
//#endregion
//#region document-models/voice/v1/gen/schema/zod.ts
const isDefinedNonNullAny = (v) => v !== void 0 && v !== null;
const definedNonNullAnySchema = any().refine((v) => isDefinedNonNullAny(v));
function DeafenInputSchema() {
	return object({ participantId: string() });
}
function JoinVoiceInputSchema() {
	return object({
		avatar: string().nullish(),
		id: string(),
		joinedAt: datetime(),
		name: string()
	});
}
function LeaveVoiceInputSchema() {
	return object({ participantId: string() });
}
function MuteInputSchema() {
	return object({ participantId: string() });
}
function SetChannelIdInputSchema() {
	return object({ channelId: string() });
}
function SetMaxParticipantsInputSchema() {
	return object({ maxParticipants: number().nullish() });
}
function UndeafenInputSchema() {
	return object({ participantId: string() });
}
function UnmuteInputSchema() {
	return object({ participantId: string() });
}
function VoiceParticipantSchema() {
	return object({
		__typename: literal("VoiceParticipant").optional(),
		avatar: string().nullish(),
		id: string(),
		isDeafened: boolean(),
		isMuted: boolean(),
		joinedAt: datetime(),
		name: string()
	});
}
function VoiceStateSchema() {
	return object({
		__typename: literal("VoiceState").optional(),
		activeParticipants: array(lazy(() => VoiceParticipantSchema())),
		channelId: string().nullish(),
		maxParticipants: number().nullish()
	});
}
//#endregion
//#region document-models/voice/v1/gen/reducer.ts
const stateReducer = (state, action, dispatch) => {
	if (isDocumentAction(action)) return state;
	switch (action.type) {
		case "SET_CHANNEL_ID":
			SetChannelIdInputSchema().parse(action.input);
			voiceConfigOperations.setChannelIdOperation(state[action.scope], action, dispatch);
			break;
		case "SET_MAX_PARTICIPANTS":
			SetMaxParticipantsInputSchema().parse(action.input);
			voiceConfigOperations.setMaxParticipantsOperation(state[action.scope], action, dispatch);
			break;
		case "JOIN_VOICE":
			JoinVoiceInputSchema().parse(action.input);
			voiceVoiceOperations.joinVoiceOperation(state[action.scope], action, dispatch);
			break;
		case "LEAVE_VOICE":
			LeaveVoiceInputSchema().parse(action.input);
			voiceVoiceOperations.leaveVoiceOperation(state[action.scope], action, dispatch);
			break;
		case "MUTE":
			MuteInputSchema().parse(action.input);
			voiceVoiceOperations.muteOperation(state[action.scope], action, dispatch);
			break;
		case "UNMUTE":
			UnmuteInputSchema().parse(action.input);
			voiceVoiceOperations.unmuteOperation(state[action.scope], action, dispatch);
			break;
		case "DEAFEN":
			DeafenInputSchema().parse(action.input);
			voiceVoiceOperations.deafenOperation(state[action.scope], action, dispatch);
			break;
		case "UNDEAFEN":
			UndeafenInputSchema().parse(action.input);
			voiceVoiceOperations.undeafenOperation(state[action.scope], action, dispatch);
			break;
		default: return state;
	}
};
const reducer = createReducer(stateReducer);
//#endregion
//#region document-models/voice/v1/gen/config/creators.ts
var creators_exports$1 = /* @__PURE__ */ __exportAll({
	setChannelId: () => setChannelId,
	setMaxParticipants: () => setMaxParticipants
});
const setChannelId = (input) => createAction("SET_CHANNEL_ID", { ...input }, void 0, SetChannelIdInputSchema, "global");
const setMaxParticipants = (input) => createAction("SET_MAX_PARTICIPANTS", { ...input }, void 0, SetMaxParticipantsInputSchema, "global");
//#endregion
//#region document-models/voice/v1/gen/voice/creators.ts
var creators_exports = /* @__PURE__ */ __exportAll({
	deafen: () => deafen,
	joinVoice: () => joinVoice,
	leaveVoice: () => leaveVoice,
	mute: () => mute,
	undeafen: () => undeafen,
	unmute: () => unmute
});
const joinVoice = (input) => createAction("JOIN_VOICE", { ...input }, void 0, JoinVoiceInputSchema, "global");
const leaveVoice = (input) => createAction("LEAVE_VOICE", { ...input }, void 0, LeaveVoiceInputSchema, "global");
const mute = (input) => createAction("MUTE", { ...input }, void 0, MuteInputSchema, "global");
const unmute = (input) => createAction("UNMUTE", { ...input }, void 0, UnmuteInputSchema, "global");
const deafen = (input) => createAction("DEAFEN", { ...input }, void 0, DeafenInputSchema, "global");
const undeafen = (input) => createAction("UNDEAFEN", { ...input }, void 0, UndeafenInputSchema, "global");
//#endregion
//#region document-models/voice/v1/actions.ts
/** Actions for the Voice document model */
const actions = {
	...baseActions,
	...creators_exports$1,
	...creators_exports
};
//#endregion
//#region document-models/voice/v1/gen/document-type.ts
const voiceDocumentType = "powerchat/voice";
//#endregion
//#region document-models/voice/v1/gen/document-schema.ts
/** Schema for validating the header object of a Voice document */
const VoiceDocumentHeaderSchema = BaseDocumentHeaderSchema.extend({ documentType: literal(voiceDocumentType) });
/** Schema for validating the state object of a Voice document */
const VoicePHStateSchema = BaseDocumentStateSchema.extend({ global: VoiceStateSchema() });
const VoiceDocumentSchema = object({
	header: VoiceDocumentHeaderSchema,
	state: VoicePHStateSchema,
	initialState: VoicePHStateSchema
});
/** Simple helper function to check if a state object is a Voice document state object */
function isVoiceState(state) {
	return VoicePHStateSchema.safeParse(state).success;
}
/** Simple helper function to assert that a document state object is a Voice document state object */
function assertIsVoiceState(state) {
	VoicePHStateSchema.parse(state);
}
/** Simple helper function to check if a document is a Voice document */
function isVoiceDocument(document) {
	return VoiceDocumentSchema.safeParse(document).success;
}
/** Simple helper function to assert that a document is a Voice document */
function assertIsVoiceDocument(document) {
	VoiceDocumentSchema.parse(document);
}
//#endregion
//#region document-models/voice/v1/gen/utils.ts
const initialGlobalState = {
	channelId: null,
	activeParticipants: [],
	maxParticipants: null
};
const initialLocalState = {};
const utils$1 = {
	fileExtension: "pvc",
	createState(state) {
		return {
			...defaultBaseState(),
			global: {
				...initialGlobalState,
				...state?.global
			},
			local: {
				...initialLocalState,
				...state?.local
			}
		};
	},
	createDocument(state) {
		const document = baseCreateDocument(utils$1.createState, state);
		document.header.documentType = voiceDocumentType;
		document.header.id = generateId();
		return document;
	},
	saveToFileHandle(document, input) {
		return baseSaveToFileHandle(document, input);
	},
	loadFromInput(input) {
		return baseLoadFromInput(input, reducer);
	},
	isStateOfType(state) {
		return isVoiceState(state);
	},
	assertIsStateOfType(state) {
		return assertIsVoiceState(state);
	},
	isDocumentOfType(document) {
		return isVoiceDocument(document);
	},
	assertIsDocumentOfType(document) {
		return assertIsVoiceDocument(document);
	}
};
//#endregion
//#region document-models/voice/v1/src/utils.ts
var utils_exports = /* @__PURE__ */ __exportAll({});
//#endregion
//#region document-models/voice/v1/utils.ts
/** Utils for the Voice document model */
const utils = {
	...utils$1,
	...utils_exports
};
//#endregion
//#region document-models/voice/v1/module.ts
/** Document model module for the Voice document type */
const Voice = {
	version: 1,
	reducer,
	actions,
	utils,
	documentModel: createState(defaultBaseState(), documentModel)
};
//#endregion
export { SetChannelIdInputSchema as A, setChannelId as C, JoinVoiceInputSchema as D, DeafenInputSchema as E, VoiceStateSchema as F, definedNonNullAnySchema as I, isDefinedNonNullAny as L, UndeafenInputSchema as M, UnmuteInputSchema as N, LeaveVoiceInputSchema as O, VoiceParticipantSchema as P, documentModel as R, creators_exports$1 as S, reducer as T, joinVoice as _, utils$1 as a, undeafen as b, VoicePHStateSchema as c, isVoiceDocument as d, isVoiceState as f, deafen as g, creators_exports as h, initialLocalState as i, SetMaxParticipantsInputSchema as j, MuteInputSchema as k, assertIsVoiceDocument as l, actions as m, utils as n, VoiceDocumentHeaderSchema as o, voiceDocumentType as p, initialGlobalState as r, VoiceDocumentSchema as s, Voice as t, assertIsVoiceState as u, leaveVoice as v, setMaxParticipants as w, unmute as x, mute as y };

//# sourceMappingURL=module-CTq-iEnt.mjs.map