@slatedb/uniffi
v0.13.1
Published
Node.js bindings for SlateDB generated from UniFFI and packaged with native libraries.
Readme
SlateDB Node Binding
bindings/node contains the official Node.js package for SlateDB.
Install
Package:
@slatedb/uniffiRequirements:
- Node.js 20 or newer
Install from npm:
npm install @slatedb/uniffiAPI Model
ObjectStore.resolve(...)opens an object store from a URL such asmemory:///orfile:///...DbBuilderopens a writable database andDbReaderBuilderopens a read-only reader- keys and values are binary; pass
BufferorUint8Array - most database operations are async and should be awaited
- builders are single-use;
DbandDbReaderstay open untilshutdown()resolves - native-backed handles also expose
dispose()for deterministic cleanup aftershutdown()or when abandoning a builder
Quick Start
import assert from "node:assert/strict";
import { DbBuilder, ObjectStore } from "@slatedb/uniffi";
async function main() {
const store = ObjectStore.resolve("memory:///");
let db;
try {
const builder = new DbBuilder("demo-db", store);
try {
db = await builder.build();
} finally {
builder.dispose();
}
const key = Buffer.from("hello");
const value = Buffer.from("world");
await db.put(key, value);
const read = await db.get(key);
assert.deepEqual(read, value);
console.log(Buffer.from(read).toString("utf8"));
} finally {
if (db != null) {
await db.shutdown();
db.dispose();
}
store.dispose();
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});Replace memory:/// with any object store URL supported by Rust's object_store crate.
Metrics
The Node binding exposes both application-provided metrics recorders and the built-in
DefaultMetricsRecorder:
DbBuilder.with_metrics_recorder(...)DbReaderBuilder.with_metrics_recorder(...)DefaultMetricsRecorder.snapshot()DefaultMetricsRecorder.metrics_by_name(...)DefaultMetricsRecorder.metric_by_name_and_labels(...)
Example:
import { DbBuilder, DefaultMetricsRecorder, ObjectStore } from "@slatedb/uniffi";
const store = ObjectStore.resolve("memory:///");
const recorder = new DefaultMetricsRecorder();
const builder = new DbBuilder("metrics-demo", store);
try {
builder.with_metrics_recorder(recorder);
const db = await builder.build();
try {
await db.put(Buffer.from("hello"), Buffer.from("world"));
const metric = recorder.metric_by_name_and_labels("slatedb.db.write_ops", []);
if (metric?.value.tag === "Counter") {
console.log(metric.value[""]);
}
} finally {
await db.shutdown();
db.dispose();
}
} finally {
builder.dispose();
recorder.dispose();
store.dispose();
}Local Development
The package is generated from the UniFFI slatedb-uniffi cdylib using uniffi-bindgen-node-js.
You only need these tools when regenerating bindings, running tests from this repository, or packing the npm artifact locally:
- Node.js 20 or newer
- Rust toolchain for this repository
uniffi-bindgen-node-jsonPATH
Install the generator with:
cargo install uniffi-bindgen-node-js --version 0.0.13Install the package dependency used by the generated bindings with:
npm --prefix bindings/node installRegenerate Bindings
From the repository root:
npm --prefix bindings/node run buildThis command:
- builds the host
slatedb-uniffilibrary - runs
uniffi-bindgen-node-js - copies the generated package files into
bindings/node - stages the host native library under
bindings/node/prebuilds/<target>/
Generated API files are written into bindings/node and are not committed. package.json, build.mjs, and this README.md are maintained by hand.
Run Tests
From the repository root:
npm --prefix bindings/node testThe test script rebuilds the package and then runs node --test inside bindings/node.
Reproduce The PR CI Flow
From the repository root, this mirrors the Node validation done in .github/workflows/pr.yaml:
npm --prefix bindings/node ci
npm --prefix bindings/node run build
(cd bindings/node && node --test)
git diff --exit-code -- bindings/node
rm -rf /tmp/slatedb-node-pack
mkdir -p /tmp/slatedb-node-pack
(cd bindings/node && npm pack --pack-destination /tmp/slatedb-node-pack)
TARBALL="$(find /tmp/slatedb-node-pack -maxdepth 1 -name '*.tgz' | head -n 1)"
test -n "${TARBALL}"
tar -tf "${TARBALL}" | grep -Fx 'package/index.js'
tar -tf "${TARBALL}" | grep -Fx 'package/index.d.ts'
tar -tf "${TARBALL}" | grep -Fx 'package/slatedb.js'
tar -tf "${TARBALL}" | grep -Fx 'package/slatedb.d.ts'
tar -tf "${TARBALL}" | grep -Fx 'package/slatedb-ffi.js'
tar -tf "${TARBALL}" | grep -Fx 'package/slatedb-ffi.d.ts'
tar -tf "${TARBALL}" | grep -Fx 'package/runtime/ffi-types.js'
tar -tf "${TARBALL}" | grep -Fx 'package/prebuilds/linux-x64-gnu/libslatedb_uniffi.so'Packaging And Runtime Notes
The published @slatedb/uniffi tarball contains generated JavaScript and TypeScript bindings plus bundled native libraries. Consumers install one npm package; there is no separate Rust build step or native download in normal usage.
At runtime, the package loads the native library that matches the current host from prebuilds/<target>/. The published package currently includes:
linux-x64-gnulinux-arm64-gnudarwin-x64darwin-arm64win32-x64win32-arm64
Linux musl targets are not packaged today. Local builds stage only the host native library; release builds stage all supported targets into the published npm package.
When assembling a release package from a prebuilt native directory, run:
npm --prefix bindings/node run build -- --prebuilt-dir <dir>The generated API files stay the same; only the packaged native libraries change between local and release builds.
