Real-time Subscriptions in Drift KV
Drift KV provides a powerful real-time subscription system through the DriftWatcher
class, allowing you to monitor and react to changes in your data in real-time.
Basic Usage
Watching a Single Entity
import { Drift, DriftEntity } from "drift-kv";
const UserEntity = new DriftEntity({
name: "user",
options: {
timestamps: true,
},
schema: (z) => ({
name: z.string(),
email: z.string().email(),
status: z.enum(["online", "offline"]),
}),
});
const drift = new Drift({
client: await Deno.openKv(),
schemas: {
entities: {
user: UserEntity,
},
},
});
// Watch a specific user
const { cancel } = drift.entities.user.watch(
{
where: {
id: "user-123",
},
select: {
name: true,
status: true,
},
},
(changes) => {
console.log("User changed:", changes);
}
);
Watching Multiple Entities
// Watch all active users
const { cancel } = drift.entities.user.watch(
{
where: {
status: "online",
},
select: {
id: true,
name: true,
status: true,
},
},
(users) => {
console.log("Active users changed:", users);
}
);
Real-world Examples
Chat Application
const MessageEntity = new DriftEntity({
name: "message",
options: {
timestamps: true,
},
schema: (z) => ({
chatId: z.string().uuid(),
userId: z.string().uuid(),
content: z.string(),
}),
});
// Watch new messages in a specific chat
const { cancel } = drift.entities.message.watch(
{
where: {
chatId: "chat-123",
createdAt: {
gte: new Date(),
},
},
},
(messages) => {
// Update UI with new messages
updateChatUI(messages);
}
);
Real-time Dashboard
const MetricEntity = new DriftEntity({
name: "metric",
options: {
timestamps: true,
},
schema: (z) => ({
name: z.string(),
value: z.number(),
}),
});
// Watch system metrics
const { cancel } = drift.entities.metric.watchAll(
{
where: {
timestamp: {
gte: new Date(Date.now() - 300000), // Last 5 minutes
},
},
select: {
name: true,
value: true,
timestamp: true,
},
},
(metrics) => {
// Update dashboard metrics
updateDashboardMetrics(metrics);
}
);
Error Handling
try {
const { cancel } = drift.entities.user.watch({
where: {
status: "online",
},
callback: (users) => {
console.log("Users updated:", users);
},
});
// Later, unsubscribe to stop watching
cancel();
} catch (error) {
if (error instanceof DriftError) {
console.error("Watcher error:", error.message);
}
}
Performance Considerations
Optimizing Watchers
- Selective Fields
// Good: Select only needed fields
const { cancel } = drift.entities.user.watch({
select: {
id: true,
status: true,
},
callback: (users) => {
console.log("Users updated:", users);
}
});
// Avoid: Watching all fields
drift.entities.user.watchAll({}, callback);
- Efficient Filtering
// Good: Use indexed fields for filtering
const { cancel } = drift.entities.user.watch({
where: {
status: "online", // Indexed field
},
callback: (users) => {
console.log("Users updated:", users);
}
);
Best Practices
-
Resource Management
- Always unsubscribe when watchers are no longer needed
- Limit the number of active watchers
- Use selective fields to reduce data transfer
-
Error Handling
- Implement proper error handling
- Handle reconnection scenarios
- Log watcher errors appropriately
-
Performance
- Use efficient filters
- Select only necessary fields
- Consider batching updates
-
Type Safety
- Leverage TypeScript types
- Validate data with Zod
- Handle edge cases
Next Steps
- Learn about Entity Relationships
- Explore Job Queues
- Understand Plugin System
- Review Performance Optimization
Built for Deno KV
Discover Drift KV: The Ultimate Type-Safe ORM for Deno KV
Experience a powerful ORM with real-time subscriptions, job queues, and seamless compatibility across Deno KV, Node.js, Bun.js, and Edge environments.