@nahisaho/yata-ui 1.7.0

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/dist/index.js ADDED
@@ -0,0 +1,548 @@
1
+ /**
2
+ * YATA UI Server
3
+ *
4
+ * Web-based visualization and management interface for YATA knowledge graphs.
5
+ *
6
+ * @packageDocumentation
7
+ * @module @nahisaho/yata-ui
8
+ *
9
+ * @see REQ-YI-WEB-001 - Web-based Visualization
10
+ * @see REQ-YI-WEB-002 - Interactive Graph Editing
11
+ * @see REQ-YI-WEB-003 - Real-time Updates
12
+ * @see DES-YATA-IMPROVEMENTS-001 - Design Document
13
+ */
14
+ import express, { Router } from 'express';
15
+ /**
16
+ * Default configuration
17
+ */
18
+ export const DEFAULT_UI_CONFIG = {
19
+ port: 3000,
20
+ host: 'localhost',
21
+ cors: true,
22
+ apiBasePath: '/api',
23
+ enableRealtime: true,
24
+ };
25
+ // ============================================================
26
+ // YataUIServer Class
27
+ // ============================================================
28
+ /**
29
+ * YATA Knowledge Graph Web UI Server
30
+ *
31
+ * Provides web-based visualization and management for YATA knowledge graphs.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const server = new YataUIServer({
36
+ * port: 3000,
37
+ * enableRealtime: true,
38
+ * });
39
+ *
40
+ * // Set data provider
41
+ * server.setDataProvider(async () => {
42
+ * return {
43
+ * nodes: [{ id: '1', label: 'Node 1', type: 'entity' }],
44
+ * edges: [],
45
+ * };
46
+ * });
47
+ *
48
+ * await server.start();
49
+ * console.log('UI available at http://localhost:3000');
50
+ * ```
51
+ *
52
+ * @see REQ-YI-WEB-001
53
+ * @see REQ-YI-WEB-002
54
+ * @see REQ-YI-WEB-003
55
+ */
56
+ export class YataUIServer {
57
+ app;
58
+ server = null;
59
+ config;
60
+ sseClients = new Map();
61
+ dataProvider = null;
62
+ constructor(config = {}) {
63
+ this.config = { ...DEFAULT_UI_CONFIG, ...config };
64
+ this.app = express();
65
+ this.setupMiddleware();
66
+ this.setupRoutes();
67
+ }
68
+ // ============================================================
69
+ // Public API
70
+ // ============================================================
71
+ /**
72
+ * Set data provider function
73
+ * @param provider - Function that returns graph data
74
+ */
75
+ setDataProvider(provider) {
76
+ this.dataProvider = provider;
77
+ }
78
+ /**
79
+ * Start the server
80
+ * @see REQ-YI-WEB-001
81
+ */
82
+ async start() {
83
+ return new Promise((resolve, reject) => {
84
+ try {
85
+ const host = this.config.host ?? '0.0.0.0';
86
+ this.server = this.app.listen(this.config.port, host, () => {
87
+ resolve();
88
+ });
89
+ }
90
+ catch (error) {
91
+ reject(error);
92
+ }
93
+ });
94
+ }
95
+ /**
96
+ * Stop the server
97
+ */
98
+ async stop() {
99
+ // Close all SSE connections
100
+ for (const client of this.sseClients.values()) {
101
+ client.response.end();
102
+ }
103
+ this.sseClients.clear();
104
+ return new Promise((resolve, reject) => {
105
+ if (!this.server) {
106
+ resolve();
107
+ return;
108
+ }
109
+ this.server.close((err) => {
110
+ if (err) {
111
+ reject(err);
112
+ }
113
+ else {
114
+ this.server = null;
115
+ resolve();
116
+ }
117
+ });
118
+ });
119
+ }
120
+ /**
121
+ * Get server URL
122
+ */
123
+ getUrl() {
124
+ return `http://${this.config.host}:${this.config.port}`;
125
+ }
126
+ /**
127
+ * Check if server is running
128
+ */
129
+ isRunning() {
130
+ return this.server !== null;
131
+ }
132
+ /**
133
+ * Broadcast update to all SSE clients
134
+ * @see REQ-YI-WEB-003
135
+ */
136
+ broadcastUpdate(event, data) {
137
+ const message = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
138
+ for (const client of this.sseClients.values()) {
139
+ client.response.write(message);
140
+ }
141
+ }
142
+ /**
143
+ * Get Express app instance for testing
144
+ */
145
+ getApp() {
146
+ return this.app;
147
+ }
148
+ // ============================================================
149
+ // Internal: Middleware
150
+ // ============================================================
151
+ setupMiddleware() {
152
+ // JSON body parser
153
+ this.app.use(express.json());
154
+ // CORS
155
+ if (this.config.cors) {
156
+ this.app.use((_req, res, next) => {
157
+ res.header('Access-Control-Allow-Origin', '*');
158
+ res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
159
+ res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
160
+ next();
161
+ });
162
+ }
163
+ }
164
+ // ============================================================
165
+ // Internal: Routes
166
+ // ============================================================
167
+ setupRoutes() {
168
+ const router = Router();
169
+ // Health check
170
+ router.get('/health', (_req, res) => {
171
+ this.sendResponse(res, { status: 'ok', timestamp: new Date().toISOString() });
172
+ });
173
+ // Get graph data
174
+ router.get('/graph', async (_req, res) => {
175
+ try {
176
+ const data = await this.getGraphData();
177
+ this.sendResponse(res, data);
178
+ }
179
+ catch (error) {
180
+ this.sendError(res, 500, error instanceof Error ? error.message : 'Failed to get graph data');
181
+ }
182
+ });
183
+ // Get nodes
184
+ router.get('/nodes', async (_req, res) => {
185
+ try {
186
+ const data = await this.getGraphData();
187
+ this.sendResponse(res, data.nodes);
188
+ }
189
+ catch (error) {
190
+ this.sendError(res, 500, error instanceof Error ? error.message : 'Failed to get nodes');
191
+ }
192
+ });
193
+ // Get edges
194
+ router.get('/edges', async (_req, res) => {
195
+ try {
196
+ const data = await this.getGraphData();
197
+ this.sendResponse(res, data.edges);
198
+ }
199
+ catch (error) {
200
+ this.sendError(res, 500, error instanceof Error ? error.message : 'Failed to get edges');
201
+ }
202
+ });
203
+ // Get single node
204
+ router.get('/nodes/:id', async (req, res) => {
205
+ try {
206
+ const data = await this.getGraphData();
207
+ const node = data.nodes.find(n => n.id === req.params.id);
208
+ if (!node) {
209
+ this.sendError(res, 404, 'Node not found');
210
+ return;
211
+ }
212
+ this.sendResponse(res, node);
213
+ }
214
+ catch (error) {
215
+ this.sendError(res, 500, error instanceof Error ? error.message : 'Failed to get node');
216
+ }
217
+ });
218
+ // SSE endpoint for real-time updates
219
+ if (this.config.enableRealtime) {
220
+ router.get('/events', (req, res) => {
221
+ this.handleSSEConnection(req, res);
222
+ });
223
+ }
224
+ // Cytoscape data format endpoint
225
+ router.get('/cytoscape', async (_req, res) => {
226
+ try {
227
+ const data = await this.getGraphData();
228
+ const cytoscapeData = this.toCytoscapeFormat(data);
229
+ this.sendResponse(res, cytoscapeData);
230
+ }
231
+ catch (error) {
232
+ this.sendError(res, 500, error instanceof Error ? error.message : 'Failed to get Cytoscape data');
233
+ }
234
+ });
235
+ // Statistics endpoint
236
+ router.get('/stats', async (_req, res) => {
237
+ try {
238
+ const data = await this.getGraphData();
239
+ const stats = {
240
+ nodeCount: data.nodes.length,
241
+ edgeCount: data.edges.length,
242
+ nodeTypes: this.countByType(data.nodes),
243
+ edgeTypes: this.countByType(data.edges),
244
+ namespaces: [...new Set(data.nodes.map(n => n.namespace).filter(Boolean))],
245
+ };
246
+ this.sendResponse(res, stats);
247
+ }
248
+ catch (error) {
249
+ this.sendError(res, 500, error instanceof Error ? error.message : 'Failed to get stats');
250
+ }
251
+ });
252
+ // Mount API routes
253
+ this.app.use(this.config.apiBasePath || '/api', router);
254
+ // Serve static files (for embedded UI)
255
+ if (this.config.staticDir) {
256
+ this.app.use(express.static(this.config.staticDir));
257
+ }
258
+ // Serve built-in UI
259
+ this.app.get('/', (_req, res) => {
260
+ res.send(this.getBuiltInUI());
261
+ });
262
+ }
263
+ // ============================================================
264
+ // Internal: SSE
265
+ // ============================================================
266
+ /**
267
+ * Handle SSE connection
268
+ * @see REQ-YI-WEB-003
269
+ */
270
+ handleSSEConnection(req, res) {
271
+ // Set SSE headers
272
+ res.setHeader('Content-Type', 'text/event-stream');
273
+ res.setHeader('Cache-Control', 'no-cache');
274
+ res.setHeader('Connection', 'keep-alive');
275
+ // Generate client ID
276
+ const clientId = `client-${Date.now()}-${Math.random().toString(36).slice(2)}`;
277
+ // Register client
278
+ this.sseClients.set(clientId, {
279
+ id: clientId,
280
+ response: res,
281
+ namespace: req.query.namespace,
282
+ });
283
+ // Send initial connection event
284
+ res.write(`event: connected\ndata: ${JSON.stringify({ clientId })}\n\n`);
285
+ // Handle client disconnect
286
+ req.on('close', () => {
287
+ this.sseClients.delete(clientId);
288
+ });
289
+ }
290
+ // ============================================================
291
+ // Internal: Helpers
292
+ // ============================================================
293
+ /**
294
+ * Get graph data from provider
295
+ */
296
+ async getGraphData() {
297
+ if (!this.dataProvider) {
298
+ return { nodes: [], edges: [] };
299
+ }
300
+ return this.dataProvider();
301
+ }
302
+ /**
303
+ * Send API response
304
+ */
305
+ sendResponse(res, data) {
306
+ const response = {
307
+ success: true,
308
+ data,
309
+ timestamp: new Date().toISOString(),
310
+ };
311
+ res.json(response);
312
+ }
313
+ /**
314
+ * Send error response
315
+ */
316
+ sendError(res, status, error) {
317
+ const response = {
318
+ success: false,
319
+ error,
320
+ timestamp: new Date().toISOString(),
321
+ };
322
+ res.status(status).json(response);
323
+ }
324
+ /**
325
+ * Convert to Cytoscape.js format
326
+ * @see REQ-YI-WEB-001
327
+ */
328
+ toCytoscapeFormat(data) {
329
+ const elements = [];
330
+ // Add nodes
331
+ for (const node of data.nodes) {
332
+ elements.push({
333
+ data: {
334
+ id: node.id,
335
+ label: node.label,
336
+ type: node.type,
337
+ namespace: node.namespace,
338
+ ...node.data,
339
+ },
340
+ position: node.position,
341
+ });
342
+ }
343
+ // Add edges
344
+ for (const edge of data.edges) {
345
+ elements.push({
346
+ data: {
347
+ id: edge.id,
348
+ source: edge.source,
349
+ target: edge.target,
350
+ label: edge.label || edge.type,
351
+ type: edge.type,
352
+ weight: edge.weight,
353
+ ...edge.data,
354
+ },
355
+ });
356
+ }
357
+ return { elements };
358
+ }
359
+ /**
360
+ * Count items by type
361
+ */
362
+ countByType(items) {
363
+ const counts = {};
364
+ for (const item of items) {
365
+ counts[item.type] = (counts[item.type] || 0) + 1;
366
+ }
367
+ return counts;
368
+ }
369
+ /**
370
+ * Get built-in UI HTML
371
+ */
372
+ getBuiltInUI() {
373
+ return `<!DOCTYPE html>
374
+ <html lang="en">
375
+ <head>
376
+ <meta charset="UTF-8">
377
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
378
+ <title>YATA Knowledge Graph</title>
379
+ <script src="https://unpkg.com/cytoscape@3.28.1/dist/cytoscape.min.js"></script>
380
+ <style>
381
+ * { margin: 0; padding: 0; box-sizing: border-box; }
382
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
383
+ .container { display: flex; height: 100vh; }
384
+ .sidebar { width: 300px; background: #f5f5f5; padding: 20px; overflow-y: auto; }
385
+ .graph-container { flex: 1; position: relative; }
386
+ #cy { width: 100%; height: 100%; }
387
+ h1 { font-size: 1.5rem; margin-bottom: 20px; color: #333; }
388
+ .stats { margin-bottom: 20px; padding: 15px; background: white; border-radius: 8px; }
389
+ .stat-item { display: flex; justify-content: space-between; margin: 8px 0; }
390
+ .stat-label { color: #666; }
391
+ .stat-value { font-weight: bold; color: #333; }
392
+ .controls { margin-top: 20px; }
393
+ button { padding: 10px 20px; margin: 5px 0; width: 100%; border: none; border-radius: 6px;
394
+ cursor: pointer; font-size: 14px; transition: background 0.2s; }
395
+ .btn-primary { background: #0066cc; color: white; }
396
+ .btn-primary:hover { background: #0052a3; }
397
+ .btn-secondary { background: #e0e0e0; color: #333; }
398
+ .btn-secondary:hover { background: #d0d0d0; }
399
+ .node-info { margin-top: 20px; padding: 15px; background: white; border-radius: 8px; display: none; }
400
+ .node-info.active { display: block; }
401
+ .node-info h3 { margin-bottom: 10px; color: #333; }
402
+ .node-info p { margin: 5px 0; color: #666; font-size: 14px; }
403
+ .legend { margin-top: 20px; }
404
+ .legend-item { display: flex; align-items: center; margin: 5px 0; }
405
+ .legend-color { width: 16px; height: 16px; border-radius: 4px; margin-right: 8px; }
406
+ .connection-status { position: fixed; top: 10px; right: 10px; padding: 8px 16px;
407
+ border-radius: 20px; font-size: 12px; }
408
+ .status-connected { background: #d4edda; color: #155724; }
409
+ .status-disconnected { background: #f8d7da; color: #721c24; }
410
+ </style>
411
+ </head>
412
+ <body>
413
+ <div id="connection-status" class="connection-status status-disconnected">Disconnected</div>
414
+ <div class="container">
415
+ <div class="sidebar">
416
+ <h1>📊 YATA Graph</h1>
417
+ <div id="stats" class="stats">
418
+ <div class="stat-item"><span class="stat-label">Nodes:</span><span id="node-count" class="stat-value">-</span></div>
419
+ <div class="stat-item"><span class="stat-label">Edges:</span><span id="edge-count" class="stat-value">-</span></div>
420
+ </div>
421
+ <div class="controls">
422
+ <button class="btn-primary" onclick="refreshGraph()">🔄 Refresh</button>
423
+ <button class="btn-secondary" onclick="fitGraph()">📐 Fit to View</button>
424
+ <button class="btn-secondary" onclick="exportPNG()">📸 Export PNG</button>
425
+ </div>
426
+ <div id="node-info" class="node-info">
427
+ <h3 id="selected-name">Selected Node</h3>
428
+ <p><strong>ID:</strong> <span id="selected-id">-</span></p>
429
+ <p><strong>Type:</strong> <span id="selected-type">-</span></p>
430
+ <p><strong>Namespace:</strong> <span id="selected-ns">-</span></p>
431
+ </div>
432
+ <div class="legend">
433
+ <h4>Node Types</h4>
434
+ <div class="legend-item"><div class="legend-color" style="background:#4CAF50"></div>Entity</div>
435
+ <div class="legend-item"><div class="legend-color" style="background:#2196F3"></div>Class</div>
436
+ <div class="legend-item"><div class="legend-color" style="background:#FF9800"></div>Function</div>
437
+ <div class="legend-item"><div class="legend-color" style="background:#9C27B0"></div>Interface</div>
438
+ </div>
439
+ </div>
440
+ <div class="graph-container">
441
+ <div id="cy"></div>
442
+ </div>
443
+ </div>
444
+ <script>
445
+ const API_BASE = '${this.config.apiBasePath || '/api'}';
446
+ let cy;
447
+ let eventSource;
448
+
449
+ const typeColors = {
450
+ entity: '#4CAF50', class: '#2196F3', function: '#FF9800',
451
+ interface: '#9C27B0', module: '#607D8B', default: '#9E9E9E'
452
+ };
453
+
454
+ async function initGraph() {
455
+ cy = cytoscape({
456
+ container: document.getElementById('cy'),
457
+ style: [
458
+ { selector: 'node', style: {
459
+ 'label': 'data(label)', 'text-valign': 'center', 'text-halign': 'center',
460
+ 'background-color': 'data(color)', 'color': '#fff', 'font-size': '12px',
461
+ 'text-outline-width': 2, 'text-outline-color': 'data(color)',
462
+ 'width': 60, 'height': 60
463
+ }},
464
+ { selector: 'edge', style: {
465
+ 'label': 'data(label)', 'curve-style': 'bezier', 'target-arrow-shape': 'triangle',
466
+ 'line-color': '#999', 'target-arrow-color': '#999', 'font-size': '10px',
467
+ 'text-background-color': '#fff', 'text-background-opacity': 0.8,
468
+ 'text-background-padding': '2px'
469
+ }},
470
+ { selector: ':selected', style: {
471
+ 'border-width': 3, 'border-color': '#ff0066'
472
+ }}
473
+ ],
474
+ layout: { name: 'cose', animate: false }
475
+ });
476
+
477
+ cy.on('tap', 'node', function(e) {
478
+ const node = e.target.data();
479
+ document.getElementById('selected-name').textContent = node.label;
480
+ document.getElementById('selected-id').textContent = node.id;
481
+ document.getElementById('selected-type').textContent = node.type || '-';
482
+ document.getElementById('selected-ns').textContent = node.namespace || '-';
483
+ document.getElementById('node-info').classList.add('active');
484
+ });
485
+
486
+ cy.on('tap', function(e) {
487
+ if (e.target === cy) {
488
+ document.getElementById('node-info').classList.remove('active');
489
+ }
490
+ });
491
+
492
+ await refreshGraph();
493
+ connectSSE();
494
+ }
495
+
496
+ async function refreshGraph() {
497
+ try {
498
+ const res = await fetch(API_BASE + '/cytoscape');
499
+ const json = await res.json();
500
+ if (json.success) {
501
+ const elements = json.data.elements.map(el => {
502
+ if (el.data && !el.data.source) {
503
+ el.data.color = typeColors[el.data.type] || typeColors.default;
504
+ }
505
+ return el;
506
+ });
507
+ cy.json({ elements });
508
+ cy.layout({ name: 'cose', animate: true, animationDuration: 500 }).run();
509
+ updateStats();
510
+ }
511
+ } catch (err) { console.error('Failed to refresh:', err); }
512
+ }
513
+
514
+ function updateStats() {
515
+ document.getElementById('node-count').textContent = cy.nodes().length;
516
+ document.getElementById('edge-count').textContent = cy.edges().length;
517
+ }
518
+
519
+ function fitGraph() { cy.fit(50); }
520
+ function exportPNG() { const png = cy.png({ full: true }); window.open(png, '_blank'); }
521
+
522
+ function connectSSE() {
523
+ if (eventSource) eventSource.close();
524
+ eventSource = new EventSource(API_BASE + '/events');
525
+ eventSource.onopen = () => {
526
+ document.getElementById('connection-status').textContent = 'Connected';
527
+ document.getElementById('connection-status').className = 'connection-status status-connected';
528
+ };
529
+ eventSource.onerror = () => {
530
+ document.getElementById('connection-status').textContent = 'Disconnected';
531
+ document.getElementById('connection-status').className = 'connection-status status-disconnected';
532
+ };
533
+ eventSource.addEventListener('update', () => refreshGraph());
534
+ }
535
+
536
+ initGraph();
537
+ </script>
538
+ </body>
539
+ </html>`;
540
+ }
541
+ }
542
+ /**
543
+ * Factory function to create YataUIServer
544
+ */
545
+ export function createYataUIServer(config) {
546
+ return new YataUIServer(config);
547
+ }
548
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@nahisaho/yata-ui",
3
+ "version": "1.7.0",
4
+ "description": "YATA Knowledge Graph Web UI - Interactive visualization and management",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "yata-ui": "./bin/yata-ui.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "scripts": {
18
+ "build": "tsc -p tsconfig.json",
19
+ "test": "vitest run",
20
+ "test:watch": "vitest",
21
+ "lint": "eslint src --ext .ts",
22
+ "clean": "rm -rf dist"
23
+ },
24
+ "keywords": [
25
+ "yata",
26
+ "knowledge-graph",
27
+ "visualization",
28
+ "cytoscape",
29
+ "express",
30
+ "musubix"
31
+ ],
32
+ "author": "nahisaho",
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "express": "^4.18.2"
36
+ },
37
+ "devDependencies": {
38
+ "@types/express": "^4.17.21",
39
+ "@types/node": "^20.10.0",
40
+ "typescript": "^5.3.3",
41
+ "vitest": "^1.6.0"
42
+ },
43
+ "engines": {
44
+ "node": ">=20.0.0"
45
+ }
46
+ }