@orkestrel/sqlite 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/dist/src/server/index.cjs +73 -19
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +316 -0
- package/dist/src/server/index.d.ts +316 -7
- package/dist/src/server/index.js +339 -0
- package/dist/src/server/index.js.map +1 -0
- package/package.json +13 -6
- package/dist/src/server/SQLiteDatabase.d.ts +0 -29
- package/dist/src/server/SQLiteStatement.d.ts +0 -23
- package/dist/src/server/constants.d.ts +0 -18
- package/dist/src/server/errors.d.ts +0 -34
- package/dist/src/server/factories.d.ts +0 -25
- package/dist/src/server/helpers.d.ts +0 -38
- package/dist/src/server/types.d.ts +0 -101
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["#statement","#closed","#require","#stream","#path","#readonly","#timeout","#foreignKeys","#bigints","#database","#require"],"sources":["../../../src/server/constants.ts","../../../src/server/errors.ts","../../../src/server/helpers.ts","../../../src/server/SQLiteStatement.ts","../../../src/server/SQLiteDatabase.ts","../../../src/server/factories.ts"],"sourcesContent":["// The wrapper's numeric SQLite result codes (AGENTS §5 constants file).\n\n/**\n * SQLite result code for a constraint violation (`SQLITE_CONSTRAINT`).\n *\n * @remarks\n * A native `errcode` packs the primary result in its low byte, with extended codes\n * in the high bits (e.g. `SQLITE_CONSTRAINT_UNIQUE`), so the low byte is masked off\n * before comparing. Read only by `wrapError`.\n */\nexport const SQLITE_CONSTRAINT = 19\n\n/**\n * SQLite result code for a locked-database fault (`SQLITE_BUSY`).\n *\n * @remarks\n * A native `errcode` packs the primary result in its low byte, with extended codes\n * in the high bits, so the low byte is masked off before comparing. Read only by\n * `wrapError`.\n */\nexport const SQLITE_BUSY = 5\n","import type { SQLiteErrorCode } from './types.js'\n\n// Errors for the SQLite wrapper. A single `SQLiteError` carries a\n// machine-readable `code` mapped from the native `node:sqlite` fault at the\n// boundary (`wrapError`), so a `catch` branches on `error.code` rather than\n// parsing a message. Mirrors the IndexedDB wrapper's `IndexedDBError`; its three\n// codes are deliberately lean — the wrapper sits right on the raw SQLite surface,\n// where the constraint fault is the one worth naming, `CLOSED` is the\n// wrapper-lifecycle fault, and everything else is `UNKNOWN` (AGENTS §12).\n\n/**\n * An error thrown by the SQLite wrapper.\n *\n * @remarks\n * Carries a {@link SQLiteErrorCode} and an optional `context` record (e.g. the\n * native SQLite `errcode`). Construct it directly for the `CLOSED`\n * wrapper-lifecycle fault; the internal `wrapError` maps a native `node:sqlite`\n * error to the right code at the boundary. Narrow a caught value with\n * {@link isSQLiteError}.\n *\n * @example\n * ```ts\n * try {\n * \tstatement.run({ id: 'u1' })\n * } catch (error) {\n * \tif (isSQLiteError(error) && error.code === 'CONSTRAINT') {\n * \t\t// a UNIQUE / PRIMARY KEY violation\n * \t}\n * }\n * ```\n */\nexport class SQLiteError extends Error {\n\treadonly code: SQLiteErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\tconstructor(code: SQLiteErrorCode, message: string, context?: Readonly<Record<string, unknown>>) {\n\t\tsuper(message)\n\t\tthis.name = 'SQLiteError'\n\t\tthis.code = code\n\t\tthis.context = context\n\t}\n}\n\n/**\n * Whether a value is a {@link SQLiteError}.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a `SQLiteError`\n */\nexport function isSQLiteError(value: unknown): value is SQLiteError {\n\treturn value instanceof SQLiteError\n}\n","import type { SQLiteParameters, SQLiteValue } from './types.js'\nimport { isArray, isObject } from '@orkestrel/contract'\nimport { SQLITE_BUSY, SQLITE_CONSTRAINT } from './constants.js'\nimport { SQLiteError } from './errors.js'\n\n// The wrapper's boundary helpers, shared by `SQLiteDatabase` and `SQLiteStatement`:\n// `wrapError` maps a thrown native `node:sqlite` error to a typed `SQLiteError`\n// (the one honest narrowing point — `isObject` + `in`, never `as`, per AGENTS\n// §14), and `bindParameters` normalizes the wrapper's `SQLiteParameters` to the\n// shape a native `StatementSync` call expects (positional spread vs. a single\n// named record). Both are pure.\n\n/**\n * Convert a thrown native `node:sqlite` error into a typed {@link SQLiteError}.\n *\n * @remarks\n * The single boundary mapping for the wrapper. The thrown value arrives as\n * `unknown` and is narrowed with `isObject` + the `in` operator (never `as`, and\n * not `isRecord` — a native `node:sqlite` error is an `Error` instance, so its\n * prototype fails the plain-record test) to read its `errcode` — a numeric SQLite\n * result code whose low byte identifies a constraint violation\n * (`SQLITE_CONSTRAINT`), mapped to code `'CONSTRAINT'`; a locked-database fault\n * (`SQLITE_BUSY`) is mapped to `'BUSY'`; anything else is `'UNKNOWN'`. The\n * original message is preserved and `{ errcode }` carried in `context` when\n * present. An already-typed `SQLiteError` is returned unchanged.\n *\n * @param error - The thrown value to convert\n * @returns The equivalent `SQLiteError`\n */\nexport function wrapError(error: unknown): SQLiteError {\n\tif (error instanceof SQLiteError) return error\n\tconst errcode =\n\t\tisObject(error) && 'errcode' in error && typeof error.errcode === 'number'\n\t\t\t? error.errcode\n\t\t\t: undefined\n\tconst message = error instanceof Error ? error.message : 'Unknown SQLite error'\n\tconst code =\n\t\terrcode !== undefined && (errcode & 0xff) === SQLITE_CONSTRAINT\n\t\t\t? 'CONSTRAINT'\n\t\t\t: errcode !== undefined && (errcode & 0xff) === SQLITE_BUSY\n\t\t\t\t? 'BUSY'\n\t\t\t\t: 'UNKNOWN'\n\treturn new SQLiteError(code, message, errcode !== undefined ? { errcode } : undefined)\n}\n\n/**\n * Normalize {@link SQLiteParameters} to the binding shape a native `StatementSync`\n * call expects.\n *\n * @remarks\n * Positional parameters (an array) bind to `?` placeholders and are spread into\n * the call; named parameters (a record) bind to bare `:name` placeholders and are\n * passed as a single leading object. Returning a discriminated result keeps the\n * `SQLiteStatement` dispatch typed against the native overloads without `as`.\n *\n * @param parameters - The wrapper parameters, or `undefined` for none\n * @returns `{ positional }` for an array (empty when omitted) or `{ named }` for a record\n */\nexport function bindParameters(\n\tparameters?: SQLiteParameters,\n):\n\t| { readonly positional: readonly SQLiteValue[] }\n\t| { readonly named: Readonly<Record<string, SQLiteValue>> } {\n\tif (parameters === undefined) return { positional: [] }\n\tif (isArray<SQLiteValue>(parameters)) return { positional: parameters }\n\treturn { named: parameters }\n}\n","import type { StatementSync } from 'node:sqlite'\nimport type {\n\tSQLiteParameters,\n\tSQLiteRow,\n\tSQLiteRunResult,\n\tSQLiteStatementInterface,\n} from './types.js'\nimport { SQLiteError } from './errors.js'\nimport { bindParameters, wrapError } from './helpers.js'\n\n/**\n * A prepared statement over `node:sqlite`'s `StatementSync` — the only way the\n * wrapper runs SQL.\n *\n * @remarks\n * Created by `database.prepare(sql)`, which threads a liveness check (internal —\n * this constructor's second parameter is not part of the documented surface).\n * Bare named parameters are enabled on construction so a record's keys bind\n * without the SQL prefix character. Each method first gates on that liveness\n * check, throwing a `CLOSED` `SQLiteError` once the owning connection has been\n * closed — a statement prepared on a connection that is later closed and then\n * reconnected stays `CLOSED`; a fresh statement must be prepared on the new\n * connection. Each method then binds the optional parameters (an array spread\n * to `?` placeholders, a record passed as a single named object) and executes\n * synchronously, mapping any native fault to a `SQLiteError` — including a\n * mid-stream fault from `iterate`'s lazy native iterator, stepped inside its own\n * try/catch so a fault on a later row is mapped exactly like an eager one. Row\n * values arrive as the native {@link SQLiteRow} types; the typed layer above\n * (the driver) imposes a precise shape through a contract rather than\n * re-narrowing here (AGENTS §14).\n */\nexport class SQLiteStatement implements SQLiteStatementInterface {\n\treadonly #statement: StatementSync\n\treadonly #closed: () => boolean\n\n\tconstructor(statement: StatementSync, closed: () => boolean) {\n\t\tthis.#statement = statement\n\t\tthis.#closed = closed\n\t\tthis.#statement.setAllowBareNamedParameters(true)\n\t}\n\n\trun(parameters?: SQLiteParameters): SQLiteRunResult {\n\t\tthis.#require()\n\t\ttry {\n\t\t\tconst bound = bindParameters(parameters)\n\t\t\tconst result =\n\t\t\t\t'named' in bound\n\t\t\t\t\t? this.#statement.run(bound.named)\n\t\t\t\t\t: this.#statement.run(...bound.positional)\n\t\t\treturn { changes: Number(result.changes), rowid: Number(result.lastInsertRowid) }\n\t\t} catch (error) {\n\t\t\tthrow wrapError(error)\n\t\t}\n\t}\n\n\tget(parameters?: SQLiteParameters): SQLiteRow | undefined {\n\t\tthis.#require()\n\t\ttry {\n\t\t\tconst bound = bindParameters(parameters)\n\t\t\treturn 'named' in bound\n\t\t\t\t? this.#statement.get(bound.named)\n\t\t\t\t: this.#statement.get(...bound.positional)\n\t\t} catch (error) {\n\t\t\tthrow wrapError(error)\n\t\t}\n\t}\n\n\tall(parameters?: SQLiteParameters): readonly SQLiteRow[] {\n\t\tthis.#require()\n\t\ttry {\n\t\t\tconst bound = bindParameters(parameters)\n\t\t\treturn 'named' in bound\n\t\t\t\t? this.#statement.all(bound.named)\n\t\t\t\t: this.#statement.all(...bound.positional)\n\t\t} catch (error) {\n\t\t\tthrow wrapError(error)\n\t\t}\n\t}\n\n\titerate(parameters?: SQLiteParameters): IterableIterator<SQLiteRow> {\n\t\tthis.#require()\n\t\tlet native: IterableIterator<SQLiteRow>\n\t\ttry {\n\t\t\tconst bound = bindParameters(parameters)\n\t\t\tnative =\n\t\t\t\t'named' in bound\n\t\t\t\t\t? this.#statement.iterate(bound.named)\n\t\t\t\t\t: this.#statement.iterate(...bound.positional)\n\t\t} catch (error) {\n\t\t\tthrow wrapError(error)\n\t\t}\n\t\treturn this.#stream(native)\n\t}\n\n\t// The single liveness gate — every operation requires the owning connection\n\t// to still be open (mirrors SQLiteDatabase#require).\n\t#require(): void {\n\t\tif (this.#closed()) {\n\t\t\tthrow new SQLiteError(\n\t\t\t\t'CLOSED',\n\t\t\t\t'Statement is closed — its connection was closed; prepare a new statement',\n\t\t\t)\n\t\t}\n\t}\n\n\t// Pulls from the native lazy iterator one step at a time, each step inside\n\t// its own try/catch — a mid-stream native fault (e.g. an out-of-range\n\t// integer on a later row) is mapped to a SQLiteError exactly like an eager\n\t// fault, instead of escaping raw from the caller's for...of.\n\t*#stream(native: IterableIterator<SQLiteRow>): IterableIterator<SQLiteRow> {\n\t\tfor (;;) {\n\t\t\tlet result: IteratorResult<SQLiteRow>\n\t\t\ttry {\n\t\t\t\tresult = native.next()\n\t\t\t} catch (error) {\n\t\t\t\tthrow wrapError(error)\n\t\t\t}\n\t\t\tif (result.done === true) return\n\t\t\tyield result.value\n\t\t}\n\t}\n}\n","import { DatabaseSync } from 'node:sqlite'\nimport type {\n\tSQLiteDatabaseInterface,\n\tSQLiteDatabaseOptions,\n\tSQLiteStatementInterface,\n\tSQLiteValue,\n} from './types.js'\nimport { isPromiseLike } from '@orkestrel/contract'\nimport { SQLiteError } from './errors.js'\nimport { wrapError } from './helpers.js'\nimport { SQLiteStatement } from './SQLiteStatement.js'\n\n/**\n * A synchronous SQLite database over `node:sqlite`'s `DatabaseSync`.\n *\n * @remarks\n * Created by `createSQLiteDatabase`. It connects lazily (`connect` opens the\n * underlying `DatabaseSync`, idempotent) and every operation routes through a\n * private gate that throws a `CLOSED` `SQLiteError` before `connect` or after\n * `close`. `exec` runs result-less SQL; `prepare` compiles a `SQLiteStatement`;\n * `transaction` wraps a scope in `BEGIN` / `COMMIT`, rolling back on a throw;\n * `begin` / `commit` / `rollback` expose those same primitives directly for a\n * long-lived or externally-driven transaction; `pragma` reads (or sets then\n * reads) one PRAGMA value — `name` is trusted\n * internal use only, never untrusted input, since pragma names cannot be bound\n * as parameters. `transacting` reports whether a transaction is currently open\n * (node:sqlite's `isTransaction`), `false` when not connected. A native fault\n * surfaces as a `SQLiteError` mapped at the boundary.\n */\nexport class SQLiteDatabase implements SQLiteDatabaseInterface {\n\treadonly #path: string\n\treadonly #readonly: boolean | undefined\n\treadonly #timeout: number | undefined\n\treadonly #foreignKeys: boolean | undefined\n\treadonly #bigints: boolean | undefined\n\t#database: DatabaseSync | undefined\n\n\tconstructor(options: SQLiteDatabaseOptions) {\n\t\tthis.#path = options.path ?? ':memory:'\n\t\tthis.#readonly = options.readonly\n\t\tthis.#timeout = options.timeout\n\t\tthis.#foreignKeys = options.foreignKeys\n\t\tthis.#bigints = options.bigints\n\t}\n\n\tget path(): string {\n\t\treturn this.#path\n\t}\n\n\tget connected(): boolean {\n\t\treturn this.#database !== undefined\n\t}\n\n\tget transacting(): boolean {\n\t\treturn this.#database?.isTransaction ?? false\n\t}\n\n\tconnect(): void {\n\t\tif (this.#database === undefined) {\n\t\t\tthis.#database = new DatabaseSync(this.#path, {\n\t\t\t\treadOnly: this.#readonly,\n\t\t\t\ttimeout: this.#timeout,\n\t\t\t\tenableForeignKeyConstraints: this.#foreignKeys,\n\t\t\t\treadBigInts: this.#bigints,\n\t\t\t})\n\t\t}\n\t}\n\n\tclose(): void {\n\t\tthis.#database?.close()\n\t\tthis.#database = undefined\n\t}\n\n\t/** Close the connection — enables `using db = createSQLiteDatabase(...)`. */\n\t[Symbol.dispose](): void {\n\t\tthis.close()\n\t}\n\n\texec(sql: string): void {\n\t\ttry {\n\t\t\tthis.#require().exec(sql)\n\t\t} catch (error) {\n\t\t\tthrow wrapError(error)\n\t\t}\n\t}\n\n\tprepare(sql: string): SQLiteStatementInterface {\n\t\ttry {\n\t\t\tconst database = this.#require()\n\t\t\t// Capture this specific connection instance — a later `close()` clears\n\t\t\t// `#database`, and a subsequent `connect()` creates a NEW instance, so\n\t\t\t// identity comparison (not just \"is a connection open\") keeps a statement\n\t\t\t// prepared on the OLD connection permanently CLOSED after reconnect.\n\t\t\treturn new SQLiteStatement(database.prepare(sql), () => this.#database !== database)\n\t\t} catch (error) {\n\t\t\tthrow wrapError(error)\n\t\t}\n\t}\n\n\ttransaction<R>(scope: () => R): R {\n\t\tthis.begin()\n\t\tlet result: R\n\t\ttry {\n\t\t\tresult = scope()\n\t\t} catch (error) {\n\t\t\t// A ROLLBACK fault (e.g. the database was closed by the scope) must never\n\t\t\t// mask the scope's own error — the caller needs to see why it failed.\n\t\t\ttry {\n\t\t\t\tthis.rollback()\n\t\t\t} catch {\n\t\t\t\t// swallowed — the original `error` is what the caller needs to see\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t\tif (isPromiseLike(result)) {\n\t\t\t// An async scope returns before its awaited work runs, so committing here\n\t\t\t// would commit prematurely — roll back and reject instead of silently\n\t\t\t// racing the caller's still-pending work.\n\t\t\ttry {\n\t\t\t\tthis.rollback()\n\t\t\t} catch {\n\t\t\t\t// swallowed — the guard error below is what the caller needs to see\n\t\t\t}\n\t\t\tthrow new SQLiteError(\n\t\t\t\t'UNKNOWN',\n\t\t\t\t'transaction(scope) requires a synchronous scope — an async or Promise-returning scope cannot commit or roll back before its awaited work runs; use begin() / commit() / rollback() directly for a transaction that spans async caller code',\n\t\t\t)\n\t\t}\n\t\tthis.commit()\n\t\treturn result\n\t}\n\n\tbegin(): void {\n\t\tthis.exec('BEGIN')\n\t}\n\n\tcommit(): void {\n\t\tthis.exec('COMMIT')\n\t}\n\n\trollback(): void {\n\t\tthis.exec('ROLLBACK')\n\t}\n\n\t// Pragmas cannot use bind parameters, so the value is interpolated — safe for\n\t// the trusted internal names this layer is called with.\n\tpragma(name: string, value?: string | number): SQLiteValue | undefined {\n\t\tif (value !== undefined) this.exec('PRAGMA ' + name + ' = ' + value)\n\t\tconst row = this.prepare('PRAGMA ' + name).get()\n\t\treturn row ? Object.values(row)[0] : undefined\n\t}\n\n\t// The single connection gate — every operation requires an open database.\n\t#require(): DatabaseSync {\n\t\tif (this.#database === undefined) {\n\t\t\tthrow new SQLiteError('CLOSED', 'Database is not connected — call connect() first')\n\t\t}\n\t\treturn this.#database\n\t}\n}\n","import type { SQLiteDatabaseInterface, SQLiteDatabaseOptions } from './types.js'\nimport { SQLiteDatabase } from './SQLiteDatabase.js'\n\n/**\n * Create a synchronous SQLite database over `node:sqlite`.\n *\n * @remarks\n * The wrapper connects lazily — call `connect` (or it is required by the first\n * operation, which throws `CLOSED` until then). This is the lower-level native\n * handle a higher-level typed database engine would be built on; here it ships\n * as the standalone, server-native SQLite surface.\n *\n * @param options - The database `path` (a file path, or `':memory:'` by default)\n * @returns A typed {@link SQLiteDatabaseInterface}\n *\n * @example\n * ```ts\n * import { createSQLiteDatabase } from '@orkestrel/sqlite'\n *\n * const db = createSQLiteDatabase({ path: ':memory:' })\n * db.connect()\n * db.exec('CREATE TABLE users (id TEXT PRIMARY KEY, name TEXT)')\n * db.prepare('INSERT INTO users VALUES (?, ?)').run(['u1', 'Ada'])\n * db.prepare('SELECT name FROM users WHERE id = ?').get(['u1']) // { name: 'Ada' }\n * ```\n */\nexport function createSQLiteDatabase(options?: SQLiteDatabaseOptions): SQLiteDatabaseInterface {\n\treturn new SQLiteDatabase(options ?? {})\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orkestrel/sqlite",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "A typed, synchronous SQLite wrapper for the @orkestrel line — prepared statements over node:sqlite. Part of the @orkestrel line.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"database",
|
|
@@ -24,13 +24,18 @@
|
|
|
24
24
|
"type": "module",
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"main": "./dist/src/server/index.cjs",
|
|
27
|
+
"module": "./dist/src/server/index.js",
|
|
27
28
|
"types": "./dist/src/server/index.d.ts",
|
|
28
29
|
"exports": {
|
|
29
30
|
".": {
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/src/server/index.d.ts",
|
|
33
|
+
"default": "./dist/src/server/index.js"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/src/server/index.d.cts",
|
|
37
|
+
"default": "./dist/src/server/index.cjs"
|
|
38
|
+
}
|
|
34
39
|
},
|
|
35
40
|
"./package.json": "./package.json"
|
|
36
41
|
},
|
|
@@ -54,19 +59,21 @@
|
|
|
54
59
|
"test:guides": "vitest run --config vite.config.ts --reporter=dot --project guides",
|
|
55
60
|
"build": "npm run clean && npm run build:src",
|
|
56
61
|
"build:src": "npm run build:src:server",
|
|
57
|
-
"build:src:server": "vite build --config configs/src/vite.server.config.ts &&
|
|
62
|
+
"build:src:server": "vite build --config configs/src/vite.server.config.ts && npm run copy dist/src/server/index.d.ts dist/src/server/index.d.cts",
|
|
58
63
|
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run check:src && npm run build && npm test"
|
|
59
64
|
},
|
|
60
65
|
"dependencies": {
|
|
61
66
|
"@orkestrel/contract": "^0.0.1"
|
|
62
67
|
},
|
|
63
68
|
"devDependencies": {
|
|
69
|
+
"@microsoft/api-extractor": "^7.58.9",
|
|
64
70
|
"@orkestrel/guide": "^0.0.1",
|
|
65
71
|
"@types/node": "^26.1.1",
|
|
66
72
|
"oxfmt": "^0.58.0",
|
|
67
73
|
"oxlint": "^1.73.0",
|
|
68
74
|
"typescript": "^6.0.3",
|
|
69
75
|
"vite": "^8.1.4",
|
|
76
|
+
"vite-plugin-dts": "^5.0.3",
|
|
70
77
|
"vitest": "^4.1.10"
|
|
71
78
|
},
|
|
72
79
|
"engines": {
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { SQLiteDatabaseInterface, SQLiteDatabaseOptions, SQLiteStatementInterface, SQLiteValue } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* A synchronous SQLite database over `node:sqlite`'s `DatabaseSync`.
|
|
4
|
-
*
|
|
5
|
-
* @remarks
|
|
6
|
-
* Created by `createSQLiteDatabase`. It connects lazily (`connect` opens the
|
|
7
|
-
* underlying `DatabaseSync`, idempotent) and every operation routes through a
|
|
8
|
-
* private gate that throws a `CLOSED` `SQLiteError` before `connect` or after
|
|
9
|
-
* `close`. `exec` runs result-less SQL; `prepare` compiles a `SQLiteStatement`;
|
|
10
|
-
* `transaction` wraps a scope in `BEGIN` / `COMMIT`, rolling back on a throw;
|
|
11
|
-
* `pragma` reads (or sets then reads) one PRAGMA value — `name` is trusted
|
|
12
|
-
* internal use only, never untrusted input, since pragma names cannot be bound
|
|
13
|
-
* as parameters. A native fault surfaces as a `SQLiteError` mapped at the
|
|
14
|
-
* boundary.
|
|
15
|
-
*/
|
|
16
|
-
export declare class SQLiteDatabase implements SQLiteDatabaseInterface {
|
|
17
|
-
#private;
|
|
18
|
-
constructor(options: SQLiteDatabaseOptions);
|
|
19
|
-
get path(): string;
|
|
20
|
-
get connected(): boolean;
|
|
21
|
-
connect(): void;
|
|
22
|
-
close(): void;
|
|
23
|
-
/** Close the connection — enables `using db = createSQLiteDatabase(...)`. */
|
|
24
|
-
[Symbol.dispose](): void;
|
|
25
|
-
exec(sql: string): void;
|
|
26
|
-
prepare(sql: string): SQLiteStatementInterface;
|
|
27
|
-
transaction<R>(scope: () => R): R;
|
|
28
|
-
pragma(name: string, value?: string | number): SQLiteValue | undefined;
|
|
29
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { StatementSync } from 'node:sqlite';
|
|
2
|
-
import type { SQLiteParameters, SQLiteRow, SQLiteRunResult, SQLiteStatementInterface } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* A prepared statement over `node:sqlite`'s `StatementSync` — the only way the
|
|
5
|
-
* wrapper runs SQL.
|
|
6
|
-
*
|
|
7
|
-
* @remarks
|
|
8
|
-
* Created by `database.prepare(sql)`. Bare named parameters are enabled on
|
|
9
|
-
* construction so a record's keys bind without the SQL prefix character. Each
|
|
10
|
-
* method binds the optional parameters (an array spread to `?` placeholders, a
|
|
11
|
-
* record passed as a single named object) and executes synchronously, mapping any
|
|
12
|
-
* native fault to a `SQLiteError`. Row values arrive as the native
|
|
13
|
-
* {@link SQLiteRow} types; the typed layer above (the driver) imposes a precise
|
|
14
|
-
* shape through a contract rather than re-narrowing here (AGENTS §14).
|
|
15
|
-
*/
|
|
16
|
-
export declare class SQLiteStatement implements SQLiteStatementInterface {
|
|
17
|
-
#private;
|
|
18
|
-
constructor(statement: StatementSync);
|
|
19
|
-
run(parameters?: SQLiteParameters): SQLiteRunResult;
|
|
20
|
-
get(parameters?: SQLiteParameters): SQLiteRow | undefined;
|
|
21
|
-
all(parameters?: SQLiteParameters): readonly SQLiteRow[];
|
|
22
|
-
iterate(parameters?: SQLiteParameters): IterableIterator<SQLiteRow>;
|
|
23
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SQLite result code for a constraint violation (`SQLITE_CONSTRAINT`).
|
|
3
|
-
*
|
|
4
|
-
* @remarks
|
|
5
|
-
* A native `errcode` packs the primary result in its low byte, with extended codes
|
|
6
|
-
* in the high bits (e.g. `SQLITE_CONSTRAINT_UNIQUE`), so the low byte is masked off
|
|
7
|
-
* before comparing. Read only by `wrapError`.
|
|
8
|
-
*/
|
|
9
|
-
export declare const SQLITE_CONSTRAINT = 19;
|
|
10
|
-
/**
|
|
11
|
-
* SQLite result code for a locked-database fault (`SQLITE_BUSY`).
|
|
12
|
-
*
|
|
13
|
-
* @remarks
|
|
14
|
-
* A native `errcode` packs the primary result in its low byte, with extended codes
|
|
15
|
-
* in the high bits, so the low byte is masked off before comparing. Read only by
|
|
16
|
-
* `wrapError`.
|
|
17
|
-
*/
|
|
18
|
-
export declare const SQLITE_BUSY = 5;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { SQLiteErrorCode } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* An error thrown by the SQLite wrapper.
|
|
4
|
-
*
|
|
5
|
-
* @remarks
|
|
6
|
-
* Carries a {@link SQLiteErrorCode} and an optional `context` record (e.g. the
|
|
7
|
-
* native SQLite `errcode`). Construct it directly for the `CLOSED`
|
|
8
|
-
* wrapper-lifecycle fault; the internal `wrapError` maps a native `node:sqlite`
|
|
9
|
-
* error to the right code at the boundary. Narrow a caught value with
|
|
10
|
-
* {@link isSQLiteError}.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* try {
|
|
15
|
-
* statement.run({ id: 'u1' })
|
|
16
|
-
* } catch (error) {
|
|
17
|
-
* if (isSQLiteError(error) && error.code === 'CONSTRAINT') {
|
|
18
|
-
* // a UNIQUE / PRIMARY KEY violation
|
|
19
|
-
* }
|
|
20
|
-
* }
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export declare class SQLiteError extends Error {
|
|
24
|
-
readonly code: SQLiteErrorCode;
|
|
25
|
-
readonly context?: Readonly<Record<string, unknown>>;
|
|
26
|
-
constructor(code: SQLiteErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Whether a value is a {@link SQLiteError}.
|
|
30
|
-
*
|
|
31
|
-
* @param value - The value to test
|
|
32
|
-
* @returns `true` when `value` is a `SQLiteError`
|
|
33
|
-
*/
|
|
34
|
-
export declare function isSQLiteError(value: unknown): value is SQLiteError;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { SQLiteDatabaseInterface, SQLiteDatabaseOptions } from './types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Create a synchronous SQLite database over `node:sqlite`.
|
|
4
|
-
*
|
|
5
|
-
* @remarks
|
|
6
|
-
* The wrapper connects lazily — call `connect` (or it is required by the first
|
|
7
|
-
* operation, which throws `CLOSED` until then). This is the lower-level native
|
|
8
|
-
* handle a higher-level typed database engine would be built on; here it ships
|
|
9
|
-
* as the standalone, server-native SQLite surface.
|
|
10
|
-
*
|
|
11
|
-
* @param options - The database `path` (a file path, or `':memory:'` by default)
|
|
12
|
-
* @returns A typed {@link SQLiteDatabaseInterface}
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* import { createSQLiteDatabase } from '@src/server'
|
|
17
|
-
*
|
|
18
|
-
* const db = createSQLiteDatabase({ path: ':memory:' })
|
|
19
|
-
* db.connect()
|
|
20
|
-
* db.exec('CREATE TABLE users (id TEXT PRIMARY KEY, name TEXT)')
|
|
21
|
-
* db.prepare('INSERT INTO users VALUES (?, ?)').run(['u1', 'Ada'])
|
|
22
|
-
* db.prepare('SELECT name FROM users WHERE id = ?').get(['u1']) // { name: 'Ada' }
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
export declare function createSQLiteDatabase(options?: SQLiteDatabaseOptions): SQLiteDatabaseInterface;
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { SQLiteParameters, SQLiteValue } from './types.js';
|
|
2
|
-
import { SQLiteError } from './errors.js';
|
|
3
|
-
/**
|
|
4
|
-
* Convert a thrown native `node:sqlite` error into a typed {@link SQLiteError}.
|
|
5
|
-
*
|
|
6
|
-
* @remarks
|
|
7
|
-
* The single boundary mapping for the wrapper. The thrown value arrives as
|
|
8
|
-
* `unknown` and is narrowed with `isObject` + the `in` operator (never `as`, and
|
|
9
|
-
* not `isRecord` — a native `node:sqlite` error is an `Error` instance, so its
|
|
10
|
-
* prototype fails the plain-record test) to read its `errcode` — a numeric SQLite
|
|
11
|
-
* result code whose low byte identifies a constraint violation
|
|
12
|
-
* (`SQLITE_CONSTRAINT`), mapped to code `'CONSTRAINT'`; a locked-database fault
|
|
13
|
-
* (`SQLITE_BUSY`) is mapped to `'BUSY'`; anything else is `'UNKNOWN'`. The
|
|
14
|
-
* original message is preserved and `{ errcode }` carried in `context` when
|
|
15
|
-
* present. An already-typed `SQLiteError` is returned unchanged.
|
|
16
|
-
*
|
|
17
|
-
* @param error - The thrown value to convert
|
|
18
|
-
* @returns The equivalent `SQLiteError`
|
|
19
|
-
*/
|
|
20
|
-
export declare function wrapError(error: unknown): SQLiteError;
|
|
21
|
-
/**
|
|
22
|
-
* Normalize {@link SQLiteParameters} to the binding shape a native `StatementSync`
|
|
23
|
-
* call expects.
|
|
24
|
-
*
|
|
25
|
-
* @remarks
|
|
26
|
-
* Positional parameters (an array) bind to `?` placeholders and are spread into
|
|
27
|
-
* the call; named parameters (a record) bind to bare `:name` placeholders and are
|
|
28
|
-
* passed as a single leading object. Returning a discriminated result keeps the
|
|
29
|
-
* `SQLiteStatement` dispatch typed against the native overloads without `as`.
|
|
30
|
-
*
|
|
31
|
-
* @param parameters - The wrapper parameters, or `undefined` for none
|
|
32
|
-
* @returns `{ positional }` for an array (empty when omitted) or `{ named }` for a record
|
|
33
|
-
*/
|
|
34
|
-
export declare function bindParameters(parameters?: SQLiteParameters): {
|
|
35
|
-
readonly positional: readonly SQLiteValue[];
|
|
36
|
-
} | {
|
|
37
|
-
readonly named: Readonly<Record<string, SQLiteValue>>;
|
|
38
|
-
};
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A value SQLite stores and returns natively — the SQL ↔ JS bridge.
|
|
3
|
-
*
|
|
4
|
-
* @remarks
|
|
5
|
-
* `node:sqlite` maps `NULL` / `INTEGER` / `REAL` / `TEXT` / `BLOB` to exactly
|
|
6
|
-
* these JS types (integers arrive as `number`, or `bigint` only past 2^53).
|
|
7
|
-
*/
|
|
8
|
-
export type SQLiteValue = null | number | bigint | string | Uint8Array;
|
|
9
|
-
/** A result row — a record of column name to {@link SQLiteValue}. */
|
|
10
|
-
export type SQLiteRow = Record<string, SQLiteValue>;
|
|
11
|
-
/**
|
|
12
|
-
* Bind parameters for a prepared statement — positional (an array, bound to `?`)
|
|
13
|
-
* or named (a record, bound to bare `:name` placeholders).
|
|
14
|
-
*/
|
|
15
|
-
export type SQLiteParameters = readonly SQLiteValue[] | Readonly<Record<string, SQLiteValue>>;
|
|
16
|
-
/** The outcome of a non-query statement (`INSERT` / `UPDATE` / `DELETE` / DDL). */
|
|
17
|
-
export interface SQLiteRunResult {
|
|
18
|
-
readonly changes: number;
|
|
19
|
-
readonly rowid: number;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* A machine-readable {@link SQLiteError} code.
|
|
23
|
-
*
|
|
24
|
-
* @remarks
|
|
25
|
-
* `'BUSY'` is retryable — it means a locked database was still held by another
|
|
26
|
-
* connection when the `timeout` (see {@link SQLiteDatabaseOptions}) elapsed; a
|
|
27
|
-
* caller may retry the operation, typically after backing off briefly.
|
|
28
|
-
*/
|
|
29
|
-
export type SQLiteErrorCode = 'CLOSED' | 'CONSTRAINT' | 'BUSY' | 'UNKNOWN';
|
|
30
|
-
/**
|
|
31
|
-
* Options for `createSQLiteDatabase`.
|
|
32
|
-
*
|
|
33
|
-
* @remarks
|
|
34
|
-
* `path` is the database file path, or the special name `':memory:'` for an
|
|
35
|
-
* in-memory database (the default when omitted). `readonly` opens the
|
|
36
|
-
* connection read-only (native `readOnly`) — an absent file fails to open
|
|
37
|
-
* rather than being created. `timeout` is the busy-timeout in milliseconds
|
|
38
|
-
* (native `timeout`) — how long SQLite retries a locked database before
|
|
39
|
-
* failing with a `BUSY` {@link SQLiteError}; defaults to `0` (fail
|
|
40
|
-
* immediately) when omitted. `foreignKeys` enables foreign-key constraint
|
|
41
|
-
* enforcement (native `enableForeignKeyConstraints`); `node:sqlite` defaults
|
|
42
|
-
* this to `true` when omitted. `bigints` reads `INTEGER` columns back as
|
|
43
|
-
* `bigint` (native `readBigInts`) — writes already accept `bigint` regardless
|
|
44
|
-
* of this option, so a stored integer beyond `Number.MAX_SAFE_INTEGER` throws
|
|
45
|
-
* on read unless `bigints` is enabled; enabling it returns EVERY integer
|
|
46
|
-
* column as `bigint`, not just out-of-range ones, closing that read/write
|
|
47
|
-
* asymmetry at the cost of `bigint` values for ordinary small integers too.
|
|
48
|
-
*/
|
|
49
|
-
export interface SQLiteDatabaseOptions {
|
|
50
|
-
readonly path?: string;
|
|
51
|
-
readonly readonly?: boolean;
|
|
52
|
-
readonly timeout?: number;
|
|
53
|
-
readonly foreignKeys?: boolean;
|
|
54
|
-
readonly bigints?: boolean;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* A prepared statement — the only way the wrapper runs SQL (no query DSL; the
|
|
58
|
-
* core database layer owns querying, exactly as the IndexedDB wrapper does).
|
|
59
|
-
*
|
|
60
|
-
* @remarks
|
|
61
|
-
* Reached through `database.prepare(sql)`. Each method binds the optional
|
|
62
|
-
* `parameters` (an array spread to positional `?` placeholders, or a record bound
|
|
63
|
-
* to bare named placeholders) and executes synchronously: `run` for a non-query,
|
|
64
|
-
* `get` for the first row, `all` for every row, `iterate` for a lazy stream. A
|
|
65
|
-
* native fault surfaces as a {@link SQLiteError}.
|
|
66
|
-
*/
|
|
67
|
-
export interface SQLiteStatementInterface {
|
|
68
|
-
run(parameters?: SQLiteParameters): SQLiteRunResult;
|
|
69
|
-
get(parameters?: SQLiteParameters): SQLiteRow | undefined;
|
|
70
|
-
all(parameters?: SQLiteParameters): readonly SQLiteRow[];
|
|
71
|
-
iterate(parameters?: SQLiteParameters): IterableIterator<SQLiteRow>;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* A synchronous SQLite database over `node:sqlite`'s `DatabaseSync` — a lean,
|
|
75
|
-
* typed, zero-dependency layer exposing prepared statements, transactions, and
|
|
76
|
-
* pragmas. Synchronous because `node:sqlite` is; the SQLite *driver* (Chunk 3)
|
|
77
|
-
* adapts it to the async `DriverInterface`.
|
|
78
|
-
*
|
|
79
|
-
* @remarks
|
|
80
|
-
* Connects lazily — `connect` opens the underlying `DatabaseSync` (idempotent),
|
|
81
|
-
* and every operation requires an open connection, throwing a `CLOSED`
|
|
82
|
-
* {@link SQLiteError} before `connect` or after `close`. `exec` runs SQL with no
|
|
83
|
-
* results (DDL, pragmas); `prepare` compiles a {@link SQLiteStatementInterface};
|
|
84
|
-
* `transaction` runs a scope between `BEGIN` and `COMMIT`, rolling back on a
|
|
85
|
-
* throw; `pragma` reads (or sets then reads) a single PRAGMA value — `name` is
|
|
86
|
-
* trusted internal use only, never untrusted input, since pragma names cannot
|
|
87
|
-
* be bound as parameters. `[Symbol.dispose]` closes the connection (same as
|
|
88
|
-
* `close`), enabling `using` to release it deterministically at the end of a
|
|
89
|
-
* block.
|
|
90
|
-
*/
|
|
91
|
-
export interface SQLiteDatabaseInterface {
|
|
92
|
-
readonly path: string;
|
|
93
|
-
readonly connected: boolean;
|
|
94
|
-
connect(): void;
|
|
95
|
-
close(): void;
|
|
96
|
-
exec(sql: string): void;
|
|
97
|
-
prepare(sql: string): SQLiteStatementInterface;
|
|
98
|
-
transaction<R>(scope: () => R): R;
|
|
99
|
-
pragma(name: string, value?: string | number): SQLiteValue | undefined;
|
|
100
|
-
[Symbol.dispose](): void;
|
|
101
|
-
}
|