@vrplatform/kysely 1.3.45-stage.934 → 1.3.45-stage.968
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.d.ts +9 -0
- package/build/main/index.js +51 -25
- package/build/main/index.js.map +1 -1
- package/build/main/local/index.js +17 -0
- package/build/main/local/index.js.map +1 -1
- package/build/module/index.d.ts +9 -0
- package/build/module/index.js +48 -25
- package/build/module/index.js.map +1 -1
- package/build/module/local/index.js +17 -0
- package/build/module/local/index.js.map +1 -1
- package/package.json +4 -4
package/build/main/index.d.ts
CHANGED
|
@@ -29,12 +29,21 @@ type PgOpt = {
|
|
|
29
29
|
probe?: true;
|
|
30
30
|
retries?: false | number;
|
|
31
31
|
} & Pick<KyselyOpts, 'hyperdrive'>;
|
|
32
|
+
/**
|
|
33
|
+
* Replays a complete database operation after a PostgreSQL deadlock (40P01)
|
|
34
|
+
* or lock timeout (55P03), using the same three-attempt jittered budget as
|
|
35
|
+
* connection retries. The operation must own its transaction and must not
|
|
36
|
+
* contain external side effects such as partner API writes.
|
|
37
|
+
*/
|
|
38
|
+
export declare function retryPostgresLockFailure<T>(operation: () => Promise<T>): Promise<T>;
|
|
32
39
|
export type Kysely = K<DB>;
|
|
33
40
|
export type ControlPlaneKysely = K<ControlPlaneDB>;
|
|
34
41
|
export type ControlPlaneTransaction = T<ControlPlaneDB>;
|
|
35
42
|
export declare function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts): K<Database>;
|
|
43
|
+
export declare function usePostgres(connectionString: string, opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive'>): postgres.Sql<{}>;
|
|
36
44
|
export declare function useAsyncPostgres(connectionString: string, opt?: PgOpt): Promise<postgres.Sql<{}>>;
|
|
37
45
|
export declare function useAsyncKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<DB>>;
|
|
38
46
|
export declare function useAsyncNeonWebSocketKysely(connectionString: string, opt?: Pick<PgOpt, 'probe'> & KyselyOpts): Promise<K<DB>>;
|
|
47
|
+
export declare function useControlPlaneKysely(postgres: Sql, options?: KyselyOpts): K<ControlPlaneDB>;
|
|
39
48
|
export declare function useAsyncControlPlaneKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<ControlPlaneDB>>;
|
|
40
49
|
export declare function forceCloseAllPostgres(timeoutMs?: number): Promise<void>;
|
package/build/main/index.js
CHANGED
|
@@ -17,10 +17,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.retryPostgresLockFailure = retryPostgresLockFailure;
|
|
20
21
|
exports.useKysely = useKysely;
|
|
22
|
+
exports.usePostgres = usePostgres;
|
|
21
23
|
exports.useAsyncPostgres = useAsyncPostgres;
|
|
22
24
|
exports.useAsyncKysely = useAsyncKysely;
|
|
23
25
|
exports.useAsyncNeonWebSocketKysely = useAsyncNeonWebSocketKysely;
|
|
26
|
+
exports.useControlPlaneKysely = useControlPlaneKysely;
|
|
24
27
|
exports.useAsyncControlPlaneKysely = useAsyncControlPlaneKysely;
|
|
25
28
|
exports.forceCloseAllPostgres = forceCloseAllPostgres;
|
|
26
29
|
const exponential_backoff_1 = require("exponential-backoff");
|
|
@@ -31,6 +34,7 @@ const postgres_1 = __importDefault(require("postgres"));
|
|
|
31
34
|
const control_plane_1 = require("./control-plane");
|
|
32
35
|
const error_1 = require("./error");
|
|
33
36
|
const plugins_1 = require("./plugins");
|
|
37
|
+
const postgres_error_1 = require("./postgres-error");
|
|
34
38
|
__exportStar(require("./error"), exports);
|
|
35
39
|
__exportStar(require("./isomorphic"), exports);
|
|
36
40
|
__exportStar(require("./postgres-error"), exports);
|
|
@@ -90,6 +94,9 @@ async function retryPostgres(operation, retry, diagnostic) {
|
|
|
90
94
|
numOfAttempts: postgresRetryAttempts,
|
|
91
95
|
startingDelay: (0, utils_1.parseDuration)('1s'),
|
|
92
96
|
maxDelay: (0, utils_1.parseDuration)('5s'),
|
|
97
|
+
// Scheduled chunk fan-outs open many connections at once; full jitter
|
|
98
|
+
// keeps their retries from reconnecting in lockstep.
|
|
99
|
+
jitter: 'full',
|
|
93
100
|
async retry(error, attemptNumber) {
|
|
94
101
|
const shouldRetry = attemptNumber < postgresRetryAttempts &&
|
|
95
102
|
(await retry(error, attemptNumber));
|
|
@@ -110,6 +117,16 @@ async function retryPostgres(operation, retry, diagnostic) {
|
|
|
110
117
|
throw error;
|
|
111
118
|
}
|
|
112
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Replays a complete database operation after a PostgreSQL deadlock (40P01)
|
|
122
|
+
* or lock timeout (55P03), using the same three-attempt jittered budget as
|
|
123
|
+
* connection retries. The operation must own its transaction and must not
|
|
124
|
+
* contain external side effects such as partner API writes.
|
|
125
|
+
*/
|
|
126
|
+
function retryPostgresLockFailure(operation) {
|
|
127
|
+
return retryPostgres(operation, (error) => (0, postgres_error_1.isPostgresError)(error, { code: '40P01' }) ||
|
|
128
|
+
(0, postgres_error_1.isPostgresError)(error, { code: '55P03' }));
|
|
129
|
+
}
|
|
113
130
|
class RetryingPostgresJSDialect extends kysely_postgres_js_1.PostgresJSDialect {
|
|
114
131
|
constructor(config, retryDiagnostic) {
|
|
115
132
|
super(config);
|
|
@@ -258,45 +275,52 @@ function useKysely(postgres, options) {
|
|
|
258
275
|
return kysely;
|
|
259
276
|
}
|
|
260
277
|
let _connections = [];
|
|
278
|
+
function usePostgres(connectionString, opt) {
|
|
279
|
+
const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;
|
|
280
|
+
const sql = (0, postgres_1.default)(connectionString, {
|
|
281
|
+
ssl: ssl ? 'require' : false,
|
|
282
|
+
target_session_attrs: 'read-write',
|
|
283
|
+
// enable prepare statements, pgbouncer on crunchy allows for prepared statements
|
|
284
|
+
prepare: true,
|
|
285
|
+
...(opt?.hyperdrive
|
|
286
|
+
? {
|
|
287
|
+
max: 5,
|
|
288
|
+
// Retire idle clients before Hyperdrive can close them asynchronously.
|
|
289
|
+
idle_timeout: 10,
|
|
290
|
+
}
|
|
291
|
+
: {
|
|
292
|
+
connect_timeout: 10,
|
|
293
|
+
idle_timeout: 60,
|
|
294
|
+
}),
|
|
295
|
+
});
|
|
296
|
+
// statement_timeout/lock_timeout are role-level settings on the cluster
|
|
297
|
+
// (ALTER ROLE application SET ...) so they cover every pooled
|
|
298
|
+
// connection; per-session SETs here only ever applied to one of them
|
|
299
|
+
_connections.push(sql);
|
|
300
|
+
return sql;
|
|
301
|
+
}
|
|
261
302
|
async function useAsyncPostgres(connectionString, opt) {
|
|
262
303
|
const delayMs = 2500;
|
|
263
304
|
const probe = opt?.probe === true;
|
|
264
305
|
const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;
|
|
265
|
-
const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;
|
|
266
306
|
const url = new URL(connectionString);
|
|
267
|
-
console.debug(`Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${
|
|
307
|
+
console.debug(`Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${opt?.forceDisableSSL !== true && opt?.hyperdrive !== true}, and port=${url.port}`);
|
|
268
308
|
if (_connections.length > 0)
|
|
269
309
|
console.warn(`We already have ${_connections.length} Postgres connections`);
|
|
270
310
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
271
311
|
let sql;
|
|
272
312
|
try {
|
|
273
|
-
sql = (
|
|
274
|
-
ssl: ssl ? 'require' : false,
|
|
275
|
-
target_session_attrs: 'read-write',
|
|
276
|
-
// enable prepare statements, pgbouncer on crunchy allows for prepared statements
|
|
277
|
-
prepare: true,
|
|
278
|
-
...(opt?.hyperdrive
|
|
279
|
-
? {
|
|
280
|
-
max: 5,
|
|
281
|
-
// Retire idle clients before Hyperdrive can close them asynchronously.
|
|
282
|
-
idle_timeout: 10,
|
|
283
|
-
}
|
|
284
|
-
: {
|
|
285
|
-
connect_timeout: 10,
|
|
286
|
-
idle_timeout: 60,
|
|
287
|
-
}),
|
|
288
|
-
});
|
|
313
|
+
sql = usePostgres(connectionString, opt);
|
|
289
314
|
if (probe) {
|
|
290
315
|
await sql `select 1`;
|
|
291
316
|
}
|
|
292
|
-
// statement_timeout/lock_timeout are role-level settings on the cluster
|
|
293
|
-
// (ALTER ROLE application SET ...) so they cover every pooled
|
|
294
|
-
// connection; per-session SETs here only ever applied to one of them
|
|
295
|
-
_connections.push(sql);
|
|
296
317
|
return sql;
|
|
297
318
|
}
|
|
298
319
|
catch (err) {
|
|
299
|
-
|
|
320
|
+
if (sql) {
|
|
321
|
+
await sql.end({ timeout: 0 }).catch(() => undefined);
|
|
322
|
+
_connections.splice(_connections.indexOf(sql), 1);
|
|
323
|
+
}
|
|
300
324
|
if (attempt === retries)
|
|
301
325
|
throw err;
|
|
302
326
|
console.warn(`Postgres connection failed (attempt ${attempt}), retrying...`);
|
|
@@ -321,9 +345,11 @@ async function useAsyncNeonWebSocketKysely(connectionString, opt) {
|
|
|
321
345
|
await pool.query('select 1');
|
|
322
346
|
return kysely;
|
|
323
347
|
}
|
|
348
|
+
function useControlPlaneKysely(postgres, options) {
|
|
349
|
+
return (0, control_plane_1.withControlPlaneSchema)(useKysely(postgres, options), 'public');
|
|
350
|
+
}
|
|
324
351
|
async function useAsyncControlPlaneKysely(connectionString, opt) {
|
|
325
|
-
|
|
326
|
-
return (0, control_plane_1.withControlPlaneSchema)(useKysely(sql, opt), 'public');
|
|
352
|
+
return useControlPlaneKysely(await useAsyncPostgres(connectionString, opt), opt);
|
|
327
353
|
}
|
|
328
354
|
async function forceCloseAllPostgres(timeoutMs = 5000) {
|
|
329
355
|
await Promise.race([
|
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 DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\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';\n\nexport type { Insertable, LogEvent } from 'kysely';\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\ntype KyselyOpts = {\n dataRegion?: TenantDataRegion;\n hyperdrive?: true;\n onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\ntype PostgresRetryDiagnostic = {\n attemptCount: number;\n dataRegion?: TenantDataRegion;\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'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n];\nconst postgresRetryAttempts = 3;\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 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 (error instanceof Error &&\n (error.message === 'connection attempt failed' ||\n ('code' in error && error.code === 'CONNECTION_DESTROYED')))\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 message === 'Node shutting down' ||\n message === 'Node shutting down.'\n );\n}\n\nasync function retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>,\n diagnostic?: Omit<PostgresRetryDiagnostic, 'attemptCount' | 'outcome'> & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n) {\n let attemptCount = 0;\n let retried = false;\n const emitDiagnostic = (outcome: PostgresRetryDiagnostic['outcome']) => {\n if (!diagnostic) return;\n diagnostic.emit({\n attemptCount,\n dataRegion: diagnostic.dataRegion,\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 async retry(error, attemptNumber) {\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 if (diagnostic?.shouldEmit(error)) {\n emitDiagnostic(\n retried && attemptCount === postgresRetryAttempts\n ? 'exhausted'\n : 'notRetryable'\n );\n }\n throw error;\n }\n}\n\nclass RetryingPostgresJSDialect extends PostgresJSDialect {\n constructor(\n private readonly config: PostgresJSDialectConfig,\n private readonly retryDiagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'operationKind' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n ) {\n super(config);\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n const connections = new WeakMap<\n DatabaseConnection,\n { connection: DatabaseConnection; inTransaction: boolean }\n >();\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 = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: (compiledQuery) => {\n const operationKind = state.inTransaction\n ? 'transaction'\n : compiledQuery.query.kind === 'SelectQueryNode'\n ? 'select'\n : 'mutation';\n return retryPostgres(\n () => state.connection.executeQuery(compiledQuery),\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 message !== 'Node shutting down' &&\n message !== 'Node shutting down.')))\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 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 driver.beginTransaction(state.connection, settings);\n } catch (error) {\n state.inTransaction = false;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.commitTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.rollbackTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n driver.savepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n driver.rollbackToSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n driver.releaseSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseConnection: async (connection) => {\n await driver.releaseConnection(getConnection(connection).connection);\n connections.delete(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 ),\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\nlet _connections: postgres.Sql[] = [];\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 ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;\n const url = new URL(connectionString);\n\n console.debug(\n `Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${ssl}, 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 = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n target_session_attrs: 'read-write',\n // enable prepare statements, pgbouncer on crunchy allows for prepared statements\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 }\n : {\n connect_timeout: 10,\n idle_timeout: 60,\n }),\n });\n\n if (probe) {\n await sql`select 1`;\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\n _connections.push(sql);\n return sql;\n } catch (err) {\n await sql?.end({ timeout: 0 }).catch(() => undefined);\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 async function useAsyncControlPlaneKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return withControlPlaneSchema(useKysely<ControlPlaneDB>(sql, opt), 'public');\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 DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\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 './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\ntype KyselyOpts = {\n dataRegion?: TenantDataRegion;\n hyperdrive?: true;\n onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\ntype PostgresRetryDiagnostic = {\n attemptCount: number;\n dataRegion?: TenantDataRegion;\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'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n];\nconst postgresRetryAttempts = 3;\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 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 (error instanceof Error &&\n (error.message === 'connection attempt failed' ||\n ('code' in error && error.code === 'CONNECTION_DESTROYED')))\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 message === 'Node shutting down' ||\n message === 'Node shutting down.'\n );\n}\n\nasync function retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>,\n diagnostic?: Omit<PostgresRetryDiagnostic, 'attemptCount' | 'outcome'> & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n) {\n let attemptCount = 0;\n let retried = false;\n const emitDiagnostic = (outcome: PostgresRetryDiagnostic['outcome']) => {\n if (!diagnostic) return;\n diagnostic.emit({\n attemptCount,\n dataRegion: diagnostic.dataRegion,\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 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 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' | 'operationKind' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n ) {\n super(config);\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n const connections = new WeakMap<\n DatabaseConnection,\n { connection: DatabaseConnection; inTransaction: boolean }\n >();\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 = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: (compiledQuery) => {\n const operationKind = state.inTransaction\n ? 'transaction'\n : compiledQuery.query.kind === 'SelectQueryNode'\n ? 'select'\n : 'mutation';\n return retryPostgres(\n () => state.connection.executeQuery(compiledQuery),\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 message !== 'Node shutting down' &&\n message !== 'Node shutting down.')))\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 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 driver.beginTransaction(state.connection, settings);\n } catch (error) {\n state.inTransaction = false;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.commitTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.rollbackTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n driver.savepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n driver.rollbackToSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n driver.releaseSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseConnection: async (connection) => {\n await driver.releaseConnection(getConnection(connection).connection);\n connections.delete(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 ),\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\nlet _connections: postgres.Sql[] = [];\nexport function usePostgres(\n connectionString: string,\n opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive'>\n) {\n const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;\n const sql = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n target_session_attrs: 'read-write',\n // enable prepare statements, pgbouncer on crunchy allows for prepared statements\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 }\n : {\n connect_timeout: 10,\n idle_timeout: 60,\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 !== true}, 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 await sql`select 1`;\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"]}
|
|
@@ -184,6 +184,23 @@ async function buildPreparedDump() {
|
|
|
184
184
|
execute replace(definition, 'public.', 'control_plane.');
|
|
185
185
|
end;
|
|
186
186
|
$$;
|
|
187
|
+
`.execute(controlPlaneBootstrapKysely);
|
|
188
|
+
// Team creation always assigns this registered feature in both databases.
|
|
189
|
+
// TODO(BIL-632): Remove both feature seeds when the billing rollout flag and
|
|
190
|
+
// its creation-time assignments are retired: https://linear.app/vrplatform/issue/BIL-632
|
|
191
|
+
await kysely
|
|
192
|
+
.insertInto('public.feature')
|
|
193
|
+
.values({
|
|
194
|
+
id: 'ed5d2ce6-92af-4ab6-84c0-32a7932fa3c0',
|
|
195
|
+
title: 'Direct pricing',
|
|
196
|
+
status: 'testing',
|
|
197
|
+
tenantId: null,
|
|
198
|
+
})
|
|
199
|
+
.execute();
|
|
200
|
+
await (0, kysely_1.sql) `
|
|
201
|
+
insert into control_plane.feature (id, title, status, tenant_id)
|
|
202
|
+
select id, title, status, tenant_id from public.feature
|
|
203
|
+
where id = 'ed5d2ce6-92af-4ab6-84c0-32a7932fa3c0'
|
|
187
204
|
`.execute(controlPlaneBootstrapKysely);
|
|
188
205
|
// The canonical VRPlatform tenant. Production code falls back to this exact id
|
|
189
206
|
// in getCalculatedBillingPartnerId, so specs need it to exist without each of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport { PGlite } from '@electric-sql/pglite';\nimport { FileMigrationProvider, type LogConfig, Migrator, sql } from 'kysely';\nimport { PGliteDialect } from 'kysely-pglite-dialect';\nimport { type ControlPlaneDB, withControlPlaneSchema } from '../control-plane';\nimport type { ControlPlaneKysely } from '../index';\nimport { appMigrationEpoch } from '../migration';\nimport { getKysely } from '../plugins';\nimport type { DB } from '../v1.generated';\nimport { ensureDigestFunction, ensureGenRandomBytesFunction } from './digest';\n\nexport const root = path.join(__dirname, '../..');\nexport const dumpPath = path.join(root, '.data.tar');\n\nexport type UseLocalKyselyOptions = {\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\nexport type LocalKysely = import('kysely').Kysely<DB> & {\n controlPlaneKysely: ControlPlaneKysely;\n};\n\nasync function migrateToLatest<Database>(\n kysely: import('kysely').Kysely<Database>\n) {\n const migrator = new Migrator({\n allowUnorderedMigrations: true,\n db: kysely,\n migrationTableSchema: appMigrationEpoch.tableSchema,\n migrationTableName: appMigrationEpoch.tableName,\n migrationLockTableName: appMigrationEpoch.lockTableName,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, appMigrationEpoch.folder),\n }),\n });\n\n const { error } = await migrator.migrateToLatest();\n if (error) {\n throw error;\n }\n}\n\n// Every spec file used to replay this identical bootstrap - migrations, the\n// schema surgery, and the control-plane seed copies - against a freshly loaded\n// snapshot, which measured ~345ms per file against ~185ms for the snapshot load\n// alone. None of it depends on the caller, so it runs once and is cached as a\n// prepared snapshot keyed by everything that determines its content.\nconst preparedDumpPrefix = '.data.prepared.';\n\nlet preparedDumpPromise: Promise<Blob> | undefined;\n\nasync function preparedDumpKey(): Promise<string> {\n const [snapshot, appMigrations, controlPlaneMigrations] = await Promise.all([\n fs.stat(dumpPath),\n fs.readdir(path.join(root, appMigrationEpoch.folder)),\n fs.readdir(path.join(root, 'control-plane-migrations')),\n ]);\n\n const hasher = new Bun.CryptoHasher('sha256');\n hasher.update(`${snapshot.size}:${snapshot.mtimeMs}`);\n hasher.update(appMigrations.sort().join(','));\n hasher.update(controlPlaneMigrations.sort().join(','));\n // Source of the bootstrap itself, so editing the surgery rebuilds the\n // snapshot. Read through toString() rather than the file: this module is also\n // published as CommonJS, where import.meta is a compile error.\n for (const step of [\n buildPreparedDump,\n migrateToLatest,\n ensureDigestFunction,\n ensureGenRandomBytesFunction,\n ]) {\n hasher.update(step.toString());\n }\n return hasher.digest('hex').slice(0, 16);\n}\n\nasync function resolvePreparedDump(): Promise<Blob> {\n const key = await preparedDumpKey();\n const target = path.join(root, `${preparedDumpPrefix}${key}.tar`);\n const cached = Bun.file(target);\n if (await cached.exists()) {\n return cached;\n }\n\n const content = await buildPreparedDump();\n // Sibling workers build this concurrently on a cold cache; rename is atomic,\n // so a reader never observes a half-written snapshot.\n const staging = `${target}.${process.pid}.tmp`;\n await Bun.write(staging, content);\n await fs.rename(staging, target);\n\n // Only finished snapshots: a sibling worker's staging file also carries the\n // prefix, and removing it would break its rename.\n const current = path.basename(target);\n for (const entry of await fs.readdir(root)) {\n if (\n entry.startsWith(preparedDumpPrefix) &&\n entry.endsWith('.tar') &&\n entry !== current\n ) {\n await fs.rm(path.join(root, entry), { force: true });\n }\n }\n\n return content;\n}\n\nasync function buildPreparedDump(): Promise<Blob> {\n const pglite = new PGlite({\n loadDataDir: Bun.file(dumpPath),\n });\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: 'localTestingPrepare',\n });\n await ensureDigestFunction(kysely);\n await ensureGenRandomBytesFunction(kysely);\n await migrateToLatest(kysely);\n\n await sql`alter schema public rename to regional_public`.execute(kysely);\n await sql`alter schema core rename to regional_core`.execute(kysely);\n await sql`create schema public`.execute(kysely);\n await sql`create schema core`.execute(kysely);\n\n const controlPlaneBootstrapKysely = getKysely<ControlPlaneDB>(dialect, {\n repositoryName: 'localTestingPrepare/control-plane-bootstrap',\n });\n const controlPlaneMigrator = new Migrator({\n db: controlPlaneBootstrapKysely,\n migrationTableSchema: 'public',\n migrationTableName: 'control_plane_kysely_migration',\n migrationLockTableName: 'control_plane_kysely_migration_lock',\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, 'control-plane-migrations'),\n }),\n });\n const { error: controlPlaneMigrationError } =\n await controlPlaneMigrator.migrateToLatest();\n if (controlPlaneMigrationError) {\n throw controlPlaneMigrationError;\n }\n\n await sql`alter table core.flow set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter table core.issue_message_overwrite set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`drop schema core`.execute(controlPlaneBootstrapKysely);\n await sql`alter schema public rename to control_plane`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_public rename to public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_core rename to core`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`\n do $$\n declare\n definition text;\n begin\n select pg_get_functiondef(\n 'control_plane.normalize_tenant_slug(text)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.build_unique_tenant_slug(text,uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_operation_state(uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_destructive_job_operation()'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n end;\n $$;\n `.execute(controlPlaneBootstrapKysely);\n // The canonical VRPlatform tenant. Production code falls back to this exact id\n // in getCalculatedBillingPartnerId, so specs need it to exist without each of\n // them creating - and mutating - their own copy of a shared singleton.\n await kysely\n .insertInto('public.tenant')\n .values({\n id: '7bfec41f-aa3f-4602-95d2-f7996e4f0e59',\n name: 'VRPlatform',\n type: 'partner',\n status: 'active',\n isActive: true,\n isGeneralLedger: false,\n isOnboarding: false,\n partnerId: null,\n billingPartnerId: null,\n defaultCurrency: 'usd',\n statementStartAt: new Date('2020-01-01T00:00:00Z'),\n })\n .onConflict((oc) => oc.column('id').doNothing())\n .execute();\n\n await sql`\n insert into control_plane.app (\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n )\n select\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n from public.app\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.currency (name)\n select name\n from public.currency\n on conflict (name) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel (\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n )\n select\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n from public.booking_channel\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel_icon_candidate (\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n )\n select\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n from public.booking_channel_icon_candidate\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.tenant (\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n )\n select\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n from public.tenant\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.token (\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n )\n select\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n from public.token\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n\n const content = await pglite.dumpDataDir('none');\n await kysely.destroy();\n return content;\n}\n\nexport async function useLocalKysely(\n args: UseLocalKyselyOptions = {}\n): Promise<LocalKysely> {\n let isDestroyed = false;\n\n preparedDumpPromise ??= resolvePreparedDump();\n const pglite = new PGlite({\n loadDataDir: await preparedDumpPromise,\n });\n // The constructor is lazy. The bootstrap this replaced forced the snapshot to\n // load before returning, so keep that contract: a returned handle is usable,\n // and a bad snapshot fails here instead of inside an unrelated test.\n await pglite.waitReady;\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: args?.repositoryName ?? 'localTesting',\n log: args?.log,\n });\n\n const controlPlaneKysely = withControlPlaneSchema(\n getKysely<ControlPlaneDB>(dialect, {\n repositoryName: `${args.repositoryName ?? 'localTesting'}/control-plane`,\n log: args.log,\n }),\n 'control_plane',\n 'control_plane'\n );\n controlPlaneKysely.destroy = async () => {};\n Object.defineProperty(kysely, 'controlPlaneKysely', {\n value: controlPlaneKysely,\n });\n\n const originalDestroy = kysely.destroy.bind(kysely);\n kysely.destroy = async () => {\n if (isDestroyed) return;\n isDestroyed = true;\n //const destroyTime = performance.now();\n await originalDestroy();\n //console.log(\n // `Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`\n //);\n };\n\n // console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);\n\n return kysely as LocalKysely;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport { PGlite } from '@electric-sql/pglite';\nimport { FileMigrationProvider, type LogConfig, Migrator, sql } from 'kysely';\nimport { PGliteDialect } from 'kysely-pglite-dialect';\nimport { type ControlPlaneDB, withControlPlaneSchema } from '../control-plane';\nimport type { ControlPlaneKysely } from '../index';\nimport { appMigrationEpoch } from '../migration';\nimport { getKysely } from '../plugins';\nimport type { DB } from '../v1.generated';\nimport { ensureDigestFunction, ensureGenRandomBytesFunction } from './digest';\n\nexport const root = path.join(__dirname, '../..');\nexport const dumpPath = path.join(root, '.data.tar');\n\nexport type UseLocalKyselyOptions = {\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\nexport type LocalKysely = import('kysely').Kysely<DB> & {\n controlPlaneKysely: ControlPlaneKysely;\n};\n\nasync function migrateToLatest<Database>(\n kysely: import('kysely').Kysely<Database>\n) {\n const migrator = new Migrator({\n allowUnorderedMigrations: true,\n db: kysely,\n migrationTableSchema: appMigrationEpoch.tableSchema,\n migrationTableName: appMigrationEpoch.tableName,\n migrationLockTableName: appMigrationEpoch.lockTableName,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, appMigrationEpoch.folder),\n }),\n });\n\n const { error } = await migrator.migrateToLatest();\n if (error) {\n throw error;\n }\n}\n\n// Every spec file used to replay this identical bootstrap - migrations, the\n// schema surgery, and the control-plane seed copies - against a freshly loaded\n// snapshot, which measured ~345ms per file against ~185ms for the snapshot load\n// alone. None of it depends on the caller, so it runs once and is cached as a\n// prepared snapshot keyed by everything that determines its content.\nconst preparedDumpPrefix = '.data.prepared.';\n\nlet preparedDumpPromise: Promise<Blob> | undefined;\n\nasync function preparedDumpKey(): Promise<string> {\n const [snapshot, appMigrations, controlPlaneMigrations] = await Promise.all([\n fs.stat(dumpPath),\n fs.readdir(path.join(root, appMigrationEpoch.folder)),\n fs.readdir(path.join(root, 'control-plane-migrations')),\n ]);\n\n const hasher = new Bun.CryptoHasher('sha256');\n hasher.update(`${snapshot.size}:${snapshot.mtimeMs}`);\n hasher.update(appMigrations.sort().join(','));\n hasher.update(controlPlaneMigrations.sort().join(','));\n // Source of the bootstrap itself, so editing the surgery rebuilds the\n // snapshot. Read through toString() rather than the file: this module is also\n // published as CommonJS, where import.meta is a compile error.\n for (const step of [\n buildPreparedDump,\n migrateToLatest,\n ensureDigestFunction,\n ensureGenRandomBytesFunction,\n ]) {\n hasher.update(step.toString());\n }\n return hasher.digest('hex').slice(0, 16);\n}\n\nasync function resolvePreparedDump(): Promise<Blob> {\n const key = await preparedDumpKey();\n const target = path.join(root, `${preparedDumpPrefix}${key}.tar`);\n const cached = Bun.file(target);\n if (await cached.exists()) {\n return cached;\n }\n\n const content = await buildPreparedDump();\n // Sibling workers build this concurrently on a cold cache; rename is atomic,\n // so a reader never observes a half-written snapshot.\n const staging = `${target}.${process.pid}.tmp`;\n await Bun.write(staging, content);\n await fs.rename(staging, target);\n\n // Only finished snapshots: a sibling worker's staging file also carries the\n // prefix, and removing it would break its rename.\n const current = path.basename(target);\n for (const entry of await fs.readdir(root)) {\n if (\n entry.startsWith(preparedDumpPrefix) &&\n entry.endsWith('.tar') &&\n entry !== current\n ) {\n await fs.rm(path.join(root, entry), { force: true });\n }\n }\n\n return content;\n}\n\nasync function buildPreparedDump(): Promise<Blob> {\n const pglite = new PGlite({\n loadDataDir: Bun.file(dumpPath),\n });\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: 'localTestingPrepare',\n });\n await ensureDigestFunction(kysely);\n await ensureGenRandomBytesFunction(kysely);\n await migrateToLatest(kysely);\n\n await sql`alter schema public rename to regional_public`.execute(kysely);\n await sql`alter schema core rename to regional_core`.execute(kysely);\n await sql`create schema public`.execute(kysely);\n await sql`create schema core`.execute(kysely);\n\n const controlPlaneBootstrapKysely = getKysely<ControlPlaneDB>(dialect, {\n repositoryName: 'localTestingPrepare/control-plane-bootstrap',\n });\n const controlPlaneMigrator = new Migrator({\n db: controlPlaneBootstrapKysely,\n migrationTableSchema: 'public',\n migrationTableName: 'control_plane_kysely_migration',\n migrationLockTableName: 'control_plane_kysely_migration_lock',\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, 'control-plane-migrations'),\n }),\n });\n const { error: controlPlaneMigrationError } =\n await controlPlaneMigrator.migrateToLatest();\n if (controlPlaneMigrationError) {\n throw controlPlaneMigrationError;\n }\n\n await sql`alter table core.flow set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter table core.issue_message_overwrite set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`drop schema core`.execute(controlPlaneBootstrapKysely);\n await sql`alter schema public rename to control_plane`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_public rename to public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_core rename to core`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`\n do $$\n declare\n definition text;\n begin\n select pg_get_functiondef(\n 'control_plane.normalize_tenant_slug(text)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.build_unique_tenant_slug(text,uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_operation_state(uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_destructive_job_operation()'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n end;\n $$;\n `.execute(controlPlaneBootstrapKysely);\n // Team creation always assigns this registered feature in both databases.\n // TODO(BIL-632): Remove both feature seeds when the billing rollout flag and\n // its creation-time assignments are retired: https://linear.app/vrplatform/issue/BIL-632\n await kysely\n .insertInto('public.feature')\n .values({\n id: 'ed5d2ce6-92af-4ab6-84c0-32a7932fa3c0',\n title: 'Direct pricing',\n status: 'testing',\n tenantId: null,\n })\n .execute();\n await sql`\n insert into control_plane.feature (id, title, status, tenant_id)\n select id, title, status, tenant_id from public.feature\n where id = 'ed5d2ce6-92af-4ab6-84c0-32a7932fa3c0'\n `.execute(controlPlaneBootstrapKysely);\n // The canonical VRPlatform tenant. Production code falls back to this exact id\n // in getCalculatedBillingPartnerId, so specs need it to exist without each of\n // them creating - and mutating - their own copy of a shared singleton.\n await kysely\n .insertInto('public.tenant')\n .values({\n id: '7bfec41f-aa3f-4602-95d2-f7996e4f0e59',\n name: 'VRPlatform',\n type: 'partner',\n status: 'active',\n isActive: true,\n isGeneralLedger: false,\n isOnboarding: false,\n partnerId: null,\n billingPartnerId: null,\n defaultCurrency: 'usd',\n statementStartAt: new Date('2020-01-01T00:00:00Z'),\n })\n .onConflict((oc) => oc.column('id').doNothing())\n .execute();\n\n await sql`\n insert into control_plane.app (\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n )\n select\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n from public.app\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.currency (name)\n select name\n from public.currency\n on conflict (name) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel (\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n )\n select\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n from public.booking_channel\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel_icon_candidate (\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n )\n select\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n from public.booking_channel_icon_candidate\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.tenant (\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n )\n select\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n from public.tenant\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.token (\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n )\n select\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n from public.token\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n\n const content = await pglite.dumpDataDir('none');\n await kysely.destroy();\n return content;\n}\n\nexport async function useLocalKysely(\n args: UseLocalKyselyOptions = {}\n): Promise<LocalKysely> {\n let isDestroyed = false;\n\n preparedDumpPromise ??= resolvePreparedDump();\n const pglite = new PGlite({\n loadDataDir: await preparedDumpPromise,\n });\n // The constructor is lazy. The bootstrap this replaced forced the snapshot to\n // load before returning, so keep that contract: a returned handle is usable,\n // and a bad snapshot fails here instead of inside an unrelated test.\n await pglite.waitReady;\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: args?.repositoryName ?? 'localTesting',\n log: args?.log,\n });\n\n const controlPlaneKysely = withControlPlaneSchema(\n getKysely<ControlPlaneDB>(dialect, {\n repositoryName: `${args.repositoryName ?? 'localTesting'}/control-plane`,\n log: args.log,\n }),\n 'control_plane',\n 'control_plane'\n );\n controlPlaneKysely.destroy = async () => {};\n Object.defineProperty(kysely, 'controlPlaneKysely', {\n value: controlPlaneKysely,\n });\n\n const originalDestroy = kysely.destroy.bind(kysely);\n kysely.destroy = async () => {\n if (isDestroyed) return;\n isDestroyed = true;\n //const destroyTime = performance.now();\n await originalDestroy();\n //console.log(\n // `Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`\n //);\n };\n\n // console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);\n\n return kysely as LocalKysely;\n}\n"]}
|
package/build/module/index.d.ts
CHANGED
|
@@ -29,12 +29,21 @@ type PgOpt = {
|
|
|
29
29
|
probe?: true;
|
|
30
30
|
retries?: false | number;
|
|
31
31
|
} & Pick<KyselyOpts, 'hyperdrive'>;
|
|
32
|
+
/**
|
|
33
|
+
* Replays a complete database operation after a PostgreSQL deadlock (40P01)
|
|
34
|
+
* or lock timeout (55P03), using the same three-attempt jittered budget as
|
|
35
|
+
* connection retries. The operation must own its transaction and must not
|
|
36
|
+
* contain external side effects such as partner API writes.
|
|
37
|
+
*/
|
|
38
|
+
export declare function retryPostgresLockFailure<T>(operation: () => Promise<T>): Promise<T>;
|
|
32
39
|
export type Kysely = K<DB>;
|
|
33
40
|
export type ControlPlaneKysely = K<ControlPlaneDB>;
|
|
34
41
|
export type ControlPlaneTransaction = T<ControlPlaneDB>;
|
|
35
42
|
export declare function useKysely<Database = DB>(postgres: Sql, options?: KyselyOpts): K<Database>;
|
|
43
|
+
export declare function usePostgres(connectionString: string, opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive'>): postgres.Sql<{}>;
|
|
36
44
|
export declare function useAsyncPostgres(connectionString: string, opt?: PgOpt): Promise<postgres.Sql<{}>>;
|
|
37
45
|
export declare function useAsyncKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<DB>>;
|
|
38
46
|
export declare function useAsyncNeonWebSocketKysely(connectionString: string, opt?: Pick<PgOpt, 'probe'> & KyselyOpts): Promise<K<DB>>;
|
|
47
|
+
export declare function useControlPlaneKysely(postgres: Sql, options?: KyselyOpts): K<ControlPlaneDB>;
|
|
39
48
|
export declare function useAsyncControlPlaneKysely(connectionString: string, opt?: PgOpt & KyselyOpts): Promise<K<ControlPlaneDB>>;
|
|
40
49
|
export declare function forceCloseAllPostgres(timeoutMs?: number): Promise<void>;
|
package/build/module/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import postgres from 'postgres';
|
|
|
6
6
|
import { withControlPlaneSchema } from './control-plane';
|
|
7
7
|
import { KyselyError } from './error';
|
|
8
8
|
import { getKysely } from './plugins';
|
|
9
|
+
import { isPostgresError } from './postgres-error';
|
|
9
10
|
export * from './error';
|
|
10
11
|
export * from './isomorphic';
|
|
11
12
|
export * from './postgres-error';
|
|
@@ -65,6 +66,9 @@ async function retryPostgres(operation, retry, diagnostic) {
|
|
|
65
66
|
numOfAttempts: postgresRetryAttempts,
|
|
66
67
|
startingDelay: parseDuration('1s'),
|
|
67
68
|
maxDelay: parseDuration('5s'),
|
|
69
|
+
// Scheduled chunk fan-outs open many connections at once; full jitter
|
|
70
|
+
// keeps their retries from reconnecting in lockstep.
|
|
71
|
+
jitter: 'full',
|
|
68
72
|
async retry(error, attemptNumber) {
|
|
69
73
|
const shouldRetry = attemptNumber < postgresRetryAttempts &&
|
|
70
74
|
(await retry(error, attemptNumber));
|
|
@@ -85,6 +89,16 @@ async function retryPostgres(operation, retry, diagnostic) {
|
|
|
85
89
|
throw error;
|
|
86
90
|
}
|
|
87
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Replays a complete database operation after a PostgreSQL deadlock (40P01)
|
|
94
|
+
* or lock timeout (55P03), using the same three-attempt jittered budget as
|
|
95
|
+
* connection retries. The operation must own its transaction and must not
|
|
96
|
+
* contain external side effects such as partner API writes.
|
|
97
|
+
*/
|
|
98
|
+
export function retryPostgresLockFailure(operation) {
|
|
99
|
+
return retryPostgres(operation, (error) => isPostgresError(error, { code: '40P01' }) ||
|
|
100
|
+
isPostgresError(error, { code: '55P03' }));
|
|
101
|
+
}
|
|
88
102
|
class RetryingPostgresJSDialect extends PostgresJSDialect {
|
|
89
103
|
config;
|
|
90
104
|
retryDiagnostic;
|
|
@@ -235,45 +249,52 @@ export function useKysely(postgres, options) {
|
|
|
235
249
|
return kysely;
|
|
236
250
|
}
|
|
237
251
|
let _connections = [];
|
|
252
|
+
export function usePostgres(connectionString, opt) {
|
|
253
|
+
const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;
|
|
254
|
+
const sql = postgres(connectionString, {
|
|
255
|
+
ssl: ssl ? 'require' : false,
|
|
256
|
+
target_session_attrs: 'read-write',
|
|
257
|
+
// enable prepare statements, pgbouncer on crunchy allows for prepared statements
|
|
258
|
+
prepare: true,
|
|
259
|
+
...(opt?.hyperdrive
|
|
260
|
+
? {
|
|
261
|
+
max: 5,
|
|
262
|
+
// Retire idle clients before Hyperdrive can close them asynchronously.
|
|
263
|
+
idle_timeout: 10,
|
|
264
|
+
}
|
|
265
|
+
: {
|
|
266
|
+
connect_timeout: 10,
|
|
267
|
+
idle_timeout: 60,
|
|
268
|
+
}),
|
|
269
|
+
});
|
|
270
|
+
// statement_timeout/lock_timeout are role-level settings on the cluster
|
|
271
|
+
// (ALTER ROLE application SET ...) so they cover every pooled
|
|
272
|
+
// connection; per-session SETs here only ever applied to one of them
|
|
273
|
+
_connections.push(sql);
|
|
274
|
+
return sql;
|
|
275
|
+
}
|
|
238
276
|
export async function useAsyncPostgres(connectionString, opt) {
|
|
239
277
|
const delayMs = 2500;
|
|
240
278
|
const probe = opt?.probe === true;
|
|
241
279
|
const retries = probe ? (opt?.retries === false ? 0 : opt?.retries || 3) : 1;
|
|
242
|
-
const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;
|
|
243
280
|
const url = new URL(connectionString);
|
|
244
|
-
console.debug(`Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${
|
|
281
|
+
console.debug(`Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${opt?.forceDisableSSL !== true && opt?.hyperdrive !== true}, and port=${url.port}`);
|
|
245
282
|
if (_connections.length > 0)
|
|
246
283
|
console.warn(`We already have ${_connections.length} Postgres connections`);
|
|
247
284
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
248
285
|
let sql;
|
|
249
286
|
try {
|
|
250
|
-
sql =
|
|
251
|
-
ssl: ssl ? 'require' : false,
|
|
252
|
-
target_session_attrs: 'read-write',
|
|
253
|
-
// enable prepare statements, pgbouncer on crunchy allows for prepared statements
|
|
254
|
-
prepare: true,
|
|
255
|
-
...(opt?.hyperdrive
|
|
256
|
-
? {
|
|
257
|
-
max: 5,
|
|
258
|
-
// Retire idle clients before Hyperdrive can close them asynchronously.
|
|
259
|
-
idle_timeout: 10,
|
|
260
|
-
}
|
|
261
|
-
: {
|
|
262
|
-
connect_timeout: 10,
|
|
263
|
-
idle_timeout: 60,
|
|
264
|
-
}),
|
|
265
|
-
});
|
|
287
|
+
sql = usePostgres(connectionString, opt);
|
|
266
288
|
if (probe) {
|
|
267
289
|
await sql `select 1`;
|
|
268
290
|
}
|
|
269
|
-
// statement_timeout/lock_timeout are role-level settings on the cluster
|
|
270
|
-
// (ALTER ROLE application SET ...) so they cover every pooled
|
|
271
|
-
// connection; per-session SETs here only ever applied to one of them
|
|
272
|
-
_connections.push(sql);
|
|
273
291
|
return sql;
|
|
274
292
|
}
|
|
275
293
|
catch (err) {
|
|
276
|
-
|
|
294
|
+
if (sql) {
|
|
295
|
+
await sql.end({ timeout: 0 }).catch(() => undefined);
|
|
296
|
+
_connections.splice(_connections.indexOf(sql), 1);
|
|
297
|
+
}
|
|
277
298
|
if (attempt === retries)
|
|
278
299
|
throw err;
|
|
279
300
|
console.warn(`Postgres connection failed (attempt ${attempt}), retrying...`);
|
|
@@ -298,9 +319,11 @@ export async function useAsyncNeonWebSocketKysely(connectionString, opt) {
|
|
|
298
319
|
await pool.query('select 1');
|
|
299
320
|
return kysely;
|
|
300
321
|
}
|
|
322
|
+
export function useControlPlaneKysely(postgres, options) {
|
|
323
|
+
return withControlPlaneSchema(useKysely(postgres, options), 'public');
|
|
324
|
+
}
|
|
301
325
|
export async function useAsyncControlPlaneKysely(connectionString, opt) {
|
|
302
|
-
|
|
303
|
-
return withControlPlaneSchema(useKysely(sql, opt), 'public');
|
|
326
|
+
return useControlPlaneKysely(await useAsyncPostgres(connectionString, opt), opt);
|
|
304
327
|
}
|
|
305
328
|
export async function forceCloseAllPostgres(timeoutMs = 5000) {
|
|
306
329
|
await Promise.race([
|
|
@@ -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 DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\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';\n\nexport type { Insertable, LogEvent } from 'kysely';\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\ntype KyselyOpts = {\n dataRegion?: TenantDataRegion;\n hyperdrive?: true;\n onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\ntype PostgresRetryDiagnostic = {\n attemptCount: number;\n dataRegion?: TenantDataRegion;\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'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n];\nconst postgresRetryAttempts = 3;\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 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 (error instanceof Error &&\n (error.message === 'connection attempt failed' ||\n ('code' in error && error.code === 'CONNECTION_DESTROYED')))\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 message === 'Node shutting down' ||\n message === 'Node shutting down.'\n );\n}\n\nasync function retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>,\n diagnostic?: Omit<PostgresRetryDiagnostic, 'attemptCount' | 'outcome'> & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n) {\n let attemptCount = 0;\n let retried = false;\n const emitDiagnostic = (outcome: PostgresRetryDiagnostic['outcome']) => {\n if (!diagnostic) return;\n diagnostic.emit({\n attemptCount,\n dataRegion: diagnostic.dataRegion,\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 async retry(error, attemptNumber) {\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 if (diagnostic?.shouldEmit(error)) {\n emitDiagnostic(\n retried && attemptCount === postgresRetryAttempts\n ? 'exhausted'\n : 'notRetryable'\n );\n }\n throw error;\n }\n}\n\nclass RetryingPostgresJSDialect extends PostgresJSDialect {\n constructor(\n private readonly config: PostgresJSDialectConfig,\n private readonly retryDiagnostic?: Omit<\n PostgresRetryDiagnostic,\n 'attemptCount' | 'operationKind' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n ) {\n super(config);\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n const connections = new WeakMap<\n DatabaseConnection,\n { connection: DatabaseConnection; inTransaction: boolean }\n >();\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 = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: (compiledQuery) => {\n const operationKind = state.inTransaction\n ? 'transaction'\n : compiledQuery.query.kind === 'SelectQueryNode'\n ? 'select'\n : 'mutation';\n return retryPostgres(\n () => state.connection.executeQuery(compiledQuery),\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 message !== 'Node shutting down' &&\n message !== 'Node shutting down.')))\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 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 driver.beginTransaction(state.connection, settings);\n } catch (error) {\n state.inTransaction = false;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.commitTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.rollbackTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n driver.savepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n driver.rollbackToSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n driver.releaseSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseConnection: async (connection) => {\n await driver.releaseConnection(getConnection(connection).connection);\n connections.delete(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 ),\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\nlet _connections: postgres.Sql[] = [];\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 ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;\n const url = new URL(connectionString);\n\n console.debug(\n `Creating Postgres connection with probe=${probe}, ${retries} attempts, ssl=${ssl}, 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 = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n target_session_attrs: 'read-write',\n // enable prepare statements, pgbouncer on crunchy allows for prepared statements\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 }\n : {\n connect_timeout: 10,\n idle_timeout: 60,\n }),\n });\n\n if (probe) {\n await sql`select 1`;\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\n _connections.push(sql);\n return sql;\n } catch (err) {\n await sql?.end({ timeout: 0 }).catch(() => undefined);\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 async function useAsyncControlPlaneKysely(\n connectionString: string,\n opt?: PgOpt & KyselyOpts\n) {\n const sql = await useAsyncPostgres(connectionString, opt);\n return withControlPlaneSchema(useKysely<ControlPlaneDB>(sql, opt), 'public');\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 DatabaseConnection,\n Driver,\n Kysely as K,\n LogConfig,\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 './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\ntype KyselyOpts = {\n dataRegion?: TenantDataRegion;\n hyperdrive?: true;\n onRetryDiagnostic?: (diagnostic: PostgresRetryDiagnostic) => void;\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\ntype PostgresRetryDiagnostic = {\n attemptCount: number;\n dataRegion?: TenantDataRegion;\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'>;\n\nconst retryableMessages = [\n 'CONNECTION_CLOSED',\n 'CONNECT_TIMEOUT',\n 'Idle connection closed by Hyperdrive.',\n 'server_login_retry',\n];\nconst postgresRetryAttempts = 3;\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 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 (error instanceof Error &&\n (error.message === 'connection attempt failed' ||\n ('code' in error && error.code === 'CONNECTION_DESTROYED')))\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 message === 'Node shutting down' ||\n message === 'Node shutting down.'\n );\n}\n\nasync function retryPostgres<T>(\n operation: () => Promise<T>,\n retry: (error: unknown, attemptNumber: number) => boolean | Promise<boolean>,\n diagnostic?: Omit<PostgresRetryDiagnostic, 'attemptCount' | 'outcome'> & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n) {\n let attemptCount = 0;\n let retried = false;\n const emitDiagnostic = (outcome: PostgresRetryDiagnostic['outcome']) => {\n if (!diagnostic) return;\n diagnostic.emit({\n attemptCount,\n dataRegion: diagnostic.dataRegion,\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 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 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' | 'operationKind' | 'outcome'\n > & {\n emit: (diagnostic: PostgresRetryDiagnostic) => void;\n shouldEmit: (error: unknown) => boolean;\n }\n ) {\n super(config);\n }\n\n override createDriver(): Driver {\n const driver = new PostgresJSDriver(this.config);\n const connections = new WeakMap<\n DatabaseConnection,\n { connection: DatabaseConnection; inTransaction: boolean }\n >();\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 = {\n connection: await driver.acquireConnection(),\n inTransaction: false,\n };\n const connection: DatabaseConnection = {\n executeQuery: (compiledQuery) => {\n const operationKind = state.inTransaction\n ? 'transaction'\n : compiledQuery.query.kind === 'SelectQueryNode'\n ? 'select'\n : 'mutation';\n return retryPostgres(\n () => state.connection.executeQuery(compiledQuery),\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 message !== 'Node shutting down' &&\n message !== 'Node shutting down.')))\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 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 driver.beginTransaction(state.connection, settings);\n } catch (error) {\n state.inTransaction = false;\n throw error;\n }\n },\n commitTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.commitTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n rollbackTransaction: async (connection) => {\n const state = getConnection(connection);\n try {\n await driver.rollbackTransaction(state.connection);\n } finally {\n state.inTransaction = false;\n }\n },\n savepoint: (connection, savepointName, compileQuery) =>\n driver.savepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n rollbackToSavepoint: (connection, savepointName, compileQuery) =>\n driver.rollbackToSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseSavepoint: (connection, savepointName, compileQuery) =>\n driver.releaseSavepoint(\n getConnection(connection).connection,\n savepointName,\n compileQuery\n ),\n releaseConnection: async (connection) => {\n await driver.releaseConnection(getConnection(connection).connection);\n connections.delete(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 ),\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\nlet _connections: postgres.Sql[] = [];\nexport function usePostgres(\n connectionString: string,\n opt?: Pick<PgOpt, 'forceDisableSSL' | 'hyperdrive'>\n) {\n const ssl = opt?.forceDisableSSL !== true && opt?.hyperdrive !== true;\n const sql = postgres(connectionString, {\n ssl: ssl ? 'require' : false,\n target_session_attrs: 'read-write',\n // enable prepare statements, pgbouncer on crunchy allows for prepared statements\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 }\n : {\n connect_timeout: 10,\n idle_timeout: 60,\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 !== true}, 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 await sql`select 1`;\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"]}
|
|
@@ -147,6 +147,23 @@ async function buildPreparedDump() {
|
|
|
147
147
|
execute replace(definition, 'public.', 'control_plane.');
|
|
148
148
|
end;
|
|
149
149
|
$$;
|
|
150
|
+
`.execute(controlPlaneBootstrapKysely);
|
|
151
|
+
// Team creation always assigns this registered feature in both databases.
|
|
152
|
+
// TODO(BIL-632): Remove both feature seeds when the billing rollout flag and
|
|
153
|
+
// its creation-time assignments are retired: https://linear.app/vrplatform/issue/BIL-632
|
|
154
|
+
await kysely
|
|
155
|
+
.insertInto('public.feature')
|
|
156
|
+
.values({
|
|
157
|
+
id: 'ed5d2ce6-92af-4ab6-84c0-32a7932fa3c0',
|
|
158
|
+
title: 'Direct pricing',
|
|
159
|
+
status: 'testing',
|
|
160
|
+
tenantId: null,
|
|
161
|
+
})
|
|
162
|
+
.execute();
|
|
163
|
+
await sql `
|
|
164
|
+
insert into control_plane.feature (id, title, status, tenant_id)
|
|
165
|
+
select id, title, status, tenant_id from public.feature
|
|
166
|
+
where id = 'ed5d2ce6-92af-4ab6-84c0-32a7932fa3c0'
|
|
150
167
|
`.execute(controlPlaneBootstrapKysely);
|
|
151
168
|
// The canonical VRPlatform tenant. Production code falls back to this exact id
|
|
152
169
|
// in getCalculatedBillingPartnerId, so specs need it to exist without each of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport { PGlite } from '@electric-sql/pglite';\nimport { FileMigrationProvider, type LogConfig, Migrator, sql } from 'kysely';\nimport { PGliteDialect } from 'kysely-pglite-dialect';\nimport { type ControlPlaneDB, withControlPlaneSchema } from '../control-plane';\nimport type { ControlPlaneKysely } from '../index';\nimport { appMigrationEpoch } from '../migration';\nimport { getKysely } from '../plugins';\nimport type { DB } from '../v1.generated';\nimport { ensureDigestFunction, ensureGenRandomBytesFunction } from './digest';\n\nexport const root = path.join(__dirname, '../..');\nexport const dumpPath = path.join(root, '.data.tar');\n\nexport type UseLocalKyselyOptions = {\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\nexport type LocalKysely = import('kysely').Kysely<DB> & {\n controlPlaneKysely: ControlPlaneKysely;\n};\n\nasync function migrateToLatest<Database>(\n kysely: import('kysely').Kysely<Database>\n) {\n const migrator = new Migrator({\n allowUnorderedMigrations: true,\n db: kysely,\n migrationTableSchema: appMigrationEpoch.tableSchema,\n migrationTableName: appMigrationEpoch.tableName,\n migrationLockTableName: appMigrationEpoch.lockTableName,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, appMigrationEpoch.folder),\n }),\n });\n\n const { error } = await migrator.migrateToLatest();\n if (error) {\n throw error;\n }\n}\n\n// Every spec file used to replay this identical bootstrap - migrations, the\n// schema surgery, and the control-plane seed copies - against a freshly loaded\n// snapshot, which measured ~345ms per file against ~185ms for the snapshot load\n// alone. None of it depends on the caller, so it runs once and is cached as a\n// prepared snapshot keyed by everything that determines its content.\nconst preparedDumpPrefix = '.data.prepared.';\n\nlet preparedDumpPromise: Promise<Blob> | undefined;\n\nasync function preparedDumpKey(): Promise<string> {\n const [snapshot, appMigrations, controlPlaneMigrations] = await Promise.all([\n fs.stat(dumpPath),\n fs.readdir(path.join(root, appMigrationEpoch.folder)),\n fs.readdir(path.join(root, 'control-plane-migrations')),\n ]);\n\n const hasher = new Bun.CryptoHasher('sha256');\n hasher.update(`${snapshot.size}:${snapshot.mtimeMs}`);\n hasher.update(appMigrations.sort().join(','));\n hasher.update(controlPlaneMigrations.sort().join(','));\n // Source of the bootstrap itself, so editing the surgery rebuilds the\n // snapshot. Read through toString() rather than the file: this module is also\n // published as CommonJS, where import.meta is a compile error.\n for (const step of [\n buildPreparedDump,\n migrateToLatest,\n ensureDigestFunction,\n ensureGenRandomBytesFunction,\n ]) {\n hasher.update(step.toString());\n }\n return hasher.digest('hex').slice(0, 16);\n}\n\nasync function resolvePreparedDump(): Promise<Blob> {\n const key = await preparedDumpKey();\n const target = path.join(root, `${preparedDumpPrefix}${key}.tar`);\n const cached = Bun.file(target);\n if (await cached.exists()) {\n return cached;\n }\n\n const content = await buildPreparedDump();\n // Sibling workers build this concurrently on a cold cache; rename is atomic,\n // so a reader never observes a half-written snapshot.\n const staging = `${target}.${process.pid}.tmp`;\n await Bun.write(staging, content);\n await fs.rename(staging, target);\n\n // Only finished snapshots: a sibling worker's staging file also carries the\n // prefix, and removing it would break its rename.\n const current = path.basename(target);\n for (const entry of await fs.readdir(root)) {\n if (\n entry.startsWith(preparedDumpPrefix) &&\n entry.endsWith('.tar') &&\n entry !== current\n ) {\n await fs.rm(path.join(root, entry), { force: true });\n }\n }\n\n return content;\n}\n\nasync function buildPreparedDump(): Promise<Blob> {\n const pglite = new PGlite({\n loadDataDir: Bun.file(dumpPath),\n });\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: 'localTestingPrepare',\n });\n await ensureDigestFunction(kysely);\n await ensureGenRandomBytesFunction(kysely);\n await migrateToLatest(kysely);\n\n await sql`alter schema public rename to regional_public`.execute(kysely);\n await sql`alter schema core rename to regional_core`.execute(kysely);\n await sql`create schema public`.execute(kysely);\n await sql`create schema core`.execute(kysely);\n\n const controlPlaneBootstrapKysely = getKysely<ControlPlaneDB>(dialect, {\n repositoryName: 'localTestingPrepare/control-plane-bootstrap',\n });\n const controlPlaneMigrator = new Migrator({\n db: controlPlaneBootstrapKysely,\n migrationTableSchema: 'public',\n migrationTableName: 'control_plane_kysely_migration',\n migrationLockTableName: 'control_plane_kysely_migration_lock',\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, 'control-plane-migrations'),\n }),\n });\n const { error: controlPlaneMigrationError } =\n await controlPlaneMigrator.migrateToLatest();\n if (controlPlaneMigrationError) {\n throw controlPlaneMigrationError;\n }\n\n await sql`alter table core.flow set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter table core.issue_message_overwrite set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`drop schema core`.execute(controlPlaneBootstrapKysely);\n await sql`alter schema public rename to control_plane`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_public rename to public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_core rename to core`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`\n do $$\n declare\n definition text;\n begin\n select pg_get_functiondef(\n 'control_plane.normalize_tenant_slug(text)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.build_unique_tenant_slug(text,uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_operation_state(uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_destructive_job_operation()'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n end;\n $$;\n `.execute(controlPlaneBootstrapKysely);\n // The canonical VRPlatform tenant. Production code falls back to this exact id\n // in getCalculatedBillingPartnerId, so specs need it to exist without each of\n // them creating - and mutating - their own copy of a shared singleton.\n await kysely\n .insertInto('public.tenant')\n .values({\n id: '7bfec41f-aa3f-4602-95d2-f7996e4f0e59',\n name: 'VRPlatform',\n type: 'partner',\n status: 'active',\n isActive: true,\n isGeneralLedger: false,\n isOnboarding: false,\n partnerId: null,\n billingPartnerId: null,\n defaultCurrency: 'usd',\n statementStartAt: new Date('2020-01-01T00:00:00Z'),\n })\n .onConflict((oc) => oc.column('id').doNothing())\n .execute();\n\n await sql`\n insert into control_plane.app (\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n )\n select\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n from public.app\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.currency (name)\n select name\n from public.currency\n on conflict (name) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel (\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n )\n select\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n from public.booking_channel\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel_icon_candidate (\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n )\n select\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n from public.booking_channel_icon_candidate\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.tenant (\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n )\n select\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n from public.tenant\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.token (\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n )\n select\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n from public.token\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n\n const content = await pglite.dumpDataDir('none');\n await kysely.destroy();\n return content;\n}\n\nexport async function useLocalKysely(\n args: UseLocalKyselyOptions = {}\n): Promise<LocalKysely> {\n let isDestroyed = false;\n\n preparedDumpPromise ??= resolvePreparedDump();\n const pglite = new PGlite({\n loadDataDir: await preparedDumpPromise,\n });\n // The constructor is lazy. The bootstrap this replaced forced the snapshot to\n // load before returning, so keep that contract: a returned handle is usable,\n // and a bad snapshot fails here instead of inside an unrelated test.\n await pglite.waitReady;\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: args?.repositoryName ?? 'localTesting',\n log: args?.log,\n });\n\n const controlPlaneKysely = withControlPlaneSchema(\n getKysely<ControlPlaneDB>(dialect, {\n repositoryName: `${args.repositoryName ?? 'localTesting'}/control-plane`,\n log: args.log,\n }),\n 'control_plane',\n 'control_plane'\n );\n controlPlaneKysely.destroy = async () => {};\n Object.defineProperty(kysely, 'controlPlaneKysely', {\n value: controlPlaneKysely,\n });\n\n const originalDestroy = kysely.destroy.bind(kysely);\n kysely.destroy = async () => {\n if (isDestroyed) return;\n isDestroyed = true;\n //const destroyTime = performance.now();\n await originalDestroy();\n //console.log(\n // `Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`\n //);\n };\n\n // console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);\n\n return kysely as LocalKysely;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["local/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport { PGlite } from '@electric-sql/pglite';\nimport { FileMigrationProvider, type LogConfig, Migrator, sql } from 'kysely';\nimport { PGliteDialect } from 'kysely-pglite-dialect';\nimport { type ControlPlaneDB, withControlPlaneSchema } from '../control-plane';\nimport type { ControlPlaneKysely } from '../index';\nimport { appMigrationEpoch } from '../migration';\nimport { getKysely } from '../plugins';\nimport type { DB } from '../v1.generated';\nimport { ensureDigestFunction, ensureGenRandomBytesFunction } from './digest';\n\nexport const root = path.join(__dirname, '../..');\nexport const dumpPath = path.join(root, '.data.tar');\n\nexport type UseLocalKyselyOptions = {\n repositoryName?: string;\n log?: true | LogConfig;\n};\n\nexport type LocalKysely = import('kysely').Kysely<DB> & {\n controlPlaneKysely: ControlPlaneKysely;\n};\n\nasync function migrateToLatest<Database>(\n kysely: import('kysely').Kysely<Database>\n) {\n const migrator = new Migrator({\n allowUnorderedMigrations: true,\n db: kysely,\n migrationTableSchema: appMigrationEpoch.tableSchema,\n migrationTableName: appMigrationEpoch.tableName,\n migrationLockTableName: appMigrationEpoch.lockTableName,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, appMigrationEpoch.folder),\n }),\n });\n\n const { error } = await migrator.migrateToLatest();\n if (error) {\n throw error;\n }\n}\n\n// Every spec file used to replay this identical bootstrap - migrations, the\n// schema surgery, and the control-plane seed copies - against a freshly loaded\n// snapshot, which measured ~345ms per file against ~185ms for the snapshot load\n// alone. None of it depends on the caller, so it runs once and is cached as a\n// prepared snapshot keyed by everything that determines its content.\nconst preparedDumpPrefix = '.data.prepared.';\n\nlet preparedDumpPromise: Promise<Blob> | undefined;\n\nasync function preparedDumpKey(): Promise<string> {\n const [snapshot, appMigrations, controlPlaneMigrations] = await Promise.all([\n fs.stat(dumpPath),\n fs.readdir(path.join(root, appMigrationEpoch.folder)),\n fs.readdir(path.join(root, 'control-plane-migrations')),\n ]);\n\n const hasher = new Bun.CryptoHasher('sha256');\n hasher.update(`${snapshot.size}:${snapshot.mtimeMs}`);\n hasher.update(appMigrations.sort().join(','));\n hasher.update(controlPlaneMigrations.sort().join(','));\n // Source of the bootstrap itself, so editing the surgery rebuilds the\n // snapshot. Read through toString() rather than the file: this module is also\n // published as CommonJS, where import.meta is a compile error.\n for (const step of [\n buildPreparedDump,\n migrateToLatest,\n ensureDigestFunction,\n ensureGenRandomBytesFunction,\n ]) {\n hasher.update(step.toString());\n }\n return hasher.digest('hex').slice(0, 16);\n}\n\nasync function resolvePreparedDump(): Promise<Blob> {\n const key = await preparedDumpKey();\n const target = path.join(root, `${preparedDumpPrefix}${key}.tar`);\n const cached = Bun.file(target);\n if (await cached.exists()) {\n return cached;\n }\n\n const content = await buildPreparedDump();\n // Sibling workers build this concurrently on a cold cache; rename is atomic,\n // so a reader never observes a half-written snapshot.\n const staging = `${target}.${process.pid}.tmp`;\n await Bun.write(staging, content);\n await fs.rename(staging, target);\n\n // Only finished snapshots: a sibling worker's staging file also carries the\n // prefix, and removing it would break its rename.\n const current = path.basename(target);\n for (const entry of await fs.readdir(root)) {\n if (\n entry.startsWith(preparedDumpPrefix) &&\n entry.endsWith('.tar') &&\n entry !== current\n ) {\n await fs.rm(path.join(root, entry), { force: true });\n }\n }\n\n return content;\n}\n\nasync function buildPreparedDump(): Promise<Blob> {\n const pglite = new PGlite({\n loadDataDir: Bun.file(dumpPath),\n });\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: 'localTestingPrepare',\n });\n await ensureDigestFunction(kysely);\n await ensureGenRandomBytesFunction(kysely);\n await migrateToLatest(kysely);\n\n await sql`alter schema public rename to regional_public`.execute(kysely);\n await sql`alter schema core rename to regional_core`.execute(kysely);\n await sql`create schema public`.execute(kysely);\n await sql`create schema core`.execute(kysely);\n\n const controlPlaneBootstrapKysely = getKysely<ControlPlaneDB>(dialect, {\n repositoryName: 'localTestingPrepare/control-plane-bootstrap',\n });\n const controlPlaneMigrator = new Migrator({\n db: controlPlaneBootstrapKysely,\n migrationTableSchema: 'public',\n migrationTableName: 'control_plane_kysely_migration',\n migrationLockTableName: 'control_plane_kysely_migration_lock',\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(root, 'control-plane-migrations'),\n }),\n });\n const { error: controlPlaneMigrationError } =\n await controlPlaneMigrator.migrateToLatest();\n if (controlPlaneMigrationError) {\n throw controlPlaneMigrationError;\n }\n\n await sql`alter table core.flow set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter table core.issue_message_overwrite set schema public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`drop schema core`.execute(controlPlaneBootstrapKysely);\n await sql`alter schema public rename to control_plane`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_public rename to public`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`alter schema regional_core rename to core`.execute(\n controlPlaneBootstrapKysely\n );\n await sql`\n do $$\n declare\n definition text;\n begin\n select pg_get_functiondef(\n 'control_plane.normalize_tenant_slug(text)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.build_unique_tenant_slug(text,uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_operation_state(uuid)'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n\n select pg_get_functiondef(\n 'control_plane.refresh_destructive_job_operation()'::regprocedure\n ) into definition;\n execute replace(definition, 'public.', 'control_plane.');\n end;\n $$;\n `.execute(controlPlaneBootstrapKysely);\n // Team creation always assigns this registered feature in both databases.\n // TODO(BIL-632): Remove both feature seeds when the billing rollout flag and\n // its creation-time assignments are retired: https://linear.app/vrplatform/issue/BIL-632\n await kysely\n .insertInto('public.feature')\n .values({\n id: 'ed5d2ce6-92af-4ab6-84c0-32a7932fa3c0',\n title: 'Direct pricing',\n status: 'testing',\n tenantId: null,\n })\n .execute();\n await sql`\n insert into control_plane.feature (id, title, status, tenant_id)\n select id, title, status, tenant_id from public.feature\n where id = 'ed5d2ce6-92af-4ab6-84c0-32a7932fa3c0'\n `.execute(controlPlaneBootstrapKysely);\n // The canonical VRPlatform tenant. Production code falls back to this exact id\n // in getCalculatedBillingPartnerId, so specs need it to exist without each of\n // them creating - and mutating - their own copy of a shared singleton.\n await kysely\n .insertInto('public.tenant')\n .values({\n id: '7bfec41f-aa3f-4602-95d2-f7996e4f0e59',\n name: 'VRPlatform',\n type: 'partner',\n status: 'active',\n isActive: true,\n isGeneralLedger: false,\n isOnboarding: false,\n partnerId: null,\n billingPartnerId: null,\n defaultCurrency: 'usd',\n statementStartAt: new Date('2020-01-01T00:00:00Z'),\n })\n .onConflict((oc) => oc.column('id').doNothing())\n .execute();\n\n await sql`\n insert into control_plane.app (\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n )\n select\n authentication,\n category,\n color,\n created_at,\n icon,\n icon_round,\n id,\n info,\n name,\n type,\n version\n from public.app\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.currency (name)\n select name\n from public.currency\n on conflict (name) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel (\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n )\n select\n channel_ref,\n color,\n created_at,\n icon,\n icon_provider,\n id,\n last_generate_run,\n logo,\n logo_provider,\n selected_booking_channel_icon_candidate_id,\n selected_booking_channel_logo_candidate_id,\n unique_ref,\n updated_at\n from public.booking_channel\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.booking_channel_icon_candidate (\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n )\n select\n booking_channel_id,\n cloudflare_image_id,\n color,\n comment,\n created_at,\n external_icon,\n height,\n id,\n provider,\n source,\n updated_at,\n width\n from public.booking_channel_icon_candidate\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.tenant (\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n )\n select\n billing_partner_id,\n billing_plan,\n created_at,\n data_region,\n id,\n name,\n partner_id,\n slug,\n status,\n storage_realm,\n type,\n unique_ref,\n updated_at\n from public.tenant\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n await sql`\n insert into control_plane.token (\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n )\n select\n created_at,\n expires_at,\n id,\n nano_id,\n payload,\n tenant_id,\n type,\n user_id\n from public.token\n on conflict (id) do nothing;\n `.execute(controlPlaneBootstrapKysely);\n\n const content = await pglite.dumpDataDir('none');\n await kysely.destroy();\n return content;\n}\n\nexport async function useLocalKysely(\n args: UseLocalKyselyOptions = {}\n): Promise<LocalKysely> {\n let isDestroyed = false;\n\n preparedDumpPromise ??= resolvePreparedDump();\n const pglite = new PGlite({\n loadDataDir: await preparedDumpPromise,\n });\n // The constructor is lazy. The bootstrap this replaced forced the snapshot to\n // load before returning, so keep that contract: a returned handle is usable,\n // and a bad snapshot fails here instead of inside an unrelated test.\n await pglite.waitReady;\n const dialect = new PGliteDialect(pglite);\n const kysely = getKysely<DB>(dialect, {\n repositoryName: args?.repositoryName ?? 'localTesting',\n log: args?.log,\n });\n\n const controlPlaneKysely = withControlPlaneSchema(\n getKysely<ControlPlaneDB>(dialect, {\n repositoryName: `${args.repositoryName ?? 'localTesting'}/control-plane`,\n log: args.log,\n }),\n 'control_plane',\n 'control_plane'\n );\n controlPlaneKysely.destroy = async () => {};\n Object.defineProperty(kysely, 'controlPlaneKysely', {\n value: controlPlaneKysely,\n });\n\n const originalDestroy = kysely.destroy.bind(kysely);\n kysely.destroy = async () => {\n if (isDestroyed) return;\n isDestroyed = true;\n //const destroyTime = performance.now();\n await originalDestroy();\n //console.log(\n // `Database destroyed: ${Math.round(performance.now() - destroyTime)}ms`\n //);\n };\n\n // console.log(`Database initialized: ${Math.round(performance.now() - now)}ms`);\n\n return kysely as LocalKysely;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.3.45-stage.
|
|
6
|
+
"version": "1.3.45-stage.968",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "build/main/index.js",
|
|
9
9
|
"module": "build/module/index.js",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"generate": "bun pgdump && bun run generate:v1 && bun run generate:v2 && bun run generate:v1:sed",
|
|
35
35
|
"migrate:control-plane": "bun migrate-control-plane.ts --up",
|
|
36
36
|
"generate:v1": "kysely-codegen --env-file=../../.env --out-file=./src/v1.generated.ts --date-parser=string --default-schema=xxx --camel-case",
|
|
37
|
-
"generate:v1:sed": "
|
|
37
|
+
"generate:v1:sed": "perl -pi -e 's/Timestamp = ColumnType<Date, Date \\| string, Date \\| string>/Timestamp = ColumnType<Date | string, Date | string, Date | string>/g' ./src/v1.generated.ts",
|
|
38
38
|
"generate:v2": "bun pg-dump:legacy-prune && rm -f .data.tar && bun setup.ts",
|
|
39
39
|
"pgdump": "dotenvx run -f ../../.env -- bun pg-dump:run && bun pg-dump:rm && bun pg-dump:fix-uuid && bun pg-dump:legacy-prune",
|
|
40
40
|
"pg-dump:run": "pg_dump --clean --schema-only --if-exists --no-owner --no-acl $DATABASE_URL > initial/0000000000000-init.sql",
|
|
41
|
-
"pg-dump:rm": "
|
|
42
|
-
"pg-dump:fix-uuid": "
|
|
41
|
+
"pg-dump:rm": "perl -ni -e 'print unless /EXTENSION/' initial/0000000000000-init.sql",
|
|
42
|
+
"pg-dump:fix-uuid": "perl -pi -e 's/public\\.gen_random_uuid\\(\\)/gen_random_uuid()/g' initial/0000000000000-init.sql",
|
|
43
43
|
"pg-dump:legacy-prune": "bun ./src/local/prune-pulled-schema.ts",
|
|
44
44
|
"build": "bun build:main && bun build:module",
|
|
45
45
|
"build:main": "tsc -b tsconfig.main.json",
|