@resolveio/server-lib 20.7.6 → 20.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client-server-app.js +1 -1
- package/client-server-app.js.map +1 -1
- package/collections/app-status.collection.js +1 -1
- package/collections/app-status.collection.js.map +1 -1
- package/collections/counter.collection.js +1 -1
- package/collections/counter.collection.js.map +1 -1
- package/collections/cron-job-history.collection.js +1 -1
- package/collections/cron-job-history.collection.js.map +1 -1
- package/collections/cron-job.collection.js +1 -1
- package/collections/cron-job.collection.js.map +1 -1
- package/collections/email-history.collection.js +1 -1
- package/collections/email-history.collection.js.map +1 -1
- package/collections/email-verified.collection.js +1 -1
- package/collections/email-verified.collection.js.map +1 -1
- package/collections/file.collection.js +1 -1
- package/collections/file.collection.js.map +1 -1
- package/collections/flag-update.collection.js +1 -1
- package/collections/flag-update.collection.js.map +1 -1
- package/collections/flag.collection.js +1 -1
- package/collections/flag.collection.js.map +1 -1
- package/collections/log-method-latency.collection.js +1 -1
- package/collections/log-method-latency.collection.js.map +1 -1
- package/collections/log-subscription.collection.js +1 -1
- package/collections/log-subscription.collection.js.map +1 -1
- package/collections/log.collection.js +1 -1
- package/collections/log.collection.js.map +1 -1
- package/collections/logged-in-users.collection.js +1 -1
- package/collections/logged-in-users.collection.js.map +1 -1
- package/collections/method-response.collection.js +1 -1
- package/collections/method-response.collection.js.map +1 -1
- package/collections/monitor-cpu.collection.js +1 -1
- package/collections/monitor-cpu.collection.js.map +1 -1
- package/collections/monitor-function.collection.js +1 -1
- package/collections/monitor-function.collection.js.map +1 -1
- package/collections/monitor-memory.collection.js +1 -1
- package/collections/monitor-memory.collection.js.map +1 -1
- package/collections/monitor-mongo.collection.js +1 -1
- package/collections/monitor-mongo.collection.js.map +1 -1
- package/collections/notification.collection.js +1 -1
- package/collections/notification.collection.js.map +1 -1
- package/collections/report-builder-dashboard-builder.collection.js +1 -1
- package/collections/report-builder-dashboard-builder.collection.js.map +1 -1
- package/collections/report-builder-library.collection.js +1 -1
- package/collections/report-builder-library.collection.js.map +1 -1
- package/collections/report-builder-report.collection.js +1 -1
- package/collections/report-builder-report.collection.js.map +1 -1
- package/collections/user-group.collection.js +1 -1
- package/collections/user-group.collection.js.map +1 -1
- package/collections/user-guide.collection.js +1 -1
- package/collections/user-guide.collection.js.map +1 -1
- package/collections/user.collection.js +1 -1
- package/collections/user.collection.js.map +1 -1
- package/fixtures/cron-jobs.js +1 -1
- package/fixtures/cron-jobs.js.map +1 -1
- package/fixtures/init.js +1 -1
- package/fixtures/init.js.map +1 -1
- package/http/auth.d.ts +2 -1
- package/http/auth.js +1 -1
- package/http/auth.js.map +1 -1
- package/http/home.js +1 -1
- package/http/home.js.map +1 -1
- package/managers/cron.manager.d.ts +3 -1
- package/managers/cron.manager.js +1 -1
- package/managers/cron.manager.js.map +1 -1
- package/managers/local-log.manager.d.ts +3 -1
- package/managers/local-log.manager.js +1 -1
- package/managers/local-log.manager.js.map +1 -1
- package/managers/method.manager.d.ts +12 -7
- package/managers/method.manager.js +1 -1
- package/managers/method.manager.js.map +1 -1
- package/managers/mongo.manager.d.ts +17 -12
- package/managers/mongo.manager.js +1 -1
- package/managers/mongo.manager.js.map +1 -1
- package/managers/monitor.manager.d.ts +15 -7
- package/managers/monitor.manager.js +1 -1
- package/managers/monitor.manager.js.map +1 -1
- package/managers/subscription.manager.d.ts +5 -3
- package/managers/subscription.manager.js +1 -1
- package/managers/subscription.manager.js.map +1 -1
- package/managers/websocket.manager.d.ts +3 -1
- package/managers/websocket.manager.js +1 -1
- package/managers/websocket.manager.js.map +1 -1
- package/methods/accounts.js +1 -1
- package/methods/accounts.js.map +1 -1
- package/methods/aws.js +1 -1
- package/methods/aws.js.map +1 -1
- package/methods/collections.js +1 -1
- package/methods/collections.js.map +1 -1
- package/methods/counters.js +1 -1
- package/methods/counters.js.map +1 -1
- package/methods/cron-jobs.js +1 -1
- package/methods/cron-jobs.js.map +1 -1
- package/methods/logs.js +1 -1
- package/methods/logs.js.map +1 -1
- package/methods/monitor.js +1 -1
- package/methods/monitor.js.map +1 -1
- package/methods/pdf.js +1 -1
- package/methods/pdf.js.map +1 -1
- package/methods/report-builder.js +1 -1
- package/methods/report-builder.js.map +1 -1
- package/methods/support.js +1 -1
- package/methods/support.js.map +1 -1
- package/models/method.model.d.ts +6 -1
- package/package.json +5 -4
- package/publications/logs.js +1 -1
- package/publications/logs.js.map +1 -1
- package/resolveio-server-app.d.ts +14 -10
- package/resolveio-server-app.js +1 -1
- package/resolveio-server-app.js.map +1 -1
- package/server-app.d.ts +5 -4
- package/server-app.js +1 -1
- package/server-app.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/managers/subscription.manager.ts"],"names":["logs_1","require","app_status_1","files_1","super_admin_1","logged_in_users_collection_1","cron_jobs_1","flags_1","method_responses_1","resolveio_server_app_1","notifications_1","report_builder_reports_1","report_builder_libraries_1","user_groups_1","user_guides_1","report_builder_dashboard_builders_1","common_1","NodeCache","flag_collection_1","os_1","flags_update_1","numCPUs","cpus","length","v8","SubscriptionManager","wss","serverConfig","monitorManagerFunction","_this","this","_publications","_subscriptions","_loggedInUsers","_mongoQueue","_mongoQueueId","_cacheId","_heapSize","getHeapStatistics","_enableDebug","_debugOplogCollections","_debugOplogHits","_debugSubCollections","_debugSubHits","_debugUnSubHits","_debugUnSubAllHits","_debugMongoQueueHits","_debugMongoQueueCollections","_debugSendQueueHits","_debugRemoveCacheHits","_oplogRetryCount","latencyBuffer","Map","LATENCY_UPDATE_INTERVAL","LATENCY_UPDATE_THRESHOLD_MS","_invalidationDebounceTimers","_invalidationPendingTimestamps","DEBOUNCE_DELAY","MAX_WAIT_TIME","_websocketManager","ResolveIOServer","getMainServer","getWebSocketManager","_monitorManagerFunction","_nodeCache","stdTTL","checkperiod","setInterval","flushThrottledLatencyUpdates","_wss","loadSuperAdminPublications","loadAppStatusPublications","loadLogPublications","loadFilePublications","loadCronJobPublications","loadFlagsUpdatePublications","loadFlagsPublications","loadMethodResponsePublications","loadNotificationPublications","loadReportBuilderReportPublications","loadReportBuilderLibraryPublications","loadUserGroupPublications","loadUserGuidePublications","loadReportBuilderDashboardBuilderPublications","tailOpLog","getEnableDebug","console","log","Date","JSON","stringify","sort","a","b","collection","localeCompare","publication","type","__awaiter","_a","LoggedInUsers","find","_b","sent","userCopy","deepCopy","i","loggedInUser","date","now","getTime","this_1","getWebSocket","id_ws","unsubscribeAll","forEach","sub","j","clients","id_socket","splice","deleteOne","_id","findIndex","client","this_2","some","Flags","findOne","then","flag","value","setCacheLimit","prototype","process","env","IS_WORKERS_ENABLED","_heapLimit","invalidatePubsCache","debounceKey","firstInvalidationTime","get","set","has","clearTimeout","delete","_executeInvalidation","setTimeout","getMongoManager","invalidateQueryCache","collSubs","filter","collections","includes","this_3","running","runAgain","user_specific","map","ws","readyState","OPEN","sendDataToOneWithRetry","messageId","err","sendDataToAllWithRetry","collSubs_1","__values","collSubs_1_1","next","done","delay","ms","Promise","resolve","sendDataToAll","sendDataToOne","publications","method","Object","assign","loggedInLatency","existingEntry","newLatency","lastUpdate","Math","abs","latency","size","updates","Array","from","entries","__read","_c","updateOne","update","$set","bulkWrite","clear","error","error_1","subscribe","messageRoute","messageDate","subscriptionData","pub","hits","push","check","_schema","valObj","rootKeys","keys","validate","errors","urlData","split","urlModule_1","urlNext","otherRouteSubs","startsWith","otherSub","unsubscribe","id_user","getPublicationCollections","cacheId","processSubscription","createLoggedInUser","reject","user","objectIdHexString","__v","insertOne","indexOf","userSubs","removeWebSocket","getActiveSubscriptions","resumeToken","_oplog$","closed","removeAllListeners","close","exit","pipeline","$match","$and","ns.coll","$nin","$not","lastResumeToken_1","getMainDB","watch","resumeAfter","errOp","on","doc","ns","coll","operationType","getMethodManager","callMethod","call","documentKey","NODE_APP_INSTANCE","IS_WORKER_INSTANCE","WORKER_INDEX","cacheData","parse","dateReviver","serverRes","hasError","data","sendWS","del","monitor","startMonitorFunction","function","apply","__spreadArray","res","finishMonitorFunction","err_1","sendEmail","subIndex","res_1","all","getBinarySize","endsWith","nodeCacheSize","getStats","vsize","deleteCount","subArr","zz","err_2","send","exports"],"mappings":"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","file":"subscription.manager.js","sourcesContent":["import { ServerResponseModel } from '../models/server-response.model';\nimport { ActiveSubscriptionModel, SubscriptionModel } from '../models/subscription.model';\nimport * as WebSocket from 'ws';\nimport { loadLogPublications } from '../publications/logs';\nimport { loadAppStatusPublications } from '../publications/app-status';\nimport { loadFilePublications } from '../publications/files';\nimport { loadSuperAdminPublications } from '../publications/super-admin';\nimport { LoggedInUsers } from '../collections/logged-in-users.collection';\nimport { loadCronJobPublications } from '../publications/cron-jobs';\nimport { loadFlagsPublications } from '../publications/flags';\nimport { loadMethodResponsePublications } from '../publications/method-responses';\nimport { ResolveIOServer } from '../resolveio-server-app';\nimport { loadNotificationPublications } from '../publications/notifications';\nimport { loadReportBuilderReportPublications } from '../publications/report-builder-reports';\nimport { LoggedInUserModel } from '../models/logged-in-users.model';\n\nimport { ChangeStream, ChangeStreamDeleteDocument, ChangeStreamInsertDocument, ChangeStreamReplaceDocument, ChangeStreamUpdateDocument, ResumeToken } from 'mongodb';\nimport { loadReportBuilderLibraryPublications } from '../publications/report-builder-libraries';\nimport { loadUserGroupPublications } from '../publications/user-groups';\nimport { loadUserGuidePublications } from '../publications/user-guides';\nimport { loadReportBuilderDashboardBuilderPublications } from '../publications/report-builder-dashboard-builders';\nimport { dateReviver, deepCopy, getBinarySize, objectIdHexString } from '../util/common';\nimport * as NodeCache from 'node-cache';\nimport { MonitorManagerFunction } from './monitor.manager';\nimport { Flags } from '../collections/flag.collection';\nimport { cpus } from 'os';\nimport { WebSocketManager } from './websocket.manager';\nimport { loadFlagsUpdatePublications } from '../publications/flags-update';\nconst numCPUs = cpus().length;\nconst v8 = require('v8');\n\n// Performance Dependencies\n// import * as path from 'path';\n// import { Worker } from 'worker_threads';\n\ninterface MongoQueueModel {\n\t_id: number,\n\ttype: string;\n\tcollection: string;\n\tsubscription: ActiveSubscriptionModel;\n\trunning: boolean;\n\trun_again: boolean;\n}\n\n// interface CurrentPerformanceMonitor {\n// \t_id: number;\n// \tfunction: string;\n// \tpublication: string;\n// \tsubscriptionData: any[];\n// \tdate_start: Date;\n// \tdate_end: Date;\n// \tduration: number;\n// \tresult: string;\n// }\n\nexport class SubscriptionManager {\n\tprivate _websocketManager: WebSocketManager;\n\tprivate _publications: SubscriptionModel = {};\n\tprivate _subscriptions: ActiveSubscriptionModel[] = [];\n\tprivate _wss: WebSocket.Server;\n\tprivate _loggedInUsers: LoggedInUserModel[] = [];\n\n\tprivate _mongoQueue: MongoQueueModel[] = [];\n\tprivate _mongoQueueId = 0;\n\t\n\tprivate _oplog$: ChangeStream;\n\n\tprivate _nodeCache;\n\tprivate _cacheId = 1;\n\n\tprivate _heapSize = v8.getHeapStatistics() / numCPUs;\n\tprivate _heapLimit: number;\n\n\tprivate serverConfig;\n\n\tprivate _monitorManagerFunction: MonitorManagerFunction;\n\n\tprivate _enableDebug = false;\n\tprivate _debugOplogCollections = [];\n\tprivate _debugOplogHits = 0;\n\tprivate _debugSubCollections = [];\n\tprivate _debugSubHits = 0;\n\tprivate _debugUnSubHits = 0;\n\tprivate _debugUnSubAllHits = 0;\n\tprivate _debugMongoQueueHits = 0;\n\tprivate _debugMongoQueueCollections = [];\n\tprivate _debugSendQueueHits = 0;\n\tprivate _debugRemoveCacheHits = 0;\n\n\tprivate _oplogRetryCount = 0;\n\n\t// Buffer to store throttled latency updates with timestamps\n\tprivate latencyBuffer = new Map<string, { latency: number, lastUpdate: Date }>();\n\n\t// Interval to flush latency updates in MongoDB\n\tprivate readonly LATENCY_UPDATE_INTERVAL = 60000;\n\n\t// Minimum time difference between two latency updates for the same user\n\tprivate readonly LATENCY_UPDATE_THRESHOLD_MS = 30000;\n\n\t// private currentPerfomanceMonitor: CurrentPerformanceMonitor[] = [];\n\t// private idPerformance: number = 0;\n\t// private performanceThread;\n\n\tprivate _invalidationDebounceTimers = new Map<string, NodeJS.Timeout>();\n\tprivate _invalidationPendingTimestamps = new Map<string, number>();\n\tprivate readonly DEBOUNCE_DELAY = 100; // 100ms debounce window\n\tprivate readonly MAX_WAIT_TIME = 500; // 500ms maximum delay\n\n\n\tconstructor(wss: WebSocket.Server, serverConfig, monitorManagerFunction: MonitorManagerFunction) {\n\t\tthis._websocketManager = ResolveIOServer.getMainServer().getWebSocketManager();\n\t\tthis._monitorManagerFunction = monitorManagerFunction;\n\n\t\tthis._nodeCache = new NodeCache( { stdTTL: 0, checkperiod: 0 } );\n\n\t\tsetInterval(() => this.flushThrottledLatencyUpdates(), this.LATENCY_UPDATE_INTERVAL);\n\n\t\t// setTimeout(() => {\n\t\t// \tconsole.log('Setting up performance thread');\n\n\t\t// \tthis.performanceThread = new Worker(path.join(__dirname, './subscription.performance.js'));\n\n\t\t// \tthis.performanceThread.on('exit', code => {\n\t\t// \t\tconsole.error(new Date(), 'THREAD EXITED!!!!!!!!!!!!!!!!!!', code);\n\t\t// \t});\n\n\t\t// \tthis.performanceThread.on('error', code => {\n\t\t// \t\tconsole.error(new Date(), 'THREAD RECV ERROR !!!!!!!!!!!!!!!!!!', code);\n\t\t// \t});\n\t\t// }, 5000);\n\n\t\t// setInterval(() => {\n\t\t// \tconsole.log('Post thread msg');\n\t\t// \tthis.performanceThread.postMessage(this.currentPerfomanceMonitor);\n\t\t// \tthis.currentPerfomanceMonitor = [];\n\t\t// }, 10000);\n\n\t\tthis.serverConfig = serverConfig;\n\t\tthis._wss = wss;\n\n\t\t// Publications\n\t\tloadSuperAdminPublications(this);\n\t\tloadAppStatusPublications(this);\n\t\tloadLogPublications(this);\n\t\tloadFilePublications(this);\n\t\tloadCronJobPublications(this);\n\t\tloadFlagsUpdatePublications(this);\n\t\tloadFlagsPublications(this);\n\t\tloadMethodResponsePublications(this);\n\t\tloadNotificationPublications(this);\n\t\tloadReportBuilderReportPublications(this);\n\t\tloadReportBuilderLibraryPublications(this);\n\t\tloadUserGroupPublications(this);\n\t\tloadUserGuidePublications(this);\n\t\tloadReportBuilderDashboardBuilderPublications(this);\n\n\t\tthis.tailOpLog();\n\n\t\tsetInterval(() => {\n\t\t\tthis._oplogRetryCount = 0;\n\t\t}, 15000);\n\n\t\tsetInterval(() => {\n\t\t\tif (this.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Subs', this._subscriptions.length);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Logged In Users', this._loggedInUsers.length);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Mongo Queue', this._mongoQueue.length);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Mongo Queue Hits', this._debugMongoQueueHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Mongo Queue Collections', JSON.stringify(this._debugMongoQueueCollections.sort((a, b) => a.collection.localeCompare(b.collection) || a.publication.localeCompare(b.publication)), null, 2));\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Oplog Hits', this._debugOplogHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Oplog Collections', JSON.stringify(this._debugOplogCollections.sort((a, b) => a.collection.localeCompare(b.collection) || a.type.localeCompare(b.type)), null, 2));\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Send Queue Hits', this._debugSendQueueHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Sub Hits', this._debugSubHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Sub Collections', JSON.stringify(this._debugSubCollections.sort((a, b) => a.publication.localeCompare(b.publication)), null, 2));\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Unsub Hits', this._debugUnSubHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Unsub All Hits', this._debugUnSubAllHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Cache Cleanup Hits', this._debugRemoveCacheHits);\n\t\t\t}\n\t\t\t\n\t\t\tthis._debugOplogHits = 0;\n\t\t\tthis._debugOplogCollections = [];\n\t\t\tthis._debugSubCollections = [];\n\t\t\tthis._debugMongoQueueHits = 0;\n\t\t\tthis._debugMongoQueueCollections = [];\n\t\t\tthis._debugSendQueueHits = 0;\n\t\t\tthis._debugSubHits = 0;\n\t\t\tthis._debugUnSubHits = 0;\n\t\t\tthis._debugUnSubAllHits = 0;\n\t\t\tthis._debugRemoveCacheHits = 0;\n\t\t}, 60000);\n\n\t\tsetInterval(async () => {\n\t\t\tthis._loggedInUsers = await LoggedInUsers.find();\n\t\n\t\t\tlet userCopy = deepCopy(this._loggedInUsers);\n\t\t\tfor (let i = this._loggedInUsers.length - 1; i >= 0; i--) {\n\t\t\t\tlet loggedInUser = userCopy[i];\n\n\t\t\t\tif (!loggedInUser.date || Date.now() - loggedInUser.date.getTime() > 120000) {\n\t\t\t\t\tif (this._websocketManager.getWebSocket(loggedInUser.id_ws)) {\n\t\t\t\t\t\tif (this.getEnableDebug()) {\n\t\t\t\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Unsub WS', this._websocketManager.getWebSocket(loggedInUser.id_ws)['user'], this._websocketManager.getWebSocket(loggedInUser.id_ws)['id_socket'], 2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.unsubscribeAll(this._websocketManager.getWebSocket(loggedInUser.id_ws));\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis._subscriptions.forEach(sub => {\n\t\t\t\t\t\t\tfor (let j = sub.clients.length - 1; j >= 0; j--) {\n\t\t\t\t\t\t\t\tlet client = sub.clients[j];\n\n\t\t\t\t\t\t\t\tif (client.id_socket === loggedInUser.id_ws) {\n\t\t\t\t\t\t\t\t\tsub.clients.splice(j, 1);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tLoggedInUsers.deleteOne({_id: loggedInUser._id});\n\n\t\t\t\t\t\tif (this._loggedInUsers.findIndex(a => a._id === loggedInUser._id) >= 0) {\n\t\t\t\t\t\t\tthis._loggedInUsers.splice(this._loggedInUsers.findIndex(a => a._id === loggedInUser._id), 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < this._subscriptions.length; i++) {\n\t\t\t\tlet sub = this._subscriptions[i];\n\n\t\t\t\tfor (let j = sub.clients.length - 1; j >= 0; j--) {\n\t\t\t\t\tlet client = sub.clients[j];\n\n\t\t\t\t\tif (!this._loggedInUsers.some(a => a.id_ws === client.id_socket)) {\n\t\t\t\t\t\tsub.clients.splice(j, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}, 30000);\n\n\t\tFlags.findOne({type: 'Enable Debug'}).then(flag => {\n\t\t\tif (flag && flag.value) {\n\t\t\t\tthis._enableDebug = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis._enableDebug = false;\n\t\t\t}\n\t\t});\n\n\t\tthis.setCacheLimit();\n\t}\n\n\tprivate setCacheLimit() {\t\n\t\tif (process.env.IS_WORKERS_ENABLED === 'true') {\n\t\t\tthis._heapLimit = this._heapSize * 0.4;\n\t\t}\n\t\telse {\n\t\t\tthis._heapLimit = this._heapSize * 0.3; // Use 50% of total heap size\n\t\t}\n\t}\n\n\tpublic async invalidatePubsCache(collection: string, type: string) {\n\t\tconst debounceKey = collection;\n\t\tconst now = Date.now();\n\t\n\t\t// Initialize or get existing timestamp\n\t\tconst firstInvalidationTime = this._invalidationPendingTimestamps.get(debounceKey) || now;\n\t\tthis._invalidationPendingTimestamps.set(debounceKey, firstInvalidationTime);\n\t\n\t\t// Clear any existing timer\n\t\tif (this._invalidationDebounceTimers.has(debounceKey)) {\n\t\t\tclearTimeout(this._invalidationDebounceTimers.get(debounceKey));\n\t\t}\n\t\n\t\t// Check if we've waited too long\n\t\tconst waitedTooLong = (now - firstInvalidationTime) >= this.MAX_WAIT_TIME;\n\t\t\n\t\tif (waitedTooLong) {\n\t\t\t// Immediate execution path\n\t\t\tthis._invalidationPendingTimestamps.delete(debounceKey);\n\t\t\tawait this._executeInvalidation(collection, type);\n\t\t} else {\n\t\t\t// Normal debounce path\n\t\t\tthis._invalidationDebounceTimers.set(\n\t\t\t\tdebounceKey,\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis._invalidationPendingTimestamps.delete(debounceKey);\n\t\t\t\t\tthis._executeInvalidation(collection, type);\n\t\t\t\t}, this.DEBOUNCE_DELAY)\n\t\t\t);\n\t\t}\n\t}\n\t\n\tprivate async _executeInvalidation(collection: string, type: string) {\n\t\t// Clean up any existing timer (defensive)\n\t\tif (this._invalidationDebounceTimers.has(collection)) {\n\t\t\tclearTimeout(this._invalidationDebounceTimers.get(collection));\n\t\t\tthis._invalidationDebounceTimers.delete(collection);\n\t\t}\n\t\n\t\t// Original invalidation logic\n\t\tResolveIOServer.getMongoManager().invalidateQueryCache(collection);\n\t\n\t\tconst collSubs = this._subscriptions.filter(a => a.collections.includes(collection));\n\t\n\t\tfor (const sub of collSubs) {\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Invalidate Sub', sub.publication, sub.running, sub.runAgain);\n\t\t\t}\n\t\n\t\t\tif (sub.running) {\n\t\t\t\tsub.runAgain = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\n\t\t\tif (this._publications[sub.publication].user_specific) {\n\t\t\t\tsub.clients.map(async client => {\n\t\t\t\t\tconst ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\tif (ws?.readyState === ws.OPEN) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tthis.sendDataToOneWithRetry(ws, client.messageId, sub, collection, type);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t\t// Error handling\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.sendDataToAllWithRetry(sub, collection, type);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async delay(ms: number) {\n\t\treturn new Promise(resolve => setTimeout(resolve, ms));\n\t}\n\n\tprivate async sendDataToAllWithRetry(sub: ActiveSubscriptionModel, collection: string, type: string) {\n\t\tsub.running = true;\n\n\t\tdo {\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Running sendDataToAll Sub', sub.publication);\n\t\t\t}\n\n\t\t\tsub.runAgain = false;\n\t\t\tawait this.sendDataToAll(sub, collection, type);\n\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Done sendDataToAll Sub', sub.publication, sub.runAgain);\n\t\t\t}\n\n\t\t\tif (sub.runAgain) {\n\t\t\t\tawait this.delay(500); // delay, adjust as needed\n\t\t\t}\n\t\t} while (sub.runAgain);\n\n\t\tsub.running = false;\n\t}\n\n\tprivate async sendDataToOneWithRetry(ws: WebSocket, messageId: number, sub: ActiveSubscriptionModel, collection: string, type: string) {\n\t\tsub.running = true;\n\n\t\tdo {\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Running sendDataToOne Sub', sub.publication);\n\t\t\t}\n\n\t\t\tsub.runAgain = false;\n\t\t\tawait this.sendDataToOne(ws, messageId, sub, collection, type);\n\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Done sendDataToOne Sub', sub.publication, sub.runAgain);\n\t\t\t}\n\n\t\t\tif (sub.runAgain) {\n\t\t\t\tawait this.delay(500); // delay, adjust as needed\n\t\t\t}\n\t\t} while (sub.runAgain);\n\t\tsub.running = false;\n\t}\n\n\t// Add all files to publications private object\n\tpublic publications(method: SubscriptionModel) {\n\t\tthis._publications = Object.assign(this._publications, method);\n\t}\n\n\t// Throttled `loggedInLatency` method\n\tpublic loggedInLatency(ws: WebSocket) {\n\t\tlet loggedInUser = this._loggedInUsers.find(a => a.id_ws === ws['id_socket']);\n\t\tif (!loggedInUser) return;\n\n\t\tconst now = new Date();\n\t\tconst existingEntry = this.latencyBuffer.get(ws['id_socket']);\n\t\tconst newLatency = ws['latency'];\n\n\t\t// Throttle updates: only update if time threshold has passed or latency has significantly changed\n\t\tif (\n\t\t\t!existingEntry || \n\t\t\t(now.getTime() - existingEntry.lastUpdate.getTime() >= this.LATENCY_UPDATE_THRESHOLD_MS) || \n\t\t\t(Math.abs(newLatency - existingEntry.latency) > 100) // Optional: log only significant changes\n\t\t) {\n\t\t\t// Update in-memory and buffer\n\t\t\tloggedInUser.date = now;\n\t\t\tthis.latencyBuffer.set(ws['id_socket'], { latency: newLatency, lastUpdate: now });\n\t\t}\n\t}\n\n\t// Method to flush buffered latency updates in bulk\n\tprivate async flushThrottledLatencyUpdates() {\n\t\tif (this.latencyBuffer.size === 0) return; // No updates to flush\n\n\t\tconst updates = Array.from(this.latencyBuffer.entries()).map(([id_ws, { latency, lastUpdate }]) => ({\n\t\t\tupdateOne: {\n\t\t\t\tfilter: { id_ws },\n\t\t\t\tupdate: { $set: { latency, date: lastUpdate } }\n\t\t\t}\n\t\t}));\n\n\t\ttry {\n\t\t\tawait LoggedInUsers.bulkWrite(updates);\n\t\t\tthis.latencyBuffer.clear(); // Clear buffer after successful update\n\n\t\t\tif (this.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Throttled latency batch update successful', updates.length);\n\t\t\t}\n\t\t}\n\t\tcatch (error) {\n\t\t\tconsole.error(new Date(), 'Sub Manager', 'Throttled latency batch update failed', error);\n\t\t\t// Optional: implement retry logic or logging for failed updates\n\t\t}\n\t}\n\n\t// Subscribe to publication\n\tpublic subscribe(messageRoute: string, messageDate: Date, ws: WebSocket, messageId: number, publication: string, subscriptionData: any[]) {\n\t\tthis._debugSubHits += 1;\n\n\t\tif (!this._debugSubCollections.some(a => a.publication === publication)) {\n\t\t\tthis._debugSubCollections.push({\n\t\t\t\tpublication: publication,\n\t\t\t\thits: 1\n\t\t\t});\n\t\t}\n\t\telse {\n\t\t\tthis._debugSubCollections.find(a => a.publication === publication).hits += 1;\n\t\t}\n\n\t\tlet pub = this._publications[publication];\n\n\t\tif (!pub) {\n\t\t\tconsole.error(new Date(), 'No Publication: ' + publication);\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\tif (subscriptionData.length > 1 || subscriptionData[0]) {\n\t\t\t\tif (!pub.check) {\n\t\t\t\t\tconsole.error(new Date(), 'No Check Function For Pub ' + publication);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (!pub.check._schema) {\n\t\t\t\t\tconsole.error(new Date(), 'No Check Schema For Pub ' + publication);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlet valObj = {};\n\t\t\t\t\tlet valKeys = Object.keys(pub.check._schema);\n\n\t\t\t\t\tlet rootKeys = valKeys.filter(a => !a.includes('.'));\n\n\t\t\t\t\tfor (let i = 0; i < subscriptionData.length; i++) {\n\t\t\t\t\t\tvalObj[rootKeys[i]] = subscriptionData[i];\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpub.check.validate(valObj);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (errors) {\n\t\t\t\t\t\tif (errors) {\n\t\t\t\t\t\t\tconsole.error(new Date(), 'Error in Pub Check (' + publication + ')', errors);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (messageRoute !== 'Bypass') {\n\t\t\t\tlet urlData = messageRoute.split('/');\n\t\t\t\tlet urlModule = '';\n\t\t\t\tlet urlNext = urlData[0];\n\n\t\t\t\tif (urlData[0] === '') {\n\t\t\t\t\turlModule = '/';\n\t\t\t\t\turlNext = urlData[1];\n\t\t\t\t}\n\n\t\t\t\turlModule += urlNext;\n\n\t\t\t\tif (urlData.length > 1) {\n\t\t\t\t\turlModule += '/';\n\t\t\t\t}\n\n\t\t\t\tlet otherRouteSubs = this._subscriptions.filter(a => a.clients.some(b => b.id_socket === ws['id_socket'] && b.messageRoute !== 'Bypass' && b.messageRoute !== '/' && b.messageRoute !== messageRoute && !b.messageRoute.startsWith(urlModule)));\n\n\t\t\t\tif (otherRouteSubs.length) {\n\t\t\t\t\t// ResolveIOServer.getMainServer().getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Detected Undestroyed Subscription - ' + this.serverConfig['CLIENT_NAME'], 'USER: ' + ws['user'] + ' (Socket: ' + ws['id_socket'] + ') ' + ' is on route: ' + messageRoute + ' but has the following subscriptions on other routes:' + JSON.stringify(otherRouteSubs, null, 2));\n\n\t\t\t\t\totherRouteSubs.forEach(otherSub => {\n\t\t\t\t\t\totherSub.clients.filter(a => a.id_socket === ws['id_socket']).forEach(client => {\n\t\t\t\t\t\t\tthis.unsubscribe(client.messageRoute, new Date(), ws, client.messageId, otherSub.publication, otherSub.subscriptionData);\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet sub = this._subscriptions.find(a => a.publication === publication && JSON.stringify(a.subscriptionData) === JSON.stringify(subscriptionData));\n\n\t\t\t// If sub found (another user watching same data), add client to same sub\n\t\t\tif (sub) {\n\t\t\t\tif (!sub.clients.some(a => a.id_socket === ws['id_socket'] && a.messageId === messageId)) {\n\t\t\t\t\tsub.clients.push({\n\t\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\tid_socket: ws['id_socket'],\n\t\t\t\t\t\tmessageRoute: messageRoute\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If sub not found, create new sub\n\t\t\telse {\n\t\t\t\tthis._subscriptions.push({\n\t\t\t\t\tpublication: publication,\n\t\t\t\t\tsubscriptionData: subscriptionData,\n\t\t\t\t\tcollections: this.getPublicationCollections(publication),\n\t\t\t\t\tclients: [{\n\t\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\tid_socket: ws['id_socket'],\n\t\t\t\t\t\tmessageRoute: messageRoute,\n\t\t\t\t\t}],\n\t\t\t\t\tcacheId: 0,\n\t\t\t\t\trunning: false,\n\t\t\t\t\trunAgain: false\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!sub) {\n\t\t\t\tsub = this._subscriptions.find(a => a.publication === publication && JSON.stringify(a.subscriptionData) === JSON.stringify(subscriptionData));\n\t\t\t}\n\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'New Sub', sub.publication, sub.running, sub.runAgain, sub.clients.length);\n\t\t\t}\n\n\t\t\t// Immediately send data to the new client\n\t\t\tthis.processSubscription(sub, ws, messageId);\n\t\t}\n\t}\n\n\tpublic async createLoggedInUser(id_ws: string): Promise<LoggedInUserModel> {\n\t\treturn new Promise(async (resolve, reject) => {\n\t\t\tlet ws = this._websocketManager.getWebSocket(id_ws);\n\n\t\t\tif (ws) {\n\t\t\t\tlet user = {\n\t\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t\t__v: 0,\n\t\t\t\t\tdate: new Date(),\n\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\tuser: ws['user'],\n\t\t\t\t\tid_ws: ws['id_socket']\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tthis._loggedInUsers.push(user);\n\t\t\t\tLoggedInUsers.insertOne(user);\n\t\t\t\t\n\t\t\t\tresolve(user);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tresolve(null);\n\t\t\t}\n\t\t});\n\t}\n\n\t// Unsubscribe from publication \n\tpublic unsubscribe(messageRoute: string, messageDate: Date, ws: WebSocket, messageId: number, publication: string, subscriptionData: any[]) {\t\t\n\t\tthis._debugUnSubHits += 1;\n\n\t\tif (!this._publications[publication]) {\n\t\t\tconsole.log('No Publication: ' + publication);\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\tlet sub = this._subscriptions.find(a => a.publication === publication && JSON.stringify(a.subscriptionData) === JSON.stringify(subscriptionData));\n\n\t\t\tif (sub) {\n\t\t\t\tfor (let i = sub.clients.length - 1; i >= 0; i--) {\n\t\t\t\t\tif (sub.clients[i].id_user === ws['id_user'] && sub.clients[i].messageId === messageId && sub.clients[i].id_socket === ws['id_socket']) {\n\t\t\t\t\t\tsub.clients.splice(i, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\tconsole.log(new Date(), 'Unsub', sub.publication, sub.running, sub.runAgain, sub.clients.length);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\t// Unsubscribe from publication\n\tpublic async unsubscribeAll(ws: WebSocket) {\n\t\tthis._debugUnSubAllHits += 1;\n\n\t\tif (ws) {\n\t\t\t// Check if WebSocket has already been unsubscribed\n\t\t\tif (ws['isUnsubscribed']) {\n\t\t\t\treturn; // Skip if already unsubscribed\n\t\t\t}\n\t\t\t\n\t\t\t// Mark the WebSocket as unsubscribed to prevent further calls\n\t\t\tws['isUnsubscribed'] = true;\n\t\t\t\n\t\t\tif (this._loggedInUsers.map(a => a.id_ws).indexOf(ws['id_socket']) >= 0) {\n\t\t\t\tthis._loggedInUsers.splice(this._loggedInUsers.map(a => a.id_ws).indexOf(ws['id_socket']), 1);\n\t\t\t}\n\t\t\tLoggedInUsers.deleteOne({ id_ws: ws['id_socket'] });\n\n\t\t\tlet userSubs = this._subscriptions.filter(a => a.clients.some(b => b.id_user === ws['id_user'] && b.id_socket === ws['id_socket']));\n\n\t\t\tfor (let i = userSubs.length - 1; i >= 0; i--) {\n\t\t\t\tlet sub = userSubs[i];\n\n\t\t\t\tfor (let j = sub.clients.length - 1; j >= 0; j--) {\n\t\t\t\t\tif (sub.clients[j].id_socket === ws['id_socket']) {\n\t\t\t\t\t\tsub.clients.splice(j, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._websocketManager.removeWebSocket(ws);\n\t\t}\n\t}\n\n\tpublic getActiveSubscriptions() {\n\t\treturn this._subscriptions;\n\t}\n\n\t// Get publication collection\n\tprivate getPublicationCollections(publication: string) {\n\t\treturn this._publications[publication].collections;\n\t}\n\n\t// Watch (tail) Mongo's operation log on the entire database (all insert/modify/delete will trigger this function)\n\tprivate async tailOpLog(resumeToken?: ResumeToken) {\n\t\tif (this._oplog$ && !this._oplog$.closed) {\n\t\t\tthis._oplog$.removeAllListeners();\n\t\t\tthis._oplog$.close();\n\t\t\tthis._oplog$ = null;\n\t\t}\n\n\t\tawait new Promise(resolve => setTimeout(resolve, 1000));\n\n\t\tif (!this._oplog$ || this._oplog$.closed) {\n\t\t\tthis._oplogRetryCount += 1;\n\n\t\t\tif (this._oplogRetryCount > 5) {\n\t\t\t\tconsole.error('****************** TAIL OPLOG ERROR, RETRYING A BUNCH OF TIMES, KILLING PROCESS **************************');\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst pipeline = [\n\t\t\t\t{\n\t\t\t\t\t$match: {\n\t\t\t\t\t\t$and: [\n\t\t\t\t\t\t\t{'ns.coll': { $nin: [\n\t\t\t\t\t\t\t\t'log-method-latencies', \n\t\t\t\t\t\t\t\t'log-subscriptions', \n\t\t\t\t\t\t\t\t'logs', \n\t\t\t\t\t\t\t\t'counters', \n\t\t\t\t\t\t\t\t'cron-job-histories', \n\t\t\t\t\t\t\t\t'email-histories',\n\t\t\t\t\t\t\t\t'qb-soap-request-histories', \n\t\t\t\t\t\t\t\t'qb-soap-request-responses', \n\t\t\t\t\t\t\t\t'qb-soap-requests',\n\t\t\t\t\t\t\t\t'qb-soap-retries'\n\t\t\t\t\t\t\t] }},\n\t\t\t\t\t\t\t{'ns.coll': { $not: /.*\\.versions$/ }},\n\t\t\t\t\t\t\t{'ns.coll': { $not: /^monitor-/ }},\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\n\t\t\tlet lastResumeToken: ResumeToken;\n\n\t\t\tif (resumeToken) {\n\t\t\t\tlastResumeToken = resumeToken;\n\t\t\t\ttry {\n\t\t\t\t\tthis._oplog$ = ResolveIOServer.getMainDB().watch(pipeline, { resumeAfter: resumeToken });\n\t\t\t\t}\n\t\t\t\tcatch (errOp) {\n\t\t\t\t\tif (this._oplog$) {\n\t\t\t\t\t\tthis._oplog$.removeAllListeners();\n\t\t\t\t\t\tthis._oplog$.close();\n\t\t\t\t\t\tthis._oplog$ = null;\n\t\t\t\t\t}\n\t\t\t\t\tthis.tailOpLog(resumeToken);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis._oplog$ = ResolveIOServer.getMainDB().watch(pipeline);\n\t\t\t}\n\n\t\t\tconsole.log(new Date(), 'oplog started');\n\n\t\t\tthis._oplog$.on('change', (doc: ChangeStreamInsertDocument | ChangeStreamUpdateDocument | ChangeStreamReplaceDocument | ChangeStreamDeleteDocument) => {\n\t\t\t\tif (doc.ns) {\n\t\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\t\tconsole.log(new Date(), 'Oplog Hit', doc.ns);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet collection = doc.ns.coll;\n\n\t\t\t\t\tif (!this._debugOplogCollections.some(a => a.collection === doc.ns.coll && a.type === doc.operationType)) {\n\t\t\t\t\t\tthis._debugOplogCollections.push({\n\t\t\t\t\t\t\tcollection: doc.ns.coll,\n\t\t\t\t\t\t\ttype: doc.operationType,\n\t\t\t\t\t\t\thits: 1\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis._debugOplogCollections.find(a => a.collection === doc.ns.coll && a.type === doc.operationType).hits += 1;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (collection) {\n\t\t\t\t\t\tthis._debugOplogHits += 1;\n\n\t\t\t\t\t\tif (doc.operationType === 'insert') {\n\t\t\t\t\t\t\tif (collection === 'support-tickets') {\n\t\t\t\t\t\t\t\tif (this.serverConfig['ROOT_URL'] === 'https://resolveio.com') {\n\t\t\t\t\t\t\t\t\tResolveIOServer.getMainServer().getMethodManager().callMethod.call(ResolveIOServer.getMainServer().getMethodManager(), 'sendSupportTicketEmail', doc.documentKey['_id']);\n\t\t\t\t\t\t\t\t\tthis.invalidatePubsCache(collection, 'insert');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (collection !== 'method-responses') {\n\t\t\t\t\t\t\t\tthis.invalidatePubsCache(collection, 'insert');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (doc.operationType === 'update' || doc.operationType === 'replace') {\n\t\t\t\t\t\t\tif (collection !== 'method-responses') {\n\t\t\t\t\t\t\t\tthis.invalidatePubsCache(collection, 'update');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (doc.operationType === 'delete') {\n\t\t\t\t\t\t\tif (collection !== 'method-responses') {\n\t\t\t\t\t\t\t\tthis.invalidatePubsCache(collection, 'delete');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (collection === 'flags') {\n\t\t\t\t\t\tFlags.findOne({ type: 'Enable Debug' }).then(flag => {\n\t\t\t\t\t\t\tif (flag && flag.value) {\n\t\t\t\t\t\t\t\tthis._enableDebug = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tthis._enableDebug = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tlastResumeToken = doc._id;\n\n\t\t\t\t\tif ((!process.env.NODE_APP_INSTANCE || process.env.NODE_APP_INSTANCE === '0') && (process.env.IS_WORKERS_ENABLED === 'false' || (process.env.IS_WORKER_INSTANCE === 'true' && process.env.WORKER_INDEX === '0'))) {\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis._oplog$.on('error', error => {\n\t\t\t\tconsole.log(new Date(), 'oplog error', error);\n\t\t\t\tthis._oplog$.removeAllListeners();\n\t\t\t\tthis._oplog$.close();\n\t\t\t\tthis._oplog$ = null;\n\t\t\t\tthis.tailOpLog(lastResumeToken);\n\t\t\t});\n\n\t\t\tthis._oplog$.on('end', () => {\n\t\t\t\tconsole.log(new Date(), 'oplog end');\n\t\t\t\tthis._oplog$.removeAllListeners();\n\t\t\t\tthis._oplog$.close();\n\t\t\t\tthis._oplog$ = null;\n\t\t\t\tthis.tailOpLog(lastResumeToken);\n\t\t\t});\n\n\t\t\tthis._oplog$.on('close', () => {\n\t\t\t\tconsole.log(new Date(), 'oplog close');\n\t\t\t\tthis._oplog$.removeAllListeners();\n\t\t\t\tthis._oplog$ = null;\n\t\t\t\tthis.tailOpLog(lastResumeToken);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async processSubscription(sub: ActiveSubscriptionModel, ws: WebSocket, messageId: number) {\n\t\tif (!this._publications[sub.publication].user_specific) {\t\t\t\n\t\t\tif (sub.cacheId) {\n\t\t\t\ttry {\n\t\t\t\t\tlet cacheData = JSON.parse(this._nodeCache.get(sub.cacheId), dateReviver);\n\n\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\tdata: cacheData\n\t\t\t\t\t};\n\n\t\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\t\tconsole.log(new Date(), 'Process Sub, Cache', sub.publication);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\tthis._nodeCache.del(sub.cacheId);\n\t\t\t\t\tsub.cacheId = 0;\n\n\t\t\t\t\tthis.sendDataToAllWithRetry(sub, '', 'newSub');\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\tconsole.log(new Date(), 'Process Sub, Non - Cache', sub.publication, sub.running);\n\t\t\t\t}\n\n\t\t\t\tif (sub.running) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.sendDataToAllWithRetry(sub, '', 'newSub');\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Process Sub Specific, Non - Cache', sub.publication, sub.running);\n\t\t\t}\n\n\t\t\tif (sub.running) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tthis.sendDataToOneWithRetry(ws, messageId, sub, '', 'newSub');\n\t\t}\n\t}\n\n\tprivate async sendDataToOne(ws: WebSocket, messageId: number, sub: ActiveSubscriptionModel, collection: string, type: string) {\n\t\tlet monitor = this._monitorManagerFunction.startMonitorFunction('User Specific Publication', sub.publication, '', '', sub.subscriptionData);\n\t\ttry {\n\t\t\tResolveIOServer.getMainServer().getMethodManager().callMethod.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertSubscriptionLog', type, sub.publication, collection, JSON.stringify(sub.subscriptionData));\n\n\t\t\tlet res = await this._publications[sub.publication].function.call(Object.assign({}, this, SubscriptionManager.prototype), ws['id_user'], ...sub.subscriptionData);\n\t\t\tthis._monitorManagerFunction.finishMonitorFunction(monitor);\n\n\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: false,\n\t\t\t\tdata: res\n\t\t\t};\n\n\t\t\tthis.sendWS(ws, serverRes);\n\t\t}\n\t\tcatch (err) {\n\t\t\tthis._monitorManagerFunction.finishMonitorFunction(monitor);\n\n\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: true,\n\t\t\t\tdata: err\n\t\t\t};\n\n\t\t\tthis.sendWS(ws, serverRes);\n\n\t\t\tResolveIOServer.getMainServer().getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'], 'Error Detected During Subscription ' + sub.publication + ' - (sendDataToOne - WS)\\n\\nData \\n' + JSON.stringify(sub.subscriptionData, null, 2) + '\\n\\nErrors\\n' + JSON.stringify(err, null, 2));\n\t\t}\n\t}\n\n\t// Fetch pub once, send to all clients linked to this pub\n\tprivate async sendDataToAll(sub: ActiveSubscriptionModel, collection: string, type: string) {\n\t\tif (!sub.clients.length) {\n\t\t\tif (sub.cacheId) {\n\t\t\t\tthis._nodeCache.del(sub.cacheId);\n\t\t\t\tsub.cacheId = 0;\n\t\t\t}\n\n\t\t\tlet subIndex = this._subscriptions.findIndex(a => a.publication === sub.publication && JSON.stringify(a.subscriptionData) === JSON.stringify(sub.subscriptionData));\n\t\t\tif (subIndex >= 0) {\n\t\t\t\tthis._subscriptions.splice(subIndex, 1);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\tlet monitor = this._monitorManagerFunction.startMonitorFunction('Publication', sub.publication, '', '', sub.subscriptionData);\n\n\t\t\ttry {\n\t\t\t\tif (sub.publication !== 'superadminAPM' && sub.publication !== 'loggedInUsers') {\n\t\t\t\t\tResolveIOServer.getMainServer().getMethodManager().callMethod.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertSubscriptionLog', type, sub.publication, collection, JSON.stringify(sub.subscriptionData));\n\t\t\t\t}\n\n\t\t\t\tlet res = await this._publications[sub.publication].function.call(Object.assign({}, this, SubscriptionManager.prototype), ...sub.subscriptionData);\n\t\t\t\tthis._monitorManagerFunction.finishMonitorFunction(monitor);\n\n\t\t\t\tif (sub.cacheId) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlet cacheData = JSON.parse(this._nodeCache.get(sub.cacheId), dateReviver);\n\t\n\t\t\t\t\t\tif (JSON.stringify(cacheData) !== JSON.stringify(res)) {\n\t\t\t\t\t\t\tPromise.all(\n\t\t\t\t\t\t\t\tsub.clients.map(async client => {\n\t\t\t\t\t\t\t\t\tlet ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\t\t\t\t\tmessageId: client.messageId,\n\t\t\t\t\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\t\t\t\t\tdata: res\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\n\t\t\t\t\t\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tthis._nodeCache.del(sub.cacheId);\n\n\t\t\t\t\t\t\tif (getBinarySize(JSON.stringify(res)) < 1000000 && \n\t\t\t\t\t\t\t\t!sub.collections.includes('logs') &&\n\t\t\t\t\t\t\t\t!sub.collections.find(a => a.endsWith('.versions')) &&\n\t\t\t\t\t\t\t\t!sub.collections.find(a => a.startsWith('monitor-'))\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis._nodeCache.set(sub.cacheId, JSON.stringify(res));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tsub.cacheId = 0;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\tPromise.all(\n\t\t\t\t\t\t\tsub.clients.map(async client => {\n\t\t\t\t\t\t\t\tlet ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\t\t\t\tmessageId: client.messageId,\n\t\t\t\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\t\t\t\tdata: res\n\t\t\t\t\t\t\t\t\t};\n\t\t\n\t\t\t\t\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tthis._nodeCache.del(sub.cacheId);\n\n\t\t\t\t\t\tif (getBinarySize(JSON.stringify(res)) < 1000000 && \n\t\t\t\t\t\t\t!sub.collections.includes('logs') &&\n\t\t\t\t\t\t\t!sub.collections.find(a => a.endsWith('.versions')) &&\n\t\t\t\t\t\t\t!sub.collections.find(a => a.startsWith('monitor-'))\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis._nodeCache.set(sub.cacheId, JSON.stringify(res));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tsub.cacheId = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tPromise.all(\n\t\t\t\t\t\tsub.clients.map(async client => {\n\t\t\t\t\t\t\tlet ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\t\t\tmessageId: client.messageId,\n\t\t\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\t\t\tdata: res\n\t\t\t\t\t\t\t\t};\n\t\n\t\t\t\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t\t\n\t\t\t\t\tif (getBinarySize(JSON.stringify(res)) < 1000000 && \n\t\t\t\t\t\t!sub.collections.includes('logs') &&\n\t\t\t\t\t\t!sub.collections.find(a => a.endsWith('.versions')) &&\n\t\t\t\t\t\t!sub.collections.find(a => a.startsWith('monitor-'))\n\t\t\t\t\t) {\n\t\t\t\t\t\tsub.cacheId = this._cacheId++;\n\t\t\t\t\t\tthis._nodeCache.set(sub.cacheId, JSON.stringify(res));\n\n\t\t\t\t\t\tconst nodeCacheSize = this._nodeCache.getStats().vsize;\n\n\t\t\t\t\t\tif (nodeCacheSize > this._heapLimit) {\n\t\t\t\t\t\t\t// Evict cache entries as needed\n\t\t\t\t\t\t\tlet deleteCount = 0;\n\t\t\t\t\t\t\tconst subArr = this._subscriptions.filter(a => a.cacheId && !a.clients.length);\n\t\t\t\t\t\n\t\t\t\t\t\t\tfor (let zz = 0; zz < subArr.length; zz++) {\n\t\t\t\t\t\t\t\tthis._debugRemoveCacheHits += 1;\n\t\t\t\t\t\t\t\tthis._nodeCache.del(subArr[zz].cacheId);\n\t\t\t\t\t\t\t\tsubArr[zz].cacheId = 0;\n\t\t\t\t\t\t\t\tdeleteCount += 1;\n\t\t\t\t\t\t\t\tif (this._nodeCache.getStats().vsize < this._heapLimit * 0.75) {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t'Sub Cache: ' +\n\t\t\t\t\t\t\t\t\t'Too Big - ' +\n\t\t\t\t\t\t\t\t\tsub.publication +\n\t\t\t\t\t\t\t\t\t' - Deleted: ' +\n\t\t\t\t\t\t\t\t\tdeleteCount +\n\t\t\t\t\t\t\t\t\t' - ' +\n\t\t\t\t\t\t\t\t\tnodeCacheSize\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tsub.cacheId = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\tthis._monitorManagerFunction.finishMonitorFunction(monitor);\n\n\t\t\t\tPromise.all(\n\t\t\t\t\tsub.clients.map(async client => {\n\t\t\t\t\t\tlet ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\t\tmessageId: client.messageId,\n\t\t\t\t\t\t\t\thasError: true,\n\t\t\t\t\t\t\t\tdata: err\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tResolveIOServer.getMainServer().getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'], 'Error Detected During Subscription ' + sub.publication + ' - (sendPubData)\\n\\nData \\n' + JSON.stringify(sub.subscriptionData, null, 2) + '\\n\\nErrors\\n' + JSON.stringify(err, null, 2));\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sendWS(ws: WebSocket, data: ServerResponseModel) {\n\t\tthis._websocketManager.send(ws, data);\n\t}\n\n\tpublic getEnableDebug() {\n\t\treturn this._enableDebug;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/managers/subscription.manager.ts"],"names":["logged_in_users_collection_1","require","app_status_1","cron_jobs_1","files_1","flags_1","logs_1","method_responses_1","notifications_1","report_builder_reports_1","super_admin_1","resolveio_server_app_1","NodeCache","os_1","flag_collection_1","flags_update_1","report_builder_dashboard_builders_1","report_builder_libraries_1","user_groups_1","user_guides_1","common_1","numCPUs","cpus","length","v8","SubscriptionManager","this","_publications","_subscriptions","_loggedInUsers","_mongoQueue","_mongoQueueId","_cacheId","_heapSize","getHeapStatistics","_enableDebug","_debugOplogCollections","_debugOplogHits","_debugSubCollections","_debugSubHits","_debugUnSubHits","_debugUnSubAllHits","_debugMongoQueueHits","_debugMongoQueueCollections","_debugSendQueueHits","_debugRemoveCacheHits","_oplogRetryCount","latencyBuffer","Map","LATENCY_UPDATE_INTERVAL","LATENCY_UPDATE_THRESHOLD_MS","_invalidationDebounceTimers","_invalidationPendingTimestamps","DEBOUNCE_DELAY","MAX_WAIT_TIME","create","wss","serverConfig","monitorManagerFunction","_this","subscriptionManager","setImmediate","__awaiter","initialize","_a","sent","prototype","_websocketManager","ResolveIOServer","getMainServer","getWebSocketManager","_monitorManagerFunction","_nodeCache","stdTTL","checkperiod","setInterval","flushThrottledLatencyUpdates","_wss","loadSuperAdminPublications","loadAppStatusPublications","loadLogPublications","loadFilePublications","loadCronJobPublications","loadFlagsUpdatePublications","loadFlagsPublications","loadMethodResponsePublications","loadNotificationPublications","loadReportBuilderReportPublications","loadReportBuilderLibraryPublications","loadUserGroupPublications","loadUserGuidePublications","loadReportBuilderDashboardBuilderPublications","tailOpLog","getEnableDebug","console","log","Date","JSON","stringify","sort","a","b","collection","localeCompare","publication","type","LoggedInUsers","find","_b","userCopy","deepCopy","i","loggedInUser","date","now","getTime","this_1","getWebSocket","id_ws","unsubscribeAll","_c","forEach","sub","j","clients","id_socket","splice","deleteOne","_id","findIndex","client","this_2","some","Flags","findOne","flag","value","setCacheLimit","process","env","IS_WORKERS_ENABLED","_heapLimit","invalidatePubsCache","debounceKey","firstInvalidationTime","get","set","has","clearTimeout","delete","_executeInvalidation","setTimeout","getMongoManager","invalidateQueryCache","collSubs","filter","collections","includes","collSubs_1","__values","collSubs_1_1","next","running","runAgain","user_specific","e_1","ws","readyState","OPEN","sendDataToOneWithRetry","messageId","_e","sendDataToAllWithRetry","delay","ms","Promise","resolve","sendDataToAll","sendDataToOne","publications","method","Object","assign","loggedInLatency","existingEntry","newLatency","lastUpdate","Math","abs","latency","size","updates","Array","from","entries","map","__read","updateOne","update","$set","bulkWrite","clear","error","error_1","subscribe","messageRoute","messageDate","subscriptionData","hits","push","pub","check","_schema","valObj","valKeys","keys","rootKeys","validate","errors","urlData","split","urlModule_1","urlNext","otherRouteSubs","startsWith","otherSub","unsubscribe","id_user","getPublicationCollections","cacheId","processSubscription","createLoggedInUser","user","objectIdHexString","__v","insertOne","Error","indexOf","userSubs","removeWebSocket","getActiveSubscriptions","resumeToken","_oplog$","closed","removeAllListeners","close","exit","pipeline","$match","$and","ns.coll","$nin","$not","lastResumeToken_1","getMainDB","watch","resumeAfter","on","doc","ns","coll","operationType","getMethodManager","callMethod","call","documentKey","NODE_APP_INSTANCE","IS_WORKER_INSTANCE","WORKER_INDEX","cacheData","parse","dateReviver","serverRes","hasError","data","sendWS","del","monitor","startMonitorFunction","function","apply","__spreadArray","res","err_3","sendEmail","finishMonitorFunction","subIndex","_g","res_1","_l","done","getBinarySize","endsWith","err","_d","nodeCacheSize","getStats","vsize","deleteCount","subArr","zz","_f","err_4","send","exports"],"mappings":"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","file":"subscription.manager.js","sourcesContent":["import * as WebSocket from 'ws';\nimport { LoggedInUsers } from '../collections/logged-in-users.collection';\nimport { LoggedInUserModel } from '../models/logged-in-users.model';\nimport { ServerResponseModel } from '../models/server-response.model';\nimport { ActiveSubscriptionModel, SubscriptionModel } from '../models/subscription.model';\nimport { loadAppStatusPublications } from '../publications/app-status';\nimport { loadCronJobPublications } from '../publications/cron-jobs';\nimport { loadFilePublications } from '../publications/files';\nimport { loadFlagsPublications } from '../publications/flags';\nimport { loadLogPublications } from '../publications/logs';\nimport { loadMethodResponsePublications } from '../publications/method-responses';\nimport { loadNotificationPublications } from '../publications/notifications';\nimport { loadReportBuilderReportPublications } from '../publications/report-builder-reports';\nimport { loadSuperAdminPublications } from '../publications/super-admin';\nimport { ResolveIOServer } from '../resolveio-server-app';\n\nimport { ChangeStream, ChangeStreamDeleteDocument, ChangeStreamInsertDocument, ChangeStreamReplaceDocument, ChangeStreamUpdateDocument, ResumeToken } from 'mongodb';\nimport * as NodeCache from 'node-cache';\nimport { cpus } from 'os';\nimport { Flags } from '../collections/flag.collection';\nimport { loadFlagsUpdatePublications } from '../publications/flags-update';\nimport { loadReportBuilderDashboardBuilderPublications } from '../publications/report-builder-dashboard-builders';\nimport { loadReportBuilderLibraryPublications } from '../publications/report-builder-libraries';\nimport { loadUserGroupPublications } from '../publications/user-groups';\nimport { loadUserGuidePublications } from '../publications/user-guides';\nimport { dateReviver, deepCopy, getBinarySize, objectIdHexString } from '../util/common';\nimport { MonitorManagerFunction } from './monitor.manager';\nimport { WebSocketManager } from './websocket.manager';\nconst numCPUs = cpus().length;\nconst v8 = require('v8');\n\n// Performance Dependencies\n// import * as path from 'path';\n// import { Worker } from 'worker_threads';\n\ninterface MongoQueueModel {\n\t_id: number,\n\ttype: string;\n\tcollection: string;\n\tsubscription: ActiveSubscriptionModel;\n\trunning: boolean;\n\trun_again: boolean;\n}\n\n// interface CurrentPerformanceMonitor {\n// \t_id: number;\n// \tfunction: string;\n// \tpublication: string;\n// \tsubscriptionData: any[];\n// \tdate_start: Date;\n// \tdate_end: Date;\n// \tduration: number;\n// \tresult: string;\n// }\n\nexport class SubscriptionManager {\n\tprivate _websocketManager: WebSocketManager;\n\tprivate _publications: SubscriptionModel = {};\n\tprivate _subscriptions: ActiveSubscriptionModel[] = [];\n\tprivate _wss: WebSocket.Server;\n\tprivate _loggedInUsers: LoggedInUserModel[] = [];\n\n\tprivate _mongoQueue: MongoQueueModel[] = [];\n\tprivate _mongoQueueId = 0;\n\t\n\tprivate _oplog$: ChangeStream;\n\n\tprivate _nodeCache;\n\tprivate _cacheId = 1;\n\n\tprivate _heapSize = v8.getHeapStatistics() / numCPUs;\n\tprivate _heapLimit: number;\n\n\tprivate serverConfig;\n\n\tprivate _monitorManagerFunction: MonitorManagerFunction;\n\n\tprivate _enableDebug = false;\n\tprivate _debugOplogCollections = [];\n\tprivate _debugOplogHits = 0;\n\tprivate _debugSubCollections = [];\n\tprivate _debugSubHits = 0;\n\tprivate _debugUnSubHits = 0;\n\tprivate _debugUnSubAllHits = 0;\n\tprivate _debugMongoQueueHits = 0;\n\tprivate _debugMongoQueueCollections = [];\n\tprivate _debugSendQueueHits = 0;\n\tprivate _debugRemoveCacheHits = 0;\n\n\tprivate _oplogRetryCount = 0;\n\n\t// Buffer to store throttled latency updates with timestamps\n\tprivate latencyBuffer = new Map<string, { latency: number, lastUpdate: Date }>();\n\n\t// Interval to flush latency updates in MongoDB\n\tprivate readonly LATENCY_UPDATE_INTERVAL = 60000;\n\n\t// Minimum time difference between two latency updates for the same user\n\tprivate readonly LATENCY_UPDATE_THRESHOLD_MS = 30000;\n\n\t// private currentPerfomanceMonitor: CurrentPerformanceMonitor[] = [];\n\t// private idPerformance: number = 0;\n\t// private performanceThread;\n\n\tprivate _invalidationDebounceTimers = new Map<string, NodeJS.Timeout>();\n\tprivate _invalidationPendingTimestamps = new Map<string, number>();\n\tprivate readonly DEBOUNCE_DELAY = 100; // 100ms debounce window\n\tprivate readonly MAX_WAIT_TIME = 500; // 500ms maximum delay\n\n\n\tconstructor() {}\n\t\n\tstatic create(wss: WebSocket.Server, serverConfig, monitorManagerFunction: MonitorManagerFunction) {\n\t\tconst subscriptionManager = new SubscriptionManager();\n\t\tsetImmediate(async () => {\n\t\t\tawait subscriptionManager.initialize(wss, serverConfig, monitorManagerFunction);\n\t\t});\n\t\treturn subscriptionManager;\n\t}\n\t\n\tprivate async initialize(wss: WebSocket.Server, serverConfig, monitorManagerFunction: MonitorManagerFunction) {\n\t\tthis._websocketManager = ResolveIOServer.getMainServer().getWebSocketManager();\n\t\tthis._monitorManagerFunction = monitorManagerFunction;\n\n\t\tthis._nodeCache = new NodeCache( { stdTTL: 0, checkperiod: 0 } );\n\n\t\tsetInterval(() => this.flushThrottledLatencyUpdates(), this.LATENCY_UPDATE_INTERVAL);\n\n\t\t// setTimeout(() => {\n\t\t// \tconsole.log('Setting up performance thread');\n\n\t\t// \tthis.performanceThread = new Worker(path.join(__dirname, './subscription.performance.js'));\n\n\t\t// \tthis.performanceThread.on('exit', code => {\n\t\t// \t\tconsole.error(new Date(), 'THREAD EXITED!!!!!!!!!!!!!!!!!!', code);\n\t\t// \t});\n\n\t\t// \tthis.performanceThread.on('error', code => {\n\t\t// \t\tconsole.error(new Date(), 'THREAD RECV ERROR !!!!!!!!!!!!!!!!!!', code);\n\t\t// \t});\n\t\t// }, 5000);\n\n\t\t// setInterval(() => {\n\t\t// \tconsole.log('Post thread msg');\n\t\t// \tthis.performanceThread.postMessage(this.currentPerfomanceMonitor);\n\t\t// \tthis.currentPerfomanceMonitor = [];\n\t\t// }, 10000);\n\n\t\tthis.serverConfig = serverConfig;\n\t\tthis._wss = wss;\n\n\t\t// Publications\n\t\tloadSuperAdminPublications(this);\n\t\tloadAppStatusPublications(this);\n\t\tloadLogPublications(this);\n\t\tloadFilePublications(this);\n\t\tloadCronJobPublications(this);\n\t\tloadFlagsUpdatePublications(this);\n\t\tloadFlagsPublications(this);\n\t\tloadMethodResponsePublications(this);\n\t\tloadNotificationPublications(this);\n\t\tloadReportBuilderReportPublications(this);\n\t\tloadReportBuilderLibraryPublications(this);\n\t\tloadUserGroupPublications(this);\n\t\tloadUserGuidePublications(this);\n\t\tloadReportBuilderDashboardBuilderPublications(this);\n\n\t\tawait this.tailOpLog();\n\n\t\tsetInterval(() => {\n\t\t\tthis._oplogRetryCount = 0;\n\t\t}, 15000);\n\n\t\tsetInterval(() => {\n\t\t\tif (this.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Subs', this._subscriptions.length);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Logged In Users', this._loggedInUsers.length);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Mongo Queue', this._mongoQueue.length);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Mongo Queue Hits', this._debugMongoQueueHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Mongo Queue Collections', JSON.stringify(this._debugMongoQueueCollections.sort((a, b) => a.collection.localeCompare(b.collection) || a.publication.localeCompare(b.publication)), null, 2));\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Oplog Hits', this._debugOplogHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Oplog Collections', JSON.stringify(this._debugOplogCollections.sort((a, b) => a.collection.localeCompare(b.collection) || a.type.localeCompare(b.type)), null, 2));\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Send Queue Hits', this._debugSendQueueHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Sub Hits', this._debugSubHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Sub Collections', JSON.stringify(this._debugSubCollections.sort((a, b) => a.publication.localeCompare(b.publication)), null, 2));\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Unsub Hits', this._debugUnSubHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Unsub All Hits', this._debugUnSubAllHits);\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Cache Cleanup Hits', this._debugRemoveCacheHits);\n\t\t\t}\n\t\t\t\n\t\t\tthis._debugOplogHits = 0;\n\t\t\tthis._debugOplogCollections = [];\n\t\t\tthis._debugSubCollections = [];\n\t\t\tthis._debugMongoQueueHits = 0;\n\t\t\tthis._debugMongoQueueCollections = [];\n\t\t\tthis._debugSendQueueHits = 0;\n\t\t\tthis._debugSubHits = 0;\n\t\t\tthis._debugUnSubHits = 0;\n\t\t\tthis._debugUnSubAllHits = 0;\n\t\t\tthis._debugRemoveCacheHits = 0;\n\t\t}, 60000);\n\n\t\tsetInterval(async () => {\n\t\t\tthis._loggedInUsers = await LoggedInUsers.find();\n\t\n\t\t\tlet userCopy = deepCopy(this._loggedInUsers);\n\t\t\tfor (let i = this._loggedInUsers.length - 1; i >= 0; i--) {\n\t\t\t\tlet loggedInUser = userCopy[i];\n\n\t\t\t\tif (!loggedInUser.date || Date.now() - loggedInUser.date.getTime() > 120000) {\n\t\t\t\t\tif (this._websocketManager.getWebSocket(loggedInUser.id_ws)) {\n\t\t\t\t\t\tif (this.getEnableDebug()) {\n\t\t\t\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Unsub WS', this._websocketManager.getWebSocket(loggedInUser.id_ws)['user'], this._websocketManager.getWebSocket(loggedInUser.id_ws)['id_socket'], 2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait this.unsubscribeAll(this._websocketManager.getWebSocket(loggedInUser.id_ws));\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis._subscriptions.forEach(sub => {\n\t\t\t\t\t\t\tfor (let j = sub.clients.length - 1; j >= 0; j--) {\n\t\t\t\t\t\t\t\tlet client = sub.clients[j];\n\n\t\t\t\t\t\t\t\tif (client.id_socket === loggedInUser.id_ws) {\n\t\t\t\t\t\t\t\t\tsub.clients.splice(j, 1);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait LoggedInUsers.deleteOne({_id: loggedInUser._id});\n\n\t\t\t\t\t\tif (this._loggedInUsers.findIndex(a => a._id === loggedInUser._id) >= 0) {\n\t\t\t\t\t\t\tthis._loggedInUsers.splice(this._loggedInUsers.findIndex(a => a._id === loggedInUser._id), 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < this._subscriptions.length; i++) {\n\t\t\t\tlet sub = this._subscriptions[i];\n\n\t\t\t\tfor (let j = sub.clients.length - 1; j >= 0; j--) {\n\t\t\t\t\tlet client = sub.clients[j];\n\n\t\t\t\t\tif (!this._loggedInUsers.some(a => a.id_ws === client.id_socket)) {\n\t\t\t\t\t\tsub.clients.splice(j, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}, 30000);\n\n\t\tlet flag = await Flags.findOne({type: 'Enable Debug'});\n\n\t\tif (flag && flag.value) {\n\t\t\tthis._enableDebug = true;\n\t\t}\n\t\telse {\n\t\t\tthis._enableDebug = false;\n\t\t}\n\n\t\tthis.setCacheLimit();\n\t}\n\n\tprivate setCacheLimit() {\t\n\t\tif (process.env.IS_WORKERS_ENABLED === 'true') {\n\t\t\tthis._heapLimit = this._heapSize * 0.4;\n\t\t}\n\t\telse {\n\t\t\tthis._heapLimit = this._heapSize * 0.3; // Use 50% of total heap size\n\t\t}\n\t}\n\n\tpublic async invalidatePubsCache(collection: string, type: string) {\n\t\tconst debounceKey = collection;\n\t\tconst now = Date.now();\n\t\n\t\t// Initialize or get existing timestamp\n\t\tconst firstInvalidationTime = this._invalidationPendingTimestamps.get(debounceKey) || now;\n\t\tthis._invalidationPendingTimestamps.set(debounceKey, firstInvalidationTime);\n\t\n\t\t// Clear any existing timer\n\t\tif (this._invalidationDebounceTimers.has(debounceKey)) {\n\t\t\tclearTimeout(this._invalidationDebounceTimers.get(debounceKey));\n\t\t}\n\t\n\t\t// Check if we've waited too long\n\t\tconst waitedTooLong = (now - firstInvalidationTime) >= this.MAX_WAIT_TIME;\n\t\t\n\t\tif (waitedTooLong) {\n\t\t\t// Immediate execution path\n\t\t\tthis._invalidationPendingTimestamps.delete(debounceKey);\n\t\t\tawait this._executeInvalidation(collection, type);\n\t\t} else {\n\t\t\t// Normal debounce path\n\t\t\tthis._invalidationDebounceTimers.set(\n\t\t\t\tdebounceKey,\n\t\t\t\tsetTimeout(async () => {\n\t\t\t\t\tthis._invalidationPendingTimestamps.delete(debounceKey);\n\t\t\t\t\tawait this._executeInvalidation(collection, type);\n\t\t\t\t}, this.DEBOUNCE_DELAY)\n\t\t\t);\n\t\t}\n\t}\n\t\n\tprivate async _executeInvalidation(collection: string, type: string) {\n\t\t// Clean up any existing timer (defensive)\n\t\tif (this._invalidationDebounceTimers.has(collection)) {\n\t\t\tclearTimeout(this._invalidationDebounceTimers.get(collection));\n\t\t\tthis._invalidationDebounceTimers.delete(collection);\n\t\t}\n\t\n\t\t// Original invalidation logic\n\t\tResolveIOServer.getMongoManager().invalidateQueryCache(collection);\n\t\n\t\tconst collSubs = this._subscriptions.filter(a => a.collections.includes(collection));\n\t\n\t\tfor (const sub of collSubs) {\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Invalidate Sub', sub.publication, sub.running, sub.runAgain);\n\t\t\t}\n\t\n\t\t\tif (sub.running) {\n\t\t\t\tsub.runAgain = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\n\t\t\tif (this._publications[sub.publication].user_specific) {\n\t\t\t\tfor (let client of sub.clients) {\n\t\t\t\t\tconst ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\tif (ws?.readyState === ws.OPEN) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait this.sendDataToOneWithRetry(ws, client.messageId, sub, collection, type);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\t\t// Error handling\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tawait this.sendDataToAllWithRetry(sub, collection, type);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async delay(ms: number) {\n\t\t// eslint-disable-next-line no-restricted-syntax\n\t\treturn new Promise(resolve => setTimeout(resolve, ms));\n\t}\n\n\tprivate async sendDataToAllWithRetry(sub: ActiveSubscriptionModel, collection: string, type: string) {\n\t\tsub.running = true;\n\n\t\tdo {\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Running sendDataToAll Sub', sub.publication);\n\t\t\t}\n\n\t\t\tsub.runAgain = false;\n\t\t\tawait this.sendDataToAll(sub, collection, type);\n\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Done sendDataToAll Sub', sub.publication, sub.runAgain);\n\t\t\t}\n\n\t\t\tif (sub.runAgain) {\n\t\t\t\tawait this.delay(500); // delay, adjust as needed\n\t\t\t}\n\t\t} while (sub.runAgain);\n\n\t\tsub.running = false;\n\t}\n\n\tprivate async sendDataToOneWithRetry(ws: WebSocket, messageId: number, sub: ActiveSubscriptionModel, collection: string, type: string) {\n\t\tsub.running = true;\n\n\t\tdo {\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Running sendDataToOne Sub', sub.publication);\n\t\t\t}\n\n\t\t\tsub.runAgain = false;\n\t\t\tawait this.sendDataToOne(ws, messageId, sub, collection, type);\n\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Done sendDataToOne Sub', sub.publication, sub.runAgain);\n\t\t\t}\n\n\t\t\tif (sub.runAgain) {\n\t\t\t\tawait this.delay(500); // delay, adjust as needed\n\t\t\t}\n\t\t} while (sub.runAgain);\n\t\tsub.running = false;\n\t}\n\n\t// Add all files to publications private object\n\tpublic publications(method: SubscriptionModel) {\n\t\tthis._publications = Object.assign(this._publications, method);\n\t}\n\n\t// Throttled `loggedInLatency` method\n\tpublic loggedInLatency(ws: WebSocket) {\n\t\tlet loggedInUser = this._loggedInUsers.find(a => a.id_ws === ws['id_socket']);\n\t\tif (!loggedInUser) return;\n\n\t\tconst now = new Date();\n\t\tconst existingEntry = this.latencyBuffer.get(ws['id_socket']);\n\t\tconst newLatency = ws['latency'];\n\n\t\t// Throttle updates: only update if time threshold has passed or latency has significantly changed\n\t\tif (\n\t\t\t!existingEntry || \n\t\t\t(now.getTime() - existingEntry.lastUpdate.getTime() >= this.LATENCY_UPDATE_THRESHOLD_MS) || \n\t\t\t(Math.abs(newLatency - existingEntry.latency) > 100) // Optional: log only significant changes\n\t\t) {\n\t\t\t// Update in-memory and buffer\n\t\t\tloggedInUser.date = now;\n\t\t\tthis.latencyBuffer.set(ws['id_socket'], { latency: newLatency, lastUpdate: now });\n\t\t}\n\t}\n\n\t// Method to flush buffered latency updates in bulk\n\tprivate async flushThrottledLatencyUpdates() {\n\t\tif (this.latencyBuffer.size === 0) return; // No updates to flush\n\n\t\tconst updates = Array.from(this.latencyBuffer.entries()).map(([id_ws, { latency, lastUpdate }]) => ({\n\t\t\tupdateOne: {\n\t\t\t\tfilter: { id_ws },\n\t\t\t\tupdate: { $set: { latency, date: lastUpdate } }\n\t\t\t}\n\t\t}));\n\n\t\ttry {\n\t\t\tawait LoggedInUsers.bulkWrite(updates);\n\t\t\tthis.latencyBuffer.clear(); // Clear buffer after successful update\n\n\t\t\tif (this.getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'Sub Manager', 'Throttled latency batch update successful', updates.length);\n\t\t\t}\n\t\t}\n\t\tcatch (error) {\n\t\t\tconsole.error(new Date(), 'Sub Manager', 'Throttled latency batch update failed', error);\n\t\t\t// Optional: implement retry logic or logging for failed updates\n\t\t}\n\t}\n\n\t// Subscribe to publication\n\tpublic async subscribe(messageRoute: string, messageDate: Date, ws: WebSocket, messageId: number, publication: string, subscriptionData: any[]) {\n\t\tthis._debugSubHits += 1;\n\n\t\tif (!this._debugSubCollections.some(a => a.publication === publication)) {\n\t\t\tthis._debugSubCollections.push({\n\t\t\t\tpublication: publication,\n\t\t\t\thits: 1\n\t\t\t});\n\t\t}\n\t\telse {\n\t\t\tthis._debugSubCollections.find(a => a.publication === publication).hits += 1;\n\t\t}\n\n\t\tlet pub = this._publications[publication];\n\n\t\tif (!pub) {\n\t\t\tconsole.error(new Date(), 'No Publication: ' + publication);\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\tif (subscriptionData.length > 1 || subscriptionData[0]) {\n\t\t\t\tif (!pub.check) {\n\t\t\t\t\tconsole.error(new Date(), 'No Check Function For Pub ' + publication);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if (!pub.check._schema) {\n\t\t\t\t\tconsole.error(new Date(), 'No Check Schema For Pub ' + publication);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlet valObj = {};\n\t\t\t\t\tlet valKeys = Object.keys(pub.check._schema);\n\n\t\t\t\t\tlet rootKeys = valKeys.filter(a => !a.includes('.'));\n\n\t\t\t\t\tfor (let i = 0; i < subscriptionData.length; i++) {\n\t\t\t\t\t\tvalObj[rootKeys[i]] = subscriptionData[i];\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpub.check.validate(valObj);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (errors) {\n\t\t\t\t\t\tif (errors) {\n\t\t\t\t\t\t\tconsole.error(new Date(), 'Error in Pub Check (' + publication + ')', errors);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (messageRoute !== 'Bypass') {\n\t\t\t\tlet urlData = messageRoute.split('/');\n\t\t\t\tlet urlModule = '';\n\t\t\t\tlet urlNext = urlData[0];\n\n\t\t\t\tif (urlData[0] === '') {\n\t\t\t\t\turlModule = '/';\n\t\t\t\t\turlNext = urlData[1];\n\t\t\t\t}\n\n\t\t\t\turlModule += urlNext;\n\n\t\t\t\tif (urlData.length > 1) {\n\t\t\t\t\turlModule += '/';\n\t\t\t\t}\n\n\t\t\t\tlet otherRouteSubs = this._subscriptions.filter(a => a.clients.some(b => b.id_socket === ws['id_socket'] && b.messageRoute !== 'Bypass' && b.messageRoute !== '/' && b.messageRoute !== messageRoute && !b.messageRoute.startsWith(urlModule)));\n\n\t\t\t\tif (otherRouteSubs.length) {\n\t\t\t\t\t// ResolveIOServer.getMainServer().getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Detected Undestroyed Subscription - ' + this.serverConfig['CLIENT_NAME'], 'USER: ' + ws['user'] + ' (Socket: ' + ws['id_socket'] + ') ' + ' is on route: ' + messageRoute + ' but has the following subscriptions on other routes:' + JSON.stringify(otherRouteSubs, null, 2));\n\n\t\t\t\t\totherRouteSubs.forEach(otherSub => {\n\t\t\t\t\t\totherSub.clients.filter(a => a.id_socket === ws['id_socket']).forEach(client => {\n\t\t\t\t\t\t\tthis.unsubscribe(client.messageRoute, new Date(), ws, client.messageId, otherSub.publication, otherSub.subscriptionData);\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet sub = this._subscriptions.find(a => a.publication === publication && JSON.stringify(a.subscriptionData) === JSON.stringify(subscriptionData));\n\n\t\t\t// If sub found (another user watching same data), add client to same sub\n\t\t\tif (sub) {\n\t\t\t\tif (!sub.clients.some(a => a.id_socket === ws['id_socket'] && a.messageId === messageId)) {\n\t\t\t\t\tsub.clients.push({\n\t\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\tid_socket: ws['id_socket'],\n\t\t\t\t\t\tmessageRoute: messageRoute\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If sub not found, create new sub\n\t\t\telse {\n\t\t\t\tthis._subscriptions.push({\n\t\t\t\t\tpublication: publication,\n\t\t\t\t\tsubscriptionData: subscriptionData,\n\t\t\t\t\tcollections: this.getPublicationCollections(publication),\n\t\t\t\t\tclients: [{\n\t\t\t\t\t\tid_user: ws['id_user'],\n\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\tid_socket: ws['id_socket'],\n\t\t\t\t\t\tmessageRoute: messageRoute,\n\t\t\t\t\t}],\n\t\t\t\t\tcacheId: 0,\n\t\t\t\t\trunning: false,\n\t\t\t\t\trunAgain: false\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!sub) {\n\t\t\t\tsub = this._subscriptions.find(a => a.publication === publication && JSON.stringify(a.subscriptionData) === JSON.stringify(subscriptionData));\n\t\t\t}\n\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'New Sub', sub.publication, sub.running, sub.runAgain, sub.clients.length);\n\t\t\t}\n\n\t\t\t// Immediately send data to the new client\n\t\t\tawait this.processSubscription(sub, ws, messageId);\n\t\t}\n\t}\n\n\tpublic async createLoggedInUser(id_ws: string): Promise<LoggedInUserModel> {\n\t\tlet ws = this._websocketManager.getWebSocket(id_ws);\n\n\t\tif (ws) {\n\t\t\tlet user = {\n\t\t\t\t_id: objectIdHexString(),\n\t\t\t\t__v: 0,\n\t\t\t\tdate: new Date(),\n\t\t\t\tid_user: ws['id_user'],\n\t\t\t\tuser: ws['user'],\n\t\t\t\tid_ws: ws['id_socket']\n\t\t\t};\n\t\t\t\n\t\t\tthis._loggedInUsers.push(user);\n\t\t\tawait LoggedInUsers.insertOne(user);\n\t\t\t\n\t\t\treturn user;\n\t\t}\n\t\telse {\n\t\t\tthrow new Error('Error in Create Logged In User: No WS');\n\t\t}\n\t}\n\n\t// Unsubscribe from publication \n\tpublic unsubscribe(messageRoute: string, messageDate: Date, ws: WebSocket, messageId: number, publication: string, subscriptionData: any[]) {\t\t\n\t\tthis._debugUnSubHits += 1;\n\n\t\tif (!this._publications[publication]) {\n\t\t\tconsole.log('No Publication: ' + publication);\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\tlet sub = this._subscriptions.find(a => a.publication === publication && JSON.stringify(a.subscriptionData) === JSON.stringify(subscriptionData));\n\n\t\t\tif (sub) {\n\t\t\t\tfor (let i = sub.clients.length - 1; i >= 0; i--) {\n\t\t\t\t\tif (sub.clients[i].id_user === ws['id_user'] && sub.clients[i].messageId === messageId && sub.clients[i].id_socket === ws['id_socket']) {\n\t\t\t\t\t\tsub.clients.splice(i, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\tconsole.log(new Date(), 'Unsub', sub.publication, sub.running, sub.runAgain, sub.clients.length);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\t// Unsubscribe from publication\n\tpublic async unsubscribeAll(ws: WebSocket) {\n\t\tthis._debugUnSubAllHits += 1;\n\n\t\tif (ws) {\n\t\t\t// Check if WebSocket has already been unsubscribed\n\t\t\tif (ws['isUnsubscribed']) {\n\t\t\t\treturn; // Skip if already unsubscribed\n\t\t\t}\n\t\t\t\n\t\t\t// Mark the WebSocket as unsubscribed to prevent further calls\n\t\t\tws['isUnsubscribed'] = true;\n\t\t\t\n\t\t\tif (this._loggedInUsers.map(a => a.id_ws).indexOf(ws['id_socket']) >= 0) {\n\t\t\t\tthis._loggedInUsers.splice(this._loggedInUsers.map(a => a.id_ws).indexOf(ws['id_socket']), 1);\n\t\t\t}\n\t\t\t\n\t\t\tawait LoggedInUsers.deleteOne({ id_ws: ws['id_socket'] });\n\n\t\t\tlet userSubs = this._subscriptions.filter(a => a.clients.some(b => b.id_user === ws['id_user'] && b.id_socket === ws['id_socket']));\n\n\t\t\tfor (let i = userSubs.length - 1; i >= 0; i--) {\n\t\t\t\tlet sub = userSubs[i];\n\n\t\t\t\tfor (let j = sub.clients.length - 1; j >= 0; j--) {\n\t\t\t\t\tif (sub.clients[j].id_socket === ws['id_socket']) {\n\t\t\t\t\t\tsub.clients.splice(j, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._websocketManager.removeWebSocket(ws);\n\t\t}\n\t}\n\n\tpublic getActiveSubscriptions() {\n\t\treturn this._subscriptions;\n\t}\n\n\t// Get publication collection\n\tprivate getPublicationCollections(publication: string) {\n\t\treturn this._publications[publication].collections;\n\t}\n\n\t// Watch (tail) Mongo's operation log on the entire database (all insert/modify/delete will trigger this function)\n\tprivate async tailOpLog(resumeToken?: ResumeToken) {\n\t\tif (this._oplog$ && !this._oplog$.closed) {\n\t\t\tthis._oplog$.removeAllListeners();\n\t\t\tawait this._oplog$.close();\n\t\t\tthis._oplog$ = null;\n\t\t}\n\n\t\t// eslint-disable-next-line no-restricted-syntax\n\t\tawait new Promise(resolve => setTimeout(resolve, 1000));\n\n\t\tif (!this._oplog$ || this._oplog$.closed) {\n\t\t\tthis._oplogRetryCount += 1;\n\n\t\t\tif (this._oplogRetryCount > 5) {\n\t\t\t\tconsole.error('****************** TAIL OPLOG ERROR, RETRYING A BUNCH OF TIMES, KILLING PROCESS **************************');\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst pipeline = [\n\t\t\t\t{\n\t\t\t\t\t$match: {\n\t\t\t\t\t\t$and: [\n\t\t\t\t\t\t\t{'ns.coll': { $nin: [\n\t\t\t\t\t\t\t\t'log-method-latencies', \n\t\t\t\t\t\t\t\t'log-subscriptions', \n\t\t\t\t\t\t\t\t'logs', \n\t\t\t\t\t\t\t\t'counters', \n\t\t\t\t\t\t\t\t'cron-job-histories', \n\t\t\t\t\t\t\t\t'email-histories',\n\t\t\t\t\t\t\t\t'qb-soap-request-histories', \n\t\t\t\t\t\t\t\t'qb-soap-request-responses', \n\t\t\t\t\t\t\t\t'qb-soap-requests',\n\t\t\t\t\t\t\t\t'qb-soap-retries'\n\t\t\t\t\t\t\t] }},\n\t\t\t\t\t\t\t{'ns.coll': { $not: /.*\\.versions$/ }},\n\t\t\t\t\t\t\t{'ns.coll': { $not: /^monitor-/ }},\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\n\t\t\tlet lastResumeToken: ResumeToken;\n\n\t\t\tif (resumeToken) {\n\t\t\t\tlastResumeToken = resumeToken;\n\t\t\t\ttry {\n\t\t\t\t\tthis._oplog$ = ResolveIOServer.getMainDB().watch(pipeline, { resumeAfter: resumeToken });\n\t\t\t\t}\n\t\t\t\tcatch (errOp) {\n\t\t\t\t\tif (this._oplog$) {\n\t\t\t\t\t\tthis._oplog$.removeAllListeners();\n\t\t\t\t\t\tawait this._oplog$.close();\n\t\t\t\t\t\tthis._oplog$ = null;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait this.tailOpLog(resumeToken);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis._oplog$ = ResolveIOServer.getMainDB().watch(pipeline);\n\t\t\t}\n\n\t\t\tconsole.log(new Date(), 'oplog started');\n\n\t\t\tthis._oplog$.on('change', async (doc: ChangeStreamInsertDocument | ChangeStreamUpdateDocument | ChangeStreamReplaceDocument | ChangeStreamDeleteDocument) => {\n\t\t\t\tif (doc.ns) {\n\t\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\t\tconsole.log(new Date(), 'Oplog Hit', doc.ns);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet collection = doc.ns.coll;\n\n\t\t\t\t\tif (!this._debugOplogCollections.some(a => a.collection === doc.ns.coll && a.type === doc.operationType)) {\n\t\t\t\t\t\tthis._debugOplogCollections.push({\n\t\t\t\t\t\t\tcollection: doc.ns.coll,\n\t\t\t\t\t\t\ttype: doc.operationType,\n\t\t\t\t\t\t\thits: 1\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis._debugOplogCollections.find(a => a.collection === doc.ns.coll && a.type === doc.operationType).hits += 1;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (collection) {\n\t\t\t\t\t\tthis._debugOplogHits += 1;\n\n\t\t\t\t\t\tif (doc.operationType === 'insert') {\n\t\t\t\t\t\t\tif (collection === 'support-tickets') {\n\t\t\t\t\t\t\t\tif (this.serverConfig['ROOT_URL'] === 'https://resolveio.com') {\n\t\t\t\t\t\t\t\t\tResolveIOServer.getMainServer().getMethodManager().callMethod.call(ResolveIOServer.getMainServer().getMethodManager(), 'sendSupportTicketEmail', doc.documentKey['_id']);\n\t\t\t\t\t\t\t\t\tawait this.invalidatePubsCache(collection, 'insert');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (collection !== 'method-responses') {\n\t\t\t\t\t\t\t\tawait this.invalidatePubsCache(collection, 'insert');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (doc.operationType === 'update' || doc.operationType === 'replace') {\n\t\t\t\t\t\t\tif (collection !== 'method-responses') {\n\t\t\t\t\t\t\t\tawait this.invalidatePubsCache(collection, 'update');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (doc.operationType === 'delete') {\n\t\t\t\t\t\t\tif (collection !== 'method-responses') {\n\t\t\t\t\t\t\t\tawait this.invalidatePubsCache(collection, 'delete');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (collection === 'flags') {\n\t\t\t\t\t\tlet flag = await Flags.findOne({ type: 'Enable Debug' });\n\t\t\t\t\t\t\n\t\t\t\t\t\tif (flag && flag.value) {\n\t\t\t\t\t\t\tthis._enableDebug = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthis._enableDebug = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tlastResumeToken = doc._id;\n\n\t\t\t\t\tif ((!process.env.NODE_APP_INSTANCE || process.env.NODE_APP_INSTANCE === '0') && (process.env.IS_WORKERS_ENABLED === 'false' || (process.env.IS_WORKER_INSTANCE === 'true' && process.env.WORKER_INDEX === '0'))) {\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis._oplog$.on('error', async error => {\n\t\t\t\tconsole.log(new Date(), 'oplog error', error);\n\t\t\t\tawait this._oplog$.close();\n\t\t\t});\n\n\t\t\tthis._oplog$.on('end', async () => {\n\t\t\t\tconsole.log(new Date(), 'oplog end');\n\t\t\t\tawait this._oplog$.close();\n\t\t\t});\n\n\t\t\tthis._oplog$.on('close', async () => {\n\t\t\t\tconsole.log(new Date(), 'oplog close');\n\t\t\t\tthis._oplog$.removeAllListeners();\n\t\t\t\tthis._oplog$ = null;\n\t\t\t\tawait this.tailOpLog(lastResumeToken);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async processSubscription(sub: ActiveSubscriptionModel, ws: WebSocket, messageId: number) {\n\t\tif (!this._publications[sub.publication].user_specific) {\t\t\t\n\t\t\tif (sub.cacheId) {\n\t\t\t\ttry {\n\t\t\t\t\tlet cacheData = JSON.parse(this._nodeCache.get(sub.cacheId), dateReviver);\n\n\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\tmessageId: messageId,\n\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\tdata: cacheData\n\t\t\t\t\t};\n\n\t\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\t\tconsole.log(new Date(), 'Process Sub, Cache', sub.publication);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t}\n\t\t\t\tcatch (err) {\n\t\t\t\t\tthis._nodeCache.del(sub.cacheId);\n\t\t\t\t\tsub.cacheId = 0;\n\n\t\t\t\t\tawait this.sendDataToAllWithRetry(sub, '', 'newSub');\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\tconsole.log(new Date(), 'Process Sub, Non - Cache', sub.publication, sub.running);\n\t\t\t\t}\n\n\t\t\t\tif (sub.running) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tawait this.sendDataToAllWithRetry(sub, '', 'newSub');\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (this._enableDebug) {\n\t\t\t\tconsole.log(new Date(), 'Process Sub Specific, Non - Cache', sub.publication, sub.running);\n\t\t\t}\n\n\t\t\tif (sub.running) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tawait this.sendDataToOneWithRetry(ws, messageId, sub, '', 'newSub');\n\t\t}\n\t}\n\n\tprivate async sendDataToOne(ws: WebSocket, messageId: number, sub: ActiveSubscriptionModel, collection: string, type: string) {\n\t\tlet monitor = this._monitorManagerFunction.startMonitorFunction('User Specific Publication', sub.publication, '', '', sub.subscriptionData);\n\t\ttry {\n\t\t\tResolveIOServer.getMainServer().getMethodManager().callMethod.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertSubscriptionLog', type, sub.publication, collection, JSON.stringify(sub.subscriptionData));\n\n\t\t\tlet res = await this._publications[sub.publication].function.call(Object.assign({}, this, SubscriptionManager.prototype), ws['id_user'], ...sub.subscriptionData);\n\n\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: false,\n\t\t\t\tdata: res\n\t\t\t};\n\n\t\t\tthis.sendWS(ws, serverRes);\n\t\t}\n\t\tcatch (err) {\n\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\tmessageId: messageId,\n\t\t\t\thasError: true,\n\t\t\t\tdata: err\n\t\t\t};\n\t\t\t\n\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\n\t\t\tawait ResolveIOServer.getMainServer().getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'], 'Error Detected During Subscription ' + sub.publication + ' - (sendDataToOne - WS)\\n\\nData \\n' + JSON.stringify(sub.subscriptionData, null, 2) + '\\n\\nErrors\\n' + JSON.stringify(err, null, 2));\n\t\t}\n\t\tfinally {\n\t\t\tawait this._monitorManagerFunction.finishMonitorFunction(monitor);\n\t\t}\n\t}\n\n\t// Fetch pub once, send to all clients linked to this pub\n\tprivate async sendDataToAll(sub: ActiveSubscriptionModel, collection: string, type: string) {\n\t\tif (!sub.clients.length) {\n\t\t\tif (sub.cacheId) {\n\t\t\t\tthis._nodeCache.del(sub.cacheId);\n\t\t\t\tsub.cacheId = 0;\n\t\t\t}\n\n\t\t\tlet subIndex = this._subscriptions.findIndex(a => a.publication === sub.publication && JSON.stringify(a.subscriptionData) === JSON.stringify(sub.subscriptionData));\n\t\t\tif (subIndex >= 0) {\n\t\t\t\tthis._subscriptions.splice(subIndex, 1);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\t\telse {\n\t\t\tlet monitor = this._monitorManagerFunction.startMonitorFunction('Publication', sub.publication, '', '', sub.subscriptionData);\n\n\t\t\ttry {\n\t\t\t\tif (sub.publication !== 'superadminAPM' && sub.publication !== 'loggedInUsers') {\n\t\t\t\t\tResolveIOServer.getMainServer().getMethodManager().callMethod.call(ResolveIOServer.getMainServer().getMethodManager(), 'insertSubscriptionLog', type, sub.publication, collection, JSON.stringify(sub.subscriptionData));\n\t\t\t\t}\n\n\t\t\t\tlet res = await this._publications[sub.publication].function.call(Object.assign({}, this, SubscriptionManager.prototype), ...sub.subscriptionData);\n\n\t\t\t\tif (sub.cacheId) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlet cacheData = JSON.parse(this._nodeCache.get(sub.cacheId), dateReviver);\n\t\n\t\t\t\t\t\tif (JSON.stringify(cacheData) !== JSON.stringify(res)) {\n\t\t\t\t\t\t\tfor (let client of sub.clients) {\n\t\t\t\t\t\t\t\tlet ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\t\t\t\tmessageId: client.messageId,\n\t\t\t\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\t\t\t\tdata: res\n\t\t\t\t\t\t\t\t\t};\n\t\t\n\t\t\t\t\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._nodeCache.del(sub.cacheId);\n\n\t\t\t\t\t\t\tif (getBinarySize(JSON.stringify(res)) < 1000000 && \n\t\t\t\t\t\t\t\t!sub.collections.includes('logs') &&\n\t\t\t\t\t\t\t\t!sub.collections.find(a => a.endsWith('.versions')) &&\n\t\t\t\t\t\t\t\t!sub.collections.find(a => a.startsWith('monitor-'))\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis._nodeCache.set(sub.cacheId, JSON.stringify(res));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tsub.cacheId = 0;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\tsub.clients.map(client => {\n\t\t\t\t\t\t\tlet ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\t\t\tmessageId: client.messageId,\n\t\t\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\t\t\tdata: res\n\t\t\t\t\t\t\t\t};\n\t\n\t\t\t\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tthis._nodeCache.del(sub.cacheId);\n\n\t\t\t\t\t\tif (getBinarySize(JSON.stringify(res)) < 1000000 && \n\t\t\t\t\t\t\t!sub.collections.includes('logs') &&\n\t\t\t\t\t\t\t!sub.collections.find(a => a.endsWith('.versions')) &&\n\t\t\t\t\t\t\t!sub.collections.find(a => a.startsWith('monitor-'))\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis._nodeCache.set(sub.cacheId, JSON.stringify(res));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tsub.cacheId = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfor (let client of sub.clients) {\n\t\t\t\t\t\tlet ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\t\tmessageId: client.messageId,\n\t\t\t\t\t\t\t\thasError: false,\n\t\t\t\t\t\t\t\tdata: res\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tif (getBinarySize(JSON.stringify(res)) < 1000000 && \n\t\t\t\t\t\t!sub.collections.includes('logs') &&\n\t\t\t\t\t\t!sub.collections.find(a => a.endsWith('.versions')) &&\n\t\t\t\t\t\t!sub.collections.find(a => a.startsWith('monitor-'))\n\t\t\t\t\t) {\n\t\t\t\t\t\tsub.cacheId = this._cacheId++;\n\t\t\t\t\t\tthis._nodeCache.set(sub.cacheId, JSON.stringify(res));\n\n\t\t\t\t\t\tconst nodeCacheSize = this._nodeCache.getStats().vsize;\n\n\t\t\t\t\t\tif (nodeCacheSize > this._heapLimit) {\n\t\t\t\t\t\t\t// Evict cache entries as needed\n\t\t\t\t\t\t\tlet deleteCount = 0;\n\t\t\t\t\t\t\tconst subArr = this._subscriptions.filter(a => a.cacheId && !a.clients.length);\n\t\t\t\t\t\n\t\t\t\t\t\t\tfor (let zz = 0; zz < subArr.length; zz++) {\n\t\t\t\t\t\t\t\tthis._debugRemoveCacheHits += 1;\n\t\t\t\t\t\t\t\tthis._nodeCache.del(subArr[zz].cacheId);\n\t\t\t\t\t\t\t\tsubArr[zz].cacheId = 0;\n\t\t\t\t\t\t\t\tdeleteCount += 1;\n\t\t\t\t\t\t\t\tif (this._nodeCache.getStats().vsize < this._heapLimit * 0.75) {\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (this._enableDebug) {\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\t'Sub Cache: ' +\n\t\t\t\t\t\t\t\t\t'Too Big - ' +\n\t\t\t\t\t\t\t\t\tsub.publication +\n\t\t\t\t\t\t\t\t\t' - Deleted: ' +\n\t\t\t\t\t\t\t\t\tdeleteCount +\n\t\t\t\t\t\t\t\t\t' - ' +\n\t\t\t\t\t\t\t\t\tnodeCacheSize\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tsub.cacheId = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\tfor (let client of sub.clients) {\n\t\t\t\t\tlet ws = this._websocketManager.getWebSocket(client.id_socket);\n\t\t\t\t\tif (ws && ws.readyState === ws.OPEN) {\n\t\t\t\t\t\tlet serverRes: ServerResponseModel = {\n\t\t\t\t\t\t\tmessageId: client.messageId,\n\t\t\t\t\t\t\thasError: true,\n\t\t\t\t\t\t\tdata: err\n\t\t\t\t\t\t};\n\t\t\t\t\t\t\n\t\t\t\t\t\tthis.sendWS(ws, serverRes);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tawait ResolveIOServer.getMainServer().getMethodManager().sendEmail('dev@resolveio.com', 'SERVER - Error Detected - ' + this.serverConfig['CLIENT_NAME'], 'Error Detected During Subscription ' + sub.publication + ' - (sendPubData)\\n\\nData \\n' + JSON.stringify(sub.subscriptionData, null, 2) + '\\n\\nErrors\\n' + JSON.stringify(err, null, 2));\n\t\t\t}\n\t\t\tfinally {\n\t\t\t\tawait this._monitorManagerFunction.finishMonitorFunction(monitor);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate sendWS(ws: WebSocket, data: ServerResponseModel) {\n\t\tthis._websocketManager.send(ws, data);\n\t}\n\n\tpublic getEnableDebug() {\n\t\treturn this._enableDebug;\n\t}\n}\n"]}
|
|
@@ -11,7 +11,9 @@ export declare class WebSocketManager {
|
|
|
11
11
|
private _maxMessageSize;
|
|
12
12
|
private _messageDelay;
|
|
13
13
|
private _webSockets;
|
|
14
|
-
constructor(
|
|
14
|
+
constructor();
|
|
15
|
+
static create(mainServer: any, maxMessageSize?: number, messageDelay?: number): WebSocketManager;
|
|
16
|
+
initialize(mainServer: any, maxMessageSize?: number, messageDelay?: number): void;
|
|
15
17
|
addWebSocket(ws: WebSocket): void;
|
|
16
18
|
removeWebSocket(ws: WebSocket): void;
|
|
17
19
|
getWebSocket(id_socket: string): WebSocket | undefined;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var __values=this&&this.__values||function(e){var t="function"==typeof Symbol&&Symbol.iterator,s=t&&e[t],n=0;if(s)return s.call(e);if(e&&"number"==typeof e.length)return{next:function(){return{value:(e=e&&n>=e.length?void 0:e)&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")},WebSocketManager=(Object.defineProperty(exports,"__esModule",{value:!0}),exports.WebSocketManager=void 0,function(){function WebSocketManager(e,t,s){void 0===t&&(t=20480),void 0===s&&(s=25)
|
|
1
|
+
"use strict";var __values=this&&this.__values||function(e){var t="function"==typeof Symbol&&Symbol.iterator,s=t&&e[t],n=0;if(s)return s.call(e);if(e&&"number"==typeof e.length)return{next:function(){return{value:(e=e&&n>=e.length?void 0:e)&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")},WebSocketManager=(Object.defineProperty(exports,"__esModule",{value:!0}),exports.WebSocketManager=void 0,function(){function WebSocketManager(){this._messageBuffers=new Map,this._batchingTimers=new Map,this._webSockets=new Map}return WebSocketManager.create=function(e,t,s){void 0===t&&(t=20480),void 0===s&&(s=25);var n=new WebSocketManager;return n.initialize(e,t,s),n},WebSocketManager.prototype.initialize=function(e,t,s){void 0===t&&(t=20480),void 0===s&&(s=25),this._mainServer=e,this._maxMessageSize=t,this._messageDelay=s},WebSocketManager.prototype.addWebSocket=function(e){var t=e.id_socket;this._webSockets.set(t,e)},WebSocketManager.prototype.removeWebSocket=function(e){var t=e.id_socket;this._webSockets.delete(t),this.closeConnection(e)},WebSocketManager.prototype.getWebSocket=function(e){return this._webSockets.get(e)},WebSocketManager.prototype.send=function(e,t){var s=this,n=e.id_socket;this._messageBuffers.has(n)||this._messageBuffers.set(n,[]),"string"==typeof t?this._messageBuffers.get(n).push({messageId:null,hasError:!1,data:t}):this._messageBuffers.get(n).push(t),this._batchingTimers.has(n)||(t=setTimeout(function(){s.flushMessages(e)},this._messageDelay),this._batchingTimers.set(n,t))},WebSocketManager.prototype.flushMessages=function(t){var e,s=this,n=t.id_socket,r=this._messageBuffers.get(n);r&&0<r.length&&(e=JSON.stringify(r),Buffer.byteLength(e,"utf8")>this._maxMessageSize?this.sendMessagesInChunks(t,r):t.send(e,function(e){e&&s.handleSendError(t,e)}),this._messageBuffers.delete(n),clearTimeout(this._batchingTimers.get(n)),this._batchingTimers.delete(n))},WebSocketManager.prototype.sendMessagesInChunks=function(t,e){var s,n,r=this,i=[],a=0;try{for(var o=__values(e),c=o.next();!c.done;c=o.next()){var g=c.value,h=JSON.stringify([g]),u=Buffer.byteLength(h,"utf8");a+u>this._maxMessageSize?(t.send(JSON.stringify(i),function(e){e&&r.handleSendError(t,e)}),i=[g],a=u):(i.push(g),a+=u)}}catch(e){s={error:e}}finally{try{c&&!c.done&&(n=o.return)&&n.call(o)}finally{if(s)throw s.error}}0<i.length&&t.send(JSON.stringify(i),function(e){e&&r.handleSendError(t,e)})},WebSocketManager.prototype.handleSendError=function(e,t){this._mainServer.getSubscriptionManager()&&(this._mainServer.getSubscriptionManager().getEnableDebug()&&console.log(new Date,"WebSocketManager","Unsub WS",e.user,e.id_socket,t),this._mainServer.getSubscriptionManager().unsubscribeAll(e),this.removeWebSocket(e))},WebSocketManager.prototype.closeConnection=function(e){e.close();var t=e.id_socket;this._messageBuffers.delete(t),this._batchingTimers.has(t)&&(clearTimeout(this._batchingTimers.get(t)),this._batchingTimers.delete(t)),process.nextTick(function(){[e.OPEN,e.CLOSING].includes(e.readyState)&&e.terminate()})},WebSocketManager}());exports.WebSocketManager=WebSocketManager;
|
|
2
2
|
//# sourceMappingURL=websocket.manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/managers/websocket.manager.ts"],"names":["WebSocketManager","
|
|
1
|
+
{"version":3,"sources":["../../src/managers/websocket.manager.ts"],"names":["WebSocketManager","this","_messageBuffers","Map","_batchingTimers","_webSockets","create","mainServer","maxMessageSize","messageDelay","websocketManager","initialize","prototype","_mainServer","_maxMessageSize","_messageDelay","addWebSocket","ws","wsId","set","removeWebSocket","delete","closeConnection","getWebSocket","id_socket","get","send","data","_this","has","push","messageId","hasError","timer","setTimeout","flushMessages","combinedData","messages","length","JSON","stringify","Buffer","byteLength","sendMessagesInChunks","error","handleSendError","clearTimeout","chunk","chunkSize","messages_1","__values","messages_1_1","next","done","message","value","messageData","messageSize","getSubscriptionManager","getEnableDebug","console","log","Date","unsubscribeAll","close","process","nextTick","OPEN","CLOSING","includes","readyState","terminate","exports"],"mappings":"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","file":"websocket.manager.js","sourcesContent":["import { WebSocket } from 'ws';\n\ninterface ServerResponseModel {\n\tmessageId: number;\n\thasError: boolean;\n\tdata: any;\n}\n\nexport class WebSocketManager {\n\tprivate _mainServer;\n\tprivate _messageBuffers: Map<string, ServerResponseModel[]> = new Map();\n\tprivate _batchingTimers: Map<string, NodeJS.Timeout> = new Map();\n\tprivate _maxMessageSize: number;\n\tprivate _messageDelay: number;\n\tprivate _webSockets: Map<string, WebSocket> = new Map();\n\n\tconstructor() {}\n\t\n\tstatic create(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25) {\n\t\tconst websocketManager = new WebSocketManager();\n\t\twebsocketManager.initialize(mainServer, maxMessageSize, messageDelay);\n\t\treturn websocketManager;\n\t}\n\n\tpublic initialize(mainServer, maxMessageSize: number = 20480, messageDelay: number = 25) {\n\t\tthis._mainServer = mainServer;\n\t\tthis._maxMessageSize = maxMessageSize;\n\t\tthis._messageDelay = messageDelay;\n\t}\n\n\tpublic addWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.set(wsId, ws);\n\t}\n\n\tpublic removeWebSocket(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tthis._webSockets.delete(wsId);\n\t\tthis.closeConnection(ws);\n\t}\n\n\tpublic getWebSocket(id_socket: string): WebSocket | undefined {\n\t\treturn this._webSockets.get(id_socket);\n\t}\n\n\tpublic send(ws: WebSocket, data: ServerResponseModel | string): void {\n\t\tconst wsId = ws['id_socket'];\n\n\t\tif (!this._messageBuffers.has(wsId)) {\n\t\t\tthis._messageBuffers.set(wsId, []);\n\t\t}\n\n\t\tif (typeof data === 'string') {\n\t\t\t// Handle string messages like 'ping' or 'pong'\n\t\t\tthis._messageBuffers.get(wsId).push({ messageId: null, hasError: false, data: data });\n\t\t}\n\t\telse {\n\t\t\tthis._messageBuffers.get(wsId).push(data);\n\t\t}\n\n\t\tif (!this._batchingTimers.has(wsId)) {\n\t\t\t// Set a timer to send the batch after a short delay\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.flushMessages(ws);\n\t\t\t}, this._messageDelay);\n\t\t\tthis._batchingTimers.set(wsId, timer);\n\t\t}\n\t}\n\n\tprivate flushMessages(ws: WebSocket): void {\n\t\tconst wsId = ws['id_socket'];\n\t\tconst messages = this._messageBuffers.get(wsId);\n\n\t\tif (messages && messages.length > 0) {\n\t\t\t// Combine messages into one payload\n\t\t\tconst combinedData = JSON.stringify(messages);\n\t\t\tconst dataSize = Buffer.byteLength(combinedData, 'utf8');\n\n\t\t\tif (dataSize > this._maxMessageSize) {\n\t\t\t\t// Split messages to ensure each does not exceed max size\n\t\t\t\tthis.sendMessagesInChunks(ws, messages);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tws.send(combinedData, (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Clear the buffer and timer\n\t\t\tthis._messageBuffers.delete(wsId);\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n\t}\n\n\tprivate sendMessagesInChunks(ws: WebSocket, messages: ServerResponseModel[]): void {\n\t\tlet chunk: ServerResponseModel[] = [];\n\t\tlet chunkSize = 0;\n\n\t\tfor (const message of messages) {\n\t\t\tconst messageData = JSON.stringify([message]); // Wrap message in array for consistency\n\t\t\tconst messageSize = Buffer.byteLength(messageData, 'utf8');\n\n\t\t\tif (chunkSize + messageSize > this._maxMessageSize) {\n\t\t\t\t// Send current chunk\n\t\t\t\tws.send(JSON.stringify(chunk), (error) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// Start new chunk\n\t\t\t\tchunk = [message];\n\t\t\t\tchunkSize = messageSize;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tchunk.push(message);\n\t\t\t\tchunkSize += messageSize;\n\t\t\t}\n\t\t}\n\n\t\t// Send any remaining messages\n\t\tif (chunk.length > 0) {\n\t\t\tws.send(JSON.stringify(chunk), (error) => {\n\t\t\t\tif (error) {\n\t\t\t\t\tthis.handleSendError(ws, error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate handleSendError(ws: WebSocket, error: Error): void {\n\t\tif (this._mainServer.getSubscriptionManager()) {\n\t\t\t// Handle send error, e.g., unsubscribe, close connection\n\t\t\tif (this._mainServer.getSubscriptionManager().getEnableDebug()) {\n\t\t\t\tconsole.log(new Date(), 'WebSocketManager', 'Unsub WS', ws['user'], ws['id_socket'], error);\n\t\t\t}\n\t\t\tthis._mainServer.getSubscriptionManager().unsubscribeAll(ws);\n\t\t\tthis.removeWebSocket(ws);\n\t\t}\n\t}\n\n\tpublic closeConnection(ws: WebSocket): void {\n\t\tws.close();\n\t\tconst wsId = ws['id_socket'];\n\t\t// Clean up buffers and timers\n\t\tthis._messageBuffers.delete(wsId);\n\t\tif (this._batchingTimers.has(wsId)) {\n\t\t\tclearTimeout(this._batchingTimers.get(wsId));\n\t\t\tthis._batchingTimers.delete(wsId);\n\t\t}\n \n process.nextTick(() => {\n if ([ws.OPEN, ws.CLOSING].includes(<any>ws.readyState)) {\n // Socket still hangs, hard close\n ws.terminate();\n }\n });\n\t}\n}"]}
|
package/methods/accounts.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var __awaiter=this&&this.__awaiter||function(e,
|
|
1
|
+
"use strict";var __awaiter=this&&this.__awaiter||function(e,n,s,o){return new(s=s||Promise)(function(t,r){function fulfilled(e){try{step(o.next(e))}catch(e){r(e)}}function rejected(e){try{step(o.throw(e))}catch(e){r(e)}}function step(e){var r;e.done?t(e.value):((r=e.value)instanceof s?r:new s(function(e){e(r)})).then(fulfilled,rejected)}step((o=o.apply(e,n||[])).next())})},__generator=this&&this.__generator||function(n,s){var o,i,a,l={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]},c={next:verb(0),throw:verb(1),return:verb(2)};return"function"==typeof Symbol&&(c[Symbol.iterator]=function(){return this}),c;function verb(t){return function(e){var r=[t,e];if(o)throw new TypeError("Generator is already executing.");for(;l=c&&r[c=0]?0:l;)try{if(o=1,i&&(a=2&r[0]?i.return:r[0]?i.throw||((a=i.return)&&a.call(i),0):i.next)&&!(a=a.call(i,r[1])).done)return a;switch(i=0,(r=a?[2&r[0],a.value]:r)[0]){case 0:case 1:a=r;break;case 4:return l.label++,{value:r[1],done:!1};case 5:l.label++,i=r[1],r=[0];continue;case 7:r=l.ops.pop(),l.trys.pop();continue;default:if(!(a=0<(a=l.trys).length&&a[a.length-1])&&(6===r[0]||2===r[0])){l=0;continue}if(3===r[0]&&(!a||r[1]>a[0]&&r[1]<a[3]))l.label=r[1];else if(6===r[0]&&l.label<a[1])l.label=a[1],a=r;else{if(!(a&&l.label<a[2])){a[2]&&l.ops.pop(),l.trys.pop();continue}l.label=a[2],l.ops.push(r)}}r=s.call(n,l)}catch(e){r=[6,e],i=0}finally{o=a=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}}},handlebars=(Object.defineProperty(exports,"__esModule",{value:!0}),exports.loadAccountMethods=void 0,require("handlebars")),jwt=require("jsonwebtoken"),simpl_schema_1=require("simpl-schema"),user_collection_1=require("../collections/user.collection"),resolveio_server_app_1=require("../resolveio-server-app"),common_1=require("../util/common");function loadAccountMethods(e){e.methods({incorrectUser:{check:new simpl_schema_1.default({old_user:{type:Object,blackbox:!0},new_user:{type:Object,blackbox:!0},client_subs:{type:Array},"client_subs.$":{type:Object,blackbox:!0}}),function:function(t,n,s){return __awaiter(this,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return resolveio_server_app_1.ResolveIOServer.getMainServer()?(r=resolveio_server_app_1.ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(this.id_ws),[4,this.sendEmail("dev@resolveio.com","SERVER - WRONG USER Detected - "+this.serverConfig.CLIENT_NAME,"Wrong User Sent!\nWS: "+JSON.stringify(r,null,2)+"\nUserMethod: "+this.user+"\nIdUserMethod: "+this.id_user+"\nSubManagerActiveSubs: "+JSON.stringify(resolveio_server_app_1.ResolveIOServer.getMainServer().getSubscriptionManager().getActiveSubscriptions(),null,2)+"\nOldUser: "+JSON.stringify(t,null,2)+"\nNewUser: "+JSON.stringify(n,null,2)+"\nClientSubs: "+JSON.stringify(s,null,2))]):[3,2];case 1:e.sent(),e.label=2;case 2:return[2,Promise.resolve(null)]}})})}},reloadWS:{check:new simpl_schema_1.default({id_ws:String}),function:function(t){return __awaiter(this,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return(r=resolveio_server_app_1.ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(t))?[4,resolveio_server_app_1.ResolveIOServer.getMainServer().unsubscribeWS(r)]:[3,2];case 1:return e.sent(),[2,!0];case 2:throw new Error("Error in Reload WS: No WS")}})})}},reconnectWS:{check:new simpl_schema_1.default({id_ws:String}),function:function(t){return __awaiter(this,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return(r=resolveio_server_app_1.ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(t))?[4,resolveio_server_app_1.ResolveIOServer.getMainServer().unsubscribeWS(r)]:[3,2];case 1:return e.sent(),[2,!0];case 2:throw new Error("Error in Reconnect WS: No WS")}})})}},disconnectWS:{check:new simpl_schema_1.default({id_ws:String}),function:function(t){return __awaiter(this,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return(r=resolveio_server_app_1.ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(t))?[4,resolveio_server_app_1.ResolveIOServer.getMainServer().unsubscribeWS(r)]:[3,2];case 1:return e.sent(),[2,!0];case 2:throw new Error("Error in Disconnect WS: No WS")}})})}},createUserAndEmailEnrollment:{check:new simpl_schema_1.default({newUser:{type:user_collection_1.Users.simplschema},sendEnrollmentEmail:{type:Boolean,optional:!0}}),function:function(n,s){return void 0===s&&(s=!0),__awaiter(this,void 0,void 0,function(){var r,t;return __generator(this,function(e){switch(e.label){case 0:if("admin"!==n.username.toLocaleLowerCase())return[3,1];throw new Error("Error in Create User And Email Enrollment: Username can not be admin");case 1:return[4,user_collection_1.Users.findOne({$or:[{username:n.username.toLocaleLowerCase()},{email:n.email.toLocaleLowerCase()}]})];case 2:if(e.sent())throw new Error("Error in Create User And Email Enrollment: Username/Email is already used");e.label=3;case 3:return n._id=(0,common_1.objectIdHexString)(),n.services={enrollment:jwt.sign({id_user:n._id},this.serverConfig.JWT_SECRET,{expiresIn:2592e5})},n.is_customer=!1,[4,user_collection_1.Users.insertOne(n)];case 4:if(e.sent(),!s)return[3,9];r={fullname:n.fullname,user:this.user,url:this.serverConfig.ROOT_URL+"/enroll-account?"+encodeURIComponent(this.serverConfig.SERVER_URL)+"&"+n.services.enrollment},e.label=5;case 5:return e.trys.push([5,7,,8]),t=this.readFile("email-templates/enrollment.html"),t=handlebars.compile(t),handlebars.registerHelper("equals",function(e,r){return e===r}),[4,this.sendEmail(n.email,"ResolveIO ("+resolveio_server_app_1.ResolveIOServer.getClientName()+") - Enrollment Email","",t(r),null,null,"")];case 6:return e.sent(),[2,n];case 7:throw(t=e.sent()).message="Error in Create User And Email Enrollment: email-templates/enrollment.html - ".concat(t.message),t;case 8:return[3,10];case 9:return[2,n];case 10:return[2]}})})}},resetUserPassword:{check:new simpl_schema_1.default({userId:{type:String}}),function:function(s){return __awaiter(this,void 0,void 0,function(){var r,t,n;return __generator(this,function(e){switch(e.label){case 0:return[4,user_collection_1.Users.findOne({_id:s})];case 1:if(!(r=e.sent()))return[3,6];r.services||(r.services={}),r.services.forgot_password=jwt.sign({id_user:s},this.serverConfig.JWT_SECRET),t={userToChangePassword:r.fullname,userWhoResetPassword:this.user,url:this.serverConfig.ROOT_URL+"/forgot-password?"+encodeURIComponent(this.serverConfig.SERVER_URL)+"&"+r.services.forgot_password},e.label=2;case 2:return e.trys.push([2,5,,6]),[4,user_collection_1.Users.updateOne({_id:r._id},{$set:{services:r.services,attempts:0}})];case 3:return e.sent(),n=this.readFile("email-templates/forgot-password.html"),n=handlebars.compile(n),handlebars.registerHelper("equals",function(e,r){return e===r}),[4,this.sendEmail(r.email,"ResolveIO ("+resolveio_server_app_1.ResolveIOServer.getClientName()+") - Forgot Password","",n(t),null,null,"")];case 4:return e.sent(),[2,!0];case 5:throw(n=e.sent()).message="Error in Reset User Password: email-templates/forgot-password.html - ".concat(n.message),n;case 6:throw new Error("Error in Reset User Password: Invalid User")}})})}},setUserPassword:{check:new simpl_schema_1.default({userId:{type:String},password:{type:String}}),function:function(t,n){return __awaiter(this,void 0,void 0,function(){var r;return __generator(this,function(e){switch(e.label){case 0:return[4,user_collection_1.Users.findOne({_id:t})];case 1:return!(r=e.sent())||r.roles.super_admin?[3,3]:[4,user_collection_1.Users.setPassword(r,n)];case 2:return e.sent(),[2,!0];case 3:throw new Error("Error in Set User Password: Invalid User")}})})}}})}exports.loadAccountMethods=loadAccountMethods;
|
|
2
2
|
//# sourceMappingURL=accounts.js.map
|
package/methods/accounts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/methods/accounts.ts"],"names":["simpl_schema_1","require","user_collection_1","handlebars","jwt","resolveio_server_app_1","common_1","loadAccountMethods","methodManager","methods","incorrectUser","check","default","old_user","type","Object","blackbox","new_user","client_subs","Array","client_subs.$","function","_this","this","Promise","resolve","reject","__awaiter","ResolveIOServer","getMainServer","ws","getWebSocketManager","getWebSocket","id_ws","sendEmail","serverConfig","JSON","stringify","user","id_user","getSubscriptionManager","getActiveSubscriptions","reloadWS","String","unsubscribeWS","reconnectWS","disconnectWS","createUserAndEmailEnrollment","newUser","Users","sendEnrollmentEmail","Boolean","optional","username","toLocaleLowerCase","findOne","$or","email","_a","sent","_id","objectIdHexString","services","enrollment","sign","expiresIn","is_customer","insertOne","emailData_1","fullname","url","encodeURIComponent","readFile","then","html","template","compile","registerHelper","a","b","getClientName","errEmail","resetUserPassword","userId","emailData_2","userToChangePassword","userWhoResetPassword","updateOne","$set","attempts","setUserPassword","password","roles","super_admin","setPassword","exports"],"mappings":"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","file":"accounts.js","sourcesContent":["import SimpleSchema from 'simpl-schema';\nimport { Users } from '../collections/user.collection';\nimport * as handlebars from 'handlebars';\nimport * as jwt from 'jsonwebtoken';\nimport { MethodManager } from '../managers/method.manager';\nimport { ResolveIOServer } from '../resolveio-server-app';\nimport { UserModel } from '../models/user.model';\nimport { objectIdHexString } from '../util/common';\n\nexport function loadAccountMethods(methodManager: MethodManager) {\n\tmethodManager.methods({\n\t\tincorrectUser: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\told_user: {\n\t\t\t\t\ttype: Object,\n\t\t\t\t\tblackbox: true\n\t\t\t\t},\n\t\t\t\tnew_user: {\n\t\t\t\t\ttype: Object,\n\t\t\t\t\tblackbox: true\n\t\t\t\t},\n\t\t\t\tclient_subs: {\n\t\t\t\t\ttype: Array\n\t\t\t\t},\n\t\t\t\t'client_subs.$': {\n\t\t\t\t\ttype: Object,\n\t\t\t\t\tblackbox: true\n\t\t\t\t}\n\t\t\t}),\n\t\t\tfunction: function(old_user, new_user, client_subs) {\n\t\t\t\treturn new Promise(async (resolve, reject) => {\n\t\t\t\t\tif (ResolveIOServer.getMainServer()) {\n\t\t\t\t\t\tlet ws = ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(this.id_ws);\n\n\t\t\t\t\t\tthis.sendEmail('dev@resolveio.com', 'SERVER - WRONG USER Detected - ' + this.serverConfig['CLIENT_NAME'], 'Wrong User Sent!\\nWS: ' + JSON.stringify(ws, null, 2) + '\\nUserMethod: ' + this.user + '\\nIdUserMethod: ' + this.id_user + '\\nSubManagerActiveSubs: ' + JSON.stringify(ResolveIOServer.getMainServer().getSubscriptionManager().getActiveSubscriptions(), null, 2) + '\\nOldUser: ' + JSON.stringify(old_user, null, 2) + '\\nNewUser: ' + JSON.stringify(new_user, null, 2) + '\\nClientSubs: ' + JSON.stringify(client_subs, null, 2));\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve(true);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\treloadWS: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tid_ws: String\n\t\t\t}),\n\t\t\tfunction: function(id_ws) {\n\t\t\t\treturn new Promise(async (resolve, reject) => {\n\t\t\t\t\tlet ws = ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(id_ws);\n\n\t\t\t\t\tif (ws) {\n\t\t\t\t\t\tResolveIOServer.getMainServer().unsubscribeWS(ws);\n\t\t\t\t\t\tresolve(true);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\treject('No WS');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\treconnectWS: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tid_ws: String\n\t\t\t}),\n\t\t\tfunction: function(id_ws) {\n\t\t\t\treturn new Promise(async (resolve, reject) => {\n\t\t\t\t\tlet ws = ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(id_ws);\n\n\t\t\t\t\tif (ws) {\n\t\t\t\t\t\tResolveIOServer.getMainServer().unsubscribeWS(ws);\n\t\t\t\t\t\tresolve(true);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\treject('No WS');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tdisconnectWS: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tid_ws: String\n\t\t\t}),\n\t\t\tfunction: function(id_ws) {\n\t\t\t\treturn new Promise(async (resolve, reject) => {\n\t\t\t\t\tlet ws = ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(id_ws);\n\n\t\t\t\t\tif (ws) {\n\t\t\t\t\t\tResolveIOServer.getMainServer().unsubscribeWS(ws);\n\t\t\t\t\t\tresolve(true);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\treject('No WS');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tcreateUserAndEmailEnrollment: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tnewUser: {\n\t\t\t\t\ttype: Users['simplschema']\n\t\t\t\t},\n\t\t\t\tsendEnrollmentEmail: {\n\t\t\t\t\ttype: Boolean,\n\t\t\t\t\toptional: true\n\t\t\t\t}\n\t\t\t}),\n\t\t\tfunction: function(newUser: UserModel, sendEnrollmentEmail = true) {\n\t\t\t\treturn new Promise(async (resolve, reject) => {\n\t\t\t\t\tif (newUser.username.toLocaleLowerCase() === 'admin') {\n\t\t\t\t\t\treject('Username can not be admin');\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tlet otherUser = await Users.findOne({\n\t\t\t\t\t\t\t$or: [\n\t\t\t\t\t\t\t\t{username: newUser.username.toLocaleLowerCase()},\n\t\t\t\t\t\t\t\t{email: newUser.email.toLocaleLowerCase()}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (otherUser) {\n\t\t\t\t\t\t\treject('Username/Email is already used');\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tnewUser._id = objectIdHexString();\n\n\t\t\t\t\tnewUser.services = {\n\t\t\t\t\t\tenrollment: jwt.sign({id_user: newUser._id}, this.serverConfig['JWT_SECRET'], {\n\t\t\t\t\t\t\texpiresIn : 3 * 24 * 60 * 60 * 1000 // 3 days\n\t\t\t\t\t\t})\n\t\t\t\t\t};\n\n\t\t\t\t\tnewUser.is_customer = false;\n\t\t\t\t\t\n\t\t\t\t\tawait Users.insertOne(newUser);\n\n\t\t\t\t\tif (sendEnrollmentEmail) {\n\t\t\t\t\t\tlet emailData = {\n\t\t\t\t\t\t\tfullname: newUser.fullname,\n\t\t\t\t\t\t\tuser: this.user,\n\t\t\t\t\t\t\turl: (this.serverConfig['ROOT_URL'] + '/enroll-account?' + encodeURIComponent(this.serverConfig['SERVER_URL']) + '&' + newUser.services['enrollment'])\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tthis.readFile('email-templates/enrollment.html').then(html => {\n\t\t\t\t\t\t\tlet template = handlebars.compile(html);\n\t\t\t\t\t\t\thandlebars.registerHelper('equals', (a, b) => {\n\t\t\t\t\t\t\t\treturn a === b;\n\t\t\t\t\t\t\t});\n\t\t\n\t\t\t\t\t\t\tthis.sendEmail(newUser.email, 'ResolveIO (' + ResolveIOServer.getClientName() + ') - Enrollment Email', '', template(emailData), null, null, '');\n\t\t\n\t\t\t\t\t\t\tresolve(newUser);\n\t\t\t\t\t\t}, errEmail => reject(errEmail));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tresetUserPassword: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tuserId: {\n\t\t\t\t\ttype: String\n\t\t\t\t}\n\t\t\t}),\n\t\t\tfunction: function(userId: string) {\n\t\t\t\treturn new Promise(async (resolve, reject) => {\t\t\t\t\n\t\t\t\t\tlet user = await Users.findOne({_id: userId});\n\t\t\n\t\t\t\t\tif (user) {\n\t\t\t\t\t\tif (!user.services) {\n\t\t\t\t\t\t\tuser.services = {};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tuser.services['forgot_password'] = jwt.sign({id_user: userId}, this.serverConfig['JWT_SECRET']);\n\n\t\t\t\t\t\tlet emailData = {\n\t\t\t\t\t\t\tuserToChangePassword: user.fullname,\n\t\t\t\t\t\t\tuserWhoResetPassword: this.user,\n\t\t\t\t\t\t\turl: (this.serverConfig['ROOT_URL'] + '/forgot-password?' + encodeURIComponent(this.serverConfig['SERVER_URL']) + '&' + user.services['forgot_password'])\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tUsers.updateOne({_id: user._id}, {$set: {services: user.services, attempts: 0}}).then(() => {\n\t\t\t\t\t\t\tthis.readFile('email-templates/forgot-password.html').then(html => {\n\t\t\t\t\t\t\t\tlet template = handlebars.compile(html);\n\t\t\t\t\t\t\t\thandlebars.registerHelper('equals', (a, b) => {\n\t\t\t\t\t\t\t\t\treturn a === b;\n\t\t\t\t\t\t\t\t});\n\t\t\t\n\t\t\t\t\t\t\t\tthis.sendEmail(user.email, 'ResolveIO (' + ResolveIOServer.getClientName() + ') - Forgot Password', '', template(emailData), null, null, '');\n\t\t\t\n\t\t\t\t\t\t\t\tresolve(true);\n\t\t\t\t\t\t\t}, errEmail => reject(errEmail));\n\t\t\t\t\t\t}, () => {});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tsetUserPassword: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tuserId: {\n\t\t\t\t\ttype: String\n\t\t\t\t},\n\t\t\t\tpassword: {\n\t\t\t\t\ttype: String\n\t\t\t\t}\n\t\t\t}),\n\t\t\tfunction: function(userId: string, password: string) {\n\t\t\t\treturn new Promise(async (resolve, reject) => {\t\t\t\t\n\t\t\t\t\tlet user = await Users.findOne({_id: userId});\n\t\t\n\t\t\t\t\tif (user && !user.roles.super_admin) {\n\t\t\t\t\t\tawait Users.setPassword(user, password);\n\n\t\t\t\t\t\tresolve(true);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\treject('Invalid User');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/methods/accounts.ts"],"names":["handlebars","require","jwt","simpl_schema_1","user_collection_1","resolveio_server_app_1","common_1","loadAccountMethods","methodManager","methods","incorrectUser","check","default","old_user","type","Object","blackbox","new_user","client_subs","Array","client_subs.$","function","ResolveIOServer","getMainServer","ws","getWebSocketManager","getWebSocket","this","id_ws","sendEmail","serverConfig","JSON","stringify","user","id_user","getSubscriptionManager","getActiveSubscriptions","_a","sent","Promise","resolve","reloadWS","String","unsubscribeWS","Error","reconnectWS","disconnectWS","createUserAndEmailEnrollment","newUser","Users","sendEnrollmentEmail","Boolean","optional","username","toLocaleLowerCase","findOne","$or","email","_id","objectIdHexString","services","enrollment","sign","expiresIn","is_customer","insertOne","emailData","fullname","url","encodeURIComponent","html","readFile","template","compile","registerHelper","a","b","getClientName","message","concat","err_1","resetUserPassword","userId","userToChangePassword","userWhoResetPassword","updateOne","$set","attempts","err_2","setUserPassword","password","roles","super_admin","setPassword","exports"],"mappings":"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","file":"accounts.js","sourcesContent":["import * as handlebars from 'handlebars';\nimport * as jwt from 'jsonwebtoken';\nimport SimpleSchema from 'simpl-schema';\nimport { Users } from '../collections/user.collection';\nimport { MethodManager } from '../managers/method.manager';\nimport { UserModel } from '../models/user.model';\nimport { ResolveIOServer } from '../resolveio-server-app';\nimport { objectIdHexString } from '../util/common';\n\nexport function loadAccountMethods(methodManager: MethodManager) {\n\tmethodManager.methods({\n\t\tincorrectUser: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\told_user: {\n\t\t\t\t\ttype: Object,\n\t\t\t\t\tblackbox: true\n\t\t\t\t},\n\t\t\t\tnew_user: {\n\t\t\t\t\ttype: Object,\n\t\t\t\t\tblackbox: true\n\t\t\t\t},\n\t\t\t\tclient_subs: {\n\t\t\t\t\ttype: Array\n\t\t\t\t},\n\t\t\t\t'client_subs.$': {\n\t\t\t\t\ttype: Object,\n\t\t\t\t\tblackbox: true\n\t\t\t\t}\n\t\t\t}),\n\t\t\tfunction: async function(old_user, new_user, client_subs) {\n\t\t\t\tif (ResolveIOServer.getMainServer()) {\n\t\t\t\t\tlet ws = ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(this.id_ws);\n\t\t\t\t\tawait this.sendEmail('dev@resolveio.com', 'SERVER - WRONG USER Detected - ' + this.serverConfig['CLIENT_NAME'], 'Wrong User Sent!\\nWS: ' + JSON.stringify(ws, null, 2) + '\\nUserMethod: ' + this.user + '\\nIdUserMethod: ' + this.id_user + '\\nSubManagerActiveSubs: ' + JSON.stringify(ResolveIOServer.getMainServer().getSubscriptionManager().getActiveSubscriptions(), null, 2) + '\\nOldUser: ' + JSON.stringify(old_user, null, 2) + '\\nNewUser: ' + JSON.stringify(new_user, null, 2) + '\\nClientSubs: ' + JSON.stringify(client_subs, null, 2));\n\t\t\t\t}\n\n\t\t\t\treturn Promise.resolve(null);\n\t\t\t}\n\t\t},\n\t\treloadWS: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tid_ws: String\n\t\t\t}),\n\t\t\tfunction: async function(id_ws) {\n\t\t\t\tlet ws = ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(id_ws);\n\n\t\t\t\tif (ws) {\n\t\t\t\t\tawait ResolveIOServer.getMainServer().unsubscribeWS(ws);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthrow new Error('Error in Reload WS: No WS');\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\treconnectWS: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tid_ws: String\n\t\t\t}),\n\t\t\tfunction: async function(id_ws) {\n\t\t\t\tlet ws = ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(id_ws);\n\n\t\t\t\tif (ws) {\n\t\t\t\t\tawait ResolveIOServer.getMainServer().unsubscribeWS(ws);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthrow new Error('Error in Reconnect WS: No WS');\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tdisconnectWS: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tid_ws: String\n\t\t\t}),\n\t\t\tfunction: async function(id_ws) {\n\t\t\t\tlet ws = ResolveIOServer.getMainServer().getWebSocketManager().getWebSocket(id_ws);\n\n\t\t\t\tif (ws) {\n\t\t\t\t\tawait ResolveIOServer.getMainServer().unsubscribeWS(ws);\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthrow new Error('Error in Disconnect WS: No WS');\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tcreateUserAndEmailEnrollment: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tnewUser: {\n\t\t\t\t\ttype: Users['simplschema']\n\t\t\t\t},\n\t\t\t\tsendEnrollmentEmail: {\n\t\t\t\t\ttype: Boolean,\n\t\t\t\t\toptional: true\n\t\t\t\t}\n\t\t\t}),\n\t\t\tfunction: async function(newUser: UserModel, sendEnrollmentEmail = true) {\n\t\t\t\tif (newUser.username.toLocaleLowerCase() === 'admin') {\n\t\t\t\t\tthrow new Error('Error in Create User And Email Enrollment: Username can not be admin');\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tlet otherUser = await Users.findOne({\n\t\t\t\t\t\t$or: [\n\t\t\t\t\t\t\t{username: newUser.username.toLocaleLowerCase()},\n\t\t\t\t\t\t\t{email: newUser.email.toLocaleLowerCase()}\n\t\t\t\t\t\t]\n\t\t\t\t\t});\n\n\t\t\t\t\tif (otherUser) {\n\t\t\t\t\t\tthrow new Error('Error in Create User And Email Enrollment: Username/Email is already used');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tnewUser._id = objectIdHexString();\n\n\t\t\t\tnewUser.services = {\n\t\t\t\t\tenrollment: jwt.sign({id_user: newUser._id}, this.serverConfig['JWT_SECRET'], {\n\t\t\t\t\t\texpiresIn : 3 * 24 * 60 * 60 * 1000 // 3 days\n\t\t\t\t\t})\n\t\t\t\t};\n\n\t\t\t\tnewUser.is_customer = false;\n\t\t\t\tawait Users.insertOne(newUser);\n\n\t\t\t\tif (sendEnrollmentEmail) {\n\t\t\t\t\tlet emailData = {\n\t\t\t\t\t\tfullname: newUser.fullname,\n\t\t\t\t\t\tuser: this.user,\n\t\t\t\t\t\turl: (this.serverConfig['ROOT_URL'] + '/enroll-account?' + encodeURIComponent(this.serverConfig['SERVER_URL']) + '&' + newUser.services['enrollment'])\n\t\t\t\t\t};\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlet html = this.readFile('email-templates/enrollment.html');\n\t\t\t\t\t\tlet template = handlebars.compile(html);\n\t\t\t\t\t\thandlebars.registerHelper('equals', (a, b) => {\n\t\t\t\t\t\t\treturn a === b;\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait this.sendEmail(newUser.email, 'ResolveIO (' + ResolveIOServer.getClientName() + ') - Enrollment Email', '', template(emailData), null, null, '');\n\n\t\t\t\t\t\treturn newUser;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\terr.message = `Error in Create User And Email Enrollment: email-templates/enrollment.html - ${err.message}`;\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn newUser;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tresetUserPassword: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tuserId: {\n\t\t\t\t\ttype: String\n\t\t\t\t}\n\t\t\t}),\n\t\t\tfunction: async function(userId: string) {\n\t\t\t\tlet user = await Users.findOne({_id: userId});\n\t\n\t\t\t\tif (user) {\n\t\t\t\t\tif (!user.services) {\n\t\t\t\t\t\tuser.services = {};\n\t\t\t\t\t}\n\n\t\t\t\t\tuser.services['forgot_password'] = jwt.sign({id_user: userId}, this.serverConfig['JWT_SECRET']);\n\n\t\t\t\t\tlet emailData = {\n\t\t\t\t\t\tuserToChangePassword: user.fullname,\n\t\t\t\t\t\tuserWhoResetPassword: this.user,\n\t\t\t\t\t\turl: (this.serverConfig['ROOT_URL'] + '/forgot-password?' + encodeURIComponent(this.serverConfig['SERVER_URL']) + '&' + user.services['forgot_password'])\n\t\t\t\t\t};\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait Users.updateOne({_id: user._id}, {$set: {services: user.services, attempts: 0}});\n\t\t\t\t\t\tlet html = this.readFile('email-templates/forgot-password.html');\n\t\t\t\t\t\tlet template = handlebars.compile(html);\n\t\t\t\t\t\thandlebars.registerHelper('equals', (a, b) => {\n\t\t\t\t\t\t\treturn a === b;\n\t\t\t\t\t\t});\n\t\n\t\t\t\t\t\tawait this.sendEmail(user.email, 'ResolveIO (' + ResolveIOServer.getClientName() + ') - Forgot Password', '', template(emailData), null, null, '');\n\t\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (err) {\n\t\t\t\t\t\terr.message = `Error in Reset User Password: email-templates/forgot-password.html - ${err.message}`;\n\t\t\t\t\t\tthrow err;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthrow new Error('Error in Reset User Password: Invalid User');\n\t\t\t}\n\t\t},\n\t\tsetUserPassword: {\n\t\t\tcheck: new SimpleSchema({\n\t\t\t\tuserId: {\n\t\t\t\t\ttype: String\n\t\t\t\t},\n\t\t\t\tpassword: {\n\t\t\t\t\ttype: String\n\t\t\t\t}\n\t\t\t}),\n\t\t\tfunction: async function(userId: string, password: string) {\n\t\t\t\tlet user = await Users.findOne({_id: userId});\n\t\n\t\t\t\tif (user && !user.roles.super_admin) {\n\t\t\t\t\tawait Users.setPassword(user, password);\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthrow new Error('Error in Set User Password: Invalid User');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n}"]}
|