driftdetect-dashboard 0.8.1 → 0.8.2
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/LICENSE +121 -0
- package/dist/server/api-routes.d.ts +50 -0
- package/dist/server/api-routes.js +652 -0
- package/dist/server/api-routes.js.map +1 -0
- package/dist/server/dashboard-server.d.ts +64 -0
- package/dist/server/dashboard-server.js +154 -0
- package/dist/server/dashboard-server.js.map +1 -0
- package/dist/server/drift-data-reader.d.ts +522 -0
- package/dist/server/drift-data-reader.js +1550 -0
- package/dist/server/drift-data-reader.js.map +1 -0
- package/dist/server/express-app.d.ts +24 -0
- package/dist/server/express-app.js +74 -0
- package/dist/server/express-app.js.map +1 -0
- package/dist/server/galaxy-data-transformer.d.ts +178 -0
- package/dist/server/galaxy-data-transformer.js +562 -0
- package/dist/server/galaxy-data-transformer.js.map +1 -0
- package/dist/server/index.d.ts +20 -0
- package/dist/server/index.js +14 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/pattern-watcher.d.ts +55 -0
- package/dist/server/pattern-watcher.d.ts.map +1 -0
- package/dist/server/pattern-watcher.js +157 -0
- package/dist/server/pattern-watcher.js.map +1 -0
- package/dist/server/quality-gates-api.d.ts +12 -0
- package/dist/server/quality-gates-api.js +226 -0
- package/dist/server/quality-gates-api.js.map +1 -0
- package/dist/server/websocket-server.d.ts +83 -0
- package/dist/server/websocket-server.js +189 -0
- package/dist/server/websocket-server.js.map +1 -0
- package/package.json +20 -20
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket Server
|
|
3
|
+
*
|
|
4
|
+
* Manages WebSocket connections for realtime violation streaming.
|
|
5
|
+
*
|
|
6
|
+
* @requirements 2.1 - Expose a WebSocket endpoint at `/ws` for realtime communication
|
|
7
|
+
* @requirements 2.3 - Broadcast violations to all connected WebSocket clients
|
|
8
|
+
*/
|
|
9
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// WebSocket Manager
|
|
12
|
+
// ============================================================================
|
|
13
|
+
export class WebSocketManager {
|
|
14
|
+
wss = null;
|
|
15
|
+
clients = new Set();
|
|
16
|
+
pingInterval = null;
|
|
17
|
+
/**
|
|
18
|
+
* Get the number of connected clients
|
|
19
|
+
*/
|
|
20
|
+
get clientCount() {
|
|
21
|
+
return this.clients.size;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Attach WebSocket server to an HTTP server
|
|
25
|
+
* @requirements 2.1 - WebSocket endpoint at /ws
|
|
26
|
+
*/
|
|
27
|
+
attach(server) {
|
|
28
|
+
this.wss = new WebSocketServer({
|
|
29
|
+
server,
|
|
30
|
+
path: '/ws',
|
|
31
|
+
});
|
|
32
|
+
this.wss.on('connection', (ws) => {
|
|
33
|
+
this.handleConnection(ws);
|
|
34
|
+
});
|
|
35
|
+
// Start ping interval for connection health
|
|
36
|
+
this.startPingInterval();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Close the WebSocket server and all connections
|
|
40
|
+
*/
|
|
41
|
+
close() {
|
|
42
|
+
// Stop ping interval
|
|
43
|
+
if (this.pingInterval) {
|
|
44
|
+
clearInterval(this.pingInterval);
|
|
45
|
+
this.pingInterval = null;
|
|
46
|
+
}
|
|
47
|
+
// Close all client connections
|
|
48
|
+
for (const client of this.clients) {
|
|
49
|
+
client.close(1000, 'Server shutting down');
|
|
50
|
+
}
|
|
51
|
+
this.clients.clear();
|
|
52
|
+
// Close the WebSocket server
|
|
53
|
+
if (this.wss) {
|
|
54
|
+
this.wss.close();
|
|
55
|
+
this.wss = null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Broadcast a violation to all connected clients
|
|
60
|
+
* @requirements 2.3 - Broadcast violations to all connected clients
|
|
61
|
+
*/
|
|
62
|
+
broadcastViolation(violation) {
|
|
63
|
+
this.broadcast({
|
|
64
|
+
type: 'violation',
|
|
65
|
+
payload: violation,
|
|
66
|
+
timestamp: new Date().toISOString(),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Broadcast a pattern update to all connected clients
|
|
71
|
+
*/
|
|
72
|
+
broadcastPatternUpdate(update) {
|
|
73
|
+
this.broadcast({
|
|
74
|
+
type: 'pattern_updated',
|
|
75
|
+
payload: update,
|
|
76
|
+
timestamp: new Date().toISOString(),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Broadcast stats update to all connected clients
|
|
81
|
+
*/
|
|
82
|
+
broadcastStatsUpdate(stats) {
|
|
83
|
+
this.broadcast({
|
|
84
|
+
type: 'stats_updated',
|
|
85
|
+
payload: stats,
|
|
86
|
+
timestamp: new Date().toISOString(),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Broadcast patterns changed event to all connected clients
|
|
91
|
+
* Triggers client-side data refresh
|
|
92
|
+
*/
|
|
93
|
+
broadcastPatternsChanged(payload) {
|
|
94
|
+
this.broadcast({
|
|
95
|
+
type: 'patterns_changed',
|
|
96
|
+
payload,
|
|
97
|
+
timestamp: new Date().toISOString(),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// ==========================================================================
|
|
101
|
+
// Private Methods
|
|
102
|
+
// ==========================================================================
|
|
103
|
+
/**
|
|
104
|
+
* Handle a new WebSocket connection
|
|
105
|
+
*/
|
|
106
|
+
handleConnection(ws) {
|
|
107
|
+
// Add to clients set
|
|
108
|
+
this.clients.add(ws);
|
|
109
|
+
// Send connected message
|
|
110
|
+
this.send(ws, {
|
|
111
|
+
type: 'connected',
|
|
112
|
+
payload: { clientCount: this.clients.size },
|
|
113
|
+
timestamp: new Date().toISOString(),
|
|
114
|
+
});
|
|
115
|
+
// Handle messages from client
|
|
116
|
+
ws.on('message', (data) => {
|
|
117
|
+
this.handleMessage(ws, data);
|
|
118
|
+
});
|
|
119
|
+
// Handle client disconnect
|
|
120
|
+
ws.on('close', () => {
|
|
121
|
+
this.clients.delete(ws);
|
|
122
|
+
});
|
|
123
|
+
// Handle errors
|
|
124
|
+
ws.on('error', (error) => {
|
|
125
|
+
console.error('WebSocket error:', error);
|
|
126
|
+
this.clients.delete(ws);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Handle incoming message from a client
|
|
131
|
+
*/
|
|
132
|
+
handleMessage(ws, data) {
|
|
133
|
+
try {
|
|
134
|
+
const message = JSON.parse(data.toString());
|
|
135
|
+
// Handle ping/pong for connection health
|
|
136
|
+
if (message.type === 'ping') {
|
|
137
|
+
this.send(ws, {
|
|
138
|
+
type: 'pong',
|
|
139
|
+
timestamp: new Date().toISOString(),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
// Ignore invalid messages
|
|
145
|
+
console.error('Invalid WebSocket message:', error);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Send a message to a specific client
|
|
150
|
+
*/
|
|
151
|
+
send(ws, message) {
|
|
152
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
153
|
+
ws.send(JSON.stringify(message));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Broadcast a message to all connected clients
|
|
158
|
+
*/
|
|
159
|
+
broadcast(message) {
|
|
160
|
+
const messageStr = JSON.stringify(message);
|
|
161
|
+
for (const client of this.clients) {
|
|
162
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
163
|
+
client.send(messageStr);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Start ping interval for connection health monitoring
|
|
169
|
+
*/
|
|
170
|
+
startPingInterval() {
|
|
171
|
+
// Ping every 30 seconds
|
|
172
|
+
this.pingInterval = setInterval(() => {
|
|
173
|
+
const pingMessage = {
|
|
174
|
+
type: 'ping',
|
|
175
|
+
timestamp: new Date().toISOString(),
|
|
176
|
+
};
|
|
177
|
+
for (const client of this.clients) {
|
|
178
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
179
|
+
client.send(JSON.stringify(pingMessage));
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// Remove dead connections
|
|
183
|
+
this.clients.delete(client);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}, 30000);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=websocket-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"websocket-server.js","sourceRoot":"","sources":["../../src/server/websocket-server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "driftdetect-dashboard",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Local web dashboard for Drift architectural drift detection",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -34,25 +34,9 @@
|
|
|
34
34
|
"files": [
|
|
35
35
|
"dist"
|
|
36
36
|
],
|
|
37
|
-
"scripts": {
|
|
38
|
-
"build": "pnpm run build:server && pnpm run build:client",
|
|
39
|
-
"build:server": "tsc -p tsconfig.server.json",
|
|
40
|
-
"build:client": "vite build",
|
|
41
|
-
"clean": "rm -rf dist",
|
|
42
|
-
"dev": "pnpm run build:server && concurrently -n server,client -c blue,green \"pnpm run dev:backend\" \"pnpm run dev:client\"",
|
|
43
|
-
"dev:backend": "node --import tsx scripts/dev-server.ts",
|
|
44
|
-
"dev:server": "tsc -p tsconfig.server.json --watch",
|
|
45
|
-
"dev:client": "vite",
|
|
46
|
-
"lint": "eslint src --ext .ts,.tsx",
|
|
47
|
-
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
48
|
-
"test": "vitest run",
|
|
49
|
-
"test:watch": "vitest",
|
|
50
|
-
"test:coverage": "vitest run --coverage",
|
|
51
|
-
"typecheck": "tsc --noEmit -p tsconfig.server.json && tsc --noEmit -p tsconfig.client.json"
|
|
52
|
-
},
|
|
53
37
|
"dependencies": {
|
|
54
|
-
"driftdetect-core": "^0.8.
|
|
55
|
-
"driftdetect-galaxy": "^0.8.
|
|
38
|
+
"driftdetect-core": "^0.8.2",
|
|
39
|
+
"driftdetect-galaxy": "^0.8.2",
|
|
56
40
|
"express": "^4.18.2",
|
|
57
41
|
"open": "^10.0.0",
|
|
58
42
|
"ws": "^8.16.0"
|
|
@@ -91,5 +75,21 @@
|
|
|
91
75
|
"peerDependencies": {
|
|
92
76
|
"react": "^18.2.0",
|
|
93
77
|
"react-dom": "^18.2.0"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "pnpm run build:server && pnpm run build:client",
|
|
81
|
+
"build:server": "tsc -p tsconfig.server.json",
|
|
82
|
+
"build:client": "vite build",
|
|
83
|
+
"clean": "rm -rf dist",
|
|
84
|
+
"dev": "pnpm run build:server && concurrently -n server,client -c blue,green \"pnpm run dev:backend\" \"pnpm run dev:client\"",
|
|
85
|
+
"dev:backend": "node --import tsx scripts/dev-server.ts",
|
|
86
|
+
"dev:server": "tsc -p tsconfig.server.json --watch",
|
|
87
|
+
"dev:client": "vite",
|
|
88
|
+
"lint": "eslint src --ext .ts,.tsx",
|
|
89
|
+
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
90
|
+
"test": "vitest run",
|
|
91
|
+
"test:watch": "vitest",
|
|
92
|
+
"test:coverage": "vitest run --coverage",
|
|
93
|
+
"typecheck": "tsc --noEmit -p tsconfig.server.json && tsc --noEmit -p tsconfig.client.json"
|
|
94
94
|
}
|
|
95
|
-
}
|
|
95
|
+
}
|