All notable changes to the aimdb-client crate will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.7.0 - 2026-09-18
tcp://endpoint validation shares one grammar with the connector.require_tcp_targethad grown a 56-line private copy of thehost:portgrammar; it now callsaimdb_core::session::split_host_port_optand keeps only its own policy on top — a URL must name its port, where a connector constructor may default one. Rejection messages are unchanged and now pinned by a test, including the two that are easy to confuse: an unbracketed IPv6 literal is told to add brackets, a bracketed one missing its port is told to add a port.
- One subscription API:
AimxConnection::subscribe. It now yieldsResult<RecordUpdate, ClientError>— the full-fidelity stream — and the value-only projections (subscribe's oldStream<Value>shape andsubscribe_with_topics) are gone. Three shapes of one stream meant every caller but one silently discarded the loss metadata the engine had already computed. A caller that only wants values maps:stream.filter_map(|r| ready(r.ok().and_then(|u| u.value))).RecordUpdatecarries:topic— the concrete record that fired (wildcard subscriptions#/*fan in many records under one subscription);value: Option<Value>—Nonewhen the frame arrived but its payload did not decode. Such a frame is delivered rather than dropped, soskippedandsnapshot_endstay exact on the update they describe, and one bad record cannot kill a wildcard stream fanning in many;skipped— updates lost immediately before this one;snapshot_end— this update closes the late-join snapshot burst; every update after it is a live event. Only set when the burst produced a final snapshot to carry it (see below).ClientHandle-level streams carrySubUpdate(seeaimdb-core).
- Dead protocol helpers removed (retired with the hand-rolled client in
PR #124, deleted now):
RequestExt,ResponseExt,serialize_message,parse_message,EventMessage,cli_hello.RecordMetadata,WelcomeMessage,Request,Response,Eventre-exports remain.
-
Loss visibility on the subscription stream.
RecordUpdateexposes the delivery gap the engine already tracks (SubUpdate::skipped) — previously reachable only from rawClientHandlestreams, so ordinary client/CLI/bridge consumers could not tell a buffer overrun from an idle producer — plussnapshot_end, which marks the last update of a late-join snapshot burst. The engine reserves a sink slot for that final update, so an overrun cannot cost you the marker and a burst closes even when no live event ever follows; the client boundary preserves that by delivering every frame as exactly one stream item (an undecodable payload arrives asvalue: Nonerather than being dropped and folded into a next update that may never come). The marker rides the last snapshot's frame, so a burst that produced none — nothing matched, nothing has a value yet, an exact-topic subscribe, a tail that failed to encode — ends without one; its absence is not a signal and must not be waited on. -
A refused subscription is observable. A terminal rejection (denied, subscription limit reached) now arrives as one
Erritem that ends the stream, instead of a silent end of stream indistinguishable from a disconnect or a closed record.aimdb watchexits non-zero on one (seeaimdb-cli). -
Transport-agnostic endpoint resolver — pick the transport at runtime via a
scheme://URL (Issue #123, follow-up to #39 / #122). Newendpointmodule:parse_endpoint(pure, feature-independent grammar) anddial(url) -> Box<dyn Dialer>map an endpoint string to a transportDialer, the way records already pick one for links. Schemes:unix://PATH/uds://PATH, a bare path (theunix://shorthand), andserial://DEVICE?baud=N. An unknown scheme — or one whose transport isn't compiled in — is rejected with a clear error. NewAimxConnection::connect_over(dialer)/connect_over_with_timeoutdial over an explicitDialer, bypassing resolution. (Rides a newimpl Dialer for Box<dyn Dialer>inaimdb-core.)
- The
hellohandshake now reports protocol version"2.0"(was a stale"1.0"). The client has spoken the AimX-v2 wire since the engine rewrite, but its localPROTOCOL_VERSIONconstant was never bumped; it is now a re-export ofaimdb_core::remote::PROTOCOL_VERSION, so client and server can no longer drift. (The server does not validate the hello version, so this is cosmetic on the wire.) README updated to match the v2 reality (AimxConnection, endpoint URLs, v2 framing).
AimxConnection::connectnow takes a&strendpoint, and transports are feature-gated (Issue #123).connect/connect_with_timeoutaccept an endpoint string (wasimpl AsRef<Path>) — ascheme://URL or a bare path — resolved through the newendpointmodule. The transports are now opt-in Cargo features:transport-uds(default; makesaimdb-uds-connectoroptional and gates thediscoverymodule — a Unix-socket scan) andtransport-serial(off by default; pullsaimdb-serial-connector, i.e.tokio-serial→ libudev).ClientError::ConnectionFailed'ssocketfield is renamedendpoint, and a newClientError::UnsupportedEndpointcovers malformed / not-built-in endpoints. The discoveryInstanceInfo.socket_pathfield is likewise renamedendpoint— it now also carries a caller-supplied endpoint, not just a discovered socket path.AimxClient→AimxConnection, rebuilt on the shared session engine (Issue #39, design doc). The synchronousconnection::AimxClientis retired; the newengine::AimxConnectiondrivesaimdb-core'srun_clientengine overaimdb-uds-connector'sUdsDialerand speaks the reshaped AimX-v2 protocol. Both the type and the module are re-exported from the crate root (aimdb_client::AimxConnection); theconnectionmodule is replaced byengine.connect()performs thehellohandshake, and the full tool surface (list/get/set/subscribe/drain/graph/query) is available.subscribe(record_name)now returns aStreamof updates directly — the engine routes events back by request id, so there is no server-allocated subscription id to track (the old(subscription_id, queue_size)handshake is gone).- New
connect_with_timeout(path, timeout)bounds the whole dial + handshake (used by discovery probing). - New dependencies:
aimdb-uds-connector(the UDS transport),aimdb-tokio-adapter(theTimeOpsclock handed torun_client), andfutures.aimdb-coreis now pulled in with theconnector-sessionfeature.
0.6.0 - 2026-05-22
AimxClient::reset_stage_profiling()(Issue #58): New method issuing theprofiling.resetAimX request to clear stage profiling counters for every record on the server. Requires the server to be built with theprofilingfeature and the connection to have write permission.
0.5.0 - 2026-02-21
- Record Drain API: New methods for batch history access
drain_record(name): Drain all pending values since last drain calldrain_record_with_limit(name, limit): Drain with maximum count limitDrainResponsestruct withrecord_name,values(JSON array), andcount- Cold-start semantics: first drain creates reader and returns empty
- Graph Introspection API: New methods for dependency graph exploration
graph_nodes(): Get all nodes with origin, buffer type, tap count, outbound statusgraph_edges(): Get all directed edges showing data flowgraph_topo_order(): Get record keys in topological (spawn) order
- Re-export:
DrainResponsenow re-exported from crate root for convenience
0.4.0 - 2025-12-25
- Dependency Update: Updated
aimdb-coredependency to 0.4.0 for RecordKey trait support
0.3.0 - 2025-12-15
- RecordMetadata Updates: Client now handles new
record_idandrecord_keyfields inRecordMetadatafrom aimdb-core - Protocol remains backward-compatible with AimX v1 - new fields are additional data
0.2.0 - 2025-11-20
- Breaking: RecordMetadata Field Rename (via aimdb-core): Re-exported
RecordMetadatatype now hasconnector_countfield renamed tooutbound_connector_count. This change originates fromaimdb-coreand affects code accessing this field throughaimdb-client.
0.1.0 - 2025-11-06
- Initial release of AimDB client library
- Reusable connection and discovery logic for remote AimDB instances
- Unix domain socket communication
- AimX v1 protocol implementation
- Clean error handling with typed errors
- Instance discovery via socket scanning
- Record querying and value retrieval
- Support for subscription management