hbh-dbms
v0.0.4
Published
A lightweight Node.js DBMS that manages content, user files, and JSON-based data.
Downloads
126
Maintainers
Readme
📦 HBH-DBMS
Overview
HBH-DBMS is a scalable, chunk-based, file-oriented DBMS for Node.js, designed to handle large datasets with safe traversal, deterministic paths, and zero external database dependency. HBH-DBMS is not just a DB layer — it is a complete filesystem database ecosystem designed for massive scale, clean hierarchy, and predictable storage. A lightweight, file-based DBMS for Node.js that manages JSON data, user files, content, channels, and configurations without requiring a traditional database (MySQL, MongoDB, etc).
hbh-dbmsis designed for backend developers who want simple, structured, and scalable file-based storage with modular services. File-Based Database Management System for Node.js HBH-DBMS is a hierarchical, file-based DBMS designed for Node.js applications where you want: It is a structured, chunk-oriented, traversal-safe DBMS designed to scale to very large datasets without filesystem collapse. HBH-DBMS is a modern, large-scale, file-based Database Management System for Node.js, built for developers who want:
- ❌ No MongoDB / MySQL
- ✅ Predictable filesystem storage
- ✅ Predictable file structure
- ✅ Massive scale support
- ✅ Chunk-based directory distribution
- ✅ Lazy folder creation
- ✅ Deterministic paths
- ✅ Clean testing & scripting usage
- ✅ Human-readable JSON storage
- ✅ Full CRUD with hierarchy
- ✅ Easy testing & debugging
⚡ This is NOT a native JSON-file database. HBH-DBMS is engineered for real-world scale.
It is especially useful for:
- CMS systems
- SaaS backends
- Content platforms
- Admin panels
- Rapid prototyping
✨ Features
- 📁 JSON-based database (no external DB required)
- 🧩 Modular & class-based architecture
- 📂 User File Management (UFM)
- 🧠 Content, Channel & Product handling
- ⚙️ Config & Infinite File Management
- 🔍 Advanced content searching & filtering
- 🧹 Safe delete & cleanup utilities
- 🚀 ESM-first (
type: module) - 🪶 Lightweight & fast
🧠 Core Philosophy
HBH-DBMS follows a strict hierarchy:
User
└── Product
└── Channel
└── ContentEach layer:
- Is owned by its parent
- Lives inside its parent directory
- Cannot exist independently
- Is managed by a dedicated DB class
This guarantees:
- 🔒 Data integrity
- 🧹 Clean deletes
- ♻️ Easy recovery
🔥 Key Design Principles (IMPORTANT)
1️⃣ Lazy Folder Creation (Very Important)
❌ User folder is NOT created immediately
Instead:
User identity is validated
Path is resolved
Folder is created only when required
Prevents:
- Empty folders
- Garbage structure
- Orphaned users
📌 This is why HBH-DBMS scales better than native file DBs.
2️⃣ Chunk-Based Storage (Large Scale Ready)
To avoid filesystem limits (10k+ folders problem), HBH-DBMS:
- Splits data into chunks
- Uses multi-level nesting
- Distributes load evenly
Example:
Users/
└── Ae/
└── [email protected]/📌 This prevents:
- Slow directory reads
- OS inode pressure
- FS traversal slowdown
3️⃣ Deterministic Path Resolution
Every entity path is:
- Derived from its ID
- Deterministic
- Rebuildable at any time
Meaning:
- No central index dependency
- No corruption cascade
- Easy recovery
4️⃣ Strict Hierarchical Ownership
User
└── Product
└── Channel
└── ContentRules:
- ❌ Product cannot exist without User
- ❌ Channel cannot exist without Product
- ❌ Content cannot exist without Channel
This guarantees:
- Data integrity
- Clean deletes
- No orphan files
📂 Real Folder Structure (Abstracted & Safe)
(No personal names, no test identifiers)
db/
├── users/
│ ├── U0/
│ │ ├── <user-id>/
│ │ │ ├── data.json
│ │ │ ├── products/
│ │ │ │ ├── <product-id>/
│ │ │ │ │ ├── data.json
│ │ │ │ │ ├── channels/
│ │ │ │ │ │ ├── <channel-id>/
│ │ │ │ │ │ │ ├── content.json
│ │ │ │ │ │ │ └── <content-type>/📌 Chunk folders are auto-calculated 📌 This allows millions of records without FS degradation
🧩 Modular Internal Design
Each DB class handles only its responsibility:
| Module | Responsibility |
| ----------- | --------------------------- |
| BaseDB | Safe FS + JSON ops |
| UserDB | User resolution & traversal |
| ProductDB | Product ownership |
| ChannelDB | Channel capacity & limits |
| ContentDB | Content chunking |
| Handle_ID | ID normalization |
| DeleteAll | Controlled cleanup |
No module:
- Assumes another module
- Hardcodes paths
- Breaks isolation
🛡️ Safe Traversal Strategy
Every operation follows this flow:
- Validate input
- Resolve deterministic path
- Traverse hierarchy safely
- Create folder only if needed
- Write JSON atomically
📌 No blind mkdir -p
📌 No unsafe recursion
📌 No overwriting without intent
🚀 Large-Scale Readiness Summary
HBH-DBMS supports:
✅ Millions of users ✅ Millions of contents ✅ Parallel directory growth ✅ Predictable performance ✅ OS-safe FS traversal
Because:
- Chunking ✔
- Lazy creation ✔
- Deterministic paths ✔
- Strict hierarchy ✔
📥 Installation
npm install hbh-dbms🧠 Basic Concept
Instead of using a traditional database, HBH-DBMS stores data as structured JSON files, organized by:
- Users
- Products
- Channels
- Content
- Configurations
- Uploaded files
This makes it:
- Easy to debug
- Easy to migrate
- Easy to back up
📌 Package Entry
import { DBMS, libs } from 'hbh-dbms';📂 Library Structure
hbh-dbms
├── db/
│ ├── BaseDB.js
│ ├── UserDB.js
│ ├── ProductDB.js
│ ├── ChannelDB.js
│ ├── ContentDB.js
│ ├── UFM.js
│ ├── ConfigManager.js
│ ├── InfFileManager.js
│ ├── DeleteAll.js
│ ├── Handle_ID.js
│ └── ContentFinder/
├── libs/
│ ├── FSHelper.js
│ ├── EmptyDIRRemover.js
│ └── .Helper.js
└── index.js🧱 DBMS Module
import { DBMS } from 'hbh-dbms';⚠️ DBMS is NOT a constructor
It is a namespace that exposes multiple DB classes.
🧱 Available DB Classes
DBMS.BaseDB
DBMS.UserDB
DBMS.ProductDB
DBMS.ChannelDB
DBMS.ContentDB
DBMS.BaseDB
DBMS.UserFileManagerHBH-DBMS is designed to be used directly, just like this:
const userDB = new DBMS.UserDB();
const productDB = new DBMS.ProductDB();
const channelDB = new DBMS.ChannelDB();
const contentDB = new DBMS.ContentDB();This is the recommended and documented approach.
🧱 BaseDB (Internal Engine)
const base = new DBMS.BaseDB("custom/path");Handles:
- Atomic JSON read/write
- Directory integrity
- Traversal protection
- Directory safety
- Atomic updates
⚠️ Normally used internally by all DB modules, but exposed for advanced users.
👤 UserDB
Manage user-related data.
Manages users as root entities.
const userDB = new DBMS.UserDB();➕ Create User
await userDB.create(
"[email protected]",
{
email: "[email protected]",
Info: {
Author: "Alice",
password: "12345678"
}
}
);📌 What happens internally:
- User directory created
Users/Ae/[email protected]/ data.jsonwritten- Duplicate IDs prevented
📄 Read User
const user = await userDB.read("[email protected]");✏️ Rename User (Update ID)
await userDB.update(
"[email protected]",
"[email protected]"
);✔ Renames folder ✔ Keeps all nested data intact
✏️ Update User Info
await userDB.updateInfo(
"[email protected]",
{
id2: 123456,
password: "1234@Alice"
}
);✔ Merges data ❌ Does not overwrite existing keys
❌ Delete User
await userDB.delete("[email protected]");Deletes:
- User
- Products
- Channels
- Content
- Files
📃 List Users
const users = await userDB.list();📦 ProductDB
const productDB = new DBMS.ProductDB('[email protected]');Products are owned by users.
➕ Create Product
await productDB.create("Product1");📁 Path created:
/Users/Ae/[email protected]/Product1/📄 Read Product
await productDB.read("Product1");✏️ Rename Product
await productDB.update("Product1","Product2");❌ Delete Product
await productDB.delete("Product2");📃 List Products
await productDB.list();📺 ChannelDB
Channels live inside products. Channels can contain content, posts, or media.
const channelDB = new DBMS.ChannelDB('[email protected]', 'Product1');
channelDB.Limit = 2;📌 Limit controls max channels inside product db.
➕ Create Channel
await channelDB.create("Channel1");
📁 Path created:
/Users/Ae/[email protected]/Product1/Channel1📄 Read Channel
await channelDB.read("Channel1");✏️ Rename Channel
await channelDB.update("Channel1", "Channel2");✏️ Update Channel Info
await channelDB.updateInfo(
"Channel2",
{ author: "HashirAttari" }
);🔍 Find Channel
await channelDB.find("Channel1");📃 List Channels
await channelDB.list();❌ Delete Channel
await channelDB.delete("Channel2");📝 ContentDB
Used for all content, including blogs, posts, articles, and videos, in JSON format. Content exists inside channels.
const contentDB = new DBMS.ContentDB(channelDB, 'Channel1');
contentDB.Limit = 2;📌 Limit controls max content inside channel db.
➕ Create Content
const contentID = await contentDB.create(
type = "list" | 'tutorial',
contentName = "First-Content",
body = ["Hello", "User", "ALice"] | { Name: "Alice", message: 'Hello' }
);📁 Path created:
/Users/Ae/[email protected]/Product1/Channel1/${ContentType}/First-Content.json📄 Read Content
await contentDB.read(contentID);✏️ Update Content Body
await contentDB.updateContent(
contentID,
["Alice", "AliceDemo"]
);✏️ Update Content Info
await contentDB.updateInfo(
contentID,
{
tags: ["updated"],
author: "New Author"
}
);❌ Delete Content
await contentDB.delete(contentID);📃 List Content
await contentDB.list({type: 'list' | 'all'});🔍 Find Content
await contentDB.find(contentID);📂 UserFileManager
UserFileManager handles user file operations inside products, including uploads, downloads, renames, deletes, and recycle bin functionality.
const ufm = new DBMS.UserFileManager("[email protected]");📌 Works per user and integrates with UserDB and ProductDB.
📌 Files are isolated per product to maintain safety.
➕ Create / Upload File
await ufm.upload(req, "[email protected]", "Product1", "rename");Handles HTTP file uploads via
formidable.Supports collision modes:
'skip'→ skip if file exists'overwrite'→ replace existing'rename'→ auto-rename new file
Validates quota (
maxBytes) before saving.Stores files in:
/Users/Ae/[email protected]/Product1/<fileName>- Adds metadata and tracks usage in the product’s config.
📄 Read File
const content = await ufm.readFileContent("[email protected]", "Product1", "myfile.txt");- Returns text content only (binary files will throw an error).
✏️ Update File
await ufm.updateFileContent("[email protected]", "Product1", "myfile.txt", "Updated text");- Replaces file content.
- Validates text content.
- Updates usage tracking.
❌ Delete File
await ufm.deleteFile("[email protected]", "Product1", "myfile.txt");- Deletes a file.
- Updates usage accordingly.
📦 Delete All Files in Product
await ufm.deleteAllFiles("[email protected]", "Product1");- Deletes all files/folders inside a product.
- Skips .config folder.
- Resets usage in config.
🔀 Rename / Move File
await ufm.renameFile("[email protected]", "Product1", "old.txt", "new.txt");
await ufm.moveFile("[email protected]", "Product1", "old.txt", "folder/new.txt");- Moves or renames files safely inside product directories.
- Validates safe paths.
📂 Create Folder
await ufm.createFolder("[email protected]", "Product1", "newFolder");- Creates a directory inside a product.
🗑 Recycle Bin
- Move to Bin:
await ufm.BinFile("[email protected]", "Product1", "file.txt");- Recover File:
await ufm.RecoverFile("[email protected]", "Product1", "file.txt.hbhbin");- List Trash:
const trashFiles = await ufm.ListTrash("[email protected]", "Product1");- Empty Trash:
await ufm.EmptyTrash("[email protected]", "Product1");📃 List Files / Directories
await ufm.listFlat("[email protected]", "Product1"); // flat list
await ufm.listTree("[email protected]", "Product1"); // tree structure
await ufm.listDir("[email protected]", "Product1"); // directories only- Filters .config folders automatically.
- Returns full metadata for files in tree/flat listings.
📊 Usage Info
const { used, limit } = await ufm.usage("[email protected]", "Product1");used→ total bytes usedlimit→ maximum allowed bytes (defaultMAX_USER_STORAGE_BYTES)
⚙️ Product Management
await ufm.createProduct("Product1");
await ufm.deleteProduct("Product1");- Creates a product with initial config.
- Deletes product safely, including files.
📦 db Module
The db object is a lightweight helper layer that exposes HBH-DBMS core classes through a simple functional API.
📌 It does not implement new database logic 📌 It is a shortcut interface for existing DBMS modules 📌 Ideal for controllers, routes, CMS systems, and services
📌 Import
import { db } from 'hbh-dbms';🧱 Structure Overview
export const db = {
user,
product,
channel,
content,
listall,
findall,
cms
};👤 db.user()
Creates a new UserDB instance.
const userDB = db.user();🔹 Internally calls: new UserDB()
🔹 Used for user CRUD operations and listing
📦 db.product(user)
Creates a ProductDB instance scoped to a user.
const productDB = db.product('[email protected]');🔹 Internally calls: new ProductDB(user)
🔹 Products always belong to a user
📺 db.channel(user, product)
Creates a ChannelDB instance under a product.
const channelDB = db.channel('[email protected]', 'Product1');🔹 Internally calls: new ChannelDB(user, product)
🔹 Channels cannot exist without a product and user
📝 db.content(channelInstance, channelName)
Creates a ContentDB instance under a channel.
const contentDB = db.content(channelDB, 'Channel1');🔹 Internally calls: new ContentDB(channelInstance, channelName)
🔹 Used for posts, articles, tutorials, media, etc.
📃 db.listall 🔍 db.findall
The listall and findall modules provide high-level traversal utilities for HBH-DBMS.
They are designed to safely scan the entire filesystem hierarchy without breaking DBMS rules.
📌 These utilities do not bypass DBMS 📌 They reuse DBMS pagination & limits 📌 Built for CMS, admin panels, dashboards, and search systems
📃 listall
listall is used to list entities across hierarchy levels using safe pagination traversal.
db.listallAvailable Methods
listall.User
listall.Channel
listall.Content👤 listall.User(options)
Lists users using paginated traversal.
await listall.User({
userPage: 1,
userLimit: 10
});Parameters
| Name | Type | Description |
| ----------- | ------ | ------------------------------ |
| userPage | Number | Page number (example: 1) |
| userLimit | Number | Users per page (example: 10) |
Response
{
success: true,
message: "Users fetched",
data: [ "[email protected]", "[email protected]" ],
pagination: { userPage: 1, userLimit: 10 }
}Notes
- Internally uses
UserDB.list() - Safe for large datasets
- No eager filesystem traversal
📺 listall.Channel(options)
Lists channels across all users under a given product.
await listall.Channel({
productName: "HBH-CMS",
userPage: 1,
userLimit: 10,
channelPage: 1,
channelLimit: 10
});Parameters
| Name | Description |
| -------------- | ------------------------------------ |
| productName | Product scope (example: "HBH-CMS") |
| userPage | User pagination (example: 1) |
| userLimit | Users per page (example: 10) |
| channelPage | Channel pagination (example: 1) |
| channelLimit | Channels per page (example: 10) |
Response
{
success: true,
data: {
"[email protected]": ["Channel1", "Channel2"],
"[email protected]": ["News"]
}
}Notes
- Traverses User → Product → Channel
- Channel names are normalized
- Errors per user are safely skipped
📝 listall.Content(options)
Lists content across users, channels, and content types.
await listall.Content({
productName: "HBH-CMS",
userPage: 1,
userLimit: 10,
channelPage: 1,
channelLimit: 10,
contentPage: 1,
contentLimit: 20
});Response
{
success: true,
data: {
"content-id-1": { user: "[email protected]", channel: "Channel1" },
"content-id-2": { user: "[email protected]", channel: "News" }
}
}Notes
- Traverses entire DB hierarchy
- Content types are auto-detected
- Designed for CMS indexing
🔍 findall
findall provides deep search utilities to locate entities without knowing their exact path.
db.findallAvailable Methods
findall.User
findall.Channel
findall.Findchannel
findall.Content
findall.Findcontent👤 findall.User(username)
Finds a user by ID using paginated scanning.
await findall.User("[email protected]");Behavior
- Scans user pages sequentially
- Stops immediately when found
- Safe for very large datasets
📺 findall.Channel or findall.Findchannel (channelName, options)
Finds a channel across all users under a product. Uses ChannelManager for indexed channel lookup.
await findall.Channel("Channel1", {
productName: "HBH-CMS"
});Response
{
success: true,
data: {
user: "[email protected]",
channel: "Channel1"
}
}Notes
- Channel names are normalized
- Stops on first match
- Uses
listall.Channelinternally
📝 findall.Content or 🆔 findall.Findcontent (contentID, options)
Finds a content item anywhere in the DB. Uses IDManager for indexed content lookup.
await findall.Content("content-id-1", {
productName: "HBH-CMS"
});Behavior
Traverses:
User → Product → Channel → ContentAuto-advances pagination
Stops early on match
await findall.Findcontent("content-id-1", { productName: "HBH-CMS" });Notes
- Direct ID resolution
- No filesystem scanning
- Most efficient content lookup method
🎯 Design Philosophy
✔ No unsafe recursion ✔ Pagination-based traversal ✔ Early-exit search ✔ CMS & admin friendly ✔ Deterministic & recoverable
📌 listall = enumeration
📌 findall = discovery
🧠 db.cms – CMS Utilities
A collection of helpers designed for content-driven and CMS-based systems.
The cms module provides high-level CMS utilities for HBH-DBMS, focusing on content fetching, content lookup, and ID handling. It integrates multi-threaded scanning, pagination-safe traversal, and indexed lookup.
📌 Designed for CMS, dashboards, and large-scale content processing. 📌 Supports product-scoped content fetchers and ID-based direct content access. 📌 Optimized for multi-threaded content scanning using workers.
🖥️ fetchcontent (Product-Specific Content Fetchers)
fetchcontent provides asynchronous content fetching functions per product. Each function returns content in paginated chunks.
db.cms.fetchcontent.HBHCodes
db.cms.fetchcontent.HBHTube
db.cms.fetchcontent.CodeBuddyExample Usage
const fetchNext = db.cms.fetchcontent.HBHCodes;
// Fetch next batch of content
const contents = await fetchNext();
console.log(contents);Behavior
- Tracks internal pagination: userPage, channelPage, contentPage.
- Auto-advances pages when current batch is empty.
- Can resume from a given pagination index:
await fetchNext({ user: 2, channel: 1, content: 5 });- Designed for CMS batch processing with large datasets.
🔍 findcontent(targetID, { productName })
Finds content by ID using indexed IDManager lookup.
const content = await db.cms.findcontent('content-id-123', { productName: 'CodeBuddy' });Response
{
success: true,
data: {
user: "[email protected]",
channel: "Channel1",
content: { ... }
}
}Notes
- Uses
IDManagerfor efficient indexed resolution. - Returns
nullif content is not found. - Avoids filesystem-wide traversal when possible.
🔍 findchannel(targetChannel, { productName })
Finds channel info by name using ChannelManager.
const channel = await db.cms.findchannel('Channel1', { productName: 'CodeBuddy' });Response
{
success: true,
data: {
user: "[email protected]",
channel: "Channel1"
}
}Notes
- Channel names are normalized internally.
- Stops on first match for efficiency.
- Uses listall traversal internally only if needed.
📄 getcontent({ page, limit, ProductName, username })
Fetches content in paginated form for a given product and user.
const pageData = await db.cms.getcontent({
page: 1,
limit: 50,
ProductName: 'CodeBuddy',
username: '[email protected]'
});Notes
- Pagination-safe: Supports
pageandlimit. - Designed for UI dashboards, CMS listing, and admin views.
🆔 handleid(ids, ProductName)
Fetches content directly via content IDs. Supports single ID or array of IDs.
const result = await db.cms.handleid('D9.x.a.h', 'CodeBuddy');
const batch = await db.cms.handleid(['D9.x.a.h','D9.x.a.$'], 'CodeBuddy');Behavior
- Uses ID-level parsing to determine hierarchy:
root → user → channel → content- Supports wildcard
$to fetch all content under a channel. - Throws structured errors via
IDProcessingErrorfor invalid IDs. - Returns
successanddatafields for matched content.
Example Response
{
success: true,
data: {
id: "D9.x.a.h",
content: { title: "Hello World", ... },
userName: "[email protected]",
channelName: "Channel1"
}
}🛠️ Worker-Based Content Scanning
The contentFinder function is an internal multi-threaded utility for CMS products.
Features
- Uses worker threads to scan directories concurrently.
- Tracks total content files and progress.
- Supports pause/resume events during scanning.
- Can stop early if a target content ID or channel is found.
- Writes output optionally to JSON for external processing.
Parameters
| Option | Type | Description |
| ------------- | -------- | ----------------------------------------------- |
| ProductName | string | Name of the product to scan |
| find | string | Target content ID(s) to search |
| findChannel | string | Target channel name to search |
| OutputDir | string | Directory to store output JSON |
| WantOutput | boolean | If true, writes results to file |
| logs | boolean | If true, logs progress info |
| onProgress | function | Callback on partial results or progress updates |
Example Usage
await contentFinder({
ProductName: 'CodeBuddy',
WantOutput: true,
find: 'D9.x.a.h',
logs: true,
onProgress: (data) => console.log('Progress:', data)
});🧭 Design Philosophy
✔ Product-scoped fetchers (fetchcontent) for CMS batch operations
✔ Direct content lookup (findcontent, handleid) using indexed resolution
✔ Worker-based multi-threaded scanning for large-scale content directories
✔ Safe pagination-based traversal, avoids full filesystem blocking
✔ Deterministic and recoverable: all fetches and searches are repeatable
If you want, I can now generate a full “CMS Reference” document with methods, parameters, examples, and detailed worker explanations in markdown just like the listall/findall documentation you shared. It would be ready for your docs site.
Do you want me to do that next?
🎯 Why This db Wrapper Exists
- ✔ Cleaner imports
- ✔ Functional API style
- ✔ Controller-friendly
- ✔ No tight class coupling
- ✔ Same DBMS power with less boilerplate
⚠️ Error Handling
- All methods throw
Error - No silent failures
- File corruption prevented
try {
await userDB.create("", {});
} catch (e) {
console.error(e.message);
}🚀 Why Use HBH-DBMS?
- ✔ CMS
- ✔ SaaS backends
- ✔ Admin systems
- ✔ Easy to deploy
- ✔ No database setup
- ✔ Fully customizable
- ✔ Debug-first systems
- ✔ File-based backends
- ✔ Offline-friendly apps
- ✔ Ideal for CMS, admin panels, APIs
- ✔ Perfect for small-to-medium projects
❌ When NOT to Use
- ❌ Very high-traffic apps
- ❌ Heavy concurrent writes
- ❌ Complex relational queries
- ❌ Financial or banking systems
📜 License
ISC License © HBH
👨💻 Author
HBH / HashirAttari Built with ❤️ for Node.js developers
