@heliyos/heliyos-api-core 1.0.15 → 1.0.17

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.
Files changed (2) hide show
  1. package/dist/mongoose.js +140 -79
  2. package/package.json +1 -1
package/dist/mongoose.js CHANGED
@@ -36,114 +36,147 @@ __exportStar(require("mongoose"), exports);
36
36
  let cachedConnection;
37
37
  let cachedReplicaConnection;
38
38
  const connectionOptions = {
39
- // Connection timeouts
39
+ // Timeouts
40
40
  serverSelectionTimeoutMS: 60000,
41
41
  connectTimeoutMS: 60000,
42
42
  socketTimeoutMS: 360000,
43
- // Connection pool
44
- maxPoolSize: 50,
45
- minPoolSize: 5,
46
- // Reliability settings
43
+ // Connection pool settings
44
+ maxPoolSize: 10,
45
+ minPoolSize: 1,
46
+ // Heartbeat monitoring
47
+ heartbeatFrequencyMS: 10000,
48
+ // Modern reliability settings
47
49
  retryWrites: true,
48
50
  retryReads: true,
49
- // Performance settings
50
- heartbeatFrequencyMS: 10000,
51
- // Monitoring
52
- monitorCommands: true,
51
+ // Required for newer MongoDB versions
52
+ useNewUrlParser: true,
53
+ useUnifiedTopology: true,
53
54
  };
54
- const MAX_RETRY_ATTEMPTS = 5;
55
- const INITIAL_RETRY_DELAY = 1000; // 1 second
55
+ const MAX_RETRY_ATTEMPTS = 10; // Increased from 5
56
+ const INITIAL_RETRY_DELAY = 2000; // Increased from 1000
56
57
  const connectWithRetry = (mongoUrl, attempt = 1) => __awaiter(void 0, void 0, void 0, function* () {
57
58
  try {
58
59
  logger_1.logger.info(`Attempting to connect to MongoDB (attempt ${attempt}/${MAX_RETRY_ATTEMPTS})`);
60
+ // Create connection with event handlers
59
61
  const connection = mongoose_1.default.createConnection(mongoUrl, connectionOptions);
60
- // Wait for connection to be ready
61
- yield new Promise((resolve, reject) => {
62
- connection.once("connected", () => resolve());
63
- connection.once("error", (err) => reject(err));
62
+ // Set up event handlers before attempting connection
63
+ connection.on("error", (err) => {
64
+ logger_1.logger.error("MongoDB connection error:", err);
65
+ // Attempt reconnection after delay
66
+ setTimeout(() => {
67
+ if (connection.readyState !== mongoose_1.default.ConnectionStates.connected) {
68
+ logger_1.logger.info("Attempting to reconnect after error...");
69
+ connection.openUri(mongoUrl, connectionOptions);
70
+ }
71
+ }, 5000);
72
+ });
73
+ connection.on("disconnected", () => {
74
+ logger_1.logger.warn("MongoDB disconnected, attempting to reconnect...");
64
75
  });
76
+ connection.on("reconnected", () => {
77
+ logger_1.logger.info("MongoDB reconnected successfully");
78
+ });
79
+ // Wait for initial connection with timeout
80
+ yield Promise.race([
81
+ new Promise((resolve, reject) => {
82
+ connection.once("connected", () => resolve());
83
+ connection.once("error", (err) => reject(err));
84
+ }),
85
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Connection timeout")), connectionOptions.connectTimeoutMS)),
86
+ ]);
65
87
  return connection;
66
88
  }
67
89
  catch (error) {
68
90
  if (attempt >= MAX_RETRY_ATTEMPTS) {
69
- logger_1.logger.error("Max retry attempts reached. Failed to connect to MongoDB");
91
+ logger_1.logger.error("Max retry attempts reached. Failed to connect to MongoDB:", error);
70
92
  return null;
71
93
  }
72
94
  const delay = INITIAL_RETRY_DELAY * Math.pow(2, attempt - 1);
73
- logger_1.logger.warn(`Connection attempt ${attempt} failed. Retrying in ${delay}ms...`);
95
+ logger_1.logger.warn(`Connection attempt ${attempt} failed. Retrying in ${delay}ms... Error: ${error.message}`);
74
96
  yield new Promise((resolve) => setTimeout(resolve, delay));
75
97
  return connectWithRetry(mongoUrl, attempt + 1);
76
98
  }
77
99
  });
78
100
  const mongooseConnected = () => __awaiter(void 0, void 0, void 0, function* () {
79
- if (cachedConnection) {
80
- // Use type assertion to check connection state
81
- if (cachedConnection.readyState ===
82
- mongoose_1.default.ConnectionStates.connected) {
83
- logger_1.logger.info("Using cached MongoDB Connection");
84
- return cachedConnection;
85
- }
86
- // Try to reconnect using existing connection
87
- try {
88
- yield cachedConnection.openUri(process.env.MONGO_DATABASE_URL, connectionOptions);
101
+ try {
102
+ if (cachedConnection) {
103
+ // Use type assertion to check connection state
89
104
  if (cachedConnection.readyState ===
90
105
  mongoose_1.default.ConnectionStates.connected) {
91
- logger_1.logger.info("Successfully reconnected using cached connection");
106
+ logger_1.logger.info("Using cached MongoDB Connection");
92
107
  return cachedConnection;
93
108
  }
109
+ // Try to reconnect using existing connection
110
+ try {
111
+ yield cachedConnection.openUri(process.env.MONGO_DATABASE_URL, connectionOptions);
112
+ if (cachedConnection.readyState ===
113
+ mongoose_1.default.ConnectionStates.connected) {
114
+ logger_1.logger.info("Successfully reconnected using cached connection");
115
+ return cachedConnection;
116
+ }
117
+ }
118
+ catch (error) {
119
+ logger_1.logger.warn("Failed to reconnect using cached connection, will create new one");
120
+ }
94
121
  }
95
- catch (error) {
96
- logger_1.logger.warn("Failed to reconnect using cached connection, will create new one");
122
+ let mongoUrl;
123
+ const nodeEnv = process.env.NODE_ENV;
124
+ if (nodeEnv === "local") {
125
+ mongoUrl = process.env.MONGO_DATABASE_URL || "";
126
+ // Add logging to debug URL
97
127
  }
128
+ else if (["development", "production"].includes(nodeEnv)) {
129
+ const secrets = yield (0, ssm_1.getSecretsManagerSecret)(process.env.ENV_SECRET_NAME);
130
+ mongoUrl = secrets.MONGO_DATABASE_URL;
131
+ }
132
+ else {
133
+ logger_1.logger.error(`Invalid NODE_ENV: ${nodeEnv}`);
134
+ return null;
135
+ }
136
+ if (nodeEnv === "development") {
137
+ logger_1.logger.info(`Connecting to MongoDB URL: ${mongoUrl === null || mongoUrl === void 0 ? void 0 : mongoUrl.replace(/\/\/[^@]*@/, "//****:****@")}`);
138
+ }
139
+ if (!mongoUrl) {
140
+ logger_1.logger.error("MONGO_DATABASE_URL not set");
141
+ return null;
142
+ }
143
+ logger_1.logger.info("Creating new MongoDB Connection");
144
+ const connection = yield connectWithRetry(mongoUrl).catch((error) => {
145
+ logger_1.logger.error("Failed to connect to MongoDB:", error);
146
+ return null;
147
+ });
148
+ if (!connection) {
149
+ logger_1.logger.error("Failed to establish MongoDB connection after retries");
150
+ return null;
151
+ }
152
+ // Enhanced error handling
153
+ connection.on("error", (err) => {
154
+ logger_1.logger.error("MongoDB connection error:", err);
155
+ // Attempt to reconnect after a delay
156
+ setTimeout(() => {
157
+ if (connection.readyState !== mongoose_1.default.ConnectionStates.connected) {
158
+ logger_1.logger.info("Attempting to reconnect...");
159
+ connection.openUri(mongoUrl, connectionOptions);
160
+ }
161
+ }, 5000);
162
+ });
163
+ // Add connection monitoring
164
+ connection.on("disconnected", () => {
165
+ logger_1.logger.warn("MongoDB disconnected. Attempting to reconnect...");
166
+ });
167
+ connection.on("reconnected", () => {
168
+ logger_1.logger.info("MongoDB reconnected successfully");
169
+ });
170
+ connection.on("connected", () => {
171
+ logger_1.logger.info("MongoDB connected successfully");
172
+ });
173
+ cachedConnection = connection;
174
+ return connection;
98
175
  }
99
- let mongoUrl;
100
- const nodeEnv = process.env.NODE_ENV;
101
- if (nodeEnv === "local" || nodeEnv === "development") {
102
- mongoUrl = process.env.MONGO_DATABASE_URL;
103
- // Add logging to debug URL
104
- logger_1.logger.info(`Connecting to MongoDB URL: ${mongoUrl.replace(/\/\/[^@]*@/, "//****:****@")}`);
105
- }
106
- else if (["development", "production"].includes(nodeEnv)) {
107
- const secrets = yield (0, ssm_1.getSecretsManagerSecret)(process.env.ENV_SECRET_NAME);
108
- mongoUrl = secrets.MONGO_DATABASE_URL;
109
- }
110
- else {
111
- logger_1.logger.error(`Invalid NODE_ENV: ${nodeEnv}`);
112
- return null;
113
- }
114
- if (!mongoUrl) {
115
- logger_1.logger.error("MONGO_DATABASE_URL not set");
116
- return null;
117
- }
118
- logger_1.logger.info("Creating new MongoDB Connection");
119
- const connection = yield connectWithRetry(mongoUrl);
120
- if (!connection) {
121
- logger_1.logger.error("Failed to establish MongoDB connection after retries");
176
+ catch (error) {
177
+ logger_1.logger.error("Unexpected error in mongooseConnected:", error);
122
178
  return null;
123
179
  }
124
- // Enhanced error handling
125
- connection.on("error", (err) => {
126
- logger_1.logger.error("MongoDB connection error:", err);
127
- // Attempt to reconnect after a delay
128
- setTimeout(() => {
129
- if (connection.readyState !== mongoose_1.default.ConnectionStates.connected) {
130
- logger_1.logger.info("Attempting to reconnect...");
131
- connection.openUri(mongoUrl, connectionOptions);
132
- }
133
- }, 5000);
134
- });
135
- // Add connection monitoring
136
- connection.on("disconnected", () => {
137
- logger_1.logger.warn("MongoDB disconnected. Attempting to reconnect...");
138
- });
139
- connection.on("reconnected", () => {
140
- logger_1.logger.info("MongoDB reconnected successfully");
141
- });
142
- connection.on("connected", () => {
143
- logger_1.logger.info("MongoDB connected successfully");
144
- });
145
- cachedConnection = connection;
146
- return connection;
147
180
  });
148
181
  const replicaMongooseConnected = () => __awaiter(void 0, void 0, void 0, function* () {
149
182
  if (cachedReplicaConnection) {
@@ -307,10 +340,11 @@ const closeConnections = () => __awaiter(void 0, void 0, void 0, function* () {
307
340
  }
308
341
  });
309
342
  exports.closeConnections = closeConnections;
310
- // Add this new utility function
343
+ // Update the startConnectionMonitoring function to be more resilient
311
344
  const startConnectionMonitoring = (checkInterval = 30000) => {
312
345
  let isReconnecting = false;
313
- setInterval(() => __awaiter(void 0, void 0, void 0, function* () {
346
+ let monitoringInterval;
347
+ const monitor = () => __awaiter(void 0, void 0, void 0, function* () {
314
348
  try {
315
349
  if (isReconnecting)
316
350
  return;
@@ -336,7 +370,34 @@ const startConnectionMonitoring = (checkInterval = 30000) => {
336
370
  isReconnecting = false;
337
371
  logger_1.logger.error("Connection monitoring error:", error);
338
372
  }
339
- }), checkInterval);
373
+ });
374
+ // Wrap the interval in a try-catch
375
+ try {
376
+ monitoringInterval = setInterval(monitor, checkInterval);
377
+ }
378
+ catch (error) {
379
+ logger_1.logger.error("Failed to start connection monitoring:", error);
380
+ }
381
+ // Return cleanup function
382
+ return () => {
383
+ try {
384
+ if (monitoringInterval) {
385
+ clearInterval(monitoringInterval);
386
+ }
387
+ }
388
+ catch (error) {
389
+ logger_1.logger.error("Error cleaning up monitoring interval:", error);
390
+ }
391
+ };
340
392
  };
341
393
  // Call this when your application starts
342
394
  startConnectionMonitoring();
395
+ // Add process-level error handling
396
+ process.on("unhandledRejection", (reason, promise) => {
397
+ logger_1.logger.error("Unhandled Rejection at:", promise, "reason:", reason);
398
+ // Don't exit the process, just log the error
399
+ });
400
+ process.on("uncaughtException", (error) => {
401
+ logger_1.logger.error("Uncaught Exception:", error);
402
+ // Don't exit the process, just log the error
403
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heliyos/heliyos-api-core",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "Heliyos's core api functions and middlewares. Its a private package hosted on npm.",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {