pub struct Instance { /* private fields */ }Expand description
Database implementation on top of the storage backend.
Instance manages infrastructure only:
- Backend storage and device identity
- System databases (_users, _databases, _sync)
- User account management (create, login, list)
All database creation and key operations happen through User after login.
Instance is a cheap-to-clone handle around Arc<InstanceInternal>.
§Example
let instance = Instance::open(Box::new(InMemory::new())).await?;
// Create passwordless user
instance.create_user("alice", None).await?;
let mut user = instance.login_user("alice", None).await?;
// Use User API for operations
let mut settings = Doc::new();
settings.set("name", "my_database");
let default_key = user.get_default_key()?;
let db = user.create_database(settings, &default_key).await?;Implementations§
Source§impl Instance
impl Instance
Sourcepub async fn open(backend: Box<dyn BackendImpl>) -> Result<Self>
pub async fn open(backend: Box<dyn BackendImpl>) -> Result<Self>
Load an existing Instance or create a new one (recommended).
This is the recommended method for initializing an Instance. It automatically detects whether the backend contains existing system state (device key and system databases) and loads them, or creates new ones if starting fresh.
Instance manages infrastructure only:
- Backend storage and device identity
- System databases (_users, _databases, _sync)
- User account management (create, login, list)
All database creation and key operations require explicit User login.
§Arguments
backend- The storage backend to use
§Returns
A Result containing the configured Instance
§Example
let backend = InMemory::new();
let instance = Instance::open(Box::new(backend)).await?;
// Create and login user explicitly
instance.create_user("alice", None).await?;
let mut user = instance.login_user("alice", None).await?;
// Use User API for operations
let mut settings = Doc::new();
settings.set("name", "my_database");
let default_key = user.get_default_key()?;
let db = user.create_database(settings, &default_key).await?;Sourcepub async fn open_with_clock(
backend: Box<dyn BackendImpl>,
clock: Arc<dyn Clock>,
) -> Result<Self>
pub async fn open_with_clock( backend: Box<dyn BackendImpl>, clock: Arc<dyn Clock>, ) -> Result<Self>
Load an existing Instance or create a new one with a custom clock.
This is the same as Instance::open but allows injecting a custom clock
for controllable timestamps in tests. The clock is used for timestamps in
height calculations and peer tracking.
Only available with the testing feature or in test builds.
§Arguments
backend- The storage backend to useclock- The time provider to use (typicallyFixedClock)
§Returns
A Result containing the configured Instance
Sourcepub async fn create(backend: Box<dyn BackendImpl>) -> Result<Self>
pub async fn create(backend: Box<dyn BackendImpl>) -> Result<Self>
Create a new Instance on a fresh backend (strict creation).
This method creates a new Instance and fails if the backend is already initialized (contains a device key and system databases). Use this when you want to ensure you’re creating a fresh instance.
Instance manages infrastructure only:
- Backend storage and device identity
- System databases (_users, _databases, _sync)
- User account management (create, login, list)
All database creation and key operations require explicit User login.
For most use cases, prefer Instance::open() which automatically handles both
new and existing backends.
§Arguments
backend- The storage backend to use (must be uninitialized)
§Returns
A Result containing the configured Instance, or InstanceAlreadyExists error if the backend is already initialized.
§Example
let backend = InMemory::new();
let instance = Instance::create(Box::new(backend)).await?;
// Create and login user explicitly
instance.create_user("alice", None).await?;
let mut user = instance.login_user("alice", None).await?;
// Use User API for operations
let mut settings = Doc::new();
settings.set("name", "my_database");
let default_key = user.get_default_key()?;
let db = user.create_database(settings, &default_key).await?;Sourcepub async fn has_database(&self, root_id: &ID) -> bool
pub async fn has_database(&self, root_id: &ID) -> bool
Check if a database is present locally.
This differs from has_entry in that it checks for the active tracking
of the database by the Instance. This method checks if we’re tracking
the database’s tip state.
Sourcepub async fn create_user(
&self,
user_id: &str,
password: Option<&str>,
) -> Result<String>
pub async fn create_user( &self, user_id: &str, password: Option<&str>, ) -> Result<String>
Create a new user account with flexible password handling.
Creates a user with or without password protection. Passwordless users are appropriate for embedded applications where filesystem access = database access.
§Arguments
user_id- Unique user identifier (username)password- Optional password. If None, user is passwordless (instant login, no encryption)
§Returns
A Result containing the user’s UUID (stable internal identifier)
Sourcepub async fn login_user(
&self,
user_id: &str,
password: Option<&str>,
) -> Result<User>
pub async fn login_user( &self, user_id: &str, password: Option<&str>, ) -> Result<User>
Login a user with flexible password handling.
Returns a User session object that provides access to user operations. For password-protected users, provide the password. For passwordless users, pass None.
§Arguments
user_id- User identifier (username)password- Optional password. None for passwordless users.
§Returns
A Result containing the User session
Sourcepub async fn list_users(&self) -> Result<Vec<String>>
pub async fn list_users(&self) -> Result<Vec<String>>
Sourcepub fn device_key(&self) -> &PrivateKey
pub fn device_key(&self) -> &PrivateKey
Test-only: Get the device signing key.
This is exposed for testing purposes only. In production, use the User API.
Sourcepub async fn enable_sync(&self) -> Result<()>
pub async fn enable_sync(&self) -> Result<()>
Initializes the Sync module for this instance.
Enables synchronization operations for this instance. This method is idempotent; calling it multiple times has no effect.
§Errors
Returns an error if the sync settings database cannot be created or if device key generation/storage fails.
Sourcepub fn sync(&self) -> Option<Arc<Sync>>
pub fn sync(&self) -> Option<Arc<Sync>>
Get a reference to the Sync module.
Returns a cheap-to-clone Arc handle to the Sync module. The Sync module uses interior mutability (AtomicBool and OnceLock) so &self methods are sufficient.
§Returns
An Option containing an Arc<Sync> if the Sync module is initialized.
Sourcepub async fn flush_sync(&self) -> Result<()>
pub async fn flush_sync(&self) -> Result<()>
Flush all pending sync operations.
This is a convenience method that processes all queued entries and retries any failed sends. If sync is not enabled, returns Ok(()).
This is useful to force pending syncs to complete, e.g. on program shutdown.
§Returns
Ok(()) if sync is not enabled or all operations completed successfully,
or an error if sends failed.
Sourcepub async fn put_entry(
&self,
tree_id: &ID,
verification: VerificationStatus,
entry: Entry,
source: WriteSource,
) -> Result<()>
pub async fn put_entry( &self, tree_id: &ID, verification: VerificationStatus, entry: Entry, source: WriteSource, ) -> Result<()>
Write an entry to the backend and dispatch callbacks.
This is the central coordination point for all entry writes in the system. All writes must go through this method to ensure:
- Entries are persisted to the backend
- Appropriate callbacks are triggered based on write source
- Hooks have full context (entry, database, instance)
§Arguments
tree_id- The root ID of the database being written toverification- Authentication verification status of the entryentry- The entry to writesource- Whether this is a local or remote write
§Returns
A Result indicating success or failure
Sourcepub fn downgrade(&self) -> WeakInstance
pub fn downgrade(&self) -> WeakInstance
Downgrade to a weak reference.
Creates a weak reference that does not prevent the Instance from being dropped. This is useful for preventing circular reference cycles in dependent objects.
§Returns
A WeakInstance that can be upgraded back to a strong reference.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Instance
impl !RefUnwindSafe for Instance
impl Send for Instance
impl Sync for Instance
impl Unpin for Instance
impl !UnwindSafe for Instance
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> CompatExt for T
impl<T> CompatExt for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more