Remote Qdrant version: Node.js SDK.
@veristamp/nqql-edge is the edge-enabled Node.js package: N-API bindings for the QQL runtime plus in-process HNSW storage and optional local ONNX embeddings. No Qdrant server and no network at inference time.
Install
Section titled “Install”Node.js >= 18. Prebuilt binaries are published for Linux x86-64, macOS arm64 (Apple Silicon), and Windows x86-64 — not macOS Intel (ONNX Runtime publishes no artifact for it; see models).
npm install @veristamp/nqql-edgeQuick start
Section titled “Quick start”const { localExecutor, listEmbeddingModels, parse, injectFilter, version,} = require("@veristamp/nqql-edge");
const client = localExecutor("./qql-data", { model: "bge-small-en-v1.5", onDiskPayload: true,});
await client.execute("CREATE COLLECTION docs HYBRID");await client.execute('UPSERT INTO docs VALUES {id: 1, text: "hello from edge"}');
const report = await client.execute( "QUERY 'hello' FROM docs USING dense LIMIT 5");console.log(report.results[0].data);
await client.close(); // flush before deleting ./qql-dataconsole.log(version, listEmbeddingModels().length);Constructors
Section titled “Constructors”localExecutor(dataDir, options)
Section titled “localExecutor(dataDir, options)”Fully offline FastEmbed-backed executor. dataDir is the storage path. options is an object (a bare boolean is accepted for backward compatibility and maps to onDiskPayload):
| Option | Default | Purpose |
|---|---|---|
onDiskPayload | true | Store payloads on disk instead of memory |
model | BGESmallENV15 | Dense ONNX model name, HF code, or alias (bge-small-en-v1.5) |
sparseModel | null | Offline sparse model (e.g. "splade") |
multiModel | null | Offline multivector model (e.g. "bge-m3") |
imageModel | null | Offline CLIP vision model (e.g. "clip-vision") |
rerankerModel | null | Offline cross-encoder model (e.g. "bge-reranker-base") |
cacheDir | fastembed default | Directory for downloaded models |
showDownloadProgress | false | Show Hugging Face progress bars |
walSegmentMb | null (32 MiB) | WAL segment capacity in whole MiB; lower values shrink the pre-allocated on-disk WAL footprint |
Models are locked at construction. A USING MODEL '…' clause naming a different model fails loudly instead of switching silently — see models.
qdrant-edge pre-allocates each WAL segment (default 32 MiB), which dominates the on-disk footprint of small embedded shards. Set walSegmentMb (whole MiB >= 1) to shrink it; it seeds the collection's edge_config.json, a persisted capacity wins on later constructions, and invalid values fail closed with QQL-VALIDATION-CONFIG.
httpExecutor(dataDir, url, embedKey, embedModel, embedDim, onDiskPayload?)
Section titled “httpExecutor(dataDir, url, embedKey, embedModel, embedDim, onDiskPayload?)”Local storage and search, remote OpenAI-compatible embeddings (Ollama, OpenAI, Cohere, Together, Mistral):
const client = httpExecutor( "./qql-data", "http://localhost:11434/v1/embeddings", "", "nomic-embed-text", 768, true,);Client and Stmt
Section titled “Client and Stmt”localExecutor and httpExecutor return a Client:
| Method | Purpose |
|---|---|
client.execute(query, options?) | Execute a query string, Stmt, or array of either; options.onError is "stop" or "continue", options.params binds :name / ? placeholders |
client.executeHits(query, options?) | Typed ScoredPoint[] hits without the report |
client.explain(query) | Human-readable plan for a string |
client.explainStmt(stmt) | Human-readable plan for a pre-parsed Stmt |
client.compile(query, params?) | Non-executing {stmt_type, method, path, payload} route (optionally binding params) |
client.close() | Flush and release edge storage. Idempotent |
execute returns an ExecutionReport:
{ ok: true, results: [ { ok: true, operation: "QUERY", message: "Found 10 hits", data: { result: { points: [{ id: 1, score: 0.75, payload: { text: "hello" } }] } }, }, ], succeeded: 1, failed: 0,}Stmt objects come from parse() and support stmt.injectFilter(field, op, value), stmt.bind(params?) (returns a new bound Stmt), stmt.compileRoute(params?), stmt.toJson(), canonical stmt.toString(), and the truncated stmt.toReadableString() preview. injectFilter is the supported tenant-scoping mechanism. Edge has no custom SHARD routing, so a SHARD '…' clause fails at execution with QQL-EDGE-UNSUPPORTED-SHARD — see capabilities.
The edge ExecutionReport also exposes typed accessors: report.hits(stmt) / report.points(stmt) return ScoredPoint objects (id, score, payload, text, collection), report.facet(stmt) returns normalized [{ value, count }], and report.count(stmt) returns an integer. A negative statement index counts from the end, matching Python list semantics.
Module-level helpers
Section titled “Module-level helpers”| Export | Purpose |
|---|---|
parse(query) | Parse one statement or a script into Stmt[] |
parseJson(query) | Raw AST JSON string (avoids V8 object allocation) |
isValid(query) | Boolean parse + plan check |
injectFilter(query, field, op, value) | Return a filtered statement |
tokenize(query) | Token list {kind, text, pos, end, len} |
compileQuery(query, params?) | Non-executing route (optionally binding params) |
bind(query, params?, { truncateVectors? }) | Substitute :name (object) or ? (array) placeholders into a string or Stmt |
explain(query) / explainStmt(stmt) | Plan rendering |
listEmbeddingModels() | Catalog of loadable ONNX models |
version | Package version string |
execute(query, options?) | One-shot execution with a temporary client (loads the model every call — prefer a long-lived Client); forwards options.params |
executeStmt(stmt, options?) | One-shot execution of a pre-parsed Stmt; forwards options.params |
executeHits(query, options?) | One-shot execution returning ScoredPoint[] |
Supported injected operators: =, >, >=, <, <= (!= is rejected by design; wrap equality and negate instead).
Errors
Section titled “Errors”Unsupported features throw with a stable code embedded in the message, e.g. QQL-EDGE-UNSUPPORTED-GROUP-LOOKUP, always with a reason and a "use remote Qdrant" hint. Errors are never silent no-ops.
See the Rust page for the underlying engine and models for embedding configuration.