driftdetect-dashboard 0.7.1 → 0.8.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.
Files changed (40) hide show
  1. package/dist/client/assets/{GalaxyTab-Bc9PKsMk.js → GalaxyTab-BsAmWarF.js} +4 -4
  2. package/dist/client/assets/{GalaxyTab-Bc9PKsMk.js.map → GalaxyTab-BsAmWarF.js.map} +1 -1
  3. package/dist/client/assets/main-CVl-4C5E.css +2 -0
  4. package/dist/client/assets/main-QuEZvA3i.js +59 -0
  5. package/dist/client/assets/main-QuEZvA3i.js.map +1 -0
  6. package/dist/client/assets/{sfxr-CO3_Kukg.js → sfxr-Cr89uVKo.js} +2 -2
  7. package/dist/client/assets/{sfxr-CO3_Kukg.js.map → sfxr-Cr89uVKo.js.map} +1 -1
  8. package/dist/client/index.html +2 -2
  9. package/dist/server/api-routes.d.ts.map +1 -1
  10. package/dist/server/quality-gates-api.d.ts.map +1 -0
  11. package/package.json +21 -21
  12. package/LICENSE +0 -21
  13. package/dist/client/assets/main-BdVQNGtK.js +0 -59
  14. package/dist/client/assets/main-BdVQNGtK.js.map +0 -1
  15. package/dist/client/assets/main-NejYwKFb.css +0 -2
  16. package/dist/server/api-routes.d.ts +0 -50
  17. package/dist/server/api-routes.js +0 -634
  18. package/dist/server/api-routes.js.map +0 -1
  19. package/dist/server/dashboard-server.d.ts +0 -64
  20. package/dist/server/dashboard-server.js +0 -154
  21. package/dist/server/dashboard-server.js.map +0 -1
  22. package/dist/server/drift-data-reader.d.ts +0 -522
  23. package/dist/server/drift-data-reader.js +0 -1550
  24. package/dist/server/drift-data-reader.js.map +0 -1
  25. package/dist/server/express-app.d.ts +0 -24
  26. package/dist/server/express-app.js +0 -74
  27. package/dist/server/express-app.js.map +0 -1
  28. package/dist/server/galaxy-data-transformer.d.ts +0 -178
  29. package/dist/server/galaxy-data-transformer.js +0 -562
  30. package/dist/server/galaxy-data-transformer.js.map +0 -1
  31. package/dist/server/index.d.ts +0 -20
  32. package/dist/server/index.js +0 -14
  33. package/dist/server/index.js.map +0 -1
  34. package/dist/server/pattern-watcher.d.ts +0 -55
  35. package/dist/server/pattern-watcher.d.ts.map +0 -1
  36. package/dist/server/pattern-watcher.js +0 -157
  37. package/dist/server/pattern-watcher.js.map +0 -1
  38. package/dist/server/websocket-server.d.ts +0 -83
  39. package/dist/server/websocket-server.js +0 -189
  40. package/dist/server/websocket-server.js.map +0 -1
@@ -1,55 +0,0 @@
1
- /**
2
- * Pattern Watcher
3
- *
4
- * Watches the .drift/patterns/ directory for changes and emits events
5
- * when patterns are added, updated, or removed.
6
- *
7
- * @requirements Phase 5 - Dashboard auto-refresh when watch mode updates patterns
8
- */
9
- import { EventEmitter } from 'node:events';
10
- export interface PatternChangeEvent {
11
- type: 'created' | 'updated' | 'deleted';
12
- category: string;
13
- status: string;
14
- timestamp: string;
15
- }
16
- export interface PatternWatcherOptions {
17
- /** Path to the .drift directory */
18
- driftDir: string;
19
- /** Debounce delay in milliseconds (default: 500) */
20
- debounceMs?: number;
21
- }
22
- export declare class PatternWatcher extends EventEmitter {
23
- private readonly driftDir;
24
- private readonly patternsDir;
25
- private readonly debounceMs;
26
- private watchers;
27
- private debounceTimers;
28
- private isWatching;
29
- constructor(options: PatternWatcherOptions);
30
- /**
31
- * Start watching for pattern changes
32
- */
33
- start(): void;
34
- /**
35
- * Stop watching for pattern changes
36
- */
37
- stop(): void;
38
- /**
39
- * Check if currently watching
40
- */
41
- get watching(): boolean;
42
- /**
43
- * Watch a directory for changes
44
- */
45
- private watchDirectory;
46
- /**
47
- * Debounce file change events
48
- */
49
- private debounceChange;
50
- /**
51
- * Handle a file change event
52
- */
53
- private handleFileChange;
54
- }
55
- //# sourceMappingURL=pattern-watcher.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pattern-watcher.d.ts","sourceRoot":"","sources":["../../src/server/pattern-watcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,cAAc,CAA0C;IAChE,OAAO,CAAC,UAAU,CAAkB;gBAExB,OAAO,EAAE,qBAAqB;IAO1C;;OAEG;IACH,KAAK,IAAI,IAAI;IAsBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAsBZ;;OAEG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAMD;;OAEG;IACH,OAAO,CAAC,cAAc;IAyCtB;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CA+BzB"}
@@ -1,157 +0,0 @@
1
- /**
2
- * Pattern Watcher
3
- *
4
- * Watches the .drift/patterns/ directory for changes and emits events
5
- * when patterns are added, updated, or removed.
6
- *
7
- * @requirements Phase 5 - Dashboard auto-refresh when watch mode updates patterns
8
- */
9
- import * as fs from 'node:fs';
10
- import * as path from 'node:path';
11
- import { EventEmitter } from 'node:events';
12
- // ============================================================================
13
- // Pattern Watcher
14
- // ============================================================================
15
- export class PatternWatcher extends EventEmitter {
16
- driftDir;
17
- patternsDir;
18
- debounceMs;
19
- watchers = [];
20
- debounceTimers = new Map();
21
- isWatching = false;
22
- constructor(options) {
23
- super();
24
- this.driftDir = options.driftDir;
25
- this.patternsDir = path.join(options.driftDir, 'patterns');
26
- this.debounceMs = options.debounceMs ?? 500;
27
- }
28
- /**
29
- * Start watching for pattern changes
30
- */
31
- start() {
32
- if (this.isWatching) {
33
- return;
34
- }
35
- this.isWatching = true;
36
- // Watch the patterns directory and subdirectories
37
- const statusDirs = ['discovered', 'approved', 'ignored'];
38
- for (const status of statusDirs) {
39
- const statusDir = path.join(this.patternsDir, status);
40
- this.watchDirectory(statusDir, status);
41
- }
42
- // Also watch the index directory for file-map changes
43
- const indexDir = path.join(this.driftDir, 'index');
44
- this.watchDirectory(indexDir, 'index');
45
- this.emit('started');
46
- }
47
- /**
48
- * Stop watching for pattern changes
49
- */
50
- stop() {
51
- if (!this.isWatching) {
52
- return;
53
- }
54
- this.isWatching = false;
55
- // Close all watchers
56
- for (const watcher of this.watchers) {
57
- watcher.close();
58
- }
59
- this.watchers = [];
60
- // Clear all debounce timers
61
- for (const timer of this.debounceTimers.values()) {
62
- clearTimeout(timer);
63
- }
64
- this.debounceTimers.clear();
65
- this.emit('stopped');
66
- }
67
- /**
68
- * Check if currently watching
69
- */
70
- get watching() {
71
- return this.isWatching;
72
- }
73
- // ==========================================================================
74
- // Private Methods
75
- // ==========================================================================
76
- /**
77
- * Watch a directory for changes
78
- */
79
- watchDirectory(dirPath, status) {
80
- // Ensure directory exists
81
- if (!fs.existsSync(dirPath)) {
82
- try {
83
- fs.mkdirSync(dirPath, { recursive: true });
84
- }
85
- catch {
86
- // Directory might be created later
87
- return;
88
- }
89
- }
90
- try {
91
- const watcher = fs.watch(dirPath, (eventType, filename) => {
92
- if (!filename || !filename.endsWith('.json')) {
93
- return;
94
- }
95
- // Skip temp files
96
- if (filename.endsWith('.tmp') || filename.startsWith('.')) {
97
- return;
98
- }
99
- const filePath = path.join(dirPath, filename);
100
- const category = filename.replace('.json', '');
101
- // Debounce to avoid multiple events for the same file
102
- this.debounceChange(filePath, () => {
103
- this.handleFileChange(filePath, category, status, eventType);
104
- });
105
- });
106
- this.watchers.push(watcher);
107
- watcher.on('error', (error) => {
108
- console.error(`Watcher error for ${dirPath}:`, error);
109
- });
110
- }
111
- catch (error) {
112
- console.error(`Failed to watch ${dirPath}:`, error);
113
- }
114
- }
115
- /**
116
- * Debounce file change events
117
- */
118
- debounceChange(key, callback) {
119
- const existing = this.debounceTimers.get(key);
120
- if (existing) {
121
- clearTimeout(existing);
122
- }
123
- const timer = setTimeout(() => {
124
- this.debounceTimers.delete(key);
125
- callback();
126
- }, this.debounceMs);
127
- this.debounceTimers.set(key, timer);
128
- }
129
- /**
130
- * Handle a file change event
131
- */
132
- handleFileChange(filePath, category, status, eventType) {
133
- // Determine the change type
134
- let changeType;
135
- if (!fs.existsSync(filePath)) {
136
- changeType = 'deleted';
137
- }
138
- else if (eventType === 'rename') {
139
- // 'rename' can mean created or deleted
140
- changeType = 'created';
141
- }
142
- else {
143
- changeType = 'updated';
144
- }
145
- const event = {
146
- type: changeType,
147
- category,
148
- status,
149
- timestamp: new Date().toISOString(),
150
- };
151
- console.log(`[PatternWatcher] Detected ${changeType}: ${status}/${category}.json`);
152
- this.emit('change', event);
153
- // Also emit specific events
154
- this.emit(changeType, event);
155
- }
156
- }
157
- //# sourceMappingURL=pattern-watcher.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pattern-watcher.js","sourceRoot":"","sources":["../../src/server/pattern-watcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAoB3C,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAE/E,MAAM,OAAO,cAAe,SAAQ,YAAY;IAC7B,QAAQ,CAAS;IACjB,WAAW,CAAS;IACpB,UAAU,CAAS;IAC5B,QAAQ,GAAmB,EAAE,CAAC;IAC9B,cAAc,GAAgC,IAAI,GAAG,EAAE,CAAC;IACxD,UAAU,GAAY,KAAK,CAAC;IAEpC,YAAY,OAA8B;QACxC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC3D,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,kDAAkD;QAClD,MAAM,UAAU,GAAG,CAAC,YAAY,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAEzD,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YACtD,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;QAED,sDAAsD;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEvC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAExB,qBAAqB;QACrB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QAEnB,4BAA4B;QAC5B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAE5B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,6EAA6E;IAC7E,kBAAkB;IAClB,6EAA6E;IAE7E;;OAEG;IACK,cAAc,CAAC,OAAe,EAAE,MAAc;QACpD,0BAA0B;QAC1B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,CAAC;YAAC,MAAM,CAAC;gBACP,mCAAmC;gBACnC,OAAO;YACT,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;gBACxD,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC7C,OAAO;gBACT,CAAC;gBAED,kBAAkB;gBAClB,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC1D,OAAO;gBACT,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBAC9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAE/C,sDAAsD;gBACtD,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,EAAE;oBACjC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;gBAC/D,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE5B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC5B,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,GAAG,EAAE,KAAK,CAAC,CAAC;YACxD,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mBAAmB,OAAO,GAAG,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,GAAW,EAAE,QAAoB;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,QAAQ,EAAE,CAAC;YACb,YAAY,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChC,QAAQ,EAAE,CAAC;QACb,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAEpB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACK,gBAAgB,CACtB,QAAgB,EAChB,QAAgB,EAChB,MAAc,EACd,SAAiB;QAEjB,4BAA4B;QAC5B,IAAI,UAAsC,CAAC;QAE3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,UAAU,GAAG,SAAS,CAAC;QACzB,CAAC;aAAM,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,uCAAuC;YACvC,UAAU,GAAG,SAAS,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,SAAS,CAAC;QACzB,CAAC;QAED,MAAM,KAAK,GAAuB;YAChC,IAAI,EAAE,UAAU;YAChB,QAAQ;YACR,MAAM;YACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,OAAO,CAAC,GAAG,CAAC,6BAA6B,UAAU,KAAK,MAAM,IAAI,QAAQ,OAAO,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAE3B,4BAA4B;QAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;CACF"}
@@ -1,83 +0,0 @@
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 type { Server } from 'http';
10
- import type { DashboardViolation } from './drift-data-reader.js';
11
- export type WebSocketMessageType = 'violation' | 'pattern_updated' | 'patterns_changed' | 'stats_updated' | 'ping' | 'pong' | 'connected';
12
- export interface WebSocketMessage {
13
- type: WebSocketMessageType;
14
- payload?: unknown;
15
- timestamp: string;
16
- }
17
- export interface PatternUpdatePayload {
18
- id: string;
19
- status: string;
20
- action: 'approved' | 'ignored' | 'deleted';
21
- }
22
- export interface PatternsChangedPayload {
23
- type: 'created' | 'updated' | 'deleted';
24
- category: string;
25
- status: string;
26
- }
27
- export declare class WebSocketManager {
28
- private wss;
29
- private clients;
30
- private pingInterval;
31
- /**
32
- * Get the number of connected clients
33
- */
34
- get clientCount(): number;
35
- /**
36
- * Attach WebSocket server to an HTTP server
37
- * @requirements 2.1 - WebSocket endpoint at /ws
38
- */
39
- attach(server: Server): void;
40
- /**
41
- * Close the WebSocket server and all connections
42
- */
43
- close(): void;
44
- /**
45
- * Broadcast a violation to all connected clients
46
- * @requirements 2.3 - Broadcast violations to all connected clients
47
- */
48
- broadcastViolation(violation: DashboardViolation): void;
49
- /**
50
- * Broadcast a pattern update to all connected clients
51
- */
52
- broadcastPatternUpdate(update: PatternUpdatePayload): void;
53
- /**
54
- * Broadcast stats update to all connected clients
55
- */
56
- broadcastStatsUpdate(stats: unknown): void;
57
- /**
58
- * Broadcast patterns changed event to all connected clients
59
- * Triggers client-side data refresh
60
- */
61
- broadcastPatternsChanged(payload: PatternsChangedPayload): void;
62
- /**
63
- * Handle a new WebSocket connection
64
- */
65
- private handleConnection;
66
- /**
67
- * Handle incoming message from a client
68
- */
69
- private handleMessage;
70
- /**
71
- * Send a message to a specific client
72
- */
73
- private send;
74
- /**
75
- * Broadcast a message to all connected clients
76
- */
77
- private broadcast;
78
- /**
79
- * Start ping interval for connection health monitoring
80
- */
81
- private startPingInterval;
82
- }
83
- //# sourceMappingURL=websocket-server.d.ts.map
@@ -1,189 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"websocket-server.js","sourceRoot":"","sources":["../../src/server/websocket-server.ts"],"names":[],"mappings":"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"}