simple magicDATA

SMKV / Build applications

Use the Node.js / TypeScript SDK

Applies to: current development source bundles. Obtain a matched client/server release through early-access support; registry publication is not available yet. Paths below are relative to the supplied source checkout.

Promise-based TCP client for Node.js 22+, with TypeScript declarations and no runtime dependencies. This first release has not been published to npm.

Install and use

From an application next to this checkout: npm install ../smkv/node-smkv. The package is ESM; use import or dynamic import() from CommonJS.

import {Client} from '@simplemagic/smkv';

const client = new Client('127.0.0.1:7379', {poolSize: 4, timeoutMs: 5000});
try {
  await client.put(Buffer.from('greeting'), Buffer.from('hello'),
                   {sync: true, ttlMs: 60000});
  console.log(await client.get(Buffer.from('greeting')));
  const users = client.table('users');
  await users.put(Buffer.from('42'), {name: 'Ada', visits: 1n});
  await users.update(Buffer.from('42'), {visits: 2n});
  console.log(await users.get(Buffer.from('42'), ['name']));
} finally {
  client.close();
}

Run node node-smkv/examples/basic.mjs 127.0.0.1:7379 against a disposable node. Keys/values are Uint8Array or Buffer; reads return Buffer. Column values are bytes, string, boolean, bigint for int64, or number for float64. Decoded columns have a null prototype; use Object.hasOwn to test membership.

Cluster and security

import {ClusterClient} from '@simplemagic/smkv';
const cluster = await ClusterClient.connect(['127.0.0.1:7381']);
try {
  console.log(await cluster.get(Buffer.from('greeting')));
  // Explicitly permits stale reads:
  console.log(await cluster.getReplica(Buffer.from('greeting')));
} finally { cluster.close(); }

Seeds are management endpoints. refresh() updates discovery and topology returns a copy. Epochs above JavaScript's safe integer range are rejected.

Data security and managementSecurity are configured independently. Plaintext and no authentication are defaults. For TLS, pass security: {tls: {ca: pem}, credential: {name, token}}; load PEM and credentials from files/your secret provider. TLS always verifies the certificate and endpoint hostname/IP. Optional servername overrides the verification name. Verification cannot be disabled; no downgrade.

Deadlines and error handling

Defaults: four connections per node, five-second operation and idle timeouts, 1 KiB keys and 1 MiB values. Set poolSize, timeoutMs, idleTimeoutMs, maxKeyBytes, or maxValueBytes to match your server. Per-operation timeoutMs can shorten the total deadline; signal accepts AbortSignal. Pool wait is included. close() aborts active requests and closes all connections.

Writes accept sync, replicaAck, and durableReplicaAck. Defaults do not request per-write disk synchronization. ttlMs accepts a safe integer or bigint; omitted means no expiry for put and preserves expiry for update, zero expires immediately. Delete does not accept TTL. Table update(key, setColumns, remove) is atomic; get(key, columns) supports projection.

SmkvError.code identifies errors (not_found differs from an empty value). status contains the server status when present. outcomeUnknown means a mutation may have completed, including after cancellation. Do not blindly replay it. Cluster retries are limited to explicit wrong_owner responses, within the original deadline. Other failures return to the caller.

Scans, batch operations, and browser connections are not included in this release. See shared contract and tests.