UNPKG

@notross/mongo-singleton

Version:

A lightweight, zero-fuss way to get a single shared MongoDB connection across your Node.js codebase.

154 lines 5.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const mongodb_1 = require("mongodb"); const utils_1 = require("./utils"); const mongodbConfig = { serverApi: { version: mongodb_1.ServerApiVersion.v1, strict: true, deprecationErrors: true, }, }; const logger = new utils_1.Logger(); /** * MongoSingleton * * Manages a single, shared MongoDB connection for the application. * Subsequent calls to `.connect()` return the same connection. * * Like me, it's single and looking for a connection. 💔 */ class MongoSingleton { /** * @param connectionProps - Either a full ConnectionProps object, a SparseConnectionProps object, or a raw MongoDB URI string. * @param database - The name of the database to operate on. */ constructor(connectionProps, database) { this.client = null; this.database = null; this.status = 'Disconnected'; this.error = null; this.initializeLogging(connectionProps); this.databaseName = database; if (typeof connectionProps === 'string') { this.uri = connectionProps; } else { this.uri = connectionProps.uri || (0, utils_1.buildConnectionString)(connectionProps); } } initializeLogging(props) { var _a, _b; const logging = typeof props === 'object' ? (_a = props.logging) !== null && _a !== void 0 ? _a : true : true; logger.toggleLogging(logging); const levels = typeof props === 'object' ? (_b = props.logLevels) !== null && _b !== void 0 ? _b : undefined : undefined; logger.setLevels(levels); } initializeClient() { if (this.client) { return this.client; } const client = new mongodb_1.MongoClient(this.uri, mongodbConfig); return client; } initializeDatabase(client) { this.database = client.db(this.databaseName); return this.database; } getDb(client) { return this.database || this.initializeDatabase(client); } /** * Establishes a connection to MongoDB if not already connected. * If already connected, returns the existing client and database. * * @returns Promise resolving to the connected MongoClient and Db. * @example * const { client, database } = await mongoClient.connect(); */ async connect() { if (this.client) { return { client: this.client, database: this.getDb(this.client), }; } this.client = this.initializeClient(); await this.client.connect().then((client) => this.initializeDatabase(client)); this.client.on('connectionReady', () => { this.status = 'MongoDB connection is ready'; logger.log(this.status); }); this.client.on('close', () => { this.status = 'MongoDB connection closed'; logger.log(this.status); }); this.client.on('error', (err) => { this.status = 'MongoDB connection error'; this.error = err; logger.error(this.status, err); }); this.client.on('reconnect', () => { this.status = 'MongoDB reconnected'; logger.log(this.status); }); this.client.on('reconnectFailed', () => { this.status = 'MongoDB reconnection failed'; logger.error(this.status); }); this.client.on('timeout', () => { this.status = 'MongoDB connection timed out'; logger.error(this.status); }); this.client.on('serverHeartbeatFailed', (err) => { this.status = 'MongoDB server heartbeat failed:'; this.error = err; logger.error(this.status, this.error); }); this.client.on('serverHeartbeatSucceeded', () => { this.status = 'MongoDB server heartbeat succeeded'; logger.log(this.status); }); this.client.on('serverClosed', () => { this.status = 'MongoDB server closed'; logger.log(this.status); }); this.client.on('serverOpening', () => { this.status = 'MongoDB server opening'; logger.log(this.status); }); return { client: this.client, database: this.getDb(this.client), }; } /** * Gracefully closes the MongoDB connection and resets internal state. * If no client exists, logs a warning instead. */ async disconnect() { if (this.client) { await this.client.close().then(() => { this.client = null; this.database = null; this.status = 'Disconnected from MongoDB'; logger.log(this.status); }).catch((err) => { this.status = 'Error disconnecting from MongoDB'; this.error = err; logger.error(this.status, err); }); } else { this.status = 'No MongoDB client to disconnect'; logger.warn(this.status); } } } exports.default = MongoSingleton; //# sourceMappingURL=client.js.map