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

evelodb-prime

v1.0.0

Published

A high-performance native B-tree database for Node.js. Made by Evelocore. With B-tree Operations.

Downloads

231

Readme

📚 Introduction

EveloDB Prime is the streamlined, high-performance evolution of EveloDB. It removes the overhead of multi-format support and encryption to focus strictly on BSON-backed B-Tree storage. It's designed for large-scale applications that need fast indexing and reliable local storage without the complexity of configuration.

Requirements

  • Node.js

Table of Contents

📥 Installation

Npm Install

npm i evelodb-prime

Import

CommonJS

const eveloDB = require('evelodb-prime');
const db = new eveloDB();

TypeScript / ES Modules

import eveloDB from 'evelodb-prime';
const db = new eveloDB();

Configuration

[!CAUTION] CRITICAL: Use a Single Instance Do NOT initialize new eveloDB() multiple times in different files (e.g., in different routes or middleware). Doing so will create separate, desynchronized memory caches and file handles, leading to missing data and EPERM lock errors. Instead, create a single db.js or db.ts file, initialize EveloDB there, and export the instance to use throughout your application.

const db = new eveloDB({
    directory: './evelodbprime', // Storage directory
    noRepeat: false,             // Reject duplicate data
    schema: {
        users: {
            fields: {
                username: { type: String, required: true, min: 5, max: 30 },
                email: { type: String, required: true },
                age: { type: Number, required: true, max: 90 },
                vehicle: {
                    type: {
                        color: { type: String, required: true },
                        model: { type: String, required: true }
                    },
                    required: false
                }
            },
            indexes: ["email", "username"],
            uniqueKeys: ["email", "username"],
            objectIdKey: "userId"
        },
        products: {
            fields: {
                name: { type: String, required: true },
                price: { type: Number, required: true, min: 0 },
                inStock: { type: Boolean, required: true }
            },
            indexes: ["name"],
            uniqueKeys: ["name"],
            objectIdKey: "productId"
        }
    }
});

Configuration Parameters

| Parameter | Type | Required | Description | Default | |--------------------|----------|----------|----------------------------------------------|-----------------------------| | directory | string | No | Where database files are stored | './evelodbprime' | | maxHandles | number | No | Max open collection handles (LRU) | 64 | | compactThreshold | number | No | Auto-compact ratio (0.1 - 0.9) | 0.3 | | schema | Object | No | Schema, Indexes, and Unique Keys for collections | {} |

Schema Definition

When defining a schema, each collection can have fields, indexes, and uniqueKeys.

Field Validation

| Property | Type | Description | Required | |------------|--------------------|-----------------------------------------------------------------------------|----------| | type | Constructor / Obj | Data type (e.g., String, Number, Boolean, or a nested object schema). | Yes | | required | boolean | If true, the field must be present during creation/update. | No | | min | number | Minimum value for Number or minimum length for String. | No | | max | number | Maximum value for Number or maximum length for String. | No |

Collection Options

| Option | Type | Description | Required | |--------------|----------|-----------------------------------------------------------------------------|----------| | fields | Object | Field validation rules (as defined in the table above). | No | | indexes | string[] | Fields to create B-Tree indexes for (enables O(log n) searches). | No | | uniqueKeys | string[] | Fields that must contain unique values across the entire collection. | No | | objectIdKey| string | Virtual name for the internal _id field (e.g., "userId"). | No | | noRepeat | boolean | If true (default), rejects insertions of exact duplicate records. | No |

[!IMPORTANT] System Managed Fields: Fields like _id (or your custom objectIdKey), _createdAt, and _modifiedAt are automatically managed by EveloDB. Any attempt to manually set or update these fields in create() or edit() will result in an error.

Note: All parameters are optional. If no directory is specified, EveloDB will default to ./evelodbprime.

Note: EveloDB Prime uses .db extension and _id as the primary key. Secondary indexes use .field.bidx files.

Easy Schema Explanation

indexes: ["email", "username"]

  • These indexes will be created as B-Trees on the disk for faster searching
  • If not specified, it will default to [objectIdKey] or ["_id"]

uniqueKeys: ["email", "username"]

  • These fields will be checked for uniqueness before insertion
  • If not specified, it will default to []

objectIdKey: "userId"

  • This field will be the auto generated id
  • If not specified, it will default to '_id'

name: { type: String, required: true }

  • 'name' is String value and required

username: { type: String, required: true, min: 5, max: 30 }

  • 'username' is String value and required
  • minimum length is 5
  • maximum length is 30

age: { type: Number, required: true, max: 90 }

  • 'age' is Number value and required
  • maximum value is 90

vehicle: { type: { color: { type: String, required: true }, model: { type: String, required: true } } }

  • 'vehicle' is Object value and not required
  • inside 'vehicle' there is 'color' and 'model' which are String value and required

📘 TypeScript / ES Modules

EveloDB Prime is fully written in TypeScript and supports both CommonJS and ES Module environments natively.

Importing Types

import eveloDB, { type EveloDBConfig } from 'evelodb-prime';

const config: EveloDBConfig = {
    directory: './database',
    noRepeat: true
};

const db = new eveloDB(config);

🔢 Comparison Operators

Used to filter with conditions like greater than, less than, equal, etc.

| Operator | Description | Example | |----------|-------------------------|-----------------------------------------| | $eq | Equal | { age: { $eq: 25 } } | | $ne | Not equal | { age: { $ne: 25 } } | | $gt | Greater than | { age: { $gt: 25 } } | | $gte | Greater than or equal | { age: { $gte: 25 } } | | $lt | Less than | { age: { $lt: 25 } } | | $lte | Less than or equal | { age: { $lte: 25 } } | | $in | Matches any in an array | { status: { $in: ["active", "pending"] } } | | $nin | Not in array | { status: { $nin: ["inactive"] } } | | $regex | Regular expression | { name: { $regex: "^Jo", $options: "i" } } |

Example: Using Operators

db.find('users', { age: { $gte: 25 } }).all()

💈 Atomic Update Operators

EveloDB supports atomic operators to modify fields without manual read-modify-write cycles. This is essential for counters (like stock) in high-traffic APIs.

| Operator | Description | Example | | :--- | :--- | :--- | | $inc | Increments/decrements a numeric field | { $inc: { stock: -1 } } | | $set | Sets a field to a specific value | { $set: { status: 'active' } } | | $unset | Removes a field from the document | { $unset: { temporaryFlag: true } } | | $push | Appends a value to an array | { $push: { tags: 'new-tag' } } | | $pull | Removes a value or matching items from an array | { $pull: { tags: 'old-tag' } } |

Example: Atomic Stock Update

db.edit('products', { productId: '123' }, { $inc: { stock: -1 } });

⚙️ Operations

[!CAUTION] Bulk Operations: Passing an empty object {} as the conditions parameter in edit(), delete(), or find() will target every record in the collection. Example: db.edit("users", {}, { status: "active" }) will update all users in the collection.

Create

Adds a new record to the collection.

db.create('users', {
    username: 'john',
    email: '[email protected]'
})

Output

{ 
  success: true, 
  userId: '662e5a4e3d5a4e3d5a4e3d5a', // Renamed via objectIdKey
  _createdAt: '2026-04-28T10:00:00Z',
  _modifiedAt: '2026-04-28T10:00:00Z'
}

Note: If objectIdKey is not defined in the schema, this field defaults to _id.

Update

Modifies existing records that match the conditions.

Note: db.update() is an alias for db.edit().

db.edit('users', 
    { username: 'john' },
    { email: '[email protected]' }
)

Output

{
  success: true,
  modifiedCount: 1,
  skippedDuplicates: 0 // If noRepeat is enabled
}

Delete

Removes records that match the conditions.

db.delete('users', { username: 'john' })

Output

{
  success: true,
  deletedCount: 1
}

Inject

Perform high-performance bulk data injection. Useful for migrations or importing backups.

const data = [
  { 
    username: 'alice', 
    email: '[email protected]',
    _createdAt: '2026-04-29T08:50:16Z',
    _modifiedAt: '2026-04-29T10:00:00Z',
    _id_: '69f1c6486266d6824c7680e4' 
  },
  // ... more records
];

// Method: 'overwrite' (default) - Clears collection before injection
db.inject("users", data);

// Method: 'merge' - Appends data to existing collection
db.inject("users", data, { method: 'merge' });

[!IMPORTANT] Data Integrity: Injected data must include system fields: _createdAt, _modifiedAt, and the ID field (e.g., userId or _id). If a schema or noRepeat is defined, validation will be enforced during injection.

Output

{ success: true, count: 2 }

Find

Search for records. Returns a QueryResult object.

// Find one using virtual ID key
const user = db.findOne('users', { userId: '662e5a4e3d5a4e3d5a4e3d5a' });

// Find many (returns QueryResult)
const result = db.find('users', { age: { $gt: 18 } });

Search

Performs a case-insensitive "contains" search on fields. Useful for autocomplete or simple text matching.

// Matches "John", "johnny", "Elton John", etc.
const results = db.search('users', { username: 'john' });

Get

Retrieves all records from a collection. Returns a QueryResult.

const allData = db.get('users').all();

Count

Returns the total number of records in a collection.

const { count } = db.count('users');

Check

Checks if at least one record exists that matches the conditions. Returns boolean.

const exists = db.check('users', { email: '[email protected]' });

Drop / Reset

Permanently deletes a collection and all its associated index files.

db.drop('users'); 
// or
db.reset('users');

Compact

Manually triggers the compaction process to reclaim storage space used by deleted or updated records.

db.compact('users');

Rebuild Indexes

Rebuilds all B-Tree indexes (primary and secondary) for a collection from the raw data. Useful for recovery if index files are corrupted or missing.

db.rebuildIndexes('users');

Close All

Closes all open collection handles and ensures all data/indexes are flushed to the disk.

db.closeAll();

🔍 Get Query Result

This is a wrapper that provides chainable methods for working with query results in eveloDB. It enables pagination, sorting, and other data manipulation operations on query results.

Overview

The Query Result returned by the following eveloDB methods:

  • db.find(collection, conditions)
  • db.search(collection, conditions)
  • db.get(collection) when data is an array

Examples

getList

  • Implements pagination by returning a subset of results.
// Get first 10 users
const firstPage = db.find('users', { status: 'active' }).getList(0, 10);

// Get next 10 users (pagination)
const secondPage = db.find('users', { status: 'active' }).getList(10, 10);

// Get 5 users starting from index 20
const customPage = db.find('users', { status: 'active' }).getList(20, 5);

count

  • Returns the total number of items in the result set.
// Get total count of active users
const totalActiveUsers = db.find('users', { status: 'active' }).count();

// Get count of search results
const searchCount = db.search('products', { name: 'phone' }).count();

// Use for pagination info
const results = db.find('orders', { status: 'pending' });
const total = results.count();
const currentPage = results.getList(0, 20);
console.log(`Showing ${currentPage.length} of ${total} results`);

sort

  • Sorts the results using a comparison function.
// Sort by name (ascending)
const sortedByName = db.find('users', { status: 'active' })
    .sort((a, b) => a.name.localeCompare(b.name))

// Sort by age (descending)
const sortedByAge = db.find('users', { status: 'active' })
    .sort((a, b) => b.age - a.age)
    .getList(0, 20);

// Sort by date (newest first)
const sortedByDate = db.find('posts', { published: true })
    .sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))
    .getList(0, 10);

Method Chaining

One of the key features of QueryResult is method chaining, allowing you to combine operations:

const db = new eveloDB();

// Chain multiple operations
const result = db.find('products', { category: 'electronics' })
    .sort((a, b) => b.price - a.price)  // Sort by price (high to low)
    .getList(10, 5);                    // Get items 11-15

// Complex chaining example
const topExpensiveProducts = db.search('products', { name: 'laptop' })
    .sort((a, b) => b.price - a.price)  // Sort by price descending
    .getList(0, 3);                     // Get top 3 most expensive

// Get count after sorting (count remains the same)
const sortedResults = db.find('users', { role: 'admin' })
    .sort((a, b) => a.name.localeCompare(b.name));
    
const totalCount = sortedResults.count();        // Total admins
const firstPage = sortedResults.getList(0, 10);  // First 10 sorted admins

💾 Backup Data

Export your collection data for safekeeping or migration.

[!NOTE] Backups always preserve the original _id field, even if you have configured an objectIdKey. This ensures your backups remain compatible even if you change your schema configuration later.

// 1. Backup as Secure Binary (Full-file XOR Encoding)
db.createBackup('users', {
    type: 'binary',
    path: './backups',
    password: 'my_secret_password',
    title: 'User Records April 2026'
});

// 2. Backup as JSON
db.createBackup('users', { type: 'json', path: './backups' });

Output (createBackup)

{
  success: true,
  backupPath: './backups/users_backup_2026-04-28.backup'
}

🔍 Read Backup Info

Inspect a backup file (Metadata & Data) without performing a restore.

Note: Backup type defaults to 'binary' if not specified.

const info = db.readBackupFile('./backups/users_backup.backup', 'my_secret_password');

Output (readBackupFile)

{
  success: true,
  title: 'User Records April 2026',
  protected: true,
  schema: { ... },
  length: 150,
  data: [ { username: 'john', ... }, ... ],
  created: 2026-04-28T10:00:00Z
}

🔄 Restore Backup

Restore a collection from a previous backup.

[!WARNING] Restoring a backup will overwrite current data in the collection.

db.restoreBackup('users', {
    type: 'binary',
    file: './backups/users_backup_2026-04-28.backup',
    password: 'my_secret_password'
});

Output (restoreBackup)

{ success: true }

📦 Object Store

Store simple application configuration or small state objects as standalone BSON files (.objdb). Perfect for keeping app data that doesn't require complex collections or indexing.

Write/Update Object

db.object("appConfig").write({ theme: 'dark', version: '1.0.4' })
db.object("appConfig").update({ theme: 'light' }) // Merges with existing data

Read Object

const config = db.object("appConfig").read() // { theme: 'light', version: '1.0.4' } or null

Rename/Delete

db.object("appConfig").rename("userSettings")
db.object("userSettings").delete()

List all objects

const objects = db.object().list() // ["userSettings", "themeCache"] or []

🔒 Transactions (db.atomic)

EveloDB provides an asynchronous transaction system to prevent race conditions during complex operations that involve await gaps.

By using db.atomic(), you can ensure that a block of code runs in isolation. Any other atomic operation targeting the same collection will wait in a queue until the current one finishes.

Usage

1. Collection-Level Lock (Recommended)

Only blocks the specific collection, allowing other collections to remain fast.

await db.atomic('products', async (tx) => {
    const item = tx.findOne('products', { id: 'p1' });
    
    await someAsyncLogic(); 
    
    tx.edit('products', { id: 'p1' }, { stock: item.stock - 1 });
});

2. Global Lock

Blocks all collections. Useful for migrations or multi-collection updates.

await db.atomic(async (tx) => {
    const user = tx.findOne('users', { id: 'u1' });
    tx.edit('logs', {}, { message: `User ${user.name} logged in` });
});

Why use this?

While Atomic Operators ($inc) are great for simple math, you need Transactions when:

  1. You have multiple steps (Read -> Logic -> Write).
  2. You have await calls between your database operations.
  3. You want to ensure "All or Nothing" behavior.

[!TIP] Alternative: db.transaction() If you only need to lock a single collection and don't need the tx object, you can use the simpler db.transaction('collection', async () => { ... }) method.

📁 File Store

EveloDB is a lightweight file storage system for handling any type of file directly in your local storage.

  • File Management – Read, write, and delete files easily.
  • Image Utilities – Special functions to process images (resize, compress, transform, ...).
  • Lightweight & Fast – No external database required, works directly with the file system.

Store image buffer as image.jpg

db.writeFile('image.jpg', imageBuffer)
{ success: true }

Read image.jpg

db.readFile('image.jpg')
{
  success: true,
  data: <Buffer ff d8 ff e0 00 10 ...>
}

Delete profile.pdf

db.deleteFile('profile.pdf')
{ success: true }

List all files

db.allFiles() // ['image.jpg', 'profile.pdf']

🖼️ Image Utilities

EveloDB includes built-in utilities to read and process images with ease, backed by an highly optimized performance architecture.

⚡ Performance Architecture

  • Zero-Decode LRU Cache: Sub-millisecond reads. A 200MB hash-based cache skips sharp processing entirely on cache hits.
  • Metadata Fast Path: Dimensions are only extracted when strictly required (pixel-budget resizing), maximizing throughput for direct format/filter conversions.
  • AVIF Concurrency Limiter: AVIF encodes are strictly bounded by a concurrency limiter (Tune via AVIF_CONCURRENCY env var, defaults to 2) to eliminate CPU saturation under burst traffic.
  • Hardware-Friendly Defaults: Disables mozjpeg in favor of standard libjpeg (3-5x faster) and reduces AVIF effort to level 2 (2-4x faster).

✨ Features

  • Resize by maximum total pixels or exact width/height constraints
  • Adjust brightness and contrast
  • Apply filters (grayscale, invert, mirror, flip vertically)
  • Control quality and dynamic output format based on extension (.jpg, .webp, .avif, .png, etc.)
  • Output formats available directly as Buffer or Base64 data URLs

⚙️ Parameters

| Parameter | Type | Default | Description | |-----------------|---------|---------|-------------| | returnBase64 | Boolean | true | If true, returns a Base64 Data URL. Otherwise returns a Buffer. | | quality | Number | 1 | Output quality (0.1 – 1). Lower values reduce size. | | pixels | Number | 0 | Maximum total pixels. 0 = keep original size. Useful for scaling down large images. | | maxWidth | Number | null | Maximum width in pixels. | | maxHeight | Number | null | Maximum height in pixels. | | blackAndWhite | Boolean | false | Converts the image to grayscale. | | mirror | Boolean | false | Flips the image horizontally. | | upToDown | Boolean | false | Flips the image vertically. | | invert | Boolean | false | Inverts image colors. | | brightness | Number | 1 | Brightness multiplier (0.1 – 5). 1 = original. | | contrast | Number | 1 | Contrast multiplier (0.1 – 5). 1 = original. |

Read image.jpg with preset config

(async () => {
  const result = await db.readImage("image.jpg", {
    returnBase64: true,
    quality: 0.8,
    pixels: 500000,
    blackAndWhite: false,
    mirror: false,
    upToDown: false,
    invert: false,
    brightness: 1,
    contrast: 1
  });

  console.log(result)
})()
{
  success: true,
  data: "data:image/jpeg;base64,/9j/4AAQSk...",
  metadata: {
    filename: "image.jpg",
    extension: ".jpg",
    originalSize: 254399,
    processingApplied: {
      resized: true,
      qualityReduced: true,
      blackAndWhite: true,
      mirrored: true,
      flippedVertical: false,
      inverted: false,
      brightnessAdjusted: true,
      contrastAdjusted: true
    }
  }
}

💡 Features

  • BSON Native: Optimized for binary serialization. No JSON overhead.
  • Secure Backups: Full-file XOR encoding for binary backups.
  • B-Tree Indexing: O(log n) lookups for primary and secondary keys.
  • Unique Constraints: Prevent data duplication at the database level.
  • Atomic Renames: Crash-safe file writes using temporary staging.
  • Auto-Compaction: Automatic reclamation of deleted record space.
  • Atomic Operators: Support for $inc, $set, $push, $pull, and $unset for safe concurrent updates.
  • System Timestamps: Automatic _createdAt and _modifiedAt management.

📈 Changelog

v1.0.0 (EveloDB Prime)

  • Feature: Added $pull atomic operator for removing items from arrays by value or condition.

v1.0.0-beta.9 (EveloDB Prime)

  • Created agents.md for AI agents and automated tools.

v1.0.0-beta.7 (EveloDB Prime)

  • Performance: Completely overhauled imageProcess with a new high-performance architecture.
  • Performance: Introduced a 200MB Zero-Decode LRU Cache for instant image processing hits.
  • Performance: Reduced AVIF CPU usage with built-in concurrency limiting and effort tuning.
  • Performance: Replaced mozjpeg with standard libjpeg for 3-5x faster JPEG encoding.

v1.0.0-beta.6 (EveloDB Prime)

  • Feature: Added Atomic Update Operators ($inc, $set, $unset, $push) for thread-safe field modifications.
  • Feature: Added db.atomic() and db.transaction() for asynchronous collection-level and global locking.
  • Bug Fix: Resolved a race condition where parallel async API calls could result in stale data reads/writes.
  • Bug Fix: Fixed a mutation issue in $push that caused double-updates during schema validation.

v1.0.0-beta.0 (EveloDB Prime)

  • Breaking: Fully modularized backup system into BackupManager.
  • Breaking: Updated restoreBackup to use single file path instead of directory/filename.
  • Feature: Added Secure Binary Backups with full-file XOR encoding.
  • Feature: Added readBackupFile for safe inspection of encrypted backups.
  • Feature: Switched to 24-character Hex ObjectIDs for better indexing compatibility.
  • Feature: Added Secondary B-Tree Indexes and Unique Key support.
  • Feature: Added objectIdKey to schema for virtual renaming of the _id field in API calls.
  • Performance: Optimized B-Tree insertion and search speeds.