@happyvertical/sql 0.102.4 → 0.102.5

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.
Files changed (30) hide show
  1. package/README.md +26 -0
  2. package/dist/chunks/{duckdb-LMyfKZGi.js → duckdb-c4vdDzPL.js} +5 -4
  3. package/dist/chunks/{duckdb-LMyfKZGi.js.map → duckdb-c4vdDzPL.js.map} +1 -1
  4. package/dist/chunks/duckdb-resources-DBlvosDo.js +44 -0
  5. package/dist/chunks/duckdb-resources-DBlvosDo.js.map +1 -0
  6. package/dist/chunks/{postgres-dialect-Bfswr4Vs.js → postgres-dialect-CGv6DxSP.js} +3 -775
  7. package/dist/chunks/postgres-dialect-CGv6DxSP.js.map +1 -0
  8. package/dist/chunks/query-RzXJ4B9s.js +353 -0
  9. package/dist/chunks/query-RzXJ4B9s.js.map +1 -0
  10. package/dist/chunks/schema-manager-cxsySSDA.js +777 -0
  11. package/dist/chunks/schema-manager-cxsySSDA.js.map +1 -0
  12. package/dist/chunks/{sqlite-connection-cache-ChWav9iY.js → sqlite-connection-cache-CYThh9l5.js} +2 -2
  13. package/dist/chunks/{sqlite-connection-cache-ChWav9iY.js.map → sqlite-connection-cache-CYThh9l5.js.map} +1 -1
  14. package/dist/chunks/{sqlite-native--z4BnolL.js → sqlite-native-CsJ_BLqN.js} +5 -4
  15. package/dist/chunks/{sqlite-native--z4BnolL.js.map → sqlite-native-CsJ_BLqN.js.map} +1 -1
  16. package/dist/chunks/{sqlite-0PMv1va2.js → sqlite-rILMdW7Z.js} +6 -5
  17. package/dist/chunks/{sqlite-0PMv1va2.js.map → sqlite-rILMdW7Z.js.map} +1 -1
  18. package/dist/index.d.ts +3 -45
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +6 -238
  21. package/dist/index.js.map +1 -1
  22. package/dist/pglite.js +2 -1
  23. package/dist/pglite.js.map +1 -1
  24. package/dist/query.d.ts +61 -0
  25. package/dist/query.d.ts.map +1 -0
  26. package/dist/query.js +3 -0
  27. package/package.json +6 -2
  28. package/dist/chunks/duckdb-resources-Cci6Lo6H.js +0 -156
  29. package/dist/chunks/duckdb-resources-Cci6Lo6H.js.map +0 -1
  30. package/dist/chunks/postgres-dialect-Bfswr4Vs.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-manager-cxsySSDA.js","names":[],"sources":["../../src/shared/utils.ts","../../src/schema-manager.ts"],"sourcesContent":["/**\n * Shared SQL utilities that work in both browser and Node.js environments\n */\n\nimport { DatabaseError } from '@happyvertical/utils';\nimport type { WhereClause } from './types.js';\n\n/**\n * Formats a database error to include its useful non-secret details.\n *\n * Database drivers often include additional properties beyond just `message`:\n * - PostgreSQL: code, detail, hint, severity\n * - DuckDB: may include additional context\n * - SQLite/LibSQL: may include errno, code\n *\n * This function extracts an allowlist of driver properties and redacts\n * credential-shaped text. When parameter values are available, prefer\n * {@link wrapDatabaseError}; it also redacts values echoed by the driver.\n *\n * @param error - The caught error object\n * @returns Formatted error string with all available error details\n */\nexport function formatDbError(error: unknown): string {\n return formatDbErrorWithSecrets(error, []);\n}\n\ntype DriverError = {\n name?: string;\n message?: string;\n code?: string;\n detail?: string;\n hint?: string;\n severity?: string;\n errno?: number;\n};\n\nconst DRIVER_ERROR_FIELDS = [\n 'code',\n 'detail',\n 'hint',\n 'severity',\n 'errno',\n] as const;\n\nconst SENSITIVE_CONTEXT_KEY =\n /^(?:args?|parameters?|params?|queries|query|sql|values?)$/i;\nconst CREDENTIAL_KEY_PART =\n /^(?:credential|credentials|passphrase|password|pwd|secret|token)$/i;\nconst CREDENTIAL_KEY_QUALIFIER =\n /^(?:access|api|auth|client|private|refresh|service|signing)$/i;\nconst DATABASE_USER_KEY =\n /^(?:user(?:name)?|(?:database|db|pg|postgres|postgresql)[._-]?user(?:name)?)$/i;\nconst DATABASE_URL_USERINFO =\n /\\b((?:https?|libsql|postgres|postgresql):\\/\\/)[^\\s/@]+@/giu;\nconst DATABASE_URL =\n /\\b(?:https?|libsql|postgres|postgresql):\\/\\/[^\\s\"'`<>()]+/giu;\nconst CREDENTIAL_ASSIGNMENT =\n /(?<![\\p{L}\\p{N}_-])([\"']?)([\\p{L}\\p{N}_.-]+(?: key)?)\\1(\\s*[:=]\\s*)(?:\"(?:\\\\.|[^\"])*\"|'(?:\\\\.|[^'])*'|[^\\s,;}\\]]+)/giu;\nconst BEARER_CREDENTIAL = /\\bbearer\\s+[^\\s,;]+/giu;\nconst SQL_NUMERIC_LITERAL =\n /(?<![\\p{L}\\p{N}_$])[-+]?(?:\\d(?:_?\\d)*(?:\\.(?:\\d(?:_?\\d)*)?)?|\\.\\d(?:_?\\d)*)(?:e[-+]?\\d(?:_?\\d)*)?(?![\\p{L}\\p{N}_$])/giu;\nconst POSTGRES_KEY_VALUE =\n /(\\bKey\\s*\\([^\\r\\n)]*\\)\\s*=\\s*\\()([\\s\\S]*?)(\\)\\s*(?:already exists|is duplicated)\\b)/giu;\nconst POSTGRES_FAILING_ROW =\n /(\\bFailing row contains\\s*\\()([\\s\\S]*)(\\)(?:\\.|$))/giu;\nconst CAST_INPUT_VALUE =\n /(\\bwith value\\s+)([\\s\\S]*?)(\\s+(?:can't|cannot)\\s+be cast\\b)/giu;\n\nfunction isCredentialKey(key: string): boolean {\n if (DATABASE_USER_KEY.test(key)) return true;\n\n const parts = key\n .replace(/([\\p{Ll}\\p{N}])(\\p{Lu})/gu, '$1 $2')\n .split(/[^\\p{L}\\p{N}]+/u)\n .filter(Boolean);\n if (parts.length === 1 && /^(?:auth|credential|key|pass)$/i.test(parts[0])) {\n return true;\n }\n if (parts.some((part) => CREDENTIAL_KEY_PART.test(part))) return true;\n\n return parts.some(\n (part, index) =>\n /^(?:key|auth)$/i.test(part) &&\n index > 0 &&\n CREDENTIAL_KEY_QUALIFIER.test(parts[index - 1]),\n );\n}\n\nfunction toDriverError(error: unknown): DriverError {\n return error && (typeof error === 'object' || typeof error === 'function')\n ? (error as DriverError)\n : {};\n}\n\nfunction redactUrl(value: string): string {\n try {\n const url = new URL(value);\n if (url.username) url.username = '[redacted]';\n if (url.password) url.password = '[redacted]';\n for (const key of url.searchParams.keys()) {\n if (isCredentialKey(key)) {\n url.searchParams.set(key, '[redacted]');\n }\n }\n if (url.hash) url.hash = '[redacted]';\n return url.toString();\n } catch {\n return value.replace(/\\/\\/[^/@\\s]+@/u, '//[redacted]@');\n }\n}\n\nfunction redactKnownValue(input: string, value: string): string {\n if (!value || !input.includes(value)) return input;\n if (!/^[\\p{L}\\p{N}_-]+$/u.test(value)) {\n return input.split(value).join('[redacted]');\n }\n\n const identifierCharacter = /^[\\p{L}\\p{N}_-]$/u;\n let cursor = 0;\n let redacted = '';\n let match = input.indexOf(value);\n while (match !== -1) {\n const end = match + value.length;\n const before = [...input.slice(Math.max(0, match - 2), match)].at(-1);\n const afterCodePoint = input.codePointAt(end);\n const after =\n afterCodePoint === undefined\n ? undefined\n : String.fromCodePoint(afterCodePoint);\n const bounded =\n (!before || !identifierCharacter.test(before)) &&\n (!after || !identifierCharacter.test(after));\n\n redacted += input.slice(cursor, match);\n redacted += bounded ? '[redacted]' : value;\n cursor = end;\n match = input.indexOf(value, cursor);\n }\n\n return redacted + input.slice(cursor);\n}\n\nfunction redactDatabaseErrorText(\n value: string,\n knownSecrets: readonly string[],\n): string {\n let redacted = value\n .replace(DATABASE_URL_USERINFO, '$1[redacted]@')\n .replace(DATABASE_URL, redactUrl)\n .replace(\n CREDENTIAL_ASSIGNMENT,\n (assignment, quote: string, key: string, delimiter: string) =>\n isCredentialKey(key)\n ? `${quote}${key}${quote}${delimiter}[redacted]`\n : assignment,\n )\n .replace(BEARER_CREDENTIAL, 'Bearer [redacted]')\n .replace(\n POSTGRES_KEY_VALUE,\n (_match, prefix: string, _value: string, suffix: string) =>\n `${prefix}[redacted]${suffix}`,\n )\n .replace(\n POSTGRES_FAILING_ROW,\n (_match, prefix: string, _value: string, suffix: string) =>\n `${prefix}[redacted]${suffix}`,\n )\n .replace(\n CAST_INPUT_VALUE,\n (_match, prefix: string, _value: string, suffix: string) =>\n `${prefix}[redacted]${suffix}`,\n );\n\n for (const secret of [...new Set(knownSecrets)].sort(\n (left, right) => right.length - left.length,\n )) {\n redacted = redactKnownValue(redacted, secret);\n }\n\n return redacted;\n}\n\nfunction collectSensitiveValues(\n value: unknown,\n output: Set<string>,\n seen: Set<object>,\n): void {\n if (typeof value === 'string') {\n if (value) output.add(value);\n return;\n }\n if (\n typeof value === 'number' ||\n typeof value === 'bigint' ||\n typeof value === 'boolean'\n ) {\n output.add(String(value));\n return;\n }\n if (!value || typeof value !== 'object' || seen.has(value)) return;\n seen.add(value);\n\n try {\n if (value instanceof Date) {\n output.add(value.toISOString());\n return;\n }\n\n if (ArrayBuffer.isView(value)) {\n const bytes = new Uint8Array(\n value.buffer,\n value.byteOffset,\n value.byteLength,\n );\n if (bytes.length > 0) {\n const hex = [...bytes]\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('');\n output.add([...bytes].join(','));\n output.add(hex);\n output.add(`\\\\x${hex}`);\n output.add(`\\\\x${hex.toUpperCase()}`);\n output.add(\n `<Buffer ${[...bytes]\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join(' ')}>`,\n );\n if (typeof Buffer !== 'undefined') {\n output.add(Buffer.from(bytes).toString('base64'));\n }\n }\n return;\n }\n } catch {\n return;\n }\n\n try {\n const serialized = JSON.stringify(value);\n if (serialized && serialized !== '{}' && serialized !== '[]') {\n output.add(serialized);\n }\n } catch {\n // Cyclic bind values are still traversed below.\n }\n\n let descriptors: Record<string, PropertyDescriptor>;\n try {\n descriptors = Object.getOwnPropertyDescriptors(value);\n } catch {\n // A proxy trap must not replace the database failure being reported.\n return;\n }\n\n for (const [key, descriptor] of Object.entries(descriptors)) {\n if (key !== 'length' && 'value' in descriptor) {\n collectSensitiveValues(descriptor.value, output, seen);\n }\n }\n}\n\nfunction collectSqlLiterals(sql: string, output: Set<string>): void {\n // Some drivers include the complete statement in their diagnostics. Treat\n // an exact echo as sensitive even when it contains no parseable literals.\n if (sql) output.add(sql);\n\n for (const match of sql.matchAll(/'((?:''|[^'])*)'/gu)) {\n const literal = match[1].replaceAll(\"''\", \"'\");\n if (literal) output.add(literal);\n }\n\n for (const match of sql.matchAll(/\\$\\$([\\s\\S]*?)\\$\\$/gu)) {\n if (match[1]) output.add(match[1]);\n }\n\n for (const match of sql.matchAll(\n /\\$([A-Za-z_][A-Za-z0-9_]*)\\$([\\s\\S]*?)\\$\\1\\$/gu,\n )) {\n if (match[2]) output.add(match[2]);\n }\n\n for (const match of sql.matchAll(SQL_NUMERIC_LITERAL)) {\n output.add(match[0]);\n output.add(match[0].replaceAll('_', ''));\n }\n}\n\nfunction contextSecrets(context: Record<string, unknown>): string[] {\n const output = new Set<string>();\n for (const [key, value] of Object.entries(context)) {\n if (/^(?:args?|parameters?|params?|values?)$/i.test(key)) {\n collectSensitiveValues(value, output, new Set());\n } else if (\n /^(?:queries|query|sql)$/i.test(key) &&\n typeof value === 'string'\n ) {\n collectSqlLiterals(value, output);\n }\n }\n return [...output];\n}\n\nfunction sanitizeContextValue(\n value: unknown,\n knownSecrets: readonly string[],\n seen: WeakSet<object>,\n): unknown {\n if (typeof value === 'string') {\n return redactDatabaseErrorText(value, knownSecrets);\n }\n if (!value || typeof value !== 'object') return value;\n if (seen.has(value)) return '[circular]';\n seen.add(value);\n\n if (Array.isArray(value)) {\n return value.map((entry) =>\n sanitizeContextValue(entry, knownSecrets, seen),\n );\n }\n\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, entry]) => [\n key,\n isCredentialKey(key)\n ? '[redacted]'\n : sanitizeContextValue(entry, knownSecrets, seen),\n ]),\n );\n}\n\nfunction sanitizeDatabaseErrorContext(\n context: Record<string, unknown>,\n knownSecrets: readonly string[],\n): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(context).map(([key, value]) => [\n key,\n SENSITIVE_CONTEXT_KEY.test(key) || isCredentialKey(key)\n ? '[redacted]'\n : sanitizeContextValue(value, knownSecrets, new WeakSet()),\n ]),\n );\n}\n\nfunction formatDbErrorWithSecrets(\n error: unknown,\n knownSecrets: readonly string[],\n): string {\n const dbError = toDriverError(error);\n\n const parts: string[] = [];\n\n if (dbError.message) {\n parts.push(redactDatabaseErrorText(dbError.message, knownSecrets));\n }\n if (dbError.code) {\n parts.push(`code=${redactDatabaseErrorText(dbError.code, knownSecrets)}`);\n }\n if (dbError.detail) {\n parts.push(\n `detail=${redactDatabaseErrorText(dbError.detail, knownSecrets)}`,\n );\n }\n if (dbError.hint) {\n parts.push(`hint=${redactDatabaseErrorText(dbError.hint, knownSecrets)}`);\n }\n if (dbError.severity) {\n parts.push(\n `severity=${redactDatabaseErrorText(dbError.severity, knownSecrets)}`,\n );\n }\n if (dbError.errno !== undefined) parts.push(`errno=${dbError.errno}`);\n\n return parts.length > 0\n ? parts.join(', ')\n : redactDatabaseErrorText(String(error), knownSecrets);\n}\n\nfunction safeDatabaseCause(\n error: unknown,\n knownSecrets: readonly string[],\n): Error {\n const dbError = toDriverError(error);\n const message = dbError.message\n ? redactDatabaseErrorText(dbError.message, knownSecrets)\n : formatDbErrorWithSecrets(error, knownSecrets);\n const cause = new Error(message);\n cause.name = dbError.name\n ? redactDatabaseErrorText(dbError.name, knownSecrets)\n : 'DatabaseDriverError';\n\n for (const field of DRIVER_ERROR_FIELDS) {\n const value = dbError[field];\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n Object.defineProperty(cause, field, {\n configurable: true,\n enumerable: true,\n value:\n typeof value === 'string'\n ? redactDatabaseErrorText(value, knownSecrets)\n : value,\n writable: true,\n });\n }\n }\n\n return cause;\n}\n\n/**\n * Wraps an engine failure in a serializable, secret-safe DatabaseError.\n *\n * Raw SQL and parameter values are replaced in context. The native `cause` is\n * a sanitized driver-error snapshot rather than the original object so normal\n * Error inspection cannot bypass the same redaction applied to messages and\n * JSON serialization.\n */\nexport function wrapDatabaseError(\n message: string,\n error: unknown,\n context: Record<string, unknown> = {},\n): DatabaseError {\n const knownSecrets = contextSecrets(context);\n const originalError = formatDbErrorWithSecrets(error, knownSecrets);\n return new DatabaseError(\n `${message}: ${originalError}`,\n {\n ...sanitizeDatabaseErrorContext(context, knownSecrets),\n originalError,\n },\n safeDatabaseCause(error, knownSecrets),\n );\n}\n\n/**\n * Resolves the column list for a multi-row INSERT and rejects batches whose\n * records disagree on it.\n *\n * A batch INSERT emits one column list for the whole statement, so it can only\n * come from the first record. That leaves two ways for a later record to be\n * written wrongly, both of them silent:\n *\n * - Its keys are the same but in a different insertion order. Callers that\n * bound values with `Object.values(record)` bound them by position, so the\n * values cross-assigned into each other's columns. Projecting each record\n * through the returned column list — `keys.map((key) => record[key])` — is\n * what makes key order irrelevant, and every caller must do it.\n * - Its key set genuinely differs. An extra key has no column to go to and a\n * missing one has no value, so the record cannot be expressed by this\n * statement at all. Guessing (dropping the extra, writing NULL for the\n * missing) is what makes the failure invisible, so this throws instead.\n *\n * A key whose value is `undefined` counts as absent. Adapters that serialize\n * records first drop such keys before this point while the rest pass them\n * through, so comparing raw key lists would make the same batch throw on some\n * adapters and silently write NULL on others. Only the comparison ignores them;\n * the returned column list is untouched, so each adapter keeps its own\n * single-record handling of `undefined`.\n *\n * @param table - Table being inserted into, for error context\n * @param records - Non-empty batch, as the adapter will bind it\n * @returns Column list taken from the first record\n * @throws DatabaseError if any later record's key set differs from the first's\n */\nexport function resolveInsertColumns(\n table: string,\n records: Record<string, any>[],\n): string[] {\n const definedKeys = (record: Record<string, any>) =>\n new Set(Object.keys(record).filter((key) => record[key] !== undefined));\n\n const keys = Object.keys(records[0]);\n const expected = definedKeys(records[0]);\n\n for (let index = 1; index < records.length; index++) {\n const recordKeys = definedKeys(records[index]);\n const missing = [...expected].filter((key) => !recordKeys.has(key));\n const extra = [...recordKeys].filter((key) => !expected.has(key));\n\n if (missing.length === 0 && extra.length === 0) {\n continue;\n }\n\n const problems = [\n missing.length > 0 ? `missing ${missing.join(', ')}` : '',\n extra.length > 0 ? `unexpected ${extra.join(', ')}` : '',\n ].filter(Boolean);\n\n throw new DatabaseError(\n `Batch insert records must all have the same keys; record ${index} has ${problems.join(\n ' and ',\n )} relative to record 0 (${[...expected].join(', ')})`,\n {\n table,\n recordIndex: index,\n expectedKeys: keys,\n recordKeys: [...recordKeys],\n missing,\n extra,\n hint: 'A batch INSERT writes one column list for every row, taken from the first record, so record 0 defines the columns even when it is the one that looks wrong. A key whose value is undefined counts as absent. Split records with differing keys into separate insert() calls, or fill the gaps explicitly with null.',\n },\n );\n }\n\n return keys;\n}\n\n/**\n * Map of valid SQL operators for use in WHERE clauses\n */\nconst VALID_OPERATORS = {\n '=': '=',\n '>': '>',\n '>=': '>=',\n '<': '<',\n '<=': '<=',\n '!=': '!=',\n like: 'LIKE',\n contains: 'CONTAINS',\n in: 'IN',\n 'not in': 'NOT IN',\n} as const;\n\nfunction isSimpleSqlIdentifier(field: string): boolean {\n return /^[a-zA-Z0-9_.]+$/.test(field);\n}\n\ndeclare const rawSqlKeyBrand: unique symbol;\n\n/**\n * A WHERE-clause key produced by {@link raw}: SQL text the caller vouches for,\n * exempt from the identifier validation `buildWhere` applies to every other key.\n */\nexport type RawSqlKey = string & { readonly [rawSqlKeyBrand]: true };\n\n/**\n * Marks a condition key as caller-authored SQL text.\n *\n * A fixed, non-secret sentinel rather than a random per-process token. A random\n * token has to travel inside the key, which means it reaches every place a key\n * is echoed — error messages, logs, each adapter's `DatabaseError` context — and\n * one disclosure would let a caller mint raw keys for the life of the process.\n * A registry of minted expressions avoids that but is not referentially\n * transparent: it would make `raw('revenue >')` in one query change what the\n * plain key `'revenue >'` means in every other one.\n *\n * The NUL delimiters cannot appear in an identifier or in SQL a developer would\n * write, so the marker never collides with a legitimate key.\n */\nconst RAW_KEY_PREFIX = '\\u0000hv-sql-raw\\u0000';\n\n/**\n * Marks a WHERE-clause key as SQL expression text rather than an identifier.\n *\n * {@link buildWhere} validates every condition key as a plain identifier. Wrap a\n * key in `raw()` to opt one condition out of that check:\n *\n * ```typescript\n * buildWhere({\n * status: 'paid', // validated as an identifier\n * [raw('SUM(total) >')]: 100, // caller-authored SQL, not validated\n * });\n * ```\n *\n * Never build the argument from end-user input. `raw()` is an assertion that\n * the caller, not the request, authored this SQL.\n *\n * The returned key carries a marker, so it is a distinct string from the bare\n * expression: minting `raw('revenue >')` never changes what the plain key\n * `'revenue >'` means anywhere else.\n *\n * The marker is a fixed sentinel, not a secret. It stops an expression key being\n * used by accident — the shape of the key no longer grants raw access, a call to\n * `raw()` does — but a caller that controls a whole key string verbatim,\n * including the NUL-delimited marker, can still reproduce it. Validate at your\n * own trust boundary; do not rely on this as the only barrier against hostile\n * input.\n *\n * Enforcement is at runtime: `WhereClause` keys are plain `string`, so a\n * computed key widens and TypeScript will not reject an unmarked expression key\n * at the call site.\n *\n * A trailing operator is recognised only if it is one of `=`, `!=`, `>`, `>=`,\n * `<`, `<=`, `like`, `contains`, `in`, `not in`. Any other trailing token is\n * treated as part of the expression and `=` is appended, so\n * `raw('name ILIKE')` silently emits `name ILIKE = $1`, which the database then\n * rejects. Fold an unsupported operator into the expression instead:\n * `raw('LOWER(name) like')`.\n *\n * @param expression - SQL field or expression text, optionally ending in a\n * supported operator (for example `SUM(total) >`)\n * @returns A branded key for use in a {@link WhereClause}\n * @throws If the expression is empty\n */\nexport function raw(expression: string): RawSqlKey {\n // Unwrap first so raw(raw(x)) === raw(x) and a marker can never nest into the\n // emitted SQL.\n const trimmed = unwrapRawKey(expression).key.trim();\n if (!trimmed) {\n throw new Error('raw() requires a non-empty SQL expression');\n }\n return `${RAW_KEY_PREFIX}${trimmed}` as RawSqlKey;\n}\n\n/**\n * Splits the raw marker off a condition key.\n * @internal\n */\nexport function unwrapRawKey(fullKey: string): {\n key: string;\n isRaw: boolean;\n} {\n return fullKey.startsWith(RAW_KEY_PREFIX)\n ? { key: fullKey.slice(RAW_KEY_PREFIX.length), isRaw: true }\n : { key: fullKey, isRaw: false };\n}\n\nexport function parseConditionKey(fullKey: string): {\n field: string;\n operator: string;\n} {\n const trimmed = fullKey.trim();\n const lower = trimmed.toLowerCase();\n const operators = [\n 'not in',\n 'contains',\n 'like',\n 'in',\n '!=',\n '>=',\n '<=',\n '>',\n '<',\n '=',\n ];\n\n for (const operator of operators) {\n if (lower.endsWith(` ${operator}`)) {\n return {\n field: trimmed.slice(0, -(operator.length + 1)).trim(),\n operator,\n };\n }\n }\n\n // Deliberately no `explicitOperator` flag: \"key ends in an operator\" was the\n // condition that used to suppress identifier validation, and that was the\n // vulnerability. Nothing should gate trust on the shape of the key again.\n return { field: trimmed, operator: '=' };\n}\n\n/**\n * SQL adapter type for adapter-specific query generation\n */\nexport type SqlAdapterType = 'sqlite' | 'postgres' | 'duckdb' | 'json';\n\n/**\n * Builds a single condition for a WHERE clause\n * @internal\n */\nconst buildCondition = (\n fullKey: string,\n value: any,\n currIndex: { value: number },\n adapterType?: SqlAdapterType,\n): { sql: string; values: any[] } => {\n const { key, isRaw } = unwrapRawKey(fullKey);\n const { field, operator } = parseConditionKey(key);\n if (!isRaw && !isSimpleSqlIdentifier(field)) {\n throw new Error(\n `Invalid SQL identifier: ${field}. Condition keys must be plain ` +\n 'identifiers; wrap developer-authored SQL expressions in raw().',\n );\n }\n const sqlOperator =\n VALID_OPERATORS[operator as keyof typeof VALID_OPERATORS] || '=';\n const values: any[] = [];\n\n let sql: string;\n\n if (sqlOperator === 'CONTAINS') {\n if (!adapterType) {\n throw new Error(\n 'CONTAINS requires an adapter type so buildWhere can preserve case-sensitive semantics',\n );\n }\n if (typeof value !== 'string') {\n throw new Error('CONTAINS requires a string value');\n }\n\n const placeholder = `$${currIndex.value++}`;\n const containsFunction = adapterType === 'sqlite' ? 'instr' : 'strpos';\n sql = `${containsFunction}(${field}, ${placeholder}) > 0`;\n values.push(value);\n } else if (value === null) {\n sql = `${field} IS ${sqlOperator === '=' ? 'NULL' : 'NOT NULL'}`;\n } else if (\n (sqlOperator === 'IN' || sqlOperator === 'NOT IN') &&\n Array.isArray(value)\n ) {\n if (value.length === 0) {\n throw new Error(`${sqlOperator} requires at least one value`);\n }\n const placeholders = value.map(() => `$${currIndex.value++}`).join(', ');\n sql = `${field} ${sqlOperator} (${placeholders})`;\n values.push(...value);\n } else if (value instanceof Date) {\n // DuckDB/JSON need CAST to TIMESTAMP to prevent ANY type inference (issue #540)\n // SQLite/PostgreSQL handle ISO strings natively without CAST\n const needsCast = adapterType === 'duckdb' || adapterType === 'json';\n if (needsCast) {\n sql = `${field} ${sqlOperator} CAST($${currIndex.value++} AS TIMESTAMP)${\n sqlOperator === 'LIKE' ? \" ESCAPE '\\\\'\" : ''\n }`;\n } else {\n sql = `${field} ${sqlOperator} $${currIndex.value++}${\n sqlOperator === 'LIKE' ? \" ESCAPE '\\\\'\" : ''\n }`;\n }\n values.push(value.toISOString());\n } else {\n sql = `${field} ${sqlOperator} $${currIndex.value++}${\n sqlOperator === 'LIKE' ? \" ESCAPE '\\\\'\" : ''\n }`;\n values.push(value);\n }\n\n return { sql, values };\n};\n\n/**\n * Builds a SQL WHERE clause with parameterized values and flexible operators\n *\n * @param where - Conditions as object (AND-only) or 2D array (OR/AND compound)\n * @param startIndex - Starting index for parameter numbering (default: 1)\n * @param adapterType - Database adapter type. Controls Date and `contains`\n * handling:\n * - `'duckdb'` / `'json'`: Wraps Date values in `CAST($N AS TIMESTAMP)` to\n * prevent DuckDB ANY-type inference issues.\n * - `'sqlite'` / `'postgres'` / `undefined`: Passes ISO strings directly\n * (these adapters handle ISO timestamp strings natively).\n * - Required for `contains`, whose case-sensitive literal substring SQL is\n * emitted with adapter-specific functions.\n *\n * Every condition key is validated as a plain SQL identifier, with or without\n * an operator suffix. To use expression text as a key, wrap it in {@link raw}:\n *\n * ```typescript\n * buildWhere({ [raw('LOWER(status) =')]: 'paid' });\n * ```\n *\n * `raw()` is the only way to reach expression text, so mapping untrusted input\n * into a condition key throws rather than emitting attacker-controlled SQL.\n *\n * @returns Object containing the SQL clause and array of values\n * @throws If a key that is not wrapped in {@link raw} is not a plain identifier\n *\n * @example Basic Usage (Object format - AND-only):\n * ```typescript\n * buildWhere({\n * 'status': 'active', // equals operator is default\n * 'price >': 100, // greater than\n * 'stock <=': 5, // less than or equal\n * 'category in': ['A', 'B'], // IN clause for arrays\n * 'name like': '%shirt%', // LIKE pattern; backslash escapes `%` / `_`\n * 'notes contains': '100% off' // literal, case-sensitive substring\n * });\n * ```\n *\n * @example 2D Array Format (OR/AND compound logic):\n * ```typescript\n * // WHERE (status = 'active' AND price > 100) OR (status = 'pending' AND priority = 'high')\n * buildWhere([\n * [{ status: 'active' }, { 'price >': 100 }],\n * [{ status: 'pending' }, { priority: 'high' }]\n * ]);\n * ```\n *\n * @example NULL Handling:\n * ```typescript\n * buildWhere({\n * 'deleted_at': null, // becomes \"deleted_at IS NULL\"\n * 'updated_at !=': null, // becomes \"updated_at IS NOT NULL\"\n * 'status': 'active' // regular comparison\n * });\n * ```\n *\n * @example Common Patterns:\n * ```typescript\n * // Price range\n * buildWhere({\n * 'price >=': 10,\n * 'price <': 100\n * });\n *\n * // Date filtering\n * buildWhere({\n * 'created_at >': startDate,\n * 'created_at <=': endDate,\n * 'deleted_at': null\n * });\n *\n * // Search with LIKE\n * buildWhere({\n * 'title like': '%search%',\n * 'description like': '%search%',\n * 'status': 'published'\n * });\n *\n * // Multiple values with IN\n * buildWhere({\n * 'role in': ['admin', 'editor'],\n * 'active': true,\n * 'last_login !=': null\n * });\n * ```\n *\n * The function handles:\n * - Standard comparisons (=, >, >=, <, <=, !=)\n * - NULL checks (IS NULL, IS NOT NULL)\n * - IN clauses for arrays\n * - LIKE for pattern matching with an explicit backslash escape character\n * - Case-sensitive literal substring matching with `contains`\n * - Object format: Multiple conditions combined with AND\n * - 2D array format: Inner arrays ANDed, outer array ORed\n */\nexport const buildWhere = (\n where: WhereClause,\n startIndex = 1,\n adapterType?: SqlAdapterType,\n) => {\n let sql = '';\n const values: any[] = [];\n const currIndex = { value: startIndex };\n\n // Handle 2D array format for OR/AND compound logic\n if (Array.isArray(where)) {\n if (where.length === 0) {\n return { sql: '', values: [] };\n }\n\n const orGroups: string[] = [];\n\n for (const andGroup of where) {\n if (!Array.isArray(andGroup) || andGroup.length === 0) {\n continue;\n }\n\n const andConditions: string[] = [];\n\n for (const conditionObj of andGroup) {\n for (const [fullKey, value] of Object.entries(conditionObj)) {\n const result = buildCondition(fullKey, value, currIndex, adapterType);\n andConditions.push(result.sql);\n values.push(...result.values);\n }\n }\n\n if (andConditions.length > 0) {\n // Wrap AND group in parentheses\n orGroups.push(`(${andConditions.join(' AND ')})`);\n }\n }\n\n if (orGroups.length > 0) {\n sql = `WHERE ${orGroups.join(' OR ')}`;\n }\n\n return { sql, values };\n }\n\n // Handle object format (original behavior - AND-only)\n if (where && Object.keys(where).length > 0) {\n sql = 'WHERE ';\n for (const [fullKey, value] of Object.entries(where)) {\n const result = buildCondition(fullKey, value, currIndex, adapterType);\n\n if (sql !== 'WHERE ') {\n sql += ' AND ';\n }\n\n sql += result.sql;\n values.push(...result.values);\n }\n }\n\n return { sql, values };\n};\n","/**\n * Schema management and dependency resolution for JSON manifests\n * Moved from SMRT package to SQL package for proper separation of concerns\n */\n\nimport type {\n DatabaseInterface,\n IndexDefinition,\n SchemaDefinition,\n SchemaInitializationOptions,\n TriggerDefinition,\n} from './shared/types.js';\n\n/**\n * Result returned by DatabaseSchemaManager.initializeSchemas()\n *\n * Contains the list of schemas that were successfully initialized,\n * any that were skipped (already up to date), errors encountered,\n * and the total execution time in milliseconds.\n */\nexport interface SchemaInitializationResult {\n initialized: string[];\n skipped: string[];\n errors: Array<{ schema: string; error: string }>;\n executionTime: number;\n}\n\n/**\n * Manages schema initialization from JSON manifests with dependency resolution\n *\n * Handles topological sorting of schema dependencies, table creation,\n * index and trigger setup, and version tracking to avoid redundant re-initialization.\n */\nexport class DatabaseSchemaManager {\n private static initializationLock = new Map<string, Promise<void>>();\n private initializedSchemas = new Set<string>();\n private schemaVersions = new Map<string, string>();\n\n /**\n * Initializes database schemas from a JSON manifest with dependency resolution\n *\n * Schemas are topologically sorted by their declared dependencies and\n * initialized in order. Supports legacy raw-SQL schemas via the `schema` option,\n * JSON manifests via the `manifest` option, and schema overrides for extending\n * base schemas.\n *\n * @param db - Database interface to execute DDL against\n * @param options - Schema initialization options (manifest, overrides, force, debug)\n * @returns Result with lists of initialized/skipped schemas, errors, and execution time\n */\n async initializeSchemas(\n db: DatabaseInterface,\n options: SchemaInitializationOptions,\n ): Promise<SchemaInitializationResult> {\n const startTime = Date.now();\n const result: SchemaInitializationResult = {\n initialized: [],\n skipped: [],\n errors: [],\n executionTime: 0,\n };\n\n try {\n let schemas: Record<string, SchemaDefinition> = {};\n\n // Handle legacy SQL schema format\n if (options.schema) {\n console.log(\n '[schema] Legacy SQL schema provided, converting to manifest format',\n );\n // For legacy support, we'll still use the original syncSchema method\n if (db.syncSchema) {\n await db.syncSchema(options.schema);\n result.initialized.push('legacy-sql');\n }\n result.executionTime = Date.now() - startTime;\n return result;\n }\n\n // Handle JSON manifest format\n if (options.manifest) {\n schemas = { ...options.manifest.schemas };\n }\n\n // Apply schema overrides\n if (options.overrides) {\n schemas = { ...schemas, ...options.overrides };\n }\n\n if (Object.keys(schemas).length === 0) {\n console.warn('[schema] No schemas provided for initialization');\n result.executionTime = Date.now() - startTime;\n return result;\n }\n\n // Build dependency graph\n const dependencyGraph = this.buildDependencyGraph(schemas);\n\n // Get initialization order\n const initializationOrder = this.resolveDependencies(dependencyGraph);\n\n if (options.debug) {\n console.log('[schema] Initialization order:', initializationOrder);\n }\n\n // Initialize schemas in dependency order\n for (const schemaName of initializationOrder) {\n const schema = schemas[schemaName];\n if (!schema) continue;\n\n try {\n await this.initializeSchema(db, schemaName, schema, {\n force: options.force,\n debug: options.debug,\n });\n result.initialized.push(schemaName);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n result.errors.push({ schema: schemaName, error: errorMessage });\n\n if (options.debug) {\n console.error(\n `[schema] Failed to initialize ${schemaName}:`,\n error,\n );\n }\n }\n }\n\n result.executionTime = Date.now() - startTime;\n\n if (options.debug) {\n console.log('[schema] Initialization complete:', result);\n }\n\n return result;\n } catch (error) {\n result.executionTime = Date.now() - startTime;\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n result.errors.push({\n schema: 'dependency-resolution',\n error: errorMessage,\n });\n return result;\n }\n }\n\n /**\n * Initialize a single schema\n */\n private async initializeSchema(\n db: DatabaseInterface,\n schemaName: string,\n schema: SchemaDefinition,\n options: { force?: boolean; debug?: boolean },\n ): Promise<void> {\n const { tableName, version } = schema;\n const lockKey = `${schemaName}:${tableName}`;\n\n // Check if already being initialized\n if (DatabaseSchemaManager.initializationLock.has(lockKey)) {\n await DatabaseSchemaManager.initializationLock.get(lockKey);\n return;\n }\n\n // Check if already initialized and up to date\n if (!options.force && this.isSchemaUpToDate(schemaName, version)) {\n if (options.debug) {\n console.log(`[schema] Skipping ${schemaName} - already up to date`);\n }\n return;\n }\n\n // Create initialization promise\n const initPromise = this.performSchemaInitialization(\n db,\n schemaName,\n schema,\n options,\n );\n DatabaseSchemaManager.initializationLock.set(lockKey, initPromise);\n\n try {\n await initPromise;\n this.markSchemaInitialized(schemaName, version);\n } finally {\n DatabaseSchemaManager.initializationLock.delete(lockKey);\n }\n }\n\n /**\n * Perform the actual schema initialization\n */\n private async performSchemaInitialization(\n db: DatabaseInterface,\n schemaName: string,\n schema: SchemaDefinition,\n options: { force?: boolean; debug?: boolean },\n ): Promise<void> {\n const { tableName, columns, indexes, triggers } = schema;\n\n if (options.debug) {\n console.log(`[schema] Initializing ${schemaName} (${tableName})`);\n }\n\n // Check if table exists\n const tableExists = await db.tableExists(tableName);\n\n if (!tableExists) {\n // Create table\n await this.createTable(db, schema);\n\n // Create indexes\n for (const index of indexes) {\n await this.createIndex(db, tableName, index);\n }\n\n // Create triggers\n for (const trigger of triggers) {\n await this.createTrigger(db, trigger);\n }\n } else if (options.force) {\n // Recreate table if forced\n await db.query(`DROP TABLE IF EXISTS ${tableName}`);\n await this.createTable(db, schema);\n\n for (const index of indexes) {\n await this.createIndex(db, tableName, index);\n }\n\n for (const trigger of triggers) {\n await this.createTrigger(db, trigger);\n }\n } else {\n // Table exists, check for schema changes\n await this.updateSchemaIfNeeded(db, schema);\n }\n }\n\n /**\n * Create table from schema definition\n */\n private async createTable(\n db: DatabaseInterface,\n schema: SchemaDefinition,\n ): Promise<void> {\n const { tableName, columns, foreignKeys } = schema;\n\n const columnDefinitions: string[] = [];\n\n // Add column definitions\n for (const [columnName, columnDef] of Object.entries(columns)) {\n let def = `${columnName} ${columnDef.type}`;\n\n if (columnDef.primaryKey) def += ' PRIMARY KEY';\n if (columnDef.unique && !columnDef.primaryKey) def += ' UNIQUE';\n if (columnDef.notNull) def += ' NOT NULL';\n if (columnDef.defaultValue !== undefined) {\n def += ` DEFAULT ${columnDef.defaultValue}`;\n }\n if (columnDef.check) def += ` CHECK (${columnDef.check})`;\n\n columnDefinitions.push(def);\n }\n\n // Add foreign key constraints\n for (const fk of foreignKeys) {\n let fkDef = `FOREIGN KEY (${fk.column}) REFERENCES ${fk.referencesTable}(${fk.referencesColumn})`;\n if (fk.onDelete) fkDef += ` ON DELETE ${fk.onDelete}`;\n if (fk.onUpdate) fkDef += ` ON UPDATE ${fk.onUpdate}`;\n columnDefinitions.push(fkDef);\n }\n\n const createTableSQL = `CREATE TABLE ${tableName} (\\n ${columnDefinitions.join(',\\n ')}\\n)`;\n await db.query(createTableSQL);\n }\n\n /**\n * Create index from definition\n */\n private async createIndex(\n db: DatabaseInterface,\n tableName: string,\n index: IndexDefinition,\n ): Promise<void> {\n const uniqueClause = index.unique ? 'UNIQUE ' : '';\n const whereClause = index.where ? ` WHERE ${index.where}` : '';\n const createIndexSQL = `CREATE ${uniqueClause}INDEX ${index.name} ON ${tableName} (${index.columns.join(', ')})${whereClause}`;\n\n await db.query(createIndexSQL);\n }\n\n /**\n * Create trigger from definition\n */\n private async createTrigger(\n db: DatabaseInterface,\n trigger: TriggerDefinition,\n ): Promise<void> {\n const conditionClause = trigger.condition\n ? ` WHEN ${trigger.condition}`\n : '';\n const createTriggerSQL = `CREATE TRIGGER ${trigger.name} ${trigger.when} ${trigger.event} ON ${trigger.table}${conditionClause} BEGIN ${trigger.body} END`;\n\n await db.query(createTriggerSQL);\n }\n\n /**\n * Update schema if changes are detected\n */\n private async updateSchemaIfNeeded(\n _db: DatabaseInterface,\n schema: SchemaDefinition,\n ): Promise<void> {\n // For now, just log that update is needed\n // In future, implement ALTER TABLE logic\n console.log(\n `[schema] Schema update logic not yet implemented for ${schema.tableName}`,\n );\n }\n\n /**\n * Build dependency graph from schemas\n */\n private buildDependencyGraph(\n schemas: Record<string, SchemaDefinition>,\n ): Map<string, string[]> {\n const graph = new Map<string, string[]>();\n\n for (const [schemaName, schema] of Object.entries(schemas)) {\n const dependencies = schema.dependencies.filter((dep) =>\n Object.values(schemas).some((s) => s.tableName === dep),\n );\n graph.set(\n schemaName,\n dependencies.map(\n (dep) =>\n Object.entries(schemas).find(\n ([_, s]) => s.tableName === dep,\n )?.[0] || dep,\n ),\n );\n }\n\n return graph;\n }\n\n /**\n * Resolve dependencies using topological sort\n */\n private resolveDependencies(graph: Map<string, string[]>): string[] {\n const resolved: string[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>();\n\n const visit = (node: string) => {\n if (visiting.has(node)) {\n throw new Error(`Circular dependency detected involving ${node}`);\n }\n if (visited.has(node)) return;\n\n visiting.add(node);\n const dependencies = graph.get(node) || [];\n\n for (const dep of dependencies) {\n if (graph.has(dep)) {\n visit(dep);\n }\n }\n\n visiting.delete(node);\n visited.add(node);\n resolved.push(node);\n };\n\n for (const node of graph.keys()) {\n if (!visited.has(node)) {\n visit(node);\n }\n }\n\n return resolved;\n }\n\n /**\n * Check if schema is up to date\n */\n private isSchemaUpToDate(schemaName: string, version: string): boolean {\n return (\n this.initializedSchemas.has(schemaName) &&\n this.schemaVersions.get(schemaName) === version\n );\n }\n\n /**\n * Mark schema as initialized\n */\n private markSchemaInitialized(schemaName: string, version: string): void {\n this.initializedSchemas.add(schemaName);\n this.schemaVersions.set(schemaName, version);\n }\n\n /**\n * Reset initialization state (for testing)\n */\n reset(): void {\n this.initializedSchemas.clear();\n this.schemaVersions.clear();\n DatabaseSchemaManager.initializationLock.clear();\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { l as ConnectionCache } from "./postgres-dialect-Bfswr4Vs.js";
1
+ import { l as ConnectionCache } from "./postgres-dialect-CGv6DxSP.js";
2
2
  //#region src/shared/sqlite-connection-cache.ts
3
3
  var sqliteConnectionCache = new ConnectionCache();
4
4
  var sqliteCacheGroups = /* @__PURE__ */ new Map();
@@ -67,4 +67,4 @@ async function getCachedSqliteDatabase(path, options, create) {
67
67
  //#endregion
68
68
  export { getCachedSqliteDatabase as t };
69
69
 
70
- //# sourceMappingURL=sqlite-connection-cache-ChWav9iY.js.map
70
+ //# sourceMappingURL=sqlite-connection-cache-CYThh9l5.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-connection-cache-ChWav9iY.js","names":[],"sources":["../../src/shared/sqlite-connection-cache.ts"],"sourcesContent":["import { ConnectionCache } from './connection-cache';\nimport type { DatabaseInterface, DatabaseOptions } from './types';\n\nexport type SqliteAdapterPath = 'libsql' | 'native' | 'secure';\n\nconst sqliteConnectionCache = new ConnectionCache<DatabaseInterface>();\ntype SqliteCacheGroup = {\n barrier?: Promise<void>;\n failure?: unknown;\n hasFailure: boolean;\n};\nconst sqliteCacheGroups = new Map<string, SqliteCacheGroup>();\n\nconst cacheKey = (dbid: string, path: SqliteAdapterPath) =>\n `sqlite:${path}:${dbid}`;\n\nasync function closeSqliteDatabase(db: DatabaseInterface): Promise<void> {\n await db.close?.();\n}\n\nasync function clearSqliteCacheGroup(dbid: string): Promise<void> {\n const group = sqliteCacheGroups.get(dbid) ?? { hasFailure: false };\n sqliteCacheGroups.set(dbid, group);\n const previous = group.barrier;\n const barrier = (previous?.catch(() => {}) ?? Promise.resolve()).then(\n async () => {\n const results = await Promise.allSettled([\n sqliteConnectionCache.evict(\n cacheKey(dbid, 'libsql'),\n closeSqliteDatabase,\n ),\n sqliteConnectionCache.evict(\n cacheKey(dbid, 'native'),\n closeSqliteDatabase,\n ),\n sqliteConnectionCache.evict(\n cacheKey(dbid, 'secure'),\n closeSqliteDatabase,\n ),\n ]);\n const failures = results.filter(\n (result): result is PromiseRejectedResult =>\n result.status === 'rejected',\n );\n if (failures.length) {\n group.failure =\n failures.length === 1\n ? failures[0].reason\n : new AggregateError(\n failures.map((failure) => failure.reason),\n 'Multiple SQLite adapter paths failed to clear',\n );\n group.hasFailure = true;\n throw group.failure;\n }\n group.failure = undefined;\n group.hasFailure = false;\n },\n );\n group.barrier = barrier;\n try {\n await barrier;\n } finally {\n if (group.barrier === barrier) {\n group.barrier = undefined;\n if (!group.hasFailure) sqliteCacheGroups.delete(dbid);\n }\n }\n}\n\nasync function awaitSqliteCacheGroup(dbid: string): Promise<void> {\n const group = sqliteCacheGroups.get(dbid);\n if (!group) return;\n if (group.barrier) await group.barrier;\n if (group.hasFailure) throw group.failure;\n}\n\nexport async function getCachedSqliteDatabase(\n path: SqliteAdapterPath,\n options: DatabaseOptions,\n create: () => Promise<DatabaseInterface>,\n): Promise<DatabaseInterface> {\n const { dbid } = options;\n if (dbid && options.clearCache) {\n await clearSqliteCacheGroup(dbid);\n } else if (dbid) {\n await awaitSqliteCacheGroup(dbid);\n }\n\n return sqliteConnectionCache.getOrCreate(\n dbid ? cacheKey(dbid, path) : undefined,\n { ...options, clearCache: false },\n async () => {\n const db = await create();\n const originalClose = db.close?.bind(db);\n let closePromise: Promise<void> | undefined;\n db.close = async () => {\n if (!closePromise) {\n closePromise = originalClose?.() ?? Promise.resolve();\n }\n try {\n await closePromise;\n sqliteConnectionCache.forget(db);\n } catch (error) {\n closePromise = undefined;\n throw error;\n }\n };\n // Secure SQLite exposes a guarded public client.close() seam. Route it\n // through the same cache-aware close boundary so a direct client close\n // cannot leave a closed adapter cached under an explicit dbid.\n if ((db.client as any)?.transactionReservation === 'exclusive') {\n (db.client as any).close = db.close;\n }\n return db;\n },\n closeSqliteDatabase,\n );\n}\n"],"mappings":";;AAKA,IAAM,wBAAwB,IAAI,gBAAmC;AAMrE,IAAM,oCAAoB,IAAI,IAA8B;AAE5D,IAAM,YAAY,MAAc,SAC9B,UAAU,KAAK,GAAG;AAEpB,eAAe,oBAAoB,IAAsC;CACvE,MAAM,GAAG,QAAQ;AACnB;AAEA,eAAe,sBAAsB,MAA6B;CAChE,MAAM,QAAQ,kBAAkB,IAAI,IAAI,KAAK,EAAE,YAAY,MAAM;CACjE,kBAAkB,IAAI,MAAM,KAAK;CAEjC,MAAM,WADW,MAAM,SACI,YAAY,CAAC,CAAC,KAAK,QAAQ,QAAQ,EAAA,CAAG,KAC/D,YAAY;EAeV,MAAM,YAAW,MAdK,QAAQ,WAAW;GACvC,sBAAsB,MACpB,SAAS,MAAM,QAAQ,GACvB,mBACF;GACA,sBAAsB,MACpB,SAAS,MAAM,QAAQ,GACvB,mBACF;GACA,sBAAsB,MACpB,SAAS,MAAM,QAAQ,GACvB,mBACF;EACF,CAAC,EAAA,CACwB,QACtB,WACC,OAAO,WAAW,UACtB;EACA,IAAI,SAAS,QAAQ;GACnB,MAAM,UACJ,SAAS,WAAW,IAChB,SAAS,EAAE,CAAC,SACZ,IAAI,eACF,SAAS,KAAK,YAAY,QAAQ,MAAM,GACxC,+CACF;GACN,MAAM,aAAa;GACnB,MAAM,MAAM;EACd;EACA,MAAM,UAAU,KAAA;EAChB,MAAM,aAAa;CACrB,CACF;CACA,MAAM,UAAU;CAChB,IAAI;EACF,MAAM;CACR,UAAU;EACR,IAAI,MAAM,YAAY,SAAS;GAC7B,MAAM,UAAU,KAAA;GAChB,IAAI,CAAC,MAAM,YAAY,kBAAkB,OAAO,IAAI;EACtD;CACF;AACF;AAEA,eAAe,sBAAsB,MAA6B;CAChE,MAAM,QAAQ,kBAAkB,IAAI,IAAI;CACxC,IAAI,CAAC,OAAO;CACZ,IAAI,MAAM,SAAS,MAAM,MAAM;CAC/B,IAAI,MAAM,YAAY,MAAM,MAAM;AACpC;AAEA,eAAsB,wBACpB,MACA,SACA,QAC4B;CAC5B,MAAM,EAAE,SAAS;CACjB,IAAI,QAAQ,QAAQ,YAClB,MAAM,sBAAsB,IAAI;MAC3B,IAAI,MACT,MAAM,sBAAsB,IAAI;CAGlC,OAAO,sBAAsB,YAC3B,OAAO,SAAS,MAAM,IAAI,IAAI,KAAA,GAC9B;EAAE,GAAG;EAAS,YAAY;CAAM,GAChC,YAAY;EACV,MAAM,KAAK,MAAM,OAAO;EACxB,MAAM,gBAAgB,GAAG,OAAO,KAAK,EAAE;EACvC,IAAI;EACJ,GAAG,QAAQ,YAAY;GACrB,IAAI,CAAC,cACH,eAAe,gBAAgB,KAAK,QAAQ,QAAQ;GAEtD,IAAI;IACF,MAAM;IACN,sBAAsB,OAAO,EAAE;GACjC,SAAS,OAAO;IACd,eAAe,KAAA;IACf,MAAM;GACR;EACF;EAIA,IAAK,GAAG,QAAgB,2BAA2B,aACjD,GAAI,OAAe,QAAQ,GAAG;EAEhC,OAAO;CACT,GACA,mBACF;AACF"}
1
+ {"version":3,"file":"sqlite-connection-cache-CYThh9l5.js","names":[],"sources":["../../src/shared/sqlite-connection-cache.ts"],"sourcesContent":["import { ConnectionCache } from './connection-cache';\nimport type { DatabaseInterface, DatabaseOptions } from './types';\n\nexport type SqliteAdapterPath = 'libsql' | 'native' | 'secure';\n\nconst sqliteConnectionCache = new ConnectionCache<DatabaseInterface>();\ntype SqliteCacheGroup = {\n barrier?: Promise<void>;\n failure?: unknown;\n hasFailure: boolean;\n};\nconst sqliteCacheGroups = new Map<string, SqliteCacheGroup>();\n\nconst cacheKey = (dbid: string, path: SqliteAdapterPath) =>\n `sqlite:${path}:${dbid}`;\n\nasync function closeSqliteDatabase(db: DatabaseInterface): Promise<void> {\n await db.close?.();\n}\n\nasync function clearSqliteCacheGroup(dbid: string): Promise<void> {\n const group = sqliteCacheGroups.get(dbid) ?? { hasFailure: false };\n sqliteCacheGroups.set(dbid, group);\n const previous = group.barrier;\n const barrier = (previous?.catch(() => {}) ?? Promise.resolve()).then(\n async () => {\n const results = await Promise.allSettled([\n sqliteConnectionCache.evict(\n cacheKey(dbid, 'libsql'),\n closeSqliteDatabase,\n ),\n sqliteConnectionCache.evict(\n cacheKey(dbid, 'native'),\n closeSqliteDatabase,\n ),\n sqliteConnectionCache.evict(\n cacheKey(dbid, 'secure'),\n closeSqliteDatabase,\n ),\n ]);\n const failures = results.filter(\n (result): result is PromiseRejectedResult =>\n result.status === 'rejected',\n );\n if (failures.length) {\n group.failure =\n failures.length === 1\n ? failures[0].reason\n : new AggregateError(\n failures.map((failure) => failure.reason),\n 'Multiple SQLite adapter paths failed to clear',\n );\n group.hasFailure = true;\n throw group.failure;\n }\n group.failure = undefined;\n group.hasFailure = false;\n },\n );\n group.barrier = barrier;\n try {\n await barrier;\n } finally {\n if (group.barrier === barrier) {\n group.barrier = undefined;\n if (!group.hasFailure) sqliteCacheGroups.delete(dbid);\n }\n }\n}\n\nasync function awaitSqliteCacheGroup(dbid: string): Promise<void> {\n const group = sqliteCacheGroups.get(dbid);\n if (!group) return;\n if (group.barrier) await group.barrier;\n if (group.hasFailure) throw group.failure;\n}\n\nexport async function getCachedSqliteDatabase(\n path: SqliteAdapterPath,\n options: DatabaseOptions,\n create: () => Promise<DatabaseInterface>,\n): Promise<DatabaseInterface> {\n const { dbid } = options;\n if (dbid && options.clearCache) {\n await clearSqliteCacheGroup(dbid);\n } else if (dbid) {\n await awaitSqliteCacheGroup(dbid);\n }\n\n return sqliteConnectionCache.getOrCreate(\n dbid ? cacheKey(dbid, path) : undefined,\n { ...options, clearCache: false },\n async () => {\n const db = await create();\n const originalClose = db.close?.bind(db);\n let closePromise: Promise<void> | undefined;\n db.close = async () => {\n if (!closePromise) {\n closePromise = originalClose?.() ?? Promise.resolve();\n }\n try {\n await closePromise;\n sqliteConnectionCache.forget(db);\n } catch (error) {\n closePromise = undefined;\n throw error;\n }\n };\n // Secure SQLite exposes a guarded public client.close() seam. Route it\n // through the same cache-aware close boundary so a direct client close\n // cannot leave a closed adapter cached under an explicit dbid.\n if ((db.client as any)?.transactionReservation === 'exclusive') {\n (db.client as any).close = db.close;\n }\n return db;\n },\n closeSqliteDatabase,\n );\n}\n"],"mappings":";;AAKA,IAAM,wBAAwB,IAAI,gBAAmC;AAMrE,IAAM,oCAAoB,IAAI,IAA8B;AAE5D,IAAM,YAAY,MAAc,SAC9B,UAAU,KAAK,GAAG;AAEpB,eAAe,oBAAoB,IAAsC;CACvE,MAAM,GAAG,QAAQ;AACnB;AAEA,eAAe,sBAAsB,MAA6B;CAChE,MAAM,QAAQ,kBAAkB,IAAI,IAAI,KAAK,EAAE,YAAY,MAAM;CACjE,kBAAkB,IAAI,MAAM,KAAK;CAEjC,MAAM,WADW,MAAM,SACI,YAAY,CAAC,CAAC,KAAK,QAAQ,QAAQ,EAAA,CAAG,KAC/D,YAAY;EAeV,MAAM,YAAW,MAdK,QAAQ,WAAW;GACvC,sBAAsB,MACpB,SAAS,MAAM,QAAQ,GACvB,mBACF;GACA,sBAAsB,MACpB,SAAS,MAAM,QAAQ,GACvB,mBACF;GACA,sBAAsB,MACpB,SAAS,MAAM,QAAQ,GACvB,mBACF;EACF,CAAC,EAAA,CACwB,QACtB,WACC,OAAO,WAAW,UACtB;EACA,IAAI,SAAS,QAAQ;GACnB,MAAM,UACJ,SAAS,WAAW,IAChB,SAAS,EAAE,CAAC,SACZ,IAAI,eACF,SAAS,KAAK,YAAY,QAAQ,MAAM,GACxC,+CACF;GACN,MAAM,aAAa;GACnB,MAAM,MAAM;EACd;EACA,MAAM,UAAU,KAAA;EAChB,MAAM,aAAa;CACrB,CACF;CACA,MAAM,UAAU;CAChB,IAAI;EACF,MAAM;CACR,UAAU;EACR,IAAI,MAAM,YAAY,SAAS;GAC7B,MAAM,UAAU,KAAA;GAChB,IAAI,CAAC,MAAM,YAAY,kBAAkB,OAAO,IAAI;EACtD;CACF;AACF;AAEA,eAAe,sBAAsB,MAA6B;CAChE,MAAM,QAAQ,kBAAkB,IAAI,IAAI;CACxC,IAAI,CAAC,OAAO;CACZ,IAAI,MAAM,SAAS,MAAM,MAAM;CAC/B,IAAI,MAAM,YAAY,MAAM,MAAM;AACpC;AAEA,eAAsB,wBACpB,MACA,SACA,QAC4B;CAC5B,MAAM,EAAE,SAAS;CACjB,IAAI,QAAQ,QAAQ,YAClB,MAAM,sBAAsB,IAAI;MAC3B,IAAI,MACT,MAAM,sBAAsB,IAAI;CAGlC,OAAO,sBAAsB,YAC3B,OAAO,SAAS,MAAM,IAAI,IAAI,KAAA,GAC9B;EAAE,GAAG;EAAS,YAAY;CAAM,GAChC,YAAY;EACV,MAAM,KAAK,MAAM,OAAO;EACxB,MAAM,gBAAgB,GAAG,OAAO,KAAK,EAAE;EACvC,IAAI;EACJ,GAAG,QAAQ,YAAY;GACrB,IAAI,CAAC,cACH,eAAe,gBAAgB,KAAK,QAAQ,QAAQ;GAEtD,IAAI;IACF,MAAM;IACN,sBAAsB,OAAO,EAAE;GACjC,SAAS,OAAO;IACd,eAAe,KAAA;IACf,MAAM;GACR;EACF;EAIA,IAAK,GAAG,QAAgB,2BAA2B,aACjD,GAAI,OAAe,QAAQ,GAAG;EAEhC,OAAO;CACT,GACA,mBACF;AACF"}
@@ -1,6 +1,7 @@
1
- import { D as wrapDatabaseError, S as formatDbError, T as resolveInsertColumns, _ as validateColumnNames, b as DatabaseSchemaManager, c as createTransactionLock, g as validateColumnName, h as generateCreateIndexStatement, m as generateAddColumnStatement, v as validateIndexName, x as buildWhere, y as validateTableName } from "./postgres-dialect-Bfswr4Vs.js";
2
- import { NestedTransactionError, resolveSchemas } from "../index.js";
3
- import { t as getCachedSqliteDatabase } from "./sqlite-connection-cache-ChWav9iY.js";
1
+ import { c as wrapDatabaseError, n as buildWhere, o as resolveInsertColumns, r as formatDbError, t as DatabaseSchemaManager } from "./schema-manager-cxsySSDA.js";
2
+ import { a as NestedTransactionError, o as resolveSchemas } from "./query-RzXJ4B9s.js";
3
+ import { _ as validateColumnNames, c as createTransactionLock, g as validateColumnName, h as generateCreateIndexStatement, m as generateAddColumnStatement, v as validateIndexName, y as validateTableName } from "./postgres-dialect-CGv6DxSP.js";
4
+ import { t as getCachedSqliteDatabase } from "./sqlite-connection-cache-CYThh9l5.js";
4
5
  import { DatabaseError } from "@happyvertical/utils";
5
6
  import { resolve } from "node:path";
6
7
  import { fileURLToPath } from "node:url";
@@ -1017,4 +1018,4 @@ async function createNativeSqliteDatabase(options, url) {
1017
1018
  //#endregion
1018
1019
  export { getNativeSqliteDatabase };
1019
1020
 
1020
- //# sourceMappingURL=sqlite-native--z4BnolL.js.map
1021
+ //# sourceMappingURL=sqlite-native-CsJ_BLqN.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite-native--z4BnolL.js","names":[],"sources":["../../src/sqlite-native.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { DatabaseError } from '@happyvertical/utils';\nimport { DatabaseSchemaManager } from './schema-manager.js';\nimport {\n generateAddColumnStatement,\n generateCreateIndexStatement,\n validateColumnName,\n validateColumnNames,\n validateIndexName,\n validateTableName,\n} from './shared/alter-utils.js';\nimport { getCachedSqliteDatabase } from './shared/sqlite-connection-cache.js';\nimport { createTransactionLock } from './shared/transaction-lock.js';\nimport type {\n ColumnDefinition,\n ColumnDefinitionWithName,\n DatabaseInterface,\n IndexDefinition,\n NotificationCapabilities,\n NotificationListenOptions,\n NotificationPruneOptions,\n NotificationWaitOptions,\n QueryResult,\n SchemaInitializationOptions,\n SchemaProvider,\n SqliteNotificationCapabilityOptions,\n SqliteVectorCapabilityOptions,\n TableInterface,\n TableSchemaInfo,\n TransactionHandle,\n UpsertOptions,\n VectorCapabilities,\n VectorIndexOptions,\n VectorSearchOptions,\n VectorSearchResult,\n WhereClause,\n} from './shared/types.js';\nimport { NestedTransactionError, resolveSchemas } from './shared/types.js';\nimport {\n buildWhere,\n formatDbError,\n resolveInsertColumns,\n wrapDatabaseError,\n} from './shared/utils.js';\nimport type { SqliteOptions } from './sqlite.js';\n\ntype NativeDatabase = any;\ntype NativeStatement = any;\ntype NativeCloseable = { close?: () => void };\n\n/** @internal Best-effort, retryable closer used by native SQLite. */\nexport function createNativeSqliteCloser(\n notificationCloseables: Set<NativeCloseable>,\n honkerDb: NativeCloseable | null,\n database: { close(): void },\n): () => Promise<void> {\n const completed = new Set<object>();\n let active: Promise<void> | undefined;\n return async () => {\n active ??= (async () => {\n const resources: NativeCloseable[] = [\n ...notificationCloseables,\n ...(honkerDb ? [honkerDb] : []),\n database,\n ];\n const errors: unknown[] = [];\n for (const resource of resources) {\n if (completed.has(resource)) continue;\n try {\n resource.close?.();\n completed.add(resource);\n notificationCloseables.delete(resource);\n } catch (error) {\n errors.push(error);\n }\n }\n if (errors.length === 1) throw errors[0];\n if (errors.length > 1) {\n throw new AggregateError(\n errors,\n 'Failed to close native SQLite resources',\n );\n }\n })();\n try {\n await active;\n } finally {\n active = undefined;\n }\n };\n}\n\nconst nativeNullAwareUpsertLocks = new Map<string, Promise<void>>();\nlet nodeSqliteModulePromise: Promise<any> | null = null;\n// sqlite-vector's ESM wrapper uses dynamic require for platform packages.\nconst requireOptionalPackage = createRequire(import.meta.url);\n\ninterface NativeSqliteLocation {\n location: string;\n filePath: string | null;\n isMemory: boolean;\n}\n\ninterface NativeQueryResult {\n rows: Record<string, any>[];\n rowCount: number;\n command?: string;\n fields?: Array<{ name: string }>;\n}\n\nfunction getCapabilityOptions<T extends Record<string, any>>(\n value: boolean | T | undefined,\n): T {\n return typeof value === 'object' && value ? value : ({} as T);\n}\n\nfunction resolveNativeLocation(url = ':memory:'): NativeSqliteLocation {\n if (\n url.startsWith('libsql://') ||\n url.startsWith('http://') ||\n url.startsWith('https://')\n ) {\n throw new DatabaseError(\n 'SQLite native capabilities are only supported for local SQLite databases',\n {\n url,\n hint: \"Use a local file path, 'file:...' URL, or ':memory:' when enabling SQLite capabilities.\",\n },\n );\n }\n\n if (url === ':memory:' || url.startsWith('file::memory:')) {\n return { location: url, filePath: null, isMemory: true };\n }\n\n if (url.startsWith('file://')) {\n const filePath = fileURLToPath(new URL(url));\n return { location: filePath, filePath, isMemory: false };\n }\n\n if (url.startsWith('file:')) {\n const path = url.slice('file:'.length);\n if (!path || path.includes('?')) {\n throw new DatabaseError(\n 'SQLite native capabilities do not support file: URLs with query parameters',\n { url },\n );\n }\n const filePath = resolve(path);\n return { location: filePath, filePath, isMemory: false };\n }\n\n const filePath = resolve(url);\n return { location: filePath, filePath, isMemory: false };\n}\n\nasync function loadNodeSqlite(): Promise<any> {\n nodeSqliteModulePromise ??= importNodeSqlite().catch((error) => {\n nodeSqliteModulePromise = null;\n throw error;\n });\n return nodeSqliteModulePromise;\n}\n\nasync function importNodeSqlite(): Promise<any> {\n const originalEmitWarning = process.emitWarning;\n\n try {\n process.emitWarning = function suppressNodeSqliteExperimentalWarning(\n warning: string | Error,\n ...args: any[]\n ) {\n if (\n args[0] === 'ExperimentalWarning' &&\n String(warning).includes('SQLite is an experimental feature')\n ) {\n return;\n }\n\n return originalEmitWarning.call(process, warning as any, ...args);\n } as typeof process.emitWarning;\n\n const moduleName = 'node:sqlite';\n return (await import(/* @vite-ignore */ moduleName)) as any;\n } catch (error) {\n throw new DatabaseError('Node native SQLite is not available', {\n originalError: formatDbError(error),\n hint: 'SQLite native capabilities require a Node.js runtime with node:sqlite support.',\n });\n } finally {\n process.emitWarning = originalEmitWarning;\n }\n}\n\nasync function loadSqliteVectorExtension(\n database: NativeDatabase,\n): Promise<void> {\n try {\n const moduleName = '@sqliteai/sqlite-vector';\n const module = requireOptionalPackage(moduleName) as any;\n const getExtensionPath =\n module.getExtensionPath ?? module.default?.getExtensionPath;\n\n if (typeof getExtensionPath !== 'function') {\n throw new Error('getExtensionPath export was not found');\n }\n\n database.enableLoadExtension(true);\n database.loadExtension(getExtensionPath());\n } catch (error) {\n throw new DatabaseError(\n 'Failed to load optional SQLite vector capability: install @sqliteai/sqlite-vector',\n {\n packageName: '@sqliteai/sqlite-vector',\n originalError: formatDbError(error),\n hint: 'Install @sqliteai/sqlite-vector to use SQLite vector capabilities.',\n },\n );\n } finally {\n try {\n database.enableLoadExtension(false);\n } catch (_error) {\n // Leave the original extension-loading failure intact.\n }\n }\n}\n\nasync function openHonkerDatabase(\n filePath: string,\n options: SqliteNotificationCapabilityOptions,\n): Promise<any> {\n try {\n const moduleName = '@russellthehippo/honker-node';\n const module = requireOptionalPackage(moduleName) as any;\n const open = module.open ?? module.default?.open;\n\n if (typeof open !== 'function') {\n throw new Error('open export was not found');\n }\n\n return open(filePath, options.maxReaders, options.watcherBackend);\n } catch (error) {\n throw new DatabaseError(\n 'Failed to load optional SQLite notification capability: install @russellthehippo/honker-node',\n {\n packageName: '@russellthehippo/honker-node',\n originalError: formatDbError(error),\n hint: 'Install @russellthehippo/honker-node to use SQLite notification capabilities.',\n },\n );\n }\n}\n\nfunction toPlainRow(row: Record<string, any>): Record<string, any> {\n return Object.fromEntries(Object.entries(row));\n}\n\nfunction getErrorMessage(error: unknown): string | undefined {\n return error instanceof Error ? error.message : undefined;\n}\n\nfunction firstSqlToken(sql: string): string {\n return sql.trim().split(/\\s+/)[0]?.toUpperCase() ?? '';\n}\n\nfunction normalizeNativeQuery(\n sql: string,\n values: any[],\n): { sql: string; args: any[] } {\n const flatArgs = Array.isArray(values[0]) ? values[0] : values;\n const parameterIndexes = Array.from(sql.matchAll(/\\$(\\d+)/g)).map((match) =>\n Number(match[1]),\n );\n\n if (parameterIndexes.length === 0) {\n return { sql, args: flatArgs };\n }\n\n const args = parameterIndexes.map((index) => flatArgs[index - 1]);\n return { sql: sql.replace(/\\$(\\d+)/g, '?'), args };\n}\n\nfunction executeNativeQuery(\n database: NativeDatabase,\n sql: string,\n args: any[] = [],\n): NativeQueryResult {\n const statement: NativeStatement = database.prepare(sql);\n const columns = statement.columns();\n\n if (columns.length > 0) {\n const rows = statement.all(...args).map(toPlainRow);\n return {\n rows,\n rowCount: rows.length,\n command: firstSqlToken(sql),\n fields: columns.map((column: { name: string }) => ({\n name: column.name,\n })),\n };\n }\n\n const result = statement.run(...args);\n return {\n rows: [],\n rowCount: Number(result?.changes ?? 0),\n command: firstSqlToken(sql),\n fields: [],\n };\n}\n\nfunction createNativeTablesFromSchemas(\n database: NativeDatabase,\n schemas: Record<string, SchemaProvider>,\n): void {\n for (const [tableName, schema] of Object.entries(schemas)) {\n try {\n const result = executeNativeQuery(\n database,\n \"SELECT name FROM sqlite_master WHERE type='table' AND name=?\",\n [tableName],\n );\n\n if (result.rows.length > 0) {\n continue;\n }\n\n database.exec(schema.ddl);\n\n for (const indexSql of schema.indexes ?? []) {\n try {\n database.exec(indexSql);\n } catch (error) {\n console.warn(\n `[sqlite] Failed to create index for ${tableName}: ${formatDbError(error)}`,\n );\n }\n }\n\n for (const triggerSql of schema.triggers ?? []) {\n try {\n database.exec(triggerSql);\n } catch (error) {\n console.warn(\n `[sqlite] Failed to create trigger for ${tableName}: ${formatDbError(error)}`,\n );\n }\n }\n } catch (error) {\n throw new DatabaseError(\n `Failed to create table ${tableName} from schema`,\n {\n tableName,\n schema,\n originalError: formatDbError(error),\n },\n );\n }\n }\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction buildQuestionWhere(where: WhereClause, startIndex = 1) {\n const built = buildWhere(where, startIndex, 'sqlite');\n return {\n sql: built.sql.replace(/\\$(\\d+)/g, '?'),\n values: built.values,\n };\n}\n\nfunction serializeValue(value: any): any {\n if (value === null || value === undefined) {\n return value;\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'object') {\n return JSON.stringify(value);\n }\n return value;\n}\n\nfunction serializeRecord(record: Record<string, any>): Record<string, any> {\n const serialized: Record<string, any> = {};\n for (const [key, value] of Object.entries(record)) {\n if (value === undefined) {\n continue;\n }\n serialized[key] = serializeValue(value);\n }\n return serialized;\n}\n\nasync function withNativeNullAwareUpsertLock<T>(\n lockKey: string,\n callback: () => Promise<T>,\n): Promise<T> {\n const previous = nativeNullAwareUpsertLocks.get(lockKey) ?? Promise.resolve();\n let release: () => void = () => {};\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const next = previous.catch(() => {}).then(() => current);\n\n nativeNullAwareUpsertLocks.set(lockKey, next);\n await previous.catch(() => {});\n\n try {\n return await callback();\n } finally {\n release();\n if (nativeNullAwareUpsertLocks.get(lockKey) === next) {\n nativeNullAwareUpsertLocks.delete(lockKey);\n }\n }\n}\n\nfunction sqliteVectorDistance(metric: 'cosine' | 'l2' | 'ip'): string {\n switch (metric) {\n case 'l2':\n return 'L2';\n case 'ip':\n return 'DOT';\n default:\n return 'COSINE';\n }\n}\n\nfunction sqliteVectorQuantization(\n options: SqliteVectorCapabilityOptions,\n): string {\n const parts: string[] = [];\n\n switch (options.quantization ?? 'turbo4') {\n case 'turbo2':\n parts.push('qtype=TURBO,qbits=2');\n break;\n case 'turbo3':\n parts.push('qtype=TURBO,qbits=3');\n break;\n case 'turbo4':\n parts.push('qtype=TURBO,qbits=4');\n break;\n case 'uint8':\n parts.push('qtype=UINT8');\n break;\n case 'int8':\n parts.push('qtype=INT8');\n break;\n case '1bit':\n parts.push('qtype=1BIT');\n break;\n }\n\n if (options.maxMemory) {\n parts.push(`max_memory=${options.maxMemory}`);\n }\n\n return parts.join(',');\n}\n\nfunction createNotificationCapabilities(\n honkerDb: any,\n closeables: Set<{ close?: () => void }>,\n): NotificationCapabilities {\n return {\n async notify(channel: string, payload: any): Promise<number> {\n return Number(honkerDb.notify(channel, payload));\n },\n\n listen(channel: string, options?: NotificationListenOptions) {\n const listener = honkerDb.listen(channel, {\n fallbackPollS:\n options?.fallbackPollMs === null\n ? null\n : options?.fallbackPollMs !== undefined\n ? options.fallbackPollMs / 1000\n : undefined,\n });\n closeables.add(listener);\n return listener;\n },\n\n async waitForUpdate(options?: NotificationWaitOptions): Promise<boolean> {\n const updateEvents = honkerDb.updateEvents();\n closeables.add(updateEvents);\n let timeout: NodeJS.Timeout | undefined;\n let removeAbortListener: (() => void) | undefined;\n\n try {\n if (options?.signal?.aborted) {\n return false;\n }\n\n const updatePromise = updateEvents.next().then(\n () => true,\n () => false,\n );\n const races: Array<Promise<boolean>> = [updatePromise];\n\n if (options?.timeoutMs !== undefined) {\n const timeoutMs = options.timeoutMs;\n races.push(\n new Promise((resolve) => {\n timeout = setTimeout(\n () => resolve(false),\n Math.max(0, timeoutMs),\n );\n }),\n );\n }\n\n if (options?.signal) {\n races.push(\n new Promise((resolve) => {\n const onAbort = () => resolve(false);\n options.signal?.addEventListener('abort', onAbort, {\n once: true,\n });\n removeAbortListener = () =>\n options.signal?.removeEventListener('abort', onAbort);\n }),\n );\n }\n\n return await Promise.race(races);\n } finally {\n if (timeout) {\n clearTimeout(timeout);\n }\n removeAbortListener?.();\n closeables.delete(updateEvents);\n updateEvents.close?.();\n }\n },\n\n async prune(options?: NotificationPruneOptions): Promise<number> {\n return Number(\n honkerDb.pruneNotifications(options?.olderThanS, options?.maxKeep),\n );\n },\n };\n}\n\nfunction createVectorCapabilities(\n database: NativeDatabase,\n options: SqliteVectorCapabilityOptions,\n): VectorCapabilities {\n const initialized = new Map<\n string,\n { dimensions: number; metric: 'cosine' | 'l2' | 'ip' }\n >();\n const indexed = new Map<\n string,\n { metric: 'cosine' | 'l2' | 'ip'; options: SqliteVectorCapabilityOptions }\n >();\n\n const keyFor = (table: string, column: string) => `${table}.${column}`;\n\n const columnExists = (table: string, column: string): boolean => {\n const rows = database\n .prepare(`PRAGMA table_info(${quoteIdentifier(table)})`)\n .all()\n .map(toPlainRow);\n return rows.some((row: Record<string, any>) => row.name === column);\n };\n\n const ensureInitialized = (\n table: string,\n column: string,\n dimensions: number,\n metric: 'cosine' | 'l2' | 'ip' = 'cosine',\n ): void => {\n if (!Number.isInteger(dimensions) || dimensions <= 0) {\n throw new DatabaseError('Vector dimensions must be a positive integer', {\n dimensions,\n });\n }\n\n validateTableName(table);\n validateColumnName(column);\n\n executeNativeQuery(database, 'SELECT vector_init(?, ?, ?)', [\n table,\n column,\n `dimension=${dimensions},type=FLOAT32,distance=${sqliteVectorDistance(metric)}`,\n ]);\n initialized.set(keyFor(table, column), { dimensions, metric });\n };\n\n const quantize = (\n table: string,\n column: string,\n vectorOptions: SqliteVectorCapabilityOptions,\n ): void => {\n const quantizationOptions = sqliteVectorQuantization(vectorOptions);\n if (quantizationOptions) {\n executeNativeQuery(database, 'SELECT vector_quantize(?, ?, ?)', [\n table,\n column,\n quantizationOptions,\n ]);\n } else {\n executeNativeQuery(database, 'SELECT vector_quantize(?, ?)', [\n table,\n column,\n ]);\n }\n\n if (vectorOptions.preload) {\n executeNativeQuery(database, 'SELECT vector_quantize_preload(?, ?)', [\n table,\n column,\n ]);\n }\n };\n\n return {\n async ensureColumn(\n table: string,\n column: string,\n dimensions: number,\n ): Promise<void> {\n validateTableName(table);\n validateColumnName(column);\n\n try {\n if (!columnExists(table, column)) {\n executeNativeQuery(\n database,\n `ALTER TABLE ${quoteIdentifier(table)} ADD COLUMN ${quoteIdentifier(column)} BLOB`,\n );\n }\n ensureInitialized(table, column, dimensions, 'cosine');\n } catch (error) {\n throw new DatabaseError('Failed to ensure SQLite vector column', {\n table,\n column,\n dimensions,\n originalError: formatDbError(error),\n });\n }\n },\n\n async ensureIndex(\n table: string,\n column: string,\n indexOptions?: VectorIndexOptions,\n ): Promise<void> {\n validateTableName(table);\n validateColumnName(column);\n\n const key = keyFor(table, column);\n const dimensions =\n indexOptions?.dimensions ?? initialized.get(key)?.dimensions;\n if (!dimensions) {\n throw new DatabaseError(\n 'SQLite vector index creation requires dimensions',\n {\n table,\n column,\n hint: 'Call ensureColumn(table, column, dimensions) first or pass dimensions to ensureIndex().',\n },\n );\n }\n\n const metric = indexOptions?.metric ?? 'cosine';\n\n try {\n ensureInitialized(table, column, dimensions, metric);\n const vectorOptions = { ...options };\n quantize(table, column, vectorOptions);\n indexed.set(key, { metric, options: vectorOptions });\n } catch (error) {\n throw new DatabaseError('Failed to ensure SQLite vector index', {\n table,\n column,\n originalError: formatDbError(error),\n });\n }\n },\n\n async upsertVector(\n table: string,\n where: Record<string, any>,\n column: string,\n embedding: number[],\n ): Promise<void> {\n validateTableName(table);\n validateColumnName(column);\n\n const key = keyFor(table, column);\n const dimensions = initialized.get(key)?.dimensions ?? embedding.length;\n const { sql: whereClause, values } = buildQuestionWhere(where);\n\n if (!whereClause) {\n throw new DatabaseError(\n 'SQLite vector update requires at least one WHERE condition',\n { table, column },\n );\n }\n\n try {\n ensureInitialized(\n table,\n column,\n dimensions,\n initialized.get(key)?.metric ?? 'cosine',\n );\n executeNativeQuery(\n database,\n `UPDATE ${quoteIdentifier(table)} SET ${quoteIdentifier(column)} = vector_as_f32(?) ${whereClause}`,\n [JSON.stringify(embedding), ...values],\n );\n\n const indexState = indexed.get(key);\n if (indexState) {\n quantize(table, column, indexState.options);\n }\n } catch (error) {\n throw new DatabaseError('Failed to upsert SQLite vector', {\n table,\n column,\n where,\n originalError: formatDbError(error),\n });\n }\n },\n\n async search(\n table: string,\n column: string,\n embedding: number[],\n searchOptions?: VectorSearchOptions,\n ): Promise<VectorSearchResult[]> {\n validateTableName(table);\n validateColumnName(column);\n\n const key = keyFor(table, column);\n const metric = searchOptions?.metric ?? 'cosine';\n const limit = searchOptions?.limit ?? 10;\n const limitArg = BigInt(limit);\n const dimensions = initialized.get(key)?.dimensions ?? embedding.length;\n const indexState = indexed.get(key);\n const useQuantizedScan = indexState?.metric === metric;\n const scanFunction = useQuantizedScan\n ? 'vector_quantize_scan'\n : 'vector_full_scan';\n const convertedWhere = searchOptions?.where\n ? searchOptions.where.replace(/\\$(\\d+)/g, '?')\n : '';\n const whereParams = searchOptions?.params ?? [];\n\n try {\n ensureInitialized(table, column, dimensions, metric);\n\n const rows = convertedWhere\n ? executeNativeQuery(\n database,\n `SELECT base.*, base.rowid AS __sqlite_rowid, vec.distance\n FROM ${scanFunction}(?, ?, vector_as_f32(?)) AS vec\n JOIN ${quoteIdentifier(table)} AS base ON base.rowid = vec.rowid\n WHERE (${convertedWhere})\n ORDER BY vec.distance\n LIMIT ?`,\n [\n table,\n column,\n JSON.stringify(embedding),\n ...whereParams,\n limitArg,\n ],\n ).rows\n : executeNativeQuery(\n database,\n `SELECT base.*, base.rowid AS __sqlite_rowid, vec.distance\n FROM ${scanFunction}(?, ?, vector_as_f32(?), ?) AS vec\n JOIN ${quoteIdentifier(table)} AS base ON base.rowid = vec.rowid\n ORDER BY vec.distance`,\n [table, column, JSON.stringify(embedding), limitArg],\n ).rows;\n\n return rows.map((row) => {\n const { __sqlite_rowid: rowid, ...result } = row;\n return {\n ...result,\n id: String(result.id ?? rowid),\n distance: Number(row.distance),\n };\n });\n } catch (error) {\n throw new DatabaseError('Failed to execute SQLite vector search', {\n table,\n column,\n metric,\n limit,\n originalError: formatDbError(error),\n });\n }\n },\n };\n}\n\nexport async function getNativeSqliteDatabase(\n options: SqliteOptions = {},\n): Promise<DatabaseInterface> {\n const url = options.url || ':memory:';\n\n return getCachedSqliteDatabase('native', options, () =>\n createNativeSqliteDatabase(options, url),\n );\n}\n\nasync function createNativeSqliteDatabase(\n options: SqliteOptions,\n url: string,\n): Promise<DatabaseInterface> {\n const location = resolveNativeLocation(url);\n const notificationsOptions = getCapabilityOptions(\n options.capabilities?.notifications,\n );\n const vectorOptions = getCapabilityOptions(options.capabilities?.vector);\n const wantsNotifications = Boolean(options.capabilities?.notifications);\n const wantsVector = Boolean(options.capabilities?.vector);\n\n if (wantsNotifications && location.isMemory) {\n throw new DatabaseError(\n 'SQLite notification capabilities require a file-backed database',\n {\n url,\n hint: 'Use a temporary file-backed .db for development and tests that need notifications.',\n },\n );\n }\n\n const { DatabaseSync } = await loadNodeSqlite();\n const database = new DatabaseSync(location.location, {\n allowExtension: wantsVector,\n });\n\n // One lock per connection. `getNativeSqliteDatabase` hands cached callers\n // this same closure, so \"created here\" and \"per connection\" are the same\n // scope.\n const connectionLock = createTransactionLock(\n 'sqlite (native)',\n options.transactionQueueTimeout,\n );\n let closeResources: (() => Promise<void>) | undefined;\n\n try {\n if (wantsVector) {\n await loadSqliteVectorExtension(database);\n }\n\n const honkerDb =\n wantsNotifications && location.filePath\n ? await openHonkerDatabase(location.filePath, notificationsOptions)\n : null;\n const notificationCloseables = new Set<{ close?: () => void }>();\n\n const vectorCapabilities = wantsVector\n ? createVectorCapabilities(database, vectorOptions)\n : undefined;\n const notificationCapabilities = honkerDb\n ? createNotificationCapabilities(honkerDb, notificationCloseables)\n : undefined;\n\n const query = async (\n sql: string,\n ...values: any[]\n ): Promise<{ rows: Record<string, any>[]; rowCount: number }> => {\n const normalized = normalizeNativeQuery(sql, values);\n try {\n const result = executeNativeQuery(\n database,\n normalized.sql,\n normalized.args,\n );\n return { rows: result.rows, rowCount: result.rowCount };\n } catch (error) {\n throw wrapDatabaseError('Failed to execute raw query', error, {\n sql: normalized.sql,\n values: normalized.args,\n });\n }\n };\n\n const parseTemplate = (strings: TemplateStringsArray, ...vars: any[]) => {\n let sql = strings[0];\n const values = [];\n for (let i = 0; i < vars.length; i++) {\n values.push(vars[i]);\n sql += `?${strings[i + 1]}`;\n }\n return { sql, values };\n };\n\n const insert = async (\n table: string,\n data: Record<string, any> | Record<string, any>[],\n ): Promise<QueryResult> => {\n validateTableName(table);\n const records = (Array.isArray(data) ? data : [data]).map(\n serializeRecord,\n );\n if (records.length === 0) {\n return { operation: 'insert', affected: 0 };\n }\n const keys = resolveInsertColumns(table, records);\n validateColumnNames(keys);\n const placeholders = records\n .map(() => `(${keys.map(() => '?').join(', ')})`)\n .join(', ');\n const values = records.flatMap((record) =>\n keys.map((key) => record[key]),\n );\n const sql = `INSERT INTO ${table} (${keys.join(', ')}) VALUES ${placeholders}`;\n\n try {\n const result = executeNativeQuery(database, sql, values);\n return { operation: 'insert', affected: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to insert records into table', {\n table,\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const get = async (\n table: string,\n where: WhereClause,\n ): Promise<Record<string, any> | null> => {\n validateTableName(table);\n const { sql: whereClause, values } = buildQuestionWhere(where);\n if (!whereClause) {\n throw new DatabaseError(\n 'GET requires at least one WHERE condition to prevent returning an arbitrary record',\n { table },\n );\n }\n\n const sql = `SELECT * FROM ${table} ${whereClause}`;\n try {\n const result = executeNativeQuery(database, sql, values);\n return result.rows[0] || null;\n } catch (error) {\n throw new DatabaseError('Failed to retrieve record from table', {\n table,\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const list = async (\n table: string,\n where: WhereClause,\n ): Promise<Record<string, any>[]> => {\n validateTableName(table);\n const { sql: whereClause, values } = buildQuestionWhere(where);\n const sql = `SELECT * FROM ${table} ${whereClause}`;\n try {\n return executeNativeQuery(database, sql, values).rows;\n } catch (error) {\n throw new DatabaseError('Failed to list records from table', {\n table,\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const update = async (\n table: string,\n where: WhereClause,\n data: Record<string, any>,\n ): Promise<QueryResult> => {\n validateTableName(table);\n const serializedData = serializeRecord(data);\n const keys = Object.keys(serializedData);\n validateColumnNames(keys);\n const values = Object.values(serializedData);\n const setClause = keys.map((key) => `${key} = ?`).join(', ');\n const { sql: whereClause, values: whereValues } =\n buildQuestionWhere(where);\n\n if (!whereClause) {\n throw new DatabaseError(\n 'UPDATE requires at least one WHERE condition to prevent accidental update of all records',\n { table },\n );\n }\n\n const sql = `UPDATE ${table} SET ${setClause} ${whereClause}`;\n try {\n const result = executeNativeQuery(database, sql, [\n ...values,\n ...whereValues,\n ]);\n return { operation: 'update', affected: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to update records in table', {\n table,\n sql,\n values: [...values, ...whereValues],\n originalError: formatDbError(error),\n });\n }\n };\n\n const hasNullConflictValue = (\n conflictColumns: string[],\n data: Record<string, any>,\n ): boolean => conflictColumns.some((column) => data[column] === null);\n\n const validateUpsertConflictColumns = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): void => {\n const missingColumns = conflictColumns.filter(\n (column) => !(column in serializedData),\n );\n\n if (missingColumns.length > 0) {\n throw new DatabaseError('Conflict columns missing from data', {\n table,\n conflictColumns,\n missingColumns,\n availableColumns: Object.keys(serializedData),\n hint: 'All columns specified in ON CONFLICT must be present in the data being inserted. Undefined values are filtered out during serialization - consider using null or an empty string instead.',\n });\n }\n };\n\n const executeStandardUpsert = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): QueryResult => {\n const keys = Object.keys(serializedData);\n const values = Object.values(serializedData);\n const placeholders = keys.map(() => '?').join(', ');\n const updateSet = keys\n .map((key) => `${key} = excluded.${key}`)\n .join(', ');\n const conflict = conflictColumns.join(', ');\n const sql = `INSERT INTO ${table} (${keys.join(', ')}) VALUES (${placeholders}) ON CONFLICT(${conflict}) DO UPDATE SET ${updateSet}`;\n const result = executeNativeQuery(database, sql, values);\n return { operation: 'upsert', affected: result.rowCount };\n };\n\n const executeNullAwareUpsertAttempt = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): QueryResult => {\n const keys = Object.keys(serializedData);\n const values = Object.values(serializedData);\n const updateSet = keys.map((key) => `${key} = ?`).join(', ');\n const whereClause = conflictColumns\n .map((column) => `${column} IS ?`)\n .join(' AND ');\n const whereValues = conflictColumns.map(\n (column) => serializedData[column],\n );\n\n const updateResult = executeNativeQuery(\n database,\n `UPDATE ${table} SET ${updateSet} WHERE ${whereClause}`,\n [...values, ...whereValues],\n );\n\n if (updateResult.rowCount > 0) {\n return { operation: 'upsert', affected: updateResult.rowCount };\n }\n\n const placeholders = keys.map(() => '?').join(', ');\n const insertResult = executeNativeQuery(\n database,\n `INSERT INTO ${table} (${keys.join(', ')}) VALUES (${placeholders})`,\n values,\n );\n\n return { operation: 'upsert', affected: insertResult.rowCount };\n };\n\n /**\n * Rejects hostile table/column identifiers before an upsert builds SQL.\n *\n * Called from the public entry points rather than from `executeUpsert`, so\n * the failure reaches the caller naming the bad identifier instead of being\n * flattened into the wrapper's generic \"Failed to upsert record into table\".\n *\n * Validates the keys of the already-serialized snapshot — the exact array\n * the executors interpolate — not a fresh enumeration of the caller's\n * `data`. Enumerating `data` again could disagree with the snapshot if it is\n * a Proxy whose `ownKeys` trap returns different keys on successive reads.\n */\n const validateUpsertIdentifiers = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): void => {\n validateTableName(table);\n validateColumnNames([...conflictColumns, ...Object.keys(serializedData)]);\n };\n\n const executeUpsert = async (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n upsertOptions: UpsertOptions | undefined,\n acquireTransaction: boolean,\n ): Promise<QueryResult> => {\n validateUpsertConflictColumns(table, conflictColumns, serializedData);\n\n if (\n upsertOptions?.nullsDistinct ||\n !hasNullConflictValue(conflictColumns, serializedData)\n ) {\n return executeStandardUpsert(table, conflictColumns, serializedData);\n }\n\n if (!acquireTransaction) {\n return executeNullAwareUpsertAttempt(\n table,\n conflictColumns,\n serializedData,\n );\n }\n\n const lockKey = `${location.location}:${table}:${conflictColumns\n .map((column) => `${column}:${JSON.stringify(serializedData[column])}`)\n .join('|')}`;\n\n return withNativeNullAwareUpsertLock(lockKey, async () => {\n // This opens a transaction on the shared connection like any other, so\n // it takes the same lock — otherwise a null-aware upsert overlapping a\n // `transaction()` call reintroduces exactly the corruption the lock\n // exists to prevent.\n const releaseConnection = await connectionLock.acquire();\n try {\n database.exec('BEGIN IMMEDIATE');\n const result = executeNullAwareUpsertAttempt(\n table,\n conflictColumns,\n serializedData,\n );\n database.exec('COMMIT');\n return result;\n } catch (error) {\n try {\n database.exec('ROLLBACK');\n } catch (_rollbackError) {\n // Preserve the original failure.\n }\n throw error;\n } finally {\n releaseConnection();\n }\n });\n };\n\n const upsert = async (\n table: string,\n conflictColumns: string[],\n data: Record<string, any>,\n upsertOptions?: UpsertOptions,\n ): Promise<QueryResult> => {\n // Snapshot the record and the conflict columns once and thread both\n // through validation and SQL, so neither a hostile record nor a hostile\n // conflict-column array can present different identifiers to each.\n const serializedData = serializeRecord(data);\n const conflictCols = [...conflictColumns];\n validateUpsertIdentifiers(table, conflictCols, serializedData);\n try {\n return await executeUpsert(\n table,\n conflictCols,\n serializedData,\n upsertOptions,\n true,\n );\n } catch (error) {\n if (getErrorMessage(error) === 'Conflict columns missing from data') {\n throw error;\n }\n throw new DatabaseError('Failed to upsert record into table', {\n table,\n values: data,\n conflictColumns,\n originalError: formatDbError(error),\n });\n }\n };\n\n const upsertInCurrentTransaction = (\n table: string,\n conflictColumns: string[],\n data: Record<string, any>,\n upsertOptions?: UpsertOptions,\n ): Promise<QueryResult> => {\n // Snapshot the record and the conflict columns once and thread both\n // through validation and SQL, so neither a hostile record nor a hostile\n // conflict-column array can present different identifiers to each.\n const serializedData = serializeRecord(data);\n const conflictCols = [...conflictColumns];\n validateUpsertIdentifiers(table, conflictCols, serializedData);\n return executeUpsert(\n table,\n conflictCols,\n serializedData,\n upsertOptions,\n false,\n );\n };\n\n const getOrInsert = async (\n table: string,\n where: WhereClause,\n data: Record<string, any>,\n ): Promise<Record<string, any>> => {\n const existing = await get(table, where);\n if (existing) return existing;\n await insert(table, data);\n const inserted = await get(table, where);\n if (!inserted) {\n throw new DatabaseError('Failed to insert and retrieve record', {\n table,\n where,\n data,\n });\n }\n return inserted;\n };\n\n const deleteRecords = async (\n table: string,\n where: WhereClause,\n ): Promise<QueryResult> => {\n validateTableName(table);\n const { sql: whereClause, values } = buildQuestionWhere(where);\n if (!whereClause) {\n throw new DatabaseError(\n 'DELETE requires at least one WHERE condition to prevent accidental deletion of all records',\n { table },\n );\n }\n\n try {\n const result = executeNativeQuery(\n database,\n `DELETE FROM ${table} ${whereClause}`,\n values,\n );\n return { operation: 'delete', affected: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to delete records from table', {\n table,\n where,\n originalError: formatDbError(error),\n });\n }\n };\n\n const count = async (\n table: string,\n where?: WhereClause,\n ): Promise<number> => {\n validateTableName(table);\n if (\n !where ||\n (typeof where === 'object' && Object.keys(where).length === 0)\n ) {\n const result = executeNativeQuery(\n database,\n `SELECT COUNT(*) as count FROM ${table}`,\n );\n return Number(result.rows[0]?.count) || 0;\n }\n\n const { sql: whereClause, values } = buildQuestionWhere(where);\n const result = executeNativeQuery(\n database,\n `SELECT COUNT(*) as count FROM ${table} ${whereClause}`,\n values,\n );\n return Number(result.rows[0]?.count) || 0;\n };\n\n const tableExists = async (tableName: string): Promise<boolean> => {\n const result = executeNativeQuery(\n database,\n \"SELECT name FROM sqlite_master WHERE type='table' AND name=?\",\n [tableName],\n );\n return result.rows.length > 0;\n };\n\n const syncSchema = async (schema: string): Promise<void> => {\n const commands = schema\n .replace(/\\s+/g, ' ')\n .replace(/DEFAULT CAST\\(([^)]+)\\s+AS\\s+\\w+\\)/gi, 'DEFAULT $1')\n .trim()\n .split(';')\n .map((command) => command.trim())\n .filter((command) => command.length > 0);\n\n for (const command of commands) {\n database.exec(command);\n }\n };\n\n const many = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<Record<string, any>[]> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n return executeNativeQuery(database, sql, values).rows;\n } catch (error) {\n throw new DatabaseError('Failed to execute many query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const single = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<Record<string, any> | null> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n return executeNativeQuery(database, sql, values).rows[0] || null;\n } catch (error) {\n throw new DatabaseError('Failed to execute single query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const pluck = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<any> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n const row = executeNativeQuery(database, sql, values).rows[0];\n return row ? Object.values(row)[0] : null;\n } catch (error) {\n throw new DatabaseError('Failed to execute pluck query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const execute = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<void> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n if (values.length === 0) {\n database.exec(sql);\n return;\n }\n executeNativeQuery(database, sql, values);\n } catch (error) {\n throw new DatabaseError('Failed to execute query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const oo = many;\n const oO = single;\n const ox = pluck;\n const xx = execute;\n\n const table = (tableName: string): TableInterface => ({\n insert: (data) => insert(tableName, data),\n get: (where) => get(tableName, where),\n list: (where) => list(tableName, where),\n });\n\n // Names nested savepoints. Only ever appended to an identifier the adapter\n // generates, never caller input.\n let savepointSequence = 0;\n\n /**\n * Re-enters the transaction already in progress under a savepoint.\n *\n * This is what the transaction-scoped interface exposes as `transaction`.\n * Handing it the top-level `transaction` instead — the previous behaviour —\n * sent a nested call into a second BEGIN on the one shared connection; that\n * throws, and the nested call's own ROLLBACK then discarded the *enclosing*\n * transaction's work while later writes committed in autocommit.\n */\n const nestedTransaction = async <T>(\n callback: (tx: DatabaseInterface) => Promise<T>,\n ): Promise<T> => {\n savepointSequence += 1;\n const name = `hv_sp_${savepointSequence}`;\n database.exec(`SAVEPOINT ${name}`);\n try {\n const result = await callback(\n buildDatabaseInterface(\n upsertInCurrentTransaction,\n nestedTransaction,\n refuseNestedBeginTransaction,\n ),\n );\n database.exec(`RELEASE SAVEPOINT ${name}`);\n return result;\n } catch (error) {\n try {\n // ROLLBACK TO leaves the savepoint defined, so release it too or it\n // accumulates for the life of the transaction.\n database.exec(`ROLLBACK TO SAVEPOINT ${name}`);\n database.exec(`RELEASE SAVEPOINT ${name}`);\n } catch {\n // The enclosing transaction is already unwinding; its teardown owns\n // the connection from here.\n }\n throw error;\n }\n };\n\n const transaction = async <T>(\n callback: (tx: DatabaseInterface) => Promise<T>,\n ): Promise<T> =>\n // Held across the whole BEGIN … COMMIT/ROLLBACK span. Without it two\n // overlapping calls raced on the one connection: the second BEGIN threw,\n // its catch ran ROLLBACK, and that rollback ended the *first*\n // transaction — half of its writes durable, half lost, and its promise\n // rejected, so the caller was told nothing had happened.\n connectionLock.run(async () => {\n try {\n database.exec('BEGIN TRANSACTION');\n const txDb = buildDatabaseInterface(\n upsertInCurrentTransaction,\n nestedTransaction,\n refuseNestedBeginTransaction,\n );\n const result = await callback(txDb);\n database.exec('COMMIT');\n return result;\n } catch (error) {\n // A failing ROLLBACK must not replace the caller's error: SQLite\n // reports \"cannot rollback - no transaction is active\" whenever the\n // transaction is already gone, which says nothing about what failed.\n try {\n database.exec('ROLLBACK');\n } catch {\n // Nothing left to roll back.\n }\n throw error;\n }\n });\n\n /**\n * The `beginTransaction` exposed on a transaction-scoped interface.\n *\n * Unlike `transaction`, a manual handle has no savepoint equivalent: it\n * would have to own the connection until the caller ends it, which the\n * enclosing transaction already does. Issuing a second BEGIN threw before\n * transactions were serialized; now it would instead wait on a lock its own\n * caller holds, so refuse explicitly rather than deadlock.\n */\n const refuseNestedBeginTransaction = async (): Promise<never> => {\n throw new NestedTransactionError(\n 'beginTransaction() cannot be called inside a transaction. Use the transaction you already have, or nest with transaction() to re-enter it under a savepoint.',\n { adapter: 'sqlite-native' },\n );\n };\n\n const beginTransaction = async (): Promise<TransactionHandle> => {\n // The handle owns the connection until the caller ends it, so the lock is\n // held across the gap rather than around a single call. A handle that is\n // never committed or rolled back therefore blocks every later transaction\n // until the queue timeout reports it.\n const releaseConnection = await connectionLock.acquire();\n try {\n database.exec('BEGIN TRANSACTION');\n } catch (error) {\n // No transaction was opened, so there is no handle to end it and\n // nothing left to release the connection.\n releaseConnection();\n throw error;\n }\n\n let active = true;\n\n // COMMIT and ROLLBACK can both throw, and the transaction is over either\n // way, so the connection goes back before the error is rethrown.\n const end = (command: 'COMMIT' | 'ROLLBACK'): void => {\n if (!active) {\n throw new DatabaseError('Transaction already ended', {});\n }\n try {\n database.exec(command);\n } catch (error) {\n // COMMIT can fail and leave the transaction *open* — SQLite documents\n // exactly that for SQLITE_BUSY. Releasing the connection then would hand\n // the next queued caller a connection still inside a transaction: its\n // BEGIN would throw, and its catch would ROLLBACK, discarding this\n // transaction's work. So normalize before releasing, the way the pooled\n // adapter's discardTxClient does.\n try {\n database.exec('ROLLBACK');\n } catch {\n // Already gone; nothing left to normalize.\n }\n throw error;\n } finally {\n active = false;\n releaseConnection();\n }\n };\n\n const commit = async (): Promise<void> => end('COMMIT');\n\n const rollback = async (): Promise<void> => end('ROLLBACK');\n\n return {\n // The handle is inside a transaction for the same reason a callback\n // scope is, so it re-enters via savepoint too.\n ...buildDatabaseInterface(\n upsertInCurrentTransaction,\n nestedTransaction,\n refuseNestedBeginTransaction,\n ),\n commit,\n rollback,\n isActive: () => active,\n };\n };\n\n const initializeSchemas = async (\n schemaOptions: SchemaInitializationOptions,\n ): Promise<void> => {\n const schemaManager = new DatabaseSchemaManager();\n await schemaManager.initializeSchemas(\n buildDatabaseInterface(upsert),\n schemaOptions,\n );\n };\n\n const getTableSchema = async (\n tableName: string,\n ): Promise<TableSchemaInfo | null> => {\n validateTableName(tableName);\n\n if (!(await tableExists(tableName))) {\n return null;\n }\n\n const columnRows = database\n .prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`)\n .all()\n .map(toPlainRow);\n\n const columns: Record<string, ColumnDefinition> = {};\n for (const row of columnRows) {\n columns[row.name as string] = {\n type: row.type as string,\n primaryKey: row.pk === 1,\n notNull: row.notnull === 1,\n defaultValue: row.dflt_value,\n };\n }\n\n const indexRows = executeNativeQuery(\n database,\n `SELECT name FROM sqlite_master\n WHERE type = 'index'\n AND tbl_name = ?\n AND name NOT LIKE 'sqlite_%'`,\n [tableName],\n ).rows;\n\n const indexes: IndexDefinition[] = [];\n for (const row of indexRows) {\n const indexName = row.name as string;\n const indexInfoRows = database\n .prepare(`PRAGMA index_info(${quoteIdentifier(indexName)})`)\n .all()\n .map(toPlainRow);\n const indexListRows = database\n .prepare(`PRAGMA index_list(${quoteIdentifier(tableName)})`)\n .all()\n .map(toPlainRow);\n\n indexes.push({\n name: indexName,\n columns: indexInfoRows.map((info: Record<string, any>) => info.name),\n unique: indexListRows.some(\n (info: Record<string, any>) =>\n info.name === indexName && info.unique === 1,\n ),\n });\n }\n\n const fkRows = database\n .prepare(`PRAGMA foreign_key_list(${quoteIdentifier(tableName)})`)\n .all()\n .map(toPlainRow);\n\n return {\n tableName,\n columns,\n indexes,\n foreignKeys: fkRows.map((row: Record<string, any>) => ({\n column: row.from as string,\n referencesTable: row.table as string,\n referencesColumn: row.to as string,\n onDelete: row.on_delete as string | undefined,\n onUpdate: row.on_update as string | undefined,\n })),\n };\n };\n\n const alterTable = {\n addColumn: async (\n tableName: string,\n column: ColumnDefinitionWithName,\n ): Promise<void> => {\n validateTableName(tableName);\n validateColumnName(column.name);\n let sql: string | undefined;\n try {\n sql = generateAddColumnStatement(tableName, column, 'sqlite');\n executeNativeQuery(database, sql);\n } catch (error) {\n throw wrapDatabaseError('Failed to add column to table', error, {\n table: tableName,\n column: column.name,\n ...(sql ? { sql } : {}),\n });\n }\n },\n\n addIndex: async (\n tableName: string,\n index: IndexDefinition,\n ): Promise<void> => {\n validateTableName(tableName);\n validateIndexName(index.name);\n for (const column of index.columns) {\n validateColumnName(column);\n }\n let sql: string | undefined;\n try {\n sql = generateCreateIndexStatement(tableName, index);\n executeNativeQuery(database, sql);\n } catch (error) {\n throw wrapDatabaseError('Failed to create index on table', error, {\n table: tableName,\n index: index.name,\n ...(sql ? { sql } : {}),\n });\n }\n },\n };\n\n const close = createNativeSqliteCloser(\n notificationCloseables,\n honkerDb,\n database,\n );\n closeResources = close;\n\n function buildDatabaseInterface(\n upsertImpl: DatabaseInterface['upsert'],\n transactionImpl: DatabaseInterface['transaction'] = transaction,\n beginTransactionImpl: DatabaseInterface['beginTransaction'] = beginTransaction,\n ): DatabaseInterface {\n return {\n url,\n client: database,\n query,\n insert,\n update,\n upsert: upsertImpl,\n get,\n list,\n getOrInsert,\n delete: deleteRecords,\n count,\n table,\n tableExists,\n many,\n single,\n pluck,\n execute,\n oo,\n oO,\n ox,\n xx,\n syncSchema,\n initializeSchemas,\n transaction: transactionImpl,\n beginTransaction: beginTransactionImpl,\n getTableSchema,\n alterTable,\n close,\n ...(vectorCapabilities ? { vector: vectorCapabilities } : {}),\n ...(notificationCapabilities\n ? { notifications: notificationCapabilities }\n : {}),\n };\n }\n\n const db = buildDatabaseInterface(upsert);\n const resolvedSchemas = resolveSchemas(options.schemas);\n if (resolvedSchemas && Object.keys(resolvedSchemas).length > 0) {\n createNativeTablesFromSchemas(database, resolvedSchemas);\n }\n\n return db;\n } catch (error) {\n try {\n if (closeResources) await closeResources();\n else database.close();\n } catch (cleanupError) {\n throw new AggregateError(\n [error, cleanupError],\n 'Native SQLite initialization and cleanup failed',\n );\n }\n throw error;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sqlite-native-CsJ_BLqN.js","names":[],"sources":["../../src/sqlite-native.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { DatabaseError } from '@happyvertical/utils';\nimport { DatabaseSchemaManager } from './schema-manager.js';\nimport {\n generateAddColumnStatement,\n generateCreateIndexStatement,\n validateColumnName,\n validateColumnNames,\n validateIndexName,\n validateTableName,\n} from './shared/alter-utils.js';\nimport { getCachedSqliteDatabase } from './shared/sqlite-connection-cache.js';\nimport { createTransactionLock } from './shared/transaction-lock.js';\nimport type {\n ColumnDefinition,\n ColumnDefinitionWithName,\n DatabaseInterface,\n IndexDefinition,\n NotificationCapabilities,\n NotificationListenOptions,\n NotificationPruneOptions,\n NotificationWaitOptions,\n QueryResult,\n SchemaInitializationOptions,\n SchemaProvider,\n SqliteNotificationCapabilityOptions,\n SqliteVectorCapabilityOptions,\n TableInterface,\n TableSchemaInfo,\n TransactionHandle,\n UpsertOptions,\n VectorCapabilities,\n VectorIndexOptions,\n VectorSearchOptions,\n VectorSearchResult,\n WhereClause,\n} from './shared/types.js';\nimport { NestedTransactionError, resolveSchemas } from './shared/types.js';\nimport {\n buildWhere,\n formatDbError,\n resolveInsertColumns,\n wrapDatabaseError,\n} from './shared/utils.js';\nimport type { SqliteOptions } from './sqlite.js';\n\ntype NativeDatabase = any;\ntype NativeStatement = any;\ntype NativeCloseable = { close?: () => void };\n\n/** @internal Best-effort, retryable closer used by native SQLite. */\nexport function createNativeSqliteCloser(\n notificationCloseables: Set<NativeCloseable>,\n honkerDb: NativeCloseable | null,\n database: { close(): void },\n): () => Promise<void> {\n const completed = new Set<object>();\n let active: Promise<void> | undefined;\n return async () => {\n active ??= (async () => {\n const resources: NativeCloseable[] = [\n ...notificationCloseables,\n ...(honkerDb ? [honkerDb] : []),\n database,\n ];\n const errors: unknown[] = [];\n for (const resource of resources) {\n if (completed.has(resource)) continue;\n try {\n resource.close?.();\n completed.add(resource);\n notificationCloseables.delete(resource);\n } catch (error) {\n errors.push(error);\n }\n }\n if (errors.length === 1) throw errors[0];\n if (errors.length > 1) {\n throw new AggregateError(\n errors,\n 'Failed to close native SQLite resources',\n );\n }\n })();\n try {\n await active;\n } finally {\n active = undefined;\n }\n };\n}\n\nconst nativeNullAwareUpsertLocks = new Map<string, Promise<void>>();\nlet nodeSqliteModulePromise: Promise<any> | null = null;\n// sqlite-vector's ESM wrapper uses dynamic require for platform packages.\nconst requireOptionalPackage = createRequire(import.meta.url);\n\ninterface NativeSqliteLocation {\n location: string;\n filePath: string | null;\n isMemory: boolean;\n}\n\ninterface NativeQueryResult {\n rows: Record<string, any>[];\n rowCount: number;\n command?: string;\n fields?: Array<{ name: string }>;\n}\n\nfunction getCapabilityOptions<T extends Record<string, any>>(\n value: boolean | T | undefined,\n): T {\n return typeof value === 'object' && value ? value : ({} as T);\n}\n\nfunction resolveNativeLocation(url = ':memory:'): NativeSqliteLocation {\n if (\n url.startsWith('libsql://') ||\n url.startsWith('http://') ||\n url.startsWith('https://')\n ) {\n throw new DatabaseError(\n 'SQLite native capabilities are only supported for local SQLite databases',\n {\n url,\n hint: \"Use a local file path, 'file:...' URL, or ':memory:' when enabling SQLite capabilities.\",\n },\n );\n }\n\n if (url === ':memory:' || url.startsWith('file::memory:')) {\n return { location: url, filePath: null, isMemory: true };\n }\n\n if (url.startsWith('file://')) {\n const filePath = fileURLToPath(new URL(url));\n return { location: filePath, filePath, isMemory: false };\n }\n\n if (url.startsWith('file:')) {\n const path = url.slice('file:'.length);\n if (!path || path.includes('?')) {\n throw new DatabaseError(\n 'SQLite native capabilities do not support file: URLs with query parameters',\n { url },\n );\n }\n const filePath = resolve(path);\n return { location: filePath, filePath, isMemory: false };\n }\n\n const filePath = resolve(url);\n return { location: filePath, filePath, isMemory: false };\n}\n\nasync function loadNodeSqlite(): Promise<any> {\n nodeSqliteModulePromise ??= importNodeSqlite().catch((error) => {\n nodeSqliteModulePromise = null;\n throw error;\n });\n return nodeSqliteModulePromise;\n}\n\nasync function importNodeSqlite(): Promise<any> {\n const originalEmitWarning = process.emitWarning;\n\n try {\n process.emitWarning = function suppressNodeSqliteExperimentalWarning(\n warning: string | Error,\n ...args: any[]\n ) {\n if (\n args[0] === 'ExperimentalWarning' &&\n String(warning).includes('SQLite is an experimental feature')\n ) {\n return;\n }\n\n return originalEmitWarning.call(process, warning as any, ...args);\n } as typeof process.emitWarning;\n\n const moduleName = 'node:sqlite';\n return (await import(/* @vite-ignore */ moduleName)) as any;\n } catch (error) {\n throw new DatabaseError('Node native SQLite is not available', {\n originalError: formatDbError(error),\n hint: 'SQLite native capabilities require a Node.js runtime with node:sqlite support.',\n });\n } finally {\n process.emitWarning = originalEmitWarning;\n }\n}\n\nasync function loadSqliteVectorExtension(\n database: NativeDatabase,\n): Promise<void> {\n try {\n const moduleName = '@sqliteai/sqlite-vector';\n const module = requireOptionalPackage(moduleName) as any;\n const getExtensionPath =\n module.getExtensionPath ?? module.default?.getExtensionPath;\n\n if (typeof getExtensionPath !== 'function') {\n throw new Error('getExtensionPath export was not found');\n }\n\n database.enableLoadExtension(true);\n database.loadExtension(getExtensionPath());\n } catch (error) {\n throw new DatabaseError(\n 'Failed to load optional SQLite vector capability: install @sqliteai/sqlite-vector',\n {\n packageName: '@sqliteai/sqlite-vector',\n originalError: formatDbError(error),\n hint: 'Install @sqliteai/sqlite-vector to use SQLite vector capabilities.',\n },\n );\n } finally {\n try {\n database.enableLoadExtension(false);\n } catch (_error) {\n // Leave the original extension-loading failure intact.\n }\n }\n}\n\nasync function openHonkerDatabase(\n filePath: string,\n options: SqliteNotificationCapabilityOptions,\n): Promise<any> {\n try {\n const moduleName = '@russellthehippo/honker-node';\n const module = requireOptionalPackage(moduleName) as any;\n const open = module.open ?? module.default?.open;\n\n if (typeof open !== 'function') {\n throw new Error('open export was not found');\n }\n\n return open(filePath, options.maxReaders, options.watcherBackend);\n } catch (error) {\n throw new DatabaseError(\n 'Failed to load optional SQLite notification capability: install @russellthehippo/honker-node',\n {\n packageName: '@russellthehippo/honker-node',\n originalError: formatDbError(error),\n hint: 'Install @russellthehippo/honker-node to use SQLite notification capabilities.',\n },\n );\n }\n}\n\nfunction toPlainRow(row: Record<string, any>): Record<string, any> {\n return Object.fromEntries(Object.entries(row));\n}\n\nfunction getErrorMessage(error: unknown): string | undefined {\n return error instanceof Error ? error.message : undefined;\n}\n\nfunction firstSqlToken(sql: string): string {\n return sql.trim().split(/\\s+/)[0]?.toUpperCase() ?? '';\n}\n\nfunction normalizeNativeQuery(\n sql: string,\n values: any[],\n): { sql: string; args: any[] } {\n const flatArgs = Array.isArray(values[0]) ? values[0] : values;\n const parameterIndexes = Array.from(sql.matchAll(/\\$(\\d+)/g)).map((match) =>\n Number(match[1]),\n );\n\n if (parameterIndexes.length === 0) {\n return { sql, args: flatArgs };\n }\n\n const args = parameterIndexes.map((index) => flatArgs[index - 1]);\n return { sql: sql.replace(/\\$(\\d+)/g, '?'), args };\n}\n\nfunction executeNativeQuery(\n database: NativeDatabase,\n sql: string,\n args: any[] = [],\n): NativeQueryResult {\n const statement: NativeStatement = database.prepare(sql);\n const columns = statement.columns();\n\n if (columns.length > 0) {\n const rows = statement.all(...args).map(toPlainRow);\n return {\n rows,\n rowCount: rows.length,\n command: firstSqlToken(sql),\n fields: columns.map((column: { name: string }) => ({\n name: column.name,\n })),\n };\n }\n\n const result = statement.run(...args);\n return {\n rows: [],\n rowCount: Number(result?.changes ?? 0),\n command: firstSqlToken(sql),\n fields: [],\n };\n}\n\nfunction createNativeTablesFromSchemas(\n database: NativeDatabase,\n schemas: Record<string, SchemaProvider>,\n): void {\n for (const [tableName, schema] of Object.entries(schemas)) {\n try {\n const result = executeNativeQuery(\n database,\n \"SELECT name FROM sqlite_master WHERE type='table' AND name=?\",\n [tableName],\n );\n\n if (result.rows.length > 0) {\n continue;\n }\n\n database.exec(schema.ddl);\n\n for (const indexSql of schema.indexes ?? []) {\n try {\n database.exec(indexSql);\n } catch (error) {\n console.warn(\n `[sqlite] Failed to create index for ${tableName}: ${formatDbError(error)}`,\n );\n }\n }\n\n for (const triggerSql of schema.triggers ?? []) {\n try {\n database.exec(triggerSql);\n } catch (error) {\n console.warn(\n `[sqlite] Failed to create trigger for ${tableName}: ${formatDbError(error)}`,\n );\n }\n }\n } catch (error) {\n throw new DatabaseError(\n `Failed to create table ${tableName} from schema`,\n {\n tableName,\n schema,\n originalError: formatDbError(error),\n },\n );\n }\n }\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction buildQuestionWhere(where: WhereClause, startIndex = 1) {\n const built = buildWhere(where, startIndex, 'sqlite');\n return {\n sql: built.sql.replace(/\\$(\\d+)/g, '?'),\n values: built.values,\n };\n}\n\nfunction serializeValue(value: any): any {\n if (value === null || value === undefined) {\n return value;\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'object') {\n return JSON.stringify(value);\n }\n return value;\n}\n\nfunction serializeRecord(record: Record<string, any>): Record<string, any> {\n const serialized: Record<string, any> = {};\n for (const [key, value] of Object.entries(record)) {\n if (value === undefined) {\n continue;\n }\n serialized[key] = serializeValue(value);\n }\n return serialized;\n}\n\nasync function withNativeNullAwareUpsertLock<T>(\n lockKey: string,\n callback: () => Promise<T>,\n): Promise<T> {\n const previous = nativeNullAwareUpsertLocks.get(lockKey) ?? Promise.resolve();\n let release: () => void = () => {};\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const next = previous.catch(() => {}).then(() => current);\n\n nativeNullAwareUpsertLocks.set(lockKey, next);\n await previous.catch(() => {});\n\n try {\n return await callback();\n } finally {\n release();\n if (nativeNullAwareUpsertLocks.get(lockKey) === next) {\n nativeNullAwareUpsertLocks.delete(lockKey);\n }\n }\n}\n\nfunction sqliteVectorDistance(metric: 'cosine' | 'l2' | 'ip'): string {\n switch (metric) {\n case 'l2':\n return 'L2';\n case 'ip':\n return 'DOT';\n default:\n return 'COSINE';\n }\n}\n\nfunction sqliteVectorQuantization(\n options: SqliteVectorCapabilityOptions,\n): string {\n const parts: string[] = [];\n\n switch (options.quantization ?? 'turbo4') {\n case 'turbo2':\n parts.push('qtype=TURBO,qbits=2');\n break;\n case 'turbo3':\n parts.push('qtype=TURBO,qbits=3');\n break;\n case 'turbo4':\n parts.push('qtype=TURBO,qbits=4');\n break;\n case 'uint8':\n parts.push('qtype=UINT8');\n break;\n case 'int8':\n parts.push('qtype=INT8');\n break;\n case '1bit':\n parts.push('qtype=1BIT');\n break;\n }\n\n if (options.maxMemory) {\n parts.push(`max_memory=${options.maxMemory}`);\n }\n\n return parts.join(',');\n}\n\nfunction createNotificationCapabilities(\n honkerDb: any,\n closeables: Set<{ close?: () => void }>,\n): NotificationCapabilities {\n return {\n async notify(channel: string, payload: any): Promise<number> {\n return Number(honkerDb.notify(channel, payload));\n },\n\n listen(channel: string, options?: NotificationListenOptions) {\n const listener = honkerDb.listen(channel, {\n fallbackPollS:\n options?.fallbackPollMs === null\n ? null\n : options?.fallbackPollMs !== undefined\n ? options.fallbackPollMs / 1000\n : undefined,\n });\n closeables.add(listener);\n return listener;\n },\n\n async waitForUpdate(options?: NotificationWaitOptions): Promise<boolean> {\n const updateEvents = honkerDb.updateEvents();\n closeables.add(updateEvents);\n let timeout: NodeJS.Timeout | undefined;\n let removeAbortListener: (() => void) | undefined;\n\n try {\n if (options?.signal?.aborted) {\n return false;\n }\n\n const updatePromise = updateEvents.next().then(\n () => true,\n () => false,\n );\n const races: Array<Promise<boolean>> = [updatePromise];\n\n if (options?.timeoutMs !== undefined) {\n const timeoutMs = options.timeoutMs;\n races.push(\n new Promise((resolve) => {\n timeout = setTimeout(\n () => resolve(false),\n Math.max(0, timeoutMs),\n );\n }),\n );\n }\n\n if (options?.signal) {\n races.push(\n new Promise((resolve) => {\n const onAbort = () => resolve(false);\n options.signal?.addEventListener('abort', onAbort, {\n once: true,\n });\n removeAbortListener = () =>\n options.signal?.removeEventListener('abort', onAbort);\n }),\n );\n }\n\n return await Promise.race(races);\n } finally {\n if (timeout) {\n clearTimeout(timeout);\n }\n removeAbortListener?.();\n closeables.delete(updateEvents);\n updateEvents.close?.();\n }\n },\n\n async prune(options?: NotificationPruneOptions): Promise<number> {\n return Number(\n honkerDb.pruneNotifications(options?.olderThanS, options?.maxKeep),\n );\n },\n };\n}\n\nfunction createVectorCapabilities(\n database: NativeDatabase,\n options: SqliteVectorCapabilityOptions,\n): VectorCapabilities {\n const initialized = new Map<\n string,\n { dimensions: number; metric: 'cosine' | 'l2' | 'ip' }\n >();\n const indexed = new Map<\n string,\n { metric: 'cosine' | 'l2' | 'ip'; options: SqliteVectorCapabilityOptions }\n >();\n\n const keyFor = (table: string, column: string) => `${table}.${column}`;\n\n const columnExists = (table: string, column: string): boolean => {\n const rows = database\n .prepare(`PRAGMA table_info(${quoteIdentifier(table)})`)\n .all()\n .map(toPlainRow);\n return rows.some((row: Record<string, any>) => row.name === column);\n };\n\n const ensureInitialized = (\n table: string,\n column: string,\n dimensions: number,\n metric: 'cosine' | 'l2' | 'ip' = 'cosine',\n ): void => {\n if (!Number.isInteger(dimensions) || dimensions <= 0) {\n throw new DatabaseError('Vector dimensions must be a positive integer', {\n dimensions,\n });\n }\n\n validateTableName(table);\n validateColumnName(column);\n\n executeNativeQuery(database, 'SELECT vector_init(?, ?, ?)', [\n table,\n column,\n `dimension=${dimensions},type=FLOAT32,distance=${sqliteVectorDistance(metric)}`,\n ]);\n initialized.set(keyFor(table, column), { dimensions, metric });\n };\n\n const quantize = (\n table: string,\n column: string,\n vectorOptions: SqliteVectorCapabilityOptions,\n ): void => {\n const quantizationOptions = sqliteVectorQuantization(vectorOptions);\n if (quantizationOptions) {\n executeNativeQuery(database, 'SELECT vector_quantize(?, ?, ?)', [\n table,\n column,\n quantizationOptions,\n ]);\n } else {\n executeNativeQuery(database, 'SELECT vector_quantize(?, ?)', [\n table,\n column,\n ]);\n }\n\n if (vectorOptions.preload) {\n executeNativeQuery(database, 'SELECT vector_quantize_preload(?, ?)', [\n table,\n column,\n ]);\n }\n };\n\n return {\n async ensureColumn(\n table: string,\n column: string,\n dimensions: number,\n ): Promise<void> {\n validateTableName(table);\n validateColumnName(column);\n\n try {\n if (!columnExists(table, column)) {\n executeNativeQuery(\n database,\n `ALTER TABLE ${quoteIdentifier(table)} ADD COLUMN ${quoteIdentifier(column)} BLOB`,\n );\n }\n ensureInitialized(table, column, dimensions, 'cosine');\n } catch (error) {\n throw new DatabaseError('Failed to ensure SQLite vector column', {\n table,\n column,\n dimensions,\n originalError: formatDbError(error),\n });\n }\n },\n\n async ensureIndex(\n table: string,\n column: string,\n indexOptions?: VectorIndexOptions,\n ): Promise<void> {\n validateTableName(table);\n validateColumnName(column);\n\n const key = keyFor(table, column);\n const dimensions =\n indexOptions?.dimensions ?? initialized.get(key)?.dimensions;\n if (!dimensions) {\n throw new DatabaseError(\n 'SQLite vector index creation requires dimensions',\n {\n table,\n column,\n hint: 'Call ensureColumn(table, column, dimensions) first or pass dimensions to ensureIndex().',\n },\n );\n }\n\n const metric = indexOptions?.metric ?? 'cosine';\n\n try {\n ensureInitialized(table, column, dimensions, metric);\n const vectorOptions = { ...options };\n quantize(table, column, vectorOptions);\n indexed.set(key, { metric, options: vectorOptions });\n } catch (error) {\n throw new DatabaseError('Failed to ensure SQLite vector index', {\n table,\n column,\n originalError: formatDbError(error),\n });\n }\n },\n\n async upsertVector(\n table: string,\n where: Record<string, any>,\n column: string,\n embedding: number[],\n ): Promise<void> {\n validateTableName(table);\n validateColumnName(column);\n\n const key = keyFor(table, column);\n const dimensions = initialized.get(key)?.dimensions ?? embedding.length;\n const { sql: whereClause, values } = buildQuestionWhere(where);\n\n if (!whereClause) {\n throw new DatabaseError(\n 'SQLite vector update requires at least one WHERE condition',\n { table, column },\n );\n }\n\n try {\n ensureInitialized(\n table,\n column,\n dimensions,\n initialized.get(key)?.metric ?? 'cosine',\n );\n executeNativeQuery(\n database,\n `UPDATE ${quoteIdentifier(table)} SET ${quoteIdentifier(column)} = vector_as_f32(?) ${whereClause}`,\n [JSON.stringify(embedding), ...values],\n );\n\n const indexState = indexed.get(key);\n if (indexState) {\n quantize(table, column, indexState.options);\n }\n } catch (error) {\n throw new DatabaseError('Failed to upsert SQLite vector', {\n table,\n column,\n where,\n originalError: formatDbError(error),\n });\n }\n },\n\n async search(\n table: string,\n column: string,\n embedding: number[],\n searchOptions?: VectorSearchOptions,\n ): Promise<VectorSearchResult[]> {\n validateTableName(table);\n validateColumnName(column);\n\n const key = keyFor(table, column);\n const metric = searchOptions?.metric ?? 'cosine';\n const limit = searchOptions?.limit ?? 10;\n const limitArg = BigInt(limit);\n const dimensions = initialized.get(key)?.dimensions ?? embedding.length;\n const indexState = indexed.get(key);\n const useQuantizedScan = indexState?.metric === metric;\n const scanFunction = useQuantizedScan\n ? 'vector_quantize_scan'\n : 'vector_full_scan';\n const convertedWhere = searchOptions?.where\n ? searchOptions.where.replace(/\\$(\\d+)/g, '?')\n : '';\n const whereParams = searchOptions?.params ?? [];\n\n try {\n ensureInitialized(table, column, dimensions, metric);\n\n const rows = convertedWhere\n ? executeNativeQuery(\n database,\n `SELECT base.*, base.rowid AS __sqlite_rowid, vec.distance\n FROM ${scanFunction}(?, ?, vector_as_f32(?)) AS vec\n JOIN ${quoteIdentifier(table)} AS base ON base.rowid = vec.rowid\n WHERE (${convertedWhere})\n ORDER BY vec.distance\n LIMIT ?`,\n [\n table,\n column,\n JSON.stringify(embedding),\n ...whereParams,\n limitArg,\n ],\n ).rows\n : executeNativeQuery(\n database,\n `SELECT base.*, base.rowid AS __sqlite_rowid, vec.distance\n FROM ${scanFunction}(?, ?, vector_as_f32(?), ?) AS vec\n JOIN ${quoteIdentifier(table)} AS base ON base.rowid = vec.rowid\n ORDER BY vec.distance`,\n [table, column, JSON.stringify(embedding), limitArg],\n ).rows;\n\n return rows.map((row) => {\n const { __sqlite_rowid: rowid, ...result } = row;\n return {\n ...result,\n id: String(result.id ?? rowid),\n distance: Number(row.distance),\n };\n });\n } catch (error) {\n throw new DatabaseError('Failed to execute SQLite vector search', {\n table,\n column,\n metric,\n limit,\n originalError: formatDbError(error),\n });\n }\n },\n };\n}\n\nexport async function getNativeSqliteDatabase(\n options: SqliteOptions = {},\n): Promise<DatabaseInterface> {\n const url = options.url || ':memory:';\n\n return getCachedSqliteDatabase('native', options, () =>\n createNativeSqliteDatabase(options, url),\n );\n}\n\nasync function createNativeSqliteDatabase(\n options: SqliteOptions,\n url: string,\n): Promise<DatabaseInterface> {\n const location = resolveNativeLocation(url);\n const notificationsOptions = getCapabilityOptions(\n options.capabilities?.notifications,\n );\n const vectorOptions = getCapabilityOptions(options.capabilities?.vector);\n const wantsNotifications = Boolean(options.capabilities?.notifications);\n const wantsVector = Boolean(options.capabilities?.vector);\n\n if (wantsNotifications && location.isMemory) {\n throw new DatabaseError(\n 'SQLite notification capabilities require a file-backed database',\n {\n url,\n hint: 'Use a temporary file-backed .db for development and tests that need notifications.',\n },\n );\n }\n\n const { DatabaseSync } = await loadNodeSqlite();\n const database = new DatabaseSync(location.location, {\n allowExtension: wantsVector,\n });\n\n // One lock per connection. `getNativeSqliteDatabase` hands cached callers\n // this same closure, so \"created here\" and \"per connection\" are the same\n // scope.\n const connectionLock = createTransactionLock(\n 'sqlite (native)',\n options.transactionQueueTimeout,\n );\n let closeResources: (() => Promise<void>) | undefined;\n\n try {\n if (wantsVector) {\n await loadSqliteVectorExtension(database);\n }\n\n const honkerDb =\n wantsNotifications && location.filePath\n ? await openHonkerDatabase(location.filePath, notificationsOptions)\n : null;\n const notificationCloseables = new Set<{ close?: () => void }>();\n\n const vectorCapabilities = wantsVector\n ? createVectorCapabilities(database, vectorOptions)\n : undefined;\n const notificationCapabilities = honkerDb\n ? createNotificationCapabilities(honkerDb, notificationCloseables)\n : undefined;\n\n const query = async (\n sql: string,\n ...values: any[]\n ): Promise<{ rows: Record<string, any>[]; rowCount: number }> => {\n const normalized = normalizeNativeQuery(sql, values);\n try {\n const result = executeNativeQuery(\n database,\n normalized.sql,\n normalized.args,\n );\n return { rows: result.rows, rowCount: result.rowCount };\n } catch (error) {\n throw wrapDatabaseError('Failed to execute raw query', error, {\n sql: normalized.sql,\n values: normalized.args,\n });\n }\n };\n\n const parseTemplate = (strings: TemplateStringsArray, ...vars: any[]) => {\n let sql = strings[0];\n const values = [];\n for (let i = 0; i < vars.length; i++) {\n values.push(vars[i]);\n sql += `?${strings[i + 1]}`;\n }\n return { sql, values };\n };\n\n const insert = async (\n table: string,\n data: Record<string, any> | Record<string, any>[],\n ): Promise<QueryResult> => {\n validateTableName(table);\n const records = (Array.isArray(data) ? data : [data]).map(\n serializeRecord,\n );\n if (records.length === 0) {\n return { operation: 'insert', affected: 0 };\n }\n const keys = resolveInsertColumns(table, records);\n validateColumnNames(keys);\n const placeholders = records\n .map(() => `(${keys.map(() => '?').join(', ')})`)\n .join(', ');\n const values = records.flatMap((record) =>\n keys.map((key) => record[key]),\n );\n const sql = `INSERT INTO ${table} (${keys.join(', ')}) VALUES ${placeholders}`;\n\n try {\n const result = executeNativeQuery(database, sql, values);\n return { operation: 'insert', affected: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to insert records into table', {\n table,\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const get = async (\n table: string,\n where: WhereClause,\n ): Promise<Record<string, any> | null> => {\n validateTableName(table);\n const { sql: whereClause, values } = buildQuestionWhere(where);\n if (!whereClause) {\n throw new DatabaseError(\n 'GET requires at least one WHERE condition to prevent returning an arbitrary record',\n { table },\n );\n }\n\n const sql = `SELECT * FROM ${table} ${whereClause}`;\n try {\n const result = executeNativeQuery(database, sql, values);\n return result.rows[0] || null;\n } catch (error) {\n throw new DatabaseError('Failed to retrieve record from table', {\n table,\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const list = async (\n table: string,\n where: WhereClause,\n ): Promise<Record<string, any>[]> => {\n validateTableName(table);\n const { sql: whereClause, values } = buildQuestionWhere(where);\n const sql = `SELECT * FROM ${table} ${whereClause}`;\n try {\n return executeNativeQuery(database, sql, values).rows;\n } catch (error) {\n throw new DatabaseError('Failed to list records from table', {\n table,\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const update = async (\n table: string,\n where: WhereClause,\n data: Record<string, any>,\n ): Promise<QueryResult> => {\n validateTableName(table);\n const serializedData = serializeRecord(data);\n const keys = Object.keys(serializedData);\n validateColumnNames(keys);\n const values = Object.values(serializedData);\n const setClause = keys.map((key) => `${key} = ?`).join(', ');\n const { sql: whereClause, values: whereValues } =\n buildQuestionWhere(where);\n\n if (!whereClause) {\n throw new DatabaseError(\n 'UPDATE requires at least one WHERE condition to prevent accidental update of all records',\n { table },\n );\n }\n\n const sql = `UPDATE ${table} SET ${setClause} ${whereClause}`;\n try {\n const result = executeNativeQuery(database, sql, [\n ...values,\n ...whereValues,\n ]);\n return { operation: 'update', affected: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to update records in table', {\n table,\n sql,\n values: [...values, ...whereValues],\n originalError: formatDbError(error),\n });\n }\n };\n\n const hasNullConflictValue = (\n conflictColumns: string[],\n data: Record<string, any>,\n ): boolean => conflictColumns.some((column) => data[column] === null);\n\n const validateUpsertConflictColumns = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): void => {\n const missingColumns = conflictColumns.filter(\n (column) => !(column in serializedData),\n );\n\n if (missingColumns.length > 0) {\n throw new DatabaseError('Conflict columns missing from data', {\n table,\n conflictColumns,\n missingColumns,\n availableColumns: Object.keys(serializedData),\n hint: 'All columns specified in ON CONFLICT must be present in the data being inserted. Undefined values are filtered out during serialization - consider using null or an empty string instead.',\n });\n }\n };\n\n const executeStandardUpsert = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): QueryResult => {\n const keys = Object.keys(serializedData);\n const values = Object.values(serializedData);\n const placeholders = keys.map(() => '?').join(', ');\n const updateSet = keys\n .map((key) => `${key} = excluded.${key}`)\n .join(', ');\n const conflict = conflictColumns.join(', ');\n const sql = `INSERT INTO ${table} (${keys.join(', ')}) VALUES (${placeholders}) ON CONFLICT(${conflict}) DO UPDATE SET ${updateSet}`;\n const result = executeNativeQuery(database, sql, values);\n return { operation: 'upsert', affected: result.rowCount };\n };\n\n const executeNullAwareUpsertAttempt = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): QueryResult => {\n const keys = Object.keys(serializedData);\n const values = Object.values(serializedData);\n const updateSet = keys.map((key) => `${key} = ?`).join(', ');\n const whereClause = conflictColumns\n .map((column) => `${column} IS ?`)\n .join(' AND ');\n const whereValues = conflictColumns.map(\n (column) => serializedData[column],\n );\n\n const updateResult = executeNativeQuery(\n database,\n `UPDATE ${table} SET ${updateSet} WHERE ${whereClause}`,\n [...values, ...whereValues],\n );\n\n if (updateResult.rowCount > 0) {\n return { operation: 'upsert', affected: updateResult.rowCount };\n }\n\n const placeholders = keys.map(() => '?').join(', ');\n const insertResult = executeNativeQuery(\n database,\n `INSERT INTO ${table} (${keys.join(', ')}) VALUES (${placeholders})`,\n values,\n );\n\n return { operation: 'upsert', affected: insertResult.rowCount };\n };\n\n /**\n * Rejects hostile table/column identifiers before an upsert builds SQL.\n *\n * Called from the public entry points rather than from `executeUpsert`, so\n * the failure reaches the caller naming the bad identifier instead of being\n * flattened into the wrapper's generic \"Failed to upsert record into table\".\n *\n * Validates the keys of the already-serialized snapshot — the exact array\n * the executors interpolate — not a fresh enumeration of the caller's\n * `data`. Enumerating `data` again could disagree with the snapshot if it is\n * a Proxy whose `ownKeys` trap returns different keys on successive reads.\n */\n const validateUpsertIdentifiers = (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n ): void => {\n validateTableName(table);\n validateColumnNames([...conflictColumns, ...Object.keys(serializedData)]);\n };\n\n const executeUpsert = async (\n table: string,\n conflictColumns: string[],\n serializedData: Record<string, any>,\n upsertOptions: UpsertOptions | undefined,\n acquireTransaction: boolean,\n ): Promise<QueryResult> => {\n validateUpsertConflictColumns(table, conflictColumns, serializedData);\n\n if (\n upsertOptions?.nullsDistinct ||\n !hasNullConflictValue(conflictColumns, serializedData)\n ) {\n return executeStandardUpsert(table, conflictColumns, serializedData);\n }\n\n if (!acquireTransaction) {\n return executeNullAwareUpsertAttempt(\n table,\n conflictColumns,\n serializedData,\n );\n }\n\n const lockKey = `${location.location}:${table}:${conflictColumns\n .map((column) => `${column}:${JSON.stringify(serializedData[column])}`)\n .join('|')}`;\n\n return withNativeNullAwareUpsertLock(lockKey, async () => {\n // This opens a transaction on the shared connection like any other, so\n // it takes the same lock — otherwise a null-aware upsert overlapping a\n // `transaction()` call reintroduces exactly the corruption the lock\n // exists to prevent.\n const releaseConnection = await connectionLock.acquire();\n try {\n database.exec('BEGIN IMMEDIATE');\n const result = executeNullAwareUpsertAttempt(\n table,\n conflictColumns,\n serializedData,\n );\n database.exec('COMMIT');\n return result;\n } catch (error) {\n try {\n database.exec('ROLLBACK');\n } catch (_rollbackError) {\n // Preserve the original failure.\n }\n throw error;\n } finally {\n releaseConnection();\n }\n });\n };\n\n const upsert = async (\n table: string,\n conflictColumns: string[],\n data: Record<string, any>,\n upsertOptions?: UpsertOptions,\n ): Promise<QueryResult> => {\n // Snapshot the record and the conflict columns once and thread both\n // through validation and SQL, so neither a hostile record nor a hostile\n // conflict-column array can present different identifiers to each.\n const serializedData = serializeRecord(data);\n const conflictCols = [...conflictColumns];\n validateUpsertIdentifiers(table, conflictCols, serializedData);\n try {\n return await executeUpsert(\n table,\n conflictCols,\n serializedData,\n upsertOptions,\n true,\n );\n } catch (error) {\n if (getErrorMessage(error) === 'Conflict columns missing from data') {\n throw error;\n }\n throw new DatabaseError('Failed to upsert record into table', {\n table,\n values: data,\n conflictColumns,\n originalError: formatDbError(error),\n });\n }\n };\n\n const upsertInCurrentTransaction = (\n table: string,\n conflictColumns: string[],\n data: Record<string, any>,\n upsertOptions?: UpsertOptions,\n ): Promise<QueryResult> => {\n // Snapshot the record and the conflict columns once and thread both\n // through validation and SQL, so neither a hostile record nor a hostile\n // conflict-column array can present different identifiers to each.\n const serializedData = serializeRecord(data);\n const conflictCols = [...conflictColumns];\n validateUpsertIdentifiers(table, conflictCols, serializedData);\n return executeUpsert(\n table,\n conflictCols,\n serializedData,\n upsertOptions,\n false,\n );\n };\n\n const getOrInsert = async (\n table: string,\n where: WhereClause,\n data: Record<string, any>,\n ): Promise<Record<string, any>> => {\n const existing = await get(table, where);\n if (existing) return existing;\n await insert(table, data);\n const inserted = await get(table, where);\n if (!inserted) {\n throw new DatabaseError('Failed to insert and retrieve record', {\n table,\n where,\n data,\n });\n }\n return inserted;\n };\n\n const deleteRecords = async (\n table: string,\n where: WhereClause,\n ): Promise<QueryResult> => {\n validateTableName(table);\n const { sql: whereClause, values } = buildQuestionWhere(where);\n if (!whereClause) {\n throw new DatabaseError(\n 'DELETE requires at least one WHERE condition to prevent accidental deletion of all records',\n { table },\n );\n }\n\n try {\n const result = executeNativeQuery(\n database,\n `DELETE FROM ${table} ${whereClause}`,\n values,\n );\n return { operation: 'delete', affected: result.rowCount };\n } catch (error) {\n throw new DatabaseError('Failed to delete records from table', {\n table,\n where,\n originalError: formatDbError(error),\n });\n }\n };\n\n const count = async (\n table: string,\n where?: WhereClause,\n ): Promise<number> => {\n validateTableName(table);\n if (\n !where ||\n (typeof where === 'object' && Object.keys(where).length === 0)\n ) {\n const result = executeNativeQuery(\n database,\n `SELECT COUNT(*) as count FROM ${table}`,\n );\n return Number(result.rows[0]?.count) || 0;\n }\n\n const { sql: whereClause, values } = buildQuestionWhere(where);\n const result = executeNativeQuery(\n database,\n `SELECT COUNT(*) as count FROM ${table} ${whereClause}`,\n values,\n );\n return Number(result.rows[0]?.count) || 0;\n };\n\n const tableExists = async (tableName: string): Promise<boolean> => {\n const result = executeNativeQuery(\n database,\n \"SELECT name FROM sqlite_master WHERE type='table' AND name=?\",\n [tableName],\n );\n return result.rows.length > 0;\n };\n\n const syncSchema = async (schema: string): Promise<void> => {\n const commands = schema\n .replace(/\\s+/g, ' ')\n .replace(/DEFAULT CAST\\(([^)]+)\\s+AS\\s+\\w+\\)/gi, 'DEFAULT $1')\n .trim()\n .split(';')\n .map((command) => command.trim())\n .filter((command) => command.length > 0);\n\n for (const command of commands) {\n database.exec(command);\n }\n };\n\n const many = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<Record<string, any>[]> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n return executeNativeQuery(database, sql, values).rows;\n } catch (error) {\n throw new DatabaseError('Failed to execute many query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const single = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<Record<string, any> | null> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n return executeNativeQuery(database, sql, values).rows[0] || null;\n } catch (error) {\n throw new DatabaseError('Failed to execute single query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const pluck = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<any> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n const row = executeNativeQuery(database, sql, values).rows[0];\n return row ? Object.values(row)[0] : null;\n } catch (error) {\n throw new DatabaseError('Failed to execute pluck query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const execute = async (\n strings: TemplateStringsArray,\n ...vars: any[]\n ): Promise<void> => {\n const { sql, values } = parseTemplate(strings, ...vars);\n try {\n if (values.length === 0) {\n database.exec(sql);\n return;\n }\n executeNativeQuery(database, sql, values);\n } catch (error) {\n throw new DatabaseError('Failed to execute query', {\n sql,\n values,\n originalError: formatDbError(error),\n });\n }\n };\n\n const oo = many;\n const oO = single;\n const ox = pluck;\n const xx = execute;\n\n const table = (tableName: string): TableInterface => ({\n insert: (data) => insert(tableName, data),\n get: (where) => get(tableName, where),\n list: (where) => list(tableName, where),\n });\n\n // Names nested savepoints. Only ever appended to an identifier the adapter\n // generates, never caller input.\n let savepointSequence = 0;\n\n /**\n * Re-enters the transaction already in progress under a savepoint.\n *\n * This is what the transaction-scoped interface exposes as `transaction`.\n * Handing it the top-level `transaction` instead — the previous behaviour —\n * sent a nested call into a second BEGIN on the one shared connection; that\n * throws, and the nested call's own ROLLBACK then discarded the *enclosing*\n * transaction's work while later writes committed in autocommit.\n */\n const nestedTransaction = async <T>(\n callback: (tx: DatabaseInterface) => Promise<T>,\n ): Promise<T> => {\n savepointSequence += 1;\n const name = `hv_sp_${savepointSequence}`;\n database.exec(`SAVEPOINT ${name}`);\n try {\n const result = await callback(\n buildDatabaseInterface(\n upsertInCurrentTransaction,\n nestedTransaction,\n refuseNestedBeginTransaction,\n ),\n );\n database.exec(`RELEASE SAVEPOINT ${name}`);\n return result;\n } catch (error) {\n try {\n // ROLLBACK TO leaves the savepoint defined, so release it too or it\n // accumulates for the life of the transaction.\n database.exec(`ROLLBACK TO SAVEPOINT ${name}`);\n database.exec(`RELEASE SAVEPOINT ${name}`);\n } catch {\n // The enclosing transaction is already unwinding; its teardown owns\n // the connection from here.\n }\n throw error;\n }\n };\n\n const transaction = async <T>(\n callback: (tx: DatabaseInterface) => Promise<T>,\n ): Promise<T> =>\n // Held across the whole BEGIN … COMMIT/ROLLBACK span. Without it two\n // overlapping calls raced on the one connection: the second BEGIN threw,\n // its catch ran ROLLBACK, and that rollback ended the *first*\n // transaction — half of its writes durable, half lost, and its promise\n // rejected, so the caller was told nothing had happened.\n connectionLock.run(async () => {\n try {\n database.exec('BEGIN TRANSACTION');\n const txDb = buildDatabaseInterface(\n upsertInCurrentTransaction,\n nestedTransaction,\n refuseNestedBeginTransaction,\n );\n const result = await callback(txDb);\n database.exec('COMMIT');\n return result;\n } catch (error) {\n // A failing ROLLBACK must not replace the caller's error: SQLite\n // reports \"cannot rollback - no transaction is active\" whenever the\n // transaction is already gone, which says nothing about what failed.\n try {\n database.exec('ROLLBACK');\n } catch {\n // Nothing left to roll back.\n }\n throw error;\n }\n });\n\n /**\n * The `beginTransaction` exposed on a transaction-scoped interface.\n *\n * Unlike `transaction`, a manual handle has no savepoint equivalent: it\n * would have to own the connection until the caller ends it, which the\n * enclosing transaction already does. Issuing a second BEGIN threw before\n * transactions were serialized; now it would instead wait on a lock its own\n * caller holds, so refuse explicitly rather than deadlock.\n */\n const refuseNestedBeginTransaction = async (): Promise<never> => {\n throw new NestedTransactionError(\n 'beginTransaction() cannot be called inside a transaction. Use the transaction you already have, or nest with transaction() to re-enter it under a savepoint.',\n { adapter: 'sqlite-native' },\n );\n };\n\n const beginTransaction = async (): Promise<TransactionHandle> => {\n // The handle owns the connection until the caller ends it, so the lock is\n // held across the gap rather than around a single call. A handle that is\n // never committed or rolled back therefore blocks every later transaction\n // until the queue timeout reports it.\n const releaseConnection = await connectionLock.acquire();\n try {\n database.exec('BEGIN TRANSACTION');\n } catch (error) {\n // No transaction was opened, so there is no handle to end it and\n // nothing left to release the connection.\n releaseConnection();\n throw error;\n }\n\n let active = true;\n\n // COMMIT and ROLLBACK can both throw, and the transaction is over either\n // way, so the connection goes back before the error is rethrown.\n const end = (command: 'COMMIT' | 'ROLLBACK'): void => {\n if (!active) {\n throw new DatabaseError('Transaction already ended', {});\n }\n try {\n database.exec(command);\n } catch (error) {\n // COMMIT can fail and leave the transaction *open* — SQLite documents\n // exactly that for SQLITE_BUSY. Releasing the connection then would hand\n // the next queued caller a connection still inside a transaction: its\n // BEGIN would throw, and its catch would ROLLBACK, discarding this\n // transaction's work. So normalize before releasing, the way the pooled\n // adapter's discardTxClient does.\n try {\n database.exec('ROLLBACK');\n } catch {\n // Already gone; nothing left to normalize.\n }\n throw error;\n } finally {\n active = false;\n releaseConnection();\n }\n };\n\n const commit = async (): Promise<void> => end('COMMIT');\n\n const rollback = async (): Promise<void> => end('ROLLBACK');\n\n return {\n // The handle is inside a transaction for the same reason a callback\n // scope is, so it re-enters via savepoint too.\n ...buildDatabaseInterface(\n upsertInCurrentTransaction,\n nestedTransaction,\n refuseNestedBeginTransaction,\n ),\n commit,\n rollback,\n isActive: () => active,\n };\n };\n\n const initializeSchemas = async (\n schemaOptions: SchemaInitializationOptions,\n ): Promise<void> => {\n const schemaManager = new DatabaseSchemaManager();\n await schemaManager.initializeSchemas(\n buildDatabaseInterface(upsert),\n schemaOptions,\n );\n };\n\n const getTableSchema = async (\n tableName: string,\n ): Promise<TableSchemaInfo | null> => {\n validateTableName(tableName);\n\n if (!(await tableExists(tableName))) {\n return null;\n }\n\n const columnRows = database\n .prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`)\n .all()\n .map(toPlainRow);\n\n const columns: Record<string, ColumnDefinition> = {};\n for (const row of columnRows) {\n columns[row.name as string] = {\n type: row.type as string,\n primaryKey: row.pk === 1,\n notNull: row.notnull === 1,\n defaultValue: row.dflt_value,\n };\n }\n\n const indexRows = executeNativeQuery(\n database,\n `SELECT name FROM sqlite_master\n WHERE type = 'index'\n AND tbl_name = ?\n AND name NOT LIKE 'sqlite_%'`,\n [tableName],\n ).rows;\n\n const indexes: IndexDefinition[] = [];\n for (const row of indexRows) {\n const indexName = row.name as string;\n const indexInfoRows = database\n .prepare(`PRAGMA index_info(${quoteIdentifier(indexName)})`)\n .all()\n .map(toPlainRow);\n const indexListRows = database\n .prepare(`PRAGMA index_list(${quoteIdentifier(tableName)})`)\n .all()\n .map(toPlainRow);\n\n indexes.push({\n name: indexName,\n columns: indexInfoRows.map((info: Record<string, any>) => info.name),\n unique: indexListRows.some(\n (info: Record<string, any>) =>\n info.name === indexName && info.unique === 1,\n ),\n });\n }\n\n const fkRows = database\n .prepare(`PRAGMA foreign_key_list(${quoteIdentifier(tableName)})`)\n .all()\n .map(toPlainRow);\n\n return {\n tableName,\n columns,\n indexes,\n foreignKeys: fkRows.map((row: Record<string, any>) => ({\n column: row.from as string,\n referencesTable: row.table as string,\n referencesColumn: row.to as string,\n onDelete: row.on_delete as string | undefined,\n onUpdate: row.on_update as string | undefined,\n })),\n };\n };\n\n const alterTable = {\n addColumn: async (\n tableName: string,\n column: ColumnDefinitionWithName,\n ): Promise<void> => {\n validateTableName(tableName);\n validateColumnName(column.name);\n let sql: string | undefined;\n try {\n sql = generateAddColumnStatement(tableName, column, 'sqlite');\n executeNativeQuery(database, sql);\n } catch (error) {\n throw wrapDatabaseError('Failed to add column to table', error, {\n table: tableName,\n column: column.name,\n ...(sql ? { sql } : {}),\n });\n }\n },\n\n addIndex: async (\n tableName: string,\n index: IndexDefinition,\n ): Promise<void> => {\n validateTableName(tableName);\n validateIndexName(index.name);\n for (const column of index.columns) {\n validateColumnName(column);\n }\n let sql: string | undefined;\n try {\n sql = generateCreateIndexStatement(tableName, index);\n executeNativeQuery(database, sql);\n } catch (error) {\n throw wrapDatabaseError('Failed to create index on table', error, {\n table: tableName,\n index: index.name,\n ...(sql ? { sql } : {}),\n });\n }\n },\n };\n\n const close = createNativeSqliteCloser(\n notificationCloseables,\n honkerDb,\n database,\n );\n closeResources = close;\n\n function buildDatabaseInterface(\n upsertImpl: DatabaseInterface['upsert'],\n transactionImpl: DatabaseInterface['transaction'] = transaction,\n beginTransactionImpl: DatabaseInterface['beginTransaction'] = beginTransaction,\n ): DatabaseInterface {\n return {\n url,\n client: database,\n query,\n insert,\n update,\n upsert: upsertImpl,\n get,\n list,\n getOrInsert,\n delete: deleteRecords,\n count,\n table,\n tableExists,\n many,\n single,\n pluck,\n execute,\n oo,\n oO,\n ox,\n xx,\n syncSchema,\n initializeSchemas,\n transaction: transactionImpl,\n beginTransaction: beginTransactionImpl,\n getTableSchema,\n alterTable,\n close,\n ...(vectorCapabilities ? { vector: vectorCapabilities } : {}),\n ...(notificationCapabilities\n ? { notifications: notificationCapabilities }\n : {}),\n };\n }\n\n const db = buildDatabaseInterface(upsert);\n const resolvedSchemas = resolveSchemas(options.schemas);\n if (resolvedSchemas && Object.keys(resolvedSchemas).length > 0) {\n createNativeTablesFromSchemas(database, resolvedSchemas);\n }\n\n return db;\n } catch (error) {\n try {\n if (closeResources) await closeResources();\n else database.close();\n } catch (cleanupError) {\n throw new AggregateError(\n [error, cleanupError],\n 'Native SQLite initialization and cleanup failed',\n );\n }\n throw error;\n }\n}\n"],"mappings":"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"}