CRDT LF Drift
A drift storage implementation for CRDT LF objects, providing efficient persistence for Change and Snapshot objects with document-scoped organization in a single drift database.
Features
- Compact Binary Storage:
ChangeandSnapshotare persisted as the self-describing binary blobs produced bycrdt_lf's nativetoBytes()/fromBytes()methods - Single Database, Many Documents: one database holds
changesandsnapshotstables; - Document-Scoped Storage: utilities that organize data by document ID for better isolation and querying
Quick Start
1. Open a database
import 'dart:io';
import 'package:crdt_lf_drift/crdt_lf_drift.dart';
Future<void> main() async {
// Open (or create) a database file...
final storage = CRDTDrift.open(File('./my_app_data.db'));
// ...or an in-memory database (useful for tests):
final memory = CRDTDrift.memory();
// Your app code here...
await storage.close();
}
2. Document-scoped storage
import 'dart:io';
import 'package:crdt_lf/crdt_lf.dart';
import 'package:crdt_lf_drift/crdt_lf_drift.dart';
const documentId = 'my-document-id';
final storage = CRDTDrift.open(File('./my_app_data.db'));
// Open storage for a specific document
final changeStorage = storage.changeStorageForDocument(documentId);
final snapshotStorage = storage.snapshotStorageForDocument(documentId);
// Or open both at once
final documentStorage = storage.storageForDocument(documentId);
Document-Scoped Storage
Data for different documents lives in the same tables and is isolated through the document_id column.
CRDTDriftChangeStorage
Manages Change objects for a specific document:
final changeStorage = storage.changeStorageForDocument('doc-123');
// Save individual changes
await changeStorage.saveChange(change);
// Batch save multiple changes
await changeStorage.saveChanges([change1, change2, change3]);
// Load all changes for the document
final changes = await changeStorage.getChanges();
// Delete changes
await changeStorage.deleteChange(change);
await changeStorage.deleteChanges([change1, change2]);
// Storage info
print('Total changes: ${await changeStorage.count}');
print('Is empty: ${await changeStorage.isEmpty}');
CRDTDriftSnapshotStorage
Manages Snapshot objects for a specific document:
final snapshotStorage = storage.snapshotStorageForDocument('doc-123');
// Save snapshots
await snapshotStorage.saveSnapshot(snapshot);
await snapshotStorage.saveSnapshots([snapshot1, snapshot2]);
// Retrieve snapshots
final snapshot = await snapshotStorage.getSnapshot('snapshot-id');
final allSnapshots = await snapshotStorage.getSnapshots();
// Check existence
if (await snapshotStorage.containsSnapshot('snapshot-id')) {
// Snapshot exists
}
How Data Is Stored
Both Change and Snapshot are stored as opaque binary blobs using the
self-describing format provided by crdt_lf (toBytes() / fromBytes()). The
schema is two tables, changes and snapshots, each with a document_id
column, an id column (change_id / snapshot_id) and a bytes blob column.
Changes are keyed by change.id, snapshots by snapshot.id.
Examples
A complete example is available here.
Storage Management
// Delete all data for a specific document
await storage.deleteDocumentData('doc-123');
// Close the database and release resources
await storage.close();
Roadmap
A roadmap is available in the project page. The roadmap provides a high-level overview of the project's goals and the current status of the project.
Packages
Other bricks of the crdt "system" are:
Libraries
- crdt_lf_drift
- A drift storage implementation for CRDT (Conflict-free Replicated Data Type) objects.