@canxjs/echo
v1.0.1
Published
CanxJS Echo - Realtime Client Library
Maintainers
Readme
@canxjs/echo
✨ Features
- 🔌 WebSocket Abstraction - Clean API over Socket.IO
- 📡 Channel Subscriptions - Public and private channels
- 🎯 Event Listeners - Listen for server-side events
- 🔐 Authentication - Built-in auth header support
- 🔄 Auto-reconnect - Handled by underlying Socket.IO
📦 Installation
npm install @canxjs/echo socket.io-client
# or
bun add @canxjs/echo socket.io-client🚀 Quick Start
Browser Setup
import Echo from "@canxjs/echo";
import io from "socket.io-client";
const echo = new Echo({
broadcaster: "socket.io",
host: "http://localhost:3000",
client: io,
auth: {
headers: {
Authorization: "Bearer your-token-here",
},
},
});Listen for Events
// Subscribe to a public channel
echo
.channel("orders")
.listen("OrderShipped", (event) => {
console.log("Order shipped:", event.order);
})
.listen("OrderCancelled", (event) => {
console.log("Order cancelled:", event.orderId);
});📖 Usage
Public Channels
Public channels can be subscribed to by anyone:
// Server-side (CanxJS)
broadcast("notifications").emit("NewMessage", { message: "Hello!" });
// Client-side
echo.channel("notifications").listen("NewMessage", (e) => {
showNotification(e.message);
});Private Channels
Private channels require authentication:
// Subscribe to a private channel
echo.private("user.123").listen("DirectMessage", (e) => {
console.log("New DM:", e.content);
});When joining private channels, the client will:
- Automatically prefix with
private- - Send auth headers for verification
- Server validates user can access this channel
Presence Channels
Track who is currently online:
echo
.join("chat.room.1")
.here((users) => {
console.log("Users in room:", users);
})
.joining((user) => {
console.log("User joined:", user);
})
.leaving((user) => {
console.log("User left:", user);
})
.listen("MessageSent", (e) => {
appendMessage(e.message);
});Stop Listening
// Stop listening to a specific event
echo.channel("orders").stopListening("OrderShipped");
// Leave a channel entirely
echo.leave("orders");🔧 How It Works
Architecture
┌─────────────────────────────────────────────────────┐
│ Your App │
├─────────────────────────────────────────────────────┤
│ @canxjs/echo │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Echo │ │ Channel │ │ Private │ │
│ │ Client │ │ Handler │ │ Channel │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────┤
│ socket.io-client │
├─────────────────────────────────────────────────────┤
│ WebSocket │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ CanxJS Server │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Socket.IO │ │ Broadcast │ │ Channel │ │
│ │ Server │ │ Manager │ │ Auth │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────┘Event Naming Convention
Events are namespaced by channel:
{channel}:{event}Example: orders:OrderShipped
When you call:
echo.channel("orders").listen("OrderShipped", callback);Internally, Echo listens for orders:OrderShipped on the socket.
Connection Lifecycle
const echo = new Echo({ ... });
// Echo automatically:
// 1. Creates Socket.IO connection
// 2. Sends auth headers if configured
// 3. Maintains connection
// When subscribing to a channel:
echo.channel('orders');
// → Emits 'join' event to server
// When leaving:
echo.leave('orders');
// → Emits 'leave' event to server📚 API Reference
Echo Class
new Echo(options: EchoConfig)Options:
| Property | Type | Description |
| -------------- | ------------- | --------------------------- |
| broadcaster | 'socket.io' | Broadcaster type |
| host | string | WebSocket server URL |
| client | object | Socket.IO client instance |
| auth.headers | object | Headers for auth (optional) |
Methods:
| Method | Returns | Description |
| --------------- | ------- | ---------------------------- |
| channel(name) | Channel | Subscribe to public channel |
| private(name) | Channel | Subscribe to private channel |
| leave(name) | void | Leave a channel |
Channel Class
| Method | Returns | Description |
| ------------------------- | ------- | ----------------------- |
| listen(event, callback) | this | Listen for an event |
| stopListening(event) | this | Stop listening to event |
🔌 Server-Side Integration
Make sure your CanxJS server is broadcasting events:
// In your controller or service
import { broadcast } from "canxjs";
// Broadcast to public channel
broadcast("orders").emit("OrderShipped", {
orderId: order.id,
customer: order.customer,
});
// Broadcast to private channel
broadcast(`private-user.${userId}`).emit("DirectMessage", {
from: sender.name,
content: message.content,
});💡 Use Cases
Real-time Notifications
echo.private(`user.${userId}`).listen("Notification", (n) => {
toast.show(n.title, n.body);
});Live Dashboard Updates
echo.channel("dashboard").listen("StatsUpdated", (stats) => {
updateCharts(stats);
});Chat Application
echo
.private(`chat.${roomId}`)
.listen("MessageSent", (m) => appendMessage(m))
.listen("UserTyping", (u) => showTypingIndicator(u));E-commerce Order Tracking
echo.private(`order.${orderId}`).listen("StatusChanged", (e) => {
updateOrderStatus(e.status);
});📄 License
MIT © CanxJS Team
