axiodb 11.9.14 β 11.9.16
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 +44 -1
- package/lib/Services/Indexation.operation.js +4 -1
- package/lib/Services/Indexation.operation.js.map +1 -1
- package/lib/client/AxioDBCloud.client.d.ts +26 -44
- package/lib/client/AxioDBCloud.client.js +106 -261
- package/lib/client/AxioDBCloud.client.js.map +1 -1
- package/lib/client/PooledConnection.d.ts +59 -0
- package/lib/client/PooledConnection.js +261 -0
- package/lib/client/PooledConnection.js.map +1 -0
- package/lib/client/types/client.types.d.ts +1 -0
- package/lib/client/types/client.types.js.map +1 -1
- package/lib/tcp/connection/ConnectionManager.js +5 -0
- package/lib/tcp/connection/ConnectionManager.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -126,6 +126,26 @@ console.log(result.data.documents[0].message); // Hello, Developer! π
|
|
|
126
126
|
|
|
127
127
|
> **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.
|
|
128
128
|
|
|
129
|
+
### `new AxioDB(options?)` β all constructor options
|
|
130
|
+
|
|
131
|
+
| Option | Type | Default | Description |
|
|
132
|
+
| --- | --- | --- | --- |
|
|
133
|
+
| `GUI` | `boolean` | `false` | Enable the web-based GUI dashboard at `localhost:27018` |
|
|
134
|
+
| `RootName` | `string` | `"AxioDB"` | Name of the root folder database files are stored under |
|
|
135
|
+
| `CustomPath` | `string` | current working directory | Custom filesystem path for database storage |
|
|
136
|
+
| `TCP` | `boolean` | `false` | Enable the AxioDBCloud TCP server on port 27019 |
|
|
137
|
+
| `TCPAuth` | `boolean` | `false` | Require username/password authentication on TCP connections (same RBAC accounts as the GUI) β see [Advanced: TCP authentication](#advanced-tcp-authentication) |
|
|
138
|
+
|
|
139
|
+
```javascript
|
|
140
|
+
const db = new AxioDB({
|
|
141
|
+
GUI: true,
|
|
142
|
+
RootName: 'MyDB',
|
|
143
|
+
CustomPath: './data',
|
|
144
|
+
TCP: true,
|
|
145
|
+
TCPAuth: true,
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
129
149
|
---
|
|
130
150
|
|
|
131
151
|
## π Features
|
|
@@ -192,7 +212,7 @@ await session.withTransaction(async (tx) => {
|
|
|
192
212
|
- **π Auto-Reconnect:** exponential backoff, up to 10 retry attempts
|
|
193
213
|
- **π Heartbeat Monitoring:** `PING`/`PONG` every 30 seconds
|
|
194
214
|
- **π Request Correlation:** UUID-based request/response matching
|
|
195
|
-
- **π§΅ Connection Pooling:**
|
|
215
|
+
- **π§΅ Connection Pooling:** client keeps a pool of `maxPoolSize` concurrent connections (default: 10, mirrors MongoDB's driver option) and distributes commands round-robin; server accepts 1,000+ concurrent connections total
|
|
196
216
|
- **π TypeScript Support:** full type definitions included
|
|
197
217
|
|
|
198
218
|
**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).
|
|
@@ -552,6 +572,29 @@ const user = await users.query({ username: 'johndoe' }).exec();
|
|
|
552
572
|
- `dropIndex(indexName: string): Promise<SuccessInterface | ErrorInterface>`
|
|
553
573
|
- `getIndexes(): Promise<SuccessInterface | ErrorInterface>` β lists all indexes registered on the collection
|
|
554
574
|
|
|
575
|
+
### Updater / Deleter
|
|
576
|
+
|
|
577
|
+
`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:
|
|
578
|
+
|
|
579
|
+
- `updater.UpdateOne(data: object): Promise<SuccessInterface | ErrorInterface>` β applies `data` to the first document matching `query`
|
|
580
|
+
- `updater.UpdateMany(data: object): Promise<SuccessInterface | ErrorInterface>` β applies `data` to every document matching `query`
|
|
581
|
+
- `deleter.deleteOne(): Promise<SuccessInterface | ErrorInterface>` β deletes the first document matching `query`
|
|
582
|
+
- `deleter.deleteMany(): Promise<SuccessInterface | ErrorInterface>` β deletes every document matching `query`
|
|
583
|
+
|
|
584
|
+
```javascript
|
|
585
|
+
// Update the first matching document
|
|
586
|
+
await collection.update({ name: 'Alice' }).UpdateOne({ status: 'active' });
|
|
587
|
+
|
|
588
|
+
// Update every matching document
|
|
589
|
+
await collection.update({ role: 'trial' }).UpdateMany({ role: 'active' });
|
|
590
|
+
|
|
591
|
+
// Delete the first matching document
|
|
592
|
+
await collection.delete({ name: 'Alice' }).deleteOne();
|
|
593
|
+
|
|
594
|
+
// Delete every matching document
|
|
595
|
+
await collection.delete({ status: 'inactive' }).deleteMany();
|
|
596
|
+
```
|
|
597
|
+
|
|
555
598
|
### Reader
|
|
556
599
|
|
|
557
600
|
- `Limit(limit: number): Reader`
|
|
@@ -101,7 +101,10 @@ class AxioDB {
|
|
|
101
101
|
}
|
|
102
102
|
if (this.TCP) {
|
|
103
103
|
Console_helper_1.default.green("Starting AxioDB TCP Server...");
|
|
104
|
-
|
|
104
|
+
// Start the TCP Server with the AxioDB instance
|
|
105
|
+
(0, server_2.default)(this, undefined, this.TCPAuth).catch((error) => {
|
|
106
|
+
console.error("[AxioDB TCP Server] Failed to start:", error);
|
|
107
|
+
});
|
|
105
108
|
}
|
|
106
109
|
});
|
|
107
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Indexation.operation.js","sourceRoot":"","sources":["../../source/Services/Indexation.operation.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Indexation.operation.js","sourceRoot":"","sources":["../../source/Services/Indexation.operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,75 +4,56 @@ import { AxioDBCloudOptions, AuthenticatedUser, ConnectionState } from './types/
|
|
|
4
4
|
import DatabaseProxy from './DatabaseProxy';
|
|
5
5
|
/**
|
|
6
6
|
* AxioDBCloud - TCP Client for remote AxioDB access
|
|
7
|
+
*
|
|
8
|
+
* Maintains a pool of `maxPoolSize` concurrent TCP connections (default: 10, mirrors
|
|
9
|
+
* MongoDB's driver default naming/behavior) to the same server. Commands are distributed
|
|
10
|
+
* round-robin across connected pool members; each member independently reconnects (with
|
|
11
|
+
* exponential backoff) and re-authenticates, so one dropped connection never affects the
|
|
12
|
+
* others or blocks in-flight commands routed to healthy members.
|
|
7
13
|
*/
|
|
8
14
|
export declare class AxioDBCloud extends EventEmitter {
|
|
9
15
|
private host;
|
|
10
16
|
private port;
|
|
11
|
-
private
|
|
12
|
-
private
|
|
13
|
-
private pendingRequests;
|
|
14
|
-
private connectionState;
|
|
17
|
+
private pool;
|
|
18
|
+
private roundRobinIndex;
|
|
15
19
|
private options;
|
|
16
|
-
private reconnectAttempt;
|
|
17
|
-
private heartbeatInterval;
|
|
18
20
|
private credentials?;
|
|
19
|
-
private authUser?;
|
|
20
21
|
constructor(connectionString: string, options?: AxioDBCloudOptions);
|
|
21
22
|
/**
|
|
22
23
|
* Parse connection string: axiodb://host:port
|
|
23
24
|
*/
|
|
24
25
|
private parseConnectionString;
|
|
25
26
|
/**
|
|
26
|
-
*
|
|
27
|
+
* Open the connection pool. Authenticates the first connection alone (if credentials are
|
|
28
|
+
* provided) before opening the rest of the pool - this avoids multiplying failed-login
|
|
29
|
+
* attempts against the server's shared per-IP rate limiter N times over for a single bad
|
|
30
|
+
* -credentials connect() call, and ensures a bad-credentials failure never leaves any pool
|
|
31
|
+
* member mid-reconnect.
|
|
27
32
|
*/
|
|
28
33
|
connect(): Promise<void>;
|
|
34
|
+
private createPooledConnection;
|
|
29
35
|
/**
|
|
30
36
|
* Authenticate with username/password (same RBAC users as the GUI Control Server).
|
|
31
37
|
* Only required when the server was started with `TCPAuth: true`.
|
|
32
38
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
39
|
+
* Authenticates every currently-connected pool member and stashes the credentials so a
|
|
40
|
+
* later automatic reconnect replays login on any member that drops - otherwise a network
|
|
41
|
+
* blip after a runtime `login()` call would silently leave the reconnected member
|
|
42
|
+
* unauthenticated.
|
|
36
43
|
*/
|
|
37
44
|
login(username: string, password: string): Promise<AuthenticatedUser>;
|
|
38
45
|
/**
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
private performAuthenticate;
|
|
42
|
-
/**
|
|
43
|
-
* The currently authenticated identity, if `login()` (or constructor credentials) succeeded.
|
|
46
|
+
* The currently authenticated identity, if `login()` (or constructor credentials)
|
|
47
|
+
* succeeded on at least one pool member.
|
|
44
48
|
*/
|
|
45
49
|
get authenticatedUser(): AuthenticatedUser | undefined;
|
|
46
50
|
/**
|
|
47
|
-
*
|
|
48
|
-
*/
|
|
49
|
-
private setupSocketHandlers;
|
|
50
|
-
/**
|
|
51
|
-
* Handle server response
|
|
52
|
-
*/
|
|
53
|
-
private handleResponse;
|
|
54
|
-
/**
|
|
55
|
-
* Handle disconnection
|
|
56
|
-
*/
|
|
57
|
-
private handleDisconnection;
|
|
58
|
-
/**
|
|
59
|
-
* Attempt to reconnect
|
|
60
|
-
*/
|
|
61
|
-
private attemptReconnect;
|
|
62
|
-
/**
|
|
63
|
-
* Start heartbeat
|
|
64
|
-
*/
|
|
65
|
-
private startHeartbeat;
|
|
66
|
-
/**
|
|
67
|
-
* Stop heartbeat
|
|
68
|
-
*/
|
|
69
|
-
private stopHeartbeat;
|
|
70
|
-
/**
|
|
71
|
-
* Send command to server
|
|
51
|
+
* Send command to server - picks a connected pool member round-robin.
|
|
72
52
|
*/
|
|
73
53
|
sendCommand(command: CommandType, params: any): Promise<any>;
|
|
54
|
+
private pickConnection;
|
|
74
55
|
/**
|
|
75
|
-
* Disconnect from server
|
|
56
|
+
* Disconnect from server - closes every connection in the pool.
|
|
76
57
|
*/
|
|
77
58
|
disconnect(): Promise<void>;
|
|
78
59
|
/**
|
|
@@ -83,11 +64,12 @@ export declare class AxioDBCloud extends EventEmitter {
|
|
|
83
64
|
isDatabaseExists(name: string): Promise<boolean>;
|
|
84
65
|
getInstanceInfo(): Promise<any>;
|
|
85
66
|
/**
|
|
86
|
-
* Get current connection state
|
|
67
|
+
* Get current connection state - CONNECTED if at least one pool member is connected,
|
|
68
|
+
* otherwise the "best" state across the pool (RECONNECTING > CONNECTING > FAILED).
|
|
87
69
|
*/
|
|
88
70
|
get state(): ConnectionState;
|
|
89
71
|
/**
|
|
90
|
-
* Check if connected
|
|
72
|
+
* Check if connected - true when at least one pool member is connected.
|
|
91
73
|
*/
|
|
92
74
|
get isConnected(): boolean;
|
|
93
75
|
}
|
|
@@ -13,29 +13,41 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.AxioDBCloud = void 0;
|
|
16
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
17
16
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
18
|
-
const net_1 = require("net");
|
|
19
|
-
const crypto_1 = require("crypto");
|
|
20
17
|
const events_1 = require("events");
|
|
21
|
-
const
|
|
18
|
+
const PooledConnection_1 = __importDefault(require("./PooledConnection"));
|
|
22
19
|
const command_types_1 = require("../tcp/types/command.types");
|
|
23
20
|
const client_types_1 = require("./types/client.types");
|
|
24
21
|
const DatabaseProxy_1 = __importDefault(require("./DatabaseProxy"));
|
|
22
|
+
const DEFAULT_MAX_POOL_SIZE = 10;
|
|
25
23
|
/**
|
|
26
24
|
* AxioDBCloud - TCP Client for remote AxioDB access
|
|
25
|
+
*
|
|
26
|
+
* Maintains a pool of `maxPoolSize` concurrent TCP connections (default: 10, mirrors
|
|
27
|
+
* MongoDB's driver default naming/behavior) to the same server. Commands are distributed
|
|
28
|
+
* round-robin across connected pool members; each member independently reconnects (with
|
|
29
|
+
* exponential backoff) and re-authenticates, so one dropped connection never affects the
|
|
30
|
+
* others or blocks in-flight commands routed to healthy members.
|
|
27
31
|
*/
|
|
28
32
|
class AxioDBCloud extends events_1.EventEmitter {
|
|
29
33
|
constructor(connectionString, options) {
|
|
30
34
|
super();
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
33
|
-
this.pendingRequests = new Map();
|
|
34
|
-
this.connectionState = client_types_1.ConnectionState.DISCONNECTED;
|
|
35
|
-
this.reconnectAttempt = 0;
|
|
36
|
-
this.heartbeatInterval = null;
|
|
35
|
+
this.pool = [];
|
|
36
|
+
this.roundRobinIndex = 0;
|
|
37
37
|
// Increase max listeners for reconnection scenarios
|
|
38
38
|
this.setMaxListeners(20);
|
|
39
|
+
// Default 'error' listener: Node's EventEmitter throws synchronously when 'error' is
|
|
40
|
+
// emitted with zero listeners attached. Every pooled connection re-emits its socket
|
|
41
|
+
// errors onto this instance (see PooledConnectionCallbacks.onError below), so without a
|
|
42
|
+
// guaranteed listener here, a network error the host application never explicitly
|
|
43
|
+
// listens for (e.g. a server restart) would crash the entire process. This listener only
|
|
44
|
+
// logs when it's the sole 'error' listener - if the consuming app has also attached its
|
|
45
|
+
// own, that one handles visibility and we don't double-log.
|
|
46
|
+
this.on('error', (error) => {
|
|
47
|
+
if (this.listenerCount('error') <= 1) {
|
|
48
|
+
console.error('[AxioDBCloud] Unhandled connection error:', error instanceof Error ? error.message : error);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
39
51
|
// Parse connection string
|
|
40
52
|
const parsed = this.parseConnectionString(connectionString);
|
|
41
53
|
this.host = parsed.host;
|
|
@@ -46,6 +58,7 @@ class AxioDBCloud extends events_1.EventEmitter {
|
|
|
46
58
|
reconnectAttempts: (options === null || options === void 0 ? void 0 : options.reconnectAttempts) || 10,
|
|
47
59
|
reconnectDelay: (options === null || options === void 0 ? void 0 : options.reconnectDelay) || 1000,
|
|
48
60
|
heartbeatInterval: (options === null || options === void 0 ? void 0 : options.heartbeatInterval) || 30000,
|
|
61
|
+
maxPoolSize: (options === null || options === void 0 ? void 0 : options.maxPoolSize) || DEFAULT_MAX_POOL_SIZE,
|
|
49
62
|
};
|
|
50
63
|
if ((options === null || options === void 0 ? void 0 : options.username) && (options === null || options === void 0 ? void 0 : options.password)) {
|
|
51
64
|
this.credentials = { username: options.username, password: options.password };
|
|
@@ -65,286 +78,105 @@ class AxioDBCloud extends events_1.EventEmitter {
|
|
|
65
78
|
};
|
|
66
79
|
}
|
|
67
80
|
/**
|
|
68
|
-
*
|
|
81
|
+
* Open the connection pool. Authenticates the first connection alone (if credentials are
|
|
82
|
+
* provided) before opening the rest of the pool - this avoids multiplying failed-login
|
|
83
|
+
* attempts against the server's shared per-IP rate limiter N times over for a single bad
|
|
84
|
+
* -credentials connect() call, and ensures a bad-credentials failure never leaves any pool
|
|
85
|
+
* member mid-reconnect.
|
|
69
86
|
*/
|
|
70
87
|
connect() {
|
|
71
88
|
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
if (this.pool.length > 0 && this.pool.some((connection) => connection.state === client_types_1.ConnectionState.CONNECTED)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const poolSize = this.options.maxPoolSize;
|
|
93
|
+
this.pool = Array.from({ length: poolSize }, () => this.createPooledConnection());
|
|
94
|
+
yield this.pool[0].connect();
|
|
95
|
+
if (poolSize > 1) {
|
|
96
|
+
yield Promise.all(this.pool.slice(1).map((connection) => connection.connect()));
|
|
97
|
+
}
|
|
98
|
+
this.emit('connected');
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
createPooledConnection() {
|
|
102
|
+
return new PooledConnection_1.default(this.host, this.port, {
|
|
103
|
+
timeout: this.options.timeout,
|
|
104
|
+
reconnectAttempts: this.options.reconnectAttempts,
|
|
105
|
+
reconnectDelay: this.options.reconnectDelay,
|
|
106
|
+
heartbeatInterval: this.options.heartbeatInterval,
|
|
107
|
+
}, () => this.credentials, {
|
|
108
|
+
onError: (error) => this.emit('error', error),
|
|
109
|
+
onDisconnected: (hadError) => this.emit('disconnected', hadError),
|
|
110
|
+
onReconnecting: (attempt) => this.emit('reconnecting', attempt),
|
|
111
|
+
onReconnected: () => this.emit('reconnected'),
|
|
112
|
+
onExhausted: () => {
|
|
113
|
+
if (this.pool.every((connection) => connection.state === client_types_1.ConnectionState.FAILED)) {
|
|
114
|
+
this.emit('failed', new Error('Max reconnection attempts reached'));
|
|
83
115
|
}
|
|
84
|
-
|
|
85
|
-
this.socket = new net_1.Socket();
|
|
86
|
-
// Setup socket event handlers
|
|
87
|
-
this.setupSocketHandlers();
|
|
88
|
-
// Connection timeout
|
|
89
|
-
const connectionTimeout = setTimeout(() => {
|
|
90
|
-
var _a;
|
|
91
|
-
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
92
|
-
this.connectionState = client_types_1.ConnectionState.FAILED;
|
|
93
|
-
reject(new Error('Connection timeout'));
|
|
94
|
-
}, this.options.timeout);
|
|
95
|
-
// Connect to server
|
|
96
|
-
this.socket.connect(this.port, this.host, () => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
-
var _a;
|
|
98
|
-
clearTimeout(connectionTimeout);
|
|
99
|
-
this.connectionState = client_types_1.ConnectionState.CONNECTED;
|
|
100
|
-
this.reconnectAttempt = 0;
|
|
101
|
-
this.startHeartbeat();
|
|
102
|
-
this.emit('connected');
|
|
103
|
-
if (!this.credentials) {
|
|
104
|
-
resolve();
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
try {
|
|
108
|
-
yield this.performAuthenticate(this.credentials.username, this.credentials.password);
|
|
109
|
-
resolve();
|
|
110
|
-
}
|
|
111
|
-
catch (authError) {
|
|
112
|
-
// Mirror disconnect()'s guard: prevent handleDisconnection's auto-reconnect
|
|
113
|
-
// from retrying the same bad credentials up to `reconnectAttempts` times.
|
|
114
|
-
this.reconnectAttempt = this.options.reconnectAttempts;
|
|
115
|
-
this.connectionState = client_types_1.ConnectionState.FAILED;
|
|
116
|
-
this.stopHeartbeat();
|
|
117
|
-
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
118
|
-
reject(authError);
|
|
119
|
-
}
|
|
120
|
-
}));
|
|
121
|
-
// Handle connection errors
|
|
122
|
-
this.socket.once('error', (error) => {
|
|
123
|
-
clearTimeout(connectionTimeout);
|
|
124
|
-
this.connectionState = client_types_1.ConnectionState.FAILED;
|
|
125
|
-
reject(error);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
116
|
+
},
|
|
128
117
|
});
|
|
129
118
|
}
|
|
130
119
|
/**
|
|
131
120
|
* Authenticate with username/password (same RBAC users as the GUI Control Server).
|
|
132
121
|
* Only required when the server was started with `TCPAuth: true`.
|
|
133
122
|
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
123
|
+
* Authenticates every currently-connected pool member and stashes the credentials so a
|
|
124
|
+
* later automatic reconnect replays login on any member that drops - otherwise a network
|
|
125
|
+
* blip after a runtime `login()` call would silently leave the reconnected member
|
|
126
|
+
* unauthenticated.
|
|
137
127
|
*/
|
|
138
128
|
login(username, password) {
|
|
139
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
-
const
|
|
130
|
+
const connectedMembers = this.pool.filter((connection) => connection.state === client_types_1.ConnectionState.CONNECTED);
|
|
131
|
+
if (connectedMembers.length === 0) {
|
|
132
|
+
throw new Error('Not connected to server');
|
|
133
|
+
}
|
|
134
|
+
const results = yield Promise.all(connectedMembers.map((connection) => connection.authenticate(username, password)));
|
|
141
135
|
this.credentials = { username, password };
|
|
142
|
-
return
|
|
136
|
+
return results[0];
|
|
143
137
|
});
|
|
144
138
|
}
|
|
145
139
|
/**
|
|
146
|
-
*
|
|
147
|
-
|
|
148
|
-
performAuthenticate(username, password) {
|
|
149
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
-
const result = yield this.sendCommand(command_types_1.CommandType.AUTHENTICATE, { username, password });
|
|
151
|
-
this.authUser = result;
|
|
152
|
-
return this.authUser;
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* The currently authenticated identity, if `login()` (or constructor credentials) succeeded.
|
|
140
|
+
* The currently authenticated identity, if `login()` (or constructor credentials)
|
|
141
|
+
* succeeded on at least one pool member.
|
|
157
142
|
*/
|
|
158
143
|
get authenticatedUser() {
|
|
159
|
-
|
|
144
|
+
var _a;
|
|
145
|
+
return (_a = this.pool.find((connection) => connection.authUser)) === null || _a === void 0 ? void 0 : _a.authUser;
|
|
160
146
|
}
|
|
161
147
|
/**
|
|
162
|
-
*
|
|
148
|
+
* Send command to server - picks a connected pool member round-robin.
|
|
163
149
|
*/
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
try {
|
|
170
|
-
const messages = this.messageBuffer.addChunk(chunk);
|
|
171
|
-
for (const message of messages) {
|
|
172
|
-
this.handleResponse(message);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
catch (error) {
|
|
176
|
-
// Clear buffer on protocol errors to prevent cascade failures
|
|
177
|
-
this.messageBuffer.clear();
|
|
178
|
-
// Check if error is due to connecting to wrong port (HTTP instead of TCP)
|
|
179
|
-
if (error instanceof Error && error.message.includes('Message exceeds maximum size')) {
|
|
180
|
-
const enhancedError = new Error('Protocol error: Message exceeds maximum size. Are you connecting to the correct port? ' +
|
|
181
|
-
'AxioDBCloud uses TCP port (default: 27019), not HTTP port (27018).');
|
|
182
|
-
this.emit('error', enhancedError);
|
|
183
|
-
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
this.emit('error', error);
|
|
187
|
-
}
|
|
150
|
+
sendCommand(command, params) {
|
|
151
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
152
|
+
const connection = this.pickConnection();
|
|
153
|
+
if (!connection) {
|
|
154
|
+
throw new Error('Not connected to server');
|
|
188
155
|
}
|
|
189
|
-
|
|
190
|
-
this.socket.on('error', (error) => {
|
|
191
|
-
this.emit('error', error);
|
|
192
|
-
this.handleDisconnection();
|
|
193
|
-
});
|
|
194
|
-
this.socket.on('close', (hadError) => {
|
|
195
|
-
this.emit('disconnected', hadError);
|
|
196
|
-
this.handleDisconnection();
|
|
197
|
-
});
|
|
198
|
-
this.socket.on('end', () => {
|
|
199
|
-
this.handleDisconnection();
|
|
156
|
+
return connection.sendCommand(command, params);
|
|
200
157
|
});
|
|
201
158
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const pending = this.pendingRequests.get(response.id);
|
|
207
|
-
if (pending) {
|
|
208
|
-
clearTimeout(pending.timeout);
|
|
209
|
-
this.pendingRequests.delete(response.id);
|
|
210
|
-
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
211
|
-
pending.resolve(response.data);
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
pending.reject(new Error(response.error || response.message));
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
console.warn(`[AxioDBCloud] Received response for unknown request: ${response.id}`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Handle disconnection
|
|
223
|
-
*/
|
|
224
|
-
handleDisconnection() {
|
|
225
|
-
this.connectionState = client_types_1.ConnectionState.DISCONNECTED;
|
|
226
|
-
this.stopHeartbeat();
|
|
227
|
-
// Clean up socket listeners
|
|
228
|
-
if (this.socket) {
|
|
229
|
-
this.socket.removeAllListeners();
|
|
230
|
-
}
|
|
231
|
-
// Reject all pending requests
|
|
232
|
-
for (const [id, pending] of this.pendingRequests.entries()) {
|
|
233
|
-
clearTimeout(pending.timeout);
|
|
234
|
-
pending.reject(new Error('Connection lost'));
|
|
235
|
-
this.pendingRequests.delete(id);
|
|
159
|
+
pickConnection() {
|
|
160
|
+
const poolSize = this.pool.length;
|
|
161
|
+
if (poolSize === 0) {
|
|
162
|
+
return null;
|
|
236
163
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
this.
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
this.emit('failed', new Error('Max reconnection attempts reached'));
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Attempt to reconnect
|
|
247
|
-
*/
|
|
248
|
-
attemptReconnect() {
|
|
249
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
250
|
-
this.reconnectAttempt++;
|
|
251
|
-
const delay = Math.min(this.options.reconnectDelay * Math.pow(2, this.reconnectAttempt - 1), 30000);
|
|
252
|
-
this.emit('reconnecting', this.reconnectAttempt);
|
|
253
|
-
this.connectionState = client_types_1.ConnectionState.RECONNECTING;
|
|
254
|
-
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
255
|
-
try {
|
|
256
|
-
yield this.connect();
|
|
257
|
-
this.emit('reconnected');
|
|
258
|
-
}
|
|
259
|
-
catch (error) {
|
|
260
|
-
// Reconnection will be attempted again in handleDisconnection
|
|
261
|
-
}
|
|
262
|
-
}), delay);
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Start heartbeat
|
|
267
|
-
*/
|
|
268
|
-
startHeartbeat() {
|
|
269
|
-
this.heartbeatInterval = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
270
|
-
try {
|
|
271
|
-
yield this.sendCommand(command_types_1.CommandType.PING, {});
|
|
272
|
-
}
|
|
273
|
-
catch (error) {
|
|
274
|
-
console.warn('[AxioDBCloud] Heartbeat failed:', error);
|
|
164
|
+
for (let attempts = 0; attempts < poolSize; attempts++) {
|
|
165
|
+
const connection = this.pool[this.roundRobinIndex % poolSize];
|
|
166
|
+
this.roundRobinIndex = (this.roundRobinIndex + 1) % poolSize;
|
|
167
|
+
if (connection.state === client_types_1.ConnectionState.CONNECTED) {
|
|
168
|
+
return connection;
|
|
275
169
|
}
|
|
276
|
-
}), this.options.heartbeatInterval);
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* Stop heartbeat
|
|
280
|
-
*/
|
|
281
|
-
stopHeartbeat() {
|
|
282
|
-
if (this.heartbeatInterval) {
|
|
283
|
-
clearInterval(this.heartbeatInterval);
|
|
284
|
-
this.heartbeatInterval = null;
|
|
285
170
|
}
|
|
171
|
+
return null;
|
|
286
172
|
}
|
|
287
173
|
/**
|
|
288
|
-
*
|
|
289
|
-
*/
|
|
290
|
-
sendCommand(command, params) {
|
|
291
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
292
|
-
if (this.connectionState !== client_types_1.ConnectionState.CONNECTED) {
|
|
293
|
-
throw new Error('Not connected to server');
|
|
294
|
-
}
|
|
295
|
-
if (!this.socket) {
|
|
296
|
-
throw new Error('Socket not initialized');
|
|
297
|
-
}
|
|
298
|
-
const id = (0, crypto_1.randomUUID)();
|
|
299
|
-
const request = {
|
|
300
|
-
id,
|
|
301
|
-
command,
|
|
302
|
-
params,
|
|
303
|
-
};
|
|
304
|
-
return new Promise((resolve, reject) => {
|
|
305
|
-
const timeout = setTimeout(() => {
|
|
306
|
-
this.pendingRequests.delete(id);
|
|
307
|
-
reject(new Error('Request timeout'));
|
|
308
|
-
}, this.options.timeout);
|
|
309
|
-
this.pendingRequests.set(id, {
|
|
310
|
-
resolve,
|
|
311
|
-
reject,
|
|
312
|
-
timeout,
|
|
313
|
-
timestamp: Date.now(),
|
|
314
|
-
});
|
|
315
|
-
try {
|
|
316
|
-
const buffer = protocol_1.MessageFramer.encode(request);
|
|
317
|
-
this.socket.write(buffer);
|
|
318
|
-
}
|
|
319
|
-
catch (error) {
|
|
320
|
-
clearTimeout(timeout);
|
|
321
|
-
this.pendingRequests.delete(id);
|
|
322
|
-
reject(error);
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Disconnect from server
|
|
174
|
+
* Disconnect from server - closes every connection in the pool.
|
|
329
175
|
*/
|
|
330
176
|
disconnect() {
|
|
331
177
|
return __awaiter(this, void 0, void 0, function* () {
|
|
332
|
-
|
|
333
|
-
this.
|
|
334
|
-
this.stopHeartbeat();
|
|
335
|
-
if (this.socket && !this.socket.destroyed) {
|
|
336
|
-
try {
|
|
337
|
-
yield this.sendCommand(command_types_1.CommandType.DISCONNECT, {});
|
|
338
|
-
}
|
|
339
|
-
catch (error) {
|
|
340
|
-
// Ignore disconnect errors
|
|
341
|
-
}
|
|
342
|
-
// Clean up all socket listeners
|
|
343
|
-
this.socket.removeAllListeners();
|
|
344
|
-
this.socket.end();
|
|
345
|
-
this.socket = null;
|
|
346
|
-
}
|
|
347
|
-
this.connectionState = client_types_1.ConnectionState.DISCONNECTED;
|
|
178
|
+
yield Promise.all(this.pool.map((connection) => connection.disconnect()));
|
|
179
|
+
this.pool = [];
|
|
348
180
|
});
|
|
349
181
|
}
|
|
350
182
|
/**
|
|
@@ -373,16 +205,29 @@ class AxioDBCloud extends events_1.EventEmitter {
|
|
|
373
205
|
});
|
|
374
206
|
}
|
|
375
207
|
/**
|
|
376
|
-
* Get current connection state
|
|
208
|
+
* Get current connection state - CONNECTED if at least one pool member is connected,
|
|
209
|
+
* otherwise the "best" state across the pool (RECONNECTING > CONNECTING > FAILED).
|
|
377
210
|
*/
|
|
378
211
|
get state() {
|
|
379
|
-
|
|
212
|
+
if (this.pool.length === 0) {
|
|
213
|
+
return client_types_1.ConnectionState.DISCONNECTED;
|
|
214
|
+
}
|
|
215
|
+
if (this.pool.some((connection) => connection.state === client_types_1.ConnectionState.CONNECTED)) {
|
|
216
|
+
return client_types_1.ConnectionState.CONNECTED;
|
|
217
|
+
}
|
|
218
|
+
if (this.pool.some((connection) => connection.state === client_types_1.ConnectionState.RECONNECTING)) {
|
|
219
|
+
return client_types_1.ConnectionState.RECONNECTING;
|
|
220
|
+
}
|
|
221
|
+
if (this.pool.some((connection) => connection.state === client_types_1.ConnectionState.CONNECTING)) {
|
|
222
|
+
return client_types_1.ConnectionState.CONNECTING;
|
|
223
|
+
}
|
|
224
|
+
return client_types_1.ConnectionState.FAILED;
|
|
380
225
|
}
|
|
381
226
|
/**
|
|
382
|
-
* Check if connected
|
|
227
|
+
* Check if connected - true when at least one pool member is connected.
|
|
383
228
|
*/
|
|
384
229
|
get isConnected() {
|
|
385
|
-
return this.
|
|
230
|
+
return this.pool.some((connection) => connection.state === client_types_1.ConnectionState.CONNECTED);
|
|
386
231
|
}
|
|
387
232
|
}
|
|
388
233
|
exports.AxioDBCloud = AxioDBCloud;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AxioDBCloud.client.js","sourceRoot":"","sources":["../../source/client/AxioDBCloud.client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"AxioDBCloud.client.js","sourceRoot":"","sources":["../../source/client/AxioDBCloud.client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { CommandType } from '../tcp/types/command.types';
|
|
2
|
+
import { AuthenticatedUser, ConnectionState } from './types/client.types';
|
|
3
|
+
/** Per-connection options a PooledConnection needs (pool-level options like maxPoolSize live one level up). */
|
|
4
|
+
export interface PooledConnectionOptions {
|
|
5
|
+
timeout: number;
|
|
6
|
+
reconnectAttempts: number;
|
|
7
|
+
reconnectDelay: number;
|
|
8
|
+
heartbeatInterval: number;
|
|
9
|
+
}
|
|
10
|
+
/** Callbacks a PooledConnection uses to surface lifecycle events to its owning AxioDBCloud pool. */
|
|
11
|
+
export interface PooledConnectionCallbacks {
|
|
12
|
+
onError: (error: Error) => void;
|
|
13
|
+
onDisconnected: (hadError: boolean) => void;
|
|
14
|
+
onReconnecting: (attempt: number) => void;
|
|
15
|
+
onReconnected: () => void;
|
|
16
|
+
/** This member exhausted its reconnect attempts and is giving up permanently. */
|
|
17
|
+
onExhausted: () => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* One physical TCP connection within an AxioDBCloud connection pool. Owns its own socket,
|
|
21
|
+
* message-framing buffer, in-flight request map, and reconnect/heartbeat lifecycle, so a
|
|
22
|
+
* failure on one pooled connection never affects the others in the pool.
|
|
23
|
+
*/
|
|
24
|
+
export default class PooledConnection {
|
|
25
|
+
private readonly host;
|
|
26
|
+
private readonly port;
|
|
27
|
+
private readonly options;
|
|
28
|
+
private readonly getCredentials;
|
|
29
|
+
private readonly callbacks;
|
|
30
|
+
private socket;
|
|
31
|
+
private messageBuffer;
|
|
32
|
+
private pendingRequests;
|
|
33
|
+
private reconnectAttempt;
|
|
34
|
+
private heartbeatInterval;
|
|
35
|
+
state: ConnectionState;
|
|
36
|
+
authUser?: AuthenticatedUser;
|
|
37
|
+
constructor(host: string, port: number, options: PooledConnectionOptions, getCredentials: () => {
|
|
38
|
+
username: string;
|
|
39
|
+
password: string;
|
|
40
|
+
} | undefined, callbacks: PooledConnectionCallbacks);
|
|
41
|
+
/**
|
|
42
|
+
* Connect (or reconnect) this pooled connection, authenticating automatically if
|
|
43
|
+
* credentials are available. On authentication failure, marks this connection FAILED and
|
|
44
|
+
* prevents its own background auto-reconnect from retrying the same bad credentials.
|
|
45
|
+
*/
|
|
46
|
+
connect(): Promise<void>;
|
|
47
|
+
/** Sends the AUTHENTICATE command over this connection and stores the resulting identity. */
|
|
48
|
+
authenticate(username: string, password: string): Promise<AuthenticatedUser>;
|
|
49
|
+
/** Send a command over this specific connection. */
|
|
50
|
+
sendCommand(command: CommandType | string, params: any): Promise<any>;
|
|
51
|
+
/** Disconnect this connection permanently (no further auto-reconnect). */
|
|
52
|
+
disconnect(): Promise<void>;
|
|
53
|
+
private setupSocketHandlers;
|
|
54
|
+
private handleResponse;
|
|
55
|
+
private handleDisconnection;
|
|
56
|
+
private attemptReconnect;
|
|
57
|
+
private startHeartbeat;
|
|
58
|
+
private stopHeartbeat;
|
|
59
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
13
|
+
const net_1 = require("net");
|
|
14
|
+
const crypto_1 = require("crypto");
|
|
15
|
+
const protocol_1 = require("../tcp/config/protocol");
|
|
16
|
+
const command_types_1 = require("../tcp/types/command.types");
|
|
17
|
+
const client_types_1 = require("./types/client.types");
|
|
18
|
+
/**
|
|
19
|
+
* One physical TCP connection within an AxioDBCloud connection pool. Owns its own socket,
|
|
20
|
+
* message-framing buffer, in-flight request map, and reconnect/heartbeat lifecycle, so a
|
|
21
|
+
* failure on one pooled connection never affects the others in the pool.
|
|
22
|
+
*/
|
|
23
|
+
class PooledConnection {
|
|
24
|
+
constructor(host, port, options, getCredentials, callbacks) {
|
|
25
|
+
this.host = host;
|
|
26
|
+
this.port = port;
|
|
27
|
+
this.options = options;
|
|
28
|
+
this.getCredentials = getCredentials;
|
|
29
|
+
this.callbacks = callbacks;
|
|
30
|
+
this.socket = null;
|
|
31
|
+
this.messageBuffer = new protocol_1.MessageBuffer();
|
|
32
|
+
this.pendingRequests = new Map();
|
|
33
|
+
this.reconnectAttempt = 0;
|
|
34
|
+
this.heartbeatInterval = null;
|
|
35
|
+
this.state = client_types_1.ConnectionState.DISCONNECTED;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Connect (or reconnect) this pooled connection, authenticating automatically if
|
|
39
|
+
* credentials are available. On authentication failure, marks this connection FAILED and
|
|
40
|
+
* prevents its own background auto-reconnect from retrying the same bad credentials.
|
|
41
|
+
*/
|
|
42
|
+
connect() {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
if (this.state === client_types_1.ConnectionState.CONNECTED) {
|
|
45
|
+
resolve();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (this.socket) {
|
|
49
|
+
this.socket.removeAllListeners();
|
|
50
|
+
if (!this.socket.destroyed) {
|
|
51
|
+
this.socket.destroy();
|
|
52
|
+
}
|
|
53
|
+
this.socket = null;
|
|
54
|
+
}
|
|
55
|
+
this.state = client_types_1.ConnectionState.CONNECTING;
|
|
56
|
+
const socket = new net_1.Socket();
|
|
57
|
+
this.socket = socket;
|
|
58
|
+
const connectionTimeout = setTimeout(() => {
|
|
59
|
+
socket.destroy();
|
|
60
|
+
this.state = client_types_1.ConnectionState.FAILED;
|
|
61
|
+
reject(new Error('Connection timeout'));
|
|
62
|
+
}, this.options.timeout);
|
|
63
|
+
// Registered before setupSocketHandlers() so it runs first (Node fires listeners in
|
|
64
|
+
// registration order), deterministically settling this connect() promise before the
|
|
65
|
+
// permanent handler below re-emits the same error onto the shared callbacks.onError -
|
|
66
|
+
// fixes a crash where the permanent handler's re-emit used to run first and throw
|
|
67
|
+
// (via the owning AxioDBCloud's EventEmitter) before reject() ever got a chance to run.
|
|
68
|
+
const connectErrorHandler = (error) => {
|
|
69
|
+
clearTimeout(connectionTimeout);
|
|
70
|
+
this.state = client_types_1.ConnectionState.FAILED;
|
|
71
|
+
reject(error);
|
|
72
|
+
};
|
|
73
|
+
socket.once('error', connectErrorHandler);
|
|
74
|
+
this.setupSocketHandlers(socket);
|
|
75
|
+
socket.connect(this.port, this.host, () => __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
clearTimeout(connectionTimeout);
|
|
77
|
+
socket.off('error', connectErrorHandler);
|
|
78
|
+
this.state = client_types_1.ConnectionState.CONNECTED;
|
|
79
|
+
this.reconnectAttempt = 0;
|
|
80
|
+
this.startHeartbeat();
|
|
81
|
+
const credentials = this.getCredentials();
|
|
82
|
+
if (!credentials) {
|
|
83
|
+
resolve();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
yield this.authenticate(credentials.username, credentials.password);
|
|
88
|
+
resolve();
|
|
89
|
+
}
|
|
90
|
+
catch (authError) {
|
|
91
|
+
// Prevents handleDisconnection's auto-reconnect from retrying the same bad
|
|
92
|
+
// credentials up to `reconnectAttempts` times.
|
|
93
|
+
this.reconnectAttempt = this.options.reconnectAttempts;
|
|
94
|
+
this.state = client_types_1.ConnectionState.FAILED;
|
|
95
|
+
this.stopHeartbeat();
|
|
96
|
+
socket.destroy();
|
|
97
|
+
reject(authError);
|
|
98
|
+
}
|
|
99
|
+
}));
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/** Sends the AUTHENTICATE command over this connection and stores the resulting identity. */
|
|
103
|
+
authenticate(username, password) {
|
|
104
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
const result = yield this.sendCommand(command_types_1.CommandType.AUTHENTICATE, { username, password });
|
|
106
|
+
this.authUser = result;
|
|
107
|
+
return this.authUser;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/** Send a command over this specific connection. */
|
|
111
|
+
sendCommand(command, params) {
|
|
112
|
+
if (this.state !== client_types_1.ConnectionState.CONNECTED || !this.socket) {
|
|
113
|
+
return Promise.reject(new Error('Not connected to server'));
|
|
114
|
+
}
|
|
115
|
+
const socket = this.socket;
|
|
116
|
+
const id = (0, crypto_1.randomUUID)();
|
|
117
|
+
const request = { id, command: command, params };
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
const timeout = setTimeout(() => {
|
|
120
|
+
this.pendingRequests.delete(id);
|
|
121
|
+
reject(new Error('Request timeout'));
|
|
122
|
+
}, this.options.timeout);
|
|
123
|
+
this.pendingRequests.set(id, {
|
|
124
|
+
resolve,
|
|
125
|
+
reject,
|
|
126
|
+
timeout,
|
|
127
|
+
timestamp: Date.now(),
|
|
128
|
+
});
|
|
129
|
+
try {
|
|
130
|
+
const buffer = protocol_1.MessageFramer.encode(request);
|
|
131
|
+
socket.write(buffer);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
clearTimeout(timeout);
|
|
135
|
+
this.pendingRequests.delete(id);
|
|
136
|
+
reject(error);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** Disconnect this connection permanently (no further auto-reconnect). */
|
|
141
|
+
disconnect() {
|
|
142
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
this.reconnectAttempt = this.options.reconnectAttempts;
|
|
144
|
+
this.stopHeartbeat();
|
|
145
|
+
if (this.socket && !this.socket.destroyed) {
|
|
146
|
+
try {
|
|
147
|
+
yield this.sendCommand(command_types_1.CommandType.DISCONNECT, {});
|
|
148
|
+
}
|
|
149
|
+
catch (_a) {
|
|
150
|
+
// Ignore disconnect errors
|
|
151
|
+
}
|
|
152
|
+
this.socket.removeAllListeners();
|
|
153
|
+
this.socket.end();
|
|
154
|
+
this.socket = null;
|
|
155
|
+
}
|
|
156
|
+
this.state = client_types_1.ConnectionState.DISCONNECTED;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
setupSocketHandlers(socket) {
|
|
160
|
+
socket.on('data', (chunk) => {
|
|
161
|
+
try {
|
|
162
|
+
const messages = this.messageBuffer.addChunk(chunk);
|
|
163
|
+
for (const message of messages) {
|
|
164
|
+
this.handleResponse(message);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
// Clear buffer on protocol errors to prevent cascade failures
|
|
169
|
+
this.messageBuffer.clear();
|
|
170
|
+
if (error instanceof Error && error.message.includes('Message exceeds maximum size')) {
|
|
171
|
+
const enhancedError = new Error('Protocol error: Message exceeds maximum size. Are you connecting to the correct port? ' +
|
|
172
|
+
'AxioDBCloud uses TCP port (default: 27019), not HTTP port (27018).');
|
|
173
|
+
this.callbacks.onError(enhancedError);
|
|
174
|
+
socket.destroy();
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
this.callbacks.onError(error instanceof Error ? error : new Error(String(error)));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
socket.on('error', (error) => {
|
|
182
|
+
this.callbacks.onError(error);
|
|
183
|
+
this.handleDisconnection();
|
|
184
|
+
});
|
|
185
|
+
socket.on('close', (hadError) => {
|
|
186
|
+
this.callbacks.onDisconnected(hadError);
|
|
187
|
+
this.handleDisconnection();
|
|
188
|
+
});
|
|
189
|
+
socket.on('end', () => {
|
|
190
|
+
this.handleDisconnection();
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
handleResponse(response) {
|
|
194
|
+
const pending = this.pendingRequests.get(response.id);
|
|
195
|
+
if (pending) {
|
|
196
|
+
clearTimeout(pending.timeout);
|
|
197
|
+
this.pendingRequests.delete(response.id);
|
|
198
|
+
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
199
|
+
pending.resolve(response.data);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
pending.reject(new Error(response.error || response.message));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
console.warn(`[AxioDBCloud] Received response for unknown request: ${response.id}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
handleDisconnection() {
|
|
210
|
+
this.state = client_types_1.ConnectionState.DISCONNECTED;
|
|
211
|
+
this.stopHeartbeat();
|
|
212
|
+
if (this.socket) {
|
|
213
|
+
this.socket.removeAllListeners();
|
|
214
|
+
}
|
|
215
|
+
for (const [id, pending] of this.pendingRequests.entries()) {
|
|
216
|
+
clearTimeout(pending.timeout);
|
|
217
|
+
pending.reject(new Error('Connection lost'));
|
|
218
|
+
this.pendingRequests.delete(id);
|
|
219
|
+
}
|
|
220
|
+
if (this.reconnectAttempt < this.options.reconnectAttempts) {
|
|
221
|
+
this.attemptReconnect();
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
this.state = client_types_1.ConnectionState.FAILED;
|
|
225
|
+
this.callbacks.onExhausted();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
attemptReconnect() {
|
|
229
|
+
this.reconnectAttempt++;
|
|
230
|
+
const delay = Math.min(this.options.reconnectDelay * Math.pow(2, this.reconnectAttempt - 1), 30000);
|
|
231
|
+
this.callbacks.onReconnecting(this.reconnectAttempt);
|
|
232
|
+
this.state = client_types_1.ConnectionState.RECONNECTING;
|
|
233
|
+
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
234
|
+
try {
|
|
235
|
+
yield this.connect();
|
|
236
|
+
this.callbacks.onReconnected();
|
|
237
|
+
}
|
|
238
|
+
catch (_a) {
|
|
239
|
+
// Reconnection will be attempted again in handleDisconnection
|
|
240
|
+
}
|
|
241
|
+
}), delay);
|
|
242
|
+
}
|
|
243
|
+
startHeartbeat() {
|
|
244
|
+
this.heartbeatInterval = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
245
|
+
try {
|
|
246
|
+
yield this.sendCommand(command_types_1.CommandType.PING, {});
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
console.warn('[AxioDBCloud] Heartbeat failed:', error);
|
|
250
|
+
}
|
|
251
|
+
}), this.options.heartbeatInterval);
|
|
252
|
+
}
|
|
253
|
+
stopHeartbeat() {
|
|
254
|
+
if (this.heartbeatInterval) {
|
|
255
|
+
clearInterval(this.heartbeatInterval);
|
|
256
|
+
this.heartbeatInterval = null;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
exports.default = PooledConnection;
|
|
261
|
+
//# sourceMappingURL=PooledConnection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PooledConnection.js","sourceRoot":"","sources":["../../source/client/PooledConnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.types.js","sourceRoot":"","sources":["../../../source/client/types/client.types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;
|
|
1
|
+
{"version":3,"file":"client.types.js","sourceRoot":"","sources":["../../../source/client/types/client.types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAyBH;;GAEG;AACH,IAAY,eAMX;AAND,WAAY,eAAe;IACzB,gDAA6B,CAAA;IAC7B,4CAAyB,CAAA;IACzB,0CAAuB,CAAA;IACvB,gDAA6B,CAAA;IAC7B,oCAAiB,CAAA;AACnB,CAAC,EANW,eAAe,aAAf,eAAe,GAAf,eAAe,QAM1B"}
|
|
@@ -31,6 +31,11 @@ class ConnectionManager extends events_1.EventEmitter {
|
|
|
31
31
|
requestCount: 0,
|
|
32
32
|
};
|
|
33
33
|
this.connections.set(connectionId, info);
|
|
34
|
+
// Idle timeout: destroys the connection (via the 'timeout' handler below) if no data
|
|
35
|
+
// is received for CONNECTION_TIMEOUT ms. Without this, a client that opens a connection
|
|
36
|
+
// and never completes its handshake (e.g. sends a partial length-prefixed header and
|
|
37
|
+
// goes silent) would hold its slot in the MAX_CONNECTIONS cap indefinitely.
|
|
38
|
+
socket.setTimeout(keys_1.CONNECTION_TIMEOUT);
|
|
34
39
|
// Setup socket handlers
|
|
35
40
|
this.setupSocketHandlers(connectionId, socket, info);
|
|
36
41
|
this.emit('connection:added', connectionId, socket.remoteAddress);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectionManager.js","sourceRoot":"","sources":["../../../source/tcp/connection/ConnectionManager.ts"],"names":[],"mappings":";;;AACA,mCAAsC;AACtC,iDAAkE;AAElE,
|
|
1
|
+
{"version":3,"file":"ConnectionManager.js","sourceRoot":"","sources":["../../../source/tcp/connection/ConnectionManager.ts"],"names":[],"mappings":";;;AACA,mCAAsC;AACtC,iDAAkE;AAElE,yCAA+F;AAgB/F;;GAEG;AACH,uBAA+B,SAAQ,qBAAY;IAIjD;QACE,KAAK,EAAE,CAAC;QAJF,gBAAW,GAAgC,IAAI,GAAG,EAAE,CAAC;QACrD,sBAAiB,GAAW,CAAC,CAAC;QAIpC,sEAAsE;QACtE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB;IAC3C,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,MAAc;QAC1B,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,sBAAe,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC,CAAC,sCAAsC;QACrD,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACjD,MAAM,IAAI,GAAmB;YAC3B,MAAM;YACN,MAAM,EAAE,IAAI,wBAAa,EAAE;YAC3B,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;YACvB,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;YACxB,YAAY,EAAE,CAAC;SAChB,CAAC;QAEF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAEzC,qFAAqF;QACrF,wFAAwF;QACxF,qFAAqF;QACrF,4EAA4E;QAC5E,MAAM,CAAC,UAAU,CAAC,yBAAkB,CAAC,CAAC;QAEtC,wBAAwB;QACxB,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAErD,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,YAAY,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QAClE,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,YAAoB;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAChD,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,YAAoB,EAAE,QAAqB;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,YAAoB;QAChC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,YAAoB,EAAE,QAA2B;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAChD,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,YAAoB;;QAC9B,OAAO,MAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,0CAAE,QAAQ,CAAC;IACtD,CAAC;IAED;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAgB;;QAChC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,QAAQ,MAAK,QAAQ,EAAE,CAAC;gBACzC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,KAAK,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YACpB,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,YAAoB,EAAE,MAAc,EAAE,IAAoB;QACpF,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAClC,IAAI,CAAC;gBACH,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAE7C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC/B,IAAI,CAAC,YAAY,EAAE,CAAC;oBACpB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,OAAqB,EAAE,MAAM,CAAC,CAAC;gBACpE,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;gBAExC,sBAAsB;gBACtB,MAAM,aAAa,GAAgB;oBACjC,EAAE,EAAE,OAAO;oBACX,UAAU,EAAE,iBAAU,CAAC,WAAW;oBAClC,OAAO,EAAE,mBAAY,CAAC,sBAAsB;oBAC5C,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC;gBACF,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;gBAE/C,4BAA4B;gBAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;YAClC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,QAAiB,EAAE,EAAE;YACvC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;YACnD,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACpB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;YACtC,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACxB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;YAC1C,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,OAAO,QAAQ,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,IAAI,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAElC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,aAAa,IAAI,IAAI,CAAC,YAAY,CAAC;YACnC,IAAI,IAAI,CAAC,WAAW,GAAG,gBAAgB,EAAE,CAAC;gBACxC,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC;YACtC,CAAC;QACH,CAAC;QAED,OAAO;YACL,iBAAiB,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YACxC,cAAc,EAAE,sBAAe;YAC/B,aAAa;YACb,mBAAmB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB;SACnD,CAAC;IACJ,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "axiodb",
|
|
3
|
-
"version": "11.9.
|
|
3
|
+
"version": "11.9.16",
|
|
4
4
|
"description": "The Pure JavaScript Alternative to SQLite. 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",
|