rdtjs
v0.2.6
Published
Client library for RDT (Realtime Document Synchronization) framework
Downloads
50
Maintainers
Readme
@rdt/client
Client library for RDT (Realtime Document Synchronization) framework. This library provides WebSocket-based real-time synchronization between your frontend application and RDT server with seamless Zustand store integration.
Features
- 🔄 Real-time bidirectional synchronization
- 🏪 Built-in Zustand store integration
- 🔌 WebSocket connection management with auto-reconnection
- 📦 lib0 encoding/decoding for efficient messaging
- 🎯 TypeScript support with full type safety
- ⚛️ React hooks for easy integration
- 🔍 Document and map-level subscriptions
- 🎨 DashMap-like API for familiar usage
Installation
npm install @rdt/client zustand lib0Quick Start
Basic Usage
import RdtClient from "@rdt/client";
// Create and connect to RDT server
const client = new RdtClient({
url: "ws://localhost:8080/ws",
});
await client.connect();
// Create a provider for a document map
const userProvider = client.createProvider({
documentId: "app-state",
mapKey: "users",
});
// Get the Zustand store
const userStore = userProvider.getStore();
// Use the store
console.log(userStore.getState().data); // Current users data
console.log(userStore.get("user-123")); // Get specific user
console.log(userStore.keys()); // Get all user IDsWith React Hooks
import { useRdtConnection, useRdtProvider } from "@rdt/client/react";
function App() {
const { connection, connectionState } = useRdtConnection({
url: "ws://localhost:8080/ws",
});
const { data, isLoading, error, get } = useRdtProvider(connection, {
documentId: "app-state",
mapKey: "users",
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
<h1>Users ({Object.keys(data).length})</h1>
{Object.entries(data).map(([id, user]) => (
<div key={id}>{JSON.stringify(user)}</div>
))}
</div>
);
}Subscribe to Specific Values
import { useRdtValue } from "@rdt/client/react";
function UserProfile({ userId }: { userId: string }) {
const { value: user, isLoading } = useRdtValue(
connection,
{ documentId: "app-state", mapKey: "users" },
userId,
);
if (isLoading) return <div>Loading user...</div>;
if (!user) return <div>User not found</div>;
return <div>Welcome, {user.name}!</div>;
}API Reference
RdtClient
Main client class for managing connections and providers.
const client = new RdtClient(options: RdtConnectionOptions);
// Methods
await client.connect(): Promise<void>
client.disconnect(): void
client.createProvider(config: RdtProviderConfig): RdtProvider
client.getConnection(): RdtConnection
client.getConnectionState(): ConnectionStateRdtConnection
Low-level WebSocket connection management.
const connection = new RdtConnection(options: RdtConnectionOptions);
// Methods
await connection.connect(): Promise<void>
connection.disconnect(): void
connection.subscribe(documentId: string, mapKey: string): void
connection.unsubscribe(documentId: string, mapKey: string): void
connection.getFullState(documentId: string, mapKey: string): void
connection.on(event: string, listener: Function): void
connection.off(event: string): void
connection.getState(): ConnectionStateRdtProvider
Document map provider with Zustand store integration.
const provider = new RdtProvider(connection: RdtConnection, config: RdtProviderConfig);
// Methods
provider.getStore(): RdtStore
provider.subscribe(listener: Function): () => void
provider.subscribeToKey(key: string, listener: Function): () => void
provider.destroy(): voidRdtStore
Enhanced Zustand store with DashMap-like API.
const store = provider.getStore();
// Properties
store.data: DocumentMap
store.isLoading: boolean
store.error: string | null
// Methods
store.get(key: string): JsonValue | undefined
store.has(key: string): boolean
store.keys(): string[]
store.values(): JsonValue[]
store.entries(): [string, JsonValue][]
store.size(): number
// Zustand methods
store.getState(): StoreState
store.setState(partial: Partial<StoreState>): void
store.subscribe(listener: Function): () => voidConfiguration
RdtConnectionOptions
interface RdtConnectionOptions {
url: string; // WebSocket server URL
reconnectInterval?: number; // Reconnection interval in ms (default: 5000)
maxReconnectAttempts?: number; // Max reconnection attempts (default: 10)
}RdtProviderConfig
interface RdtProviderConfig {
documentId: string; // Document identifier
mapKey: string; // Map key within the document
options?: {
initialSync?: boolean; // Request initial state (default: true)
};
}Events
Connection Events
connection.on("stateChange", (state: ConnectionState) => {
console.log("Connection state:", state);
});
connection.on("error", (error: Error) => {
console.error("Connection error:", error);
});
connection.on("fullState", (message: FullStateMessage) => {
console.log("Received full state:", message);
});
connection.on("mapChange", (message: MapChangeMessage) => {
console.log("Map changed:", message);
});Message Protocol
The library uses lib0 encoding for efficient WebSocket communication:
Client Messages
Subscribe- Subscribe to map updatesUnsubscribe- Unsubscribe from map updatesGetFullState- Request current map state
Server Messages
FullState- Complete map dataMapChange- Incremental change (Insert/Update/Remove)Error- Error messageAck- Acknowledgment
Advanced Usage
Multiple Documents
const client = new RdtClient({ url: "ws://localhost:8080/ws" });
await client.connect();
// Different document maps
const usersProvider = client.createProvider({
documentId: "users-doc",
mapKey: "profiles",
});
const settingsProvider = client.createProvider({
documentId: "app-config",
mapKey: "settings",
});Error Handling
const { connection, error } = useRdtConnection({
url: "ws://localhost:8080/ws",
});
useEffect(() => {
if (error) {
console.error("RDT Connection Error:", error);
// Handle connection errors
}
}, [error]);Manual Connection Management
const connection = new RdtConnection({ url: "ws://localhost:8080/ws" });
connection.on("stateChange", (state) => {
if (state === "connected") {
console.log("Connected to RDT server");
} else if (state === "disconnected") {
console.log("Disconnected from RDT server");
}
});
await connection.connect();Contributing
Please read our contributing guidelines and submit pull requests to our repository.
License
MIT
