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

@axiomdb/runtime

v0.1.1

Published

SQL compiler runtime for AxiomDB with dialect support

Readme

@axiomdb/runtime

SQL compiler runtime for AxiomDB. Compiles query builder AST into parameterized SQL, provides database clients for PostgreSQL, MySQL, and MSSQL, and handles dialect-specific placeholder styles and type coercion.

Installation

npm install @axiomdb/runtime

Install the driver for your database (these are optional peer dependencies — only the one you use is required):

# PostgreSQL
npm install pg

# MySQL
npm install mysql2

# MSSQL
npm install mssql

API Reference

Table of Contents

  1. Database Clients
  2. Dialect Tags
  3. Query Execution
  4. Compiler API
  5. Standalone table() and configure()
  6. Dialect Modules
  7. Batch Execution
  8. Row Coercion
  9. Re-exported Core API

1. Database Clients

Each database has a dedicated client class that wraps its native driver pool.

1.1 PostgreSQL — ClientPG

import { Pool } from "pg";
import { ClientPG } from "@axiomdb/runtime";

const client = new ClientPG({
  pool: new Pool({ connectionString: "postgresql://user:pass@localhost:5432/mydb" }),
});

Constructor options:

| Option | Type | Description | |--------|------|-------------| | pool | pg.Pool \| pg.Client | A pg pool or client instance | | logLevel | 'none' \| 'error' \| 'debug' | Query logging level (default: 'error') |

1.2 MySQL — ClientMySQL

import mysql from "mysql2/promise";
import { ClientMySQL } from "@axiomdb/runtime";

const client = new ClientMySQL({
  pool: mysql.createPool({ host: "localhost", database: "mydb" }),
});

Constructor options:

| Option | Type | Description | |--------|------|-------------| | pool | mysql2.Pool | A mysql2/promise pool instance | | logLevel | 'none' \| 'error' \| 'debug' | Query logging level (default: 'error') |

1.3 MSSQL — ClientMSSQL

import sql from "mssql";
import { ClientMSSQL } from "@axiomdb/runtime";

const pool = await sql.connect({ server: "localhost", database: "mydb" });
const client = new ClientMSSQL({ pool });

Constructor options:

| Option | Type | Description | |--------|------|-------------| | pool | mssql.ConnectionPool | A mssql connection pool instance | | logLevel | 'none' \| 'error' \| 'debug' | Query logging level (default: 'error') |


2. Dialect Tags

The primary way to execute SQL is through dialect-specific tagged template methods on a client instance. These require the @axiomdb/babel-plugin to transform the templates at build time.

2.1 PostgreSQL

const users = await client.psql`
  SELECT id, name FROM users WHERE active = ${true}
`;
// Compiles to: SELECT id, name FROM users WHERE active = $1
// params: [true]

2.2 MySQL

const users = await client.mysql`
  SELECT id, name FROM users WHERE active = ${true}
`;
// Compiles to: SELECT id, name FROM users WHERE active = ?
// params: [true]

2.3 MSSQL

const users = await client.mssql`
  SELECT id, name FROM users WHERE active = ${true}
`;
// Compiles to: SELECT id, name FROM users WHERE active = @p1
// params: [true]

Values are never interpolated into the SQL string — they always become parameterized placeholders.


3. Query Execution

3.1 client.__execute(queryOrText, params?)

Execute a query builder chain or a raw SQL string. This is what the Babel plugin compiles dialect tags into.

// With a query builder
const query = table("users").select("*").where({ column: "active", op: EQ, value: true });
const rows = await client.__execute(query);

// With raw SQL (placeholders use $_ which are resolved to dialect-specific style)
const rows = await client.__execute("SELECT * FROM users WHERE id = $_", [42]);

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | textOrBuilder | QueryBuilder \| string | A query builder instance or SQL string | | rawParams | unknown[] | Parameters (only for string queries) |

Returns: Promise<Record<string, unknown>[]> — array of row objects.

3.2 client.__executeBatch(text, params)

Execute a multi-statement SQL string. Statements are separated by semicolons.

const results = await client.__executeBatch(
  "INSERT INTO users (name) VALUES ($_); SELECT * FROM users WHERE name = $_",
  ["Alice", "Alice"]
);
// results[0] = rows from INSERT (if RETURNING)
// results[1] = rows from SELECT

Returns: Promise<Record<string, unknown>[][]> — array of result sets, one per statement.


4. Compiler API

4.1 createCompiler(dialect)

Create a standalone compiler for a specific dialect. Useful when you need to compile queries without a client.

import { createCompiler, postgres } from "@axiomdb/runtime";

const compiler = createCompiler(postgres);
const { text, params } = compiler.compile(query.toAST());
// text:   "SELECT id, name FROM users WHERE active = $1"
// params: [true]

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | dialect | DialectCompiler | A dialect module (postgres, mysql, or mssql) |

Returns: Compiler — object with a compile(node) method that returns { text: string, params: unknown[] }.

4.2 CompileContext

Low-level compilation context used by dialect implementations. Manages parameter tracking and identifier quoting.

import { CompileContext, postgres } from "@axiomdb/runtime";

const ctx = new CompileContext(postgres);
const sql = ctx.compileNode(query.toAST());
const params = ctx.getParams();

| Method | Description | |--------|-------------| | addParam(value) | Add a parameter and return its placeholder string | | getParams() | Return all collected parameters | | getDialect() | Return the dialect compiler | | quoteId(name) | Quote a single identifier | | quoteColumnRef(ref) | Quote a dotted column reference (e.g. "users"."id") | | compileNode(node) | Compile a query AST node to SQL |


5. Standalone table() and configure()

For use without a client class — configure a default dialect and optionally a database adapter, then use table() directly.

5.1 configure(dialect)

Set the default dialect for standalone table() calls. Must be called before using table().

import { configure, postgres } from "@axiomdb/runtime";

configure(postgres);

5.2 connect(db)

Set a default database adapter for .execute() calls.

import { configure, connect, postgres } from "@axiomdb/runtime";
import { Pool } from "pg";

configure(postgres);

const pool = new Pool({ connectionString: "..." });
connect({
  query: async (text, params) => {
    const result = await pool.query(text, params);
    return { rows: result.rows, fields: result.fields };
  },
});

5.3 table(name, options?)

Create a query builder bound to the configured dialect. Returns an ExecutableQueryBuilder with .build() and .execute() methods.

import { configure, postgres, table, EQ } from "@axiomdb/runtime";

configure(postgres);

const query = table("users")
  .select({ id: true, name: true })
  .where({ column: "active", op: EQ, value: true });

// Compile to SQL
const { text, params } = query.build();
// text:   "SELECT id, name FROM users WHERE active = $1"
// params: [true]

// Or execute directly (requires connect() or passing an adapter)
const rows = await query.execute();

5.4 withCTEs(ctes, body)

Create a CTE query bound to the configured dialect.

import { configure, postgres, table, withCTEs, GT } from "@axiomdb/runtime";

configure(postgres);

const recent = table("users")
  .select({ id: true, name: true })
  .where({ column: "created_at", op: GT, value: cutoff })
  .asCTE("recent_users");

const query = withCTEs([recent], recent.select("*").limit(10));
const { text, params } = query.build();

6. Dialect Modules

Three built-in dialect modules handle SQL generation differences:

import { postgres, mysql, mssql } from "@axiomdb/runtime";

| Dialect | Placeholder style | Identifier quoting | Notes | |---------|------------------|-------------------|-------| | postgres | $1, $2, ... | "identifier" | Supports row coercion for int8, numeric, bool | | mysql | ? | `identifier` | Supports row coercion for NEWDECIMAL, LONGLONG | | mssql | @p1, @p2, ... | [identifier] | Uses request.input() for parameter binding |

Each dialect implements the full DialectCompiler interface with compile methods for all query types (SELECT, INSERT, UPDATE, DELETE, MERGE), clause types (WHERE, JOIN, GROUP BY, ORDER BY, etc.), and SQL primitives (placeholders, identifier quoting, row coercion).


7. Batch Execution

Multi-statement queries are supported through __executeBatch(). Behavior varies by driver:

PostgreSQL

Statements are split and executed sequentially within a single client connection (acquired from the pool). Each statement's $N placeholders are re-indexed to $1..$K with only the referenced params.

MySQL

Requires multiStatements: true on the pool. The mysql2 driver returns multiple result sets natively.

MSSQL

The mssql driver handles multi-statement batches natively via request.query(), returning recordsets as an array.


8. Row Coercion

Drivers return some SQL types as strings (e.g. BIGINT, NUMERIC). Each dialect's coerceRow() function automatically converts these to JavaScript numbers or booleans based on field metadata:

| SQL type | JS type | Dialects | |----------|---------|----------| | int8 / BIGINT / LONGLONG | number | PostgreSQL, MySQL, MSSQL | | numeric / NEWDECIMAL | number | PostgreSQL, MySQL | | bool / BIT | boolean | PostgreSQL, MSSQL |

Coercion happens automatically when using a client class — no configuration needed.


9. Re-exported Core API

The runtime package re-exports everything from @axiomdb/core for convenience, so you only need a single import:

import {
  // Operators
  EQ, NEQ, GT, GTE, LT, LTE, IN, NOT_IN, LIKE, ILIKE,
  BETWEEN, IS_NULL, IS_NOT_NULL, IS_TRUE, IS_FALSE,
  CONTAINS, OVERLAPS, ANY, SIMILAR_TO, POSIX_MATCH,

  // Combinators
  and, or, not,

  // Aggregate functions
  COUNT, SUM, AVG, MIN, MAX, ARRAY_AGG, JSON_AGG, STRING_AGG,

  // Window functions
  ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, FIRST_VALUE, LAST_VALUE,

  // Query builder
  QueryBuilder, RawExpression, raw,

  // Client classes
  ClientPG, ClientMySQL, ClientMSSQL,

  // Compiler
  createCompiler, CompileContext,

  // Dialects
  postgres, mysql, mssql,

  // Standalone API
  configure, connect, table, withCTEs,
  extendBuilder,
} from "@axiomdb/runtime";

See the @axiomdb/core README for the full query builder API reference (SELECT, WHERE, JOIN, GROUP BY, INSERT, UPDATE, DELETE, CTEs, subqueries, window functions, set operations, and more).


Types

DatabaseAdapter

Interface for providing a custom database adapter:

interface DatabaseAdapter {
  query(text: string, params: unknown[]): Promise<{
    rows: Record<string, unknown>[];
    fields?: unknown[];
  }>;
  queryBatch?(text: string, params: unknown[]): Promise<{
    resultSets: Array<{ rows: Record<string, unknown>[]; fields?: unknown[] }>;
  }>;
}

DialectCompiler

Interface for implementing a custom dialect. See the built-in postgres, mysql, and mssql modules for reference implementations.

ExecutableQueryBuilder

Extends QueryBuilder from @axiomdb/core with two additional methods:

| Method | Returns | Description | |--------|---------|-------------| | build() | { text: string, params: unknown[] } | Compile the query to SQL | | execute(db?) | Promise<TResult[]> | Compile and execute against a database adapter |

All chaining methods (.select(), .where(), .join(), etc.) return ExecutableQueryBuilder, so .build() and .execute() are always available at the end of the chain.

License

MIT