mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 22:26: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
57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
import { createHash } from 'node:crypto';
|
|
import { getPortalData } from './data-store.js';
|
|
import type { PerformanceManifest } from './performance-control.types.js';
|
|
|
|
const PERFORMANCE_USERNAME = 'performance';
|
|
const PERFORMANCE_PASSWORD = 'performance';
|
|
|
|
/**
|
|
* The property insertion order is part of the fixture identity contract.
|
|
* Never add credentials, server origins, or response envelopes to this input.
|
|
*/
|
|
export function buildPerformanceManifest(epoch: number): PerformanceManifest {
|
|
const data = getPortalData(PERFORMANCE_USERNAME, PERFORMANCE_PASSWORD);
|
|
const catalog = {
|
|
liveCategories: data.liveCategories,
|
|
vodCategories: data.vodCategories,
|
|
seriesCategories: data.seriesCategories,
|
|
liveCatalog: data.liveStreams,
|
|
vodCatalog: data.vodStreams,
|
|
seriesCatalog: data.seriesItems,
|
|
};
|
|
const serialized = JSON.stringify(catalog);
|
|
const categoryCounts = {
|
|
live: data.liveCategories.length,
|
|
vod: data.vodCategories.length,
|
|
series: data.seriesCategories.length,
|
|
};
|
|
const itemCounts = {
|
|
live: data.liveStreams.length,
|
|
vod: data.vodStreams.length,
|
|
series: data.seriesItems.length,
|
|
};
|
|
|
|
return {
|
|
epoch,
|
|
scenario: 'performance-100k',
|
|
seed: data.scenario.seed,
|
|
counts: {
|
|
categories: {
|
|
...categoryCounts,
|
|
total:
|
|
categoryCounts.live +
|
|
categoryCounts.vod +
|
|
categoryCounts.series,
|
|
},
|
|
items: {
|
|
...itemCounts,
|
|
total: itemCounts.live + itemCounts.vod + itemCounts.series,
|
|
},
|
|
},
|
|
bytes: Buffer.byteLength(serialized, 'utf8'),
|
|
catalogSha256: createHash('sha256')
|
|
.update(serialized, 'utf8')
|
|
.digest('hex'),
|
|
};
|
|
}
|