{"_id":"@abdelfatah12/webrtc-signaling","name":"@abdelfatah12/webrtc-signaling","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@abdelfatah12/webrtc-signaling","version":"1.0.0","description":"A flexible, type-safe WebRTC signaling server supporting both room-based and peer-to-peer calling modes","main":"./dist/index.js","types":"./dist/index.d.ts","type":"module","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"test":"echo \"Error: no test specified\" && exit 1","dev":"tsx watch src/server.ts","build":"tsc","start":"node dist/server.js","prepublishOnly":"npm run build"},"keywords":["webrtc","signaling","socket.io","peer-to-peer","video-call","real-time","typescript"],"author":{"name":"abdelfatah","email":"abdelfatahmoharem@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/abdelfatah403/webRtc-package.git"},"bugs":{"url":"https://github.com/your-username/webrtc-signaling-server/issues"},"homepage":"https://github.com/your-username/webrtc-signaling-server#readme","license":"MIT","dependencies":{"express":"^5.1.0","socket.io":"^4.8.1"},"devDependencies":{"@types/express":"^5.0.5","@types/node":"^24.10.1","ts-node-dev":"^2.0.0","tsx":"^4.20.6","typescript":"^5.9.3"},"peerDependencies":{"socket.io":"^4.0.0"},"engines":{"node":">=18.0.0"},"gitHead":"d533daa88bb800624a4a5a0593009d06e2a6a0a0","_id":"@abdelfatah12/webrtc-signaling@1.0.0","_nodeVersion":"22.21.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-p9HKKMbYXI4FBvi3frnJsO7q3okdicC/pgJ+5wFc5/EpLhORQGmqBW5fxwx67GiG8KHjrEwwPVfp8v2ZG492AA==","shasum":"d93583d3d011043f13b07c97b3cee590789aa55b","tarball":"https://registry.npmjs.org/@abdelfatah12/webrtc-signaling/-/webrtc-signaling-1.0.0.tgz","fileCount":27,"unpackedSize":93927,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDQDM9RQs5K9FUuYnhg3h0HHPjwVDSnhsQWaIgEuUZ0pAIga0rWCw/Gh/ejP6ET3beV9g7bmnr0U+WOHFtt4eGSKJQ="}]},"_npmUser":{"name":"abdelfatah12","email":"abdelfatahmoharem@gmail.com"},"directories":{},"maintainers":[{"name":"abdelfatah12","email":"abdelfatahmoharem@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/webrtc-signaling_1.0.0_1764251449958_0.8118626009184611"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-27T13:50:49.801Z","1.0.0":"2025-11-27T13:50:50.140Z","modified":"2025-11-27T13:50:50.476Z"},"maintainers":[{"name":"abdelfatah12","email":"abdelfatahmoharem@gmail.com"}],"description":"A flexible, type-safe WebRTC signaling server supporting both room-based and peer-to-peer calling modes","homepage":"https://github.com/your-username/webrtc-signaling-server#readme","keywords":["webrtc","signaling","socket.io","peer-to-peer","video-call","real-time","typescript"],"repository":{"type":"git","url":"git+https://github.com/abdelfatah403/webRtc-package.git"},"author":{"name":"abdelfatah","email":"abdelfatahmoharem@gmail.com"},"bugs":{"url":"https://github.com/your-username/webrtc-signaling-server/issues"},"license":"MIT","readme":"# WebRTC Signaling Server\n\nA flexible, type-safe WebRTC signaling server built with TypeScript and Socket.IO. Supports both **room-based** and **peer-to-peer** calling modes with extensive customization options.\n\n## Features\n\n-   🎯 **Dual Mode Support**: Choose between room-based, peer-to-peer, or both\n-   🔒 **Type-Safe**: Full TypeScript support with comprehensive type definitions\n-   🪝 **Event Hooks**: Customize behavior with lifecycle hooks\n-   📊 **Built-in Monitoring**: Track users, rooms, and connections\n-   ✅ **Validation**: Built-in payload validation and error handling\n-   🧹 **Auto Cleanup**: Automatic resource cleanup on disconnect\n-   ⚡ **Production Ready**: Graceful shutdown and error handling\n\n## Installation\n\n```bash\nnpm install @yourname/webrtc-signaling socket.io\n```\n\n## Quick Start\n\n### Peer-to-Peer Mode\n\nUsers register with unique IDs and call each other directly:\n\n```typescript\nimport { createServer } from 'http';\nimport express from 'express';\nimport { SignalingServer } from '@yourname/webrtc-signaling';\n\nconst app = express();\nconst httpServer = createServer(app);\n\nconst signaling = new SignalingServer(httpServer, {\n    mode: 'peer',\n    enableLogging: true,\n});\n\nhttpServer.listen(3000, () => {\n    console.log('Signaling server running on port 3000');\n});\n```\n\n### Room-Based Mode\n\nUsers join rooms and broadcast to all members:\n\n```typescript\nconst signaling = new SignalingServer(httpServer, {\n    mode: 'room',\n    enableLogging: true,\n    maxRoomSize: 4, // Optional: limit room size\n});\n```\n\n### Both Modes\n\nAllow users to use either mode:\n\n```typescript\nconst signaling = new SignalingServer(httpServer, {\n    mode: 'both',\n    enableLogging: true,\n});\n```\n\n## Configuration\n\n```typescript\ninterface SignalingServerConfig {\n    mode: 'room' | 'peer' | 'both';\n    enableLogging?: boolean;\n    maxRoomSize?: number; // Room mode only\n    hooks?: SignalingHooks;\n}\n```\n\n## Event Hooks\n\nCustomize behavior with lifecycle hooks:\n\n```typescript\nconst signaling = new SignalingServer(httpServer, {\n    mode: 'peer',\n    hooks: {\n        // Called when a user registers (peer mode)\n        onUserRegistered: async data => {\n            console.log(`User ${data.userId} registered`);\n            // Save to database, send notifications, etc.\n        },\n\n        // Called when a user joins a room (room mode)\n        onUserJoinedRoom: async data => {\n            console.log(`User joined room ${data.room}`);\n        },\n\n        // Validate before registration (return false to reject)\n        beforeRegister: async data => {\n            // Check against database, validate format, etc.\n            const isValid = await validateUser(data.userId);\n            return isValid;\n        },\n\n        // Validate before joining room (return false to reject)\n        beforeJoinRoom: async data => {\n            // Check permissions, room capacity, etc.\n            return true;\n        },\n\n        // Called when offer is sent\n        onOfferSent: async data => {\n            console.log(`Offer from ${data.fromUserId}`);\n        },\n\n        // Called when answer is sent\n        onAnswerSent: async data => {\n            console.log(`Answer from ${data.fromUserId}`);\n        },\n\n        // Called on disconnect\n        onUserDisconnected: async data => {\n            console.log(`User ${data.userId} disconnected`);\n        },\n    },\n});\n```\n\n## Client Usage\n\n### Peer-to-Peer Mode (Client)\n\n```javascript\nimport io from 'socket.io-client';\n\nconst socket = io('http://localhost:3000');\n\n// 1. Register with a unique ID\nsocket.emit('register', { userId: 'user123' });\n\nsocket.on('register_success', data => {\n    console.log('Registered:', data.userId);\n});\n\nsocket.on('register_error', error => {\n    console.error('Registration failed:', error.message);\n});\n\n// 2. Create offer and send to specific user\nconst offer = await peerConnection.createOffer();\nawait peerConnection.setLocalDescription(offer);\n\nsocket.emit('offer', {\n    targetUserId: 'user456',\n    offer: offer,\n});\n\n// 3. Receive offer from another user\nsocket.on('offer', async data => {\n    const { offer, fromUserId } = data;\n    await peerConnection.setRemoteDescription(offer);\n\n    const answer = await peerConnection.createAnswer();\n    await peerConnection.setLocalDescription(answer);\n\n    socket.emit('answer', {\n        targetUserId: fromUserId,\n        answer: answer,\n    });\n});\n\n// 4. Receive answer\nsocket.on('answer', async data => {\n    await peerConnection.setRemoteDescription(data.answer);\n});\n\n// 5. Exchange ICE candidates\npeerConnection.onicecandidate = event => {\n    if (event.candidate) {\n        socket.emit('ice', {\n            targetUserId: 'user456',\n            candidate: event.candidate,\n        });\n    }\n};\n\nsocket.on('ice', async data => {\n    await peerConnection.addIceCandidate(data.candidate);\n});\n```\n\n### Room-Based Mode (Client)\n\n```javascript\nconst socket = io('http://localhost:3000');\n\n// 1. Join a room\nsocket.emit('join', { room: 'room123' });\n\nsocket.on('joined_room', data => {\n    console.log('Joined room:', data.room);\n});\n\n// 2. When another user joins\nsocket.on('user_joined', data => {\n    console.log('User joined:', data.socketId);\n    // Start offer process for new user\n});\n\n// 3. Broadcast offer to room\nsocket.emit('offer', {\n    room: 'room123',\n    offer: offer,\n});\n\n// 4. Receive offer from anyone in room\nsocket.on('offer', async data => {\n    const { offer, fromSocketId } = data;\n    // Handle offer...\n});\n\n// 5. Leave room\nsocket.emit('leave', { room: 'room123' });\n\nsocket.on('left_room', data => {\n    console.log('Left room:', data.room);\n});\n\nsocket.on('room_closed', data => {\n    console.log('Room closed:', data.message);\n});\n```\n\n## API Methods\n\n```typescript\n// Get Socket.IO instance for advanced usage\nconst io = signaling.getIO();\n\n// Get online users (peer mode)\nconst users = signaling.getOnlineUsers();\n// ['user123', 'user456', ...]\n\n// Check if user is online (peer mode)\nconst isOnline = signaling.isUserOnline('user123');\n\n// Get all active rooms with sizes\nconst rooms = signaling.getRooms();\n// Map { 'room123' => 4, 'room456' => 2 }\n\n// Send custom event to specific user\nsignaling.sendToUser('user123', 'custom_event', { data: 'hello' });\n\n// Send custom event to room\nsignaling.sendToRoom('room123', 'custom_event', { data: 'hello' });\n\n// Broadcast to all users\nsignaling.broadcast('announcement', { message: 'Server maintenance soon' });\n\n// Get current state\nconst state = signaling.getState();\n\n// Graceful shutdown\nawait signaling.close();\n```\n\n## Monitoring Endpoints Example\n\n```typescript\napp.get('/api/online-users', (req, res) => {\n    const users = signaling.getOnlineUsers();\n    res.json({ users, count: users.length });\n});\n\napp.get('/api/rooms', (req, res) => {\n    const rooms = Array.from(signaling.getRooms().entries());\n    res.json({ rooms });\n});\n```\n\n## Error Handling\n\nAll errors are emitted with a consistent structure:\n\n```typescript\nsocket.on('error', error => {\n    console.error(error.error); // Error code\n    console.error(error.message); // Human-readable message\n    console.error(error.timestamp); // When it occurred\n});\n\n// Error codes include:\n// - INVALID_USER_ID\n// - USER_ID_TAKEN\n// - USER_NOT_FOUND\n// - INVALID_ROOM\n// - ROOM_FULL\n// - NOT_REGISTERED\n// - INVALID_PAYLOAD\n// - REGISTRATION_REJECTED\n// - JOIN_REJECTED\n```\n\n## Best Practices\n\n1. **Always validate user IDs** in `beforeRegister` hook\n2. **Set `maxRoomSize`** in room mode to prevent overcrowding\n3. **Enable logging** during development, disable in production\n4. **Use monitoring endpoints** to track server health\n5. **Implement graceful shutdown** for production deployments\n6. **Handle all error events** on the client side\n\n## TypeScript Support\n\nFull type definitions included:\n\n```typescript\nimport type {\n    SignalingServerConfig,\n    SignalingHooks,\n    OfferPayload,\n    AnswerPayload,\n    // ... and many more\n} from '@yourname/webrtc-signaling';\n```\n\n## License\n\nMIT\n\n## Contributing\n\nContributions welcome! Please open an issue or PR.\n","readmeFilename":"README.md","_rev":"1-c5b1a735323122bc3a123cb2faa882b8"}