@vrplatform/kysely 1.3.45-stage.38238828821 → 1.3.45-stage.38241224723
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/build/main/index.js +34 -7
- package/build/main/index.js.map +1 -1
- package/build/module/index.js +34 -7
- package/build/module/index.js.map +1 -1
- package/package.json +1 -1
package/build/main/index.js
CHANGED
|
@@ -70,11 +70,22 @@ class StatementTypes extends Map {
|
|
|
70
70
|
return super.set(signature, types);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
/**
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Kept for the isolate's lifetime, one map per origin database. One isolate
|
|
75
|
+
* can open several databases through different Hyperdrive bindings, and enum
|
|
76
|
+
* and row types have different OIDs in each, so the key is the binding's
|
|
77
|
+
* connection string, not the role (PRO-19353).
|
|
78
|
+
*/
|
|
79
|
+
const hyperdriveStatementTypes = new Map();
|
|
80
|
+
/**
|
|
81
|
+
* Array type OIDs by element type OID, per origin database (PRO-19353).
|
|
82
|
+
* Postgres.js looks them up on every new connection, one origin round trip
|
|
83
|
+
* each, about 100 ms from Crunchy to the control plane. The first connection
|
|
84
|
+
* to a database in an isolate fills its map and later connections reuse it.
|
|
85
|
+
* A migration that adds an array type reaches an isolate when it restarts;
|
|
86
|
+
* until then values of that type arrive as text.
|
|
87
|
+
*/
|
|
88
|
+
const hyperdriveArrayTypes = new Map();
|
|
78
89
|
function isRetryableConnectionError(error) {
|
|
79
90
|
const message = error instanceof Error ? error.message : String(error);
|
|
80
91
|
return retryableMessages.some((retryable) => message.includes(retryable));
|
|
@@ -407,9 +418,19 @@ const scriptQueryTimeoutMs = (0, utils_1.parseDuration)('1h');
|
|
|
407
418
|
let _connections = [];
|
|
408
419
|
function usePostgres(connectionString, opt) {
|
|
409
420
|
const ssl = opt?.forceDisableSSL !== true && !opt?.hyperdrive;
|
|
421
|
+
if (opt?.hyperdrive && !hyperdriveStatementTypes.has(connectionString)) {
|
|
422
|
+
// A Worker binds seven Hyperdrive configs. Keep a few more, so a binding
|
|
423
|
+
// whose host changed between requests cannot grow the caches unbounded.
|
|
424
|
+
if (hyperdriveStatementTypes.size >= 16) {
|
|
425
|
+
const oldest = hyperdriveStatementTypes.keys().next().value;
|
|
426
|
+
hyperdriveStatementTypes.delete(oldest);
|
|
427
|
+
hyperdriveArrayTypes.delete(oldest);
|
|
428
|
+
}
|
|
429
|
+
hyperdriveStatementTypes.set(connectionString, new StatementTypes());
|
|
430
|
+
hyperdriveArrayTypes.set(connectionString, new Map());
|
|
431
|
+
}
|
|
410
432
|
const sql = (0, postgres_1.default)(connectionString, {
|
|
411
433
|
ssl: ssl ? 'require' : false,
|
|
412
|
-
target_session_attrs: 'read-write',
|
|
413
434
|
// Named prepared statements: PRO-17965 (Hyperdrive and Crunchy PgBouncer).
|
|
414
435
|
prepare: true,
|
|
415
436
|
...(opt?.hyperdrive
|
|
@@ -417,9 +438,15 @@ function usePostgres(connectionString, opt) {
|
|
|
417
438
|
max: 5,
|
|
418
439
|
// Retire idle clients before Hyperdrive can close them asynchronously.
|
|
419
440
|
idle_timeout: 10,
|
|
420
|
-
statement_types: hyperdriveStatementTypes
|
|
441
|
+
statement_types: hyperdriveStatementTypes.get(connectionString),
|
|
442
|
+
array_types: hyperdriveArrayTypes.get(connectionString),
|
|
443
|
+
// No read-write check (PRO-17156): Hyperdrive pools by transaction,
|
|
444
|
+
// so the check covered one origin connection, never the ones later
|
|
445
|
+
// statements run on, and it cost an origin round trip per
|
|
446
|
+
// connection (PRO-19353).
|
|
421
447
|
}
|
|
422
448
|
: {
|
|
449
|
+
target_session_attrs: 'read-write',
|
|
423
450
|
connect_timeout: 10,
|
|
424
451
|
idle_timeout: 60,
|
|
425
452
|
...(opt?.script ? { keep_alive: 10 } : {}),
|
package/build/main/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { backOff } from 'exponential-backoff';\nimport { Pool } from '@neondatabase/serverless';\nimport type {\n CompiledQuery,\n DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\n QueryResult,\n Transaction as T,\n} from 'kysely';\nimport { PostgresDialect } from 'kysely';\nimport {\n PostgresJSDialect,\n type PostgresJSDialectConfig,\n PostgresJSDriver,\n} from 'kysely-postgres-js';\nimport postgres, { type Sql } from 'postgres';\nimport { type ControlPlaneDB, withControlPlaneSchema } from './control-plane';\nimport { KyselyError } from './error';\nimport { getKysely } from './plugins';\nimport { isPostgresError } from './postgres-error';\n\nexport type { Insertable, LogEvent } from 'kysely';\nexport * from './connect-handoff';\nexport * from './error';\nexport * from './isomorphic';\nexport * from './postgres-error';\nexport * from './query';\nexport * from './regional';\nexport * from './transaction';\n\nimport { parseDuration } from '@vrplatform/utils';\nimport type { TenantDataRegion } from './regional';\nimport type { DB } from './v1.generated';\n\n/** The database a Worker reaches through its Hyperdrive binding. */\ntype HyperdriveDatabase = 'controlPlane' | 'regional';\n\ntype KyselyOpts = {\n dataRegion?: TenantDataRegion;\n hyperdrive?: HyperdriveDatabase;\n /** Called after every connection reservation, including the startup probe. */\n onReserve?: (timing: {\n durationMs: number;\n startedAtEpochMs: number;\n }) => void;\n onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;\n repositoryName?: string;\n log?: true | LogConfig;\n /**\n * Scripts and repairs (PRO-19037). Probes an idle TCP connection after 10 s.\n * A query, commit, begin, rollback or savepoint with no answer for an hour,\n * longer than any statement timeout a script sets, fails the run and closes\n * the Postgres client that issued it. Backstop for a connection the kernel\n * keeps open while the peer never answers.\n */\n script?: true;\n};\n\ntype PostgresRetryDiagnostic = {\n attemptCount: number;\n dataRegion?: TenantDataRegion;\n errorClass: string;\n operationKind: 'acquisition' | 'mutation' | 'select' | 'transaction';\n outcome: 'exhausted' | 'notRetryable' | 'retrying';\n repositoryName?: string;\n};\n\ntype PgOpt = {\n forceDisableSSL?: boolean;\n probe?: true;\n retries?: false | number;\n} & Pick<KyselyOpts, 'hyperdrive' | 'onReserve' | 'script'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n 'Timed out while creating a new server connection.',\n // Neon rejects the login before any statement runs (PRO-19169).\n 'Failed to acquire permit to connect to the database',\n];\nconst postgresRetryAttempts = 3;\n\n/**\n * Parameter types PostgreSQL described per statement signature (PRO-18871).\n * Postgres.js describes a statement in a round trip of its own before it can\n * execute it when a parameter type is unknown, and a Worker request always\n * starts on new connections. The patched driver reads and fills this map\n * through its `statement_types` option and then parses, describes, binds and\n * executes a known statement in one round trip. It forgets a statement's\n * types when the statement fails, so a schema change is described again.\n */\nclass StatementTypes extends Map<string, number[]> {\n override set(signature: string, types: number[]) {\n if (!this.has(signature) && this.size >= 2000) {\n this.delete(this.keys().next().value!);\n }\n return super.set(signature, types);\n }\n}\n\n/** Kept for the isolate's lifetime, one map per Hyperdrive database. */\nconst hyperdriveStatementTypes: Record<HyperdriveDatabase, StatementTypes> = {\n controlPlane: new StatementTypes(),\n regional: new StatementTypes(),\n};\n\nfunction isRetryableConnectionError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return retryableMessages.some((retryable) => message.includes(retryable));\n}\n\nfunction isNodeShuttingDown(error: unknown) {\n return (\n error instanceof Error &&\n (error.message === 'Node shutting down' ||\n error.message === 'Node shutting down.' ||\n error.message === 'shutting down')\n );\n}\n\nfunction isConnectionReset(error: unknown) {\n return (\n error instanceof Error && 'code' in error && error.code === 'ECONNRESET'\n );\n}\n\nfunction isRetryableConnectionAcquisitionError(error: unknown) {\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n // Hyperdrive refuses any new connection while its node shuts down\n // (PRO-19168).\n isNodeShuttingDown(error) ||\n (error instanceof Error &&\n (error.message === 'connection attempt failed' ||\n // Opening a connection happens before any statement runs, so the\n // open is safe to retry (PRO-18866).\n error.message === 'Egress connection severed outside of Hyperdrive' ||\n error.message === 'Network connection lost.' ||\n ('code' in error && error.code === 'CONNECTION_DESTROYED')))\n );\n}\n\n/**\n * Postgres.js closes a reserved connection when its socket dies, whether the\n * statement in flight fails with `CONNECTION_CLOSED` or with the socket error.\n * A statement sent to it afterwards is never answered: it throws in a timer\n * callback or is silently never written (PRO-17710). A destroyed connection\n * rejects at once, so it needs no guard.\n */\nfunction isConnectionClosed(error: unknown): error is Error {\n return (\n isConnectionReset(error) ||\n (error instanceof Error &&\n 'code' in error &&\n (error.code === 'CONNECTION_CLOSED' ||\n error.code === 'EPIPE' ||\n error.code === 'ETIMEDOUT'))\n );\n}\n\nfunction isQueryRetryDiagnosticError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n message === 'Egress connection severed outside of Hyperdrive' ||\n message === 'Network connection lost.' ||\n isNodeShuttingDown(error)\n );\n}\n\nasync function retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>,\n diagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'errorClass' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n) {\n let attemptCount = 0;\n let retried = false;\n let lastError: unknown;\n const emitDiagnostic = (outcome: PostgresRetryDiagnostic['outcome']) => {\n if (!diagnostic) return;\n diagnostic.emit({\n attemptCount,\n dataRegion: diagnostic.dataRegion,\n errorClass:\n lastError instanceof Error\n ? 'code' in lastError && typeof lastError.code === 'string'\n ? lastError.code\n : lastError.constructor.name\n : 'unknown',\n operationKind: diagnostic.operationKind,\n outcome,\n repositoryName: diagnostic.repositoryName,\n });\n };\n try {\n return await backOff(\n async () => {\n attemptCount++;\n return await operation();\n },\n {\n numOfAttempts: postgresRetryAttempts,\n startingDelay: parseDuration('1s'),\n maxDelay: parseDuration('5s'),\n // Scheduled chunk fan-outs open many connections at once; full jitter\n // keeps their retries from reconnecting in lockstep.\n jitter: 'full',\n async retry(error, attemptNumber) {\n lastError = error;\n const shouldRetry =\n attemptNumber < postgresRetryAttempts &&\n (await retry(error, attemptNumber));\n if (shouldRetry && diagnostic) {\n retried = true;\n emitDiagnostic('retrying');\n }\n return shouldRetry;\n },\n }\n );\n } catch (error) {\n lastError = error;\n if (diagnostic?.shouldEmit(error)) {\n emitDiagnostic(\n retried && attemptCount === postgresRetryAttempts\n ? 'exhausted'\n : 'notRetryable'\n );\n }\n throw error;\n }\n}\n\n/**\n * Replays a complete database operation after a PostgreSQL deadlock (40P01)\n * or lock timeout (55P03), using the same three-attempt jittered budget as\n * connection retries. The operation must own its transaction and must not\n * contain external side effects such as partner API writes.\n */\nexport function retryPostgresLockFailure<T>(operation: () => Promise<T>) {\n return retryPostgres(\n operation,\n (error) =>\n isPostgresError(error, { code: '40P01' }) ||\n isPostgresError(error, { code: '55P03' })\n );\n}\n\nclass RetryingPostgresJSDialect extends PostgresJSDialect {\n constructor(\n private readonly config: PostgresJSDialectConfig,\n private readonly retryDiagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'errorClass' | 'operationKind' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n },\n private readonly closeOnScriptTimeout?: () => void\n ) {\n super(config);\n }\n\n /** Ends the run when a script's database operation gets no answer (PRO-19037). */\n private async withScriptDeadline<T>(operation: () => Promise<T>) {\n if (!this.closeOnScriptTimeout) return await operation();\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n operation(),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n console.error('Postgres operation timed out', {\n timeoutMs: scriptQueryTimeoutMs,\n });\n this.closeOnScriptTimeout?.();\n reject(\n new KyselyError('Postgres operation timed out', {\n timeoutMs: scriptQueryTimeoutMs,\n })\n );\n }, scriptQueryTimeoutMs);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n type ConnectionState = {\n connection: Awaited<ReturnType<typeof driver.acquireConnection>>;\n inTransaction: boolean;\n /** Set once the reserved connection reported that its socket closed. */\n lost?: Error;\n };\n const connections = new WeakMap<DatabaseConnection, ConnectionState>();\n const getConnection = (connection: DatabaseConnection) => {\n const state = connections.get(connection);\n if (!state) throw new Error('Postgres connection state is unavailable');\n return state;\n };\n\n return {\n init: () => driver.init(),\n acquireConnection: async () => {\n const state: ConnectionState = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: <R>(compiledQuery: CompiledQuery) =>\n this.withScriptDeadline(() => {\n const operationKind = state.inTransaction\n ? 'transaction'\n : compiledQuery.query.kind === 'SelectQueryNode'\n ? 'select'\n : 'mutation';\n return retryPostgres<QueryResult<R>>(\n () => {\n if (state.lost) return Promise.reject(state.lost);\n return state.connection\n .executeQuery<R>(compiledQuery)\n .catch((error) => {\n if (isConnectionClosed(error)) state.lost = error;\n throw error;\n });\n },\n async (error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n if (\n state.inTransaction ||\n (!isRetryableConnectionError(error) &&\n (compiledQuery.query.kind !== 'SelectQueryNode' ||\n (!isConnectionReset(error) &&\n message !==\n 'Egress connection severed outside of Hyperdrive' &&\n message !== 'Network connection lost.' &&\n !isNodeShuttingDown(error))))\n ) {\n return false;\n }\n\n // Postgres.js already ejects a severed reserved connection.\n // Acquire a new reservation before replaying the safe read.\n state.connection = await driver.acquireConnection();\n state.lost = undefined;\n return true;\n },\n this.retryDiagnostic\n ? {\n ...this.retryDiagnostic,\n operationKind,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined\n );\n }),\n streamQuery: (compiledQuery, chunkSize) => {\n if (chunkSize === undefined) {\n throw new Error('Postgres stream chunk size is required');\n }\n return state.connection.streamQuery(compiledQuery, chunkSize);\n },\n };\n connections.set(connection, state);\n return connection;\n },\n beginTransaction: async (connection, settings) => {\n const state = getConnection(connection);\n state.inTransaction = true;\n try {\n await this.withScriptDeadline(() =>\n driver.beginTransaction(state.connection, settings)\n );\n } catch (error) {\n state.inTransaction = false;\n if (isConnectionClosed(error)) state.lost = error;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n if (state.lost) throw state.lost;\n await this.withScriptDeadline(() =>\n driver.commitTransaction(state.connection)\n );\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n // PostgreSQL rolls the transaction back when its session ends, and a\n // statement on the closed connection would never be answered.\n if (state.lost) return;\n await this.withScriptDeadline(() =>\n driver.rollbackTransaction(state.connection)\n );\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.savepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.rollbackToSavepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.releaseSavepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n releaseConnection: async (connection) => {\n const state = getConnection(connection);\n connections.delete(connection);\n // Releasing a closed connection would put it back in the open pool,\n // and the next statement on it would hang. Postgres.js reconnects\n // from the closed pool on demand, and a failed reconnect is a\n // retryable CONNECT_TIMEOUT.\n if (state.lost) return;\n await driver.releaseConnection(state.connection);\n },\n destroy: () => driver.destroy(),\n };\n }\n}\n\nexport type Kysely = K<DB>;\nexport type ControlPlaneKysely = K<ControlPlaneDB>;\nexport type ControlPlaneTransaction = T<ControlPlaneDB>;\nexport function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts) {\n console.debug('Creating Kysely instance');\n const emitRetryDiagnostic =\n options?.onRetryDiagnostic ??\n (options?.repositoryName\n ? (diagnostic: PostgresRetryDiagnostic) =>\n console.warn('Postgres operation retry diagnostic', diagnostic)\n : undefined);\n const reserveConnection = postgres.reserve.bind(postgres);\n postgres.reserve = async () => {\n const connection = await retryPostgres(\n reserveConnection,\n isRetryableConnectionAcquisitionError,\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n operationKind: 'acquisition',\n repositoryName: options?.repositoryName,\n shouldEmit: isRetryableConnectionAcquisitionError,\n }\n : undefined\n );\n if (options?.hyperdrive) {\n const unsafe = connection.unsafe;\n connection.unsafe = (query, parameters, queryOptions) =>\n unsafe(query, parameters, { ...queryOptions, prepare: true });\n }\n return connection;\n };\n const kysely = getKysely<Database>(\n new RetryingPostgresJSDialect(\n { postgres },\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n repositoryName: options?.repositoryName,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined,\n options?.script\n ? () => void postgres.end({ timeout: 0 }).catch(() => undefined)\n : undefined\n ),\n {\n repositoryName: options?.repositoryName,\n log: options?.log,\n }\n );\n kysely.destroy = async () => {\n console.debug('Closing Kysely connection');\n await postgres.end({ timeout: 5 }).catch(() => undefined);\n const index = _connections.indexOf(postgres);\n if (index !== -1) _connections.splice(index, 1);\n };\n\n return kysely;\n}\n\nconst scriptQueryTimeoutMs = parseDuration('1h');\nlet _connections: postgres.Sql[] = [];\nexport function usePostgres(\n connectionString: string,\n opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive' | 'onReserve' | 'script'>\n) {\n const ssl = opt?.forceDisableSSL !== true && !opt?.hyperdrive;\n const sql = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n target_session_attrs: 'read-write',\n // Named prepared statements: PRO-17965 (Hyperdrive and Crunchy PgBouncer).\n prepare: true,\n ...(opt?.hyperdrive\n ? {\n max: 5,\n // Retire idle clients before Hyperdrive can close them asynchronously.\n idle_timeout: 10,\n statement_types: hyperdriveStatementTypes[opt.hyperdrive],\n }\n : {\n connect_timeout: 10,\n idle_timeout: 60,\n ...(opt?.script ? { keep_alive: 10 } : {}),\n }),\n });\n if (opt?.onReserve) {\n const { onReserve } = opt;\n const reserve = sql.reserve.bind(sql);\n // Innermost wrapper: it times each open or reuse of a connection, the\n // startup probe too, and is not part of the retry loop (PRO-18952).\n sql.reserve = async () => {\n const startedAtEpochMs = Date.now();\n const startedAt = performance.now();\n try {\n return await reserve();\n } finally {\n onReserve({\n durationMs: performance.now() - startedAt,\n startedAtEpochMs,\n });\n }\n };\n }\n // statement_timeout/lock_timeout are role-level settings on the cluster\n // (ALTER ROLE application SET ...) so they cover every pooled\n // connection; per-session SETs here only ever applied to one of them\n _connections.push(sql);\n return sql;\n}\n\nexport async function useAsyncPostgres(connectionString: string, opt?: PgOpt) {\n const delayMs = 2500;\n const probe = opt?.probe === true;\n const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;\n const url = new URL(connectionString);\n\n console.debug(\n `Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${opt?.forceDisableSSL !== true && !opt?.hyperdrive}, and port=${url.port}`\n );\n if (_connections.length > 0)\n console.warn(`We already have ${_connections.length} Postgres connections`);\n\n for (let attempt = 1; attempt <= retries; attempt++) {\n let sql: Sql | undefined;\n try {\n sql = usePostgres(connectionString, opt);\n if (probe) {\n // Opening a connection already checks that the session is writable\n // and loads the array types; a probe query would add a round trip.\n (await sql.reserve()).release();\n }\n return sql;\n } catch (err) {\n if (sql) {\n await sql.end({ timeout: 0 }).catch(() => undefined);\n _connections.splice(_connections.indexOf(sql), 1);\n }\n if (attempt === retries) throw err;\n console.warn(\n `Postgres connection failed (attempt ${attempt}), retrying...`\n );\n console.error('error', err);\n await new Promise((res) => setTimeout(res, delayMs));\n }\n }\n throw new KyselyError('Unable to connect to Postgres');\n}\n\nexport async function useAsyncKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return useKysely(sql, opt);\n}\n\nexport async function useAsyncNeonWebSocketKysely(\n connectionString: string,\n opt?: Pick<PgOpt, 'probe'> & KyselyOpts\n) {\n const pool = new Pool({ connectionString, max: 5 });\n const kysely = getKysely<DB>(new PostgresDialect({ pool }), opt ?? {});\n kysely.destroy = async () => {\n console.debug('Closing Neon WebSocket Kysely connection');\n await pool.end();\n };\n if (opt?.probe) await pool.query('select 1');\n return kysely;\n}\n\nexport function useControlPlaneKysely(postgres: Sql, options?: KyselyOpts) {\n return withControlPlaneSchema(\n useKysely<ControlPlaneDB>(postgres, options),\n 'public'\n );\n}\n\nexport async function useAsyncControlPlaneKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n return useControlPlaneKysely(\n await useAsyncPostgres(connectionString, opt),\n opt\n );\n}\n\nexport async function forceCloseAllPostgres(timeoutMs = 5000) {\n await Promise.race([\n Promise.all(\n _connections.map((pg) =>\n pg.end({ timeout: timeoutMs / 1000 }).catch(() => undefined)\n )\n ),\n new Promise((res) => setTimeout(res, timeoutMs + 1000)),\n ]);\n _connections = [];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { backOff } from 'exponential-backoff';\nimport { Pool } from '@neondatabase/serverless';\nimport type {\n CompiledQuery,\n DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\n QueryResult,\n Transaction as T,\n} from 'kysely';\nimport { PostgresDialect } from 'kysely';\nimport {\n PostgresJSDialect,\n type PostgresJSDialectConfig,\n PostgresJSDriver,\n} from 'kysely-postgres-js';\nimport postgres, { type Sql } from 'postgres';\nimport { type ControlPlaneDB, withControlPlaneSchema } from './control-plane';\nimport { KyselyError } from './error';\nimport { getKysely } from './plugins';\nimport { isPostgresError } from './postgres-error';\n\nexport type { Insertable, LogEvent } from 'kysely';\nexport * from './connect-handoff';\nexport * from './error';\nexport * from './isomorphic';\nexport * from './postgres-error';\nexport * from './query';\nexport * from './regional';\nexport * from './transaction';\n\nimport { parseDuration } from '@vrplatform/utils';\nimport type { TenantDataRegion } from './regional';\nimport type { DB } from './v1.generated';\n\n/** The database a Worker reaches through its Hyperdrive binding. */\ntype HyperdriveDatabase = 'controlPlane' | 'regional';\n\ntype KyselyOpts = {\n dataRegion?: TenantDataRegion;\n hyperdrive?: HyperdriveDatabase;\n /** Called after every connection reservation, including the startup probe. */\n onReserve?: (timing: {\n durationMs: number;\n startedAtEpochMs: number;\n }) => void;\n onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;\n repositoryName?: string;\n log?: true | LogConfig;\n /**\n * Scripts and repairs (PRO-19037). Probes an idle TCP connection after 10 s.\n * A query, commit, begin, rollback or savepoint with no answer for an hour,\n * longer than any statement timeout a script sets, fails the run and closes\n * the Postgres client that issued it. Backstop for a connection the kernel\n * keeps open while the peer never answers.\n */\n script?: true;\n};\n\ntype PostgresRetryDiagnostic = {\n attemptCount: number;\n dataRegion?: TenantDataRegion;\n errorClass: string;\n operationKind: 'acquisition' | 'mutation' | 'select' | 'transaction';\n outcome: 'exhausted' | 'notRetryable' | 'retrying';\n repositoryName?: string;\n};\n\ntype PgOpt = {\n forceDisableSSL?: boolean;\n probe?: true;\n retries?: false | number;\n} & Pick<KyselyOpts, 'hyperdrive' | 'onReserve' | 'script'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n 'Timed out while creating a new server connection.',\n // Neon rejects the login before any statement runs (PRO-19169).\n 'Failed to acquire permit to connect to the database',\n];\nconst postgresRetryAttempts = 3;\n\n/**\n * Parameter types PostgreSQL described per statement signature (PRO-18871).\n * Postgres.js describes a statement in a round trip of its own before it can\n * execute it when a parameter type is unknown, and a Worker request always\n * starts on new connections. The patched driver reads and fills this map\n * through its `statement_types` option and then parses, describes, binds and\n * executes a known statement in one round trip. It forgets a statement's\n * types when the statement fails, so a schema change is described again.\n */\nclass StatementTypes extends Map<string, number[]> {\n override set(signature: string, types: number[]) {\n if (!this.has(signature) && this.size >= 2000) {\n this.delete(this.keys().next().value!);\n }\n return super.set(signature, types);\n }\n}\n\n/**\n * Kept for the isolate's lifetime, one map per origin database. One isolate\n * can open several databases through different Hyperdrive bindings, and enum\n * and row types have different OIDs in each, so the key is the binding's\n * connection string, not the role (PRO-19353).\n */\nconst hyperdriveStatementTypes = new Map<string, StatementTypes>();\n\n/**\n * Array type OIDs by element type OID, per origin database (PRO-19353).\n * Postgres.js looks them up on every new connection, one origin round trip\n * each, about 100 ms from Crunchy to the control plane. The first connection\n * to a database in an isolate fills its map and later connections reuse it.\n * A migration that adds an array type reaches an isolate when it restarts;\n * until then values of that type arrive as text.\n */\nconst hyperdriveArrayTypes = new Map<string, Map<number, number>>();\n\nfunction isRetryableConnectionError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return retryableMessages.some((retryable) => message.includes(retryable));\n}\n\nfunction isNodeShuttingDown(error: unknown) {\n return (\n error instanceof Error &&\n (error.message === 'Node shutting down' ||\n error.message === 'Node shutting down.' ||\n error.message === 'shutting down')\n );\n}\n\nfunction isConnectionReset(error: unknown) {\n return (\n error instanceof Error && 'code' in error && error.code === 'ECONNRESET'\n );\n}\n\nfunction isRetryableConnectionAcquisitionError(error: unknown) {\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n // Hyperdrive refuses any new connection while its node shuts down\n // (PRO-19168).\n isNodeShuttingDown(error) ||\n (error instanceof Error &&\n (error.message === 'connection attempt failed' ||\n // Opening a connection happens before any statement runs, so the\n // open is safe to retry (PRO-18866).\n error.message === 'Egress connection severed outside of Hyperdrive' ||\n error.message === 'Network connection lost.' ||\n ('code' in error && error.code === 'CONNECTION_DESTROYED')))\n );\n}\n\n/**\n * Postgres.js closes a reserved connection when its socket dies, whether the\n * statement in flight fails with `CONNECTION_CLOSED` or with the socket error.\n * A statement sent to it afterwards is never answered: it throws in a timer\n * callback or is silently never written (PRO-17710). A destroyed connection\n * rejects at once, so it needs no guard.\n */\nfunction isConnectionClosed(error: unknown): error is Error {\n return (\n isConnectionReset(error) ||\n (error instanceof Error &&\n 'code' in error &&\n (error.code === 'CONNECTION_CLOSED' ||\n error.code === 'EPIPE' ||\n error.code === 'ETIMEDOUT'))\n );\n}\n\nfunction isQueryRetryDiagnosticError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n message === 'Egress connection severed outside of Hyperdrive' ||\n message === 'Network connection lost.' ||\n isNodeShuttingDown(error)\n );\n}\n\nasync function retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>,\n diagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'errorClass' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n) {\n let attemptCount = 0;\n let retried = false;\n let lastError: unknown;\n const emitDiagnostic = (outcome: PostgresRetryDiagnostic['outcome']) => {\n if (!diagnostic) return;\n diagnostic.emit({\n attemptCount,\n dataRegion: diagnostic.dataRegion,\n errorClass:\n lastError instanceof Error\n ? 'code' in lastError && typeof lastError.code === 'string'\n ? lastError.code\n : lastError.constructor.name\n : 'unknown',\n operationKind: diagnostic.operationKind,\n outcome,\n repositoryName: diagnostic.repositoryName,\n });\n };\n try {\n return await backOff(\n async () => {\n attemptCount++;\n return await operation();\n },\n {\n numOfAttempts: postgresRetryAttempts,\n startingDelay: parseDuration('1s'),\n maxDelay: parseDuration('5s'),\n // Scheduled chunk fan-outs open many connections at once; full jitter\n // keeps their retries from reconnecting in lockstep.\n jitter: 'full',\n async retry(error, attemptNumber) {\n lastError = error;\n const shouldRetry =\n attemptNumber < postgresRetryAttempts &&\n (await retry(error, attemptNumber));\n if (shouldRetry && diagnostic) {\n retried = true;\n emitDiagnostic('retrying');\n }\n return shouldRetry;\n },\n }\n );\n } catch (error) {\n lastError = error;\n if (diagnostic?.shouldEmit(error)) {\n emitDiagnostic(\n retried && attemptCount === postgresRetryAttempts\n ? 'exhausted'\n : 'notRetryable'\n );\n }\n throw error;\n }\n}\n\n/**\n * Replays a complete database operation after a PostgreSQL deadlock (40P01)\n * or lock timeout (55P03), using the same three-attempt jittered budget as\n * connection retries. The operation must own its transaction and must not\n * contain external side effects such as partner API writes.\n */\nexport function retryPostgresLockFailure<T>(operation: () => Promise<T>) {\n return retryPostgres(\n operation,\n (error) =>\n isPostgresError(error, { code: '40P01' }) ||\n isPostgresError(error, { code: '55P03' })\n );\n}\n\nclass RetryingPostgresJSDialect extends PostgresJSDialect {\n constructor(\n private readonly config: PostgresJSDialectConfig,\n private readonly retryDiagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'errorClass' | 'operationKind' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n },\n private readonly closeOnScriptTimeout?: () => void\n ) {\n super(config);\n }\n\n /** Ends the run when a script's database operation gets no answer (PRO-19037). */\n private async withScriptDeadline<T>(operation: () => Promise<T>) {\n if (!this.closeOnScriptTimeout) return await operation();\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n operation(),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n console.error('Postgres operation timed out', {\n timeoutMs: scriptQueryTimeoutMs,\n });\n this.closeOnScriptTimeout?.();\n reject(\n new KyselyError('Postgres operation timed out', {\n timeoutMs: scriptQueryTimeoutMs,\n })\n );\n }, scriptQueryTimeoutMs);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n type ConnectionState = {\n connection: Awaited<ReturnType<typeof driver.acquireConnection>>;\n inTransaction: boolean;\n /** Set once the reserved connection reported that its socket closed. */\n lost?: Error;\n };\n const connections = new WeakMap<DatabaseConnection, ConnectionState>();\n const getConnection = (connection: DatabaseConnection) => {\n const state = connections.get(connection);\n if (!state) throw new Error('Postgres connection state is unavailable');\n return state;\n };\n\n return {\n init: () => driver.init(),\n acquireConnection: async () => {\n const state: ConnectionState = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: <R>(compiledQuery: CompiledQuery) =>\n this.withScriptDeadline(() => {\n const operationKind = state.inTransaction\n ? 'transaction'\n : compiledQuery.query.kind === 'SelectQueryNode'\n ? 'select'\n : 'mutation';\n return retryPostgres<QueryResult<R>>(\n () => {\n if (state.lost) return Promise.reject(state.lost);\n return state.connection\n .executeQuery<R>(compiledQuery)\n .catch((error) => {\n if (isConnectionClosed(error)) state.lost = error;\n throw error;\n });\n },\n async (error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n if (\n state.inTransaction ||\n (!isRetryableConnectionError(error) &&\n (compiledQuery.query.kind !== 'SelectQueryNode' ||\n (!isConnectionReset(error) &&\n message !==\n 'Egress connection severed outside of Hyperdrive' &&\n message !== 'Network connection lost.' &&\n !isNodeShuttingDown(error))))\n ) {\n return false;\n }\n\n // Postgres.js already ejects a severed reserved connection.\n // Acquire a new reservation before replaying the safe read.\n state.connection = await driver.acquireConnection();\n state.lost = undefined;\n return true;\n },\n this.retryDiagnostic\n ? {\n ...this.retryDiagnostic,\n operationKind,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined\n );\n }),\n streamQuery: (compiledQuery, chunkSize) => {\n if (chunkSize === undefined) {\n throw new Error('Postgres stream chunk size is required');\n }\n return state.connection.streamQuery(compiledQuery, chunkSize);\n },\n };\n connections.set(connection, state);\n return connection;\n },\n beginTransaction: async (connection, settings) => {\n const state = getConnection(connection);\n state.inTransaction = true;\n try {\n await this.withScriptDeadline(() =>\n driver.beginTransaction(state.connection, settings)\n );\n } catch (error) {\n state.inTransaction = false;\n if (isConnectionClosed(error)) state.lost = error;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n if (state.lost) throw state.lost;\n await this.withScriptDeadline(() =>\n driver.commitTransaction(state.connection)\n );\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n // PostgreSQL rolls the transaction back when its session ends, and a\n // statement on the closed connection would never be answered.\n if (state.lost) return;\n await this.withScriptDeadline(() =>\n driver.rollbackTransaction(state.connection)\n );\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.savepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.rollbackToSavepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.releaseSavepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n releaseConnection: async (connection) => {\n const state = getConnection(connection);\n connections.delete(connection);\n // Releasing a closed connection would put it back in the open pool,\n // and the next statement on it would hang. Postgres.js reconnects\n // from the closed pool on demand, and a failed reconnect is a\n // retryable CONNECT_TIMEOUT.\n if (state.lost) return;\n await driver.releaseConnection(state.connection);\n },\n destroy: () => driver.destroy(),\n };\n }\n}\n\nexport type Kysely = K<DB>;\nexport type ControlPlaneKysely = K<ControlPlaneDB>;\nexport type ControlPlaneTransaction = T<ControlPlaneDB>;\nexport function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts) {\n console.debug('Creating Kysely instance');\n const emitRetryDiagnostic =\n options?.onRetryDiagnostic ??\n (options?.repositoryName\n ? (diagnostic: PostgresRetryDiagnostic) =>\n console.warn('Postgres operation retry diagnostic', diagnostic)\n : undefined);\n const reserveConnection = postgres.reserve.bind(postgres);\n postgres.reserve = async () => {\n const connection = await retryPostgres(\n reserveConnection,\n isRetryableConnectionAcquisitionError,\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n operationKind: 'acquisition',\n repositoryName: options?.repositoryName,\n shouldEmit: isRetryableConnectionAcquisitionError,\n }\n : undefined\n );\n if (options?.hyperdrive) {\n const unsafe = connection.unsafe;\n connection.unsafe = (query, parameters, queryOptions) =>\n unsafe(query, parameters, { ...queryOptions, prepare: true });\n }\n return connection;\n };\n const kysely = getKysely<Database>(\n new RetryingPostgresJSDialect(\n { postgres },\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n repositoryName: options?.repositoryName,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined,\n options?.script\n ? () => void postgres.end({ timeout: 0 }).catch(() => undefined)\n : undefined\n ),\n {\n repositoryName: options?.repositoryName,\n log: options?.log,\n }\n );\n kysely.destroy = async () => {\n console.debug('Closing Kysely connection');\n await postgres.end({ timeout: 5 }).catch(() => undefined);\n const index = _connections.indexOf(postgres);\n if (index !== -1) _connections.splice(index, 1);\n };\n\n return kysely;\n}\n\nconst scriptQueryTimeoutMs = parseDuration('1h');\nlet _connections: postgres.Sql[] = [];\nexport function usePostgres(\n connectionString: string,\n opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive' | 'onReserve' | 'script'>\n) {\n const ssl = opt?.forceDisableSSL !== true && !opt?.hyperdrive;\n if (opt?.hyperdrive && !hyperdriveStatementTypes.has(connectionString)) {\n // A Worker binds seven Hyperdrive configs. Keep a few more, so a binding\n // whose host changed between requests cannot grow the caches unbounded.\n if (hyperdriveStatementTypes.size >= 16) {\n const oldest = hyperdriveStatementTypes.keys().next().value!;\n hyperdriveStatementTypes.delete(oldest);\n hyperdriveArrayTypes.delete(oldest);\n }\n hyperdriveStatementTypes.set(connectionString, new StatementTypes());\n hyperdriveArrayTypes.set(connectionString, new Map());\n }\n const sql = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n // Named prepared statements: PRO-17965 (Hyperdrive and Crunchy PgBouncer).\n prepare: true,\n ...(opt?.hyperdrive\n ? {\n max: 5,\n // Retire idle clients before Hyperdrive can close them asynchronously.\n idle_timeout: 10,\n statement_types: hyperdriveStatementTypes.get(connectionString),\n array_types: hyperdriveArrayTypes.get(connectionString),\n // No read-write check (PRO-17156): Hyperdrive pools by transaction,\n // so the check covered one origin connection, never the ones later\n // statements run on, and it cost an origin round trip per\n // connection (PRO-19353).\n }\n : {\n target_session_attrs: 'read-write',\n connect_timeout: 10,\n idle_timeout: 60,\n ...(opt?.script ? { keep_alive: 10 } : {}),\n }),\n });\n if (opt?.onReserve) {\n const { onReserve } = opt;\n const reserve = sql.reserve.bind(sql);\n // Innermost wrapper: it times each open or reuse of a connection, the\n // startup probe too, and is not part of the retry loop (PRO-18952).\n sql.reserve = async () => {\n const startedAtEpochMs = Date.now();\n const startedAt = performance.now();\n try {\n return await reserve();\n } finally {\n onReserve({\n durationMs: performance.now() - startedAt,\n startedAtEpochMs,\n });\n }\n };\n }\n // statement_timeout/lock_timeout are role-level settings on the cluster\n // (ALTER ROLE application SET ...) so they cover every pooled\n // connection; per-session SETs here only ever applied to one of them\n _connections.push(sql);\n return sql;\n}\n\nexport async function useAsyncPostgres(connectionString: string, opt?: PgOpt) {\n const delayMs = 2500;\n const probe = opt?.probe === true;\n const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;\n const url = new URL(connectionString);\n\n console.debug(\n `Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${opt?.forceDisableSSL !== true && !opt?.hyperdrive}, and port=${url.port}`\n );\n if (_connections.length > 0)\n console.warn(`We already have ${_connections.length} Postgres connections`);\n\n for (let attempt = 1; attempt <= retries; attempt++) {\n let sql: Sql | undefined;\n try {\n sql = usePostgres(connectionString, opt);\n if (probe) {\n // Opening a connection already checks that the session is writable\n // and loads the array types; a probe query would add a round trip.\n (await sql.reserve()).release();\n }\n return sql;\n } catch (err) {\n if (sql) {\n await sql.end({ timeout: 0 }).catch(() => undefined);\n _connections.splice(_connections.indexOf(sql), 1);\n }\n if (attempt === retries) throw err;\n console.warn(\n `Postgres connection failed (attempt ${attempt}), retrying...`\n );\n console.error('error', err);\n await new Promise((res) => setTimeout(res, delayMs));\n }\n }\n throw new KyselyError('Unable to connect to Postgres');\n}\n\nexport async function useAsyncKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return useKysely(sql, opt);\n}\n\nexport async function useAsyncNeonWebSocketKysely(\n connectionString: string,\n opt?: Pick<PgOpt, 'probe'> & KyselyOpts\n) {\n const pool = new Pool({ connectionString, max: 5 });\n const kysely = getKysely<DB>(new PostgresDialect({ pool }), opt ?? {});\n kysely.destroy = async () => {\n console.debug('Closing Neon WebSocket Kysely connection');\n await pool.end();\n };\n if (opt?.probe) await pool.query('select 1');\n return kysely;\n}\n\nexport function useControlPlaneKysely(postgres: Sql, options?: KyselyOpts) {\n return withControlPlaneSchema(\n useKysely<ControlPlaneDB>(postgres, options),\n 'public'\n );\n}\n\nexport async function useAsyncControlPlaneKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n return useControlPlaneKysely(\n await useAsyncPostgres(connectionString, opt),\n opt\n );\n}\n\nexport async function forceCloseAllPostgres(timeoutMs = 5000) {\n await Promise.race([\n Promise.all(\n _connections.map((pg) =>\n pg.end({ timeout: timeoutMs / 1000 }).catch(() => undefined)\n )\n ),\n new Promise((res) => setTimeout(res, timeoutMs + 1000)),\n ]);\n _connections = [];\n}\n"]}
|
package/build/module/index.js
CHANGED
|
@@ -42,11 +42,22 @@ class StatementTypes extends Map {
|
|
|
42
42
|
return super.set(signature, types);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Kept for the isolate's lifetime, one map per origin database. One isolate
|
|
47
|
+
* can open several databases through different Hyperdrive bindings, and enum
|
|
48
|
+
* and row types have different OIDs in each, so the key is the binding's
|
|
49
|
+
* connection string, not the role (PRO-19353).
|
|
50
|
+
*/
|
|
51
|
+
const hyperdriveStatementTypes = new Map();
|
|
52
|
+
/**
|
|
53
|
+
* Array type OIDs by element type OID, per origin database (PRO-19353).
|
|
54
|
+
* Postgres.js looks them up on every new connection, one origin round trip
|
|
55
|
+
* each, about 100 ms from Crunchy to the control plane. The first connection
|
|
56
|
+
* to a database in an isolate fills its map and later connections reuse it.
|
|
57
|
+
* A migration that adds an array type reaches an isolate when it restarts;
|
|
58
|
+
* until then values of that type arrive as text.
|
|
59
|
+
*/
|
|
60
|
+
const hyperdriveArrayTypes = new Map();
|
|
50
61
|
function isRetryableConnectionError(error) {
|
|
51
62
|
const message = error instanceof Error ? error.message : String(error);
|
|
52
63
|
return retryableMessages.some((retryable) => message.includes(retryable));
|
|
@@ -382,9 +393,19 @@ const scriptQueryTimeoutMs = parseDuration('1h');
|
|
|
382
393
|
let _connections = [];
|
|
383
394
|
export function usePostgres(connectionString, opt) {
|
|
384
395
|
const ssl = opt?.forceDisableSSL !== true && !opt?.hyperdrive;
|
|
396
|
+
if (opt?.hyperdrive && !hyperdriveStatementTypes.has(connectionString)) {
|
|
397
|
+
// A Worker binds seven Hyperdrive configs. Keep a few more, so a binding
|
|
398
|
+
// whose host changed between requests cannot grow the caches unbounded.
|
|
399
|
+
if (hyperdriveStatementTypes.size >= 16) {
|
|
400
|
+
const oldest = hyperdriveStatementTypes.keys().next().value;
|
|
401
|
+
hyperdriveStatementTypes.delete(oldest);
|
|
402
|
+
hyperdriveArrayTypes.delete(oldest);
|
|
403
|
+
}
|
|
404
|
+
hyperdriveStatementTypes.set(connectionString, new StatementTypes());
|
|
405
|
+
hyperdriveArrayTypes.set(connectionString, new Map());
|
|
406
|
+
}
|
|
385
407
|
const sql = postgres(connectionString, {
|
|
386
408
|
ssl: ssl ? 'require' : false,
|
|
387
|
-
target_session_attrs: 'read-write',
|
|
388
409
|
// Named prepared statements: PRO-17965 (Hyperdrive and Crunchy PgBouncer).
|
|
389
410
|
prepare: true,
|
|
390
411
|
...(opt?.hyperdrive
|
|
@@ -392,9 +413,15 @@ export function usePostgres(connectionString, opt) {
|
|
|
392
413
|
max: 5,
|
|
393
414
|
// Retire idle clients before Hyperdrive can close them asynchronously.
|
|
394
415
|
idle_timeout: 10,
|
|
395
|
-
statement_types: hyperdriveStatementTypes
|
|
416
|
+
statement_types: hyperdriveStatementTypes.get(connectionString),
|
|
417
|
+
array_types: hyperdriveArrayTypes.get(connectionString),
|
|
418
|
+
// No read-write check (PRO-17156): Hyperdrive pools by transaction,
|
|
419
|
+
// so the check covered one origin connection, never the ones later
|
|
420
|
+
// statements run on, and it cost an origin round trip per
|
|
421
|
+
// connection (PRO-19353).
|
|
396
422
|
}
|
|
397
423
|
: {
|
|
424
|
+
target_session_attrs: 'read-write',
|
|
398
425
|
connect_timeout: 10,
|
|
399
426
|
idle_timeout: 60,
|
|
400
427
|
...(opt?.script ? { keep_alive: 10 } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import { backOff } from 'exponential-backoff';\nimport { Pool } from '@neondatabase/serverless';\nimport type {\n CompiledQuery,\n DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\n QueryResult,\n Transaction as T,\n} from 'kysely';\nimport { PostgresDialect } from 'kysely';\nimport {\n PostgresJSDialect,\n type PostgresJSDialectConfig,\n PostgresJSDriver,\n} from 'kysely-postgres-js';\nimport postgres, { type Sql } from 'postgres';\nimport { type ControlPlaneDB, withControlPlaneSchema } from './control-plane';\nimport { KyselyError } from './error';\nimport { getKysely } from './plugins';\nimport { isPostgresError } from './postgres-error';\n\nexport type { Insertable, LogEvent } from 'kysely';\nexport * from './connect-handoff';\nexport * from './error';\nexport * from './isomorphic';\nexport * from './postgres-error';\nexport * from './query';\nexport * from './regional';\nexport * from './transaction';\n\nimport { parseDuration } from '@vrplatform/utils';\nimport type { TenantDataRegion } from './regional';\nimport type { DB } from './v1.generated';\n\n/** The database a Worker reaches through its Hyperdrive binding. */\ntype HyperdriveDatabase = 'controlPlane' | 'regional';\n\ntype KyselyOpts = {\n dataRegion?: TenantDataRegion;\n hyperdrive?: HyperdriveDatabase;\n /** Called after every connection reservation, including the startup probe. */\n onReserve?: (timing: {\n durationMs: number;\n startedAtEpochMs: number;\n }) => void;\n onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;\n repositoryName?: string;\n log?: true | LogConfig;\n /**\n * Scripts and repairs (PRO-19037). Probes an idle TCP connection after 10 s.\n * A query, commit, begin, rollback or savepoint with no answer for an hour,\n * longer than any statement timeout a script sets, fails the run and closes\n * the Postgres client that issued it. Backstop for a connection the kernel\n * keeps open while the peer never answers.\n */\n script?: true;\n};\n\ntype PostgresRetryDiagnostic = {\n attemptCount: number;\n dataRegion?: TenantDataRegion;\n errorClass: string;\n operationKind: 'acquisition' | 'mutation' | 'select' | 'transaction';\n outcome: 'exhausted' | 'notRetryable' | 'retrying';\n repositoryName?: string;\n};\n\ntype PgOpt = {\n forceDisableSSL?: boolean;\n probe?: true;\n retries?: false | number;\n} & Pick<KyselyOpts, 'hyperdrive' | 'onReserve' | 'script'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n 'Timed out while creating a new server connection.',\n // Neon rejects the login before any statement runs (PRO-19169).\n 'Failed to acquire permit to connect to the database',\n];\nconst postgresRetryAttempts = 3;\n\n/**\n * Parameter types PostgreSQL described per statement signature (PRO-18871).\n * Postgres.js describes a statement in a round trip of its own before it can\n * execute it when a parameter type is unknown, and a Worker request always\n * starts on new connections. The patched driver reads and fills this map\n * through its `statement_types` option and then parses, describes, binds and\n * executes a known statement in one round trip. It forgets a statement's\n * types when the statement fails, so a schema change is described again.\n */\nclass StatementTypes extends Map<string, number[]> {\n override set(signature: string, types: number[]) {\n if (!this.has(signature) && this.size >= 2000) {\n this.delete(this.keys().next().value!);\n }\n return super.set(signature, types);\n }\n}\n\n/** Kept for the isolate's lifetime, one map per Hyperdrive database. */\nconst hyperdriveStatementTypes: Record<HyperdriveDatabase, StatementTypes> = {\n controlPlane: new StatementTypes(),\n regional: new StatementTypes(),\n};\n\nfunction isRetryableConnectionError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return retryableMessages.some((retryable) => message.includes(retryable));\n}\n\nfunction isNodeShuttingDown(error: unknown) {\n return (\n error instanceof Error &&\n (error.message === 'Node shutting down' ||\n error.message === 'Node shutting down.' ||\n error.message === 'shutting down')\n );\n}\n\nfunction isConnectionReset(error: unknown) {\n return (\n error instanceof Error && 'code' in error && error.code === 'ECONNRESET'\n );\n}\n\nfunction isRetryableConnectionAcquisitionError(error: unknown) {\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n // Hyperdrive refuses any new connection while its node shuts down\n // (PRO-19168).\n isNodeShuttingDown(error) ||\n (error instanceof Error &&\n (error.message === 'connection attempt failed' ||\n // Opening a connection happens before any statement runs, so the\n // open is safe to retry (PRO-18866).\n error.message === 'Egress connection severed outside of Hyperdrive' ||\n error.message === 'Network connection lost.' ||\n ('code' in error && error.code === 'CONNECTION_DESTROYED')))\n );\n}\n\n/**\n * Postgres.js closes a reserved connection when its socket dies, whether the\n * statement in flight fails with `CONNECTION_CLOSED` or with the socket error.\n * A statement sent to it afterwards is never answered: it throws in a timer\n * callback or is silently never written (PRO-17710). A destroyed connection\n * rejects at once, so it needs no guard.\n */\nfunction isConnectionClosed(error: unknown): error is Error {\n return (\n isConnectionReset(error) ||\n (error instanceof Error &&\n 'code' in error &&\n (error.code === 'CONNECTION_CLOSED' ||\n error.code === 'EPIPE' ||\n error.code === 'ETIMEDOUT'))\n );\n}\n\nfunction isQueryRetryDiagnosticError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n message === 'Egress connection severed outside of Hyperdrive' ||\n message === 'Network connection lost.' ||\n isNodeShuttingDown(error)\n );\n}\n\nasync function retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>,\n diagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'errorClass' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n) {\n let attemptCount = 0;\n let retried = false;\n let lastError: unknown;\n const emitDiagnostic = (outcome: PostgresRetryDiagnostic['outcome']) => {\n if (!diagnostic) return;\n diagnostic.emit({\n attemptCount,\n dataRegion: diagnostic.dataRegion,\n errorClass:\n lastError instanceof Error\n ? 'code' in lastError && typeof lastError.code === 'string'\n ? lastError.code\n : lastError.constructor.name\n : 'unknown',\n operationKind: diagnostic.operationKind,\n outcome,\n repositoryName: diagnostic.repositoryName,\n });\n };\n try {\n return await backOff(\n async () => {\n attemptCount++;\n return await operation();\n },\n {\n numOfAttempts: postgresRetryAttempts,\n startingDelay: parseDuration('1s'),\n maxDelay: parseDuration('5s'),\n // Scheduled chunk fan-outs open many connections at once; full jitter\n // keeps their retries from reconnecting in lockstep.\n jitter: 'full',\n async retry(error, attemptNumber) {\n lastError = error;\n const shouldRetry =\n attemptNumber < postgresRetryAttempts &&\n (await retry(error, attemptNumber));\n if (shouldRetry && diagnostic) {\n retried = true;\n emitDiagnostic('retrying');\n }\n return shouldRetry;\n },\n }\n );\n } catch (error) {\n lastError = error;\n if (diagnostic?.shouldEmit(error)) {\n emitDiagnostic(\n retried && attemptCount === postgresRetryAttempts\n ? 'exhausted'\n : 'notRetryable'\n );\n }\n throw error;\n }\n}\n\n/**\n * Replays a complete database operation after a PostgreSQL deadlock (40P01)\n * or lock timeout (55P03), using the same three-attempt jittered budget as\n * connection retries. The operation must own its transaction and must not\n * contain external side effects such as partner API writes.\n */\nexport function retryPostgresLockFailure<T>(operation: () => Promise<T>) {\n return retryPostgres(\n operation,\n (error) =>\n isPostgresError(error, { code: '40P01' }) ||\n isPostgresError(error, { code: '55P03' })\n );\n}\n\nclass RetryingPostgresJSDialect extends PostgresJSDialect {\n constructor(\n private readonly config: PostgresJSDialectConfig,\n private readonly retryDiagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'errorClass' | 'operationKind' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n },\n private readonly closeOnScriptTimeout?: () => void\n ) {\n super(config);\n }\n\n /** Ends the run when a script's database operation gets no answer (PRO-19037). */\n private async withScriptDeadline<T>(operation: () => Promise<T>) {\n if (!this.closeOnScriptTimeout) return await operation();\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n operation(),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n console.error('Postgres operation timed out', {\n timeoutMs: scriptQueryTimeoutMs,\n });\n this.closeOnScriptTimeout?.();\n reject(\n new KyselyError('Postgres operation timed out', {\n timeoutMs: scriptQueryTimeoutMs,\n })\n );\n }, scriptQueryTimeoutMs);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n type ConnectionState = {\n connection: Awaited<ReturnType<typeof driver.acquireConnection>>;\n inTransaction: boolean;\n /** Set once the reserved connection reported that its socket closed. */\n lost?: Error;\n };\n const connections = new WeakMap<DatabaseConnection, ConnectionState>();\n const getConnection = (connection: DatabaseConnection) => {\n const state = connections.get(connection);\n if (!state) throw new Error('Postgres connection state is unavailable');\n return state;\n };\n\n return {\n init: () => driver.init(),\n acquireConnection: async () => {\n const state: ConnectionState = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: <R>(compiledQuery: CompiledQuery) =>\n this.withScriptDeadline(() => {\n const operationKind = state.inTransaction\n ? 'transaction'\n : compiledQuery.query.kind === 'SelectQueryNode'\n ? 'select'\n : 'mutation';\n return retryPostgres<QueryResult<R>>(\n () => {\n if (state.lost) return Promise.reject(state.lost);\n return state.connection\n .executeQuery<R>(compiledQuery)\n .catch((error) => {\n if (isConnectionClosed(error)) state.lost = error;\n throw error;\n });\n },\n async (error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n if (\n state.inTransaction ||\n (!isRetryableConnectionError(error) &&\n (compiledQuery.query.kind !== 'SelectQueryNode' ||\n (!isConnectionReset(error) &&\n message !==\n 'Egress connection severed outside of Hyperdrive' &&\n message !== 'Network connection lost.' &&\n !isNodeShuttingDown(error))))\n ) {\n return false;\n }\n\n // Postgres.js already ejects a severed reserved connection.\n // Acquire a new reservation before replaying the safe read.\n state.connection = await driver.acquireConnection();\n state.lost = undefined;\n return true;\n },\n this.retryDiagnostic\n ? {\n ...this.retryDiagnostic,\n operationKind,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined\n );\n }),\n streamQuery: (compiledQuery, chunkSize) => {\n if (chunkSize === undefined) {\n throw new Error('Postgres stream chunk size is required');\n }\n return state.connection.streamQuery(compiledQuery, chunkSize);\n },\n };\n connections.set(connection, state);\n return connection;\n },\n beginTransaction: async (connection, settings) => {\n const state = getConnection(connection);\n state.inTransaction = true;\n try {\n await this.withScriptDeadline(() =>\n driver.beginTransaction(state.connection, settings)\n );\n } catch (error) {\n state.inTransaction = false;\n if (isConnectionClosed(error)) state.lost = error;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n if (state.lost) throw state.lost;\n await this.withScriptDeadline(() =>\n driver.commitTransaction(state.connection)\n );\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n // PostgreSQL rolls the transaction back when its session ends, and a\n // statement on the closed connection would never be answered.\n if (state.lost) return;\n await this.withScriptDeadline(() =>\n driver.rollbackTransaction(state.connection)\n );\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.savepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.rollbackToSavepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.releaseSavepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n releaseConnection: async (connection) => {\n const state = getConnection(connection);\n connections.delete(connection);\n // Releasing a closed connection would put it back in the open pool,\n // and the next statement on it would hang. Postgres.js reconnects\n // from the closed pool on demand, and a failed reconnect is a\n // retryable CONNECT_TIMEOUT.\n if (state.lost) return;\n await driver.releaseConnection(state.connection);\n },\n destroy: () => driver.destroy(),\n };\n }\n}\n\nexport type Kysely = K<DB>;\nexport type ControlPlaneKysely = K<ControlPlaneDB>;\nexport type ControlPlaneTransaction = T<ControlPlaneDB>;\nexport function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts) {\n console.debug('Creating Kysely instance');\n const emitRetryDiagnostic =\n options?.onRetryDiagnostic ??\n (options?.repositoryName\n ? (diagnostic: PostgresRetryDiagnostic) =>\n console.warn('Postgres operation retry diagnostic', diagnostic)\n : undefined);\n const reserveConnection = postgres.reserve.bind(postgres);\n postgres.reserve = async () => {\n const connection = await retryPostgres(\n reserveConnection,\n isRetryableConnectionAcquisitionError,\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n operationKind: 'acquisition',\n repositoryName: options?.repositoryName,\n shouldEmit: isRetryableConnectionAcquisitionError,\n }\n : undefined\n );\n if (options?.hyperdrive) {\n const unsafe = connection.unsafe;\n connection.unsafe = (query, parameters, queryOptions) =>\n unsafe(query, parameters, { ...queryOptions, prepare: true });\n }\n return connection;\n };\n const kysely = getKysely<Database>(\n new RetryingPostgresJSDialect(\n { postgres },\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n repositoryName: options?.repositoryName,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined,\n options?.script\n ? () => void postgres.end({ timeout: 0 }).catch(() => undefined)\n : undefined\n ),\n {\n repositoryName: options?.repositoryName,\n log: options?.log,\n }\n );\n kysely.destroy = async () => {\n console.debug('Closing Kysely connection');\n await postgres.end({ timeout: 5 }).catch(() => undefined);\n const index = _connections.indexOf(postgres);\n if (index !== -1) _connections.splice(index, 1);\n };\n\n return kysely;\n}\n\nconst scriptQueryTimeoutMs = parseDuration('1h');\nlet _connections: postgres.Sql[] = [];\nexport function usePostgres(\n connectionString: string,\n opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive' | 'onReserve' | 'script'>\n) {\n const ssl = opt?.forceDisableSSL !== true && !opt?.hyperdrive;\n const sql = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n target_session_attrs: 'read-write',\n // Named prepared statements: PRO-17965 (Hyperdrive and Crunchy PgBouncer).\n prepare: true,\n ...(opt?.hyperdrive\n ? {\n max: 5,\n // Retire idle clients before Hyperdrive can close them asynchronously.\n idle_timeout: 10,\n statement_types: hyperdriveStatementTypes[opt.hyperdrive],\n }\n : {\n connect_timeout: 10,\n idle_timeout: 60,\n ...(opt?.script ? { keep_alive: 10 } : {}),\n }),\n });\n if (opt?.onReserve) {\n const { onReserve } = opt;\n const reserve = sql.reserve.bind(sql);\n // Innermost wrapper: it times each open or reuse of a connection, the\n // startup probe too, and is not part of the retry loop (PRO-18952).\n sql.reserve = async () => {\n const startedAtEpochMs = Date.now();\n const startedAt = performance.now();\n try {\n return await reserve();\n } finally {\n onReserve({\n durationMs: performance.now() - startedAt,\n startedAtEpochMs,\n });\n }\n };\n }\n // statement_timeout/lock_timeout are role-level settings on the cluster\n // (ALTER ROLE application SET ...) so they cover every pooled\n // connection; per-session SETs here only ever applied to one of them\n _connections.push(sql);\n return sql;\n}\n\nexport async function useAsyncPostgres(connectionString: string, opt?: PgOpt) {\n const delayMs = 2500;\n const probe = opt?.probe === true;\n const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;\n const url = new URL(connectionString);\n\n console.debug(\n `Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${opt?.forceDisableSSL !== true && !opt?.hyperdrive}, and port=${url.port}`\n );\n if (_connections.length > 0)\n console.warn(`We already have ${_connections.length} Postgres connections`);\n\n for (let attempt = 1; attempt <= retries; attempt++) {\n let sql: Sql | undefined;\n try {\n sql = usePostgres(connectionString, opt);\n if (probe) {\n // Opening a connection already checks that the session is writable\n // and loads the array types; a probe query would add a round trip.\n (await sql.reserve()).release();\n }\n return sql;\n } catch (err) {\n if (sql) {\n await sql.end({ timeout: 0 }).catch(() => undefined);\n _connections.splice(_connections.indexOf(sql), 1);\n }\n if (attempt === retries) throw err;\n console.warn(\n `Postgres connection failed (attempt ${attempt}), retrying...`\n );\n console.error('error', err);\n await new Promise((res) => setTimeout(res, delayMs));\n }\n }\n throw new KyselyError('Unable to connect to Postgres');\n}\n\nexport async function useAsyncKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return useKysely(sql, opt);\n}\n\nexport async function useAsyncNeonWebSocketKysely(\n connectionString: string,\n opt?: Pick<PgOpt, 'probe'> & KyselyOpts\n) {\n const pool = new Pool({ connectionString, max: 5 });\n const kysely = getKysely<DB>(new PostgresDialect({ pool }), opt ?? {});\n kysely.destroy = async () => {\n console.debug('Closing Neon WebSocket Kysely connection');\n await pool.end();\n };\n if (opt?.probe) await pool.query('select 1');\n return kysely;\n}\n\nexport function useControlPlaneKysely(postgres: Sql, options?: KyselyOpts) {\n return withControlPlaneSchema(\n useKysely<ControlPlaneDB>(postgres, options),\n 'public'\n );\n}\n\nexport async function useAsyncControlPlaneKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n return useControlPlaneKysely(\n await useAsyncPostgres(connectionString, opt),\n opt\n );\n}\n\nexport async function forceCloseAllPostgres(timeoutMs = 5000) {\n await Promise.race([\n Promise.all(\n _connections.map((pg) =>\n pg.end({ timeout: timeoutMs / 1000 }).catch(() => undefined)\n )\n ),\n new Promise((res) => setTimeout(res, timeoutMs + 1000)),\n ]);\n _connections = [];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAUhD,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EACL,iBAAiB,EAEjB,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,QAAsB,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAuB,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGnD,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAE9B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA2ClD,MAAM,iBAAiB,GAAG;IACxB,mBAAmB;IACnB,iBAAiB;IACjB,uCAAuC;IACvC,oBAAoB;IACpB,mDAAmD;IACnD,gEAAgE;IAChE,qDAAqD;CACtD,CAAC;AACF,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEhC;;;;;;;;GAQG;AACH,MAAM,cAAe,SAAQ,GAAqB;IACvC,GAAG,CAAC,SAAiB,EAAE,KAAe;QAC7C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAA+B,CAAC;AAEpE,SAAS,0BAA0B,CAAC,KAAc;IAChD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAO,CACL,KAAK,YAAY,KAAK;QACtB,CAAC,KAAK,CAAC,OAAO,KAAK,oBAAoB;YACrC,KAAK,CAAC,OAAO,KAAK,qBAAqB;YACvC,KAAK,CAAC,OAAO,KAAK,eAAe,CAAC,CACrC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,CACL,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CACzE,CAAC;AACJ,CAAC;AAED,SAAS,qCAAqC,CAAC,KAAc;IAC3D,OAAO,CACL,0BAA0B,CAAC,KAAK,CAAC;QACjC,iBAAiB,CAAC,KAAK,CAAC;QACxB,kEAAkE;QAClE,eAAe;QACf,kBAAkB,CAAC,KAAK,CAAC;QACzB,CAAC,KAAK,YAAY,KAAK;YACrB,CAAC,KAAK,CAAC,OAAO,KAAK,2BAA2B;gBAC5C,iEAAiE;gBACjE,qCAAqC;gBACrC,KAAK,CAAC,OAAO,KAAK,iDAAiD;gBACnE,KAAK,CAAC,OAAO,KAAK,0BAA0B;gBAC5C,CAAC,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,sBAAsB,CAAC,CAAC,CAAC,CACjE,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAO,CACL,iBAAiB,CAAC,KAAK,CAAC;QACxB,CAAC,KAAK,YAAY,KAAK;YACrB,MAAM,IAAI,KAAK;YACf,CAAC,KAAK,CAAC,IAAI,KAAK,mBAAmB;gBACjC,KAAK,CAAC,IAAI,KAAK,OAAO;gBACtB,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAc;IACjD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CACL,0BAA0B,CAAC,KAAK,CAAC;QACjC,iBAAiB,CAAC,KAAK,CAAC;QACxB,OAAO,KAAK,iDAAiD;QAC7D,OAAO,KAAK,0BAA0B;QACtC,kBAAkB,CAAC,KAAK,CAAC,CAC1B,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,SAA2B,EAC3B,KAA4E,EAC5E,UAMC;IAED,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,SAAkB,CAAC;IACvB,MAAM,cAAc,GAAG,CAAC,OAA2C,EAAE,EAAE;QACrE,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,UAAU,CAAC,IAAI,CAAC;YACd,YAAY;YACZ,UAAU,EAAE,UAAU,CAAC,UAAU;YACjC,UAAU,EACR,SAAS,YAAY,KAAK;gBACxB,CAAC,CAAC,MAAM,IAAI,SAAS,IAAI,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ;oBACzD,CAAC,CAAC,SAAS,CAAC,IAAI;oBAChB,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI;gBAC9B,CAAC,CAAC,SAAS;YACf,aAAa,EAAE,UAAU,CAAC,aAAa;YACvC,OAAO;YACP,cAAc,EAAE,UAAU,CAAC,cAAc;SAC1C,CAAC,CAAC;IACL,CAAC,CAAC;IACF,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAClB,KAAK,IAAI,EAAE;YACT,YAAY,EAAE,CAAC;YACf,OAAO,MAAM,SAAS,EAAE,CAAC;QAC3B,CAAC,EACD;YACE,aAAa,EAAE,qBAAqB;YACpC,aAAa,EAAE,aAAa,CAAC,IAAI,CAAC;YAClC,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC;YAC7B,sEAAsE;YACtE,qDAAqD;YACrD,MAAM,EAAE,MAAM;YACd,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,aAAa;gBAC9B,SAAS,GAAG,KAAK,CAAC;gBAClB,MAAM,WAAW,GACf,aAAa,GAAG,qBAAqB;oBACrC,CAAC,MAAM,KAAK,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC;gBACtC,IAAI,WAAW,IAAI,UAAU,EAAE,CAAC;oBAC9B,OAAO,GAAG,IAAI,CAAC;oBACf,cAAc,CAAC,UAAU,CAAC,CAAC;gBAC7B,CAAC;gBACD,OAAO,WAAW,CAAC;YACrB,CAAC;SACF,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,SAAS,GAAG,KAAK,CAAC;QAClB,IAAI,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,cAAc,CACZ,OAAO,IAAI,YAAY,KAAK,qBAAqB;gBAC/C,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,cAAc,CACnB,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAI,SAA2B;IACrE,OAAO,aAAa,CAClB,SAAS,EACT,CAAC,KAAK,EAAE,EAAE,CACR,eAAe,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACzC,eAAe,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED,MAAM,yBAA0B,SAAQ,iBAAiB;IAEpC;IACA;IAOA;IATnB,YACmB,MAA+B,EAC/B,eAMhB,EACgB,oBAAiC;QAElD,KAAK,CAAC,MAAM,CAAC,CAAC;QAVG,WAAM,GAAN,MAAM,CAAyB;QAC/B,oBAAe,GAAf,eAAe,CAM/B;QACgB,yBAAoB,GAApB,oBAAoB,CAAa;IAGpD,CAAC;IAED,kFAAkF;IAC1E,KAAK,CAAC,kBAAkB,CAAI,SAA2B;QAC7D,IAAI,CAAC,IAAI,CAAC,oBAAoB;YAAE,OAAO,MAAM,SAAS,EAAE,CAAC;QACzD,IAAI,KAAgD,CAAC;QACrD,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;gBACxB,SAAS,EAAE;gBACX,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;oBAC/B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;wBACtB,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE;4BAC5C,SAAS,EAAE,oBAAoB;yBAChC,CAAC,CAAC;wBACH,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;wBAC9B,MAAM,CACJ,IAAI,WAAW,CAAC,8BAA8B,EAAE;4BAC9C,SAAS,EAAE,oBAAoB;yBAChC,CAAC,CACH,CAAC;oBACJ,CAAC,EAAE,oBAAoB,CAAC,CAAC;gBAC3B,CAAC,CAAC;aACH,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAEQ,YAAY;QACnB,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAOjD,MAAM,WAAW,GAAG,IAAI,OAAO,EAAuC,CAAC;QACvE,MAAM,aAAa,GAAG,CAAC,UAA8B,EAAE,EAAE;YACvD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC1C,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACxE,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,OAAO;YACL,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE;YACzB,iBAAiB,EAAE,KAAK,IAAI,EAAE;gBAC5B,MAAM,KAAK,GAAoB;oBAC7B,UAAU,EAAE,MAAM,MAAM,CAAC,iBAAiB,EAAE;oBAC5C,aAAa,EAAE,KAAK;iBACrB,CAAC;gBACF,MAAM,UAAU,GAAuB;oBACrC,YAAY,EAAE,CAAI,aAA4B,EAAE,EAAE,CAChD,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE;wBAC3B,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa;4BACvC,CAAC,CAAC,aAAa;4BACf,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,iBAAiB;gCAC9C,CAAC,CAAC,QAAQ;gCACV,CAAC,CAAC,UAAU,CAAC;wBACjB,OAAO,aAAa,CAClB,GAAG,EAAE;4BACH,IAAI,KAAK,CAAC,IAAI;gCAAE,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BAClD,OAAO,KAAK,CAAC,UAAU;iCACpB,YAAY,CAAI,aAAa,CAAC;iCAC9B,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gCACf,IAAI,kBAAkB,CAAC,KAAK,CAAC;oCAAE,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;gCAClD,MAAM,KAAK,CAAC;4BACd,CAAC,CAAC,CAAC;wBACP,CAAC,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;4BACd,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;4BACzD,IACE,KAAK,CAAC,aAAa;gCACnB,CAAC,CAAC,0BAA0B,CAAC,KAAK,CAAC;oCACjC,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,iBAAiB;wCAC7C,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC;4CACxB,OAAO;gDACL,iDAAiD;4CACnD,OAAO,KAAK,0BAA0B;4CACtC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EACnC,CAAC;gCACD,OAAO,KAAK,CAAC;4BACf,CAAC;4BAED,4DAA4D;4BAC5D,4DAA4D;4BAC5D,KAAK,CAAC,UAAU,GAAG,MAAM,MAAM,CAAC,iBAAiB,EAAE,CAAC;4BACpD,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC;4BACvB,OAAO,IAAI,CAAC;wBACd,CAAC,EACD,IAAI,CAAC,eAAe;4BAClB,CAAC,CAAC;gCACE,GAAG,IAAI,CAAC,eAAe;gCACvB,aAAa;gCACb,UAAU,EAAE,2BAA2B;6BACxC;4BACH,CAAC,CAAC,SAAS,CACd,CAAC;oBACJ,CAAC,CAAC;oBACJ,WAAW,EAAE,CAAC,aAAa,EAAE,SAAS,EAAE,EAAE;wBACxC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;4BAC5B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;wBAC5D,CAAC;wBACD,OAAO,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;oBAChE,CAAC;iBACF,CAAC;gBACF,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;gBACnC,OAAO,UAAU,CAAC;YACpB,CAAC;YACD,gBAAgB,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE;gBAC/C,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;gBACxC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC3B,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,CACjC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CACpD,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;oBAC5B,IAAI,kBAAkB,CAAC,KAAK,CAAC;wBAAE,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;oBAClD,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YACD,iBAAiB,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACtC,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;gBACxC,IAAI,CAAC;oBACH,IAAI,KAAK,CAAC,IAAI;wBAAE,MAAM,KAAK,CAAC,IAAI,CAAC;oBACjC,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,CACjC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,CAC3C,CAAC;gBACJ,CAAC;wBAAS,CAAC;oBACT,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;gBAC9B,CAAC;YACH,CAAC;YACD,mBAAmB,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACxC,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;gBACxC,IAAI,CAAC;oBACH,qEAAqE;oBACrE,8DAA8D;oBAC9D,IAAI,KAAK,CAAC,IAAI;wBAAE,OAAO;oBACvB,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,CACjC,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CAC7C,CAAC;gBACJ,CAAC;wBAAS,CAAC;oBACT,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;gBAC9B,CAAC;YACH,CAAC;YACD,SAAS,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,CACrD,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE;gBAC3B,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;gBACxC,IAAI,KAAK,CAAC,IAAI;oBAAE,MAAM,KAAK,CAAC,IAAI,CAAC;gBACjC,OAAO,MAAM,CAAC,SAAS,CACrB,KAAK,CAAC,UAAU,EAChB,aAAa,EACb,YAAY,CACb,CAAC;YACJ,CAAC,CAAC;YACJ,mBAAmB,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,CAC/D,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE;gBAC3B,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;gBACxC,IAAI,KAAK,CAAC,IAAI;oBAAE,MAAM,KAAK,CAAC,IAAI,CAAC;gBACjC,OAAO,MAAM,CAAC,mBAAmB,CAC/B,KAAK,CAAC,UAAU,EAChB,aAAa,EACb,YAAY,CACb,CAAC;YACJ,CAAC,CAAC;YACJ,gBAAgB,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,CAC5D,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE;gBAC3B,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;gBACxC,IAAI,KAAK,CAAC,IAAI;oBAAE,MAAM,KAAK,CAAC,IAAI,CAAC;gBACjC,OAAO,MAAM,CAAC,gBAAgB,CAC5B,KAAK,CAAC,UAAU,EAChB,aAAa,EACb,YAAY,CACb,CAAC;YACJ,CAAC,CAAC;YACJ,iBAAiB,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBACtC,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;gBACxC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC/B,oEAAoE;gBACpE,kEAAkE;gBAClE,8DAA8D;gBAC9D,6BAA6B;gBAC7B,IAAI,KAAK,CAAC,IAAI;oBAAE,OAAO;gBACvB,MAAM,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE;SAChC,CAAC;IACJ,CAAC;CACF;AAKD,MAAM,UAAU,SAAS,CAAgB,QAAa,EAAE,OAAoB;IAC1E,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC1C,MAAM,mBAAmB,GACvB,OAAO,EAAE,iBAAiB;QAC1B,CAAC,OAAO,EAAE,cAAc;YACtB,CAAC,CAAC,CAAC,UAAmC,EAAE,EAAE,CACtC,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,UAAU,CAAC;YACnE,CAAC,CAAC,SAAS,CAAC,CAAC;IACjB,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1D,QAAQ,CAAC,OAAO,GAAG,KAAK,IAAI,EAAE;QAC5B,MAAM,UAAU,GAAG,MAAM,aAAa,CACpC,iBAAiB,EACjB,qCAAqC,EACrC,mBAAmB;YACjB,CAAC,CAAC;gBACE,UAAU,EAAE,OAAO,EAAE,UAAU;gBAC/B,IAAI,EAAE,mBAAmB;gBACzB,aAAa,EAAE,aAAa;gBAC5B,cAAc,EAAE,OAAO,EAAE,cAAc;gBACvC,UAAU,EAAE,qCAAqC;aAClD;YACH,CAAC,CAAC,SAAS,CACd,CAAC;QACF,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;YACjC,UAAU,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,CACtD,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,GAAG,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,SAAS,CACtB,IAAI,yBAAyB,CAC3B,EAAE,QAAQ,EAAE,EACZ,mBAAmB;QACjB,CAAC,CAAC;YACE,UAAU,EAAE,OAAO,EAAE,UAAU;YAC/B,IAAI,EAAE,mBAAmB;YACzB,cAAc,EAAE,OAAO,EAAE,cAAc;YACvC,UAAU,EAAE,2BAA2B;SACxC;QACH,CAAC,CAAC,SAAS,EACb,OAAO,EAAE,MAAM;QACb,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;QAChE,CAAC,CAAC,SAAS,CACd,EACD;QACE,cAAc,EAAE,OAAO,EAAE,cAAc;QACvC,GAAG,EAAE,OAAO,EAAE,GAAG;KAClB,CACF,CAAC;IACF,MAAM,CAAC,OAAO,GAAG,KAAK,IAAI,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC3C,MAAM,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,oBAAoB,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;AACjD,IAAI,YAAY,GAAmB,EAAE,CAAC;AACtC,MAAM,UAAU,WAAW,CACzB,gBAAwB,EACxB,GAA4E;IAE5E,MAAM,GAAG,GAAG,GAAG,EAAE,eAAe,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC;IAC9D,IAAI,GAAG,EAAE,UAAU,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACvE,yEAAyE;QACzE,wEAAwE;QACxE,IAAI,wBAAwB,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,wBAAwB,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC;YAC7D,wBAAwB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACxC,oBAAoB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;QACD,wBAAwB,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,cAAc,EAAE,CAAC,CAAC;QACrE,oBAAoB,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,GAAG,GAAG,QAAQ,CAAC,gBAAgB,EAAE;QACrC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK;QAC5B,2EAA2E;QAC3E,OAAO,EAAE,IAAI;QACb,GAAG,CAAC,GAAG,EAAE,UAAU;YACjB,CAAC,CAAC;gBACE,GAAG,EAAE,CAAC;gBACN,uEAAuE;gBACvE,YAAY,EAAE,EAAE;gBAChB,eAAe,EAAE,wBAAwB,CAAC,GAAG,CAAC,gBAAgB,CAAC;gBAC/D,WAAW,EAAE,oBAAoB,CAAC,GAAG,CAAC,gBAAgB,CAAC;gBACvD,oEAAoE;gBACpE,mEAAmE;gBACnE,0DAA0D;gBAC1D,0BAA0B;aAC3B;YACH,CAAC,CAAC;gBACE,oBAAoB,EAAE,YAAY;gBAClC,eAAe,EAAE,EAAE;gBACnB,YAAY,EAAE,EAAE;gBAChB,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3C,CAAC;KACP,CAAC,CAAC;IACH,IAAI,GAAG,EAAE,SAAS,EAAE,CAAC;QACnB,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC;QAC1B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,sEAAsE;QACtE,oEAAoE;QACpE,GAAG,CAAC,OAAO,GAAG,KAAK,IAAI,EAAE;YACvB,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YACpC,IAAI,CAAC;gBACH,OAAO,MAAM,OAAO,EAAE,CAAC;YACzB,CAAC;oBAAS,CAAC;gBACT,SAAS,CAAC;oBACR,UAAU,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS;oBACzC,gBAAgB;iBACjB,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IACD,wEAAwE;IACxE,8DAA8D;IAC9D,qEAAqE;IACrE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,gBAAwB,EAAE,GAAW;IAC1E,MAAM,OAAO,GAAG,IAAI,CAAC;IACrB,MAAM,KAAK,GAAG,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAClC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAEtC,OAAO,CAAC,KAAK,CACX,2CAA2C,KAAK,KAAK,OAAO,kBAAkB,GAAG,EAAE,eAAe,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,UAAU,cAAc,GAAG,CAAC,IAAI,EAAE,CACxJ,CAAC;IACF,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,mBAAmB,YAAY,CAAC,MAAM,uBAAuB,CAAC,CAAC;IAE9E,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QACpD,IAAI,GAAoB,CAAC;QACzB,IAAI,CAAC;YACH,GAAG,GAAG,WAAW,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;YACzC,IAAI,KAAK,EAAE,CAAC;gBACV,mEAAmE;gBACnE,mEAAmE;gBACnE,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YAClC,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBACrD,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACpD,CAAC;YACD,IAAI,OAAO,KAAK,OAAO;gBAAE,MAAM,GAAG,CAAC;YACnC,OAAO,CAAC,IAAI,CACV,uCAAuC,OAAO,gBAAgB,CAC/D,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC5B,MAAM,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IACD,MAAM,IAAI,WAAW,CAAC,+BAA+B,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,gBAAwB,EACxB,GAAwB;IAExB,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IAC1D,OAAO,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,gBAAwB,EACxB,GAAuC;IAEvC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,SAAS,CAAK,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,CAAC,OAAO,GAAG,KAAK,IAAI,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;IACnB,CAAC,CAAC;IACF,IAAI,GAAG,EAAE,KAAK;QAAE,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAa,EAAE,OAAoB;IACvE,OAAO,sBAAsB,CAC3B,SAAS,CAAiB,QAAQ,EAAE,OAAO,CAAC,EAC5C,QAAQ,CACT,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,gBAAwB,EACxB,GAAwB;IAExB,OAAO,qBAAqB,CAC1B,MAAM,gBAAgB,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAC7C,GAAG,CACJ,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,SAAS,GAAG,IAAI;IAC1D,MAAM,OAAO,CAAC,IAAI,CAAC;QACjB,OAAO,CAAC,GAAG,CACT,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CACtB,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,SAAS,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAC7D,CACF;QACD,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;KACxD,CAAC,CAAC;IACH,YAAY,GAAG,EAAE,CAAC;AACpB,CAAC","sourcesContent":["import { backOff } from 'exponential-backoff';\nimport { Pool } from '@neondatabase/serverless';\nimport type {\n CompiledQuery,\n DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\n QueryResult,\n Transaction as T,\n} from 'kysely';\nimport { PostgresDialect } from 'kysely';\nimport {\n PostgresJSDialect,\n type PostgresJSDialectConfig,\n PostgresJSDriver,\n} from 'kysely-postgres-js';\nimport postgres, { type Sql } from 'postgres';\nimport { type ControlPlaneDB, withControlPlaneSchema } from './control-plane';\nimport { KyselyError } from './error';\nimport { getKysely } from './plugins';\nimport { isPostgresError } from './postgres-error';\n\nexport type { Insertable, LogEvent } from 'kysely';\nexport * from './connect-handoff';\nexport * from './error';\nexport * from './isomorphic';\nexport * from './postgres-error';\nexport * from './query';\nexport * from './regional';\nexport * from './transaction';\n\nimport { parseDuration } from '@vrplatform/utils';\nimport type { TenantDataRegion } from './regional';\nimport type { DB } from './v1.generated';\n\n/** The database a Worker reaches through its Hyperdrive binding. */\ntype HyperdriveDatabase = 'controlPlane' | 'regional';\n\ntype KyselyOpts = {\n dataRegion?: TenantDataRegion;\n hyperdrive?: HyperdriveDatabase;\n /** Called after every connection reservation, including the startup probe. */\n onReserve?: (timing: {\n durationMs: number;\n startedAtEpochMs: number;\n }) => void;\n onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;\n repositoryName?: string;\n log?: true | LogConfig;\n /**\n * Scripts and repairs (PRO-19037). Probes an idle TCP connection after 10 s.\n * A query, commit, begin, rollback or savepoint with no answer for an hour,\n * longer than any statement timeout a script sets, fails the run and closes\n * the Postgres client that issued it. Backstop for a connection the kernel\n * keeps open while the peer never answers.\n */\n script?: true;\n};\n\ntype PostgresRetryDiagnostic = {\n attemptCount: number;\n dataRegion?: TenantDataRegion;\n errorClass: string;\n operationKind: 'acquisition' | 'mutation' | 'select' | 'transaction';\n outcome: 'exhausted' | 'notRetryable' | 'retrying';\n repositoryName?: string;\n};\n\ntype PgOpt = {\n forceDisableSSL?: boolean;\n probe?: true;\n retries?: false | number;\n} & Pick<KyselyOpts, 'hyperdrive' | 'onReserve' | 'script'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n 'Timed out while creating a new server connection.',\n // Neon rejects the login before any statement runs (PRO-19169).\n 'Failed to acquire permit to connect to the database',\n];\nconst postgresRetryAttempts = 3;\n\n/**\n * Parameter types PostgreSQL described per statement signature (PRO-18871).\n * Postgres.js describes a statement in a round trip of its own before it can\n * execute it when a parameter type is unknown, and a Worker request always\n * starts on new connections. The patched driver reads and fills this map\n * through its `statement_types` option and then parses, describes, binds and\n * executes a known statement in one round trip. It forgets a statement's\n * types when the statement fails, so a schema change is described again.\n */\nclass StatementTypes extends Map<string, number[]> {\n override set(signature: string, types: number[]) {\n if (!this.has(signature) && this.size >= 2000) {\n this.delete(this.keys().next().value!);\n }\n return super.set(signature, types);\n }\n}\n\n/**\n * Kept for the isolate's lifetime, one map per origin database. One isolate\n * can open several databases through different Hyperdrive bindings, and enum\n * and row types have different OIDs in each, so the key is the binding's\n * connection string, not the role (PRO-19353).\n */\nconst hyperdriveStatementTypes = new Map<string, StatementTypes>();\n\n/**\n * Array type OIDs by element type OID, per origin database (PRO-19353).\n * Postgres.js looks them up on every new connection, one origin round trip\n * each, about 100 ms from Crunchy to the control plane. The first connection\n * to a database in an isolate fills its map and later connections reuse it.\n * A migration that adds an array type reaches an isolate when it restarts;\n * until then values of that type arrive as text.\n */\nconst hyperdriveArrayTypes = new Map<string, Map<number, number>>();\n\nfunction isRetryableConnectionError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return retryableMessages.some((retryable) => message.includes(retryable));\n}\n\nfunction isNodeShuttingDown(error: unknown) {\n return (\n error instanceof Error &&\n (error.message === 'Node shutting down' ||\n error.message === 'Node shutting down.' ||\n error.message === 'shutting down')\n );\n}\n\nfunction isConnectionReset(error: unknown) {\n return (\n error instanceof Error && 'code' in error && error.code === 'ECONNRESET'\n );\n}\n\nfunction isRetryableConnectionAcquisitionError(error: unknown) {\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n // Hyperdrive refuses any new connection while its node shuts down\n // (PRO-19168).\n isNodeShuttingDown(error) ||\n (error instanceof Error &&\n (error.message === 'connection attempt failed' ||\n // Opening a connection happens before any statement runs, so the\n // open is safe to retry (PRO-18866).\n error.message === 'Egress connection severed outside of Hyperdrive' ||\n error.message === 'Network connection lost.' ||\n ('code' in error && error.code === 'CONNECTION_DESTROYED')))\n );\n}\n\n/**\n * Postgres.js closes a reserved connection when its socket dies, whether the\n * statement in flight fails with `CONNECTION_CLOSED` or with the socket error.\n * A statement sent to it afterwards is never answered: it throws in a timer\n * callback or is silently never written (PRO-17710). A destroyed connection\n * rejects at once, so it needs no guard.\n */\nfunction isConnectionClosed(error: unknown): error is Error {\n return (\n isConnectionReset(error) ||\n (error instanceof Error &&\n 'code' in error &&\n (error.code === 'CONNECTION_CLOSED' ||\n error.code === 'EPIPE' ||\n error.code === 'ETIMEDOUT'))\n );\n}\n\nfunction isQueryRetryDiagnosticError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return (\n isRetryableConnectionError(error) ||\n isConnectionReset(error) ||\n message === 'Egress connection severed outside of Hyperdrive' ||\n message === 'Network connection lost.' ||\n isNodeShuttingDown(error)\n );\n}\n\nasync function retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>,\n diagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'errorClass' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n) {\n let attemptCount = 0;\n let retried = false;\n let lastError: unknown;\n const emitDiagnostic = (outcome: PostgresRetryDiagnostic['outcome']) => {\n if (!diagnostic) return;\n diagnostic.emit({\n attemptCount,\n dataRegion: diagnostic.dataRegion,\n errorClass:\n lastError instanceof Error\n ? 'code' in lastError && typeof lastError.code === 'string'\n ? lastError.code\n : lastError.constructor.name\n : 'unknown',\n operationKind: diagnostic.operationKind,\n outcome,\n repositoryName: diagnostic.repositoryName,\n });\n };\n try {\n return await backOff(\n async () => {\n attemptCount++;\n return await operation();\n },\n {\n numOfAttempts: postgresRetryAttempts,\n startingDelay: parseDuration('1s'),\n maxDelay: parseDuration('5s'),\n // Scheduled chunk fan-outs open many connections at once; full jitter\n // keeps their retries from reconnecting in lockstep.\n jitter: 'full',\n async retry(error, attemptNumber) {\n lastError = error;\n const shouldRetry =\n attemptNumber < postgresRetryAttempts &&\n (await retry(error, attemptNumber));\n if (shouldRetry && diagnostic) {\n retried = true;\n emitDiagnostic('retrying');\n }\n return shouldRetry;\n },\n }\n );\n } catch (error) {\n lastError = error;\n if (diagnostic?.shouldEmit(error)) {\n emitDiagnostic(\n retried && attemptCount === postgresRetryAttempts\n ? 'exhausted'\n : 'notRetryable'\n );\n }\n throw error;\n }\n}\n\n/**\n * Replays a complete database operation after a PostgreSQL deadlock (40P01)\n * or lock timeout (55P03), using the same three-attempt jittered budget as\n * connection retries. The operation must own its transaction and must not\n * contain external side effects such as partner API writes.\n */\nexport function retryPostgresLockFailure<T>(operation: () => Promise<T>) {\n return retryPostgres(\n operation,\n (error) =>\n isPostgresError(error, { code: '40P01' }) ||\n isPostgresError(error, { code: '55P03' })\n );\n}\n\nclass RetryingPostgresJSDialect extends PostgresJSDialect {\n constructor(\n private readonly config: PostgresJSDialectConfig,\n private readonly retryDiagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'errorClass' | 'operationKind' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n },\n private readonly closeOnScriptTimeout?: () => void\n ) {\n super(config);\n }\n\n /** Ends the run when a script's database operation gets no answer (PRO-19037). */\n private async withScriptDeadline<T>(operation: () => Promise<T>) {\n if (!this.closeOnScriptTimeout) return await operation();\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n operation(),\n new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n console.error('Postgres operation timed out', {\n timeoutMs: scriptQueryTimeoutMs,\n });\n this.closeOnScriptTimeout?.();\n reject(\n new KyselyError('Postgres operation timed out', {\n timeoutMs: scriptQueryTimeoutMs,\n })\n );\n }, scriptQueryTimeoutMs);\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n type ConnectionState = {\n connection: Awaited<ReturnType<typeof driver.acquireConnection>>;\n inTransaction: boolean;\n /** Set once the reserved connection reported that its socket closed. */\n lost?: Error;\n };\n const connections = new WeakMap<DatabaseConnection, ConnectionState>();\n const getConnection = (connection: DatabaseConnection) => {\n const state = connections.get(connection);\n if (!state) throw new Error('Postgres connection state is unavailable');\n return state;\n };\n\n return {\n init: () => driver.init(),\n acquireConnection: async () => {\n const state: ConnectionState = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: <R>(compiledQuery: CompiledQuery) =>\n this.withScriptDeadline(() => {\n const operationKind = state.inTransaction\n ? 'transaction'\n : compiledQuery.query.kind === 'SelectQueryNode'\n ? 'select'\n : 'mutation';\n return retryPostgres<QueryResult<R>>(\n () => {\n if (state.lost) return Promise.reject(state.lost);\n return state.connection\n .executeQuery<R>(compiledQuery)\n .catch((error) => {\n if (isConnectionClosed(error)) state.lost = error;\n throw error;\n });\n },\n async (error) => {\n const message =\n error instanceof Error ? error.message : String(error);\n if (\n state.inTransaction ||\n (!isRetryableConnectionError(error) &&\n (compiledQuery.query.kind !== 'SelectQueryNode' ||\n (!isConnectionReset(error) &&\n message !==\n 'Egress connection severed outside of Hyperdrive' &&\n message !== 'Network connection lost.' &&\n !isNodeShuttingDown(error))))\n ) {\n return false;\n }\n\n // Postgres.js already ejects a severed reserved connection.\n // Acquire a new reservation before replaying the safe read.\n state.connection = await driver.acquireConnection();\n state.lost = undefined;\n return true;\n },\n this.retryDiagnostic\n ? {\n ...this.retryDiagnostic,\n operationKind,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined\n );\n }),\n streamQuery: (compiledQuery, chunkSize) => {\n if (chunkSize === undefined) {\n throw new Error('Postgres stream chunk size is required');\n }\n return state.connection.streamQuery(compiledQuery, chunkSize);\n },\n };\n connections.set(connection, state);\n return connection;\n },\n beginTransaction: async (connection, settings) => {\n const state = getConnection(connection);\n state.inTransaction = true;\n try {\n await this.withScriptDeadline(() =>\n driver.beginTransaction(state.connection, settings)\n );\n } catch (error) {\n state.inTransaction = false;\n if (isConnectionClosed(error)) state.lost = error;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n if (state.lost) throw state.lost;\n await this.withScriptDeadline(() =>\n driver.commitTransaction(state.connection)\n );\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n // PostgreSQL rolls the transaction back when its session ends, and a\n // statement on the closed connection would never be answered.\n if (state.lost) return;\n await this.withScriptDeadline(() =>\n driver.rollbackTransaction(state.connection)\n );\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.savepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.rollbackToSavepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n this.withScriptDeadline(() => {\n const state = getConnection(connection);\n if (state.lost) throw state.lost;\n return driver.releaseSavepoint(\n state.connection,\n savepointName,\n compileQuery\n );\n }),\n releaseConnection: async (connection) => {\n const state = getConnection(connection);\n connections.delete(connection);\n // Releasing a closed connection would put it back in the open pool,\n // and the next statement on it would hang. Postgres.js reconnects\n // from the closed pool on demand, and a failed reconnect is a\n // retryable CONNECT_TIMEOUT.\n if (state.lost) return;\n await driver.releaseConnection(state.connection);\n },\n destroy: () => driver.destroy(),\n };\n }\n}\n\nexport type Kysely = K<DB>;\nexport type ControlPlaneKysely = K<ControlPlaneDB>;\nexport type ControlPlaneTransaction = T<ControlPlaneDB>;\nexport function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts) {\n console.debug('Creating Kysely instance');\n const emitRetryDiagnostic =\n options?.onRetryDiagnostic ??\n (options?.repositoryName\n ? (diagnostic: PostgresRetryDiagnostic) =>\n console.warn('Postgres operation retry diagnostic', diagnostic)\n : undefined);\n const reserveConnection = postgres.reserve.bind(postgres);\n postgres.reserve = async () => {\n const connection = await retryPostgres(\n reserveConnection,\n isRetryableConnectionAcquisitionError,\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n operationKind: 'acquisition',\n repositoryName: options?.repositoryName,\n shouldEmit: isRetryableConnectionAcquisitionError,\n }\n : undefined\n );\n if (options?.hyperdrive) {\n const unsafe = connection.unsafe;\n connection.unsafe = (query, parameters, queryOptions) =>\n unsafe(query, parameters, { ...queryOptions, prepare: true });\n }\n return connection;\n };\n const kysely = getKysely<Database>(\n new RetryingPostgresJSDialect(\n { postgres },\n emitRetryDiagnostic\n ? {\n dataRegion: options?.dataRegion,\n emit: emitRetryDiagnostic,\n repositoryName: options?.repositoryName,\n shouldEmit: isQueryRetryDiagnosticError,\n }\n : undefined,\n options?.script\n ? () => void postgres.end({ timeout: 0 }).catch(() => undefined)\n : undefined\n ),\n {\n repositoryName: options?.repositoryName,\n log: options?.log,\n }\n );\n kysely.destroy = async () => {\n console.debug('Closing Kysely connection');\n await postgres.end({ timeout: 5 }).catch(() => undefined);\n const index = _connections.indexOf(postgres);\n if (index !== -1) _connections.splice(index, 1);\n };\n\n return kysely;\n}\n\nconst scriptQueryTimeoutMs = parseDuration('1h');\nlet _connections: postgres.Sql[] = [];\nexport function usePostgres(\n connectionString: string,\n opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive' | 'onReserve' | 'script'>\n) {\n const ssl = opt?.forceDisableSSL !== true && !opt?.hyperdrive;\n if (opt?.hyperdrive && !hyperdriveStatementTypes.has(connectionString)) {\n // A Worker binds seven Hyperdrive configs. Keep a few more, so a binding\n // whose host changed between requests cannot grow the caches unbounded.\n if (hyperdriveStatementTypes.size >= 16) {\n const oldest = hyperdriveStatementTypes.keys().next().value!;\n hyperdriveStatementTypes.delete(oldest);\n hyperdriveArrayTypes.delete(oldest);\n }\n hyperdriveStatementTypes.set(connectionString, new StatementTypes());\n hyperdriveArrayTypes.set(connectionString, new Map());\n }\n const sql = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n // Named prepared statements: PRO-17965 (Hyperdrive and Crunchy PgBouncer).\n prepare: true,\n ...(opt?.hyperdrive\n ? {\n max: 5,\n // Retire idle clients before Hyperdrive can close them asynchronously.\n idle_timeout: 10,\n statement_types: hyperdriveStatementTypes.get(connectionString),\n array_types: hyperdriveArrayTypes.get(connectionString),\n // No read-write check (PRO-17156): Hyperdrive pools by transaction,\n // so the check covered one origin connection, never the ones later\n // statements run on, and it cost an origin round trip per\n // connection (PRO-19353).\n }\n : {\n target_session_attrs: 'read-write',\n connect_timeout: 10,\n idle_timeout: 60,\n ...(opt?.script ? { keep_alive: 10 } : {}),\n }),\n });\n if (opt?.onReserve) {\n const { onReserve } = opt;\n const reserve = sql.reserve.bind(sql);\n // Innermost wrapper: it times each open or reuse of a connection, the\n // startup probe too, and is not part of the retry loop (PRO-18952).\n sql.reserve = async () => {\n const startedAtEpochMs = Date.now();\n const startedAt = performance.now();\n try {\n return await reserve();\n } finally {\n onReserve({\n durationMs: performance.now() - startedAt,\n startedAtEpochMs,\n });\n }\n };\n }\n // statement_timeout/lock_timeout are role-level settings on the cluster\n // (ALTER ROLE application SET ...) so they cover every pooled\n // connection; per-session SETs here only ever applied to one of them\n _connections.push(sql);\n return sql;\n}\n\nexport async function useAsyncPostgres(connectionString: string, opt?: PgOpt) {\n const delayMs = 2500;\n const probe = opt?.probe === true;\n const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;\n const url = new URL(connectionString);\n\n console.debug(\n `Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${opt?.forceDisableSSL !== true && !opt?.hyperdrive}, and port=${url.port}`\n );\n if (_connections.length > 0)\n console.warn(`We already have ${_connections.length} Postgres connections`);\n\n for (let attempt = 1; attempt <= retries; attempt++) {\n let sql: Sql | undefined;\n try {\n sql = usePostgres(connectionString, opt);\n if (probe) {\n // Opening a connection already checks that the session is writable\n // and loads the array types; a probe query would add a round trip.\n (await sql.reserve()).release();\n }\n return sql;\n } catch (err) {\n if (sql) {\n await sql.end({ timeout: 0 }).catch(() => undefined);\n _connections.splice(_connections.indexOf(sql), 1);\n }\n if (attempt === retries) throw err;\n console.warn(\n `Postgres connection failed (attempt ${attempt}), retrying...`\n );\n console.error('error', err);\n await new Promise((res) => setTimeout(res, delayMs));\n }\n }\n throw new KyselyError('Unable to connect to Postgres');\n}\n\nexport async function useAsyncKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return useKysely(sql, opt);\n}\n\nexport async function useAsyncNeonWebSocketKysely(\n connectionString: string,\n opt?: Pick<PgOpt, 'probe'> & KyselyOpts\n) {\n const pool = new Pool({ connectionString, max: 5 });\n const kysely = getKysely<DB>(new PostgresDialect({ pool }), opt ?? {});\n kysely.destroy = async () => {\n console.debug('Closing Neon WebSocket Kysely connection');\n await pool.end();\n };\n if (opt?.probe) await pool.query('select 1');\n return kysely;\n}\n\nexport function useControlPlaneKysely(postgres: Sql, options?: KyselyOpts) {\n return withControlPlaneSchema(\n useKysely<ControlPlaneDB>(postgres, options),\n 'public'\n );\n}\n\nexport async function useAsyncControlPlaneKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n return useControlPlaneKysely(\n await useAsyncPostgres(connectionString, opt),\n opt\n );\n}\n\nexport async function forceCloseAllPostgres(timeoutMs = 5000) {\n await Promise.race([\n Promise.all(\n _connections.map((pg) =>\n pg.end({ timeout: timeoutMs / 1000 }).catch(() => undefined)\n )\n ),\n new Promise((res) => setTimeout(res, timeoutMs + 1000)),\n ]);\n _connections = [];\n}\n"]}
|