1.0.7 • Published 10 months ago

@sinkingsheep/jsondb v1.0.7

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

JsonDB

A powerful, MongoDB-like JSON database for Node.js with TypeScript support. JsonDB provides rich querying capabilities, transactions, indexing, and more, while maintaining data in simple JSON files.

Features

  • 💪 Strong TypeScript support
  • 🔍 Rich query API (MongoDB-like operators)
  • 📑 Multiple collection support
  • 🔄 Transaction support with rollback
  • 📇 Indexing with unique and sparse options
  • 🔗 Collection joins
  • ✅ Schema validation
  • 💾 Automatic saving
  • 🎯 Event system
  • ⛓️ Chain syntax for queries

Installation

npm install @sinkingsheep/jsondb
# or
yarn add @sinkingsheep/jsondb

Quick Start

import JsonDB from '@sinkingsheep/jsondb';

interface User {
  id?: string;
  name: string;
  age: number;
  email: string;
}

async function main() {
  // Initialize database
  const db = new JsonDB({ 
    directory: './data',
    autoSave: true,
    saveInterval: 1000
  });
  await db.init();

  // Insert a document
  const user = await db.insert<User>('users', {
    name: 'John Doe',
    age: 30,
    email: 'john@example.com'
  });

  // Query documents
  const users = await db.find('users', {
    age: { $gt: 25 }
  });

  // Close database
  await db.close();
}

Database Operations

Initialization

interface DBOptions {
  directory: string;
  autoSave?: boolean;
  saveInterval?: number;
  prettyPrint?: boolean;
}

const db = new JsonDB({
  directory: './data',
  autoSave: true,
  saveInterval: 1000,
  prettyPrint: true
});
await db.init();

Basic CRUD Operations

Insert

// Single insert
const user = await db.insert<User>('users', {
  name: 'John',
  age: 30
});

// Bulk insert
const users = await db.insertMany<User>('users', [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 }
]);

Find

// Find all matching documents
const users = await db.find('users', {
  age: { $gt: 25 }
});

// Find one document
const user = await db.findOne('users', {
  name: 'John'
});

// Chain syntax
const results = await db
  .chain('users')
  .where({ status: 'active' })
  .sort({ age: -1 })
  .limit(10)
  .find();

Update

// Update multiple documents
const updateCount = await db.update('users', 
  { status: 'inactive' },
  { status: 'active' }
);

// Update single document
const updated = await db.updateOne('users',
  { id: 'user123' },
  { status: 'active' }
);

Delete

const deleteCount = await db.delete('users', {
  status: 'inactive'
});

Query Operators

Comparison Operators

// Equal to
{ age: { $eq: 30 } }

// Greater than
{ age: { $gt: 25 } }

// Less than or equal to
{ age: { $lte: 40 } }

// In array
{ status: { $in: ['active', 'pending'] } }

// Not in array
{ status: { $nin: ['deleted', 'banned'] } }

Logical Operators

// AND
{
  $and: [
    { status: 'active' },
    { age: { $gt: 25 } }
  ]
}

// OR
{
  $or: [
    { status: 'admin' },
    { role: 'moderator' }
  ]
}

// NOT
{
  status: { $not: { $eq: 'inactive' } }
}

Array Operators

// Array contains all elements
{ scores: { $all: [80, 85] } }

// Array size
{ scores: { $size: 3 } }

// Element match
{ scores: { $elemMatch: { $gte: 90 } } }

Indexing

// Create unique index
await db.createIndex('users', 'email', { unique: true });

// Create sparse index
await db.createIndex('users', 'optional_field', { sparse: true });

Transactions

// Begin transaction
const transactionId = await db.beginTransaction();

try {
  await db.insert('accounts', { id: '1', balance: 100 });
  await db.update('accounts', { id: '1' }, { balance: 50 });
  await db.commitTransaction(transactionId);
} catch (error) {
  await db.rollbackTransaction(transactionId);
  throw error;
}

Joins

const results = await db.findWithJoin('orders', 
  { status: 'pending' },
  {
    joins: [{
      collection: 'users',
      localField: 'userId',
      foreignField: 'id',
      as: 'user'
    }]
  }
);

Schema Validation

const userSchema = defineSchema({
  name: 'string',
  age: 'number',
  email: 'string'
});

const isValid = validateDocument(userSchema, document);

Events

db.on('save', (collectionName) => {
  console.log(`Collection ${collectionName} was saved`);
});

db.on('update', (collectionName, document) => {
  console.log(`Document updated in ${collectionName}`);
});

db.on('delete', (collectionName, documentId) => {
  console.log(`Document ${documentId} deleted from ${collectionName}`);
});

Chain Syntax

JsonDB provides a fluent chain syntax for building queries:

const results = await db
  .chain('users')
  .where({ status: 'active' })
  .sort({ age: -1 })
  .skip(10)
  .limit(5)
  .find();

const user = await db
  .chain('users')
  .where({ age: { $gt: 30 } })
  .findOne();

Performance Considerations

  • Collections are loaded lazily on first access
  • Each collection is stored in a separate file
  • Indexes improve query performance for indexed fields
  • Auto-save interval is configurable
  • In-memory caching of loaded collections

Error Handling

try {
  await db.insert('users', { email: 'duplicate@email.com' });
} catch (error) {
  if (error.message.includes('Unique constraint violation')) {
    // Handle unique constraint violation
  }
  throw error;
}

TypeScript Support

JsonDB is written in TypeScript and provides full type support:

interface User {
  id?: string;
  name: string;
  age: number;
  email: string;
}

const user = await db.insert<User>('users', {
  name: 'John',
  age: 30,
  email: 'john@example.com'
});

Best Practices

  1. Collection Management

    • Use separate collections for different types of data
    • Consider collection joins for related data
    • Drop unused collections to free up resources
  2. Indexing

    • Create indexes for frequently queried fields
    • Use sparse indexes for optional fields
    • Be mindful of index overhead for write operations
  3. Transactions

    • Use transactions for operations that need to be atomic
    • Always handle transaction errors and rollbacks
    • Keep transactions as short as possible
  4. Performance

    • Use specific queries instead of loading all documents
    • Implement pagination for large result sets
    • Configure auto-save interval based on your needs

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT

Credits

Created and maintained by sinkingsheep

1.0.7

10 months ago

1.0.6

10 months ago

1.0.5

10 months ago

1.0.4

10 months ago

1.0.2

10 months ago

1.0.1

10 months ago

1.0.0

10 months ago