A lightweight Node.js DBMS that manages content, user files, and JSON-based data.
npm install hbh-dbmshbh-dbms is designed for backend developers who want simple, structured, and scalable file-based storage with modular services.
type: module)
User
βββ Product
βββ Channel
βββ Content
`
Each 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)
$3
> β 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.
---
$3
To avoid filesystem limits (10k+ folders problem), HBH-DBMS:
* Splits data into chunks
* Uses multi-level nesting
* Distributes load evenly
Example:
`
Users/
βββ Ae/
βββ Alice@example.com/
`
π This prevents:
* Slow directory reads
* OS inode pressure
* FS traversal slowdown
---
$3
Every entity path is:
* Derived from its ID
* Deterministic
* Rebuildable at any time
Meaning:
* No central index dependency
* No corruption cascade
* Easy recovery
---
$3
`
User
βββ Product
βββ Channel
βββ Content
`
Rules:
* β 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/
β β βββ /
β β β βββ data.json
β β β βββ products/
β β β β βββ /
β β β β β βββ data.json
β β β β β βββ channels/
β β β β β β βββ /
β β β β β β β βββ content.json
β β β β β β β βββ /
`
π 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:
1. Validate input
2. Resolve deterministic path
3. Traverse hierarchy safely
4. Create folder only if needed
5. 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
`bash
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
`js
import { DBMS, libs } from 'hbh-dbms';
`
---
π Library Structure
`text
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
`js
import { DBMS } from 'hbh-dbms';
`
β οΈ DBMS is NOT a constructor
It is a namespace that exposes multiple DB classes.
---
$3
`js
DBMS.BaseDB
DBMS.UserDB
DBMS.ProductDB
DBMS.ChannelDB
DBMS.ContentDB
DBMS.BaseDB
DBMS.UserFileManager
`
HBH-DBMS is designed to be used directly, just like this:
`js
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.
---
$3
`js
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.
---
$3
Manage user-related data.
Manages users as root entities.
`js
const userDB = new DBMS.UserDB();
`
---
#### β Create User
`js
await userDB.create(
"Alice@example.com",
{
email: "Alice@example.com",
Info: {
Author: "Alice",
password: "12345678"
}
}
);
`
π What happens internally:
* User directory created Users/Ae/Alice@example.com/
* data.json written
* Duplicate IDs prevented
---
#### π Read User
`js
const user = await userDB.read("Alice@example.com");
`
---
#### βοΈ Rename User (Update ID)
`js
await userDB.update(
"Alice@example.com",
"AliceDemo@gmail.com"
);
`
β Renames folder
β Keeps all nested data intact
---
#### βοΈ Update User Info
`js
await userDB.updateInfo(
"AliceDemo@gmail.com",
{
id2: 123456,
password: "1234@Alice"
}
);
`
β Merges data
β Does not overwrite existing keys
---
#### β Delete User
`js
await userDB.delete("AliceDemo@example.com");
`
Deletes:
* User
* Products
* Channels
* Content
* Files
---
#### π List Users
`js
const users = await userDB.list();
`
---
$3
`js
const productDB = new DBMS.ProductDB('Alice@example.com');
`
Products are owned by users.
---
#### β Create Product
`js
await productDB.create("Product1");
`
π Path created:
`
/Users/Ae/Alice@example.com/Product1/
`
---
#### π Read Product
`js
await productDB.read("Product1");
`
---
#### βοΈ Rename Product
`js
await productDB.update("Product1","Product2");
`
---
#### β Delete Product
`js
await productDB.delete("Product2");
`
---
#### π List Products
`js
await productDB.list();
`
---
$3
Channels live inside products.
Channels can contain content, posts, or media.
`js
const channelDB = new DBMS.ChannelDB('Alice@example.com', 'Product1');
channelDB.Limit = 2;
`
π Limit controls max channels inside product db.
---
#### β Create Channel
`js
await channelDB.create("Channel1");
`
π Path created:
`js
/Users/Ae/Alice@example.com/Product1/Channel1
`
---
#### π Read Channel
`js
await channelDB.read("Channel1");
`
---
#### βοΈ Rename Channel
`js
await channelDB.update("Channel1", "Channel2");
`
---
#### βοΈ Update Channel Info
`js
await channelDB.updateInfo(
"Channel2",
{ author: "HashirAttari" }
);
`
---
#### π Find Channel
`js
await channelDB.find("Channel1");
`
---
#### π List Channels
`js
await channelDB.list();
`
---
#### β Delete Channel
`js
await channelDB.delete("Channel2");
`
---
$3
Used for all content, including blogs, posts, articles, and videos, in JSON format.
Content exists inside channels.
`js
const contentDB = new DBMS.ContentDB(channelDB, 'Channel1');
contentDB.Limit = 2;
`
π Limit controls max content inside channel db.
---
#### β Create Content
`js
const contentID = await contentDB.create(
type = "list" | 'tutorial',
contentName = "First-Content",
body = ["Hello", "User", "ALice"] | { Name: "Alice", message: 'Hello' }
);
`
π Path created:
`js
/Users/Ae/Alice@example.com/Product1/Channel1/${ContentType}/First-Content.json
`
---
#### π Read Content
`js
await contentDB.read(contentID);
`
---
#### βοΈ Update Content Body
`js
await contentDB.updateContent(
contentID,
["Alice", "AliceDemo"]
);
`
---
#### βοΈ Update Content Info
`js
await contentDB.updateInfo(
contentID,
{
tags: ["updated"],
author: "New Author"
}
);
`
---
#### β Delete Content
`js
await contentDB.delete(contentID);
`
---
#### π List Content
`js
await contentDB.list({type: 'list' | 'all'});
`
---
#### π Find Content
`js
await contentDB.find(contentID);
`
---
$3
UserFileManager handles user file operations inside products, including uploads, downloads, renames, deletes, and recycle bin functionality.
`js
const ufm = new DBMS.UserFileManager("Alice@example.com");
`
π Works per user and integrates with UserDB and ProductDB.
π Files are isolated per product to maintain safety.
---
#### β Create / Upload File
`js
await ufm.upload(req, "Alice@example.com", "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/Alice@example.com/Product1/
`
* Adds metadata and tracks usage in the productβs config.
---
#### π Read File
`js
const content = await ufm.readFileContent("Alice@example.com", "Product1", "myfile.txt");
`
* Returns text content only (binary files will throw an error).
---
#### βοΈ Update File
`js
await ufm.updateFileContent("Alice@example.com", "Product1", "myfile.txt", "Updated text");
`
* Replaces file content.
* Validates text content.
* Updates usage tracking.
---
#### β Delete File
`js
await ufm.deleteFile("Alice@example.com", "Product1", "myfile.txt");
`
* Deletes a file.
* Updates usage accordingly.
---
#### π¦ Delete All Files in Product
`js
await ufm.deleteAllFiles("Alice@example.com", "Product1");
`
* Deletes all files/folders inside a product.
* Skips .config folder.
* Resets usage in config.
---
#### π Rename / Move File
`js
await ufm.renameFile("Alice@example.com", "Product1", "old.txt", "new.txt");
await ufm.moveFile("Alice@example.com", "Product1", "old.txt", "folder/new.txt");
`
* Moves or renames files safely inside product directories.
* Validates safe paths.
---
#### π Create Folder
`js
await ufm.createFolder("Alice@example.com", "Product1", "newFolder");
`
* Creates a directory inside a product.
---
#### π Recycle Bin
* Move to Bin:
`js
await ufm.BinFile("Alice@example.com", "Product1", "file.txt");
`
* Recover File:
`js
await ufm.RecoverFile("Alice@example.com", "Product1", "file.txt.hbhbin");
`
* List Trash:
`js
const trashFiles = await ufm.ListTrash("Alice@example.com", "Product1");
`
* Empty Trash:
`js
await ufm.EmptyTrash("Alice@example.com", "Product1");
`
---
#### π List Files / Directories
`js
await ufm.listFlat("Alice@example.com", "Product1"); // flat list
await ufm.listTree("Alice@example.com", "Product1"); // tree structure
await ufm.listDir("Alice@example.com", "Product1"); // directories only
`
* Filters .config folders automatically.
* Returns full metadata for files in tree/flat listings.
---
#### π Usage Info
`js
const { used, limit } = await ufm.usage("Alice@example.com", "Product1");
`
* used β total bytes used
* limit β maximum allowed bytes (default MAX_USER_STORAGE_BYTES)
---
#### βοΈ Product Management
`js
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
---
$3
`js
import { db } from 'hbh-dbms';
`
---
$3
`js
export const db = {
user,
product,
channel,
content,
listall,
findall,
cms
};
`
---
$3
Creates a new UserDB instance.
`js
const userDB = db.user();
`
πΉ Internally calls: new UserDB()
πΉ Used for user CRUD operations and listing
---
$3
Creates a ProductDB instance scoped to a user.
`js
const productDB = db.product('Alice@example.com');
`
πΉ Internally calls: new ProductDB(user)
πΉ Products always belong to a user
---
$3
Creates a ChannelDB instance under a product.
`js
const channelDB = db.channel('Alice@example.com', 'Product1');
`
πΉ Internally calls: new ChannelDB(user, product)
πΉ Channels cannot exist without a product and user
---
$3
Creates a ContentDB instance under a channel.
`js
const contentDB = db.content(channelDB, 'Channel1');
`
πΉ Internally calls: new ContentDB(channelInstance, channelName)
πΉ Used for posts, articles, tutorials, media, etc.
---
$3
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.
`js
db.listall
`
##### Available Methods
`js
listall.User
listall.Channel
listall.Content
`
---
##### π€ listall.User(options)
Lists users using paginated traversal.
`js
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
`js
{
success: true,
message: "Users fetched",
data: [ "alice@example.com", "bob@example.com" ],
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.
`js
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
`js
{
success: true,
data: {
"alice@example.com": ["Channel1", "Channel2"],
"bob@example.com": ["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.
`js
await listall.Content({
productName: "HBH-CMS",
userPage: 1,
userLimit: 10,
channelPage: 1,
channelLimit: 10,
contentPage: 1,
contentLimit: 20
});
`
###### Response
`js
{
success: true,
data: {
"content-id-1": { user: "alice@example.com", channel: "Channel1" },
"content-id-2": { user: "bob@example.com", 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.
`js
db.findall
`
##### Available Methods
`js
findall.User
findall.Channel
findall.Findchannel
findall.Content
findall.Findcontent
`
---
##### π€ findall.User(username)
Finds a user by ID using paginated scanning.
`js
await findall.User("alice@example.com");
`
###### 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.
`js
await findall.Channel("Channel1", {
productName: "HBH-CMS"
});
`
###### Response
`js
{
success: true,
data: {
user: "alice@example.com",
channel: "Channel1"
}
}
`
###### Notes
* Channel names are normalized
* Stops on first match
* Uses listall.Channel internally
---
##### π findall.Content or π findall.Findcontent (contentID, options)
Finds a content item anywhere in the DB.
Uses IDManager for indexed content lookup.
`js
await findall.Content("content-id-1", {
productName: "HBH-CMS"
});
`
###### Behavior
* Traverses:
`
User β Product β Channel β Content
`
* Auto-advances pagination
* Stops early on match
`js
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
---
$3
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.
`js
db.cms.fetchcontent.HBHCodes
db.cms.fetchcontent.HBHTube
db.cms.fetchcontent.CodeBuddy
`
##### Example Usage
`js
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:
`js
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.
`js
const content = await db.cms.findcontent('content-id-123', { productName: 'CodeBuddy' });
`
##### Response
`js
{
success: true,
data: {
user: "alice@example.com",
channel: "Channel1",
content: { ... }
}
}
`
##### Notes
* Uses IDManager for efficient indexed resolution.
* Returns null if content is not found.
* Avoids filesystem-wide traversal when possible.
---
#### π findchannel(targetChannel, { productName })
Finds channel info by name using ChannelManager.
`js
const channel = await db.cms.findchannel('Channel1', { productName: 'CodeBuddy' });
`
##### Response
`js
{
success: true,
data: {
user: "alice@example.com",
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.
`js
const pageData = await db.cms.getcontent({
page: 1,
limit: 50,
ProductName: 'CodeBuddy',
username: 'alice@example.com'
});
`
##### Notes
* Pagination-safe: Supports page and limit.
* 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.
`js
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:
`text
root β user β channel β content
`
* Supports wildcard $ to fetch all content under a channel.
* Throws structured errors via IDProcessingError for invalid IDs.
* Returns success and data fields for matched content.
##### Example Response
`js
{
success: true,
data: {
id: "D9.x.a.h",
content: { title: "Hello World", ... },
userName: "alice@example.com",
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
`js
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?
---
$3
* β 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
`js
try {
await userDB.create("", {});
} catch (e) {
console.error(e.message);
}
``