@push.rocks/smartdb 2.0.0 → 2.3.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 +11 -0
- 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/index.d.ts +2 -0
- package/dist_ts/index.js +3 -1
- package/dist_ts/ts_local/classes.localsmartdb.js +7 -4
- package/dist_ts/ts_migration/classes.storagemigrator.d.ts +24 -0
- package/dist_ts/ts_migration/classes.storagemigrator.js +75 -0
- package/dist_ts/ts_migration/index.d.ts +1 -0
- package/dist_ts/ts_migration/index.js +2 -0
- package/dist_ts/ts_migration/migrators/v0_to_v1.d.ts +9 -0
- package/dist_ts/ts_migration/migrators/v0_to_v1.js +225 -0
- package/dist_ts/ts_smartdb/index.d.ts +1 -0
- package/dist_ts/ts_smartdb/rust-db-bridge.d.ts +80 -1
- package/dist_ts/ts_smartdb/rust-db-bridge.js +17 -2
- package/dist_ts/ts_smartdb/server/SmartdbServer.d.ts +31 -0
- package/dist_ts/ts_smartdb/server/SmartdbServer.js +47 -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/package.json +9 -4
- package/readme.md +161 -42
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +14 -0
- package/ts/ts_local/classes.localsmartdb.ts +5 -0
- package/ts/ts_migration/classes.storagemigrator.ts +93 -0
- package/ts/ts_migration/index.ts +1 -0
- package/ts/ts_migration/migrators/v0_to_v1.ts +253 -0
- package/ts/ts_smartdb/index.ts +11 -0
- package/ts/ts_smartdb/rust-db-bridge.ts +127 -3
- package/ts/ts_smartdb/server/SmartdbServer.ts +71 -0
package/.smartconfig.json
CHANGED
|
@@ -32,6 +32,17 @@
|
|
|
32
32
|
"@git.zone/tsdoc": {
|
|
33
33
|
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
|
34
34
|
},
|
|
35
|
+
"@git.zone/tsbundle": {
|
|
36
|
+
"bundles": [
|
|
37
|
+
{
|
|
38
|
+
"from": "./ts_debugui/index.ts",
|
|
39
|
+
"to": "./ts_debugserver/bundled.ts",
|
|
40
|
+
"outputMode": "base64ts",
|
|
41
|
+
"bundler": "esbuild",
|
|
42
|
+
"includeFiles": ["./html/index.html"]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
35
46
|
"@git.zone/tsrust": {
|
|
36
47
|
"targets": ["linux_amd64", "linux_arm64"]
|
|
37
48
|
},
|
|
Binary file
|
|
Binary file
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartdb',
|
|
6
|
-
version: '2.
|
|
6
|
+
version: '2.3.0',
|
|
7
7
|
description: 'A MongoDB-compatible embedded database server with wire protocol support, backed by a high-performance Rust engine.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxxQkFBcUI7SUFDM0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHFIQUFxSDtDQUNuSSxDQUFBIn0=
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -2,4 +2,6 @@ import { commitinfo } from './00_commitinfo_data.js';
|
|
|
2
2
|
export * from './ts_smartdb/index.js';
|
|
3
3
|
export { LocalSmartDb } from './ts_local/index.js';
|
|
4
4
|
export type { ILocalSmartDbOptions, ILocalSmartDbConnectionInfo } from './ts_local/index.js';
|
|
5
|
+
export { StorageMigrator } from './ts_migration/index.js';
|
|
5
6
|
export { commitinfo };
|
|
7
|
+
export type { IOpLogEntry, IOpLogResult, IOpLogStats, IRevertResult, ICollectionInfo, IDocumentsResult, ISmartDbMetrics, } from './ts_smartdb/index.js';
|
package/dist_ts/index.js
CHANGED
|
@@ -3,6 +3,8 @@ import { commitinfo } from './00_commitinfo_data.js';
|
|
|
3
3
|
export * from './ts_smartdb/index.js';
|
|
4
4
|
// Export LocalSmartDb
|
|
5
5
|
export { LocalSmartDb } from './ts_local/index.js';
|
|
6
|
+
// Export migration
|
|
7
|
+
export { StorageMigrator } from './ts_migration/index.js';
|
|
6
8
|
// Export commitinfo
|
|
7
9
|
export { commitinfo };
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFckQsNkJBQTZCO0FBQzdCLGNBQWMsdUJBQXVCLENBQUM7QUFFdEMsc0JBQXNCO0FBQ3RCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUduRCxtQkFBbUI7QUFDbkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRTFELG9CQUFvQjtBQUNwQixPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMifQ==
|
|
@@ -2,6 +2,7 @@ import * as crypto from 'crypto';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import * as os from 'os';
|
|
4
4
|
import { SmartdbServer } from '../ts_smartdb/index.js';
|
|
5
|
+
import { StorageMigrator } from '../ts_migration/index.js';
|
|
5
6
|
/**
|
|
6
7
|
* LocalSmartDb - Lightweight local MongoDB-compatible database using Unix sockets
|
|
7
8
|
*
|
|
@@ -31,10 +32,9 @@ import { SmartdbServer } from '../ts_smartdb/index.js';
|
|
|
31
32
|
* ```
|
|
32
33
|
*/
|
|
33
34
|
export class LocalSmartDb {
|
|
34
|
-
options;
|
|
35
|
-
server = null;
|
|
36
|
-
generatedSocketPath = null;
|
|
37
35
|
constructor(options) {
|
|
36
|
+
this.server = null;
|
|
37
|
+
this.generatedSocketPath = null;
|
|
38
38
|
this.options = options;
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
@@ -51,6 +51,9 @@ export class LocalSmartDb {
|
|
|
51
51
|
if (this.server) {
|
|
52
52
|
throw new Error('LocalSmartDb is already running');
|
|
53
53
|
}
|
|
54
|
+
// Run storage migration before starting the Rust engine
|
|
55
|
+
const migrator = new StorageMigrator(this.options.folderPath);
|
|
56
|
+
await migrator.run();
|
|
54
57
|
// Use provided socket path or generate one
|
|
55
58
|
this.generatedSocketPath = this.options.socketPath ?? this.generateSocketPath();
|
|
56
59
|
this.server = new SmartdbServer({
|
|
@@ -111,4 +114,4 @@ export class LocalSmartDb {
|
|
|
111
114
|
}
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
117
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5sb2NhbHNtYXJ0ZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy90c19sb2NhbC9jbGFzc2VzLmxvY2Fsc21hcnRkYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUNqQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBbUIzRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMkJHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFLdkIsWUFBWSxPQUE2QjtRQUhqQyxXQUFNLEdBQXlCLElBQUksQ0FBQztRQUNwQyx3QkFBbUIsR0FBa0IsSUFBSSxDQUFDO1FBR2hELElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7T0FFRztJQUNLLGtCQUFrQjtRQUN4QixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2RCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFLFdBQVcsUUFBUSxPQUFPLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsS0FBSztRQUNULElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUNyRCxDQUFDO1FBRUQsd0RBQXdEO1FBQ3hELE1BQU0sUUFBUSxHQUFHLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUQsTUFBTSxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFckIsMkNBQTJDO1FBQzNDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUVoRixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksYUFBYSxDQUFDO1lBQzlCLFVBQVUsRUFBRSxJQUFJLENBQUMsbUJBQW1CO1lBQ3BDLE9BQU8sRUFBRSxNQUFNO1lBQ2YsV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVTtTQUNyQyxDQUFDLENBQUM7UUFDSCxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFMUIsT0FBTztZQUNMLFVBQVUsRUFBRSxJQUFJLENBQUMsbUJBQW1CO1lBQ3BDLGFBQWEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFO1NBQzlDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxpQkFBaUI7UUFDZixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlDLE1BQU0sSUFBSSxLQUFLLENBQUMsa0RBQWtELENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBQ0QsT0FBTztZQUNMLFVBQVUsRUFBRSxJQUFJLENBQUMsbUJBQW1CO1lBQ3BDLGFBQWEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFO1NBQzlDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxTQUFTO1FBQ1AsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7UUFDdEUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxnQkFBZ0I7UUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsa0RBQWtELENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDeEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxPQUFPO1FBQ1QsT0FBTyxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUNyRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsSUFBSTtRQUNSLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN6QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztZQUNuQixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1FBQ2xDLENBQUM7SUFDSCxDQUFDO0NBQ0YifQ==
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StorageMigrator — runs before the Rust engine starts.
|
|
3
|
+
*
|
|
4
|
+
* Detects the current storage format version and runs the appropriate
|
|
5
|
+
* migration chain. The Rust engine only knows the current format (v1).
|
|
6
|
+
*
|
|
7
|
+
* Migration is safe: original files are never modified or deleted.
|
|
8
|
+
* On success, a console hint is printed about which old files can be removed.
|
|
9
|
+
*/
|
|
10
|
+
export declare class StorageMigrator {
|
|
11
|
+
private storagePath;
|
|
12
|
+
constructor(storagePath: string);
|
|
13
|
+
/**
|
|
14
|
+
* Run any needed migrations. Safe to call even if storage is already current.
|
|
15
|
+
*/
|
|
16
|
+
run(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Detect the storage format version by inspecting the directory structure.
|
|
19
|
+
*
|
|
20
|
+
* v0: {db}/{coll}.json files exist
|
|
21
|
+
* v1: {db}/{coll}/data.rdb directories exist
|
|
22
|
+
*/
|
|
23
|
+
private detectVersion;
|
|
24
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { migrateV0ToV1 } from './migrators/v0_to_v1.js';
|
|
4
|
+
/**
|
|
5
|
+
* StorageMigrator — runs before the Rust engine starts.
|
|
6
|
+
*
|
|
7
|
+
* Detects the current storage format version and runs the appropriate
|
|
8
|
+
* migration chain. The Rust engine only knows the current format (v1).
|
|
9
|
+
*
|
|
10
|
+
* Migration is safe: original files are never modified or deleted.
|
|
11
|
+
* On success, a console hint is printed about which old files can be removed.
|
|
12
|
+
*/
|
|
13
|
+
export class StorageMigrator {
|
|
14
|
+
constructor(storagePath) {
|
|
15
|
+
this.storagePath = storagePath;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Run any needed migrations. Safe to call even if storage is already current.
|
|
19
|
+
*/
|
|
20
|
+
async run() {
|
|
21
|
+
if (!fs.existsSync(this.storagePath)) {
|
|
22
|
+
return; // No data yet — nothing to migrate
|
|
23
|
+
}
|
|
24
|
+
const version = this.detectVersion();
|
|
25
|
+
if (version === 1) {
|
|
26
|
+
return; // Already current
|
|
27
|
+
}
|
|
28
|
+
if (version === 0) {
|
|
29
|
+
console.log(`[smartdb] Detected v0 (JSON) storage format at ${this.storagePath}`);
|
|
30
|
+
console.log(`[smartdb] Running migration v0 → v1 (Bitcask binary format)...`);
|
|
31
|
+
const deletableFiles = await migrateV0ToV1(this.storagePath);
|
|
32
|
+
if (deletableFiles.length > 0) {
|
|
33
|
+
console.log(`[smartdb] Migration v0 → v1 complete.`);
|
|
34
|
+
console.log(`[smartdb] The following old files can be safely deleted:`);
|
|
35
|
+
for (const f of deletableFiles) {
|
|
36
|
+
console.log(`[smartdb] ${f}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
console.log(`[smartdb] Migration v0 → v1 complete. No old files to clean up.`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Detect the storage format version by inspecting the directory structure.
|
|
46
|
+
*
|
|
47
|
+
* v0: {db}/{coll}.json files exist
|
|
48
|
+
* v1: {db}/{coll}/data.rdb directories exist
|
|
49
|
+
*/
|
|
50
|
+
detectVersion() {
|
|
51
|
+
const entries = fs.readdirSync(this.storagePath, { withFileTypes: true });
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
if (!entry.isDirectory())
|
|
54
|
+
continue;
|
|
55
|
+
const dbDir = path.join(this.storagePath, entry.name);
|
|
56
|
+
const dbEntries = fs.readdirSync(dbDir, { withFileTypes: true });
|
|
57
|
+
for (const dbEntry of dbEntries) {
|
|
58
|
+
// v1: subdirectory with data.rdb
|
|
59
|
+
if (dbEntry.isDirectory()) {
|
|
60
|
+
const dataRdb = path.join(dbDir, dbEntry.name, 'data.rdb');
|
|
61
|
+
if (fs.existsSync(dataRdb)) {
|
|
62
|
+
return 1;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// v0: .json file (not .indexes.json)
|
|
66
|
+
if (dbEntry.isFile() && dbEntry.name.endsWith('.json') && !dbEntry.name.endsWith('.indexes.json')) {
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Empty or unrecognized — treat as v1 (fresh start)
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zdG9yYWdlbWlncmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy90c19taWdyYXRpb24vY2xhc3Nlcy5zdG9yYWdlbWlncmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBU3hEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFHMUIsWUFBWSxXQUFtQjtRQUM3QixJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztJQUNqQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsR0FBRztRQUNQLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ3JDLE9BQU8sQ0FBQyxtQ0FBbUM7UUFDN0MsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUVyQyxJQUFJLE9BQU8sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNsQixPQUFPLENBQUMsa0JBQWtCO1FBQzVCLENBQUM7UUFFRCxJQUFJLE9BQU8sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNsQixPQUFPLENBQUMsR0FBRyxDQUFDLGtEQUFrRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUNsRixPQUFPLENBQUMsR0FBRyxDQUFDLGdFQUFnRSxDQUFDLENBQUM7WUFFOUUsTUFBTSxjQUFjLEdBQUcsTUFBTSxhQUFhLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRTdELElBQUksY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO2dCQUNyRCxPQUFPLENBQUMsR0FBRyxDQUFDLDBEQUEwRCxDQUFDLENBQUM7Z0JBQ3hFLEtBQUssTUFBTSxDQUFDLElBQUksY0FBYyxFQUFFLENBQUM7b0JBQy9CLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNsQyxDQUFDO1lBQ0gsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUVBQWlFLENBQUMsQ0FBQztZQUNqRixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLGFBQWE7UUFDbkIsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFFMUUsS0FBSyxNQUFNLEtBQUssSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRTtnQkFBRSxTQUFTO1lBRW5DLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdEQsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUVqRSxLQUFLLE1BQU0sT0FBTyxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNoQyxpQ0FBaUM7Z0JBQ2pDLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7b0JBQzFCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7b0JBQzNELElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO3dCQUMzQixPQUFPLENBQUMsQ0FBQztvQkFDWCxDQUFDO2dCQUNILENBQUM7Z0JBQ0QscUNBQXFDO2dCQUNyQyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7b0JBQ2xHLE9BQU8sQ0FBQyxDQUFDO2dCQUNYLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELG9EQUFvRDtRQUNwRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StorageMigrator } from './classes.storagemigrator.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { StorageMigrator } from './classes.storagemigrator.js';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy90c19taWdyYXRpb24vaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDIn0=
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrate a storage directory from v0 (JSON-per-collection) to v1 (Bitcask binary).
|
|
3
|
+
*
|
|
4
|
+
* - Original .json files are NOT modified or deleted.
|
|
5
|
+
* - New v1 files are written into {db}/{coll}/ subdirectories.
|
|
6
|
+
* - Returns a list of old files that can be safely deleted.
|
|
7
|
+
* - On failure, cleans up any partial new files and throws.
|
|
8
|
+
*/
|
|
9
|
+
export declare function migrateV0ToV1(storagePath: string): Promise<string[]>;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as crypto from 'crypto';
|
|
4
|
+
import { BSON } from 'bson';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Binary format constants (must match Rust: record.rs)
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
/** File-level magic: "SMARTDB\0" */
|
|
9
|
+
const FILE_MAGIC = Buffer.from('SMARTDB\0', 'ascii');
|
|
10
|
+
/** Current format version */
|
|
11
|
+
const FORMAT_VERSION = 1;
|
|
12
|
+
/** File type tags */
|
|
13
|
+
const FILE_TYPE_DATA = 1;
|
|
14
|
+
const FILE_TYPE_HINT = 3;
|
|
15
|
+
/** File header total size */
|
|
16
|
+
const FILE_HEADER_SIZE = 64;
|
|
17
|
+
/** Per-record magic */
|
|
18
|
+
const RECORD_MAGIC = 0xDB01;
|
|
19
|
+
/** Per-record header size */
|
|
20
|
+
const RECORD_HEADER_SIZE = 22; // 2 + 8 + 4 + 4 + 4
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Binary encoding helpers
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
function writeFileHeader(fileType) {
|
|
25
|
+
const buf = Buffer.alloc(FILE_HEADER_SIZE, 0);
|
|
26
|
+
FILE_MAGIC.copy(buf, 0);
|
|
27
|
+
buf.writeUInt16LE(FORMAT_VERSION, 8);
|
|
28
|
+
buf.writeUInt8(fileType, 10);
|
|
29
|
+
buf.writeUInt32LE(0, 11); // flags
|
|
30
|
+
const now = BigInt(Date.now());
|
|
31
|
+
buf.writeBigUInt64LE(now, 15);
|
|
32
|
+
// bytes 23..64 are reserved (zeros)
|
|
33
|
+
return buf;
|
|
34
|
+
}
|
|
35
|
+
function encodeDataRecord(timestamp, key, value) {
|
|
36
|
+
const keyLen = key.length;
|
|
37
|
+
const valLen = value.length;
|
|
38
|
+
const totalSize = RECORD_HEADER_SIZE + keyLen + valLen;
|
|
39
|
+
const buf = Buffer.alloc(totalSize);
|
|
40
|
+
// Write header fields (without CRC)
|
|
41
|
+
buf.writeUInt16LE(RECORD_MAGIC, 0);
|
|
42
|
+
buf.writeBigUInt64LE(timestamp, 2);
|
|
43
|
+
buf.writeUInt32LE(keyLen, 10);
|
|
44
|
+
buf.writeUInt32LE(valLen, 14);
|
|
45
|
+
// CRC placeholder at offset 18..22 (will fill below)
|
|
46
|
+
key.copy(buf, RECORD_HEADER_SIZE);
|
|
47
|
+
value.copy(buf, RECORD_HEADER_SIZE + keyLen);
|
|
48
|
+
// CRC32 covers everything except the CRC field itself:
|
|
49
|
+
// bytes [0..18] + bytes [22..]
|
|
50
|
+
const crc = crc32(Buffer.concat([
|
|
51
|
+
buf.subarray(0, 18),
|
|
52
|
+
buf.subarray(22),
|
|
53
|
+
]));
|
|
54
|
+
buf.writeUInt32LE(crc, 18);
|
|
55
|
+
return buf;
|
|
56
|
+
}
|
|
57
|
+
function encodeHintEntry(key, offset, recordLen, valueLen, timestamp) {
|
|
58
|
+
const keyBuf = Buffer.from(key, 'utf-8');
|
|
59
|
+
const buf = Buffer.alloc(4 + keyBuf.length + 8 + 4 + 4 + 8);
|
|
60
|
+
let pos = 0;
|
|
61
|
+
buf.writeUInt32LE(keyBuf.length, pos);
|
|
62
|
+
pos += 4;
|
|
63
|
+
keyBuf.copy(buf, pos);
|
|
64
|
+
pos += keyBuf.length;
|
|
65
|
+
buf.writeBigUInt64LE(offset, pos);
|
|
66
|
+
pos += 8;
|
|
67
|
+
buf.writeUInt32LE(recordLen, pos);
|
|
68
|
+
pos += 4;
|
|
69
|
+
buf.writeUInt32LE(valueLen, pos);
|
|
70
|
+
pos += 4;
|
|
71
|
+
buf.writeBigUInt64LE(timestamp, pos);
|
|
72
|
+
return buf;
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// CRC32 (matching crc32fast in Rust)
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
const CRC32_TABLE = (() => {
|
|
78
|
+
const table = new Uint32Array(256);
|
|
79
|
+
for (let i = 0; i < 256; i++) {
|
|
80
|
+
let crc = i;
|
|
81
|
+
for (let j = 0; j < 8; j++) {
|
|
82
|
+
crc = (crc & 1) ? (0xEDB88320 ^ (crc >>> 1)) : (crc >>> 1);
|
|
83
|
+
}
|
|
84
|
+
table[i] = crc;
|
|
85
|
+
}
|
|
86
|
+
return table;
|
|
87
|
+
})();
|
|
88
|
+
function crc32(data) {
|
|
89
|
+
let crc = 0xFFFFFFFF;
|
|
90
|
+
for (let i = 0; i < data.length; i++) {
|
|
91
|
+
crc = CRC32_TABLE[(crc ^ data[i]) & 0xFF] ^ (crc >>> 8);
|
|
92
|
+
}
|
|
93
|
+
return (crc ^ 0xFFFFFFFF) >>> 0;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Migrate a storage directory from v0 (JSON-per-collection) to v1 (Bitcask binary).
|
|
97
|
+
*
|
|
98
|
+
* - Original .json files are NOT modified or deleted.
|
|
99
|
+
* - New v1 files are written into {db}/{coll}/ subdirectories.
|
|
100
|
+
* - Returns a list of old files that can be safely deleted.
|
|
101
|
+
* - On failure, cleans up any partial new files and throws.
|
|
102
|
+
*/
|
|
103
|
+
export async function migrateV0ToV1(storagePath) {
|
|
104
|
+
const deletableFiles = [];
|
|
105
|
+
const createdDirs = [];
|
|
106
|
+
try {
|
|
107
|
+
const dbEntries = fs.readdirSync(storagePath, { withFileTypes: true });
|
|
108
|
+
for (const dbEntry of dbEntries) {
|
|
109
|
+
if (!dbEntry.isDirectory())
|
|
110
|
+
continue;
|
|
111
|
+
const dbDir = path.join(storagePath, dbEntry.name);
|
|
112
|
+
const collFiles = fs.readdirSync(dbDir, { withFileTypes: true });
|
|
113
|
+
for (const collFile of collFiles) {
|
|
114
|
+
if (!collFile.isFile())
|
|
115
|
+
continue;
|
|
116
|
+
if (!collFile.name.endsWith('.json'))
|
|
117
|
+
continue;
|
|
118
|
+
if (collFile.name.endsWith('.indexes.json'))
|
|
119
|
+
continue;
|
|
120
|
+
const collName = collFile.name.replace(/\.json$/, '');
|
|
121
|
+
const jsonPath = path.join(dbDir, collFile.name);
|
|
122
|
+
const indexJsonPath = path.join(dbDir, `${collName}.indexes.json`);
|
|
123
|
+
// Target directory
|
|
124
|
+
const collDir = path.join(dbDir, collName);
|
|
125
|
+
if (fs.existsSync(collDir)) {
|
|
126
|
+
// Already migrated
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
console.log(`[smartdb] Migrating ${dbEntry.name}.${collName}...`);
|
|
130
|
+
// Read the JSON collection
|
|
131
|
+
const jsonData = fs.readFileSync(jsonPath, 'utf-8');
|
|
132
|
+
const docs = JSON.parse(jsonData);
|
|
133
|
+
// Create collection directory
|
|
134
|
+
fs.mkdirSync(collDir, { recursive: true });
|
|
135
|
+
createdDirs.push(collDir);
|
|
136
|
+
// Write data.rdb
|
|
137
|
+
const dataPath = path.join(collDir, 'data.rdb');
|
|
138
|
+
const fd = fs.openSync(dataPath, 'w');
|
|
139
|
+
try {
|
|
140
|
+
// File header
|
|
141
|
+
const headerBuf = writeFileHeader(FILE_TYPE_DATA);
|
|
142
|
+
fs.writeSync(fd, headerBuf);
|
|
143
|
+
let currentOffset = BigInt(FILE_HEADER_SIZE);
|
|
144
|
+
const keydir = new Map();
|
|
145
|
+
const ts = BigInt(Date.now());
|
|
146
|
+
for (const doc of docs) {
|
|
147
|
+
// Extract _id
|
|
148
|
+
let idHex;
|
|
149
|
+
if (doc._id && doc._id.$oid) {
|
|
150
|
+
idHex = doc._id.$oid;
|
|
151
|
+
}
|
|
152
|
+
else if (typeof doc._id === 'string') {
|
|
153
|
+
idHex = doc._id;
|
|
154
|
+
}
|
|
155
|
+
else if (doc._id) {
|
|
156
|
+
idHex = String(doc._id);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// Generate a new ObjectId
|
|
160
|
+
idHex = crypto.randomBytes(12).toString('hex');
|
|
161
|
+
doc._id = { $oid: idHex };
|
|
162
|
+
}
|
|
163
|
+
// Serialize to BSON
|
|
164
|
+
const bsonBytes = BSON.serialize(doc);
|
|
165
|
+
const keyBuf = Buffer.from(idHex, 'utf-8');
|
|
166
|
+
const valueBuf = Buffer.from(bsonBytes);
|
|
167
|
+
const record = encodeDataRecord(ts, keyBuf, valueBuf);
|
|
168
|
+
fs.writeSync(fd, record);
|
|
169
|
+
keydir.set(idHex, {
|
|
170
|
+
offset: currentOffset,
|
|
171
|
+
recordLen: record.length,
|
|
172
|
+
valueLen: valueBuf.length,
|
|
173
|
+
timestamp: ts,
|
|
174
|
+
});
|
|
175
|
+
currentOffset += BigInt(record.length);
|
|
176
|
+
}
|
|
177
|
+
fs.fsyncSync(fd);
|
|
178
|
+
fs.closeSync(fd);
|
|
179
|
+
// Write keydir.hint
|
|
180
|
+
const hintPath = path.join(collDir, 'keydir.hint');
|
|
181
|
+
const hintFd = fs.openSync(hintPath, 'w');
|
|
182
|
+
fs.writeSync(hintFd, writeFileHeader(FILE_TYPE_HINT));
|
|
183
|
+
for (const [key, entry] of keydir) {
|
|
184
|
+
fs.writeSync(hintFd, encodeHintEntry(key, entry.offset, entry.recordLen, entry.valueLen, entry.timestamp));
|
|
185
|
+
}
|
|
186
|
+
fs.fsyncSync(hintFd);
|
|
187
|
+
fs.closeSync(hintFd);
|
|
188
|
+
}
|
|
189
|
+
catch (writeErr) {
|
|
190
|
+
// Clean up on write failure
|
|
191
|
+
try {
|
|
192
|
+
fs.closeSync(fd);
|
|
193
|
+
}
|
|
194
|
+
catch { }
|
|
195
|
+
throw writeErr;
|
|
196
|
+
}
|
|
197
|
+
// Copy indexes.json if it exists
|
|
198
|
+
if (fs.existsSync(indexJsonPath)) {
|
|
199
|
+
const destIndexPath = path.join(collDir, 'indexes.json');
|
|
200
|
+
fs.copyFileSync(indexJsonPath, destIndexPath);
|
|
201
|
+
deletableFiles.push(indexJsonPath);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// Write default _id index
|
|
205
|
+
const destIndexPath = path.join(collDir, 'indexes.json');
|
|
206
|
+
fs.writeFileSync(destIndexPath, JSON.stringify([{ name: '_id_', key: { _id: 1 } }], null, 2));
|
|
207
|
+
}
|
|
208
|
+
deletableFiles.push(jsonPath);
|
|
209
|
+
console.log(`[smartdb] Migrated ${dbEntry.name}.${collName}: ${docs.length} documents`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
// Clean up any partially created directories
|
|
215
|
+
for (const dir of createdDirs) {
|
|
216
|
+
try {
|
|
217
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
218
|
+
}
|
|
219
|
+
catch { }
|
|
220
|
+
}
|
|
221
|
+
throw err;
|
|
222
|
+
}
|
|
223
|
+
return deletableFiles;
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidjBfdG9fdjEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy90c19taWdyYXRpb24vbWlncmF0b3JzL3YwX3RvX3YxLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFNUIsOEVBQThFO0FBQzlFLHVEQUF1RDtBQUN2RCw4RUFBOEU7QUFFOUUsb0NBQW9DO0FBQ3BDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3JELDZCQUE2QjtBQUM3QixNQUFNLGNBQWMsR0FBRyxDQUFDLENBQUM7QUFDekIscUJBQXFCO0FBQ3JCLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQztBQUN6QixNQUFNLGNBQWMsR0FBRyxDQUFDLENBQUM7QUFDekIsNkJBQTZCO0FBQzdCLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO0FBQzVCLHVCQUF1QjtBQUN2QixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUM7QUFDNUIsNkJBQTZCO0FBQzdCLE1BQU0sa0JBQWtCLEdBQUcsRUFBRSxDQUFDLENBQUMsb0JBQW9CO0FBRW5ELDhFQUE4RTtBQUM5RSwwQkFBMEI7QUFDMUIsOEVBQThFO0FBRTlFLFNBQVMsZUFBZSxDQUFDLFFBQWdCO0lBQ3ZDLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUMsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDeEIsR0FBRyxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENB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
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { SmartdbServer } from './server/SmartdbServer.js';
|
|
2
2
|
export type { ISmartdbServerOptions } from './server/SmartdbServer.js';
|
|
3
3
|
export { RustDbBridge } from './rust-db-bridge.js';
|
|
4
|
+
export type { IOpLogEntry, IOpLogResult, IOpLogStats, IRevertResult, ICollectionInfo, IDocumentsResult, ISmartDbMetrics, } from './rust-db-bridge.js';
|
|
@@ -1,4 +1,73 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
+
/**
|
|
3
|
+
* A single oplog entry returned from the Rust engine.
|
|
4
|
+
*/
|
|
5
|
+
export interface IOpLogEntry {
|
|
6
|
+
seq: number;
|
|
7
|
+
timestampMs: number;
|
|
8
|
+
op: 'insert' | 'update' | 'delete';
|
|
9
|
+
db: string;
|
|
10
|
+
collection: string;
|
|
11
|
+
documentId: string;
|
|
12
|
+
document: Record<string, any> | null;
|
|
13
|
+
previousDocument: Record<string, any> | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Aggregate oplog statistics.
|
|
17
|
+
*/
|
|
18
|
+
export interface IOpLogStats {
|
|
19
|
+
currentSeq: number;
|
|
20
|
+
totalEntries: number;
|
|
21
|
+
oldestSeq: number;
|
|
22
|
+
entriesByOp: {
|
|
23
|
+
insert: number;
|
|
24
|
+
update: number;
|
|
25
|
+
delete: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Result of a getOpLog query.
|
|
30
|
+
*/
|
|
31
|
+
export interface IOpLogResult {
|
|
32
|
+
entries: IOpLogEntry[];
|
|
33
|
+
currentSeq: number;
|
|
34
|
+
totalEntries: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Result of a revertToSeq command.
|
|
38
|
+
*/
|
|
39
|
+
export interface IRevertResult {
|
|
40
|
+
dryRun: boolean;
|
|
41
|
+
reverted: number;
|
|
42
|
+
targetSeq?: number;
|
|
43
|
+
entries?: IOpLogEntry[];
|
|
44
|
+
errors?: string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A collection info entry.
|
|
48
|
+
*/
|
|
49
|
+
export interface ICollectionInfo {
|
|
50
|
+
db: string;
|
|
51
|
+
name: string;
|
|
52
|
+
count: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Result of a getDocuments query.
|
|
56
|
+
*/
|
|
57
|
+
export interface IDocumentsResult {
|
|
58
|
+
documents: Record<string, any>[];
|
|
59
|
+
total: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Server metrics.
|
|
63
|
+
*/
|
|
64
|
+
export interface ISmartDbMetrics {
|
|
65
|
+
databases: number;
|
|
66
|
+
collections: number;
|
|
67
|
+
oplogEntries: number;
|
|
68
|
+
oplogCurrentSeq: number;
|
|
69
|
+
uptimeSeconds: number;
|
|
70
|
+
}
|
|
2
71
|
/**
|
|
3
72
|
* Configuration sent to the Rust binary on start.
|
|
4
73
|
*/
|
|
@@ -38,6 +107,16 @@ export declare class RustDbBridge extends EventEmitter {
|
|
|
38
107
|
getStatus(): Promise<{
|
|
39
108
|
running: boolean;
|
|
40
109
|
}>;
|
|
41
|
-
getMetrics(): Promise<
|
|
110
|
+
getMetrics(): Promise<ISmartDbMetrics>;
|
|
111
|
+
getOpLog(params?: {
|
|
112
|
+
sinceSeq?: number;
|
|
113
|
+
limit?: number;
|
|
114
|
+
db?: string;
|
|
115
|
+
collection?: string;
|
|
116
|
+
}): Promise<IOpLogResult>;
|
|
117
|
+
getOpLogStats(): Promise<IOpLogStats>;
|
|
118
|
+
revertToSeq(seq: number, dryRun?: boolean): Promise<IRevertResult>;
|
|
119
|
+
getCollections(db?: string): Promise<ICollectionInfo[]>;
|
|
120
|
+
getDocuments(db: string, collection: string, limit?: number, skip?: number): Promise<IDocumentsResult>;
|
|
42
121
|
}
|
|
43
122
|
export {};
|
|
@@ -47,7 +47,6 @@ function buildLocalPaths() {
|
|
|
47
47
|
* Wraps @push.rocks/smartrust's RustBridge with type-safe command definitions.
|
|
48
48
|
*/
|
|
49
49
|
export class RustDbBridge extends EventEmitter {
|
|
50
|
-
bridge;
|
|
51
50
|
constructor() {
|
|
52
51
|
super();
|
|
53
52
|
this.bridge = new plugins.smartrust.RustBridge({
|
|
@@ -94,5 +93,21 @@ export class RustDbBridge extends EventEmitter {
|
|
|
94
93
|
async getMetrics() {
|
|
95
94
|
return this.bridge.sendCommand('getMetrics', {});
|
|
96
95
|
}
|
|
96
|
+
async getOpLog(params = {}) {
|
|
97
|
+
return this.bridge.sendCommand('getOpLog', params);
|
|
98
|
+
}
|
|
99
|
+
async getOpLogStats() {
|
|
100
|
+
return this.bridge.sendCommand('getOpLogStats', {});
|
|
101
|
+
}
|
|
102
|
+
async revertToSeq(seq, dryRun = false) {
|
|
103
|
+
return this.bridge.sendCommand('revertToSeq', { seq, dryRun });
|
|
104
|
+
}
|
|
105
|
+
async getCollections(db) {
|
|
106
|
+
const result = await this.bridge.sendCommand('getCollections', db ? { db } : {});
|
|
107
|
+
return result.collections;
|
|
108
|
+
}
|
|
109
|
+
async getDocuments(db, collection, limit = 50, skip = 0) {
|
|
110
|
+
return this.bridge.sendCommand('getDocuments', { db, collection, limit, skip });
|
|
111
|
+
}
|
|
97
112
|
}
|
|
98
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
113
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVzdC1kYi1icmlkZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy90c19zbWFydGRiL3J1c3QtZGItYnJpZGdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBQzNCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFzSHRDOzs7R0FHRztBQUNILFNBQVMsY0FBYztJQUNyQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLHVCQUF1QjtJQUM5QixNQUFNLE9BQU8sR0FBMkIsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN6RSxNQUFNLEtBQUssR0FBMkIsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUMxRSxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ25DLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsSUFBSSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUM7UUFDZixPQUFPLEdBQUcsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7O0dBR0c7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
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IOpLogResult, IOpLogStats, IRevertResult, ICollectionInfo, IDocumentsResult, ISmartDbMetrics } from '../rust-db-bridge.js';
|
|
1
2
|
/**
|
|
2
3
|
* Server configuration options
|
|
3
4
|
*/
|
|
@@ -70,4 +71,34 @@ export declare class SmartdbServer {
|
|
|
70
71
|
* Get the host the server is bound to
|
|
71
72
|
*/
|
|
72
73
|
get host(): string;
|
|
74
|
+
/**
|
|
75
|
+
* Get oplog entries, optionally filtered.
|
|
76
|
+
*/
|
|
77
|
+
getOpLog(params?: {
|
|
78
|
+
sinceSeq?: number;
|
|
79
|
+
limit?: number;
|
|
80
|
+
db?: string;
|
|
81
|
+
collection?: string;
|
|
82
|
+
}): Promise<IOpLogResult>;
|
|
83
|
+
/**
|
|
84
|
+
* Get aggregate oplog statistics.
|
|
85
|
+
*/
|
|
86
|
+
getOpLogStats(): Promise<IOpLogStats>;
|
|
87
|
+
/**
|
|
88
|
+
* Revert database state to a specific oplog sequence number.
|
|
89
|
+
* Use dryRun=true to preview which entries would be reverted.
|
|
90
|
+
*/
|
|
91
|
+
revertToSeq(seq: number, dryRun?: boolean): Promise<IRevertResult>;
|
|
92
|
+
/**
|
|
93
|
+
* List all collections across all databases, with document counts.
|
|
94
|
+
*/
|
|
95
|
+
getCollections(db?: string): Promise<ICollectionInfo[]>;
|
|
96
|
+
/**
|
|
97
|
+
* Get documents from a collection with pagination.
|
|
98
|
+
*/
|
|
99
|
+
getDocuments(db: string, collection: string, limit?: number, skip?: number): Promise<IDocumentsResult>;
|
|
100
|
+
/**
|
|
101
|
+
* Get server metrics including database/collection counts and oplog info.
|
|
102
|
+
*/
|
|
103
|
+
getMetrics(): Promise<ISmartDbMetrics>;
|
|
73
104
|
}
|