feat(smartdb): add operation log APIs, point-in-time revert support, and a web-based debug dashboard
This commit is contained in:
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/smartdb',
|
||||
version: '2.0.0',
|
||||
version: '2.1.0',
|
||||
description: 'A MongoDB-compatible embedded database server with wire protocol support, backed by a high-performance Rust engine.'
|
||||
}
|
||||
|
||||
11
ts/index.ts
11
ts/index.ts
@@ -9,3 +9,14 @@ export type { ILocalSmartDbOptions, ILocalSmartDbConnectionInfo } from './ts_loc
|
||||
|
||||
// Export commitinfo
|
||||
export { commitinfo };
|
||||
|
||||
// Re-export oplog / debug types for convenience
|
||||
export type {
|
||||
IOpLogEntry,
|
||||
IOpLogResult,
|
||||
IOpLogStats,
|
||||
IRevertResult,
|
||||
ICollectionInfo,
|
||||
IDocumentsResult,
|
||||
ISmartDbMetrics,
|
||||
} from './ts_smartdb/index.js';
|
||||
|
||||
@@ -6,3 +6,14 @@ export type { ISmartdbServerOptions } from './server/SmartdbServer.js';
|
||||
|
||||
// Export bridge for advanced usage
|
||||
export { RustDbBridge } from './rust-db-bridge.js';
|
||||
|
||||
// Export oplog / debug types
|
||||
export type {
|
||||
IOpLogEntry,
|
||||
IOpLogResult,
|
||||
IOpLogStats,
|
||||
IRevertResult,
|
||||
ICollectionInfo,
|
||||
IDocumentsResult,
|
||||
ISmartDbMetrics,
|
||||
} from './rust-db-bridge.js';
|
||||
|
||||
@@ -3,6 +3,82 @@ import * as path from 'path';
|
||||
import * as url from 'url';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
/**
|
||||
* A single oplog entry returned from the Rust engine.
|
||||
*/
|
||||
export interface IOpLogEntry {
|
||||
seq: number;
|
||||
timestampMs: number;
|
||||
op: 'insert' | 'update' | 'delete';
|
||||
db: string;
|
||||
collection: string;
|
||||
documentId: string;
|
||||
document: Record<string, any> | null;
|
||||
previousDocument: Record<string, any> | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregate oplog statistics.
|
||||
*/
|
||||
export interface IOpLogStats {
|
||||
currentSeq: number;
|
||||
totalEntries: number;
|
||||
oldestSeq: number;
|
||||
entriesByOp: {
|
||||
insert: number;
|
||||
update: number;
|
||||
delete: number;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of a getOpLog query.
|
||||
*/
|
||||
export interface IOpLogResult {
|
||||
entries: IOpLogEntry[];
|
||||
currentSeq: number;
|
||||
totalEntries: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of a revertToSeq command.
|
||||
*/
|
||||
export interface IRevertResult {
|
||||
dryRun: boolean;
|
||||
reverted: number;
|
||||
targetSeq?: number;
|
||||
entries?: IOpLogEntry[];
|
||||
errors?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection info entry.
|
||||
*/
|
||||
export interface ICollectionInfo {
|
||||
db: string;
|
||||
name: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of a getDocuments query.
|
||||
*/
|
||||
export interface IDocumentsResult {
|
||||
documents: Record<string, any>[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Server metrics.
|
||||
*/
|
||||
export interface ISmartDbMetrics {
|
||||
databases: number;
|
||||
collections: number;
|
||||
oplogEntries: number;
|
||||
oplogCurrentSeq: number;
|
||||
uptimeSeconds: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safe command definitions for the RustDb IPC protocol.
|
||||
*/
|
||||
@@ -10,7 +86,24 @@ type TSmartDbCommands = {
|
||||
start: { params: { config: ISmartDbRustConfig }; result: { connectionUri: string } };
|
||||
stop: { params: Record<string, never>; result: void };
|
||||
getStatus: { params: Record<string, never>; result: { running: boolean } };
|
||||
getMetrics: { params: Record<string, never>; result: any };
|
||||
getMetrics: { params: Record<string, never>; result: ISmartDbMetrics };
|
||||
getOpLog: {
|
||||
params: { sinceSeq?: number; limit?: number; db?: string; collection?: string };
|
||||
result: IOpLogResult;
|
||||
};
|
||||
getOpLogStats: { params: Record<string, never>; result: IOpLogStats };
|
||||
revertToSeq: {
|
||||
params: { seq: number; dryRun?: boolean };
|
||||
result: IRevertResult;
|
||||
};
|
||||
getCollections: {
|
||||
params: { db?: string };
|
||||
result: { collections: ICollectionInfo[] };
|
||||
};
|
||||
getDocuments: {
|
||||
params: { db: string; collection: string; limit?: number; skip?: number };
|
||||
result: IDocumentsResult;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -132,7 +225,38 @@ export class RustDbBridge extends EventEmitter {
|
||||
return await this.bridge.sendCommand('getStatus', {} as Record<string, never>) as { running: boolean };
|
||||
}
|
||||
|
||||
public async getMetrics(): Promise<any> {
|
||||
return this.bridge.sendCommand('getMetrics', {} as Record<string, never>);
|
||||
public async getMetrics(): Promise<ISmartDbMetrics> {
|
||||
return this.bridge.sendCommand('getMetrics', {} as Record<string, never>) as Promise<ISmartDbMetrics>;
|
||||
}
|
||||
|
||||
public async getOpLog(params: {
|
||||
sinceSeq?: number;
|
||||
limit?: number;
|
||||
db?: string;
|
||||
collection?: string;
|
||||
} = {}): Promise<IOpLogResult> {
|
||||
return this.bridge.sendCommand('getOpLog', params) as Promise<IOpLogResult>;
|
||||
}
|
||||
|
||||
public async getOpLogStats(): Promise<IOpLogStats> {
|
||||
return this.bridge.sendCommand('getOpLogStats', {} as Record<string, never>) as Promise<IOpLogStats>;
|
||||
}
|
||||
|
||||
public async revertToSeq(seq: number, dryRun = false): Promise<IRevertResult> {
|
||||
return this.bridge.sendCommand('revertToSeq', { seq, dryRun }) as Promise<IRevertResult>;
|
||||
}
|
||||
|
||||
public async getCollections(db?: string): Promise<ICollectionInfo[]> {
|
||||
const result = await this.bridge.sendCommand('getCollections', db ? { db } : {}) as { collections: ICollectionInfo[] };
|
||||
return result.collections;
|
||||
}
|
||||
|
||||
public async getDocuments(
|
||||
db: string,
|
||||
collection: string,
|
||||
limit = 50,
|
||||
skip = 0,
|
||||
): Promise<IDocumentsResult> {
|
||||
return this.bridge.sendCommand('getDocuments', { db, collection, limit, skip }) as Promise<IDocumentsResult>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
import { RustDbBridge } from '../rust-db-bridge.js';
|
||||
import type {
|
||||
IOpLogEntry,
|
||||
IOpLogResult,
|
||||
IOpLogStats,
|
||||
IRevertResult,
|
||||
ICollectionInfo,
|
||||
IDocumentsResult,
|
||||
ISmartDbMetrics,
|
||||
} from '../rust-db-bridge.js';
|
||||
|
||||
/**
|
||||
* Server configuration options
|
||||
@@ -156,4 +165,59 @@ export class SmartdbServer {
|
||||
get host(): string {
|
||||
return this.options.host ?? '127.0.0.1';
|
||||
}
|
||||
|
||||
// --- OpLog / Debug API ---
|
||||
|
||||
/**
|
||||
* Get oplog entries, optionally filtered.
|
||||
*/
|
||||
async getOpLog(params: {
|
||||
sinceSeq?: number;
|
||||
limit?: number;
|
||||
db?: string;
|
||||
collection?: string;
|
||||
} = {}): Promise<IOpLogResult> {
|
||||
return this.bridge.getOpLog(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get aggregate oplog statistics.
|
||||
*/
|
||||
async getOpLogStats(): Promise<IOpLogStats> {
|
||||
return this.bridge.getOpLogStats();
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert database state to a specific oplog sequence number.
|
||||
* Use dryRun=true to preview which entries would be reverted.
|
||||
*/
|
||||
async revertToSeq(seq: number, dryRun = false): Promise<IRevertResult> {
|
||||
return this.bridge.revertToSeq(seq, dryRun);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all collections across all databases, with document counts.
|
||||
*/
|
||||
async getCollections(db?: string): Promise<ICollectionInfo[]> {
|
||||
return this.bridge.getCollections(db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documents from a collection with pagination.
|
||||
*/
|
||||
async getDocuments(
|
||||
db: string,
|
||||
collection: string,
|
||||
limit = 50,
|
||||
skip = 0,
|
||||
): Promise<IDocumentsResult> {
|
||||
return this.bridge.getDocuments(db, collection, limit, skip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server metrics including database/collection counts and oplog info.
|
||||
*/
|
||||
async getMetrics(): Promise<ISmartDbMetrics> {
|
||||
return this.bridge.getMetrics();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user