Move variant grouping work out of Live TV rendering into the catalog pipeline: a liveProjectionService builds the logical channel projection (schema in liveProjectionSchema) whenever a source is added, synced or modified (name change, new address), and the projection is served through a /live route. ChannelList now consumes the precomputed projection via a liveChannelProjection client service, recalculating only when the catalog changes. Cover projection building, incremental recompute and client consumption with tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
1.7 KiB
JavaScript
35 lines
1.7 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const projection = require('../public/js/services/liveChannelProjection.js');
|
|
|
|
test('maps projected logical channels to the frontend variant format', () => {
|
|
const response = {
|
|
projection: { status: 'success', stale: false },
|
|
channels: [{
|
|
id: 'logical:one', fingerprint: 'news', displayName: 'News',
|
|
variants: [{
|
|
id: 42, sourceId: 7, name: 'News HD', categoryId: 'News',
|
|
streamIcon: 'logo.png', streamUrl: 'https://stream.test/live',
|
|
tvgId: 'news.fr', isFavorite: true, isHidden: true
|
|
}]
|
|
}]
|
|
};
|
|
const mapped = projection.mapResponse(response, [{ id: 7, type: 'm3u', name: 'Local' }]);
|
|
assert.deepEqual(mapped.channels[0], {
|
|
id: '42', sourceId: 7, name: 'News HD', categoryId: 'News',
|
|
streamIcon: 'logo.png', streamUrl: 'https://stream.test/live', tvgId: 'news.fr',
|
|
isFavorite: true, isHidden: true, logicalId: 'logical:one',
|
|
logicalFingerprint: 'news', logicalDisplayName: 'News',
|
|
streamId: '42', tvgLogo: 'logo.png',
|
|
url: 'https://stream.test/live', groupTitle: 'News', sourceType: 'm3u', sourceName: 'Local'
|
|
});
|
|
assert.equal(mapped.favorites.has('7:42'), true);
|
|
assert.equal(mapped.hiddenItems.has('channel:7:42'), true);
|
|
});
|
|
|
|
test('rejects stale projections so ChannelList can use its legacy fallback', () => {
|
|
assert.equal(projection.canUse({ projection: { stale: true }, channels: [] }), false);
|
|
assert.equal(projection.canUse({ projection: { stale: false }, channels: [] }), true);
|
|
assert.equal(projection.canUse(null), false);
|
|
});
|