@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.
@@ -939,9 +939,12 @@ interface WithConnectionFactory<ConnectionType extends AnyConnection = AnyConnec
939
939
  }
940
940
  //#endregion
941
941
  //#region src/core/connections/pool.d.ts
942
+ type PoolCloseOptions = {
943
+ force?: boolean;
944
+ };
942
945
  interface ConnectionPool<ConnectionType extends AnyConnection = AnyConnection> extends WithSQLExecutor, WithConnectionFactory<ConnectionType>, WithDatabaseTransactionFactory<ConnectionType> {
943
946
  driverType: ConnectionType['driverType'];
944
- close: () => Promise<void>;
947
+ close: (options?: PoolCloseOptions) => Promise<void>;
945
948
  }
946
949
  //#endregion
947
950
  //#region src/core/index.d.ts
@@ -939,9 +939,12 @@ interface WithConnectionFactory<ConnectionType extends AnyConnection = AnyConnec
939
939
  }
940
940
  //#endregion
941
941
  //#region src/core/connections/pool.d.ts
942
+ type PoolCloseOptions = {
943
+ force?: boolean;
944
+ };
942
945
  interface ConnectionPool<ConnectionType extends AnyConnection = AnyConnection> extends WithSQLExecutor, WithConnectionFactory<ConnectionType>, WithDatabaseTransactionFactory<ConnectionType> {
943
946
  driverType: ConnectionType['driverType'];
944
- close: () => Promise<void>;
947
+ close: (options?: PoolCloseOptions) => Promise<void>;
945
948
  }
946
949
  //#endregion
947
950
  //#region src/core/index.d.ts
package/dist/sqlite.cjs CHANGED
@@ -254,6 +254,65 @@ const executeInAmbientConnection = async (handle, options) => {
254
254
 
255
255
  //#endregion
256
256
  //#region src/core/connections/transaction.ts
257
+ const transactionNestingCounter = () => {
258
+ let transactionLevel = 0;
259
+ return {
260
+ reset: () => {
261
+ transactionLevel = 0;
262
+ },
263
+ increment: () => {
264
+ transactionLevel++;
265
+ },
266
+ decrement: () => {
267
+ transactionLevel--;
268
+ if (transactionLevel < 0) throw new Error("Transaction level is out of bounds");
269
+ },
270
+ get level() {
271
+ return transactionLevel;
272
+ }
273
+ };
274
+ };
275
+ const databaseTransaction = (backend, options) => {
276
+ const allowNestedTransactions = options?.allowNestedTransactions ?? false;
277
+ const useSavepoints = options?.useSavepoints ?? false;
278
+ const counter = transactionNestingCounter();
279
+ let hasBegun = false;
280
+ return {
281
+ begin: async () => {
282
+ if (!allowNestedTransactions && hasBegun) throw new InvalidOperationError("Cannot start a nested transaction: allowNestedTransactions is false. Set transactionOptions: { allowNestedTransactions: true } on your pool or connection.");
283
+ if (allowNestedTransactions) {
284
+ if (counter.level >= 1) {
285
+ counter.increment();
286
+ if (useSavepoints && backend.savepoint) await backend.savepoint(counter.level);
287
+ return;
288
+ }
289
+ counter.increment();
290
+ }
291
+ hasBegun = true;
292
+ await backend.begin();
293
+ },
294
+ commit: async () => {
295
+ if (allowNestedTransactions && counter.level > 1) {
296
+ if (useSavepoints && backend.releaseSavepoint) await backend.releaseSavepoint(counter.level);
297
+ counter.decrement();
298
+ return;
299
+ }
300
+ if (allowNestedTransactions) counter.reset();
301
+ hasBegun = false;
302
+ await backend.commit();
303
+ },
304
+ rollback: async (error) => {
305
+ if (allowNestedTransactions && counter.level > 1) {
306
+ if (useSavepoints && backend.rollbackToSavepoint) await backend.rollbackToSavepoint(counter.level);
307
+ counter.decrement();
308
+ return;
309
+ }
310
+ if (allowNestedTransactions) counter.reset();
311
+ hasBegun = false;
312
+ await backend.rollback(error);
313
+ }
314
+ };
315
+ };
257
316
  const toTransactionResult = (transactionResult) => transactionResult !== void 0 && transactionResult !== null && typeof transactionResult === "object" && "success" in transactionResult ? transactionResult : {
258
317
  success: true,
259
318
  result: transactionResult
@@ -444,22 +503,53 @@ const createAmbientConnectionPool = (options) => {
444
503
  const createSingletonConnectionPool = (options) => {
445
504
  const { driverType, getConnection } = options;
446
505
  let connectionPromise = null;
506
+ let closed = false;
507
+ const activeOperations = /* @__PURE__ */ new Set();
508
+ const closedError = () => /* @__PURE__ */ new Error("Singleton connection pool has been closed");
509
+ const run = async (operation) => {
510
+ if (closed) throw closedError();
511
+ const activeOperation = operation();
512
+ activeOperations.add(activeOperation);
513
+ try {
514
+ return await activeOperation;
515
+ } finally {
516
+ activeOperations.delete(activeOperation);
517
+ }
518
+ };
447
519
  const getExistingOrNewConnection = () => {
448
520
  if (!connectionPromise) connectionPromise ??= Promise.resolve(getConnection());
449
521
  return connectionPromise;
450
522
  };
523
+ const innerTransactionFactory = transactionFactoryWithAsyncAmbientConnection(options.driverType, getExistingOrNewConnection, options.closeConnection);
451
524
  return {
452
525
  driverType,
453
- connection: () => getExistingOrNewConnection().then((conn) => wrapPooledConnection(conn, () => Promise.resolve())),
454
- execute: sqlExecutorInAmbientConnection({
455
- driverType,
456
- connection: getExistingOrNewConnection
457
- }),
458
- withConnection: (handle, _options) => executeInAmbientConnection(handle, { connection: getExistingOrNewConnection }),
459
- ...transactionFactoryWithAsyncAmbientConnection(options.driverType, getExistingOrNewConnection, options.closeConnection),
460
- close: async () => {
526
+ connection: () => run(() => getExistingOrNewConnection().then((conn) => wrapPooledConnection(conn, () => Promise.resolve()))),
527
+ execute: (() => {
528
+ const ambientExecutor = sqlExecutorInAmbientConnection({
529
+ driverType,
530
+ connection: getExistingOrNewConnection
531
+ });
532
+ return {
533
+ query: (sql, opts) => run(() => ambientExecutor.query(sql, opts)),
534
+ batchQuery: (sqls, opts) => run(() => ambientExecutor.batchQuery(sqls, opts)),
535
+ command: (sql, opts) => run(() => ambientExecutor.command(sql, opts)),
536
+ batchCommand: (sqls, opts) => run(() => ambientExecutor.batchCommand(sqls, opts))
537
+ };
538
+ })(),
539
+ withConnection: (handle, _options) => run(() => executeInAmbientConnection(handle, { connection: getExistingOrNewConnection })),
540
+ transaction: (transactionOptions) => {
541
+ if (closed) throw closedError();
542
+ return innerTransactionFactory.transaction(transactionOptions);
543
+ },
544
+ withTransaction: (handle, transactionOptions) => run(() => innerTransactionFactory.withTransaction(handle, transactionOptions)),
545
+ close: async (closeOptions) => {
546
+ if (closed) return;
547
+ closed = true;
548
+ if (!closeOptions?.force) await Promise.allSettled([...activeOperations]);
461
549
  if (!connectionPromise) return;
462
- await (await connectionPromise).close();
550
+ const connection = await connectionPromise;
551
+ connectionPromise = null;
552
+ await connection.close();
463
553
  }
464
554
  };
465
555
  };
@@ -1812,54 +1902,46 @@ const sqliteSQLExecutor = (driverType, serializer, formatter, errorMapper) => ({
1812
1902
  //#endregion
1813
1903
  //#region src/storage/sqlite/core/transactions/index.ts
1814
1904
  const sqliteTransaction = (driverType, connection, allowNestedTransactions, serializer, defaultTransactionMode) => (getClient, options) => {
1815
- const transactionCounter = transactionNestingCounter();
1816
1905
  allowNestedTransactions = options?.allowNestedTransactions ?? allowNestedTransactions;
1817
- let hasBegun = false;
1818
- return {
1819
- connection: connection(),
1820
- driverType,
1821
- begin: async function() {
1906
+ const useSavepoints = options?.useSavepoints ?? false;
1907
+ const tx = databaseTransaction({
1908
+ begin: async () => {
1822
1909
  const client = await getClient;
1823
- if (allowNestedTransactions) {
1824
- if (transactionCounter.level >= 1) {
1825
- transactionCounter.increment();
1826
- if (options?.useSavepoints) await client.command(SQL`SAVEPOINT transaction${SQL.plain(transactionCounter.level.toString())}`);
1827
- return;
1828
- }
1829
- transactionCounter.increment();
1830
- } else if (hasBegun) throw new InvalidOperationError("Cannot start a nested transaction: allowNestedTransactions is false. Set transactionOptions: { allowNestedTransactions: true } on your pool or connection.");
1831
- hasBegun = true;
1832
1910
  const mode = options?.mode ?? defaultTransactionMode ?? "IMMEDIATE";
1833
1911
  await client.command(SQL`BEGIN ${SQL.plain(mode)} TRANSACTION`);
1834
1912
  },
1835
- commit: async function() {
1913
+ commit: async () => {
1836
1914
  const client = await getClient;
1837
- if (allowNestedTransactions && transactionCounter.level > 1) {
1838
- if (options?.useSavepoints) await client.command(SQL`RELEASE transaction${SQL.plain(transactionCounter.level.toString())}`);
1839
- transactionCounter.decrement();
1840
- return;
1841
- }
1842
1915
  try {
1843
- if (allowNestedTransactions) transactionCounter.reset();
1844
- hasBegun = false;
1845
1916
  await client.command(SQL`COMMIT`);
1846
1917
  } finally {
1847
- if (options?.close) await options?.close(client);
1918
+ if (options?.close) await options.close(client);
1848
1919
  }
1849
1920
  },
1850
- rollback: async function(error) {
1921
+ rollback: async (error) => {
1851
1922
  const client = await getClient;
1852
- if (allowNestedTransactions && transactionCounter.level > 1) {
1853
- transactionCounter.decrement();
1854
- return;
1855
- }
1856
1923
  try {
1857
- hasBegun = false;
1858
1924
  await client.command(SQL`ROLLBACK`);
1859
1925
  } finally {
1860
- if (options?.close) await options?.close(client, error);
1926
+ if (options?.close) await options.close(client, error);
1861
1927
  }
1862
1928
  },
1929
+ savepoint: async (level) => {
1930
+ await (await getClient).command(SQL`SAVEPOINT transaction${SQL.plain(level.toString())}`);
1931
+ },
1932
+ releaseSavepoint: async (level) => {
1933
+ await (await getClient).command(SQL`RELEASE transaction${SQL.plain(level.toString())}`);
1934
+ }
1935
+ }, {
1936
+ allowNestedTransactions,
1937
+ useSavepoints
1938
+ });
1939
+ return {
1940
+ connection: connection(),
1941
+ driverType,
1942
+ begin: tx.begin,
1943
+ commit: tx.commit,
1944
+ rollback: tx.rollback,
1863
1945
  execute: sqlExecutor(sqliteSQLExecutor(driverType, serializer), { connect: () => getClient }),
1864
1946
  _transactionOptions: {
1865
1947
  ...options,
@@ -1905,24 +1987,6 @@ const isSQLiteError = (error) => {
1905
1987
  if (error instanceof Error && "code" in error) return true;
1906
1988
  return false;
1907
1989
  };
1908
- const transactionNestingCounter = () => {
1909
- let transactionLevel = 0;
1910
- return {
1911
- reset: () => {
1912
- transactionLevel = 0;
1913
- },
1914
- increment: () => {
1915
- transactionLevel++;
1916
- },
1917
- decrement: () => {
1918
- transactionLevel--;
1919
- if (transactionLevel < 0) throw new Error("Transaction level is out of bounds");
1920
- },
1921
- get level() {
1922
- return transactionLevel;
1923
- }
1924
- };
1925
- };
1926
1990
  const sqliteAmbientClientConnection = (options) => {
1927
1991
  const { client, driverType, initTransaction, allowNestedTransactions, defaultTransactionMode, serializer, errorMapper } = options;
1928
1992
  return createAmbientConnection({
@@ -2121,5 +2185,4 @@ exports.sqliteSingletonConnectionPool = sqliteSingletonConnectionPool;
2121
2185
  exports.sqliteTransaction = sqliteTransaction;
2122
2186
  exports.tableExists = tableExists;
2123
2187
  exports.toSqlitePoolOptions = toSqlitePoolOptions;
2124
- exports.transactionNestingCounter = transactionNestingCounter;
2125
2188
  //# sourceMappingURL=sqlite.cjs.map