@barocss/collaboration
Core interfaces and base adapter for connecting Barocss DataStore to CRDT/OT backends. All concrete adapters (Yjs, Liveblocks) extend this package.
Role in Architecture
- Listens to
DataStoreemitOperationevents and forwards atomic operations to the backend. - Applies remote operations back to
DataStorewhile preventing circular re-emission. - Provides shared config (client/user metadata, debug, transformOperation) and lifecycle (
connect / disconnect).
Operation Flow
Key Interfaces
-
CollaborationAdapterconnect(dataStore): Promise<void>disconnect(): Promise<void>isConnected(): booleansendOperation(op): Promise<void>receiveOperation(op): Promise<void>getDocumentState(): Promise<INode | null>setDocumentState(root: INode): Promise<void>
-
AdapterConfigclientId?: stringuser?: { id: string; name?: string; color?: string; avatar?: string }debug?: booleantransformOperation?: (op: AtomicOperation) => AtomicOperation
BaseAdapter Hooks (for implementers)
doConnect() / doDisconnect()doSendOperation(op)doReceiveOperation(op)doGetDocumentState() / doSetDocumentState(root)- Helpers:
applyOperationToDataStore(op),isRemoteOperation(op),handleLocalOperation(op)
Implementing a Custom Adapter (sketch)
class CustomAdapter extends BaseAdapter {
constructor(private backend: YourBackend, config?: AdapterConfig) {
super(config);
}
protected async doConnect() {
await this.backend.connect();
this.backend.on('remote-op', (op) => this.receiveOperation(op));
}
protected async doSendOperation(op) {
await this.backend.send(op);
}
protected async doReceiveOperation(op) {
await this.applyOperationToDataStore(op);
}
protected async doGetDocumentState() {
return this.backend.loadAsINode();
}
protected async doSetDocumentState(root: INode) {
await this.backend.saveFromINode(root);
}
}
When to Use
- Building a new collaborative backend.
- Extending existing adapters with extra metadata (
transformOperation). - Adding presence/awareness on top of a CRDT/OT layer.
@barocss/collaboration
Core collaboration interfaces and base adapter for Barocss Editor. Provides the foundation for integrating with CRDT/OT libraries.
Purpose
Enables real-time collaborative editing by:
- Providing base adapter interface
- Handling operation synchronization
- Managing conflict resolution
- Supporting multiple collaboration backends
Key Exports
CollaborationAdapter- Base adapter interfaceBaseAdapter- Common adapter logicAdapterConfig- Adapter configurationOperationMetadata- Operation metadata types
Architecture
Editor → DataStore → BaseAdapter → Backend (Yjs/Liveblocks/etc.)
↑ ↓
└─── Remote Operations ───┘
Base Adapter
The base adapter provides common functionality:
import { BaseAdapter } from '@barocss/collaboration';
class MyAdapter extends BaseAdapter {
async sendOperation(operation: AtomicOperation): Promise<void> {
// Send to backend
}
async receiveOperation(operation: AtomicOperation): Promise<void> {
// Receive from backend and apply
await this.applyOperationToDataStore(operation);
}
}
Operation Flow
Local Operations
- User performs action
- DataStore executes operation
- BaseAdapter receives operation via listener
- BaseAdapter sends to backend
Remote Operations
- Backend receives operation from other client
- Backend syncs with other clients
- BaseAdapter receives remote operation
- BaseAdapter applies to DataStore (temporarily disables listener)
- DataStore updates model
- View re-renders
Adapter Configuration
import { BaseAdapter } from '@barocss/collaboration';
const adapter = new BaseAdapter({
dataStore: dataStore,
onOperation: (operation) => {
// Handle operation
},
onError: (error) => {
// Handle error
}
});
Integration with DataStore
Adapters listen to DataStore operations:
// Adapter listens to DataStore
dataStore.on('operation', (operation) => {
adapter.handleLocalOperation(operation);
});
// Adapter applies remote operations
adapter.applyOperationToDataStore(remoteOperation);
Conflict Resolution
The base adapter handles conflicts:
- Operation Ordering: Ensures operations are applied in correct order
- Temporary Listener Disable: Prevents circular updates
- Error Handling: Handles operation failures gracefully
Available Adapters
Yjs Adapter
import { YjsAdapter } from '@barocss/collaboration-yjs';
const adapter = new YjsAdapter({
dataStore: dataStore,
ydoc: yjsDoc
});
Liveblocks Adapter
import { LiveblocksAdapter } from '@barocss/collaboration-liveblocks';
const adapter = new LiveblocksAdapter({
dataStore: dataStore,
room: liveblocksRoom
});
When to Use
- Real-time Collaboration: Enable multiple users to edit simultaneously
- Sync Across Clients: Keep documents in sync
- Conflict Resolution: Handle concurrent edits
- Backend Integration: Connect to collaboration backends
Related
- Collaboration Yjs - Yjs integration
- Collaboration Liveblocks - Liveblocks integration
- DataStore - Operation source and target