import { r as __exportAll } from "./chunk-D_gEzPfs.js";

//#region src/gateway/readiness.ts
var readiness_exports = /* @__PURE__ */ __exportAll({
	awaitReady: () => awaitReady,
	isReady: () => isReady,
	markReadyStep: () => markReadyStep,
	readinessSnapshot: () => readinessSnapshot
});
const state = {
	workspaceReady: false,
	companionsReady: false,
	startedAtMs: Date.now(),
	waiters: []
};
function markReadyStep(step) {
	if (step === "workspace") state.workspaceReady = true;
	if (step === "companions") state.companionsReady = true;
	if (step === "platform") state.companionsReady = true;
	if (isReady() && !state.readyAtMs) {
		state.readyAtMs = Date.now();
		const pending = state.waiters.splice(0);
		for (const w of pending) try {
			w();
		} catch {}
	}
}
function isReady() {
	return state.workspaceReady && state.companionsReady;
}
function readinessSnapshot() {
	return {
		ready: isReady(),
		workspaceReady: state.workspaceReady,
		companionsReady: state.companionsReady,
		bootedMs: state.readyAtMs ? state.readyAtMs - state.startedAtMs : null,
		uptimeMs: Date.now() - state.startedAtMs
	};
}
/**
* Resolve when the gateway is ready, or after `timeoutMs` (false in
* that case). Used by inbound RPC handlers to hold the first chat
* during the boot window — anything more than ~5s and we'd rather
* return a typed error than block the WS forever.
*/
function awaitReady(timeoutMs) {
	if (isReady()) return Promise.resolve(true);
	if (timeoutMs <= 0) return Promise.resolve(false);
	return new Promise((resolve) => {
		let settled = false;
		const onReady = () => {
			if (settled) return;
			settled = true;
			clearTimeout(timer);
			resolve(true);
		};
		const timer = setTimeout(() => {
			if (settled) return;
			settled = true;
			const idx = state.waiters.indexOf(onReady);
			if (idx >= 0) state.waiters.splice(idx, 1);
			resolve(false);
		}, timeoutMs);
		state.waiters.push(onReady);
	});
}

//#endregion
export { readiness_exports as i, isReady as n, markReadyStep as r, awaitReady as t };