Real-Time Reactivity
Enable real-time updates with WebSocket, SSE, or polling support in DBindly v2.4.0.
DBindly v2.4.0 introduces a powerful reactivity system that enables real-time data updates. When data changes on the server, your UI automatically updates without requiring page refreshes or manual polling.
Quick Start
Enable reactivity in your initialization:
DBindly.init({
apiUrl: 'https://your-api.com/api',
apiKey: 'pk_live_xxx',
reactive: true, // Enable real-time updates
});Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
reactive | boolean | false | Enable real-time updates |
reactiveMode | string | 'auto' | Connection mode: 'auto', 'websocket', 'sse', or 'polling' |
wsUrl | string | - | WebSocket URL (auto-derived from apiUrl if empty) |
pollInterval | number | 5000 | Polling interval in milliseconds |
onReactiveConnect | function | - | Callback when connected |
onReactiveDisconnect | function | - | Callback when disconnected |
onReactiveUpdate | function | - | Callback when data updates |
Connection Modes
Auto Mode (Recommended)
In auto mode, DBindly tries connections in this order:
- WebSocket - Best for bidirectional, low-latency updates
- SSE (Server-Sent Events) - Fallback for one-way updates
- Polling - Final fallback using periodic HTTP requests
DBindly.init({
apiUrl: 'https://your-api.com/api',
reactive: true,
reactiveMode: 'auto', // Default
});WebSocket Mode
Force WebSocket connection:
DBindly.init({
apiUrl: 'https://your-api.com/api',
wsUrl: 'wss://your-api.com/ws', // Optional: custom WebSocket URL
reactive: true,
reactiveMode: 'websocket',
});SSE Mode
Use Server-Sent Events:
DBindly.init({
apiUrl: 'https://your-api.com/api',
reactive: true,
reactiveMode: 'sse',
});Polling Mode
Use HTTP polling as fallback:
DBindly.init({
apiUrl: 'https://your-api.com/api',
reactive: true,
reactiveMode: 'polling',
pollInterval: 3000, // Poll every 3 seconds
});The dbind_reactive Attribute
Mark elements for automatic real-time updates:
<!-- Auto-subscribe to updates for this data ID -->
<div dbind_reactive="product-123">
<h1 dbind_data="title"></h1>
<p dbind_data="price" dbind_format="currency:USD"></p>
<span dbind_data="stock"></span>
</div>When product-123 is updated on the server, all elements inside this container automatically update.
Multiple Reactive Elements
<!-- Each reactive element subscribes independently -->
<div dbind_reactive="user-profile">
<span dbind_data="name"></span>
</div>
<div dbind_reactive="notifications">
<span dbind_data="count"></span>
</div>
<div dbind_reactive="stock-ticker">
<span dbind_data="price" dbind_format="currency:USD"></span>
</div>JavaScript API
Subscribe to Data Updates
// Subscribe with callback
const unsubscribe = DBindly.subscribe('product-123', (data, action) => {
console.log('Update received:', data);
console.log('Action:', action); // 'update' or 'delete'
});
// Later: unsubscribe
unsubscribe();Subscribe to Collection Updates
// Subscribe to a collection
const unsubscribe = DBindly.subscribeCollection(
'products',
{ limit: 10, sort: { field: 'price', direction: 'desc' } },
(result, action) => {
console.log('Collection updated:', result.data);
}
);Check Connection Status
const status = DBindly.getReactiveStatus();
console.log(status);
// {
// connected: true,
// mode: 'websocket',
// subscriptions: ['product-123', 'user-profile'],
// collectionSubscriptions: ['products']
// }Disconnect
// Disconnect and clean up all subscriptions
DBindly.disconnectReactive();Event Listeners
Listen for reactive events on the document:
// When connected
document.addEventListener('dbindly:reactive-connect', (e) => {
console.log('Connected via:', e.detail.mode);
});
// When disconnected
document.addEventListener('dbindly:reactive-disconnect', (e) => {
console.log('Disconnected:', e.detail.mode, e.detail.reason);
});
// When data updates
document.addEventListener('dbindly:data-updated', (e) => {
console.log('Data updated:', e.detail.dataId, e.detail.data);
});
// When data is deleted
document.addEventListener('dbindly:data-deleted', (e) => {
console.log('Data deleted:', e.detail.dataId);
});
// When collection updates
document.addEventListener('dbindly:collection-updated', (e) => {
console.log('Collection updated:', e.detail.slug);
});Callbacks
Use configuration callbacks for centralized handling:
DBindly.init({
apiUrl: 'https://your-api.com/api',
reactive: true,
onReactiveConnect: ({ mode }) => {
console.log('Connected via', mode);
showToast('Real-time updates enabled');
},
onReactiveDisconnect: ({ mode, code }) => {
console.log('Disconnected from', mode);
showToast('Connection lost, reconnecting...');
},
onReactiveUpdate: ({ dataId, data, action }) => {
console.log('Update:', dataId, action);
// Flash updated elements
document.querySelectorAll(`[dbind_reactive="${dataId}"]`)
.forEach(el => el.classList.add('dbindly-updated'));
},
});Update Animations
DBindly includes built-in CSS classes for update animations:
/* Applied during update */
.dbindly-updating {
opacity: 0.7;
transition: opacity 0.15s ease;
}
/* Flash effect after update */
.dbindly-updated {
animation: dbindly-flash 0.5s ease;
}
@keyframes dbindly-flash {
0% { background-color: rgba(34, 197, 94, 0.2); }
100% { background-color: transparent; }
}Customize these in your own CSS:
/* Custom update flash */
.dbindly-updated {
animation: my-flash 0.3s ease;
}
@keyframes my-flash {
0% { box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5); }
100% { box-shadow: none; }
}Reactive Attributes Reference
| Attribute | Reactive | Description |
|---|---|---|
dbind_data | Yes | Text content updates in real-time |
dbind_href | Yes | URL updates in real-time |
dbind_src | Yes | Image source updates in real-time |
dbind_alt | Yes | Alt text updates in real-time |
dbind_class | Yes | CSS classes update in real-time |
dbind_style | Yes | Inline styles update in real-time |
dbind_show | Yes | Visibility toggles in real-time |
dbind_hide | Yes | Visibility toggles in real-time |
dbind_if | Yes | Conditional display in real-time |
dbind_repeat | Yes | Lists re-render in real-time |
dbind_collection | Yes | Collections sync in real-time |
dbind_compute | Yes | Computed values recalculate |
dbind_reactive | - | Marks element for auto-subscription |
Best Practices
1. Use Specific Subscriptions
Subscribe only to the data you need:
// Good: Subscribe to specific items
DBindly.subscribe('product-123');
DBindly.subscribe('cart-total');
// Avoid: Subscribing to everything2. Unsubscribe When Done
Clean up subscriptions when components unmount:
// In a React component
useEffect(() => {
const unsubscribe = DBindly.subscribe('data-id', callback);
return () => unsubscribe();
}, []);3. Handle Disconnections
Always handle disconnection scenarios:
DBindly.init({
reactive: true,
onReactiveDisconnect: () => {
showNotification('Connection lost. Data may be stale.');
},
});4. Use Polling for Critical Data
For critical data where updates must not be missed:
DBindly.init({
reactive: true,
reactiveMode: 'polling',
pollInterval: 2000, // Poll every 2 seconds
});Server Integration
For real-time updates to work, your server needs to broadcast changes. DBindly provides a utility for this:
// In your API route or server action
import { broadcastDataUpdate } from '@/lib/reactive-events';
// After updating data in the database
await updateCollectionData(dataId, newData);
// Broadcast the change to connected clients
broadcastDataUpdate(dataId, newData);Troubleshooting
Connection Not Establishing
- Check that
reactive: trueis set - Verify WebSocket/SSE endpoints are accessible
- Check browser console for connection errors
- Try forcing
reactiveMode: 'polling'as fallback
Updates Not Showing
- Verify the
dbind_reactiveattribute matches the data ID - Check that the server is broadcasting updates
- Use
DBindly.getReactiveStatus()to verify subscriptions - Enable
debug: trueto see reactive logs
Performance Issues
- Reduce the number of active subscriptions
- Increase
pollIntervalif using polling - Use collection subscriptions instead of individual items
- Consider pagination for large collections