axiodb 20.3.3 β†’ 20.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +56 -1061
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -21,1106 +21,101 @@
21
21
  [![TypeScript](https://img.shields.io/badge/TypeScript-6.0-blue)](https://www.typescriptlang.org/)
22
22
  [![Zero Dependencies](https://img.shields.io/badge/dependencies-0%20native-success)](https://www.npmjs.com/package/axiodb)
23
23
 
24
- πŸ‘‰ **[Official Documentation](https://axiodb.in/)**: Access full guides, examples, and API references.
24
+ πŸ‘‰ **[Official Documentation β€” axiodb.in](https://axiodb.in/)**: Full guides, API reference, and examples. This README is a quick start β€” see the site for everything else.
25
25
 
26
26
  ---
27
27
 
28
- ## Table of Contents
28
+ ## What is AxioDB?
29
29
 
30
- - [What is AxioDB, and why does it exist?](#what-is-axiodb-and-why-does-it-exist)
31
- - [Installation](#-installation)
32
- - [Quick Start β€” Local AxioDB](#-quick-start--local-axiodb)
33
- - [Features](#-features)
34
- - [AxioDBCloud β€” Connecting Remotely](#-axiodbcloud--connecting-remotely)
35
- - [Simple: connect without authentication](#simple-connect-without-authentication)
36
- - [Advanced: TCP authentication](#advanced-tcp-authentication)
37
- - [Advanced: TLS encryption](#advanced-tls-encryption)
38
- - [AxioDB CLI β€” Command Line Interface](#-axiodb-cli--command-line-interface)
39
- - [Troubleshooting](#-troubleshooting)
40
- - [Docker Deployment](#-docker-deployment)
41
- - [Simple: run the container](#simple-run-the-container)
42
- - [Advanced: env vars, volumes, Compose](#advanced-env-vars-volumes-compose)
43
- - [MCP Server β€” AI Agent Integration](#-mcp-server--ai-agent-integration)
44
- - [Built-in Web GUI & Authentication (RBAC)](#-built-in-web-gui--authentication-rbac)
45
- - [Detailed Usage](#-detailed-usage)
46
- - [API Reference](#-api-reference)
47
- - [Best Practices](#-best-practices)
48
- - [Architecture & Internal Mechanisms](#-architecture--internal-mechanisms)
49
- - [Comparisons](#-comparisons)
50
- - [Limitations & Honest Positioning](#-limitations--honest-positioning)
51
- - [FAQ](#-faq)
52
- - [Contributing, License & Support](#-contributing-license--support)
30
+ **Embedded NoSQL for Node.js, zero native deps.** `npm install axiodb` and you have a database β€” no server, no `node-gyp`, no `electron-rebuild`.
53
31
 
54
- ---
55
-
56
- ## What is AxioDB, and why does it exist?
57
-
58
- **AxioDB is an embedded NoSQL database for Node.js, with MongoDB-style queries, zero native dependencies, and a built-in web GUI.** Think SQLite, but NoSQL β€” install it with npm, and you have a working database with no server, no compilation step, and no platform-specific binaries.
59
-
60
- ### The problem
61
-
62
- SQLite is great, but its native C bindings cause real deployment pain in JavaScript projects:
63
-
64
- - ❌ `electron-rebuild` on every Electron update
65
- - ❌ Platform-specific builds (Windows `.node` files β‰  Mac `.node` files)
66
- - ❌ SQL strings instead of JavaScript objects
67
- - ❌ Schema migrations when your data model changes
68
- - ❌ `node-gyp` compilation headaches
69
-
70
- Meanwhile, plain JSON files have no querying, no caching, and no indexing β€” they just don't scale past a few thousand records. And MongoDB solves the query/caching problem, but needs a separate server process, which is overkill for a desktop app, CLI tool, or embedded system.
71
-
72
- ### The solution
73
-
74
- AxioDB combines the parts of each that actually matter for an embedded use case:
75
-
76
- - βœ… Works everywhere Node.js runs β€” no rebuild, no native dependencies
77
- - βœ… MongoDB-style queries: `{ age: { $gt: 25 } }`
78
- - βœ… Schema-less JSON documents β€” no migrations
79
- - βœ… Built-in `InMemoryCache` with automatic invalidation
80
- - βœ… Multi-core parallelism with Worker Threads
81
- - βœ… Built-in web GUI at `localhost:27018`
82
- - βœ… AxioDBCloud β€” optional TCP remote access for Docker/cloud deployments
83
-
84
- ### Is it a fit for you?
85
-
86
- **Great fit for:**
87
- - πŸ–₯️ Desktop apps (Electron, Tauri)
88
- - πŸ› οΈ CLI tools
89
- - πŸ“¦ Embedded systems
90
- - πŸš€ Rapid prototyping
91
- - 🏠 Local-first applications
92
- - πŸ’» Node.js apps requiring local storage
93
-
94
- **Sweet spot:** 10K–500K documents with intelligent caching.
95
-
96
- **Not a fit for:**
97
- - 10M+ documents, or datasets that need to scale far beyond a single node β†’ use PostgreSQL, MongoDB, or SQLite
98
- - Multi-user web applications with hundreds of concurrent connections β†’ AxioDB is single-instance, not a client-server database
99
- - Relational data with JOINs and foreign-key constraints β†’ AxioDB is document-based NoSQL
100
- - Distributed systems needing replication, sharding, or clustering β†’ AxioDB is single-node only
101
- - Cross-collection ACID transactions β†’ AxioDB's transactions are scoped to a single collection
102
-
103
- **AxioDB isn't competing with PostgreSQL or MongoDB.** It's for when you need a database *embedded in your app* β€” no server setup, no native dependencies. When you outgrow it, migrating to PostgreSQL or MongoDB is the right call, and expected.
104
-
105
- ---
106
-
107
- ## πŸ“¦ Installation
108
-
109
- ```bash
110
- npm install axiodb@latest --save
111
- ```
112
-
113
- **Requirements:** Node.js β‰₯20.0.0, npm β‰₯6.0.0 (yarn β‰₯1.0.0 optional). AxioDB runs on Node.js servers only β€” it requires the filesystem, so it does not run in a browser.
114
-
115
- ---
116
-
117
- ## πŸ› οΈ Quick Start β€” Local AxioDB
118
-
119
- ```javascript
120
- const { AxioDB } = require('axiodb');
121
-
122
- // Create AxioDB instance with the built-in GUI enabled
123
- const db = new AxioDB({ GUI: true }); // GUI available at http://localhost:27018
124
-
125
- // Create a database and a collection
126
- const myDB = await db.createDB('HelloWorldDB');
127
- const collection = await myDB.createCollection('greetings');
128
-
129
- // Insert and query β€” Hello World! πŸ‘‹
130
- await collection.insert({ message: 'Hello, Developer! πŸ‘‹' });
131
- const result = await collection.query({}).exec();
132
- console.log(result.data.documents[0].message); // Hello, Developer! πŸ‘‹
133
- ```
134
-
135
- > **Only one `AxioDB` instance per application.** It's a singleton by design β€” create it once, then create as many databases and collections as you need under it.
136
-
137
- ### `new AxioDB(options?)` β€” all constructor options
138
-
139
- | Option | Type | Default | Description |
140
- | --- | --- | --- | --- |
141
- | `GUI` | `boolean` | `false` | Enable the web-based GUI dashboard at `localhost:27018` |
142
- | `HTTP` | `boolean` | mirrors `GUI` | Enable the HTTP API server on port 27018 β€” auto-enables when GUI is on; `GUI: true` + `HTTP: false` throws an error |
143
- | `RootName` | `string` | `"AxioDB"` | Name of the root folder database files are stored under |
144
- | `CustomPath` | `string` | current working directory | Custom filesystem path for database storage |
145
- | `TCP` | `boolean` | `false` | Enable the AxioDBCloud TCP server on port 27019 |
146
- | `TCPAuth` | `boolean` | `false` | Require username/password authentication on TCP connections (same RBAC accounts as the GUI) β€” see [Advanced: TCP authentication](#advanced-tcp-authentication) |
147
-
148
- ```javascript
149
- const db = new AxioDB({
150
- GUI: true,
151
- RootName: 'MyDB',
152
- CustomPath: './data',
153
- TCP: true,
154
- TCPAuth: true,
155
- });
156
- ```
157
-
158
- ---
159
-
160
- ## πŸš€ Features
161
-
162
- ### Querying
163
- - **Chainable Query API:** `.query()`, `.Sort()`, `.Limit()`, `.Skip()`, `.setCount()`, `.setProject()`, `.exec()` / `.findOne()`
164
- - **Index Hints:** `.hint('fieldName')` to force a specific index on any query for predictable performance
165
- - **Batch Read:** `.findByIds(['id1', 'id2'])` to retrieve multiple documents by ID in a single call
166
- - **MongoDB-style Query Operators:** `$gt`, `$gte`, `$lt`, `$lte`, `$ne`, `$in`, `$nin`, `$exists`, `$regex`, `$or`, `$and`
167
- - **Aggregation Pipelines:** 60+ MongoDB-compatible stages (`$match`, `$group`, `$sort`, `$project`, `$limit`, `$skip`, `$unwind`, `$addFields`, `$lookup`, `$facet`, `$bucket`, `$count`, `$sample`, ...) with full expression evaluator, cross-collection `$lookup` joins, and custom operator registration via `OperatorRegistry`
168
- - **Bulk Operations:** high-performance `insertMany`, `UpdateMany`, `deleteMany`
169
-
170
- ### Indexing
171
- - **Auto Indexing:** every collection gets an automatic `documentId` index for O(1) lookups
172
- - **Custom Field Indexes:** `newIndex(...fieldNames)` to add fast lookups on any field, `dropIndex(indexName)` to remove one, `getIndexes()` to list what's registered
173
- - **Index Cache with TTL:** in-memory index cache with random 5–15 min TTL (prevents cache stampede) and disk persistence for cold-start recovery
174
- - **Automatic Document Removal:** documents are automatically removed from indexes when deleted
175
- - **Dual-Write Pattern:** indexes persist to both memory (speed) and disk (durability)
176
-
177
- ### Transactions
178
- - **ACID-compliant, single-collection transactions** with savepoints, rollback, and Write-Ahead Logging (WAL) for crash recovery
179
- - **Session Management:** scoped transactions with timeout support
180
- - **TCP Transactions:** BEGIN/COMMIT/ROLLBACK over TCP with savepoints, connection-pinned client proxy, and auto-rollback on disconnect
181
-
182
- ```javascript
183
- // Local transaction
184
- const session = collection.startSession();
185
- await session.withTransaction(async (tx) => {
186
- await tx.insert({ name: 'Alice', balance: 1000 });
187
- // Updates are flat merges; AxioDB does not implement MongoDB's $inc operator.
188
- await tx.update({ name: 'Bob' }, { balance: 900 });
189
- // Auto-commits on success, auto-rolls-back on error
190
- });
191
-
192
- // TCP transaction
193
- const tx = await client.db('mydb').collection('users').beginTransaction();
194
- await tx.insert({ name: 'Alice', balance: 1000 });
195
- await tx.update({ name: 'Bob' }, { balance: 900 });
196
- await tx.commit(); // or await tx.rollback();
197
- ```
198
-
199
- ### Caching
200
- - **`InMemoryCache`:** automatic eviction policies, random TTL (5–15 min) to avoid thundering-herd cache expiry
201
- - **Selective Invalidation:** only the affected cache entries are cleared on update/delete β€” not the whole cache
202
- - **Async, Non-blocking Updates:** cache writes don't block the response path
203
- - **Collection-Scoped Keys:** cache keys include the collection path, so there's no cross-collection collision
204
-
205
- ### Security
206
- - **File-level Isolation:** each document lives in its own `.axiodb` file with locking
207
- - See [Built-in Web GUI & Authentication](#-built-in-web-gui--authentication-rbac) for RBAC/login and [Security Best Practices](#-best-practices) below
208
-
209
- ### Architecture
210
- - **Tree-like Storage:** hierarchical, file-per-document layout for efficient retrieval, selective loading, and easy backup
211
- - **Worker Threads:** non-blocking I/O and multi-core utilization, especially for reads
212
- - **Single Instance Architecture:** one `AxioDB` instance manages unlimited databases and collections, with strong consistency
213
- - **Zero-Configuration Setup:** serverless β€” install and start building instantly
214
- - **Custom Database Path:** flexible storage location via `CustomPath`
215
-
216
- ### GUI & Remote Access
217
- - **Web-based GUI Dashboard:** visual database browser, query execution, real-time monitoring at `localhost:27018`
218
- - **Role-Based Access Control:** Super Admin / Admin / View roles, shared between the GUI and AxioDBCloud
219
- - **AxioDBCloud:** TCP-based remote access β€” connect to a running AxioDB instance from anywhere with the exact same API as embedded mode
220
-
221
- ---
222
-
223
- ## ☁️ AxioDBCloud β€” Connecting Remotely
224
-
225
- **Host AxioDB in Docker or on a server, connect from anywhere** β€” AxioDBCloud is a TCP client that mirrors the embedded API exactly, so switching from local to remote is a one-line change (`new AxioDB()` β†’ `new AxioDBCloud()`).
226
-
227
- - **πŸ”„ Zero Code Changes:** same `createDB`/`createCollection`/`insert`/`query` API as embedded AxioDB
228
- - **⚑ Fast Binary Protocol:** length-prefixed JSON framing, with automatic reconnection
229
- - **πŸ” Optional Authentication:** shared RBAC with the GUI, per-IP rate limiting (see [Advanced](#advanced-tcp-authentication) below)
230
- - **πŸ“¦ 32 Commands:** full CRUD, aggregation, indexing, and transactions over the wire
231
- - **πŸ” Auto-Reconnect:** exponential backoff, up to 10 retry attempts
232
- - **πŸ’“ Heartbeat Monitoring:** `PING`/`PONG` every 30 seconds
233
- - **πŸ†” Request Correlation:** UUID-based request/response matching
234
- - **🧡 Connection Pooling:** client keeps a pool of `maxPoolSize` concurrent connections (default: 10, mirrors MongoDB's driver option) and routes each command to the least-busy connected member (fewest in-flight requests); server accepts 1,000+ concurrent connections total, capped at 100 per remote IP (see the [file descriptor limit note](#connection-refused--too-many-open-files-errors-at-high-concurrency) below if you're running near that scale)
235
- - **πŸ›‘οΈ Connection-Level DoS Protection:** per-IP concurrent connection cap (100) plus a separate per-IP connection-*attempt* rate limiter (300 attempts / 10s β†’ 30s cooldown), so one client can't starve the server either by holding too many sockets open or by rapidly opening and dropping them
236
- - **πŸ”’ Optional TLS Encryption:** encrypt the wire protocol with your own cert (see [Advanced: TLS](#advanced-tls-encryption) below) β€” off by default, so existing plaintext deployments are unaffected unless you turn it on
237
- - **πŸ“ TypeScript Support:** full type definitions included
238
-
239
- **Use cases:** microservices sharing one AxioDB instance, Electron apps connecting to a local or remote database, teams sharing a development database, container/cloud deployments (AWS, Azure, GCP, DigitalOcean).
240
-
241
- ### Simple: connect without authentication
242
-
243
- By default, TCP connections are unauthenticated β€” anyone who can reach the port can run any command. This is fine for local development or a fully trusted private network.
244
-
245
- **Server:**
246
- ```javascript
247
- const { AxioDB } = require('axiodb');
248
- const db = new AxioDB({ GUI: false, RootName: 'MyDB', CustomPath: '.', TCP: true }); // TCP on port 27019
249
- ```
250
-
251
- **Client:**
252
- ```javascript
253
- const { AxioDBCloud } = require('axiodb');
254
-
255
- const client = new AxioDBCloud("axiodb://localhost:27019");
256
- await client.connect();
257
-
258
- const db = await client.createDB("ProductionDB");
259
- const users = await db.createCollection("Users");
260
-
261
- await users.insert({ name: "Alice", role: "admin" });
262
- const results = await users.query({ role: "admin" })
263
- .Limit(10)
264
- .Sort({ createdAt: -1 })
265
- .exec();
266
-
267
- await client.disconnect();
268
- ```
269
-
270
- ### Advanced: TCP authentication
271
-
272
- Opt in with `TCPAuth: true` to require a username/password on every connection. This reuses the **exact same accounts and roles** as the GUI's RBAC system (see [Built-in Web GUI & Authentication](#-built-in-web-gui--authentication-rbac)) β€” one set of credentials for both.
273
-
274
- **Server:**
275
- ```javascript
276
- const db = new AxioDB({ TCP: true, TCPAuth: true, RootName: 'MyDB', CustomPath: '.' });
277
- ```
278
-
279
- **Client β€” credentials in the constructor** (recommended; `connect()` authenticates automatically):
280
- ```javascript
281
- const client = new AxioDBCloud("axiodb://localhost:27019", {
282
- username: 'admin',
283
- password: 'admin',
284
- });
285
- await client.connect();
286
-
287
- console.log(client.authenticatedUser); // { username, role, mustChangePassword }
288
- ```
289
-
290
- **Client β€” authenticate after connecting** (e.g. credentials supplied at runtime):
291
- ```javascript
292
- const client = new AxioDBCloud("axiodb://localhost:27019");
293
- await client.connect();
294
- await client.login('admin', 'admin');
295
- ```
296
-
297
- **What's enforced:**
298
- - Every command except `PING`/`DISCONNECT`/`AUTHENTICATE` requires a prior successful login on that connection.
299
- - The same role permissions as the GUI apply per command (e.g. a `View`-role user gets `403` on `CREATE_DB`).
300
- - **Shared per-IP login rate limiter with the GUI:** 5 failed attempts within a trailing 15-minute window locks that IP out for 15 minutes (`429 Too Many Requests`) β€” counted across both TCP and GUI login attempts from that IP.
301
- - **Accounts that still need their forced password change are rejected outright (`403`)**, not allowed through with a warning β€” there's no TCP command to change a password today, so log into the GUI (`http://localhost:27018`) to complete it first, or authenticate with an account that already has.
302
- - If a Super Admin resets a user's password, changes their role, or deletes them via the GUI while that user has an open TCP connection, the TCP connection is immediately forced to re-authenticate on its next command.
303
-
304
- **Known limitations:** there's currently no TCP command to change a password; that must go through the GUI.
32
+ **Problem:** `better-sqlite3` needs compiled binaries, `electron-rebuild` on every Electron update, per-platform builds. Plain JSON files have no query/cache/index.
305
33
 
306
- ### Advanced: TLS encryption
34
+ **Solution:** AxioDB is a file-based document database with ACID transactions and MongoDB-style queries on plain JavaScript objects.
307
35
 
308
- By default, the TCP protocol is **plaintext** β€” anyone who can capture the network traffic between client and server (e.g. Wireshark on a shared network) can read your data and, if `TCPAuth` is on, your password. TLS fixes this. It's **off by default** β€” nothing below is required, and existing plaintext deployments keep working exactly as before unless you turn it on.
309
-
310
- **You must provide your own certificate + key.** AxioDB never generates one for you β€” that's a security decision only you can make (a real cert from a CA, or a self-signed one for local/private use).
311
-
312
- **Step 1 β€” get a cert + key.** For local/dev/private use, generate a self-signed one (one-time, takes a second):
313
- ```bash
314
- openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj "/CN=localhost"
315
- ```
316
- This creates two files, `cert.pem` and `key.pem`, in your current folder. For a real production deployment reachable from the internet, use a cert from a real CA (Let's Encrypt, your org's CA, your cloud provider's managed cert) instead β€” the rest of the setup below is identical either way.
317
-
318
- **Step 2 β€” point the server at them:**
319
36
  ```javascript
320
37
  const { AxioDB } = require('axiodb');
321
- const db = new AxioDB({
322
- TCP: true,
323
- TLS: true,
324
- TLSCertPath: './cert.pem', // path to the file from step 1
325
- TLSKeyPath: './key.pem',
326
- });
327
- ```
328
- If `TLS: true` but either path is missing or unreadable, AxioDB throws immediately at startup β€” it never silently falls back to plaintext.
329
-
330
- **Step 3 β€” point the client at the same cert** (only needed because it's self-signed; a real CA-issued cert wouldn't need this step, the same way your browser trusts `https://` sites without extra setup):
331
- ```javascript
332
- const { AxioDBCloud } = require('axiodb');
333
- const client = new AxioDBCloud("axiodb://localhost:27019", {
334
- tls: true,
335
- tlsCAPath: './cert.pem', // same cert.pem from step 1 - proves this server is the real one
336
- });
337
- await client.connect();
338
- ```
339
- Without `tlsCAPath`, the client refuses to connect to a self-signed server by default (`tlsRejectUnauthorized` defaults to `true`) β€” this is intentional, it's the same protection that stops your browser from silently trusting a fake `https://` site. Only set `tlsRejectUnauthorized: false` for local/dev testing, never in production, since it turns that protection off entirely.
340
-
341
- **Running this in Docker?** The cert/key files need to get *into* the container. The simplest way to think about it: your cert files live on your real machine; a Docker **bind mount** (`-v`) makes a folder from your machine visible inside the container at whatever path you choose, and you point `AXIODB_TLS_CERT_PATH`/`AXIODB_TLS_KEY_PATH` at *that in-container path*, not your real machine's path:
342
- ```bash
343
- # cert.pem and key.pem are really at /home/you/mycerts/ on your machine.
344
- # "/certs" below is just a name we're choosing for where they'll appear inside the container.
345
- docker run -d --name axiodb-server \
346
- -p 27018:27018 -p 27019:27019 \
347
- -v /home/you/mycerts:/certs:ro \
348
- -e AXIODB_TLS=true \
349
- -e AXIODB_TLS_CERT_PATH=/certs/cert.pem \
350
- -e AXIODB_TLS_KEY_PATH=/certs/key.pem \
351
- theankansaha/axiodb
352
- ```
353
- The rule: the `-e AXIODB_TLS_CERT_PATH=...` value must always match the *right-hand side* of the `-v` mount (`/certs/...`), never the real path on your machine (`/home/you/mycerts/...`) β€” the container can't see your machine's filesystem directly, only whatever you've explicitly mounted into it.
354
-
355
- πŸ‘‰ **[Full AxioDBCloud Documentation](https://axiodb.in/cloud)** β€” setup guides, API reference, Docker examples
356
-
357
- ---
358
-
359
- ## πŸ’» AxioDB CLI β€” Command Line Interface
360
-
361
- A Go-based CLI tool for interacting with AxioDB servers via the TCP protocol. Supports all database operations with both single-command and interactive REPL modes. Export and import databases via the HTTP API.
362
-
363
- ### Quick Install
364
-
365
- **Linux/macOS:**
366
- ```bash
367
- curl -fsSL https://raw.githubusercontent.com/nexoral/AxioDB/main/cli/Scripts/install.sh | bash
368
- ```
369
-
370
- **Windows (PowerShell):**
371
- ```powershell
372
- irm https://raw.githubusercontent.com/nexoral/AxioDB/main/cli/Scripts/install.ps1 | iex
373
- ```
374
-
375
- **Or download directly:** [GitHub Releases](https://github.com/nexoral/AxioDB/releases?q=cli-v&expanded=true)
376
-
377
- ### Supported Platforms
378
-
379
- | OS | Architectures |
380
- |------|--------------|
381
- | Linux | amd64, arm64, 386, armv7 |
382
- | macOS | amd64 (Intel), arm64 (Apple Silicon) |
383
- | Windows | amd64, arm64, 386 |
384
- | FreeBSD | amd64 |
385
- | OpenBSD | amd64 |
386
- | NetBSD | amd64 |
387
-
388
- ### Usage
389
-
390
- > **Activation notice:** Data commands (`db`/`collection`/`document`/`index`/`transaction`/`ping`/`health`/`connect`) require the server started with `TCP: true` (`AXIODB_TCP=true`, port 27019). Management commands (`user`/`role`/`user change-password`/`export`/`import`) require `GUI: true`/`HTTP: true` (`AXIODB_GUI=true`, port 27018). TCP is data-plane only β€” no management over TCP by design.
391
-
392
- **Single commands:**
393
- ```bash
394
- axiodb -c axiodb://127.0.0.1:27019 ping
395
- axiodb -c axiodb://127.0.0.1:27019 db list
396
- axiodb -c axiodb://127.0.0.1:27019 document insert '{"name":"Alice"}' --db mydb --collection users
397
- axiodb -c axiodb://127.0.0.1:27019 document query '{}' --db mydb --collection users
398
- axiodb -c axiodb://127.0.0.1:27019 document query '{}' --hint email --db mydb --collection users
399
- axiodb -c axiodb://127.0.0.1:27019 health
400
- axiodb -c axiodb://127.0.0.1:27019 transaction begin --db mydb --collection users
401
- ```
402
-
403
- **Interactive REPL (MongoDB shell style):**
404
- ```bash
405
- axiodb connect
406
- # axiodb> use mydb
407
- # axiodb:mydb> show collections
408
- # axiodb:mydb> use mydb.users
409
- # axiodb:mydb:users> db.users.find({})
410
- # axiodb:mydb:users> db.users.insert({name: "Bob"})
411
- # axiodb:mydb:users> exit
412
- ```
413
-
414
- **With authentication:**
415
- ```bash
416
- axiodb -c axiodb://127.0.0.1:27019 -u admin -p admin connect
417
- ```
418
-
419
- **With TLS:**
420
- ```bash
421
- axiodb -c axiodb://127.0.0.1:27019 --tls --tls-cert ./cert.pem connect
422
- ```
423
-
424
- **Export database (via HTTP API):**
425
- ```bash
426
- axiodb export mydb --http-host localhost --http-port 27018 -u admin -p secret
427
- # Saves mydb.tar.gz in current directory
428
- ```
429
-
430
- **Import database (via HTTP API):**
431
- ```bash
432
- axiodb import ./backups/mydb.tar.gz --http-host localhost --http-port 27018 -u admin -p secret
433
- # Tab completes .tar.gz file paths
434
- ```
435
-
436
- **User and role administration (via HTTP API):**
437
- ```bash
438
- axiodb user list --http-host localhost --http-port 27018 -u admin -p secret
439
- axiodb user create analyst analyst123 View --http-host localhost --http-port 27018 -u admin -p secret
440
- axiodb user change-password oldPass newPass --http-host localhost --http-port 27018 -u analyst -p analyst123
441
- axiodb role list --http-host localhost --http-port 27018 -u admin -p secret
442
- axiodb role create Auditor document:view,document:query --http-host localhost --http-port 27018 -u admin -p secret
443
- ```
444
-
445
- **Transactions (via TCP, full lifecycle):**
446
- ```bash
447
- # File-based batch (auto-commit/rollback)
448
- axiodb transaction run operations.json --db mydb --collection users
449
- # Manual control
450
- axiodb transaction begin --db mydb --collection users # β†’ transactionId
451
- axiodb transaction savepoint <txnId> sp1
452
- axiodb transaction rollback-to <txnId> sp1
453
- axiodb transaction release <txnId> sp1
454
- axiodb transaction commit <txnId>
455
- axiodb transaction rollback <txnId>
456
- ```
457
-
458
- Management commands use the authenticated HTTP API; they do not add management commands to the
459
- TCP client protocol, which remains focused on database, collection, document, index, aggregation,
460
- count, and transaction operations.
461
-
462
- ### Features
463
-
464
- - **TCP data operations:** database, collection, document CRUD, aggregation, indexing, counts, and transactions
465
- - **CLI transactions and diagnostics:** run a transaction operation file, use query index hints, find documents by IDs, and check TCP health
466
- - **Interactive REPL:** MongoDB shell syntax (`use`, `show dbs`, `db.coll.find()`)
467
- - **Export & Import:** backup/restore databases via HTTP API, tab-completes file paths
468
- - **TLS support:** `--tls`, `--tls-cert`, `--tls-skip-verify`
469
- - **Auth support:** `-u` / `-p` flags (TCP and HTTP)
470
- - **JSON output:** `--output json` for scripting
471
- - **Tab autocomplete** in REPL mode and file path completion
472
-
473
- πŸ‘‰ **[Full CLI Documentation](https://github.com/nexoral/AxioDB/tree/main/cli)**
474
-
475
- ---
476
-
477
- ## πŸ”§ Troubleshooting
478
-
479
- ### "Not connected to server" right after calling `connect()`
480
-
481
- `client.connect()` is asynchronous and must be `await`ed before you use the connection β€” it resolves only once the TCP handshake (and, if `TCPAuth` is on, the `AUTHENTICATE` round-trip) has completed.
482
-
483
- ```javascript
484
- // ❌ Wrong β€” races ahead before the connection (and login) finish
485
- client.connect();
486
- console.log(client.authenticatedUser); // undefined
487
- await client.createDB("MyDB"); // "Not connected to server"
488
-
489
- // βœ… Right
490
- await client.connect();
491
- console.log(client.authenticatedUser); // populated
492
- await client.createDB("MyDB"); // works
493
- ```
494
-
495
- ### `401` β€” "Authentication required..."
496
-
497
- You're running with `TCPAuth: true` and sent a command before a successful `AUTHENTICATE`. Either pass `{ username, password }` in the `AxioDBCloud` constructor (auto-authenticates on `connect()`), or call `await client.login(username, password)` yourself before any other command.
498
-
499
- ### `403` β€” "This account must change its password before it can be used over TCP..."
500
-
501
- Your credentials are correct, but that account is still flagged for a forced password change (true for the default `admin`/`admin` account, and for any newly created user). Log into the GUI at `http://localhost:27018`, sign in, and complete the password change there β€” there's no TCP command for this yet. Then reconnect with the new password, or use a different account that has already completed its change.
502
-
503
- ### `429` β€” "Too many failed login attempts..."
504
-
505
- Five failed logins from your IP within 15 minutes trigger a 15-minute lockout, shared between TCP and the GUI. Double check the credentials you're sending, wait out the cooldown, or fix the underlying typo/config issue causing repeated failures β€” there's no way to clear the lockout early.
506
-
507
- ### `429` β€” "Too many concurrent connections from this IP address"
508
-
509
- Unrelated to the login lockout above β€” this fires at connection time, before any `AUTHENTICATE`, once a single remote IP has 100 concurrent open TCP sockets to the server (`MAX_CONNECTIONS_PER_IP`), regardless of whether any of those connections are authenticated. This caps how much of the server's total 1,000-connection budget one IP can claim, so one client can't starve every other client. It's per-*connection*, not per-*request* β€” a single `AxioDBCloud` client at the default `maxPoolSize: 10` is nowhere near this limit; you'd only hit it by running many separate client processes behind the same IP/NAT gateway, or a runaway reconnect loop leaking sockets. If you legitimately need more than 100 concurrent connections from one IP, that's a server-side constant (`MAX_CONNECTIONS_PER_IP` in `source/tcp/config/keys.ts`) β€” there's no runtime option to raise it yet.
510
-
511
- If you do set a `maxPoolSize` that pushes past this cap (or any other subset of the pool fails for another reason, e.g. a network blip), `connect()` doesn't throw as long as at least one pool member connected β€” it resolves with a smaller-than-requested pool and emits a `poolDegraded` event so you know about it instead of silently running under capacity:
512
-
513
- ```javascript
514
- client.on('poolDegraded', ({ requested, connected, failed, errors }) => {
515
- console.warn(`Pool came up smaller than requested: ${connected}/${requested} connected, ${failed} failed`);
516
- console.warn(errors[0].message); // e.g. "Too many concurrent connections from this IP address"
517
- });
518
-
519
- await client.connect(); // resolves even if some pool members were rejected
520
- ```
521
-
522
- (The very first connection in the pool is the exception β€” if *that* one fails, `connect()` rejects entirely, since it's the signal that the server is reachable and credentials are valid at all.)
523
-
524
- ### `429` β€” "Too many connection attempts from this IP address. Try again later."
525
-
526
- Different from both `429`s above, and checked first: this guards against rapid connect-then-drop *churn*, which the concurrent-connection cap (`MAX_CONNECTIONS_PER_IP`) doesn't catch on its own β€” an attacker who never holds more than a few sockets open at once could still hammer the server with a high rate of connection attempts, each costing a TCP handshake and an accept/reject cycle, and stay under that cap the whole time. This is tracked separately, per IP, as a sliding window: once an IP crosses 300 connection attempts (successful or rejected, it doesn't matter which) within a trailing 10-second window, every new connection from that IP is rejected outright for the next 30 seconds. A normal `AxioDBCloud` client, even reconnecting a full `maxPoolSize: 10` pool repeatedly, is nowhere near this threshold β€” you'd only hit it via a genuine connection flood or a reconnect loop gone very wrong (e.g. retrying without backoff). There's no runtime option to raise these thresholds yet; they're constants in `source/tcp/config/keys.ts` (`CONNECTION_RATE_LIMIT_*`).
527
-
528
- ### `403` β€” "This is a reserved system database"
529
-
530
- You (or a client) tried to read/write a database literally named `config` β€” that name is reserved for AxioDB's own RBAC storage (`users`/`roles`/`permissions`) and is blocked on both the GUI and TCP, authenticated or not. Use a different database name.
531
-
532
- ### Connection refused / timeout connecting to `axiodb://host:27019`
533
-
534
- - Confirm the server was started with `TCP: true` (or, in Docker, `AXIODB_TCP=true`, the default).
535
- - Confirm the port is published: `-p 27019:27019` on `docker run`, or that nothing else on the host is bound to 27019.
536
- - If you're getting a protocol error mentioning "Message exceeds maximum size" or "Received HTTP data on TCP port," you're likely pointed at the GUI port (27018) instead of the TCP port (27019) β€” check your connection string.
38
+ const db = new AxioDB({ GUI: true }); // Dashboard at http://localhost:27018
39
+ const users = await (await db.createDB('AppDB')).createCollection('users');
537
40
 
538
- ### Docker container issues (won't start, port conflicts, data not persisting)
539
-
540
- See the [Docker Deployment](#-docker-deployment) section below, and `Docker/README.md` in the repository for a fuller Docker-specific troubleshooting guide (`docker logs`, port-conflict remapping, volume-mounting checklist).
541
-
542
- ### Connection refused / "Too many open files" errors at high concurrency
543
-
544
- Each `AxioDBCloud` client opens `maxPoolSize` TCP sockets (default: 10), and the server holds one socket per connected client β€” both count against the OS's open-file-descriptor limit. Most Linux distros default `ulimit -n` to 1024 per process, which is enough for only ~100 clients at the default pool size before the server starts refusing new connections with `EMFILE`/`ENFILE`.
545
-
546
- The published Docker image already raises its own soft limit to 65536 on startup (see `Docker/Dockerfile`'s `CMD`), so this is normally only something to think about on bare-metal/host installs, or if your Docker host's *hard* limit is itself capped below 65536:
547
-
548
- ```bash
549
- ulimit -n 65536 # current shell / process (non-Docker deployments)
550
- node lib/config/DB.js
551
- ```
552
-
553
- If the container still refuses connections, the host's hard limit is the ceiling to raise instead:
554
-
555
- ```bash
556
- docker run --ulimit nofile=65536:65536 -p 27018:27018 -p 27019:27019 theankansaha/axiodb
557
- ```
558
-
559
- or, in Compose:
560
-
561
- ```yaml
562
- services:
563
- axiodb:
564
- image: theankansaha/axiodb
565
- ulimits:
566
- nofile:
567
- soft: 65536
568
- hard: 65536
41
+ await users.insert({ name: 'Alice', age: 30 });
42
+ const { data } = await users.query({ age: { $gt: 25 } }).Sort({ age: -1 }).Limit(10).exec();
43
+ console.log(data.documents);
569
44
  ```
570
45
 
571
- On the client side, prefer a smaller `maxPoolSize` per instance rather than raising it β€” the least-busy routing (see [Connection Pooling](#-axiodbcloud--connecting-remotely) above) already avoids the head-of-line blocking a bigger pool would otherwise compensate for.
572
-
573
- ### Raising libuv's thread pool for higher disk-I/O concurrency
46
+ ## Objective
574
47
 
575
- File reads/writes (`FileManager`) go through Node's async `fs` APIs, which run on libuv's threadpool - 4 threads by default, regardless of how many TCP connections are open. Under many concurrent clients doing real disk I/O at once, that pool - not connection count - is the throughput ceiling.
48
+ **Great for:** Electron, CLI tools, embedded systems, local-first apps, rapid prototyping.
576
49
 
577
- The published image (`Docker/runner.js`) computes a default automatically from the container's actual CPU allotment (its cgroup quota, not the host's core count - `--cpus`/Kubernetes `resources.limits.cpu` are read directly, since Node has no stdlib API for this), roughly `4 Γ— allotted CPUs`, clamped to `[4, 64]`. Override it explicitly if you want a fixed value instead, no rebuild required:
50
+ **Sweet spot:** Local applications, desktop apps, CLI tools, and services that need a simple document database without a separate database server.
578
51
 
579
- ```bash
580
- docker run -e UV_THREADPOOL_SIZE=16 -p 27018:27018 -p 27019:27019 theankansaha/axiodb
581
- ```
52
+ **Not for:** 10M+ docs, hundreds of concurrent users, JOINs, replication/sharding β€” use PostgreSQL/MongoDB.
582
53
 
583
54
  ---
584
55
 
585
- ## 🐳 Docker Deployment
586
-
587
- ### Simple: run the container
56
+ ## Installation
588
57
 
589
58
  ```bash
590
- docker run -d \
591
- --name axiodb-server \
592
- -p 27018:27018 \
593
- -p 27019:27019 \
594
- -e AXIODB_TCP_AUTH_ENABLED=true \
595
- -v axiodb-data:/app \
596
- theankansaha/axiodb
597
-
598
- # Ports:
599
- # 27018 - HTTP GUI Dashboard
600
- # 27019 - TCP Remote Access (AxioDBCloud)
601
- # Volume: /app is the main data directory
59
+ npm install axiodb
60
+ # Node.js β‰₯20
602
61
  ```
603
62
 
604
- TCP authentication is on by default in the image. Log into the GUI at `http://localhost:27018` as `admin`/`admin` to complete the forced password change before connecting over TCP (see [Troubleshooting](#-troubleshooting) if you skip this step).
605
-
606
- ### Advanced: env vars, volumes, Compose
607
-
608
- Every option below has a default matching the image's previous fixed behavior β€” override any of them with `-e VAR=value` at `docker run` time, no rebuild required:
609
-
610
- | Variable | Default | Description |
611
- | --- | --- | --- |
612
- | `AXIODB_GUI` | `true` | Enable the HTTP Control Server / web GUI on port 27018 |
613
- | `AXIODB_HTTP` | mirrors `AXIODB_GUI` | Enable the HTTP API server on port 27018 β€” auto-enables when GUI is on; `AXIODB_GUI=true` + `AXIODB_HTTP=false` is an error |
614
- | `AXIODB_TCP` | `true` | Enable the AxioDBCloud TCP server on port 27019 |
615
- | `AXIODB_TCP_AUTH_ENABLED` | `true` | Require username/password authentication on TCP connections (same RBAC accounts as the GUI) |
616
- | `AXIODB_TLS` | `false` | Encrypt TCP connections with TLS instead of plaintext (see [Advanced: TLS encryption](#advanced-tls-encryption)) |
617
- | `AXIODB_TLS_CERT_PATH` | *(none)* | Path **inside the container** to a PEM cert file - required when `AXIODB_TLS=true`. Mount the real file in with `-v` first (see the TLS section above) |
618
- | `AXIODB_TLS_KEY_PATH` | *(none)* | Path **inside the container** to the matching PEM private key - required when `AXIODB_TLS=true` |
619
- | `AXIODB_ROOT_NAME` | `AxioDB` | Name of the root database folder created under the data volume |
620
- | `AXIODB_CUSTOM_PATH` | *(container's working directory)* | Custom path for database storage inside the container |
621
- | `AXIODB_MCP` | `false` | Enable the MCP server (AI agent integration) on port 27020 - see [MCP Server](#-mcp-server--ai-agent-integration) |
622
- | `AXIODB_MCP_PORT` | `27020` | Port the MCP server listens on inside the container |
623
-
624
- > Ports themselves (27018/27019) aren't configurable via environment variable β€” remap them at the Docker layer with `-p <host-port>:27018` / `-p <host-port>:27019`.
625
-
626
- **Disabling TCP authentication** (only on a trusted private network β€” the wire is plaintext unless you also enable `AXIODB_TLS`; see [Advanced: TLS encryption](#advanced-tls-encryption)):
627
- ```bash
628
- docker run -d \
629
- --name axiodb-server \
630
- -p 27018:27018 \
631
- -p 27019:27019 \
632
- -e AXIODB_TCP_AUTH_ENABLED=false \
633
- -v axiodb-data:/app \
634
- theankansaha/axiodb
635
- ```
636
-
637
- **Docker Compose:**
638
- ```yaml
639
- version: "3.8"
640
-
641
- services:
642
- axiodb:
643
- image: theankansaha/axiodb
644
- container_name: axiodb-server
645
- ports:
646
- - "27018:27018"
647
- - "27019:27019"
648
- environment:
649
- - AXIODB_GUI=true
650
- - AXIODB_TCP=true
651
- - AXIODB_TCP_AUTH_ENABLED=true
652
- - AXIODB_ROOT_NAME=AxioDB
653
- volumes:
654
- - axiodb-data:/app
655
- restart: unless-stopped
656
-
657
- volumes:
658
- axiodb-data:
659
- ```
660
-
661
- **The same, with TLS enabled** β€” note the two different kinds of entry under `volumes:`: `./mycerts:/certs:ro` is *your real folder* on the machine running Compose (because it contains a `/`), mounted read-only at `/certs` inside the container; `axiodb-data:/app` is a Docker-managed named volume (no `/`, just a label) for the actual database files:
662
- ```yaml
663
- version: "3.8"
664
-
665
- services:
666
- axiodb:
667
- image: theankansaha/axiodb
668
- container_name: axiodb-server
669
- ports:
670
- - "27018:27018"
671
- - "27019:27019"
672
- environment:
673
- - AXIODB_GUI=true
674
- - AXIODB_TCP=true
675
- - AXIODB_TCP_AUTH_ENABLED=true
676
- - AXIODB_TLS=true
677
- - AXIODB_TLS_CERT_PATH=/certs/cert.pem
678
- - AXIODB_TLS_KEY_PATH=/certs/key.pem
679
- - AXIODB_ROOT_NAME=AxioDB
680
- volumes:
681
- - ./mycerts:/certs:ro # your real cert.pem/key.pem folder -> /certs in the container
682
- - axiodb-data:/app # Docker-managed volume for database files
683
- restart: unless-stopped
684
-
685
- volumes:
686
- axiodb-data:
687
- ```
688
-
689
- **Building the image from source, and a fuller Docker troubleshooting guide** (container won't start, port-in-use, data-persistence checks) live in [`Docker/README.md`](Docker/README.md) β€” the canonical Docker doc, not duplicated here in full.
690
-
691
- ---
692
-
693
- ## πŸ€– MCP Server β€” AI Agent Integration
694
-
695
- Spin up the same Docker container with `AXIODB_MCP=true` and let Claude (or any MCP-compatible
696
- AI agent) talk to your AxioDB instance directly β€” 43 tools covering databases, collections,
697
- documents, aggregation, indexes, dashboard stats, and user/role management, all gated by the
698
- same RBAC as the web GUI. It runs in the same process as your existing container; nothing new
699
- to install, no second database instance.
700
-
701
- ```bash
702
- docker run -d \
703
- --name axiodb-server \
704
- -e AXIODB_GUI=true \
705
- -e AXIODB_MCP=true \
706
- -p 27018:27018 \
707
- -p 27019:27019 \
708
- -p 27020:27020 \
709
- -v axiodb-data:/app \
710
- theankansaha/axiodb
711
- ```
712
-
713
- Register the endpoint (`http://localhost:27020/mcp`) with whichever AI tool you use:
714
-
715
- | Tool | How |
716
- | --- | --- |
717
- | **Claude Code** | `claude mcp add --transport http axiodb http://localhost:27020/mcp` |
718
- | **OpenAI Codex CLI** | `codex mcp add axiodb --url http://localhost:27020/mcp` (or `[mcp_servers.axiodb]` + `url = "..."` in `~/.codex/config.toml`) |
719
- | **opencode** | `opencode mcp add` (interactive β†’ type "remote") or add `"axiodb": { "type": "remote", "url": "...", "enabled": true }` under `mcp` in `opencode.json` |
720
- | **GitHub Copilot CLI** | `/mcp add` inside the `copilot` REPL, or add to `~/.copilot/mcp-config.json`: `{ "mcpServers": { "axiodb": { "type": "http", "url": "..." } } }` |
721
- | **Cursor** | Add to `.cursor/mcp.json` (or `~/.cursor/mcp.json`): `{ "mcpServers": { "axiodb": { "url": "..." } } }` |
722
- | **Windsurf** | Add to `~/.codeium/windsurf/mcp_config.json`: `{ "mcpServers": { "axiodb": { "serverUrl": "..." } } }` |
723
- | **Google Antigravity** (IDE & CLI) | Add to `~/.gemini/config/mcp_config.json`: `{ "mcpServers": { "axiodb": { "serverUrl": "..." } } }` β€” note `serverUrl`, not `url` |
63
+ ## Basic CRUD
724
64
 
725
- Every tool except `axiodb_login` requires a `sessionId` obtained by logging in first (default
726
- seeded account: `admin`/`admin`, same as the GUI) β€” every subsequent call is checked against
727
- that logged-in user's actual role, exactly like the HTTP Control Server. A View-role session
728
- gets a real `403` on write tools; nothing is gated by a static container environment variable.
729
-
730
- `AXIODB_MCP=true` only has RBAC to serve once it's actually seeded, which requires
731
- `AXIODB_GUI=true` (the default) or `AXIODB_TCP=true` + `AXIODB_TCP_AUTH_ENABLED=true`.
732
-
733
- Full tool catalogue, examples, and security notes: **[MCP Server docs](https://axiodb.in/mcp-server)**.
734
-
735
- ---
736
-
737
- ## 🎨 Built-in Web GUI & Authentication (RBAC)
738
-
739
- AxioDB includes a built-in web-based GUI for database visualization and management β€” perfect for Electron apps and development environments.
740
-
741
- ### Enabling the GUI
742
-
743
- ```javascript
744
- // Enable GUI when creating the AxioDB instance
745
- const db = new AxioDB({ GUI: true }); // GUI available at localhost:27018
746
-
747
- // With a custom database path
748
- const db = new AxioDB({ GUI: true, RootName: "MyDB", CustomPath: "./custom/path" });
749
- ```
750
-
751
- **GUI Features:** visual database and collection browser, real-time data inspection, query execution interface, performance monitoring, no external dependencies required. Access at `http://localhost:27018` when enabled.
752
-
753
- ### Authentication & Access Control
754
-
755
- The Control Server ships with built-in login and role-based access control (RBAC) β€” the same system TCP's [`TCPAuth`](#advanced-tcp-authentication) reuses. On first start with `GUI: true` (or `TCP: true, TCPAuth: true`), AxioDB seeds a reserved `config` database (hidden from the regular database list) containing three collections β€” `users`, `roles`, `permissions` β€” and a default account:
756
-
757
- ```
758
- Username: admin
759
- Password: admin
760
- ```
761
-
762
- You'll be forced to change this password on first login (this applies to every account, not just the default one β€” there's currently no way around it other than completing the change via the GUI). Three predefined roles are seeded automatically:
763
-
764
- | Role | Access |
765
- |------|--------|
766
- | **Super Admin** | Full access, including creating users/roles |
767
- | **Admin** | Full database/collection/document access, no user or role management |
768
- | **View** | Read-only access to databases, collections, documents, and indexes |
769
-
770
- A Super Admin can create additional roles from the predefined permission catalogue and create new users with any role. Sessions are held only in server memory (never persisted to disk) and are tied to an httpOnly cookie, so restarting the server logs everyone out.
771
-
772
- **Login rate limiting:** after 5 failed login attempts from the same IP within a trailing 15-minute window, that IP is locked out for 15 minutes (`429 Too Many Requests`) β€” regardless of username. This limiter is shared with [TCP `AUTHENTICATE` attempts](#advanced-tcp-authentication) (see [Troubleshooting](#-troubleshooting) for what the error looks like).
773
-
774
- **Index management:** the Control Server also exposes `GET /api/index/list`, `POST /api/index/create`, and `DELETE /api/index/delete`, gated by the same `index:view` / `index:create` / `index:delete` permissions (View role gets view-only, Admin and Super Admin get all three).
775
-
776
- > **Security note:** RBAC protects the Control Server's HTTP API and TCP server, but the HTTP GUI itself has no TLS support - keep it on a trusted local/private network, not public internet exposure. The TCP server *can* be encrypted (see [Advanced: TLS encryption](#advanced-tls-encryption)), which is recommended if it's reachable over any untrusted network.
777
-
778
- ---
779
-
780
- ## πŸ› οΈ Detailed Usage
781
-
782
- ### Collection Creation Options
783
-
784
- ```javascript
785
- createCollection(
786
- name: string, // Name of the collection (required)
787
- )
788
- ```
789
-
790
- ### Example
791
-
792
- ```javascript
793
- const { AxioDB } = require("axiodb");
794
- const db = new AxioDB();
795
-
796
- const userDB = await db.createDB("MyDB");
797
-
798
- // Create a collection
799
- const userCollection = await userDB.createCollection("Users");
800
-
801
- await userCollection.insert({
802
- name: "John Doe",
803
- email: "john.doe@example.com",
804
- age: 30,
805
- });
806
-
807
- const results = await userCollection
808
- .query({ age: { $gt: 25 } })
809
- .Limit(10)
810
- .Sort({ age: 1 })
811
- .exec();
812
- console.log(results.data.documents);
813
- ```
814
-
815
- ### Worked example: e-commerce product catalog
65
+ CRUD means **Create, Read, Update, and Delete**. The following example creates a database and
66
+ collection, then demonstrates each basic operation:
816
67
 
817
68
  ```javascript
818
69
  const { AxioDB } = require('axiodb');
819
- const db = new AxioDB();
820
-
821
- const shopDB = await db.createDB('ecommerce');
822
- const products = await shopDB.createCollection('products');
823
70
 
824
- await products.insert({
825
- name: 'Laptop',
826
- price: 999.99,
827
- category: 'Electronics',
828
- inStock: true,
829
- });
830
-
831
- // Sorted, filtered query
832
- const electronics = await products
833
- .query({ category: 'Electronics', inStock: true })
834
- .Sort({ price: 1 })
835
- .exec();
836
- ```
837
-
838
- ---
839
-
840
- ## 🌟 Advanced Features
841
-
842
- - **Multiple Databases:** architect scalable apps with multiple databases and collections, each with independent security settings
843
- - **Custom Query Processing:** the full operator set (`$gt`, `$lt`, `$in`, `$regex`, `$gte`, `$lte`, `$ne`, `$nin`, `$exists`, `$or`, `$and`) plus aggregation pipelines
844
- - **Enterprise Data Management:** bulk operations, conditional updates, atomic transactions
845
- - **Performance Optimization:** fast lookups, pagination, and intelligent caching with random TTL
846
-
847
- ---
848
-
849
- ## πŸ“– API Reference
850
-
851
- ### AxioDB
852
-
853
- - `createDB(dbName: string): Promise<Database>`
854
- - `deleteDatabase(dbName: string): Promise<SuccessInterface | ErrorInterface>`
855
- - `isDatabaseExists(dbName: string): Promise<boolean>`
856
- - `getInstanceInfo(): Promise<SuccessInterface | undefined>`
857
-
858
- ### Database
859
-
860
- - `createCollection(name: string): Promise<Collection>`
861
- - `deleteCollection(name: string): Promise<SuccessInterface | ErrorInterface>`
862
- - `isCollectionExists(name: string): Promise<boolean>`
863
- - `getCollectionInfo(): Promise<SuccessInterface>`
864
-
865
- ### Collection
866
-
867
- - `insert(document: object): Promise<SuccessInterface | ErrorInterface>`
868
- - `insertMany(documents: object | object[]): Promise<SuccessInterface | ErrorInterface>`
869
- - `totalDocuments(): Promise<SuccessInterface | ErrorInterface>`
870
- - `query(query: object): Reader`
871
- - `update(query: object): Updater`
872
- - `delete(query: object): Deleter`
873
- - `aggregate(pipeline: object[]): Aggregation`
874
- - `startSession(options?: SessionOptions): Session`
875
- - `newIndex(...fieldNames: string[]): Promise<SuccessInterface>`
876
- - `dropIndex(indexName: string): Promise<SuccessInterface | ErrorInterface>`
877
- - `getIndexes(): Promise<SuccessInterface | ErrorInterface>` β€” lists all indexes registered on the collection
878
-
879
- ### Updater / Deleter
880
-
881
- `update(query)` and `delete(query)` on their own don't change anything β€” they return a chainable object. Call one of the methods below to actually apply the change:
882
-
883
- Updates are flat shallow merges. AxioDB does not implement MongoDB update operators such as `$inc`, `$set`, or `$push`; keys beginning with `$` are stored as ordinary field names.
884
-
885
- - `updater.UpdateOne(data: object): Promise<SuccessInterface | ErrorInterface>` β€” applies `data` to the first document matching `query`
886
- - `updater.UpdateMany(data: object): Promise<SuccessInterface | ErrorInterface>` β€” applies `data` to every document matching `query`
887
- - `deleter.deleteOne(): Promise<SuccessInterface | ErrorInterface>` β€” deletes the first document matching `query`
888
- - `deleter.deleteMany(): Promise<SuccessInterface | ErrorInterface>` β€” deletes every document matching `query`
889
-
890
- ```javascript
891
- // Update the first matching document
892
- await collection.update({ name: 'Alice' }).UpdateOne({ status: 'active' });
893
-
894
- // Update every matching document
895
- await collection.update({ role: 'trial' }).UpdateMany({ role: 'active' });
896
-
897
- // Delete the first matching document
898
- await collection.delete({ name: 'Alice' }).deleteOne();
899
-
900
- // Delete every matching document
901
- await collection.delete({ status: 'inactive' }).deleteMany();
902
- ```
903
-
904
- ### Reader
905
-
906
- - `Limit(limit: number): Reader`
907
- - `Skip(skip: number): Reader`
908
- - `Sort(sort: object): Reader`
909
- - `setCount(count: boolean): Reader`
910
- - `setProject(project: object): Reader`
911
- - `exec(): Promise<SuccessInterface | ErrorInterface>`
912
- - `findOne(): Promise<SuccessInterface | ErrorInterface>`
913
-
914
- ### Transaction (Session)
915
-
916
- - `startSession(options?: { timeout?: number }): Session`
917
- - `session.withTransaction(callback: (transaction: Transaction) => Promise<void>): Promise<SuccessInterface | ErrorInterface>`
918
- - `session.startTransaction(): Transaction`
919
- - `transaction.insert(document: object): Transaction`
920
- - `transaction.update(query: object, update: object): Transaction`
921
- - `transaction.delete(query: object): Transaction`
922
- - `transaction.savepoint(name: string): Transaction`
923
- - `transaction.rollbackToSavepoint(name: string): Transaction`
924
- - `transaction.commit(): Promise<SuccessInterface>`
925
- - `transaction.rollback(): Promise<SuccessInterface | ErrorInterface>`
926
-
927
- ### MCP transactions (Docker image)
928
-
929
- The Docker-only MCP server exposes authenticated, single-collection ACID transactions with
930
- insert, update, delete, savepoint, commit, and rollback tools. Begin with
931
- `axiodb_begin_transaction`, then pass its `transactionId` to the other transaction tools.
932
-
933
- ### TCP Transaction Proxy
934
-
935
- - `collection.beginTransaction(): Promise<TransactionProxy>`
936
- - `transactionProxy.insert(data: object): Promise<unknown>`
937
- - `transactionProxy.insertMany(documents: object[]): Promise<unknown>`
938
- - `transactionProxy.query(query: object, options?): Promise<unknown>`
939
- - `transactionProxy.findByIds(ids: string[]): Promise<unknown>`
940
- - `transactionProxy.updateById(documentId: string, updateData: object): Promise<unknown>`
941
- - `transactionProxy.updateByQuery(query: object, updateData: object, updateOne?: boolean): Promise<unknown>`
942
- - `transactionProxy.deleteById(documentId: string): Promise<unknown>`
943
- - `transactionProxy.deleteByQuery(query: object, deleteOne?: boolean): Promise<unknown>`
944
- - `transactionProxy.savepoint(name: string): Promise<unknown>`
945
- - `transactionProxy.rollbackToSavepoint(name: string): Promise<unknown>`
946
- - `transactionProxy.releaseSavepoint(name: string): Promise<unknown>`
947
- - `transactionProxy.commit(): Promise<unknown>`
948
- - `transactionProxy.rollback(): Promise<unknown>`
949
-
950
- ---
951
-
952
- ## βœ… Best Practices
953
-
954
- **Use environment variables for TCP credentials β€” never hardcode them:**
955
-
956
- ```javascript
957
- // ❌ Bad
958
- const client = new AxioDBCloud("axiodb://localhost:27019", {
959
- username: 'admin',
960
- password: 'myPassword123',
961
- });
962
-
963
- // βœ… Good
964
- const client = new AxioDBCloud("axiodb://localhost:27019", {
965
- username: process.env.AXIODB_TCP_USERNAME,
966
- password: process.env.AXIODB_TCP_PASSWORD,
967
- });
968
- ```
969
-
970
- **Use `documentId` for the fastest possible lookups** β€” it's the one field that's always indexed automatically, backed by `InMemoryCache`:
971
-
972
- ```javascript
973
- const user = await collection.query({ documentId: 'ABC123' }).exec();
974
- ```
71
+ const db = new AxioDB();
72
+ const database = await db.createDB('AppDB');
73
+ const users = await database.createCollection('users');
975
74
 
976
- **Handle errors explicitly** β€” AxioDB operations reject/return error responses rather than throwing silently:
75
+ // Create: insert a document. AxioDB adds documentId and updatedAt automatically.
76
+ const created = await users.insert({ name: 'Alice', email: 'alice@example.com', age: 30 });
77
+ const userId = created.data.documentId;
977
78
 
978
- ```javascript
979
- try {
980
- await collection.insert({ name: 'User' });
981
- } catch (error) {
982
- console.error('Insert failed:', error);
983
- }
984
- ```
79
+ // Read: query documents and execute the chainable reader.
80
+ const result = await users.query({ age: { $gte: 18 } }).exec();
81
+ console.log(result.data.documents);
985
82
 
986
- **Clean up resources you no longer need:**
83
+ // Update: update the first document matching the query.
84
+ await users.update({ documentId: userId }).UpdateOne({ age: 31 });
987
85
 
988
- ```javascript
989
- await database.deleteCollection('tempCollection');
990
- await db.deleteDatabase('tempDB');
86
+ // Delete: delete the first document matching the query.
87
+ await users.delete({ documentId: userId }).deleteOne();
991
88
  ```
992
89
 
993
- **Access control:**
994
- - Never hardcode credentials β€” use environment variables or a secrets manager
995
- - Implement proper access controls and take regular backups
996
- - For AxioDBCloud/GUI, rotate the default `admin` password immediately (see [Authentication & Access Control](#-built-in-web-gui--authentication-rbac))
997
-
998
- For vulnerability reporting, see [SECURITY.md](SECURITY.md).
999
-
1000
- ---
1001
-
1002
- ## βš™οΈ Architecture & Internal Mechanisms
1003
-
1004
- - **Tree Structure for Fast Data Retrieval:** hierarchical storage enables O(1) document lookups and efficient indexing. Each document is isolated in its own file, supporting selective loading and easy backup.
1005
- - **Worker Threads for Parallel Processing:** leverages Node.js Worker Threads for non-blocking I/O, multi-core utilization, and scalable performance β€” especially for read operations.
1006
- - **`InMemoryCache` System:** automatic eviction policies, TTL support, and memory optimization, delivering sub-millisecond response times for frequently accessed data.
1007
- - **Query Processing Pipeline:** intelligent caching, parallelized processing, lazy evaluation, and just-in-time query optimization.
1008
- - **Single Instance Architecture:** ensures ACID compliance, strong data consistency, and simplified deployment β€” one `AxioDB` instance manages all databases and collections.
1009
- - **Designed for Node.js Developers:** native JavaScript API, promise-based interface, lightweight dependency footprint, simple learning curve.
1010
-
1011
- ---
1012
-
1013
- ## πŸ† Comparisons
1014
-
1015
- ### AxioDB vs SQLite
1016
-
1017
- | Feature | SQLite | AxioDB |
1018
- | ------- | ------ | ------ |
1019
- | **Native Dependencies** | ❌ Yes (C bindings) | βœ… Pure JavaScript |
1020
- | **Query Language** | SQL Strings | JavaScript Objects |
1021
- | **Schema Migrations** | ❌ Required (ALTER TABLE) | βœ… Schema-less |
1022
- | **Built-in Caching** | ⚠️ Manual | βœ… InMemoryCache |
1023
- | **Multi-core Processing** | ❌ Single-threaded | βœ… Worker Threads |
1024
- | **Built-in GUI** | ❌ External tools only | βœ… Web interface included |
1025
- | **Best For** | 10M+ records, relational data | 10K–500K documents, embedded apps |
1026
-
1027
- ### AxioDB vs Traditional JSON Files
1028
-
1029
- | Feature | Traditional JSON Files | AxioDB |
1030
- | ------- | --------------------- | ------ |
1031
- | **Storage** | Single JSON file | File-per-document |
1032
- | **Caching** | None | InMemoryCache |
1033
- | **Indexing** | None | Auto `documentId` + custom fields |
1034
- | **Query Speed** | Linear O(n) | Sub-millisecond O(1) |
1035
- | **Scalability** | Poor | Excellent (up to sweet spot) |
1036
- | **Built-in Query Operators** | None | `$gt`, `$lt`, `$regex`, `$in`, ... |
1037
-
1038
- **Benchmark:** AxioDB's `documentId` search with `InMemoryCache` provides instant retrieval compared to traditional JSON files, which require full-file parsing (tested with 1M+ documents).
1039
-
1040
- ### AxioDB vs lowdb, nedb, better-sqlite3
1041
-
1042
- | Feature | lowdb | nedb | better-sqlite3 | AxioDB |
1043
- |---------|-------|------|---------------|--------|
1044
- | **Maintained** | βœ… | ❌ Abandoned | βœ… | βœ… |
1045
- | **Native bindings** | βœ… None | βœ… None | ❌ Yes (C/node-gyp) | βœ… None |
1046
- | **Storage** | Single JSON file | Single file / in-memory | Single .db file | File-per-document |
1047
- | **Query language** | JS/Lodash | JS objects | SQL strings | JS objects (MongoDB-style) |
1048
- | **Built-in caching** | ❌ | ❌ | ❌ | βœ… InMemoryCache |
1049
- | **Worker Threads** | ❌ | ❌ | ❌ | βœ… |
1050
- | **ACID Transactions** | ❌ | ❌ | βœ… | βœ… |
1051
- | **Aggregation Pipelines** | ❌ | Partial | ❌ | βœ… 60+ stages, $lookup, custom operators |
1052
- | **TypeScript support** | βœ… | Partial | βœ… | βœ… Full |
1053
- | **Electron compatible** | βœ… | βœ… | ❌ (requires rebuild) | βœ… |
1054
- | **Sweet spot** | <5K docs | <100K docs | 10M+ (relational) | 10K–500K docs |
1055
- | **Built-in GUI** | ❌ | ❌ | ❌ | βœ… localhost:27018 |
90
+ Use `UpdateMany()` or `deleteMany()` when the operation should affect every matching document.
91
+ Updates are flat merges; MongoDB update operators such as `$inc`, `$set`, and `$push` are not
92
+ supported.
1056
93
 
1057
- ---
94
+ ## Features
1058
95
 
1059
- ## ⚠️ Limitations & Honest Positioning
96
+ * **Zero native deps** β€” pure JS, no `node-gyp`, no `electron-rebuild`
97
+ * **MongoDB-style queries** β€” `{ age: { $gt: 25 } }`, 19 operators + `hint()` + `findByIds()`
98
+ * **ACID transactions** β€” `savepoint`/`rollbackTo`/`WAL`, crashes recover via `Transaction.recoverTransactions()`
99
+ * **Aggregation** β€” 60+ stages, `$lookup` joins, `OperatorRegistry` custom ops
100
+ * **InMemoryCache + indexes** β€” dual-write, auto `IndexCache`
101
+ * **Ports:** GUI `27018` Β· TCP `27019` `AxioDBCloud` Β· MCP `27020` Docker-only
1060
102
 
1061
- - **Dataset Size:** optimized for 10K–500K documents. For 10M+, use PostgreSQL, MongoDB, or SQLite.
1062
- - **Concurrency:** single-instance architecture. For multi-user web apps with hundreds of concurrent connections, use a traditional client-server database.
1063
- - **Relational Data:** document-based NoSQL, no JOIN operations. For complex relational data with foreign keys, use a SQL database.
1064
- - **Distributed Systems:** single-node only β€” no replication, sharding, or clustering. Use MongoDB or CouchDB for that.
1065
- - **Transactions:** single-collection ACID transactions only. For cross-collection transaction requirements, use PostgreSQL or MongoDB.
103
+ > **Docs:** `axiodb.in` is the single source β€” this README is a quick start only.
1066
104
 
1067
- None of this is a shortcoming to apologize for β€” AxioDB is deliberately scoped to the embedded/local-first niche. When you outgrow it, that's a sign to migrate, not a bug to file.
105
+ * **AxioDBCloud (TCP)** β€” remote `AxioDBCloud` client, 32 commands, optional `TCPAuth` + `TLS` β†’ [axiodb.in/cloud](https://axiodb.in/cloud)
106
+ * **CLI (Go)** β€” `axiodb document insert/query` `--hint` `find-by-ids` `transaction begin/commit` `user change-password` (HTTP `27018` for management, TCP `27019` for data) β†’ [axiodb.in/cli](https://axiodb.in/cli)
107
+ * **Docker** β€” `theankansaha/axiodb` `AXIODB_GUI/TCP/MCP` `27018/27019/27020` β†’ [axiodb.in/docker](https://axiodb.in/docker)
108
+ * **MCP Server** β€” 43 tools `axiodb_login` β†’ `sessionId` + `withConfirmation` `Docker/mcp/tools/*.js` β†’ [axiodb.in/mcp-server](https://axiodb.in/mcp-server)
109
+ * **GUI + RBAC** β€” `Super Admin/Admin/View`, `mustChangePassword`, `LoginRateLimiter` β†’ [axiodb.in/security](https://axiodb.in/security)
110
+ * **API & Types** β€” `Document/src/data/serverApi.ts` 41 endpoints `openapi.json`, TS 6.0 strict β†’ [axiodb.in/api-reference](https://axiodb.in/api-reference) [axiodb.in/server-api](https://axiodb.in/server-api)
1068
111
 
1069
112
  ---
1070
113
 
1071
- ## ❓ FAQ
1072
-
1073
- **Q: What is AxioDB?**
1074
- An embedded NoSQL database for Node.js. Pure JavaScript, zero native dependencies. `npm install axiodb` and you have a database β€” no server, no `node-gyp`, no `electron-rebuild`.
1075
-
1076
- **Q: Is AxioDB a replacement for MongoDB?**
1077
- No. AxioDB is embedded (runs inside your app); MongoDB is a client-server database for multi-user systems. Use AxioDB for desktop apps, CLI tools, and local-first apps up to ~500K documents; use MongoDB when you need a shared networked database.
1078
-
1079
- **Q: Does AxioDB work with Electron?**
1080
- Yes β€” this is the primary use case it was built for. Zero native dependencies means no `electron-rebuild`, no platform-specific `.node` files, no compilation step.
1081
-
1082
- **Q: How does AxioDB compare to better-sqlite3 / lowdb / nedb?**
1083
- See the [Comparisons](#-comparisons) tables above for the full breakdown β€” in short: no native bindings (unlike better-sqlite3), no single-file bottleneck (unlike lowdb), and actively maintained with TypeScript/transactions (unlike the abandoned nedb).
1084
-
1085
- **Q: How many documents can AxioDB handle?**
1086
- Optimized for 10,000–500,000 documents. For 1M+, use PostgreSQL or MongoDB. `documentId` lookups take ~1ms on 10K documents with `InMemoryCache`.
1087
-
1088
- **Q: Does AxioDB support TypeScript?**
1089
- Yes. Full type definitions are included β€” no separate `@types` package needed.
1090
-
1091
- **Q: Does AxioDB work in the browser?**
1092
- No. AxioDB requires Node.js (v20+) and the filesystem β€” server-side and desktop only.
1093
-
1094
- **Q: What is AxioDBCloud?**
1095
- TCP-based remote access for AxioDB. Deploy AxioDB in Docker, connect from multiple clients with the exact same API. Supports 1,000+ concurrent connections with auto-reconnect. Optional username/password authentication (`TCPAuth: true`) reuses the same RBAC accounts as the GUI, and optional TLS encryption (`TLS: true`) protects the wire protocol on untrusted networks β€” see [AxioDBCloud](#-axiodbcloud--connecting-remotely) above.
1096
-
1097
- ---
114
+ ## Contributing, License & Support
1098
115
 
1099
- ## 🀝 Contributing, License & Support
116
+ * **Contributing:** see [CONTRIBUTING.md](CONTRIBUTING.md) + [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)
117
+ * **Security:** see [SECURITY.md](SECURITY.md) β€” `admin/admin` must change password, report via GitHub Security Advisories
118
+ * **License:** MIT β€” [LICENSE](LICENSE)
119
+ * **Support:** ⭐ star, πŸ› issues, πŸ’‘ discussions β€” [https://github.com/nexoral/AxioDB](https://github.com/nexoral/AxioDB) Β· [sponsor](https://github.com/sponsors/AnkanSaha)
1100
120
 
1101
- **Contributing:** we welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
1102
-
1103
- **License:** MIT. See [LICENSE](LICENSE).
1104
-
1105
- **Requirements:** Node.js β‰₯20.0.0, npm β‰₯6.0.0, yarn β‰₯1.0.0 (optional).
1106
-
1107
- **Documentation website:** built with React 18 + TypeScript, Vite, TailwindCSS, and Lucide React. To run it locally:
1108
- ```bash
1109
- cd Document
1110
- npm install
1111
- npm run dev
1112
- ```
1113
- Available at `http://localhost:5173`.
1114
-
1115
- **Author:** Ankan Saha
1116
-
1117
- **Support the project:**
1118
- - ⭐ Star the repository
1119
- - πŸ› Report issues
1120
- - πŸ’‘ Suggest features
1121
- - 🀝 Contribute code
1122
- - πŸ’° [Sponsor the project](https://github.com/sponsors/AnkanSaha)
1123
-
1124
- **Acknowledgments:** special thanks to all contributors and supporters of AxioDB β€” your feedback and contributions make this project better.
1125
-
1126
- ---
121
+ **Author:** Ankan Saha Β· **Docs:** `cd Document && npm run dev` `http://localhost:5173`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axiodb",
3
- "version": "20.3.3",
3
+ "version": "20.5.2",
4
4
  "description": "SQLite Alternative for JavaScript. Embedded NoSQL database for Node.js with MongoDB-style queries, zero native dependencies, built-in InMemoryCache, and web GUI. Perfect for desktop apps, CLI tools, and embedded systems. No compilation, no platform issuesβ€”pure JavaScript from npm install to production.",
5
5
  "main": "./lib/config/DB.js",
6
6
  "types": "./lib/config/DB.d.ts",