@event-driven-io/dumbo 0.13.0-beta.43 → 0.13.0-beta.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pg.d.cts CHANGED
@@ -949,9 +949,12 @@ interface WithConnectionFactory<ConnectionType extends AnyConnection = AnyConnec
949
949
  }
950
950
  //#endregion
951
951
  //#region src/core/connections/pool.d.ts
952
+ type PoolCloseOptions = {
953
+ force?: boolean;
954
+ };
952
955
  interface ConnectionPool<ConnectionType extends AnyConnection = AnyConnection> extends WithSQLExecutor, WithConnectionFactory<ConnectionType>, WithDatabaseTransactionFactory<ConnectionType> {
953
956
  driverType: ConnectionType['driverType'];
954
- close: () => Promise<void>;
957
+ close: (options?: PoolCloseOptions) => Promise<void>;
955
958
  }
956
959
  //#endregion
957
960
  //#region src/core/index.d.ts
@@ -1045,6 +1048,7 @@ type PgTransaction = DatabaseTransaction<PgConnection, PgTransactionOptions>;
1045
1048
  type PgIsolationLevel = 'READ UNCOMMITTED' | 'READ COMMITTED' | 'REPEATABLE READ' | 'SERIALIZABLE';
1046
1049
  type PgTransactionOptions = DatabaseTransactionOptions & {
1047
1050
  isolationLevel?: PgIsolationLevel;
1051
+ useSavepoints?: boolean;
1048
1052
  };
1049
1053
  declare const pgTransaction: <ConnectionType extends AnyConnection = AnyConnection>(connection: () => ConnectionType, serializer: JSONSerializer) => <DbClient extends PgPoolOrClient = PgPoolOrClient>(getClient: Promise<DbClient>, options?: {
1050
1054
  close: (client: DbClient, error?: unknown) => Promise<void>;
@@ -1072,9 +1076,11 @@ type PgClientOptions = {
1072
1076
  };
1073
1077
  type PgClientConnectionOptions = PgClientOptions & {
1074
1078
  serializer: JSONSerializer;
1079
+ transactionOptions?: PgTransactionOptions;
1075
1080
  };
1076
1081
  type PgPoolClientConnectionOptions = PgPoolClientOptions & {
1077
1082
  serializer: JSONSerializer;
1083
+ transactionOptions?: PgTransactionOptions;
1078
1084
  };
1079
1085
  declare const pgClientConnection: (options: PgClientConnectionOptions) => PgClientConnection;
1080
1086
  declare const pgPoolClientConnection: (options: PgPoolClientConnectionOptions) => PgPoolClientConnection;
@@ -1100,10 +1106,12 @@ declare const pgNativePool: (options: {
1100
1106
  connectionString: string;
1101
1107
  database?: string | undefined;
1102
1108
  serializer: JSONSerializer;
1109
+ transactionOptions?: PgTransactionOptions | undefined;
1103
1110
  }) => PgNativePool;
1104
1111
  declare const pgAmbientNativePool: (options: {
1105
1112
  pool: pg.Pool;
1106
1113
  serializer: JSONSerializer;
1114
+ transactionOptions?: PgTransactionOptions | undefined;
1107
1115
  }) => PgNativePool;
1108
1116
  declare const pgAmbientConnectionPool: (options: {
1109
1117
  connection: PgPoolClientConnection | PgClientConnection;
@@ -1112,10 +1120,12 @@ declare const pgClientPool: (options: {
1112
1120
  connectionString: string;
1113
1121
  database?: string | undefined;
1114
1122
  serializer: JSONSerializer;
1123
+ transactionOptions?: PgTransactionOptions | undefined;
1115
1124
  }) => PgAmbientClientPool;
1116
1125
  declare const pgAmbientClientPool: (options: {
1117
1126
  client: pg.Client;
1118
1127
  serializer: JSONSerializer;
1128
+ transactionOptions?: PgTransactionOptions | undefined;
1119
1129
  }) => PgAmbientClientPool;
1120
1130
  type PgPoolPooledOptions = {
1121
1131
  connectionString: string;
@@ -1153,9 +1163,15 @@ type PgPoolNotPooledOptions = {
1153
1163
  connection: PgPoolClientConnection | PgClientConnection;
1154
1164
  pooled?: false;
1155
1165
  };
1156
- type PgPoolOptions = (PgPoolPooledOptions | PgPoolNotPooledOptions) & JSONSerializationOptions;
1157
- declare function pgPool(options: PgPoolPooledOptions): PgNativePool;
1158
- declare function pgPool(options: PgPoolNotPooledOptions): PgAmbientClientPool;
1166
+ type PgPoolOptions = (PgPoolPooledOptions | PgPoolNotPooledOptions) & JSONSerializationOptions & {
1167
+ transactionOptions?: PgTransactionOptions;
1168
+ };
1169
+ declare function pgPool(options: PgPoolPooledOptions & {
1170
+ transactionOptions?: PgTransactionOptions;
1171
+ }): PgNativePool;
1172
+ declare function pgPool(options: PgPoolNotPooledOptions & {
1173
+ transactionOptions?: PgTransactionOptions;
1174
+ }): PgAmbientClientPool;
1159
1175
  declare const getPgPool: (connectionStringOrOptions: string | pg.PoolConfig) => pg.Pool;
1160
1176
  declare const endPgPool: ({
1161
1177
  connectionString,
package/dist/pg.d.ts CHANGED
@@ -949,9 +949,12 @@ interface WithConnectionFactory<ConnectionType extends AnyConnection = AnyConnec
949
949
  }
950
950
  //#endregion
951
951
  //#region src/core/connections/pool.d.ts
952
+ type PoolCloseOptions = {
953
+ force?: boolean;
954
+ };
952
955
  interface ConnectionPool<ConnectionType extends AnyConnection = AnyConnection> extends WithSQLExecutor, WithConnectionFactory<ConnectionType>, WithDatabaseTransactionFactory<ConnectionType> {
953
956
  driverType: ConnectionType['driverType'];
954
- close: () => Promise<void>;
957
+ close: (options?: PoolCloseOptions) => Promise<void>;
955
958
  }
956
959
  //#endregion
957
960
  //#region src/core/index.d.ts
@@ -1045,6 +1048,7 @@ type PgTransaction = DatabaseTransaction<PgConnection, PgTransactionOptions>;
1045
1048
  type PgIsolationLevel = 'READ UNCOMMITTED' | 'READ COMMITTED' | 'REPEATABLE READ' | 'SERIALIZABLE';
1046
1049
  type PgTransactionOptions = DatabaseTransactionOptions & {
1047
1050
  isolationLevel?: PgIsolationLevel;
1051
+ useSavepoints?: boolean;
1048
1052
  };
1049
1053
  declare const pgTransaction: <ConnectionType extends AnyConnection = AnyConnection>(connection: () => ConnectionType, serializer: JSONSerializer) => <DbClient extends PgPoolOrClient = PgPoolOrClient>(getClient: Promise<DbClient>, options?: {
1050
1054
  close: (client: DbClient, error?: unknown) => Promise<void>;
@@ -1072,9 +1076,11 @@ type PgClientOptions = {
1072
1076
  };
1073
1077
  type PgClientConnectionOptions = PgClientOptions & {
1074
1078
  serializer: JSONSerializer;
1079
+ transactionOptions?: PgTransactionOptions;
1075
1080
  };
1076
1081
  type PgPoolClientConnectionOptions = PgPoolClientOptions & {
1077
1082
  serializer: JSONSerializer;
1083
+ transactionOptions?: PgTransactionOptions;
1078
1084
  };
1079
1085
  declare const pgClientConnection: (options: PgClientConnectionOptions) => PgClientConnection;
1080
1086
  declare const pgPoolClientConnection: (options: PgPoolClientConnectionOptions) => PgPoolClientConnection;
@@ -1100,10 +1106,12 @@ declare const pgNativePool: (options: {
1100
1106
  connectionString: string;
1101
1107
  database?: string | undefined;
1102
1108
  serializer: JSONSerializer;
1109
+ transactionOptions?: PgTransactionOptions | undefined;
1103
1110
  }) => PgNativePool;
1104
1111
  declare const pgAmbientNativePool: (options: {
1105
1112
  pool: pg.Pool;
1106
1113
  serializer: JSONSerializer;
1114
+ transactionOptions?: PgTransactionOptions | undefined;
1107
1115
  }) => PgNativePool;
1108
1116
  declare const pgAmbientConnectionPool: (options: {
1109
1117
  connection: PgPoolClientConnection | PgClientConnection;
@@ -1112,10 +1120,12 @@ declare const pgClientPool: (options: {
1112
1120
  connectionString: string;
1113
1121
  database?: string | undefined;
1114
1122
  serializer: JSONSerializer;
1123
+ transactionOptions?: PgTransactionOptions | undefined;
1115
1124
  }) => PgAmbientClientPool;
1116
1125
  declare const pgAmbientClientPool: (options: {
1117
1126
  client: pg.Client;
1118
1127
  serializer: JSONSerializer;
1128
+ transactionOptions?: PgTransactionOptions | undefined;
1119
1129
  }) => PgAmbientClientPool;
1120
1130
  type PgPoolPooledOptions = {
1121
1131
  connectionString: string;
@@ -1153,9 +1163,15 @@ type PgPoolNotPooledOptions = {
1153
1163
  connection: PgPoolClientConnection | PgClientConnection;
1154
1164
  pooled?: false;
1155
1165
  };
1156
- type PgPoolOptions = (PgPoolPooledOptions | PgPoolNotPooledOptions) & JSONSerializationOptions;
1157
- declare function pgPool(options: PgPoolPooledOptions): PgNativePool;
1158
- declare function pgPool(options: PgPoolNotPooledOptions): PgAmbientClientPool;
1166
+ type PgPoolOptions = (PgPoolPooledOptions | PgPoolNotPooledOptions) & JSONSerializationOptions & {
1167
+ transactionOptions?: PgTransactionOptions;
1168
+ };
1169
+ declare function pgPool(options: PgPoolPooledOptions & {
1170
+ transactionOptions?: PgTransactionOptions;
1171
+ }): PgNativePool;
1172
+ declare function pgPool(options: PgPoolNotPooledOptions & {
1173
+ transactionOptions?: PgTransactionOptions;
1174
+ }): PgAmbientClientPool;
1159
1175
  declare const getPgPool: (connectionStringOrOptions: string | pg.PoolConfig) => pg.Pool;
1160
1176
  declare const endPgPool: ({
1161
1177
  connectionString,
package/dist/pg.js CHANGED
@@ -346,6 +346,65 @@ const executeInNewConnection = async (handle, options) => {
346
346
 
347
347
  //#endregion
348
348
  //#region src/core/connections/transaction.ts
349
+ const transactionNestingCounter = () => {
350
+ let transactionLevel = 0;
351
+ return {
352
+ reset: () => {
353
+ transactionLevel = 0;
354
+ },
355
+ increment: () => {
356
+ transactionLevel++;
357
+ },
358
+ decrement: () => {
359
+ transactionLevel--;
360
+ if (transactionLevel < 0) throw new Error("Transaction level is out of bounds");
361
+ },
362
+ get level() {
363
+ return transactionLevel;
364
+ }
365
+ };
366
+ };
367
+ const databaseTransaction = (backend, options) => {
368
+ const allowNestedTransactions = options?.allowNestedTransactions ?? false;
369
+ const useSavepoints = options?.useSavepoints ?? false;
370
+ const counter = transactionNestingCounter();
371
+ let hasBegun = false;
372
+ return {
373
+ begin: async () => {
374
+ if (!allowNestedTransactions && hasBegun) throw new InvalidOperationError("Cannot start a nested transaction: allowNestedTransactions is false. Set transactionOptions: { allowNestedTransactions: true } on your pool or connection.");
375
+ if (allowNestedTransactions) {
376
+ if (counter.level >= 1) {
377
+ counter.increment();
378
+ if (useSavepoints && backend.savepoint) await backend.savepoint(counter.level);
379
+ return;
380
+ }
381
+ counter.increment();
382
+ }
383
+ hasBegun = true;
384
+ await backend.begin();
385
+ },
386
+ commit: async () => {
387
+ if (allowNestedTransactions && counter.level > 1) {
388
+ if (useSavepoints && backend.releaseSavepoint) await backend.releaseSavepoint(counter.level);
389
+ counter.decrement();
390
+ return;
391
+ }
392
+ if (allowNestedTransactions) counter.reset();
393
+ hasBegun = false;
394
+ await backend.commit();
395
+ },
396
+ rollback: async (error) => {
397
+ if (allowNestedTransactions && counter.level > 1) {
398
+ if (useSavepoints && backend.rollbackToSavepoint) await backend.rollbackToSavepoint(counter.level);
399
+ counter.decrement();
400
+ return;
401
+ }
402
+ if (allowNestedTransactions) counter.reset();
403
+ hasBegun = false;
404
+ await backend.rollback(error);
405
+ }
406
+ };
407
+ };
349
408
  const toTransactionResult = (transactionResult) => transactionResult !== void 0 && transactionResult !== null && typeof transactionResult === "object" && "success" in transactionResult ? transactionResult : {
350
409
  success: true,
351
410
  result: transactionResult
@@ -2052,57 +2111,92 @@ async function batchCommand(client, sqls, serializer, options) {
2052
2111
 
2053
2112
  //#endregion
2054
2113
  //#region src/storage/postgresql/pg/connections/transaction.ts
2055
- const pgTransaction = (connection, serializer) => (getClient, options) => ({
2056
- connection: connection(),
2057
- driverType: PgDriverType,
2058
- begin: async () => {
2059
- const client = await getClient;
2060
- const parts = ["BEGIN"];
2061
- if (options?.isolationLevel) parts.push(`ISOLATION LEVEL ${options.isolationLevel}`);
2062
- if (options?.readonly) parts.push("READ ONLY");
2063
- await client.query(parts.join(" "));
2064
- },
2065
- commit: async () => {
2066
- const client = await getClient;
2067
- try {
2068
- await client.query("COMMIT");
2069
- } finally {
2070
- if (options?.close) await options?.close(client);
2114
+ const pgTransaction = (connection, serializer) => (getClient, options) => {
2115
+ const allowNestedTransactions = options?.allowNestedTransactions ?? false;
2116
+ const tx = databaseTransaction({
2117
+ begin: async () => {
2118
+ const client = await getClient;
2119
+ const parts = ["BEGIN"];
2120
+ if (options?.isolationLevel) parts.push(`ISOLATION LEVEL ${options.isolationLevel}`);
2121
+ if (options?.readonly) parts.push("READ ONLY");
2122
+ await client.query(parts.join(" "));
2123
+ },
2124
+ commit: async () => {
2125
+ const client = await getClient;
2126
+ try {
2127
+ await client.query("COMMIT");
2128
+ } finally {
2129
+ if (options?.close) await options.close(client);
2130
+ }
2131
+ },
2132
+ rollback: async (error) => {
2133
+ const client = await getClient;
2134
+ try {
2135
+ await client.query("ROLLBACK");
2136
+ } finally {
2137
+ if (options?.close) await options.close(client, error);
2138
+ }
2139
+ },
2140
+ savepoint: async (level) => {
2141
+ await (await getClient).query(`SAVEPOINT pg_savepoint_${level}`);
2142
+ },
2143
+ releaseSavepoint: async (level) => {
2144
+ await (await getClient).query(`RELEASE SAVEPOINT pg_savepoint_${level}`);
2145
+ },
2146
+ rollbackToSavepoint: async (level) => {
2147
+ await (await getClient).query(`ROLLBACK TO SAVEPOINT pg_savepoint_${level}`);
2071
2148
  }
2072
- },
2073
- rollback: async (error) => {
2074
- const client = await getClient;
2075
- try {
2076
- await client.query("ROLLBACK");
2077
- } finally {
2078
- if (options?.close) await options?.close(client, error);
2149
+ }, {
2150
+ allowNestedTransactions,
2151
+ useSavepoints: options?.useSavepoints ?? false
2152
+ });
2153
+ return {
2154
+ connection: connection(),
2155
+ driverType: PgDriverType,
2156
+ begin: tx.begin,
2157
+ commit: tx.commit,
2158
+ rollback: tx.rollback,
2159
+ execute: sqlExecutor(pgSQLExecutor({ serializer }), { connect: () => getClient }),
2160
+ _transactionOptions: {
2161
+ ...options ?? {},
2162
+ allowNestedTransactions
2079
2163
  }
2080
- },
2081
- execute: sqlExecutor(pgSQLExecutor({ serializer }), { connect: () => getClient }),
2082
- _transactionOptions: options ?? {}
2083
- });
2164
+ };
2165
+ };
2084
2166
 
2085
2167
  //#endregion
2086
2168
  //#region src/storage/postgresql/pg/connections/connection.ts
2087
2169
  const PgDriverType = "PostgreSQL:pg";
2088
2170
  const pgClientConnection = (options) => {
2089
- const { connect, close } = options;
2171
+ const { connect, close, transactionOptions } = options;
2090
2172
  return createConnection({
2091
2173
  driverType: PgDriverType,
2092
2174
  connect,
2093
2175
  close,
2094
- initTransaction: (connection) => pgTransaction(connection, options.serializer),
2176
+ initTransaction: (connection) => {
2177
+ const txFactory = pgTransaction(connection, options.serializer);
2178
+ return (client, perCallOptions) => txFactory(client, {
2179
+ ...transactionOptions ?? {},
2180
+ ...perCallOptions ?? {}
2181
+ });
2182
+ },
2095
2183
  executor: pgSQLExecutor,
2096
2184
  serializer: options.serializer
2097
2185
  });
2098
2186
  };
2099
2187
  const pgPoolClientConnection = (options) => {
2100
- const { connect, close } = options;
2188
+ const { connect, close, transactionOptions } = options;
2101
2189
  return createConnection({
2102
2190
  driverType: PgDriverType,
2103
2191
  connect,
2104
2192
  close,
2105
- initTransaction: (connection) => pgTransaction(connection, options.serializer),
2193
+ initTransaction: (connection) => {
2194
+ const txFactory = pgTransaction(connection, options.serializer);
2195
+ return (client, perCallOptions) => txFactory(client, {
2196
+ ...transactionOptions ?? {},
2197
+ ...perCallOptions ?? {}
2198
+ });
2199
+ },
2106
2200
  executor: pgSQLExecutor,
2107
2201
  serializer: options.serializer
2108
2202
  });
@@ -2141,7 +2235,7 @@ const setPgTypeParser = (client, options) => {
2141
2235
  //#endregion
2142
2236
  //#region src/storage/postgresql/pg/connections/pool.ts
2143
2237
  const pgNativePool = (options) => {
2144
- const { connectionString, database } = options;
2238
+ const { connectionString, database, transactionOptions } = options;
2145
2239
  const pool = getPgPool({
2146
2240
  connectionString,
2147
2241
  database
@@ -2157,7 +2251,8 @@ const pgNativePool = (options) => {
2157
2251
  return client;
2158
2252
  },
2159
2253
  close: (client) => Promise.resolve(client.release()),
2160
- serializer: options.serializer
2254
+ serializer: options.serializer,
2255
+ ...transactionOptions ? { transactionOptions } : {}
2161
2256
  });
2162
2257
  const open = () => Promise.resolve(getConnection());
2163
2258
  const close = () => endPgPool({
@@ -2172,14 +2267,15 @@ const pgNativePool = (options) => {
2172
2267
  });
2173
2268
  };
2174
2269
  const pgAmbientNativePool = (options) => {
2175
- const { pool } = options;
2270
+ const { pool, transactionOptions } = options;
2176
2271
  return createConnectionPool({
2177
2272
  driverType: PgDriverType,
2178
2273
  getConnection: () => pgConnection({
2179
2274
  type: "PoolClient",
2180
2275
  connect: () => pool.connect(),
2181
2276
  close: (client) => Promise.resolve(client.release()),
2182
- serializer: options.serializer
2277
+ serializer: options.serializer,
2278
+ ...transactionOptions ? { transactionOptions } : {}
2183
2279
  })
2184
2280
  });
2185
2281
  };
@@ -2191,7 +2287,7 @@ const pgAmbientConnectionPool = (options) => {
2191
2287
  });
2192
2288
  };
2193
2289
  const pgClientPool = (options) => {
2194
- const { connectionString, database } = options;
2290
+ const { connectionString, database, transactionOptions } = options;
2195
2291
  return createConnectionPool({
2196
2292
  driverType: PgDriverType,
2197
2293
  getConnection: () => {
@@ -2211,20 +2307,22 @@ const pgClientPool = (options) => {
2211
2307
  type: "Client",
2212
2308
  connect,
2213
2309
  close: (client) => client.end(),
2214
- serializer: options.serializer
2310
+ serializer: options.serializer,
2311
+ ...transactionOptions ? { transactionOptions } : {}
2215
2312
  });
2216
2313
  }
2217
2314
  });
2218
2315
  };
2219
2316
  const pgAmbientClientPool = (options) => {
2220
- const { client } = options;
2317
+ const { client, transactionOptions } = options;
2221
2318
  const getConnection = () => {
2222
2319
  const connect = () => Promise.resolve(client);
2223
2320
  return pgConnection({
2224
2321
  type: "Client",
2225
2322
  connect,
2226
2323
  close: () => Promise.resolve(),
2227
- serializer: options.serializer
2324
+ serializer: options.serializer,
2325
+ ...transactionOptions ? { transactionOptions } : {}
2228
2326
  });
2229
2327
  };
2230
2328
  const open = () => Promise.resolve(getConnection());
@@ -2237,26 +2335,31 @@ const pgAmbientClientPool = (options) => {
2237
2335
  });
2238
2336
  };
2239
2337
  function pgPool(options) {
2240
- const { connectionString, database } = options;
2338
+ const { connectionString, database, transactionOptions } = options;
2241
2339
  const serializer = options.serialization?.serializer ?? JSONSerializer;
2340
+ const txOpts = transactionOptions ? { transactionOptions } : {};
2242
2341
  if ("client" in options && options.client) return pgAmbientClientPool({
2243
2342
  client: options.client,
2244
- serializer
2343
+ serializer,
2344
+ ...txOpts
2245
2345
  });
2246
2346
  if ("connection" in options && options.connection) return pgAmbientConnectionPool({ connection: options.connection });
2247
2347
  if ("pooled" in options && options.pooled === false) return pgClientPool({
2248
2348
  connectionString,
2249
2349
  database,
2250
- serializer
2350
+ serializer,
2351
+ ...txOpts
2251
2352
  });
2252
2353
  if ("pool" in options && options.pool) return pgAmbientNativePool({
2253
2354
  pool: options.pool,
2254
- serializer
2355
+ serializer,
2356
+ ...txOpts
2255
2357
  });
2256
2358
  return pgNativePool({
2257
2359
  connectionString,
2258
2360
  database,
2259
- serializer
2361
+ serializer,
2362
+ ...txOpts
2260
2363
  });
2261
2364
  }
2262
2365
  const pools = /* @__PURE__ */ new Map();