config/database.js

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.connectToDatabase = exports.closeClient = exports.getClient = void 0;
const mongodb_1 = require("mongodb");
/**
 * @namespace config
 * @description Configuration and utility functions for managing MongoDB connections.
 */
/**
 * MongoDB connection URI from the environment variable `MONGO_URI`.
 * Throws an error if not set.
 *
 * @memberof config
 * @constant {string}
 */
const mongoUrl = process.env.MONGO_URI;
if (!mongoUrl) {
    throw new Error("MONGODB_URI environment variable not set");
}
/**
 * MongoDB client instance. Initialized as `null` and set upon first connection.
 *
 * @memberof config
 * @type {(MongoClient | null)}
 */
let client = null;
/**
 * Promise for the MongoDB client instance. Ensures only one connection is created.
 *
 * @memberof config
 * @type {(Promise<MongoClient> | null)}
 */
let clientPromise = null;
/**
 * Retrieves the MongoDB client instance, connecting if necessary.
 * Ensures only one connection is created across multiple calls.
 *
 * @memberof config
 * @async
 * @function
 * @returns {Promise<MongoClient>} Resolves to the MongoDB client instance.
 * @throws {Error} Throws an error if the client cannot be connected.
 * @example
 * const client = await getClient();
 * console.log(client.isConnected());
 */
const getClient = () => __awaiter(void 0, void 0, void 0, function* () {
    if (!client) {
        if (!clientPromise) {
            clientPromise = (() => __awaiter(void 0, void 0, void 0, function* () {
                const newClient = new mongodb_1.MongoClient(mongoUrl, {
                    maxPoolSize: 10,
                    compressors: 'zlib,snappy,zstd'
                });
                yield newClient.connect();
                console.log('MongoDB client connected');
                return newClient;
            }))();
        }
        client = yield clientPromise;
    }
    return client;
});
exports.getClient = getClient;
/**
 * Connects to the specified database using the MongoDB client.
 * If no database name is provided, the default database is used.
 *
 * @memberof config
 * @async
 * @function
 * @param {?string} [dbName] - Name of the database to connect to. Optional.
 * @returns {Promise<Db>} Resolves to the database instance.
 * @throws {Error} Throws an error if the database connection fails.
 * @example
 * const db = await connectToDatabase("myDatabase");
 * console.log(db.databaseName);
 */
const connectToDatabase = (dbName) => __awaiter(void 0, void 0, void 0, function* () {
    const client = yield getClient();
    return client.db(dbName);
});
exports.connectToDatabase = connectToDatabase;
/**
 * Closes the MongoDB client connection.
 * Ensures the client and its promise are reset to avoid stale connections.
 *
 * @memberof config
 * @async
 * @function
 * @returns {Promise<void>} Resolves when the client is successfully closed.
 * @throws {Error} Throws an error if the client fails to close.
 * @example
 * await closeClient();
 * console.log('Connection closed');
 */
const closeClient = () => __awaiter(void 0, void 0, void 0, function* () {
    if (client) {
        yield client.close();
        console.log('MongoDB client closed.');
        client = null; // Make sure to set the client to null after closing
        clientPromise = null; // Reset clientPromise to avoid stale promises
    }
});
exports.closeClient = closeClient;