@holo-js/db-sqlite 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,64 @@
1
+ interface DriverQueryResult<TRow extends Record<string, unknown> = Record<string, unknown>> {
2
+ rows: TRow[];
3
+ rowCount: number;
4
+ }
5
+ interface DriverExecutionResult {
6
+ affectedRows?: number;
7
+ lastInsertId?: number | string;
8
+ }
9
+ interface DriverAdapter {
10
+ initialize(): Promise<void>;
11
+ disconnect(): Promise<void>;
12
+ isConnected(): boolean;
13
+ query<TRow extends Record<string, unknown> = Record<string, unknown>>(sql: string, bindings?: readonly unknown[]): Promise<DriverQueryResult<TRow>>;
14
+ execute(sql: string, bindings?: readonly unknown[]): Promise<DriverExecutionResult>;
15
+ beginTransaction(): Promise<void>;
16
+ commit(): Promise<void>;
17
+ rollback(): Promise<void>;
18
+ createSavepoint?(name: string): Promise<void>;
19
+ rollbackToSavepoint?(name: string): Promise<void>;
20
+ releaseSavepoint?(name: string): Promise<void>;
21
+ }
22
+ interface SQLiteStatementLike {
23
+ all(...params: readonly unknown[]): Record<string, unknown>[];
24
+ run(...params: readonly unknown[]): {
25
+ changes?: number;
26
+ lastInsertRowid?: unknown;
27
+ };
28
+ }
29
+ interface SQLiteDatabaseLike {
30
+ prepare(sql: string): SQLiteStatementLike;
31
+ exec(sql: string): unknown;
32
+ close(): unknown;
33
+ }
34
+ interface SQLiteAdapterOptions {
35
+ filename?: string;
36
+ database?: SQLiteDatabaseLike;
37
+ createDatabase?: (filename: string) => SQLiteDatabaseLike;
38
+ }
39
+ declare class SQLiteAdapter implements DriverAdapter {
40
+ private database?;
41
+ private connected;
42
+ private readonly filename;
43
+ private readonly createDatabaseInstance;
44
+ constructor(options?: SQLiteAdapterOptions);
45
+ initialize(): Promise<void>;
46
+ disconnect(): Promise<void>;
47
+ isConnected(): boolean;
48
+ query<TRow extends Record<string, unknown> = Record<string, unknown>>(sql: string, bindings?: readonly unknown[]): Promise<DriverQueryResult<TRow>>;
49
+ introspect<TRow extends Record<string, unknown> = Record<string, unknown>>(sql: string, bindings?: readonly unknown[]): Promise<DriverQueryResult<TRow>>;
50
+ execute(sql: string, bindings?: readonly unknown[]): Promise<DriverExecutionResult>;
51
+ beginTransaction(): Promise<void>;
52
+ commit(): Promise<void>;
53
+ rollback(): Promise<void>;
54
+ createSavepoint(name: string): Promise<void>;
55
+ rollbackToSavepoint(name: string): Promise<void>;
56
+ releaseSavepoint(name: string): Promise<void>;
57
+ private getDatabase;
58
+ private normalizeSavepointName;
59
+ private invokeStatement;
60
+ private isBindingArityError;
61
+ }
62
+ declare function createSQLiteAdapter(options?: SQLiteAdapterOptions): SQLiteAdapter;
63
+
64
+ export { type DriverAdapter, type DriverExecutionResult, type DriverQueryResult, SQLiteAdapter, type SQLiteAdapterOptions, type SQLiteDatabaseLike, type SQLiteStatementLike, createSQLiteAdapter };
package/dist/index.mjs ADDED
@@ -0,0 +1,104 @@
1
+ // src/index.ts
2
+ import Database from "better-sqlite3";
3
+ var TransactionError = class extends Error {
4
+ };
5
+ var SQLiteAdapter = class {
6
+ database;
7
+ connected;
8
+ filename;
9
+ createDatabaseInstance;
10
+ constructor(options = {}) {
11
+ this.database = options.database;
12
+ this.connected = !!options.database;
13
+ this.filename = options.filename ?? ":memory:";
14
+ this.createDatabaseInstance = options.createDatabase ?? ((filename) => new Database(filename));
15
+ }
16
+ async initialize() {
17
+ if (this.connected) {
18
+ return;
19
+ }
20
+ this.database = this.createDatabaseInstance(this.filename);
21
+ this.connected = true;
22
+ }
23
+ async disconnect() {
24
+ if (!this.connected || !this.database) {
25
+ return;
26
+ }
27
+ this.database.close();
28
+ this.database = void 0;
29
+ this.connected = false;
30
+ }
31
+ isConnected() {
32
+ return this.connected;
33
+ }
34
+ async query(sql, bindings = []) {
35
+ const statement = this.getDatabase().prepare(sql);
36
+ const rows = this.invokeStatement(statement, "all", bindings);
37
+ return {
38
+ rows,
39
+ rowCount: rows.length
40
+ };
41
+ }
42
+ async introspect(sql, bindings = []) {
43
+ return this.query(sql, bindings);
44
+ }
45
+ async execute(sql, bindings = []) {
46
+ const statement = this.getDatabase().prepare(sql);
47
+ const result = this.invokeStatement(statement, "run", bindings);
48
+ return {
49
+ affectedRows: result.changes,
50
+ lastInsertId: typeof result.lastInsertRowid === "bigint" ? Number(result.lastInsertRowid) : result.lastInsertRowid
51
+ };
52
+ }
53
+ async beginTransaction() {
54
+ this.getDatabase().exec("BEGIN");
55
+ }
56
+ async commit() {
57
+ this.getDatabase().exec("COMMIT");
58
+ }
59
+ async rollback() {
60
+ this.getDatabase().exec("ROLLBACK");
61
+ }
62
+ async createSavepoint(name) {
63
+ this.getDatabase().exec(`SAVEPOINT ${this.normalizeSavepointName(name)}`);
64
+ }
65
+ async rollbackToSavepoint(name) {
66
+ this.getDatabase().exec(`ROLLBACK TO SAVEPOINT ${this.normalizeSavepointName(name)}`);
67
+ }
68
+ async releaseSavepoint(name) {
69
+ this.getDatabase().exec(`RELEASE SAVEPOINT ${this.normalizeSavepointName(name)}`);
70
+ }
71
+ getDatabase() {
72
+ if (!this.connected || !this.database) {
73
+ this.database = this.createDatabaseInstance(this.filename);
74
+ this.connected = true;
75
+ }
76
+ return this.database;
77
+ }
78
+ normalizeSavepointName(name) {
79
+ if (!/^[A-Z_]\w*$/i.test(name)) {
80
+ throw new TransactionError(`Invalid savepoint name "${name}".`);
81
+ }
82
+ return name;
83
+ }
84
+ invokeStatement(statement, method, bindings) {
85
+ try {
86
+ return statement[method](...bindings);
87
+ } catch (error) {
88
+ if (bindings.length > 0 && this.isBindingArityError(error)) {
89
+ return statement[method](bindings);
90
+ }
91
+ throw error;
92
+ }
93
+ }
94
+ isBindingArityError(error) {
95
+ return error instanceof RangeError && (error.message.includes("Too many parameter values were provided") || error.message.includes("Too few parameter values were provided"));
96
+ }
97
+ };
98
+ function createSQLiteAdapter(options = {}) {
99
+ return new SQLiteAdapter(options);
100
+ }
101
+ export {
102
+ SQLiteAdapter,
103
+ createSQLiteAdapter
104
+ };
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@holo-js/db-sqlite",
3
+ "version": "0.1.3",
4
+ "description": "Holo-JS Framework - SQLite database adapter",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.mjs",
11
+ "default": "./dist/index.mjs"
12
+ }
13
+ },
14
+ "main": "./dist/index.mjs",
15
+ "types": "./dist/index.d.ts",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "stub": "tsup --watch",
22
+ "typecheck": "tsc -p tsconfig.json --noEmit",
23
+ "test": "vitest --run"
24
+ },
25
+ "peerDependencies": {
26
+ "@holo-js/db": "^0.1.3"
27
+ },
28
+ "dependencies": {
29
+ "better-sqlite3": "^11.7.0"
30
+ },
31
+ "devDependencies": {
32
+ "@holo-js/db": "workspace:*",
33
+ "@types/better-sqlite3": "^7.6.12",
34
+ "tsup": "^8.3.5",
35
+ "typescript": "^5.7.2",
36
+ "vitest": "^2.1.8"
37
+ }
38
+ }