stormflow
v1.1.9
Published
StormFlow is a versatile Node.js data management library designed for efficient data management.
Maintainers
Readme
Stormflow
A lightweight, flexible data modeling and storage library for Node.js applications. Stormflow enables you to define data schemas, manage collections, and perform CRUD operations easily, without the overhead of a full database system.
Key Features
- Schema Definition: Strict or flexible schemas for data consistency.
- Data Collections: Full CRUD support for collections.
- Middleware: Pre- and post-operation hooks for custom logic.
- Query Engine: Advanced queries with comparison and logical operators.
- File Persistence: Data is persisted to disk with optional backups.
- References: Seamless handling of document references.
- Universal Compatibility: Works with CommonJS, ES modules, and TypeScript.
Installation
Install via npm or yarn:
npm install stormflow
# or
yarn add stormflowGetting Started
Initialization
import db from 'stormflow';
await db.start({
strict: false, // Enforce strict schema validation
defaultFields: true, // Auto add _created/_updated timestamps
verbose: false, // Verbose logging
});Defining Schemas and Models
const userSchema = db.Schema({
name: { type: 'string', required: true },
email: { type: 'string', required: true, unique: true },
age: { type: 'number', default: 0 },
friends: [{ type: 'string', $ref: 'user' }],
});
const User = db.model('users', userSchema);CRUD Operations
const newUser = await User.insertOne({ name: 'John Doe', email: '[email protected]', age: 30 });
const adults = await User.find({ age: { $gte: 18 } });
const updatedUser = await User.findByIdAndUpdate(newUser._id, { age: 31 });
await User.findByIdAndDelete(newUser._id);Model Methods
| Method | Description |
| ------------------------------------- | ---------------------------------------------- |
| insertOne(item) | Insert a single document. |
| insertMany(items) | Insert multiple documents. |
| find(query) | Find all documents matching the query. |
| findById(id) | Find a document by its unique ID. |
| findOne(query) | Find the first document matching the query. |
| findByIdAndReplace(id, replacement) | Replace a document by ID. |
| findByIdAndUpdate(id, updates) | Update fields of a document by ID. |
| findByIdAndDelete(id) | Delete a document by its ID. |
| updateOne(query, updates) | Update one document matching the query. |
| updateMany(query, updates) | Update multiple documents matching the query. |
| replaceOne(query, replacement) | Replace one document matching the query. |
| replaceMany(query, replacement) | Replace multiple documents matching the query. |
| deleteOne(query) | Delete one document matching the query. |
| deleteMany(query) | Delete multiple documents matching the query. |
| count(query) | Count documents matching the query. |
| exists(query) | Check if at least one document matches. |
| pre(method, fn) | Register middleware before the given action. |
| post(method, fn) | Register middleware after the given action. |
Middleware
Register middleware for operations (wildcard * is supported only for method):
User.pre('*', async (doc) => {
// Before any operation
});
User.post('update', async (doc) => {
// After updating user
});Supported methods: 'create' | 'read' | 'update' | 'replace' | 'delete' | '*'.
Querying
Stormflow supports rich queries with comparison and logical operators.
Comparison Operators
| Operator | Description |
| -------- | -------------------------- |
| $eq | Equal |
| $ne | Not equal |
| $lt | Less than |
| $lte | Less than or equal |
| $gt | Greater than |
| $gte | Greater than or equal |
| $in | Value in array |
| $nin | Value not in array |
| $regex | Matches regular expression |
Logical Operators
| Operator | Description |
| -------- | ----------- |
| $and | Logical AND |
| $or | Logical OR |
| $not | Logical NOT |
| $nor | Logical NOR |
Example Query
const result = await User.find({
$or: [{ age: { $lt: 20 } }, { age: { $gt: 60 } }],
});Storage Adapters
Stormflow uses a pluggable storage adapter system. The default file-based storage is implemented via a storage adapter, but you can provide your own adapter for custom persistence.
File Storage Adapter
The file storage adapter persists collections in a specified directory. You can configure the location and behavior via options.
Example usage:
import fileStorageAdapter from 'stormflow/adapters/fileStorageAdapter';
const adapter = fileStorageAdapter({
dataFolder: './data', // default: './data'
throttle: 100, // ms, default: 100
verbose: false, // logging
});File Backup Adapter
For automatic backups, use the file backup adapter:
import fileBackupAdapter from 'stormflow/adapters/fileBackupAdapter';
const backup = fileBackupAdapter({
backupFolder: './data/backup', // default
backupInterval: 60, // minutes
maxBackups: 5, // how many to keep
verbose: false,
});See the
src/storage/fileStorageAdapter.d.tsandfileBackupAdapter.d.tsfor full API details.
Example: Using file-based storage and backup adapter
import db from 'stormflow';
import fileStorageAdapter from 'stormflow/adapters/fileStorageAdapter';
import fileBackupAdapter from 'stormflow/adapters/fileBackupAdapter';
const storage = fileStorageAdapter({
dataFolder: './data',
throttle: 100,
verbose: false,
});
const backup = fileBackupAdapter({
backupFolder: './data/backup',
backupInterval: 60,
maxBackups: 5,
verbose: false,
});
await db.start({}, storage, backup);API Reference
start(options?: Options, storageAdapter?: any, backupAdapter?: any): Promise<void>— Start Stormflow with configuration.setConfig(options: Options): void— Update configuration at runtime.getConfig(): Options— Get current configuration.Schema(definition: SchemaDefinition): SchemaDefinition— Create a schema.model(name: string, schema?: SchemaDefinition): StormflowModel— Create or get a model.
Guidelines
See Code of Conduct, Contributing, and Security Policy.
License
MIT License © 2022–2024 Zsolt Tövis
If you find this project useful, please consider sponsoring me on GitHub, PayPal, or give the repo a star.
