UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

404 lines 14.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.GridManager = void 0; const contrib = __importStar(require("blessed-contrib")); class GridManager { constructor(screen, eventBus, rows = 12, cols = 12) { this.cells = []; this.layouts = new Map(); this.screen = screen; this.eventBus = eventBus; this.rows = rows; this.cols = cols; this.currentLayout = 'default'; this.initializeGrid(); this.initializeCells(); this.setupEventListeners(); this.registerDefaultLayouts(); } initializeGrid() { this.grid = contrib.grid({ rows: this.rows, cols: this.cols, screen: this.screen, }); } initializeCells() { this.cells = []; for (let row = 0; row < this.rows; row++) { this.cells[row] = []; for (let col = 0; col < this.cols; col++) { if (this.cells[row]) { this.cells[row][col] = { position: { x: col, y: row, width: 1, height: 1 }, occupied: false, }; } } } } setupEventListeners() { if (this.screen?.on) { this.screen.on('resize', () => { this.handleResize(); }); } this.eventBus.on('layout:change', (data) => { this.setLayout(data.layout); }); this.eventBus.on('component:created', (_data) => { this.handleComponentCreated(); }); this.eventBus.on('component:destroyed', (data) => { this.handleComponentDestroyed(data); }); } handleResize() { if (this.resizeTimeout) { clearTimeout(this.resizeTimeout); } this.resizeTimeout = setTimeout(() => { this.recalculateLayout(); const envWidth = process.env['POLYV_TERMINAL_WIDTH']; const envHeight = process.env['POLYV_TERMINAL_HEIGHT']; let width = process.stdout.columns && process.stdout.columns > 0 ? process.stdout.columns : 120; let height = process.stdout.rows && process.stdout.rows > 0 ? process.stdout.rows : 30; if (envWidth && parseInt(envWidth) > 0) { width = parseInt(envWidth); } if (envHeight && parseInt(envHeight) > 0) { height = parseInt(envHeight); } if (this.screen?.width && this.screen.width > 1) { width = this.screen.width; } if (this.screen?.height && this.screen.height > 1) { height = this.screen.height; } this.eventBus.emit('terminal:resize', { width, height, }); }, 100); } handleComponentCreated() { } handleComponentDestroyed(data) { this.removeComponentFromGrid(data.componentId); } registerDefaultLayouts() { this.layouts.set('default', { id: 'default', name: 'default', isBuiltIn: true, grid: { cols: 12, rows: 12, cellWidth: 10, cellHeight: 3, padding: 1 }, responsive: true, minTerminalSize: { width: 120, height: 30 }, components: [ { type: 'stream-metrics', position: { x: 0, y: 0, width: 8, height: 6 }, size: { minWidth: 40, minHeight: 15 }, config: {}, }, { type: 'channel-status', position: { x: 8, y: 0, width: 4, height: 6 }, size: { minWidth: 30, minHeight: 15 }, config: {}, }, { type: 'system-resources', position: { x: 0, y: 6, width: 6, height: 6 }, size: { minWidth: 30, minHeight: 15 }, config: {}, }, { type: 'activity-log', position: { x: 6, y: 6, width: 6, height: 6 }, size: { minWidth: 30, minHeight: 15 }, config: {}, }, ], }); this.layouts.set('compact', { id: 'compact', name: 'compact', isBuiltIn: true, grid: { cols: 12, rows: 12, cellWidth: 8, cellHeight: 2, padding: 1 }, responsive: true, minTerminalSize: { width: 80, height: 24 }, components: [ { type: 'stream-metrics', position: { x: 0, y: 0, width: 12, height: 8 }, size: { minWidth: 40, minHeight: 15 }, config: {}, }, { type: 'channel-status', position: { x: 0, y: 8, width: 12, height: 4 }, size: { minWidth: 30, minHeight: 8 }, config: {}, }, ], }); this.layouts.set('single', { id: 'single', name: 'single', isBuiltIn: true, grid: { cols: 12, rows: 12, cellWidth: 6, cellHeight: 2, padding: 1 }, responsive: true, minTerminalSize: { width: 60, height: 20 }, components: [ { type: 'stream-metrics', position: { x: 0, y: 0, width: 12, height: 12 }, size: { minWidth: 40, minHeight: 15 }, config: {}, }, ], }); } setLayout(layoutName) { const layout = this.layouts.get(layoutName); if (!layout) { throw new Error(`Layout '${layoutName}' not found`); } const envWidth = process.env['POLYV_TERMINAL_WIDTH']; const envHeight = process.env['POLYV_TERMINAL_HEIGHT']; let width = process.stdout.columns && process.stdout.columns > 0 ? process.stdout.columns : 120; let height = process.stdout.rows && process.stdout.rows > 0 ? process.stdout.rows : 30; if (envWidth && parseInt(envWidth) > 0) { width = parseInt(envWidth); } if (envHeight && parseInt(envHeight) > 0) { height = parseInt(envHeight); } if (this.screen.width && this.screen.width > 1) { width = this.screen.width; } if (this.screen.height && this.screen.height > 1) { height = this.screen.height; } const terminalSize = { width, height }; if (terminalSize.width < layout.minTerminalSize.width || terminalSize.height < layout.minTerminalSize.height) { throw new Error(`Terminal size too small for layout '${layoutName}'. ` + `Required: ${layout.minTerminalSize.width}x${layout.minTerminalSize.height}, ` + `Current: ${terminalSize.width}x${terminalSize.height}`); } this.currentLayout = layoutName; this.clearGrid(); this.eventBus.emit('layout:changed', { layout: layoutName, config: layout, timestamp: new Date(), }); } addComponent(component, position) { if (!this.canPlaceComponent(position)) { throw new Error(`Cannot place component at position ${JSON.stringify(position)}`); } if (!this.grid) { throw new Error('Grid is not initialized. Make sure blessed-contrib is properly imported and initialized.'); } const widget = this.grid.set(position.y, position.x, position.height, position.width, component.getWidget(), {}); this.markCellsOccupied(position, component); this.eventBus.emit('grid:componentAdded', { componentId: component.getState().id, position, timestamp: new Date(), }); return widget; } removeComponent(componentId) { const component = this.findComponentById(componentId); if (!component) { return false; } this.markCellsUnoccupied(component.position); this.eventBus.emit('grid:componentRemoved', { componentId, timestamp: new Date(), }); return true; } canPlaceComponent(position) { if (position.x < 0 || position.y < 0 || position.x + position.width > this.cols || position.y + position.height > this.rows) { return false; } for (let row = position.y; row < position.y + position.height; row++) { for (let col = position.x; col < position.x + position.width; col++) { if (this.cells[row]?.[col]?.occupied) { return false; } } } return true; } getOptimalPosition(size) { const width = Math.min(size.maxWidth || size.minWidth, this.cols); const height = Math.min(size.maxHeight || size.minHeight, this.rows); for (let row = 0; row <= this.rows - height; row++) { for (let col = 0; col <= this.cols - width; col++) { const position = { x: col, y: row, width, height }; if (this.canPlaceComponent(position)) { return position; } } } return null; } getAvailableLayouts() { return Array.from(this.layouts.keys()); } getCurrentLayout() { return this.currentLayout; } getLayoutConfig(layoutName) { return this.layouts.get(layoutName); } registerLayout(layout) { this.layouts.set(layout.name, layout); } getGrid() { return this.grid; } getGridSize() { return { rows: this.rows, cols: this.cols }; } getOccupiedCells() { const occupied = []; for (let row = 0; row < this.rows; row++) { for (let col = 0; col < this.cols; col++) { const cell = this.cells[row]?.[col]; if (cell?.occupied) { occupied.push(cell.position); } } } return occupied; } findComponentById(componentId) { for (let row = 0; row < this.rows; row++) { for (let col = 0; col < this.cols; col++) { const cell = this.cells[row]?.[col]; if (cell?.component && cell.component.getState().id === componentId) { return cell; } } } return undefined; } markCellsOccupied(position, component) { for (let row = position.y; row < position.y + position.height; row++) { for (let col = position.x; col < position.x + position.width; col++) { const cell = this.cells[row]?.[col]; if (cell) { cell.occupied = true; cell.component = component; } } } } markCellsUnoccupied(position) { for (let row = position.y; row < position.y + position.height; row++) { for (let col = position.x; col < position.x + position.width; col++) { const cell = this.cells[row]?.[col]; if (cell) { cell.occupied = false; cell.component = undefined; } } } } removeComponentFromGrid(componentId) { const component = this.findComponentById(componentId); if (component) { this.markCellsUnoccupied(component.position); } } clearGrid() { for (let row = 0; row < this.rows; row++) { for (let col = 0; col < this.cols; col++) { const cell = this.cells[row]?.[col]; if (cell) { cell.occupied = false; cell.component = undefined; } } } } recalculateLayout() { const layout = this.layouts.get(this.currentLayout); if (!layout) return; const envWidth = process.env['POLYV_TERMINAL_WIDTH']; const envHeight = process.env['POLYV_TERMINAL_HEIGHT']; let width = process.stdout.columns && process.stdout.columns > 0 ? process.stdout.columns : 120; let height = process.stdout.rows && process.stdout.rows > 0 ? process.stdout.rows : 30; if (envWidth && parseInt(envWidth) > 0) { width = parseInt(envWidth); } if (envHeight && parseInt(envHeight) > 0) { height = parseInt(envHeight); } if (this.screen.width && this.screen.width > 1) { width = this.screen.width; } if (this.screen.height && this.screen.height > 1) { height = this.screen.height; } this.eventBus.emit('grid:recalculated', { layout: this.currentLayout, terminalSize: { width, height }, timestamp: new Date(), }); } destroy() { if (this.resizeTimeout) { clearTimeout(this.resizeTimeout); } this.clearGrid(); this.layouts.clear(); this.screen.removeAllListeners('resize'); } } exports.GridManager = GridManager; //# sourceMappingURL=grid-manager.js.map