npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hatidata/sdk

v0.1.1

Published

HatiData TypeScript SDK — RAM for Agents

Readme

@hatidata/sdk

The official TypeScript SDK for HatiData -- RAM for Agents. Connect to your HatiData instance from Node.js or browser environments with full type safety.

Installation

npm install @hatidata/sdk

For local mode (in-process DuckDB, no server required):

npm install @hatidata/sdk @duckdb/duckdb-wasm

Quick Start

Connect and Query

import { HatiDataClient } from "@hatidata/sdk";

const client = new HatiDataClient({
  host: "localhost",
  port: 8080,
  apiKey: "hd_your_api_key",
});

await client.connect();

// Execute SQL queries
const result = await client.query("SELECT * FROM sales LIMIT 10");
console.log(result.columns); // [{ name: "id", type: "INTEGER" }, ...]
console.log(result.rows);    // [{ id: 1, amount: 99.99 }, ...]
console.log(result.rowCount); // 10

// List tables
const tables = await client.listTables();
console.log(tables); // [{ name: "sales", schema: "main", columnCount: 5, rowCount: 1000 }]

await client.close();

Hybrid SQL

Combine structured queries with semantic search. Standard SQL runs locally — hybrid SQL is transparently transpiled via the HatiData cloud API (50 free queries/day).

import { HatiDataClient } from "@hatidata/sdk";

const client = new HatiDataClient({
  host: "localhost",
  port: 8080,
  apiKey: "hd_your_api_key",
  cloudKey: "hd_live_...", // free at hatidata.com/signup
});

await client.connect();

// Semantic search
const tickets = await client.query(`
  SELECT ticket_id, subject
  FROM support_tickets
  WHERE semantic_match(embedding, 'billing dispute')
  ORDER BY semantic_rank(embedding, 'billing dispute') DESC
  LIMIT 10
`);

// Hybrid join
const enriched = await client.query(`
  SELECT t.ticket_id, k.article_title, k.solution
  FROM support_tickets t
  JOIN_VECTOR knowledge_base k ON semantic_match(k.embedding, t.subject)
  WHERE t.status = 'open'
`);

You can also set the HATIDATA_CLOUD_KEY env var instead of passing cloudKey.

Local Mode (No Server)

Run queries entirely in-process using DuckDB-WASM -- perfect for development, testing, and edge workloads.

import { LocalEngine } from "@hatidata/sdk";

const engine = new LocalEngine(); // or new LocalEngine(":memory:")
await engine.init();

await engine.query("CREATE TABLE events (id INT, name VARCHAR)");
await engine.query("INSERT INTO events VALUES (1, 'click'), (2, 'view')");

const result = await engine.query("SELECT * FROM events");
console.log(result.rows); // [{ id: 1, name: "click" }, { id: 2, name: "view" }]

await engine.close();

Push & Pull Sync

Sync data between local and remote HatiData instances.

import { HatiDataClient } from "@hatidata/sdk";

const client = new HatiDataClient({
  host: "localhost",
  port: 8080,
  apiKey: "hd_local_key",
});

await client.connect();

// Push local tables to cloud
const pushResult = await client.push({
  target: "cloud",
  tables: ["events", "users"],
  apiKey: "hd_cloud_key",
});
console.log(`Pushed ${pushResult.tablesSync} tables`);

// Pull remote tables locally
const pullResult = await client.pull({
  tables: ["analytics_summary"],
});
console.log(`Pulled ${pullResult.tablesPulled} tables`);

await client.close();

Error Handling

import {
  HatiDataClient,
  ConnectionError,
  QueryError,
  AuthenticationError,
} from "@hatidata/sdk";

const client = new HatiDataClient({ apiKey: "hd_my_key" });

try {
  await client.connect();
  const result = await client.query("SELECT * FROM nonexistent_table");
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error("Bad credentials:", error.message);
  } else if (error instanceof QueryError) {
    console.error("Query failed:", error.message, "SQLSTATE:", error.sqlState);
  } else if (error instanceof ConnectionError) {
    console.error("Connection issue:", error.message);
  }
} finally {
  await client.close();
}

API Reference

HatiDataClient

| Method | Description | |--------|-------------| | constructor(config: HatiDataConfig) | Create a new client instance | | connect(): Promise<void> | Connect to the HatiData control plane | | query(sql, params?): Promise<QueryResult> | Execute a SQL query | | listTables(): Promise<TableInfo[]> | List all accessible tables | | push(options): Promise<{ tablesSync }> | Push local data to cloud/VPC | | pull(options): Promise<{ tablesPulled }> | Pull remote data locally | | close(): Promise<void> | Close the connection | | state: ConnectionState | Current connection state |

LocalEngine

| Method | Description | |--------|-------------| | constructor(dbPath?: string) | Create engine (default: .hati/local.duckdb) | | init(): Promise<void> | Initialize DuckDB-WASM | | query(sql): Promise<QueryResult> | Execute a SQL query locally | | listTables(): Promise<TableInfo[]> | List local tables | | close(): Promise<void> | Close and release resources |

Configuration

interface HatiDataConfig {
  host?: string;          // Default: "localhost"
  port?: number;          // Default: 8080
  database?: string;      // Default: "default"
  user?: string;
  password?: string;
  apiKey?: string;         // Takes precedence over user/password
  ssl?: boolean;           // Default: false
  timeout?: number;        // Default: 30000 (ms)
  cloudKey?: string;       // For hybrid SQL (from hatidata.com/signup)
  cloudEndpoint?: string;  // Default: "https://api.hatidata.com"
}

Error Types

| Error | Code | Description | |-------|------|-------------| | HatiDataError | varies | Base error class | | ConnectionError | CONNECTION_FAILED | Connection issues | | QueryError | QUERY_ERROR | Query execution failures (includes sqlState) | | AuthenticationError | AUTHENTICATION_FAILED | Invalid credentials | | SyncError | SYNC_FAILED | Push/pull sync failures | | HybridSQLError | HYBRID_SQL_ERROR | Hybrid SQL used without cloud key | | TranspileQuotaError | QUOTA_EXCEEDED | Daily hybrid SQL quota exceeded |

Tiers

| Tier | Connection | Use Case | |------|-----------|----------| | Local (free) | LocalEngine with DuckDB-WASM | Development, testing, edge | | Cloud ($29/mo) | HatiDataClient to managed instance | Teams, production | | Enterprise (VPC) | HatiDataClient to VPC-deployed instance | Regulated industries |

Documentation

Full documentation is available at docs.hatidata.com.

License

Apache-2.0. Copyright Marviy Pte Ltd.