lodestone-client 0.0.29

Current-only asynchronous Rust client for the Lodestone API
Documentation

lodestone-client

lodestone-client is the current-only asynchronous Rust client for the Lodestone API request/reply protocol and canonical subscription gRPC stream. It depends on the generated leaf lodestone-wire DTO crate and does not expose internal Core RPC, storage, authority, Elasticsearch, RESP, or server types.

Cargo consumers declare only an exact lodestone-client version from crates.io. The same-version lodestone-wire package is an exact transitive dependency; a consumer does not need a direct wire dependency, Git pin, path patch, or custom registry.

Construct one CellTransport per exact cell and operation class, then attach lightweight CollectionSession values containing a validated connection profile and caller-owned CredentialProvider. Sessions for different Collections share the bounded transport only when endpoints, TLS server name and trust, cluster/schema identity, operation class, and pool limits match exactly. Credential material remains session-local and request-scoped. A bounded transport LRU may retain only verified non-secret metadata, which each session rechecks against its complete profile before use. Create CallOptions, then pass those options to CollectionSession::connect. Client remains the ordinary Collection-session spelling used by generated methods. CallOptions::new converts its duration to one absolute deadline immediately; clones retain that exact deadline. Connection verifies TLS and ALPN, authenticates, discovers the exact schema and stream, and validates the cluster, Collection, expected principal, configuration generation, and binding revision before returning. Reuse the same options for a caller workflow when discovery, binding, preparation, submission, and resolution share one budget. Endpoints rotate in profile order; a read may move to the next endpoint only within its bounded retry policy. Mutations retry only before the submission boundary.

State helpers accept a semantic StateIndex, enforce the 254-byte key bound, and provide get, colocated mget, absolute-expiry set, and delete. Callers retain a durable StateActionId for writes. The helpers perform prepare/submit/resolve and return StateWriteOutcome, preserving retired, reset, and indeterminate outcomes rather than claiming success. Secret material is never Clone, Debug, serialized, or included in errors, and is overwritten on drop.

append_exact, mutate_document_exact, and reconcile_index_exact share one recovery contract. ExactWorkflowRecoveryV2 retains the first absolute effect deadline, caller action/request digest, exact cluster/Collection/index scope, prepared locator, monotonic revision, and closed phase. The executor persists submission_started before a submit RPC, so a restart resolves the original locator instead of treating a missing response as proof of no effect.

Replicated applications inject an Arc<dyn ExactWorkflowRecoveryStore> with with_recovery_store. Its load and single-key compare_exchange must be linearizable and durable; a conflict returns the observed V2 value. The caller-selected workflow key is stable and collision-resistant, stays outside the recovery value, and must not contain credentials or raw requests. Deleting or reassigning a key while an effect is unresolved destroys the caller's recovery guarantee. FilesystemExactWorkflowRecoveryStore provides the same contract over the sealed local journal. Format-1 recovery values and local journal directories require a fresh start. Callers without a store must persist the returned V2 value and pass it back with with_recovery.

Once submission may have happened, the helpers resolve the original locator and never prepare a replacement action. reconcile_index_exact creates only an absent exact definition and reports a conflict instead of updating an existing index.

This package is an unreleased development artifact. It has no protocol downgrade or compatibility mode.

Document-bulk and retained-append callers derive the request batch_id with the re-exported bulk_batch_id(&Identity, &Resource, &[Digest]). It rejects malformed, zero, duplicate, or over-bound action identities and preserves caller order. There is no append-specific alias or predecessor hash.

Raw-source document-bulk callers derive each item's exact semantic_digest locally with the re-exported document_mutation_semantic_digest(document_id, operation, source_bytes, routing, condition). The helper accepts byte-exact JSON put/update sources and source-free deletes, validates the same document, routing, and condition bounds as Core, and returns the Digest placed in BulkDocumentItem. Native-record projection and pipeline selection still require authoritative server preparation because their effective bytes depend on current Core state. The item action identity remains caller-owned and distinct from this semantic digest; response-loss recovery remains the existing bulk locator workflow. execute_document_bulk returns BulkRecoveryError::Client only while the batch is authoritatively safe to replay: preparation failure or submit failure reported as NotSubmitted. Once submission may have occurred, every resolver failure returns BulkRecoveryError::Indeterminate with a BulkRecovery that retains the original request identities and last authoritative outcome; a read-only resolver call's own disposition never makes the original mutation safe to replay. execute_document_bulk returns success only when every item is Resolved. A terminal all-NotSubmitted or mixed Resolved/NotSubmitted result returns ExactReplayRequired; pass that exact recovery value to replay_document_bulk, which reuses the original batch, item actions, semantics, and locators. Use resume_document_bulk for an indeterminate recovery value before deciding whether exact replay is admitted.

The direct hyper-util and tower dependencies reuse versions already in Core's dependency closure. Only TokioIo and service_fn are enabled so the subscription channel can use the crate's TLS-1.3-only rustls connector instead of a broader transport default. No native/system dependency is added.