
      import { Temporal } from "@js-temporal/polyfill";
      import { URLPattern } from "urlpattern-polyfill";
      globalThis.addEventListener = () => {};
    
import { preloadedContexts } from "@fedify/vocab-runtime";
import { getLogger } from "@logtape/logtape";

//#region src/utils/kv-cache.ts
const logger = getLogger([
	"fedify",
	"utils",
	"kv-cache"
]);
/**
* A mock implementation of a key–value store for testing purposes.
*/
var MockKvStore = class {
	#values = {};
	get(key) {
		return Promise.resolve(this.#values[JSON.stringify(key)]);
	}
	set(key, value, _options) {
		this.#values[JSON.stringify(key)] = value;
		return Promise.resolve();
	}
	async delete(_) {}
	cas(..._) {
		return Promise.resolve(false);
	}
};
/**
* Decorates a {@link DocumentLoader} with a cache backed by a {@link Deno.Kv}.
* @param parameters The parameters for the cache.
* @returns The decorated document loader which is cache-enabled.
*/
function kvCache({ loader, kv, prefix, rules }) {
	const keyPrefix = prefix ?? ["_fedify", "remoteDocument"];
	rules ??= [[new URLPattern({}), Temporal.Duration.from({ minutes: 5 })]];
	for (const [p, duration] of rules) if (Temporal.Duration.compare(duration, { days: 30 }) > 0) throw new TypeError("The maximum cache duration is 30 days: " + (p instanceof URLPattern ? `${p.protocol}://${p.username}:${p.password}@${p.hostname}:${p.port}/${p.pathname}?${p.search}#${p.hash}` : p.toString()));
	return async (url, options) => {
		if (url in preloadedContexts) {
			logger.debug("Using preloaded context: {url}.", { url });
			return {
				contextUrl: null,
				document: preloadedContexts[url],
				documentUrl: url
			};
		}
		const match = matchRule(url, rules);
		if (match == null) return await loader(url, options);
		const key = [...keyPrefix, url];
		let cache = void 0;
		try {
			cache = await kv.get(key);
		} catch (error) {
			if (error instanceof Error) logger.warn("Failed to get the document of {url} from the KV cache: {error}", {
				url,
				error
			});
		}
		if (cache == null) {
			const remoteDoc = await loader(url, options);
			try {
				await kv.set(key, remoteDoc, { ttl: match });
			} catch (error) {
				logger.warn("Failed to save the document of {url} to the KV cache: {error}", {
					url,
					error
				});
			}
			return remoteDoc;
		}
		return cache;
	};
}
function matchRule(url, rules) {
	for (const [pattern, d] of rules) {
		const duration = d instanceof Temporal.Duration ? d : Temporal.Duration.from(d);
		if (typeof pattern === "string") {
			if (url === pattern) return duration;
			continue;
		}
		if (pattern instanceof URL) {
			if (pattern.href == url) return duration;
			continue;
		}
		if (pattern.test(url)) return duration;
	}
	return null;
}

//#endregion
export { MockKvStore, kvCache };