Skip to content

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.

Webhooks are the most reliable way to get real-time updates. DeltaBase will POST events to your endpoint.

import express from 'express';
import { eventBus } from './deltabase';
const app = express();
app.use(express.json());
// Webhook endpoint
app.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);
// Subscribe to all todo events
const subscription = await eventBus.subscribeWebhook(
'todo.*', // Event pattern
'https://your-app.com/webhooks/deltabase',
{
retryPolicy: {
maxRetries: 3,
backoffMultiplier: 2
}
}
);
console.log('Subscription created:', subscription.id);

Control which events you receive:

// All events
await eventBus.subscribeWebhook('*', webhookUrl);
// All todo events
await eventBus.subscribeWebhook('todo.*', webhookUrl);
// Only creation events
await eventBus.subscribeWebhook('*.created', webhookUrl);
// Specific event type
await eventBus.subscribeWebhook('todo.completed', webhookUrl);

For browser applications, use WebSockets for real-time updates.

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);
};

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);
});

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 component
function TodoList() {
const todos = useRealTimeTodos();
return (
<div>
{todos.map(todo => (
<TodoItem key={todo.id} todo={todo} />
))}
</div>
);
}

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);
}
}
}

Use ngrok to expose your local server:

Terminal window
# Install ngrok
npm install -g ngrok
# Expose your local server
ngrok http 3000
# Use the ngrok URL for your webhook
# https://abc123.ngrok.io/webhooks/deltabase

Keep track of your subscriptions:

// List all subscriptions
const subscriptions = await eventBus.listSubscriptions();
// Check subscription health
for (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 subscriptions
const 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.