/** * pg-backed Pool factory. Installed at boot by the Node play runner * (Daytona/local). */ import { Pool, type PoolClient } from 'pg'; import { registerRuntimePoolFactory, type RuntimePool, type RuntimePoolClient, type RuntimePoolFactory, } from './runtime-pg-driver'; function wrapPgClient(client: PoolClient): RuntimePoolClient { let released = false; const releaseClient = (destroy = false) => { if (released) return; released = true; client.release(destroy); }; const destroyTransport = () => { // `release(true)` is node-postgres' supported pool-client destruction // path. The pool removes the client and Client.end() destroys the socket // when a query is active, while keeping pool accounting correct. Runtime // callers still run their ordinary `finally { release() }` path after a // deadline destroys the transport, so this wrapper owns idempotence. releaseClient(true); }; return { query: = Record>( text: string, params?: unknown[], ) => ( client.query as unknown as ( t: string, p?: unknown[], ) => Promise<{ rows: R[] }> )(text, params).then((result) => ({ rows: result.rows, })), release: (destroy = false) => { releaseClient(destroy); }, destroy: destroyTransport, }; } function wrapPgPool(pool: Pool): RuntimePool { return { connect: async () => wrapPgClient(await pool.connect()), end: () => pool.end(), }; } const pgRuntimePoolFactory: RuntimePoolFactory = (input): RuntimePool => { const pool = new Pool({ connectionString: input.connectionString, max: input.maxConnections ?? 2, idleTimeoutMillis: input.idleTimeoutMs ?? 15_000, connectionTimeoutMillis: input.connectTimeoutMs ?? 10_000, }); pool.on('error', (error) => { console.warn( `[warn] runtime Postgres discarded an idle client after an error: ${error.message}`, ); }); return wrapPgPool(pool); }; export function installPgRuntimePoolDriver(): void { registerRuntimePoolFactory(pgRuntimePoolFactory); }