pub struct WorkspaceCrdt { /* private fields */ }Expand description
A CRDT document representing the workspace file hierarchy.
This wraps a yrs Doc and provides methods for managing file metadata
in a conflict-free manner across multiple clients.
Implementations§
Source§impl WorkspaceCrdt
impl WorkspaceCrdt
Sourcepub fn new(storage: Arc<dyn CrdtStorage>) -> Self
pub fn new(storage: Arc<dyn CrdtStorage>) -> Self
Create a new empty workspace CRDT with the given storage backend.
Sourcepub fn with_name(storage: Arc<dyn CrdtStorage>, doc_name: String) -> Self
pub fn with_name(storage: Arc<dyn CrdtStorage>, doc_name: String) -> Self
Create a new workspace CRDT with a custom document name.
Sourcepub fn load(storage: Arc<dyn CrdtStorage>) -> StorageResult<Self>
pub fn load(storage: Arc<dyn CrdtStorage>) -> StorageResult<Self>
Load an existing workspace CRDT from storage.
If no document exists in storage, returns a new empty workspace.
Sourcepub fn load_with_name(
storage: Arc<dyn CrdtStorage>,
doc_name: String,
) -> StorageResult<Self>
pub fn load_with_name( storage: Arc<dyn CrdtStorage>, doc_name: String, ) -> StorageResult<Self>
Load a workspace CRDT with a custom document name from storage.
This loads both the base snapshot (if any) and all incremental updates to reconstruct the current state.
Sourcepub fn set_event_callback(
&mut self,
callback: Arc<dyn Fn(&FileSystemEvent) + Send + Sync>,
)
pub fn set_event_callback( &mut self, callback: Arc<dyn Fn(&FileSystemEvent) + Send + Sync>, )
Set the event callback for emitting filesystem events on remote/sync updates.
When set, this callback will be invoked with FileSystemEvents whenever
apply_update() is called with a non-Local origin. This enables unified
event handling where the UI responds the same way to both local and remote changes.
§Example
let mut crdt = WorkspaceCrdt::load(storage)?;
crdt.set_event_callback(Arc::new(|event| {
println!("Remote change: {:?}", event);
}));Sourcepub fn storage(&self) -> &Arc<dyn CrdtStorage>
pub fn storage(&self) -> &Arc<dyn CrdtStorage>
Get a reference to the storage backend.
Sourcepub fn get_file(&self, path: &str) -> Option<FileMetadata>
pub fn get_file(&self, path: &str) -> Option<FileMetadata>
Get metadata for a file at the given path.
Sourcepub fn set_file(&self, path: &str, metadata: FileMetadata) -> StorageResult<()>
pub fn set_file(&self, path: &str, metadata: FileMetadata) -> StorageResult<()>
Set metadata for a file at the given path.
This will create a new entry or update an existing one. The change is automatically recorded in the update history.
§Errors
Returns an error if the update fails to persist to storage.
Sourcepub fn delete_file(&self, path: &str) -> StorageResult<()>
pub fn delete_file(&self, path: &str) -> StorageResult<()>
Mark a file as deleted (soft delete).
This sets the deleted flag to true rather than removing the entry,
which is important for proper CRDT tombstone handling.
§Errors
Returns an error if the update fails to persist to storage.
Sourcepub fn remove_file(&self, path: &str) -> StorageResult<()>
pub fn remove_file(&self, path: &str) -> StorageResult<()>
Remove a file entry completely from the CRDT.
Warning: This should generally not be used. Prefer [delete_file]
for proper tombstone handling. Use this only for garbage collection
of very old deleted entries.
§Errors
Returns an error if the update fails to persist to storage.
Sourcepub fn list_files(&self) -> Vec<(String, FileMetadata)>
pub fn list_files(&self) -> Vec<(String, FileMetadata)>
List all files in the workspace.
Returns a vector of (path, metadata) tuples for all files,
including deleted ones (check metadata.deleted).
Sourcepub fn list_active_files(&self) -> Vec<(String, FileMetadata)>
pub fn list_active_files(&self) -> Vec<(String, FileMetadata)>
List all non-deleted files in the workspace.
Sourcepub fn file_count(&self) -> usize
pub fn file_count(&self) -> usize
Get the number of files in the workspace (including deleted).
Sourcepub fn create_file(&self, metadata: FileMetadata) -> StorageResult<String>
pub fn create_file(&self, metadata: FileMetadata) -> StorageResult<String>
Create a new file with a generated UUID as the key.
This is the primary method for creating files in the doc-ID based system. Returns the generated doc_id that can be used to reference this file.
§Arguments
metadata- File metadata (must havefilenameset)
§Returns
The generated doc_id (UUID) for the new file.
Sourcepub fn get_path(&self, doc_id: &str) -> Option<PathBuf>
pub fn get_path(&self, doc_id: &str) -> Option<PathBuf>
Derive the filesystem path from a doc_id by walking the parent chain.
This reconstructs the full path by traversing the part_of references
up to the root and then joining the filenames.
§Arguments
doc_id- The document ID to get the path for
§Returns
The derived path, or None if the doc_id doesn’t exist or the chain is broken.
Sourcepub fn find_by_path(&self, path: &Path) -> Option<String>
pub fn find_by_path(&self, path: &Path) -> Option<String>
Sourcepub fn rename_file(&self, doc_id: &str, new_filename: &str) -> StorageResult<()>
pub fn rename_file(&self, doc_id: &str, new_filename: &str) -> StorageResult<()>
Rename a file by updating its filename.
In the doc-ID system, renames are trivial - just update the filename property. The doc_id remains stable.
§Arguments
doc_id- The document ID of the file to renamenew_filename- The new filename (e.g., “new-name.md”)
Sourcepub fn move_file(
&self,
doc_id: &str,
new_parent_id: Option<&str>,
) -> StorageResult<()>
pub fn move_file( &self, doc_id: &str, new_parent_id: Option<&str>, ) -> StorageResult<()>
Move a file by updating its parent reference.
In the doc-ID system, moves are trivial - just update the part_of property. The doc_id remains stable.
§Arguments
doc_id- The document ID of the file to movenew_parent_id- The doc_id of the new parent, or None for root
Sourcepub fn needs_migration(&self) -> bool
pub fn needs_migration(&self) -> bool
Check if the workspace needs migration from path-based to doc-ID-based format.
Returns true if any file key contains a path separator (‘/’).
Sourcepub fn migrate_to_doc_ids(&self) -> StorageResult<usize>
pub fn migrate_to_doc_ids(&self) -> StorageResult<usize>
Migrate the workspace from path-based to doc-ID-based format.
This performs the following steps:
- Generate UUIDs for all existing files
- Extract filename from each path
- Convert part_of paths to doc_ids
- Convert contents paths to doc_ids
- Delete old path-based entries
- Create new UUID-based entries
§Returns
Number of files migrated, or an error.
Sourcepub fn encode_state_vector(&self) -> Vec<u8> ⓘ
pub fn encode_state_vector(&self) -> Vec<u8> ⓘ
Encode the current state vector for sync handshake.
Send this to a remote peer to initiate synchronization. The remote peer will use it to compute what updates you’re missing.
Sourcepub fn encode_state_as_update(&self) -> Vec<u8> ⓘ
pub fn encode_state_as_update(&self) -> Vec<u8> ⓘ
Encode the full document state as an update.
This returns a binary blob that can be applied to another document to bring it up to date with this one.
Sourcepub fn encode_diff(&self, remote_state_vector: &[u8]) -> StorageResult<Vec<u8>>
pub fn encode_diff(&self, remote_state_vector: &[u8]) -> StorageResult<Vec<u8>>
Encode only the updates that the remote peer is missing.
Given the remote peer’s state vector, this computes and returns only the updates they don’t have yet.
Sourcepub fn apply_update(
&self,
update: &[u8],
origin: UpdateOrigin,
) -> StorageResult<Option<i64>>
pub fn apply_update( &self, update: &[u8], origin: UpdateOrigin, ) -> StorageResult<Option<i64>>
Apply an update from a remote peer.
Returns the update ID if the update was persisted to storage.
For non-Local origins (Remote, Sync), this method will detect what changed
and emit corresponding FileSystemEvents via the event callback. This enables
unified event handling where the UI responds the same way to both local and
remote changes.
Sourcepub fn replace_state(
&mut self,
full_state: &[u8],
origin: UpdateOrigin,
) -> StorageResult<Option<i64>>
pub fn replace_state( &mut self, full_state: &[u8], origin: UpdateOrigin, ) -> StorageResult<Option<i64>>
Replace the entire CRDT state with the given state.
This is used during initial sync when a new client receives the full state from the server. Instead of merging (which can cause tombstoning), this completely replaces the local state.
Important: This method discards all local state and replaces it with the provided state. Any local changes not synced will be lost.
§Arguments
full_state- The full CRDT state as a Y-update encoded in v1 formatorigin- The origin of the update (typicallyUpdateOrigin::Sync)
§Returns
The update ID if the state was persisted to storage.
Sourcepub fn apply_update_tracking_changes(
&self,
update: &[u8],
origin: UpdateOrigin,
) -> StorageResult<(Option<i64>, Vec<String>, Vec<(String, String)>)>
pub fn apply_update_tracking_changes( &self, update: &[u8], origin: UpdateOrigin, ) -> StorageResult<(Option<i64>, Vec<String>, Vec<(String, String)>)>
Apply an update from a remote peer and return the list of changed file paths.
This is like apply_update but returns the paths of files that changed,
allowing callers to selectively write those files to disk.
Returns (update_id, changed_paths, renames) where:
- changed_paths includes newly created, deleted, and modified files
- renames is a list of (old_path, new_path) pairs for detected renames
Sourcepub fn save(&self) -> StorageResult<()>
pub fn save(&self) -> StorageResult<()>
Save the current document state to storage.
Sourcepub fn reload(&mut self) -> StorageResult<()>
pub fn reload(&mut self) -> StorageResult<()>
Reload the document state from storage, discarding local changes.
Sourcepub fn get_history(&self) -> StorageResult<Vec<CrdtUpdate>>
pub fn get_history(&self) -> StorageResult<Vec<CrdtUpdate>>
Get all updates from storage for this document.
Sourcepub fn get_updates_since(&self, since_id: i64) -> StorageResult<Vec<CrdtUpdate>>
pub fn get_updates_since(&self, since_id: i64) -> StorageResult<Vec<CrdtUpdate>>
Get updates since a specific update ID.
Sourcepub fn get_latest_update_id(&self) -> StorageResult<i64>
pub fn get_latest_update_id(&self) -> StorageResult<i64>
Get the latest update ID.
Sourcepub fn observe_updates<F>(&self, callback: F) -> Subscription
pub fn observe_updates<F>(&self, callback: F) -> Subscription
Subscribe to document updates.
The callback receives the binary update data whenever the document changes. Returns a subscription that will unsubscribe when dropped.
§Panics
Panics if unable to acquire transaction for observing.
Sourcepub fn observe_files<F>(&self, callback: F) -> Subscription
pub fn observe_files<F>(&self, callback: F) -> Subscription
Subscribe to changes in the files map.
The callback receives the path and new metadata (or None if removed) for each changed file.