mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 11:06:16 -08:00
* docs(performance): plan Xtream benchmark * feat(xtream-mock-server): add deterministic 100k fixture * style(xtream-mock-server): apply repository formatting * fix(xtream-mock-server): harden performance fixture data * feat(xtream-mock-server): add performance control plane * docs(performance): correct Xtream capture plan * fix(xtream-mock-server): harden performance controls * fix(xtream-mock-server): harden control lifecycle * feat(performance): add Xtream preload markers * feat(performance): trace Xtream main phases * feat(performance): mark Xtream store publications * feat(performance): trace Xtream database phases * feat(performance): trace Xtream delete cancellation * feat(performance): capture Xtream phase attribution * feat(performance): mark Sources Xtream refresh * test(performance): define Xtream benchmark evidence contracts * test(performance): add Xtream benchmark runner * test(performance): surface failure evidence writes * test(performance): align database read clock * test(performance): preserve capture failure contracts
110 lines
4.1 KiB
TypeScript
110 lines
4.1 KiB
TypeScript
import { XtreamCodeActions } from '@iptvnator/shared/interfaces';
|
|
|
|
import {
|
|
XTREAM_PHASE_SEMANTIC_TYPE as SEMANTIC,
|
|
type XtreamPhaseSemanticType,
|
|
} from './xtream-phase-inventory';
|
|
|
|
export type XtreamPhaseCategoryType = 'live' | 'movies' | 'series';
|
|
export type XtreamPhaseContentType = 'live' | 'movie' | 'series';
|
|
export type XtreamPhaseProviderAction =
|
|
| XtreamCodeActions.GetAccountInfo
|
|
| XtreamCodeActions.GetLiveCategories
|
|
| XtreamCodeActions.GetLiveStreams
|
|
| XtreamCodeActions.GetSeries
|
|
| XtreamCodeActions.GetSeriesCategories
|
|
| XtreamCodeActions.GetVodCategories
|
|
| XtreamCodeActions.GetVodStreams;
|
|
|
|
export interface XtreamPhaseSemanticSource {
|
|
readonly categoryType: XtreamPhaseCategoryType | null;
|
|
readonly contentType: XtreamPhaseContentType | null;
|
|
readonly providerAction: XtreamPhaseProviderAction | null;
|
|
}
|
|
|
|
const ACTION_SEMANTICS = new Map<string, XtreamPhaseSemanticType>([
|
|
[XtreamCodeActions.GetAccountInfo, SEMANTIC.ACCOUNT],
|
|
[XtreamCodeActions.GetLiveCategories, SEMANTIC.LIVE_CATEGORIES],
|
|
[XtreamCodeActions.GetVodCategories, SEMANTIC.VOD_CATEGORIES],
|
|
[XtreamCodeActions.GetSeriesCategories, SEMANTIC.SERIES_CATEGORIES],
|
|
[XtreamCodeActions.GetLiveStreams, SEMANTIC.LIVE_CONTENT],
|
|
[XtreamCodeActions.GetVodStreams, SEMANTIC.VOD_CONTENT],
|
|
[XtreamCodeActions.GetSeries, SEMANTIC.SERIES_CONTENT],
|
|
]);
|
|
const CATEGORY_SEMANTICS = new Map<string, XtreamPhaseSemanticType>([
|
|
['live', SEMANTIC.LIVE_CATEGORIES],
|
|
['movies', SEMANTIC.VOD_CATEGORIES],
|
|
['series', SEMANTIC.SERIES_CATEGORIES],
|
|
]);
|
|
const CONTENT_SEMANTICS = new Map<string, XtreamPhaseSemanticType>([
|
|
['live', SEMANTIC.LIVE_CONTENT],
|
|
['movie', SEMANTIC.VOD_CONTENT],
|
|
['series', SEMANTIC.SERIES_CONTENT],
|
|
]);
|
|
|
|
export function semanticTypeFromXtreamPhaseSource(
|
|
source: Readonly<Record<keyof XtreamPhaseSemanticSource, unknown>>
|
|
): XtreamPhaseSemanticType | null | undefined {
|
|
const populated = [
|
|
source.providerAction,
|
|
source.categoryType,
|
|
source.contentType,
|
|
].filter((value) => value !== null);
|
|
if (populated.length === 0) return null;
|
|
if (populated.length !== 1) return undefined;
|
|
if (source.providerAction !== null) {
|
|
return typeof source.providerAction === 'string'
|
|
? ACTION_SEMANTICS.get(source.providerAction)
|
|
: undefined;
|
|
}
|
|
if (source.categoryType !== null) {
|
|
return typeof source.categoryType === 'string'
|
|
? CATEGORY_SEMANTICS.get(source.categoryType)
|
|
: undefined;
|
|
}
|
|
return typeof source.contentType === 'string'
|
|
? CONTENT_SEMANTICS.get(source.contentType)
|
|
: undefined;
|
|
}
|
|
|
|
export function xtreamDataSemanticSource(
|
|
semanticType: XtreamPhaseSemanticType | null
|
|
): XtreamPhaseSemanticSource {
|
|
switch (semanticType) {
|
|
case SEMANTIC.LIVE_CATEGORIES:
|
|
return source(null, 'live', null);
|
|
case SEMANTIC.VOD_CATEGORIES:
|
|
return source(null, 'movies', null);
|
|
case SEMANTIC.SERIES_CATEGORIES:
|
|
return source(null, 'series', null);
|
|
case SEMANTIC.LIVE_CONTENT:
|
|
return source(null, null, 'live');
|
|
case SEMANTIC.VOD_CONTENT:
|
|
return source(null, null, 'movie');
|
|
case SEMANTIC.SERIES_CONTENT:
|
|
return source(null, null, 'series');
|
|
case SEMANTIC.ACCOUNT:
|
|
throw new Error('account has no database semantic source');
|
|
case null:
|
|
return source(null, null, null);
|
|
}
|
|
}
|
|
|
|
export function xtreamProviderSemanticSource(
|
|
semanticType: XtreamPhaseSemanticType
|
|
): XtreamPhaseSemanticSource {
|
|
const action = [...ACTION_SEMANTICS].find(
|
|
([, mapped]) => mapped === semanticType
|
|
)?.[0];
|
|
if (!action) throw new Error('invalid provider semantic type');
|
|
return source(action as XtreamPhaseProviderAction, null, null);
|
|
}
|
|
|
|
function source(
|
|
providerAction: XtreamPhaseProviderAction | null,
|
|
categoryType: XtreamPhaseCategoryType | null,
|
|
contentType: XtreamPhaseContentType | null
|
|
): XtreamPhaseSemanticSource {
|
|
return Object.freeze({ categoryType, contentType, providerAction });
|
|
}
|