| Crates.io | aimdb-core |
| lib.rs | aimdb-core |
| version | 0.4.0 |
| created_at | 2025-11-06 22:03:57.710524+00 |
| updated_at | 2025-12-25 20:46:54.473432+00 |
| description | Core database engine for AimDB - async in-memory data synchronization with bidirectional connectors |
| homepage | https://aimdb.dev |
| repository | https://github.com/aimdb-dev/aimdb |
| max_upload_size | |
| id | 1920803 |
| size | 387,819 |
Core database engine for AimDB - async in-memory storage with data synchronization.
aimdb-core provides the foundational database engine for AimDB, designed for data synchronization across MCU → edge → cloud environments with low-latency synchronization.
Key Features:
TypeId-based routing eliminates string keys and enables compile-time safety┌─────────────────────────────────────────────────┐
│ Database<A: RuntimeAdapter> │
│ - Unified API for all operations │
│ - Type-safe record management │
│ - Builder pattern configuration │
└─────────────────────────────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
Producers Consumers Connectors
(Async) (Async) (MQTT/Kafka)
Add to your Cargo.toml:
[dependencies]
aimdb-core = "0.4"
aimdb-tokio-adapter = "0.4" # or aimdb-embassy-adapter
use aimdb_core::{AimDbBuilder, DbResult};
use aimdb_core::buffer::BufferCfg;
use aimdb_tokio_adapter::TokioAdapter;
use std::sync::Arc;
#[tokio::main]
async fn main() -> DbResult<()> {
// Create runtime adapter
let runtime = Arc::new(TokioAdapter::new()?);
// Build database with typed records
let mut builder = AimDbBuilder::new().runtime(runtime);
builder.configure::<Temperature>(|reg| {
reg.buffer(BufferCfg::SingleLatest)
.source(temperature_producer) // Async function that produces data
.tap(temperature_consumer); // Async function that consumes data
});
// Start the database
let db = builder.build()?;
db.start().await?;
Ok(())
}
For complete working examples with producers, consumers, and connectors, see:
examples/tokio-mqtt-connector-demo - Full producer/consumer with MQTT publishingexamples/sync-api-demo - Synchronous API usageexamples/remote-access-demo - Remote introspection serverChoose the right buffer strategy for your use case:
Use for: High-frequency data streams with bounded memory
use aimdb_core::buffer::BufferCfg;
reg.buffer(BufferCfg::SpmcRing { capacity: 2048 })
Use for: State synchronization, configuration updates
reg.buffer(BufferCfg::SingleLatest)
Use for: Commands and one-shot events
reg.buffer(BufferCfg::Mailbox)
Async function that generates and sends data:
async fn my_producer(
ctx: RuntimeContext<TokioAdapter>,
producer: Producer<MyData, TokioAdapter>,
) {
let data = MyData { /* ... */ };
producer.produce(data).await.ok();
}
// Register in builder
reg.buffer(BufferCfg::SingleLatest)
.source(my_producer);
Async function that receives and processes data:
async fn my_consumer(
ctx: RuntimeContext<TokioAdapter>,
consumer: Consumer<MyData, TokioAdapter>,
) {
let mut reader = consumer.subscribe().expect("Failed to subscribe");
while let Ok(data) = reader.recv().await {
// Process data
}
}
// Register in builder
reg.tap(my_consumer);
For complete examples, see examples/tokio-mqtt-connector-demo.
Records are identified by TypeId, not strings:
use std::any::TypeId;
let type_id = TypeId::of::<Temperature>();
// TypeId automatically used for record lookup
Benefits:
Core depends on abstract traits from aimdb-executor:
Adapters provide:
Spawn)TimeOps)Logger)RuntimeAdapter)[features]
std = [] # Standard library support
tracing = ["dep:tracing"] # Structured logging
metrics = [] # Performance metrics
defmt = ["dep:defmt"] # Embedded logging
All operations return DbResult<T> with DbError enum:
use aimdb_core::{DbResult, DbError};
pub async fn operation() -> DbResult<()> {
// ... operations ...
Ok(())
}
Common errors:
RecordNotFound: Requested type not registeredProducerFailed / ConsumerFailed: Task execution errorsBufferError: Buffer operations failedConnectorError: External connector issuesIntegrate with external systems like MQTT, Kafka, or custom protocols:
use aimdb_mqtt_connector::MqttConnector;
use std::sync::Arc;
let mqtt = Arc::new(MqttConnector::new("mqtt://localhost:1883").await?);
let mut builder = AimDbBuilder::new()
.runtime(runtime)
.with_connector("mqtt", mqtt);
builder.configure::<Temperature>(|reg| {
reg.buffer(BufferCfg::SingleLatest)
.source(temperature_producer)
.link("mqtt://sensors/temperature")
.with_serializer(|t| serde_json::to_vec(t).map_err(|_| SerializeError::InvalidData))
.finish();
});
let db = builder.build()?;
See examples/tokio-mqtt-connector-demo for complete connector integration.
# Run tests (std)
cargo test -p aimdb-core
# Run tests (no_std embedded)
cargo test -p aimdb-core --no-default-features --target thumbv7em-none-eabihf
Design targets:
Generate API docs:
cargo doc -p aimdb-core --open
See LICENSE file.