Set Up Real-time Updates
Stream live events to your application using webhooks and WebSockets
Real-time updates are where DeltaBase gets interesting. Here’s how to set them up.
Option 1: Webhooks (Recommended)
Section titled “Option 1: Webhooks (Recommended)”Webhooks are the most reliable way to get real-time updates. DeltaBase will POST events to your endpoint.
Set up your webhook endpoint
Section titled “Set up your webhook endpoint”import express from 'express';import { eventBus } from './deltabase';
const app = express();app.use(express.json());
// Webhook endpointapp.post('/webhooks/deltabase', (req, res) => { const { event, eventStoreId, subscriptionId } = req.body;
console.log('Received event:', event);
// Process the event switch (event.type) { case 'todo.created': notifyClients('todo_created', event); break; case 'todo.completed': notifyClients('todo_completed', event); break; // ... handle other events }
// Always respond with 200 OK res.status(200).send('OK');});
app.listen(3000);
Create the subscription
Section titled “Create the subscription”// Subscribe to all todo eventsconst subscription = await eventBus.subscribeWebhook( 'todo.*', // Event pattern 'https://your-app.com/webhooks/deltabase', { retryPolicy: { maxRetries: 3, backoffMultiplier: 2 } });
console.log('Subscription created:', subscription.id);
Event patterns
Section titled “Event patterns”Control which events you receive:
// All eventsawait eventBus.subscribeWebhook('*', webhookUrl);
// All todo eventsawait eventBus.subscribeWebhook('todo.*', webhookUrl);
// Only creation eventsawait eventBus.subscribeWebhook('*.created', webhookUrl);
// Specific event typeawait eventBus.subscribeWebhook('todo.completed', webhookUrl);
Option 2: WebSockets (Browser clients)
Section titled “Option 2: WebSockets (Browser clients)”For browser applications, use WebSockets for real-time updates.
Client-side connection
Section titled “Client-side connection”const eventStoreId = 'your-event-store';const ws = new WebSocket( `wss://api.delta-base.com/event-stores/${eventStoreId}/events/ws?apiKey=your-key`);
ws.onopen = () => { console.log('Connected to DeltaBase');
// Subscribe to specific events ws.send(JSON.stringify({ action: 'subscribe', eventFilter: 'todo.*' }));};
ws.onmessage = (event) => { const data = JSON.parse(event.data); console.log('Received event:', data);
// Update your UI updateTodoList(data);};
ws.onerror = (error) => { console.error('WebSocket error:', error);};
Server-side WebSocket proxy
Section titled “Server-side WebSocket proxy”If you need server-side WebSocket handling:
import WebSocket from 'ws';
const ws = new WebSocket( `wss://api.delta-base.com/event-stores/todos/events/ws?apiKey=${process.env.DELTABASE_API_KEY}`);
ws.on('open', () => { ws.send(JSON.stringify({ action: 'subscribe', eventFilter: 'todo.*' }));});
ws.on('message', (data) => { const event = JSON.parse(data.toString());
// Forward to your clients via Socket.IO, SSE, etc. io.emit('todo_event', event);});
React real-time hook
Section titled “React real-time hook”Make it easy to use in React:
import { useEffect, useState } from 'react';
export function useRealTimeTodos() { const [todos, setTodos] = useState<Todo[]>([]);
useEffect(() => { const ws = new WebSocket( `wss://api.delta-base.com/event-stores/todos/events/ws?apiKey=${process.env.REACT_APP_DELTABASE_API_KEY}` );
ws.onopen = () => { ws.send(JSON.stringify({ action: 'subscribe', eventFilter: 'todo.*' })); };
ws.onmessage = (event) => { const data = JSON.parse(event.data);
switch (data.type) { case 'todo.created': setTodos(prev => [...prev, buildTodoFromEvent(data)]); break; case 'todo.completed': setTodos(prev => prev.map(todo => todo.id === data.data.id ? { ...todo, completed: true } : todo )); break; // ... handle other events } };
return () => ws.close(); }, []);
return todos;}
// Usage in componentfunction TodoList() { const todos = useRealTimeTodos();
return ( <div> {todos.map(todo => ( <TodoItem key={todo.id} todo={todo} /> ))} </div> );}
Handling connection issues
Section titled “Handling connection issues”Real-time connections can fail. Handle it gracefully:
class ReliableWebSocket { private ws: WebSocket | null = null; private reconnectAttempts = 0; private maxReconnectAttempts = 5;
constructor(private url: string) { this.connect(); }
private connect() { this.ws = new WebSocket(this.url);
this.ws.onopen = () => { console.log('Connected'); this.reconnectAttempts = 0; };
this.ws.onclose = () => { console.log('Disconnected'); this.handleReconnect(); };
this.ws.onerror = (error) => { console.error('WebSocket error:', error); }; }
private handleReconnect() { if (this.reconnectAttempts < this.maxReconnectAttempts) { this.reconnectAttempts++; const delay = Math.pow(2, this.reconnectAttempts) * 1000;
console.log(`Reconnecting in ${delay}ms...`); setTimeout(() => this.connect(), delay); } }
send(data: string) { if (this.ws?.readyState === WebSocket.OPEN) { this.ws.send(data); } }}
Testing webhooks locally
Section titled “Testing webhooks locally”Use ngrok to expose your local server:
# Install ngroknpm install -g ngrok
# Expose your local serverngrok http 3000
# Use the ngrok URL for your webhook# https://abc123.ngrok.io/webhooks/deltabase
Monitoring subscriptions
Section titled “Monitoring subscriptions”Keep track of your subscriptions:
// List all subscriptionsconst subscriptions = await eventBus.listSubscriptions();
// Check subscription healthfor (const sub of subscriptions) { console.log(`Subscription ${sub.id}:`); console.log(` Status: ${sub.status}`); console.log(` Last delivery: ${sub.lastDeliveryAttempt}`); console.log(` Failed deliveries: ${sub.failedDeliveries}`);}
// Delete unhealthy subscriptionsconst unhealthy = subscriptions.filter(s => s.failedDeliveries > 10);for (const sub of unhealthy) { await eventBus.unsubscribe(sub.id);}
Real-time updates make your app feel alive. Users see changes instantly, no refresh required.