UNPKG

@just-in/core

Version:

A TypeScript-first framework for building adaptive digital health interventions.

264 lines 11.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const mongo_data_manager_1 = require("./mongo/mongo-data-manager"); const events_1 = require("events"); const change_listener_manager_1 = require("./change-listener.manager"); const data_manager_type_1 = require("./data-manager.type"); const data_manager_constants_1 = require("./data-manager.constants"); const data_manager_helpers_1 = require("./data-manager.helpers"); const logger_manager_1 = require("../logger/logger-manager"); const data_manager_constants_2 = require("./data-manager.constants"); /** * Manages database operations and collection change listeners. */ class DataManager extends events_1.EventEmitter { constructor() { super(); this.db = mongo_data_manager_1.MongoDBManager; this.changeListenerManager = change_listener_manager_1.ChangeListenerManager.getInstance(); this.isInitialized = false; this.initializedAt = null; this.isInitialized = false; this.initializedAt = new Date(); } /** * Retrieves the singleton instance of DataManager. * @returns {DataManager} The singleton instance. */ static getInstance() { if (!DataManager.instance) { DataManager.instance = new DataManager(); } return DataManager.instance; } /** * Deletes the singleton instance of DataManager. */ static killInstance() { if (DataManager.instance) { DataManager.instance = null; } } /** * Initializes the DataManager with the specified database type. * Sets up listeners for collection changes. * @param {DBType} dbType - The type of database to initialize. Defaults to MongoDB. * @returns {Promise<void>} Resolves when initialization is complete. */ async init(dbType = data_manager_constants_1.DBType.MONGO) { logger_manager_1.Log.dev('Entering DM.init, isInitialized:', this.isInitialized); try { if (this.getInitializationStatus() && dbType === data_manager_constants_1.DBType.MONGO) return; if (dbType !== data_manager_constants_1.DBType.MONGO) { throw new Error('MongoDB is the only supported DB type'); } await this.db.init(); this.isInitialized = true; // TODO: figure out why we're doing this here this.changeListenerManager.addChangeListener('EVENTS_QUEUE', data_manager_type_1.CollectionChangeType.INSERT, this.handleEventsQueueInsert.bind(this)); logger_manager_1.Log.dev('DataManager initialized successfully'); } catch (error) { (0, data_manager_helpers_1.handleDbError)('Failed to initialize DataManager', error); } } /** * Handles `insert` changes in the EVENTS_QUEUE collection. * Emits an `eventAdded` signal to notify external systems. * @param {any} data - Data from the change stream. * @private */ async handleEventsQueueInsert(data) { this.emit('eventAdded', data); } /** * Checks if DataManager is initialized. * @returns {boolean} Initialization status. */ getInitializationStatus() { return this.isInitialized; } /** * Closes the DataManager and removes all listeners. * @returns {Promise<void>} Resolves when closed. */ async close() { logger_manager_1.Log.dev('Initiating DataManager.close'); try { this.checkInitialization(); this.changeListenerManager.clearChangeListeners(); await this.db.close(); this.isInitialized = false; logger_manager_1.Log.dev('DataManager closed and uninitialized'); } catch (error) { (0, data_manager_helpers_1.handleDbError)('Failed to close DataManager', error); } } checkInitialization() { logger_manager_1.Log.dev('Checking DataManager initialization status:', this.isInitialized); if (!this.isInitialized) { throw new Error('DataManager has not been initialized'); } } /** * Adds an item to a specified collection, ensuring the collection exists. * Emits a specific event (e.g., `userAdded`) if applicable to the collection. * @param {string} collectionName - The name of the collection to which the item will be added. * @param {object} item - The item to add to the collection. * @returns {Promise<object | null>} Resolves with the added item, or `null` if an error occurs. */ async addItemToCollection(collectionName, item) { try { this.checkInitialization(); const id = await this.db.addItemToCollection(collectionName, item); const newItem = { id, ...item }; if (collectionName === data_manager_constants_2.USERS) { this.emit('userAdded', newItem); } else if (collectionName === 'EVENTS_QUEUE') { this.emit('eventAdded', newItem); } return newItem; } catch (error) { return (0, data_manager_helpers_1.handleDbError)(`Failed to add item to collection: ${collectionName}`, error); } } /** * Updates an item in a collection by ID and emits an event. * @param {string} collectionName - The name of the collection. * @param {string} id - The ID of the item to update. * @param {object} updateObject - The update data. * @returns {Promise<object | null>} Resolves with the updated item or `null` on error. */ async updateItemByIdInCollection(collectionName, id, updateObject) { try { this.checkInitialization(); const updatedItem = await this.db.updateItemInCollection(collectionName, id, updateObject); if (collectionName === data_manager_constants_2.USERS) { this.emit('userUpdated', { id, ...updateObject }); } return updatedItem; } catch (error) { return (0, data_manager_helpers_1.handleDbError)(`Failed to update item in collection: ${collectionName}`, error); } } /** * Removes an item from a collection by ID and emits an event. * @param {string} collectionName - The name of the collection. * @param {string} id - The ID of the item to remove. * @returns {Promise<boolean>} Resolves with `true` if removed, `false` on error. */ async removeItemFromCollection(collectionName, id) { var _a; try { this.checkInitialization(); const result = await this.db.removeItemFromCollection(collectionName, id); if (result && collectionName === data_manager_constants_2.USERS) { this.emit('userDeleted', id); } return result; } catch (error) { return ((_a = (0, data_manager_helpers_1.handleDbError)(`Failed to remove item from collection: ${collectionName}`, error)) !== null && _a !== void 0 ? _a : false); } } /** * Retrieves all items from a collection. * @param {string} collectionName - The name of the collection. * @returns {Promise<T[] | null>} Resolves with items or `null` on error. */ async getAllInCollection(collectionName) { try { this.checkInitialization(); return this.db.getAllInCollection(collectionName); } catch (error) { return (0, data_manager_helpers_1.handleDbError)(`Failed to retrieve items from collection: ${collectionName}`, error); } } /** * Clears all items in a collection. * @param {string} collectionName - The name of the collection. * @returns {Promise<void>} Resolves when the collection is cleared. */ async clearCollection(collectionName) { try { this.checkInitialization(); await this.db.clearCollection(collectionName); } catch (error) { (0, data_manager_helpers_1.handleDbError)(`Failed to clear collection: ${collectionName}`, error); } } /** * Checks if a collection is empty. * @param {string} collectionName - The name of the collection. * @returns {Promise<boolean>} Resolves with `true` if empty, `false` on error. */ async isCollectionEmpty(collectionName) { var _a; try { this.checkInitialization(); return await this.db.isCollectionEmpty(collectionName); } catch (error) { return ((_a = (0, data_manager_helpers_1.handleDbError)(`Failed to check if collection is empty: ${collectionName}`, error)) !== null && _a !== void 0 ? _a : false); } } /** * Finds an item by ID in a specified collection. * @template T - The expected type of the item in the collection. * @param {string} collectionName - The name of the collection. * @param {string} id - The ID of the item to find. * @returns {Promise<T | null>} Resolves with the found item of type `T` or `null` if not found or on error. */ async findItemByIdInCollection(collectionName, id) { try { this.checkInitialization(); const item = await this.db.findItemByIdInCollection(collectionName, id); return item; } catch (error) { return (0, data_manager_helpers_1.handleDbError)(`Failed to find item by ID in collection: ${collectionName}`, error); } } /** * Finds items by criteria in a specified collection. * @template T - The expected type of the item in the collection. * @param {string} collectionName - The name of the collection. * @param {object} criteria - An object containing the key-value pair to search for. An empty object will return all items. * If `null`, it will return `null`. * @returns {Promise<T[] | null>} Resolves with the found item of type `T` or `null` if not found or on error. */ async findItemsInCollection(collectionName, criteria) { if (!criteria || !collectionName) { return null; // Return null if criteria is null } try { this.checkInitialization(); const itemList = await this.db.findItemsInCollection(collectionName, criteria); return itemList; } catch (error) { return (0, data_manager_helpers_1.handleDbError)(`Failed to find items by criteria: ${criteria} in collection: ${collectionName}`, error); } } /** * Provides a change stream for a specific collection and change type. * This method is used by the ChangeListenerManager to abstract away database-specific logic. * @param {string} collectionName - The name of the collection to monitor. * @param {CollectionChangeType} changeType - The type of change to monitor. * @returns {Readable} A readable stream of change events. */ getChangeStream(collectionName, changeType) { this.checkInitialization(); return this.db.getCollectionChangeReadable(collectionName, changeType); } } DataManager.instance = null; exports.default = DataManager; //# sourceMappingURL=data-manager.js.map