corium-client 0.1.36

Fluent async Datomic-style client for corium peers and peer servers
Documentation

corium-client

A fluent, async, Datomic-style client for corium. One API surface, two backends: query the peer library directly from storage, or reach a peer server over gRPC.

What it does

corium-client is the ergonomic front door to the peer. Datalog queries, pull specifications, and transactions are built as typesafe, immutable, builder-patterned values that lower to the boundary EDN the engine parses — a malformed query is a type error, not a runtime parse failure.

  • [LocalPeer] wraps the corium-peer Connection, so queries execute in-process against immutable database values read straight from storage — no round trip to the transactor.
  • [RemotePeer] speaks the peer-server gRPC protocol, presenting the identical surface to processes that reach a hosted peer over the network.

Both implement the Peer trait and hand back Db values sharing query, pull, datoms, stats, and the time-view methods as_of / since / history.

Example

use corium_client::{LocalPeer, Peer, Args};
use corium_client::query::{Query, data, var, attr, gte};
use corium_client::pull::Pull;
use corium_client::tx::{TxBuilder, EntityMap, tempid, lookup};
use corium_peer::ConnectConfig;

# async fn demo() -> Result<(), corium_client::ClientError> {
let peer = LocalPeer::connect(ConnectConfig::new("http://127.0.0.1:4334", "people")).await?;

// Transact, with the typed builder.
peer.transact(
    TxBuilder::new()
        .entity(EntityMap::with_id(tempid("alice"))
            .set("person/name", "Alice")
            .set("person/age", 39_i64))
        .build(),
).await?;

let db = peer.db().await?;

// [:find [?name ...] :in $ ?min
//  :where [?e :person/name ?name] [?e :person/age ?age] [(>= ?age ?min)]]
let adults = Query::find_coll(var("name"))
    .in_scalar(var("min"))
    .where_(data(var("e"), attr("person/name"), var("name")))
    .and(data(var("e"), attr("person/age"), var("age")))
    .and(gte(var("age"), var("min")));
let names: Vec<String> = db.query(&adults, Args::new().scalar(21_i64)).await?.values_as()?;

// Pull an entity by lookup ref.
let alice = db.pull(
    &Pull::new().attr("person/name").attr("person/age"),
    lookup("person/name", "Alice"),
).await?;
# Ok(())
# }

The remote client is a drop-in: swap LocalPeer::connect for RemotePeer::connect(endpoint, "people", token, tls) and the same query/pull/transact code runs against a peer server.

Modules

Module What it provides
query Query, Var, Term, Clause, find/aggregate/pull elements, data/pred/not/or/rule combinators
pull Pull and Attr specs: attributes, *, :db/id, reverse refs, nesting, recursion, :as/:limit/:default
tx TxBuilder, EntityMap, tempid/lookup/eid — the Datomic-dialect transaction forms
result QueryResult, Row, and ResultShape with typed cell access
value IntoEdn / FromEdn for boundary conversion and typed extraction

Dependencies

  • Engine: corium-core, corium-db, corium-query.
  • Peer/network: corium-peer, corium-protocol, tonic, tokio, async-trait.

See docs/architecture.md and the peer library for the topology this sits on top of.