import { getRequestContext } from "./request-context.mjs";

//#region src/request-cache.ts
const STORE_KEY = Symbol.for("emdash:request-cache");
const g = globalThis;
const store = g[STORE_KEY] ?? (() => {
	const wm = /* @__PURE__ */ new WeakMap();
	g[STORE_KEY] = wm;
	return wm;
})();
/**
* Return a cached result for `key` if one exists in the current
* request scope, otherwise call `fn`, cache its promise, and return it.
*
* Caches the *promise*, not the resolved value, so concurrent calls
* with the same key share a single in-flight query.
*/
function requestCached(key, fn) {
	const ctx = getRequestContext();
	if (!ctx) return fn();
	let cache = store.get(ctx);
	if (!cache) {
		cache = /* @__PURE__ */ new Map();
		store.set(ctx, cache);
	}
	const existing = cache.get(key);
	if (existing) {
		if (ctx.metrics) ctx.metrics.cacheHits += 1;
		return existing;
	}
	if (ctx.metrics) ctx.metrics.cacheMisses += 1;
	const promise = Promise.resolve().then(fn).catch((error) => {
		cache.delete(key);
		throw error;
	});
	cache.set(key, promise);
	return promise;
}
/**
* Look up an entry in the request-scoped cache without inserting one.
*
* Returns the in-flight or resolved promise if the key exists in the
* current request, otherwise `undefined`. Callers can use this to
* opportunistically satisfy a narrower query (e.g. `getSiteSetting("seo")`)
* from a broader one (`getSiteSettings()`) that's already been loaded
* by a parent template — avoiding a redundant round-trip.
*
* No-ops outside a request context.
*/
function peekRequestCache(key) {
	const ctx = getRequestContext();
	if (!ctx) return void 0;
	return store.get(ctx)?.get(key);
}
/**
* Pre-populate the request-scoped cache with a resolved value.
*
* Internal helper shared between hydration paths (taxonomy terms,
* bylines, etc.) that already have the data in hand and want downstream
* callers using `requestCached(key, ...)` to skip the database entirely.
* Not exported from the package entrypoint — keep it internal until we
* have a documented plugin/extension surface for hydration.
*
* No-ops outside a request context (local dev without ALS).
*
* Does not overwrite an existing entry — if a query for this key is already
* in flight, its promise wins.
*/
function setRequestCacheEntry(key, value) {
	const ctx = getRequestContext();
	if (!ctx) return;
	let cache = store.get(ctx);
	if (!cache) {
		cache = /* @__PURE__ */ new Map();
		store.set(ctx, cache);
	}
	if (cache.has(key)) return;
	cache.set(key, Promise.resolve(value));
}
/**
* Remove a key from the request-scoped cache.
*
* Used by write paths that need to invalidate a downstream read cache —
* `setRequestCacheEntry` deliberately doesn't overwrite, and `requestCached`
* returns the cached promise even after the underlying data has changed.
* Without an explicit clear, a `read → write → read` sequence in a single
* request can return stale data on the second read.
*
* Concrete case: `BylineRepository.update` invalidates
* `byline-field-group-values:${translation_group}` after writing a
* non-translatable custom-field value, so the post-update `findById`
* (and any later reads in the same request) see the fresh value.
*
* No-ops outside a request context.
*/
function clearRequestCacheEntry(key) {
	const ctx = getRequestContext();
	if (!ctx) return;
	store.get(ctx)?.delete(key);
}

//#endregion
export { setRequestCacheEntry as i, peekRequestCache as n, requestCached as r, clearRequestCacheEntry as t };
//# sourceMappingURL=request-cache-KCNHp_RJ.mjs.map