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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@hemia/db-connector

v0.0.8

Published

Hemia Database Conector

Readme

@hemia/db-connector

Conector unificado para bases de datos SQL, NoSQL y OLAP, diseñado para facilitar operaciones comunes como conexión, transacciones, queries y manipulación de datos. Ideal para aplicaciones Node.js que requieren una interfaz abstracta para distintos motores de base de datos.


Instalación

npm install @hemia/db-connector

Bases de Datos Soportadas

🗄️ SQL (OLTP - Online Transaction Processing)

Bases de datos relacionales optimizadas para transacciones y operaciones CRUD.

  • MySQL - Base de datos relacional de código abierto
  • PostgreSQL - Base de datos relacional avanzada con soporte JSON
  • Microsoft SQL Server (MSSQL) - Base de datos empresarial de Microsoft

Casos de uso:

  • Sistemas transaccionales (e-commerce, banking)
  • Aplicaciones empresariales (ERP, CRM)
  • Gestión de usuarios y autenticación
  • Aplicaciones que requieren integridad referencial

📄 NoSQL (Document Store)

Bases de datos orientadas a documentos para datos no estructurados.

  • MongoDB - Base de datos de documentos JSON flexible y escalable

Casos de uso:

  • Aplicaciones con esquemas flexibles
  • Gestión de contenido (CMS)
  • Perfiles de usuario complejos
  • Catálogos de productos
  • Logs y eventos en formato JSON
  • Aplicaciones en tiempo real

📊 OLAP (Online Analytical Processing)

Bases de datos columnares optimizadas para análisis y consultas agregadas.

  • ClickHouse - Base de datos columnar de alta velocidad para análisis en tiempo real

Casos de uso:

  • Análisis de logs y trazas (APM, Observability)
  • Métricas y monitoreo en tiempo real
  • Business Intelligence y Data Warehousing
  • Análisis de eventos y comportamiento de usuarios
  • Procesamiento de grandes volúmenes de datos
  • Dashboards analíticos de alto rendimiento

Uso rápido

MongoDB

import { MongoDBConnector } from '@hemia/db-connector';

const mongo = new MongoDBConnector({
  host: 'localhost',
  user: 'admin',
  password: '1234',
  database: 'mydb',
});

await mongo.connect();
const docs = await mongo.find(MyModel, { status: 'active' });

SQL (MySQL/MSSQL/PostgreSQL)

import { DBConnector } from '@hemia/db-connector';
import { DBSQLType } from '@hemia/db-connector/types/DBSQLTypes';

const dbConnector = DBConnector.getInstance();
const sql = dbConnector.getEngine(DBSQLType.MySQL, {
  host: 'localhost',
  user: 'root',
  password: 'pass',
  database: 'mydb',
  dialect: 'mysql'
});

await sql.connect();
const rows = await sql.select('users', { where: { active: true } });

// Transacciones
await sql.withTransaction(async (transaction) => {
  await sql.insert('orders', { userId: 1, total: 100 }, { transaction });
  await sql.update('users', { id: 1 }, { balance: 500 }, { transaction });
});

ClickHouse (OLAP)

import { DBConnector } from '@hemia/db-connector';
import { DBOLAPType } from '@hemia/db-connector/types/OLAPTypes';

const dbConnector = DBConnector.getInstance();
const clickhouse = dbConnector.getEngine(DBOLAPType.ClickHouse, {
  host: 'http://localhost:8123',
  user: 'default',
  password: '',
  database: 'analytics',
});

await clickhouse.connect();

// Insertar datos (JSONEachRow por defecto)
await clickhouse.insert({
  table: 'traces',
  values: [
    { trace_id: '123', service_name: 'api', duration_ms: 45 },
    { trace_id: '124', service_name: 'db', duration_ms: 120 }
  ]
});

// Insertar con formato CSV
await clickhouse.insert({
  table: 'traces',
  values: '125,"cache",30\n126,"queue",85',
  format: 'CSV'
});

// Buscar con filtros
const traces = await clickhouse.find('traces', { 
  service_name: 'api',
  error: false 
});

// Query personalizada para análisis
const stats = await clickhouse.query(`
  SELECT 
    service_name,
    count() as total_requests,
    avg(duration_ms) as avg_duration,
    max(duration_ms) as max_duration
  FROM traces
  WHERE start_time >= now() - INTERVAL 1 HOUR
  GROUP BY service_name
  ORDER BY total_requests DESC
`);

Uso con DBConnector (Recomendado)

El patrón recomendado es usar DBConnector como punto de entrada único:

import { DBConnector } from '@hemia/db-connector';
import { DBSQLType, DBNoSQLType, DBOLAPType } from '@hemia/db-connector';

const dbConnector = DBConnector.getInstance();

// Obtener motor SQL
const mysql = dbConnector.getEngine(DBSQLType.MySQL, credentials);

// Obtener motor NoSQL  
const mongo = dbConnector.getEngine(DBNoSQLType.MongoDB, credentials);

// Obtener motor OLAP
const clickhouse = dbConnector.getEngine(DBOLAPType.ClickHouse, credentials);

Características destacadas

MongoDBConnector (NoSQL)

  • Conexión y desconexión automáticas
  • Transacciones con rollback (withTransaction)
  • CRUD genérico (create, find, findOne, update, delete, etc.)
  • Operaciones avanzadas: aggregate, findAllFromMultipleModels
  • Soporte para modelos Mongoose
  • Manejo automático de sesiones

Ejemplo de uso avanzado:

// Aggregate pipeline
const results = await mongo.aggregate(UserModel, [
  { $match: { active: true } },
  { $group: { _id: '$country', total: { $sum: 1 } } }
]);

// Transacciones
await mongo.withTransaction(async (session) => {
  await mongo.create(UserModel, { name: 'John' }, session);
  await mongo.update(UserModel, { _id: userId }, { status: 'active' }, session);
});

SequelizeSqlConnector (SQL)

  • Operaciones CRUD: select, insert, update, delete
  • Transacciones con soporte completo de Sequelize (withTransaction)
  • Query SQL libre con query() para consultas complejas
  • Manejo de errores y mapeo de códigos SQLSTATE (createDatabaseError)
  • Soporte para stored procedures
  • Conexión a MySQL, PostgreSQL, MSSQL

Ejemplo de uso avanzado:

// Query con stored procedure
const result = await sql.query('CALL get_user_stats(:userId)', {
  replacements: { userId: 123 },
  type: QueryTypes.SELECT
});

// Transacciones
await sql.withTransaction(async (transaction) => {
  await sql.insert('orders', orderData, { transaction });
  await sql.update('inventory', { productId: 1 }, { stock: 10 }, { transaction });
});

ClickHouseConnector (OLAP)

  • Conexión optimizada para análisis de alto rendimiento
  • Múltiples formatos de inserción: JSONEachRow, CSV, TabSeparated, etc.
  • Método find() con filtros para búsquedas rápidas
  • Query SQL libre para análisis complejos
  • Ideal para procesamiento de grandes volúmenes de datos
  • Soporte para columnas calculadas (MATERIALIZED)

Ejemplo de uso avanzado:

// Insertar millones de registros eficientemente
await clickhouse.insert({
  table: 'events',
  values: largeDataArray, // Array con millones de registros
  format: 'JSONEachRow'
});

// Análisis en tiempo real
const metrics = await clickhouse.query(`
  SELECT 
    toStartOfMinute(timestamp) as minute,
    countIf(status = 200) as success,
    countIf(status >= 400) as errors,
    quantile(0.95)(response_time) as p95_latency
  FROM http_logs
  WHERE timestamp >= now() - INTERVAL 1 HOUR
  GROUP BY minute
  ORDER BY minute DESC
`);

// Búsqueda con filtros múltiples
const errorTraces = await clickhouse.find('traces', {
  service_name: 'payment-api',
  error: true,
  duration_ms: 1000 // Mayor a 1 segundo
});

Tipos esperados de configuración

interface CredentialsConnection {
  host: string;
  port?: number;
  user?: string;
  password?: string;
  database: string;
  dialect?: 'mysql' | 'mssql' | 'postgres';
  logging?: boolean;
}

Arquitectura y Patrones de Uso

Lambda Architecture: Combinando SQL, NoSQL y OLAP

Una arquitectura común es usar diferentes bases de datos para diferentes propósitos:

// 1. OLTP (MySQL/PostgreSQL) - Transacciones en tiempo real
const mysql = dbConnector.getEngine(DBSQLType.MySQL, mysqlCredentials);
await mysql.insert('orders', { userId: 123, amount: 99.99 });

// 2. NoSQL (MongoDB) - Datos flexibles y documentos
const mongo = dbConnector.getEngine(DBNoSQLType.MongoDB, mongoCredentials);
await mongo.create(ProductModel, { 
  name: 'Laptop',
  specs: { ram: '16GB', cpu: 'i7' } // Esquema flexible
});

// 3. OLAP (ClickHouse) - Análisis y reportes
const clickhouse = dbConnector.getEngine(DBOLAPType.ClickHouse, clickhouseCredentials);
await clickhouse.insert({
  table: 'order_analytics',
  values: [{ 
    order_id: orderId,
    user_id: 123,
    amount: 99.99,
    timestamp: new Date()
  }]
});

Casos de Uso por Tipo de Base de Datos

🗄️ SQL (MySQL/PostgreSQL/MSSQL)

Cuándo usar:

  • Necesitas transacciones ACID
  • Relaciones complejas entre entidades
  • Integridad referencial crítica
  • Consultas con JOINs

Ejemplos:

  • Sistema de facturación
  • Gestión de inventario
  • Sistema de usuarios y permisos
  • Carrito de compras

📄 NoSQL (MongoDB)

Cuándo usar:

  • Esquemas variables o en evolución
  • Necesitas escalar horizontalmente
  • Documentos JSON complejos
  • Alto volumen de escrituras

Ejemplos:

  • Catálogo de productos con atributos variables
  • Perfiles de usuario con datos personalizados
  • Sistema de logs y auditoría
  • Gestión de contenido (CMS)

📊 OLAP (ClickHouse)

Cuándo usar:

  • Análisis de grandes volúmenes de datos
  • Consultas agregadas complejas
  • Necesitas latencias de milisegundos en análisis
  • Datos de series temporales

Ejemplos:

  • Observabilidad y APM (traces, logs, métricas)
  • Análisis de comportamiento de usuarios
  • Dashboards de BI en tiempo real
  • Análisis de eventos y clickstream
  • Monitoreo de infraestructura

Ejemplo Completo: Sistema de E-commerce con Observabilidad

import { DBConnector, DBSQLType, DBNoSQLType, DBOLAPType } from '@hemia/db-connector';

const connector = DBConnector.getInstance();

// 1. Base de datos transaccional (MySQL)
const mysql = connector.getEngine(DBSQLType.MySQL, {
  host: 'localhost',
  database: 'ecommerce',
  user: 'root',
  password: 'pass'
});

// 2. Base de datos de documentos (MongoDB)
const mongo = connector.getEngine(DBNoSQLType.MongoDB, {
  host: 'localhost',
  database: 'ecommerce_content'
});

// 3. Base de datos analítica (ClickHouse)
const clickhouse = connector.getEngine(DBOLAPType.ClickHouse, {
  host: 'http://localhost:8123',
  database: 'analytics'
});

// Procesar orden
async function processOrder(orderData) {
  const startTime = Date.now();
  
  try {
    // 1. Guardar orden en MySQL (transaccional)
    await mysql.withTransaction(async (tx) => {
      const order = await mysql.insert('orders', orderData, { transaction: tx });
      await mysql.update('inventory', 
        { productId: orderData.productId }, 
        { stock: { decrement: 1 } },
        { transaction: tx }
      );
    });
    
    // 2. Guardar detalles enriquecidos en MongoDB
    await mongo.create(OrderDetailsModel, {
      orderId: orderData.id,
      userPreferences: orderData.preferences,
      metadata: orderData.metadata
    });
    
    // 3. Registrar evento en ClickHouse para análisis
    await clickhouse.insert({
      table: 'order_events',
      values: [{
        event_type: 'order_created',
        order_id: orderData.id,
        user_id: orderData.userId,
        amount: orderData.amount,
        duration_ms: Date.now() - startTime,
        timestamp: new Date(),
        success: true
      }]
    });
    
  } catch (error) {
    // Registrar error en ClickHouse
    await clickhouse.insert({
      table: 'order_events',
      values: [{
        event_type: 'order_failed',
        order_id: orderData.id,
        error_message: error.message,
        duration_ms: Date.now() - startTime,
        timestamp: new Date(),
        success: false
      }]
    });
    throw error;
  }
}

// Análisis de órdenes en tiempo real
async function getOrderStats() {
  return await clickhouse.query(`
    SELECT 
      toStartOfHour(timestamp) as hour,
      countIf(success = true) as successful_orders,
      countIf(success = false) as failed_orders,
      avg(amount) as avg_order_value,
      quantile(0.95)(duration_ms) as p95_duration
    FROM order_events
    WHERE timestamp >= now() - INTERVAL 24 HOUR
    GROUP BY hour
    ORDER BY hour DESC
  `);
}

Licencia

MIT


Autor

Hemia Technologies