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

@jamx-framework/db

v1.0.0

Published

JAMX Framework — Database ORM

Readme

@jamx-framework/db

Descripción

Módulo de base de datos y ORM (Object-Relational Mapping) para JAMX Framework. Proporciona una API tipada yagnóstica para interactuar con diferentes motores de base de datos (SQLite, PostgreSQL, MySQL, etc.) mediante drivers específicos, ofreciendo funcionalidades como:

  • Repository: Acceso a tablas con operaciones CRUD tipadas
  • Migrations: Sistema de migraciones de esquema con generación automática de SQL
  • Query Builder: Construcción segura de consultas con parámetros serializados
  • Transaction Management: Manejo de transacciones con rollback automático
  • Schema Introspection: Detección de diferencias entre el esquema definido y la base de datos real

Cómo funciona

El módulo está estructurado en varios componentes clave que trabajan juntos:

  1. Database: Punto de entrada principal que crea y gestiona conexiones a drivers de base de datos
  2. Repository: Acceso a tablas con operaciones CRUD tipadas y gestión de entidades
  3. Migrations: Sistema para versionar cambios de esquema con up/down methods
  4. Schema Diff: Detecta diferencias entre el esquema definido y la base de datos real
  5. Query Builder: Construcción segura de consultas con serialización de parámetros
  6. Drivers: Implementaciones específicas para cada motor (SQLite, MySQL, PostgreSQL, etc.)

Componentes principales

  • src/database.ts: Clase Database que crea y gestiona conexiones a drivers
  • src/repository.ts: Clase genérica Repository<T> con operaciones CRUD
  • src/migrations/runner.ts: Clase MigrationRunner que ejecuta y rastrea migraciones
  • src/migrations/schema-diff.ts: Clase SchemaDiff que detecta diferencias de esquema
  • src/query/builder.ts: Clase base BaseQuery con lógica compartida de consultas
  • src/drivers/sqlite.ts: Driver para SQLite (y otros drivers en src/drivers/)
  • src/schema/table.ts: Definiciones de tablas y columnas con tipado fuerte
  • src/schema/column.ts: Definiciones de columnas con tipos y restricciones
  • src/types/*: Tipos compartidos como PaginatedResult, Result, Brand, etc.

Uso básico

import { Database } from '@jamx-framework/db';
import { defineTable, column, integer, text } from '@jamx-framework/db/schema';

// Definir la tabla de usuarios
export const usersTable = defineTable(
  'users',
  {
    id: column.text('id').primaryKey(),
    name: column.text('name').notNull(),
    email: column.text('email').unique(),
    createdAt: column.integer('created_at').default(0),
  }
);

// Crear instancia de la base de datos
const db = new Database({
  driver: 'sqlite',
  url: './data.db',
});

// Conectar y crear tabla si no existe
await db.connect();
await db.createTable(usersTable);

// Insertar un usuario
await db.repository(usersTable).insert({
  id: '1',
  name: 'Juan Pérez',
  email: '[email protected]',
  createdAt: Date.now(),
});

// Consultar usuarios
const users = await db.repository(usersTable).findAll();
console.log('Usuarios:', users);

Ejemplos

Operaciones CRUD básicas

// Crear tabla
await db.createTable(usersTable);

// Insertar registro
await db.repository(usersTable).insert({
  id: '2',
  name: 'Ana Gómez',
  email: '[email protected]',
});

// Buscar por ID
const user = await db.repository(usersTable).findById('1');
console.log('Usuario encontrado:', user);

// Actualizar registro
await db.repository(usersTable).update('1', { name: 'Juan Pérez Updated' });

// Eliminar registro
await db.repository(usersTable).delete('1');

Migraciones automáticas

# Generar migración a partir de cambios en el esquema
jamx db:generate-migration --name add_posts_table

# Aplicar migraciones pendientes
jamx db:migrate

# Revertir última migración
jamx db:rollback

Uso avanzado con transacciones

await db.transaction(async (txDb) => {
  // Todas las operaciones dentro de esta función se ejecutan en una transacción
  await txDb.repository(usersTable).insert({ id: '3', name: 'Pedro', email: '[email protected]' });
  await txDb.repository(usersTable).update('2', { email: '[email protected]' });
});

Paginación y resultados seguros

const result = await db.repository(usersTable)
  .select()
  .paginate({ page: 1, limit: 10 });

console.log(`Página 1 de ${result.totalPages} con ${result.total} usuarios`);
console.log('Datos:', result.data);

Flujo interno

  1. Inicialización: Database crea el driver apropiado según la configuración (sqlite, postgres, etc.)
  2. Conexión: Se establece la conexión con la base de datos mediante driver.connect()
  3. Definición de esquema: Las tablas se definen usando defineTable() y column() con tipos y restricciones
  4. Operaciones CRUD: Repository ejecuta consultas mediante BaseQuery y sus subclasses (SelectQuery, InsertQuery, etc.)
  5. Serialización de parámetros: Los valores se serializan adecuadamente según el tipo de columna (ej: boolean → 0/1, JSON → stringificado)
  6. Transacciones: Cuando se usa transaction(), todas las operaciones se ejecutan dentro de una transacción con rollback automático en caso de error
  7. Migraciones: MigrationRunner mantiene una tabla interna __jamx_migrations para rastrear qué migraciones se han ejecutado
  8. Detección de diferencias: SchemaDiff compara el esquema definido con la base de datos real para generar migraciones automáticas
  9. Resultados tipados: Los métodos devuelven resultados tipados que pueden ser manejados con Result.ok()/Result.err() para manejo explícito de errores

API Reference (Resumen)

Database

  • new Database(config): Crea una nueva instancia
  • connect(): Establece la conexión
  • disconnect(): Cierra la conexión
  • repository(table): Obtiene un Repository para una tabla
  • raw(sql, params?): Ejecuta SQL crudo

Repository

  • findAll(): Obtiene todos los registros
  • findById(id): Busca por ID
  • findOne(where): Busca el primer registro que coincida
  • findMany(where): Busca múltiples registros
  • insert(entity): Inserta un nuevo registro
  • update(id, data): Actualiza un registro existente
  • delete(id): Elimina un registro
  • paginate(options): Paginación con metadatos

Migrations

  • MigrationRunner.initialize(): Inicializa la tabla de migraciones
  • MigrationRunner.run(migrations): Ejecuta migraciones pendientes
  • MigrationRunner.rollback(migrations, steps?): Revierte migraciones
  • MigrationRunner.status(migrations): Obtiene el estado de todas las migraciones

Schema Definition

  • defineTable(name, columns): Define una tabla con sus columnas
  • column(name, type): Define una columna con tipo y restricciones
  • Tipos de columnas: text(), integer(), real(), boolean(), blob(), json()

Performance Considerations

  • Prepared Statements: Todos los drivers usan consultas preparadas para prevenir SQL injection
  • Batch Operations: insertMany() y operaciones similares están optimizadas para inserciones en lote
  • Connection Pooling: Los drivers implementan pooling de conexiones para reutilizar conexiones activas
  • Lazy Loading: Las tablas y relaciones se cargan solo cuando se accede a ellas

Compatibility

  • Compatible con Node.js 18+ y TypeScript 5.x
  • Soporta SQLite (por defecto), PostgreSQL, MySQL, y otros motores mediante drivers adicionales
  • Funciona en Windows, macOS y Linux
  • No requiere dependencias globales; todas las herramientas se instalan como devDependencies

Plugin Development

Para crear un driver personalizado:

  1. Extiende DatabaseDriver e implementa los métodos abstractos (connect, disconnect, query, transaction)
  2. Registra el driver en la configuración del Database
  3. Implementa métodos de transacción si tu motor los soporta

Ejemplo mínimo de driver:

import { DatabaseDriver } from '@jamx-framework/db';

export class MyCustomDriver implements DatabaseDriver {
  async connect() { /* lógica de conexión */ }
  async disconnect() { /* lógica de desconexión */ }
  async query(sql: string, params: unknown[]) { /* lógica de consulta */ }
  async transaction(fn: (db: Database) => Promise<unknown>) { /* lógica de transacción */ }
}

Testing

El proyecto incluye tests unitarios en packages/db/tests/unit/. Para ejecutarlos:

pnpm test
# o
npm run test

Los tests cubren:

  • Conexión y operaciones básicas con SQLite
  • CRUD completo mediante Repository
  • Sistema de migraciones y rollback
  • Detección de diferencias de esquema
  • Manejo de transacciones
  • Serialización segura de parámetros

Configuration Options

new Database({
  driver: 'sqlite' | 'postgres' | 'mysql' | 'mariadb' | 'mongodb',
  url: string,           // Cadena de conexión (ej: 'sqlite:./data.db')
  entities: TableDefinition[], // Opcional: tablas a registrar automáticamente
  // Opciones específicas por driver:
  //   sqlite: { url: string }
  //   postgres: { host, port, database, user, password }
  //   mysql: { host, port, database, user, password }
});

CLI Commands (Jamx)

  • jamx db:generate-migration --name <nombre>: Genera una migración basada en cambios de esquema
  • jamx db:migrate: Aplica todas las migraciones pendientes
  • jamx db:rollback: Revierte la última migración ejecutada
  • jamx db:status: Muestra el estado actual de las migraciones
  • jamx db:push: Genera y aplica migraciones automáticamente

This database module provides a robust, type-safe foundation for database interactions in JAMX applications, enabling developers to work with multiple database engines through a unified and expressive API while maintaining full control over schema evolution and data operations.