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

@oglofus/drizzle-events

v0.0.5

Published

A lightweight, strongly-typed event management library for Drizzle ORM.

Readme

@oglofus/drizzle-events

A lightweight, type-safe event layer for Drizzle ORM operations. It lets you hook into CRUD lifecycles (pre/post insert, update, delete) to validate, transform, and optionally cancel operations, with optional automatic rollback for post-event cancellations.

Currently focuses on Drizzle SQLite via drizzle-orm/sqlite-core.

  • Events: pre-insert, post-insert, pre-update, post-update, pre-delete, post-delete
  • Cancel or modify payloads in pre events
  • Optionally rollback changes if a post event is cancelled
  • Deep merge support when updating JSON-like objects

Installation

npm install @oglofus/drizzle-events @oglofus/event-manager drizzle-orm

This library is ESM-only.

Quick start (SQLite)

import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
import { Database } from 'drizzle-orm/sqlite-core'; // your BaseSQLiteDatabase type/instance
import { SQLiteEventManager } from '@oglofus/drizzle-events/sqlite';

// Define a Drizzle table
export const users = sqliteTable('users', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  email: text('email').notNull().unique(),
  profile: text('profile') // JSON string in this simple example
});

// Create your Drizzle database instance "db" with sqlite driver of your choice
// const db: BaseSQLiteDatabase = ...

const events = new SQLiteEventManager(db, {
  merge_objects: true,          // Deep-merge objects on update
  array_strategy: 'union',      // Array merge strategy: 'replace' | 'concat' | 'union'
  rollback_on_cancel: true      // Rollback when a post-event is cancelled
});

// Add a pre-insert validation and transformation
events.put(users, 'pre-insert', (ev) => {
  const data = ev.data;

  if (!('email' in data) || typeof data.email !== 'string') {
    ev.cancel('email is required');
    return;
  }

  // Example transformation
  ev.data = {
    ...data,
    email: data.email.toLowerCase()
  };
});

// Insert with events
const result = await events.insert(users, 'id', { email: '[email protected]' });
if (result.type === 'error') {
  console.error('Insert failed:', result.message);
} else {
  console.log('Inserted row:', result.data);
}

API

SQLiteEventManager

new SQLiteEventManager(database, config)
  • database: A Drizzle BaseSQLiteDatabase instance
  • config (optional):
    • merge_objects: boolean — Deep-merge nested objects on update (default: true)
    • array_strategy: 'replace' | 'concat' | 'union' — How to merge arrays when merge_objects is enabled (default: union)
    • rollback_on_cancel: boolean — If a post-event is cancelled, revert the change (default: true)

Methods:

  • insert(table, primary_field, data)

    • Emits pre-insert with a mutable data payload
    • On success, emits post-insert with the inserted row
    • Returns { type: 'success', data: row } or { type: 'error', message }
    • If post-insert is cancelled and rollback_on_cancel is true, the inserted row is deleted
  • update(table, primary_field, primary_value, data)

    • Emits pre-update with a mutable data and the current row
    • If merge_objects is true, object fields in data are deep-merged into existing row values
    • On success, emits post-update with row and old_row
    • Returns { type: 'success', data: row } or { type: 'error', message }
    • If post-update is cancelled and rollback_on_cancel is true, reverts to old_row
  • delete(table, primary_field, primary_value)

    • Emits pre-delete with the current row
    • On success, emits post-delete with the deleted row
    • Returns { type: 'success', data: row } or { type: 'error', message }
    • If post-delete is cancelled and rollback_on_cancel is true, reinserts the row

Registering handlers

events.put(table, type, handler, priority)
  • type: one of 'pre-insert' | 'post-insert' | 'pre-update' | 'post-update' | 'pre-delete' | 'post-delete'
  • handler(event): function receiving a cancellable event object
  • priority (optional): number (higher runs earlier). Uses priorities from @oglofus/event-manager.

Event objects share a common cancellable interface from @oglofus/event-manager:

  • event.cancel(reason?: string) — marks the event as cancelled
  • event.isCancelled() — returns boolean
  • event.getCancelReason() — string | undefined

Per event type:

  • pre-insertevent.data: insert payload (mutable)
  • post-insertevent.row: inserted row (readonly)
  • pre-updateevent.data (mutable), event.row (current row before update)
  • post-updateevent.row (updated row), event.old_row (previous row)
  • pre-deleteevent.row (row to be deleted)
  • post-deleteevent.row (deleted row)

Deep merge behavior on update

When merge_objects is enabled (default), and you pass partial objects in data to update, nested objects are deep-merged with existing row values. Arrays use the configured array_strategy:

  • replace — replace existing array with the new one
  • concat — concatenate arrays
  • union — unique set union (default)

Error handling

All public operations return a discriminated union:

type Response<T> =
  | { type: 'success'; data: T }
  | { type: 'error'; message?: string };

Check result.type to branch success vs error.

Import paths

  • Full package: @oglofus/drizzle-events
  • SQLite module: @oglofus/drizzle-events/sqlite
  • Base utilities/types: @oglofus/drizzle-events/base

Examples:

import { SQLiteEventManager } from '@oglofus/drizzle-events/sqlite';
import { deepMerge } from '@oglofus/drizzle-events/base';

Notes

  • This package builds on top of @oglofus/event-manager for the core event system.
  • Current focus is SQLite; additional dialects can follow a similar pattern.

License

ISC © oglofus