Licence
MIT
Version
1.2.0
Deps
0
Size
378 kB
Vulns
0
Weekly
0
@nolag/chat
High-level chat SDK for NoLag — multi-room chat, presence, typing indicators, and message replay.
How It Works with NoLag
NoLag is a real-time messaging platform that handles WebSocket connections, message routing, persistence, and scaling. This SDK wraps the low-level @nolag/js-sdk and gives you a purpose-built chat API — rooms, messages, typing indicators, and presence — without needing to manage topics or subscriptions yourself.
Getting Your Token
- Sign up at nolag.app
- Create a new project in the portal
- Choose the Chat blueprint when creating an app — this pre-configures the topics (
messages,_typing), rooms, and lobbies your chat app needs - Go to the app's Tokens page and generate an actor token
- Use that token when connecting with this SDK
Each token identifies a unique user (actor) in NoLag. The blueprint handles all the infrastructure setup — you just write your chat UI.
Install
npm install @nolag/js-sdk @nolag/chat
Quick Start
The app owns one core NoLag client; wrappers attach to it. Any number of wrapper SDKs (chat, notify, dash, ...) can share the same connection as long as each uses its own app.
import { NoLag } from "@nolag/js-sdk";
import { NoLagChat } from "@nolag/chat";
// One client for the whole app. In a browser, use a token provider so the
// SDK can mint fresh short-lived client tokens from your backend.
const client = NoLag(async () => (await (await fetch("/api/nolag-token")).json()).token);
const chat = new NoLagChat({ client, username: "Alice" });
await client.connect(); // the app owns the connection
await chat.ready(); // wrapper setup done (identity, presence, rooms)
// Join a room and send a message
const room = chat.joinRoom("general");
room.sendMessage("Hello, everyone!");
// Listen for messages
room.on("message", (msg) => {
console.log(`${msg.username}: ${msg.text}`);
});
// See who's online
chat.on("userOnline", (user) => {
console.log(`${user.username} came online`);
});
// Typing indicators
room.startTyping(); // auto-stops after timeout
room.on("typing", (users) => {
console.log("Typing:", users.map((u) => u.username).join(", "));
});
// Teardown: the wrapper releases its handlers and topics; the app closes
// the socket (never the other way around).
chat.detach();
client.disconnect();
Lifecycle
- Construction = attach. The wrapper wires its handlers onto the injected
client immediately. If the client is already connected, setup runs on the
next microtask; otherwise it runs when the client's
connectevent fires. ready()resolves once the first setup completed (identity, online lobby, configured rooms). Auth failures surface via your ownawait client.connect(), not viaready().- Reconnects are automatic. The wrapper restores presence and reconciles the online-user list, emitting only real deltas.
detach()removes exactly this wrapper's handlers and topics and never touches the socket. It is terminal: construct a new instance to re-attach. Detach while the client is still connected so server-side unsubscribes go through. In frameworks, call it from your dispose hook (onUnmounted, HMR dispose).- One wrapper per (client, app). Sharing a client across wrappers of DIFFERENT apps is the intended pattern; two wrappers on the same app would collide on topics and presence (the SDK warns if you do this).
API Reference
NoLagChat
Constructor
const chat = new NoLagChat(options: NoLagChatOptions);
Options:
| Option | Type | Default | Description |
|---|---|---|---|
client |
NoLagSocket |
required | The injected core NoLag client |
username |
string |
required | Display name for this user |
avatar |
string |
— | Avatar URL |
metadata |
Record<string, unknown> |
— | Custom user data |
appName |
string |
'chat' |
NoLag app for topic prefixes |
rooms |
string[] |
— | Auto-join these rooms on connect |
typingTimeout |
number |
3000 |
Ms before typing indicator auto-clears |
maxMessageCache |
number |
500 |
Max messages kept in memory per room |
debug |
boolean |
false |
Enable wrapper debug logging |
Methods
| Method | Returns | Description |
|---|---|---|
ready() |
Promise<void> |
Resolves when wrapper setup completed |
detach() |
void |
Release handlers and topics (terminal; never closes the socket) |
joinRoom(name) |
ChatRoom |
Join a chat room |
leaveRoom(name) |
void |
Leave a room |
getRooms() |
ChatRoom[] |
Get all joined rooms |
getOnlineUsers() |
ChatUser[] |
Get all online users |
setStatus(status) |
void |
Set status: 'online', 'away', 'busy', 'offline' |
updateProfile(updates) |
void |
Update username, avatar, or metadata |
Properties
| Property | Type | Description |
|---|---|---|
connected |
boolean |
Whether currently connected |
localUser |
ChatUser | null |
The current user |
rooms |
Map<string, ChatRoom> |
All joined rooms |
Events
| Event | Payload | Description |
|---|---|---|
connected |
— | Connected to NoLag |
disconnected |
— | Disconnected |
reconnected |
— | Reconnected after disconnect |
error |
Error |
Connection or protocol error |
userOnline |
ChatUser |
A user came online |
userOffline |
ChatUser |
A user went offline |
userUpdated |
ChatUser |
A user updated their profile/status |
ChatRoom
Methods
| Method | Returns | Description |
|---|---|---|
sendMessage(text, options?) |
ChatMessage |
Send a message |
getMessages() |
ChatMessage[] |
Get cached messages |
startTyping() |
void |
Broadcast typing indicator |
stopTyping() |
void |
Clear typing indicator |
getUsers() |
ChatUser[] |
Get users in this room |
getUser(userId) |
ChatUser | undefined |
Get a specific user |
markRead() |
void |
Mark all messages as read |
Properties
| Property | Type | Description |
|---|---|---|
name |
string |
Room name |
messages |
ChatMessage[] |
Cached messages |
typingUsers |
ChatUser[] |
Users currently typing |
unreadCount |
number |
Number of unread messages |
active |
boolean |
Whether currently joined |
Events
| Event | Payload | Description |
|---|---|---|
message |
ChatMessage |
New message received |
messageSent |
ChatMessage |
Your message was confirmed |
userJoined |
ChatUser |
User joined the room |
userLeft |
ChatUser |
User left the room |
typing |
ChatUser[] |
Typing users changed |
replayStart |
— | Message replay started |
replayEnd |
— | Message replay finished |
unreadChanged |
number |
Unread count changed |
Types
interface ChatUser {
userId: string;
actorTokenId: string;
username: string;
avatar?: string;
metadata?: Record<string, unknown>;
status: "online" | "away" | "busy" | "offline";
joinedAt: number;
isLocal: boolean;
}
interface ChatMessage {
id: string;
userId: string;
username: string;
avatar?: string;
text: string;
data?: Record<string, unknown>;
timestamp: number;
status: "sending" | "sent" | "error";
isReplay: boolean;
}
interface SendMessageOptions {
data?: Record<string, unknown>;
}
License
MIT