@syncular/dialect-expo-sqlite 0.0.1-120 → 0.0.1-123
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 +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +37 -3
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* SQLite-compatible — use with @syncular/server-dialect-sqlite.
|
|
7
7
|
*
|
|
8
8
|
* Implements a custom Kysely Driver that wraps expo-sqlite's sync API
|
|
9
|
-
* into the promise-based interface Kysely expects.
|
|
9
|
+
* into the promise-based interface Kysely expects. All operations are
|
|
10
|
+
* serialized through a single connection to prevent "database is locked"
|
|
11
|
+
* errors from concurrent access on the native handle.
|
|
10
12
|
*/
|
|
11
13
|
import { SerializePlugin } from '@syncular/core';
|
|
12
14
|
import type { DatabaseIntrospector, Dialect, DialectAdapter, Driver, QueryCompiler } from 'kysely';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAEV,oBAAoB,EACpB,OAAO,EACP,cAAc,EACd,MAAM,EACN,aAAa,EAGd,MAAM,QAAQ,CAAC;AAChB,OAAO,EAEL,MAAM,EAIP,MAAM,QAAQ,CAAC;AAEhB,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;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC,CAAC,CAAC,CAK3E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,iBAAiB,GACzB,iBAAiB,CAEnB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD;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"}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* SQLite-compatible — use with @syncular/server-dialect-sqlite.
|
|
7
7
|
*
|
|
8
8
|
* Implements a custom Kysely Driver that wraps expo-sqlite's sync API
|
|
9
|
-
* into the promise-based interface Kysely expects.
|
|
9
|
+
* into the promise-based interface Kysely expects. All operations are
|
|
10
|
+
* serialized through a single connection to prevent "database is locked"
|
|
11
|
+
* errors from concurrent access on the native handle.
|
|
10
12
|
*/
|
|
11
13
|
import { SerializePlugin } from '@syncular/core';
|
|
12
14
|
import { CompiledQuery, Kysely, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler, } from 'kysely';
|
|
@@ -44,6 +46,31 @@ export function createSerializePlugin() {
|
|
|
44
46
|
return new SerializePlugin();
|
|
45
47
|
}
|
|
46
48
|
// ---------------------------------------------------------------------------
|
|
49
|
+
// Simple async mutex — serializes all DB access on a single native handle.
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
class Mutex {
|
|
52
|
+
#queue = [];
|
|
53
|
+
#locked = false;
|
|
54
|
+
async acquire() {
|
|
55
|
+
if (!this.#locked) {
|
|
56
|
+
this.#locked = true;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
this.#queue.push(resolve);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
release() {
|
|
64
|
+
const next = this.#queue.shift();
|
|
65
|
+
if (next) {
|
|
66
|
+
next();
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.#locked = false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
47
74
|
// Kysely Dialect implementation for expo-sqlite
|
|
48
75
|
// ---------------------------------------------------------------------------
|
|
49
76
|
class ExpoSqliteDialect {
|
|
@@ -67,6 +94,8 @@ class ExpoSqliteDialect {
|
|
|
67
94
|
class ExpoSqliteDriver {
|
|
68
95
|
#options;
|
|
69
96
|
#db;
|
|
97
|
+
#connection;
|
|
98
|
+
#mutex = new Mutex();
|
|
70
99
|
constructor(options) {
|
|
71
100
|
this.#options = options;
|
|
72
101
|
}
|
|
@@ -77,9 +106,11 @@ class ExpoSqliteDriver {
|
|
|
77
106
|
this.#db.runSync('PRAGMA journal_mode = WAL', []);
|
|
78
107
|
// Wait up to 5s for locks to clear instead of failing immediately.
|
|
79
108
|
this.#db.runSync('PRAGMA busy_timeout = 5000', []);
|
|
109
|
+
this.#connection = new ExpoSqliteConnection(this.#db);
|
|
80
110
|
}
|
|
81
111
|
async acquireConnection() {
|
|
82
|
-
|
|
112
|
+
await this.#mutex.acquire();
|
|
113
|
+
return this.#connection;
|
|
83
114
|
}
|
|
84
115
|
async beginTransaction(connection, _settings) {
|
|
85
116
|
await connection.executeQuery(CompiledQuery.raw('begin immediate'));
|
|
@@ -91,7 +122,7 @@ class ExpoSqliteDriver {
|
|
|
91
122
|
await connection.executeQuery(CompiledQuery.raw('rollback'));
|
|
92
123
|
}
|
|
93
124
|
async releaseConnection(_connection) {
|
|
94
|
-
|
|
125
|
+
this.#mutex.release();
|
|
95
126
|
}
|
|
96
127
|
async destroy() {
|
|
97
128
|
if (this.#db) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncular/dialect-expo-sqlite",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-123",
|
|
4
4
|
"description": "Expo SQLite dialect for the Syncular client",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Benjamin Kniffler",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"release": "bunx syncular-publish"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@syncular/core": "0.0.1-
|
|
46
|
+
"@syncular/core": "0.0.1-123"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"expo-sqlite": "^16.0.10",
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* SQLite-compatible — use with @syncular/server-dialect-sqlite.
|
|
7
7
|
*
|
|
8
8
|
* Implements a custom Kysely Driver that wraps expo-sqlite's sync API
|
|
9
|
-
* into the promise-based interface Kysely expects.
|
|
9
|
+
* into the promise-based interface Kysely expects. All operations are
|
|
10
|
+
* serialized through a single connection to prevent "database is locked"
|
|
11
|
+
* errors from concurrent access on the native handle.
|
|
10
12
|
*/
|
|
11
13
|
|
|
12
14
|
import { SerializePlugin } from '@syncular/core';
|
|
@@ -105,6 +107,34 @@ export function createSerializePlugin(): SerializePlugin {
|
|
|
105
107
|
return new SerializePlugin();
|
|
106
108
|
}
|
|
107
109
|
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Simple async mutex — serializes all DB access on a single native handle.
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
class Mutex {
|
|
115
|
+
#queue: Array<() => void> = [];
|
|
116
|
+
#locked = false;
|
|
117
|
+
|
|
118
|
+
async acquire(): Promise<void> {
|
|
119
|
+
if (!this.#locked) {
|
|
120
|
+
this.#locked = true;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
return new Promise<void>((resolve) => {
|
|
124
|
+
this.#queue.push(resolve);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
release(): void {
|
|
129
|
+
const next = this.#queue.shift();
|
|
130
|
+
if (next) {
|
|
131
|
+
next();
|
|
132
|
+
} else {
|
|
133
|
+
this.#locked = false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
108
138
|
// ---------------------------------------------------------------------------
|
|
109
139
|
// Kysely Dialect implementation for expo-sqlite
|
|
110
140
|
// ---------------------------------------------------------------------------
|
|
@@ -136,6 +166,8 @@ class ExpoSqliteDialect implements Dialect {
|
|
|
136
166
|
class ExpoSqliteDriver implements Driver {
|
|
137
167
|
readonly #options: ExpoSqliteOptions;
|
|
138
168
|
#db: ExpoSqliteDatabaseLike | undefined;
|
|
169
|
+
#connection: ExpoSqliteConnection | undefined;
|
|
170
|
+
readonly #mutex = new Mutex();
|
|
139
171
|
|
|
140
172
|
constructor(options: ExpoSqliteOptions) {
|
|
141
173
|
this.#options = options;
|
|
@@ -148,10 +180,12 @@ class ExpoSqliteDriver implements Driver {
|
|
|
148
180
|
this.#db.runSync('PRAGMA journal_mode = WAL', []);
|
|
149
181
|
// Wait up to 5s for locks to clear instead of failing immediately.
|
|
150
182
|
this.#db.runSync('PRAGMA busy_timeout = 5000', []);
|
|
183
|
+
this.#connection = new ExpoSqliteConnection(this.#db);
|
|
151
184
|
}
|
|
152
185
|
|
|
153
186
|
async acquireConnection(): Promise<DatabaseConnection> {
|
|
154
|
-
|
|
187
|
+
await this.#mutex.acquire();
|
|
188
|
+
return this.#connection!;
|
|
155
189
|
}
|
|
156
190
|
|
|
157
191
|
async beginTransaction(
|
|
@@ -170,7 +204,7 @@ class ExpoSqliteDriver implements Driver {
|
|
|
170
204
|
}
|
|
171
205
|
|
|
172
206
|
async releaseConnection(_connection: DatabaseConnection): Promise<void> {
|
|
173
|
-
|
|
207
|
+
this.#mutex.release();
|
|
174
208
|
}
|
|
175
209
|
|
|
176
210
|
async destroy(): Promise<void> {
|