# KV
`deft/kv` is the Valkey/Redis client: pipeline-friendly wrappers over the
native `keyval/*` plugin with client-first arguments, batched
pipelining, MULTI/EXEC transactions, and pub/sub. It is a nested package
inside stdext and mounts as its own top-level package.
import "deft/kv" as kv
## Connecting
| Def | Signature | Description |
|---|---|---|
| `connect` | `{| host port opts |}` | Lazy-dial client; opts `:tls :timeout :username :password :db` |
| `cmd` | `{| client @args |}` | Raw command → Future (`%Err` on error reply) |
| `call` | `{| client @args |}` | `cmd` + await helper |
| `await-all` | `{| futures |}` | Join a batch of futures |
| `close` | `{| client |}` | Close the connection |
## Commands
| Family | Functions |
|---|---|
| Strings | `get get-num get-int set del exists expire ttl incr decr mget mset append` |
| Hashes | `hget hset hgetall (keyword map) hdel hlen hkeys hvals` |
| Lists | `lpush rpush lrange llen lpop rpop` |
| Sets | `sadd srem smembers sismember` |
| Server | `ping info dbsize keys type` |
| Batched | `pipeline` (one round trip), `multi` (atomic EXEC), `subscribe` / `unsubscribe` |
Replies are RESP3-typed (strings, numbers, booleans, nil, vectors, maps,
sets); error replies surface as `%Err{:message}`.
## Example
def rds [kv/connect "localhost" 6379] $rds |> kv/set "greeting" "hello" echo [kv/get $rds "greeting"] # "hello" echo [kv/pipeline $rds @{ # one round trip @{ "SET" "a" "1" } @{ "GET" "a" } }] [kv/subscribe $rds "updates" {| msg | log/info "got: " $msg }]
On a subscribed connection the client is in RESP3 subscriber mode:
message results arrive through the handler as pushes, and command acks
are ignored. Use `multi` on a dedicated handle — the connection is busy
until EXEC completes.
## Testing
`src/kv/test/test_kv.dft` runs against a real `valkey-server` on a
random high port and skips cleanly when one isn't available.
## See Also
- Packages — nested-package mounting rules
- SMTP / IMAP — the other network nested packages