npm.io
1.0.0 • Published 4d ago

@aellopus/client

Licence
Apache-2.0
Version
1.0.0
Deps
0
Size
74 kB
Vulns
0
Weekly
0

@aellopus/client

The official Node.js and Bun client for Aellopus, a key–value server speaking the Aellopus Wire Protocol (AWP/1) over TCP.

  • Zero runtime dependencies — only Node/Bun built-ins (node:net).
  • ESM-only, TypeScript-first — ships type declarations; runs on Node 18+ and Bun.
  • Binary-safe — values are bytes; keys and values may contain CR, LF, or NUL.
  • Promise-based with per-call timeouts and AbortSignal cancellation.
  • Pipelining-safe — one connection is shared across concurrent callers, replies correlated in FIFO order.

Validated against the AWP/1 conformance vectors and end-to-end against the reference Rust server.

Install

npm install @aellopus/client
# or: pnpm add @aellopus/client / yarn add @aellopus/client / bun add @aellopus/client

Quick start

import { connect, NotFoundError } from '@aellopus/client';

const client = await connect('127.0.0.1:6969');
try {
  await client.set('greeting', 'hello world');
  console.log(await client.getString('greeting')); // "hello world"

  await client.set('session:42', 'token', { expiresSeconds: 60 });
  console.log((await client.ttl('session:42')).seconds); // ~60

  try {
    await client.get('missing');
  } catch (err) {
    if (err instanceof NotFoundError) console.log('no such key');
  }
} finally {
  await client.close();
}

A Client is safe to share across concurrent work — hold one rather than pooling.

Running a server

The client talks to an Aellopus server. The quickest way to get one for local development:

docker run --rm -p 6969:6969 adibhauzan/aellopus:latest

The server listens on 127.0.0.1:6969 by default. See the server repository for other options.

API

connect(addr, options?): Promise<Client>

Opens a client to addr, a host:port TCP address with no scheme (IPv6 hosts are bracketed, e.g. [::1]:6969). options ({ timeoutMs?, signal? }) bound establishing the connection only.

Values
Method Returns Notes
get(key) Promise<Uint8Array> Throws NotFoundError on a miss. An empty value is a present zero-length array.
getString(key) Promise<string> UTF-8 convenience over get.
set(key, value, options?) Promise<void> value is Uint8Array | string; options.expiresSeconds attaches a TTL.
del(key) Promise<boolean> true if the key existed.
exists(key) Promise<boolean>
incr(key) / decr(key) Promise<number> Post-operation value.
TTL
Method Returns Notes
ttl(key) Promise<TTL> Throws NotFoundError if the key is absent.
expire(key, seconds) Promise<boolean> true if the key existed.

TTL exposes hasExpiry: boolean and seconds: number \| undefined (undefined when the key persists with no expiry).

Keys & scanning
Method Returns Notes
keys(pattern) Promise<string[]> Glob match; may block the server on a large keyspace.
scanPage(cursor, options?) Promise<ScanResult> One page. Pass '' to begin; options accepts match / count.
scan(options?) AsyncIterableIterator<string> Incremental walk; hides cursor bookkeeping.
for await (const key of client.scan({ match: 'user:*' })) {
  console.log(key);
}
Health & metadata
Method Returns
ping() Promise<void>
version() Promise<string> — server semver
stats() Promise<string> — server stats text
Maintenance & lifecycle
Method Returns
flushAll() Promise<void> — remove every key
close() Promise<void> — idempotent
Per-call options

Every method takes an optional final options argument:

const ac = new AbortController();
const value = await client.get('key', { timeoutMs: 250, signal: ac.signal });

A timed-out or aborted call rejects but leaves the connection usable — its eventual reply is discarded and later calls stay correctly correlated.

Errors

All thrown errors extend AellopusError, so you can catch the family and discriminate the case:

Error Meaning Recoverable?
NotFoundError Key absent (get, getString, ttl) Yes
ServerError Well-formed server error; has .code (e.g. NOTINT, TTLRANGE) Yes
TimeoutError Call exceeded timeoutMs Yes
ProtocolError Malformed or wrong-shaped reply No — connection is closed
ClosedError Client closed or connection ended No — reconnect

A cancelled call rejects with a Web-standard DOMException named AbortError.

Compatibility

  • Runtimes: Node.js 18+ and Bun. ESM only.
  • Protocol: AWP/1. Tested against Aellopus server 0.1.0.

License

Apache-2.0

Keywords