JSPM

@lithdew/chdb-bun

0.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 11
  • Score
    100M100P100Q46320F
  • License MIT

Native chDB bindings for Bun.

Package Exports

  • @lithdew/chdb-bun
  • @lithdew/chdb-bun/index.ts

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@lithdew/chdb-bun) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

chdb-bun

Native chDB bindings for Bun.

chDB is a fast, reliable, and scalable in-process OLAP SQL database built on top of Clickhouse.

Motivation

The official chDB bindings for Bun are out-of-date. It:

  1. requires libchdb to be installed on the system,
  2. requires gcc or clang to be available on the system for building C code,
  3. does not support the latest version of chdb, which includes several performance improvements and bug fixes and features such as:
  4. does not automatically release/destroy resources when garbage-collected.

Features

  • Built using bun:ffi.
  • Supports the latest version of libchdb.
  • Streaming query support.
  • Connection-based API support.
  • Connections are closed and cleaned up if garbage-collected via. FinalizationRegistry.
  • Streams are closed and cleaned up if garbage-collected via. FinalizationRegistry.

Installation

bun install @lithdew/chdb-bun && bun pm trust @lithdew/chdb-bun

Usage

import { query, Connection } from "@lithdew/chdb-bun";

Stateless Query

For single, self-contained queries:

try {
  const result = query(
    "SELECT number, toString(number) FROM system.numbers LIMIT 3",
    "Pretty"
  );
  console.log("Query Result:\n", result.data);
  console.log("Statistics:", result.stats);
  // Output:
  // Query Result:
  // ┌─number─┬─toString(number)─┐
  // │      0 │ 0                │
  // │      1 │ 1                │
  // │      2 │ 2                │
  // └────────┴──────────────────┘
  // Statistics: { elapsed: 0.001234, rowsRead: 3n, bytesRead: 24n }
} catch (e) {
  console.error("Stateless query execution failed:", e);
}

Stateful Connection

For scenarios involving persistent storage, multiple queries within a session, or UDFs.

In-Memory Database

try {
  const conn = new Connection(":memory:"); // Establishes an in-memory database session

  conn.query(
    "CREATE TABLE IF NOT EXISTS users (id UInt32, name String) ENGINE = Memory;"
  );
  conn.query("INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob');");

  const result = conn.query("SELECT * FROM users ORDER BY id", "JSONEachRow");
  console.log("Users:\n", result.data);
  // Output:
  // Users:
  // {"id":1,"name":"Alice"}
  // {"id":2,"name":"Bob"}
} catch (e) {
  console.error("In-memory connection operation failed:", e);
}

File-Based Database

Data is persisted to the specified file path.

try {
  const conn = new Connection("my_database.db"); // Relative path
  // Alternatively, an absolute path: new Connection("/path/to/my_database.db")
  // Or using the file: prefix: new Connection("file:my_database.db")

  conn.query(
    "CREATE TABLE IF NOT EXISTS events (timestamp DateTime, event_name String) ENGINE = MergeTree ORDER BY timestamp;"
  );
  conn.query(
    "INSERT INTO events VALUES (now(), 'AppStart'), (now() + 1, 'UserLogin');"
  );

  const events = conn.query("SELECT * FROM events", "CSVWithNames");
  console.log("Events:\n", events.data);
} catch (e) {
  console.error("File-based connection operation failed:", e);
}

Streaming Query

Process large result sets efficiently by iterating over data chunks.

try {
  const conn = new Connection(":memory:");

  conn.query(
    "CREATE TABLE IF NOT EXISTS large_data (value Int64) ENGINE = Memory;"
  );
  conn.query(
    "INSERT INTO large_data SELECT number FROM system.numbers LIMIT 200000;"
  ); // Populates with 200,000 rows

  const stream = conn.stream("SELECT * FROM large_data", "CSV");

  let totalRowsStreamed = 0n;
  let chunkCount = 0;

  for (const chunk of stream) {
    chunkCount++;
    // chunk.data contains a segment of the result set
    console.log(
      `Chunk ${chunkCount} statistics: ${chunk.stats.rowsRead} rows, ${chunk.stats.bytesRead} bytes, duration ${chunk.stats.elapsed}s`
    );
    totalRowsStreamed += chunk.stats.rowsRead;
  }

  console.log(
    `\nTotal rows processed via stream: ${totalRowsStreamed} across ${chunkCount} chunks.`
  );
} catch (e) {
  console.error("Streaming query execution failed:", e);
}

Error Handling

Errors originating from chDB operations will throw a CHDBError.