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

@qrvey/enginex

v0.0.1-1247-beta.1

Published

Connect to a data engine from an already-resolved config, and read from it through one engine-agnostic contract. Owns the `Enginex.create()` facade, the adapter registry/factory, the `Connector` contract, and errors. Reading env / resolving config lives i

Readme

@qrvey/enginex

Connect to a data engine from an already-resolved config, and read from it through one engine-agnostic contract. Owns the Enginex.create() facade, the adapter registry/factory, the Connector contract, and errors. Reading env / resolving config lives in @qrvey/enginex-resolvers — this package never reads env.

Usage

import { Enginex } from '@qrvey/enginex';
import { fromDefaultStorage } from '@qrvey/enginex-resolvers';

const db = await Enginex.create(fromDefaultStorage());
await db.connect(); // autoConnect defaults to false

if (await db.storageExists('dataset_123')) {
    const total = await db.count('dataset_123');
    const { rows } = await db.query({
        statement: 'SELECT * FROM dataset_123 LIMIT 100',
    });
}

await db.close();

Stream a large read, or read column types — both part of the always-present read core:

for await (const { rows } of db.stream({
    statement: 'SELECT * FROM dataset_123',
})) {
    handle(rows);
}

const columns = await db.getColumnMetadata('dataset_123');

Repository operations are optional — present only when the engine backs them. Gate with if (db.method), and TypeScript narrows the method to defined inside the block:

if (db.reindex) {
    await db.reindex('dataset_123', 'dataset_123_v2'); // ES/OS; ClickHouse omits it
}

Connect automatically, or pass a raw definition instead of a resolver:

const db = await Enginex.create(fromDefaultStorage({ autoConnect: true }));

await Enginex.create({
    source: 'internal',
    engine: 'clickhouse',
    config: { url: 'http://clickhouse:8123', database: 'default' },
});

// Elasticsearch / OpenSearch — basic auth, or AWS SigV4 when no user/pass
await Enginex.create({
    source: 'internal',
    engine: 'opensearch',
    config: { url: 'https://opensearch:9200', region: 'us-east-1' },
});

Contracts: source & repository

A connector implements one of two contracts, split by role:

  • SourceConnector — the read surface a data source needs (MySQL, MSSQL, Redshift, Athena…). Read-only by construction; the type has no write methods.
  • RepositoryConnector — extends SourceConnector with the write + management surface, for engines used as a writable data repository (ClickHouse, Elasticsearch, OpenSearch).

Read core (SourceConnector)

| Member | Does | | ---------------------------------- | ----------------------------------------------- | | connect() · close() · ping() | open · release · liveness (boolean) | | query(input) | run an engine-native query → QueryResult | | execute(input) | raw statement → { rows, raw } (escape hatch) | | count(storage) | row count → number | | storageExists(storage) | storage (table/index) exists → boolean | | getColumnMetadata(storage) | field types → ColumnMetadata[] | | stream(input) | incremental read → AsyncIterable<QueryResult> |

query(input) runs a ready-to-run, engine-native query — a SQL statement for ClickHouse, a search DSL body for Elasticsearch/OpenSearch — and returns a normalized QueryResult = { rows, total?, aggregations?, raw }. The input is executed as-is; build the native query upstream (e.g. with @qrvey/query-builder). execute is the raw escape hatch.

Repository surface (RepositoryConnector)

Adds records (bulk, putRecord, …), storage admin (createStorage, reindex, …), cluster ops, scroll, snapshots, scripts, and native-client access. These optional methods are present only when the engine backs them — an adapter defines what it supports and omits the rest. Gate each call with if (db.method); because the optional members are typed optional, TypeScript enforces the guard and narrows inside the block. There is no capabilities object and no supports() — presence is the capability.

Errors

Failures throw ConnectError with a stable code (CONFIG_ERROR / CONNECTION_ERROR / EXECUTION_ERROR / AUTH_ERROR), the failing engine, and the original error on .cause. Unsupported operations are not an error case — an engine simply omits the methods it does not back, so callers gate with if (db.method) instead of catching.