2025-08-12 11:25:42 +00:00
# @push.rocks/smartdata 🚀
2025-02-03 14:03:03 +01:00
[](https://www.npmjs.com/package/@push .rocks/smartdata)
2026-03-24 19:51:52 +00:00
**The ultimate TypeScript-first MongoDB ODM** — type-safe decorators, real-time change streams, Lucene-powered search, distributed leader election, and cursor streaming. Built for modern applications that demand performance, correctness, and developer experience.
2025-02-03 14:03:03 +01:00
2026-03-24 19:51:52 +00:00
## Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/ ](https://community.foss.global/ ). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/ ](https://code.foss.global/ ) account to submit Pull Requests directly.
2025-02-03 14:03:03 +01:00
2026-03-24 19:51:52 +00:00
## 🌟 Why SmartData?
2025-02-03 14:03:03 +01:00
2026-03-24 19:51:52 +00:00
- 🔒 **100% Type-Safe ** — TC39 Stage 3 decorators, generic filters, and compile-time query validation
- ⚡ **High Performance ** — Connection pooling, cursor streaming, and automatic indexing
- 🔄 **Real-time Ready ** — MongoDB Change Streams with RxJS for reactive applications
- 🌍 **Distributed Systems ** — Built-in leader election and task coordination via `@push.rocks/taskbuffer`
- 🛡️ **Security First ** — `$where` injection prevention, operator allow-listing, and input sanitization
- 🔎 **Lucene Search ** — Full-text, wildcard, boolean, and range queries out of the box
- 🎯 **Great DX ** — Intuitive API, IntelliSense that just works, and lifecycle hooks
2025-02-03 14:03:03 +01:00
2025-08-12 11:25:42 +00:00
## 📦 Installation
2020-06-11 23:05:45 +00:00
2024-04-14 04:00:56 +02:00
```bash
2025-03-10 23:55:44 +00:00
pnpm add @push .rocks/smartdata
```
2020-06-11 23:05:45 +00:00
2025-08-12 11:25:42 +00:00
## 🚦 Requirements
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
- **Node.js** >= 20.x
- **Deno** >= 2.0 (for Deno projects)
- **MongoDB** >= 5.0
2025-11-17 12:51:45 +00:00
- **TypeScript** >= 5.2 (for TC39 decorator support)
2026-03-24 19:51:52 +00:00
> **Note**: SmartData uses TC39 Stage 3 decorators (the standard). Make sure `experimentalDecorators` is **not** set in your tsconfig.json. Bun is not currently supported as it doesn't implement TC39 decorators yet.
2020-06-11 23:05:45 +00:00
2025-08-12 11:25:42 +00:00
## 🎯 Quick Start
2025-04-06 18:18:39 +00:00
2025-08-12 11:25:42 +00:00
### 1️ ⃣ Connect to Your Database
2020-06-11 23:05:45 +00:00
```typescript
2024-04-14 04:00:56 +02:00
import { SmartdataDb } from '@push .rocks/smartdata';
const db = new SmartdataDb({
2025-08-12 11:25:42 +00:00
mongoDbUrl: 'mongodb://localhost:27017/myapp',
mongoDbName: 'myapp',
mongoDbUser: 'username',
mongoDbPass: 'password',
2020-06-11 23:05:45 +00:00
});
2024-04-14 04:00:56 +02:00
await db.init();
2026-03-24 19:51:52 +00:00
console.log(db.status); // 'connected'
2020-06-11 23:05:45 +00:00
```
2025-08-12 11:25:42 +00:00
### 2️ ⃣ Define Your Data Models
2020-06-11 23:05:45 +00:00
```typescript
2025-04-06 18:18:39 +00:00
import {
SmartDataDbDoc,
Collection,
unI,
svDb,
index,
searchable,
} from '@push .rocks/smartdata';
2024-04-14 04:00:56 +02:00
2025-08-12 11:25:42 +00:00
@Collection (() => db)
2024-04-14 04:00:56 +02:00
class User extends SmartDataDbDoc<User, User> {
@unI ()
2026-03-24 19:51:52 +00:00
public id!: string;
2025-11-17 12:51:45 +00:00
2024-04-14 04:00:56 +02:00
@svDb ()
2025-08-12 11:25:42 +00:00
@searchable ()
2026-03-24 19:51:52 +00:00
public username!: string;
2025-11-17 12:51:45 +00:00
2025-03-10 23:55:44 +00:00
@svDb ()
2026-03-24 19:51:52 +00:00
@searchable ()
@index ({ unique: false })
public email!: string;
2025-11-17 12:51:45 +00:00
2025-08-18 11:50:37 +00:00
@svDb ()
2026-03-24 19:51:52 +00:00
public status!: 'active' | 'inactive' | 'pending';
2025-11-17 12:51:45 +00:00
2025-08-18 11:50:37 +00:00
@svDb ()
2026-03-24 19:51:52 +00:00
public tags!: string[];
2025-11-17 12:51:45 +00:00
2025-08-12 11:25:42 +00:00
@svDb ()
public createdAt: Date = new Date();
2025-11-17 12:51:45 +00:00
2024-04-14 04:00:56 +02:00
constructor(username: string, email: string) {
super();
this.username = username;
this.email = email;
2020-06-11 23:05:45 +00:00
}
}
2024-04-14 04:00:56 +02:00
```
2020-06-11 23:05:45 +00:00
2026-03-24 19:51:52 +00:00
### 3️ ⃣ CRUD Operations
2025-04-06 18:18:39 +00:00
2024-04-14 04:00:56 +02:00
```typescript
2025-08-12 11:25:42 +00:00
// ✨ Create
const user = new User('johndoe', 'john@example .com');
2025-08-18 11:50:37 +00:00
user.status = 'active';
user.tags = ['developer', 'typescript'];
2025-08-12 11:25:42 +00:00
await user.save();
2020-06-11 23:05:45 +00:00
2026-03-24 19:51:52 +00:00
// 🔍 Read — fully type-safe filters
2025-08-12 11:25:42 +00:00
const foundUser = await User.getInstance({ username: 'johndoe' });
2025-08-18 11:50:37 +00:00
const activeUsers = await User.getInstances({ status: 'active' });
2020-06-11 23:05:45 +00:00
2025-08-12 11:25:42 +00:00
// ✏️ Update
foundUser.email = 'newemail@example .com';
await foundUser.save();
2025-03-10 23:55:44 +00:00
2025-08-12 11:25:42 +00:00
// 🗑️ Delete
await foundUser.delete();
2024-04-14 04:00:56 +02:00
```
2020-06-11 23:05:45 +00:00
2026-03-24 19:51:52 +00:00
## 🔥 Features
feat: Add comprehensive query filters guide and enhance type safety for MongoDB queries
- Introduced a detailed guide on query filters in the README, covering basic filtering, comparison operators, array operators, logical operators, element operators, and advanced filtering patterns.
- Implemented a type-safe filtering system in `classes.doc.ts` with `MongoFilterCondition` and `MongoFilter` types to support MongoDB operators while maintaining nested type safety.
- Enhanced error handling for invalid operators and conditions in the filtering logic.
- Added extensive tests for various filtering scenarios, including basic, comparison, array, logical, and complex filters, ensuring robust functionality and performance.
- Implemented security measures to prevent the use of dangerous operators like `$where` and validate operator usage.
2025-08-18 11:29:15 +00:00
2025-08-18 11:50:37 +00:00
### 🎯 Type-Safe Query Filters
feat: Add comprehensive query filters guide and enhance type safety for MongoDB queries
- Introduced a detailed guide on query filters in the README, covering basic filtering, comparison operators, array operators, logical operators, element operators, and advanced filtering patterns.
- Implemented a type-safe filtering system in `classes.doc.ts` with `MongoFilterCondition` and `MongoFilter` types to support MongoDB operators while maintaining nested type safety.
- Enhanced error handling for invalid operators and conditions in the filtering logic.
- Added extensive tests for various filtering scenarios, including basic, comparison, array, logical, and complex filters, ensuring robust functionality and performance.
- Implemented security measures to prevent the use of dangerous operators like `$where` and validate operator usage.
2025-08-18 11:29:15 +00:00
2026-03-24 19:51:52 +00:00
SmartData provides a rich, type-safe filtering system supporting all MongoDB operators with full IntelliSense:
2025-08-18 20:24:16 +00:00
feat: Add comprehensive query filters guide and enhance type safety for MongoDB queries
- Introduced a detailed guide on query filters in the README, covering basic filtering, comparison operators, array operators, logical operators, element operators, and advanced filtering patterns.
- Implemented a type-safe filtering system in `classes.doc.ts` with `MongoFilterCondition` and `MongoFilter` types to support MongoDB operators while maintaining nested type safety.
- Enhanced error handling for invalid operators and conditions in the filtering logic.
- Added extensive tests for various filtering scenarios, including basic, comparison, array, logical, and complex filters, ensuring robust functionality and performance.
- Implemented security measures to prevent the use of dangerous operators like `$where` and validate operator usage.
2025-08-18 11:29:15 +00:00
```typescript
2026-03-24 19:51:52 +00:00
// Comparison operators
2025-08-18 11:50:37 +00:00
const adults = await User.getInstances({
2026-03-24 19:51:52 +00:00
age: { $gte: 18, $lt: 65 },
2025-08-18 20:24:16 +00:00
});
2026-03-24 19:51:52 +00:00
// Array operators
2025-08-18 11:50:37 +00:00
const experts = await User.getInstances({
2026-03-24 19:51:52 +00:00
tags: { $all: ['typescript', 'mongodb'] },
skills: { $size: 5 },
feat: Add comprehensive query filters guide and enhance type safety for MongoDB queries
- Introduced a detailed guide on query filters in the README, covering basic filtering, comparison operators, array operators, logical operators, element operators, and advanced filtering patterns.
- Implemented a type-safe filtering system in `classes.doc.ts` with `MongoFilterCondition` and `MongoFilter` types to support MongoDB operators while maintaining nested type safety.
- Enhanced error handling for invalid operators and conditions in the filtering logic.
- Added extensive tests for various filtering scenarios, including basic, comparison, array, logical, and complex filters, ensuring robust functionality and performance.
- Implemented security measures to prevent the use of dangerous operators like `$where` and validate operator usage.
2025-08-18 11:29:15 +00:00
});
2026-03-24 19:51:52 +00:00
// Logical operators
2025-08-18 20:24:16 +00:00
const complex = await Order.getInstances({
$and: [
{ status: 'active' },
2026-03-24 19:51:52 +00:00
{ $or: [{ priority: 'high' }, { value: { $gte: 1000 } }] },
2026-03-24 19:44:49 +00:00
],
2025-08-18 20:24:16 +00:00
});
2026-03-24 19:51:52 +00:00
// Deep nested object queries
const users = await User.getInstances({
profile: {
settings: {
notifications: { email: true },
},
},
2025-08-18 20:24:16 +00:00
});
2026-03-24 19:51:52 +00:00
// Dot notation
const sameUsers = await User.getInstances({
'profile.settings.notifications.email': true,
2025-08-18 20:24:16 +00:00
});
// Regex patterns
const gmailUsers = await User.getInstances({
2026-03-24 19:44:49 +00:00
email: { $regex: '@gmail \\.com$', $options: 'i' },
2025-08-18 20:24:16 +00:00
});
```
2026-03-24 19:51:52 +00:00
**Security**: The `$where` operator is automatically blocked to prevent NoSQL injection. Unknown operators trigger warnings.
2025-08-18 20:24:16 +00:00
2026-03-24 19:51:52 +00:00
### 🔎 Lucene-Powered Search
2025-08-18 20:24:16 +00:00
2026-03-24 19:51:52 +00:00
Mark fields with `@searchable()` to enable a built-in search engine with automatic compound text indexing:
2025-04-06 18:18:39 +00:00
2024-04-14 04:00:56 +02:00
```typescript
2025-04-06 18:14:46 +00:00
@Collection (() => db)
class Product extends SmartDataDbDoc<Product, Product> {
2026-03-24 19:51:52 +00:00
@unI () public id!: string;
@svDb () @searchable () public name!: string;
@svDb () @searchable () public description!: string;
@svDb () @searchable () public category!: string;
@svDb () public price!: number;
2025-04-21 15:27:55 +00:00
}
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
// Simple text search across all @searchable fields
2025-08-18 11:50:37 +00:00
const results = await Product.search('laptop');
2025-04-06 18:14:46 +00:00
2025-08-18 11:50:37 +00:00
// Field-specific search
const electronics = await Product.search('category:Electronics');
2025-04-06 18:14:46 +00:00
2026-03-24 19:51:52 +00:00
// Wildcard
2025-08-18 11:50:37 +00:00
const matches = await Product.search('Mac*');
2025-04-06 18:14:46 +00:00
2026-03-24 19:51:52 +00:00
// Boolean operators (AND, OR, NOT)
2025-08-18 11:50:37 +00:00
const query = await Product.search('laptop AND NOT gaming');
2025-04-06 18:14:46 +00:00
2025-08-18 11:50:37 +00:00
// Phrase search
2026-03-24 19:51:52 +00:00
const exact = await Product.search('"MacBook Pro"');
// Range queries
const midRange = await Product.search('price:[100 TO 500]');
2025-04-06 18:14:46 +00:00
2026-03-24 19:51:52 +00:00
// Combined with MongoDB filters and post-fetch validation
2025-08-18 11:50:37 +00:00
const affordable = await Product.search('laptop', {
filter: { price: { $lte: 1500 } },
2026-03-24 19:51:52 +00:00
validate: async (p) => p.price > 0,
2025-08-12 11:25:42 +00:00
});
2025-04-06 18:14:46 +00:00
```
2025-08-18 11:50:37 +00:00
### 📡 Real-Time Change Streams
2026-03-24 19:51:52 +00:00
Watch for database changes with RxJS subjects and EventEmitter support:
2025-08-18 11:50:37 +00:00
```typescript
const watcher = await User.watch(
2026-03-24 19:51:52 +00:00
{ status: 'active' },
2025-11-17 12:51:45 +00:00
{
2026-03-24 19:51:52 +00:00
fullDocument: 'updateLookup',
bufferTimeMs: 100, // optional: buffer changes via RxJS
2026-03-24 19:44:49 +00:00
},
2025-08-18 11:50:37 +00:00
);
2026-03-24 19:51:52 +00:00
// RxJS subscription
watcher.changeSubject.subscribe((user) => {
console.log('User changed:', user);
2025-08-18 11:50:37 +00:00
});
2026-03-24 19:51:52 +00:00
// Or EventEmitter style
watcher.on('change', (user) => {
console.log('User changed:', user);
2025-08-18 11:50:37 +00:00
});
2025-03-10 23:55:44 +00:00
2026-03-24 19:51:52 +00:00
// Clean up
await watcher.close();
2025-02-03 14:03:03 +01:00
```
2026-03-24 19:51:52 +00:00
### 🔄 Cursor Streaming
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
Process large datasets without memory pressure:
2025-03-10 23:55:44 +00:00
```typescript
2025-08-12 11:25:42 +00:00
const cursor = await User.getCursor(
2025-08-18 11:50:37 +00:00
{ status: 'active' },
{
2026-03-24 19:51:52 +00:00
modifier: (c) => c.sort({ createdAt: -1 }).limit(10000),
2026-03-24 19:44:49 +00:00
},
2025-08-12 11:25:42 +00:00
);
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
// Iterate one-by-one
2025-08-12 11:25:42 +00:00
await cursor.forEach(async (user) => {
2026-03-24 19:51:52 +00:00
await processUser(user);
2025-08-12 11:25:42 +00:00
});
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
// Or collect into an array
const users = await cursor.toArray();
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
// Always close when done
2025-08-12 11:25:42 +00:00
await cursor.close();
2025-03-10 23:55:44 +00:00
```
2026-03-24 19:51:52 +00:00
### 🔐 Transactions
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
Ensure atomic consistency across multiple operations:
2025-03-10 23:55:44 +00:00
```typescript
2025-04-23 17:28:49 +00:00
const session = db.startSession();
2025-08-12 11:25:42 +00:00
2025-03-10 23:55:44 +00:00
try {
await session.withTransaction(async () => {
2026-03-24 19:51:52 +00:00
const sender = await User.getInstance({ id: 'user-1' }, { session });
2025-08-12 11:25:42 +00:00
sender.balance -= 100;
await sender.save({ session });
2025-11-17 12:51:45 +00:00
2026-03-24 19:44:49 +00:00
const receiver = await User.getInstance({ id: 'user-2' }, { session });
2025-08-12 11:25:42 +00:00
receiver.balance += 100;
await receiver.save({ session });
2025-03-10 23:55:44 +00:00
});
} finally {
await session.endSession();
}
```
2026-03-24 19:51:52 +00:00
### 💾 EasyStore — Type-Safe Key-Value Storage
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
Built on top of SmartData collections, EasyStore provides simple key-value persistence:
2025-03-10 23:55:44 +00:00
```typescript
2026-03-24 19:51:52 +00:00
interface AppConfig {
apiKey: string;
features: { darkMode: boolean; notifications: boolean };
limits: { maxUsers: number };
}
2025-11-17 12:51:45 +00:00
2026-03-24 19:51:52 +00:00
const config = await db.createEasyStore<AppConfig>('app-config');
// Write
await config.writeKey('features', { darkMode: true, notifications: false });
// Read
const features = await config.readKey('features');
// TypeScript knows: features.darkMode is boolean ✅
// Read all
const all = await config.readAll();
// Write multiple keys
await config.writeAll({ apiKey: 'new-key', limits: { maxUsers: 500 } });
// Delete a key
await config.deleteKey('features');
// Wipe the store
await config.wipe();
```
### 🌐 Distributed Coordination
Built-in leader election using MongoDB for coordination, integrating with `@push.rocks/taskbuffer` :
```typescript
import { SmartdataDistributedCoordinator } from '@push .rocks/smartdata';
const coordinator = new SmartdataDistributedCoordinator(db);
// Start coordination — automatic heartbeat and leader election
await coordinator.start();
2025-11-17 12:51:45 +00:00
2026-03-24 19:51:52 +00:00
// Fire distributed task requests
const result = await coordinator.fireDistributedTaskRequest({
submitterId: 'instance-1',
requestResponseId: 'unique-id',
taskName: 'process-payments',
taskVersion: '1.0.0',
taskExecutionTime: Date.now(),
taskExecutionTimeout: 30000,
taskExecutionParallel: 1,
status: 'requesting',
});
// Graceful shutdown with leadership handoff
await coordinator.stop();
```
### 🎨 Custom Serialization
Transform data on its way in and out of MongoDB:
```typescript
@Collection (() => db)
class Doc extends SmartDataDbDoc<Doc, Doc> {
2025-08-12 11:25:42 +00:00
@svDb ({
serialize: (set) => Array.from(set),
2026-03-24 19:44:49 +00:00
deserialize: (arr) => new Set(arr),
2025-08-12 11:25:42 +00:00
})
2026-03-24 19:51:52 +00:00
public tags!: Set<string>;
2025-11-17 12:51:45 +00:00
2025-08-18 11:50:37 +00:00
@svDb ({
serialize: (date) => date?.toISOString(),
2026-03-24 19:44:49 +00:00
deserialize: (str) => (str ? new Date(str) : null),
2025-08-18 11:50:37 +00:00
})
2026-03-24 19:51:52 +00:00
public scheduledAt!: Date | null;
2025-03-10 23:55:44 +00:00
}
```
2025-08-12 11:25:42 +00:00
### 🎣 Lifecycle Hooks
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
Add custom logic before and after save/delete:
2025-03-10 23:55:44 +00:00
```typescript
@Collection (() => db)
class Order extends SmartDataDbDoc<Order, Order> {
2026-03-24 19:51:52 +00:00
@unI () public id!: string;
@svDb () public items!: Array<{ product: string; quantity: number; price: number }>;
@svDb () public totalAmount!: number;
2025-11-17 12:51:45 +00:00
2025-03-10 23:55:44 +00:00
async beforeSave() {
2026-03-24 19:51:52 +00:00
this.totalAmount = this.items.reduce((s, i) => s + i.price * i.quantity, 0);
2025-03-10 23:55:44 +00:00
}
2025-11-17 12:51:45 +00:00
2025-03-10 23:55:44 +00:00
async afterSave() {
2025-08-18 11:50:37 +00:00
await notificationService.orderUpdated(this.id);
2025-03-10 23:55:44 +00:00
}
2025-11-17 12:51:45 +00:00
2025-03-10 23:55:44 +00:00
async beforeDelete() {
2026-03-24 19:51:52 +00:00
if (this.totalAmount > 0) throw new Error('Cannot delete non-zero orders');
2025-03-10 23:55:44 +00:00
}
2025-11-17 12:51:45 +00:00
2025-04-23 17:28:49 +00:00
async afterDelete() {
2025-08-18 11:50:37 +00:00
await cache.delete(`order:${this.id}` );
2025-04-23 17:28:49 +00:00
}
2025-03-10 23:55:44 +00:00
}
```
2026-03-24 19:51:52 +00:00
### 🏗️ Indexing
2025-04-06 18:18:39 +00:00
2025-08-12 11:25:42 +00:00
```typescript
@Collection (() => db)
2026-03-24 19:51:52 +00:00
class HighPerformanceDoc extends SmartDataDbDoc<HighPerformanceDoc, HighPerformanceDoc> {
@unI ()
public id!: string; // Unique index
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
@index ()
public userId!: string; // Regular index
2025-03-10 23:55:44 +00:00
2026-03-24 19:51:52 +00:00
@index ({ sparse: true })
public deletedAt?: Date; // Sparse index — only indexes docs where field exists
2025-04-06 18:18:39 +00:00
2026-03-24 19:51:52 +00:00
@index ({ expireAfterSeconds: 86400 })
public sessionToken!: string; // TTL index — auto-expires after 24h
2025-08-18 11:50:37 +00:00
}
2025-08-12 11:25:42 +00:00
```
2020-06-11 23:05:45 +00:00
2026-03-24 19:51:52 +00:00
### 🔧 Connection Options
2025-08-18 11:50:37 +00:00
2025-08-12 11:25:42 +00:00
```typescript
2025-08-18 11:50:37 +00:00
const db = new SmartdataDb({
mongoDbUrl: 'mongodb://localhost:27017',
mongoDbName: 'myapp',
2026-03-24 19:51:52 +00:00
mongoDbUser: 'admin',
mongoDbPass: 's3cret',
2025-08-12 11:25:42 +00:00
2026-03-24 19:51:52 +00:00
// Connection pool tuning (all optional)
maxPoolSize: 100, // Max connections (default: 100)
maxIdleTimeMS: 300000, // Close idle connections after 5min (default)
serverSelectionTimeoutMS: 30000, // Timeout for server selection
socketTimeoutMS: 30000, // Socket timeout to prevent hung operations
2025-08-18 11:50:37 +00:00
});
```
2026-03-24 19:51:52 +00:00
## 📚 Decorators Reference
2025-08-18 11:50:37 +00:00
2026-03-24 19:51:52 +00:00
| Decorator | Target | Description |
|-----------|--------|-------------|
| `@Collection(dbGetter)` | Class | Binds a document class to a MongoDB collection |
| `@managed(managerGetter?)` | Class | Like `@Collection` but controlled by a manager instance |
| `@unI()` | Field | Marks as unique index + saveable |
| `@svDb(options?)` | Field | Marks field as saveable, with optional `serialize` /`deserialize` |
| `@index(options?)` | Field | Creates a regular MongoDB index |
| `@searchable()` | Field | Enables Lucene-style text search on this field |
| `@globalSvDb()` | Field | Marks field as globally saveable across all doc types |
2025-08-18 11:50:37 +00:00
## 📚 API Reference
### Core Classes
2026-03-24 19:51:52 +00:00
| Class | Description |
|-------|-------------|
| `SmartdataDb` | Database connection, session management, EasyStore factory |
| `SmartDataDbDoc<T, TImpl>` | Base class for all document models |
| `SmartdataCollection<T>` | Underlying collection manager (usually accessed indirectly) |
| `SmartdataDbCursor<T>` | Cursor for streaming large result sets |
| `SmartdataDbWatcher<T>` | Change stream watcher with RxJS + EventEmitter |
| `SmartdataDistributedCoordinator` | Leader election and distributed task coordination |
| `EasyStore<T>` | Type-safe key-value store backed by a collection |
### Key Static Methods on `SmartDataDbDoc`
| Method | Description |
|--------|-------------|
| `getInstances(filter, opts?)` | Find multiple documents |
| `getInstance(filter, opts?)` | Find a single document (or `null` ) |
| `getCursor(filter, opts?)` | Get a streaming cursor |
| `getCount(filter?)` | Count matching documents |
| `watch(filter, opts?)` | Watch for real-time changes |
| `search(query, opts?)` | Lucene-style full-text search |
| `forEach(filter, fn)` | Iterate all matches with a callback |
| `getNewId(length?)` | Generate a class-prefixed unique ID |
| `createSearchFilter(luceneQuery)` | Convert Lucene query to MongoDB filter |
| `getSearchableFields()` | List all `@searchable()` fields |
### Key Instance Methods on `SmartDataDbDoc`
| Method | Description |
|--------|-------------|
| `save(opts?)` | Insert or update the document |
| `delete(opts?)` | Delete the document |
| `updateFromDb()` | Refresh fields from the database |
| `saveDeep(savedMap?)` | Recursively save referenced documents |
| `createSavableObject()` | Serialize to a plain object for persistence |
| `createIdentifiableObject()` | Extract unique index fields for filtering |
2020-06-11 23:05:45 +00:00
2024-04-14 04:00:56 +02:00
## License and Legal Information
2020-06-11 23:05:45 +00:00
2026-03-24 19:51:52 +00:00
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE ](./license ) file.
2020-06-11 23:05:45 +00:00
2024-04-14 04:00:56 +02:00
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
2020-06-11 23:05:45 +00:00
2024-04-14 04:00:56 +02:00
### Trademarks
2020-06-11 23:05:45 +00:00
2026-03-24 19:51:52 +00:00
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
2020-06-11 23:05:45 +00:00
2024-04-14 04:00:56 +02:00
### Company Information
2020-06-12 05:59:07 +00:00
2025-11-17 12:51:45 +00:00
Task Venture Capital GmbH
2026-03-24 19:51:52 +00:00
Registered at District Court Bremen HRB 35230 HB, Germany
2020-06-12 05:59:07 +00:00
2026-03-24 19:51:52 +00:00
For any legal inquiries or further information, please contact us via email at hello@task .vc.
2020-06-11 23:05:45 +00:00
2025-11-17 12:51:45 +00:00
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.