@vielzeug/vault 2.3.1 → 2.4.0

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 (68) hide show
  1. package/dist/adapter-core.cjs +1 -1
  2. package/dist/adapter-core.cjs.map +1 -1
  3. package/dist/adapter-core.d.ts +2 -2
  4. package/dist/adapter-core.d.ts.map +1 -1
  5. package/dist/adapter-core.js +66 -116
  6. package/dist/adapter-core.js.map +1 -1
  7. package/dist/adapters/indexeddb.cjs +1 -1
  8. package/dist/adapters/indexeddb.cjs.map +1 -1
  9. package/dist/adapters/indexeddb.d.ts +3 -3
  10. package/dist/adapters/indexeddb.d.ts.map +1 -1
  11. package/dist/adapters/indexeddb.js +93 -102
  12. package/dist/adapters/indexeddb.js.map +1 -1
  13. package/dist/adapters/memory.cjs +1 -1
  14. package/dist/adapters/memory.cjs.map +1 -1
  15. package/dist/adapters/memory.d.ts +1 -3
  16. package/dist/adapters/memory.d.ts.map +1 -1
  17. package/dist/adapters/memory.js +24 -105
  18. package/dist/adapters/memory.js.map +1 -1
  19. package/dist/adapters/sqlite.cjs +16 -4
  20. package/dist/adapters/sqlite.cjs.map +1 -1
  21. package/dist/adapters/sqlite.d.ts +2 -3
  22. package/dist/adapters/sqlite.d.ts.map +1 -1
  23. package/dist/adapters/sqlite.js +122 -90
  24. package/dist/adapters/sqlite.js.map +1 -1
  25. package/dist/adapters/webstorage.cjs +1 -1
  26. package/dist/adapters/webstorage.cjs.map +1 -1
  27. package/dist/adapters/webstorage.d.ts.map +1 -1
  28. package/dist/adapters/webstorage.js +59 -66
  29. package/dist/adapters/webstorage.js.map +1 -1
  30. package/dist/index.cjs +1 -1
  31. package/dist/index.d.ts +1 -2
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +2 -3
  34. package/dist/internal.cjs +1 -1
  35. package/dist/internal.cjs.map +1 -1
  36. package/dist/internal.d.ts +1 -1
  37. package/dist/internal.d.ts.map +1 -1
  38. package/dist/internal.js +18 -23
  39. package/dist/internal.js.map +1 -1
  40. package/dist/query.cjs +1 -1
  41. package/dist/query.cjs.map +1 -1
  42. package/dist/query.d.ts +11 -79
  43. package/dist/query.d.ts.map +1 -1
  44. package/dist/query.js +14 -71
  45. package/dist/query.js.map +1 -1
  46. package/dist/types.cjs.map +1 -1
  47. package/dist/types.d.ts +1 -31
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/types.js.map +1 -1
  50. package/dist/vault.cjs +1 -1
  51. package/dist/vault.cjs.map +1 -1
  52. package/dist/vault.iife.js +1 -1
  53. package/dist/vault.iife.js.map +1 -1
  54. package/dist/vault.js +1 -1
  55. package/dist/vault.js.map +1 -1
  56. package/package.json +2 -1
  57. package/dist/_dev.cjs +0 -2
  58. package/dist/_dev.cjs.map +0 -1
  59. package/dist/_dev.d.ts +0 -2
  60. package/dist/_dev.d.ts.map +0 -1
  61. package/dist/_dev.js +0 -6
  62. package/dist/_dev.js.map +0 -1
  63. package/dist/prune.cjs +0 -2
  64. package/dist/prune.cjs.map +0 -1
  65. package/dist/prune.d.ts +0 -21
  66. package/dist/prune.d.ts.map +0 -1
  67. package/dist/prune.js +0 -16
  68. package/dist/prune.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.cjs","names":[],"sources":["../../src/adapters/sqlite.ts"],"sourcesContent":["import {\n assertBatchTables,\n type BatchImpl,\n buildAdapterOps,\n buildTxContext,\n type StorageBackend,\n} from '../adapter-core';\nimport { VaultDisposedError, VaultError } from '../errors';\nimport { encodeVaultKey, getRecordKey } from '../internal';\nimport { isExpired } from '../ttl';\nimport type {\n AnySchema,\n BaseAdapterOptions,\n IterableVaultStore,\n KeyOf,\n RecordOf,\n TransactionalVaultStore,\n TransactionContext,\n} from '../types';\n\nexport type { TransactionContext };\n\nexport type SQLiteParameter = null | number | string;\ntype SQLiteRow = Record<string, unknown>;\n\n/**\n * A synchronous SQLite statement with positional parameter binding.\n *\n * Adapters for drivers whose native statement API differs can implement this\n * structural protocol without adding a runtime dependency to Vault.\n */\nexport interface SQLiteStatement {\n all(...parameters: SQLiteParameter[]): readonly SQLiteRow[];\n finalize?(): void;\n get(...parameters: SQLiteParameter[]): SQLiteRow | undefined;\n run(...parameters: SQLiteParameter[]): unknown;\n}\n\n/**\n * A runtime-neutral synchronous SQLite connection.\n *\n * Node's `DatabaseSync`, Bun's `Database`, and Deno's `@db/sqlite` `Database`\n * satisfy this protocol directly.\n */\nexport interface SQLiteDatabase {\n close?(): void;\n exec(sql: string): void;\n prepare(sql: string): SQLiteStatement;\n}\n\nexport type SQLiteVaultOptions<S extends AnySchema> = BaseAdapterOptions<S> & {\n /** Closes the caller-provided connection during store disposal when true. */\n closeOnDispose?: boolean;\n database: SQLiteDatabase;\n /** Namespace that isolates this store's records in the shared connection. */\n name: string;\n};\n\n/** SQLite provides atomic batches and lazy keyset-paginated iteration. */\nexport interface SQLiteVaultStore<S extends AnySchema> extends TransactionalVaultStore<S>, IterableVaultStore<S> {}\n\ntype ConnectionState = {\n batchActive: boolean;\n executor: ConnectionExecutor;\n initialized: Promise<void>;\n listeners: Set<ConnectionListener>;\n};\ntype ConnectionListener = (name: string, table: string) => void;\ntype KeyColumns = { encoded: string; kind: 'number' | 'string'; number: number | null; string: string | null };\ntype StoredRow = { expiresAt: number | undefined; json: string; rowId: number };\n\nconst connectionStates = new WeakMap<SQLiteDatabase, ConnectionState>();\nconst RECORDS_TABLE = '\"__vielzeug_vault_records\"';\nconst METADATA_TABLE = '\"__vielzeug_vault_metadata\"';\nconst STORAGE_FORMAT_VERSION = 1;\nconst ITERATION_PAGE_SIZE = 100;\n\nclass ConnectionExecutor {\n private tail: Promise<void> = Promise.resolve();\n\n async acquire(): Promise<() => void> {\n let release: (() => void) | undefined;\n const previous = this.tail;\n\n this.tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous;\n\n return () => release?.();\n }\n\n async run<T>(work: () => T | Promise<T>): Promise<T> {\n const release = await this.acquire();\n\n try {\n return await work();\n } finally {\n release();\n }\n }\n}\n\nfunction getConnectionState(database: SQLiteDatabase): ConnectionState {\n const current = connectionStates.get(database);\n\n if (current) return current;\n\n const executor = new ConnectionExecutor();\n const state: ConnectionState = {\n batchActive: false,\n executor,\n initialized: executor.run(() => initializeDatabase(database)),\n listeners: new Set(),\n };\n\n connectionStates.set(database, state);\n\n return state;\n}\n\nfunction initializeDatabase(database: SQLiteDatabase): void {\n database.exec(\n `\n CREATE TABLE IF NOT EXISTS ${METADATA_TABLE} (\n namespace TEXT PRIMARY KEY,\n format_version INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS ${RECORDS_TABLE} (\n namespace TEXT NOT NULL,\n table_name TEXT NOT NULL,\n key_tag TEXT NOT NULL,\n key_kind TEXT NOT NULL,\n key_number REAL,\n key_string TEXT,\n value_json TEXT NOT NULL,\n expires_at INTEGER,\n PRIMARY KEY (namespace, table_name, key_tag)\n );\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_expiration\"\n ON ${RECORDS_TABLE} (namespace, table_name, expires_at);\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_number_key\"\n ON ${RECORDS_TABLE} (namespace, table_name, key_kind, key_number);\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_string_key\"\n ON ${RECORDS_TABLE} (namespace, table_name, key_kind, key_string);\n `,\n );\n}\n\nfunction initializeNamespace(database: SQLiteDatabase, name: string): void {\n const row = get(database, `SELECT format_version FROM ${METADATA_TABLE} WHERE namespace = ?`, [name]);\n\n if (row === undefined) {\n run(database, `INSERT INTO ${METADATA_TABLE} (namespace, format_version) VALUES (?, ?)`, [\n name,\n STORAGE_FORMAT_VERSION,\n ]);\n\n return;\n }\n\n if (row.format_version !== STORAGE_FORMAT_VERSION) {\n throw new VaultError(`SQLite storage format for \"${name}\" is not supported`);\n }\n}\n\nfunction assertName(name: string): void {\n if (name.length === 0) throw new VaultError('createSQLite: name must not be empty');\n}\n\nfunction assertJsonValue(value: unknown, seen: Set<object>, path: string): void {\n if (value === null || typeof value === 'boolean' || typeof value === 'string') return;\n\n if (typeof value === 'number') {\n if (Number.isFinite(value)) return;\n\n throw new VaultError(`SQLite serialization failed at ${path}: numbers must be finite`);\n }\n\n if (typeof value !== 'object') {\n throw new VaultError(`SQLite serialization failed at ${path}: expected a JSON-compatible value`);\n }\n\n if (seen.has(value))\n throw new VaultError(`SQLite serialization failed at ${path}: circular references are not supported`);\n\n if (Array.isArray(value)) {\n seen.add(value);\n\n for (let index = 0; index < value.length; index += 1) {\n assertJsonValue(value[index], seen, `${path}[${String(index)}]`);\n }\n\n seen.delete(value);\n\n return;\n }\n\n const prototype = Object.getPrototypeOf(value);\n\n if (prototype !== null && prototype !== Object.prototype) {\n throw new VaultError(`SQLite serialization failed at ${path}: expected a plain object`);\n }\n\n seen.add(value);\n\n for (const [key, nested] of Object.entries(value)) {\n assertJsonValue(nested, seen, `${path}.${key}`);\n }\n\n seen.delete(value);\n}\n\nfunction encodeJson(value: object): string {\n assertJsonValue(value, new Set(), 'record');\n\n return JSON.stringify(value);\n}\n\nfunction decodeJson(json: string): object {\n try {\n const value: unknown = JSON.parse(json);\n\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new VaultError('stored record is not a JSON object');\n }\n\n return value;\n } catch (error) {\n if (error instanceof VaultError) throw error;\n\n throw new VaultError('stored record contains invalid JSON', { cause: error });\n }\n}\n\nfunction toKeyColumns(key: number | string): KeyColumns {\n const encoded = encodeVaultKey(key);\n\n return typeof key === 'number'\n ? { encoded, kind: 'number', number: key, string: null }\n : { encoded, kind: 'string', number: null, string: key };\n}\n\nfunction getStoredRow(row: SQLiteRow): StoredRow {\n const json = row.value_json;\n const rawExpiresAt = row.expires_at;\n const rowId = row.row_id;\n\n if (typeof json !== 'string' || typeof rowId !== 'number' || !Number.isInteger(rowId)) {\n throw new VaultError('SQLite storage contains a malformed record');\n }\n\n if (rawExpiresAt !== null && (typeof rawExpiresAt !== 'number' || !Number.isFinite(rawExpiresAt))) {\n throw new VaultError('SQLite storage contains a malformed expiration timestamp');\n }\n\n const expiresAt = typeof rawExpiresAt === 'number' ? rawExpiresAt : undefined;\n\n return { expiresAt, json, rowId };\n}\n\nfunction withStatement<T>(database: SQLiteDatabase, sql: string, work: (statement: SQLiteStatement) => T): T {\n const statement = database.prepare(sql);\n\n try {\n return work(statement);\n } finally {\n statement.finalize?.();\n }\n}\n\nfunction run(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): unknown {\n return withStatement(database, sql, (statement) => statement.run(...parameters));\n}\n\nfunction get(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): SQLiteRow | undefined {\n return withStatement(database, sql, (statement) => statement.get(...parameters));\n}\n\nfunction all(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): readonly SQLiteRow[] {\n return withStatement(database, sql, (statement) => statement.all(...parameters));\n}\n\nfunction deleteExpired(database: SQLiteDatabase, name: string, table: string): void {\n run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND expires_at IS NOT NULL AND expires_at <= ?`,\n [name, table, Date.now()],\n );\n}\n\nfunction decodeLiveRecord<T extends object>(database: SQLiteDatabase, row: SQLiteRow): T | undefined {\n const stored = getStoredRow(row);\n\n if (isExpired(stored.expiresAt)) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE rowid = ?`, [stored.rowId]);\n\n return undefined;\n }\n\n return decodeJson(stored.json) as T;\n}\n\nfunction getAllLive<T extends object>(\n database: SQLiteDatabase,\n name: string,\n table: string,\n filterSql = '',\n filterParameters: SQLiteParameter[] = [],\n): T[] {\n deleteExpired(database, name, table);\n\n const records = all(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ?${filterSql}\n ORDER BY rowid`,\n [name, table, ...filterParameters],\n );\n\n return records.flatMap((row) => {\n const record = decodeLiveRecord<T>(database, row);\n\n return record === undefined ? [] : [record];\n });\n}\n\nfunction createDirectCore<S extends AnySchema, K extends keyof S & string>(\n database: SQLiteDatabase,\n name: string,\n schema: S,\n): StorageBackend<S, K> {\n const getRecord = <T extends K>(table: T, key: KeyOf<S, T>): RecordOf<S, T> | undefined => {\n const columns = toKeyColumns(key);\n const row = get(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag = ?`,\n [name, table, columns.encoded],\n );\n\n return row === undefined ? undefined : decodeLiveRecord<RecordOf<S, T>>(database, row);\n };\n\n const core: StorageBackend<S, K> = {\n async clear(table) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`, [name, table]);\n },\n async count(table) {\n deleteExpired(database, name, table);\n\n const row = get(\n database,\n `SELECT COUNT(*) AS count FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`,\n [name, table],\n );\n const count = row?.count;\n\n if (typeof count !== 'number') throw new VaultError('SQLite storage returned an invalid count');\n\n return count;\n },\n async delete(table, key) {\n const live = getRecord(table, key) !== undefined;\n const columns = toKeyColumns(key);\n\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ? AND key_tag = ?`, [\n name,\n table,\n columns.encoded,\n ]);\n\n return live;\n },\n async deleteMany(table, keys) {\n let deleted = 0;\n\n for (const key of keys) {\n if (await core.delete(table, key)) deleted += 1;\n }\n\n return deleted;\n },\n async get(table, key) {\n return getRecord(table, key);\n },\n async getAll(table) {\n return getAllLive<RecordOf<S, typeof table>>(database, name, table);\n },\n async getAllKeys(table) {\n return (await core.getAll(table)).map((record) => getRecordKey(schema, table, record));\n },\n async getByKeyRange(table, range) {\n if (range.type === 'eq')\n return getAllLive<RecordOf<S, typeof table>>(database, name, table, ' AND key_tag = ?', [\n toKeyColumns(range.value as KeyOf<S, typeof table>).encoded,\n ]);\n\n if (range.type === 'between') {\n if (\n typeof range.lower !== typeof range.upper ||\n (typeof range.lower !== 'number' && typeof range.lower !== 'string')\n ) {\n return getAllLive<RecordOf<S, typeof table>>(database, name, table);\n }\n\n const column = typeof range.lower === 'number' ? 'key_number' : 'key_string';\n\n return getAllLive<RecordOf<S, typeof table>>(\n database,\n name,\n table,\n ` AND key_kind = ? AND ${column} >= ? AND ${column} <= ?`,\n [typeof range.lower === 'number' ? 'number' : 'string', range.lower, range.upper as string | number],\n );\n }\n\n return getAllLive<RecordOf<S, typeof table>>(\n database,\n name,\n table,\n ' AND key_kind = ? AND substr(key_string, 1, length(?)) = ?',\n ['string', range.prefix, range.prefix],\n );\n },\n async getMany(table, keys) {\n return keys.map((key) => getRecord(table, key));\n },\n async getRawCount(table) {\n const row = get(\n database,\n `SELECT COUNT(*) AS count FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`,\n [name, table],\n );\n const count = row?.count;\n\n if (typeof count !== 'number') throw new VaultError('SQLite storage returned an invalid count');\n\n return count;\n },\n async has(table, key) {\n return getRecord(table, key) !== undefined;\n },\n async pruneAllExpired() {\n const results: Record<string, number> = {};\n\n for (const table of Object.keys(schema)) {\n results[table] = await core.pruneExpiredInTable(table as K);\n }\n\n return results;\n },\n async pruneExpiredInTable(table) {\n const before = await core.getRawCount!(table);\n\n deleteExpired(database, name, table);\n\n return before - (await core.getRawCount!(table));\n },\n async put(table, value, ttl) {\n const key = getRecordKey(schema, table, value);\n const columns = toKeyColumns(key);\n const expiresAt = ttl === undefined ? null : Date.now() + ttl;\n\n run(\n database,\n `INSERT INTO ${RECORDS_TABLE}\n (namespace, table_name, key_tag, key_kind, key_number, key_string, value_json, expires_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET\n key_kind = excluded.key_kind,\n key_number = excluded.key_number,\n key_string = excluded.key_string,\n value_json = excluded.value_json,\n expires_at = excluded.expires_at`,\n [name, table, columns.encoded, columns.kind, columns.number, columns.string, encodeJson(value), expiresAt],\n );\n },\n async putAll(table, values, ttl) {\n for (const value of values) {\n await core.put(table, value, ttl);\n }\n },\n };\n\n return core;\n}\n\n/**\n * Creates a SQLite-backed Vault store. The connection is caller-owned unless\n * `closeOnDispose` is explicitly enabled.\n */\nexport function createSQLite<S extends AnySchema>(options: SQLiteVaultOptions<S>): SQLiteVaultStore<S> {\n const { closeOnDispose = false, database, logger, name, onMetrics, schema, validators } = options;\n\n assertName(name);\n\n const state = getConnectionState(database);\n const namespaceReady = state.executor.run(async () => {\n await state.initialized;\n initializeNamespace(database, name);\n });\n let ownListener: ConnectionListener | undefined;\n\n const directCore = createDirectCore(database, name, schema);\n const withConnection = <T>(work: () => Promise<T>): Promise<T> =>\n state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n\n return work();\n });\n const guardedCore = Object.fromEntries(\n Object.entries(directCore).map(([method, implementation]) => [\n method,\n (...arguments_: unknown[]) => {\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n return withConnection(() => (implementation as (...args: unknown[]) => Promise<unknown>)(...arguments_));\n },\n ]),\n ) as StorageBackend<S>;\n\n let batch: BatchImpl<S> | undefined;\n const adapter = buildAdapterOps(schema, guardedCore, {\n logger,\n onCrossTabMessage(notify) {\n const listener: ConnectionListener = (eventName, table) => {\n if (eventName === name && Object.hasOwn(schema, table)) notify(table as keyof S & string);\n };\n\n ownListener = listener;\n state.listeners.add(listener);\n\n return () => {\n state.listeners.delete(listener);\n\n if (ownListener === listener) ownListener = undefined;\n };\n },\n onMetrics,\n onMutation(table) {\n for (const listener of state.listeners) {\n if (listener !== ownListener) listener(name, table);\n }\n },\n onTransactions: (deps) => {\n batch = async (tables, fn) => {\n assertBatchTables(tables);\n\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n return state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n\n const dirtyTables = new Set<keyof S & string>();\n const txCore = createDirectCore<S, keyof S & string>(database, name, schema);\n const tx = buildTxContext(\n schema,\n txCore,\n (table) => dirtyTables.add(table),\n deps.validate,\n new Set<string>(tables),\n );\n let transactionStarted = false;\n let committed = false;\n\n state.batchActive = true;\n\n try {\n database.exec('BEGIN IMMEDIATE');\n transactionStarted = true;\n\n const result = await fn(tx);\n\n database.exec('COMMIT');\n committed = true;\n\n for (const table of dirtyTables) {\n deps.notifyMutation(table);\n }\n\n return result;\n } catch (error) {\n if (transactionStarted && !committed) {\n try {\n database.exec('ROLLBACK');\n } catch (rollbackError) {\n throw new VaultError('SQLite batch rollback failed', { cause: rollbackError });\n }\n }\n\n throw error;\n } finally {\n state.batchActive = false;\n }\n });\n };\n },\n schema,\n validators,\n });\n\n if (!batch) throw new VaultError('SQLite transaction capability was not initialized');\n\n const store: SQLiteVaultStore<S> = {\n ...adapter,\n batch,\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>> {\n if (adapter.disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<RecordOf<S, K>> {\n let completed = false;\n let lastRowId = 0;\n let lease: (() => void) | undefined;\n let rows: readonly SQLiteRow[] = [];\n let index = 0;\n\n const release = (): void => {\n lease?.();\n lease = undefined;\n };\n const loadNextPage = (): void => {\n rows = all(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND rowid > ?\n ORDER BY rowid\n LIMIT ?`,\n [name, table, lastRowId, ITERATION_PAGE_SIZE],\n );\n index = 0;\n };\n\n return {\n async next(): Promise<IteratorResult<RecordOf<S, K>>> {\n if (completed) return { done: true, value: undefined };\n\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n try {\n if (!lease) {\n lease = await state.executor.acquire();\n await state.initialized;\n await namespaceReady;\n }\n\n while (true) {\n if (index >= rows.length) {\n loadNextPage();\n\n if (rows.length === 0) {\n completed = true;\n release();\n\n return { done: true, value: undefined };\n }\n }\n\n const row = rows[index++];\n const stored = getStoredRow(row);\n\n lastRowId = stored.rowId;\n\n const value = decodeLiveRecord<RecordOf<S, K>>(database, row);\n\n if (value !== undefined) return { done: false, value };\n }\n } catch (error) {\n completed = true;\n release();\n\n throw error;\n }\n },\n async return(value?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n completed = true;\n release();\n\n return { done: true, value: value as RecordOf<S, K> };\n },\n async throw(error?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n completed = true;\n release();\n\n throw error;\n },\n };\n },\n };\n },\n };\n\n if (closeOnDispose) {\n const dispose = store.dispose.bind(store);\n let closePromise: Promise<void> | undefined;\n\n store.dispose = async (): Promise<void> => {\n await dispose();\n closePromise ??= state.executor.run(() => database.close?.());\n await closePromise;\n };\n store[Symbol.asyncDispose] = async (): Promise<void> => {\n await store.dispose();\n };\n }\n\n return store;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sqlite.cjs","names":[],"sources":["../../src/adapters/sqlite.ts"],"sourcesContent":["import {\n assertBatchTables,\n type BatchImpl,\n buildAdapterOps,\n buildTxContext,\n type StorageBackend,\n} from '../adapter-core';\nimport { VaultDisposedError, VaultError } from '../errors';\nimport { encodeVaultKey, getRecordKey } from '../internal';\nimport { isExpired } from '../ttl';\nimport type {\n AnySchema,\n BaseAdapterOptions,\n KeyOf,\n RecordOf,\n TransactionalVaultStore,\n TransactionContext,\n} from '../types';\n\nexport type { TransactionContext };\n\nexport type SQLiteParameter = null | number | string;\ntype SQLiteRow = Record<string, unknown>;\n\n/**\n * A synchronous SQLite statement with positional parameter binding.\n *\n * Adapters for drivers whose native statement API differs can implement this\n * structural protocol without adding a runtime dependency to Vault.\n */\nexport interface SQLiteStatement {\n all(...parameters: SQLiteParameter[]): readonly SQLiteRow[];\n finalize?(): void;\n get(...parameters: SQLiteParameter[]): SQLiteRow | undefined;\n run(...parameters: SQLiteParameter[]): unknown;\n}\n\n/**\n * A runtime-neutral synchronous SQLite connection.\n *\n * Node's `DatabaseSync`, Bun's `Database`, and Deno's `@db/sqlite` `Database`\n * satisfy this protocol directly.\n */\nexport interface SQLiteDatabase {\n close?(): void;\n exec(sql: string): void;\n prepare(sql: string): SQLiteStatement;\n}\n\nexport type SQLiteVaultOptions<S extends AnySchema> = BaseAdapterOptions<S> & {\n /** Closes the caller-provided connection during store disposal when true. */\n closeOnDispose?: boolean;\n database: SQLiteDatabase;\n /** Namespace that isolates this store's records in the shared connection. */\n name: string;\n};\n\n/** SQLite provides atomic batches and lazy keyset-paginated iteration. */\nexport type SQLiteVaultStore<S extends AnySchema> = TransactionalVaultStore<S>;\n\ntype ConnectionState = {\n batchActive: boolean;\n executor: ConnectionExecutor;\n initialized: Promise<void>;\n listeners: Set<ConnectionListener>;\n};\ntype ConnectionListener = (name: string, table: string) => void;\ntype KeyColumns = { encoded: string; kind: 'number' | 'string'; number: number | null; string: string | null };\ntype StoredRow = { expiresAt: number | undefined; json: string; rowId: number };\n\nconst connectionStates = new WeakMap<SQLiteDatabase, ConnectionState>();\nconst RECORDS_TABLE = '\"__vielzeug_vault_records\"';\nconst METADATA_TABLE = '\"__vielzeug_vault_metadata\"';\nconst STORAGE_FORMAT_VERSION = 1;\nconst ITERATION_PAGE_SIZE = 100;\n\nclass ConnectionExecutor {\n private tail: Promise<void> = Promise.resolve();\n\n async acquire(): Promise<() => void> {\n let release: (() => void) | undefined;\n const previous = this.tail;\n\n this.tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous;\n\n return () => release?.();\n }\n\n async run<T>(work: () => T | Promise<T>): Promise<T> {\n const release = await this.acquire();\n\n try {\n return await work();\n } finally {\n release();\n }\n }\n}\n\nfunction getConnectionState(database: SQLiteDatabase): ConnectionState {\n const current = connectionStates.get(database);\n\n if (current) return current;\n\n const executor = new ConnectionExecutor();\n const state: ConnectionState = {\n batchActive: false,\n executor,\n initialized: executor.run(() => initializeDatabase(database)),\n listeners: new Set(),\n };\n\n connectionStates.set(database, state);\n\n return state;\n}\n\nfunction initializeDatabase(database: SQLiteDatabase): void {\n database.exec(\n `\n CREATE TABLE IF NOT EXISTS ${METADATA_TABLE} (\n namespace TEXT PRIMARY KEY,\n format_version INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS ${RECORDS_TABLE} (\n namespace TEXT NOT NULL,\n table_name TEXT NOT NULL,\n key_tag TEXT NOT NULL,\n key_kind TEXT NOT NULL,\n key_number REAL,\n key_string TEXT,\n value_json TEXT NOT NULL,\n expires_at INTEGER,\n PRIMARY KEY (namespace, table_name, key_tag)\n );\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_expiration\"\n ON ${RECORDS_TABLE} (namespace, table_name, expires_at);\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_number_key\"\n ON ${RECORDS_TABLE} (namespace, table_name, key_kind, key_number);\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_string_key\"\n ON ${RECORDS_TABLE} (namespace, table_name, key_kind, key_string);\n `,\n );\n}\n\nfunction initializeNamespace(database: SQLiteDatabase, name: string): void {\n const row = get(database, `SELECT format_version FROM ${METADATA_TABLE} WHERE namespace = ?`, [name]);\n\n if (row === undefined) {\n run(database, `INSERT INTO ${METADATA_TABLE} (namespace, format_version) VALUES (?, ?)`, [\n name,\n STORAGE_FORMAT_VERSION,\n ]);\n\n return;\n }\n\n if (row.format_version !== STORAGE_FORMAT_VERSION) {\n throw new VaultError(`SQLite storage format for \"${name}\" is not supported`);\n }\n}\n\nfunction assertName(name: string): void {\n if (name.length === 0) throw new VaultError('createSQLite: name must not be empty');\n}\n\nfunction assertJsonValue(value: unknown, seen: Set<object>, path: string): void {\n if (value === null || typeof value === 'boolean' || typeof value === 'string') return;\n\n if (typeof value === 'number') {\n if (Number.isFinite(value)) return;\n\n throw new VaultError(`SQLite serialization failed at ${path}: numbers must be finite`);\n }\n\n if (typeof value !== 'object') {\n throw new VaultError(`SQLite serialization failed at ${path}: expected a JSON-compatible value`);\n }\n\n if (seen.has(value as object)) {\n throw new VaultError(`SQLite serialization failed at ${path}: circular references are not supported`);\n }\n\n if (Array.isArray(value)) {\n seen.add(value);\n\n for (let index = 0; index < value.length; index += 1) {\n assertJsonValue(value[index], seen, `${path}[${String(index)}]`);\n }\n\n seen.delete(value);\n\n return;\n }\n\n const prototype = Object.getPrototypeOf(value);\n\n if (prototype !== null && prototype !== Object.prototype) {\n throw new VaultError(`SQLite serialization failed at ${path}: expected a plain object`);\n }\n\n seen.add(value as object);\n\n for (const [key, nested] of Object.entries(value)) {\n assertJsonValue(nested, seen, `${path}.${key}`);\n }\n\n seen.delete(value);\n}\n\nfunction encodeJson(value: object): string {\n assertJsonValue(value, new Set(), 'record');\n\n return JSON.stringify(value);\n}\n\nfunction decodeJson(json: string): object {\n try {\n const value: unknown = JSON.parse(json);\n\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new VaultError('stored record is not a JSON object');\n }\n\n return value;\n } catch (error) {\n if (error instanceof VaultError) throw error;\n\n throw new VaultError('stored record contains invalid JSON', { cause: error });\n }\n}\n\nfunction toKeyColumns(key: number | string): KeyColumns {\n const encoded = encodeVaultKey(key);\n\n return typeof key === 'number'\n ? { encoded, kind: 'number', number: key, string: null }\n : { encoded, kind: 'string', number: null, string: key };\n}\n\nfunction getStoredRow(row: SQLiteRow): StoredRow {\n const json = row.value_json;\n const rawExpiresAt = row.expires_at;\n const rowId = row.row_id;\n\n if (typeof json !== 'string' || typeof rowId !== 'number' || !Number.isInteger(rowId)) {\n throw new VaultError('SQLite storage contains a malformed record');\n }\n\n if (rawExpiresAt !== null && (typeof rawExpiresAt !== 'number' || !Number.isFinite(rawExpiresAt))) {\n throw new VaultError('SQLite storage contains a malformed expiration timestamp');\n }\n\n const expiresAt = typeof rawExpiresAt === 'number' ? rawExpiresAt : undefined;\n\n return { expiresAt, json, rowId };\n}\n\nfunction withStatement<T>(database: SQLiteDatabase, sql: string, work: (statement: SQLiteStatement) => T): T {\n const statement = database.prepare(sql);\n\n try {\n return work(statement);\n } finally {\n statement.finalize?.();\n }\n}\n\nfunction run(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): unknown {\n return withStatement(database, sql, (statement) => statement.run(...parameters));\n}\n\nfunction get(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): SQLiteRow | undefined {\n return withStatement(database, sql, (statement) => statement.get(...parameters));\n}\n\nfunction all(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): readonly SQLiteRow[] {\n return withStatement(database, sql, (statement) => statement.all(...parameters));\n}\n\nfunction deleteExpired(database: SQLiteDatabase, name: string, table: string): void {\n run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND expires_at IS NOT NULL AND expires_at <= ?`,\n [name, table, Date.now()],\n );\n}\n\nfunction decodeLiveRecord<T extends object>(database: SQLiteDatabase, row: SQLiteRow): T | undefined {\n const stored = getStoredRow(row);\n\n if (isExpired(stored.expiresAt)) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE rowid = ?`, [stored.rowId]);\n\n return undefined;\n }\n\n return decodeJson(stored.json) as T;\n}\n\nfunction getAllLive<T extends object>(\n database: SQLiteDatabase,\n name: string,\n table: string,\n filterSql = '',\n filterParameters: SQLiteParameter[] = [],\n): T[] {\n deleteExpired(database, name, table);\n\n const records = all(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ?${filterSql}\n ORDER BY rowid`,\n [name, table, ...filterParameters],\n );\n\n return records.flatMap((row) => {\n const record = decodeLiveRecord<T>(database, row);\n\n return record === undefined ? [] : [record];\n });\n}\n\nfunction createDirectCore<S extends AnySchema, K extends keyof S & string>(\n database: SQLiteDatabase,\n name: string,\n schema: S,\n inTransaction = false,\n): StorageBackend<S, K> {\n const getRecord = <T extends K>(table: T, key: KeyOf<S, T>): RecordOf<S, T> | undefined => {\n const columns = toKeyColumns(key);\n const row = get(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag = ?`,\n [name, table, columns.encoded],\n );\n\n return row === undefined ? undefined : decodeLiveRecord<RecordOf<S, T>>(database, row);\n };\n\n const core: StorageBackend<S, K> = {\n async clear(table) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`, [name, table]);\n },\n async count(table) {\n deleteExpired(database, name, table);\n\n const row = get(\n database,\n `SELECT COUNT(*) AS count FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`,\n [name, table],\n );\n const count = row?.count;\n\n if (typeof count !== 'number') throw new VaultError('SQLite storage returned an invalid count');\n\n return count;\n },\n async delete(table, key) {\n const columns = toKeyColumns(key);\n const result = run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag = ?\n AND (expires_at IS NULL OR expires_at > ?)`,\n [name, table, columns.encoded, Date.now()],\n ) as { changes?: number } | undefined;\n\n return (result?.changes ?? 0) > 0;\n },\n async deleteMany(table, keys) {\n if (keys.length === 0) return 0;\n\n let deleted = 0;\n // 3 fixed params: namespace, table_name, expires_at check.\n const SQLITE_PARAM_LIMIT = 999;\n const MAX_KEYS_PER_CHUNK = SQLITE_PARAM_LIMIT - 3;\n const encodedKeys = keys.map((k) => toKeyColumns(k).encoded);\n\n for (let i = 0; i < encodedKeys.length; i += MAX_KEYS_PER_CHUNK) {\n const chunk = encodedKeys.slice(i, i + MAX_KEYS_PER_CHUNK);\n const placeholders = chunk.map(() => '?').join(', ');\n const result = run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag IN (${placeholders})\n AND (expires_at IS NULL OR expires_at > ?)`,\n [name, table, ...chunk, Date.now()],\n ) as { changes?: number } | undefined;\n\n deleted += result?.changes ?? 0;\n }\n\n return deleted;\n },\n async get(table, key) {\n return getRecord(table, key);\n },\n async getAll(table) {\n return getAllLive<RecordOf<S, typeof table>>(database, name, table);\n },\n async getAllKeys(table) {\n return (await core.getAll(table)).map((record) => getRecordKey(schema, table, record));\n },\n async getMany(table, keys) {\n return keys.map((key) => getRecord(table, key));\n },\n async has(table, key) {\n return getRecord(table, key) !== undefined;\n },\n async pruneAllExpired() {\n const results: Record<string, number> = {};\n\n for (const table of Object.keys(schema)) {\n results[table] = await core.pruneExpiredInTable(table as K);\n }\n\n return results;\n },\n async pruneExpiredInTable(table) {\n const beforeRow = get(\n database,\n `SELECT COUNT(*) AS count FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`,\n [name, table],\n );\n const before = beforeRow?.count;\n\n if (typeof before !== 'number') throw new VaultError('SQLite storage returned an invalid count');\n\n deleteExpired(database, name, table);\n\n const afterRow = get(\n database,\n `SELECT COUNT(*) AS count FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`,\n [name, table],\n );\n const after = afterRow?.count;\n\n if (typeof after !== 'number') throw new VaultError('SQLite storage returned an invalid count');\n\n return before - after;\n },\n async put(table, value, ttl) {\n const key = getRecordKey(schema, table, value);\n const columns = toKeyColumns(key);\n const expiresAt = ttl === undefined ? null : Date.now() + ttl;\n\n run(\n database,\n `INSERT INTO ${RECORDS_TABLE}\n (namespace, table_name, key_tag, key_kind, key_number, key_string, value_json, expires_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET\n key_kind = excluded.key_kind,\n key_number = excluded.key_number,\n key_string = excluded.key_string,\n value_json = excluded.value_json,\n expires_at = excluded.expires_at`,\n [name, table, columns.encoded, columns.kind, columns.number, columns.string, encodeJson(value), expiresAt],\n );\n },\n async putAll(table, values, ttl) {\n if (values.length === 0) return;\n\n const expiresAt = ttl === undefined ? null : Date.now() + ttl;\n const encodedJsonValues = values.map((v) => encodeJson(v));\n const columnsList = values.map((v) => toKeyColumns(getRecordKey(schema, table, v)));\n\n const writeAll = () => {\n for (let i = 0; i < values.length; i++) {\n const columns = columnsList[i];\n run(\n database,\n `INSERT INTO ${RECORDS_TABLE}\n (namespace, table_name, key_tag, key_kind, key_number, key_string, value_json, expires_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET\n key_kind = excluded.key_kind,\n key_number = excluded.key_number,\n key_string = excluded.key_string,\n value_json = excluded.value_json,\n expires_at = excluded.expires_at`,\n [\n name,\n table,\n columns.encoded,\n columns.kind,\n columns.number,\n columns.string,\n encodedJsonValues[i],\n expiresAt,\n ],\n );\n }\n };\n\n if (inTransaction) {\n writeAll();\n return;\n }\n\n database.exec('BEGIN');\n try {\n writeAll();\n database.exec('COMMIT');\n } catch (error) {\n try {\n database.exec('ROLLBACK');\n } catch (rollbackError) {\n throw new VaultError('SQLite putAll rollback failed', { cause: rollbackError });\n }\n throw error;\n }\n },\n };\n\n return core;\n}\n\n/**\n * Creates a SQLite-backed Vault store. The connection is caller-owned unless\n * `closeOnDispose` is explicitly enabled.\n */\nexport function createSQLite<S extends AnySchema>(options: SQLiteVaultOptions<S>): SQLiteVaultStore<S> {\n const { closeOnDispose = false, database, name, schema, validators } = options;\n\n assertName(name);\n\n const state = getConnectionState(database);\n const namespaceReady = state.executor.run(async () => {\n await state.initialized;\n initializeNamespace(database, name);\n });\n let ownListener: ConnectionListener | undefined;\n\n const directCore = createDirectCore(database, name, schema);\n const withConnection = <T>(work: () => Promise<T>): Promise<T> =>\n state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n\n return work();\n });\n const guardedCore = Object.fromEntries(\n Object.entries(directCore).map(([method, implementation]) => [\n method,\n (...arguments_: unknown[]) => {\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n return withConnection(() => (implementation as (...args: unknown[]) => Promise<unknown>)(...arguments_));\n },\n ]),\n ) as StorageBackend<S>;\n\n let batch: BatchImpl<S> | undefined;\n const adapter = buildAdapterOps(schema, guardedCore, {\n onCrossTabMessage(notify) {\n const listener: ConnectionListener = (eventName, table) => {\n if (eventName === name && Object.hasOwn(schema, table)) notify(table as keyof S & string);\n };\n\n ownListener = listener;\n state.listeners.add(listener);\n\n return () => {\n state.listeners.delete(listener);\n\n if (ownListener === listener) ownListener = undefined;\n };\n },\n onMutation(table) {\n for (const listener of state.listeners) {\n if (listener !== ownListener) listener(name, table);\n }\n },\n onTransactions: (deps) => {\n batch = async (tables, fn) => {\n assertBatchTables(tables);\n\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n return state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n\n const dirtyTables = new Set<keyof S & string>();\n const txCore = createDirectCore<S, keyof S & string>(database, name, schema, true);\n const tx = buildTxContext(\n schema,\n txCore,\n (table) => dirtyTables.add(table),\n deps.validate,\n new Set<string>(tables),\n );\n let transactionStarted = false;\n let committed = false;\n\n state.batchActive = true;\n\n try {\n database.exec('BEGIN IMMEDIATE');\n transactionStarted = true;\n\n const result = await fn(tx);\n\n database.exec('COMMIT');\n committed = true;\n\n for (const table of dirtyTables) {\n deps.notifyMutation(table);\n }\n\n return result;\n } catch (error) {\n if (transactionStarted && !committed) {\n try {\n database.exec('ROLLBACK');\n } catch (rollbackError) {\n throw new VaultError('SQLite batch rollback failed', { cause: rollbackError });\n }\n }\n\n throw error;\n } finally {\n state.batchActive = false;\n }\n });\n };\n },\n schema,\n validators,\n });\n\n if (!batch) throw new VaultError('SQLite transaction capability was not initialized');\n\n const store: SQLiteVaultStore<S> = {\n ...adapter,\n batch,\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>> {\n if (adapter.disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<RecordOf<S, K>> {\n let completed = false;\n let lastRowId = 0;\n let lease: (() => void) | undefined;\n let rows: readonly SQLiteRow[] = [];\n let index = 0;\n\n const release = (): void => {\n lease?.();\n lease = undefined;\n };\n const loadNextPage = (): void => {\n rows = all(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND rowid > ?\n ORDER BY rowid\n LIMIT ?`,\n [name, table, lastRowId, ITERATION_PAGE_SIZE],\n );\n index = 0;\n };\n\n return {\n async next(): Promise<IteratorResult<RecordOf<S, K>>> {\n if (completed) return { done: true, value: undefined };\n\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n try {\n if (!lease) {\n lease = await state.executor.acquire();\n await state.initialized;\n await namespaceReady;\n }\n\n while (true) {\n if (index >= rows.length) {\n loadNextPage();\n\n if (rows.length === 0) {\n completed = true;\n release();\n\n return { done: true, value: undefined };\n }\n }\n\n const row = rows[index++];\n const stored = getStoredRow(row);\n\n lastRowId = stored.rowId;\n\n const value = decodeLiveRecord<RecordOf<S, K>>(database, row);\n\n if (value !== undefined) return { done: false, value };\n }\n } catch (error) {\n completed = true;\n release();\n\n throw error;\n }\n },\n async return(value?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n completed = true;\n release();\n\n return { done: true, value: value as RecordOf<S, K> };\n },\n async throw(error?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n completed = true;\n release();\n\n throw error;\n },\n };\n },\n };\n },\n };\n\n if (closeOnDispose) {\n const dispose = store.dispose.bind(store);\n let closePromise: Promise<void> | undefined;\n\n store.dispose = async (): Promise<void> => {\n await dispose();\n closePromise ??= state.executor.run(() => database.close?.());\n await closePromise;\n };\n store[Symbol.asyncDispose] = async (): Promise<void> => {\n await store.dispose();\n };\n }\n\n return store;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { AnySchema, BaseAdapterOptions, IterableVaultStore, TransactionalVaultStore, TransactionContext } from '../types';
1
+ import type { AnySchema, BaseAdapterOptions, TransactionalVaultStore, TransactionContext } from '../types';
2
2
  export type { TransactionContext };
3
3
  export type SQLiteParameter = null | number | string;
4
4
  type SQLiteRow = Record<string, unknown>;
@@ -33,8 +33,7 @@ export type SQLiteVaultOptions<S extends AnySchema> = BaseAdapterOptions<S> & {
33
33
  name: string;
34
34
  };
35
35
  /** SQLite provides atomic batches and lazy keyset-paginated iteration. */
36
- export interface SQLiteVaultStore<S extends AnySchema> extends TransactionalVaultStore<S>, IterableVaultStore<S> {
37
- }
36
+ export type SQLiteVaultStore<S extends AnySchema> = TransactionalVaultStore<S>;
38
37
  /**
39
38
  * Creates a SQLite-backed Vault store. The connection is caller-owned unless
40
39
  * `closeOnDispose` is explicitly enabled.
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAGlB,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEnC,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AACrD,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,SAAS,SAAS,EAAE,CAAC;IAC5D,QAAQ,CAAC,IAAI,IAAI,CAAC;IAClB,GAAG,CAAC,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,SAAS,GAAG,SAAS,CAAC;IAC7D,GAAG,CAAC,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;CAChD;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;CACvC;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,SAAS,IAAI,kBAAkB,CAAC,CAAC,CAAC,GAAG;IAC5E,6EAA6E;IAC7E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,uBAAuB,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC;CAAG;AAgbnH;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAuOrG"}
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,SAAS,EACT,kBAAkB,EAGlB,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEnC,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AACrD,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,SAAS,SAAS,EAAE,CAAC;IAC5D,QAAQ,CAAC,IAAI,IAAI,CAAC;IAClB,GAAG,CAAC,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,SAAS,GAAG,SAAS,CAAC;IAC7D,GAAG,CAAC,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;CAChD;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;CACvC;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,SAAS,IAAI,kBAAkB,CAAC,CAAC,CAAC,GAAG;IAC5E,6EAA6E;IAC7E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,SAAS,IAAI,uBAAuB,CAAC,CAAC,CAAC,CAAC;AAqd/E;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAqOrG"}
@@ -169,8 +169,8 @@ function k(e, t, n, r = "", i = []) {
169
169
  return n === void 0 ? [] : [n];
170
170
  });
171
171
  }
172
- function A(e, n, r) {
173
- let a = (t, r) => {
172
+ function A(e, n, r, a = !1) {
173
+ let o = (t, r) => {
174
174
  let i = x(r), a = T(e, `SELECT rowid AS row_id, expires_at, value_json
175
175
  FROM ${l}
176
176
  WHERE namespace = ? AND table_name = ? AND key_tag = ?`, [
@@ -179,7 +179,7 @@ function A(e, n, r) {
179
179
  i.encoded
180
180
  ]);
181
181
  return a === void 0 ? void 0 : O(e, a);
182
- }, o = {
182
+ }, s = {
183
183
  async clear(t) {
184
184
  w(e, `DELETE FROM ${l} WHERE namespace = ? AND table_name = ?`, [n, t]);
185
185
  },
@@ -190,63 +190,59 @@ function A(e, n, r) {
190
190
  return i;
191
191
  },
192
192
  async delete(t, r) {
193
- let i = a(t, r) !== void 0, o = x(r);
194
- return w(e, `DELETE FROM ${l} WHERE namespace = ? AND table_name = ? AND key_tag = ?`, [
193
+ let i = x(r);
194
+ return (w(e, `DELETE FROM ${l}
195
+ WHERE namespace = ? AND table_name = ? AND key_tag = ?
196
+ AND (expires_at IS NULL OR expires_at > ?)`, [
195
197
  n,
196
198
  t,
197
- o.encoded
198
- ]), i;
199
+ i.encoded,
200
+ Date.now()
201
+ ])?.changes ?? 0) > 0;
199
202
  },
200
- async deleteMany(e, t) {
201
- let n = 0;
202
- for (let r of t) await o.delete(e, r) && (n += 1);
203
- return n;
203
+ async deleteMany(t, r) {
204
+ if (r.length === 0) return 0;
205
+ let i = 0, a = r.map((e) => x(e).encoded);
206
+ for (let r = 0; r < a.length; r += 996) {
207
+ let o = a.slice(r, r + 996), s = w(e, `DELETE FROM ${l}
208
+ WHERE namespace = ? AND table_name = ? AND key_tag IN (${o.map(() => "?").join(", ")})
209
+ AND (expires_at IS NULL OR expires_at > ?)`, [
210
+ n,
211
+ t,
212
+ ...o,
213
+ Date.now()
214
+ ]);
215
+ i += s?.changes ?? 0;
216
+ }
217
+ return i;
204
218
  },
205
219
  async get(e, t) {
206
- return a(e, t);
220
+ return o(e, t);
207
221
  },
208
222
  async getAll(t) {
209
223
  return k(e, n, t);
210
224
  },
211
225
  async getAllKeys(e) {
212
- return (await o.getAll(e)).map((t) => i(r, e, t));
213
- },
214
- async getByKeyRange(t, r) {
215
- if (r.type === "eq") return k(e, n, t, " AND key_tag = ?", [x(r.value).encoded]);
216
- if (r.type === "between") {
217
- if (typeof r.lower != typeof r.upper || typeof r.lower != "number" && typeof r.lower != "string") return k(e, n, t);
218
- let i = typeof r.lower == "number" ? "key_number" : "key_string";
219
- return k(e, n, t, ` AND key_kind = ? AND ${i} >= ? AND ${i} <= ?`, [
220
- typeof r.lower == "number" ? "number" : "string",
221
- r.lower,
222
- r.upper
223
- ]);
224
- }
225
- return k(e, n, t, " AND key_kind = ? AND substr(key_string, 1, length(?)) = ?", [
226
- "string",
227
- r.prefix,
228
- r.prefix
229
- ]);
226
+ return (await s.getAll(e)).map((t) => i(r, e, t));
230
227
  },
231
228
  async getMany(e, t) {
232
- return t.map((t) => a(e, t));
233
- },
234
- async getRawCount(r) {
235
- let i = T(e, `SELECT COUNT(*) AS count FROM ${l} WHERE namespace = ? AND table_name = ?`, [n, r])?.count;
236
- if (typeof i != "number") throw new t("SQLite storage returned an invalid count");
237
- return i;
229
+ return t.map((t) => o(e, t));
238
230
  },
239
231
  async has(e, t) {
240
- return a(e, t) !== void 0;
232
+ return o(e, t) !== void 0;
241
233
  },
242
234
  async pruneAllExpired() {
243
235
  let e = {};
244
- for (let t of Object.keys(r)) e[t] = await o.pruneExpiredInTable(t);
236
+ for (let t of Object.keys(r)) e[t] = await s.pruneExpiredInTable(t);
245
237
  return e;
246
238
  },
247
- async pruneExpiredInTable(t) {
248
- let r = await o.getRawCount(t);
249
- return D(e, n, t), r - await o.getRawCount(t);
239
+ async pruneExpiredInTable(r) {
240
+ let i = T(e, `SELECT COUNT(*) AS count FROM ${l} WHERE namespace = ? AND table_name = ?`, [n, r])?.count;
241
+ if (typeof i != "number") throw new t("SQLite storage returned an invalid count");
242
+ D(e, n, r);
243
+ let a = T(e, `SELECT COUNT(*) AS count FROM ${l} WHERE namespace = ? AND table_name = ?`, [n, r])?.count;
244
+ if (typeof a != "number") throw new t("SQLite storage returned an invalid count");
245
+ return i - a;
250
246
  },
251
247
  async put(t, a, o) {
252
248
  let s = x(i(r, t, a)), c = o === void 0 ? null : Date.now() + o;
@@ -269,71 +265,107 @@ function A(e, n, r) {
269
265
  c
270
266
  ]);
271
267
  },
272
- async putAll(e, t, n) {
273
- for (let r of t) await o.put(e, r, n);
268
+ async putAll(o, s, c) {
269
+ if (s.length === 0) return;
270
+ let u = c === void 0 ? null : Date.now() + c, d = s.map((e) => y(e)), f = s.map((e) => x(i(r, o, e))), p = () => {
271
+ for (let t = 0; t < s.length; t++) {
272
+ let r = f[t];
273
+ w(e, `INSERT INTO ${l}
274
+ (namespace, table_name, key_tag, key_kind, key_number, key_string, value_json, expires_at)
275
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
276
+ ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET
277
+ key_kind = excluded.key_kind,
278
+ key_number = excluded.key_number,
279
+ key_string = excluded.key_string,
280
+ value_json = excluded.value_json,
281
+ expires_at = excluded.expires_at`, [
282
+ n,
283
+ o,
284
+ r.encoded,
285
+ r.kind,
286
+ r.number,
287
+ r.string,
288
+ d[t],
289
+ u
290
+ ]);
291
+ }
292
+ };
293
+ if (a) {
294
+ p();
295
+ return;
296
+ }
297
+ e.exec("BEGIN");
298
+ try {
299
+ p(), e.exec("COMMIT");
300
+ } catch (n) {
301
+ try {
302
+ e.exec("ROLLBACK");
303
+ } catch (e) {
304
+ throw new t("SQLite putAll rollback failed", { cause: e });
305
+ }
306
+ throw n;
307
+ }
274
308
  }
275
309
  };
276
- return o;
310
+ return s;
277
311
  }
278
312
  function j(n) {
279
- let { closeOnDispose: r = !1, database: i, logger: c, name: u, onMetrics: d, schema: p, validators: h } = n;
280
- _(u);
281
- let v = m(i), y = v.executor.run(async () => {
282
- await v.initialized, g(i, u);
283
- }), b, x = A(i, u, p), C = (e) => v.executor.run(async () => (await v.initialized, await y, e())), w = Object.fromEntries(Object.entries(x).map(([e, n]) => [e, (...e) => {
284
- if (v.batchActive) throw new t("cannot call a SQLite store sharing this connection from batch(); use the transaction context instead");
285
- return C(() => n(...e));
286
- }])), T, D = o(p, w, {
287
- logger: c,
313
+ let { closeOnDispose: r = !1, database: i, name: c, schema: u, validators: d } = n;
314
+ _(c);
315
+ let p = m(i), h = p.executor.run(async () => {
316
+ await p.initialized, g(i, c);
317
+ }), v, y = A(i, c, u), b = (e) => p.executor.run(async () => (await p.initialized, await h, e())), x = Object.fromEntries(Object.entries(y).map(([e, n]) => [e, (...e) => {
318
+ if (p.batchActive) throw new t("cannot call a SQLite store sharing this connection from batch(); use the transaction context instead");
319
+ return b(() => n(...e));
320
+ }])), C, w = o(u, x, {
288
321
  onCrossTabMessage(e) {
289
322
  let t = (t, n) => {
290
- t === u && Object.hasOwn(p, n) && e(n);
323
+ t === c && Object.hasOwn(u, n) && e(n);
291
324
  };
292
- return b = t, v.listeners.add(t), () => {
293
- v.listeners.delete(t), b === t && (b = void 0);
325
+ return v = t, p.listeners.add(t), () => {
326
+ p.listeners.delete(t), v === t && (v = void 0);
294
327
  };
295
328
  },
296
- onMetrics: d,
297
329
  onMutation(e) {
298
- for (let t of v.listeners) t !== b && t(u, e);
330
+ for (let t of p.listeners) t !== v && t(c, e);
299
331
  },
300
332
  onTransactions: (e) => {
301
- T = async (n, r) => {
302
- if (a(n), v.batchActive) throw new t("cannot call a SQLite store sharing this connection from batch(); use the transaction context instead");
303
- return v.executor.run(async () => {
304
- await v.initialized, await y;
305
- let a = /* @__PURE__ */ new Set(), o = A(i, u, p), c = s(p, o, (e) => a.add(e), e.validate, new Set(n)), l = !1, d = !1;
306
- v.batchActive = !0;
333
+ C = async (n, r) => {
334
+ if (a(n), p.batchActive) throw new t("cannot call a SQLite store sharing this connection from batch(); use the transaction context instead");
335
+ return p.executor.run(async () => {
336
+ await p.initialized, await h;
337
+ let a = /* @__PURE__ */ new Set(), o = A(i, c, u, !0), l = s(u, o, (e) => a.add(e), e.validate, new Set(n)), d = !1, f = !1;
338
+ p.batchActive = !0;
307
339
  try {
308
- i.exec("BEGIN IMMEDIATE"), l = !0;
309
- let t = await r(c);
310
- i.exec("COMMIT"), d = !0;
340
+ i.exec("BEGIN IMMEDIATE"), d = !0;
341
+ let t = await r(l);
342
+ i.exec("COMMIT"), f = !0;
311
343
  for (let t of a) e.notifyMutation(t);
312
344
  return t;
313
345
  } catch (e) {
314
- if (l && !d) try {
346
+ if (d && !f) try {
315
347
  i.exec("ROLLBACK");
316
348
  } catch (e) {
317
349
  throw new t("SQLite batch rollback failed", { cause: e });
318
350
  }
319
351
  throw e;
320
352
  } finally {
321
- v.batchActive = !1;
353
+ p.batchActive = !1;
322
354
  }
323
355
  });
324
356
  };
325
357
  },
326
- schema: p,
327
- validators: h
358
+ schema: u,
359
+ validators: d
328
360
  });
329
- if (!T) throw new t("SQLite transaction capability was not initialized");
330
- let k = {
331
- ...D,
332
- batch: T,
361
+ if (!C) throw new t("SQLite transaction capability was not initialized");
362
+ let T = {
363
+ ...w,
364
+ batch: C,
333
365
  iterate(n) {
334
- if (D.disposed) throw new e(`"${u}" is disposed`);
366
+ if (w.disposed) throw new e(`"${c}" is disposed`);
335
367
  return { [Symbol.asyncIterator]() {
336
- let e = !1, r = 0, a, o = [], s = 0, c = () => {
368
+ let e = !1, r = 0, a, o = [], s = 0, u = () => {
337
369
  a?.(), a = void 0;
338
370
  }, d = () => {
339
371
  o = E(i, `SELECT rowid AS row_id, expires_at, value_json
@@ -341,7 +373,7 @@ function j(n) {
341
373
  WHERE namespace = ? AND table_name = ? AND rowid > ?
342
374
  ORDER BY rowid
343
375
  LIMIT ?`, [
344
- u,
376
+ c,
345
377
  n,
346
378
  r,
347
379
  f
@@ -353,10 +385,10 @@ function j(n) {
353
385
  done: !0,
354
386
  value: void 0
355
387
  };
356
- if (v.batchActive) throw new t("cannot call a SQLite store sharing this connection from batch(); use the transaction context instead");
388
+ if (p.batchActive) throw new t("cannot call a SQLite store sharing this connection from batch(); use the transaction context instead");
357
389
  try {
358
- for (a || (a = await v.executor.acquire(), await v.initialized, await y);;) {
359
- if (s >= o.length && (d(), o.length === 0)) return e = !0, c(), {
390
+ for (a || (a = await p.executor.acquire(), await p.initialized, await h);;) {
391
+ if (s >= o.length && (d(), o.length === 0)) return e = !0, u(), {
360
392
  done: !0,
361
393
  value: void 0
362
394
  };
@@ -369,31 +401,31 @@ function j(n) {
369
401
  };
370
402
  }
371
403
  } catch (t) {
372
- throw e = !0, c(), t;
404
+ throw e = !0, u(), t;
373
405
  }
374
406
  },
375
407
  async return(t) {
376
- return e = !0, c(), {
408
+ return e = !0, u(), {
377
409
  done: !0,
378
410
  value: t
379
411
  };
380
412
  },
381
413
  async throw(t) {
382
- throw e = !0, c(), t;
414
+ throw e = !0, u(), t;
383
415
  }
384
416
  };
385
417
  } };
386
418
  }
387
419
  };
388
420
  if (r) {
389
- let e = k.dispose.bind(k), t;
390
- k.dispose = async () => {
391
- await e(), t ??= v.executor.run(() => i.close?.()), await t;
392
- }, k[Symbol.asyncDispose] = async () => {
393
- await k.dispose();
421
+ let e = T.dispose.bind(T), t;
422
+ T.dispose = async () => {
423
+ await e(), t ??= p.executor.run(() => i.close?.()), await t;
424
+ }, T[Symbol.asyncDispose] = async () => {
425
+ await T.dispose();
394
426
  };
395
427
  }
396
- return k;
428
+ return T;
397
429
  }
398
430
  //#endregion
399
431
  export { j as createSQLite };