-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnostr-server.ts
110 lines (99 loc) · 2.96 KB
/
nostr-server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { WebSocketServer, WebSocket } from 'ws';
import { v4 as uuidv4 } from 'uuid';
import { getLogger } from '../utils/logger.js';
import { NostrWSServerSocket, NostrWSServerOptions, NostrWSServerMessage } from '../types/websocket.js';
const logger = getLogger('NostrWSServer');
/**
* Represents a Nostr WebSocket server
*/
export class NostrWSServer {
/**
* The underlying WebSocket server instance
*/
private server: WebSocketServer;
/**
* Creates a new Nostr WebSocket server instance
*
* @param {NostrWSServerOptions} options - Server configuration options
*/
constructor(options: NostrWSServerOptions) {
this.server = new WebSocketServer({
port: options.port,
host: options.host
});
/**
* Handles incoming WebSocket connections
*
* @param {WebSocket} ws - The connected WebSocket client
*/
this.server.on('connection', async (ws: WebSocket) => {
const socket = ws as NostrWSServerSocket;
socket.clientId = uuidv4();
socket.subscriptions = new Set();
socket.isAlive = true;
logger.info(`Client connected: ${socket.clientId}`);
/**
* Calls the onConnection handler if provided
*/
await options.onConnection?.(socket);
/**
* Handles incoming messages from the client
*
* @param {Buffer} data - The incoming message data
*/
socket.on('message', async (data: Buffer) => {
try {
const message = JSON.parse(data.toString()) as NostrWSServerMessage;
logger.info('Received message:', message);
/**
* Calls the onMessage handler if provided
*/
await options.onMessage?.(message, socket);
} catch (error) {
logger.error('Error processing message:', error);
/**
* Calls the onError handler if provided
*/
options.onError?.(error as Error, socket);
}
});
/**
* Handles WebSocket errors
*
* @param {Error} error - The error that occurred
*/
socket.on('error', (error: Error) => {
logger.error(`Client error (${socket.clientId}):`, error);
/**
* Calls the onError handler if provided
*/
options.onError?.(error, socket);
});
/**
* Handles client disconnections
*/
socket.on('close', () => {
logger.info(`Client disconnected: ${socket.clientId}`);
/**
* Calls the onClose handler if provided
*/
options.onClose?.(socket);
});
});
}
/**
* Closes the WebSocket server
*/
public stop(): void {
this.server.close();
}
}
/**
* Creates a new Nostr WebSocket server instance
*
* @param {NostrWSServerOptions} options - Server configuration options
* @returns {NostrWSServer} The created server instance
*/
export function createWSServer(options: NostrWSServerOptions): NostrWSServer {
return new NostrWSServer(options);
}