pg-cache 3.13.1 → 3.14.1
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/driver.d.ts +41 -0
- package/driver.js +22 -0
- package/esm/driver.js +16 -0
- package/esm/index.js +2 -1
- package/esm/pg.js +22 -7
- package/index.d.ts +3 -1
- package/index.js +6 -1
- package/package.json +3 -3
- package/pg.d.ts +6 -0
- package/pg.js +24 -8
package/driver.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type pg from 'pg';
|
|
2
|
+
import type { PgConfig, PgPoolConfig } from 'pg-env';
|
|
3
|
+
/**
|
|
4
|
+
* Minimal connection-factory seam for pg-cache.
|
|
5
|
+
*
|
|
6
|
+
* `getPgPool` funnels every pooled connection in the stack through a single
|
|
7
|
+
* factory. By default that factory builds a real `pg.Pool` (see
|
|
8
|
+
* `defaultPgPoolFactory`). Registering an alternate factory lets a different
|
|
9
|
+
* backend (e.g. an in-process PGlite instance) supply the pool WITHOUT any
|
|
10
|
+
* backend-specific dependency leaking into pg-cache or its consumers.
|
|
11
|
+
*
|
|
12
|
+
* The only surface pgpm/pgsql-* actually rely on is `query()`, `connect()` and
|
|
13
|
+
* `end()` (plus an `ended` flag for disposal), so a factory may return anything
|
|
14
|
+
* implementing that subset — `QueryablePool`. A real `pg.Pool` structurally
|
|
15
|
+
* satisfies it, so the default path is unchanged and fully backward-compatible.
|
|
16
|
+
*/
|
|
17
|
+
export interface QueryableClient {
|
|
18
|
+
query(text: string, values?: any[]): Promise<any>;
|
|
19
|
+
release(...args: any[]): void;
|
|
20
|
+
}
|
|
21
|
+
export interface QueryablePool {
|
|
22
|
+
query(text: string, values?: any[]): Promise<any>;
|
|
23
|
+
connect(): Promise<QueryableClient>;
|
|
24
|
+
end(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export type PgPoolFactory = (config: Partial<PgConfig> & {
|
|
27
|
+
pool?: PgPoolConfig;
|
|
28
|
+
}) => pg.Pool | QueryablePool;
|
|
29
|
+
/**
|
|
30
|
+
* Register the factory `getPgPool` uses to build new pools. Pass `undefined`
|
|
31
|
+
* to restore the default (`pg.Pool`) behavior.
|
|
32
|
+
*
|
|
33
|
+
* Note: only affects pools created after registration; already-cached pools are
|
|
34
|
+
* unchanged. Callers that need a clean slate should tear down existing pools
|
|
35
|
+
* first (see `teardownPgPools`).
|
|
36
|
+
*/
|
|
37
|
+
export declare const registerPgPoolFactory: (factory: PgPoolFactory | undefined) => void;
|
|
38
|
+
/** The currently-registered factory, or `undefined` when using the default. */
|
|
39
|
+
export declare const getActivePgPoolFactory: () => PgPoolFactory | undefined;
|
|
40
|
+
/** Whether a non-default pool factory is currently registered. */
|
|
41
|
+
export declare const hasPgPoolFactory: () => boolean;
|
package/driver.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasPgPoolFactory = exports.getActivePgPoolFactory = exports.registerPgPoolFactory = void 0;
|
|
4
|
+
let activeFactory;
|
|
5
|
+
/**
|
|
6
|
+
* Register the factory `getPgPool` uses to build new pools. Pass `undefined`
|
|
7
|
+
* to restore the default (`pg.Pool`) behavior.
|
|
8
|
+
*
|
|
9
|
+
* Note: only affects pools created after registration; already-cached pools are
|
|
10
|
+
* unchanged. Callers that need a clean slate should tear down existing pools
|
|
11
|
+
* first (see `teardownPgPools`).
|
|
12
|
+
*/
|
|
13
|
+
const registerPgPoolFactory = (factory) => {
|
|
14
|
+
activeFactory = factory;
|
|
15
|
+
};
|
|
16
|
+
exports.registerPgPoolFactory = registerPgPoolFactory;
|
|
17
|
+
/** The currently-registered factory, or `undefined` when using the default. */
|
|
18
|
+
const getActivePgPoolFactory = () => activeFactory;
|
|
19
|
+
exports.getActivePgPoolFactory = getActivePgPoolFactory;
|
|
20
|
+
/** Whether a non-default pool factory is currently registered. */
|
|
21
|
+
const hasPgPoolFactory = () => activeFactory !== undefined;
|
|
22
|
+
exports.hasPgPoolFactory = hasPgPoolFactory;
|
package/esm/driver.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
let activeFactory;
|
|
2
|
+
/**
|
|
3
|
+
* Register the factory `getPgPool` uses to build new pools. Pass `undefined`
|
|
4
|
+
* to restore the default (`pg.Pool`) behavior.
|
|
5
|
+
*
|
|
6
|
+
* Note: only affects pools created after registration; already-cached pools are
|
|
7
|
+
* unchanged. Callers that need a clean slate should tear down existing pools
|
|
8
|
+
* first (see `teardownPgPools`).
|
|
9
|
+
*/
|
|
10
|
+
export const registerPgPoolFactory = (factory) => {
|
|
11
|
+
activeFactory = factory;
|
|
12
|
+
};
|
|
13
|
+
/** The currently-registered factory, or `undefined` when using the default. */
|
|
14
|
+
export const getActivePgPoolFactory = () => activeFactory;
|
|
15
|
+
/** Whether a non-default pool factory is currently registered. */
|
|
16
|
+
export const hasPgPoolFactory = () => activeFactory !== undefined;
|
package/esm/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
// Main exports from pg-cache package
|
|
2
|
+
export { getActivePgPoolFactory, hasPgPoolFactory, registerPgPoolFactory } from './driver';
|
|
2
3
|
export { close, getPgCacheConfig, pgCache, PgPoolCacheManager, teardownPgPools } from './lru';
|
|
3
|
-
export { buildConnectionString, getPgPool, getPgPoolConfig } from './pg';
|
|
4
|
+
export { buildConnectionString, defaultPgPoolFactory, getPgPool, getPgPoolConfig } from './pg';
|
package/esm/pg.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import pg from 'pg';
|
|
2
2
|
import { getPgEnvOptions } from 'pg-env';
|
|
3
3
|
import { Logger } from '@pgpmjs/logger';
|
|
4
|
+
import { getActivePgPoolFactory } from './driver';
|
|
4
5
|
import { pgCache } from './lru';
|
|
5
6
|
const log = new Logger('pg-cache');
|
|
6
7
|
export const buildConnectionString = (user, password, host, port, database) => `postgres://${user}:${password}@${host}:${port}/${database}`;
|
|
@@ -26,14 +27,13 @@ export function getPgPoolConfig(overrides) {
|
|
|
26
27
|
...(overrides?.allowExitOnIdle !== undefined && { allowExitOnIdle: overrides.allowExitOnIdle }),
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Default pool factory: builds a real `pg.Pool` over TCP. This is the behavior
|
|
32
|
+
* used whenever no alternate driver is registered (see `./driver`).
|
|
33
|
+
*/
|
|
34
|
+
export const defaultPgPoolFactory = (pgConfig) => {
|
|
30
35
|
const config = getPgEnvOptions(pgConfig);
|
|
31
|
-
const { user, password, host, port, database
|
|
32
|
-
if (pgCache.has(database)) {
|
|
33
|
-
const cached = pgCache.get(database);
|
|
34
|
-
if (cached)
|
|
35
|
-
return cached;
|
|
36
|
-
}
|
|
36
|
+
const { user, password, host, port, database } = config;
|
|
37
37
|
const connectionString = buildConnectionString(user, password, host, port, database);
|
|
38
38
|
const poolConfig = getPgPoolConfig(pgConfig.pool);
|
|
39
39
|
const pgPool = new pg.Pool({ connectionString, ...poolConfig });
|
|
@@ -89,6 +89,21 @@ export const getPgPool = (pgConfig) => {
|
|
|
89
89
|
log.error(`Pool ${database} unexpected idle connection error [${err.code || 'unknown'}]: ${err.message}`);
|
|
90
90
|
}
|
|
91
91
|
});
|
|
92
|
+
return pgPool;
|
|
93
|
+
};
|
|
94
|
+
export const getPgPool = (pgConfig) => {
|
|
95
|
+
const config = getPgEnvOptions(pgConfig);
|
|
96
|
+
const { database } = config;
|
|
97
|
+
if (pgCache.has(database)) {
|
|
98
|
+
const cached = pgCache.get(database);
|
|
99
|
+
if (cached)
|
|
100
|
+
return cached;
|
|
101
|
+
}
|
|
102
|
+
// Route through the registered driver (default = pg.Pool over TCP). A custom
|
|
103
|
+
// factory may return any QueryablePool (e.g. an in-process PGlite pool); it is
|
|
104
|
+
// treated as a pg.Pool since that is the only surface consumers use.
|
|
105
|
+
const factory = getActivePgPoolFactory() ?? defaultPgPoolFactory;
|
|
106
|
+
const pgPool = factory(pgConfig);
|
|
92
107
|
pgCache.set(database, pgPool);
|
|
93
108
|
return pgPool;
|
|
94
109
|
};
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { getActivePgPoolFactory, hasPgPoolFactory, registerPgPoolFactory } from './driver';
|
|
1
2
|
export { close, getPgCacheConfig, pgCache, PgPoolCacheManager, teardownPgPools } from './lru';
|
|
2
|
-
export { buildConnectionString, getPgPool, getPgPoolConfig } from './pg';
|
|
3
|
+
export { buildConnectionString, defaultPgPoolFactory, getPgPool, getPgPoolConfig } from './pg';
|
|
4
|
+
export type { PgPoolFactory, QueryableClient, QueryablePool } from './driver';
|
|
3
5
|
export type { PgCacheConfig, PoolCleanupCallback } from './lru';
|
package/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPgPoolConfig = exports.getPgPool = exports.buildConnectionString = exports.teardownPgPools = exports.PgPoolCacheManager = exports.pgCache = exports.getPgCacheConfig = void 0;
|
|
3
|
+
exports.getPgPoolConfig = exports.getPgPool = exports.defaultPgPoolFactory = exports.buildConnectionString = exports.teardownPgPools = exports.PgPoolCacheManager = exports.pgCache = exports.getPgCacheConfig = exports.registerPgPoolFactory = exports.hasPgPoolFactory = exports.getActivePgPoolFactory = void 0;
|
|
4
4
|
// Main exports from pg-cache package
|
|
5
|
+
var driver_1 = require("./driver");
|
|
6
|
+
Object.defineProperty(exports, "getActivePgPoolFactory", { enumerable: true, get: function () { return driver_1.getActivePgPoolFactory; } });
|
|
7
|
+
Object.defineProperty(exports, "hasPgPoolFactory", { enumerable: true, get: function () { return driver_1.hasPgPoolFactory; } });
|
|
8
|
+
Object.defineProperty(exports, "registerPgPoolFactory", { enumerable: true, get: function () { return driver_1.registerPgPoolFactory; } });
|
|
5
9
|
var lru_1 = require("./lru");
|
|
6
10
|
Object.defineProperty(exports, "close", { enumerable: true, get: function () { return lru_1.close; } });
|
|
7
11
|
Object.defineProperty(exports, "getPgCacheConfig", { enumerable: true, get: function () { return lru_1.getPgCacheConfig; } });
|
|
@@ -10,5 +14,6 @@ Object.defineProperty(exports, "PgPoolCacheManager", { enumerable: true, get: fu
|
|
|
10
14
|
Object.defineProperty(exports, "teardownPgPools", { enumerable: true, get: function () { return lru_1.teardownPgPools; } });
|
|
11
15
|
var pg_1 = require("./pg");
|
|
12
16
|
Object.defineProperty(exports, "buildConnectionString", { enumerable: true, get: function () { return pg_1.buildConnectionString; } });
|
|
17
|
+
Object.defineProperty(exports, "defaultPgPoolFactory", { enumerable: true, get: function () { return pg_1.defaultPgPoolFactory; } });
|
|
13
18
|
Object.defineProperty(exports, "getPgPool", { enumerable: true, get: function () { return pg_1.getPgPool; } });
|
|
14
19
|
Object.defineProperty(exports, "getPgPoolConfig", { enumerable: true, get: function () { return pg_1.getPgPoolConfig; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg-cache",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.14.1",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "PostgreSQL connection pool LRU cache manager",
|
|
6
6
|
"main": "index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@pgpmjs/logger": "^2.13.0",
|
|
33
|
-
"@pgpmjs/types": "^2.
|
|
33
|
+
"@pgpmjs/types": "^2.32.0",
|
|
34
34
|
"lru-cache": "^11.2.7",
|
|
35
35
|
"pg": "^8.21.0",
|
|
36
36
|
"pg-env": "^1.17.0"
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"connection",
|
|
49
49
|
"constructive"
|
|
50
50
|
],
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "87e65cd31d4e23c367ca4d398416b19ac863c7de"
|
|
52
52
|
}
|
package/pg.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import pg from 'pg';
|
|
2
2
|
import { PgConfig, PgPoolConfig } from 'pg-env';
|
|
3
|
+
import { PgPoolFactory } from './driver';
|
|
3
4
|
export declare const buildConnectionString: (user: string, password: string, host: string, port: string | number, database: string) => string;
|
|
4
5
|
/**
|
|
5
6
|
* Read per-pool configuration from environment variables.
|
|
@@ -10,6 +11,11 @@ export declare const buildConnectionString: (user: string, password: string, hos
|
|
|
10
11
|
* - PG_POOL_CONNECTION_TIMEOUT_MS: Fail connect() after ms (default: 5000)
|
|
11
12
|
*/
|
|
12
13
|
export declare function getPgPoolConfig(overrides?: PgPoolConfig): pg.PoolConfig;
|
|
14
|
+
/**
|
|
15
|
+
* Default pool factory: builds a real `pg.Pool` over TCP. This is the behavior
|
|
16
|
+
* used whenever no alternate driver is registered (see `./driver`).
|
|
17
|
+
*/
|
|
18
|
+
export declare const defaultPgPoolFactory: PgPoolFactory;
|
|
13
19
|
export declare const getPgPool: (pgConfig: Partial<PgConfig> & {
|
|
14
20
|
pool?: PgPoolConfig;
|
|
15
21
|
}) => pg.Pool;
|
package/pg.js
CHANGED
|
@@ -3,11 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getPgPool = exports.buildConnectionString = void 0;
|
|
6
|
+
exports.getPgPool = exports.defaultPgPoolFactory = exports.buildConnectionString = void 0;
|
|
7
7
|
exports.getPgPoolConfig = getPgPoolConfig;
|
|
8
8
|
const pg_1 = __importDefault(require("pg"));
|
|
9
9
|
const pg_env_1 = require("pg-env");
|
|
10
10
|
const logger_1 = require("@pgpmjs/logger");
|
|
11
|
+
const driver_1 = require("./driver");
|
|
11
12
|
const lru_1 = require("./lru");
|
|
12
13
|
const log = new logger_1.Logger('pg-cache');
|
|
13
14
|
const buildConnectionString = (user, password, host, port, database) => `postgres://${user}:${password}@${host}:${port}/${database}`;
|
|
@@ -34,14 +35,13 @@ function getPgPoolConfig(overrides) {
|
|
|
34
35
|
...(overrides?.allowExitOnIdle !== undefined && { allowExitOnIdle: overrides.allowExitOnIdle }),
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Default pool factory: builds a real `pg.Pool` over TCP. This is the behavior
|
|
40
|
+
* used whenever no alternate driver is registered (see `./driver`).
|
|
41
|
+
*/
|
|
42
|
+
const defaultPgPoolFactory = (pgConfig) => {
|
|
38
43
|
const config = (0, pg_env_1.getPgEnvOptions)(pgConfig);
|
|
39
|
-
const { user, password, host, port, database
|
|
40
|
-
if (lru_1.pgCache.has(database)) {
|
|
41
|
-
const cached = lru_1.pgCache.get(database);
|
|
42
|
-
if (cached)
|
|
43
|
-
return cached;
|
|
44
|
-
}
|
|
44
|
+
const { user, password, host, port, database } = config;
|
|
45
45
|
const connectionString = (0, exports.buildConnectionString)(user, password, host, port, database);
|
|
46
46
|
const poolConfig = getPgPoolConfig(pgConfig.pool);
|
|
47
47
|
const pgPool = new pg_1.default.Pool({ connectionString, ...poolConfig });
|
|
@@ -97,6 +97,22 @@ const getPgPool = (pgConfig) => {
|
|
|
97
97
|
log.error(`Pool ${database} unexpected idle connection error [${err.code || 'unknown'}]: ${err.message}`);
|
|
98
98
|
}
|
|
99
99
|
});
|
|
100
|
+
return pgPool;
|
|
101
|
+
};
|
|
102
|
+
exports.defaultPgPoolFactory = defaultPgPoolFactory;
|
|
103
|
+
const getPgPool = (pgConfig) => {
|
|
104
|
+
const config = (0, pg_env_1.getPgEnvOptions)(pgConfig);
|
|
105
|
+
const { database } = config;
|
|
106
|
+
if (lru_1.pgCache.has(database)) {
|
|
107
|
+
const cached = lru_1.pgCache.get(database);
|
|
108
|
+
if (cached)
|
|
109
|
+
return cached;
|
|
110
|
+
}
|
|
111
|
+
// Route through the registered driver (default = pg.Pool over TCP). A custom
|
|
112
|
+
// factory may return any QueryablePool (e.g. an in-process PGlite pool); it is
|
|
113
|
+
// treated as a pg.Pool since that is the only surface consumers use.
|
|
114
|
+
const factory = (0, driver_1.getActivePgPoolFactory)() ?? exports.defaultPgPoolFactory;
|
|
115
|
+
const pgPool = factory(pgConfig);
|
|
100
116
|
lru_1.pgCache.set(database, pgPool);
|
|
101
117
|
return pgPool;
|
|
102
118
|
};
|