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 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
+ [![npm version](https://img.shields.io/npm/v/node-xdb-driver.svg)](https://www.npmjs.com/package/node-xdb-driver)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](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.
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @file index.ts
3
+ * @brief Public API exports for the Node.js XDB Driver.
4
+ */
5
+ export { XDBClient } from './xdb-client';
6
+ export * from './types/definitions';
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
+ }