synz-db
v1.2.0
Published
A lightweight JSON-based database with Mongoose-like schema and model API
Maintainers
Readme
Synz-DB
A lightweight, file-based JSON database with a Mongoose-like schema and model API for Node.js applications.
Features
- 🚀 Mongoose-like API - Familiar schema and model syntax
- 📁 File-based storage - No external database required
- ✅ Schema validation - Type checking, required fields, custom validators
- 🔄 Data transformation - Automatic trimming, case conversion, type coercion
- 🏃 Performance - Built-in caching and indexing
- 🔒 Concurrency safe - File locking prevents data corruption
- 📝 TypeScript ready - Full TypeScript support (coming soon)
Installation
npm install synz-dbQuick Start
const { Schema, model } = require('synz-db');
// Define a schema
const userSchema = new Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
unique: true,
lowercase: true
},
age: {
type: Number,
min: 0
}
}, {
timestamps: true // Adds createdAt and updatedAt
});
// Create a model
const User = model('User', userSchema);
// Use the model
async function example() {
// Create a user
const user = await User.create({
name: ' John Doe ', // Will be trimmed
email: '[email protected]', // Will be lowercased
age: 25
});
// Find users
const users = await User.find({ age: { $gte: 18 } });
// Update user
user.age = 26;
await user.save();
}API Reference
Schema
Create a new schema to define the structure and validation rules for your data.
const { Schema } = require('synz-db');
const schema = new Schema({
fieldName: {
type: String, // String, Number, Boolean, Date, Array, Object
required: true, // Field is required
default: 'value', // Default value (can be a function)
trim: true, // Trim whitespace (String only)
lowercase: true, // Convert to lowercase (String only)
uppercase: true, // Convert to uppercase (String only)
minlength: 5, // Minimum length (String/Array)
maxlength: 100, // Maximum length (String/Array)
min: 0, // Minimum value (Number)
max: 100, // Maximum value (Number)
enum: ['a', 'b'], // Allowed values
match: /pattern/, // Regex pattern (String only)
validate: function(value) {
// Custom validator
return value !== 'invalid';
}
}
}, {
timestamps: true // Automatically add createdAt/updatedAt
});Schema Methods
virtual(name, getter)- Add virtual propertiespre(method, fn)- Add pre-middlewarepost(method, fn)- Add post-middleware
// Virtual property
schema.virtual('fullName', function() {
return `${this.firstName} ${this.lastName}`;
});
// Pre-save middleware
schema.pre('save', function() {
this.slug = this.title.toLowerCase().replace(/\s+/g, '-');
});
// Post-save middleware
schema.post('save', function() {
console.log('Document saved:', this.id);
});Model
Models are created from schemas and provide the interface for interacting with your data.
const User = model('User', userSchema);Static Methods
create(data)- Create and save a new documentfind(query)- Find documents matching the queryfindOne(query)- Find one document matching the queryfindById(id)- Find document by IDfindByIdAndUpdate(id, update)- Find by ID and updatefindByIdAndDelete(id)- Find by ID and deleteupdateMany(query, update)- Update multiple documentsdeleteMany(query)- Delete multiple documentscountDocuments(query)- Count matching documentsexists(query)- Check if documents existinsertMany(docs)- Insert multiple documentscreateIndex(field)- Create an index for faster queries
Instance Methods
save()- Save the documentremove()- Remove the documenttoObject()- Convert to plain objecttoJSON()- Convert to JSON
Database Connection
const { connect } = require('synz-db');
// Connect to a specific directory (default: './data')
connect('./my-database');Query Examples
// Find all users
const users = await User.find();
// Find with conditions
const adults = await User.find({ age: { $gte: 18 } });
// Find one user
const user = await User.findOne({ email: '[email protected]' });
// Find by ID
const user = await User.findById('user-id-123');
// Update user
const user = await User.findById('user-id-123');
user.age = 26;
await user.save();
// Or update directly
await User.findByIdAndUpdate('user-id-123', { age: 26 });
// Delete user
await User.findByIdAndDelete('user-id-123');
// Count documents
const count = await User.countDocuments({ isActive: true });
// Check existence
const exists = await User.exists({ email: '[email protected]' });Validation
Synz-DB provides comprehensive validation similar to Mongoose:
const userSchema = new Schema({
email: {
type: String,
required: true,
match: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
validate: {
validator: function(email) {
return !email.includes('spam');
},
message: 'Email cannot contain spam'
}
},
age: {
type: Number,
min: [0, 'Age cannot be negative'],
max: [120, 'Age seems unrealistic']
},
role: {
type: String,
enum: {
values: ['user', 'admin', 'moderator'],
message: '{VALUE} is not a valid role'
}
}
});Performance
Indexing
Create indexes on frequently queried fields for better performance:
// Create an index
await User.createIndex('email');
// The index will speed up queries like:
const user = await User.findOne({ email: '[email protected]' });Caching
Synz-DB automatically caches collections in memory with a default timeout of 30 seconds. You can clear the cache manually:
const { JsonDB } = require('synz-db');
const db = new JsonDB();
// Clear cache for specific collection
db.clearCache('users');
// Clear all cache
db.clearCache();
// Get cache statistics
const stats = db.getCacheStats();
console.log(stats); // { size: 2, collections: ['users', 'posts'], memory: 1024 }File Structure
By default, Synz-DB stores data in JSON files:
./data/
├── users.json
├── posts.json
└── comments.jsonEach collection is stored as a separate JSON file with automatic atomic writes to prevent corruption.
Error Handling
try {
await User.create({ name: 'John' }); // Missing required email
} catch (error) {
console.error('Validation failed:', error.message);
// "Validation failed: Field 'email' is required"
}TypeScript Support
Full TypeScript definitions are coming soon! For now, you can use basic typing:
interface IUser {
name: string;
email: string;
age?: number;
}
const User = model<IUser>('User', userSchema);Migration from Mongoose
Synz-DB uses a similar API to Mongoose, making migration straightforward:
// Before (Mongoose)
const mongoose = require('mongoose');
const User = mongoose.model('User', userSchema);
// After (Synz-DB)
const { model } = require('synz-db');
const User = model('User', userSchema);
// Most operations remain the same!Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see the LICENSE file for details.
Changelog
v1.0.0
- Initial release
- Mongoose-like schema and model API
- File-based JSON storage
- Validation and transformation
- Caching and indexing
- Concurrency safety
