OpLog and DocState
Quick Reference
- OpLog = Sequence of events/operations that compose the document history
- DocState = Current materialized state of the document
This separation enables time travel, efficient sync, and flexible storage strategies.
Key Concepts
OpLog (Operation Log)
- Append-only sequence of operations
- Causal relationships and metadata
DocState (Document State)
- Current materialized view of the document
- Actual data structures and values
- What your app reads and displays
Benefits
- Memory efficiency: Load OpLog without state (relay servers)
- Time travel: Navigate history without losing the log
- Fast startup: Load state via snapshots, fetch history later
- Flexible storage: Store separately for optimization
const = new ();
// Edit updates both
.("text").(0, "Hello");
.(.()); // Latest known version
.(.()); // The version of the current state of the document
// If the document is attached, they are the same.
Time Travel & Detachment
const = new ();
.("text").(0, "v1");
const = .();
.("text").(2, " -> v2");
// Checkout old version - DocState diverges from OpLog
.();
.(.()); // v1 state
.(.()); // Still has v2
.(.()); // true
// Return to latest
.();
Detached state: DocState shows old version while OpLog has all operations. Editing disabled by default.
Export Strategies
// Update: OpLog only (sync)
const = .({ : "update" });
// Snapshot: OpLog + DocState (persistence)
const = .({ : "snapshot" });
// Shallow: Minimal OpLog + DocState (fast startup)
const = .({ : "shallow-snapshot", : .() });
Common Patterns
Relay Server (OpLog Only)
class {
private : ;
constructor() {
this. = new ();
this..(); // Never materialize state
}
(: ) {
this..();
}
}
Best Practices
- Export modes: Updates for sync, snapshots for persistence, shallow for startup
- Optimize by use case:
- Editors: Both in memory
- Relays: OpLog only
Related Documentation
- Attached/Detached States - Document and container states
- Shallow Snapshots - History trimming
- Time Travel - Using checkout