UNPKG

@krunal_tarale-5/ultimate-streaming-package

Version:

🚀 Ultimate Real-Time Streaming Package v2.1.9 - Multi-Platform, Multi-Collection Architecture with Native MongoDB & MySQL Support, 99.96% Performance Improvement. Enterprise-grade real-time data streaming with Socket.IO integration, dynamic schema evolut

290 lines (245 loc) • 8.04 kB
const MongoConnector = require('./lib/mongoConnector'); const MySQLConnector = require('./lib/mysqlConnector'); const HeartbeatSystem = require('./lib/heartbeatSystem'); class RealtimeStreamPackage { constructor() { this.dbConnector = null; this.heartbeatSystem = null; this.initialized = false; this.config = null; } /** * Initialize the streaming package with database configuration * @param {Object} config - Configuration object * @param {string} config.dbType - Database type: 'mongodb' or 'mysql' * @param {string} config.host - Database host * @param {number} [config.port] - Database port (optional) * @param {string} config.user - Database username * @param {string} config.password - Database password * @param {string} config.database - Database name * @param {number} [config.pollingInterval] - Polling interval in milliseconds (default: 2000) * @param {boolean} [config.debug] - Enable debug logging (default: false) * @returns {Promise<boolean>} - Success status */ async init(config) { if (this.initialized) { throw new Error('Package already initialized. Call destroy() first to reinitialize.'); } if (!config || typeof config !== 'object') { throw new Error('Configuration object is required'); } const { dbType, host, user, password, database } = config; // Validate required fields if (!dbType || !host || !database) { throw new Error('Required fields: dbType, host, database'); } // For non-local connections, user and password are required const isLocalConnection = host === 'localhost' || host === '127.0.0.1' || host.includes('localhost'); if (!isLocalConnection && (!user || !password)) { throw new Error('User and password are required for remote database connections'); } if (!['mongodb', 'mysql'].includes(dbType.toLowerCase())) { throw new Error('dbType must be either "mongodb" or "mysql"'); } try { // Store configuration this.config = { ...config }; // Initialize appropriate database connector if (dbType.toLowerCase() === 'mongodb') { this.dbConnector = new MongoConnector(); } else { this.dbConnector = new MySQLConnector(); } // Connect to database await this.dbConnector.connect(config); // Initialize heartbeat system this.heartbeatSystem = new HeartbeatSystem(this.dbConnector, { pollingInterval: config.pollingInterval || 2000, debug: config.debug || false }); this.initialized = true; console.log(`Realtime Stream Package initialized with ${dbType.toUpperCase()}`); return true; } catch (error) { console.error('Initialization failed:', error.message); this.cleanup(); throw error; } } /** * Listen for changes to a specific key * @param {string} key - The key to listen for changes * @param {Function} callback - Callback function to be called when data changes * @returns {Function} - Unsubscribe function */ on(key, callback) { this.ensureInitialized(); if (!key || typeof key !== 'string') { throw new Error('Key must be a non-empty string'); } if (!callback || typeof callback !== 'function') { throw new Error('Callback must be a function'); } return this.heartbeatSystem.addListener(key, callback); } /** * Push data to a specific key * @param {string} key - The key to update * @param {*} data - The data to store (will be JSON serialized) * @returns {Promise<Object>} - Operation result */ async push(key, data) { this.ensureInitialized(); if (!key || typeof key !== 'string') { throw new Error('Key must be a non-empty string'); } if (data === undefined) { throw new Error('Data cannot be undefined'); } try { return await this.dbConnector.writeData(key, data); } catch (error) { console.error(`Failed to push data for key "${key}":`, error.message); throw error; } } /** * Get current data for a key without listening for changes * @param {string} key - The key to retrieve data for * @returns {Promise<*>} - The current data or null if not found */ async get(key) { this.ensureInitialized(); if (!key || typeof key !== 'string') { throw new Error('Key must be a non-empty string'); } try { const result = await this.dbConnector.readData(key); return result ? result.data : null; } catch (error) { console.error(`Failed to get data for key "${key}":`, error.message); throw error; } } /** * Delete data for a specific key * @param {string} key - The key to delete * @returns {Promise<Object>} - Operation result */ async delete(key) { this.ensureInitialized(); if (!key || typeof key !== 'string') { throw new Error('Key must be a non-empty string'); } try { return await this.dbConnector.deleteData(key); } catch (error) { console.error(`Failed to delete data for key "${key}":`, error.message); throw error; } } /** * Remove a specific listener for a key * @param {string} key - The key to remove listener from * @param {Function} callback - The specific callback to remove */ off(key, callback) { this.ensureInitialized(); if (!key || typeof key !== 'string') { throw new Error('Key must be a non-empty string'); } this.heartbeatSystem.removeListener(key, callback); } /** * Remove all listeners for a key (or all keys if key is not provided) * @param {string} [key] - The key to remove listeners from (optional) */ removeAllListeners(key) { this.ensureInitialized(); this.heartbeatSystem.removeAllListeners(key); } /** * Set the polling interval * @param {number} interval - Polling interval in milliseconds (minimum 100ms) */ setPollingInterval(interval) { this.ensureInitialized(); this.heartbeatSystem.setPollingInterval(interval); } /** * Get current status and statistics * @returns {Object} - Status information */ getStatus() { if (!this.initialized) { return { initialized: false }; } return { initialized: this.initialized, dbType: this.config.dbType, dbConnected: this.dbConnector.isConnected(), heartbeat: this.heartbeatSystem.getStatus() }; } /** * Get all available keys in the database * @returns {Promise<Array>} - Array of key objects */ async getAllKeys() { this.ensureInitialized(); try { return await this.dbConnector.getAllKeys(); } catch (error) { console.error('Failed to get all keys:', error.message); throw error; } } /** * Destroy and cleanup the package instance */ async destroy() { if (!this.initialized) { return; } console.log('Destroying Realtime Stream Package...'); try { // Stop heartbeat system if (this.heartbeatSystem) { this.heartbeatSystem.destroy(); this.heartbeatSystem = null; } // Disconnect from database if (this.dbConnector) { await this.dbConnector.disconnect(); this.dbConnector = null; } this.cleanup(); console.log('Realtime Stream Package destroyed successfully'); } catch (error) { console.error('Error during cleanup:', error.message); this.cleanup(); } } /** * Internal cleanup method * @private */ cleanup() { this.initialized = false; this.config = null; this.dbConnector = null; this.heartbeatSystem = null; } /** * Ensure the package is initialized * @private */ ensureInitialized() { if (!this.initialized) { throw new Error('Package not initialized. Call init() first.'); } } } // Create and export a singleton instance const streamInstance = new RealtimeStreamPackage(); module.exports = streamInstance;