//#region src/elements/EFMedia/videoTasks/ScrubInputCache.ts
/**
* Cache for scrub BufferedSeekingInput instances.
*
* For JIT media (segmented scrub tracks), caches by src + segment ID.
* For Asset media (single-file scrub tracks), caches by URL so all segments
* share the same BufferedSeekingInput instance.
*
* Uses promise deduplication to prevent race conditions when multiple
* concurrent requests arrive for the same segment.
*/
var ScrubInputCache = class {
	#cache = /* @__PURE__ */ new Map();
	#urlCache = /* @__PURE__ */ new Map();
	#pendingBySegment = /* @__PURE__ */ new Map();
	#pendingByUrl = /* @__PURE__ */ new Map();
	#maxCacheSize = 5;
	/**
	* Create a cache key that uniquely identifies a segment for a specific video
	*/
	#getCacheKey(src, segmentId) {
		return `${src}:${segmentId}`;
	}
	/**
	* Get or create BufferedSeekingInput for a scrub segment.
	*
	* Uses promise deduplication to prevent race conditions when multiple
	* concurrent requests arrive for the same segment.
	*
	* @param src - The source URL of the video (required to distinguish between videos)
	* @param segmentId - The segment ID
	* @param createInputFn - Factory function to create the input
	* @param scrubUrl - Optional URL for single-file scrub tracks (all segments share same input)
	*/
	async getOrCreateInput(src, segmentId, createInputFn, scrubUrl) {
		if (scrubUrl) {
			const cached$1 = this.#urlCache.get(scrubUrl);
			if (cached$1) return cached$1;
			const pending$1 = this.#pendingByUrl.get(scrubUrl);
			if (pending$1) return pending$1;
			const promise$1 = createInputFn().then((input) => {
				this.#pendingByUrl.delete(scrubUrl);
				if (input) this.#urlCache.set(scrubUrl, input);
				return input;
			}).catch((error) => {
				this.#pendingByUrl.delete(scrubUrl);
				throw error;
			});
			this.#pendingByUrl.set(scrubUrl, promise$1);
			return promise$1;
		}
		const cacheKey = this.#getCacheKey(src, segmentId);
		const cached = this.#cache.get(cacheKey);
		if (cached) return cached;
		const pending = this.#pendingBySegment.get(cacheKey);
		if (pending) return pending;
		const promise = createInputFn().then((input) => {
			this.#pendingBySegment.delete(cacheKey);
			if (input) {
				this.#cache.set(cacheKey, input);
				if (this.#cache.size > this.#maxCacheSize) {
					const oldestKey = this.#cache.keys().next().value;
					if (oldestKey !== void 0) this.#cache.delete(oldestKey);
				}
			}
			return input;
		}).catch((error) => {
			this.#pendingBySegment.delete(cacheKey);
			throw error;
		});
		this.#pendingBySegment.set(cacheKey, promise);
		return promise;
	}
	/**
	* Clear the entire cache (called when video changes)
	*/
	clear() {
		this.#cache.clear();
		this.#urlCache.clear();
		this.#pendingBySegment.clear();
		this.#pendingByUrl.clear();
	}
	/**
	* Get cache statistics
	*/
	getStats() {
		return {
			size: this.#cache.size,
			urlCacheSize: this.#urlCache.size,
			pendingCount: this.#pendingBySegment.size + this.#pendingByUrl.size,
			cacheKeys: Array.from(this.#cache.keys())
		};
	}
};

//#endregion
export { ScrubInputCache };
//# sourceMappingURL=ScrubInputCache.js.map