Appearance
State & Events
Subscribe to real-time state changes from PulseClient.
When Do You Need This?
Only if you're building custom UI instead of using <pulse-widget>.
Subscribing to Changes
Use client.state.on() to get notified when data changes. It returns an unsubscribe function.
typescript
// Threads updated (created, resolved, deleted, new comment, etc.)
const unsub = client.state.on('threads', (threads) => {
renderThreadList(threads);
});
// Presence changed (user joined, left, or changed status)
client.state.on('presence', (users) => {
renderAvatars(users);
});
// Notifications
client.state.on('notifications', (notifs) => {
const unread = notifs.filter(n => !n.read).length;
updateBadge(unread);
});
// Reactions
client.state.on('reactions', (reactions) => {
updateReactionCounts(reactions);
});
// Activity log
client.state.on('activity-logs', (logs) => {
renderActivityFeed(logs);
});
// Unsubscribe when done
unsub();Real-Time Events
Individual events for live interactions:
typescript
// Someone's cursor moved
client.state.on('cursor', ({ userId, position }) => { ... });
// Someone clicked
client.state.on('click', ({ userId, position }) => { ... });
// Someone is typing
client.state.on('typing', ({ userId, threadId }) => { ... });
// Viewport update
client.state.on('viewport', ({ userId, scrollX, scrollY, ... }) => { ... });
// Text selection changed
client.state.on('selection', ({ userId, selection }) => { ... });
// Drawing stroke
client.state.on('draw:stroke', ({ userId, points, color, width }) => { ... });Connection Events
typescript
client.on('connection', (state) => {
// 'connected' | 'connecting' | 'disconnected'
});
client.on('auth:ok', (data) => {
console.log('Authenticated as:', data.user.name);
});
client.on('auth:error', (data) => {
console.error('Auth failed:', data.message);
});Key Types
typescript
interface PulseUser {
id: string;
name: string;
avatar?: string;
color: string; // auto-assigned by Pulse
}
interface Thread {
id: string;
roomId: string;
resolved: boolean;
position: { x: number; y: number; selector?: string } | null;
comments: Comment[];
createdAt: string;
updatedAt: string;
}
interface Comment {
id: string;
threadId: string;
userId: string;
body: string;
mentions: string[];
createdAt: string;
editedAt: string | null;
}
interface PresenceUser {
user: PulseUser;
status: 'online' | 'idle';
lastSeen: string;
}
interface Notification {
id: string;
type: 'comment:created' | 'comment:mention' | 'comment:reply'
| 'thread:resolved' | 'reaction:added';
actorId: string;
read: boolean;
createdAt: string;
}
interface Reaction {
id: string;
targetId: string;
userId: string;
emoji: string;
}