appdb
appdb is a lightweight SurrealDB helper library for embedded applications, including Tauri-style desktop apps. It provides derive-driven model APIs, a small public surface, and optional field encryption for local-first persistence.
The workspace publishes two crates:
appdb: the main libraryappdb-macros: procedural macros used byappdb
Installation
Quick Start
use *;
use Store;
use ;
use SurrealValue;
async
Core Concepts
Model-first CRUD
#[derive(Store)] generates model-level persistence APIs such as save, save_many, create, get, and list. The intended public API is the model type itself rather than manually assembling repository calls.
Common imports are re-exported from appdb::prelude::*.
Managed schema startup and schemaless persistence
init_db* and DbRuntime::open* are the schema-managed startup path. They apply registered schema items such as indexes generated from #[unique].
Persistence itself keeps a separate contract: first saves on the default embedded runtime still support schemaless storage. Startup management and model CRUD are related, but they are not the same guarantee.
Sensitive fields
#[derive(Sensitive)] supports encrypted fields marked with #[secure].
use *;
use ;
use ;
use SurrealValue;
The model still uses the same Store APIs, while secure fields are encrypted before persistence and decrypted on read.
Sensitive models now auto-register their crypto metadata on first runtime use, so the default Store/resolver paths do not require manual registration code. You can override the defaults globally with appdb::crypto::set_default_crypto_service, set_default_crypto_account, or set_default_crypto_config, and refine a model or field with #[crypto(...)].
Supported secure shapes include:
StringOption<String>- nested
Sensitivechildren such asChild,Option<Child>, andVec<Child> - enum-bearing leaves inside a secure container via
SensitiveValueOf<T>
Every Sensitive model also exposes stable secure-field metadata through Model::secure_fields().
Foreign fields
Use #[foreign] on supported child model fields to persist related values as record links while hydrating them back into full models when reading.
Supported shapes include:
ChildOption<Child>Vec<Child>
#[table_as(...)] is also supported for referenced models.
Relation-backed fields
Use #[relate("edge_name")] on supported child model fields when the relation should live in a dedicated SurrealDB relation table instead of being stored inline on the parent row.
Supported shapes include:
ChildOption<Child>Vec<Child>
At write time the parent table omits the field, while appdb synchronizes ordered edges in the named relation table. get, list, list_limit, save, and save_many hydrate those fields back into full models on read.
Graph relations
GraphRepo provides helpers around SurrealDB relation tables.
use *;
let rel = ;
relate_at.await?;
let targets = out_ids.await?;
Raw SQL with bind values
For queries outside the derive-driven CRUD surface, use the raw SQL helpers with bind values.
use *;
let stmt = new.bind;
let value: = query_bound_return.await?;
Capabilities
#[derive(Store)]for model-level CRUDappdb::prelude::*for common imports#[derive(Sensitive)]and#[secure]for encrypted fields#[unique]-driven schema registration- Foreign fields via
#[foreign] - Table remapping with
#[table_as(...)] - Graph relation helpers via
GraphRepo - Raw SQL helpers with bind support
Workspace Layout
core/: source for the publishedappdbcratemacros/: source for the publishedappdb-macroscrate
Development
Run the final Rust 2024 workspace validator contract from the workspace root: