Package Exports
- @vorkath/sdk
- @vorkath/sdk/errors
- @vorkath/sdk/filters
- @vorkath/sdk/package.json
- @vorkath/sdk/rank
- @vorkath/sdk/testing
- @vorkath/sdk/tokenizer
Readme
vorkath
Official TypeScript SDK for Vorkath - the distributed OLTP + vector + BM25 database. Works in Node.js (>=18), Bun, Deno, Cloudflare Workers, and modern browsers.
npm install vorkathQuick start
import { VorkathClient } from "@vorkath/sdk";
import * as f from "@vorkath/sdk/filters";
const client = VorkathClient.fromEnv();
await client.databases.create({ name: "docs", dimensions: 64, metric: "l2" });
await client.vectors("docs").insert({ key: "d1", vector: new Array(64).fill(0.1) });
const hits = await client.vectors("docs").search({
vector: new Array(64).fill(0.1),
k: 5,
filters: f.and(f.eq("source", "wiki"), f.in_("lang", ["en", "de"])).toJSON(),
});
for (const hit of hits.results) {
console.log(hit.key, hit.distance);
}Managed-search quickstart
The managed-search methods (embed, rerank, search.text) wrap
vorkath-backend's /v1/embed, /v1/rerank, and /v1/search
endpoints. The backend embeds the query, runs hybrid retrieval, and
optionally reranks - all in one round trip.
import { VorkathClient } from "@vorkath/sdk";
const client = VorkathClient.fromEnv();
// One-call canonical pipeline (embed -> retrieve -> rerank).
const res = await client.search.text("docs", "best hiking trails near seattle", {
k: 10,
mode: "hybrid",
rerank: true,
rerankTopN: 50,
filters: { category: "outdoors" },
});
console.log(res.results, res.totalMs, res.degraded);
// Manage the pipeline yourself:
const embed = await client.embed("hello world");
const reranked = await client.rerank(
"best hiking trails",
["doc 1", "doc 2", "doc 3"],
{ topN: 2, returnDocuments: true },
);See examples/managed-search.ts and
examples/explicit-pipeline.ts.
Backend contract: vorkath-backend/docs/embedding-and-rerank.md.
Configuration
| Env var | Default | Notes |
|---|---|---|
VORKATH_BASE_URL |
- | REST root, e.g. http://localhost:8080. |
VORKATH_CORE_URL |
(= VORKATH_BASE_URL) |
Override for hybrid deployments where vector ops route to a self-hosted vorkath core. |
VORKATH_API_KEY |
- | Bearer token, sent on every request. |
VORKATH_TIMEOUT |
30000 ms |
Per-request timeout. |
VorkathClient.fromUrl("vorkaths://<key>@host:port/db") parses
everything in one call.
Feature surface
| Area | Status |
|---|---|
| Database CRUD | yes |
| Vector insert / upsert / search / multi-search / kNN exact / delete | yes |
patchByFilter / deleteByFilter |
yes |
aggregate (count / sum / avg / min / max / forEachUnique) |
yes |
Hybrid + BM25 indexes (bm25(db)) |
yes |
Filter DSL (@vorkath/sdk/filters) |
yes |
Rank operators (@vorkath/sdk/rank) |
yes |
Tokenizer config (@vorkath/sdk/tokenizer) |
yes |
| Schema CRUD | yes |
Admin (warmCache, pin, namespaceMetadata, copyFrom) |
yes |
| Snapshot + restore | yes |
| SQL execute | yes |
CAS writes (ifMatch, ifNoneMatch, expectedVersion) |
yes |
| Idempotency keys (auto + override) | yes |
Retries with jitter + Retry-After |
yes |
AbortSignal end-to-end (composed with timeout) |
yes |
Telemetry hook (onRequest) |
yes |
| Bulk upsert with chunking + bounded inflight | yes |
Mock transport for tests (@vorkath/sdk/testing) |
yes |
| Cross-runtime: Node / Bun / Deno / Workers / browser | yes |
Managed embed (client.embed) |
yes |
Managed rerank (client.rerank) |
yes |
Managed search (client.search.text) |
yes |
Hybrid coreUrl deployments |
yes |
Tree-shakeable exports
import { VorkathClient } from "@vorkath/sdk";
import * as f from "@vorkath/sdk/filters";
import * as rank from "@vorkath/sdk/rank";
import * as tk from "@vorkath/sdk/tokenizer";
import { mockTransport, MockRouter } from "@vorkath/sdk/testing";Error hierarchy
VorkathError
+- APIConnectionError
| +- APITimeoutError
+- APIStatusError
+- BadRequestError (400)
+- AuthenticationError (401)
+- PermissionDeniedError (403)
+- NotFoundError (404)
+- ConflictError (409)
+- PreconditionFailedError (412) # CAS failures
+- RateLimitError (429)
+- NotImplementedAPIError (501)
+- DeadlineExceededError (504)
+- InternalServerError (5xx)Every error carries status, requestId, serverMessage, body,
and headers. status_code is preserved as a getter for v0
back-compat.
Testing your code against the SDK
import { VorkathClient } from "@vorkath/sdk";
import { mockTransport } from "@vorkath/sdk/testing";
const client = new VorkathClient({
baseUrl: "http://mock",
fetch: mockTransport({
"GET /healthz": { status: "ok" },
"POST /v1/databases": { success: true, database: { db_id: "x" } },
}),
});Node performance: optional undici.Agent
import { Agent } from "undici";
import { VorkathClient } from "@vorkath/sdk";
const dispatcher = new Agent({ keepAliveTimeout: 60_000, allowH2: true });
const client = new VorkathClient({ baseUrl: "...", dispatcher });undici is an optional peer dependency; the SDK works with native
fetch everywhere if you don't install it.
Versioning
Pre-1.0 (0.x.y): minor bumps may break public API. Patch bumps are
non-breaking. From 1.0 onwards, semver is enforced strictly with at
least one minor release of deprecation warnings before any removal.
See CHANGELOG.md.