@powersync/capacitor 0.5.0 → 0.5.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.
@@ -1,14 +1,7 @@
1
1
  import { SQLiteDBConnection } from '@capacitor-community/sqlite';
2
- import { BaseObserver, DBAdapter, DBAdapterListener, DBLockOptions, LockContext, QueryResult, Transaction } from '@powersync/web';
3
- import { Mutex } from 'async-mutex';
2
+ import { BaseObserver, ConnectionPool, DBAdapterListener, DBLockOptions, LockContext, Mutex, QueryResult, Transaction } from '@powersync/web';
4
3
  import { CapacitorSQLiteOpenFactoryOptions } from './CapacitorSQLiteOpenFactory.js';
5
- /**
6
- * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).
7
- *
8
- * @experimental
9
- * @alpha This is currently experimental and may change without a major version bump.
10
- */
11
- export declare class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> implements DBAdapter {
4
+ declare class CapacitorConnectionPool extends BaseObserver<DBAdapterListener> implements ConnectionPool {
12
5
  protected options: CapacitorSQLiteOpenFactoryOptions;
13
6
  protected _writeConnection: SQLiteDBConnection | null;
14
7
  protected _readConnection: SQLiteDBConnection | null;
@@ -22,16 +15,32 @@ export declare class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListen
22
15
  private init;
23
16
  close(): Promise<void>;
24
17
  protected generateLockContext(db: SQLiteDBConnection): LockContext;
25
- execute(query: string, params?: any[]): Promise<QueryResult>;
26
- executeRaw(query: string, params?: any[]): Promise<any[][]>;
27
- executeBatch(query: string, params?: any[][]): Promise<QueryResult>;
28
18
  readLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T>;
29
- readTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T>;
30
19
  writeLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T>;
31
- writeTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T>;
32
20
  refreshSchema(): Promise<void>;
21
+ }
22
+ declare const CapacitorSQLiteAdapter_base: (new (...args: any[]) => {
23
+ readTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T>;
24
+ writeTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T>;
33
25
  getAll<T>(sql: string, parameters?: any[]): Promise<T[]>;
34
26
  getOptional<T>(sql: string, parameters?: any[]): Promise<T | null>;
35
27
  get<T>(sql: string, parameters?: any[]): Promise<T>;
36
- protected internalTransaction<T>(ctx: LockContext, fn: (tx: Transaction) => Promise<T>): Promise<T>;
28
+ execute(query: string, params?: any[]): Promise<QueryResult>;
29
+ executeRaw(query: string, params?: any[]): Promise<any[][]>;
30
+ executeBatch(query: string, params?: any[][]): Promise<QueryResult>;
31
+ name: string;
32
+ close: () => void | Promise<void>;
33
+ readLock: <T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions) => Promise<T>;
34
+ writeLock: <T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions) => Promise<T>;
35
+ refreshSchema: () => Promise<void>;
36
+ registerListener(listener: Partial<DBAdapterListener>): () => void;
37
+ }) & typeof CapacitorConnectionPool;
38
+ /**
39
+ * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).
40
+ *
41
+ * @experimental
42
+ * @alpha This is currently experimental and may change without a major version bump.
43
+ */
44
+ export declare class CapacitorSQLiteAdapter extends CapacitorSQLiteAdapter_base {
37
45
  }
46
+ export {};
@@ -1,7 +1,6 @@
1
1
  import { CapacitorSQLite, SQLiteConnection } from '@capacitor-community/sqlite';
2
2
  import { Capacitor } from '@capacitor/core';
3
- import { BaseObserver, mutexRunExclusive } from '@powersync/web';
4
- import { Mutex } from 'async-mutex';
3
+ import { BaseObserver, DBAdapterDefaultMixin, Mutex, timeoutSignal } from '@powersync/web';
5
4
  import { PowerSyncCore } from '../plugin/PowerSyncCore.js';
6
5
  import { messageForErrorCode } from '../plugin/PowerSyncPlugin.js';
7
6
  import { DEFAULT_SQLITE_OPTIONS } from './CapacitorSQLiteOpenFactory.js';
@@ -20,13 +19,7 @@ async function monitorQuery(sql, executor) {
20
19
  throw e;
21
20
  }
22
21
  }
23
- /**
24
- * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).
25
- *
26
- * @experimental
27
- * @alpha This is currently experimental and may change without a major version bump.
28
- */
29
- export class CapacitorSQLiteAdapter extends BaseObserver {
22
+ class CapacitorConnectionPool extends BaseObserver {
30
23
  constructor(options) {
31
24
  super();
32
25
  this.options = options;
@@ -171,24 +164,9 @@ export class CapacitorSQLiteAdapter extends BaseObserver {
171
164
  const results = await execute(query, params);
172
165
  return (_b = (_a = results.rows) === null || _a === void 0 ? void 0 : _a._array.map((row) => Object.values(row))) !== null && _b !== void 0 ? _b : [];
173
166
  };
174
- return {
175
- getAll,
176
- getOptional,
177
- get,
178
- executeRaw,
179
- execute
180
- };
181
- }
182
- execute(query, params) {
183
- return this.writeLock((tx) => tx.execute(query, params));
184
- }
185
- executeRaw(query, params) {
186
- return this.writeLock((tx) => tx.executeRaw(query, params));
187
- }
188
- async executeBatch(query, params = []) {
189
- return this.writeLock(async (tx) => {
167
+ const executeBatch = async (query, params = []) => {
190
168
  var _a, _b, _c;
191
- let result = await this.writeConnection.executeSet(params.map((param) => ({
169
+ let result = await db.executeSet(params.map((param) => ({
192
170
  statement: query,
193
171
  values: param
194
172
  })));
@@ -196,21 +174,24 @@ export class CapacitorSQLiteAdapter extends BaseObserver {
196
174
  rowsAffected: (_b = (_a = result.changes) === null || _a === void 0 ? void 0 : _a.changes) !== null && _b !== void 0 ? _b : 0,
197
175
  insertId: (_c = result.changes) === null || _c === void 0 ? void 0 : _c.lastId
198
176
  };
199
- });
177
+ };
178
+ return {
179
+ getAll,
180
+ getOptional,
181
+ get,
182
+ executeRaw,
183
+ execute,
184
+ executeBatch
185
+ };
200
186
  }
201
187
  readLock(fn, options) {
202
- return mutexRunExclusive(this.readMutex, async () => {
188
+ return this.readMutex.runExclusive(async () => {
203
189
  await this.initializedPromise;
204
- return await fn(this.generateLockContext(this.readConnection));
205
- }, options);
206
- }
207
- readTransaction(fn, options) {
208
- return this.readLock(async (ctx) => {
209
- return this.internalTransaction(ctx, fn);
210
- });
190
+ return fn(this.generateLockContext(this.readConnection));
191
+ }, timeoutSignal(options === null || options === void 0 ? void 0 : options.timeoutMs));
211
192
  }
212
193
  writeLock(fn, options) {
213
- return mutexRunExclusive(this.writeMutex, async () => {
194
+ return this.writeMutex.runExclusive(async () => {
214
195
  var _a;
215
196
  await this.initializedPromise;
216
197
  const result = await fn(this.generateLockContext(this.writeConnection));
@@ -227,12 +208,7 @@ export class CapacitorSQLiteAdapter extends BaseObserver {
227
208
  };
228
209
  this.iterateListeners((l) => { var _a; return (_a = l.tablesUpdated) === null || _a === void 0 ? void 0 : _a.call(l, notification); });
229
210
  return result;
230
- }, options);
231
- }
232
- writeTransaction(fn, options) {
233
- return this.writeLock(async (ctx) => {
234
- return this.internalTransaction(ctx, fn);
235
- });
211
+ }, timeoutSignal(options === null || options === void 0 ? void 0 : options.timeoutMs));
236
212
  }
237
213
  refreshSchema() {
238
214
  return this.writeLock(async (writeTx) => {
@@ -243,48 +219,13 @@ export class CapacitorSQLiteAdapter extends BaseObserver {
243
219
  });
244
220
  });
245
221
  }
246
- getAll(sql, parameters) {
247
- return this.readLock((tx) => tx.getAll(sql, parameters));
248
- }
249
- getOptional(sql, parameters) {
250
- return this.readLock((tx) => tx.getOptional(sql, parameters));
251
- }
252
- get(sql, parameters) {
253
- return this.readLock((tx) => tx.get(sql, parameters));
254
- }
255
- async internalTransaction(ctx, fn) {
256
- let finalized = false;
257
- const commit = async () => {
258
- if (finalized) {
259
- return { rowsAffected: 0 };
260
- }
261
- finalized = true;
262
- return ctx.execute('COMMIT');
263
- };
264
- const rollback = async () => {
265
- if (finalized) {
266
- return { rowsAffected: 0 };
267
- }
268
- finalized = true;
269
- return ctx.execute('ROLLBACK');
270
- };
271
- try {
272
- await ctx.execute('BEGIN');
273
- const result = await fn(Object.assign(Object.assign({}, ctx), { commit,
274
- rollback }));
275
- await commit();
276
- return result;
277
- }
278
- catch (ex) {
279
- try {
280
- await rollback();
281
- }
282
- catch (ex2) {
283
- // In rare cases, a rollback may fail.
284
- // Safe to ignore.
285
- }
286
- throw ex;
287
- }
288
- }
222
+ }
223
+ /**
224
+ * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).
225
+ *
226
+ * @experimental
227
+ * @alpha This is currently experimental and may change without a major version bump.
228
+ */
229
+ export class CapacitorSQLiteAdapter extends DBAdapterDefaultMixin(CapacitorConnectionPool) {
289
230
  }
290
231
  //# sourceMappingURL=CapacitorSQLiteAdapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CapacitorSQLiteAdapter.js","sourceRoot":"","sources":["../../../src/adapter/CapacitorSQLiteAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { CapacitorSQLite, SQLiteConnection, SQLiteDBConnection } from '@capacitor-community/sqlite';\nimport { Capacitor } from '@capacitor/core';\n\nimport {\n BaseObserver,\n BatchedUpdateNotification,\n DBAdapter,\n DBAdapterListener,\n DBLockOptions,\n LockContext,\n mutexRunExclusive,\n QueryResult,\n Transaction\n} from '@powersync/web';\nimport { Mutex } from 'async-mutex';\nimport { PowerSyncCore } from '../plugin/PowerSyncCore.js';\nimport { messageForErrorCode } from '../plugin/PowerSyncPlugin.js';\nimport { CapacitorSQLiteOpenFactoryOptions, DEFAULT_SQLITE_OPTIONS } from './CapacitorSQLiteOpenFactory.js';\n/**\n * Monitors the execution time of a query and logs it to the performance timeline.\n */\nasync function monitorQuery(sql: string, executor: () => Promise<QueryResult>): Promise<QueryResult> {\n const start = performance.now();\n try {\n const r = await executor();\n performance.measure(`[SQL] ${sql}`, { start });\n return r;\n } catch (e: any) {\n performance.measure(`[SQL] [ERROR: ${e.message}] ${sql}`, { start });\n throw e;\n }\n}\n/**\n * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).\n *\n * @experimental\n * @alpha This is currently experimental and may change without a major version bump.\n */\nexport class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> implements DBAdapter {\n protected _writeConnection: SQLiteDBConnection | null;\n protected _readConnection: SQLiteDBConnection | null;\n protected initializedPromise: Promise<void>;\n protected writeMutex: Mutex;\n protected readMutex: Mutex;\n\n constructor(protected options: CapacitorSQLiteOpenFactoryOptions) {\n super();\n this._writeConnection = null;\n this._readConnection = null;\n this.writeMutex = new Mutex();\n this.readMutex = new Mutex();\n this.initializedPromise = this.init();\n }\n\n protected get writeConnection(): SQLiteDBConnection {\n if (!this._writeConnection) {\n throw new Error('Init not completed yet');\n }\n return this._writeConnection;\n }\n\n protected get readConnection(): SQLiteDBConnection {\n if (!this._readConnection) {\n throw new Error('Init not completed yet');\n }\n return this._readConnection;\n }\n\n get name() {\n return this.options.dbFilename;\n }\n\n private async init() {\n const { responseCode: registrationResponseCode } = await PowerSyncCore.registerCore();\n if (registrationResponseCode != 0) {\n throw new Error(`Could not register PowerSync core extension: ${messageForErrorCode(registrationResponseCode)}`);\n }\n\n const sqlite = new SQLiteConnection(CapacitorSQLite);\n\n // It seems like the isConnection and retrieveConnection methods\n // only check a JS side map of connections.\n // On hot reload this JS cache can be cleared, while the connection\n // still exists natively. and `createConnection` will fail if it already exists.\n await sqlite.closeConnection(this.options.dbFilename, false).catch(() => {});\n await sqlite.closeConnection(this.options.dbFilename, true).catch(() => {});\n\n // TODO support encryption eventually\n this._writeConnection = await sqlite.createConnection(this.options.dbFilename, false, 'no-encryption', 1, false);\n this._readConnection = await sqlite.createConnection(this.options.dbFilename, false, 'no-encryption', 1, true);\n\n await this._writeConnection.open();\n\n const { cacheSizeKb, journalSizeLimit, synchronous } = { ...DEFAULT_SQLITE_OPTIONS, ...this.options.sqliteOptions };\n\n await this.writeConnection.query('PRAGMA journal_mode = WAL');\n await this.writeConnection.query(`PRAGMA journal_size_limit = ${journalSizeLimit}`);\n await this.writeConnection.query(`PRAGMA temp_store = memory`);\n await this.writeConnection.query(`PRAGMA synchronous = ${synchronous}`);\n await this.writeConnection.query(`PRAGMA cache_size = -${cacheSizeKb}`);\n\n await this._readConnection.open();\n\n const platform = Capacitor.getPlatform();\n if (platform == 'android') {\n /**\n * SQLCipher for Android enables dynamic loading of extensions.\n * On iOS we use a static auto extension registration.\n */\n const extensionQuery = \"SELECT load_extension('libpowersync.so', 'sqlite3_powersync_init')\";\n await this.writeConnection.query(extensionQuery);\n await this.readConnection.query(extensionQuery);\n }\n await this.writeConnection.query(\"SELECT powersync_update_hooks('install')\");\n }\n\n async close(): Promise<void> {\n await this.initializedPromise;\n await this.writeConnection.close();\n await this.readConnection.close();\n }\n\n protected generateLockContext(db: SQLiteDBConnection): LockContext {\n const _query = async (query: string, params: any[] = []) => {\n const result = await db.query(query, params);\n const arrayResult = result.values ?? [];\n return {\n rowsAffected: 0,\n rows: {\n _array: arrayResult,\n length: arrayResult.length,\n item: (idx: number) => arrayResult[idx]\n }\n };\n };\n\n const _execute = async (query: string, params: any[] = []): Promise<QueryResult> => {\n const platform = Capacitor.getPlatform();\n\n if (db.getConnectionReadOnly()) {\n return _query(query, params);\n }\n\n if (platform == 'android') {\n // Android: use query for SELECT and executeSet for mutations\n // We cannot use `run` here for both cases.\n if (query.toLowerCase().trim().startsWith('select')) {\n return _query(query, params);\n } else {\n const result = await db.executeSet([{ statement: query, values: params }], false);\n return {\n insertId: result.changes?.lastId,\n rowsAffected: result.changes?.changes ?? 0,\n rows: {\n _array: [],\n length: 0,\n item: () => null\n }\n };\n }\n }\n\n // iOS (and other platforms): use run(\"all\")\n const result = await db.run(query, params, false, 'all');\n const resultSet = result.changes?.values ?? [];\n return {\n insertId: result.changes?.lastId,\n rowsAffected: result.changes?.changes ?? 0,\n rows: {\n _array: resultSet,\n length: resultSet.length,\n item: (idx) => resultSet[idx]\n }\n };\n };\n\n const execute = this.options.debugMode\n ? (sql: string, params?: any[]) => monitorQuery(sql, () => _execute(sql, params))\n : _execute;\n\n const executeQuery = this.options.debugMode\n ? (sql: string, params?: any[]) => monitorQuery(sql, () => _query(sql, params))\n : _query;\n\n const getAll = async <T>(query: string, params?: any[]): Promise<T[]> => {\n const result = await executeQuery(query, params);\n return result.rows?._array ?? ([] as T[]);\n };\n\n const getOptional = async <T>(query: string, params?: any[]): Promise<T | null> => {\n const results = await getAll<T>(query, params);\n return results.length > 0 ? results[0] : null;\n };\n\n const get = async <T>(query: string, params?: any[]): Promise<T> => {\n const result = await getOptional<T>(query, params);\n if (!result) {\n throw new Error(`No results for query: ${query}`);\n }\n return result;\n };\n\n const executeRaw = async (query: string, params?: any[]): Promise<any[][]> => {\n // This is a workaround, we don't support multiple columns of the same name\n const results = await execute(query, params);\n return results.rows?._array.map((row) => Object.values(row)) ?? [];\n };\n\n return {\n getAll,\n getOptional,\n get,\n executeRaw,\n execute\n };\n }\n\n execute(query: string, params?: any[]): Promise<QueryResult> {\n return this.writeLock((tx) => tx.execute(query, params));\n }\n\n executeRaw(query: string, params?: any[]): Promise<any[][]> {\n return this.writeLock((tx) => tx.executeRaw(query, params));\n }\n\n async executeBatch(query: string, params: any[][] = []): Promise<QueryResult> {\n return this.writeLock(async (tx) => {\n let result = await this.writeConnection.executeSet(\n params.map((param) => ({\n statement: query,\n values: param\n }))\n );\n\n return {\n rowsAffected: result.changes?.changes ?? 0,\n insertId: result.changes?.lastId\n };\n });\n }\n\n readLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {\n return mutexRunExclusive(\n this.readMutex,\n async () => {\n await this.initializedPromise;\n return await fn(this.generateLockContext(this.readConnection));\n },\n options\n );\n }\n\n readTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {\n return this.readLock(async (ctx) => {\n return this.internalTransaction(ctx, fn);\n });\n }\n\n writeLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {\n return mutexRunExclusive(\n this.writeMutex,\n async () => {\n await this.initializedPromise;\n const result = await fn(this.generateLockContext(this.writeConnection));\n\n // Fetch table updates\n const updates = await this.writeConnection.query(\"SELECT powersync_update_hooks('get') AS table_name\");\n const jsonUpdates = updates.values?.[0];\n if (!jsonUpdates || !jsonUpdates.table_name) {\n throw new Error('Could not fetch table updates');\n }\n const notification: BatchedUpdateNotification = {\n rawUpdates: [],\n tables: JSON.parse(jsonUpdates.table_name),\n groupedUpdates: {}\n };\n this.iterateListeners((l) => l.tablesUpdated?.(notification));\n return result;\n },\n options\n );\n }\n\n writeTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {\n return this.writeLock(async (ctx) => {\n return this.internalTransaction(ctx, fn);\n });\n }\n\n refreshSchema(): Promise<void> {\n return this.writeLock(async (writeTx) => {\n return this.readLock(async (readTx) => {\n const updateQuery = `PRAGMA table_info('sqlite_master')`;\n await writeTx.get(updateQuery);\n await readTx.get(updateQuery);\n });\n });\n }\n\n getAll<T>(sql: string, parameters?: any[]): Promise<T[]> {\n return this.readLock((tx) => tx.getAll<T>(sql, parameters));\n }\n\n getOptional<T>(sql: string, parameters?: any[]): Promise<T | null> {\n return this.readLock((tx) => tx.getOptional<T>(sql, parameters));\n }\n\n get<T>(sql: string, parameters?: any[]): Promise<T> {\n return this.readLock((tx) => tx.get<T>(sql, parameters));\n }\n\n protected async internalTransaction<T>(ctx: LockContext, fn: (tx: Transaction) => Promise<T>): Promise<T> {\n let finalized = false;\n const commit = async (): Promise<QueryResult> => {\n if (finalized) {\n return { rowsAffected: 0 };\n }\n finalized = true;\n return ctx.execute('COMMIT');\n };\n const rollback = async (): Promise<QueryResult> => {\n if (finalized) {\n return { rowsAffected: 0 };\n }\n finalized = true;\n return ctx.execute('ROLLBACK');\n };\n try {\n await ctx.execute('BEGIN');\n const result = await fn({\n ...ctx,\n commit,\n rollback\n });\n await commit();\n return result;\n } catch (ex) {\n try {\n await rollback();\n } catch (ex2) {\n // In rare cases, a rollback may fail.\n // Safe to ignore.\n }\n throw ex;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"CapacitorSQLiteAdapter.js","sourceRoot":"","sources":["../../../src/adapter/CapacitorSQLiteAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { CapacitorSQLite, SQLiteConnection, SQLiteDBConnection } from '@capacitor-community/sqlite';\nimport { Capacitor } from '@capacitor/core';\n\nimport {\n BaseObserver,\n BatchedUpdateNotification,\n ConnectionPool,\n DBAdapter,\n DBAdapterDefaultMixin,\n DBAdapterListener,\n DBLockOptions,\n LockContext,\n Mutex,\n QueryResult,\n timeoutSignal,\n Transaction\n} from '@powersync/web';\nimport { PowerSyncCore } from '../plugin/PowerSyncCore.js';\nimport { messageForErrorCode } from '../plugin/PowerSyncPlugin.js';\nimport { CapacitorSQLiteOpenFactoryOptions, DEFAULT_SQLITE_OPTIONS } from './CapacitorSQLiteOpenFactory.js';\n/**\n * Monitors the execution time of a query and logs it to the performance timeline.\n */\nasync function monitorQuery(sql: string, executor: () => Promise<QueryResult>): Promise<QueryResult> {\n const start = performance.now();\n try {\n const r = await executor();\n performance.measure(`[SQL] ${sql}`, { start });\n return r;\n } catch (e: any) {\n performance.measure(`[SQL] [ERROR: ${e.message}] ${sql}`, { start });\n throw e;\n }\n}\n\nclass CapacitorConnectionPool extends BaseObserver<DBAdapterListener> implements ConnectionPool {\n protected _writeConnection: SQLiteDBConnection | null;\n protected _readConnection: SQLiteDBConnection | null;\n protected initializedPromise: Promise<void>;\n protected writeMutex: Mutex;\n protected readMutex: Mutex;\n\n constructor(protected options: CapacitorSQLiteOpenFactoryOptions) {\n super();\n this._writeConnection = null;\n this._readConnection = null;\n this.writeMutex = new Mutex();\n this.readMutex = new Mutex();\n this.initializedPromise = this.init();\n }\n\n protected get writeConnection(): SQLiteDBConnection {\n if (!this._writeConnection) {\n throw new Error('Init not completed yet');\n }\n return this._writeConnection;\n }\n\n protected get readConnection(): SQLiteDBConnection {\n if (!this._readConnection) {\n throw new Error('Init not completed yet');\n }\n return this._readConnection;\n }\n\n get name() {\n return this.options.dbFilename;\n }\n\n private async init() {\n const { responseCode: registrationResponseCode } = await PowerSyncCore.registerCore();\n if (registrationResponseCode != 0) {\n throw new Error(`Could not register PowerSync core extension: ${messageForErrorCode(registrationResponseCode)}`);\n }\n\n const sqlite = new SQLiteConnection(CapacitorSQLite);\n\n // It seems like the isConnection and retrieveConnection methods\n // only check a JS side map of connections.\n // On hot reload this JS cache can be cleared, while the connection\n // still exists natively. and `createConnection` will fail if it already exists.\n await sqlite.closeConnection(this.options.dbFilename, false).catch(() => {});\n await sqlite.closeConnection(this.options.dbFilename, true).catch(() => {});\n\n // TODO support encryption eventually\n this._writeConnection = await sqlite.createConnection(this.options.dbFilename, false, 'no-encryption', 1, false);\n this._readConnection = await sqlite.createConnection(this.options.dbFilename, false, 'no-encryption', 1, true);\n\n await this._writeConnection.open();\n\n const { cacheSizeKb, journalSizeLimit, synchronous } = { ...DEFAULT_SQLITE_OPTIONS, ...this.options.sqliteOptions };\n\n await this.writeConnection.query('PRAGMA journal_mode = WAL');\n await this.writeConnection.query(`PRAGMA journal_size_limit = ${journalSizeLimit}`);\n await this.writeConnection.query(`PRAGMA temp_store = memory`);\n await this.writeConnection.query(`PRAGMA synchronous = ${synchronous}`);\n await this.writeConnection.query(`PRAGMA cache_size = -${cacheSizeKb}`);\n\n await this._readConnection.open();\n\n const platform = Capacitor.getPlatform();\n if (platform == 'android') {\n /**\n * SQLCipher for Android enables dynamic loading of extensions.\n * On iOS we use a static auto extension registration.\n */\n const extensionQuery = \"SELECT load_extension('libpowersync.so', 'sqlite3_powersync_init')\";\n await this.writeConnection.query(extensionQuery);\n await this.readConnection.query(extensionQuery);\n }\n await this.writeConnection.query(\"SELECT powersync_update_hooks('install')\");\n }\n\n async close(): Promise<void> {\n await this.initializedPromise;\n await this.writeConnection.close();\n await this.readConnection.close();\n }\n\n protected generateLockContext(db: SQLiteDBConnection): LockContext {\n const _query = async (query: string, params: any[] = []) => {\n const result = await db.query(query, params);\n const arrayResult = result.values ?? [];\n return {\n rowsAffected: 0,\n rows: {\n _array: arrayResult,\n length: arrayResult.length,\n item: (idx: number) => arrayResult[idx]\n }\n };\n };\n\n const _execute = async (query: string, params: any[] = []): Promise<QueryResult> => {\n const platform = Capacitor.getPlatform();\n\n if (db.getConnectionReadOnly()) {\n return _query(query, params);\n }\n\n if (platform == 'android') {\n // Android: use query for SELECT and executeSet for mutations\n // We cannot use `run` here for both cases.\n if (query.toLowerCase().trim().startsWith('select')) {\n return _query(query, params);\n } else {\n const result = await db.executeSet([{ statement: query, values: params }], false);\n return {\n insertId: result.changes?.lastId,\n rowsAffected: result.changes?.changes ?? 0,\n rows: {\n _array: [],\n length: 0,\n item: () => null\n }\n };\n }\n }\n\n // iOS (and other platforms): use run(\"all\")\n const result = await db.run(query, params, false, 'all');\n const resultSet = result.changes?.values ?? [];\n return {\n insertId: result.changes?.lastId,\n rowsAffected: result.changes?.changes ?? 0,\n rows: {\n _array: resultSet,\n length: resultSet.length,\n item: (idx) => resultSet[idx]\n }\n };\n };\n\n const execute = this.options.debugMode\n ? (sql: string, params?: any[]) => monitorQuery(sql, () => _execute(sql, params))\n : _execute;\n\n const executeQuery = this.options.debugMode\n ? (sql: string, params?: any[]) => monitorQuery(sql, () => _query(sql, params))\n : _query;\n\n const getAll = async <T>(query: string, params?: any[]): Promise<T[]> => {\n const result = await executeQuery(query, params);\n return result.rows?._array ?? ([] as T[]);\n };\n\n const getOptional = async <T>(query: string, params?: any[]): Promise<T | null> => {\n const results = await getAll<T>(query, params);\n return results.length > 0 ? results[0] : null;\n };\n\n const get = async <T>(query: string, params?: any[]): Promise<T> => {\n const result = await getOptional<T>(query, params);\n if (!result) {\n throw new Error(`No results for query: ${query}`);\n }\n return result;\n };\n\n const executeRaw = async (query: string, params?: any[]): Promise<any[][]> => {\n // This is a workaround, we don't support multiple columns of the same name\n const results = await execute(query, params);\n return results.rows?._array.map((row) => Object.values(row)) ?? [];\n };\n\n const executeBatch = async (query: string, params: any[][] = []): Promise<QueryResult> => {\n let result = await db.executeSet(\n params.map((param) => ({\n statement: query,\n values: param\n }))\n );\n\n return {\n rowsAffected: result.changes?.changes ?? 0,\n insertId: result.changes?.lastId\n };\n };\n\n return {\n getAll,\n getOptional,\n get,\n executeRaw,\n execute,\n executeBatch\n };\n }\n\n readLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {\n return this.readMutex.runExclusive(async () => {\n await this.initializedPromise;\n return fn(this.generateLockContext(this.readConnection));\n }, timeoutSignal(options?.timeoutMs));\n }\n\n writeLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {\n return this.writeMutex.runExclusive(async () => {\n await this.initializedPromise;\n const result = await fn(this.generateLockContext(this.writeConnection));\n\n // Fetch table updates\n const updates = await this.writeConnection.query(\"SELECT powersync_update_hooks('get') AS table_name\");\n const jsonUpdates = updates.values?.[0];\n if (!jsonUpdates || !jsonUpdates.table_name) {\n throw new Error('Could not fetch table updates');\n }\n const notification: BatchedUpdateNotification = {\n rawUpdates: [],\n tables: JSON.parse(jsonUpdates.table_name),\n groupedUpdates: {}\n };\n this.iterateListeners((l) => l.tablesUpdated?.(notification));\n return result;\n }, timeoutSignal(options?.timeoutMs));\n }\n\n refreshSchema(): Promise<void> {\n return this.writeLock(async (writeTx) => {\n return this.readLock(async (readTx) => {\n const updateQuery = `PRAGMA table_info('sqlite_master')`;\n await writeTx.get(updateQuery);\n await readTx.get(updateQuery);\n });\n });\n }\n}\n\n/**\n * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).\n *\n * @experimental\n * @alpha This is currently experimental and may change without a major version bump.\n */\nexport class CapacitorSQLiteAdapter extends DBAdapterDefaultMixin(CapacitorConnectionPool) {}\n"]}
@@ -1,5 +1,4 @@
1
- import { AbstractStreamingSyncImplementation, LockType, mutexRunExclusive } from '@powersync/web';
2
- import { Mutex } from 'async-mutex';
1
+ import { AbstractStreamingSyncImplementation, LockType, Mutex } from '@powersync/web';
3
2
  const GLOBAL_MUTEX_STORE = new Map();
4
3
  /**
5
4
  * Used to identify multiple instances of CapacitorStreamingSyncImplementation
@@ -40,13 +39,9 @@ export class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncI
40
39
  const mutexRecord = GLOBAL_MUTEX_STORE.get(baseIdentifier);
41
40
  mutexRecord.tracking.add(this.instanceId);
42
41
  const mutex = mutexRecord.locks[lockOptions.type];
43
- return mutexRunExclusive(mutex, async () => {
44
- var _a;
45
- if ((_a = lockOptions.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
46
- throw new Error('Aborted');
47
- }
42
+ return mutex.runExclusive(async () => {
48
43
  return await lockOptions.callback();
49
- });
44
+ }, lockOptions.signal);
50
45
  }
51
46
  }
52
47
  //# sourceMappingURL=CapacitorSyncImplementation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CapacitorSyncImplementation.js","sourceRoot":"","sources":["../../../src/sync/CapacitorSyncImplementation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAe,QAAQ,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC/G,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAapC,MAAM,kBAAkB,GAA0B,IAAI,GAAG,EAAE,CAAC;AAE5D;;GAEG;AACH,IAAI,kCAAkC,GAAG,CAAC,CAAC;AAE3C,MAAM,OAAO,oCAAqC,SAAQ,mCAAmC;IAA7F;;QACE,yFAAyF;QAC/E,eAAU,GAAG,kCAAkC,EAAE,CAAC;IA0C9D,CAAC;IAxCC,KAAK,CAAC,OAAO;QACX,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QAEtB,wDAAwD;QACxD,KAAK,MAAM,UAAU,IAAI,kBAAkB,CAAC,OAAO,EAAE,EAAE,CAAC;YACtD,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzC,SAAS;YACX,CAAC;YACD,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;gBAC7B,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAI,WAA2B;QAC7C,4FAA4F;QAC5F,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAChE,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YAC5C,kBAAkB,CAAC,GAAG,CAAC,cAAc,EAAE;gBACrC,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACpC,KAAK,EAAE;oBACL,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,EAAE;oBAC5B,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,EAAE;iBAC7B;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,cAAc,CAAE,CAAC;QAC5D,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAElD,OAAO,iBAAiB,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE;;YACzC,IAAI,MAAA,WAAW,CAAC,MAAM,0CAAE,OAAO,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;YAC7B,CAAC;YACD,OAAO,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["import { AbstractStreamingSyncImplementation, LockOptions, LockType, mutexRunExclusive } from '@powersync/web';\nimport { Mutex } from 'async-mutex';\n\ntype MutexMap = {\n /**\n * Used to track the consumers of this Mutex.\n * It should be safe to dispose the Mutex if this is empty.\n */\n tracking: Set<number>;\n locks: {\n [Type in LockType]: Mutex;\n };\n};\n\nconst GLOBAL_MUTEX_STORE: Map<string, MutexMap> = new Map();\n\n/**\n * Used to identify multiple instances of CapacitorStreamingSyncImplementation\n */\nlet _CAPACITOR_STREAMING_SYNC_SEQUENCE = 0;\n\nexport class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncImplementation {\n // A unique ID for tacking this specific instance of CapacitorStreamingSyncImplementation\n protected instanceId = _CAPACITOR_STREAMING_SYNC_SEQUENCE++;\n\n async dispose(): Promise<void> {\n await super.dispose();\n\n // Clear up any global mutexes which aren't used anymore\n for (const mutexEntry of GLOBAL_MUTEX_STORE.entries()) {\n const [identifier, mutex] = mutexEntry;\n if (!mutex.tracking.has(this.instanceId)) {\n continue;\n }\n mutex.tracking.delete(this.instanceId);\n if (mutex.tracking.size == 0) {\n GLOBAL_MUTEX_STORE.delete(identifier);\n }\n }\n }\n\n async obtainLock<T>(lockOptions: LockOptions<T>): Promise<T> {\n // If we don't have an identifier for some reason (should not happen), we use a shared Mutex\n const { identifier: baseIdentifier = 'DEFAULT' } = this.options;\n if (!GLOBAL_MUTEX_STORE.has(baseIdentifier)) {\n GLOBAL_MUTEX_STORE.set(baseIdentifier, {\n tracking: new Set([this.instanceId]),\n locks: {\n [LockType.CRUD]: new Mutex(),\n [LockType.SYNC]: new Mutex()\n }\n });\n }\n\n const mutexRecord = GLOBAL_MUTEX_STORE.get(baseIdentifier)!;\n mutexRecord.tracking.add(this.instanceId);\n const mutex = mutexRecord.locks[lockOptions.type];\n\n return mutexRunExclusive(mutex, async () => {\n if (lockOptions.signal?.aborted) {\n throw new Error('Aborted');\n }\n return await lockOptions.callback();\n });\n }\n}\n"]}
1
+ {"version":3,"file":"CapacitorSyncImplementation.js","sourceRoot":"","sources":["../../../src/sync/CapacitorSyncImplementation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAe,QAAQ,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAanG,MAAM,kBAAkB,GAA0B,IAAI,GAAG,EAAE,CAAC;AAE5D;;GAEG;AACH,IAAI,kCAAkC,GAAG,CAAC,CAAC;AAE3C,MAAM,OAAO,oCAAqC,SAAQ,mCAAmC;IAA7F;;QACE,yFAAyF;QAC/E,eAAU,GAAG,kCAAkC,EAAE,CAAC;IAuC9D,CAAC;IArCC,KAAK,CAAC,OAAO;QACX,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QAEtB,wDAAwD;QACxD,KAAK,MAAM,UAAU,IAAI,kBAAkB,CAAC,OAAO,EAAE,EAAE,CAAC;YACtD,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACzC,SAAS;YACX,CAAC;YACD,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;gBAC7B,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAI,WAA2B;QAC7C,4FAA4F;QAC5F,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAChE,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YAC5C,kBAAkB,CAAC,GAAG,CAAC,cAAc,EAAE;gBACrC,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACpC,KAAK,EAAE;oBACL,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,EAAE;oBAC5B,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,EAAE;iBAC7B;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,cAAc,CAAE,CAAC;QAC5D,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAElD,OAAO,KAAK,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YACnC,OAAO,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;QACtC,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;CACF","sourcesContent":["import { AbstractStreamingSyncImplementation, LockOptions, LockType, Mutex } from '@powersync/web';\n\ntype MutexMap = {\n /**\n * Used to track the consumers of this Mutex.\n * It should be safe to dispose the Mutex if this is empty.\n */\n tracking: Set<number>;\n locks: {\n [Type in LockType]: Mutex;\n };\n};\n\nconst GLOBAL_MUTEX_STORE: Map<string, MutexMap> = new Map();\n\n/**\n * Used to identify multiple instances of CapacitorStreamingSyncImplementation\n */\nlet _CAPACITOR_STREAMING_SYNC_SEQUENCE = 0;\n\nexport class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncImplementation {\n // A unique ID for tacking this specific instance of CapacitorStreamingSyncImplementation\n protected instanceId = _CAPACITOR_STREAMING_SYNC_SEQUENCE++;\n\n async dispose(): Promise<void> {\n await super.dispose();\n\n // Clear up any global mutexes which aren't used anymore\n for (const mutexEntry of GLOBAL_MUTEX_STORE.entries()) {\n const [identifier, mutex] = mutexEntry;\n if (!mutex.tracking.has(this.instanceId)) {\n continue;\n }\n mutex.tracking.delete(this.instanceId);\n if (mutex.tracking.size == 0) {\n GLOBAL_MUTEX_STORE.delete(identifier);\n }\n }\n }\n\n async obtainLock<T>(lockOptions: LockOptions<T>): Promise<T> {\n // If we don't have an identifier for some reason (should not happen), we use a shared Mutex\n const { identifier: baseIdentifier = 'DEFAULT' } = this.options;\n if (!GLOBAL_MUTEX_STORE.has(baseIdentifier)) {\n GLOBAL_MUTEX_STORE.set(baseIdentifier, {\n tracking: new Set([this.instanceId]),\n locks: {\n [LockType.CRUD]: new Mutex(),\n [LockType.SYNC]: new Mutex()\n }\n });\n }\n\n const mutexRecord = GLOBAL_MUTEX_STORE.get(baseIdentifier)!;\n mutexRecord.tracking.add(this.instanceId);\n const mutex = mutexRecord.locks[lockOptions.type];\n\n return mutex.runExclusive(async () => {\n return await lockOptions.callback();\n }, lockOptions.signal);\n }\n}\n"]}
package/dist/plugin.cjs CHANGED
@@ -3,7 +3,6 @@
3
3
  var sqlite = require('@capacitor-community/sqlite');
4
4
  var core = require('@capacitor/core');
5
5
  var web$1 = require('@powersync/web');
6
- var asyncMutex = require('async-mutex');
7
6
 
8
7
  const PowerSyncCore = core.registerPlugin('PowerSync', {
9
8
  web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.PowerSyncWeb())
@@ -53,20 +52,14 @@ async function monitorQuery(sql, executor) {
53
52
  throw e;
54
53
  }
55
54
  }
56
- /**
57
- * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).
58
- *
59
- * @experimental
60
- * @alpha This is currently experimental and may change without a major version bump.
61
- */
62
- class CapacitorSQLiteAdapter extends web$1.BaseObserver {
55
+ class CapacitorConnectionPool extends web$1.BaseObserver {
63
56
  constructor(options) {
64
57
  super();
65
58
  this.options = options;
66
59
  this._writeConnection = null;
67
60
  this._readConnection = null;
68
- this.writeMutex = new asyncMutex.Mutex();
69
- this.readMutex = new asyncMutex.Mutex();
61
+ this.writeMutex = new web$1.Mutex();
62
+ this.readMutex = new web$1.Mutex();
70
63
  this.initializedPromise = this.init();
71
64
  }
72
65
  get writeConnection() {
@@ -204,24 +197,9 @@ class CapacitorSQLiteAdapter extends web$1.BaseObserver {
204
197
  const results = await execute(query, params);
205
198
  return (_b = (_a = results.rows) === null || _a === void 0 ? void 0 : _a._array.map((row) => Object.values(row))) !== null && _b !== void 0 ? _b : [];
206
199
  };
207
- return {
208
- getAll,
209
- getOptional,
210
- get,
211
- executeRaw,
212
- execute
213
- };
214
- }
215
- execute(query, params) {
216
- return this.writeLock((tx) => tx.execute(query, params));
217
- }
218
- executeRaw(query, params) {
219
- return this.writeLock((tx) => tx.executeRaw(query, params));
220
- }
221
- async executeBatch(query, params = []) {
222
- return this.writeLock(async (tx) => {
200
+ const executeBatch = async (query, params = []) => {
223
201
  var _a, _b, _c;
224
- let result = await this.writeConnection.executeSet(params.map((param) => ({
202
+ let result = await db.executeSet(params.map((param) => ({
225
203
  statement: query,
226
204
  values: param
227
205
  })));
@@ -229,21 +207,24 @@ class CapacitorSQLiteAdapter extends web$1.BaseObserver {
229
207
  rowsAffected: (_b = (_a = result.changes) === null || _a === void 0 ? void 0 : _a.changes) !== null && _b !== void 0 ? _b : 0,
230
208
  insertId: (_c = result.changes) === null || _c === void 0 ? void 0 : _c.lastId
231
209
  };
232
- });
210
+ };
211
+ return {
212
+ getAll,
213
+ getOptional,
214
+ get,
215
+ executeRaw,
216
+ execute,
217
+ executeBatch
218
+ };
233
219
  }
234
220
  readLock(fn, options) {
235
- return web$1.mutexRunExclusive(this.readMutex, async () => {
221
+ return this.readMutex.runExclusive(async () => {
236
222
  await this.initializedPromise;
237
- return await fn(this.generateLockContext(this.readConnection));
238
- }, options);
239
- }
240
- readTransaction(fn, options) {
241
- return this.readLock(async (ctx) => {
242
- return this.internalTransaction(ctx, fn);
243
- });
223
+ return fn(this.generateLockContext(this.readConnection));
224
+ }, web$1.timeoutSignal(options === null || options === void 0 ? void 0 : options.timeoutMs));
244
225
  }
245
226
  writeLock(fn, options) {
246
- return web$1.mutexRunExclusive(this.writeMutex, async () => {
227
+ return this.writeMutex.runExclusive(async () => {
247
228
  var _a;
248
229
  await this.initializedPromise;
249
230
  const result = await fn(this.generateLockContext(this.writeConnection));
@@ -260,12 +241,7 @@ class CapacitorSQLiteAdapter extends web$1.BaseObserver {
260
241
  };
261
242
  this.iterateListeners((l) => { var _a; return (_a = l.tablesUpdated) === null || _a === void 0 ? void 0 : _a.call(l, notification); });
262
243
  return result;
263
- }, options);
264
- }
265
- writeTransaction(fn, options) {
266
- return this.writeLock(async (ctx) => {
267
- return this.internalTransaction(ctx, fn);
268
- });
244
+ }, web$1.timeoutSignal(options === null || options === void 0 ? void 0 : options.timeoutMs));
269
245
  }
270
246
  refreshSchema() {
271
247
  return this.writeLock(async (writeTx) => {
@@ -276,49 +252,14 @@ class CapacitorSQLiteAdapter extends web$1.BaseObserver {
276
252
  });
277
253
  });
278
254
  }
279
- getAll(sql, parameters) {
280
- return this.readLock((tx) => tx.getAll(sql, parameters));
281
- }
282
- getOptional(sql, parameters) {
283
- return this.readLock((tx) => tx.getOptional(sql, parameters));
284
- }
285
- get(sql, parameters) {
286
- return this.readLock((tx) => tx.get(sql, parameters));
287
- }
288
- async internalTransaction(ctx, fn) {
289
- let finalized = false;
290
- const commit = async () => {
291
- if (finalized) {
292
- return { rowsAffected: 0 };
293
- }
294
- finalized = true;
295
- return ctx.execute('COMMIT');
296
- };
297
- const rollback = async () => {
298
- if (finalized) {
299
- return { rowsAffected: 0 };
300
- }
301
- finalized = true;
302
- return ctx.execute('ROLLBACK');
303
- };
304
- try {
305
- await ctx.execute('BEGIN');
306
- const result = await fn(Object.assign(Object.assign({}, ctx), { commit,
307
- rollback }));
308
- await commit();
309
- return result;
310
- }
311
- catch (ex) {
312
- try {
313
- await rollback();
314
- }
315
- catch (ex2) {
316
- // In rare cases, a rollback may fail.
317
- // Safe to ignore.
318
- }
319
- throw ex;
320
- }
321
- }
255
+ }
256
+ /**
257
+ * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).
258
+ *
259
+ * @experimental
260
+ * @alpha This is currently experimental and may change without a major version bump.
261
+ */
262
+ class CapacitorSQLiteAdapter extends web$1.DBAdapterDefaultMixin(CapacitorConnectionPool) {
322
263
  }
323
264
 
324
265
  const GLOBAL_MUTEX_STORE = new Map();
@@ -353,21 +294,17 @@ class CapacitorStreamingSyncImplementation extends web$1.AbstractStreamingSyncIm
353
294
  GLOBAL_MUTEX_STORE.set(baseIdentifier, {
354
295
  tracking: new Set([this.instanceId]),
355
296
  locks: {
356
- [web$1.LockType.CRUD]: new asyncMutex.Mutex(),
357
- [web$1.LockType.SYNC]: new asyncMutex.Mutex()
297
+ [web$1.LockType.CRUD]: new web$1.Mutex(),
298
+ [web$1.LockType.SYNC]: new web$1.Mutex()
358
299
  }
359
300
  });
360
301
  }
361
302
  const mutexRecord = GLOBAL_MUTEX_STORE.get(baseIdentifier);
362
303
  mutexRecord.tracking.add(this.instanceId);
363
304
  const mutex = mutexRecord.locks[lockOptions.type];
364
- return web$1.mutexRunExclusive(mutex, async () => {
365
- var _a;
366
- if ((_a = lockOptions.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
367
- throw new Error('Aborted');
368
- }
305
+ return mutex.runExclusive(async () => {
369
306
  return await lockOptions.callback();
370
- });
307
+ }, lockOptions.signal);
371
308
  }
372
309
  }
373
310