@push.rocks/smartdb 1.0.1 → 2.1.1
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/.smartconfig.json +18 -4
- package/dist_rust/rustdb_linux_amd64 +0 -0
- package/dist_rust/rustdb_linux_arm64 +0 -0
- package/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/ts_local/classes.localsmartdb.d.ts +5 -5
- package/dist_ts/ts_local/classes.localsmartdb.js +7 -9
- package/dist_ts/ts_local/plugins.d.ts +1 -2
- package/dist_ts/ts_local/plugins.js +3 -3
- package/dist_ts/ts_smartdb/index.d.ts +2 -24
- package/dist_ts/ts_smartdb/index.js +4 -29
- package/dist_ts/ts_smartdb/plugins.d.ts +2 -10
- package/dist_ts/ts_smartdb/plugins.js +3 -13
- package/dist_ts/ts_smartdb/rust-db-bridge.d.ts +122 -0
- package/dist_ts/ts_smartdb/rust-db-bridge.js +113 -0
- package/dist_ts/ts_smartdb/server/SmartdbServer.d.ts +39 -37
- package/dist_ts/ts_smartdb/server/SmartdbServer.js +87 -206
- package/dist_ts/ts_smartdb/server/index.d.ts +0 -4
- package/dist_ts/ts_smartdb/server/index.js +1 -5
- package/dist_ts_debugserver/bundled.d.ts +4 -0
- package/dist_ts_debugserver/bundled.js +12 -0
- package/dist_ts_debugserver/classes.debugserver.d.ts +36 -0
- package/dist_ts_debugserver/classes.debugserver.js +95 -0
- package/dist_ts_debugserver/index.d.ts +2 -0
- package/dist_ts_debugserver/index.js +2 -0
- package/dist_ts_debugserver/plugins.d.ts +2 -0
- package/dist_ts_debugserver/plugins.js +3 -0
- package/dist_ts_debugui/index.d.ts +2 -0
- package/dist_ts_debugui/index.js +2 -0
- package/dist_ts_debugui/plugins.d.ts +1 -0
- package/dist_ts_debugui/plugins.js +2 -0
- package/dist_ts_debugui/smartdb-debugui.d.ts +62 -0
- package/dist_ts_debugui/smartdb-debugui.js +1132 -0
- package/license +3 -1
- package/package.json +14 -13
- package/readme.md +209 -177
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/index.ts +11 -0
- package/ts/ts_local/classes.localsmartdb.ts +5 -6
- package/ts/ts_local/plugins.ts +1 -3
- package/ts/ts_smartdb/index.ts +14 -41
- package/ts/ts_smartdb/plugins.ts +2 -15
- package/ts/ts_smartdb/rust-db-bridge.ts +262 -0
- package/ts/ts_smartdb/server/SmartdbServer.ts +115 -246
- package/ts/ts_smartdb/server/index.ts +0 -7
- package/dist_ts/ts_smartdb/engine/AggregationEngine.d.ts +0 -66
- package/dist_ts/ts_smartdb/engine/AggregationEngine.js +0 -189
- package/dist_ts/ts_smartdb/engine/IndexEngine.d.ts +0 -97
- package/dist_ts/ts_smartdb/engine/IndexEngine.js +0 -678
- package/dist_ts/ts_smartdb/engine/QueryEngine.d.ts +0 -54
- package/dist_ts/ts_smartdb/engine/QueryEngine.js +0 -271
- package/dist_ts/ts_smartdb/engine/QueryPlanner.d.ts +0 -64
- package/dist_ts/ts_smartdb/engine/QueryPlanner.js +0 -308
- package/dist_ts/ts_smartdb/engine/SessionEngine.d.ts +0 -117
- package/dist_ts/ts_smartdb/engine/SessionEngine.js +0 -232
- package/dist_ts/ts_smartdb/engine/TransactionEngine.d.ts +0 -85
- package/dist_ts/ts_smartdb/engine/TransactionEngine.js +0 -287
- package/dist_ts/ts_smartdb/engine/UpdateEngine.d.ts +0 -47
- package/dist_ts/ts_smartdb/engine/UpdateEngine.js +0 -461
- package/dist_ts/ts_smartdb/errors/SmartdbErrors.d.ts +0 -100
- package/dist_ts/ts_smartdb/errors/SmartdbErrors.js +0 -155
- package/dist_ts/ts_smartdb/server/CommandRouter.d.ts +0 -87
- package/dist_ts/ts_smartdb/server/CommandRouter.js +0 -222
- package/dist_ts/ts_smartdb/server/WireProtocol.d.ts +0 -117
- package/dist_ts/ts_smartdb/server/WireProtocol.js +0 -298
- package/dist_ts/ts_smartdb/server/handlers/AdminHandler.d.ts +0 -100
- package/dist_ts/ts_smartdb/server/handlers/AdminHandler.js +0 -668
- package/dist_ts/ts_smartdb/server/handlers/AggregateHandler.d.ts +0 -31
- package/dist_ts/ts_smartdb/server/handlers/AggregateHandler.js +0 -277
- package/dist_ts/ts_smartdb/server/handlers/DeleteHandler.d.ts +0 -8
- package/dist_ts/ts_smartdb/server/handlers/DeleteHandler.js +0 -95
- package/dist_ts/ts_smartdb/server/handlers/FindHandler.d.ts +0 -31
- package/dist_ts/ts_smartdb/server/handlers/FindHandler.js +0 -291
- package/dist_ts/ts_smartdb/server/handlers/HelloHandler.d.ts +0 -11
- package/dist_ts/ts_smartdb/server/handlers/HelloHandler.js +0 -62
- package/dist_ts/ts_smartdb/server/handlers/IndexHandler.d.ts +0 -20
- package/dist_ts/ts_smartdb/server/handlers/IndexHandler.js +0 -183
- package/dist_ts/ts_smartdb/server/handlers/InsertHandler.d.ts +0 -8
- package/dist_ts/ts_smartdb/server/handlers/InsertHandler.js +0 -79
- package/dist_ts/ts_smartdb/server/handlers/UpdateHandler.d.ts +0 -24
- package/dist_ts/ts_smartdb/server/handlers/UpdateHandler.js +0 -296
- package/dist_ts/ts_smartdb/server/handlers/index.d.ts +0 -8
- package/dist_ts/ts_smartdb/server/handlers/index.js +0 -10
- package/dist_ts/ts_smartdb/storage/FileStorageAdapter.d.ts +0 -85
- package/dist_ts/ts_smartdb/storage/FileStorageAdapter.js +0 -465
- package/dist_ts/ts_smartdb/storage/IStorageAdapter.d.ts +0 -145
- package/dist_ts/ts_smartdb/storage/IStorageAdapter.js +0 -2
- package/dist_ts/ts_smartdb/storage/MemoryStorageAdapter.d.ts +0 -67
- package/dist_ts/ts_smartdb/storage/MemoryStorageAdapter.js +0 -378
- package/dist_ts/ts_smartdb/storage/OpLog.d.ts +0 -93
- package/dist_ts/ts_smartdb/storage/OpLog.js +0 -221
- package/dist_ts/ts_smartdb/storage/WAL.d.ts +0 -117
- package/dist_ts/ts_smartdb/storage/WAL.js +0 -286
- package/dist_ts/ts_smartdb/types/interfaces.d.ts +0 -363
- package/dist_ts/ts_smartdb/types/interfaces.js +0 -2
- package/dist_ts/ts_smartdb/utils/checksum.d.ts +0 -30
- package/dist_ts/ts_smartdb/utils/checksum.js +0 -77
- package/dist_ts/ts_smartdb/utils/index.d.ts +0 -1
- package/dist_ts/ts_smartdb/utils/index.js +0 -2
- package/ts/ts_smartdb/engine/AggregationEngine.ts +0 -283
- package/ts/ts_smartdb/engine/IndexEngine.ts +0 -798
- package/ts/ts_smartdb/engine/QueryEngine.ts +0 -301
- package/ts/ts_smartdb/engine/QueryPlanner.ts +0 -393
- package/ts/ts_smartdb/engine/SessionEngine.ts +0 -292
- package/ts/ts_smartdb/engine/TransactionEngine.ts +0 -351
- package/ts/ts_smartdb/engine/UpdateEngine.ts +0 -506
- package/ts/ts_smartdb/errors/SmartdbErrors.ts +0 -181
- package/ts/ts_smartdb/server/CommandRouter.ts +0 -289
- package/ts/ts_smartdb/server/WireProtocol.ts +0 -416
- package/ts/ts_smartdb/server/handlers/AdminHandler.ts +0 -719
- package/ts/ts_smartdb/server/handlers/AggregateHandler.ts +0 -342
- package/ts/ts_smartdb/server/handlers/DeleteHandler.ts +0 -115
- package/ts/ts_smartdb/server/handlers/FindHandler.ts +0 -330
- package/ts/ts_smartdb/server/handlers/HelloHandler.ts +0 -78
- package/ts/ts_smartdb/server/handlers/IndexHandler.ts +0 -207
- package/ts/ts_smartdb/server/handlers/InsertHandler.ts +0 -97
- package/ts/ts_smartdb/server/handlers/UpdateHandler.ts +0 -344
- package/ts/ts_smartdb/server/handlers/index.ts +0 -10
- package/ts/ts_smartdb/storage/FileStorageAdapter.ts +0 -562
- package/ts/ts_smartdb/storage/IStorageAdapter.ts +0 -208
- package/ts/ts_smartdb/storage/MemoryStorageAdapter.ts +0 -455
- package/ts/ts_smartdb/storage/OpLog.ts +0 -282
- package/ts/ts_smartdb/storage/WAL.ts +0 -375
- package/ts/ts_smartdb/types/interfaces.ts +0 -433
- package/ts/ts_smartdb/utils/checksum.ts +0 -88
- package/ts/ts_smartdb/utils/index.ts +0 -1
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { RustDbBridge } from '../rust-db-bridge.js';
|
|
2
|
+
import type {
|
|
3
|
+
IOpLogEntry,
|
|
4
|
+
IOpLogResult,
|
|
5
|
+
IOpLogStats,
|
|
6
|
+
IRevertResult,
|
|
7
|
+
ICollectionInfo,
|
|
8
|
+
IDocumentsResult,
|
|
9
|
+
ISmartDbMetrics,
|
|
10
|
+
} from '../rust-db-bridge.js';
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* Server configuration options
|
|
@@ -28,90 +30,41 @@ export interface ISmartdbServerOptions {
|
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
|
-
*
|
|
32
|
-
*/
|
|
33
|
-
interface IConnectionState {
|
|
34
|
-
id: number;
|
|
35
|
-
socket: net.Socket;
|
|
36
|
-
buffer: Buffer;
|
|
37
|
-
authenticated: boolean;
|
|
38
|
-
database: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* SmartdbServer - MongoDB Wire Protocol compatible server
|
|
33
|
+
* SmartdbServer - Wire protocol compatible database server backed by Rust
|
|
43
34
|
*
|
|
44
|
-
* This server implements the
|
|
45
|
-
*
|
|
35
|
+
* This server implements the wire protocol to allow official drivers to
|
|
36
|
+
* connect and perform operations. The core engine runs as a Rust sidecar
|
|
37
|
+
* binary managed via @push.rocks/smartrust IPC.
|
|
46
38
|
*
|
|
47
39
|
* @example
|
|
48
40
|
* ```typescript
|
|
49
|
-
* import { SmartdbServer } from '@push.rocks/
|
|
41
|
+
* import { SmartdbServer } from '@push.rocks/smartdb';
|
|
50
42
|
* import { MongoClient } from 'mongodb';
|
|
51
43
|
*
|
|
52
44
|
* const server = new SmartdbServer({ port: 27017 });
|
|
53
45
|
* await server.start();
|
|
54
46
|
*
|
|
55
|
-
* const client = new MongoClient(
|
|
47
|
+
* const client = new MongoClient(server.getConnectionUri());
|
|
56
48
|
* await client.connect();
|
|
57
49
|
* ```
|
|
58
50
|
*/
|
|
59
51
|
export class SmartdbServer {
|
|
60
|
-
private options:
|
|
61
|
-
private
|
|
62
|
-
private storage: IStorageAdapter;
|
|
63
|
-
private commandRouter: CommandRouter;
|
|
64
|
-
private connections: Map<number, IConnectionState> = new Map();
|
|
65
|
-
private connectionIdCounter = 0;
|
|
52
|
+
private options: ISmartdbServerOptions;
|
|
53
|
+
private bridge: RustDbBridge;
|
|
66
54
|
private isRunning = false;
|
|
67
|
-
private
|
|
68
|
-
private useSocket: boolean;
|
|
55
|
+
private resolvedConnectionUri = '';
|
|
69
56
|
|
|
70
57
|
constructor(options: ISmartdbServerOptions = {}) {
|
|
71
|
-
this.useSocket = !!options.socketPath;
|
|
72
58
|
this.options = {
|
|
73
59
|
port: options.port ?? 27017,
|
|
74
60
|
host: options.host ?? '127.0.0.1',
|
|
75
|
-
socketPath: options.socketPath
|
|
61
|
+
socketPath: options.socketPath,
|
|
76
62
|
storage: options.storage ?? 'memory',
|
|
77
63
|
storagePath: options.storagePath ?? './data',
|
|
78
|
-
persistPath: options.persistPath
|
|
64
|
+
persistPath: options.persistPath,
|
|
79
65
|
persistIntervalMs: options.persistIntervalMs ?? 60000,
|
|
80
66
|
};
|
|
81
|
-
|
|
82
|
-
// Create storage adapter
|
|
83
|
-
if (this.options.storage === 'file') {
|
|
84
|
-
this.storage = new FileStorageAdapter(this.options.storagePath);
|
|
85
|
-
} else {
|
|
86
|
-
this.storage = new MemoryStorageAdapter({
|
|
87
|
-
persistPath: this.options.persistPath || undefined,
|
|
88
|
-
persistIntervalMs: this.options.persistPath ? this.options.persistIntervalMs : undefined,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Create command router
|
|
93
|
-
this.commandRouter = new CommandRouter(this.storage, this);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Get the storage adapter (for testing/debugging)
|
|
98
|
-
*/
|
|
99
|
-
getStorage(): IStorageAdapter {
|
|
100
|
-
return this.storage;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Get server uptime in seconds
|
|
105
|
-
*/
|
|
106
|
-
getUptime(): number {
|
|
107
|
-
return Math.floor((Date.now() - this.startTime.getTime()) / 1000);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Get current connection count
|
|
112
|
-
*/
|
|
113
|
-
getConnectionCount(): number {
|
|
114
|
-
return this.connections.size;
|
|
67
|
+
this.bridge = new RustDbBridge();
|
|
115
68
|
}
|
|
116
69
|
|
|
117
70
|
/**
|
|
@@ -122,233 +75,149 @@ export class SmartdbServer {
|
|
|
122
75
|
throw new Error('Server is already running');
|
|
123
76
|
}
|
|
124
77
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
await fs.unlink(this.options.socketPath);
|
|
132
|
-
} catch (err: any) {
|
|
133
|
-
// Ignore ENOENT (file doesn't exist)
|
|
134
|
-
if (err.code !== 'ENOENT') {
|
|
135
|
-
throw err;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
78
|
+
const spawned = await this.bridge.spawn();
|
|
79
|
+
if (!spawned) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
'smartdb Rust binary not found. Set SMARTDB_RUST_BINARY env var, ' +
|
|
82
|
+
'install the platform package, or build locally with `tsrust`.'
|
|
83
|
+
);
|
|
138
84
|
}
|
|
139
85
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
this.server.on('error', (err) => {
|
|
146
|
-
if (!this.isRunning) {
|
|
147
|
-
reject(err);
|
|
148
|
-
} else {
|
|
149
|
-
console.error('Server error:', err);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
if (this.useSocket && this.options.socketPath) {
|
|
154
|
-
// Listen on Unix socket
|
|
155
|
-
this.server.listen(this.options.socketPath, () => {
|
|
156
|
-
this.isRunning = true;
|
|
157
|
-
this.startTime = new Date();
|
|
158
|
-
resolve();
|
|
159
|
-
});
|
|
160
|
-
} else {
|
|
161
|
-
// Listen on TCP
|
|
162
|
-
this.server.listen(this.options.port, this.options.host, () => {
|
|
163
|
-
this.isRunning = true;
|
|
164
|
-
this.startTime = new Date();
|
|
165
|
-
resolve();
|
|
166
|
-
});
|
|
86
|
+
// Forward unexpected exit
|
|
87
|
+
this.bridge.on('exit', (code: number | null, signal: string | null) => {
|
|
88
|
+
if (this.isRunning) {
|
|
89
|
+
console.error(`smartdb Rust process exited unexpectedly (code=${code}, signal=${signal})`);
|
|
167
90
|
}
|
|
168
91
|
});
|
|
92
|
+
|
|
93
|
+
// Send config, get back connectionUri
|
|
94
|
+
const result = await this.bridge.startDb({
|
|
95
|
+
port: this.options.port,
|
|
96
|
+
host: this.options.host,
|
|
97
|
+
socketPath: this.options.socketPath,
|
|
98
|
+
storage: this.options.storage ?? 'memory',
|
|
99
|
+
storagePath: this.options.storagePath,
|
|
100
|
+
persistPath: this.options.persistPath,
|
|
101
|
+
persistIntervalMs: this.options.persistIntervalMs,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
this.resolvedConnectionUri = result.connectionUri;
|
|
105
|
+
this.isRunning = true;
|
|
169
106
|
}
|
|
170
107
|
|
|
171
108
|
/**
|
|
172
109
|
* Stop the server
|
|
173
110
|
*/
|
|
174
111
|
async stop(): Promise<void> {
|
|
175
|
-
if (!this.isRunning
|
|
112
|
+
if (!this.isRunning) {
|
|
176
113
|
return;
|
|
177
114
|
}
|
|
178
115
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
116
|
+
try {
|
|
117
|
+
await this.bridge.stopDb();
|
|
118
|
+
} catch {
|
|
119
|
+
// Bridge may already be dead
|
|
182
120
|
}
|
|
183
|
-
this.connections.clear();
|
|
184
|
-
|
|
185
|
-
// Close command router (cleans up session engine, cursors, etc.)
|
|
186
|
-
this.commandRouter.close();
|
|
187
|
-
|
|
188
|
-
// Close storage
|
|
189
|
-
await this.storage.close();
|
|
190
121
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
this.isRunning = false;
|
|
194
|
-
this.server = null;
|
|
195
|
-
|
|
196
|
-
// Clean up socket file if using Unix socket
|
|
197
|
-
if (this.useSocket && this.options.socketPath) {
|
|
198
|
-
try {
|
|
199
|
-
await fs.unlink(this.options.socketPath);
|
|
200
|
-
} catch (err: any) {
|
|
201
|
-
// Ignore ENOENT (file doesn't exist)
|
|
202
|
-
if (err.code !== 'ENOENT') {
|
|
203
|
-
console.error('Failed to remove socket file:', err);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
resolve();
|
|
209
|
-
});
|
|
210
|
-
});
|
|
122
|
+
this.bridge.kill();
|
|
123
|
+
this.isRunning = false;
|
|
211
124
|
}
|
|
212
125
|
|
|
213
126
|
/**
|
|
214
|
-
*
|
|
127
|
+
* Get the connection URI for this server
|
|
215
128
|
*/
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
this.connections.set(connectionId, state);
|
|
228
|
-
|
|
229
|
-
socket.on('data', (data) => {
|
|
230
|
-
this.handleData(state, Buffer.isBuffer(data) ? data : Buffer.from(data));
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
socket.on('close', () => {
|
|
234
|
-
this.connections.delete(connectionId);
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
socket.on('error', (err) => {
|
|
238
|
-
// Connection errors are expected when clients disconnect
|
|
239
|
-
this.connections.delete(connectionId);
|
|
240
|
-
});
|
|
129
|
+
getConnectionUri(): string {
|
|
130
|
+
if (this.resolvedConnectionUri) {
|
|
131
|
+
return this.resolvedConnectionUri;
|
|
132
|
+
}
|
|
133
|
+
// Fallback: compute from options
|
|
134
|
+
if (this.options.socketPath) {
|
|
135
|
+
const encodedPath = encodeURIComponent(this.options.socketPath);
|
|
136
|
+
return `mongodb://${encodedPath}`;
|
|
137
|
+
}
|
|
138
|
+
return `mongodb://${this.options.host ?? '127.0.0.1'}:${this.options.port ?? 27017}`;
|
|
241
139
|
}
|
|
242
140
|
|
|
243
141
|
/**
|
|
244
|
-
*
|
|
142
|
+
* Get the socket path (if using Unix socket mode)
|
|
245
143
|
*/
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
state.buffer = Buffer.concat([state.buffer, data]);
|
|
249
|
-
|
|
250
|
-
// Process messages from buffer
|
|
251
|
-
this.processMessages(state);
|
|
144
|
+
get socketPath(): string | undefined {
|
|
145
|
+
return this.options.socketPath;
|
|
252
146
|
}
|
|
253
147
|
|
|
254
148
|
/**
|
|
255
|
-
*
|
|
149
|
+
* Check if the server is running
|
|
256
150
|
*/
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const result = WireProtocol.parseMessage(state.buffer);
|
|
261
|
-
|
|
262
|
-
if (!result) {
|
|
263
|
-
// Not enough data for a complete message
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const { command, bytesConsumed } = result;
|
|
268
|
-
|
|
269
|
-
// Remove processed bytes from buffer
|
|
270
|
-
state.buffer = state.buffer.subarray(bytesConsumed);
|
|
271
|
-
|
|
272
|
-
// Process the command
|
|
273
|
-
const response = await this.commandRouter.route(command);
|
|
151
|
+
get running(): boolean {
|
|
152
|
+
return this.isRunning;
|
|
153
|
+
}
|
|
274
154
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
[response]
|
|
282
|
-
);
|
|
283
|
-
} else {
|
|
284
|
-
// OP_MSG gets OP_MSG response
|
|
285
|
-
responseBuffer = WireProtocol.encodeOpMsgResponse(
|
|
286
|
-
command.requestID,
|
|
287
|
-
response
|
|
288
|
-
);
|
|
289
|
-
}
|
|
155
|
+
/**
|
|
156
|
+
* Get the port the server is listening on
|
|
157
|
+
*/
|
|
158
|
+
get port(): number {
|
|
159
|
+
return this.options.port ?? 27017;
|
|
160
|
+
}
|
|
290
161
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
0, // We don't have the requestID at this point
|
|
298
|
-
1,
|
|
299
|
-
error.message || 'Internal error'
|
|
300
|
-
);
|
|
162
|
+
/**
|
|
163
|
+
* Get the host the server is bound to
|
|
164
|
+
*/
|
|
165
|
+
get host(): string {
|
|
166
|
+
return this.options.host ?? '127.0.0.1';
|
|
167
|
+
}
|
|
301
168
|
|
|
302
|
-
|
|
303
|
-
state.socket.write(errorResponse);
|
|
304
|
-
}
|
|
169
|
+
// --- OpLog / Debug API ---
|
|
305
170
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Get oplog entries, optionally filtered.
|
|
173
|
+
*/
|
|
174
|
+
async getOpLog(params: {
|
|
175
|
+
sinceSeq?: number;
|
|
176
|
+
limit?: number;
|
|
177
|
+
db?: string;
|
|
178
|
+
collection?: string;
|
|
179
|
+
} = {}): Promise<IOpLogResult> {
|
|
180
|
+
return this.bridge.getOpLog(params);
|
|
313
181
|
}
|
|
314
182
|
|
|
315
183
|
/**
|
|
316
|
-
* Get
|
|
184
|
+
* Get aggregate oplog statistics.
|
|
317
185
|
*/
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
// URL-encode the socket path (replace / with %2F)
|
|
321
|
-
const encodedPath = encodeURIComponent(this.options.socketPath);
|
|
322
|
-
return `mongodb://${encodedPath}`;
|
|
323
|
-
}
|
|
324
|
-
return `mongodb://${this.options.host}:${this.options.port}`;
|
|
186
|
+
async getOpLogStats(): Promise<IOpLogStats> {
|
|
187
|
+
return this.bridge.getOpLogStats();
|
|
325
188
|
}
|
|
326
189
|
|
|
327
190
|
/**
|
|
328
|
-
*
|
|
191
|
+
* Revert database state to a specific oplog sequence number.
|
|
192
|
+
* Use dryRun=true to preview which entries would be reverted.
|
|
329
193
|
*/
|
|
330
|
-
|
|
331
|
-
return this.
|
|
194
|
+
async revertToSeq(seq: number, dryRun = false): Promise<IRevertResult> {
|
|
195
|
+
return this.bridge.revertToSeq(seq, dryRun);
|
|
332
196
|
}
|
|
333
197
|
|
|
334
198
|
/**
|
|
335
|
-
*
|
|
199
|
+
* List all collections across all databases, with document counts.
|
|
336
200
|
*/
|
|
337
|
-
|
|
338
|
-
return this.
|
|
201
|
+
async getCollections(db?: string): Promise<ICollectionInfo[]> {
|
|
202
|
+
return this.bridge.getCollections(db);
|
|
339
203
|
}
|
|
340
204
|
|
|
341
205
|
/**
|
|
342
|
-
* Get
|
|
206
|
+
* Get documents from a collection with pagination.
|
|
343
207
|
*/
|
|
344
|
-
|
|
345
|
-
|
|
208
|
+
async getDocuments(
|
|
209
|
+
db: string,
|
|
210
|
+
collection: string,
|
|
211
|
+
limit = 50,
|
|
212
|
+
skip = 0,
|
|
213
|
+
): Promise<IDocumentsResult> {
|
|
214
|
+
return this.bridge.getDocuments(db, collection, limit, skip);
|
|
346
215
|
}
|
|
347
216
|
|
|
348
217
|
/**
|
|
349
|
-
* Get
|
|
218
|
+
* Get server metrics including database/collection counts and oplog info.
|
|
350
219
|
*/
|
|
351
|
-
|
|
352
|
-
return this.
|
|
220
|
+
async getMetrics(): Promise<ISmartDbMetrics> {
|
|
221
|
+
return this.bridge.getMetrics();
|
|
353
222
|
}
|
|
354
223
|
}
|
|
@@ -1,10 +1,3 @@
|
|
|
1
1
|
// Server module exports
|
|
2
|
-
|
|
3
2
|
export { SmartdbServer } from './SmartdbServer.js';
|
|
4
3
|
export type { ISmartdbServerOptions } from './SmartdbServer.js';
|
|
5
|
-
export { WireProtocol } from './WireProtocol.js';
|
|
6
|
-
export { CommandRouter } from './CommandRouter.js';
|
|
7
|
-
export type { ICommandHandler, IHandlerContext, ICursorState } from './CommandRouter.js';
|
|
8
|
-
|
|
9
|
-
// Export handlers
|
|
10
|
-
export * from './handlers/index.js';
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import type { Document, IStoredDocument, IAggregateOptions } from '../types/interfaces.js';
|
|
2
|
-
/**
|
|
3
|
-
* Aggregation engine using mingo for MongoDB-compatible aggregation pipeline execution
|
|
4
|
-
*/
|
|
5
|
-
export declare class AggregationEngine {
|
|
6
|
-
/**
|
|
7
|
-
* Execute an aggregation pipeline on a collection of documents
|
|
8
|
-
*/
|
|
9
|
-
static aggregate(documents: IStoredDocument[], pipeline: Document[], options?: IAggregateOptions): Document[];
|
|
10
|
-
/**
|
|
11
|
-
* Execute aggregation and return an iterator for lazy evaluation
|
|
12
|
-
*/
|
|
13
|
-
static aggregateIterator(documents: IStoredDocument[], pipeline: Document[], options?: IAggregateOptions): Generator<Document>;
|
|
14
|
-
/**
|
|
15
|
-
* Execute a $lookup stage manually (for cross-collection lookups)
|
|
16
|
-
* This is used when the lookup references another collection in the same database
|
|
17
|
-
*/
|
|
18
|
-
static executeLookup(documents: IStoredDocument[], lookupSpec: {
|
|
19
|
-
from: string;
|
|
20
|
-
localField: string;
|
|
21
|
-
foreignField: string;
|
|
22
|
-
as: string;
|
|
23
|
-
}, foreignCollection: IStoredDocument[]): Document[];
|
|
24
|
-
/**
|
|
25
|
-
* Execute a $graphLookup stage manually
|
|
26
|
-
*/
|
|
27
|
-
static executeGraphLookup(documents: IStoredDocument[], graphLookupSpec: {
|
|
28
|
-
from: string;
|
|
29
|
-
startWith: string | Document;
|
|
30
|
-
connectFromField: string;
|
|
31
|
-
connectToField: string;
|
|
32
|
-
as: string;
|
|
33
|
-
maxDepth?: number;
|
|
34
|
-
depthField?: string;
|
|
35
|
-
restrictSearchWithMatch?: Document;
|
|
36
|
-
}, foreignCollection: IStoredDocument[]): Document[];
|
|
37
|
-
/**
|
|
38
|
-
* Execute a $facet stage manually
|
|
39
|
-
*/
|
|
40
|
-
static executeFacet(documents: IStoredDocument[], facetSpec: Record<string, Document[]>): Document;
|
|
41
|
-
/**
|
|
42
|
-
* Execute a $unionWith stage
|
|
43
|
-
*/
|
|
44
|
-
static executeUnionWith(documents: IStoredDocument[], otherDocuments: IStoredDocument[], pipeline?: Document[]): Document[];
|
|
45
|
-
/**
|
|
46
|
-
* Execute a $merge stage (output to another collection)
|
|
47
|
-
* Returns the documents that would be inserted/updated
|
|
48
|
-
*/
|
|
49
|
-
static prepareMerge(documents: Document[], mergeSpec: {
|
|
50
|
-
into: string;
|
|
51
|
-
on?: string | string[];
|
|
52
|
-
whenMatched?: 'replace' | 'keepExisting' | 'merge' | 'fail' | Document[];
|
|
53
|
-
whenNotMatched?: 'insert' | 'discard' | 'fail';
|
|
54
|
-
}): {
|
|
55
|
-
toInsert: Document[];
|
|
56
|
-
toUpdate: Array<{
|
|
57
|
-
filter: Document;
|
|
58
|
-
update: Document;
|
|
59
|
-
}>;
|
|
60
|
-
onField: string | string[];
|
|
61
|
-
whenMatched: string | Document[];
|
|
62
|
-
whenNotMatched: string;
|
|
63
|
-
};
|
|
64
|
-
private static getNestedValue;
|
|
65
|
-
private static valuesMatch;
|
|
66
|
-
}
|