Repository navigation
2.8.0
Added
feat: Added withTransaction to the main Mongo instance. This wrapper simplifies ACID-compliant operations by automatically handling session creation, committing, and aborting (rollback) on errors.
const db = new Mongo({ ... });
const accounts = db.query('accounts');
try {
// Automatically handles commit/rollback based on promise resolution/rejection
await db.withTransaction(async (session) => {
// Step 1: Deduct from Alice
const debit = await accounts.updateOne(
{ name: 'Alice', balance: { $gte: 50 } },
{ $inc: { balance: -50 } },
{ session } // ⚠️ Important: Pass session to every operation
);
if (!debit) throw new Error('Alice has insufficient funds');
// Step 2: Add to Bob
const credit = await accounts.updateOne(
{ name: 'Bob' },
{ $inc: { balance: 50 } },
{ session }
);
if (!credit) throw new Error('Bob not found');
});
} catch (err) {
console.error('Transaction aborted, no data changed:', err);
}- feat: Added
exists(filter)to theQueryclass. This is a high-performance utility that internally applieslimit: 1to check for document existence without the overhead of fetching the document or counting all matches.
const UserQuery = db.query<UserDocument>('users');
// Efficiently check if an email is taken
if (await UserQuery.exists({ email: 'jane@example.com' })) {
throw new Error('Email already in use');
}- feat: Added
distinct(key, filter)to theQueryclass. Allows for retrieving unique values for a specific field across a collection, with optional filtering.
const ProductQuery = db.query<ProductDocument>('products');
// Get all unique categories for active products
const categories = await ProductQuery.distinct('category', { isActive: true });
console.log(categories); // ['Electronics', 'Clothing', 'Home']Improved
- feat:
createIndexnow supports specialized index types beyond standard ascending/descending. You can now use string literals for Text, Hashed, and Geospatial indexes. Supported types: 1 | -1 | 'text' | 'hashed' | '2dsphere' | '2d' | 'geoHaystack'
// Text Index (for search)
await db.createIndex('products', 'text_search_idx',
{ title: 'text', description: 'text' },
{ weights: { title: 10, description: 1 } }
);
// Geospatial Index (for location queries)
await db.createIndex('restaurants', 'geo_location_idx', {
coordinates: '2dsphere'
});
// Partial Filtered Index
await db.createIndex('users', 'email_unique_idx',
{ email: 1 },
{ unique: true, partialFilterExpression: { email: { $exists: true } } }
);- deps: Upgrade @types/node to 24.10.4
- deps: Upgrade @valkyriestudios/utils to 12.48.0
- deps: Upgrade @valkyriestudios/validator to 10.11.0
- deps: Upgrade @vitest/coverage-v8 to 4.0.16
- deps: Upgrade eslint to 9.39.2
- deps: Upgrade mongodb to 6.21.0
- deps: Upgrade typescript to 5.9.3
- deps: Upgrade typescript-eslint to 8.51.0
- deps: Upgrade vitest to 4.0.16