A thin EDN-over-HTTP client for the vaelii daemon (vaelii.serve). Runs no engine:
it POSTs {:op :args} and reads the result back, over JDK java.net.http (no
dependency — JDK 21 ships it).
Every call threads an explicit connection handle as its first argument —
(query conn '(dog ?x) 'Ctx) — the network mirror of vaelii.core's explicit-kb
API. A conn from client holds a reusable HttpClient; no socket opens until a
call. A daemon reply of {:ok false} becomes an ex-info carrying the daemon's
:error and :type, so a remote naming or disjointness refusal surfaces like a
local one.
A daemon with VAELII_API_TOKEN set answers 401 (:unauthorized) to a call that
presents no bearer token; the conn reads the same variable, so a client in the
daemon's environment carries it with nothing said.
Public because a client is a thing applications write against; the implementation is
vaelii.impl.client, which is free to change. Result shapes are vaelii.core's: a
sentex comes back as a plain map (the daemon projects the record), a solution as a
binding map.
A thin EDN-over-HTTP client for the vaelii daemon (`vaelii.serve`). Runs no engine:
it POSTs `{:op :args}` and reads the result back, over JDK `java.net.http` (no
dependency — JDK 21 ships it).
Every call threads an **explicit connection handle** as its first argument —
`(query conn '(dog ?x) 'Ctx)` — the network mirror of `vaelii.core`'s explicit-`kb`
API. A `conn` from `client` holds a reusable `HttpClient`; no socket opens until a
call. A daemon reply of `{:ok false}` becomes an `ex-info` carrying the daemon's
`:error` and `:type`, so a remote naming or disjointness refusal surfaces like a
local one.
A daemon with `VAELII_API_TOKEN` set answers 401 (`:unauthorized`) to a call that
presents no bearer token; the `conn` reads the same variable, so a client in the
daemon's environment carries it with nothing said.
Public because a client is a thing applications write against; the implementation is
`vaelii.impl.client`, which is free to change. Result shapes are `vaelii.core`'s: a
sentex comes back as a plain map (the daemon projects the record), a solution as a
binding map.(ask conn goal)(ask conn goal context)The first solution for goal, or nil.
The first solution for `goal`, or nil.
(ask? conn goal)(ask? conn goal context)Whether goal has any solution.
Whether `goal` has any solution.
(assert conn sentence context)(assert conn sentence context opts)Assert sentence in context (optional opts) — returns the handle(s). Bare —
no ! — for vaelii.core/assert's reason: additive, and retract! takes it back.
Assert `sentence` in `context` (optional `opts`) — returns the handle(s). Bare — no `!` — for `vaelii.core/assert`'s reason: additive, and `retract!` takes it back.
(assert-many conn sentences context)(assert-many conn sentences context opts)Assert every sentence in sentences into context, as one call.
Assert every sentence in `sentences` into `context`, as one call.
(assert-rule conn antecedents consequent context)(assert-rule conn antecedents consequent context opts)Assert a rule from antecedents to consequent in context — returns the
handle(s); a conjunctive consequent yields one handle per conjunct.
Assert a rule from `antecedents` to `consequent` in `context` — returns the handle(s); a conjunctive consequent yields one handle per conjunct.
(call conn op args)(call conn op args opts)POST {:op op :args args} and return the :result, or throw ex-info on an
{:ok false} reply. The low-level entry the wrappers below use; reach for it for
an op with no wrapper yet — vaelii.serve/op-names is the reachable set. opts is
{:timeout-ms n} for this call alone, which the long poll below is what needs.
POST `{:op op :args args}` and return the `:result`, or throw `ex-info` on an
`{:ok false}` reply. The low-level entry the wrappers below use; reach for it for
an op with no wrapper yet — `vaelii.serve/op-names` is the reachable set. `opts` is
`{:timeout-ms n}` for this call alone, which the long `poll` below is what needs.(client host port)(client host port opts)A connection handle to a daemon at host:port (opts: :timeout-ms, default
30000; :token, the bearer token every call presents — VAELII_API_TOKEN when the
key is absent, and an explicit nil to send no Authorization header at all). Holds
a reusable HttpClient; no network happens until a call.
A connection handle to a daemon at `host`:`port` (opts: `:timeout-ms`, default 30000; `:token`, the bearer token every call presents — `VAELII_API_TOKEN` when the key is absent, and an explicit nil to send no `Authorization` header at all). Holds a reusable `HttpClient`; no network happens until a call.
(conflicts conn)The KB's current conflicts.
The KB's current conflicts.
(contexts conn)Every context the KB holds.
Every context the KB holds.
(contradictions conn)The coexisting P/¬P dilemmas.
The coexisting P/¬P dilemmas.
(find-sentexes conn term)Every sentex containing term.
Every sentex containing `term`.
(genls conn t)The types t is a subtype of, transitively.
The types `t` is a subtype of, transitively.
(handle-of conn sentence context)The handle for sentence in context, or nil.
The handle for `sentence` in `context`, or nil.
(health conn)The daemon's liveness reply, {:ok true} — a GET, so it needs no op.
The daemon's liveness reply, `{:ok true}` — a GET, so it needs no op.
(in? conn handle)Whether the sentex handle names is currently believed.
Whether the sentex `handle` names is currently believed.
(isa? conn x t)(isa? conn x t context)Whether individual x is of type t, through the genl closure.
Whether individual `x` is of type `t`, through the `genl` closure.
(poll conn token cursor)(poll conn token cursor opts)Read a subscription forward from cursor — {:events [...] :cursor n :lagged k}.
Each event is {:believed-added [...] :believed-removed [...]} in preview's entry
shapes, one per settle, oldest first.
opts is {:wait-ms n}: the daemon holds the request open that long waiting for the
first event, and this client extends its read timeout to cover it.
:lagged is on every reply and is the one field a caller must read. Non-zero, the
daemon's ring dropped that many events before this poll reached them, and the caller is
behind rather than current — re-read what it cares about rather than trusting the
events it did get to be the whole story.
Read a subscription forward from `cursor` — `{:events [...] :cursor n :lagged k}`.
Each event is `{:believed-added [...] :believed-removed [...]}` in `preview`'s entry
shapes, one per settle, oldest first.
`opts` is `{:wait-ms n}`: the daemon holds the request open that long waiting for the
first event, and this client extends its read timeout to cover it.
**`:lagged` is on every reply and is the one field a caller must read.** Non-zero, the
daemon's ring dropped that many events before this poll reached them, and the caller is
behind rather than current — re-read what it cares about rather than trusting the
events it did get to be the whole story.(provable? conn goal)(provable? conn goal context)Whether goal is provable.
Whether `goal` is provable.
(prove conn goal)(prove conn goal context)A proof tree for goal, as data.
A proof tree for `goal`, as data.
(query conn goal)(query conn goal context)(query conn goal context opts)Solutions for goal as binding maps — ({?x Muffet}).
Solutions for `goal` as binding maps — `({?x Muffet})`.
(retract! conn handle)Retract the sentex handle names, tearing down what it solely supported.
Retract the sentex `handle` names, tearing down what it solely supported.
(sentex conn handle)The sentex handle names, as a map.
The sentex `handle` names, as a map.
(sentexes-matching conn sentence)(sentexes-matching conn sentence context)The believed sentexes matching sentence (a pattern may carry ?vars), as maps.
The believed sentexes matching `sentence` (a pattern may carry `?vars`), as maps.
(specs conn t)The types that are subtypes of t, transitively.
The types that are subtypes of `t`, transitively.
(types-of conn x)(types-of conn x context)The types individual x belongs to.
The types individual `x` belongs to.
(unwatch conn token)Drop subscription token; true if there was one. Idempotent.
Drop subscription `token`; true if there was one. Idempotent.
(violations conn)The recorded definitional violations.
The recorded definitional violations.
(watch conn)(watch conn goal context)Open a change-feed subscription and return {:token t :cursor 0 :max-events n}.
In process vaelii.core/watch takes a callback; a callback does not cross an EDN
wire, so what a remote caller holds is a subscription the daemon keeps and this client
reads forward with a cursor. With no goal it is every belief change; with one it is
the same standing query, and a goal that cannot be answered from a moved region is
refused with the same :not-watchable it is refused with in process.
(let [{:keys [token cursor]} (watch conn)]
(loop [c cursor]
(let [{:keys [events cursor lagged]} (poll conn token c {:wait-ms 20000})]
(when (pos? lagged) (resync!))
(run! render! events)
(recur cursor))))
Open a change-feed subscription and return `{:token t :cursor 0 :max-events n}`.
In process `vaelii.core/watch` takes a callback; a callback does not cross an EDN
wire, so what a remote caller holds is a subscription the daemon keeps and this client
reads forward with a cursor. With no goal it is every belief change; with one it is
the same standing query, and a goal that cannot be answered from a moved region is
refused with the same `:not-watchable` it is refused with in process.
(let [{:keys [token cursor]} (watch conn)]
(loop [c cursor]
(let [{:keys [events cursor lagged]} (poll conn token c {:wait-ms 20000})]
(when (pos? lagged) (resync!))
(run! render! events)
(recur cursor))))(watchers conn)What the daemon is holding open: one entry per subscription with its goal, how many
events it has been :delivered, and how many are still :pending on its ring. Neither
is the reader's own position — that lives here, not there.
What the daemon is holding open: one entry per subscription with its goal, how many events it has been `:delivered`, and how many are still `:pending` on its ring. Neither is the reader's own position — that lives here, not there.
(why conn handle)Why the sentex handle names is believed — its supporting justifications, as data.
Why the sentex `handle` names is believed — its supporting justifications, as data.
(why-not conn handle)(why-not conn sentence context)Why a sentence is not believed, by handle or by sentence and context.
Why a sentence is *not* believed, by handle or by sentence and context.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |