From 6a37a773ea6f10dcd09c28f292c11e2e078ddf8a Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 3 Feb 2026 08:14:58 +0000 Subject: [PATCH] feat(docs): add LocalTsmDb documentation and examples; update README code samples and imports; correct examples and variable names; update package author --- changelog.md | 9 ++ package.json | 2 +- readme.md | 222 ++++++++++++++++++++++++++++----------- ts/00_commitinfo_data.ts | 2 +- 4 files changed, 170 insertions(+), 65 deletions(-) diff --git a/changelog.md b/changelog.md index 703b2a3..6c0f44a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,14 @@ # Changelog +## 2026-02-03 - 4.3.0 - feat(docs) +add LocalTsmDb documentation and examples; update README code samples and imports; correct examples and variable names; update package author + +- Introduce LocalTsmDb: zero-config local database with automatic persistence, auto port discovery, and pre-connected client (added Quick Start, API, Features, and testing examples). +- Expand comparison table to include LocalTsmDb alongside SmartMongo and TsmDB. +- Update README examples: new LocalTsmDb usage, reorder options (LocalTsmDb, TsmDB, SmartMongo), rename test DB variable (db -> testDb), and adjust test snippets for Jest/Mocha and tap. +- Adjust code snippets and API notes: switch some example imports to use tsmdb, replace FileStorageAdapter references, change planner.createPlan to await planner.plan, and use wal.getEntriesAfter(...) without awaiting. +- Update package.json author from 'Lossless GmbH' to 'Task Venture Capital GmbH'. + ## 2026-02-03 - 4.2.1 - fix(package.json) replace main and typings with exports field pointing to ./dist_ts/index.js diff --git a/package.json b/package.json index fb37e72..0f75fab 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ ".": "./dist_ts/index.js" }, "type": "module", - "author": "Lossless GmbH", + "author": "Task Venture Capital GmbH", "license": "MIT", "scripts": { "test": "(tstest test/. --verbose --logfile --timeout 60)", diff --git a/readme.md b/readme.md index 171861e..b8e6968 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # @push.rocks/smartmongo -A powerful MongoDB toolkit for testing and development โ€” featuring both a real MongoDB memory server (**SmartMongo**) and an ultra-fast, lightweight wire-protocol-compatible in-memory database server (**TsmDB**). ๐Ÿš€ +A powerful MongoDB toolkit for testing and development โ€” featuring a real MongoDB memory server (**SmartMongo**), an ultra-fast wire-protocol-compatible in-memory database server (**TsmDB**), and a zero-config local database (**LocalTsmDb**). ๐Ÿš€ ## Install @@ -16,21 +16,79 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community ## Overview -`@push.rocks/smartmongo` provides two powerful approaches for MongoDB in testing and development: +`@push.rocks/smartmongo` provides three powerful approaches for MongoDB in testing and development: -| Feature | SmartMongo | TsmDB | -|---------|------------|---------| -| **Type** | Real MongoDB (memory server) | Pure TypeScript wire protocol server | -| **Speed** | ~2-5s startup | โšก Instant startup (~5ms) | -| **Compatibility** | 100% MongoDB | MongoDB driver compatible | -| **Dependencies** | Downloads MongoDB binary | Zero external dependencies | -| **Replication** | โœ… Full replica set support | Single node emulation | -| **Use Case** | Integration testing | Unit testing, CI/CD | -| **Persistence** | Dump to directory | Optional file/memory persistence | +| Feature | SmartMongo | TsmDB | LocalTsmDb | +|---------|------------|-------|------------| +| **Type** | Real MongoDB (memory server) | Wire protocol server | Zero-config local DB | +| **Speed** | ~2-5s startup | โšก Instant (~5ms) | โšก Instant + auto-connect | +| **Compatibility** | 100% MongoDB | MongoDB driver compatible | MongoDB driver compatible | +| **Dependencies** | Downloads MongoDB binary | Zero external deps | Zero external deps | +| **Replication** | โœ… Full replica set | Single node | Single node | +| **Persistence** | Dump to directory | Memory or file | File-based (automatic) | +| **Use Case** | Integration testing | Unit testing, CI/CD | Quick prototyping, local dev | ## ๐Ÿš€ Quick Start -### Option 1: SmartMongo (Real MongoDB) +### Option 1: LocalTsmDb (Zero-Config Local Database) โญ NEW + +The easiest way to get started โ€” just point it at a folder and you have a persistent MongoDB-compatible database with automatic port discovery! + +```typescript +import { LocalTsmDb } from '@push.rocks/smartmongo'; + +// Create a local database backed by files +const db = new LocalTsmDb({ folderPath: './my-data' }); + +// Start and get a connected MongoDB client +const client = await db.start(); + +// Use exactly like MongoDB +const users = client.db('myapp').collection('users'); +await users.insertOne({ name: 'Alice', email: 'alice@example.com' }); + +const user = await users.findOne({ name: 'Alice' }); +console.log(user); // { _id: ObjectId(...), name: 'Alice', email: 'alice@example.com' } + +// Data persists to disk automatically! +await db.stop(); + +// Later... data is still there +const db2 = new LocalTsmDb({ folderPath: './my-data' }); +const client2 = await db2.start(); +const savedUser = await client2.db('myapp').collection('users').findOne({ name: 'Alice' }); +// savedUser exists! +``` + +### Option 2: TsmDB (Wire Protocol Server) + +A lightweight, pure TypeScript MongoDB-compatible server โ€” use the official `mongodb` driver directly! + +```typescript +import { tsmdb } from '@push.rocks/smartmongo'; +import { MongoClient } from 'mongodb'; + +// Start TsmDB server +const server = new tsmdb.TsmdbServer({ port: 27017 }); +await server.start(); + +// Connect with the official MongoDB driver +const client = new MongoClient('mongodb://127.0.0.1:27017'); +await client.connect(); + +// Use exactly like real MongoDB +const db = client.db('myapp'); +await db.collection('users').insertOne({ name: 'Alice', age: 30 }); + +const user = await db.collection('users').findOne({ name: 'Alice' }); +console.log(user); // { _id: ObjectId(...), name: 'Alice', age: 30 } + +// Clean up +await client.close(); +await server.stop(); +``` + +### Option 3: SmartMongo (Real MongoDB) Spin up a real MongoDB replica set in memory โ€” perfect for integration tests that need full MongoDB compatibility. @@ -51,34 +109,42 @@ console.log(descriptor.mongoDbUrl); // mongodb://127.0.0.1:xxxxx/... await mongo.stop(); ``` -### Option 2: TsmDB (Wire Protocol Server) +## ๐Ÿ“– LocalTsmDb API -A lightweight, pure TypeScript MongoDB-compatible server that speaks the wire protocol โ€” use the official `mongodb` driver directly! +The simplest option for local development and prototyping โ€” zero config, auto port discovery, and automatic persistence. + +### Basic Usage ```typescript -import { tsmdb } from '@push.rocks/smartmongo'; -import { MongoClient } from 'mongodb'; +import { LocalTsmDb } from '@push.rocks/smartmongo'; -// Start TsmDB server -const server = new tsmdb.TsmdbServer({ port: 27017 }); -await server.start(); +const db = new LocalTsmDb({ + folderPath: './data', // Required: where to store data + port: 27017, // Optional: defaults to auto-discovery + host: '127.0.0.1', // Optional: bind address +}); -// Connect with the official MongoDB driver! -const client = new MongoClient('mongodb://127.0.0.1:27017'); -await client.connect(); +// Start and get connected client +const client = await db.start(); -// Use exactly like real MongoDB -const db = client.db('myapp'); -await db.collection('users').insertOne({ name: 'Alice', age: 30 }); +// Access the underlying server if needed +const server = db.getServer(); +const uri = db.getConnectionUri(); -const user = await db.collection('users').findOne({ name: 'Alice' }); -console.log(user); // { _id: ObjectId(...), name: 'Alice', age: 30 } +// Check status +console.log(db.running); // true -// Clean up -await client.close(); -await server.stop(); +// Stop when done +await db.stop(); ``` +### Features + +- ๐Ÿ” **Auto Port Discovery** โ€” Automatically finds an available port if 27017 is in use +- ๐Ÿ’พ **Automatic Persistence** โ€” Data saved to files, survives restarts +- ๐Ÿ”Œ **Pre-connected Client** โ€” `start()` returns a ready-to-use MongoDB client +- ๐ŸŽฏ **Zero Config** โ€” Just specify a folder path and you're good to go + ## ๐Ÿ“– SmartMongo API ### Creating an Instance @@ -293,11 +359,11 @@ const server = new tsmdb.TsmdbServer({ }); // File-based - persistent storage with optional checksums -import { FileStorageAdapter } from '@push.rocks/smartmongo/tsmdb'; +import { tsmdb } from '@push.rocks/smartmongo'; -const adapter = new FileStorageAdapter('./data/tsmdb', { - enableChecksums: true, // CRC32 checksums for data integrity - strictChecksums: false // Log warnings vs throw on mismatch +const server = new tsmdb.TsmdbServer({ + storage: 'file', + storagePath: './data/tsmdb' }); ``` @@ -331,14 +397,14 @@ import { tsmdb } from '@push.rocks/smartmongo'; // For debugging, you can access the query planner const planner = new tsmdb.QueryPlanner(indexEngine); -const plan = planner.createPlan(filter); +const plan = await planner.plan(filter); console.log(plan); // { // type: 'IXSCAN', // or 'IXSCAN_RANGE', 'COLLSCAN' // indexName: 'email_1', -// estimatedCost: 1, -// selectivity: 0.001 +// selectivity: 0.01, +// indexCovering: true // } ``` @@ -357,10 +423,10 @@ await wal.initialize(); // - Timestamp // - Operation type (insert, update, delete, checkpoint) // - Document data (BSON serialized) -// - CRC32 checksum +// - CRC32 checksum for integrity // Recovery support -const entries = await wal.getEntriesAfter(lastCheckpointLsn); +const entries = wal.getEntriesAfter(lastCheckpointLsn); ``` ### ๐Ÿ” Session Management @@ -393,15 +459,10 @@ try { File-based storage supports CRC32 checksums to detect corruption: ```typescript -import { FileStorageAdapter } from '@push.rocks/smartmongo/tsmdb'; - -const adapter = new FileStorageAdapter('./data', { - enableChecksums: true, - strictChecksums: true // Throw error on corruption (vs warning) -}); +import { tsmdb } from '@push.rocks/smartmongo'; +// Checksums are used internally for WAL and data integrity // Documents are checksummed on write, verified on read -// Checksums are automatically stripped before returning to client ``` ### ๐Ÿ“‹ Supported Wire Protocol Commands @@ -420,6 +481,38 @@ TsmDB supports MongoDB wire protocol versions 0-21, compatible with MongoDB 3.6 ## ๐Ÿงช Testing Examples +### Jest/Mocha with LocalTsmDb + +```typescript +import { LocalTsmDb } from '@push.rocks/smartmongo'; +import { MongoClient, Db } from 'mongodb'; + +let db: LocalTsmDb; +let client: MongoClient; + +beforeAll(async () => { + db = new LocalTsmDb({ folderPath: './test-data' }); + client = await db.start(); +}); + +afterAll(async () => { + await db.stop(); +}); + +beforeEach(async () => { + // Clean slate for each test + await client.db('test').dropDatabase(); +}); + +test('should insert and find user', async () => { + const users = client.db('test').collection('users'); + await users.insertOne({ name: 'Alice', email: 'alice@example.com' }); + + const user = await users.findOne({ name: 'Alice' }); + expect(user?.email).toBe('alice@example.com'); +}); +``` + ### Jest/Mocha with TsmDB ```typescript @@ -428,7 +521,7 @@ import { MongoClient, Db } from 'mongodb'; let server: tsmdb.TsmdbServer; let client: MongoClient; -let db: Db; +let testDb: Db; beforeAll(async () => { server = new tsmdb.TsmdbServer({ port: 27117 }); @@ -436,7 +529,7 @@ beforeAll(async () => { client = new MongoClient('mongodb://127.0.0.1:27117'); await client.connect(); - db = client.db('test'); + testDb = client.db('test'); }); afterAll(async () => { @@ -445,12 +538,11 @@ afterAll(async () => { }); beforeEach(async () => { - // Clean slate for each test - await db.dropDatabase(); + await testDb.dropDatabase(); }); test('should insert and find user', async () => { - const users = db.collection('users'); + const users = testDb.collection('users'); await users.insertOne({ name: 'Alice', email: 'alice@example.com' }); const user = await users.findOne({ name: 'Alice' }); @@ -462,22 +554,18 @@ test('should insert and find user', async () => { ```typescript import { expect, tap } from '@git.zone/tstest/tapbundle'; -import { tsmdb } from '@push.rocks/smartmongo'; -import { MongoClient } from 'mongodb'; +import { LocalTsmDb } from '@push.rocks/smartmongo'; -let server: tsmdb.TsmdbServer; -let client: MongoClient; +let db: LocalTsmDb; tap.test('setup', async () => { - server = new tsmdb.TsmdbServer({ port: 27117 }); - await server.start(); - client = new MongoClient('mongodb://127.0.0.1:27117'); - await client.connect(); + db = new LocalTsmDb({ folderPath: './test-data' }); + await db.start(); }); tap.test('should perform CRUD operations', async () => { - const db = client.db('test'); - const col = db.collection('items'); + const client = db.getClient(); + const col = client.db('test').collection('items'); // Create const result = await col.insertOne({ name: 'Widget', price: 9.99 }); @@ -499,8 +587,7 @@ tap.test('should perform CRUD operations', async () => { }); tap.test('teardown', async () => { - await client.close(); - await server.stop(); + await db.stop(); }); export default tap.start(); @@ -508,6 +595,15 @@ export default tap.start(); ## ๐Ÿ—๏ธ Architecture +### Module Structure + +``` +@push.rocks/smartmongo +โ”œโ”€โ”€ SmartMongo โ†’ Real MongoDB memory server (mongodb-memory-server wrapper) +โ”œโ”€โ”€ tsmdb โ†’ Wire protocol server with full engine stack +โ””โ”€โ”€ LocalTsmDb โ†’ Zero-config local database (convenience wrapper) +``` + ### TsmDB Wire Protocol Stack ``` diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index d4a163f..e75ddde 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartmongo', - version: '4.2.1', + version: '4.3.0', description: 'A module for creating and managing a local MongoDB instance for testing purposes.' }