@abhishekkashyap2698/tarang-react
v1.0.1
Published
React hooks and provider for Tarang SDK
Maintainers
Readme
⚡ Tarang SDK (@abhishekkashyap2698/tarang)
Production-ready, lightweight, transport-agnostic real-time JavaScript/TypeScript SDK with built-in React hooks, React Native, WebRTC DataChannel, WebSocket, and custom transport adapters.
🌟 Key Highlights
- 📦 Single All-In-One Package: Install
@abhishekkashyap2698/tarangfor React, Node.js, React Native, TypeScript, or Vanilla JS. - 🔌 Universal Transport Agnostic: Switch effortlessly between WebSocket, WebRTC DataChannels, Mock (for offline testing), or Custom Transports (Socket.IO, Supabase, MQTT, etc.).
- ⚡ Zero Backend & Zero STUN/TURN Lock-in: Works out of the box with your existing endpoints without forcing proprietary backends or third-party STUN/TURN servers.
- 🔄 Auto Reconnect & Offline Queue: Automatic reconnection with exponential backoff & full jitter, plus bounded offline message buffers.
- 💓 Built-in Heartbeat & RPC: Keep-alive ping/pong detection and typed request-response RPC with configurable timeouts.
- ⚛️ First-Class React Integration: Built-in
<TarangProvider>,useTarang(),useTarangEvent(),useTarangStatus(), anduseTarangRequest().
📥 Installation
npm install @abhishekkashyap2698/tarang(Optional: If you use yarn or pnpm)
yarn add @abhishekkashyap2698/tarang
# or
pnpm add @abhishekkashyap2698/tarang🚀 Quick Start Guide
1. ⚛️ React Integration (Standard)
import React, { useState } from "react";
import {
createTarang,
TarangProvider,
useTarang,
useTarangEvent,
useTarangStatus
} from "@abhishekkashyap2698/tarang";
// 1. Create client instance
const tarang = createTarang({
transport: "websocket",
url: "wss://echo.websocket.events", // or your WebSocket URL
reconnect: {
enabled: true,
maxRetries: 10,
initialDelay: 1000,
maxDelay: 30000,
backoff: "exponential",
jitter: true
},
queue: {
enabled: true,
maxSize: 100
},
heartbeat: {
enabled: true,
interval: 30000,
timeout: 10000
}
});
// 2. Component using hooks
function ChatWidget() {
const tarang = useTarang();
const { state, isConnected } = useTarangStatus();
const [messages, setMessages] = useState<string[]>([]);
const [input, setInput] = useState("");
// Listen to incoming real-time events automatically
useTarangEvent("chat:message", (data: any) => {
setMessages((prev) => [...prev, data.text]);
});
const sendMessage = async () => {
if (!input.trim()) return;
await tarang.emit("chat:message", { text: input, timestamp: Date.now() });
setInput("");
};
return (
<div>
<div>Status: <strong>{state}</strong> (Connected: {String(isConnected)})</div>
<input value={input} onChange={(e) => setInput(e.target.value)} placeholder="Type a message..." />
<button onClick={sendMessage}>Send</button>
<ul>
{messages.map((m, i) => <li key={i}>{m}</li>)}
</ul>
</div>
);
}
// 3. Wrap with Provider
export default function App() {
return (
<TarangProvider client={tarang}>
<ChatWidget />
</TarangProvider>
);
}2. 🟢 Node.js / Backend & TypeScript
import { createTarang } from "@abhishekkashyap2698/tarang";
// Strongly typed event map
type ServerEvents = {
"user:login": { userId: string; timestamp: number };
"order:created": { orderId: string; amount: number };
};
const tarang = createTarang<ServerEvents>({
transport: "websocket",
url: "wss://your-realtime-server.com/socket"
});
// Connect
await tarang.connect();
// Listen
tarang.on("order:created", (order) => {
console.log(`Processing Order ${order.orderId} for $${order.amount}`);
});
// Emit
await tarang.emit("user:login", {
userId: "usr_1029",
timestamp: Date.now()
});
// RPC Request / Response
const result = await tarang.request("fetchUserProfile", { id: "usr_1029" }, 5000);
console.log("Profile:", result);3. 🌐 WebRTC Peer-to-Peer with Custom Signaling
Tarang exposes raw WebRTC DataChannel primitives without hardcoding any STUN/TURN or signaling server:
import { createTarang } from "@abhishekkashyap2698/tarang";
const tarang = createTarang({
transport: "webrtc",
webrtc: {
rtcConfig: {
iceServers: [] // Pass your own STUN/TURN if required
}
}
});
const peer = tarang.webrtc!();
// Handle ICE Candidates generated locally
peer.onIceCandidate((candidate) => {
mySignalingChannel.send({ type: "candidate", candidate });
});
// Initiator creates Offer
const offer = await peer.createOffer();
await mySignalingChannel.send({ type: "offer", offer });
// Receiver sets Remote Description and creates Answer
await peer.setRemoteDescription(receivedOffer);
const answer = await peer.createAnswer();
await mySignalingChannel.send({ type: "answer", answer });
// Connect & emit over RTCDataChannel
await tarang.connect();
await tarang.emit("p2p:message", { text: "Hello peer!" });4. 🛠️ Custom Transport Adapter
Wrap any proprietary or custom socket library (Socket.IO, Firebase, Supabase, MQTT, WebTransport):
import { createTarang, createCustomTransport } from "@abhishekkashyap2698/tarang";
const customTransport = createCustomTransport({
connect: async () => { /* custom socket connect logic */ },
disconnect: async () => { /* custom socket disconnect logic */ },
send: (data) => { /* custom socket send logic */ },
onMessage: (cb) => { /* wire incoming messages to cb(data) */ },
onOpen: (cb) => { /* wire socket open to cb() */ },
onClose: (cb) => { /* wire socket close to cb(reason) */ },
onError: (cb) => { /* wire socket error to cb(error) */ }
});
const tarang = createTarang({
transport: customTransport
});5. 🧪 Offline Testing Without Any Backend (MockTransport)
Test and build your entire UI offline with zero backend:
import { createTarang, MockTransport } from "@abhishekkashyap2698/tarang";
const mock = new MockTransport({ autoOpen: true });
const tarang = createTarang({ transport: mock });
await tarang.connect();
tarang.on("test:event", (data) => {
console.log("Mock event received:", data);
});
// Simulate an incoming wire frame
mock.simulateMessage(JSON.stringify({
id: "test-1",
type: "event",
event: "test:event",
payload: { hello: "offline test" },
timestamp: Date.now()
}));📖 API Reference
Tarang Client
await tarang.connect(): Connect to endpoint.await tarang.disconnect(): Gracefully disconnect.await tarang.reconnect(): Immediately trigger reconnection.await tarang.emit(event, payload): Emit an event (auto-queued if offline).tarang.on(event, handler): Register event listener (returnsunsubscribefunction).tarang.once(event, handler): Register one-time event listener.tarang.off(event, handler): Unregister event listener.await tarang.request(method, params, timeoutMs): Perform RPC request with timeout.tarang.isConnected(): Check if active.tarang.getState(): Returns"idle" | "connecting" | "connected" | "reconnecting" | "disconnecting" | "disconnected" | "failed".tarang.getQueueSize(),tarang.clearQueue(),tarang.flushQueue(): Offline buffer tools.
React Hooks
<TarangProvider client={tarang}>: React context provider.useTarang(): Access Tarang client instance from context.useTarangEvent(event, handler): Auto-managed event subscription with automatic unmount cleanup.useTarangStatus(): Returns{ state, isConnected }with zero unnecessary re-renders.useTarangRequest(method): Memoized RPC request caller.
🔒 Security & Reliability
- Safe Deserialization: Guarded by
TarangProtocolErrorboundaries. - Message Size Limits: Configurable byte length validation against payload bombing.
- Bounded Offline Buffers: Strict
drop-oldest,drop-newest, orthrowoverflow strategies. - Zero Sensitive Leaks: Tokens and credentials stripped from error logs.
📄 License
MIT © Abhishek Kashyap
