Skip to content

Commit ee43049

Browse files
committed
feat(types): enhance type safety and fix linting issues
- Improve TypeScript type definitions with jest.MockedFunction - Replace any[] with unknown[] for better type safety - Fix unused variable warnings in test files - Update documentation with latest changes - Bump version to 0.2.4 Changes: - Use proper jest.MockedFunction types in test files - Remove unused socket variables from destructuring - Add underscore prefix to unused parameters - Update README with latest features and examples - Fix ESLint warnings across the codebase
1 parent 0e1a214 commit ee43049

File tree

10 files changed

+518
-138
lines changed

10 files changed

+518
-138
lines changed

README.md

Lines changed: 73 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -19,186 +19,126 @@ A TypeScript library providing WebSocket utilities for Nostr applications, focus
1919
- 🛡️ Comprehensive error handling and validation
2020
- 🧪 100% test coverage with Jest
2121
- 📦 Zero DOM dependencies
22+
- 🔍 Full TypeScript type safety
2223

2324
## Installation
2425

2526
```bash
2627
npm install nostr-websocket-utils
2728
```
2829

29-
## Breaking Changes in v0.2.2
30+
## Breaking Changes in v0.2.4
3031

31-
- 🔥 Removed all DOM-related code for better server-side compatibility
32-
- 🆔 Added UUID support for message tracking and correlation
33-
- 🔌 Introduced `WebSocketImpl` option for custom WebSocket implementations
34-
- 🛡️ Enhanced TypeScript type safety and validation
35-
- 🔄 Improved reconnection and error handling logic
36-
- 📝 Added comprehensive logging support
32+
- 🆕 Added dedicated Nostr WebSocket server implementation
33+
- 📝 Enhanced TypeScript type definitions for Nostr messages
34+
- 🔄 Improved message handling with strict type checking
35+
- 🧪 Added comprehensive test suite for Nostr server
36+
- 🛡️ Strengthened type safety with `unknown` types
37+
- 🔌 Added support for Nostr EVENT and REQ messages
3738

3839
## Usage
3940

40-
### Server Example
41+
### Nostr Server Example
4142

4243
```typescript
43-
import { NostrWSServer } from 'nostr-websocket-utils';
44-
import { WebSocketServer } from 'ws';
45-
import { getLogger } from './utils/logger';
44+
import { NostrWSServer, createWSServer } from 'nostr-websocket-utils';
45+
import { NostrWSMessageType, NostrWSEvent } from 'nostr-websocket-utils/types/nostr';
4646

47-
// Create WebSocket server
48-
const wss = new WebSocketServer({ port: 8080 });
49-
50-
// Initialize NostrWSServer with handlers
51-
const server = new NostrWSServer(wss, {
52-
logger: getLogger('nostr-server'),
47+
// Create Nostr WebSocket server
48+
const server = createWSServer({
49+
port: 8080,
5350
heartbeatInterval: 30000, // Optional: 30 seconds
5451
handlers: {
5552
// Required: Handle incoming messages
56-
message: async (ws, message) => {
57-
switch (message.type) {
58-
case 'subscribe':
59-
// Handle subscription
60-
ws.subscriptions?.add(message.data.channel);
53+
message: async (socket, message) => {
54+
switch (message[0]) {
55+
case NostrWSMessageType.EVENT:
56+
const event = message[1] as NostrWSEvent;
57+
// Handle Nostr event
6158
break;
62-
case 'event':
63-
// Broadcast to relevant subscribers
64-
server.broadcastToChannel(message.data.channel, message);
59+
case NostrWSMessageType.REQ:
60+
const [_type, subscriptionId, filter] = message;
61+
// Handle subscription request
6562
break;
6663
}
6764
},
6865
// Optional: Handle errors
69-
error: (ws, error) => {
70-
logger.error('WebSocket error:', error);
66+
error: (socket, error) => {
67+
console.error('WebSocket error:', error);
7168
},
7269
// Optional: Handle client disconnection
73-
close: (ws) => {
74-
logger.info(`Client ${ws.clientId} disconnected`);
70+
close: (socket) => {
71+
console.info('Client disconnected');
7572
}
7673
}
7774
});
78-
```
79-
80-
### Client Example
81-
82-
```typescript
83-
import { NostrWSClient } from 'nostr-websocket-utils';
84-
import { getLogger } from './utils/logger';
85-
86-
const client = new NostrWSClient('ws://localhost:8080', {
87-
logger: getLogger('nostr-client'),
88-
heartbeatInterval: 30000,
89-
handlers: {
90-
// Required: Handle incoming messages
91-
message: async (ws, message) => {
92-
console.log('Received:', message);
93-
}
94-
}
95-
});
96-
97-
// Listen for connection events
98-
client.on('connect', () => {
99-
console.log('Connected to server');
100-
101-
// Subscribe to a channel
102-
client.subscribe('my-channel');
103-
104-
// Send an event
105-
client.send({
106-
type: 'event',
107-
data: {
108-
channel: 'my-channel',
109-
content: 'Hello, Nostr!'
110-
}
111-
});
112-
});
11375

114-
// Connect to server
115-
client.connect();
76+
// Start listening
77+
server.listen();
11678
```
11779

118-
## API Reference
119-
120-
### NostrWSServer
121-
122-
The server-side WebSocket handler with support for channels and broadcasting.
80+
### Types
12381

12482
```typescript
125-
class NostrWSServer {
126-
constructor(wss: WebSocketServer, options: NostrWSOptions);
127-
128-
// Broadcast to all connected clients
129-
broadcast(message: NostrWSMessage): void;
130-
131-
// Broadcast to specific channel subscribers
132-
broadcastToChannel(channel: string, message: NostrWSMessage): void;
133-
134-
// Close the server and all connections
135-
close(): void;
83+
// Nostr Event Type
84+
interface NostrWSEvent {
85+
id: string;
86+
pubkey: string;
87+
created_at: number;
88+
kind: number;
89+
tags: string[][];
90+
content: string;
91+
sig: string;
13692
}
137-
```
13893

139-
### NostrWSClient
140-
141-
The client-side WebSocket handler with automatic reconnection and message queueing.
94+
// Nostr Filter Type
95+
interface NostrWSFilter {
96+
ids?: string[];
97+
authors?: string[];
98+
kinds?: number[];
99+
'#e'?: string[];
100+
'#p'?: string[];
101+
since?: number;
102+
until?: number;
103+
limit?: number;
104+
}
142105

143-
```typescript
144-
class NostrWSClient {
145-
constructor(url: string, options: NostrWSOptions);
146-
147-
// Connect to the server
148-
connect(): void;
149-
150-
// Subscribe to a channel
151-
subscribe(channel: string, filter?: unknown): void;
152-
153-
// Unsubscribe from a channel
154-
unsubscribe(channel: string): void;
155-
156-
// Send a message to the server
157-
send(message: NostrWSMessage): Promise<void>;
158-
159-
// Close the connection
160-
close(): void;
106+
// Message Types
107+
enum NostrWSMessageType {
108+
EVENT = 'EVENT',
109+
REQ = 'REQ',
110+
CLOSE = 'CLOSE',
111+
NOTICE = 'NOTICE',
112+
AUTH = 'AUTH',
113+
EOSE = 'EOSE'
161114
}
162115
```
163116

164-
### NostrWSMessage
117+
## Advanced Configuration
165118

166-
The standard message format for communication.
119+
### Server Options
167120

168121
```typescript
169-
interface NostrWSMessage {
170-
id?: string; // Auto-generated UUID if not provided
171-
type: string; // Message type (e.g., 'subscribe', 'event')
172-
data: {
173-
channel?: string; // Target channel for subscription/broadcast
174-
[key: string]: any; // Additional message data
122+
interface NostrWSServerOptions {
123+
port: number;
124+
heartbeatInterval?: number;
125+
maxPayloadSize?: number;
126+
cors?: {
127+
origin?: string | string[];
128+
methods?: string[];
129+
};
130+
handlers: {
131+
message: MessageHandler;
132+
error?: ErrorHandler;
133+
close?: CloseHandler;
175134
};
176135
}
177136
```
178137

179-
## Why Choose This Library
180-
181-
### 1. Nostr-Optimized
182-
- Built specifically for Nostr protocol requirements
183-
- Efficient pub/sub model with filtered subscriptions
184-
- Type-safe message handling for all Nostr events
185-
186-
### 2. Production-Ready
187-
- Comprehensive error handling and recovery
188-
- Memory-efficient subscription management
189-
- Built-in logging and monitoring
190-
- Extensive test coverage
191-
192-
### 3. Developer-Friendly
193-
- Clear TypeScript definitions
194-
- Flexible configuration options
195-
- Detailed documentation
196-
- Active maintenance
197-
198138
## Contributing
199139

200-
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
140+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
201141

202142
## License
203143

204-
MIT License - see the [LICENSE](LICENSE) file for details.
144+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

package-lock.json

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nostr-websocket-utils",
3-
"version": "0.2.3",
3+
"version": "0.2.4",
44
"description": "Robust WebSocket utilities for Nostr applications with automatic reconnection, channel-based messaging, and type-safe handlers. Features heartbeat monitoring, message queueing, and comprehensive error handling.",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -51,6 +51,7 @@
5151
"nostr-tools": "^2.1.4"
5252
},
5353
"devDependencies": {
54+
"@jest/globals": "^29.7.0",
5455
"@types/jest": "^29.5.14",
5556
"@types/node": "^20.11.0",
5657
"@types/ws": "^8.5.10",

src/__mocks__/logger.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
type LoggerFunction = (message: string, ...args: unknown[]) => void;
2+
3+
interface MockLogger {
4+
debug: LoggerFunction;
5+
info: LoggerFunction;
6+
warn: LoggerFunction;
7+
error: LoggerFunction;
8+
}
9+
10+
export const getLogger = (_name: string): MockLogger => ({
11+
debug: () => {},
12+
info: () => {},
13+
warn: () => {},
14+
error: () => {},
15+
});

0 commit comments

Comments
 (0)