@honeypipe/client
v0.0.6
Published
Sweet, smooth, and simple WebRTC connections
Downloads
7
Readme
🍯 HoneyPipe
Sweet, smooth, and simple WebRTC connections
🐝 What's the Buzz?
Ever tried to set up WebRTC and felt like you were wrestling with a swarm of angry bees? Well, grab your beekeeper suit no more! HoneyPipe makes WebRTC connections as smooth as honey sliding off a warm spoon.
✨ Why HoneyPipe?
- 🚀 Zero Config Magic - Just like bees know how to make honey, HoneyPipe knows how to make connections
- 🎯 Straight to the Point - No more drowning in boilerplate. We handle the sticky stuff
- 🔧 Type-Safe - TypeScript support out of the box
- 📦 Room-Based - Organize your connections like a well-structured hive
- 🌐 P2P Messaging - Direct peer-to-peer communication with automatic connection management
📦 Installation
npm install @honeypipe/client
# or
yarn add @honeypipe/client
# or
pnpm add @honeypipe/client🛠️ Usage as a Library
Basic Setup
Note: By default, HoneyPipe uses the public signaling server at
https://honeypipe.wasmer.app. For production use, consider hosting your own signaling server.
import { Peer, Room } from "@honeypipe/client"
// Create a room - think of it as a space where peers can meet
// By default, it uses FetchSignalAdapter with https://honeypipe.wasmer.app
const room = new Room<{ type: "chat"; message: string }>("room-123")
// Or configure with a custom adapter
// const room = new Room<{ type: "chat"; message: string }>("room-123", {
// adapter: new FetchSignalAdapter({ baseUrl: "https://your-server.com" })
// })
// Create peers - each peer is like a bee in the hive
const alice = new Peer({ peerId: "alice" })
const bob = new Peer({ peerId: "bob" })
// Listen for room events
room.on("presence", (event) => {
console.log(`${event.peer.id} ${event.type}ed the room`)
})
room.on("message", (event) => {
console.log(`${event.peer.id}:`, event.message)
})
// Join the room
await alice.join(room)
await bob.join(room)
// Get room connection for sending messages
const aliceConnection = alice.in(room)
const bobConnection = bob.in(room)
// Wait for peers to be ready
await aliceConnection.waitForOtherPeers()
// Send messages to all peers in the room
aliceConnection.sendMessage({ type: "chat", message: "Hello from Alice! 🐝" })
bobConnection.sendMessage({ type: "chat", message: "Hey Alice! 👋" })Type-Safe Rooms
// Define your message types
interface GameMessage {
type: "move" | "shoot" | "score"
playerId: string
data: any
}
// Create a typed room
const gameRoom = new Peer.Room<GameMessage>("game-session", signalingAdapter)
// TypeScript knows the message shape!
const connection = player.in(gameRoom)
connection.sendMessage({
type: "move",
playerId: "alice",
data: { x: 100, y: 200 },
})Managing Connections
// Get room connection
const connection = peer.in(room)
// Get all connected peers in the room
const peers = connection.getPeers()
// Get a specific peer
const remotePeer = connection.getPeer("bob")
// Check if a peer's data channel is active
if (remotePeer?.isDataChannelActive()) {
console.log("Bob is ready to receive messages!")
}
// Wait for a peer to be ready
await remotePeer?.waitForConnectionReady()
// Leave a room
peer.leave(room)Room Events
// Listen for peer presence changes
room.on("presence", (event) => {
switch (event.type) {
case "join":
console.log(`${event.peer.id} joined the room`)
break
case "alive":
console.log(`${event.peer.id} is still active`)
break
case "leave":
console.log(`${event.peer.id} left the room`)
break
}
})
// Listen for messages
room.on("message", (event) => {
console.log(`Message from ${event.peer.id}:`, event.message)
})Real-World Example: Chat Room
import { Peer, Room, RoomConnection } from "@honeypipe/client"
interface ChatMessage {
type: "message" | "typing" | "reaction"
userId: string
content?: string
timestamp: number
}
class ChatRoom {
private peer: Peer
private room: Room<ChatMessage>
private connection: RoomConnection<ChatMessage>
constructor(userId: string, roomId: string) {
this.peer = new Peer({ peerId: userId })
this.room = new Room<ChatMessage>(roomId)
// Set up event handling
this.room.on("presence", (event) => {
if (event.type === "join") {
console.log(`${event.peer.id} joined the hive! 🐝`)
} else if (event.type === "leave") {
console.log(`${event.peer.id} flew away 👋`)
}
})
this.room.on("message", (event) => {
const message = event.message
switch (message.type) {
case "message":
console.log(`${message.userId}: ${message.content}`)
break
case "typing":
console.log(`${message.userId} is typing...`)
break
case "reaction":
console.log(`${message.userId} reacted: ${message.content}`)
break
}
})
}
async join() {
await this.peer.join(this.room)
this.connection = this.peer.in(this.room)
// Wait for other peers before sending messages
await this.connection.waitForOtherPeers()
}
sendMessage(content: string) {
this.connection.sendMessage({
type: "message",
userId: this.peer.id,
content,
timestamp: Date.now(),
})
}
sendTypingIndicator() {
this.connection.sendMessage({
type: "typing",
userId: this.peer.id,
timestamp: Date.now(),
})
}
async leave() {
this.peer.leave(this.room)
}
}
// Usage
const chatRoom = new ChatRoom("alice", "general-chat")
await chatRoom.join()
chatRoom.sendMessage("Hello everyone! 🍯")🏃♂️ Development Setup
# Clone the hive
git clone https://github.com/yourusername/honeypipe.git
# Enter the colony
cd honeypipe
# Gather the nectar (install dependencies)
yarn install
# Start the development playground
yarn dev🍯 Signaling Adapters
HoneyPipe uses signaling adapters to facilitate peer discovery. Choose the one that fits your architecture:
FetchSignalingAdapter
For client-server architectures using HTTP polling.
import { FetchSignalingAdapter } from "honeypipe/adapters"
const adapter = new FetchSignalingAdapter({
serverUrl: "https://your-signaling-server.com",
})Custom Signaling Adapter
Create your own adapter by extending the base class:
import { SignalingAdapter } from "honeypipe/adapters"
class CustomSignalingAdapter extends SignalingAdapter {
async push(event: SignalingEvent): Promise<void> {
// Send the event to your signaling server
}
async pull(config: PullConfig): Promise<SignalingEvent[]> {
// Retrieve events from your signaling server
}
getRtcConfiguration(): RTCConfiguration {
return {
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
}
}
}🎮 Playground
The /playground directory is your experimental garden! 🌻
- WebRTC Debugger - See your connections in real-time
- Live Examples - Copy, paste, and modify to your heart's content
- Visual Tools - Because seeing is bee-lieving
🏗️ Project Structure
honeypipe/
├── 📁 src/ # The queen's chamber (core library)
│ ├── Peer.ts # Peer class - manages connections
│ ├── Room.ts # Room class - spaces for peers
│ ├── RoomConnection.ts # Room connection manager
│ ├── RemotePeer.ts # Remote peer connections
│ └── adapters/ # Signaling adapters
│ ├── InMemorySignalingAdapter.ts
│ ├── FetchSignalingAdapter.ts
│ ├── PostMessageSignalingAdapter.ts
│ └── RedisSignalingAdapter.ts
├── 📁 playground/ # Your experimental garden
│ ├── components/ # React components for testing
│ └── debug/ # WebRTC debugging tools
├── 📁 tests/ # Test suites
│ └── index.test.ts # Core functionality tests
└── 🍯 package.json # The recipe book🐛 Debugging
Having trouble? Check the hive:
Connection Issues?
- Ensure peers are using the same room ID and signaling adapter
- Check if
remotePeer.isDataChannelActive()returns true before sending messages - Use
connection.waitForOtherPeers()to ensure peers are ready
Messages not arriving?
- Verify both peers have joined the same room
- Check room events with
room.on('message', ...) - Ensure message types match your TypeScript definitions
Peer discovery problems?
- Verify your signaling adapter is configured correctly
- Check
room.on('presence', ...)events to see peer join/leave activity - For production, ensure STUN/TURN servers are configured
TypeScript errors?
- Make sure your message types are consistent across all peers
- Use the generic type parameter:
new Peer.Room<YourMessageType>()
Still stuck? - Create an issue, we don't sting! 🐝
🤝 Contributing
Found a bug? Got a sweet idea? We love contributions!
- Fork the hive 🍴
- Create your feature branch (
git checkout -b feature/amazing-honey) - Commit your changes (
git commit -m 'Add some sweet feature') - Push to the branch (
git push origin feature/amazing-honey) - Open a Pull Request and let's make this sweeter together!
📜 License
MIT - Free as a bee! 🐝
