initial commit
This commit is contained in:
commit
619cb97fa3
23 changed files with 9242 additions and 0 deletions
458
README.md
Normal file
458
README.md
Normal file
|
@ -0,0 +1,458 @@
|
|||
# @siwatsystem/smtp-ws-relay-client
|
||||
|
||||
[](https://badge.fury.io/js/@siwatsystem%2Fsmtp-ws-relay-client)
|
||||
[](http://www.typescriptlang.org/)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
A production-ready TypeScript client library for SMTP over WebSocket protocol with intelligent queue management, automatic reconnection, and comprehensive error handling.
|
||||
|
||||
## Features
|
||||
|
||||
🚀 **Intelligent Queue Management**
|
||||
- Automatic WebSocket connection when messages are queued
|
||||
- Priority-based message processing
|
||||
- Configurable batch processing
|
||||
- Queue size limits and overflow protection
|
||||
|
||||
🔄 **Robust Connection Handling**
|
||||
- Automatic reconnection with exponential backoff
|
||||
- Connection state management
|
||||
- Heartbeat monitoring
|
||||
- Graceful connection lifecycle
|
||||
|
||||
⚡ **High Performance**
|
||||
- Efficient SMTP channel cycling
|
||||
- Concurrent message processing support
|
||||
- Optimized resource usage
|
||||
- Minimal memory footprint
|
||||
|
||||
🛡️ **Enterprise-Grade Reliability**
|
||||
- Comprehensive error handling and classification
|
||||
- Timeout management for all operations
|
||||
- Retry logic with configurable attempts
|
||||
- Graceful degradation and recovery
|
||||
|
||||
📊 **Monitoring & Observability**
|
||||
- Real-time statistics and metrics
|
||||
- Structured logging with configurable levels
|
||||
- Event-driven architecture for monitoring
|
||||
- Performance tracking and analytics
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @siwatsystem/smtp-ws-relay-client
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```typescript
|
||||
import { SMTPOverWSClient, MessagePriority } from '@siwatsystem/smtp-ws-relay-client';
|
||||
|
||||
// Create client instance
|
||||
const client = new SMTPOverWSClient({
|
||||
url: 'ws://your-smtp-relay-server:3000/smtp',
|
||||
apiKey: 'your-api-key',
|
||||
debug: true
|
||||
});
|
||||
|
||||
// Send SMTP commands
|
||||
try {
|
||||
const response1 = await client.sendSMTPCommand('EHLO example.com\\r\\n');
|
||||
const response2 = await client.sendSMTPCommand('MAIL FROM: <test@example.com>\\r\\n');
|
||||
const response3 = await client.sendSMTPCommand('RCPT TO: <recipient@example.com>\\r\\n');
|
||||
|
||||
console.log('SMTP responses:', [response1, response2, response3]);
|
||||
} catch (error) {
|
||||
console.error('SMTP error:', error);
|
||||
}
|
||||
|
||||
// Graceful shutdown
|
||||
await client.shutdown();
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
```typescript
|
||||
interface SMTPClientConfig {
|
||||
/** WebSocket server URL */
|
||||
url: string;
|
||||
|
||||
/** API key for authentication */
|
||||
apiKey: string;
|
||||
|
||||
/** Interval between reconnection attempts (default: 5000ms) */
|
||||
reconnectInterval?: number;
|
||||
|
||||
/** Maximum reconnection attempts (default: 10) */
|
||||
maxReconnectAttempts?: number;
|
||||
|
||||
/** Authentication timeout (default: 30000ms) */
|
||||
authTimeout?: number;
|
||||
|
||||
/** Channel operation timeout (default: 10000ms) */
|
||||
channelTimeout?: number;
|
||||
|
||||
/** Message timeout (default: 60000ms) */
|
||||
messageTimeout?: number;
|
||||
|
||||
/** Maximum concurrent messages (default: 1) */
|
||||
maxConcurrentMessages?: number;
|
||||
|
||||
/** Enable debug logging (default: false) */
|
||||
debug?: boolean;
|
||||
|
||||
/** Custom logger implementation */
|
||||
logger?: Logger;
|
||||
|
||||
/** Connection heartbeat interval (default: 30000ms) */
|
||||
heartbeatInterval?: number;
|
||||
|
||||
/** Queue processing batch size (default: 10) */
|
||||
batchSize?: number;
|
||||
|
||||
/** Maximum queue size (default: 1000) */
|
||||
maxQueueSize?: number;
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Priority-Based Message Queuing
|
||||
|
||||
```typescript
|
||||
import { MessagePriority } from '@siwatsystem/smtp-ws-relay-client';
|
||||
|
||||
// High priority message (processed first)
|
||||
await client.sendSMTPCommand('URGENT EMAIL DATA\\r\\n', {
|
||||
priority: MessagePriority.HIGH,
|
||||
timeout: 30000
|
||||
});
|
||||
|
||||
// Normal priority message
|
||||
await client.sendSMTPCommand('NORMAL EMAIL DATA\\r\\n', {
|
||||
priority: MessagePriority.NORMAL
|
||||
});
|
||||
|
||||
// Low priority message (processed last)
|
||||
await client.sendSMTPCommand('NEWSLETTER DATA\\r\\n', {
|
||||
priority: MessagePriority.LOW
|
||||
});
|
||||
```
|
||||
|
||||
### Event Monitoring
|
||||
|
||||
```typescript
|
||||
// Connection events
|
||||
client.on('connected', () => {
|
||||
console.log('WebSocket connected');
|
||||
});
|
||||
|
||||
client.on('authenticated', () => {
|
||||
console.log('Authentication successful');
|
||||
});
|
||||
|
||||
client.on('disconnected', (reason) => {
|
||||
console.log('Disconnected:', reason);
|
||||
});
|
||||
|
||||
// Queue events
|
||||
client.on('messageQueued', (messageId, queueSize) => {
|
||||
console.log(`Message ${messageId} queued. Queue size: ${queueSize}`);
|
||||
});
|
||||
|
||||
client.on('messageProcessed', (messageId, responseTime) => {
|
||||
console.log(`Message ${messageId} processed in ${responseTime}ms`);
|
||||
});
|
||||
|
||||
client.on('queueProcessingStarted', (queueSize) => {
|
||||
console.log(`Processing ${queueSize} queued messages`);
|
||||
});
|
||||
|
||||
// Error events
|
||||
client.on('error', (error) => {
|
||||
console.error('Client error:', error);
|
||||
});
|
||||
|
||||
client.on('messageFailed', (messageId, error) => {
|
||||
console.error(`Message ${messageId} failed:`, error);
|
||||
});
|
||||
```
|
||||
|
||||
### Statistics and Monitoring
|
||||
|
||||
```typescript
|
||||
// Get real-time statistics
|
||||
const stats = client.getStats();
|
||||
console.log('Client Statistics:', {
|
||||
messagesQueued: stats.messagesQueued,
|
||||
messagesProcessed: stats.messagesProcessed,
|
||||
messagesFailed: stats.messagesFailed,
|
||||
averageResponseTime: stats.averageResponseTime,
|
||||
connectionUptime: stats.connectionUptime,
|
||||
queueSize: stats.queueSize
|
||||
});
|
||||
|
||||
// Monitor connection state
|
||||
console.log('Current state:', client.getConnectionState());
|
||||
console.log('Queue size:', client.getQueueSize());
|
||||
```
|
||||
|
||||
### Custom Logger
|
||||
|
||||
```typescript
|
||||
import { Logger } from '@siwatsystem/smtp-ws-relay-client';
|
||||
|
||||
class CustomLogger implements Logger {
|
||||
debug(message: string, ...args: any[]): void {
|
||||
// Send to your logging service
|
||||
console.debug(`[DEBUG] ${message}`, ...args);
|
||||
}
|
||||
|
||||
info(message: string, ...args: any[]): void {
|
||||
console.info(`[INFO] ${message}`, ...args);
|
||||
}
|
||||
|
||||
warn(message: string, ...args: any[]): void {
|
||||
console.warn(`[WARN] ${message}`, ...args);
|
||||
}
|
||||
|
||||
error(message: string, ...args: any[]): void {
|
||||
console.error(`[ERROR] ${message}`, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
const client = new SMTPOverWSClient({
|
||||
url: 'ws://localhost:3000/smtp',
|
||||
apiKey: 'your-api-key',
|
||||
logger: new CustomLogger()
|
||||
});
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
The library provides comprehensive error classification:
|
||||
|
||||
```typescript
|
||||
import {
|
||||
ConnectionError,
|
||||
AuthenticationError,
|
||||
ChannelError,
|
||||
TimeoutError,
|
||||
QueueError,
|
||||
MessageError
|
||||
} from '@siwatsystem/smtp-ws-relay-client';
|
||||
|
||||
try {
|
||||
await client.sendSMTPCommand('EHLO example.com\\r\\n');
|
||||
} catch (error) {
|
||||
if (error instanceof ConnectionError) {
|
||||
console.error('Connection failed:', error.message);
|
||||
} else if (error instanceof AuthenticationError) {
|
||||
console.error('Authentication failed:', error.message);
|
||||
} else if (error instanceof TimeoutError) {
|
||||
console.error('Operation timed out:', error.message);
|
||||
} else if (error instanceof QueueError) {
|
||||
console.error('Queue error:', error.message);
|
||||
} else if (error instanceof MessageError) {
|
||||
console.error('Message processing failed:', error.message);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Connection States
|
||||
|
||||
The client manages several connection states:
|
||||
|
||||
- `DISCONNECTED` - No connection to server
|
||||
- `CONNECTING` - Establishing WebSocket connection
|
||||
- `CONNECTED` - WebSocket connected, authentication pending
|
||||
- `AUTHENTICATING` - Sending authentication credentials
|
||||
- `AUTHENTICATED` - Ready to open SMTP channels
|
||||
- `CHANNEL_OPENING` - Opening SMTP channel
|
||||
- `CHANNEL_READY` - SMTP channel active, ready for data
|
||||
- `CHANNEL_CLOSED` - SMTP channel closed
|
||||
- `CHANNEL_ERROR` - SMTP channel error occurred
|
||||
- `RECONNECTING` - Attempting to reconnect
|
||||
- `FAILED` - Connection failed, max retries reached
|
||||
|
||||
## Protocol Support
|
||||
|
||||
This client implements the SMTP over WebSocket protocol specification:
|
||||
|
||||
### Message Types
|
||||
|
||||
- `AUTHENTICATE` / `AUTHENTICATE_RESPONSE` - Authentication flow
|
||||
- `SMTP_CHANNEL_OPEN` / `SMTP_CHANNEL_READY` - Channel management
|
||||
- `SMTP_CHANNEL_CLOSED` / `SMTP_CHANNEL_ERROR` - Channel lifecycle
|
||||
- `SMTP_TO_SERVER` / `SMTP_FROM_SERVER` - Data transfer
|
||||
|
||||
### Connection Flow
|
||||
|
||||
1. **WebSocket Connection** - Establish WebSocket to relay server
|
||||
2. **Authentication** - Authenticate using API key
|
||||
3. **Channel Management** - Open/close SMTP channels per message
|
||||
4. **Data Transfer** - Exchange SMTP commands and responses
|
||||
5. **Cleanup** - Close channels and connection when queue empty
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Queue Management
|
||||
- Messages are processed in priority order
|
||||
- Batch processing reduces connection overhead
|
||||
- Automatic queue size management prevents memory issues
|
||||
|
||||
### Connection Efficiency
|
||||
- Single WebSocket connection handles multiple SMTP sessions
|
||||
- Intelligent connect/disconnect based on queue state
|
||||
- Connection pooling and reuse optimization
|
||||
|
||||
### Memory Usage
|
||||
- Efficient message queuing with cleanup
|
||||
- Automatic resource management
|
||||
- Configurable limits and timeouts
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Production Configuration
|
||||
|
||||
```typescript
|
||||
const client = new SMTPOverWSClient({
|
||||
url: 'ws://your-production-server/smtp',
|
||||
apiKey: process.env.SMTP_RELAY_API_KEY!,
|
||||
|
||||
// Connection settings
|
||||
reconnectInterval: 10000,
|
||||
maxReconnectAttempts: 5,
|
||||
heartbeatInterval: 30000,
|
||||
|
||||
// Timeouts
|
||||
authTimeout: 30000,
|
||||
channelTimeout: 15000,
|
||||
messageTimeout: 120000,
|
||||
|
||||
// Queue settings
|
||||
maxQueueSize: 5000,
|
||||
batchSize: 50,
|
||||
|
||||
// Monitoring
|
||||
debug: false,
|
||||
logger: new ProductionLogger()
|
||||
});
|
||||
```
|
||||
|
||||
### Error Recovery
|
||||
|
||||
```typescript
|
||||
client.on('error', async (error) => {
|
||||
// Log error to monitoring system
|
||||
logger.error('SMTP client error', { error: error.toJSON() });
|
||||
|
||||
// Implement circuit breaker pattern
|
||||
if (error instanceof ConnectionError && consecutiveErrors > 10) {
|
||||
await client.shutdown();
|
||||
// Implement fallback mechanism
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Graceful Shutdown
|
||||
|
||||
```typescript
|
||||
process.on('SIGTERM', async () => {
|
||||
console.log('Shutting down SMTP client...');
|
||||
try {
|
||||
await client.shutdown(30000); // 30 second timeout
|
||||
console.log('SMTP client shutdown complete');
|
||||
} catch (error) {
|
||||
console.error('Forced shutdown due to timeout');
|
||||
}
|
||||
process.exit(0);
|
||||
});
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Building from Source
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/siwatsystem/smtp-ws-relay-client.git
|
||||
cd smtp-ws-relay-client
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Build library
|
||||
npm run build
|
||||
|
||||
# Run tests
|
||||
npm test
|
||||
|
||||
# Run examples
|
||||
npm run example:basic
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
npm test
|
||||
|
||||
# Run with coverage
|
||||
npm run test:coverage
|
||||
|
||||
# Watch mode
|
||||
npm run test:watch
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### SMTPOverWSClient
|
||||
|
||||
#### Constructor
|
||||
- `new SMTPOverWSClient(config: SMTPClientConfig)`
|
||||
|
||||
#### Methods
|
||||
- `sendSMTPCommand(data: string, options?: SendOptions): Promise<string>`
|
||||
- `getStats(): ClientStats`
|
||||
- `getConnectionState(): ConnectionState`
|
||||
- `getQueueSize(): number`
|
||||
- `clearQueue(): void`
|
||||
- `shutdown(timeout?: number): Promise<void>`
|
||||
|
||||
#### Events
|
||||
- `connecting`, `connected`, `authenticated`, `disconnected`
|
||||
- `reconnecting`, `reconnected`, `error`
|
||||
- `messageQueued`, `messageProcessed`, `messageFailed`
|
||||
- `queueProcessingStarted`, `queueProcessingCompleted`
|
||||
- `channelOpened`, `channelClosed`, `channelError`
|
||||
- `stateChanged`
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
||||
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
||||
4. Push to the branch (`git push origin feature/amazing-feature`)
|
||||
5. Open a Pull Request
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
## Support
|
||||
|
||||
- 📧 Email: [support@siwatsystem.com](mailto:support@siwatsystem.com)
|
||||
- 🐛 Issues: [GitHub Issues](https://github.com/siwatsystem/smtp-ws-relay-client/issues)
|
||||
- 📖 Documentation: [API Docs](https://siwatsystem.github.io/smtp-ws-relay-client/)
|
||||
|
||||
## Changelog
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md) for version history and updates.
|
||||
|
||||
---
|
||||
|
||||
Built with ❤️ by [SiwatSystem](https://siwatsystem.com)
|
Loading…
Add table
Add a link
Reference in a new issue