@nextlyhq/adapter-sqlite 0.0.2-alpha.66 → 0.0.2-alpha.68

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["DrizzleAdapter","checkDialectVersion","isApplicationError","createDatabaseError","drizzle","getTableConfig","isDatabaseError"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @nextlyhq/adapter-sqlite\n *\n * SQLite database adapter for Nextly.\n * Extends DrizzleAdapter from @nextlyhq/adapter-drizzle to provide SQLite-specific functionality.\n *\n * @remarks\n * This adapter uses the better-sqlite3 package for database connectivity and provides:\n * - Synchronous API wrapped for async interface compatibility\n * - Full transaction support with savepoints (via better-sqlite3's native transaction handling)\n * - CRUD operations with RETURNING clause support (SQLite 3.35+)\n * - WAL mode for better concurrent read performance\n * - In-memory and file-based database support\n *\n * @example\n * ```typescript\n * import { createSqliteAdapter } from '@nextlyhq/adapter-sqlite';\n *\n * const adapter = createSqliteAdapter({\n * url: 'file:./data/app.db',\n * });\n *\n * await adapter.connect();\n *\n * // Query data\n * const users = await adapter.select('users', {\n * where: { and: [{ column: 'status', op: '=', value: 'active' }] },\n * limit: 10,\n * });\n *\n * await adapter.disconnect();\n * ```\n *\n * @packageDocumentation\n */\n\nimport { DrizzleAdapter } from \"@nextlyhq/adapter-drizzle\";\n// F17: connect-time DB version check shared across all adapters.\nimport {\n createDatabaseError,\n isDatabaseError,\n type SqliteAdapterConfig,\n type DatabaseCapabilities,\n type PoolStats,\n type TransactionContext,\n type TransactionOptions,\n type SqlParam,\n type WhereClause,\n type WhereCondition,\n type WhereOperator,\n type SelectOptions,\n type InsertOptions,\n type UpdateOptions,\n type DeleteOptions,\n type UpsertOptions,\n type OrderBySpec,\n type JoinSpec,\n type DatabaseError,\n type DatabaseErrorKind,\n type BaseAdapterConfig,\n type AdapterLogger,\n isApplicationError,\n} from \"@nextlyhq/adapter-drizzle/types\";\nimport { checkDialectVersion } from \"@nextlyhq/adapter-drizzle/version-check\";\nimport type Database from \"better-sqlite3\";\nimport type { AnyRelations, SQL } from \"drizzle-orm\";\nimport {\n drizzle,\n type BetterSQLite3Database,\n} from \"drizzle-orm/better-sqlite3\";\nimport { getTableConfig, type SQLiteTable } from \"drizzle-orm/sqlite-core\";\n\n// Re-export types for convenience\nexport type {\n SqliteAdapterConfig,\n DatabaseCapabilities,\n PoolStats,\n TransactionContext,\n TransactionOptions,\n SqlParam,\n WhereClause,\n WhereCondition,\n WhereOperator,\n SelectOptions,\n InsertOptions,\n UpdateOptions,\n DeleteOptions,\n UpsertOptions,\n OrderBySpec,\n JoinSpec,\n DatabaseError,\n DatabaseErrorKind,\n BaseAdapterConfig,\n AdapterLogger,\n};\n\n/**\n * Package version\n */\nexport const VERSION = \"0.1.0\";\n\n/**\n * SQLite error codes mapping to DatabaseErrorKind.\n *\n * @see https://sqlite.org/rescode.html\n */\nconst SQLITE_ERROR_CODES: Record<string, DatabaseErrorKind> = {\n // Constraint violations\n SQLITE_CONSTRAINT: \"constraint\",\n SQLITE_CONSTRAINT_UNIQUE: \"unique_violation\",\n SQLITE_CONSTRAINT_PRIMARYKEY: \"unique_violation\",\n SQLITE_CONSTRAINT_FOREIGNKEY: \"foreign_key_violation\",\n SQLITE_CONSTRAINT_NOTNULL: \"not_null_violation\",\n SQLITE_CONSTRAINT_CHECK: \"check_violation\",\n\n // Busy/locked errors\n SQLITE_BUSY: \"timeout\",\n SQLITE_LOCKED: \"timeout\",\n\n // Connection errors\n SQLITE_CANTOPEN: \"connection\",\n SQLITE_NOTADB: \"connection\",\n SQLITE_CORRUPT: \"connection\",\n\n // Query errors\n SQLITE_ERROR: \"query\",\n SQLITE_MISUSE: \"query\",\n SQLITE_RANGE: \"query\",\n};\n\n/**\n * Default configuration values.\n */\nconst DEFAULT_CONFIG = {\n busyTimeout: 5000,\n wal: true,\n foreignKeys: true,\n};\n\n/**\n * Converts a JavaScript value to a type that better-sqlite3 can bind.\n * better-sqlite3 only accepts: number, string, bigint, Buffer, null.\n *\n * These conversions have to match what the schema declares, because the rows\n * they write are read back through it. Every column here that takes a `Date`\n * is `integer({ mode: \"timestamp\" })` — the system columns and user date\n * fields in `runtime-schema-generator.ts`, and the core tables, whose date\n * columns are all INTEGER. So a date is bound as unix seconds, which is what\n * that mode reads.\n */\nfunction sanitizeSqliteValue(v: unknown): unknown {\n if (v === undefined) return null;\n if (typeof v === \"boolean\") return v ? 1 : 0;\n // Binary is bound as binary: better-sqlite3 takes a Buffer or a typed\n // array for a BLOB as it is, and the object branch below would spell it\n // out as JSON text instead.\n if (Buffer.isBuffer(v) || ArrayBuffer.isView(v)) return v;\n // Seconds, not an ISO string. SQLite stores whatever it is given regardless\n // of the declared type, so a string lands in the column without complaint\n // and only fails on the way back out, where the timestamp decoder reads it\n // as a number and yields an Invalid Date.\n if (v instanceof Date) return Math.floor(v.getTime() / 1000);\n if (v !== null && typeof v === \"object\") return JSON.stringify(v);\n return v;\n}\n\n/**\n * SQLite database adapter for Nextly.\n *\n * Extends the base DrizzleAdapter to provide SQLite-specific functionality\n * using the better-sqlite3 package.\n *\n * @remarks\n * SQLite has some differences from PostgreSQL:\n * - Synchronous API (wrapped for async compatibility)\n * - No connection pooling (single file/connection)\n * - RETURNING clause supported (SQLite 3.35+)\n * - Savepoints supported via nested transactions\n * - No native ILIKE (uses LOWER() LIKE workaround)\n * - JSON support (not JSONB)\n * - No array types\n *\n * @example\n * ```typescript\n * const adapter = new SqliteAdapter({\n * url: 'file:./data.db',\n * });\n *\n * await adapter.connect();\n * ```\n */\nexport class SqliteAdapter extends DrizzleAdapter {\n // getDrizzle memoization: drizzle v1's constructor builds a relational\n // query builder per table in the relations config (~40 tables), and the\n // service layer resolves an instance on every db access — construct once\n // per relations object (identity-stable: the schema registry caches it\n // and hands out a NEW object on invalidation, which naturally misses\n // this cache and produces a fresh instance).\n private drizzleByRelations = new WeakMap<AnyRelations, unknown>();\n private drizzleBare: unknown;\n\n /**\n * The database dialect - always 'sqlite' for this adapter.\n */\n readonly dialect = \"sqlite\" as const;\n\n /**\n * Adapter configuration.\n */\n protected readonly config: SqliteAdapterConfig;\n\n /**\n * better-sqlite3 Database instance.\n */\n private db: Database.Database | null = null;\n\n /**\n * Connection state flag.\n */\n private connected = false;\n\n /**\n * Serialization queue for concurrent `transaction()` calls.\n *\n * better-sqlite3 is synchronous, single-connection, and rejects nested\n * `BEGIN` with \"cannot start a transaction within a transaction\".\n * When two `await adapter.transaction(...)` calls overlap (e.g. a bulk\n * mutation calling `Promise.allSettled` with N per-row updates), the\n * second one tries to BEGIN while the first is still open and the\n * driver throws.\n *\n * Postgres/MySQL avoid this by allocating a fresh client/connection\n * per transaction from a pool — there is no equivalent for\n * better-sqlite3, so we serialize at the JS layer instead. Every\n * `transaction()` invocation chains onto this promise; only one\n * BEGIN→COMMIT/ROLLBACK section runs at any moment, preserving\n * write-isolation semantics that callers expect from a transactional\n * adapter.\n *\n * Performance impact is the natural floor: SQLite already serializes\n * writers at the file-lock level, so the queue removes failed-call\n * surface area without changing the achievable concurrency.\n */\n private transactionQueue: Promise<unknown> = Promise.resolve();\n\n /**\n * Creates a new SQLite adapter instance.\n *\n * @param config - Adapter configuration\n */\n constructor(config: SqliteAdapterConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Connect to the SQLite database.\n *\n * @remarks\n * This method initializes the database connection. For SQLite, this\n * opens the database file or creates an in-memory database.\n * Also configures WAL mode and foreign keys based on config.\n *\n * @throws {DatabaseError} If connection fails\n */\n async connect(): Promise<void> {\n if (this.connected && this.db) {\n return;\n }\n\n try {\n // Dynamic import of better-sqlite3 to avoid bundling issues\n const BetterSqlite3 = await import(\"better-sqlite3\");\n const Database = BetterSqlite3.default;\n\n // Determine database path\n let dbPath: string;\n if (this.config.memory) {\n dbPath = \":memory:\";\n } else if (this.config.url) {\n // Strip file: prefix if present\n dbPath = this.config.url.replace(/^file:/, \"\");\n } else {\n dbPath = \":memory:\";\n }\n\n // Ensure the parent directory exists for file-backed databases.\n // better-sqlite3 fails with a confusing \"Cannot open database\n // because the directory does not exist\" error if it doesn't, and\n // a fresh clone with `DATABASE_URL=file:./data/app.db` reliably\n // hits this on first run. Create the dir lazily so DATABASE_URL\n // can point anywhere without a separate setup step.\n if (dbPath !== \":memory:\" && !this.config.readonly) {\n const fs = await import(\"node:fs\");\n const path = await import(\"node:path\");\n const dir = path.dirname(path.resolve(dbPath));\n await fs.promises.mkdir(dir, { recursive: true });\n }\n\n // Create database instance\n this.db = new Database(dbPath, {\n readonly: this.config.readonly ?? false,\n timeout: this.config.busyTimeout ?? DEFAULT_CONFIG.busyTimeout,\n });\n\n // Configure WAL mode for better concurrency (unless in-memory or readonly)\n if (\n (this.config.wal ?? DEFAULT_CONFIG.wal) &&\n dbPath !== \":memory:\" &&\n !this.config.readonly\n ) {\n this.db.pragma(\"journal_mode = WAL\");\n }\n\n // Enable foreign keys\n if (this.config.foreignKeys ?? DEFAULT_CONFIG.foreignKeys) {\n this.db.pragma(\"foreign_keys = ON\");\n }\n\n // F17: check SQLite version. Hard-fails on SQLite <3.38. SQLite has\n // no recognized cloud variants we warn on, so onWarning is omitted.\n // Note: better-sqlite3's bundled SQLite is set by the package\n // version; users on this package's pinned better-sqlite3 (3.45+)\n // will always pass.\n await checkDialectVersion(this.db, \"sqlite\");\n\n this.connected = true;\n\n if (this.config.logger?.info) {\n this.config.logger.info(\"SQLite connection established\", {\n url: dbPath === \":memory:\" ? \"in-memory\" : dbPath,\n wal: this.config.wal ?? DEFAULT_CONFIG.wal,\n foreignKeys: this.config.foreignKeys ?? DEFAULT_CONFIG.foreignKeys,\n });\n }\n } catch (error) {\n // Clean up on failure\n if (this.db) {\n try {\n this.db.close();\n } catch {\n // Ignore close errors during error handling\n }\n this.db = null;\n }\n throw this.classifyError(error);\n }\n }\n\n /**\n * Disconnect from the SQLite database.\n *\n * @remarks\n * This method closes the database connection and releases resources.\n */\n // better-sqlite3 is synchronous; method is async to satisfy the DatabaseAdapter contract.\n // eslint-disable-next-line @typescript-eslint/require-await\n async disconnect(): Promise<void> {\n // Drop memoized drizzle instances — they wrap the connection being\n // closed and must not survive a reconnect.\n this.drizzleBare = undefined;\n this.drizzleByRelations = new WeakMap();\n if (!this.db) {\n return;\n }\n\n try {\n this.db.close();\n\n if (this.config.logger?.info) {\n this.config.logger.info(\"SQLite connection closed\");\n }\n } finally {\n this.db = null;\n this.connected = false;\n }\n }\n\n /**\n * Check if connected to the database.\n */\n isConnected(): boolean {\n return this.connected && this.db !== null;\n }\n\n /**\n * Get connection pool statistics.\n *\n * @remarks\n * SQLite doesn't use connection pooling, so this returns null.\n * The database is single-file with a single connection.\n */\n getPoolStats(): PoolStats | null {\n // SQLite doesn't have connection pooling\n return null;\n }\n\n /**\n * Execute a raw SQL query.\n *\n * @param sql - SQL query string with $1, $2 placeholders (converted to ? for SQLite)\n * @param params - Query parameters\n * @returns Query results\n *\n * @throws {DatabaseError} If query execution fails\n */\n // better-sqlite3 is synchronous; method is async to satisfy the DatabaseAdapter contract.\n // eslint-disable-next-line @typescript-eslint/require-await\n async executeQuery<T = unknown>(\n sql: string,\n params: SqlParam[] = []\n ): Promise<T[]> {\n const db = this.ensureDb();\n const startTime = Date.now();\n\n try {\n // Convert $1, $2 placeholders to ? for better-sqlite3\n const convertedSql = this.convertPlaceholders(sql);\n\n // Determine if this is a SELECT query or a modifying query\n const trimmedSql = convertedSql.trim().toUpperCase();\n\n // Check for PRAGMA query statements (e.g., \"PRAGMA foreign_keys\").\n // Setting PRAGMAs (e.g., \"PRAGMA foreign_keys = OFF\") don't return data.\n const isPragmaQuery =\n trimmedSql.startsWith(\"PRAGMA\") && !trimmedSql.includes(\"=\");\n\n const isSelect =\n trimmedSql.startsWith(\"SELECT\") ||\n isPragmaQuery ||\n trimmedSql.startsWith(\"WITH\");\n const hasReturning = trimmedSql.includes(\"RETURNING\");\n\n let result: T[];\n\n const sanitizedParams = params.map(sanitizeSqliteValue);\n\n if (isSelect || hasReturning) {\n // Use .all() for SELECT queries or queries with RETURNING\n const stmt = db.prepare(convertedSql);\n result = stmt.all(...sanitizedParams) as T[];\n } else {\n // Use .run() for INSERT/UPDATE/DELETE/PRAGMA settings without RETURNING\n const stmt = db.prepare(convertedSql);\n const runResult = stmt.run(...sanitizedParams);\n // Return info about the operation\n result = [\n {\n changes: runResult.changes,\n lastInsertRowid: runResult.lastInsertRowid,\n } as unknown as T,\n ];\n }\n\n // Log query if logger configured\n if (this.config.logger?.query) {\n const durationMs = Date.now() - startTime;\n this.config.logger.query(convertedSql, params, durationMs);\n }\n\n return result;\n } catch (error) {\n throw this.classifyError(error, sql);\n }\n }\n\n /**\n * Execute work within a transaction.\n *\n * @param work - Function containing transactional operations\n * @param options - Transaction options (isolation level not fully supported in SQLite)\n * @returns Result of the work function\n *\n * @remarks\n * Uses better-sqlite3's native transaction handling which:\n * - Automatically commits on success\n * - Automatically rolls back on error\n * - Converts nested transactions to savepoints\n *\n * Note: SQLite uses DEFERRED, IMMEDIATE, or EXCLUSIVE transaction modes\n * rather than isolation levels. This adapter uses IMMEDIATE by default.\n */\n async transaction<T>(\n work: (tx: TransactionContext) => Promise<T>,\n _options?: TransactionOptions\n ): Promise<T> {\n // Why: serialize concurrent transaction() invocations to dodge\n // better-sqlite3's \"cannot start a transaction within a transaction\"\n // error when two awaits overlap on the same connection. See the\n // `transactionQueue` field comment for the full rationale. The queue\n // chains every call onto a tail promise so only one BEGIN → COMMIT\n // section runs at a time; the next call's BEGIN waits for the\n // previous COMMIT/ROLLBACK to finish.\n //\n // Failure isolation: the queue's tail promise must not reject (a\n // rejection would poison every subsequent transaction with the same\n // rejected value). We attach a no-op `.catch` so the chain stays\n // resolved while the actual error propagates back to the original\n // caller through the inner promise.\n const run = async (): Promise<T> => this.runTransaction(work);\n const next = this.transactionQueue.then(run, run);\n this.transactionQueue = next.catch(() => undefined);\n return next;\n }\n\n /**\n * Inner transaction body. Kept private so callers always go through\n * the serialized `transaction()` queue above and the BEGIN/COMMIT\n * pair is never invoked outside of it.\n */\n private async runTransaction<T>(\n work: (tx: TransactionContext) => Promise<T>\n ): Promise<T> {\n const db = this.ensureDb();\n const startTime = Date.now();\n\n try {\n // Create transaction context\n const ctx = this.createTransactionContext(db);\n\n // Since better-sqlite3's db.transaction() doesn't support async functions,\n // we manually manage the transaction with BEGIN/COMMIT/ROLLBACK\n db.exec(\"BEGIN IMMEDIATE\");\n\n try {\n const result = await work(ctx);\n db.exec(\"COMMIT\");\n\n // Log success\n if (this.config.logger?.debug) {\n const durationMs = Date.now() - startTime;\n this.config.logger.debug(\"Transaction committed\", {\n durationMs,\n });\n }\n\n return result;\n } catch (error) {\n // Rollback on error\n try {\n db.exec(\"ROLLBACK\");\n } catch {\n // Ignore rollback errors - transaction may already be aborted\n }\n throw error;\n }\n } catch (error) {\n // Work inside a transaction may throw to roll the write back — a refused\n // value, a denied permission — and that is the application's verdict, not\n // the driver's failure. Classifying it would replace its code and payload\n // with a generic database error, so a caller that asked for a refusal is\n // handed an unexplained failure and the per-field detail never arrives.\n if (isApplicationError(error)) throw error;\n throw this.classifyError(error);\n }\n }\n\n /**\n * Get SQLite database capabilities.\n *\n * @remarks\n * SQLite capabilities:\n * - JSON support (not JSONB)\n * - No arrays\n * - No native ILIKE\n * - RETURNING clause (3.35+)\n * - Savepoints supported\n * - ON CONFLICT supported\n */\n getCapabilities(): DatabaseCapabilities {\n return {\n dialect: \"sqlite\",\n supportsJsonb: false, // SQLite uses JSON, not JSONB\n supportsJson: true,\n supportsArrays: false, // SQLite doesn't support array types\n supportsGeneratedColumns: true, // SQLite 3.31+\n supportsFts: true, // SQLite FTS5\n supportsIlike: false, // No native ILIKE, use LOWER() LIKE\n supportsReturning: true, // SQLite 3.35+\n supportsSavepoints: true, // SQLite supports savepoints\n supportsOnConflict: true, // ON CONFLICT clause\n maxParamsPerQuery: 999, // SQLite SQLITE_MAX_VARIABLE_NUMBER default\n maxIdentifierLength: 128, // SQLite doesn't have a strict limit\n };\n }\n\n /**\n * Override insertMany for bulk insert optimization.\n *\n * @remarks\n * Uses a single multi-row INSERT statement for better performance.\n */\n override async insertMany<T = unknown>(\n table: string,\n data: Record<string, unknown>[],\n options?: InsertOptions\n ): Promise<T[]> {\n if (data.length === 0) {\n return [];\n }\n\n const db = this.ensureDb();\n\n // For single record, use parent implementation\n if (data.length === 1) {\n const result = await this.insert<T>(table, data[0], options);\n return [result];\n }\n\n // Build multi-row INSERT\n const columns = Object.keys(data[0]);\n const params: SqlParam[] = [];\n const valuesClauses: string[] = [];\n\n for (const record of data) {\n const placeholders: string[] = [];\n for (const col of columns) {\n params.push(sanitizeSqliteValue(record[col]) as SqlParam);\n placeholders.push(\"?\");\n }\n valuesClauses.push(`(${placeholders.join(\", \")})`);\n }\n\n const columnList = columns\n .map(col => this.escapeIdentifier(col))\n .join(\", \");\n let sql = `INSERT INTO ${this.escapeIdentifier(table)} (${columnList}) VALUES ${valuesClauses.join(\", \")}`;\n\n // Add RETURNING clause\n if (options?.returning) {\n const returning =\n options.returning === \"*\"\n ? \"*\"\n : options.returning.map(col => this.escapeIdentifier(col)).join(\", \");\n sql += ` RETURNING ${returning}`;\n } else {\n sql += \" RETURNING *\";\n }\n\n try {\n const stmt = db.prepare(sql);\n const rows = stmt.all(...(params as unknown[])) as T[];\n // SQLite stores a timestamp as an integer and hands it back as one. The\n // Drizzle read paths decode it through the column definition, so without\n // this a bulk insert answers with numbers where a read answers `Date`.\n const tableObj = this.getTableObject(table);\n return rows.map(r => this.mapRowFromRawSql(tableObj, r));\n } catch (error) {\n throw this.handleQueryError(error, \"insertMany\", table);\n }\n }\n\n // ============================================================\n // Protected Helper Methods\n // ============================================================\n\n /**\n * Ensures database is connected and returns it.\n *\n * @throws {DatabaseError} If not connected\n */\n private ensureDb(): Database.Database {\n if (!this.db) {\n throw createDatabaseError({\n kind: \"connection\",\n message: \"SqliteAdapter is not connected. Call connect() first.\",\n });\n }\n return this.db;\n }\n\n /**\n * Return the typed Drizzle instance for SQLite.\n * Guarded for server-only usage and requires an active connection.\n *\n * @param schema - Optional schema for relational queries (db.query.*)\n * @returns Drizzle ORM instance wrapping the better-sqlite3 connection\n * @throws {Error} If called in browser or not connected\n */\n getDrizzle<T = BetterSQLite3Database<AnyRelations>>(\n relations?: AnyRelations\n ): T {\n if (typeof window !== \"undefined\") {\n throw new Error(\"getDrizzle() is server-only\");\n }\n const db = this.ensureDb();\n // drizzle v1 removed the positional (client, config) form — positional\n // calls silently open a NEW :memory: database. Object form only.\n if (!relations) {\n this.drizzleBare ??= drizzle({ client: db });\n return this.drizzleBare as T;\n }\n let cached = this.drizzleByRelations.get(relations);\n if (!cached) {\n cached = drizzle({ client: db, relations });\n this.drizzleByRelations.set(relations, cached);\n }\n return cached as T;\n }\n\n /**\n * Convert $1, $2 placeholders to ? for better-sqlite3.\n *\n * @param sql - SQL with PostgreSQL-style placeholders\n * @returns SQL with ? placeholders\n */\n private convertPlaceholders(sql: string): string {\n // Replace $1, $2, etc. with ?\n return sql.replace(/\\$\\d+/g, \"?\");\n }\n\n /**\n * Creates a TransactionContext for the given database connection.\n */\n /** A table-level `primaryKey({ columns })`, read through the SQLite table config. */\n protected override compositePrimaryKey(\n tableObj: Record<string, unknown>\n ): object[] {\n return getTableConfig(\n tableObj as unknown as SQLiteTable\n ).primaryKeys.flatMap(key => key.columns);\n }\n\n private createTransactionContext(db: Database.Database): TransactionContext {\n // better-sqlite3 is synchronous; the methods below are async to satisfy\n // the TransactionContext contract shared with truly-async dialect adapters.\n // Bind a Drizzle instance to the transaction's connection so the delegated\n // CRUD methods run inside it. better-sqlite3 is single-connection, so this\n // is the same connection getDrizzle() would use, but binding explicitly\n // keeps the three adapters consistent and correct if that ever changes.\n // Built lazily and memoized: transactions that use only raw execute/insert\n // never construct it.\n const buildTxExecutor = () => drizzle({ client: db });\n let txExecutor: ReturnType<typeof buildTxExecutor> | undefined;\n const txDb = () => (txExecutor ??= buildTxExecutor());\n return {\n // SQLite has no row-level locking and needs none here: `withTransaction`\n // opens SQLite transactions with BEGIN IMMEDIATE, which takes the write\n // lock up front and serializes writers for the whole transaction.\n lockRow: (): Promise<void> => Promise.resolve(),\n\n // `run`, not `all`: better-sqlite3 throws on a statement that returns no\n // rows, which is every statement this method exists to carry. The Drizzle\n // instance is the transaction-bound one, so the statement runs inside this\n // transaction.\n //\n // better-sqlite3 is synchronous, so this resolves an already-settled\n // promise rather than being declared `async` over a body that never\n // awaits.\n runStatement: (statement: SQL): Promise<void> => {\n txDb().run(statement);\n return Promise.resolve();\n },\n\n // `all`, not `run`: this is the reading half, and better-sqlite3 returns\n // rows only from `all`. Synchronous, so the promise is already settled.\n queryStatement: <T = Record<string, unknown>>(\n statement: SQL\n ): Promise<T[]> => Promise.resolve(txDb().all(statement)),\n\n // eslint-disable-next-line @typescript-eslint/require-await\n execute: async <T = unknown>(\n sql: string,\n params: SqlParam[] = []\n ): Promise<T[]> => {\n const convertedSql = this.convertPlaceholders(sql);\n const trimmedSql = convertedSql.trim().toUpperCase();\n const isSelect =\n trimmedSql.startsWith(\"SELECT\") || trimmedSql.includes(\"RETURNING\");\n const sanitizedParams = params.map(sanitizeSqliteValue);\n\n if (isSelect) {\n const stmt = db.prepare(convertedSql);\n return stmt.all(...sanitizedParams) as T[];\n } else {\n const stmt = db.prepare(convertedSql);\n const result = stmt.run(...sanitizedParams);\n return [\n {\n changes: result.changes,\n lastInsertRowid: result.lastInsertRowid,\n } as unknown as T,\n ];\n }\n },\n\n // Keys only, unlike the PostgreSQL and MySQL raw paths, which also encode\n // their date values. `sanitizeSqliteValue` below binds a `Date` as unix\n // seconds, and an instant carries no zone -- so what SQLite stores does\n // not depend on the server's timezone and there is nothing to correct.\n // eslint-disable-next-line @typescript-eslint/require-await\n insert: async <T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options?: InsertOptions\n ): Promise<T> => {\n const mapped = this.mapKeysToSqlColumns(\n this.getTableObject(table),\n data\n );\n const columns = Object.keys(mapped);\n const values = Object.values(mapped).map(sanitizeSqliteValue);\n const placeholders = values.map(() => \"?\").join(\", \");\n\n let sql = `INSERT INTO ${this.escapeIdentifier(table)} (${columns.map(c => this.escapeIdentifier(c)).join(\", \")}) VALUES (${placeholders})`;\n\n const ret = options?.returning;\n const returningEmpty = Array.isArray(ret) && ret.length === 0;\n if (!returningEmpty) {\n const returning =\n !ret || ret === \"*\"\n ? \"*\"\n : this.mapColumnNamesToSql(this.getTableObject(table), ret)\n .map(col => this.escapeIdentifier(col))\n .join(\", \");\n sql += ` RETURNING ${returning}`;\n }\n\n const stmt = db.prepare(sql);\n if (returningEmpty) {\n // No RETURNING clause: better-sqlite3's .all() rejects a statement\n // that returns no columns, so run it and return nothing.\n stmt.run(...values);\n return undefined as T;\n }\n const rows = stmt.all(...values) as T[];\n // Return JS property-named keys AND Drizzle-decoded date values, so a\n // write inside a transaction answers with the same representation a\n // read of the same row gives.\n return this.mapRowFromRawSql(this.getTableObject(table), rows[0]);\n },\n\n // eslint-disable-next-line @typescript-eslint/require-await\n insertMany: async <T = unknown>(\n table: string,\n data: Record<string, unknown>[],\n options?: InsertOptions\n ): Promise<T[]> => {\n if (data.length === 0) return [];\n\n const tableObj = this.getTableObject(table);\n const mappedRecords = data.map(r =>\n this.mapKeysToSqlColumns(tableObj, r)\n );\n const columns = Object.keys(mappedRecords[0]);\n const allValues: unknown[] = [];\n const valuesClauses: string[] = [];\n\n for (const record of mappedRecords) {\n const placeholders: string[] = [];\n for (const col of columns) {\n allValues.push(sanitizeSqliteValue(record[col]));\n placeholders.push(\"?\");\n }\n valuesClauses.push(`(${placeholders.join(\", \")})`);\n }\n\n let sql = `INSERT INTO ${this.escapeIdentifier(table)} (${columns.map(c => this.escapeIdentifier(c)).join(\", \")}) VALUES ${valuesClauses.join(\", \")}`;\n\n const ret = options?.returning;\n const returningEmpty = Array.isArray(ret) && ret.length === 0;\n if (!returningEmpty) {\n const returning =\n !ret || ret === \"*\"\n ? \"*\"\n : this.mapColumnNamesToSql(this.getTableObject(table), ret)\n .map(col => this.escapeIdentifier(col))\n .join(\", \");\n sql += ` RETURNING ${returning}`;\n }\n\n const stmt = db.prepare(sql);\n if (returningEmpty) {\n stmt.run(...allValues);\n return [];\n }\n return (stmt.all(...allValues) as T[]).map(r =>\n this.mapRowFromRawSql(tableObj, r)\n );\n },\n\n // Adapter-built, as `insert` above is; `transactionUpdate` says why.\n // A column the model does not declare binds as every other value on\n // this path does, through `sanitizeSqliteValue`. `all` only when the\n // statement carries RETURNING: better-sqlite3 throws on `all` for a\n // statement that returns no rows, and on `run` for one that does.\n update: this.transactionUpdate(\n txDb,\n (statement, returnsRows) =>\n returnsRows\n ? txDb().all<Record<string, unknown>>(statement)\n : (txDb().run(statement), undefined),\n sanitizeSqliteValue\n ),\n\n ...this.createTransactionForwarders(txDb),\n\n // eslint-disable-next-line @typescript-eslint/require-await\n savepoint: async (name: string): Promise<void> => {\n db.exec(`SAVEPOINT ${this.escapeIdentifier(name)}`);\n },\n\n // eslint-disable-next-line @typescript-eslint/require-await\n rollbackToSavepoint: async (name: string): Promise<void> => {\n db.exec(`ROLLBACK TO SAVEPOINT ${this.escapeIdentifier(name)}`);\n },\n\n // eslint-disable-next-line @typescript-eslint/require-await\n releaseSavepoint: async (name: string): Promise<void> => {\n db.exec(`RELEASE SAVEPOINT ${this.escapeIdentifier(name)}`);\n },\n };\n }\n\n /**\n * Classifies a SQLite error into a DatabaseError.\n *\n * @param error - Original error from better-sqlite3\n * @param sql - SQL statement that caused the error (optional)\n * @returns DatabaseError with proper classification\n */\n // fallow-ignore-next-line complexity\n protected override classifyError(\n error: unknown,\n sql?: string\n ): DatabaseError {\n // Why short-circuit on existing DatabaseError: F17's\n // UnsupportedDialectVersionError is already a typed DatabaseError with\n // kind: \"unsupported_version\" plus detectedVersion/requiredVersion\n // fields. Re-wrapping it here would erase those fields.\n if (isDatabaseError(error)) return error;\n\n // Classify from the DRIVER's error, which is not necessarily the one handed\n // in. A query failure arrives wrapped: DrizzleQueryError carries the SQL\n // statement as its message and no code, and better-sqlite3's own error —\n // the only object that knows what actually went wrong — sits below it in\n // the `cause` chain. Classifying the wrapper means classifying the QUERY\n // TEXT, which reported a unique violation on a table with a `locked_by`\n // column as a \"timeout\", because the statement contains the word LOCKED.\n const sqliteError = findDriverError(error);\n\n // Determine error kind from SQLite error code\n let kind: DatabaseErrorKind = \"unknown\";\n\n if (sqliteError.code) {\n kind = SQLITE_ERROR_CODES[sqliteError.code] || \"unknown\";\n } else if (sqliteError.message) {\n // Try to extract error type from message. Safe to match loosely now:\n // `sqliteError` is the driver's error, so its message is the driver's\n // description of the failure and never a SQL statement.\n const msg = sqliteError.message.toUpperCase();\n if (msg.includes(\"UNIQUE CONSTRAINT\")) {\n kind = \"unique_violation\";\n } else if (msg.includes(\"FOREIGN KEY CONSTRAINT\")) {\n kind = \"foreign_key_violation\";\n } else if (msg.includes(\"NOT NULL CONSTRAINT\")) {\n kind = \"not_null_violation\";\n } else if (msg.includes(\"CHECK CONSTRAINT\")) {\n kind = \"check_violation\";\n } else if (msg.includes(\"BUSY\") || msg.includes(\"LOCKED\")) {\n kind = \"timeout\";\n } else if (\n msg.includes(\"SQLITE_CANTOPEN\") ||\n msg.includes(\"UNABLE TO OPEN\")\n ) {\n kind = \"connection\";\n }\n }\n\n // Build error message from the driver's description, for the same reason\n // the classification uses it: the wrapper's message is the SQL statement.\n let message = sqliteError.message ?? String(error);\n if (sql && kind === \"query\") {\n message = `Query failed: ${message}`;\n }\n\n return createDatabaseError({\n kind,\n message,\n code: sqliteError.code,\n cause: error instanceof Error ? error : undefined,\n });\n }\n}\n\n/** The fields this classifier reads off an error, at any depth in the chain. */\ninterface DriverErrorShape {\n code?: string;\n message?: string;\n name?: string;\n cause?: unknown;\n}\n\n/**\n * The deepest error in the `cause` chain that carries a SQLite error code, or\n * the outermost error when none does.\n *\n * better-sqlite3 sets `code` (`SQLITE_CONSTRAINT_UNIQUE`, `SQLITE_BUSY`, ...);\n * the wrappers around it do not. Walking to the code is therefore walking to\n * the only object that knows what failed. The walk is depth-bounded rather than\n * unbounded because an error chain can be made cyclic, and a classifier that\n * can hang is worse than one that occasionally gives up.\n *\n * Falls back to the outermost error so a driver error that genuinely carries no\n * code — one constructed from a message alone — still classifies exactly as it\n * did before.\n */\nfunction findDriverError(error: unknown): DriverErrorShape {\n let cursor = error as DriverErrorShape | null | undefined;\n for (let depth = 0; depth < 10 && cursor != null; depth++) {\n if (typeof cursor.code === \"string\" && cursor.code.length > 0)\n return cursor;\n cursor = cursor.cause as DriverErrorShape | null | undefined;\n }\n return error ?? {};\n}\n\n/**\n * Create a SQLite database adapter.\n *\n * @param config - SQLite adapter configuration\n * @returns A new SqliteAdapter instance\n *\n * @example\n * ```typescript\n * // Simple usage with file path\n * const adapter = createSqliteAdapter({\n * url: 'file:./data.db',\n * });\n *\n * // In-memory database\n * const memAdapter = createSqliteAdapter({\n * memory: true,\n * });\n *\n * // Full configuration\n * const adapter = createSqliteAdapter({\n * url: 'file:./data.db',\n * wal: true,\n * foreignKeys: true,\n * busyTimeout: 5000,\n * logger: {\n * query: (sql, params, duration) => console.log(`Query: ${sql}`),\n * },\n * });\n *\n * await adapter.connect();\n * ```\n */\nexport function createSqliteAdapter(\n config: SqliteAdapterConfig\n): SqliteAdapter {\n return new SqliteAdapter(config);\n}\n\n/**\n * Type guard to check if a value is a SqliteAdapter.\n *\n * @param value - Value to check\n * @returns True if value is a SqliteAdapter instance\n *\n * @example\n * ```typescript\n * if (isSqliteAdapter(adapter)) {\n * // TypeScript knows adapter is SqliteAdapter\n * console.log('Using SQLite');\n * }\n * ```\n */\nexport function isSqliteAdapter(value: unknown): value is SqliteAdapter {\n return value instanceof SqliteAdapter;\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["DrizzleAdapter","AsyncLocalStorage","checkDialectVersion","AsyncResource","isApplicationError","createDatabaseError","drizzle","getTableConfig","isDatabaseError"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @nextlyhq/adapter-sqlite\n *\n * SQLite database adapter for Nextly.\n * Extends DrizzleAdapter from @nextlyhq/adapter-drizzle to provide SQLite-specific functionality.\n *\n * @remarks\n * This adapter uses the better-sqlite3 package for database connectivity and provides:\n * - Synchronous API wrapped for async interface compatibility\n * - Transactions the adapter runs itself (BEGIN IMMEDIATE / COMMIT / ROLLBACK), with nested calls run as savepoints\n * - CRUD operations with RETURNING clause support (SQLite 3.35+)\n * - WAL mode for better concurrent read performance\n * - In-memory and file-based database support\n *\n * @example\n * ```typescript\n * import { createSqliteAdapter } from '@nextlyhq/adapter-sqlite';\n *\n * const adapter = createSqliteAdapter({\n * url: 'file:./data/app.db',\n * });\n *\n * await adapter.connect();\n *\n * // Query data\n * const users = await adapter.select('users', {\n * where: { and: [{ column: 'status', op: '=', value: 'active' }] },\n * limit: 10,\n * });\n *\n * await adapter.disconnect();\n * ```\n *\n * @packageDocumentation\n */\n\nimport { AsyncLocalStorage, AsyncResource } from \"node:async_hooks\";\n\nimport { DrizzleAdapter } from \"@nextlyhq/adapter-drizzle\";\n// F17: connect-time DB version check shared across all adapters.\nimport {\n createDatabaseError,\n isDatabaseError,\n type SqliteAdapterConfig,\n type DatabaseCapabilities,\n type PoolStats,\n type TransactionContext,\n type TransactionOptions,\n type SqlParam,\n type WhereClause,\n type WhereCondition,\n type WhereOperator,\n type SelectOptions,\n type InsertOptions,\n type UpdateOptions,\n type DeleteOptions,\n type UpsertOptions,\n type OrderBySpec,\n type JoinSpec,\n type DatabaseError,\n type DatabaseErrorKind,\n type BaseAdapterConfig,\n type AdapterLogger,\n isApplicationError,\n} from \"@nextlyhq/adapter-drizzle/types\";\nimport { checkDialectVersion } from \"@nextlyhq/adapter-drizzle/version-check\";\nimport type Database from \"better-sqlite3\";\nimport type { AnyRelations, SQL } from \"drizzle-orm\";\nimport {\n drizzle,\n type BetterSQLite3Database,\n} from \"drizzle-orm/better-sqlite3\";\nimport { getTableConfig, type SQLiteTable } from \"drizzle-orm/sqlite-core\";\n\n// Re-export types for convenience\nexport type {\n SqliteAdapterConfig,\n DatabaseCapabilities,\n PoolStats,\n TransactionContext,\n TransactionOptions,\n SqlParam,\n WhereClause,\n WhereCondition,\n WhereOperator,\n SelectOptions,\n InsertOptions,\n UpdateOptions,\n DeleteOptions,\n UpsertOptions,\n OrderBySpec,\n JoinSpec,\n DatabaseError,\n DatabaseErrorKind,\n BaseAdapterConfig,\n AdapterLogger,\n};\n\n/**\n * Package version\n */\nexport const VERSION = \"0.1.0\";\n\n/**\n * SQLite error codes mapping to DatabaseErrorKind.\n *\n * @see https://sqlite.org/rescode.html\n */\nconst SQLITE_ERROR_CODES: Record<string, DatabaseErrorKind> = {\n // Constraint violations\n SQLITE_CONSTRAINT: \"constraint\",\n SQLITE_CONSTRAINT_UNIQUE: \"unique_violation\",\n SQLITE_CONSTRAINT_PRIMARYKEY: \"unique_violation\",\n SQLITE_CONSTRAINT_FOREIGNKEY: \"foreign_key_violation\",\n SQLITE_CONSTRAINT_NOTNULL: \"not_null_violation\",\n SQLITE_CONSTRAINT_CHECK: \"check_violation\",\n\n // Busy/locked errors\n SQLITE_BUSY: \"timeout\",\n SQLITE_LOCKED: \"timeout\",\n\n // Connection errors\n SQLITE_CANTOPEN: \"connection\",\n SQLITE_NOTADB: \"connection\",\n SQLITE_CORRUPT: \"connection\",\n\n // Query errors\n SQLITE_ERROR: \"query\",\n SQLITE_MISUSE: \"query\",\n SQLITE_RANGE: \"query\",\n};\n\n/**\n * Default configuration values.\n */\nconst DEFAULT_CONFIG = {\n busyTimeout: 5000,\n wal: true,\n foreignKeys: true,\n};\n\n/**\n * Converts a JavaScript value to a type that better-sqlite3 can bind.\n * better-sqlite3 only accepts: number, string, bigint, Buffer, null.\n *\n * These conversions have to match what the schema declares, because the rows\n * they write are read back through it. Every column here that takes a `Date`\n * is `integer({ mode: \"timestamp\" })` — the system columns and user date\n * fields in `runtime-schema-generator.ts`, and the core tables, whose date\n * columns are all INTEGER. So a date is bound as unix seconds, which is what\n * that mode reads.\n */\nfunction sanitizeSqliteValue(v: unknown): unknown {\n if (v === undefined) return null;\n if (typeof v === \"boolean\") return v ? 1 : 0;\n // Binary is bound as binary: better-sqlite3 takes a Buffer or a typed\n // array for a BLOB as it is, and the object branch below would spell it\n // out as JSON text instead.\n if (Buffer.isBuffer(v) || ArrayBuffer.isView(v)) return v;\n // Seconds, not an ISO string. SQLite stores whatever it is given regardless\n // of the declared type, so a string lands in the column without complaint\n // and only fails on the way back out, where the timestamp decoder reads it\n // as a number and yields an Invalid Date.\n if (v instanceof Date) return Math.floor(v.getTime() / 1000);\n if (v !== null && typeof v === \"object\") return JSON.stringify(v);\n return v;\n}\n\n/**\n * SQLite database adapter for Nextly.\n *\n * Extends the base DrizzleAdapter to provide SQLite-specific functionality\n * using the better-sqlite3 package.\n *\n * @remarks\n * SQLite has some differences from PostgreSQL:\n * - Synchronous API (wrapped for async compatibility)\n * - No connection pooling (single file/connection)\n * - RETURNING clause supported (SQLite 3.35+)\n * - Savepoints supported via nested transactions\n * - No native ILIKE (uses LOWER() LIKE workaround)\n * - JSON support (not JSONB)\n * - No array types\n *\n * @example\n * ```typescript\n * const adapter = new SqliteAdapter({\n * url: 'file:./data.db',\n * });\n *\n * await adapter.connect();\n * ```\n */\nexport class SqliteAdapter extends DrizzleAdapter {\n // getDrizzle memoization: drizzle v1's constructor builds a relational\n // query builder per table in the relations config (~40 tables), and the\n // service layer resolves an instance on every db access — construct once\n // per relations object (identity-stable: the schema registry caches it\n // and hands out a NEW object on invalidation, which naturally misses\n // this cache and produces a fresh instance).\n private drizzleByRelations = new WeakMap<AnyRelations, unknown>();\n private drizzleBare: unknown;\n\n /**\n * The database dialect - always 'sqlite' for this adapter.\n */\n readonly dialect = \"sqlite\" as const;\n\n /**\n * Adapter configuration.\n */\n protected readonly config: SqliteAdapterConfig;\n\n /**\n * better-sqlite3 Database instance.\n */\n private db: Database.Database | null = null;\n\n /**\n * Connection state flag.\n */\n private connected = false;\n\n /**\n * Serialization queue for concurrent `transaction()` calls.\n *\n * better-sqlite3 is synchronous, single-connection, and rejects nested\n * `BEGIN` with \"cannot start a transaction within a transaction\".\n * When two `await adapter.transaction(...)` calls overlap (e.g. a bulk\n * mutation calling `Promise.allSettled` with N per-row updates), the\n * second one tries to BEGIN while the first is still open and the\n * driver throws.\n *\n * Postgres/MySQL avoid this by allocating a fresh client/connection\n * per transaction from a pool — there is no equivalent for\n * better-sqlite3, so we serialize at the JS layer instead. Every\n * `transaction()` invocation chains onto this promise; only one\n * BEGIN→COMMIT/ROLLBACK section runs at any moment, preserving\n * write-isolation semantics that callers expect from a transactional\n * adapter.\n *\n * Performance impact is the natural floor: SQLite already serializes\n * writers at the file-lock level, so the queue removes failed-call\n * surface area without changing the achievable concurrency.\n */\n private transactionQueue: Promise<unknown> = Promise.resolve();\n\n /**\n * The transaction the current async chain is running inside, if any.\n *\n * A `transaction()` call made from INSIDE a transaction's work — a store\n * writing on behalf of the caller, a plugin's write inside its own\n * `ctx.db.transaction` — used to queue behind the very transaction that\n * was waiting for it, and neither ever settled: that hung every later\n * transaction on the instance too. Such a call now runs as a SAVEPOINT of\n * the active transaction instead, so it commits or rolls back with it and\n * its own failure undoes only its own part.\n */\n private readonly transactionScope = new AsyncLocalStorage<TransactionScope>();\n\n /**\n * Creates a new SQLite adapter instance.\n *\n * @param config - Adapter configuration\n */\n constructor(config: SqliteAdapterConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Connect to the SQLite database.\n *\n * @remarks\n * This method initializes the database connection. For SQLite, this\n * opens the database file or creates an in-memory database.\n * Also configures WAL mode and foreign keys based on config.\n *\n * @throws {DatabaseError} If connection fails\n */\n async connect(): Promise<void> {\n if (this.connected && this.db) {\n return;\n }\n\n try {\n // Dynamic import of better-sqlite3 to avoid bundling issues\n const BetterSqlite3 = await import(\"better-sqlite3\");\n const Database = BetterSqlite3.default;\n\n // Determine database path\n let dbPath: string;\n if (this.config.memory) {\n dbPath = \":memory:\";\n } else if (this.config.url) {\n // Strip file: prefix if present\n dbPath = this.config.url.replace(/^file:/, \"\");\n } else {\n dbPath = \":memory:\";\n }\n\n // Ensure the parent directory exists for file-backed databases.\n // better-sqlite3 fails with a confusing \"Cannot open database\n // because the directory does not exist\" error if it doesn't, and\n // a fresh clone with `DATABASE_URL=file:./data/app.db` reliably\n // hits this on first run. Create the dir lazily so DATABASE_URL\n // can point anywhere without a separate setup step.\n if (dbPath !== \":memory:\" && !this.config.readonly) {\n const fs = await import(\"node:fs\");\n const path = await import(\"node:path\");\n const dir = path.dirname(path.resolve(dbPath));\n await fs.promises.mkdir(dir, { recursive: true });\n }\n\n // Create database instance\n this.db = new Database(dbPath, {\n readonly: this.config.readonly ?? false,\n timeout: this.config.busyTimeout ?? DEFAULT_CONFIG.busyTimeout,\n });\n\n // Configure WAL mode for better concurrency (unless in-memory or readonly)\n if (\n (this.config.wal ?? DEFAULT_CONFIG.wal) &&\n dbPath !== \":memory:\" &&\n !this.config.readonly\n ) {\n this.db.pragma(\"journal_mode = WAL\");\n }\n\n // Enable foreign keys\n if (this.config.foreignKeys ?? DEFAULT_CONFIG.foreignKeys) {\n this.db.pragma(\"foreign_keys = ON\");\n }\n\n // F17: check SQLite version. Hard-fails on SQLite <3.38. SQLite has\n // no recognized cloud variants we warn on, so onWarning is omitted.\n // Note: better-sqlite3's bundled SQLite is set by the package\n // version; users on this package's pinned better-sqlite3 (3.45+)\n // will always pass.\n await checkDialectVersion(this.db, \"sqlite\");\n\n this.connected = true;\n\n if (this.config.logger?.info) {\n this.config.logger.info(\"SQLite connection established\", {\n url: dbPath === \":memory:\" ? \"in-memory\" : dbPath,\n wal: this.config.wal ?? DEFAULT_CONFIG.wal,\n foreignKeys: this.config.foreignKeys ?? DEFAULT_CONFIG.foreignKeys,\n });\n }\n } catch (error) {\n // Clean up on failure\n if (this.db) {\n try {\n this.db.close();\n } catch {\n // Ignore close errors during error handling\n }\n this.db = null;\n }\n throw this.classifyError(error);\n }\n }\n\n /**\n * Disconnect from the SQLite database.\n *\n * @remarks\n * This method closes the database connection and releases resources.\n */\n // better-sqlite3 is synchronous; method is async to satisfy the DatabaseAdapter contract.\n // eslint-disable-next-line @typescript-eslint/require-await\n async disconnect(): Promise<void> {\n // Drop memoized drizzle instances — they wrap the connection being\n // closed and must not survive a reconnect.\n this.drizzleBare = undefined;\n this.drizzleByRelations = new WeakMap();\n if (!this.db) {\n return;\n }\n\n try {\n this.db.close();\n\n if (this.config.logger?.info) {\n this.config.logger.info(\"SQLite connection closed\");\n }\n } finally {\n this.db = null;\n this.connected = false;\n }\n }\n\n /**\n * Check if connected to the database.\n */\n isConnected(): boolean {\n return this.connected && this.db !== null;\n }\n\n /**\n * Get connection pool statistics.\n *\n * @remarks\n * SQLite doesn't use connection pooling, so this returns null.\n * The database is single-file with a single connection.\n */\n getPoolStats(): PoolStats | null {\n // SQLite doesn't have connection pooling\n return null;\n }\n\n /**\n * Execute a raw SQL query.\n *\n * @param sql - SQL query string with $1, $2 placeholders (converted to ? for SQLite)\n * @param params - Query parameters\n * @returns Query results\n *\n * @throws {DatabaseError} If query execution fails\n */\n // better-sqlite3 is synchronous; method is async to satisfy the DatabaseAdapter contract.\n // eslint-disable-next-line @typescript-eslint/require-await\n async executeQuery<T = unknown>(\n sql: string,\n params: SqlParam[] = []\n ): Promise<T[]> {\n const db = this.ensureDb();\n const startTime = Date.now();\n\n try {\n // Convert $1, $2 placeholders to ? for better-sqlite3\n const convertedSql = this.convertPlaceholders(sql);\n\n // Determine if this is a SELECT query or a modifying query\n const trimmedSql = convertedSql.trim().toUpperCase();\n\n // Check for PRAGMA query statements (e.g., \"PRAGMA foreign_keys\").\n // Setting PRAGMAs (e.g., \"PRAGMA foreign_keys = OFF\") don't return data.\n const isPragmaQuery =\n trimmedSql.startsWith(\"PRAGMA\") && !trimmedSql.includes(\"=\");\n\n const isSelect =\n trimmedSql.startsWith(\"SELECT\") ||\n isPragmaQuery ||\n trimmedSql.startsWith(\"WITH\");\n const hasReturning = trimmedSql.includes(\"RETURNING\");\n\n let result: T[];\n\n const sanitizedParams = params.map(sanitizeSqliteValue);\n\n if (isSelect || hasReturning) {\n // Use .all() for SELECT queries or queries with RETURNING\n const stmt = db.prepare(convertedSql);\n result = stmt.all(...sanitizedParams) as T[];\n } else {\n // Use .run() for INSERT/UPDATE/DELETE/PRAGMA settings without RETURNING\n const stmt = db.prepare(convertedSql);\n const runResult = stmt.run(...sanitizedParams);\n // Return info about the operation\n result = [\n {\n changes: runResult.changes,\n lastInsertRowid: runResult.lastInsertRowid,\n } as unknown as T,\n ];\n }\n\n // Log query if logger configured\n if (this.config.logger?.query) {\n const durationMs = Date.now() - startTime;\n this.config.logger.query(convertedSql, params, durationMs);\n }\n\n return result;\n } catch (error) {\n throw this.classifyError(error, sql);\n }\n }\n\n /**\n * Execute work within a transaction.\n *\n * @param work - Function containing transactional operations\n * @param options - Transaction options (isolation level not fully supported in SQLite)\n * @returns Result of the work function\n *\n * @remarks\n * The adapter manages the transaction itself, because better-sqlite3's\n * `db.transaction()` does not take async work: it runs `BEGIN IMMEDIATE`,\n * then `COMMIT` when `work` resolves or `ROLLBACK` when it throws.\n * - Top-level calls run one at a time.\n * - A call made inside an open transaction's work joins it as a savepoint\n * (`SAVEPOINT` / `RELEASE` / `ROLLBACK TO`).\n * - Nested calls of one scope run one at a time.\n * - A call made later from a savepoint that has already released joins the\n * innermost scope still open.\n * - Nested work started and not awaited finishes before the enclosing scope\n * commits or rolls back.\n *\n * Note: SQLite uses DEFERRED, IMMEDIATE, or EXCLUSIVE transaction modes\n * rather than isolation levels. This adapter uses IMMEDIATE.\n */\n async transaction<T>(\n work: (tx: TransactionContext) => Promise<T>,\n _options?: TransactionOptions\n ): Promise<T> {\n // Why: serialize concurrent transaction() invocations to dodge\n // SQLite's \"cannot start a transaction within a transaction\"\n // error when two awaits overlap on the same connection. See the\n // `transactionQueue` field comment for the full rationale. The queue\n // chains every call onto a tail promise so only one BEGIN → COMMIT\n // section runs at a time; the next call's BEGIN waits for the\n // previous COMMIT/ROLLBACK to finish.\n //\n // Failure isolation: the queue's tail promise must not reject (a\n // rejection would poison every subsequent transaction with the same\n // rejected value). We attach a no-op `.catch` so the chain stays\n // resolved while the actual error propagates back to the original\n // caller through the inner promise.\n // A call made inside an open transaction's work joins it as a savepoint;\n // see `nestingScope` for which scope it joins.\n const own = this.transactionScope.getStore();\n const parent = this.nestingScope();\n // Called from a scope that has closed: what this writes is no longer that\n // scope's to undo.\n if (own && parent !== own) own.writesAfterClosing += 1;\n if (parent) {\n // Nested calls of one scope are serialized among themselves too: two\n // interleaved savepoints would release or roll back each other.\n return enqueueIn(parent, () => this.runSavepoint(work, parent));\n }\n const run = async (): Promise<Committed<T>> => this.runTransaction(work);\n const next = this.transactionQueue.then(run, run);\n this.transactionQueue = next.catch(() => undefined);\n const { result, effects } = await next;\n // After the queue has moved on rather than inside it: an effect that opens\n // a transaction of its own would otherwise wait behind the one running it.\n await this.runHeldEffects(effects);\n return result;\n }\n\n /**\n * Hold `effect` until the transaction enclosing this async context commits,\n * or run it now when none does.\n *\n * The effect belongs to the scope this async context runs in, even one\n * that has already released or rolled back: a service whose own\n * transaction nested as a savepoint registers from its caller's scope once\n * that savepoint has released, and the change is undoable for as long as\n * any scope around it is. The outermost transaction runs the effect once\n * its COMMIT succeeds, unless a scope between the effect's scope and the\n * outermost transaction rolled back, and drops every effect on ROLLBACK or\n * a failed COMMIT. A context whose outermost transaction has already\n * finished is outside any transaction, so its effect runs now, unless what\n * it announces was undone and it has run no transaction since.\n */\n override async afterCommit(\n effect: () => unknown,\n onDeferredFailure?: (error: unknown) => void\n ): Promise<void> {\n const scope = this.transactionScope.getStore();\n if (!scope) {\n await effect();\n return;\n }\n const root = outermost(scope);\n if (!root.finished) {\n root.held.push({\n effect: this.inRegisteringContext(effect),\n onDeferredFailure,\n scope,\n writesBefore: scope.writesAfterClosing,\n });\n return;\n }\n if (!undone(scope, scope.writesAfterClosing)) await effect();\n }\n\n /**\n * `effect`, bound to the async context it is registered from.\n *\n * A held effect runs after the outermost COMMIT, from the code that ran the\n * outermost transaction, so without this it sees that code's context rather\n * than its own: whatever its caller pinned around the write is gone. That\n * includes who is calling. A scope pinned for a scoped API key lost there\n * leaves a hook's nested call judged by the key's owner instead of the key,\n * and a person's frame lost there leaves the hook told of nobody.\n *\n * The adapter's own transaction scope is the one store it leaves: the\n * effect runs once that transaction has finished, outside it, as an effect\n * held to the outermost commit always has.\n */\n private inRegisteringContext(effect: () => unknown): () => unknown {\n return AsyncResource.bind(() => this.transactionScope.exit(effect));\n }\n\n /**\n * Run the effects a committed transaction held, in order. A failure is\n * reported, never thrown: the change is durable, and reporting the\n * transaction as failed would invite a retry of something already done.\n */\n private async runHeldEffects(effects: HeldEffect[]): Promise<void> {\n for (const { effect, onDeferredFailure } of effects) {\n try {\n await effect();\n } catch (error) {\n this.reportHeldEffectFailure(error, onDeferredFailure);\n }\n }\n }\n\n /** Hand a held effect's failure to its reporter, or to the adapter's log. */\n private reportHeldEffectFailure(\n error: unknown,\n onDeferredFailure: ((error: unknown) => void) | undefined\n ): void {\n try {\n if (onDeferredFailure) {\n onDeferredFailure(error);\n return;\n }\n } catch {\n // A reporter that throws is reported on below, like no reporter at all.\n }\n const failure = error instanceof Error ? error : new Error(String(error));\n if (this.config.logger?.error) {\n this.config.logger.error(failure, { phase: \"after-commit\" });\n } else {\n console.error(\"An effect held until commit failed:\", failure);\n }\n }\n\n /**\n * Whether a `transaction()` call made here would join an open transaction\n * as a savepoint. On SQLite it would: the connection is the only one, so a\n * transaction open on it encloses whatever the async chain that opened it\n * starts.\n */\n override inTransaction(): boolean {\n return this.nestingScope() !== undefined;\n }\n\n /**\n * Whether the calling async flow is inside a transaction that has not\n * finished, judged from the transaction this flow was started inside,\n * never from the connection: another request's open transaction answers\n * false here, where its own `transaction()` queues behind that one.\n *\n * A flow started inside a transaction, even inside a savepoint that has\n * since released, stays inside it until its outermost transaction has\n * committed or rolled back: until then whatever it writes on the one\n * connection lands in that transaction.\n */\n override transactionOpenInFlow(): boolean {\n const own = this.transactionScope.getStore();\n return own !== undefined && !outermost(own).finished;\n }\n\n /**\n * The scope a `transaction()` call made here nests in, or none when it\n * opens a transaction of its own.\n *\n * A call made later from inside a savepoint that has since released runs\n * inside the innermost scope open on the connection. Queued on an enclosing\n * scope, or on the instance, it would wait behind the scope running there,\n * which may be the one awaiting it. Savepoints on one connection form a\n * stack, so whatever opens now is inside that innermost scope anyway; when\n * none is open the call queues on the instance.\n *\n * The innermost open scope need not be related to the call. When it is a\n * sibling savepoint that later rolls back, the call's write rolls back with\n * it, although the call itself already resolved. Waiting for an unrelated\n * scope instead could wait on the very scope that awaits the call.\n */\n private nestingScope(): TransactionScope | undefined {\n const own = this.transactionScope.getStore();\n return own?.active ? own : own?.open.at(-1);\n }\n\n /**\n * Run `work` as a savepoint of the active transaction: released when it\n * resolves, rolled back to when it throws.\n */\n private async runSavepoint<T>(\n work: (tx: TransactionContext) => Promise<T>,\n parent: TransactionScope\n ): Promise<T> {\n const db = this.ensureDb();\n const depth = parent.depth + 1;\n const name = `nextly_sp_${depth}`;\n try {\n const ctx = this.createTransactionContext(db);\n db.exec(`SAVEPOINT ${name}`);\n // Open only once the savepoint exists, so a failed SAVEPOINT leaves no\n // scope behind for a later call to nest in.\n const scope = openScope(parent);\n try {\n const result = await this.transactionScope.run(scope, () => work(ctx));\n await settleNested(scope);\n db.exec(`RELEASE ${name}`);\n return result;\n } catch (error) {\n // Nested work this savepoint started and did not wait for is part of\n // it: let it finish first, so the rollback discards its writes rather\n // than leaving it to run afterwards on the enclosing transaction.\n await settleNested(scope);\n // Its change is undone, so nothing registered from it, before or\n // after this point, may announce it.\n scope.rolledBack = true;\n try {\n db.exec(`ROLLBACK TO ${name}`);\n db.exec(`RELEASE ${name}`);\n } catch {\n // The enclosing transaction may already have ended.\n }\n throw error;\n }\n } catch (error) {\n if (isApplicationError(error)) throw error;\n throw this.classifyError(error);\n }\n }\n\n /**\n * Inner transaction body. Kept private so callers always go through\n * the serialized `transaction()` queue above and the BEGIN/COMMIT\n * pair is never invoked outside of it.\n */\n private async runTransaction<T>(\n work: (tx: TransactionContext) => Promise<T>\n ): Promise<Committed<T>> {\n const db = this.ensureDb();\n const startTime = Date.now();\n\n try {\n // Create transaction context\n const ctx = this.createTransactionContext(db);\n\n // Since better-sqlite3's db.transaction() doesn't support async functions,\n // we manually manage the transaction with BEGIN/COMMIT/ROLLBACK\n db.exec(\"BEGIN IMMEDIATE\");\n\n // The scope nested `transaction()` calls from this work join.\n const scope = openScope();\n try {\n const result = await this.transactionScope.run(scope, () => work(ctx));\n // Anything the work started and did not wait for is part of this\n // transaction, so it finishes before the commit rather than after.\n await settleNested(scope);\n db.exec(\"COMMIT\");\n scope.finished = true;\n\n // Log success\n if (this.config.logger?.debug) {\n const durationMs = Date.now() - startTime;\n this.config.logger.debug(\"Transaction committed\", {\n durationMs,\n });\n }\n\n return {\n result,\n effects: scope.held.filter(\n held => !undone(held.scope, held.writesBefore)\n ),\n };\n } catch (error) {\n // As on commit: queued nested work finishes inside the transaction,\n // so the rollback discards it instead of it running in autocommit.\n await settleNested(scope);\n // Rolled back, or a COMMIT that failed: the effects held for this\n // transaction describe a change that did not happen.\n scope.rolledBack = true;\n scope.finished = true;\n scope.held.length = 0;\n // Rollback on error\n try {\n db.exec(\"ROLLBACK\");\n } catch {\n // Ignore rollback errors - transaction may already be aborted\n }\n throw error;\n }\n } catch (error) {\n // Work inside a transaction may throw to roll the write back — a refused\n // value, a denied permission — and that is the application's verdict, not\n // the driver's failure. Classifying it would replace its code and payload\n // with a generic database error, so a caller that asked for a refusal is\n // handed an unexplained failure and the per-field detail never arrives.\n if (isApplicationError(error)) throw error;\n throw this.classifyError(error);\n }\n }\n\n /**\n * Get SQLite database capabilities.\n *\n * @remarks\n * SQLite capabilities:\n * - JSON support (not JSONB)\n * - No arrays\n * - No native ILIKE\n * - RETURNING clause (3.35+)\n * - Savepoints supported\n * - ON CONFLICT supported\n */\n getCapabilities(): DatabaseCapabilities {\n return {\n dialect: \"sqlite\",\n supportsJsonb: false, // SQLite uses JSON, not JSONB\n supportsJson: true,\n supportsArrays: false, // SQLite doesn't support array types\n supportsGeneratedColumns: true, // SQLite 3.31+\n supportsFts: true, // SQLite FTS5\n supportsIlike: false, // No native ILIKE, use LOWER() LIKE\n supportsReturning: true, // SQLite 3.35+\n supportsSavepoints: true, // SQLite supports savepoints\n supportsOnConflict: true, // ON CONFLICT clause\n maxParamsPerQuery: 999, // SQLite SQLITE_MAX_VARIABLE_NUMBER default\n maxIdentifierLength: 128, // SQLite doesn't have a strict limit\n };\n }\n\n /**\n * Override insertMany for bulk insert optimization.\n *\n * @remarks\n * Uses a single multi-row INSERT statement for better performance.\n */\n override async insertMany<T = unknown>(\n table: string,\n data: Record<string, unknown>[],\n options?: InsertOptions\n ): Promise<T[]> {\n if (data.length === 0) {\n return [];\n }\n\n const db = this.ensureDb();\n\n // For single record, use parent implementation\n if (data.length === 1) {\n const result = await this.insert<T>(table, data[0], options);\n return [result];\n }\n\n // Build multi-row INSERT\n const columns = Object.keys(data[0]);\n const params: SqlParam[] = [];\n const valuesClauses: string[] = [];\n\n for (const record of data) {\n const placeholders: string[] = [];\n for (const col of columns) {\n params.push(sanitizeSqliteValue(record[col]) as SqlParam);\n placeholders.push(\"?\");\n }\n valuesClauses.push(`(${placeholders.join(\", \")})`);\n }\n\n const columnList = columns\n .map(col => this.escapeIdentifier(col))\n .join(\", \");\n let sql = `INSERT INTO ${this.escapeIdentifier(table)} (${columnList}) VALUES ${valuesClauses.join(\", \")}`;\n\n // Add RETURNING clause\n if (options?.returning) {\n const returning =\n options.returning === \"*\"\n ? \"*\"\n : options.returning.map(col => this.escapeIdentifier(col)).join(\", \");\n sql += ` RETURNING ${returning}`;\n } else {\n sql += \" RETURNING *\";\n }\n\n try {\n const stmt = db.prepare(sql);\n const rows = stmt.all(...(params as unknown[])) as T[];\n // SQLite stores a timestamp as an integer and hands it back as one. The\n // Drizzle read paths decode it through the column definition, so without\n // this a bulk insert answers with numbers where a read answers `Date`.\n const tableObj = this.getTableObject(table);\n return rows.map(r => this.mapRowFromRawSql(tableObj, r));\n } catch (error) {\n throw this.handleQueryError(error, \"insertMany\", table);\n }\n }\n\n // ============================================================\n // Protected Helper Methods\n // ============================================================\n\n /**\n * Ensures database is connected and returns it.\n *\n * @throws {DatabaseError} If not connected\n */\n private ensureDb(): Database.Database {\n if (!this.db) {\n throw createDatabaseError({\n kind: \"connection\",\n message: \"SqliteAdapter is not connected. Call connect() first.\",\n });\n }\n return this.db;\n }\n\n /**\n * Return the typed Drizzle instance for SQLite.\n * Guarded for server-only usage and requires an active connection.\n *\n * @param schema - Optional schema for relational queries (db.query.*)\n * @returns Drizzle ORM instance wrapping the better-sqlite3 connection\n * @throws {Error} If called in browser or not connected\n */\n getDrizzle<T = BetterSQLite3Database<AnyRelations>>(\n relations?: AnyRelations\n ): T {\n if (typeof window !== \"undefined\") {\n throw new Error(\"getDrizzle() is server-only\");\n }\n const db = this.ensureDb();\n // drizzle v1 removed the positional (client, config) form — positional\n // calls silently open a NEW :memory: database. Object form only.\n if (!relations) {\n this.drizzleBare ??= drizzle({ client: db });\n return this.drizzleBare as T;\n }\n let cached = this.drizzleByRelations.get(relations);\n if (!cached) {\n cached = drizzle({ client: db, relations });\n this.drizzleByRelations.set(relations, cached);\n }\n return cached as T;\n }\n\n /**\n * Convert $1, $2 placeholders to ? for better-sqlite3.\n *\n * @param sql - SQL with PostgreSQL-style placeholders\n * @returns SQL with ? placeholders\n */\n private convertPlaceholders(sql: string): string {\n // Replace $1, $2, etc. with ?\n return sql.replace(/\\$\\d+/g, \"?\");\n }\n\n /**\n * Creates a TransactionContext for the given database connection.\n */\n /** A table-level `primaryKey({ columns })`, read through the SQLite table config. */\n protected override compositePrimaryKey(\n tableObj: Record<string, unknown>\n ): object[] {\n return getTableConfig(\n tableObj as unknown as SQLiteTable\n ).primaryKeys.flatMap(key => key.columns);\n }\n\n private createTransactionContext(db: Database.Database): TransactionContext {\n // better-sqlite3 is synchronous; the methods below are async to satisfy\n // the TransactionContext contract shared with truly-async dialect adapters.\n // Bind a Drizzle instance to the transaction's connection so the delegated\n // CRUD methods run inside it. better-sqlite3 is single-connection, so this\n // is the same connection getDrizzle() would use, but binding explicitly\n // keeps the three adapters consistent and correct if that ever changes.\n // Built lazily and memoized: transactions that use only raw execute/insert\n // never construct it.\n const txHandles = this.transactionDrizzleHandles(relations =>\n relations ? drizzle({ client: db, relations }) : drizzle({ client: db })\n );\n const txDb = txHandles.bare;\n return {\n drizzleWithRelations: txHandles.withRelations,\n\n // SQLite has no row-level locking and needs none here: `withTransaction`\n // opens SQLite transactions with BEGIN IMMEDIATE, which takes the write\n // lock up front and serializes writers for the whole transaction.\n lockRow: (): Promise<void> => Promise.resolve(),\n\n // `run`, not `all`: better-sqlite3 throws on a statement that returns no\n // rows, which is every statement this method exists to carry. The Drizzle\n // instance is the transaction-bound one, so the statement runs inside this\n // transaction.\n //\n // better-sqlite3 is synchronous, so this resolves an already-settled\n // promise rather than being declared `async` over a body that never\n // awaits.\n runStatement: (statement: SQL): Promise<void> => {\n txDb().run(statement);\n return Promise.resolve();\n },\n\n // `all`, not `run`: this is the reading half, and better-sqlite3 returns\n // rows only from `all`. Synchronous, so the promise is already settled.\n queryStatement: <T = Record<string, unknown>>(\n statement: SQL\n ): Promise<T[]> => Promise.resolve(txDb().all(statement)),\n\n // eslint-disable-next-line @typescript-eslint/require-await\n execute: async <T = unknown>(\n sql: string,\n params: SqlParam[] = []\n ): Promise<T[]> => {\n const convertedSql = this.convertPlaceholders(sql);\n const trimmedSql = convertedSql.trim().toUpperCase();\n const isSelect =\n trimmedSql.startsWith(\"SELECT\") || trimmedSql.includes(\"RETURNING\");\n const sanitizedParams = params.map(sanitizeSqliteValue);\n\n if (isSelect) {\n const stmt = db.prepare(convertedSql);\n return stmt.all(...sanitizedParams) as T[];\n } else {\n const stmt = db.prepare(convertedSql);\n const result = stmt.run(...sanitizedParams);\n return [\n {\n changes: result.changes,\n lastInsertRowid: result.lastInsertRowid,\n } as unknown as T,\n ];\n }\n },\n\n // Keys only, unlike the PostgreSQL and MySQL raw paths, which also encode\n // their date values. `sanitizeSqliteValue` below binds a `Date` as unix\n // seconds, and an instant carries no zone -- so what SQLite stores does\n // not depend on the server's timezone and there is nothing to correct.\n // eslint-disable-next-line @typescript-eslint/require-await\n insert: async <T = unknown>(\n table: string,\n data: Record<string, unknown>,\n options?: InsertOptions\n ): Promise<T> => {\n const mapped = this.mapKeysToSqlColumns(\n this.getTableObject(table),\n data\n );\n const columns = Object.keys(mapped);\n const values = Object.values(mapped).map(sanitizeSqliteValue);\n const placeholders = values.map(() => \"?\").join(\", \");\n\n let sql = `INSERT INTO ${this.escapeIdentifier(table)} (${columns.map(c => this.escapeIdentifier(c)).join(\", \")}) VALUES (${placeholders})`;\n\n const ret = options?.returning;\n const returningEmpty = Array.isArray(ret) && ret.length === 0;\n if (!returningEmpty) {\n const returning =\n !ret || ret === \"*\"\n ? \"*\"\n : this.mapColumnNamesToSql(this.getTableObject(table), ret)\n .map(col => this.escapeIdentifier(col))\n .join(\", \");\n sql += ` RETURNING ${returning}`;\n }\n\n const stmt = db.prepare(sql);\n if (returningEmpty) {\n // No RETURNING clause: better-sqlite3's .all() rejects a statement\n // that returns no columns, so run it and return nothing.\n stmt.run(...values);\n return undefined as T;\n }\n const rows = stmt.all(...values) as T[];\n // Return JS property-named keys AND Drizzle-decoded date values, so a\n // write inside a transaction answers with the same representation a\n // read of the same row gives.\n return this.mapRowFromRawSql(this.getTableObject(table), rows[0]);\n },\n\n // eslint-disable-next-line @typescript-eslint/require-await\n insertMany: async <T = unknown>(\n table: string,\n data: Record<string, unknown>[],\n options?: InsertOptions\n ): Promise<T[]> => {\n if (data.length === 0) return [];\n\n const tableObj = this.getTableObject(table);\n const mappedRecords = data.map(r =>\n this.mapKeysToSqlColumns(tableObj, r)\n );\n const columns = Object.keys(mappedRecords[0]);\n const allValues: unknown[] = [];\n const valuesClauses: string[] = [];\n\n for (const record of mappedRecords) {\n const placeholders: string[] = [];\n for (const col of columns) {\n allValues.push(sanitizeSqliteValue(record[col]));\n placeholders.push(\"?\");\n }\n valuesClauses.push(`(${placeholders.join(\", \")})`);\n }\n\n let sql = `INSERT INTO ${this.escapeIdentifier(table)} (${columns.map(c => this.escapeIdentifier(c)).join(\", \")}) VALUES ${valuesClauses.join(\", \")}`;\n\n const ret = options?.returning;\n const returningEmpty = Array.isArray(ret) && ret.length === 0;\n if (!returningEmpty) {\n const returning =\n !ret || ret === \"*\"\n ? \"*\"\n : this.mapColumnNamesToSql(this.getTableObject(table), ret)\n .map(col => this.escapeIdentifier(col))\n .join(\", \");\n sql += ` RETURNING ${returning}`;\n }\n\n const stmt = db.prepare(sql);\n if (returningEmpty) {\n stmt.run(...allValues);\n return [];\n }\n return (stmt.all(...allValues) as T[]).map(r =>\n this.mapRowFromRawSql(tableObj, r)\n );\n },\n\n // Adapter-built, as `insert` above is; `transactionUpdate` says why.\n // A column the model does not declare binds as every other value on\n // this path does, through `sanitizeSqliteValue`. `all` only when the\n // statement carries RETURNING: better-sqlite3 throws on `all` for a\n // statement that returns no rows, and on `run` for one that does.\n update: this.transactionUpdate(\n txDb,\n (statement, returnsRows) =>\n returnsRows\n ? txDb().all<Record<string, unknown>>(statement)\n : (txDb().run(statement), undefined),\n sanitizeSqliteValue\n ),\n\n ...this.createTransactionForwarders(txDb),\n\n // eslint-disable-next-line @typescript-eslint/require-await\n savepoint: async (name: string): Promise<void> => {\n db.exec(`SAVEPOINT ${this.escapeIdentifier(name)}`);\n },\n\n // eslint-disable-next-line @typescript-eslint/require-await\n rollbackToSavepoint: async (name: string): Promise<void> => {\n db.exec(`ROLLBACK TO SAVEPOINT ${this.escapeIdentifier(name)}`);\n },\n\n // eslint-disable-next-line @typescript-eslint/require-await\n releaseSavepoint: async (name: string): Promise<void> => {\n db.exec(`RELEASE SAVEPOINT ${this.escapeIdentifier(name)}`);\n },\n };\n }\n\n /**\n * Classifies a SQLite error into a DatabaseError.\n *\n * @param error - Original error from better-sqlite3\n * @param sql - SQL statement that caused the error (optional)\n * @returns DatabaseError with proper classification\n */\n // fallow-ignore-next-line complexity\n protected override classifyError(\n error: unknown,\n sql?: string\n ): DatabaseError {\n // Why short-circuit on existing DatabaseError: F17's\n // UnsupportedDialectVersionError is already a typed DatabaseError with\n // kind: \"unsupported_version\" plus detectedVersion/requiredVersion\n // fields. Re-wrapping it here would erase those fields.\n if (isDatabaseError(error)) return error;\n\n // Classify from the DRIVER's error, which is not necessarily the one handed\n // in. A query failure arrives wrapped: DrizzleQueryError carries the SQL\n // statement as its message and no code, and better-sqlite3's own error —\n // the only object that knows what actually went wrong — sits below it in\n // the `cause` chain. Classifying the wrapper means classifying the QUERY\n // TEXT, which reported a unique violation on a table with a `locked_by`\n // column as a \"timeout\", because the statement contains the word LOCKED.\n const sqliteError = this.driverErrorIn<DriverErrorShape>(\n error,\n candidate => typeof candidate.code === \"string\" && candidate.code !== \"\"\n );\n\n // Determine error kind from SQLite error code\n let kind: DatabaseErrorKind = \"unknown\";\n\n if (sqliteError.code) {\n kind = SQLITE_ERROR_CODES[sqliteError.code] || \"unknown\";\n } else if (sqliteError.message) {\n // Try to extract error type from message. Safe to match loosely now:\n // `sqliteError` is the driver's error, so its message is the driver's\n // description of the failure and never a SQL statement.\n const msg = sqliteError.message.toUpperCase();\n if (msg.includes(\"UNIQUE CONSTRAINT\")) {\n kind = \"unique_violation\";\n } else if (msg.includes(\"FOREIGN KEY CONSTRAINT\")) {\n kind = \"foreign_key_violation\";\n } else if (msg.includes(\"NOT NULL CONSTRAINT\")) {\n kind = \"not_null_violation\";\n } else if (msg.includes(\"CHECK CONSTRAINT\")) {\n kind = \"check_violation\";\n } else if (msg.includes(\"BUSY\") || msg.includes(\"LOCKED\")) {\n kind = \"timeout\";\n } else if (\n msg.includes(\"SQLITE_CANTOPEN\") ||\n msg.includes(\"UNABLE TO OPEN\")\n ) {\n kind = \"connection\";\n }\n }\n\n // Build error message from the driver's description, for the same reason\n // the classification uses it: the wrapper's message is the SQL statement.\n let message = sqliteError.message ?? String(error);\n if (sql && kind === \"query\") {\n message = `Query failed: ${message}`;\n }\n\n return createDatabaseError({\n kind,\n message,\n code: sqliteError.code,\n cause: error instanceof Error ? error : undefined,\n });\n }\n}\n\n/** The fields this classifier reads off an error, at any depth in the chain. */\ninterface DriverErrorShape {\n code?: string;\n message?: string;\n name?: string;\n cause?: unknown;\n}\n\n/**\n * Create a SQLite database adapter.\n *\n * @param config - SQLite adapter configuration\n * @returns A new SqliteAdapter instance\n *\n * @example\n * ```typescript\n * // Simple usage with file path\n * const adapter = createSqliteAdapter({\n * url: 'file:./data.db',\n * });\n *\n * // In-memory database\n * const memAdapter = createSqliteAdapter({\n * memory: true,\n * });\n *\n * // Full configuration\n * const adapter = createSqliteAdapter({\n * url: 'file:./data.db',\n * wal: true,\n * foreignKeys: true,\n * busyTimeout: 5000,\n * logger: {\n * query: (sql, params, duration) => console.log(`Query: ${sql}`),\n * },\n * });\n *\n * await adapter.connect();\n * ```\n */\nexport function createSqliteAdapter(\n config: SqliteAdapterConfig\n): SqliteAdapter {\n return new SqliteAdapter(config);\n}\n\n/**\n * Type guard to check if a value is a SqliteAdapter.\n *\n * @param value - Value to check\n * @returns True if value is a SqliteAdapter instance\n *\n * @example\n * ```typescript\n * if (isSqliteAdapter(adapter)) {\n * // TypeScript knows adapter is SqliteAdapter\n * console.log('Using SQLite');\n * }\n * ```\n */\nexport function isSqliteAdapter(value: unknown): value is SqliteAdapter {\n return value instanceof SqliteAdapter;\n}\n\n/** One active transaction, as the calls nested inside it see it. */\ninterface TransactionScope {\n /** False once the transaction has finished, or is finishing. */\n active: boolean;\n /** 0 for the transaction itself; each savepoint is one deeper. */\n depth: number;\n /** The scope this savepoint was opened in; none for the transaction. */\n parent?: TransactionScope;\n /** True once this savepoint, or this outermost transaction, rolled back. */\n rolledBack: boolean;\n /**\n * How many `transaction()` calls this scope's context has made since it\n * closed, each running somewhere else: an effect registered after one of\n * them may announce a write this scope's rollback did not undo.\n */\n writesAfterClosing: number;\n /** True once this outermost transaction has committed or rolled back. */\n finished: boolean;\n /**\n * Effects registered with `afterCommit` from any scope of the outermost\n * transaction, in order. Only the outermost transaction's list is used.\n */\n held: HeldEffect[];\n /** Serializes the calls nested directly inside this transaction. */\n queue: Promise<unknown>;\n /**\n * The scopes open on this connection, outermost first, shared by the\n * transaction and every savepoint inside it. Each scope runs inside the\n * one before it: a scope runs one nested call at a time, so the scopes\n * still running form a single chain and the last one open is the innermost.\n */\n open: TransactionScope[];\n}\n\n/** An `afterCommit` effect waiting for the outermost transaction to commit. */\ninterface HeldEffect {\n effect: () => unknown;\n onDeferredFailure?: (error: unknown) => void;\n /** The scope it was registered from; it is dropped if that one is undone. */\n scope: TransactionScope;\n /** `scope.writesAfterClosing` when it was registered. */\n writesBefore: number;\n}\n\n/** What a committed transaction hands back: its result and its held effects. */\ninterface Committed<T> {\n result: T;\n effects: HeldEffect[];\n}\n\n/**\n * Open the scope of a savepoint inside `parent`, or of an outermost\n * transaction when there is none, and record it among the connection's open\n * scopes.\n */\nfunction openScope(parent?: TransactionScope): TransactionScope {\n const scope: TransactionScope = {\n active: true,\n depth: parent ? parent.depth + 1 : 0,\n parent,\n rolledBack: false,\n writesAfterClosing: 0,\n finished: false,\n held: [],\n queue: Promise.resolve(),\n open: parent ? parent.open : [],\n };\n scope.open.push(scope);\n return scope;\n}\n\n/** The outermost transaction `scope` runs inside; itself for that one. */\nfunction outermost(scope: TransactionScope): TransactionScope {\n let at = scope;\n while (at.parent) at = at.parent;\n return at;\n}\n\n/**\n * Whether an effect registered from `scope` describes a write that was\n * undone: `scope`, or a scope it runs inside, rolled back, and no\n * transaction had run from its context since it closed when the effect was\n * registered (`writesBefore`). An effect registered before such a write\n * still describes the undone one.\n */\nfunction undone(scope: TransactionScope, writesBefore: number): boolean {\n if (writesBefore > 0) return false;\n for (let at: TransactionScope | undefined = scope; at; at = at.parent) {\n if (at.rolledBack) return true;\n }\n return false;\n}\n\n/** Chain `run` onto a scope's queue, keeping the queue itself unrejected. */\nfunction enqueueIn<T>(\n scope: TransactionScope,\n run: () => Promise<T>\n): Promise<T> {\n const next = scope.queue.then(run, run);\n scope.queue = next.catch(() => undefined);\n return next;\n}\n\n/**\n * Close a scope to new nested calls and wait for those already queued. A call\n * arriving after this joins the innermost scope still open on the connection,\n * or, when none is, goes to the instance queue behind the transaction.\n */\nasync function settleNested(scope: TransactionScope): Promise<void> {\n scope.active = false;\n // A failed RELEASE or COMMIT settles the same scope a second time.\n const index = scope.open.indexOf(scope);\n if (index !== -1) scope.open.splice(index, 1);\n await scope.queue;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -13,7 +13,7 @@ import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
13
13
  * @remarks
14
14
  * This adapter uses the better-sqlite3 package for database connectivity and provides:
15
15
  * - Synchronous API wrapped for async interface compatibility
16
- * - Full transaction support with savepoints (via better-sqlite3's native transaction handling)
16
+ * - Transactions the adapter runs itself (BEGIN IMMEDIATE / COMMIT / ROLLBACK), with nested calls run as savepoints
17
17
  * - CRUD operations with RETURNING clause support (SQLite 3.35+)
18
18
  * - WAL mode for better concurrent read performance
19
19
  * - In-memory and file-based database support
@@ -111,6 +111,18 @@ declare class SqliteAdapter extends DrizzleAdapter {
111
111
  * surface area without changing the achievable concurrency.
112
112
  */
113
113
  private transactionQueue;
114
+ /**
115
+ * The transaction the current async chain is running inside, if any.
116
+ *
117
+ * A `transaction()` call made from INSIDE a transaction's work — a store
118
+ * writing on behalf of the caller, a plugin's write inside its own
119
+ * `ctx.db.transaction` — used to queue behind the very transaction that
120
+ * was waiting for it, and neither ever settled: that hung every later
121
+ * transaction on the instance too. Such a call now runs as a SAVEPOINT of
122
+ * the active transaction instead, so it commits or rolls back with it and
123
+ * its own failure undoes only its own part.
124
+ */
125
+ private readonly transactionScope;
114
126
  /**
115
127
  * Creates a new SQLite adapter instance.
116
128
  *
@@ -165,15 +177,102 @@ declare class SqliteAdapter extends DrizzleAdapter {
165
177
  * @returns Result of the work function
166
178
  *
167
179
  * @remarks
168
- * Uses better-sqlite3's native transaction handling which:
169
- * - Automatically commits on success
170
- * - Automatically rolls back on error
171
- * - Converts nested transactions to savepoints
180
+ * The adapter manages the transaction itself, because better-sqlite3's
181
+ * `db.transaction()` does not take async work: it runs `BEGIN IMMEDIATE`,
182
+ * then `COMMIT` when `work` resolves or `ROLLBACK` when it throws.
183
+ * - Top-level calls run one at a time.
184
+ * - A call made inside an open transaction's work joins it as a savepoint
185
+ * (`SAVEPOINT` / `RELEASE` / `ROLLBACK TO`).
186
+ * - Nested calls of one scope run one at a time.
187
+ * - A call made later from a savepoint that has already released joins the
188
+ * innermost scope still open.
189
+ * - Nested work started and not awaited finishes before the enclosing scope
190
+ * commits or rolls back.
172
191
  *
173
192
  * Note: SQLite uses DEFERRED, IMMEDIATE, or EXCLUSIVE transaction modes
174
- * rather than isolation levels. This adapter uses IMMEDIATE by default.
193
+ * rather than isolation levels. This adapter uses IMMEDIATE.
175
194
  */
176
195
  transaction<T>(work: (tx: TransactionContext) => Promise<T>, _options?: TransactionOptions): Promise<T>;
196
+ /**
197
+ * Hold `effect` until the transaction enclosing this async context commits,
198
+ * or run it now when none does.
199
+ *
200
+ * The effect belongs to the scope this async context runs in, even one
201
+ * that has already released or rolled back: a service whose own
202
+ * transaction nested as a savepoint registers from its caller's scope once
203
+ * that savepoint has released, and the change is undoable for as long as
204
+ * any scope around it is. The outermost transaction runs the effect once
205
+ * its COMMIT succeeds, unless a scope between the effect's scope and the
206
+ * outermost transaction rolled back, and drops every effect on ROLLBACK or
207
+ * a failed COMMIT. A context whose outermost transaction has already
208
+ * finished is outside any transaction, so its effect runs now, unless what
209
+ * it announces was undone and it has run no transaction since.
210
+ */
211
+ afterCommit(effect: () => unknown, onDeferredFailure?: (error: unknown) => void): Promise<void>;
212
+ /**
213
+ * `effect`, bound to the async context it is registered from.
214
+ *
215
+ * A held effect runs after the outermost COMMIT, from the code that ran the
216
+ * outermost transaction, so without this it sees that code's context rather
217
+ * than its own: whatever its caller pinned around the write is gone. That
218
+ * includes who is calling. A scope pinned for a scoped API key lost there
219
+ * leaves a hook's nested call judged by the key's owner instead of the key,
220
+ * and a person's frame lost there leaves the hook told of nobody.
221
+ *
222
+ * The adapter's own transaction scope is the one store it leaves: the
223
+ * effect runs once that transaction has finished, outside it, as an effect
224
+ * held to the outermost commit always has.
225
+ */
226
+ private inRegisteringContext;
227
+ /**
228
+ * Run the effects a committed transaction held, in order. A failure is
229
+ * reported, never thrown: the change is durable, and reporting the
230
+ * transaction as failed would invite a retry of something already done.
231
+ */
232
+ private runHeldEffects;
233
+ /** Hand a held effect's failure to its reporter, or to the adapter's log. */
234
+ private reportHeldEffectFailure;
235
+ /**
236
+ * Whether a `transaction()` call made here would join an open transaction
237
+ * as a savepoint. On SQLite it would: the connection is the only one, so a
238
+ * transaction open on it encloses whatever the async chain that opened it
239
+ * starts.
240
+ */
241
+ inTransaction(): boolean;
242
+ /**
243
+ * Whether the calling async flow is inside a transaction that has not
244
+ * finished, judged from the transaction this flow was started inside,
245
+ * never from the connection: another request's open transaction answers
246
+ * false here, where its own `transaction()` queues behind that one.
247
+ *
248
+ * A flow started inside a transaction, even inside a savepoint that has
249
+ * since released, stays inside it until its outermost transaction has
250
+ * committed or rolled back: until then whatever it writes on the one
251
+ * connection lands in that transaction.
252
+ */
253
+ transactionOpenInFlow(): boolean;
254
+ /**
255
+ * The scope a `transaction()` call made here nests in, or none when it
256
+ * opens a transaction of its own.
257
+ *
258
+ * A call made later from inside a savepoint that has since released runs
259
+ * inside the innermost scope open on the connection. Queued on an enclosing
260
+ * scope, or on the instance, it would wait behind the scope running there,
261
+ * which may be the one awaiting it. Savepoints on one connection form a
262
+ * stack, so whatever opens now is inside that innermost scope anyway; when
263
+ * none is open the call queues on the instance.
264
+ *
265
+ * The innermost open scope need not be related to the call. When it is a
266
+ * sibling savepoint that later rolls back, the call's write rolls back with
267
+ * it, although the call itself already resolved. Waiting for an unrelated
268
+ * scope instead could wait on the very scope that awaits the call.
269
+ */
270
+ private nestingScope;
271
+ /**
272
+ * Run `work` as a savepoint of the active transaction: released when it
273
+ * resolves, rolled back to when it throws.
274
+ */
275
+ private runSavepoint;
177
276
  /**
178
277
  * Inner transaction body. Kept private so callers always go through
179
278
  * the serialized `transaction()` queue above and the BEGIN/COMMIT
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
13
13
  * @remarks
14
14
  * This adapter uses the better-sqlite3 package for database connectivity and provides:
15
15
  * - Synchronous API wrapped for async interface compatibility
16
- * - Full transaction support with savepoints (via better-sqlite3's native transaction handling)
16
+ * - Transactions the adapter runs itself (BEGIN IMMEDIATE / COMMIT / ROLLBACK), with nested calls run as savepoints
17
17
  * - CRUD operations with RETURNING clause support (SQLite 3.35+)
18
18
  * - WAL mode for better concurrent read performance
19
19
  * - In-memory and file-based database support
@@ -111,6 +111,18 @@ declare class SqliteAdapter extends DrizzleAdapter {
111
111
  * surface area without changing the achievable concurrency.
112
112
  */
113
113
  private transactionQueue;
114
+ /**
115
+ * The transaction the current async chain is running inside, if any.
116
+ *
117
+ * A `transaction()` call made from INSIDE a transaction's work — a store
118
+ * writing on behalf of the caller, a plugin's write inside its own
119
+ * `ctx.db.transaction` — used to queue behind the very transaction that
120
+ * was waiting for it, and neither ever settled: that hung every later
121
+ * transaction on the instance too. Such a call now runs as a SAVEPOINT of
122
+ * the active transaction instead, so it commits or rolls back with it and
123
+ * its own failure undoes only its own part.
124
+ */
125
+ private readonly transactionScope;
114
126
  /**
115
127
  * Creates a new SQLite adapter instance.
116
128
  *
@@ -165,15 +177,102 @@ declare class SqliteAdapter extends DrizzleAdapter {
165
177
  * @returns Result of the work function
166
178
  *
167
179
  * @remarks
168
- * Uses better-sqlite3's native transaction handling which:
169
- * - Automatically commits on success
170
- * - Automatically rolls back on error
171
- * - Converts nested transactions to savepoints
180
+ * The adapter manages the transaction itself, because better-sqlite3's
181
+ * `db.transaction()` does not take async work: it runs `BEGIN IMMEDIATE`,
182
+ * then `COMMIT` when `work` resolves or `ROLLBACK` when it throws.
183
+ * - Top-level calls run one at a time.
184
+ * - A call made inside an open transaction's work joins it as a savepoint
185
+ * (`SAVEPOINT` / `RELEASE` / `ROLLBACK TO`).
186
+ * - Nested calls of one scope run one at a time.
187
+ * - A call made later from a savepoint that has already released joins the
188
+ * innermost scope still open.
189
+ * - Nested work started and not awaited finishes before the enclosing scope
190
+ * commits or rolls back.
172
191
  *
173
192
  * Note: SQLite uses DEFERRED, IMMEDIATE, or EXCLUSIVE transaction modes
174
- * rather than isolation levels. This adapter uses IMMEDIATE by default.
193
+ * rather than isolation levels. This adapter uses IMMEDIATE.
175
194
  */
176
195
  transaction<T>(work: (tx: TransactionContext) => Promise<T>, _options?: TransactionOptions): Promise<T>;
196
+ /**
197
+ * Hold `effect` until the transaction enclosing this async context commits,
198
+ * or run it now when none does.
199
+ *
200
+ * The effect belongs to the scope this async context runs in, even one
201
+ * that has already released or rolled back: a service whose own
202
+ * transaction nested as a savepoint registers from its caller's scope once
203
+ * that savepoint has released, and the change is undoable for as long as
204
+ * any scope around it is. The outermost transaction runs the effect once
205
+ * its COMMIT succeeds, unless a scope between the effect's scope and the
206
+ * outermost transaction rolled back, and drops every effect on ROLLBACK or
207
+ * a failed COMMIT. A context whose outermost transaction has already
208
+ * finished is outside any transaction, so its effect runs now, unless what
209
+ * it announces was undone and it has run no transaction since.
210
+ */
211
+ afterCommit(effect: () => unknown, onDeferredFailure?: (error: unknown) => void): Promise<void>;
212
+ /**
213
+ * `effect`, bound to the async context it is registered from.
214
+ *
215
+ * A held effect runs after the outermost COMMIT, from the code that ran the
216
+ * outermost transaction, so without this it sees that code's context rather
217
+ * than its own: whatever its caller pinned around the write is gone. That
218
+ * includes who is calling. A scope pinned for a scoped API key lost there
219
+ * leaves a hook's nested call judged by the key's owner instead of the key,
220
+ * and a person's frame lost there leaves the hook told of nobody.
221
+ *
222
+ * The adapter's own transaction scope is the one store it leaves: the
223
+ * effect runs once that transaction has finished, outside it, as an effect
224
+ * held to the outermost commit always has.
225
+ */
226
+ private inRegisteringContext;
227
+ /**
228
+ * Run the effects a committed transaction held, in order. A failure is
229
+ * reported, never thrown: the change is durable, and reporting the
230
+ * transaction as failed would invite a retry of something already done.
231
+ */
232
+ private runHeldEffects;
233
+ /** Hand a held effect's failure to its reporter, or to the adapter's log. */
234
+ private reportHeldEffectFailure;
235
+ /**
236
+ * Whether a `transaction()` call made here would join an open transaction
237
+ * as a savepoint. On SQLite it would: the connection is the only one, so a
238
+ * transaction open on it encloses whatever the async chain that opened it
239
+ * starts.
240
+ */
241
+ inTransaction(): boolean;
242
+ /**
243
+ * Whether the calling async flow is inside a transaction that has not
244
+ * finished, judged from the transaction this flow was started inside,
245
+ * never from the connection: another request's open transaction answers
246
+ * false here, where its own `transaction()` queues behind that one.
247
+ *
248
+ * A flow started inside a transaction, even inside a savepoint that has
249
+ * since released, stays inside it until its outermost transaction has
250
+ * committed or rolled back: until then whatever it writes on the one
251
+ * connection lands in that transaction.
252
+ */
253
+ transactionOpenInFlow(): boolean;
254
+ /**
255
+ * The scope a `transaction()` call made here nests in, or none when it
256
+ * opens a transaction of its own.
257
+ *
258
+ * A call made later from inside a savepoint that has since released runs
259
+ * inside the innermost scope open on the connection. Queued on an enclosing
260
+ * scope, or on the instance, it would wait behind the scope running there,
261
+ * which may be the one awaiting it. Savepoints on one connection form a
262
+ * stack, so whatever opens now is inside that innermost scope anyway; when
263
+ * none is open the call queues on the instance.
264
+ *
265
+ * The innermost open scope need not be related to the call. When it is a
266
+ * sibling savepoint that later rolls back, the call's write rolls back with
267
+ * it, although the call itself already resolved. Waiting for an unrelated
268
+ * scope instead could wait on the very scope that awaits the call.
269
+ */
270
+ private nestingScope;
271
+ /**
272
+ * Run `work` as a savepoint of the active transaction: released when it
273
+ * resolves, rolled back to when it throws.
274
+ */
275
+ private runSavepoint;
177
276
  /**
178
277
  * Inner transaction body. Kept private so callers always go through
179
278
  * the serialized `transaction()` queue above and the BEGIN/COMMIT