xdb-driver 1.0.0
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/LICENSE +21 -0
- package/README.md +663 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +24 -0
- package/dist/types/definitions.d.ts +44 -0
- package/dist/types/definitions.js +7 -0
- package/dist/xdb-client.d.ts +78 -0
- package/dist/xdb-client.js +196 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License Copyright (c) 2026 Firr, The Creator.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted,
|
|
4
|
+
free of charge, to any person obtaining a copy of this software and associated
|
|
5
|
+
documentation files (the "Software"), to deal in the Software without
|
|
6
|
+
restriction, including without limitation the rights to use, copy, modify, merge,
|
|
7
|
+
publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to the
|
|
9
|
+
following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice
|
|
12
|
+
(including the next paragraph) shall be included in all copies or substantial
|
|
13
|
+
portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
16
|
+
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
|
18
|
+
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
19
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
20
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
# Node.js XDB Driver
|
|
2
|
+
|
|
3
|
+
> A high-performance TypeScript driver for the XDB NoSQL database engine
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/node-xdb-driver)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
9
|
+
## 📋 Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Overview](#overview)
|
|
12
|
+
- [Features](#features)
|
|
13
|
+
- [Prerequisites](#prerequisites)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Quick Start](#quick-start)
|
|
16
|
+
- [API Reference](#api-reference)
|
|
17
|
+
- [Usage Examples](#usage-examples)
|
|
18
|
+
- [Configuration](#configuration)
|
|
19
|
+
- [Error Handling](#error-handling)
|
|
20
|
+
- [Testing](#testing)
|
|
21
|
+
- [XDB Server Setup](#xdb-server-setup)
|
|
22
|
+
- [Architecture](#architecture)
|
|
23
|
+
- [Contributing](#contributing)
|
|
24
|
+
- [License](#license)
|
|
25
|
+
|
|
26
|
+
## 🎯 Overview
|
|
27
|
+
|
|
28
|
+
Node.js XDB Driver is a modern TypeScript client library for interacting with the XDB database engine—a lightweight, high-performance NoSQL database written in C. It provides a Promise-based API for seamless integration with Node.js applications while maintaining type safety through TypeScript.
|
|
29
|
+
|
|
30
|
+
The driver handles TCP communication with the XDB server, manages connection state, buffers streaming data, and provides comprehensive error reporting with helpful diagnostics.
|
|
31
|
+
|
|
32
|
+
## ✨ Features
|
|
33
|
+
|
|
34
|
+
- **Type-Safe API**: Full TypeScript support with generics for compile-time type checking
|
|
35
|
+
- **Promise-Based**: Modern async/await syntax for all operations
|
|
36
|
+
- **Connection Management**: Automatic connection pooling and error recovery
|
|
37
|
+
- **Stream Buffering**: Handles TCP packet fragmentation transparently
|
|
38
|
+
- **Error Diagnostics**: Helpful error messages when the server is unavailable
|
|
39
|
+
- **Zero Dependencies**: Lightweight implementation using only Node.js built-ins
|
|
40
|
+
- **Production Ready**: Thoroughly tested and used in production environments
|
|
41
|
+
|
|
42
|
+
## 📦 Prerequisites
|
|
43
|
+
|
|
44
|
+
Before using Node.js XDB Driver, ensure you have:
|
|
45
|
+
|
|
46
|
+
| Requirement | Version | Purpose |
|
|
47
|
+
| ----------- | ------- | ------------------------------------------------------------ |
|
|
48
|
+
| Node.js | 14.0+ | JavaScript runtime |
|
|
49
|
+
| npm or pnpm | Latest | Package manager |
|
|
50
|
+
| XDB Server | 1.0+ | Database backend (see [XDB Server Setup](#xdb-server-setup)) |
|
|
51
|
+
|
|
52
|
+
## 🚀 Installation
|
|
53
|
+
|
|
54
|
+
### Via npm
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm install xdb-driver
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Via pnpm
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pnpm add xdb-driver
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Via yarn
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
yarn add xdb-driver
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## ⚡ Quick Start
|
|
73
|
+
|
|
74
|
+
### Basic Connection
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { XDBClient } from 'xdb-driver';
|
|
78
|
+
|
|
79
|
+
const db = new XDBClient({ host: '127.0.0.1', port: 8080 });
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
await db.connect();
|
|
83
|
+
console.log('Connected to XDB');
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error('Connection failed:', error);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### CRUD Operations
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { XDBClient } from 'xdb-driver';
|
|
93
|
+
|
|
94
|
+
interface User {
|
|
95
|
+
username: string;
|
|
96
|
+
email: string;
|
|
97
|
+
active: boolean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const db = new XDBClient();
|
|
101
|
+
await db.connect();
|
|
102
|
+
|
|
103
|
+
// Insert a document
|
|
104
|
+
const createResult = await db.insert<User>('users', {
|
|
105
|
+
username: 'alice',
|
|
106
|
+
email: 'alice@example.com',
|
|
107
|
+
active: true,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
console.log(`Document created with ID: ${createResult.data?._id}`);
|
|
111
|
+
|
|
112
|
+
// Find documents
|
|
113
|
+
const users = await db.find<User>('users', { active: true });
|
|
114
|
+
console.log(`Found ${users.data?.length} active users`);
|
|
115
|
+
|
|
116
|
+
// Count documents
|
|
117
|
+
const count = await db.count('users');
|
|
118
|
+
console.log(`Total users: ${count.data?.count}`);
|
|
119
|
+
|
|
120
|
+
// Delete a document
|
|
121
|
+
await db.delete('users', createResult.data?._id);
|
|
122
|
+
|
|
123
|
+
// Close connection
|
|
124
|
+
await db.close();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## 📚 API Reference
|
|
128
|
+
|
|
129
|
+
### Constructor
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
new XDBClient(options?: XDBConnectionOptions)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Parameters:**
|
|
136
|
+
|
|
137
|
+
- `options.host` (string, default: `'127.0.0.1'`) - XDB server hostname
|
|
138
|
+
- `options.port` (number, default: `8080`) - XDB server port
|
|
139
|
+
|
|
140
|
+
### Methods
|
|
141
|
+
|
|
142
|
+
#### `connect(): Promise<void>`
|
|
143
|
+
|
|
144
|
+
Establishes a connection to the XDB server.
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
await db.connect();
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Throws:** Error if connection fails
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
#### `insert<T>(collection: string, data: T): Promise<XDBResponse<InsertResult>>`
|
|
155
|
+
|
|
156
|
+
Inserts a new document into a collection.
|
|
157
|
+
|
|
158
|
+
**Parameters:**
|
|
159
|
+
|
|
160
|
+
- `collection` (string) - Collection name
|
|
161
|
+
- `data` (T) - Document data to insert
|
|
162
|
+
|
|
163
|
+
**Returns:** Promise with inserted document including auto-generated `_id`
|
|
164
|
+
|
|
165
|
+
**Example:**
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const result = await db.insert('users', { name: 'Alice', email: 'alice@example.com' });
|
|
169
|
+
console.log(result.data?._id); // Auto-generated ID
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
#### `find<T>(collection: string, query?: Record<string, any>, limit?: number): Promise<XDBResponse<T[]>>`
|
|
175
|
+
|
|
176
|
+
Queries documents in a collection with optional filtering.
|
|
177
|
+
|
|
178
|
+
**Parameters:**
|
|
179
|
+
|
|
180
|
+
- `collection` (string) - Collection name
|
|
181
|
+
- `query` (object, optional) - Filter criteria (exact match semantics)
|
|
182
|
+
- `limit` (number, optional) - Maximum number of results to return
|
|
183
|
+
|
|
184
|
+
**Returns:** Promise with array of matching documents
|
|
185
|
+
|
|
186
|
+
**Example:**
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
const admins = await db.find('users', { role: 'admin' }, 10);
|
|
190
|
+
console.log(`Found ${admins.data?.length} admins`);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
#### `count(collection: string, query?: Record<string, any>): Promise<XDBResponse<CountResult>>`
|
|
196
|
+
|
|
197
|
+
Returns the count of documents matching a query.
|
|
198
|
+
|
|
199
|
+
**Parameters:**
|
|
200
|
+
|
|
201
|
+
- `collection` (string) - Collection name
|
|
202
|
+
- `query` (object, optional) - Filter criteria
|
|
203
|
+
|
|
204
|
+
**Returns:** Promise with count
|
|
205
|
+
|
|
206
|
+
**Example:**
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const result = await db.count('users', { active: true });
|
|
210
|
+
console.log(`Active users: ${result.data?.count}`);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
#### `delete(collection: string, id: string): Promise<XDBResponse<void>>`
|
|
216
|
+
|
|
217
|
+
Deletes a document by ID.
|
|
218
|
+
|
|
219
|
+
**Parameters:**
|
|
220
|
+
|
|
221
|
+
- `collection` (string) - Collection name
|
|
222
|
+
- `id` (string) - Document ID to delete
|
|
223
|
+
|
|
224
|
+
**Returns:** Promise that resolves when deletion is complete
|
|
225
|
+
|
|
226
|
+
**Example:**
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
await db.delete('users', 'a1b2c3d4e5f6g7h8');
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
#### `close(): Promise<void>`
|
|
235
|
+
|
|
236
|
+
Gracefully closes the connection to the server.
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
await db.close();
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Types
|
|
243
|
+
|
|
244
|
+
#### `XDBConnectionOptions`
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
interface XDBConnectionOptions {
|
|
248
|
+
host?: string; // Default: '127.0.0.1'
|
|
249
|
+
port?: number; // Default: 8080
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
#### `XDBResponse<T>`
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
interface XDBResponse<T = any> {
|
|
257
|
+
status: 'ok' | 'error';
|
|
258
|
+
message: string;
|
|
259
|
+
data?: T;
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### `XDBAction`
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
type XDBAction = 'insert' | 'find' | 'delete' | 'count' | 'exit';
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## 💡 Usage Examples
|
|
270
|
+
|
|
271
|
+
### Type-Safe Operations
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
import { XDBClient } from 'xdb-driver';
|
|
275
|
+
|
|
276
|
+
interface Product {
|
|
277
|
+
name: string;
|
|
278
|
+
price: number;
|
|
279
|
+
inStock: boolean;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const db = new XDBClient({ host: 'localhost', port: 8080 });
|
|
283
|
+
|
|
284
|
+
async function productDemo() {
|
|
285
|
+
await db.connect();
|
|
286
|
+
|
|
287
|
+
// Insert with type safety
|
|
288
|
+
const product = await db.insert<Product>('products', {
|
|
289
|
+
name: 'Laptop',
|
|
290
|
+
price: 999.99,
|
|
291
|
+
inStock: true,
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// Find with type inference
|
|
295
|
+
const results = await db.find<Product>('products', { inStock: true });
|
|
296
|
+
results.data?.forEach((item) => {
|
|
297
|
+
console.log(`${item.name}: $${item.price}`);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
await db.close();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
productDemo().catch(console.error);
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Error Handling
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
const db = new XDBClient({ host: '127.0.0.1', port: 8080 });
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
await db.connect();
|
|
313
|
+
} catch (error: any) {
|
|
314
|
+
if (error.code === 'ECONNREFUSED') {
|
|
315
|
+
console.error('XDB server is not running. Please start it first.');
|
|
316
|
+
} else {
|
|
317
|
+
console.error('Connection error:', error.message);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Batch Operations
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
const db = new XDBClient();
|
|
326
|
+
await db.connect();
|
|
327
|
+
|
|
328
|
+
// Insert multiple documents
|
|
329
|
+
const ids = [];
|
|
330
|
+
for (const user of userData) {
|
|
331
|
+
const result = await db.insert('users', user);
|
|
332
|
+
if (result.data?._id) {
|
|
333
|
+
ids.push(result.data._id);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Query all inserted documents
|
|
338
|
+
const insertedUsers = await db.find('users', {});
|
|
339
|
+
console.log(`Inserted ${insertedUsers.data?.length} users`);
|
|
340
|
+
|
|
341
|
+
await db.close();
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## ⚙️ Configuration
|
|
345
|
+
|
|
346
|
+
### Environment Variables
|
|
347
|
+
|
|
348
|
+
While not required, you can configure the XDB server address via environment variables:
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
export XDB_HOST=127.0.0.1
|
|
352
|
+
export XDB_PORT=8080
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Programmatic Configuration
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
const db = new XDBClient({
|
|
359
|
+
host: process.env.XDB_HOST || 'localhost',
|
|
360
|
+
port: parseInt(process.env.XDB_PORT || '8080'),
|
|
361
|
+
});
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## 🚨 Error Handling
|
|
365
|
+
|
|
366
|
+
The driver provides detailed error messages for common issues:
|
|
367
|
+
|
|
368
|
+
### Connection Errors
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
try {
|
|
372
|
+
await db.connect();
|
|
373
|
+
} catch (error) {
|
|
374
|
+
console.error(error);
|
|
375
|
+
// Output if server is down:
|
|
376
|
+
// [ERROR] Could not connect to XDB at 127.0.0.1:8080
|
|
377
|
+
// [HINT] Is the XDB server running?
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Response Errors
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
const result = await db.find('users', {});
|
|
385
|
+
|
|
386
|
+
if (result.status === 'error') {
|
|
387
|
+
console.error(`Operation failed: ${result.message}`);
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Query Semantics
|
|
392
|
+
|
|
393
|
+
- **Exact Matching**: Queries require exact field matches (no regex or partial matching)
|
|
394
|
+
- **Null Handling**: Missing fields in documents do not match query filters
|
|
395
|
+
- **Pagination**: Use `limit` parameter to control result set size
|
|
396
|
+
|
|
397
|
+
## 🧪 Testing
|
|
398
|
+
|
|
399
|
+
Run the test suite:
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
npm test
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Run tests in watch mode:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
npm run test:watch
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Generate coverage report:
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
npm run test:coverage
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Writing Tests
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
import { XDBClient } from '../src';
|
|
421
|
+
|
|
422
|
+
describe('XDBClient', () => {
|
|
423
|
+
let db: XDBClient;
|
|
424
|
+
|
|
425
|
+
beforeAll(async () => {
|
|
426
|
+
db = new XDBClient();
|
|
427
|
+
await db.connect();
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
afterAll(async () => {
|
|
431
|
+
await db.close();
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
it('should insert a document', async () => {
|
|
435
|
+
const result = await db.insert('test', { value: 42 });
|
|
436
|
+
expect(result.status).toBe('ok');
|
|
437
|
+
expect(result.data?._id).toBeDefined();
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it('should find documents', async () => {
|
|
441
|
+
const result = await db.find('test', { value: 42 });
|
|
442
|
+
expect(result.data).toBeInstanceOf(Array);
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## 🗄️ XDB Server Setup
|
|
448
|
+
|
|
449
|
+
The Node.js XDB Driver requires a running XDB server. Follow these steps to set up the backend:
|
|
450
|
+
|
|
451
|
+
### Prerequisites
|
|
452
|
+
|
|
453
|
+
| Requirement | Version | Description |
|
|
454
|
+
| ------------- | ------- | ---------------------------------- |
|
|
455
|
+
| GCC | 7.0+ | C compiler with C99 support |
|
|
456
|
+
| GNU Make | 3.81+ | Build automation tool |
|
|
457
|
+
| POSIX Threads | - | For concurrent connection handling |
|
|
458
|
+
|
|
459
|
+
### Supported Platforms
|
|
460
|
+
|
|
461
|
+
- Linux (Ubuntu 20.04+, Debian, Fedora, etc.)
|
|
462
|
+
- macOS (with Homebrew-installed GCC)
|
|
463
|
+
- Other POSIX-compliant systems
|
|
464
|
+
|
|
465
|
+
### Installation Steps
|
|
466
|
+
|
|
467
|
+
#### 1. Clone the XDB Repository
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
git clone https://github.com/firrthecreator/XDB.git
|
|
471
|
+
cd XDB
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
#### 2. Verify Dependencies
|
|
475
|
+
|
|
476
|
+
Ensure the following files exist:
|
|
477
|
+
|
|
478
|
+
- `third_party/cJSON/cJSON.h`
|
|
479
|
+
- `third_party/cJSON/cJSON.c`
|
|
480
|
+
|
|
481
|
+
The cJSON library is included in the repository.
|
|
482
|
+
|
|
483
|
+
#### 3. Compile the Project
|
|
484
|
+
|
|
485
|
+
```bash
|
|
486
|
+
make
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
This command will:
|
|
490
|
+
|
|
491
|
+
- Create the `bin/` and `data/` directories
|
|
492
|
+
- Compile all source files with optimizations
|
|
493
|
+
- Link the executable to `bin/xdb`
|
|
494
|
+
|
|
495
|
+
#### 4. Clean Build Artifacts (Optional)
|
|
496
|
+
|
|
497
|
+
To remove compiled files and start fresh:
|
|
498
|
+
|
|
499
|
+
```bash
|
|
500
|
+
make clean
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
#### 5. Start the Server
|
|
504
|
+
|
|
505
|
+
```bash
|
|
506
|
+
./bin/xdb
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
The database server will start listening on `localhost:8080`.
|
|
510
|
+
|
|
511
|
+
**Expected Output:**
|
|
512
|
+
|
|
513
|
+
```
|
|
514
|
+
[08:17:43] [INFO] Initialized new database instance.
|
|
515
|
+
[08:17:43] [INFO] Server listening on 0.0.0.0:8080
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
#### 6. Run Unit Tests (Optional)
|
|
519
|
+
|
|
520
|
+
Verify the server is built correctly:
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
make test
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
**Expected Output:**
|
|
527
|
+
|
|
528
|
+
```
|
|
529
|
+
XDB Unit Test Suite
|
|
530
|
+
[TEST] test_query_exact_match PASS
|
|
531
|
+
[TEST] test_crud_workflow PASS
|
|
532
|
+
Summary: 2 Run, 0 Failed
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
### Server Configuration
|
|
536
|
+
|
|
537
|
+
By default, XDB listens on:
|
|
538
|
+
|
|
539
|
+
- **Host:** `0.0.0.0` (all interfaces)
|
|
540
|
+
- **Port:** `8080`
|
|
541
|
+
|
|
542
|
+
To modify these settings, edit `src/server.c` and recompile:
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
make clean
|
|
546
|
+
make
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### XDB API
|
|
550
|
+
|
|
551
|
+
The XDB server accepts JSON commands over TCP. For complete API documentation, see the [API Documentation](https://github.com/firrthecreator/XDB#api-documentation) in the XDB repository.
|
|
552
|
+
|
|
553
|
+
**Quick Reference:**
|
|
554
|
+
|
|
555
|
+
```bash
|
|
556
|
+
# Connect to server
|
|
557
|
+
telnet localhost 8080
|
|
558
|
+
|
|
559
|
+
# Insert a document
|
|
560
|
+
{"action": "insert", "collection": "users", "data": {"name": "Alice"}}
|
|
561
|
+
|
|
562
|
+
# Find documents
|
|
563
|
+
{"action": "find", "collection": "users", "query": {"name": "Alice"}}
|
|
564
|
+
|
|
565
|
+
# Delete a document
|
|
566
|
+
{"action": "delete", "collection": "users", "id": "uuid-here"}
|
|
567
|
+
|
|
568
|
+
# Count documents
|
|
569
|
+
{"action": "count", "collection": "users"}
|
|
570
|
+
|
|
571
|
+
# Close connection
|
|
572
|
+
{"action": "exit"}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
## 🏗️ Architecture
|
|
576
|
+
|
|
577
|
+
### Design Principles
|
|
578
|
+
|
|
579
|
+
The Node.js XDB Driver follows these architectural principles:
|
|
580
|
+
|
|
581
|
+
1. **Modularity**: Clean separation between connection, request handling, and response parsing
|
|
582
|
+
2. **Promise-Based**: Modern async/await support for intuitive control flow
|
|
583
|
+
3. **Type Safety**: Full TypeScript support with generic types for compile-time validation
|
|
584
|
+
4. **Error Resilience**: Graceful handling of network errors with helpful diagnostics
|
|
585
|
+
|
|
586
|
+
### Project Structure
|
|
587
|
+
|
|
588
|
+
```
|
|
589
|
+
src/
|
|
590
|
+
├── index.ts # Public API exports
|
|
591
|
+
├── xdb-client.ts # Main client implementation
|
|
592
|
+
└── types/
|
|
593
|
+
└── definitions.ts # TypeScript type definitions
|
|
594
|
+
|
|
595
|
+
examples/
|
|
596
|
+
└── app.ts # Usage example
|
|
597
|
+
|
|
598
|
+
tests/
|
|
599
|
+
└── xdb-client.spec.ts # Test suite
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### Component Overview
|
|
603
|
+
|
|
604
|
+
- **XDBClient**: Main entry point, handles connection lifecycle and API operations
|
|
605
|
+
- **Type Definitions**: Strict contracts for requests, responses, and configuration
|
|
606
|
+
- **Stream Handler**: Manages TCP packet buffering and JSON deserialization
|
|
607
|
+
|
|
608
|
+
## 🤝 Contributing
|
|
609
|
+
|
|
610
|
+
Contributions are welcome! Please follow these guidelines:
|
|
611
|
+
|
|
612
|
+
### Code Style
|
|
613
|
+
|
|
614
|
+
- Use TypeScript for all code
|
|
615
|
+
- Follow the existing code conventions
|
|
616
|
+
- Use 4-space indentation
|
|
617
|
+
- Use meaningful variable and function names
|
|
618
|
+
|
|
619
|
+
### Testing
|
|
620
|
+
|
|
621
|
+
- Add tests for new features
|
|
622
|
+
- Ensure all tests pass before submitting PR
|
|
623
|
+
|
|
624
|
+
```bash
|
|
625
|
+
npm test
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Commits
|
|
629
|
+
|
|
630
|
+
Use descriptive commit messages:
|
|
631
|
+
|
|
632
|
+
```
|
|
633
|
+
feat: Add support for batch operations
|
|
634
|
+
fix: Handle connection timeouts gracefully
|
|
635
|
+
docs: Update API documentation
|
|
636
|
+
test: Add integration tests
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
### Pull Request Process
|
|
640
|
+
|
|
641
|
+
1. Fork the repository
|
|
642
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
643
|
+
3. Commit your changes (`git commit -m 'feat: Amazing feature'`)
|
|
644
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
645
|
+
5. Open a Pull Request
|
|
646
|
+
|
|
647
|
+
## 📝 License
|
|
648
|
+
|
|
649
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
650
|
+
|
|
651
|
+
## 🔗 Resources
|
|
652
|
+
|
|
653
|
+
- **GitHub Repository**: [github.com/firrthecreator/node-xdb-driver](https://github.com/firrthecreator/node-xdb-driver)
|
|
654
|
+
- **XDB Server**: [github.com/firrthecreator/XDB](https://github.com/firrthecreator/XDB)
|
|
655
|
+
- **npm Package**: [npmjs.com/package/node-xdb-driver](https://www.npmjs.com/package/node-xdb-driver)
|
|
656
|
+
|
|
657
|
+
## 👨💻 Author
|
|
658
|
+
|
|
659
|
+
**Firr, The Creator** - [GitHub](https://github.com/firrthecreator)
|
|
660
|
+
|
|
661
|
+
---
|
|
662
|
+
|
|
663
|
+
**Node.js XDB Driver** © 2026. Built with ❤️ by Firr, The Creator.
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file index.ts
|
|
4
|
+
* @brief Public API exports for the Node.js XDB Driver.
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.XDBClient = void 0;
|
|
22
|
+
var xdb_client_1 = require("./xdb-client");
|
|
23
|
+
Object.defineProperty(exports, "XDBClient", { enumerable: true, get: function () { return xdb_client_1.XDBClient; } });
|
|
24
|
+
__exportStar(require("./types/definitions"), exports);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file definitions.ts
|
|
3
|
+
* @brief Core type definitions and interfaces for the Node.js XDB Driver.
|
|
4
|
+
* Defines the contract for requests, responses, and internal queue handling.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @brief Supported actions by the XDB Server.
|
|
8
|
+
*/
|
|
9
|
+
export type XDBAction = 'insert' | 'find' | 'delete' | 'count' | 'exit';
|
|
10
|
+
/**
|
|
11
|
+
* @brief Configuration options for the client connection.
|
|
12
|
+
*/
|
|
13
|
+
export interface XDBConnectionOptions {
|
|
14
|
+
host?: string;
|
|
15
|
+
port?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @brief Standard request structure sent to the C server.
|
|
19
|
+
*/
|
|
20
|
+
export interface XDBRequest {
|
|
21
|
+
action: XDBAction;
|
|
22
|
+
collection?: string;
|
|
23
|
+
data?: Record<string, any>;
|
|
24
|
+
query?: Record<string, any>;
|
|
25
|
+
limit?: number;
|
|
26
|
+
id?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* @brief Standard response structure received from the C server.
|
|
30
|
+
* @template T The type of data expected in the response.
|
|
31
|
+
*/
|
|
32
|
+
export interface XDBResponse<T = any> {
|
|
33
|
+
status: 'ok' | 'error';
|
|
34
|
+
message: string;
|
|
35
|
+
data?: T;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @brief Internal interface for managing the Promise queue.
|
|
39
|
+
* Used to map asynchronous server responses back to the correct caller.
|
|
40
|
+
*/
|
|
41
|
+
export interface ResponseResolver {
|
|
42
|
+
resolve: (value: XDBResponse | PromiseLike<XDBResponse>) => void;
|
|
43
|
+
reject: (reason?: any) => void;
|
|
44
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file definitions.ts
|
|
4
|
+
* @brief Core type definitions and interfaces for the Node.js XDB Driver.
|
|
5
|
+
* Defines the contract for requests, responses, and internal queue handling.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file xdb-client.ts
|
|
3
|
+
* @brief Main Implementation of the XDB Database Client.
|
|
4
|
+
* Handles TCP persistence, stream buffering, command dispatching,
|
|
5
|
+
* and user-friendly error reporting.
|
|
6
|
+
*/
|
|
7
|
+
import { XDBResponse, XDBConnectionOptions } from './types/definitions';
|
|
8
|
+
/**
|
|
9
|
+
* @class XDBClient
|
|
10
|
+
* @brief A persistent TCP client for interacting with the XDB Server.
|
|
11
|
+
* Encapsulates the raw socket operations and provides a Promise-based API.
|
|
12
|
+
*/
|
|
13
|
+
export declare class XDBClient {
|
|
14
|
+
private socket;
|
|
15
|
+
private isConnected;
|
|
16
|
+
private responseQueue;
|
|
17
|
+
private streamBuffer;
|
|
18
|
+
private readonly host;
|
|
19
|
+
private readonly port;
|
|
20
|
+
/**
|
|
21
|
+
* @brief Initializes the XDB Client instance.
|
|
22
|
+
* @param options Configuration object containing host and port.
|
|
23
|
+
*/
|
|
24
|
+
constructor(options?: XDBConnectionOptions);
|
|
25
|
+
/**
|
|
26
|
+
* @brief Establishes a connection to the XDB Server.
|
|
27
|
+
* * Sets up event listeners for data streaming and error handling.
|
|
28
|
+
* * Checks for 'ECONNREFUSED' to provide a helpful hint if the server is down.
|
|
29
|
+
* * @returns Promise<void> Resolves when connection is successful.
|
|
30
|
+
*/
|
|
31
|
+
connect(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* @brief Processes raw TCP stream data.
|
|
34
|
+
* * Splits the stream by newline characters to reconstruct distinct JSON objects.
|
|
35
|
+
* * Handles packet fragmentation (partial JSONs) by buffering incomplete data.
|
|
36
|
+
* @param chunk Raw string data from the socket.
|
|
37
|
+
*/
|
|
38
|
+
private handleStreamData;
|
|
39
|
+
/**
|
|
40
|
+
* @brief Internal helper to send commands to the server.
|
|
41
|
+
* * Wraps the request in a Promise and pushes the resolver to the queue.
|
|
42
|
+
* @param payload The request object.
|
|
43
|
+
* @returns Promise<XDBResponse<T>> The server's response.
|
|
44
|
+
*/
|
|
45
|
+
private sendCommand;
|
|
46
|
+
/**
|
|
47
|
+
* @brief Inserts a document into a specific collection.
|
|
48
|
+
* @param collection Target collection name.
|
|
49
|
+
* @param data JSON object to insert.
|
|
50
|
+
*/
|
|
51
|
+
insert<T extends Record<string, any> = Record<string, any>>(collection: string, data: T): Promise<XDBResponse<T & {
|
|
52
|
+
_id: string;
|
|
53
|
+
}>>;
|
|
54
|
+
/**
|
|
55
|
+
* @brief Finds documents matching a query filter.
|
|
56
|
+
* @param collection Target collection name.
|
|
57
|
+
* @param query Filter criteria (default: match all).
|
|
58
|
+
* @param limit Max number of results (0 for unlimited).
|
|
59
|
+
*/
|
|
60
|
+
find<T extends Record<string, any> = Record<string, any>>(collection: string, query?: object, limit?: number): Promise<XDBResponse<T[]>>;
|
|
61
|
+
/**
|
|
62
|
+
* @brief Deletes a document by its ID.
|
|
63
|
+
* @param collection Target collection name.
|
|
64
|
+
* @param id The unique _id string of the document.
|
|
65
|
+
*/
|
|
66
|
+
delete(collection: string, id: string): Promise<XDBResponse<null>>;
|
|
67
|
+
/**
|
|
68
|
+
* @brief Counts the total number of documents in a collection.
|
|
69
|
+
* @param collection Target collection name.
|
|
70
|
+
*/
|
|
71
|
+
count(collection: string): Promise<XDBResponse<{
|
|
72
|
+
count: number;
|
|
73
|
+
}>>;
|
|
74
|
+
/**
|
|
75
|
+
* @brief Terminates the session and closes the socket.
|
|
76
|
+
*/
|
|
77
|
+
close(): Promise<void>;
|
|
78
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file xdb-client.ts
|
|
4
|
+
* @brief Main Implementation of the XDB Database Client.
|
|
5
|
+
* Handles TCP persistence, stream buffering, command dispatching,
|
|
6
|
+
* and user-friendly error reporting.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.XDBClient = void 0;
|
|
43
|
+
const net = __importStar(require("net"));
|
|
44
|
+
/**
|
|
45
|
+
* @class XDBClient
|
|
46
|
+
* @brief A persistent TCP client for interacting with the XDB Server.
|
|
47
|
+
* Encapsulates the raw socket operations and provides a Promise-based API.
|
|
48
|
+
*/
|
|
49
|
+
class XDBClient {
|
|
50
|
+
/**
|
|
51
|
+
* @brief Initializes the XDB Client instance.
|
|
52
|
+
* @param options Configuration object containing host and port.
|
|
53
|
+
*/
|
|
54
|
+
constructor(options = {}) {
|
|
55
|
+
this.isConnected = false;
|
|
56
|
+
this.responseQueue = [];
|
|
57
|
+
this.streamBuffer = '';
|
|
58
|
+
this.host = options.host || '127.0.0.1';
|
|
59
|
+
this.port = options.port || 8080;
|
|
60
|
+
this.socket = new net.Socket();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @brief Establishes a connection to the XDB Server.
|
|
64
|
+
* * Sets up event listeners for data streaming and error handling.
|
|
65
|
+
* * Checks for 'ECONNREFUSED' to provide a helpful hint if the server is down.
|
|
66
|
+
* * @returns Promise<void> Resolves when connection is successful.
|
|
67
|
+
*/
|
|
68
|
+
connect() {
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
this.socket.connect(this.port, this.host, () => {
|
|
71
|
+
this.isConnected = true;
|
|
72
|
+
console.log(`[INFO] Connected to XDB at ${this.host}:${this.port}`);
|
|
73
|
+
resolve();
|
|
74
|
+
});
|
|
75
|
+
// Handle incoming data stream
|
|
76
|
+
this.socket.on('data', (chunk) => {
|
|
77
|
+
this.handleStreamData(chunk.toString());
|
|
78
|
+
});
|
|
79
|
+
// Handle socket errors
|
|
80
|
+
this.socket.on('error', (err) => {
|
|
81
|
+
this.isConnected = false;
|
|
82
|
+
// Check if the connection was refused (Server not running)
|
|
83
|
+
if (err.code === 'ECONNREFUSED') {
|
|
84
|
+
console.error(`\n\x1b[31m[ERROR] Could not connect to XDB at ${this.host}:${this.port}\x1b[0m`);
|
|
85
|
+
console.error(`\x1b[33m[HINT] Is the XDB server running?\x1b[0m`);
|
|
86
|
+
console.error(` Please start the server first (e.g., \x1b[36m./bin/server\x1b[0m)\n`);
|
|
87
|
+
}
|
|
88
|
+
// If it's a connection error during init, reject the promise
|
|
89
|
+
if (this.responseQueue.length === 0) {
|
|
90
|
+
reject(err);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Otherwise, reject the current pending command
|
|
94
|
+
const resolver = this.responseQueue.shift();
|
|
95
|
+
if (resolver)
|
|
96
|
+
resolver.reject(err);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
this.socket.on('close', () => {
|
|
100
|
+
this.isConnected = false;
|
|
101
|
+
// We only log if this was a clean exit, not an error-induced close
|
|
102
|
+
if (this.responseQueue.length === 0) {
|
|
103
|
+
// Optional: console.log('[INFO] Connection closed.');
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* @brief Processes raw TCP stream data.
|
|
110
|
+
* * Splits the stream by newline characters to reconstruct distinct JSON objects.
|
|
111
|
+
* * Handles packet fragmentation (partial JSONs) by buffering incomplete data.
|
|
112
|
+
* @param chunk Raw string data from the socket.
|
|
113
|
+
*/
|
|
114
|
+
handleStreamData(chunk) {
|
|
115
|
+
this.streamBuffer += chunk;
|
|
116
|
+
// Split by newline (the protocol delimiter)
|
|
117
|
+
const lines = this.streamBuffer.split('\n');
|
|
118
|
+
// The last element is either an empty string (if exact split)
|
|
119
|
+
// or an incomplete JSON fragment. Keep it in the buffer.
|
|
120
|
+
this.streamBuffer = lines.pop() || '';
|
|
121
|
+
for (const line of lines) {
|
|
122
|
+
if (line.trim() === '')
|
|
123
|
+
continue;
|
|
124
|
+
const resolver = this.responseQueue.shift();
|
|
125
|
+
if (resolver) {
|
|
126
|
+
try {
|
|
127
|
+
const json = JSON.parse(line);
|
|
128
|
+
resolver.resolve(json);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
resolver.reject(new Error(`Critical: Malformed JSON received. Raw: ${line}`));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* @brief Internal helper to send commands to the server.
|
|
138
|
+
* * Wraps the request in a Promise and pushes the resolver to the queue.
|
|
139
|
+
* @param payload The request object.
|
|
140
|
+
* @returns Promise<XDBResponse<T>> The server's response.
|
|
141
|
+
*/
|
|
142
|
+
sendCommand(payload) {
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
if (!this.isConnected) {
|
|
145
|
+
return reject(new Error('Client is not connected to XDB Server.'));
|
|
146
|
+
}
|
|
147
|
+
this.responseQueue.push({ resolve, reject });
|
|
148
|
+
// Append newline as required by the server's protocol
|
|
149
|
+
const message = JSON.stringify(payload) + '\n';
|
|
150
|
+
this.socket.write(message);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Public API Methods
|
|
154
|
+
/**
|
|
155
|
+
* @brief Inserts a document into a specific collection.
|
|
156
|
+
* @param collection Target collection name.
|
|
157
|
+
* @param data JSON object to insert.
|
|
158
|
+
*/
|
|
159
|
+
async insert(collection, data) {
|
|
160
|
+
return this.sendCommand({ action: 'insert', collection, data });
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* @brief Finds documents matching a query filter.
|
|
164
|
+
* @param collection Target collection name.
|
|
165
|
+
* @param query Filter criteria (default: match all).
|
|
166
|
+
* @param limit Max number of results (0 for unlimited).
|
|
167
|
+
*/
|
|
168
|
+
async find(collection, query = {}, limit = 0) {
|
|
169
|
+
return this.sendCommand({ action: 'find', collection, query, limit });
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* @brief Deletes a document by its ID.
|
|
173
|
+
* @param collection Target collection name.
|
|
174
|
+
* @param id The unique _id string of the document.
|
|
175
|
+
*/
|
|
176
|
+
async delete(collection, id) {
|
|
177
|
+
return this.sendCommand({ action: 'delete', collection, id });
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* @brief Counts the total number of documents in a collection.
|
|
181
|
+
* @param collection Target collection name.
|
|
182
|
+
*/
|
|
183
|
+
async count(collection) {
|
|
184
|
+
return this.sendCommand({ action: 'count', collection });
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* @brief Terminates the session and closes the socket.
|
|
188
|
+
*/
|
|
189
|
+
async close() {
|
|
190
|
+
if (this.isConnected) {
|
|
191
|
+
await this.sendCommand({ action: 'exit' });
|
|
192
|
+
this.socket.end();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
exports.XDBClient = XDBClient;
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xdb-driver",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A High-performance Node.js driver for the XDB Database Engine",
|
|
5
|
+
"author": "Firr, The Creator.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"database",
|
|
9
|
+
"tcp",
|
|
10
|
+
"driver",
|
|
11
|
+
"xdb",
|
|
12
|
+
"node.js",
|
|
13
|
+
"nosql"
|
|
14
|
+
],
|
|
15
|
+
"packageManager": "pnpm@10.27.0",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"module": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"homepage": "https://github.com/firrthecreator/node-xdb-driver#readme",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/firrthecreator/node-xdb-driver.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/firrthecreator/node-xdb-driver/issues"
|
|
26
|
+
},
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"require": "./dist/index.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"dev": "ts-node examples/app.ts",
|
|
41
|
+
"build": "tsc",
|
|
42
|
+
"format": "prettier --write \"src/**/*.ts\" \"examples/**/*.ts\" \"tests/**/*.ts\"",
|
|
43
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"examples/**/*.ts\" \"tests/**/*.ts\"",
|
|
44
|
+
"clean": "rm -rf dist coverage",
|
|
45
|
+
"test": "jest",
|
|
46
|
+
"test:watch": "jest --watch",
|
|
47
|
+
"test:coverage": "jest --coverage",
|
|
48
|
+
"prepublishOnly": "pnpm run clean && pnpm run format:check && pnpm run test && pnpm run build"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/jest": "^29.5.0",
|
|
52
|
+
"@types/node": "^22.0.0",
|
|
53
|
+
"jest": "^29.7.0",
|
|
54
|
+
"prettier": "^3.5.0",
|
|
55
|
+
"ts-jest": "^29.2.0",
|
|
56
|
+
"ts-node": "^10.9.2",
|
|
57
|
+
"typescript": "^5.7.0"
|
|
58
|
+
}
|
|
59
|
+
}
|