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

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.
@@ -269,6 +269,65 @@ const executeInAmbientConnection = async (handle, options) => {
269
269
 
270
270
  //#endregion
271
271
  //#region src/core/connections/transaction.ts
272
+ const transactionNestingCounter = () => {
273
+ let transactionLevel = 0;
274
+ return {
275
+ reset: () => {
276
+ transactionLevel = 0;
277
+ },
278
+ increment: () => {
279
+ transactionLevel++;
280
+ },
281
+ decrement: () => {
282
+ transactionLevel--;
283
+ if (transactionLevel < 0) throw new Error("Transaction level is out of bounds");
284
+ },
285
+ get level() {
286
+ return transactionLevel;
287
+ }
288
+ };
289
+ };
290
+ const databaseTransaction = (backend, options) => {
291
+ const allowNestedTransactions = options?.allowNestedTransactions ?? false;
292
+ const useSavepoints = options?.useSavepoints ?? false;
293
+ const counter = transactionNestingCounter();
294
+ let hasBegun = false;
295
+ return {
296
+ begin: async () => {
297
+ if (!allowNestedTransactions && hasBegun) throw new InvalidOperationError("Cannot start a nested transaction: allowNestedTransactions is false. Set transactionOptions: { allowNestedTransactions: true } on your pool or connection.");
298
+ if (allowNestedTransactions) {
299
+ if (counter.level >= 1) {
300
+ counter.increment();
301
+ if (useSavepoints && backend.savepoint) await backend.savepoint(counter.level);
302
+ return;
303
+ }
304
+ counter.increment();
305
+ }
306
+ hasBegun = true;
307
+ await backend.begin();
308
+ },
309
+ commit: async () => {
310
+ if (allowNestedTransactions && counter.level > 1) {
311
+ if (useSavepoints && backend.releaseSavepoint) await backend.releaseSavepoint(counter.level);
312
+ counter.decrement();
313
+ return;
314
+ }
315
+ if (allowNestedTransactions) counter.reset();
316
+ hasBegun = false;
317
+ await backend.commit();
318
+ },
319
+ rollback: async (error) => {
320
+ if (allowNestedTransactions && counter.level > 1) {
321
+ if (useSavepoints && backend.rollbackToSavepoint) await backend.rollbackToSavepoint(counter.level);
322
+ counter.decrement();
323
+ return;
324
+ }
325
+ if (allowNestedTransactions) counter.reset();
326
+ hasBegun = false;
327
+ await backend.rollback(error);
328
+ }
329
+ };
330
+ };
272
331
  const toTransactionResult = (transactionResult) => transactionResult !== void 0 && transactionResult !== null && typeof transactionResult === "object" && "success" in transactionResult ? transactionResult : {
273
332
  success: true,
274
333
  result: transactionResult
@@ -459,22 +518,53 @@ const createAmbientConnectionPool = (options) => {
459
518
  const createSingletonConnectionPool = (options) => {
460
519
  const { driverType, getConnection } = options;
461
520
  let connectionPromise = null;
521
+ let closed = false;
522
+ const activeOperations = /* @__PURE__ */ new Set();
523
+ const closedError = () => /* @__PURE__ */ new Error("Singleton connection pool has been closed");
524
+ const run = async (operation) => {
525
+ if (closed) throw closedError();
526
+ const activeOperation = operation();
527
+ activeOperations.add(activeOperation);
528
+ try {
529
+ return await activeOperation;
530
+ } finally {
531
+ activeOperations.delete(activeOperation);
532
+ }
533
+ };
462
534
  const getExistingOrNewConnection = () => {
463
535
  if (!connectionPromise) connectionPromise ??= Promise.resolve(getConnection());
464
536
  return connectionPromise;
465
537
  };
538
+ const innerTransactionFactory = transactionFactoryWithAsyncAmbientConnection(options.driverType, getExistingOrNewConnection, options.closeConnection);
466
539
  return {
467
540
  driverType,
468
- connection: () => getExistingOrNewConnection().then((conn) => wrapPooledConnection(conn, () => Promise.resolve())),
469
- execute: sqlExecutorInAmbientConnection({
470
- driverType,
471
- connection: getExistingOrNewConnection
472
- }),
473
- withConnection: (handle, _options) => executeInAmbientConnection(handle, { connection: getExistingOrNewConnection }),
474
- ...transactionFactoryWithAsyncAmbientConnection(options.driverType, getExistingOrNewConnection, options.closeConnection),
475
- close: async () => {
541
+ connection: () => run(() => getExistingOrNewConnection().then((conn) => wrapPooledConnection(conn, () => Promise.resolve()))),
542
+ execute: (() => {
543
+ const ambientExecutor = sqlExecutorInAmbientConnection({
544
+ driverType,
545
+ connection: getExistingOrNewConnection
546
+ });
547
+ return {
548
+ query: (sql, opts) => run(() => ambientExecutor.query(sql, opts)),
549
+ batchQuery: (sqls, opts) => run(() => ambientExecutor.batchQuery(sqls, opts)),
550
+ command: (sql, opts) => run(() => ambientExecutor.command(sql, opts)),
551
+ batchCommand: (sqls, opts) => run(() => ambientExecutor.batchCommand(sqls, opts))
552
+ };
553
+ })(),
554
+ withConnection: (handle, _options) => run(() => executeInAmbientConnection(handle, { connection: getExistingOrNewConnection })),
555
+ transaction: (transactionOptions) => {
556
+ if (closed) throw closedError();
557
+ return innerTransactionFactory.transaction(transactionOptions);
558
+ },
559
+ withTransaction: (handle, transactionOptions) => run(() => innerTransactionFactory.withTransaction(handle, transactionOptions)),
560
+ close: async (closeOptions) => {
561
+ if (closed) return;
562
+ closed = true;
563
+ if (!closeOptions?.force) await Promise.allSettled([...activeOperations]);
476
564
  if (!connectionPromise) return;
477
- await (await connectionPromise).close();
565
+ const connection = await connectionPromise;
566
+ connectionPromise = null;
567
+ await connection.close();
478
568
  }
479
569
  };
480
570
  };
@@ -1827,54 +1917,46 @@ const sqliteSQLExecutor = (driverType, serializer, formatter, errorMapper) => ({
1827
1917
  //#endregion
1828
1918
  //#region src/storage/sqlite/core/transactions/index.ts
1829
1919
  const sqliteTransaction = (driverType, connection, allowNestedTransactions, serializer, defaultTransactionMode) => (getClient, options) => {
1830
- const transactionCounter = transactionNestingCounter();
1831
1920
  allowNestedTransactions = options?.allowNestedTransactions ?? allowNestedTransactions;
1832
- let hasBegun = false;
1833
- return {
1834
- connection: connection(),
1835
- driverType,
1836
- begin: async function() {
1921
+ const useSavepoints = options?.useSavepoints ?? false;
1922
+ const tx = databaseTransaction({
1923
+ begin: async () => {
1837
1924
  const client = await getClient;
1838
- if (allowNestedTransactions) {
1839
- if (transactionCounter.level >= 1) {
1840
- transactionCounter.increment();
1841
- if (options?.useSavepoints) await client.command(SQL`SAVEPOINT transaction${SQL.plain(transactionCounter.level.toString())}`);
1842
- return;
1843
- }
1844
- transactionCounter.increment();
1845
- } else if (hasBegun) throw new InvalidOperationError("Cannot start a nested transaction: allowNestedTransactions is false. Set transactionOptions: { allowNestedTransactions: true } on your pool or connection.");
1846
- hasBegun = true;
1847
1925
  const mode = options?.mode ?? defaultTransactionMode ?? "IMMEDIATE";
1848
1926
  await client.command(SQL`BEGIN ${SQL.plain(mode)} TRANSACTION`);
1849
1927
  },
1850
- commit: async function() {
1928
+ commit: async () => {
1851
1929
  const client = await getClient;
1852
- if (allowNestedTransactions && transactionCounter.level > 1) {
1853
- if (options?.useSavepoints) await client.command(SQL`RELEASE transaction${SQL.plain(transactionCounter.level.toString())}`);
1854
- transactionCounter.decrement();
1855
- return;
1856
- }
1857
1930
  try {
1858
- if (allowNestedTransactions) transactionCounter.reset();
1859
- hasBegun = false;
1860
1931
  await client.command(SQL`COMMIT`);
1861
1932
  } finally {
1862
- if (options?.close) await options?.close(client);
1933
+ if (options?.close) await options.close(client);
1863
1934
  }
1864
1935
  },
1865
- rollback: async function(error) {
1936
+ rollback: async (error) => {
1866
1937
  const client = await getClient;
1867
- if (allowNestedTransactions && transactionCounter.level > 1) {
1868
- transactionCounter.decrement();
1869
- return;
1870
- }
1871
1938
  try {
1872
- hasBegun = false;
1873
1939
  await client.command(SQL`ROLLBACK`);
1874
1940
  } finally {
1875
- if (options?.close) await options?.close(client, error);
1941
+ if (options?.close) await options.close(client, error);
1876
1942
  }
1877
1943
  },
1944
+ savepoint: async (level) => {
1945
+ await (await getClient).command(SQL`SAVEPOINT transaction${SQL.plain(level.toString())}`);
1946
+ },
1947
+ releaseSavepoint: async (level) => {
1948
+ await (await getClient).command(SQL`RELEASE transaction${SQL.plain(level.toString())}`);
1949
+ }
1950
+ }, {
1951
+ allowNestedTransactions,
1952
+ useSavepoints
1953
+ });
1954
+ return {
1955
+ connection: connection(),
1956
+ driverType,
1957
+ begin: tx.begin,
1958
+ commit: tx.commit,
1959
+ rollback: tx.rollback,
1878
1960
  execute: sqlExecutor(sqliteSQLExecutor(driverType, serializer), { connect: () => getClient }),
1879
1961
  _transactionOptions: {
1880
1962
  ...options,
@@ -1920,24 +2002,6 @@ const isSQLiteError = (error) => {
1920
2002
  if (error instanceof Error && "code" in error) return true;
1921
2003
  return false;
1922
2004
  };
1923
- const transactionNestingCounter = () => {
1924
- let transactionLevel = 0;
1925
- return {
1926
- reset: () => {
1927
- transactionLevel = 0;
1928
- },
1929
- increment: () => {
1930
- transactionLevel++;
1931
- },
1932
- decrement: () => {
1933
- transactionLevel--;
1934
- if (transactionLevel < 0) throw new Error("Transaction level is out of bounds");
1935
- },
1936
- get level() {
1937
- return transactionLevel;
1938
- }
1939
- };
1940
- };
1941
2005
  const sqliteAmbientClientConnection = (options) => {
1942
2006
  const { client, driverType, initTransaction, allowNestedTransactions, defaultTransactionMode, serializer, errorMapper } = options;
1943
2007
  return createAmbientConnection({
@@ -2500,6 +2564,5 @@ exports.sqliteSingletonConnectionPool = sqliteSingletonConnectionPool;
2500
2564
  exports.sqliteTransaction = sqliteTransaction;
2501
2565
  exports.tableExists = tableExists;
2502
2566
  exports.toSqlitePoolOptions = toSqlitePoolOptions;
2503
- exports.transactionNestingCounter = transactionNestingCounter;
2504
2567
  exports.useD1DumboDriver = useD1DumboDriver;
2505
2568
  //# sourceMappingURL=cloudflare.cjs.map