MDCS WebAssembly Bindings
WebAssembly bindings for the Merkle-Delta CRDT Store (MDCS), enabling real-time collaborative editing in web browsers.
Features
- CollaborativeDocument: Rich text document with CRDT-based conflict resolution
- UserPresence: Cursor and selection tracking for collaborative UIs
- Offline-first: All CRDT operations work locally, sync when connected
- Zero dependencies at runtime: Pure WASM, no JavaScript CRDT libraries needed
Installation
Building from source
# Install wasm-pack if you haven't already
# Build the WASM package
Using in a project
After building, copy the pkg directory to your project or publish to npm:
# Link locally for development
&&
&&
Quick Start
Basic Usage
import init from 'mdcs-wasm';
;
Multi-User Collaboration
import init from 'mdcs-wasm';
await ;
// User A creates a document
const docA = ;
docA.;
// User B creates their replica
const docB = ;
docB.;
// Sync: serialize states
const stateA = docA.;
const stateB = docB.;
// Merge remote states (order doesn't matter!)
docA.;
docB.;
// Both converge to the same state
console.log; // true
User Presence Tracking
import init from 'mdcs-wasm';
await ;
// Create presence for local user
const myPresence = ;
// Update cursor on text input
myPresence.;
// Update selection on mouse drag
myPresence.;
// Send to other users via WebSocket
const presenceJson = myPresence.;
ws.;
// Receive and render remote presence
ws ;
API Reference
CollaborativeDocument
| Method | Description |
|---|---|
new(doc_id, replica_id) |
Create a new document |
insert(position, text) |
Insert text at position |
delete(position, length) |
Delete text range |
apply_bold(start, end) |
Apply bold formatting |
apply_italic(start, end) |
Apply italic formatting |
apply_underline(start, end) |
Apply underline formatting |
apply_strikethrough(start, end) |
Apply strikethrough |
apply_link(start, end, url) |
Apply hyperlink |
get_text() |
Get plain text content |
get_html() |
Get HTML with formatting |
len() |
Get character count |
is_empty() |
Check if document is empty |
version() |
Get current version number |
serialize() |
Export state for sync |
merge(remote_state) |
Merge remote state (CRDT merge) |
snapshot() |
Create full snapshot |
restore(snapshot) |
Restore from snapshot |
UserPresence
| Property/Method | Description |
|---|---|
new(user_id, user_name, color) |
Create presence |
user_id |
Get user ID |
user_name |
Get display name |
color |
Get cursor color |
cursor |
Get cursor position |
selection_start |
Get selection start |
selection_end |
Get selection end |
set_cursor(position) |
Update cursor |
set_selection(start, end) |
Update selection |
clear() |
Clear cursor/selection |
has_selection() |
Check if has selection |
to_json() |
Serialize for network |
from_json(data) |
Deserialize from network |
Utility Functions
| Function | Description |
|---|---|
generate_replica_id() |
Generate unique replica ID |
generate_user_color() |
Get random user color |
console_log(message) |
Log to browser console |
React Integration Example
// hooks/useCollaborativeDocument.ts
import { useState, useEffect, useCallback, useRef } from 'react';
import init, { CollaborativeDocument } from 'mdcs-wasm';
export function useCollaborativeDocument(docId: string, userId: string) {
const [doc, setDoc] = useState<CollaborativeDocument | null>(null);
const [content, setContent] = useState('');
const [isReady, setIsReady] = useState(false);
useEffect(() => {
init().then(() => {
const newDoc = new CollaborativeDocument(docId, userId);
setDoc(newDoc);
setIsReady(true);
});
}, [docId, userId]);
const insert = useCallback((pos: number, text: string) => {
if (doc) {
doc.insert(pos, text);
setContent(doc.get_text());
}
}, [doc]);
const deleteText = useCallback((pos: number, len: number) => {
if (doc) {
doc.delete(pos, len);
setContent(doc.get_text());
}
}, [doc]);
return { doc, content, isReady, insert, deleteText };
}
Architecture
┌──────────────────────────────────────────────────┐
│ React App │
│ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ React Hooks │ │ Document Editor UI │ │
│ └──────┬───────┘ └──────────┬───────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────────────────────────────────┐ │
│ │ mdcs-wasm (WASM Module) │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │CollaborativeDoc │ │ UserPresence │ │ │
│ │ └─────────────────┘ └─────────────────┘ │ │
│ └────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
│
│ WebSocket (optional)
▼
┌──────────────────────┐
│ Sync Server │
│ (State Relay Only) │
└──────────────────────┘
Building for Production
# Optimized build with size reduction
# The pkg/ directory will contain:
# - mdcs_wasm.js (JavaScript glue code)
# - mdcs_wasm_bg.wasm (WebAssembly binary)
# - mdcs_wasm.d.ts (TypeScript definitions)
Bundle Size Optimization
The crate is configured with optimizations in Cargo.toml:
[]
= "s" # Optimize for size
= true # Link-time optimization
Expected bundle size: ~50-100KB gzipped (varies with features).
Testing
Rust Unit Tests
WASM Integration Tests
License
MIT License - see repository root for details.
Related Packages
mdcs-core- Core CRDT implementationsmdcs-delta- Delta-state synchronizationmdcs-merkle- Merkle-DAG causal trackingmdcs-db- Database layer with RichText supportmdcs-sdk- Rust SDK for server-side usage