import './src-DG3l2-J-.js';

//#region src/lib/server/brain/cache.ts
/** Maximum number of cache entries before oldest is evicted. */
var MAX_ENTRIES = 5;
/** Time-to-live in milliseconds. */
var TTL_MS = 3e4;
/** All five substrate names in canonical sort order. */
var ALL_SUBSTRATES_SORTED = [
	"agent-registry",
	"brain",
	"conduit",
	"nexus",
	"tasks"
];
var _store = /* @__PURE__ */ new Map();
var _insertionCounter = 0;
var _metrics = {
	hits: 0,
	misses: 0,
	evictions: 0
};
/**
* Derives a stable string cache key from the provided key parts.
*
* Substrate order is normalised (sorted) so callers passing substrates in
* different orders still hit the same cache slot.
*
* @param parts - Key components.
* @returns Stable string key.
*/
function buildCacheKey(parts) {
	const subs = !parts.substrates || parts.substrates.length === 0 ? ALL_SUBSTRATES_SORTED : [...parts.substrates].sort();
	return `${parts.projectId}|${subs.join(",")}|${parts.limit}`;
}
/**
* Attempts to retrieve a {@link BrainGraph} from the cache.
*
* Returns `null` on a cache miss or when the stored entry has expired.
* Expired entries are lazily removed on access.
*
* @param key - Serialised cache key from {@link buildCacheKey}.
* @returns Cached graph or `null`.
*/
function getCachedGraph(key) {
	const entry = _store.get(key);
	if (!entry) {
		_metrics.misses++;
		return null;
	}
	if (Date.now() > entry.expiresAt) {
		_store.delete(key);
		_metrics.misses++;
		return null;
	}
	_metrics.hits++;
	return entry.graph;
}
/**
* Stores a {@link BrainGraph} in the cache under the given key.
*
* When the store has reached {@link MAX_ENTRIES}, the entry with the lowest
* `insertedAt` counter (i.e. the oldest insert) is evicted first.
*
* @param key - Serialised cache key from {@link buildCacheKey}.
* @param graph - Graph payload to store.
*/
function setCachedGraph(key, graph) {
	if (!_store.has(key) && _store.size >= MAX_ENTRIES) {
		let oldestKey = null;
		let oldestInsert = Number.POSITIVE_INFINITY;
		for (const [k, v] of _store) if (v.insertedAt < oldestInsert) {
			oldestInsert = v.insertedAt;
			oldestKey = k;
		}
		if (oldestKey !== null) {
			_store.delete(oldestKey);
			_metrics.evictions++;
		}
	}
	_store.set(key, {
		graph,
		expiresAt: Date.now() + TTL_MS,
		insertedAt: _insertionCounter++
	});
}
/**
* Returns a snapshot of hit/miss/eviction counters.
*
* The `size` field reflects only non-expired entries at the moment of the call
* (expired entries that have not been lazily removed are excluded from the count
* for accuracy).
*
* @returns {@link CacheMetrics} snapshot.
*/
function getBrainCacheMetrics() {
	const now = Date.now();
	let liveSize = 0;
	for (const entry of _store.values()) if (now <= entry.expiresAt) liveSize++;
	return {
		hits: _metrics.hits,
		misses: _metrics.misses,
		evictions: _metrics.evictions,
		size: liveSize
	};
}
//#endregion
//#region src/lib/server/brain/metrics.ts
/**
* Server-side performance metrics for the Brain load path.
*
* Captures timing samples for each tier (0, 1, 2) of the progressive
* disclosure strategy, plus a rolling window of the last N durations.
* Metrics are intentionally in-process and non-persistent — they reset
* on server restart and are only useful during a running dev/prod session.
*
* Exposed at `/api/health` via {@link getBrainLoadMetrics} so the operator
* can verify p95 numbers without attaching a profiler.
*
* @module
* @task T990
*/
/** Maximum number of timing samples retained per tier. */
var WINDOW_SIZE = 50;
var _tiers = {
	0: {
		samples: [],
		totalRequests: 0
	},
	1: {
		samples: [],
		totalRequests: 0
	},
	2: {
		samples: [],
		totalRequests: 0
	}
};
/**
* Records a load duration for the given tier.
*
* Rolls off the oldest sample when the window is full.
* Logs to `console.info` so durations appear in the dev server output
* where the operator can immediately verify performance budgets.
*
* @param tier - Which tier completed.
* @param durationMs - Elapsed time in milliseconds.
*/
function recordBrainLoadDuration(tier, durationMs) {
	const tm = _tiers[tier];
	tm.totalRequests++;
	if (tm.samples.length >= WINDOW_SIZE) tm.samples.shift();
	tm.samples.push({
		durationMs,
		recordedAt: Date.now()
	});
	console.info(`[brain/perf] tier=${tier} duration=${durationMs.toFixed(1)}ms`);
}

export { getBrainCacheMetrics as a, buildCacheKey as b, getCachedGraph as g, recordBrainLoadDuration as r, setCachedGraph as s };
//# sourceMappingURL=brain-D3P07VKO.js.map
