@agentuity/postgres 1.0.0 → 1.0.2

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/dist/pool.js ADDED
@@ -0,0 +1,574 @@
1
+ import pg from 'pg';
2
+ import { ConnectionClosedError, PostgresError, QueryTimeoutError, ReconnectFailedError, isRetryableError, } from './errors';
3
+ import { computeBackoff, sleep, mergeReconnectConfig } from './reconnect';
4
+ import { registerClient, unregisterClient } from './registry';
5
+ /**
6
+ * A resilient PostgreSQL connection pool with automatic reconnection.
7
+ *
8
+ * Wraps the `pg` package's Pool and adds:
9
+ * - Automatic reconnection with exponential backoff
10
+ * - Connection state tracking
11
+ * - Pool statistics
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const pool = new PostgresPool({
16
+ * connectionString: process.env.DATABASE_URL,
17
+ * max: 20,
18
+ * reconnect: { maxAttempts: 5 }
19
+ * });
20
+ *
21
+ * // Execute queries
22
+ * const result = await pool.query('SELECT * FROM users WHERE id = $1', [userId]);
23
+ *
24
+ * // Close when done
25
+ * await pool.close();
26
+ * ```
27
+ */
28
+ export class PostgresPool {
29
+ _pool = null;
30
+ _config;
31
+ _connected = false;
32
+ _reconnecting = false;
33
+ _closed = false;
34
+ _shuttingDown = false;
35
+ _signalHandlers = [];
36
+ _reconnectPromise = null;
37
+ _connectPromise = null;
38
+ _stats = {
39
+ totalConnections: 0,
40
+ reconnectAttempts: 0,
41
+ failedReconnects: 0,
42
+ lastConnectedAt: null,
43
+ lastDisconnectedAt: null,
44
+ lastReconnectAttemptAt: null,
45
+ };
46
+ /**
47
+ * Creates a new PostgresPool.
48
+ *
49
+ * Note: By default, the actual connection is established lazily on first query.
50
+ * Set `preconnect: true` in config to verify connectivity immediately.
51
+ *
52
+ * @param config - Connection configuration. Can be a connection URL string or a config object.
53
+ * If not provided, uses `process.env.DATABASE_URL`.
54
+ */
55
+ constructor(config) {
56
+ if (typeof config === 'string') {
57
+ this._config = { connectionString: config };
58
+ }
59
+ else {
60
+ this._config = config ?? {};
61
+ }
62
+ // Initialize the pool
63
+ this._initializePool();
64
+ // Register shutdown signal handlers to prevent reconnection during app shutdown
65
+ this._registerShutdownHandlers();
66
+ // Register this pool in the global registry for coordinated shutdown
67
+ registerClient(this);
68
+ // If preconnect is enabled, establish connection immediately
69
+ if (this._config.preconnect) {
70
+ const p = this._warmConnection();
71
+ // Attach no-op catch to suppress unhandled rejection warnings
72
+ p.catch(() => { });
73
+ this._connectPromise = p;
74
+ }
75
+ }
76
+ /**
77
+ * Whether the pool is currently connected.
78
+ */
79
+ get connected() {
80
+ return this._connected;
81
+ }
82
+ /**
83
+ * Whether the pool is shutting down (won't attempt reconnection).
84
+ */
85
+ get shuttingDown() {
86
+ return this._shuttingDown;
87
+ }
88
+ /**
89
+ * Whether a reconnection attempt is in progress.
90
+ */
91
+ get reconnecting() {
92
+ return this._reconnecting;
93
+ }
94
+ /**
95
+ * Pool statistics.
96
+ */
97
+ get stats() {
98
+ return {
99
+ ...this._stats,
100
+ connected: this._connected,
101
+ reconnecting: this._reconnecting,
102
+ totalCount: this._pool?.totalCount ?? 0,
103
+ idleCount: this._pool?.idleCount ?? 0,
104
+ waitingCount: this._pool?.waitingCount ?? 0,
105
+ };
106
+ }
107
+ /**
108
+ * Execute a query on the pool.
109
+ * If reconnection is in progress, waits for it to complete before executing.
110
+ * Automatically retries on retryable errors.
111
+ *
112
+ * @param text - The query string or query config object
113
+ * @param values - Optional array of parameter values
114
+ * @returns The query result
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * const result = await pool.query('SELECT * FROM users WHERE id = $1', [userId]);
119
+ * console.log(result.rows);
120
+ * ```
121
+ */
122
+ async query(text, values) {
123
+ return this._executeWithRetry(async () => {
124
+ const pool = await this._ensureConnectedAsync();
125
+ return pool.query(text, values);
126
+ });
127
+ }
128
+ /**
129
+ * Acquire a client from the pool.
130
+ * The client must be released back to the pool when done.
131
+ *
132
+ * @returns A pooled client
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const client = await pool.connect();
137
+ * try {
138
+ * await client.query('BEGIN');
139
+ * await client.query('INSERT INTO users (name) VALUES ($1)', ['Alice']);
140
+ * await client.query('COMMIT');
141
+ * } catch (error) {
142
+ * await client.query('ROLLBACK');
143
+ * throw error;
144
+ * } finally {
145
+ * client.release();
146
+ * }
147
+ * ```
148
+ */
149
+ async connect() {
150
+ return this._executeWithRetry(async () => {
151
+ const pool = await this._ensureConnectedAsync();
152
+ return pool.connect();
153
+ });
154
+ }
155
+ /**
156
+ * Signal that the application is shutting down.
157
+ * This prevents reconnection attempts but doesn't immediately close the pool.
158
+ * Use this when you want to gracefully drain connections before calling close().
159
+ */
160
+ shutdown() {
161
+ this._shuttingDown = true;
162
+ }
163
+ /**
164
+ * Close the pool and release all connections.
165
+ * Alias for end() for compatibility with PostgresClient.
166
+ */
167
+ async close() {
168
+ return this.end();
169
+ }
170
+ /**
171
+ * Close the pool and release all connections.
172
+ */
173
+ async end() {
174
+ this._closed = true;
175
+ this._shuttingDown = true;
176
+ this._connected = false;
177
+ this._reconnecting = false;
178
+ // Remove signal handlers
179
+ this._removeShutdownHandlers();
180
+ // Unregister from global registry
181
+ unregisterClient(this);
182
+ if (this._pool) {
183
+ await this._pool.end();
184
+ this._pool = null;
185
+ }
186
+ }
187
+ /**
188
+ * Access to the raw pg.Pool instance for advanced use cases.
189
+ * Returns the underlying pg.Pool instance.
190
+ */
191
+ get raw() {
192
+ return this._ensureConnected();
193
+ }
194
+ /**
195
+ * Wait for the connection to be established.
196
+ * If the connection hasn't been established yet (lazy connection), this will
197
+ * warm the connection by acquiring and releasing a client.
198
+ * If reconnection is in progress, waits for it to complete.
199
+ *
200
+ * @param timeoutMs - Optional timeout in milliseconds
201
+ * @throws {ConnectionClosedError} If the pool has been closed or connection fails
202
+ */
203
+ async waitForConnection(timeoutMs) {
204
+ if (this._connected && this._pool) {
205
+ return;
206
+ }
207
+ if (this._closed) {
208
+ throw new ConnectionClosedError({
209
+ message: 'Pool has been closed',
210
+ });
211
+ }
212
+ const connectOperation = async () => {
213
+ // Wait for preconnect if in progress
214
+ if (this._connectPromise) {
215
+ try {
216
+ await this._connectPromise;
217
+ }
218
+ catch (err) {
219
+ this._connectPromise = null;
220
+ throw err;
221
+ }
222
+ this._connectPromise = null;
223
+ }
224
+ // Wait for reconnection if in progress
225
+ if (this._reconnecting && this._reconnectPromise) {
226
+ await this._reconnectPromise;
227
+ }
228
+ // If still not connected, warm the connection
229
+ if (!this._connected && this._pool) {
230
+ await this._warmConnection();
231
+ }
232
+ if (!this._connected || !this._pool) {
233
+ throw new ConnectionClosedError({
234
+ message: 'Failed to establish connection',
235
+ });
236
+ }
237
+ };
238
+ if (timeoutMs !== undefined) {
239
+ let timerId;
240
+ const timeoutPromise = new Promise((_, reject) => {
241
+ timerId = setTimeout(() => reject(new QueryTimeoutError({
242
+ timeoutMs,
243
+ })), timeoutMs);
244
+ });
245
+ try {
246
+ await Promise.race([connectOperation(), timeoutPromise]);
247
+ }
248
+ finally {
249
+ if (timerId !== undefined) {
250
+ clearTimeout(timerId);
251
+ }
252
+ }
253
+ }
254
+ else {
255
+ await connectOperation();
256
+ }
257
+ }
258
+ /**
259
+ * Registers signal handlers to detect application shutdown.
260
+ * When shutdown is detected, reconnection is disabled.
261
+ */
262
+ _registerShutdownHandlers() {
263
+ const shutdownHandler = () => {
264
+ this._shuttingDown = true;
265
+ };
266
+ const signals = ['SIGTERM', 'SIGINT'];
267
+ for (const signal of signals) {
268
+ process.on(signal, shutdownHandler);
269
+ this._signalHandlers.push({ signal, handler: shutdownHandler });
270
+ }
271
+ }
272
+ /**
273
+ * Removes signal handlers registered for shutdown detection.
274
+ */
275
+ _removeShutdownHandlers() {
276
+ for (const { signal, handler } of this._signalHandlers) {
277
+ process.off(signal, handler);
278
+ }
279
+ this._signalHandlers = [];
280
+ }
281
+ /**
282
+ * Initializes the pg.Pool instance.
283
+ */
284
+ _initializePool() {
285
+ if (this._closed || this._pool) {
286
+ return;
287
+ }
288
+ const connectionString = this._config.connectionString ?? process.env.DATABASE_URL;
289
+ const poolConfig = {};
290
+ if (connectionString) {
291
+ poolConfig.connectionString = connectionString;
292
+ }
293
+ if (this._config.host)
294
+ poolConfig.host = this._config.host;
295
+ if (this._config.port)
296
+ poolConfig.port = this._config.port;
297
+ if (this._config.user)
298
+ poolConfig.user = this._config.user;
299
+ if (this._config.password)
300
+ poolConfig.password = this._config.password;
301
+ if (this._config.database)
302
+ poolConfig.database = this._config.database;
303
+ if (this._config.max)
304
+ poolConfig.max = this._config.max;
305
+ if (this._config.idleTimeoutMillis !== undefined)
306
+ poolConfig.idleTimeoutMillis = this._config.idleTimeoutMillis;
307
+ if (this._config.connectionTimeoutMillis !== undefined)
308
+ poolConfig.connectionTimeoutMillis = this._config.connectionTimeoutMillis;
309
+ // Handle SSL configuration
310
+ if (this._config.ssl !== undefined) {
311
+ if (typeof this._config.ssl === 'boolean') {
312
+ poolConfig.ssl = this._config.ssl;
313
+ }
314
+ else {
315
+ poolConfig.ssl = this._config.ssl;
316
+ }
317
+ }
318
+ this._pool = new pg.Pool(poolConfig);
319
+ // Handle pool error events for reconnection
320
+ this._pool.on('error', (err) => {
321
+ this._handlePoolError(err);
322
+ });
323
+ }
324
+ /**
325
+ * Warms the connection by acquiring and releasing a client.
326
+ * This verifies the pool can connect to the database.
327
+ */
328
+ async _warmConnection() {
329
+ if (this._closed || this._connected) {
330
+ return;
331
+ }
332
+ if (!this._pool) {
333
+ this._initializePool();
334
+ }
335
+ // Acquire a client to verify connectivity
336
+ const client = await this._pool.connect();
337
+ client.release();
338
+ this._connected = true;
339
+ this._stats.totalConnections++;
340
+ this._stats.lastConnectedAt = new Date();
341
+ }
342
+ /**
343
+ * Re-initializes the pool for reconnection.
344
+ */
345
+ _reinitializePool() {
346
+ this._connected = false;
347
+ this._pool = null;
348
+ this._initializePool();
349
+ }
350
+ /**
351
+ * Handles pool error events.
352
+ */
353
+ _handlePoolError(error) {
354
+ const wasConnected = this._connected;
355
+ this._connected = false;
356
+ this._stats.lastDisconnectedAt = new Date();
357
+ // Call user's onclose callback
358
+ this._config.onclose?.(error);
359
+ // Don't reconnect if explicitly closed OR if application is shutting down
360
+ if (this._closed || this._shuttingDown) {
361
+ return;
362
+ }
363
+ // Check if reconnection is enabled
364
+ const reconnectConfig = mergeReconnectConfig(this._config.reconnect);
365
+ if (!reconnectConfig.enabled) {
366
+ return;
367
+ }
368
+ // Check if it's a retryable error
369
+ if (!isRetryableError(error)) {
370
+ return;
371
+ }
372
+ // Start reconnection if not already in progress
373
+ if (!this._reconnecting && wasConnected) {
374
+ this._startReconnect();
375
+ }
376
+ }
377
+ /**
378
+ * Starts the reconnection process.
379
+ */
380
+ _startReconnect() {
381
+ if (this._reconnecting || this._closed || this._shuttingDown) {
382
+ return;
383
+ }
384
+ this._reconnecting = true;
385
+ this._reconnectPromise = this._reconnectLoop();
386
+ }
387
+ /**
388
+ * The main reconnection loop with exponential backoff.
389
+ */
390
+ async _reconnectLoop() {
391
+ const config = mergeReconnectConfig(this._config.reconnect);
392
+ let attempt = 0;
393
+ let lastError;
394
+ while (attempt < config.maxAttempts && !this._closed && !this._shuttingDown) {
395
+ this._stats.reconnectAttempts++;
396
+ this._stats.lastReconnectAttemptAt = new Date();
397
+ // Notify about reconnection attempt
398
+ this._config.onreconnect?.(attempt + 1);
399
+ // Calculate backoff delay
400
+ const delay = computeBackoff(attempt, config);
401
+ // Wait before attempting
402
+ await sleep(delay);
403
+ if (this._closed) {
404
+ break;
405
+ }
406
+ try {
407
+ // Close existing pool if any
408
+ if (this._pool) {
409
+ try {
410
+ await this._pool.end();
411
+ }
412
+ catch {
413
+ // Ignore close errors
414
+ }
415
+ this._pool = null;
416
+ }
417
+ // Attempt to reconnect
418
+ this._reinitializePool();
419
+ await this._warmConnection();
420
+ // Success!
421
+ this._reconnecting = false;
422
+ this._reconnectPromise = null;
423
+ this._config.onreconnected?.();
424
+ return;
425
+ }
426
+ catch (error) {
427
+ lastError =
428
+ error instanceof Error
429
+ ? error
430
+ : new PostgresError({
431
+ message: String(error),
432
+ });
433
+ this._stats.failedReconnects++;
434
+ attempt++;
435
+ }
436
+ }
437
+ // All attempts failed
438
+ this._reconnecting = false;
439
+ this._reconnectPromise = null;
440
+ // Only invoke callback if not explicitly closed/shutdown
441
+ if (!this._closed && !this._shuttingDown) {
442
+ const finalError = new ReconnectFailedError({
443
+ attempts: attempt,
444
+ lastError,
445
+ });
446
+ this._config.onreconnectfailed?.(finalError);
447
+ }
448
+ }
449
+ /**
450
+ * Ensures the pool is initialized and returns it.
451
+ */
452
+ _ensureConnected() {
453
+ if (this._closed) {
454
+ throw new ConnectionClosedError({
455
+ message: 'Pool has been closed',
456
+ });
457
+ }
458
+ if (!this._pool) {
459
+ throw new ConnectionClosedError({
460
+ message: 'Pool not initialized',
461
+ wasReconnecting: this._reconnecting,
462
+ });
463
+ }
464
+ return this._pool;
465
+ }
466
+ /**
467
+ * Ensures the pool is connected and returns it.
468
+ * If reconnection is in progress, waits for it to complete.
469
+ * If connection hasn't been established yet, warms it first.
470
+ */
471
+ async _ensureConnectedAsync() {
472
+ if (this._closed) {
473
+ throw new ConnectionClosedError({
474
+ message: 'Pool has been closed',
475
+ });
476
+ }
477
+ // If preconnect is in progress, wait for it
478
+ if (this._connectPromise) {
479
+ try {
480
+ await this._connectPromise;
481
+ }
482
+ catch (err) {
483
+ this._connectPromise = null;
484
+ throw err;
485
+ }
486
+ this._connectPromise = null;
487
+ }
488
+ // If reconnection is in progress, wait for it to complete
489
+ if (this._reconnecting && this._reconnectPromise) {
490
+ await this._reconnectPromise;
491
+ }
492
+ if (!this._pool) {
493
+ throw new ConnectionClosedError({
494
+ message: 'Pool not initialized',
495
+ wasReconnecting: false,
496
+ });
497
+ }
498
+ // If not yet connected, warm the connection
499
+ if (!this._connected) {
500
+ await this._warmConnection();
501
+ }
502
+ return this._pool;
503
+ }
504
+ /**
505
+ * Executes an operation with retry logic for retryable errors.
506
+ * Waits for reconnection if one is in progress.
507
+ */
508
+ async _executeWithRetry(operation, maxRetries = 3) {
509
+ let lastError;
510
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
511
+ try {
512
+ // Wait for preconnect if in progress
513
+ if (this._connectPromise) {
514
+ try {
515
+ await this._connectPromise;
516
+ }
517
+ catch (err) {
518
+ this._connectPromise = null;
519
+ throw err;
520
+ }
521
+ this._connectPromise = null;
522
+ }
523
+ // Wait for reconnection if in progress
524
+ if (this._reconnecting && this._reconnectPromise) {
525
+ await this._reconnectPromise;
526
+ }
527
+ if (!this._pool) {
528
+ throw new ConnectionClosedError({
529
+ message: 'Pool not initialized',
530
+ wasReconnecting: this._reconnecting,
531
+ });
532
+ }
533
+ // If not yet connected, warm the connection
534
+ if (!this._connected) {
535
+ await this._warmConnection();
536
+ }
537
+ return await operation();
538
+ }
539
+ catch (error) {
540
+ lastError = error instanceof Error ? error : new Error(String(error));
541
+ // If it's a retryable error and we have retries left, wait and retry
542
+ if (isRetryableError(error) && attempt < maxRetries) {
543
+ // Wait for reconnection to complete if it started
544
+ if (this._reconnecting && this._reconnectPromise) {
545
+ try {
546
+ await this._reconnectPromise;
547
+ }
548
+ catch {
549
+ // Reconnection failed, will throw below
550
+ }
551
+ }
552
+ continue;
553
+ }
554
+ throw error;
555
+ }
556
+ }
557
+ throw lastError;
558
+ }
559
+ }
560
+ /**
561
+ * Creates a new PostgresPool.
562
+ * This is an alias for `new PostgresPool(config)` for convenience.
563
+ *
564
+ * @param config - Connection configuration
565
+ * @returns A new PostgresPool instance
566
+ */
567
+ export function createPool(config) {
568
+ return new PostgresPool(config);
569
+ }
570
+ /**
571
+ * Alias for PostgresPool for convenient imports.
572
+ */
573
+ export { PostgresPool as Pool };
574
+ //# sourceMappingURL=pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"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"}