modernx-gui 1.1.1

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.
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # ModernX GUI
2
+
3
+ Development GUI with real-time visualization for ModernX applications, providing comprehensive debugging and state inspection capabilities.
4
+
5
+ ## Features
6
+
7
+ - **Real-time Visualization**: Live display of Redux state and actions
8
+ - **Project Structure Analysis**: Automatic detection and visualization of ModernX models
9
+ - **WebSocket Communication**: Real-time data synchronization between app and GUI
10
+ - **Action History**: Complete history of Redux actions with timestamps and payloads
11
+ - **State Inspector**: Visual tree view of application state
12
+ - **Hot Module Replacement**: Automatic GUI updates during development
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install modernx-gui --save-dev
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### Command Line Interface
23
+
24
+ Start the GUI from any ModernX project directory:
25
+
26
+ ```bash
27
+ npx modernx-gui
28
+ ```
29
+
30
+ This will:
31
+ 1. Automatically detect your ModernX project structure
32
+ 2. Start a local development server
33
+ 3. Open your default browser to the GUI interface
34
+ 4. Begin real-time state monitoring
35
+
36
+ ### Programmatic Integration
37
+
38
+ ```javascript
39
+ import modernx from 'modernx';
40
+ import gui from 'modernx-gui';
41
+
42
+ const app = modernx({
43
+ plugins: [
44
+ gui({
45
+ port: 3000,
46
+ autoOpen: true,
47
+ websocket: true,
48
+ }),
49
+ ],
50
+ });
51
+ ```
52
+
53
+ ### CLI Integration
54
+
55
+ When creating a new ModernX project, you can include the GUI automatically:
56
+
57
+ ```bash
58
+ npx modernx create my-app --tools gui
59
+ ```
60
+
61
+ ## GUI Interface
62
+
63
+ ### Project Structure Panel
64
+
65
+ - **Models List**: Displays all detected ModernX models
66
+ - **File Tree**: Shows project structure and relationships
67
+ - **Configuration**: Shows current ModernX configuration
68
+
69
+ ### State Viewer
70
+
71
+ - **Current State**: Real-time display of application state
72
+ - **State Tree**: Expandable tree view of nested state
73
+ - **State Diff**: Visual diff between state changes
74
+
75
+ ### Action History
76
+
77
+ - **Action Timeline**: Chronological list of all actions
78
+ - **Action Details**: Payload, timestamp, and metadata
79
+ - **State Transitions**: Visual representation of state changes
80
+
81
+ ### Real-time Monitoring
82
+
83
+ - **Live Updates**: Automatic state and action updates
84
+ - **Performance Metrics**: Action execution time and performance
85
+ - **Error Tracking**: Visual error reporting and stack traces
86
+
87
+ ## Configuration Options
88
+
89
+ | Option | Type | Default | Description |
90
+ |--------|------|---------|-------------|
91
+ | `port` | number | `3000` | GUI server port |
92
+ | `autoOpen` | boolean | `true` | Auto-open browser |
93
+ | `websocket` | boolean | `true` | Enable WebSocket communication |
94
+ | `host` | string | `'localhost'` | GUI server host |
95
+
96
+ ### Example Configuration
97
+
98
+ ```javascript
99
+ gui({
100
+ port: 3001,
101
+ autoOpen: false,
102
+ websocket: true,
103
+ host: '0.0.0.0', // Allow remote connections
104
+ });
105
+ ```
106
+
107
+ ## Development Workflow
108
+
109
+ ### 1. Start Development Server
110
+
111
+ ```bash
112
+ cd my-modernx-app
113
+ npx modernx-gui
114
+ ```
115
+
116
+ ### 2. Start Your Application
117
+
118
+ ```bash
119
+ npm run dev
120
+ ```
121
+
122
+ ### 3. Open GUI Interface
123
+
124
+ The GUI will automatically:
125
+ - Detect your running ModernX application
126
+ - Connect via WebSocket for real-time updates
127
+ - Display current state and action history
128
+
129
+ ### 4. Monitor and Debug
130
+
131
+ Use the GUI interface to:
132
+ - Inspect current application state
133
+ - Review action history and payloads
134
+ - Monitor performance metrics
135
+ - Track state changes in real-time
136
+
137
+ ## WebSocket Protocol
138
+
139
+ The GUI communicates with your application via WebSocket:
140
+
141
+ ```javascript
142
+ // Send state update to GUI
143
+ ws.send(JSON.stringify({
144
+ type: 'state_update',
145
+ payload: newState,
146
+ timestamp: Date.now(),
147
+ }));
148
+
149
+ // Send action to GUI
150
+ ws.send(JSON.stringify({
151
+ type: 'action',
152
+ payload: {
153
+ type: 'USER_ACTION',
154
+ payload: actionData,
155
+ },
156
+ timestamp: Date.now(),
157
+ }));
158
+ ```
159
+
160
+ ## Migration from DVA GUI
161
+
162
+ If you're migrating from DVA, the ModernX GUI provides enhanced capabilities:
163
+
164
+ ```javascript
165
+ // DVA GUI (Electron-based)
166
+ import dva from 'dva';
167
+ import gui from 'dva-gui';
168
+
169
+ // ModernX GUI (Web-based, enhanced)
170
+ import modernx from 'modernx';
171
+ import gui from 'modernx-gui';
172
+
173
+ // Enhanced features:
174
+ // - WebSocket real-time communication
175
+ // - Cross-browser compatibility
176
+ // - Hot module replacement
177
+ // - Enhanced state visualization
178
+ ```
179
+
180
+ ## Browser Compatibility
181
+
182
+ - **Chrome**: Full support
183
+ - **Firefox**: Full support
184
+ - **Safari**: Full support
185
+ - **Edge**: Full support
186
+ - **Legacy browsers**: Graceful degradation
187
+
188
+ ## Development
189
+
190
+ ### Building
191
+
192
+ ```bash
193
+ npm run build
194
+ ```
195
+
196
+ ### Development Mode
197
+
198
+ ```bash
199
+ npm run dev
200
+ ```
201
+
202
+ ### Testing
203
+
204
+ ```bash
205
+ npm test
206
+ ```
207
+
208
+ ## Troubleshooting
209
+
210
+ ### Common Issues
211
+
212
+ 1. **GUI not connecting**
213
+ - Check if WebSocket is enabled
214
+ - Verify port availability
215
+ - Check firewall settings
216
+
217
+ 2. **Project not detected**
218
+ - Ensure `package.json` has ModernX dependency
219
+ - Check for `src/models/` directory
220
+ - Verify project structure
221
+
222
+ 3. **Browser not opening**
223
+ - Check default browser settings
224
+ - Try manual browser navigation to GUI URL
225
+ - Verify port is not in use
226
+
227
+ ### Debug Mode
228
+
229
+ Enable debug logging:
230
+
231
+ ```bash
232
+ DEBUG=modernx-gui:* npx modernx-gui
233
+ ```
234
+
235
+ ## License
236
+
237
+ MIT
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { startServer } = require('../lib/server');
4
+ const { detectProject } = require('../lib/project-detector');
5
+ const { openBrowser } = require('../lib/browser');
6
+
7
+ async function main() {
8
+ try {
9
+ console.log('🚀 Starting ModernX GUI...');
10
+
11
+ // Detect current project structure
12
+ const projectInfo = await detectProject(process.cwd());
13
+ console.log('📁 Project detected:', projectInfo.name);
14
+
15
+ // Start development server
16
+ const server = await startServer({
17
+ port: 3000,
18
+ projectInfo,
19
+ });
20
+
21
+ console.log(`🌐 GUI Server running at: ${server.url}`);
22
+
23
+ // Open browser automatically
24
+ await openBrowser(server.url);
25
+ console.log('✅ ModernX GUI is ready!');
26
+
27
+ } catch (error) {
28
+ console.error('❌ Failed to start ModernX GUI:', error.message);
29
+ process.exit(1);
30
+ }
31
+ }
32
+
33
+ main();
@@ -0,0 +1,326 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ModernX GUI 开发版本启动脚本
5
+ * 直接使用源代码,无需构建
6
+ */
7
+
8
+ const express = require('express');
9
+ const WebSocket = require('ws');
10
+ const path = require('path');
11
+ const fs = require('fs');
12
+
13
+ // 直接导入源代码模块
14
+ const { detectProject } = require('./src/lib/project-detector.js');
15
+
16
+ async function openBrowser(url) {
17
+ try {
18
+ const { execSync } = require('child_process');
19
+ const platform = process.platform;
20
+
21
+ if (platform === 'darwin') {
22
+ execSync(`open "${url}"`);
23
+ } else if (platform === 'win32') {
24
+ execSync(`start "${url}"`);
25
+ } else {
26
+ execSync(`xdg-open "${url}"`);
27
+ }
28
+
29
+ console.log(`🌐 已在浏览器中打开: ${url}`);
30
+ } catch (error) {
31
+ console.warn('无法自动打开浏览器:', error.message);
32
+ console.log(`请手动访问: ${url}`);
33
+ }
34
+ }
35
+
36
+ async function startServer(options = {}) {
37
+ const app = express();
38
+ const port = options.port || 3000;
39
+
40
+ // 创建一个简单的 HTML 界面(因为还没有构建前端)
41
+ app.get('/', (req, res) => {
42
+ const html = `
43
+ <!DOCTYPE html>
44
+ <html lang="zh-CN">
45
+ <head>
46
+ <meta charset="UTF-8">
47
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
48
+ <title>ModernX GUI - 开发版</title>
49
+ <style>
50
+ * { margin: 0; padding: 0; box-sizing: border-box; }
51
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f5f5f5; }
52
+ .header { background: #2563eb; color: white; padding: 1rem; display: flex; justify-content: space-between; align-items: center; }
53
+ .header h1 { font-size: 1.5rem; }
54
+ .status { display: flex; align-items: center; gap: 0.5rem; }
55
+ .status-dot { width: 12px; height: 12px; border-radius: 50%; background: #10b981; }
56
+ .container { display: grid; grid-template-columns: 300px 1fr; height: calc(100vh - 60px); }
57
+ .sidebar { background: white; border-right: 1px solid #e5e7eb; padding: 1rem; overflow-y: auto; }
58
+ .main-content { padding: 1rem; overflow-y: auto; }
59
+ .card { background: white; border-radius: 8px; padding: 1rem; margin-bottom: 1rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
60
+ .card h3 { margin-bottom: 0.5rem; color: #374151; }
61
+ .state-display { background: #1f2937; color: #10b981; padding: 1rem; border-radius: 4px; font-family: 'Monaco', 'Consolas', monospace; font-size: 0.875rem; white-space: pre-wrap; max-height: 300px; overflow-y: auto; }
62
+ .action-item { background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 4px; padding: 0.75rem; margin-bottom: 0.5rem; }
63
+ .action-type { font-weight: 600; color: #2563eb; }
64
+ .action-time { font-size: 0.75rem; color: #6b7280; margin-left: 0.5rem; }
65
+ .action-payload { background: #1f2937; color: #f3f4f6; padding: 0.5rem; border-radius: 4px; font-family: monospace; font-size: 0.75rem; margin-top: 0.5rem; white-space: pre-wrap; }
66
+ .models-list ul { list-style: none; }
67
+ .models-list li { background: #f3f4f6; padding: 0.5rem; border-radius: 4px; margin-bottom: 0.25rem; }
68
+ .connection-status { display: flex; align-items: center; gap: 0.5rem; }
69
+ .connected { color: #10b981; }
70
+ .disconnected { color: #ef4444; }
71
+ </style>
72
+ </head>
73
+ <body>
74
+ <header class="header">
75
+ <h1>🎨 ModernX GUI</h1>
76
+ <div class="connection-status">
77
+ <div class="status-dot"></div>
78
+ <span id="connection-status">连接中...</span>
79
+ </div>
80
+ </header>
81
+
82
+ <div class="container">
83
+ <aside class="sidebar">
84
+ <div class="card">
85
+ <h3>📁 项目信息</h3>
86
+ <div id="project-info">
87
+ <p>加载中...</p>
88
+ </div>
89
+ </div>
90
+
91
+ <div class="card">
92
+ <h3>📊 模型列表</h3>
93
+ <div class="models-list">
94
+ <ul id="models-list">
95
+ <li>加载中...</li>
96
+ </ul>
97
+ </div>
98
+ </div>
99
+ </aside>
100
+
101
+ <main class="main-content">
102
+ <div class="card">
103
+ <h3>🔄 当前状态</h3>
104
+ <div class="state-display" id="state-display">
105
+ {
106
+ "user": {
107
+ "currentUser": null,
108
+ "loading": false,
109
+ "error": null
110
+ },
111
+ "counter": {
112
+ "count": 0,
113
+ "history": []
114
+ }
115
+ }
116
+ </div>
117
+ </div>
118
+
119
+ <div class="card">
120
+ <h3>⚡ 动作历史</h3>
121
+ <div id="actions-history">
122
+ <div class="action-item">
123
+ <div>
124
+ <span class="action-type">等待动作...</span>
125
+ <span class="action-time">--:--:--</span>
126
+ </div>
127
+ </div>
128
+ </div>
129
+ </div>
130
+ </main>
131
+ </div>
132
+
133
+ <script>
134
+ let ws;
135
+ let actions = [];
136
+
137
+ // 连接 WebSocket
138
+ function connectWebSocket() {
139
+ const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
140
+ ws = new WebSocket(\`\${protocol}//\${window.location.host}\`);
141
+
142
+ ws.onopen = () => {
143
+ console.log('Connected to ModernX GUI');
144
+ document.getElementById('connection-status').textContent = '已连接';
145
+ document.querySelector('.status-dot').style.background = '#10b981';
146
+ };
147
+
148
+ ws.onmessage = (event) => {
149
+ try {
150
+ const data = JSON.parse(event.data);
151
+
152
+ if (data.type === 'state_update') {
153
+ document.getElementById('state-display').textContent = JSON.stringify(data.payload, null, 2);
154
+ } else if (data.type === 'action') {
155
+ addActionToHistory(data.payload);
156
+ }
157
+ } catch (error) {
158
+ console.error('Error parsing message:', error);
159
+ }
160
+ };
161
+
162
+ ws.onclose = () => {
163
+ console.log('Disconnected from ModernX GUI');
164
+ document.getElementById('connection-status').textContent = '连接断开';
165
+ document.querySelector('.status-dot').style.background = '#ef4444';
166
+ // 尝试重连
167
+ setTimeout(connectWebSocket, 2000);
168
+ };
169
+ }
170
+
171
+ // 添加动作到历史记录
172
+ function addActionToHistory(action) {
173
+ actions.unshift(action);
174
+ if (actions.length > 50) actions.pop(); // 只保留最近50条
175
+
176
+ const historyContainer = document.getElementById('actions-history');
177
+ historyContainer.innerHTML = actions.map(action => \`
178
+ <div class="action-item">
179
+ <div>
180
+ <span class="action-type">\${action.type}</span>
181
+ <span class="action-time">\${new Date(action.timestamp).toLocaleTimeString()}</span>
182
+ </div>
183
+ <div class="action-payload">\${JSON.stringify(action.payload, null, 2)}</div>
184
+ </div>
185
+ \`).join('');
186
+ }
187
+
188
+ // 加载项目信息
189
+ async function loadProjectInfo() {
190
+ try {
191
+ const response = await fetch('/api/project');
192
+ const projectInfo = await response.json();
193
+
194
+ document.getElementById('project-info').innerHTML = \`
195
+ <p><strong>项目名称:</strong> \${projectInfo.name || '未知'}</p>
196
+ <p><strong>项目路径:</strong> \${projectInfo.path || '未知'}</p>
197
+ <p><strong>ModernX 项目:</strong> \${projectInfo.isModernX ? '✅ 是' : '❌ 否'}</p>
198
+ \`;
199
+
200
+ const modelsList = document.getElementById('models-list');
201
+ if (projectInfo.models && projectInfo.models.length > 0) {
202
+ modelsList.innerHTML = projectInfo.models.map(model =>
203
+ \`<li>\${model}</li>\`
204
+ ).join('');
205
+ } else {
206
+ modelsList.innerHTML = '<li>暂无模型文件</li>';
207
+ }
208
+ } catch (error) {
209
+ console.error('Failed to load project info:', error);
210
+ }
211
+ }
212
+
213
+ // 初始化
214
+ document.addEventListener('DOMContentLoaded', () => {
215
+ connectWebSocket();
216
+ loadProjectInfo();
217
+ });
218
+ </script>
219
+ </body>
220
+ </html>`;
221
+ res.send(html);
222
+ });
223
+
224
+ // API endpoint for project info
225
+ app.get('/api/project', (req, res) => {
226
+ res.json(options.projectInfo || {});
227
+ });
228
+
229
+ // WebSocket server for real-time communication
230
+ const server = app.listen(port, () => {
231
+ console.log(`🚀 ModernX GUI 服务器运行在端口 ${port}`);
232
+ });
233
+
234
+ const wss = new WebSocket.Server({ server });
235
+
236
+ // Handle WebSocket connections
237
+ wss.on('connection', (ws) => {
238
+ console.log('📡 客户端连接到 GUI');
239
+
240
+ ws.on('message', (message) => {
241
+ try {
242
+ const data = JSON.parse(message);
243
+ console.log('📨 收到消息:', data);
244
+
245
+ // Broadcast to all clients
246
+ wss.clients.forEach((client) => {
247
+ if (client.readyState === WebSocket.OPEN) {
248
+ client.send(JSON.stringify(data));
249
+ }
250
+ });
251
+ } catch (error) {
252
+ console.error('❌ 处理消息错误:', error);
253
+ }
254
+ });
255
+
256
+ ws.on('close', () => {
257
+ console.log('📡 客户端断开连接');
258
+ });
259
+ });
260
+
261
+ return {
262
+ server,
263
+ wss,
264
+ url: `http://localhost:${port}`,
265
+ port,
266
+ };
267
+ }
268
+
269
+ async function main() {
270
+ try {
271
+ console.log('🚀 启动 ModernX GUI (开发版)...');
272
+
273
+ // 检测当前项目结构
274
+ const projectInfo = await detectProject(process.cwd());
275
+ console.log('📁 项目检测完成:', projectInfo.name);
276
+
277
+ // 启动开发服务器
278
+ const server = await startServer({
279
+ port: 3000,
280
+ projectInfo,
281
+ });
282
+
283
+ console.log(`🌐 GUI 服务器地址: ${server.url}`);
284
+
285
+ // 自动打开浏览器
286
+ await openBrowser(server.url);
287
+ console.log('✅ ModernX GUI 已就绪!');
288
+ console.log('');
289
+ console.log('💡 提示:');
290
+ console.log(' - 这是一个开发版本,使用临时界面');
291
+ console.log(' - 完整功能需要构建前端代码');
292
+ console.log(' - 可以手动发送状态更新进行测试');
293
+ console.log('');
294
+ console.log('🔧 测试命令:');
295
+ console.log(' curl -X POST http://localhost:3000/api/test -d \'{"type":"state_update","payload":{"test":"hello"}}\'');
296
+
297
+ // 添加测试端点
298
+ server.server.on('request', (req, res) => {
299
+ if (req.method === 'POST' && req.url === '/api/test') {
300
+ let body = '';
301
+ req.on('data', chunk => body += chunk);
302
+ req.on('end', () => {
303
+ try {
304
+ const data = JSON.parse(body);
305
+ server.wss.clients.forEach(client => {
306
+ if (client.readyState === WebSocket.OPEN) {
307
+ client.send(JSON.stringify(data));
308
+ }
309
+ });
310
+ res.writeHead(200, { 'Content-Type': 'application/json' });
311
+ res.end(JSON.stringify({ success: true, message: '数据已广播' }));
312
+ } catch (error) {
313
+ res.writeHead(400, { 'Content-Type': 'application/json' });
314
+ res.end(JSON.stringify({ error: 'Invalid JSON' }));
315
+ }
316
+ });
317
+ }
318
+ });
319
+
320
+ } catch (error) {
321
+ console.error('❌ 启动 ModernX GUI 失败:', error.message);
322
+ process.exit(1);
323
+ }
324
+ }
325
+
326
+ main();