fix(live): prevent analysis crash on large catalogs (#26)
Bound synchronous live channel enrichment and tolerate minimal projection payloads so analysis and listings do not blank the UI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -1214,7 +1214,7 @@
|
||||
<script src="/js/services/channelLanguageFusion.js?v=1"></script>
|
||||
<script src="/js/services/layaStatusPresentation.js?v=5"></script>
|
||||
<script src="/js/services/liveAnalysisPresentation.js?v=1"></script>
|
||||
<script src="/js/services/liveChannelProjection.js?v=3"></script>
|
||||
<script src="/js/services/liveChannelProjection.js?v=4"></script>
|
||||
<script src="/js/services/channelVariantGrouping.js?v=7"></script>
|
||||
<script src="/js/components/ChannelList.js?v=13"></script>
|
||||
<script src="/js/components/SourceManager.js?v=4"></script>
|
||||
|
||||
@ -23,6 +23,18 @@
|
||||
return wanted.every(token => corpus.some(candidate => candidate.includes(token)));
|
||||
}
|
||||
|
||||
function normalizeLanguage(language) {
|
||||
const rawCode = typeof language?.code === 'string' ? language.code.trim().toLowerCase() : '';
|
||||
const code = rawCode || 'und';
|
||||
const confidence = Number(language?.confidence);
|
||||
return {
|
||||
code,
|
||||
short: language?.short || (code === 'und' ? 'UND' : code.toUpperCase()),
|
||||
label: language?.label || (code === 'und' ? 'Unknown' : code.toUpperCase()),
|
||||
confidence: Number.isFinite(confidence) ? confidence : 0
|
||||
};
|
||||
}
|
||||
|
||||
function mapResponse(response, sources = []) {
|
||||
if (!response || !Array.isArray(response.channels)) {
|
||||
throw new Error('Invalid live channel projection response');
|
||||
@ -33,12 +45,15 @@
|
||||
const hiddenItems = new Set();
|
||||
const channels = [];
|
||||
const logicalChannels = [];
|
||||
const hasLanguageViews = response.channels.every(channel => channel?.language && channel?.logicalChannelId);
|
||||
const hasLanguageViews = response.channels.every(channel => channel?.logicalChannelId);
|
||||
|
||||
response.channels.forEach(logicalChannel => {
|
||||
if (!logicalChannel || !Array.isArray(logicalChannel.variants)) return;
|
||||
if (!logicalChannel) return;
|
||||
const rawVariants = Array.isArray(logicalChannel.variants)
|
||||
? logicalChannel.variants.filter(Boolean)
|
||||
: (logicalChannel.preferredVariant ? [logicalChannel.preferredVariant] : []);
|
||||
const mappedVariants = [];
|
||||
logicalChannel.variants.forEach(variant => {
|
||||
rawVariants.forEach(variant => {
|
||||
const source = sourceById.get(String(variant.sourceId));
|
||||
const id = String(variant.id);
|
||||
const mapped = {
|
||||
@ -55,9 +70,7 @@
|
||||
sourceType: variant.sourceType ?? source?.type ?? 'xtream',
|
||||
sourceName: variant.sourceName ?? source?.name ?? ''
|
||||
};
|
||||
if (variant.language || logicalChannel.language) {
|
||||
mapped.language = variant.language || logicalChannel.language;
|
||||
}
|
||||
mapped.language = normalizeLanguage(variant.language || logicalChannel.language);
|
||||
channels.push(mapped);
|
||||
mappedVariants.push(mapped);
|
||||
const key = `${mapped.sourceId}:${id}`;
|
||||
@ -69,7 +82,7 @@
|
||||
`${variant.sourceId}:${variant.id}` === String(logicalChannel.selectedVariantId)
|
||||
) || mappedVariants.find(variant => String(variant.id) === String(logicalChannel.preferredVariant?.id))
|
||||
|| mappedVariants[0];
|
||||
const language = logicalChannel.language || preferredVariant.language;
|
||||
const language = normalizeLanguage(logicalChannel.language || preferredVariant.language);
|
||||
if (hasLanguageViews) logicalChannels.push({
|
||||
...logicalChannel,
|
||||
fingerprint: logicalChannel.id,
|
||||
@ -90,7 +103,7 @@
|
||||
|
||||
return {
|
||||
channels, logicalChannels: hasLanguageViews ? logicalChannels : null, favorites, hiddenItems,
|
||||
availableLanguages: response.filters?.availableLanguages || [],
|
||||
availableLanguages: (response.filters?.availableLanguages || []).filter(Boolean).map(normalizeLanguage),
|
||||
projection: response.projection || {}
|
||||
};
|
||||
}
|
||||
@ -109,5 +122,5 @@
|
||||
return response.channels.length > 0 || !expectedChannelCount;
|
||||
}
|
||||
|
||||
return { canUse, mapResponse, matchesSearch, normalizeSearch };
|
||||
return { canUse, mapResponse, matchesSearch, normalizeLanguage, normalizeSearch };
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user