Files
smartdb/ts/ts_local/classes.localsmartdb.ts

143 lines
3.7 KiB
TypeScript

import * as crypto from 'crypto';
import * as path from 'path';
import * as os from 'os';
import { SmartdbServer } from '../ts_smartdb/index.js';
/**
* Connection information returned by LocalSmartDb.start()
*/
export interface ILocalSmartDbConnectionInfo {
/** The Unix socket file path */
socketPath: string;
/** Connection URI (mongodb:// scheme) ready for MongoClient */
connectionUri: string;
}
export interface ILocalSmartDbOptions {
/** Required: where to store data */
folderPath: string;
/** Optional: custom socket path (default: auto-generated in /tmp) */
socketPath?: string;
}
/**
* LocalSmartDb - Lightweight local MongoDB-compatible database using Unix sockets
*
* This class wraps SmartdbServer and provides a simple interface for
* starting a local file-based database server. Returns connection
* info that you can use with any compatible driver instance.
*
* @example
* ```typescript
* import { LocalSmartDb } from '@push.rocks/smartdb';
* import { MongoClient } from 'mongodb';
*
* const db = new LocalSmartDb({ folderPath: './data' });
* const { connectionUri } = await db.start();
*
* // Connect with the driver
* const client = new MongoClient(connectionUri, { directConnection: true });
* await client.connect();
*
* // Use the client
* const collection = client.db('mydb').collection('users');
* await collection.insertOne({ name: 'Alice' });
*
* // When done
* await client.close();
* await db.stop();
* ```
*/
export class LocalSmartDb {
private options: ILocalSmartDbOptions;
private server: SmartdbServer | null = null;
private generatedSocketPath: string | null = null;
constructor(options: ILocalSmartDbOptions) {
this.options = options;
}
/**
* Generate a unique socket path in /tmp
*/
private generateSocketPath(): string {
const randomId = crypto.randomBytes(8).toString('hex');
return path.join(os.tmpdir(), `smartdb-${randomId}.sock`);
}
/**
* Start the local SmartDB server and return connection info
*/
async start(): Promise<ILocalSmartDbConnectionInfo> {
if (this.server) {
throw new Error('LocalSmartDb is already running');
}
// Use provided socket path or generate one
this.generatedSocketPath = this.options.socketPath ?? this.generateSocketPath();
this.server = new SmartdbServer({
socketPath: this.generatedSocketPath,
storage: 'file',
storagePath: this.options.folderPath,
});
await this.server.start();
return {
socketPath: this.generatedSocketPath,
connectionUri: this.server.getConnectionUri(),
};
}
/**
* Get connection info (throws if not started)
*/
getConnectionInfo(): ILocalSmartDbConnectionInfo {
if (!this.server || !this.generatedSocketPath) {
throw new Error('LocalSmartDb is not running. Call start() first.');
}
return {
socketPath: this.generatedSocketPath,
connectionUri: this.server.getConnectionUri(),
};
}
/**
* Get the underlying SmartdbServer instance (throws if not started)
*/
getServer(): SmartdbServer {
if (!this.server) {
throw new Error('LocalSmartDb is not running. Call start() first.');
}
return this.server;
}
/**
* Get the connection URI
*/
getConnectionUri(): string {
if (!this.server) {
throw new Error('LocalSmartDb is not running. Call start() first.');
}
return this.server.getConnectionUri();
}
/**
* Check if the server is running
*/
get running(): boolean {
return this.server !== null && this.server.running;
}
/**
* Stop the local SmartDB server
*/
async stop(): Promise<void> {
if (this.server) {
await this.server.stop();
this.server = null;
this.generatedSocketPath = null;
}
}
}