All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Note: This is the global changelog for the AimDB project. For detailed changes to individual crates, see their respective CHANGELOG.md files:
- aimdb-core/CHANGELOG.md
- aimdb-codegen/CHANGELOG.md
- aimdb-data-contracts/CHANGELOG.md
- aimdb-derive/CHANGELOG.md
- aimdb-executor/CHANGELOG.md
- aimdb-tokio-adapter/CHANGELOG.md
- aimdb-embassy-adapter/CHANGELOG.md
- aimdb-mqtt-connector/CHANGELOG.md
- aimdb-knx-connector/CHANGELOG.md
- aimdb-websocket-connector/CHANGELOG.md
- aimdb-ws-protocol/CHANGELOG.md
- aimdb-wasm-adapter/CHANGELOG.md
- aimdb-sync/CHANGELOG.md
- aimdb-client/CHANGELOG.md
- aimdb-persistence/CHANGELOG.md
- aimdb-persistence-sqlite/CHANGELOG.md
- tools/aimdb-cli/CHANGELOG.md
- tools/aimdb-mcp/CHANGELOG.md
- MCP public mode: New
--publicflag restricts the MCP server to read-only tools for safe internet-facing deployments with SSRF protection (tools/aimdb-mcp) - MCP
--socketflag: Default socket path can be set at startup, simplifying single-instance workflows (tools/aimdb-mcp) - Context-Aware Deserializers (Design 026): Inbound connector deserializers can now receive a
RuntimeContext<R>for platform-independent timestamps and logging- New
.with_deserializer(|ctx, bytes| ...)API onInboundConnectorBuilderprovidesRuntimeContext<R>to deserialization closures - New
.with_deserializer_raw(|bytes| ...)for plain bytes-only deserialization when context is unnecessary DeserializerKindenum enforces mutual exclusivity between raw and context-aware deserializersRouter::route()propagates optional runtime context to context-aware routes
- New
- Context-Aware Serializers: Outbound connector serializers can now receive a
RuntimeContext<R>, symmetric with deserializers- New
.with_serializer(|ctx, value| ...)API onOutboundConnectorBuilderprovidesRuntimeContext<R>to serialization closures - New
.with_serializer_raw(|value| ...)for plain value-only serialization when context is unnecessary SerializerKindenum (Raw/Context) enforces mutual exclusivity- All outbound connector publishers updated to propagate runtime context via
db.runtime_any()
- New
- Design document: 026 (Context-Aware Deserializers)
- aimdb-core: Breaking API changes to
InboundConnectorLink,Router, andRouterBuilderto supportDeserializerKind(see aimdb-core/CHANGELOG.md) - aimdb-core: Breaking API change β
ConnectorLink.serializernow storesSerializerKindinstead ofSerializerFn - aimdb-core:
.with_serializer()renamed to.with_serializer_raw()for the old single-argument pattern - aimdb-mqtt-connector: Updated router dispatch for new
route()signature; outbound publishers dispatch viaSerializerKind - aimdb-knx-connector: Updated router dispatch for new
route()signature; outbound publishers dispatch viaSerializerKind - aimdb-websocket-connector: Updated router dispatch for new
route()signature; outbound publishers dispatch viaSerializerKind - All connector examples updated to use new
.with_deserializer(|_ctx, bytes| ...)and.with_serializer_raw(|value| ...)signatures rand0.8 β 0.10.1: Upgraded across workspace (aimdb-data-contracts,aimdb-embassy-adapter, examples). Migrated API:genβrandom,SmallRngseed size 16 β 32, addedRngExtimports.- README: Reordered quickstart β remote MCP exploration (zero install) is now step 2, local Docker setup moved to step 3.
- aimdb-core promoted to 1.0.0 β stable public API milestone
- aimdb-websocket-connector: New crate for real-time bidirectional WebSocket streaming
- Server mode (Axum-based) with
link_to("ws://topic")for pushing data to browser clients - Client mode (tokio-tungstenite) with
link_to("ws-client://host/topic")for AimDB-to-AimDB sync AuthHandlertrait for pluggable authentication- Client session management with automatic cleanup and late-join support
StreamableRegistryfor extensible type-erased dispatch β register types via.register::<T>()
- Server mode (Axum-based) with
- aimdb-ws-protocol: New crate with shared wire protocol types for the WebSocket ecosystem
ServerMessageandClientMessageenums with JSON-encoded"type"discriminant- MQTT-style wildcard topic matching (
#multi-level,*single-level)
- aimdb-wasm-adapter: New crate enabling AimDB to run in the browser via WebAssembly
- Full
aimdb-executortrait implementations (RuntimeAdapter,Spawn,TimeOps,Logger) Rc<RefCell<β¦>>buffers β zero-overhead for single-threaded WASMWasmDbfacade via#[wasm_bindgen]withconfigureRecord,get,set,subscribeWsBridgeβ WebSocket bridge connecting browser to remote AimDB serverSchemaRegistryfor type-erased record dispatch with extensible.register::<T>()API- React hooks:
useRecord<T>,useSetRecord<T>,useBridge
- Full
- aimdb-codegen: New crate for architecture-to-code generation
ArchitectureStatetype for reading.aimdb/state.tomldecision records- Mermaid diagram generation (
generate_mermaid) - Rust source generation (
generate_rust) β value structs, key enums,SchemaType/Linkableimpls,configure_schema()scaffolding - Common crate, hub crate, and binary crate scaffolding
- State validation module for architecture integrity checks
- aimdb-data-contracts: Refocused as a pure trait-definition crate (
SchemaType,Streamable,Linkable,Simulatable,Observable,Migratable)Streamabletrait as capability marker for types crossing serialization boundariesMigratabletrait withMigrationChainandMigrationStepfor schema evolution- Concrete contracts (Temperature, Humidity, GpsLocation) moved to application-level crates
- Removed closed
StreamableVisitordispatcher in favor of extensible registry pattern - Removed
tsfeature (ts-rsdependency)
- aimdb-core: Added
ws://andwss://URL scheme support inConnectorUrlfor WebSocket connectors - tools/aimdb-cli: New
aimdb generatesubcommand for Mermaid diagrams, Rust schema generation, and crate scaffolding viaaimdb-codegen - tools/aimdb-cli: New
aimdb watchsubcommand for live record monitoring - tools/aimdb-mcp: Architecture agent module with session state machine (
Idle β Gathering β Proposing β Resolve) - tools/aimdb-mcp: 16+ new MCP tools:
propose_add_record,propose_add_connector,propose_modify_buffer,propose_modify_fields,propose_modify_key_variants,remove_record,rename_record,reset_session,resolve_proposal,save_memory,validate_against_instance,get_architecture,get_buffer_metrics, and more - tools/aimdb-mcp: Architecture MCP resources β Mermaid diagram and validation results
- tools/aimdb-mcp:
CONVENTIONS.mdasset for architecture agent prompts - Design documents: 023 (Architecture Agent), 024 (Codegen Common Crate), 025 (WASM Adapter)
- aimdb-data-contracts: Restructured from schema+contract crate to pure trait-definition crate (version reset to 0.1.0)
- aimdb-websocket-connector: Replaced closed dispatcher with extensible
StreamableRegistryβ users register types via builder.register::<T>() - aimdb-wasm-adapter:
SchemaRegistryupdated to use extensible.register::<T>()pattern - aimdb-knx-connector: Updated Embassy dependency versions (executor 0.10.0, time 0.5.1, sync 0.8.0, net 0.9.0)
- aimdb-mqtt-connector: Updated Embassy dependency versions (executor 0.10.0, time 0.5.1, sync 0.8.0, net 0.9.0)
- Embassy submodules updated to latest upstream commits
| Crate | Previous | New |
|---|---|---|
aimdb-core |
0.5.0 | 1.0.0 |
aimdb-data-contracts |
0.5.0 | 0.1.0 |
aimdb-cli |
0.5.0 | 0.6.0 |
aimdb-mcp |
0.5.0 | 0.6.0 |
aimdb-codegen |
β | 0.1.0 (new) |
aimdb-websocket-connector |
β | 0.1.0 (new) |
aimdb-ws-protocol |
β | 0.1.0 (new) |
aimdb-wasm-adapter |
β | 0.1.1 (new) |
aimdb-tokio-adapter |
0.5.0 | unchanged |
aimdb-embassy-adapter |
0.5.0 | unchanged |
aimdb-client |
0.5.0 | unchanged |
aimdb-sync |
0.5.0 | unchanged |
aimdb-mqtt-connector |
0.5.0 | 0.5.1 |
aimdb-knx-connector |
0.3.0 | 0.3.1 |
aimdb-persistence |
0.1.0 | unchanged |
aimdb-persistence-sqlite |
0.1.0 | unchanged |
aimdb-derive |
0.1.0 | unchanged |
aimdb-executor |
0.1.0 | unchanged |
0.5.0 - 2026-02-21
- aimdb-persistence: New crate providing a pluggable persistence layer for long-term record history
PersistenceBackendtrait withstore,query,cleanup, andinitializehooksAimDbBuilderPersistExttrait adding.with_persistence(backend, retention)toAimDbBuilder<R>RecordRegistrarPersistExttrait adding.persist(record_name)toRecordRegistrar<T, R>AimDbQueryExttrait withquery_latest,query_range, andquery_rawmethods- Automatic 24-hour retention cleanup task registration
- aimdb-persistence-sqlite: New crate providing a SQLite backend for
aimdb-persistenceSqliteBackendwith WAL journal mode, actor-model command dispatch, and window-function queries- Pattern-based queries with
*wildcard support and optional time/row-count limits - Dedicated OS writer thread;
Clone=O(1)handle copy
- aimdb-data-contracts: New crate for portable, versioned AimDB data schemas
- Optional features:
observable,simulatable,migratable,ts(TypeScript bindings viats-rs) - Schema versioning and migration support
- Optional features:
- Transform API (Design 020) in
aimdb-core: Reactive data transformations between recordstransform_raw()for single-input derivations andtransform_join_raw()for multi-input joinsTransformBuilderandJoinBuilderfluent APIs with optional stateful handlers- Transforms spawned as tasks during
AimDb::build(); mutual exclusion with.source()enforced
- Graph Introspection API (Design 021) in
aimdb-coreandaimdb-client:RecordOriginenum classifying record sources (Source,Link,Transform,TransformJoin,Passive)GraphNode,GraphEdge,DependencyGraphtypes for full graph representationgraph_nodes(),graph_edges(),graph_topo_order()methods onAimDbandAimDbClient
- Record Drain API (Design 019) in
aimdb-core,aimdb-tokio-adapter, andaimdb-client:try_recv()onBufferReaderfor non-blocking batch pullsrecord.drainAimX protocol method with cold-start semantics and optional limitDrainResponsetype inaimdb-client
- Dynamic Topic/Address Routing (Design 018) in
aimdb-core,aimdb-mqtt-connector,aimdb-knx-connector:TopicProvider<T>trait for per-message outbound topic/address determinationTopicResolverFnfor late-binding inbound topic resolution at connector startupwith_topic_provider()andwith_topic_resolver()builder methods on connector links
- Graph Tools in
tools/aimdb-mcp:graph_nodes,graph_edges,graph_topo_orderMCP tools for LLM-powered graph explorationdrain_recordMCP tool for batch history access with persistent cold-start reader
- Graph Commands in
tools/aimdb-cli:aimdb graph nodes,graph edges,graph order,graph dotsubcommands- Color-coded output and DOT format export for Graphviz visualization
- Extension Macro in
aimdb-core:impl_record_registrar_ext!for generating runtime adapter extension traits
- aimdb-core: Renamed
.with_serialization()to.with_remote_access()for clearer semantics (breaking) - aimdb-core:
RecordId::new()now requires aRecordOriginparameter for dependency graph support (breaking) - aimdb-core:
set_from_jsonnow also rejects writes on records with active transforms - aimdb-core:
collect_outbound_routes()returnsOutboundRoutetuples with optionalTopicProviderFn - aimdb-core:
collect_inbound_routes()callslink.resolve_topic()for dynamic topic resolution - tools/aimdb-mcp: Replaced real-time subscription system with simpler drain-based polling
- Removed
subscribe_record,unsubscribe_record,list_subscriptions,get_notification_directorytools - Simplified architecture reduces infrastructure complexity for LLM clients
- Removed
| Crate | Previous | New |
|---|---|---|
aimdb-core |
0.4.0 | 0.5.0 |
aimdb-tokio-adapter |
0.4.0 | 0.5.0 |
aimdb-embassy-adapter |
0.4.0 | 0.5.0 |
aimdb-client |
0.4.0 | 0.5.0 |
aimdb-sync |
0.4.0 | 0.5.0 |
aimdb-mqtt-connector |
0.4.0 | 0.5.0 |
aimdb-knx-connector |
0.2.0 | 0.3.0 |
aimdb-cli |
0.4.0 | 0.5.0 |
aimdb-mcp |
0.4.0 | 0.5.0 |
aimdb-persistence |
β | 0.1.0 (new) |
aimdb-persistence-sqlite |
β | 0.1.0 (new) |
aimdb-derive |
0.1.0 | unchanged |
aimdb-executor |
0.1.0 | unchanged |
0.4.0 - 2025-12-25
- aimdb-derive: New crate providing
#[derive(RecordKey)]macro for compile-time checked record keys#[key = "..."]attribute for string representation#[key_prefix = "..."]attribute for namespace prefixing#[link_address = "..."]attribute for connector metadata (MQTT topics, KNX addresses)- Auto-generates
Hashimplementation to satisfyBorrow<str>contract
- aimdb-core:
RecordKeyis now a trait instead of a struct, enabling user-defined enum keysRecordKeytrait withas_str()and optionallink_address()methodsStringKeytype replaces oldRecordKeystruct (static/interned string keys)derivefeature flag to enable#[derive(RecordKey)]macro- Blanket implementation for
&'static str
- examples: New
mqtt-connector-demo-commonandknx-connector-demo-commoncrates for shared cross-platform types and monitors - docs: Added design documents:
016-M6-record-key-trait.md- RecordKey trait design017-M6-record-key-hash-impl.md- Hash implementation for Borrow compliance
- aimdb-mqtt-connector: Fixed initialization deadlock when subscribing to >10 MQTT topics (Issue #63)
- Event loop now spawned before subscribing (spawn-before-subscribe pattern)
- Dynamic channel capacity scales with topic count (
topics + 10)
- aimdb-mqtt-connector: Upgraded
rumqttcdependency from 0.24 to 0.25 - deny.toml: Added
OpenSSLlicense allowance (transitive via rumqttc/rustls) - deny.toml: Ignored
RUSTSEC-2025-0134advisory (rustls-pemfile unmaintained but not vulnerable)
0.3.0 - 2025-12-15
- aimdb-core: New
RecordIdtype for stable O(1) record indexing (Issue #60) - aimdb-core: New
RecordKeytype for string-based record identification with zero-alloc static keys - aimdb-core: Key-based producer/consumer API:
produce_by_key(),subscribe_by_key(),producer_by_key(),consumer_by_key() - aimdb-core:
ProducerByKey<T, R>andConsumerByKey<T, R>types for key-bound access - aimdb-core:
records_of_type::<T>()introspection method to find all records of a given type - aimdb-core:
resolve_key()method for O(1) key-to-RecordId lookups - aimdb-core: New error variants:
RecordKeyNotFound,InvalidRecordId,TypeMismatch,AmbiguousType,DuplicateRecordKey - aimdb-core:
RecordMetadatanow includesrecord_idandrecord_keyfields - aimdb-tokio-adapter: Multi-instance tests validating same-type different-key scenarios
- aimdb-core: New
BufferMetricstrait andBufferMetricsSnapshotstruct for buffer introspection (feature-gated behindmetrics)produced_count: Total items pushed to the bufferconsumed_count: Total items consumed across all readersdropped_count: Total items dropped due to lag (with per-reader semantics documented)occupancy: Current buffer fill level as(current, capacity)tuple
- aimdb-core:
RecordMetadatanow includes optional buffer metrics fields whenmetricsfeature is enabled - aimdb-tokio-adapter: Full
BufferMetricsimplementation for all buffer types (SPMC Ring, SingleLatest, Mailbox) - aimdb-tokio-adapter: Comprehensive test suite for metrics (
metrics_testsmodule) - Makefile: Added test targets for
metricsfeature combinations - docs: Added design document
015-M6-record-id-architecture.mdfor future RecordId-based storage
- aimdb-core:
configure<T>()now requires a key parameter:configure::<T>("key", |reg| ...) - aimdb-core: Internal storage changed from
BTreeMap<TypeId>toVec+HashMapindexes for O(1) hot-path access - aimdb-core:
SecurityPolicy::ReadWritenow usesHashSet<String>for writable record keys - aimdb-core: Added
hashbrowndependency for no_std-compatible HashMap - deny.toml: Added
Zliblicense allowance (used byfoldhash, hashbrown's default hasher) - aimdb-core:
DynBuffertrait no longer has a blanket implementation. Each adapter now provides its own explicit implementation. This enables adapters to providemetrics_snapshot()when themetricsfeature is enabled.
Breaking: configure<T>() now requires a key parameter
The record registration API now requires an explicit key for each record:
// Before (v0.2.x)
builder.configure::<Temperature>(|reg| {
reg.buffer(BufferCfg::SingleLatest);
});
// After (v0.3.0)
builder.configure::<Temperature>("sensor.temperature", |reg| {
reg.buffer(BufferCfg::SingleLatest);
});Key naming conventions:
- Use dot-separated hierarchical names:
"sensors.indoor","config.app" - Keys must be unique across all records (duplicate keys panic at registration)
- For single-instance records, any descriptive string works (e.g.,
"sensor.temperature","app.config")
Breaking: Type-based lookup may return AmbiguousType error
If you register multiple records of the same type, type-based methods (produce(), subscribe(), producer(), consumer()) will return AmbiguousType error:
// With multiple Temperature records registered...
db.produce(temp).await // Returns Err(AmbiguousType { count: 2, ... })
// Use key-based methods instead:
db.produce_by_key("sensors.indoor", temp).await // Works correctlyNew key-based API (recommended for multi-instance scenarios):
// Key-bound producer/consumer
let indoor_producer = db.producer_by_key::<Temperature>("sensors.indoor");
let outdoor_producer = db.producer_by_key::<Temperature>("sensors.outdoor");
// Each produces to its own record
indoor_producer.produce(temp).await?;
outdoor_producer.produce(temp).await?;
// Introspection
let temp_ids = db.records_of_type::<Temperature>(); // Returns &[RecordId]
let id = db.resolve_key("sensors.indoor"); // Returns Option<RecordId>Breaking: DynBuffer no longer has blanket impl
If you have custom Buffer<T> implementations, you now need to also implement DynBuffer<T>:
// Before (v0.2.x) - automatic via blanket impl
impl<T: Clone + Send> Buffer<T> for MyBuffer<T> { ... }
// DynBuffer was automatically implemented
// After (v0.3.0) - explicit implementation required
impl<T: Clone + Send> Buffer<T> for MyBuffer<T> { ... }
impl<T: Clone + Send + 'static> DynBuffer<T> for MyBuffer<T> {
fn push(&self, value: T) {
<Self as Buffer<T>>::push(self, value)
}
fn subscribe_boxed(&self) -> Box<dyn BufferReader<T> + Send> {
Box::new(self.subscribe())
}
fn as_any(&self) -> &dyn core::any::Any {
self
}
// Optional: implement metrics_snapshot() if you support metrics
#[cfg(feature = "metrics")]
fn metrics_snapshot(&self) -> Option<BufferMetricsSnapshot> {
None // or Some(...) if you track metrics
}
}0.2.0 - 2025-11-20
This release introduces bidirectional connector support, enabling true two-way data synchronization between AimDB and external systems. The new architecture supports simultaneous publishing and subscribing with automatic message routing, working seamlessly across both Tokio (std) and Embassy (no_std) runtimes.
- π Bidirectional Connectors: New
.link_to()and.link_from()APIs for clear directional data flows - π― Type-Erased Router: Automatic routing of incoming messages to correct typed producers
- ποΈ ConnectorBuilder Pattern: Simplified connector registration with automatic initialization
- π‘ Enhanced MQTT Connector: Complete rewrite supporting simultaneous pub/sub with automatic reconnection
- π Embassy Network Integration: Connectors can now access Embassy's network stack for network operations
- π Comprehensive Guide: New 1000+ line connector development guide with real-world examples
- aimdb-core:
.build()is now async; connector registration changed from.with_connector(scheme, instance)to.with_connector(builder) - aimdb-core:
.link()deprecated in favor of.link_to()(outbound) and.link_from()(inbound) - aimdb-core: Outbound connector architecture refactored to trait-based system:
- Removed:
TypedRecord::spawn_outbound_consumers()method (was called automatically) - Added:
ConsumerTrait,AnyReadertraits for type-erased outbound routing - Added:
AimDb::collect_outbound_routes()method to gather configured routes - Required: Connectors must implement
spawn_outbound_publishers()and call it inConnectorBuilder::build()
- Removed:
- aimdb-mqtt-connector: API changed from
MqttConnector::new()toMqttConnectorBuilder::new(); automatic task spawning removes need for manual background task management - aimdb-mqtt-connector: Added
spawn_outbound_publishers()method; must be called inbuild()for outbound publishing to work
See individual changelogs for detailed changes:
- aimdb-core: Core connector architecture, router system, bidirectional APIs
- aimdb-tokio-adapter: Connector builder integration
- aimdb-embassy-adapter: Network stack access, connector support
- aimdb-mqtt-connector: Complete bidirectional rewrite for both runtimes
- aimdb-sync: Compatibility with async build
1. Update connector registration:
// Old (v0.1.0)
let mqtt = MqttConnector::new("mqtt://broker:1883").await?;
builder.with_connector("mqtt", Arc::new(mqtt))
// New (v0.2.0)
builder.with_connector(MqttConnectorBuilder::new("mqtt://broker:1883"))2. Make build() async:
// Old (v0.1.0)
let db = builder.build()?;
// New (v0.2.0)
let db = builder.build().await?;3. Use directional link methods:
// Old (v0.1.0)
.link("mqtt://sensors/temp")
// New (v0.2.0)
.link_to("mqtt://sensors/temp") // For publishing (AimDB β External)
.link_from("mqtt://commands/temp") // For subscribing (External β AimDB)4. Remove manual MQTT task spawning (Embassy):
// Old (v0.1.0) - Manual task spawning required
let mqtt_result = MqttConnector::create(...).await?;
spawner.spawn(mqtt_task(mqtt_result.task))?;
builder.with_connector("mqtt", Arc::new(mqtt_result.connector))
// New (v0.2.0) - Automatic task spawning
builder.with_connector(MqttConnectorBuilder::new("mqtt://broker:1883"))
// Tasks spawn automatically during build()5. Update custom connectors to spawn outbound publishers:
If you've implemented a custom connector, you must add spawn_outbound_publishers() support:
// Old (v0.1.0) - Outbound consumers spawned automatically
impl ConnectorBuilder for MyConnectorBuilder {
fn build<R>(&self, db: &AimDb<R>) -> DbResult<Arc<dyn Connector>> {
// ... setup code ...
Ok(Arc::new(MyConnector { /* fields */ }))
}
// Outbound publishing happened automatically via TypedRecord::spawn_outbound_consumers()
}
// New (v0.2.0) - Must explicitly spawn outbound publishers
impl ConnectorBuilder for MyConnectorBuilder {
fn build<R>(&self, db: &AimDb<R>) -> DbResult<Arc<dyn Connector>> {
// ... setup code ...
let connector = MyConnector { /* fields */ };
// REQUIRED: Collect and spawn outbound publishers
let outbound_routes = db.collect_outbound_routes(self.protocol_name());
connector.spawn_outbound_publishers(db, outbound_routes)?;
Ok(Arc::new(connector))
}
}
// REQUIRED: Implement spawn_outbound_publishers method
impl MyConnector {
fn spawn_outbound_publishers<R: RuntimeAdapter + 'static>(
&self,
db: &AimDb<R>,
routes: Vec<(String, Box<dyn ConsumerTrait>, SerializerFn, Vec<(String, String)>)>,
) -> DbResult<()> {
for (topic, consumer, serializer, _config) in routes {
let client = self.client.clone();
let topic_clone = topic.clone();
db.runtime().spawn(async move {
// Subscribe to record updates using ConsumerTrait
match consumer.subscribe_any().await {
Ok(mut reader) => {
loop {
match reader.recv_any().await {
Ok(value) => {
// Serialize and publish
if let Ok(bytes) = serializer(&*value) {
let _ = client.publish(&topic_clone, bytes).await;
}
}
Err(_) => break,
}
}
}
Err(_) => { /* Log error */ }
}
})?;
}
Ok(())
}
}Why this change? The new trait-based architecture provides:
- β
Symmetry with inbound routing (
ProducerTraitβConsumerTrait) - β
Testability (can mock
ConsumerTraitwithout real records) - β Type safety via factory pattern (type capture at configuration time)
- β Maintainability (connector logic stays in connector crate)
Migration checklist for custom connectors:
- Add
spawn_outbound_publishers()method to connector implementation - Call
db.collect_outbound_routes(protocol_name)inConnectorBuilder::build() - Call
connector.spawn_outbound_publishers(db, routes)?before returning - Use
ConsumerTrait::subscribe_any()to get type-erased readers - Handle serialization with provided
SerializerFn - Test both inbound (
.link_from()) and outbound (.link_to()) data flows
See Connector Development Guide for complete examples.
- Added comprehensive Connector Development Guide
- Updated MQTT connector examples for both Tokio and Embassy
- Enhanced API documentation with bidirectional patterns
0.1.0 - 2025-11-06
- Initial release of AimDB async in-memory database engine
- Type-safe record system using
TypeId-based routing - Three buffer types for different data flow patterns:
- SPMC Ring Buffer: High-frequency data streams with bounded memory
- SingleLatest: State synchronization and configuration updates
- Mailbox: Commands and one-shot events
- Producer-consumer model with async task spawning
- Runtime adapter abstraction for cross-platform support
no_stdcompatibility for embedded targets- Error handling with comprehensive
DbResult<T>andDbErrortypes - Remote access protocol (AimX v1) for cross-process introspection
- Tokio Adapter (
aimdb-tokio-adapter): Full-featured std runtime support- Lock-free buffer implementations
- Configurable buffer capacities
- Comprehensive async task spawning
- Embassy Adapter (
aimdb-embassy-adapter): Embeddedno_stdruntime support- Configurable task pool sizes (8/16/32 concurrent tasks)
- Optimized for resource-constrained devices
- Compatible with ARM Cortex-M targets
- Dual runtime support for both Tokio and Embassy
- Automatic consumer registration via builder pattern
- Topic mapping with QoS and retain configuration
- Pluggable serializers (JSON, MessagePack, Postcard, custom)
- Automatic reconnection handling
- Uses
rumqttcfor std environments - Uses
mountain-mqttfor embedded environments
- MCP Server (
aimdb-mcp): LLM-powered introspection and debugging- Discover running AimDB instances
- Query record values and schemas
- Subscribe to live updates
- Set writable record values
- JSON Schema inference from record values
- Notification persistence to JSONL files
- CLI Tool (
aimdb-cli): Command-line interface (skeleton)- Instance discovery and management commands
- Record inspection capabilities
- Live watch functionality
- Client Library (
aimdb-client): Reusable connection and discovery logic- Unix domain socket communication
- AimX v1 protocol implementation
- Clean error handling
- Blocking wrapper around async AimDB core
- Thread-safe synchronous record access
- Automatic Tokio runtime management
- Ideal for gradual migration from sync to async
- Comprehensive README with architecture overview
- Individual crate documentation with examples
- 12 detailed design documents in
/docs/design - Working examples:
tokio-mqtt-connector-demo: Full Tokio MQTT integrationembassy-mqtt-connector-demo: Embedded RP2040 with WiFi MQTTsync-api-demo: Synchronous API usage patternsremote-access-demo: Cross-process introspection server
- Comprehensive Makefile with color-coded output
- GitHub Actions workflows:
- Continuous integration (format, lint, test)
- Security audits (weekly schedule + on-demand)
- Documentation generation
- Release automation
- Cross-compilation testing for
thumbv7em-none-eabihftarget cargo-denyconfiguration for license and dependency auditing- Dev container setup for consistent development environment
- β Sub-50ms latency for data synchronization
- β Lock-free buffer operations
- β Cross-platform support (MCU β edge β cloud)
- β Type safety with zero-cost abstractions
- β Protocol-agnostic connector architecture
- Kafka and DDS connectors planned for future releases
- CLI tool is currently skeleton implementation
- Performance benchmarks not yet included
- Limited to Unix domain sockets for remote access (no TCP yet)
- Rust 1.75+ required
- Tokio 1.47+ for std environments
- Embassy 0.9+ for embedded environments
- See
deny.tomlfor approved dependency licenses
None (initial release)
Not applicable (initial release)
AimDB v0.1.0 establishes the foundational architecture for async, in-memory data synchronization across MCU β edge β cloud environments. This release focuses on core functionality, dual runtime support, and developer tooling.
Highlights:
- π Dual runtime support: Works on both standard library (Tokio) and embedded (Embassy)
- π Type-safe record system eliminates runtime string lookups
- π¦ Three buffer types cover most data patterns
- π MQTT connector works in both std and
no_stdenvironments - π€ MCP server enables LLM-powered introspection
- β 27+ core tests, comprehensive CI/CD, security auditing
Get Started:
cargo add aimdb-core aimdb-tokio-adapterSee README.md for quickstart guide and examples.
Feedback Welcome: This is an early release. Please report issues, suggest features, or contribute at: https://github.com/aimdb-dev/aimdb