Real-time

Events & Scoping

Push real-time updates with scoped delivery

Events & Scoping#

Events let your server push real-time updates to connected clients. A key security feature is event scoping โ€” controlling who receives each event.

typescript
const surf = await createSurf({
name: 'My App',
events: {
// Session-scoped (default) โ€” only the triggering session receives it
'cart.updated': {
description: 'Cart contents changed',
scope: 'session',
data: { items: { type: 'array' } },
},
ย 
// Global โ€” delivered to all subscribers (system announcements)
'maintenance.scheduled': {
description: 'System maintenance upcoming',
scope: 'global',
data: { startsAt: { type: 'string' }, message: { type: 'string' } },
},
ย 
// Broadcast โ€” delivered to all connected sessions
'product.restocked': {
description: 'A product came back in stock',
scope: 'broadcast',
data: { sku: { type: 'string' }, name: { type: 'string' } },
},
},
commands: { /* ... */ },
})

| Scope | Delivery | Use Case | |-------|----------|----------| | session | Only the session that triggered it | Cart updates, user-specific notifications | | global | All subscribers (including server-side) | System announcements, maintenance alerts | | broadcast | All connected sessions | Stock updates, live notifications |

You can also subscribe and emit events programmatically on the server:

typescript
// Subscribe to events
const unsubscribe = surf.events.on('cart.updated', (data) => {
console.log('Cart updated:', data)
}, sessionId) // Optional: scope to a session
ย 
// Emit events
surf.emit('maintenance.scheduled', {
startsAt: '2025-03-21T02:00:00Z',
message: 'Scheduled maintenance window',
})
ย 
// Clean up session listeners on disconnect
surf.events.removeSession(sessionId)

โš ๏ธ Note: Session scoping is a security feature. By default, events are scoped to session, preventing one user from receiving another user's updates. Only use global or broadcast for non-sensitive data.