@syncular/dialect-expo-sqlite 0.0.6-159 → 0.0.6-167

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/dist/index.d.ts CHANGED
@@ -1,15 +1,10 @@
1
1
  /**
2
2
  * @syncular/dialect-expo-sqlite - Expo SQLite dialect for sync
3
3
  *
4
- * Provides a Kysely dialect for Expo's SQLite module (expo-sqlite)
4
+ * Provides a Kysely dialect for Expo's SQLite module (expo-sqlite).
5
5
  * SQLite-compatible — use with @syncular/server-dialect-sqlite.
6
- *
7
- * Implements a custom Kysely Driver that wraps expo-sqlite's sync API
8
- * into the promise-based interface Kysely expects. All operations are
9
- * serialized through a single connection to prevent "database is locked"
10
- * errors from concurrent access on the native handle.
11
6
  */
12
- import type { DatabaseIntrospector, Dialect, DialectAdapter, Driver, Kysely, QueryCompiler } from 'kysely';
7
+ import type { Dialect } from 'kysely';
13
8
  export type ExpoSqliteBindValue = null | string | number | Uint8Array;
14
9
  export type ExpoSqliteBindParams = ExpoSqliteBindValue[];
15
10
  export interface ExpoSqliteRunResult {
@@ -39,14 +34,6 @@ export type ExpoSqliteOptions = ExpoSqliteNameOptions | ExpoSqliteInstanceOption
39
34
  /**
40
35
  * Create the Expo SQLite dialect directly.
41
36
  */
42
- export declare function createExpoSqliteDialect(options: ExpoSqliteOptions): ExpoSqliteDialect;
43
- declare class ExpoSqliteDialect implements Dialect {
44
- #private;
45
- constructor(options: ExpoSqliteOptions);
46
- createAdapter(): DialectAdapter;
47
- createDriver(): Driver;
48
- createQueryCompiler(): QueryCompiler;
49
- createIntrospector(db: Kysely<unknown>): DatabaseIntrospector;
50
- }
37
+ export declare function createExpoSqliteDialect(options: ExpoSqliteOptions): Dialect;
51
38
  export {};
52
39
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAEV,oBAAoB,EACpB,OAAO,EACP,cAAc,EACd,MAAM,EACN,MAAM,EACN,aAAa,EAGd,MAAM,QAAQ,CAAC;AAQhB,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAEtE,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,EAAE,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,CAAC,EAAE,CAAC;IAC9D,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,mBAAmB,EAAE,GAAG,CAAC,EAAE,CAAC;IAC3E,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,mBAAmB,CAAC;IACxE,OAAO,CACL,GAAG,EAAE,MAAM,EACX,GAAG,MAAM,EAAE,SAAS,mBAAmB,EAAE,GACxC,mBAAmB,CAAC;IACvB,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,0DAA0D;AAC1D,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,sBAAsB,CAAC;AAEjE,UAAU,qBAAqB;IAC7B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED,UAAU,yBAAyB;IACjC,gDAAgD;IAChD,QAAQ,EAAE,sBAAsB,CAAC;CAClC;AAED,MAAM,MAAM,iBAAiB,GACzB,qBAAqB,GACrB,yBAAyB,CAAC;AAE9B;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,iBAAiB,GACzB,iBAAiB,CAEnB;AAkCD,cAAM,iBAAkB,YAAW,OAAO;;IAGxC,YAAY,OAAO,EAAE,iBAAiB,EAErC;IAED,aAAa,IAAI,cAAc,CAE9B;IAED,YAAY,IAAI,MAAM,CAErB;IAED,mBAAmB,IAAI,aAAa,CAEnC;IAED,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,oBAAoB,CAE5D;CACF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAsB,OAAO,EAAe,MAAM,QAAQ,CAAC;AAIvE,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAEtE,MAAM,MAAM,oBAAoB,GAAG,mBAAmB,EAAE,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,CAAC,EAAE,CAAC;IAC9D,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,mBAAmB,EAAE,GAAG,CAAC,EAAE,CAAC;IAC3E,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,mBAAmB,CAAC;IACxE,OAAO,CACL,GAAG,EAAE,MAAM,EACX,GAAG,MAAM,EAAE,SAAS,mBAAmB,EAAE,GACxC,mBAAmB,CAAC;IACvB,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,0DAA0D;AAC1D,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,sBAAsB,CAAC;AAEjE,UAAU,qBAAqB;IAC7B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED,UAAU,yBAAyB;IACjC,gDAAgD;IAChD,QAAQ,EAAE,sBAAsB,CAAC;CAClC;AAED,MAAM,MAAM,iBAAiB,GACzB,qBAAqB,GACrB,yBAAyB,CAAC;AAE9B;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAE3E"}
package/dist/index.js CHANGED
@@ -1,111 +1,42 @@
1
1
  /**
2
2
  * @syncular/dialect-expo-sqlite - Expo SQLite dialect for sync
3
3
  *
4
- * Provides a Kysely dialect for Expo's SQLite module (expo-sqlite)
4
+ * Provides a Kysely dialect for Expo's SQLite module (expo-sqlite).
5
5
  * SQLite-compatible — use with @syncular/server-dialect-sqlite.
6
- *
7
- * Implements a custom Kysely Driver that wraps expo-sqlite's sync API
8
- * into the promise-based interface Kysely expects. All operations are
9
- * serialized through a single connection to prevent "database is locked"
10
- * errors from concurrent access on the native handle.
11
6
  */
12
- import { CompiledQuery, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler, } from 'kysely';
7
+ import { CompiledQuery } from 'kysely';
8
+ import { BaseSqliteDialect, BaseSqliteDriver } from 'kysely-generic-sqlite';
13
9
  /**
14
10
  * Create the Expo SQLite dialect directly.
15
11
  */
16
12
  export function createExpoSqliteDialect(options) {
17
- return new ExpoSqliteDialect(options);
18
- }
19
- // ---------------------------------------------------------------------------
20
- // Simple async mutex — serializes all DB access on a single native handle.
21
- // ---------------------------------------------------------------------------
22
- class Mutex {
23
- #queue = [];
24
- #locked = false;
25
- async acquire() {
26
- if (!this.#locked) {
27
- this.#locked = true;
28
- return;
29
- }
30
- return new Promise((resolve) => {
31
- this.#queue.push(resolve);
32
- });
33
- }
34
- release() {
35
- const next = this.#queue.shift();
36
- if (next) {
37
- next();
38
- }
39
- else {
40
- this.#locked = false;
41
- }
42
- }
43
- }
44
- // ---------------------------------------------------------------------------
45
- // Kysely Dialect implementation for expo-sqlite
46
- // ---------------------------------------------------------------------------
47
- class ExpoSqliteDialect {
48
- #options;
49
- constructor(options) {
50
- this.#options = options;
51
- }
52
- createAdapter() {
53
- return new SqliteAdapter();
54
- }
55
- createDriver() {
56
- return new ExpoSqliteDriver(this.#options);
57
- }
58
- createQueryCompiler() {
59
- return new SqliteQueryCompiler();
60
- }
61
- createIntrospector(db) {
62
- return new SqliteIntrospector(db);
63
- }
13
+ return new BaseSqliteDialect(() => new ExpoSqliteDriver(options));
64
14
  }
65
- class ExpoSqliteDriver {
66
- #options;
15
+ class ExpoSqliteDriver extends BaseSqliteDriver {
67
16
  #db;
68
- #connection;
69
- #mutex = new Mutex();
70
17
  constructor(options) {
71
- this.#options = options;
72
- }
73
- async init() {
74
- this.#db = this.#resolveDatabase();
75
- // Enable WAL mode for better concurrency (allows concurrent reads
76
- // while writing, prevents "database is locked" errors during sync).
77
- this.#db.runSync('PRAGMA journal_mode = WAL', []);
78
- // Wait up to 5s for locks to clear instead of failing immediately.
79
- this.#db.runSync('PRAGMA busy_timeout = 5000', []);
80
- this.#connection = new ExpoSqliteConnection(this.#db);
81
- }
82
- async acquireConnection() {
83
- await this.#mutex.acquire();
84
- return this.#connection;
18
+ super(async () => {
19
+ this.#db = resolveExpoSqliteDatabase(options);
20
+ // Better concurrency defaults for sync workloads.
21
+ this.#db.runSync('PRAGMA journal_mode = WAL', []);
22
+ this.#db.runSync('PRAGMA busy_timeout = 5000', []);
23
+ this.conn = new ExpoSqliteConnection(this.#db);
24
+ });
85
25
  }
86
- async beginTransaction(connection, _settings) {
26
+ async beginTransaction(connection) {
87
27
  await connection.executeQuery(CompiledQuery.raw('begin immediate'));
88
28
  }
89
- async commitTransaction(connection) {
90
- await connection.executeQuery(CompiledQuery.raw('commit'));
91
- }
92
- async rollbackTransaction(connection) {
93
- await connection.executeQuery(CompiledQuery.raw('rollback'));
94
- }
95
- async releaseConnection(_connection) {
96
- this.#mutex.release();
97
- }
98
29
  async destroy() {
99
- if (this.#db) {
100
- this.#db.closeSync();
101
- }
30
+ const db = this.#db;
31
+ this.#db = undefined;
32
+ db?.closeSync();
102
33
  }
103
- #resolveDatabase() {
104
- if ('database' in this.#options) {
105
- return this.#options.database;
106
- }
107
- return this.#options.openDatabaseSync(this.#options.name);
34
+ }
35
+ function resolveExpoSqliteDatabase(options) {
36
+ if ('database' in options) {
37
+ return options.database;
108
38
  }
39
+ return options.openDatabaseSync(options.name);
109
40
  }
110
41
  class ExpoSqliteConnection {
111
42
  #db;
@@ -127,7 +58,6 @@ class ExpoSqliteConnection {
127
58
  : {}),
128
59
  };
129
60
  }
130
- // For INSERT, UPDATE, DELETE — use runSync to get lastInsertRowId and changes
131
61
  const result = this.#db.runSync(sql, params);
132
62
  return {
133
63
  rows: [],
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAyC5E;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAA0B,EAAW;IAC3E,OAAO,IAAI,iBAAiB,CAAC,GAAG,EAAE,CAAC,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;AAAA,CACnE;AAED,MAAM,gBAAiB,SAAQ,gBAAgB;IAC7C,GAAG,CAAqC;IAExC,YAAY,OAA0B,EAAE;QACtC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;YAChB,IAAI,CAAC,GAAG,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;YAC9C,kDAAkD;YAClD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,IAAI,GAAG,IAAI,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAAA,CAChD,CAAC,CAAC;IAAA,CACJ;IAED,KAAK,CAAC,gBAAgB,CAAC,UAA8B,EAAiB;QACpE,MAAM,UAAU,CAAC,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAAA,CACrE;IAED,KAAK,CAAC,OAAO,GAAkB;QAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;QACpB,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC;QACrB,EAAE,EAAE,SAAS,EAAE,CAAC;IAAA,CACjB;CACF;AAED,SAAS,yBAAyB,CAChC,OAA0B,EACF;IACxB,IAAI,UAAU,IAAI,OAAO,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC,QAAQ,CAAC;IAC1B,CAAC;IACD,OAAO,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAAA,CAC/C;AAED,MAAM,oBAAoB;IACf,GAAG,CAAyB;IAErC,YAAY,EAA0B,EAAE;QACtC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;IAAA,CACf;IAED,KAAK,CAAC,YAAY,CAAI,aAA4B,EAA2B;QAC3E,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,aAAa,CAAC;QAC1C,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAyB,CAAC;QAEvD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,YAAY,GAAG,qCAAqC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAErE,IAAI,YAAY,IAAI,YAAY,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAI,GAAG,EAAE,MAAM,CAAC,CAAC;YACjD,MAAM,cAAc,GAAG,IAAI,IAAI,EAAE,CAAC;YAClC,OAAO;gBACL,IAAI,EAAE,cAAc;gBACpB,GAAG,CAAC,YAAY;oBACd,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;oBACpD,CAAC,CAAC,EAAE,CAAC;aACR,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAwB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAClE,OAAO;YACL,IAAI,EAAE,EAAE;YACR,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;YACvC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC;SACzC,CAAC;IAAA,CACH;IAED,WAAW,CACT,cAA6B,EAC7B,UAAmB,EACoB;QACvC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAAA,CAClE;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncular/dialect-expo-sqlite",
3
- "version": "0.0.6-159",
3
+ "version": "0.0.6-167",
4
4
  "description": "Expo SQLite dialect for the Syncular client",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Benjamin Kniffler",
@@ -42,14 +42,16 @@
42
42
  "build": "tsgo",
43
43
  "release": "bunx syncular-publish"
44
44
  },
45
- "dependencies": {},
45
+ "dependencies": {
46
+ "kysely-generic-sqlite": "^1.2.1"
47
+ },
46
48
  "peerDependencies": {
47
49
  "expo-sqlite": "*",
48
50
  "kysely": "^0.28.0"
49
51
  },
50
52
  "devDependencies": {
51
53
  "@syncular/config": "0.0.0",
52
- "@syncular/core": "0.0.6-159",
54
+ "@syncular/core": "0.0.6-167",
53
55
  "kysely": "*"
54
56
  },
55
57
  "files": [
package/src/index.ts CHANGED
@@ -1,32 +1,13 @@
1
1
  /**
2
2
  * @syncular/dialect-expo-sqlite - Expo SQLite dialect for sync
3
3
  *
4
- * Provides a Kysely dialect for Expo's SQLite module (expo-sqlite)
4
+ * Provides a Kysely dialect for Expo's SQLite module (expo-sqlite).
5
5
  * SQLite-compatible — use with @syncular/server-dialect-sqlite.
6
- *
7
- * Implements a custom Kysely Driver that wraps expo-sqlite's sync API
8
- * into the promise-based interface Kysely expects. All operations are
9
- * serialized through a single connection to prevent "database is locked"
10
- * errors from concurrent access on the native handle.
11
6
  */
12
7
 
13
- import type {
14
- DatabaseConnection,
15
- DatabaseIntrospector,
16
- Dialect,
17
- DialectAdapter,
18
- Driver,
19
- Kysely,
20
- QueryCompiler,
21
- QueryResult,
22
- TransactionSettings,
23
- } from 'kysely';
24
- import {
25
- CompiledQuery,
26
- SqliteAdapter,
27
- SqliteIntrospector,
28
- SqliteQueryCompiler,
29
- } from 'kysely';
8
+ import type { DatabaseConnection, Dialect, QueryResult } from 'kysely';
9
+ import { CompiledQuery } from 'kysely';
10
+ import { BaseSqliteDialect, BaseSqliteDriver } from 'kysely-generic-sqlite';
30
11
 
31
12
  export type ExpoSqliteBindValue = null | string | number | Uint8Array;
32
13
 
@@ -70,124 +51,41 @@ export type ExpoSqliteOptions =
70
51
  /**
71
52
  * Create the Expo SQLite dialect directly.
72
53
  */
73
- export function createExpoSqliteDialect(
74
- options: ExpoSqliteOptions
75
- ): ExpoSqliteDialect {
76
- return new ExpoSqliteDialect(options);
54
+ export function createExpoSqliteDialect(options: ExpoSqliteOptions): Dialect {
55
+ return new BaseSqliteDialect(() => new ExpoSqliteDriver(options));
77
56
  }
78
57
 
79
- // ---------------------------------------------------------------------------
80
- // Simple async mutex — serializes all DB access on a single native handle.
81
- // ---------------------------------------------------------------------------
82
-
83
- class Mutex {
84
- #queue: Array<() => void> = [];
85
- #locked = false;
86
-
87
- async acquire(): Promise<void> {
88
- if (!this.#locked) {
89
- this.#locked = true;
90
- return;
91
- }
92
- return new Promise<void>((resolve) => {
93
- this.#queue.push(resolve);
94
- });
95
- }
96
-
97
- release(): void {
98
- const next = this.#queue.shift();
99
- if (next) {
100
- next();
101
- } else {
102
- this.#locked = false;
103
- }
104
- }
105
- }
106
-
107
- // ---------------------------------------------------------------------------
108
- // Kysely Dialect implementation for expo-sqlite
109
- // ---------------------------------------------------------------------------
110
-
111
- class ExpoSqliteDialect implements Dialect {
112
- readonly #options: ExpoSqliteOptions;
113
-
114
- constructor(options: ExpoSqliteOptions) {
115
- this.#options = options;
116
- }
117
-
118
- createAdapter(): DialectAdapter {
119
- return new SqliteAdapter();
120
- }
121
-
122
- createDriver(): Driver {
123
- return new ExpoSqliteDriver(this.#options);
124
- }
125
-
126
- createQueryCompiler(): QueryCompiler {
127
- return new SqliteQueryCompiler();
128
- }
129
-
130
- createIntrospector(db: Kysely<unknown>): DatabaseIntrospector {
131
- return new SqliteIntrospector(db);
132
- }
133
- }
134
-
135
- class ExpoSqliteDriver implements Driver {
136
- readonly #options: ExpoSqliteOptions;
58
+ class ExpoSqliteDriver extends BaseSqliteDriver {
137
59
  #db: ExpoSqliteDatabaseLike | undefined;
138
- #connection: ExpoSqliteConnection | undefined;
139
- readonly #mutex = new Mutex();
140
60
 
141
61
  constructor(options: ExpoSqliteOptions) {
142
- this.#options = options;
143
- }
144
-
145
- async init(): Promise<void> {
146
- this.#db = this.#resolveDatabase();
147
- // Enable WAL mode for better concurrency (allows concurrent reads
148
- // while writing, prevents "database is locked" errors during sync).
149
- this.#db.runSync('PRAGMA journal_mode = WAL', []);
150
- // Wait up to 5s for locks to clear instead of failing immediately.
151
- this.#db.runSync('PRAGMA busy_timeout = 5000', []);
152
- this.#connection = new ExpoSqliteConnection(this.#db);
153
- }
154
-
155
- async acquireConnection(): Promise<DatabaseConnection> {
156
- await this.#mutex.acquire();
157
- return this.#connection!;
62
+ super(async () => {
63
+ this.#db = resolveExpoSqliteDatabase(options);
64
+ // Better concurrency defaults for sync workloads.
65
+ this.#db.runSync('PRAGMA journal_mode = WAL', []);
66
+ this.#db.runSync('PRAGMA busy_timeout = 5000', []);
67
+ this.conn = new ExpoSqliteConnection(this.#db);
68
+ });
158
69
  }
159
70
 
160
- async beginTransaction(
161
- connection: DatabaseConnection,
162
- _settings: TransactionSettings
163
- ): Promise<void> {
71
+ async beginTransaction(connection: DatabaseConnection): Promise<void> {
164
72
  await connection.executeQuery(CompiledQuery.raw('begin immediate'));
165
73
  }
166
74
 
167
- async commitTransaction(connection: DatabaseConnection): Promise<void> {
168
- await connection.executeQuery(CompiledQuery.raw('commit'));
169
- }
170
-
171
- async rollbackTransaction(connection: DatabaseConnection): Promise<void> {
172
- await connection.executeQuery(CompiledQuery.raw('rollback'));
173
- }
174
-
175
- async releaseConnection(_connection: DatabaseConnection): Promise<void> {
176
- this.#mutex.release();
177
- }
178
-
179
75
  async destroy(): Promise<void> {
180
- if (this.#db) {
181
- this.#db.closeSync();
182
- }
76
+ const db = this.#db;
77
+ this.#db = undefined;
78
+ db?.closeSync();
183
79
  }
80
+ }
184
81
 
185
- #resolveDatabase(): ExpoSqliteDatabaseLike {
186
- if ('database' in this.#options) {
187
- return this.#options.database;
188
- }
189
- return this.#options.openDatabaseSync(this.#options.name);
82
+ function resolveExpoSqliteDatabase(
83
+ options: ExpoSqliteOptions
84
+ ): ExpoSqliteDatabaseLike {
85
+ if ('database' in options) {
86
+ return options.database;
190
87
  }
88
+ return options.openDatabaseSync(options.name);
191
89
  }
192
90
 
193
91
  class ExpoSqliteConnection implements DatabaseConnection {
@@ -215,7 +113,6 @@ class ExpoSqliteConnection implements DatabaseConnection {
215
113
  };
216
114
  }
217
115
 
218
- // For INSERT, UPDATE, DELETE — use runSync to get lastInsertRowId and changes
219
116
  const result: ExpoSqliteRunResult = this.#db.runSync(sql, params);
220
117
  return {
221
118
  rows: [],