Thin MongoDB ODM built for Standard Schema
mongodb zod deno
at main 3.3 kB view raw
1import { type Db, MongoClient, type MongoClientOptions } from "mongodb"; 2import { ConnectionError } from "../errors.ts"; 3 4/** 5 * Connection management module 6 * 7 * Handles MongoDB connection lifecycle including connect, disconnect, 8 * and connection state management. 9 */ 10 11export interface Connection { 12 client: MongoClient; 13 db: Db; 14} 15 16export interface ConnectOptions extends MongoClientOptions {} 17 18// Singleton connection state 19let connection: Connection | null = null; 20 21/** 22 * Connect to MongoDB with connection pooling, retry logic, and resilience options 23 * 24 * The MongoDB driver handles connection pooling and automatic retries. 25 * Retry logic is enabled by default for both reads and writes in MongoDB 4.2+. 26 * 27 * @param uri - MongoDB connection string 28 * @param dbName - Name of the database to connect to 29 * @param options - Connection options (pooling, retries, timeouts, etc.) 30 * @returns Connection object with client and db 31 * 32 * @example 33 * Basic connection with pooling: 34 * ```ts 35 * await connect("mongodb://localhost:27017", "mydb", { 36 * maxPoolSize: 10, 37 * minPoolSize: 2, 38 * maxIdleTimeMS: 30000, 39 * connectTimeoutMS: 10000, 40 * socketTimeoutMS: 45000, 41 * }); 42 * ``` 43 * 44 * @example 45 * Production-ready connection with retry logic and resilience: 46 * ```ts 47 * await connect("mongodb://localhost:27017", "mydb", { 48 * // Connection pooling 49 * maxPoolSize: 10, 50 * minPoolSize: 2, 51 * 52 * // Automatic retry logic (enabled by default) 53 * retryReads: true, // Retry failed read operations 54 * retryWrites: true, // Retry failed write operations 55 * 56 * // Timeouts 57 * connectTimeoutMS: 10000, // Initial connection timeout 58 * socketTimeoutMS: 45000, // Socket operation timeout 59 * serverSelectionTimeoutMS: 10000, // Server selection timeout 60 * 61 * // Connection resilience 62 * maxIdleTimeMS: 30000, // Close idle connections 63 * heartbeatFrequencyMS: 10000, // Server health check interval 64 * 65 * // Optional: Compression for reduced bandwidth 66 * compressors: ['snappy', 'zlib'], 67 * }); 68 * ``` 69 */ 70export async function connect( 71 uri: string, 72 dbName: string, 73 options?: ConnectOptions, 74): Promise<Connection> { 75 if (connection) { 76 return connection; 77 } 78 79 try { 80 const client = new MongoClient(uri, options); 81 await client.connect(); 82 const db = client.db(dbName); 83 84 connection = { client, db }; 85 return connection; 86 } catch (error) { 87 throw new ConnectionError( 88 `Failed to connect to MongoDB: ${ 89 error instanceof Error ? error.message : String(error) 90 }`, 91 uri, 92 ); 93 } 94} 95 96/** 97 * Disconnect from MongoDB and clean up resources 98 */ 99export async function disconnect(): Promise<void> { 100 if (connection) { 101 await connection.client.close(); 102 connection = null; 103 } 104} 105 106/** 107 * Get the current database connection 108 * 109 * @returns MongoDB Db instance 110 * @throws {ConnectionError} If not connected 111 * @internal 112 */ 113export function getDb(): Db { 114 if (!connection) { 115 throw new ConnectionError("MongoDB not connected. Call connect() first."); 116 } 117 return connection.db; 118} 119 120/** 121 * Get the current connection state 122 * 123 * @returns Connection object or null if not connected 124 * @internal 125 */ 126export function getConnection(): Connection | null { 127 return connection; 128}