polyv-live-cli 1.1.2 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/dist/commands/index.d.ts +1 -0
  2. package/dist/commands/index.d.ts.map +1 -1
  3. package/dist/commands/index.js +3 -1
  4. package/dist/commands/index.js.map +1 -1
  5. package/dist/commands/monitor.commands.d.ts +12 -0
  6. package/dist/commands/monitor.commands.d.ts.map +1 -0
  7. package/dist/commands/monitor.commands.js +75 -0
  8. package/dist/commands/monitor.commands.js.map +1 -0
  9. package/dist/components/alert.panel.d.ts +98 -0
  10. package/dist/components/alert.panel.d.ts.map +1 -0
  11. package/dist/components/alert.panel.js +1000 -0
  12. package/dist/components/alert.panel.js.map +1 -0
  13. package/dist/components/base.component.d.ts +61 -0
  14. package/dist/components/base.component.d.ts.map +1 -0
  15. package/dist/components/base.component.js +346 -0
  16. package/dist/components/base.component.js.map +1 -0
  17. package/dist/components/batch-operations.dialog.d.ts +58 -0
  18. package/dist/components/batch-operations.dialog.d.ts.map +1 -0
  19. package/dist/components/batch-operations.dialog.js +340 -0
  20. package/dist/components/batch-operations.dialog.js.map +1 -0
  21. package/dist/components/channel-details.popup.d.ts +55 -0
  22. package/dist/components/channel-details.popup.d.ts.map +1 -0
  23. package/dist/components/channel-details.popup.js +416 -0
  24. package/dist/components/channel-details.popup.js.map +1 -0
  25. package/dist/components/channel-status.panel.d.ts +129 -0
  26. package/dist/components/channel-status.panel.d.ts.map +1 -0
  27. package/dist/components/channel-status.panel.js +858 -0
  28. package/dist/components/channel-status.panel.js.map +1 -0
  29. package/dist/components/component-registry.d.ts +36 -0
  30. package/dist/components/component-registry.d.ts.map +1 -0
  31. package/dist/components/component-registry.js +119 -0
  32. package/dist/components/component-registry.js.map +1 -0
  33. package/dist/components/context-menu-factory.d.ts +13 -0
  34. package/dist/components/context-menu-factory.d.ts.map +1 -0
  35. package/dist/components/context-menu-factory.js +341 -0
  36. package/dist/components/context-menu-factory.js.map +1 -0
  37. package/dist/components/context-menu.d.ts +54 -0
  38. package/dist/components/context-menu.d.ts.map +1 -0
  39. package/dist/components/context-menu.js +235 -0
  40. package/dist/components/context-menu.js.map +1 -0
  41. package/dist/components/grid-manager.d.ts +52 -0
  42. package/dist/components/grid-manager.d.ts.map +1 -0
  43. package/dist/components/grid-manager.js +404 -0
  44. package/dist/components/grid-manager.js.map +1 -0
  45. package/dist/components/help-panel.d.ts +34 -0
  46. package/dist/components/help-panel.d.ts.map +1 -0
  47. package/dist/components/help-panel.js +249 -0
  48. package/dist/components/help-panel.js.map +1 -0
  49. package/dist/components/index.d.ts +20 -0
  50. package/dist/components/index.d.ts.map +1 -0
  51. package/dist/components/index.js +43 -0
  52. package/dist/components/index.js.map +1 -0
  53. package/dist/components/interaction-manager.d.ts +47 -0
  54. package/dist/components/interaction-manager.d.ts.map +1 -0
  55. package/dist/components/interaction-manager.js +597 -0
  56. package/dist/components/interaction-manager.js.map +1 -0
  57. package/dist/components/layout-manager.d.ts +76 -0
  58. package/dist/components/layout-manager.d.ts.map +1 -0
  59. package/dist/components/layout-manager.js +538 -0
  60. package/dist/components/layout-manager.js.map +1 -0
  61. package/dist/components/monitoring-dashboard.d.ts +85 -0
  62. package/dist/components/monitoring-dashboard.d.ts.map +1 -0
  63. package/dist/components/monitoring-dashboard.js +908 -0
  64. package/dist/components/monitoring-dashboard.js.map +1 -0
  65. package/dist/components/search-panel.d.ts +80 -0
  66. package/dist/components/search-panel.d.ts.map +1 -0
  67. package/dist/components/search-panel.js +585 -0
  68. package/dist/components/search-panel.js.map +1 -0
  69. package/dist/components/status-bar.d.ts +77 -0
  70. package/dist/components/status-bar.d.ts.map +1 -0
  71. package/dist/components/status-bar.js +482 -0
  72. package/dist/components/status-bar.js.map +1 -0
  73. package/dist/components/status.component.d.ts +16 -0
  74. package/dist/components/status.component.d.ts.map +1 -0
  75. package/dist/components/status.component.js +79 -0
  76. package/dist/components/status.component.js.map +1 -0
  77. package/dist/components/stream-metrics.panel.d.ts +86 -0
  78. package/dist/components/stream-metrics.panel.d.ts.map +1 -0
  79. package/dist/components/stream-metrics.panel.js +395 -0
  80. package/dist/components/stream-metrics.panel.js.map +1 -0
  81. package/dist/components/system-resource.panel.d.ts +78 -0
  82. package/dist/components/system-resource.panel.d.ts.map +1 -0
  83. package/dist/components/system-resource.panel.js +642 -0
  84. package/dist/components/system-resource.panel.js.map +1 -0
  85. package/dist/components/tooltip.d.ts +35 -0
  86. package/dist/components/tooltip.d.ts.map +1 -0
  87. package/dist/components/tooltip.js +156 -0
  88. package/dist/components/tooltip.js.map +1 -0
  89. package/dist/config/config-io.d.ts +63 -0
  90. package/dist/config/config-io.d.ts.map +1 -0
  91. package/dist/config/config-io.js +352 -0
  92. package/dist/config/config-io.js.map +1 -0
  93. package/dist/config/config-manager.d.ts +51 -0
  94. package/dist/config/config-manager.d.ts.map +1 -0
  95. package/dist/config/config-manager.js +404 -0
  96. package/dist/config/config-manager.js.map +1 -0
  97. package/dist/config/config-validator.d.ts +27 -0
  98. package/dist/config/config-validator.d.ts.map +1 -0
  99. package/dist/config/config-validator.js +421 -0
  100. package/dist/config/config-validator.js.map +1 -0
  101. package/dist/config/custom-theme-builder.d.ts +88 -0
  102. package/dist/config/custom-theme-builder.d.ts.map +1 -0
  103. package/dist/config/custom-theme-builder.js +458 -0
  104. package/dist/config/custom-theme-builder.js.map +1 -0
  105. package/dist/config/layout-manager.d.ts +60 -0
  106. package/dist/config/layout-manager.d.ts.map +1 -0
  107. package/dist/config/layout-manager.js +595 -0
  108. package/dist/config/layout-manager.js.map +1 -0
  109. package/dist/config/monitoring.d.ts +27 -0
  110. package/dist/config/monitoring.d.ts.map +1 -0
  111. package/dist/config/monitoring.js +276 -0
  112. package/dist/config/monitoring.js.map +1 -0
  113. package/dist/config/theme-manager.d.ts +53 -0
  114. package/dist/config/theme-manager.d.ts.map +1 -0
  115. package/dist/config/theme-manager.js +490 -0
  116. package/dist/config/theme-manager.js.map +1 -0
  117. package/dist/handlers/monitor.handler.d.ts +28 -0
  118. package/dist/handlers/monitor.handler.d.ts.map +1 -0
  119. package/dist/handlers/monitor.handler.js +457 -0
  120. package/dist/handlers/monitor.handler.js.map +1 -0
  121. package/dist/index.d.ts +9 -1
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +24 -3
  124. package/dist/index.js.map +1 -1
  125. package/dist/performance/adaptive-polling.d.ts +69 -0
  126. package/dist/performance/adaptive-polling.d.ts.map +1 -0
  127. package/dist/performance/adaptive-polling.js +313 -0
  128. package/dist/performance/adaptive-polling.js.map +1 -0
  129. package/dist/performance/api-analytics.d.ts +137 -0
  130. package/dist/performance/api-analytics.d.ts.map +1 -0
  131. package/dist/performance/api-analytics.js +351 -0
  132. package/dist/performance/api-analytics.js.map +1 -0
  133. package/dist/performance/api-optimizer.d.ts +66 -0
  134. package/dist/performance/api-optimizer.d.ts.map +1 -0
  135. package/dist/performance/api-optimizer.js +368 -0
  136. package/dist/performance/api-optimizer.js.map +1 -0
  137. package/dist/performance/batch-request-manager.d.ts +89 -0
  138. package/dist/performance/batch-request-manager.d.ts.map +1 -0
  139. package/dist/performance/batch-request-manager.js +351 -0
  140. package/dist/performance/batch-request-manager.js.map +1 -0
  141. package/dist/performance/change-detector.d.ts +75 -0
  142. package/dist/performance/change-detector.d.ts.map +1 -0
  143. package/dist/performance/change-detector.js +392 -0
  144. package/dist/performance/change-detector.js.map +1 -0
  145. package/dist/performance/connection-pool-manager.d.ts +99 -0
  146. package/dist/performance/connection-pool-manager.d.ts.map +1 -0
  147. package/dist/performance/connection-pool-manager.js +474 -0
  148. package/dist/performance/connection-pool-manager.js.map +1 -0
  149. package/dist/performance/error-recovery-manager.d.ts +134 -0
  150. package/dist/performance/error-recovery-manager.d.ts.map +1 -0
  151. package/dist/performance/error-recovery-manager.js +673 -0
  152. package/dist/performance/error-recovery-manager.js.map +1 -0
  153. package/dist/performance/fallback-manager.d.ts +123 -0
  154. package/dist/performance/fallback-manager.d.ts.map +1 -0
  155. package/dist/performance/fallback-manager.js +524 -0
  156. package/dist/performance/fallback-manager.js.map +1 -0
  157. package/dist/performance/index.d.ts +13 -0
  158. package/dist/performance/index.d.ts.map +1 -0
  159. package/dist/performance/index.js +28 -0
  160. package/dist/performance/index.js.map +1 -0
  161. package/dist/performance/memory-manager.d.ts +97 -0
  162. package/dist/performance/memory-manager.d.ts.map +1 -0
  163. package/dist/performance/memory-manager.js +417 -0
  164. package/dist/performance/memory-manager.js.map +1 -0
  165. package/dist/performance/performance-monitor.d.ts +149 -0
  166. package/dist/performance/performance-monitor.d.ts.map +1 -0
  167. package/dist/performance/performance-monitor.js +513 -0
  168. package/dist/performance/performance-monitor.js.map +1 -0
  169. package/dist/performance/performance-optimizer.d.ts +110 -0
  170. package/dist/performance/performance-optimizer.d.ts.map +1 -0
  171. package/dist/performance/performance-optimizer.js +476 -0
  172. package/dist/performance/performance-optimizer.js.map +1 -0
  173. package/dist/performance/render-optimizer.d.ts +95 -0
  174. package/dist/performance/render-optimizer.d.ts.map +1 -0
  175. package/dist/performance/render-optimizer.js +408 -0
  176. package/dist/performance/render-optimizer.js.map +1 -0
  177. package/dist/services/index.d.ts +1 -0
  178. package/dist/services/index.d.ts.map +1 -1
  179. package/dist/services/index.js +3 -1
  180. package/dist/services/index.js.map +1 -1
  181. package/dist/services/system-resource.service.d.ts +168 -0
  182. package/dist/services/system-resource.service.d.ts.map +1 -0
  183. package/dist/services/system-resource.service.js +544 -0
  184. package/dist/services/system-resource.service.js.map +1 -0
  185. package/dist/types/alert.d.ts +147 -0
  186. package/dist/types/alert.d.ts.map +1 -0
  187. package/dist/types/alert.js +3 -0
  188. package/dist/types/alert.js.map +1 -0
  189. package/dist/types/index.d.ts +3 -0
  190. package/dist/types/index.d.ts.map +1 -1
  191. package/dist/types/index.js +2 -0
  192. package/dist/types/index.js.map +1 -1
  193. package/dist/types/interaction.d.ts +147 -0
  194. package/dist/types/interaction.d.ts.map +1 -0
  195. package/dist/types/interaction.js +3 -0
  196. package/dist/types/interaction.js.map +1 -0
  197. package/dist/types/monitoring.d.ts +233 -0
  198. package/dist/types/monitoring.d.ts.map +1 -0
  199. package/dist/types/monitoring.js +35 -0
  200. package/dist/types/monitoring.js.map +1 -0
  201. package/dist/utils/alert-history-manager.d.ts +72 -0
  202. package/dist/utils/alert-history-manager.d.ts.map +1 -0
  203. package/dist/utils/alert-history-manager.js +492 -0
  204. package/dist/utils/alert-history-manager.js.map +1 -0
  205. package/dist/utils/alert-manager.d.ts +75 -0
  206. package/dist/utils/alert-manager.d.ts.map +1 -0
  207. package/dist/utils/alert-manager.js +348 -0
  208. package/dist/utils/alert-manager.js.map +1 -0
  209. package/dist/utils/alert-rule-manager.d.ts +51 -0
  210. package/dist/utils/alert-rule-manager.d.ts.map +1 -0
  211. package/dist/utils/alert-rule-manager.js +515 -0
  212. package/dist/utils/alert-rule-manager.js.map +1 -0
  213. package/dist/utils/data-manager.d.ts +53 -0
  214. package/dist/utils/data-manager.d.ts.map +1 -0
  215. package/dist/utils/data-manager.js +228 -0
  216. package/dist/utils/data-manager.js.map +1 -0
  217. package/dist/utils/formatter.d.ts +5 -0
  218. package/dist/utils/formatter.d.ts.map +1 -1
  219. package/dist/utils/formatter.js +19 -0
  220. package/dist/utils/formatter.js.map +1 -1
  221. package/dist/utils/index.d.ts +6 -0
  222. package/dist/utils/index.d.ts.map +1 -1
  223. package/dist/utils/index.js +6 -0
  224. package/dist/utils/index.js.map +1 -1
  225. package/dist/utils/keyboard-handler.d.ts +32 -0
  226. package/dist/utils/keyboard-handler.d.ts.map +1 -0
  227. package/dist/utils/keyboard-handler.js +193 -0
  228. package/dist/utils/keyboard-handler.js.map +1 -0
  229. package/dist/utils/mouse-handler.d.ts +61 -0
  230. package/dist/utils/mouse-handler.d.ts.map +1 -0
  231. package/dist/utils/mouse-handler.js +192 -0
  232. package/dist/utils/mouse-handler.js.map +1 -0
  233. package/dist/utils/stream-verification.d.ts.map +1 -1
  234. package/dist/utils/stream-verification.js +2 -13
  235. package/dist/utils/stream-verification.js.map +1 -1
  236. package/dist/utils/terminal.d.ts +24 -0
  237. package/dist/utils/terminal.d.ts.map +1 -0
  238. package/dist/utils/terminal.js +148 -0
  239. package/dist/utils/terminal.js.map +1 -0
  240. package/dist/utils/time-series.processor.d.ts +65 -0
  241. package/dist/utils/time-series.processor.d.ts.map +1 -0
  242. package/dist/utils/time-series.processor.js +263 -0
  243. package/dist/utils/time-series.processor.js.map +1 -0
  244. package/package.json +28 -4
@@ -0,0 +1,908 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MonitoringDashboard = void 0;
7
+ const blessed_1 = __importDefault(require("blessed"));
8
+ const events_1 = require("events");
9
+ const grid_manager_1 = require("./grid-manager");
10
+ const component_registry_1 = require("./component-registry");
11
+ const status_component_1 = require("./status.component");
12
+ const channel_status_panel_1 = require("./channel-status.panel");
13
+ const system_resource_panel_1 = require("./system-resource.panel");
14
+ const interaction_manager_1 = require("./interaction-manager");
15
+ const help_panel_1 = require("./help-panel");
16
+ const tooltip_1 = require("./tooltip");
17
+ const context_menu_1 = require("./context-menu");
18
+ const context_menu_factory_1 = require("./context-menu-factory");
19
+ const search_panel_1 = require("./search-panel");
20
+ const layout_manager_1 = require("./layout-manager");
21
+ class MonitoringDashboard {
22
+ constructor(config) {
23
+ this.isRunning = false;
24
+ this.cleanupHandlers = [];
25
+ this.startTime = Date.now();
26
+ this.config = config;
27
+ this.eventBus = new events_1.EventEmitter();
28
+ this.eventBus.setMaxListeners(100);
29
+ this.initializeScreen();
30
+ this.setupSignalHandlers();
31
+ this.componentRegistry = new component_registry_1.ComponentRegistry(this.eventBus);
32
+ this.registerComponentFactories();
33
+ this.gridManager = new grid_manager_1.GridManager(this.screen, this.eventBus, 12, 12);
34
+ this.setupEventListeners();
35
+ this.setupInteractionManager();
36
+ }
37
+ registerComponentFactories() {
38
+ this.componentRegistry.registerFactory(status_component_1.StatusComponentFactory);
39
+ const ChannelStatusPanelFactory = {
40
+ type: 'channel-status',
41
+ create: (config, eventBus) => {
42
+ const channelConfig = {
43
+ ...config,
44
+ refreshInterval: config.config?.refreshInterval || 5000,
45
+ maxChannels: config.config?.maxChannels || 100,
46
+ showColors: config.config?.showColors !== false,
47
+ columnWidths: config.config?.columnWidths || [20, 12, 10, 10, 15, 15],
48
+ sortField: config.config?.sortField || 'name',
49
+ sortOrder: config.config?.sortOrder || 'asc',
50
+ filters: config.config?.filters || {}
51
+ };
52
+ return new channel_status_panel_1.ChannelStatusPanel(channelConfig, eventBus);
53
+ },
54
+ };
55
+ this.componentRegistry.registerFactory(ChannelStatusPanelFactory);
56
+ const createPlaceholderFactory = (type) => ({
57
+ type,
58
+ create: (config, eventBus) => {
59
+ return new status_component_1.StatusComponent({
60
+ ...config,
61
+ type,
62
+ }, eventBus);
63
+ },
64
+ });
65
+ const SystemResourcePanelFactory = {
66
+ type: 'system-resources',
67
+ create: (config, eventBus) => {
68
+ return new system_resource_panel_1.SystemResourcePanel(config, eventBus);
69
+ },
70
+ };
71
+ this.componentRegistry.registerFactory(SystemResourcePanelFactory);
72
+ this.componentRegistry.registerFactory(createPlaceholderFactory('stream-metrics'));
73
+ this.componentRegistry.registerFactory(createPlaceholderFactory('activity-log'));
74
+ }
75
+ initializeScreen() {
76
+ const width = process.stdout.columns && process.stdout.columns > 0 ? process.stdout.columns : 120;
77
+ const height = process.stdout.rows && process.stdout.rows > 0 ? process.stdout.rows : 30;
78
+ const envWidth = process.env['POLYV_TERMINAL_WIDTH'];
79
+ const envHeight = process.env['POLYV_TERMINAL_HEIGHT'];
80
+ const finalWidth = envWidth && parseInt(envWidth) > 0 ? parseInt(envWidth) : width;
81
+ const finalHeight = envHeight && parseInt(envHeight) > 0 ? parseInt(envHeight) : height;
82
+ this.screen = blessed_1.default.screen({
83
+ smartCSR: true,
84
+ title: 'PolyV Live Monitoring Dashboard',
85
+ width: finalWidth,
86
+ height: finalHeight,
87
+ cursor: {
88
+ artificial: true,
89
+ shape: 'line',
90
+ blink: true,
91
+ color: 'white',
92
+ },
93
+ debug: false,
94
+ dockBorders: true,
95
+ fullUnicode: this.config.terminal?.unicodeSupport ?? true,
96
+ sendFocus: true,
97
+ warnings: false,
98
+ });
99
+ this.applyTheme(this.config.theme);
100
+ }
101
+ setupSignalHandlers() {
102
+ const handleShutdown = () => {
103
+ this.stop().then(() => {
104
+ process.exit(0);
105
+ }).catch((error) => {
106
+ console.error('Error during shutdown:', error);
107
+ process.exit(1);
108
+ });
109
+ };
110
+ process.on('SIGINT', handleShutdown);
111
+ process.on('SIGTERM', handleShutdown);
112
+ process.on('SIGQUIT', handleShutdown);
113
+ this.cleanupHandlers.push(() => {
114
+ process.off('SIGINT', handleShutdown);
115
+ process.off('SIGTERM', handleShutdown);
116
+ process.off('SIGQUIT', handleShutdown);
117
+ });
118
+ }
119
+ setupEventListeners() {
120
+ this.eventBus.on('component:error', (data) => {
121
+ this.handleComponentError(data);
122
+ });
123
+ this.eventBus.on('component:requestUpdate', (data) => {
124
+ this.handleComponentUpdateRequest(data);
125
+ });
126
+ this.eventBus.on('layout:changed', (data) => {
127
+ this.handleLayoutChange(data);
128
+ });
129
+ this.eventBus.on('grid:componentAdded', (_data) => {
130
+ this.screen.render();
131
+ });
132
+ this.eventBus.on('grid:componentRemoved', (_data) => {
133
+ this.screen.render();
134
+ });
135
+ this.screen.on('keypress', (ch, key) => {
136
+ this.handleKeyPress(ch, key);
137
+ });
138
+ this.screen.on('resize', () => {
139
+ this.handleScreenResize();
140
+ });
141
+ }
142
+ setupInteractionManager() {
143
+ const interactionConfig = {
144
+ mouseEnabled: this.config.terminal?.mouseSupport ?? true,
145
+ keyboardEnabled: true,
146
+ focusRing: {
147
+ enabled: true,
148
+ style: {
149
+ border: { fg: 'cyan' }
150
+ }
151
+ },
152
+ shortcuts: [
153
+ {
154
+ key: 'f5',
155
+ description: 'Refresh all data',
156
+ action: 'refresh',
157
+ global: true,
158
+ },
159
+ {
160
+ key: 'f1',
161
+ description: 'Show help',
162
+ action: 'help',
163
+ global: true,
164
+ },
165
+ {
166
+ key: 'ctrl+r',
167
+ description: 'Refresh screen',
168
+ action: 'refresh-screen',
169
+ global: true,
170
+ },
171
+ {
172
+ key: 'ctrl+l',
173
+ description: 'Clear and redraw screen',
174
+ action: 'clear-screen',
175
+ global: true,
176
+ },
177
+ {
178
+ key: 'ctrl+f',
179
+ description: 'Open search panel',
180
+ action: 'search',
181
+ global: true,
182
+ },
183
+ {
184
+ key: '/',
185
+ description: 'Open search panel',
186
+ action: 'search',
187
+ global: true,
188
+ },
189
+ {
190
+ key: 'f11',
191
+ description: 'Toggle fullscreen panel',
192
+ action: 'fullscreen',
193
+ global: true,
194
+ },
195
+ {
196
+ key: '1',
197
+ description: 'Switch to compact layout',
198
+ action: 'layout:compact',
199
+ global: true,
200
+ },
201
+ {
202
+ key: '2',
203
+ description: 'Switch to standard layout',
204
+ action: 'layout:standard',
205
+ global: true,
206
+ },
207
+ {
208
+ key: '3',
209
+ description: 'Switch to detailed layout',
210
+ action: 'layout:detailed',
211
+ global: true,
212
+ }
213
+ ],
214
+ search: {
215
+ placeholder: 'Search channels...',
216
+ caseSensitive: false,
217
+ mode: 'fuzzy',
218
+ searchFields: ['name', 'channelId', 'status'],
219
+ maxHistory: 10,
220
+ showSuggestions: true,
221
+ },
222
+ statusBar: {
223
+ enabled: true,
224
+ position: 'bottom',
225
+ height: 1,
226
+ },
227
+ };
228
+ this.interactionManager = new interaction_manager_1.InteractionManager(this.screen, interactionConfig);
229
+ this.helpPanel = new help_panel_1.HelpPanel(this.screen, this.eventBus, {
230
+ title: 'PolyV Live Monitoring Dashboard - Help',
231
+ showShortcuts: true,
232
+ showNavigation: true,
233
+ showUsageTips: true,
234
+ });
235
+ this.helpPanel.setShortcuts(this.interactionManager.getAllShortcuts());
236
+ this.tooltip = new tooltip_1.Tooltip(this.screen, this.eventBus);
237
+ this.contextMenu = new context_menu_1.ContextMenu(this.screen, this.eventBus);
238
+ this.searchPanel = new search_panel_1.SearchPanel(this.screen, this.eventBus, {
239
+ placeholder: interactionConfig.search.placeholder,
240
+ caseSensitive: interactionConfig.search.caseSensitive,
241
+ mode: interactionConfig.search.mode,
242
+ searchFields: interactionConfig.search.searchFields,
243
+ maxHistory: interactionConfig.search.maxHistory,
244
+ showSuggestions: interactionConfig.search.showSuggestions,
245
+ });
246
+ this.layoutManager = new layout_manager_1.LayoutManager(this.screen, this.eventBus);
247
+ this.setupInteractionEventHandlers();
248
+ }
249
+ setupInteractionEventHandlers() {
250
+ this.interactionManager.on('shortcut:activated', (data) => {
251
+ this.handleShortcutAction(data.action);
252
+ });
253
+ this.interactionManager.on('focus:changed', (data) => {
254
+ this.eventBus.emit('focus:changed', data);
255
+ });
256
+ this.interactionManager.on('action:refresh', () => {
257
+ this.refresh();
258
+ });
259
+ this.interactionManager.on('action:help', () => {
260
+ this.showHelp();
261
+ });
262
+ this.interactionManager.on('action:exit', () => {
263
+ this.stop();
264
+ });
265
+ this.interactionManager.on('action:fullscreen', () => {
266
+ this.toggleFullscreen();
267
+ });
268
+ this.interactionManager.on('action:panel', (data) => {
269
+ this.switchToPanel(parseInt(data.panel) - 1);
270
+ });
271
+ this.interactionManager.on('contextmenu:requested', (data) => {
272
+ this.showContextMenu(data.x, data.y, data.context, data.componentId);
273
+ });
274
+ this.interactionManager.on('component:hover', (data) => {
275
+ this.showTooltip(data);
276
+ });
277
+ this.interactionManager.on('component:hover:clear', () => {
278
+ this.tooltip.hide();
279
+ });
280
+ this.interactionManager.on('scroll:event', (_data) => {
281
+ this.tooltip.hide();
282
+ this.contextMenu.hide();
283
+ });
284
+ this.eventBus.on('contextmenu:action', (data) => {
285
+ this.handleContextMenuAction(data.action, data.componentId, data.context);
286
+ });
287
+ this.eventBus.on('search:result:selected', (data) => {
288
+ this.handleSearchResultSelected(data.result, data.query);
289
+ });
290
+ this.eventBus.on('search:shown', () => {
291
+ this.tooltip.hide();
292
+ this.contextMenu.hide();
293
+ });
294
+ this.eventBus.on('search:hidden', () => {
295
+ });
296
+ this.eventBus.on('layout:switched', (data) => {
297
+ console.log(`Layout switched from ${data.fromLayout} to ${data.toLayout}`);
298
+ });
299
+ this.eventBus.on('layout:size:insufficient', (data) => {
300
+ console.log(`Terminal size insufficient for ${data.layout}: required ${data.required.width}x${data.required.height}, current ${data.current.width}x${data.current.height}`);
301
+ });
302
+ this.eventBus.on('panel:fullscreen:entered', (data) => {
303
+ console.log(`Panel ${data.panelId} entered fullscreen mode`);
304
+ });
305
+ this.eventBus.on('panel:fullscreen:exited', (data) => {
306
+ console.log(`Panel ${data.panelId} exited fullscreen mode`);
307
+ });
308
+ }
309
+ handleShortcutAction(action) {
310
+ switch (action) {
311
+ case 'refresh':
312
+ this.refresh();
313
+ break;
314
+ case 'refresh-screen':
315
+ this.screen.realloc();
316
+ this.screen.render();
317
+ break;
318
+ case 'clear-screen':
319
+ this.screen.clear();
320
+ this.screen.render();
321
+ break;
322
+ case 'help':
323
+ this.showHelp();
324
+ break;
325
+ case 'search':
326
+ this.showSearch();
327
+ break;
328
+ case 'fullscreen':
329
+ this.toggleFullscreen();
330
+ break;
331
+ case 'layout:compact':
332
+ this.switchLayout('compact');
333
+ break;
334
+ case 'layout:standard':
335
+ this.switchLayout('standard');
336
+ break;
337
+ case 'layout:detailed':
338
+ this.switchLayout('detailed');
339
+ break;
340
+ default:
341
+ break;
342
+ }
343
+ }
344
+ toggleFullscreen() {
345
+ const focused = this.interactionManager.getCurrentFocus();
346
+ if (focused) {
347
+ this.layoutManager.toggleFullscreen(focused);
348
+ }
349
+ }
350
+ switchLayout(layoutName) {
351
+ try {
352
+ this.layoutManager.switchLayout(layoutName);
353
+ }
354
+ catch (error) {
355
+ console.error(`Failed to switch to layout ${layoutName}:`, error);
356
+ }
357
+ }
358
+ switchToPanel(index) {
359
+ const layouts = this.gridManager.getAvailableLayouts();
360
+ if (index >= 0 && index < layouts.length) {
361
+ const layout = layouts[index];
362
+ if (layout) {
363
+ this.setLayout(layout);
364
+ }
365
+ }
366
+ }
367
+ showContextMenu(x, y, context, componentId) {
368
+ this.tooltip.hide();
369
+ const menuItems = context_menu_factory_1.ContextMenuFactory.generateMenuItems(context || 'global', componentId || '', this.getComponentContext(componentId, context));
370
+ const filteredItems = context_menu_factory_1.ContextMenuFactory.filterMenuItems(menuItems);
371
+ const enhancedItems = context_menu_factory_1.ContextMenuFactory.addShortcutsToMenuItems(filteredItems, new Map());
372
+ if (enhancedItems.length === 0) {
373
+ return;
374
+ }
375
+ this.contextMenu.show({
376
+ items: enhancedItems,
377
+ x,
378
+ y,
379
+ context,
380
+ componentId,
381
+ autoHide: true,
382
+ style: {
383
+ fg: 'white',
384
+ bg: 'black',
385
+ selectedFg: 'black',
386
+ selectedBg: 'cyan',
387
+ border: {
388
+ fg: 'gray',
389
+ },
390
+ },
391
+ });
392
+ }
393
+ getComponentContext(componentId, context) {
394
+ if (!componentId || !context) {
395
+ return {};
396
+ }
397
+ return {
398
+ componentId,
399
+ context,
400
+ status: context === 'channel-status' ? 'live' : 'unknown',
401
+ channelData: context === 'channel-status' ? { id: componentId } : undefined,
402
+ };
403
+ }
404
+ handleContextMenuAction(action, componentId, context) {
405
+ switch (action) {
406
+ case 'channel:view-details':
407
+ this.handleChannelViewDetails(componentId);
408
+ break;
409
+ case 'channel:refresh':
410
+ this.handleChannelRefresh(componentId);
411
+ break;
412
+ case 'channel:start-stream':
413
+ this.handleChannelStartStream(componentId);
414
+ break;
415
+ case 'channel:stop-stream':
416
+ this.handleChannelStopStream(componentId);
417
+ break;
418
+ case 'channel:stream-info':
419
+ this.handleChannelStreamInfo(componentId);
420
+ break;
421
+ case 'channel:copy-id':
422
+ this.handleChannelCopyId(componentId);
423
+ break;
424
+ case 'channel:export':
425
+ this.handleChannelExport(componentId);
426
+ break;
427
+ case 'channel:delete':
428
+ this.handleChannelDelete(componentId);
429
+ break;
430
+ case 'system:refresh':
431
+ this.handleSystemRefresh(componentId);
432
+ break;
433
+ case 'system:view-history':
434
+ this.handleSystemViewHistory(componentId);
435
+ break;
436
+ case 'system:configure-alerts':
437
+ this.handleSystemConfigureAlerts(componentId);
438
+ break;
439
+ case 'system:export':
440
+ this.handleSystemExport(componentId);
441
+ break;
442
+ case 'system:reset':
443
+ this.handleSystemReset(componentId);
444
+ break;
445
+ case 'system:settings':
446
+ this.handleSystemSettings(componentId);
447
+ break;
448
+ case 'dashboard:refresh-all':
449
+ this.refresh();
450
+ break;
451
+ case 'dashboard:clear':
452
+ this.screen.clear();
453
+ this.screen.render();
454
+ break;
455
+ case 'dashboard:settings':
456
+ this.handleDashboardSettings();
457
+ break;
458
+ case 'dashboard:help':
459
+ this.showHelp();
460
+ break;
461
+ case 'dashboard:exit':
462
+ this.stop();
463
+ break;
464
+ case 'component:focus':
465
+ this.handleComponentFocus(componentId);
466
+ break;
467
+ case 'component:refresh':
468
+ this.handleComponentRefresh(componentId);
469
+ break;
470
+ case 'component:fullscreen':
471
+ this.toggleFullscreen();
472
+ break;
473
+ case 'component:help':
474
+ this.showHelp();
475
+ break;
476
+ default:
477
+ console.log(`Unhandled context menu action: ${action}`);
478
+ break;
479
+ }
480
+ this.eventBus.emit('contextmenu:action:executed', {
481
+ action,
482
+ componentId,
483
+ context,
484
+ timestamp: new Date(),
485
+ });
486
+ }
487
+ showTooltip(data) {
488
+ const content = this.generateTooltipContent(data.componentType, data.componentId);
489
+ if (content) {
490
+ this.tooltip.show({
491
+ content,
492
+ x: data.x,
493
+ y: data.y,
494
+ maxWidth: 50,
495
+ autoHideDelay: 3000,
496
+ style: {
497
+ fg: 'white',
498
+ bg: 'black',
499
+ border: {
500
+ fg: 'yellow',
501
+ },
502
+ },
503
+ });
504
+ }
505
+ }
506
+ generateTooltipContent(componentType, componentId) {
507
+ switch (componentType) {
508
+ case 'channel-status':
509
+ return `Channel Status Panel\nID: ${componentId}\n\nFeatures:\n• Real-time channel monitoring\n• Status indicators\n• Quick actions\n\nTip: Right-click for menu`;
510
+ case 'system-resource':
511
+ return `System Resource Monitor\nID: ${componentId}\n\nShows:\n• CPU usage\n• Memory usage\n• Network activity\n\nTip: Scroll to view history`;
512
+ case 'stream-metrics':
513
+ return `Stream Metrics Panel\nID: ${componentId}\n\nMetrics:\n• Bitrate\n• Frame rate\n• Quality indicators\n\nTip: Click to focus panel`;
514
+ case 'help-panel':
515
+ return `Help Panel\n\nKeyboard shortcuts:\n• ESC/Q - Close\n• Arrow keys - Scroll\n• Enter - Close`;
516
+ default:
517
+ return `${componentType}\nID: ${componentId}\n\nTip: Use Tab to navigate\nPress F1 for help`;
518
+ }
519
+ }
520
+ handleComponentError(data) {
521
+ console.error(`Component error (${data.componentId}):`, data.error);
522
+ this.eventBus.emit('dashboard:error', {
523
+ type: 'component',
524
+ message: data.error,
525
+ componentId: data.componentId,
526
+ timestamp: new Date(),
527
+ });
528
+ }
529
+ handleComponentUpdateRequest(data) {
530
+ this.eventBus.emit('data:requestUpdate', {
531
+ componentId: data.componentId,
532
+ type: data.type,
533
+ timestamp: data.timestamp,
534
+ });
535
+ }
536
+ handleLayoutChange(_data) {
537
+ this.reinitializeComponents();
538
+ }
539
+ handleKeyPress(_ch, _key) {
540
+ }
541
+ handleScreenResize() {
542
+ const width = this.screen.width || 80;
543
+ const height = this.screen.height || 24;
544
+ const currentLayout = this.gridManager.getCurrentLayout();
545
+ const layoutConfig = this.gridManager.getLayoutConfig(currentLayout);
546
+ if (layoutConfig &&
547
+ (width < layoutConfig.minTerminalSize.width ||
548
+ height < layoutConfig.minTerminalSize.height)) {
549
+ this.switchToCompatibleLayout(width, height);
550
+ }
551
+ this.screen.render();
552
+ }
553
+ switchToCompatibleLayout(width, height) {
554
+ const layouts = this.gridManager.getAvailableLayouts();
555
+ for (const layoutName of layouts) {
556
+ const layoutConfig = this.gridManager.getLayoutConfig(layoutName);
557
+ if (layoutConfig &&
558
+ width >= layoutConfig.minTerminalSize.width &&
559
+ height >= layoutConfig.minTerminalSize.height) {
560
+ this.setLayout(layoutName);
561
+ break;
562
+ }
563
+ }
564
+ }
565
+ applyTheme(themeName) {
566
+ const themes = {
567
+ 'default': {
568
+ colors: {
569
+ primary: 'blue',
570
+ secondary: 'cyan',
571
+ background: 'black',
572
+ foreground: 'white',
573
+ accent: 'yellow',
574
+ error: 'red',
575
+ warning: 'yellow',
576
+ success: 'green',
577
+ info: 'blue',
578
+ muted: 'gray',
579
+ highlight: 'yellow',
580
+ border: 'white',
581
+ selection: 'blue',
582
+ },
583
+ },
584
+ dark: {
585
+ colors: {
586
+ primary: 'white',
587
+ secondary: 'gray',
588
+ background: 'black',
589
+ foreground: 'white',
590
+ accent: 'cyan',
591
+ error: 'red',
592
+ warning: 'yellow',
593
+ success: 'green',
594
+ info: 'blue',
595
+ muted: 'gray',
596
+ highlight: 'cyan',
597
+ border: 'gray',
598
+ selection: 'white',
599
+ },
600
+ },
601
+ };
602
+ const theme = themes[themeName] || themes['default'];
603
+ this.eventBus.emit('theme:change', {
604
+ theme: themeName,
605
+ config: theme,
606
+ timestamp: new Date(),
607
+ });
608
+ }
609
+ reinitializeComponents() {
610
+ this.componentRegistry.removeAllComponents();
611
+ const layout = this.gridManager.getCurrentLayout();
612
+ const layoutConfig = this.gridManager.getLayoutConfig(layout);
613
+ if (layoutConfig) {
614
+ for (const componentLayout of layoutConfig.components) {
615
+ try {
616
+ const config = {
617
+ type: componentLayout.type,
618
+ position: componentLayout.position,
619
+ size: componentLayout.size,
620
+ config: componentLayout.config,
621
+ visible: true,
622
+ priority: 1,
623
+ };
624
+ const component = this.componentRegistry.createComponent(config);
625
+ this.gridManager.addComponent(component, componentLayout.position);
626
+ if (component && typeof component.canFocus === 'function') {
627
+ this.interactionManager.registerComponent(component);
628
+ }
629
+ if (component) {
630
+ this.layoutManager.registerPanel(componentLayout.type, component);
631
+ }
632
+ }
633
+ catch (error) {
634
+ console.error(`Failed to create component ${componentLayout.type}:`, error);
635
+ }
636
+ }
637
+ }
638
+ }
639
+ handleChannelViewDetails(componentId) {
640
+ console.log(`Viewing details for channel: ${componentId}`);
641
+ }
642
+ handleChannelRefresh(componentId) {
643
+ console.log(`Refreshing channel: ${componentId}`);
644
+ }
645
+ handleChannelStartStream(componentId) {
646
+ console.log(`Starting stream for channel: ${componentId}`);
647
+ }
648
+ handleChannelStopStream(componentId) {
649
+ console.log(`Stopping stream for channel: ${componentId}`);
650
+ }
651
+ handleChannelStreamInfo(componentId) {
652
+ console.log(`Viewing stream info for channel: ${componentId}`);
653
+ }
654
+ handleChannelCopyId(componentId) {
655
+ console.log(`Copying channel ID: ${componentId}`);
656
+ }
657
+ handleChannelExport(componentId) {
658
+ console.log(`Exporting channel data: ${componentId}`);
659
+ }
660
+ handleChannelDelete(componentId) {
661
+ console.log(`Deleting channel: ${componentId}`);
662
+ }
663
+ handleSystemRefresh(componentId) {
664
+ console.log(`Refreshing system metrics: ${componentId}`);
665
+ }
666
+ handleSystemViewHistory(componentId) {
667
+ console.log(`Viewing system history: ${componentId}`);
668
+ }
669
+ handleSystemConfigureAlerts(componentId) {
670
+ console.log(`Configuring alerts: ${componentId}`);
671
+ }
672
+ handleSystemExport(componentId) {
673
+ console.log(`Exporting system metrics: ${componentId}`);
674
+ }
675
+ handleSystemReset(componentId) {
676
+ console.log(`Resetting system counters: ${componentId}`);
677
+ }
678
+ handleSystemSettings(componentId) {
679
+ console.log(`Opening system settings: ${componentId}`);
680
+ }
681
+ handleDashboardSettings() {
682
+ console.log('Opening dashboard settings');
683
+ }
684
+ handleComponentFocus(componentId) {
685
+ if (componentId) {
686
+ this.interactionManager.setFocus(componentId);
687
+ }
688
+ }
689
+ handleComponentRefresh(componentId) {
690
+ console.log(`Refreshing component: ${componentId}`);
691
+ }
692
+ showHelp() {
693
+ this.helpPanel.setShortcuts(this.interactionManager.getAllShortcuts());
694
+ this.helpPanel.show();
695
+ }
696
+ showSearch() {
697
+ const searchData = this.gatherSearchableData();
698
+ this.searchPanel.setDataSource(searchData);
699
+ this.searchPanel.show();
700
+ }
701
+ gatherSearchableData() {
702
+ const searchData = [];
703
+ const components = this.componentRegistry.getAllComponents();
704
+ components.forEach((component, componentId) => {
705
+ try {
706
+ if (typeof component.getSearchableData === 'function') {
707
+ const componentData = component.getSearchableData();
708
+ if (Array.isArray(componentData)) {
709
+ componentData.forEach(item => {
710
+ searchData.push({
711
+ ...item,
712
+ componentId,
713
+ componentType: component.constructor.name,
714
+ });
715
+ });
716
+ }
717
+ }
718
+ }
719
+ catch (error) {
720
+ }
721
+ });
722
+ if (searchData.length === 0) {
723
+ searchData.push({
724
+ id: 'ch001',
725
+ name: 'Live Stream Channel 1',
726
+ status: 'live',
727
+ type: 'channel',
728
+ componentType: 'ChannelStatusPanel',
729
+ }, {
730
+ id: 'ch002',
731
+ name: 'Test Channel',
732
+ status: 'offline',
733
+ type: 'channel',
734
+ componentType: 'ChannelStatusPanel',
735
+ }, {
736
+ id: 'sys001',
737
+ name: 'System Resources',
738
+ status: 'active',
739
+ type: 'system',
740
+ componentType: 'SystemResourcePanel',
741
+ });
742
+ }
743
+ return searchData;
744
+ }
745
+ handleSearchResultSelected(result, query) {
746
+ console.log(`Search result selected: ${result.item.name} (query: ${query})`);
747
+ if (result.item.componentId) {
748
+ this.interactionManager.setFocus(result.item.componentId);
749
+ }
750
+ this.eventBus.emit('search:action:executed', {
751
+ result,
752
+ query,
753
+ action: 'focus-component',
754
+ timestamp: new Date(),
755
+ });
756
+ this.searchPanel.hide();
757
+ }
758
+ async start() {
759
+ if (this.isRunning) {
760
+ throw new Error('Dashboard is already running');
761
+ }
762
+ try {
763
+ this.isRunning = true;
764
+ this.createWelcomeScreen();
765
+ this.eventBus.emit('dashboard:started', {
766
+ timestamp: new Date(),
767
+ config: this.config,
768
+ });
769
+ this.screen.render();
770
+ this.startRefreshCycle();
771
+ }
772
+ catch (error) {
773
+ this.isRunning = false;
774
+ throw error;
775
+ }
776
+ }
777
+ createWelcomeScreen() {
778
+ const welcomeBox = blessed_1.default.box({
779
+ top: 'center',
780
+ left: 'center',
781
+ width: '80%',
782
+ height: '60%',
783
+ content: this.getWelcomeMessage(),
784
+ tags: true,
785
+ border: {
786
+ type: 'line',
787
+ },
788
+ style: {
789
+ fg: 'white',
790
+ bg: 'black',
791
+ border: {
792
+ fg: 'cyan',
793
+ },
794
+ },
795
+ label: ' PolyV Live Monitoring Dashboard ',
796
+ });
797
+ this.screen.append(welcomeBox);
798
+ }
799
+ getWelcomeMessage() {
800
+ return `
801
+ {center}Welcome to PolyV Live Monitoring Dashboard{/center}
802
+
803
+ {cyan-fg}Dashboard Status:{/cyan-fg}
804
+ • Status: Running
805
+ • Layout: ${this.config.layout}
806
+ • Theme: ${this.config.theme}
807
+ • Refresh Interval: ${this.config.refreshInterval}ms
808
+
809
+ {cyan-fg}Available Commands:{/cyan-fg}
810
+ • Press 'q', 'Escape', or 'Ctrl+C' to exit
811
+ • Press 'Ctrl+R' to refresh
812
+ • Press 'Ctrl+L' to clear screen
813
+ • Press '?' or 'h' for help
814
+
815
+ {cyan-fg}Features (Coming Soon):{/cyan-fg}
816
+ • Stream metrics monitoring
817
+ • Channel status tracking
818
+ • System resource monitoring
819
+ • Activity logging
820
+
821
+ {yellow-fg}Note: This is a basic interface. Full grid-based dashboard is under development.{/yellow-fg}
822
+
823
+ Press any key to continue monitoring...
824
+ `;
825
+ }
826
+ async stop() {
827
+ if (!this.isRunning) {
828
+ return;
829
+ }
830
+ try {
831
+ this.isRunning = false;
832
+ this.stopRefreshCycle();
833
+ this.componentRegistry.removeAllComponents();
834
+ this.gridManager.destroy();
835
+ if (this.interactionManager) {
836
+ this.interactionManager.destroy();
837
+ }
838
+ if (this.searchPanel) {
839
+ this.searchPanel.destroy();
840
+ }
841
+ if (this.layoutManager) {
842
+ this.layoutManager.destroy();
843
+ }
844
+ this.cleanupHandlers.forEach(handler => handler());
845
+ this.cleanupHandlers = [];
846
+ this.screen.destroy();
847
+ this.eventBus.emit('dashboard:stopped', {
848
+ timestamp: new Date(),
849
+ });
850
+ }
851
+ catch (error) {
852
+ console.error('Error stopping dashboard:', error);
853
+ }
854
+ }
855
+ refresh() {
856
+ this.eventBus.emit('dashboard:refresh', {
857
+ timestamp: new Date(),
858
+ });
859
+ this.screen.render();
860
+ }
861
+ setLayout(layoutName) {
862
+ try {
863
+ this.gridManager.setLayout(layoutName);
864
+ this.reinitializeComponents();
865
+ this.screen.render();
866
+ }
867
+ catch (error) {
868
+ console.error(`Failed to set layout ${layoutName}:`, error);
869
+ }
870
+ }
871
+ getStatus() {
872
+ return {
873
+ isRunning: this.isRunning,
874
+ layout: this.gridManager.getCurrentLayout(),
875
+ components: this.componentRegistry.getComponentCount(),
876
+ uptime: this.isRunning ? Date.now() - this.startTime : 0,
877
+ };
878
+ }
879
+ startRefreshCycle() {
880
+ this.refreshInterval = setInterval(() => {
881
+ if (this.isRunning) {
882
+ this.eventBus.emit('dashboard:tick', {
883
+ timestamp: new Date(),
884
+ });
885
+ }
886
+ }, this.config.refreshInterval);
887
+ }
888
+ stopRefreshCycle() {
889
+ if (this.refreshInterval) {
890
+ clearInterval(this.refreshInterval);
891
+ this.refreshInterval = undefined;
892
+ }
893
+ }
894
+ getComponentRegistry() {
895
+ return this.componentRegistry;
896
+ }
897
+ getGridManager() {
898
+ return this.gridManager;
899
+ }
900
+ getEventBus() {
901
+ return this.eventBus;
902
+ }
903
+ getScreen() {
904
+ return this.screen;
905
+ }
906
+ }
907
+ exports.MonitoringDashboard = MonitoringDashboard;
908
+ //# sourceMappingURL=monitoring-dashboard.js.map