DBDelve
Dive deep into your data. A fast, native, multi-engine database client written in Rust. Free and open source, no telemetry.
翻訳待ち
Native rqlite client for JavaScript and TypeScript runtimes.
翻訳待ち
Loading the full README.
Read the full README ↗Native rqlite client for JavaScript and TypeScript runtimes. Zero runtime
dependencies — uses native fetch.
/db/requestnone, weak, strongnone consistency reads/nodes; rotates through all peers on
failurehostsfetch injection for client certificatesResult<T, E> discriminated unions, no thrown exceptionsConnectionError, QueryError, AuthenticationError with isError() guardsfetchbun add @qualithm/rqlite-client
# or
npm install @qualithm/rqlite-client
import { createRqliteClient } from "@qualithm/rqlite-client"
const client = createRqliteClient({ host: "localhost:4001" })
// Execute a write
await client.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
await client.execute("INSERT INTO users(name) VALUES(?)", ["Alice"])
// Query
const result = await client.query("SELECT * FROM users")
if (result.ok) {
console.log(result.value.columns) // ["id", "name"]
console.log(result.value.values) // [[1, "Alice"]]
}
| rqlite version | Client version | Status |
|---|---|---|
| 10.x | 0.x | Tested |
The integration test suite runs against the rqlite image pinned in docker-compose.test.yaml:
docker compose -f docker-compose.test.yaml up -d
Use serverVersion() at runtime to check the connected server:
const ver = await client.serverVersion()
if (ver.ok) console.log(ver.value) // "v10.5.0"
import { createRqliteClient } from "@qualithm/rqlite-client"
const client = createRqliteClient({
host: "localhost:4001",
tls: false, // use HTTPS
auth: {
// basic authentication
username: "admin",
password: "secret"
},
timeout: 10_000, // default request timeout (ms)
consistencyLevel: "weak", // default for queries
freshness: {
// for "none" consistency
freshness: "5s",
freshnessStrict: true
},
followRedirects: true, // follow leader redirects
maxRetries: 3, // retry attempts for transient failures
maxRedirects: 5, // redirect attempts during leader election
retryBaseDelay: 100, // backoff base delay (ms)
hosts: ["localhost:4003", "localhost:4005"], // additional seed nodes
clusterDiscovery: true, // discover peers via /nodes after first success
fetch: customFetch // custom fetch for mTLS (see examples/mtls.ts)
})
Supply a custom fetch function to enable mTLS or other advanced transport options. The custom
function receives the same arguments as the global fetch and must return a Promise<Response>.
// Node.js with undici
import { Agent, fetch as undiciFetch } from "undici"
const agent = new Agent({
connect: {
ca: readFileSync("certs/ca.pem"),
cert: readFileSync("certs/client-cert.pem"),
key: readFileSync("certs/client-key.pem")
}
})
const client = createRqliteClient({
host: "rqlite.example.com:4001",
tls: true,
fetch: (input, init) => undiciFetch(input, { ...init, dispatcher: agent })
})
See examples/mtls.ts for Bun and Deno examples.
When the rqlite password rotates, supply authProvider instead of auth so a new value is adopted
without reconstructing the client:
const client = createRqliteClient({
host: "localhost:4001",
authProvider: async () => ({
username: "admin",
password: await readFile("/var/run/secrets/rqlite/password", "utf8")
})
})
The resolved credential is cached and reused across requests. When the server answers 401, the
client discards it, calls the provider once more, and replays that request a single time — a second
rejection surfaces as an AuthenticationError rather than looping. Concurrent refreshes collapse
into one provider invocation, and 403 is never retried, since it means the credential is valid but
unauthorized. authProvider takes precedence over auth when both are set.
This is the beginning of the README. Read the rest at the original. Read the full README ↗