@pineliner/odb-client 1.1.2 → 1.1.3

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/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  var __webpack_modules__ = {
3
- "./src/orm/index.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
3
+ "./src/orm/index.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
4
4
  __webpack_require__.r(__webpack_exports__);
5
5
  __webpack_require__.d(__webpack_exports__, {
6
6
  ORM: ()=>ORM,
@@ -446,7 +446,7 @@ function __webpack_require__(moduleId) {
446
446
  })();
447
447
  (()=>{
448
448
  __webpack_require__.r = (exports1)=>{
449
- if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
449
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
450
450
  value: 'Module'
451
451
  });
452
452
  Object.defineProperty(exports1, '__esModule', {
@@ -458,53 +458,53 @@ var __webpack_exports__ = {};
458
458
  (()=>{
459
459
  __webpack_require__.r(__webpack_exports__);
460
460
  __webpack_require__.d(__webpack_exports__, {
461
- insertValues: ()=>src_insertValues,
462
- updateSet: ()=>src_updateSet,
463
461
  gte: ()=>orm.gte,
464
- ODBLiteClient: ()=>ODBLiteClient,
465
- QueryError: ()=>types_QueryError,
462
+ ODBLiteTransaction: ()=>ODBLiteTransaction,
463
+ updateSet: ()=>src_updateSet,
466
464
  sql: ()=>sql_parser_sql,
467
- sqlFragment: ()=>sql_template_fragment,
468
- ODBLiteError: ()=>ODBLiteError,
465
+ isNotNull: ()=>orm.isNotNull,
466
+ LibSQLAdapter: ()=>LibSQLAdapter,
469
467
  ORM: ()=>orm.ORM,
470
- ConnectionError: ()=>ConnectionError,
471
468
  join: ()=>src_join,
472
- convertTemplateToQuery: ()=>convertTemplateToQuery,
473
- HTTPClient: ()=>HTTPClient,
474
- BunSQLiteAdapter: ()=>BunSQLiteAdapter,
475
- SQLParser: ()=>sql_parser_SQLParser,
469
+ lte: ()=>orm.lte,
476
470
  default: ()=>odblite,
471
+ splitSQLStatements: ()=>splitSQLStatements,
472
+ ne: ()=>orm.ne,
477
473
  gt: ()=>orm.gt,
478
474
  eq: ()=>orm.eq,
479
- identifier: ()=>src_identifier,
480
- lte: ()=>orm.lte,
481
- ne: ()=>orm.ne,
482
- parseSQL: ()=>parseSQL,
483
- splitSQLStatements: ()=>splitSQLStatements,
484
- where: ()=>src_where,
485
- LibSQLAdapter: ()=>LibSQLAdapter,
486
- ORMTransaction: ()=>orm.Transaction,
487
- lt: ()=>orm.lt,
488
475
  fragment: ()=>fragment,
476
+ where: ()=>src_where,
477
+ identifier: ()=>src_identifier,
478
+ insertValues: ()=>src_insertValues,
479
+ ConnectionError: ()=>ConnectionError,
480
+ ODBLiteClient: ()=>ODBLiteClient,
489
481
  isNull: ()=>orm.isNull,
490
- DatabaseManager: ()=>DatabaseManager,
482
+ HTTPClient: ()=>HTTPClient,
483
+ SQLParser: ()=>sql_parser_SQLParser,
484
+ BunSQLiteAdapter: ()=>BunSQLiteAdapter,
485
+ QueryError: ()=>types_QueryError,
486
+ createORM: ()=>orm.createORM,
487
+ lt: ()=>orm.lt,
491
488
  or: ()=>orm.or,
492
- ODBLiteTransaction: ()=>ODBLiteTransaction,
493
- ServiceClient: ()=>ServiceClient,
494
489
  and: ()=>orm.and,
495
490
  odblite: ()=>odblite,
491
+ parseSQL: ()=>parseSQL,
496
492
  rawSQL: ()=>sql_template_raw,
497
- set: ()=>set,
498
- sqlJoin: ()=>sql_template_join,
499
- createORM: ()=>orm.createORM,
493
+ ServiceClient: ()=>ServiceClient,
494
+ ORMTransaction: ()=>orm.Transaction,
495
+ ODBLiteAdapter: ()=>ODBLiteAdapter,
496
+ convertTemplateToQuery: ()=>convertTemplateToQuery,
500
497
  empty: ()=>empty,
501
- sqlTemplate: ()=>sql_template_sql,
498
+ set: ()=>set,
499
+ ODBLiteError: ()=>ODBLiteError,
502
500
  SimpleTransaction: ()=>SimpleTransaction,
503
501
  inArray: ()=>orm.inArray,
502
+ sqlFragment: ()=>sql_template_fragment,
503
+ sqlJoin: ()=>sql_template_join,
504
504
  sqlWhere: ()=>sql_template_where,
505
- ODBLiteAdapter: ()=>ODBLiteAdapter,
506
- isNotNull: ()=>orm.isNotNull,
505
+ DatabaseManager: ()=>DatabaseManager,
507
506
  like: ()=>orm.like,
507
+ sqlTemplate: ()=>sql_template_sql,
508
508
  raw: ()=>src_raw
509
509
  });
510
510
  class ODBLiteError extends Error {
@@ -2020,55 +2020,29 @@ var __webpack_exports__ = {};
2020
2020
  };
2021
2021
  }
2022
2022
  async transaction(fn) {
2023
- if (this.inTransaction) return fn(this);
2023
+ if (this.inTransaction) {
2024
+ const savepointName = `sp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
2025
+ try {
2026
+ await this.execute(`SAVEPOINT ${savepointName}`);
2027
+ const result = await fn(this);
2028
+ await this.execute(`RELEASE SAVEPOINT ${savepointName}`);
2029
+ return result;
2030
+ } catch (error) {
2031
+ await this.execute(`ROLLBACK TO SAVEPOINT ${savepointName}`).catch(()=>{});
2032
+ throw error;
2033
+ }
2034
+ }
2024
2035
  this.inTransaction = true;
2025
- const queuedStatements = [];
2026
- const txConnection = {
2027
- ...this,
2028
- execute: async (sql, params = [], options)=>{
2029
- const sqlStr = 'string' == typeof sql ? sql : sql.sql;
2030
- const sqlParams = 'string' == typeof sql ? params : sql.args || [];
2031
- queuedStatements.push({
2032
- sql: sqlStr,
2033
- params: sqlParams
2034
- });
2035
- return {
2036
- rows: [],
2037
- rowsAffected: 0
2038
- };
2039
- },
2040
- query: async (sql, params = [], options)=>{
2041
- queuedStatements.push({
2042
- sql,
2043
- params
2044
- });
2045
- return {
2046
- rows: [],
2047
- rowsAffected: 0
2048
- };
2049
- },
2050
- transaction: async (innerFn)=>innerFn(txConnection),
2051
- begin: async (innerFn)=>innerFn(txConnection)
2052
- };
2053
2036
  try {
2054
- const result = await fn(txConnection);
2055
- if (queuedStatements.length > 0) {
2056
- const batchStatements = [
2057
- {
2058
- sql: 'BEGIN',
2059
- params: []
2060
- },
2061
- ...queuedStatements,
2062
- {
2063
- sql: 'COMMIT',
2064
- params: []
2065
- }
2066
- ];
2067
- await this.client.sql.batch(batchStatements);
2037
+ await this.execute('BEGIN');
2038
+ try {
2039
+ const result = await fn(this);
2040
+ await this.execute('COMMIT');
2041
+ return result;
2042
+ } catch (error) {
2043
+ await this.execute('ROLLBACK').catch(()=>{});
2044
+ throw error;
2068
2045
  }
2069
- return result;
2070
- } catch (error) {
2071
- throw error;
2072
2046
  } finally{
2073
2047
  this.inTransaction = false;
2074
2048
  }
@@ -2264,11 +2238,11 @@ var __webpack_exports__ = {};
2264
2238
  return Array.from(this.connections.keys());
2265
2239
  }
2266
2240
  async close() {
2267
- console.log(`🔌 Closing all database connections...`);
2241
+ console.log("\uD83D\uDD0C Closing all database connections...");
2268
2242
  for (const [name, conn] of this.connections)await conn.close();
2269
2243
  this.connections.clear();
2270
2244
  this.connectionTimestamps.clear();
2271
- console.log(`✅ All connections closed`);
2245
+ console.log("✅ All connections closed");
2272
2246
  }
2273
2247
  async runMigrations(conn, config) {
2274
2248
  const { pragmaStatements, regularStatements } = parseSQL(config.schemaContent);
@@ -2377,7 +2351,7 @@ exports.sqlTemplate = __webpack_exports__.sqlTemplate;
2377
2351
  exports.sqlWhere = __webpack_exports__.sqlWhere;
2378
2352
  exports.updateSet = __webpack_exports__.updateSet;
2379
2353
  exports.where = __webpack_exports__.where;
2380
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
2354
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
2381
2355
  "BunSQLiteAdapter",
2382
2356
  "ConnectionError",
2383
2357
  "DatabaseManager",
@@ -2426,7 +2400,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
2426
2400
  "sqlWhere",
2427
2401
  "updateSet",
2428
2402
  "where"
2429
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
2403
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
2430
2404
  Object.defineProperty(exports, '__esModule', {
2431
2405
  value: true
2432
2406
  });
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
+ import { __webpack_require__ } from "./rslib-runtime.js";
1
2
  import { Database } from "bun:sqlite";
2
3
  import { createClient } from "@libsql/client";
3
4
  import node_fs from "node:fs";
4
- var __webpack_modules__ = {
5
- "./src/orm/index.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5
+ __webpack_require__.add({
6
+ "./src/orm/index.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
6
7
  __webpack_require__.r(__webpack_exports__);
7
8
  __webpack_require__.d(__webpack_exports__, {
8
9
  ORM: ()=>ORM,
@@ -415,38 +416,7 @@ var __webpack_modules__ = {
415
416
  return new ORM(db);
416
417
  }
417
418
  }
418
- };
419
- var __webpack_module_cache__ = {};
420
- function __webpack_require__(moduleId) {
421
- var cachedModule = __webpack_module_cache__[moduleId];
422
- if (void 0 !== cachedModule) return cachedModule.exports;
423
- var module = __webpack_module_cache__[moduleId] = {
424
- exports: {}
425
- };
426
- __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
427
- return module.exports;
428
- }
429
- (()=>{
430
- __webpack_require__.d = (exports, definition)=>{
431
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
432
- enumerable: true,
433
- get: definition[key]
434
- });
435
- };
436
- })();
437
- (()=>{
438
- __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
439
- })();
440
- (()=>{
441
- __webpack_require__.r = (exports)=>{
442
- if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, {
443
- value: 'Module'
444
- });
445
- Object.defineProperty(exports, '__esModule', {
446
- value: true
447
- });
448
- };
449
- })();
419
+ });
450
420
  class ODBLiteError extends Error {
451
421
  code;
452
422
  query;
@@ -1958,55 +1928,29 @@ class ODBLiteConnection {
1958
1928
  };
1959
1929
  }
1960
1930
  async transaction(fn) {
1961
- if (this.inTransaction) return fn(this);
1931
+ if (this.inTransaction) {
1932
+ const savepointName = `sp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
1933
+ try {
1934
+ await this.execute(`SAVEPOINT ${savepointName}`);
1935
+ const result = await fn(this);
1936
+ await this.execute(`RELEASE SAVEPOINT ${savepointName}`);
1937
+ return result;
1938
+ } catch (error) {
1939
+ await this.execute(`ROLLBACK TO SAVEPOINT ${savepointName}`).catch(()=>{});
1940
+ throw error;
1941
+ }
1942
+ }
1962
1943
  this.inTransaction = true;
1963
- const queuedStatements = [];
1964
- const txConnection = {
1965
- ...this,
1966
- execute: async (sql, params = [], options)=>{
1967
- const sqlStr = 'string' == typeof sql ? sql : sql.sql;
1968
- const sqlParams = 'string' == typeof sql ? params : sql.args || [];
1969
- queuedStatements.push({
1970
- sql: sqlStr,
1971
- params: sqlParams
1972
- });
1973
- return {
1974
- rows: [],
1975
- rowsAffected: 0
1976
- };
1977
- },
1978
- query: async (sql, params = [], options)=>{
1979
- queuedStatements.push({
1980
- sql,
1981
- params
1982
- });
1983
- return {
1984
- rows: [],
1985
- rowsAffected: 0
1986
- };
1987
- },
1988
- transaction: async (innerFn)=>innerFn(txConnection),
1989
- begin: async (innerFn)=>innerFn(txConnection)
1990
- };
1991
1944
  try {
1992
- const result = await fn(txConnection);
1993
- if (queuedStatements.length > 0) {
1994
- const batchStatements = [
1995
- {
1996
- sql: 'BEGIN',
1997
- params: []
1998
- },
1999
- ...queuedStatements,
2000
- {
2001
- sql: 'COMMIT',
2002
- params: []
2003
- }
2004
- ];
2005
- await this.client.sql.batch(batchStatements);
1945
+ await this.execute('BEGIN');
1946
+ try {
1947
+ const result = await fn(this);
1948
+ await this.execute('COMMIT');
1949
+ return result;
1950
+ } catch (error) {
1951
+ await this.execute('ROLLBACK').catch(()=>{});
1952
+ throw error;
2006
1953
  }
2007
- return result;
2008
- } catch (error) {
2009
- throw error;
2010
1954
  } finally{
2011
1955
  this.inTransaction = false;
2012
1956
  }
@@ -2200,11 +2144,11 @@ class DatabaseManager {
2200
2144
  return Array.from(this.connections.keys());
2201
2145
  }
2202
2146
  async close() {
2203
- console.log(`🔌 Closing all database connections...`);
2147
+ console.log("\uD83D\uDD0C Closing all database connections...");
2204
2148
  for (const [name, conn] of this.connections)await conn.close();
2205
2149
  this.connections.clear();
2206
2150
  this.connectionTimestamps.clear();
2207
- console.log(`✅ All connections closed`);
2151
+ console.log("✅ All connections closed");
2208
2152
  }
2209
2153
  async runMigrations(conn, config) {
2210
2154
  const { pragmaStatements, regularStatements } = parseSQL(config.schemaContent);
@@ -2262,21 +2206,22 @@ class DatabaseManager {
2262
2206
  }
2263
2207
  }
2264
2208
  }
2265
- var orm = __webpack_require__("./src/orm/index.ts");
2266
2209
  const { raw: src_raw, identifier: src_identifier, where: src_where, insertValues: src_insertValues, updateSet: src_updateSet, join: src_join } = ODBLiteClient;
2267
- var __webpack_exports__ORM = orm.ORM;
2268
- var __webpack_exports__ORMTransaction = orm.Transaction;
2269
- var __webpack_exports__and = orm.and;
2270
- var __webpack_exports__createORM = orm.createORM;
2271
- var __webpack_exports__eq = orm.eq;
2272
- var __webpack_exports__gt = orm.gt;
2273
- var __webpack_exports__gte = orm.gte;
2274
- var __webpack_exports__inArray = orm.inArray;
2275
- var __webpack_exports__isNotNull = orm.isNotNull;
2276
- var __webpack_exports__isNull = orm.isNull;
2277
- var __webpack_exports__like = orm.like;
2278
- var __webpack_exports__lt = orm.lt;
2279
- var __webpack_exports__lte = orm.lte;
2280
- var __webpack_exports__ne = orm.ne;
2281
- var __webpack_exports__or = orm.or;
2282
- export { BunSQLiteAdapter, ConnectionError, DatabaseManager, HTTPClient, LibSQLAdapter, ODBLiteAdapter, ODBLiteClient, ODBLiteError, ODBLiteTransaction, types_QueryError as QueryError, sql_parser_SQLParser as SQLParser, ServiceClient, SimpleTransaction, convertTemplateToQuery, odblite as default, empty, fragment, src_identifier as identifier, src_insertValues as insertValues, src_join as join, odblite, parseSQL, src_raw as raw, sql_template_raw as rawSQL, set, splitSQLStatements, sql_parser_sql as sql, sql_template_fragment as sqlFragment, sql_template_join as sqlJoin, sql_template_sql as sqlTemplate, sql_template_where as sqlWhere, src_updateSet as updateSet, src_where as where, __webpack_exports__ORM as ORM, __webpack_exports__ORMTransaction as ORMTransaction, __webpack_exports__and as and, __webpack_exports__createORM as createORM, __webpack_exports__eq as eq, __webpack_exports__gt as gt, __webpack_exports__gte as gte, __webpack_exports__inArray as inArray, __webpack_exports__isNotNull as isNotNull, __webpack_exports__isNull as isNull, __webpack_exports__like as like, __webpack_exports__lt as lt, __webpack_exports__lte as lte, __webpack_exports__ne as ne, __webpack_exports__or as or };
2210
+ const orm = __webpack_require__("./src/orm/index.ts");
2211
+ var ORM = orm.ORM;
2212
+ var Transaction = orm.Transaction;
2213
+ var and = orm.and;
2214
+ var createORM_0 = orm.createORM;
2215
+ var eq = orm.eq;
2216
+ var gt = orm.gt;
2217
+ var gte = orm.gte;
2218
+ var inArray = orm.inArray;
2219
+ var isNotNull = orm.isNotNull;
2220
+ var isNull = orm.isNull;
2221
+ var like = orm.like;
2222
+ var lt = orm.lt;
2223
+ var lte = orm.lte;
2224
+ var ne = orm.ne;
2225
+ var or = orm.or;
2226
+ export default odblite;
2227
+ export { BunSQLiteAdapter, ConnectionError, DatabaseManager, HTTPClient, LibSQLAdapter, ODBLiteAdapter, ODBLiteClient, ODBLiteError, ODBLiteTransaction, ORM, ServiceClient, SimpleTransaction, Transaction as ORMTransaction, and, convertTemplateToQuery, createORM_0 as createORM, empty, eq, fragment, gt, gte, inArray, isNotNull, isNull, like, lt, lte, ne, odblite, or, parseSQL, set, splitSQLStatements, sql_parser_SQLParser as SQLParser, sql_parser_sql as sql, sql_template_fragment as sqlFragment, sql_template_join as sqlJoin, sql_template_raw as rawSQL, sql_template_sql as sqlTemplate, sql_template_where as sqlWhere, src_identifier as identifier, src_insertValues as insertValues, src_join as join, src_raw as raw, src_updateSet as updateSet, src_where as where, types_QueryError as QueryError };
@@ -0,0 +1,39 @@
1
+ var __webpack_modules__ = {};
2
+ var __webpack_module_cache__ = {};
3
+ function __webpack_require__(moduleId) {
4
+ var cachedModule = __webpack_module_cache__[moduleId];
5
+ if (void 0 !== cachedModule) return cachedModule.exports;
6
+ var module = __webpack_module_cache__[moduleId] = {
7
+ exports: {}
8
+ };
9
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
10
+ return module.exports;
11
+ }
12
+ __webpack_require__.m = __webpack_modules__;
13
+ (()=>{
14
+ __webpack_require__.add = function(modules) {
15
+ Object.assign(__webpack_require__.m, modules);
16
+ };
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.d = (exports, definition)=>{
20
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
21
+ enumerable: true,
22
+ get: definition[key]
23
+ });
24
+ };
25
+ })();
26
+ (()=>{
27
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
28
+ })();
29
+ (()=>{
30
+ __webpack_require__.r = (exports)=>{
31
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports, Symbol.toStringTag, {
32
+ value: 'Module'
33
+ });
34
+ Object.defineProperty(exports, '__esModule', {
35
+ value: true
36
+ });
37
+ };
38
+ })();
39
+ export { __webpack_require__ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pineliner/odb-client",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Isomorphic client for ODB-Lite with postgres.js-like template string SQL support",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -14,12 +14,12 @@
14
14
  "deploy": "bun run build && npm publish --access public"
15
15
  },
16
16
  "dependencies": {
17
- "@libsql/client": "^0.15.15",
17
+ "@libsql/client": "^0.17.0",
18
18
  "node-sql-parser": "^5.3.12"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/bun": "latest",
22
- "@rslib/core": "0.15.0",
22
+ "@rslib/core": "0.19.3",
23
23
  "typescript": "^5.9.2"
24
24
  },
25
25
  "exports": {
@@ -289,61 +289,50 @@ class ODBLiteConnection implements Connection {
289
289
  }
290
290
 
291
291
  /**
292
- * Execute function in transaction using batch endpoint
293
- * All statements are collected and executed atomically
292
+ * Execute function in transaction using immediate execution mode
293
+ *
294
+ * Each statement is executed immediately via the query endpoint,
295
+ * wrapped in BEGIN/COMMIT. This allows lastInsertRowid to be
296
+ * available for subsequent statements within the transaction.
297
+ *
298
+ * NOTE: Atomicity is maintained by the router's transaction lock
299
+ * which ensures all statements from BEGIN to COMMIT run on the
300
+ * same connection without interleaving from other requests.
294
301
  */
295
302
  async transaction<T>(fn: (tx: Connection) => Promise<T>): Promise<T> {
296
303
  if (this.inTransaction) {
297
- // Nested transaction - just execute the function
298
- return fn(this)
304
+ // Nested transaction - use savepoint
305
+ const savepointName = `sp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
306
+ try {
307
+ await this.execute(`SAVEPOINT ${savepointName}`)
308
+ const result = await fn(this)
309
+ await this.execute(`RELEASE SAVEPOINT ${savepointName}`)
310
+ return result
311
+ } catch (error) {
312
+ await this.execute(`ROLLBACK TO SAVEPOINT ${savepointName}`).catch(() => {})
313
+ throw error
314
+ }
299
315
  }
300
316
 
301
317
  this.inTransaction = true
302
- const queuedStatements: Array<{ sql: string; params: any[] }> = []
303
318
 
304
- // Create a transactional connection that queues statements
305
- const txConnection: Connection = {
306
- ...this,
307
- execute: async (sql: string | { sql: string; args?: any[] }, params: any[] = [], options?: any) => {
308
- const sqlStr = typeof sql === 'string' ? sql : sql.sql
309
- const sqlParams = typeof sql === 'string' ? params : (sql.args || [])
319
+ try {
320
+ // Start transaction
321
+ await this.execute('BEGIN')
310
322
 
311
- // Queue the statement
312
- queuedStatements.push({ sql: sqlStr, params: sqlParams })
323
+ try {
324
+ // Execute user function - each statement executes immediately
325
+ const result = await fn(this)
313
326
 
314
- // Return placeholder
315
- return { rows: [], rowsAffected: 0 }
316
- },
317
- query: async (sql: string, params: any[] = [], options?: any) => {
318
- queuedStatements.push({ sql, params })
319
- return { rows: [], rowsAffected: 0 }
320
- },
321
- transaction: async (innerFn: any) => {
322
- // For nested transactions, just execute inline
323
- return innerFn(txConnection)
324
- },
325
- begin: async (innerFn: any) => {
326
- return innerFn(txConnection)
327
- }
328
- } as Connection
327
+ // Commit transaction
328
+ await this.execute('COMMIT')
329
329
 
330
- try {
331
- const result = await fn(txConnection)
332
-
333
- // Commit: execute all statements as a batch
334
- if (queuedStatements.length > 0) {
335
- const batchStatements = [
336
- { sql: 'BEGIN', params: [] },
337
- ...queuedStatements,
338
- { sql: 'COMMIT', params: [] }
339
- ]
340
- await this.client.sql.batch(batchStatements)
330
+ return result
331
+ } catch (error) {
332
+ // Rollback on error
333
+ await this.execute('ROLLBACK').catch(() => {})
334
+ throw error
341
335
  }
342
-
343
- return result
344
- } catch (error) {
345
- // On error, batch is never sent - implicit rollback
346
- throw error
347
336
  } finally {
348
337
  this.inTransaction = false
349
338
  }