// KefinTweaks Studios Cache Manager // Handles fetching, processing, and caching of Series Studios (function() { 'use strict'; const LOG = (...args) => console.log('[KefinTweaks StudiosCache]', ...args); const WARN = (...args) => console.warn('[KefinTweaks StudiosCache]', ...args); const ERR = (...args) => console.error('[KefinTweaks StudiosCache]', ...args); // State let _seriesStudios = null; /** * Fetches and caches Series Studios using apiHelper.getQuery * Uses progressive loading: returns immediate cached data if available, * then updates in-memory cache when fresh data arrives */ async function fetchAndCacheSeriesStudios() { if (!window.apiHelper) { ERR('apiHelper is not available'); return []; } try { const apiClient = window.ApiClient; if (!apiClient) { ERR('ApiClient is not available'); return []; } const serverUrl = apiClient.serverAddress(); const url = `${serverUrl}/Studios?IncludeItemTypes=Series`; LOG('Fetching Series Studios...'); const result = await window.apiHelper.getQuery(url, { useCache: true }); // Extract immediate data (may be null/empty if uncached) const immediateData = result.data; const studios = immediateData?.Items ?? (await result.dataPromise)?.Items ?? []; // When dataPromise resolves, update in-memory cache result.dataPromise.then(freshData => { const freshStudios = freshData?.Items || freshData || []; _seriesStudios = freshStudios; LOG(`Updated in-memory cache with ${freshStudios.length} Series Studios`); }).catch(err => { WARN('Error updating in-memory cache from dataPromise:', err); }); return studios; } catch (err) { ERR('Error fetching Series Studios:', err); return []; } } /** * Gets all Series Studios, using in-memory cache if available * Otherwise fetches and caches the data */ async function getSeriesStudios() { if (_seriesStudios !== null) { return _seriesStudios; } // Fetch and cache, which will return immediate data and update cache when promise resolves const studios = await fetchAndCacheSeriesStudios(); // Update in-memory cache with immediate data (even if empty) to avoid repeated calls if (_seriesStudios === null) { _seriesStudios = studios; } return studios; } /** * Initializes the cache */ async function initialize() { await getSeriesStudios(); } /** * Gets popular TV networks (studios) filtered by minimum series count * @param {number|{ MinCount?: number, minCount?: number, minimumSeries?: number }} minOrOptions * Minimum series count, or queryOptions bag from fetchFromDataSource * @returns {Promise} - Array of studios meeting the minimum threshold */ async function getPopularTVNetworks(minOrOptions) { let minimumSeries; if (minOrOptions && typeof minOrOptions === 'object') { minimumSeries = minOrOptions.MinCount ?? minOrOptions.minCount ?? minOrOptions.minimumSeries; } else { minimumSeries = minOrOptions; } if (minimumSeries == null || minimumSeries === '') { minimumSeries = window.KefinTweaksConfig?.HOME_SETTINGS?.minimumSeriesForPopularTVNetworks ?? window.KefinHomeConfig2?.HOME_SETTINGS?.minimumSeriesForPopularTVNetworks; } const studios = await getSeriesStudios(); const threshold = Number(minimumSeries); if (Number.isFinite(threshold) && threshold > 0) { return studios.filter(studio => (studio.SeriesCount || studio.ChildCount || 0) >= threshold ); } return studios; } // Expose API window.StudiosCache = { init: initialize, getPopularTVNetworks: getPopularTVNetworks, getSeriesStudios: getSeriesStudios }; LOG('Module loaded'); })();