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.
- package/README.md +56 -1061
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,1106 +21,101 @@
|
|
|
21
21
|
[](https://www.typescriptlang.org/)
|
|
22
22
|
[](https://www.npmjs.com/package/axiodb)
|
|
23
23
|
|
|
24
|
-
π **[Official Documentation](https://axiodb.in/)**:
|
|
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
|
-
##
|
|
28
|
+
## What is AxioDB?
|
|
29
29
|
|
|
30
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
539
|
-
|
|
540
|
-
|
|
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
|
-
|
|
572
|
-
|
|
573
|
-
### Raising libuv's thread pool for higher disk-I/O concurrency
|
|
46
|
+
## Objective
|
|
574
47
|
|
|
575
|
-
|
|
48
|
+
**Great for:** Electron, CLI tools, embedded systems, local-first apps, rapid prototyping.
|
|
576
49
|
|
|
577
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
586
|
-
|
|
587
|
-
### Simple: run the container
|
|
56
|
+
## Installation
|
|
588
57
|
|
|
589
58
|
```bash
|
|
590
|
-
|
|
591
|
-
|
|
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
|
-
|
|
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
|
-
|
|
726
|
-
|
|
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
|
-
|
|
825
|
-
|
|
826
|
-
|
|
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
|
-
|
|
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
|
-
|
|
979
|
-
|
|
980
|
-
|
|
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
|
-
|
|
83
|
+
// Update: update the first document matching the query.
|
|
84
|
+
await users.update({ documentId: userId }).UpdateOne({ age: 31 });
|
|
987
85
|
|
|
988
|
-
|
|
989
|
-
await
|
|
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
|
-
|
|
994
|
-
|
|
995
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
**
|
|
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
|
+
"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",
|