UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

228 lines 7.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DataManager = void 0; const events_1 = require("events"); class DataManager extends events_1.EventEmitter { constructor(streamService, channelService, config) { super(); this.isRunning = false; this.streamService = streamService; this._channelService = channelService; this.config = config; this.channelCache = new Map(); this.lastCollectionTime = new Date(0); this.setMaxListeners(50); } start() { if (this.isRunning) return; this.isRunning = true; this.scheduleNextCollection(); this.emit('dataManager:started', { timestamp: new Date(), config: this.config }); } stop() { if (!this.isRunning) return; this.isRunning = false; if (this.refreshTimer) { clearTimeout(this.refreshTimer); this.refreshTimer = undefined; } this.emit('dataManager:stopped', { timestamp: new Date() }); } addChannel(channelId) { if (!this.config.channels.includes(channelId)) { this.config.channels.push(channelId); this.channelCache.set(channelId, { channelId, lastUpdate: new Date(0), retryCount: 0 }); this.emit('dataManager:channelAdded', { channelId, timestamp: new Date() }); if (this.isRunning) { this.collectChannelData(channelId); } } } removeChannel(channelId) { const index = this.config.channels.indexOf(channelId); if (index !== -1) { this.config.channels.splice(index, 1); this.channelCache.delete(channelId); this.emit('dataManager:channelRemoved', { channelId, timestamp: new Date() }); } } getChannelData(channelId) { const entry = this.channelCache.get(channelId); return entry?.metrics || null; } getAllChannelsData() { const results = []; for (const entry of this.channelCache.values()) { if (entry.metrics) { results.push(entry.metrics); } } return results; } async collectData() { const startTime = Date.now(); const timestamp = new Date(); try { const metrics = []; const errors = []; const promises = this.config.channels.map(channelId => this.collectChannelData(channelId).catch(error => { errors.push(error); return null; })); const results = await Promise.all(promises); for (const result of results) { if (result) { metrics.push(result); } } this.lastCollectionTime = timestamp; const duration = Date.now() - startTime; const collectionResult = { success: errors.length === 0, data: metrics, error: errors.length > 0 ? errors[0] : undefined, timestamp, duration }; this.emit('dataManager:dataCollected', { ...collectionResult, channelCount: this.config.channels.length, successCount: metrics.length, errorCount: errors.length }); return collectionResult; } catch (error) { const duration = Date.now() - startTime; const collectionResult = { success: false, error: error instanceof Error ? error : new Error('Unknown collection error'), timestamp, duration }; this.emit('dataManager:dataCollected', collectionResult); return collectionResult; } } async collectChannelData(channelId) { const entry = this.channelCache.get(channelId) || { channelId, lastUpdate: new Date(0), retryCount: 0 }; try { const streamStatus = await this.streamService.getStreamStatus({ channelId }); const metrics = { channelId, bitrate: streamStatus.metrics?.bandwidth ? Math.round(streamStatus.metrics.bandwidth / 1000) : 0, fps: streamStatus.metrics?.fps || 0, resolution: '1920x1080', viewerCount: 0, status: streamStatus.isLive ? 'live' : 'offline', uptime: streamStatus.duration || 0, bandwidth: streamStatus.metrics?.bandwidth || 0, lastUpdate: new Date() }; entry.metrics = metrics; entry.lastUpdate = new Date(); entry.error = undefined; entry.retryCount = 0; this.channelCache.set(channelId, entry); this.emit('dataManager:channelUpdated', { channelId, metrics, timestamp: new Date() }); return metrics; } catch (error) { entry.error = error instanceof Error ? error : new Error('Unknown channel error'); entry.retryCount++; entry.lastUpdate = new Date(); this.channelCache.set(channelId, entry); this.emit('dataManager:channelError', { channelId, error: entry.error, retryCount: entry.retryCount, timestamp: new Date() }); throw entry.error; } } scheduleNextCollection() { if (!this.isRunning) return; this.refreshTimer = setTimeout(async () => { if (this.isRunning) { await this.collectData(); this.scheduleNextCollection(); } }, this.config.refreshInterval); } setRefreshInterval(intervalMs) { this.config.refreshInterval = intervalMs; if (this.isRunning) { this.stop(); this.start(); } this.emit('dataManager:configUpdated', { refreshInterval: intervalMs, timestamp: new Date() }); } getConfig() { return { ...this.config }; } getStats() { let activeChannels = 0; let errorChannels = 0; for (const entry of this.channelCache.values()) { if (entry.metrics) { activeChannels++; } if (entry.error) { errorChannels++; } } return { isRunning: this.isRunning, channelCount: this.config.channels.length, lastCollectionTime: this.lastCollectionTime, cacheStats: { totalEntries: this.channelCache.size, activeChannels, errorChannels } }; } clearCache() { this.channelCache.clear(); this.emit('dataManager:cacheCleared', { timestamp: new Date() }); } destroy() { this.stop(); this.clearCache(); this.removeAllListeners(); } } exports.DataManager = DataManager; //# sourceMappingURL=data-manager.js.map