@push.rocks/smartdb 2.7.0 → 2.8.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/dist_rust/rustdb_linux_amd64 +0 -0
- package/dist_rust/rustdb_linux_arm64 +0 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/ts_smartdb/index.d.ts +1 -1
- package/dist_ts/ts_smartdb/index.js +1 -1
- package/dist_ts/ts_smartdb/rust-db-bridge.d.ts +22 -0
- package/dist_ts/ts_smartdb/rust-db-bridge.js +1 -1
- package/dist_ts/ts_smartdb/server/SmartdbServer.d.ts +23 -0
- package/dist_ts/ts_smartdb/server/SmartdbServer.js +7 -2
- package/dist_ts_debugserver/bundled.js +1 -1
- package/package.json +1 -1
- package/readme.md +63 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/ts_smartdb/index.ts +6 -1
- package/ts/ts_smartdb/rust-db-bridge.ts +22 -0
- package/ts/ts_smartdb/server/SmartdbServer.ts +32 -1
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -248,6 +248,64 @@ const server = new SmartdbServer({
|
|
|
248
248
|
persistPath: './data/snapshot.json',
|
|
249
249
|
persistIntervalMs: 30000, // Save every 30s
|
|
250
250
|
});
|
|
251
|
+
|
|
252
|
+
// TLS transport for TCP mode
|
|
253
|
+
const tlsServer = new SmartdbServer({
|
|
254
|
+
port: 27017,
|
|
255
|
+
tls: {
|
|
256
|
+
enabled: true,
|
|
257
|
+
certPath: './certs/server.pem',
|
|
258
|
+
keyPath: './certs/server.key',
|
|
259
|
+
// caPath: './certs/client-ca.pem',
|
|
260
|
+
// requireClientCert: true, // Enables mTLS client certificate checks
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// SCRAM-SHA-256 authentication
|
|
265
|
+
const secureServer = new SmartdbServer({
|
|
266
|
+
port: 27017,
|
|
267
|
+
auth: {
|
|
268
|
+
enabled: true,
|
|
269
|
+
usersPath: './data/smartdb-users.json', // Optional: persists derived SCRAM credentials
|
|
270
|
+
users: [
|
|
271
|
+
{
|
|
272
|
+
username: 'root',
|
|
273
|
+
password: 'change-me',
|
|
274
|
+
database: 'admin',
|
|
275
|
+
roles: ['root'],
|
|
276
|
+
},
|
|
277
|
+
],
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
When `auth.enabled` is true, protected commands require successful SCRAM-SHA-256 authentication through the official MongoDB driver:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
const client = new MongoClient('mongodb://root:change-me@127.0.0.1:27017/admin?authSource=admin', {
|
|
286
|
+
directConnection: true,
|
|
287
|
+
});
|
|
288
|
+
await client.connect();
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
TLS is available for TCP listeners. `getConnectionUri()` includes `?tls=true` when TLS is enabled; pass the trusted CA to the MongoDB driver with `tlsCAFile`, `ca`, or `secureContext`.
|
|
292
|
+
|
|
293
|
+
Authentication verifies SCRAM credentials, denies unauthenticated commands, and enforces command-level built-in roles for supported operations. `connectionStatus` reports the authenticated users and roles for the current socket.
|
|
294
|
+
|
|
295
|
+
Supported built-in role names are `root`, `read`, `readWrite`, `dbAdmin`, `userAdmin`, `clusterMonitor`, plus `readAnyDatabase`, `readWriteAnyDatabase`, `dbAdminAnyDatabase`, and `userAdminAnyDatabase`. When `usersPath` is set, SmartDB persists SCRAM credential material atomically and does not store plaintext passwords.
|
|
296
|
+
|
|
297
|
+
Single-node transactions are supported through official MongoDB driver sessions. Writes with `startTransaction` and `autocommit: false` are buffered per logical session, reads inside the transaction see the buffered overlay, `commitTransaction` applies the write set with conflict checks, and `abortTransaction` discards it.
|
|
298
|
+
|
|
299
|
+
Basic user management commands are available for authenticated users with `root` or `userAdmin` privileges:
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
await client.db('admin').command({
|
|
303
|
+
createUser: 'reader',
|
|
304
|
+
pwd: 'readpass',
|
|
305
|
+
roles: [{ role: 'read', db: 'myapp' }],
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
await client.db('admin').command({ usersInfo: 'reader' });
|
|
251
309
|
```
|
|
252
310
|
|
|
253
311
|
#### Methods & Properties
|
|
@@ -261,7 +319,7 @@ const server = new SmartdbServer({
|
|
|
261
319
|
| `port` | `number` | Configured port (TCP mode) |
|
|
262
320
|
| `host` | `string` | Configured host (TCP mode) |
|
|
263
321
|
| `socketPath` | `string \| undefined` | Socket path (socket mode) |
|
|
264
|
-
| `getMetrics()` | `Promise<ISmartDbMetrics>` | Server metrics (db/collection counts, uptime) |
|
|
322
|
+
| `getMetrics()` | `Promise<ISmartDbMetrics>` | Server metrics (db/collection counts, sessions, transactions, auth, uptime) |
|
|
265
323
|
| `getOpLog(params?)` | `Promise<IOpLogResult>` | Query oplog entries with optional filters |
|
|
266
324
|
| `getOpLogStats()` | `Promise<IOpLogStats>` | Aggregate oplog statistics |
|
|
267
325
|
| `revertToSeq(seq, dryRun?)` | `Promise<IRevertResult>` | Revert to a specific oplog sequence |
|
|
@@ -475,7 +533,7 @@ const names = await collection.distinct('name');
|
|
|
475
533
|
| **Aggregation** | `aggregate`, `count`, `distinct` |
|
|
476
534
|
| **Indexes** | `createIndexes`, `dropIndexes`, `listIndexes` |
|
|
477
535
|
| **Sessions** | `startSession`, `endSessions` |
|
|
478
|
-
| **Transactions** | `commitTransaction`, `abortTransaction` |
|
|
536
|
+
| **Transactions** | `startTransaction`, `commitTransaction`, `abortTransaction` through driver sessions |
|
|
479
537
|
| **Admin** | `ping`, `listDatabases`, `listCollections`, `drop`, `dropDatabase`, `create`, `serverStatus`, `buildInfo`, `dbStats`, `collStats`, `connectionStatus`, `currentOp`, `renameCollection` |
|
|
480
538
|
|
|
481
539
|
Compatible with wire protocol versions 0–21 (driver versions 3.6 through 7.0).
|
|
@@ -484,7 +542,7 @@ Compatible with wire protocol versions 0–21 (driver versions 3.6 through 7.0).
|
|
|
484
542
|
|
|
485
543
|
## Rust Crate Architecture 🦀
|
|
486
544
|
|
|
487
|
-
The Rust engine is organized as a Cargo workspace with
|
|
545
|
+
The Rust engine is organized as a Cargo workspace with 9 focused crates:
|
|
488
546
|
|
|
489
547
|
| Crate | Purpose |
|
|
490
548
|
|---|---|
|
|
@@ -495,6 +553,7 @@ The Rust engine is organized as a Cargo workspace with 8 focused crates:
|
|
|
495
553
|
| `rustdb-storage` | Storage backends (memory, file), OpLog with point-in-time replay |
|
|
496
554
|
| `rustdb-index` | B-tree/hash indexes, query planner (IXSCAN/COLLSCAN) |
|
|
497
555
|
| `rustdb-txn` | Transaction + session management with snapshot isolation |
|
|
556
|
+
| `rustdb-auth` | SCRAM-SHA-256 credential handling, user metadata persistence, RBAC checks |
|
|
498
557
|
| `rustdb-commands` | 40+ command handlers wiring everything together |
|
|
499
558
|
|
|
500
559
|
Cross-compiled for `linux_amd64` and `linux_arm64` via [@git.zone/tsrust](https://www.npmjs.com/package/@git.zone/tsrust).
|
|
@@ -507,6 +566,7 @@ The Bitcask-style file storage engine includes several reliability features:
|
|
|
507
566
|
- **CRC32 checksums** — every record is integrity-checked on read
|
|
508
567
|
- **Automatic compaction** — dead records are reclaimed when they exceed 50% of file size, runs on startup and after every write
|
|
509
568
|
- **Hint file staleness detection** — the hint file records the data file size at write time; if data.rdb changed since (e.g. crash after a delete), the engine falls back to a full scan to ensure tombstones are not lost
|
|
569
|
+
- **Torn-tail repair** — startup scans `data.rdb` to the last valid record, truncates invalid trailing bytes, and preserves all verified records after interrupted writes
|
|
510
570
|
- **Stale socket cleanup** — orphaned `/tmp/smartdb-*.sock` files from crashed instances are automatically cleaned up on startup
|
|
511
571
|
|
|
512
572
|
### Data Integrity CLI 🔍
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/ts_smartdb/index.ts
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
// Export server (the main entry point for using SmartDB)
|
|
4
4
|
export { SmartdbServer } from './server/SmartdbServer.js';
|
|
5
|
-
export type {
|
|
5
|
+
export type {
|
|
6
|
+
ISmartdbAuthOptions,
|
|
7
|
+
ISmartdbAuthUser,
|
|
8
|
+
ISmartdbServerOptions,
|
|
9
|
+
ISmartdbTlsOptions,
|
|
10
|
+
} from './server/SmartdbServer.js';
|
|
6
11
|
|
|
7
12
|
// Export bridge for advanced usage
|
|
8
13
|
export { RustDbBridge } from './rust-db-bridge.js';
|
|
@@ -76,6 +76,10 @@ export interface ISmartDbMetrics {
|
|
|
76
76
|
collections: number;
|
|
77
77
|
oplogEntries: number;
|
|
78
78
|
oplogCurrentSeq: number;
|
|
79
|
+
sessions: number;
|
|
80
|
+
activeTransactions: number;
|
|
81
|
+
authEnabled: boolean;
|
|
82
|
+
authUsers: number;
|
|
79
83
|
uptimeSeconds: number;
|
|
80
84
|
}
|
|
81
85
|
|
|
@@ -117,6 +121,24 @@ interface ISmartDbRustConfig {
|
|
|
117
121
|
storagePath?: string;
|
|
118
122
|
persistPath?: string;
|
|
119
123
|
persistIntervalMs?: number;
|
|
124
|
+
auth?: {
|
|
125
|
+
enabled?: boolean;
|
|
126
|
+
users?: Array<{
|
|
127
|
+
username: string;
|
|
128
|
+
password: string;
|
|
129
|
+
database?: string;
|
|
130
|
+
roles?: string[];
|
|
131
|
+
}>;
|
|
132
|
+
usersPath?: string;
|
|
133
|
+
scramIterations?: number;
|
|
134
|
+
};
|
|
135
|
+
tls?: {
|
|
136
|
+
enabled?: boolean;
|
|
137
|
+
certPath?: string;
|
|
138
|
+
keyPath?: string;
|
|
139
|
+
caPath?: string;
|
|
140
|
+
requireClientCert?: boolean;
|
|
141
|
+
};
|
|
120
142
|
}
|
|
121
143
|
|
|
122
144
|
/**
|
|
@@ -28,6 +28,32 @@ export interface ISmartdbServerOptions {
|
|
|
28
28
|
persistPath?: string;
|
|
29
29
|
/** Persistence interval in ms (default: 60000) */
|
|
30
30
|
persistIntervalMs?: number;
|
|
31
|
+
/** Authentication configuration. Disabled by default. */
|
|
32
|
+
auth?: ISmartdbAuthOptions;
|
|
33
|
+
/** TLS transport configuration for TCP listeners. Disabled by default. */
|
|
34
|
+
tls?: ISmartdbTlsOptions;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ISmartdbAuthOptions {
|
|
38
|
+
enabled?: boolean;
|
|
39
|
+
users?: ISmartdbAuthUser[];
|
|
40
|
+
usersPath?: string;
|
|
41
|
+
scramIterations?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ISmartdbAuthUser {
|
|
45
|
+
username: string;
|
|
46
|
+
password: string;
|
|
47
|
+
database?: string;
|
|
48
|
+
roles?: string[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface ISmartdbTlsOptions {
|
|
52
|
+
enabled?: boolean;
|
|
53
|
+
certPath?: string;
|
|
54
|
+
keyPath?: string;
|
|
55
|
+
caPath?: string;
|
|
56
|
+
requireClientCert?: boolean;
|
|
31
57
|
}
|
|
32
58
|
|
|
33
59
|
/**
|
|
@@ -64,6 +90,8 @@ export class SmartdbServer {
|
|
|
64
90
|
storagePath: options.storagePath ?? './data',
|
|
65
91
|
persistPath: options.persistPath,
|
|
66
92
|
persistIntervalMs: options.persistIntervalMs ?? 60000,
|
|
93
|
+
auth: options.auth,
|
|
94
|
+
tls: options.tls,
|
|
67
95
|
};
|
|
68
96
|
this.bridge = new RustDbBridge();
|
|
69
97
|
}
|
|
@@ -106,6 +134,8 @@ export class SmartdbServer {
|
|
|
106
134
|
storagePath: this.options.storagePath,
|
|
107
135
|
persistPath: this.options.persistPath,
|
|
108
136
|
persistIntervalMs: this.options.persistIntervalMs,
|
|
137
|
+
auth: this.options.auth,
|
|
138
|
+
tls: this.options.tls,
|
|
109
139
|
});
|
|
110
140
|
|
|
111
141
|
this.resolvedConnectionUri = result.connectionUri;
|
|
@@ -142,7 +172,8 @@ export class SmartdbServer {
|
|
|
142
172
|
const encodedPath = encodeURIComponent(this.options.socketPath);
|
|
143
173
|
return `mongodb://${encodedPath}`;
|
|
144
174
|
}
|
|
145
|
-
|
|
175
|
+
const baseUri = `mongodb://${this.options.host ?? '127.0.0.1'}:${this.options.port ?? 27017}`;
|
|
176
|
+
return this.options.tls?.enabled ? `${baseUri}/?tls=true` : baseUri;
|
|
146
177
|
}
|
|
147
178
|
|
|
148
179
|
/**
|