@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.
- package/dist/esm/adapter/CapacitorSQLiteAdapter.d.ts +24 -15
- package/dist/esm/adapter/CapacitorSQLiteAdapter.js +26 -85
- package/dist/esm/adapter/CapacitorSQLiteAdapter.js.map +1 -1
- package/dist/esm/sync/CapacitorSyncImplementation.js +3 -8
- package/dist/esm/sync/CapacitorSyncImplementation.js.map +1 -1
- package/dist/plugin.cjs +31 -94
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +23 -15
- package/dist/plugin.js +33 -95
- package/dist/plugin.js.map +1 -1
- package/package.json +2 -5
- package/src/adapter/CapacitorSQLiteAdapter.ts +48 -120
- package/src/sync/CapacitorSyncImplementation.ts +3 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powersync/capacitor",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Adds PowerSync Capacitor support for iOS/Android",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"@capacitor-community/sqlite": "^7.0.2",
|
|
70
|
-
"@powersync/web": "^1.
|
|
70
|
+
"@powersync/web": "^1.37.0"
|
|
71
71
|
},
|
|
72
72
|
"swiftlint": "@ionic/swiftlint-config",
|
|
73
73
|
"capacitor": {
|
|
@@ -80,9 +80,6 @@
|
|
|
80
80
|
"src": "android"
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
|
-
"dependencies": {
|
|
84
|
-
"async-mutex": "^0.5.0"
|
|
85
|
-
},
|
|
86
83
|
"scripts": {
|
|
87
84
|
"verify": "pnpm verify:ios && pnpm verify:android && pnpm verify:web",
|
|
88
85
|
"verify:ios": "cd example-app && npm install && cd ios/App && pod install && xcodebuild -workspace App.xcworkspace -scheme App -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest'",
|
|
@@ -4,15 +4,17 @@ import { Capacitor } from '@capacitor/core';
|
|
|
4
4
|
import {
|
|
5
5
|
BaseObserver,
|
|
6
6
|
BatchedUpdateNotification,
|
|
7
|
+
ConnectionPool,
|
|
7
8
|
DBAdapter,
|
|
9
|
+
DBAdapterDefaultMixin,
|
|
8
10
|
DBAdapterListener,
|
|
9
11
|
DBLockOptions,
|
|
10
12
|
LockContext,
|
|
11
|
-
|
|
13
|
+
Mutex,
|
|
12
14
|
QueryResult,
|
|
15
|
+
timeoutSignal,
|
|
13
16
|
Transaction
|
|
14
17
|
} from '@powersync/web';
|
|
15
|
-
import { Mutex } from 'async-mutex';
|
|
16
18
|
import { PowerSyncCore } from '../plugin/PowerSyncCore.js';
|
|
17
19
|
import { messageForErrorCode } from '../plugin/PowerSyncPlugin.js';
|
|
18
20
|
import { CapacitorSQLiteOpenFactoryOptions, DEFAULT_SQLITE_OPTIONS } from './CapacitorSQLiteOpenFactory.js';
|
|
@@ -30,13 +32,8 @@ async function monitorQuery(sql: string, executor: () => Promise<QueryResult>):
|
|
|
30
32
|
throw e;
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
* @experimental
|
|
37
|
-
* @alpha This is currently experimental and may change without a major version bump.
|
|
38
|
-
*/
|
|
39
|
-
export class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> implements DBAdapter {
|
|
35
|
+
|
|
36
|
+
class CapacitorConnectionPool extends BaseObserver<DBAdapterListener> implements ConnectionPool {
|
|
40
37
|
protected _writeConnection: SQLiteDBConnection | null;
|
|
41
38
|
protected _readConnection: SQLiteDBConnection | null;
|
|
42
39
|
protected initializedPromise: Promise<void>;
|
|
@@ -206,26 +203,8 @@ export class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> impl
|
|
|
206
203
|
return results.rows?._array.map((row) => Object.values(row)) ?? [];
|
|
207
204
|
};
|
|
208
205
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
getOptional,
|
|
212
|
-
get,
|
|
213
|
-
executeRaw,
|
|
214
|
-
execute
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
execute(query: string, params?: any[]): Promise<QueryResult> {
|
|
219
|
-
return this.writeLock((tx) => tx.execute(query, params));
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
executeRaw(query: string, params?: any[]): Promise<any[][]> {
|
|
223
|
-
return this.writeLock((tx) => tx.executeRaw(query, params));
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
async executeBatch(query: string, params: any[][] = []): Promise<QueryResult> {
|
|
227
|
-
return this.writeLock(async (tx) => {
|
|
228
|
-
let result = await this.writeConnection.executeSet(
|
|
206
|
+
const executeBatch = async (query: string, params: any[][] = []): Promise<QueryResult> => {
|
|
207
|
+
let result = await db.executeSet(
|
|
229
208
|
params.map((param) => ({
|
|
230
209
|
statement: query,
|
|
231
210
|
values: param
|
|
@@ -236,55 +215,44 @@ export class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> impl
|
|
|
236
215
|
rowsAffected: result.changes?.changes ?? 0,
|
|
237
216
|
insertId: result.changes?.lastId
|
|
238
217
|
};
|
|
239
|
-
}
|
|
240
|
-
}
|
|
218
|
+
};
|
|
241
219
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
);
|
|
220
|
+
return {
|
|
221
|
+
getAll,
|
|
222
|
+
getOptional,
|
|
223
|
+
get,
|
|
224
|
+
executeRaw,
|
|
225
|
+
execute,
|
|
226
|
+
executeBatch
|
|
227
|
+
};
|
|
251
228
|
}
|
|
252
229
|
|
|
253
|
-
|
|
254
|
-
return this.
|
|
255
|
-
|
|
256
|
-
|
|
230
|
+
readLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
231
|
+
return this.readMutex.runExclusive(async () => {
|
|
232
|
+
await this.initializedPromise;
|
|
233
|
+
return fn(this.generateLockContext(this.readConnection));
|
|
234
|
+
}, timeoutSignal(options?.timeoutMs));
|
|
257
235
|
}
|
|
258
236
|
|
|
259
237
|
writeLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
260
|
-
return
|
|
261
|
-
this.
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
return result;
|
|
279
|
-
},
|
|
280
|
-
options
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
writeTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
285
|
-
return this.writeLock(async (ctx) => {
|
|
286
|
-
return this.internalTransaction(ctx, fn);
|
|
287
|
-
});
|
|
238
|
+
return this.writeMutex.runExclusive(async () => {
|
|
239
|
+
await this.initializedPromise;
|
|
240
|
+
const result = await fn(this.generateLockContext(this.writeConnection));
|
|
241
|
+
|
|
242
|
+
// Fetch table updates
|
|
243
|
+
const updates = await this.writeConnection.query("SELECT powersync_update_hooks('get') AS table_name");
|
|
244
|
+
const jsonUpdates = updates.values?.[0];
|
|
245
|
+
if (!jsonUpdates || !jsonUpdates.table_name) {
|
|
246
|
+
throw new Error('Could not fetch table updates');
|
|
247
|
+
}
|
|
248
|
+
const notification: BatchedUpdateNotification = {
|
|
249
|
+
rawUpdates: [],
|
|
250
|
+
tables: JSON.parse(jsonUpdates.table_name),
|
|
251
|
+
groupedUpdates: {}
|
|
252
|
+
};
|
|
253
|
+
this.iterateListeners((l) => l.tablesUpdated?.(notification));
|
|
254
|
+
return result;
|
|
255
|
+
}, timeoutSignal(options?.timeoutMs));
|
|
288
256
|
}
|
|
289
257
|
|
|
290
258
|
refreshSchema(): Promise<void> {
|
|
@@ -296,52 +264,12 @@ export class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> impl
|
|
|
296
264
|
});
|
|
297
265
|
});
|
|
298
266
|
}
|
|
299
|
-
|
|
300
|
-
getAll<T>(sql: string, parameters?: any[]): Promise<T[]> {
|
|
301
|
-
return this.readLock((tx) => tx.getAll<T>(sql, parameters));
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
getOptional<T>(sql: string, parameters?: any[]): Promise<T | null> {
|
|
305
|
-
return this.readLock((tx) => tx.getOptional<T>(sql, parameters));
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
get<T>(sql: string, parameters?: any[]): Promise<T> {
|
|
309
|
-
return this.readLock((tx) => tx.get<T>(sql, parameters));
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
protected async internalTransaction<T>(ctx: LockContext, fn: (tx: Transaction) => Promise<T>): Promise<T> {
|
|
313
|
-
let finalized = false;
|
|
314
|
-
const commit = async (): Promise<QueryResult> => {
|
|
315
|
-
if (finalized) {
|
|
316
|
-
return { rowsAffected: 0 };
|
|
317
|
-
}
|
|
318
|
-
finalized = true;
|
|
319
|
-
return ctx.execute('COMMIT');
|
|
320
|
-
};
|
|
321
|
-
const rollback = async (): Promise<QueryResult> => {
|
|
322
|
-
if (finalized) {
|
|
323
|
-
return { rowsAffected: 0 };
|
|
324
|
-
}
|
|
325
|
-
finalized = true;
|
|
326
|
-
return ctx.execute('ROLLBACK');
|
|
327
|
-
};
|
|
328
|
-
try {
|
|
329
|
-
await ctx.execute('BEGIN');
|
|
330
|
-
const result = await fn({
|
|
331
|
-
...ctx,
|
|
332
|
-
commit,
|
|
333
|
-
rollback
|
|
334
|
-
});
|
|
335
|
-
await commit();
|
|
336
|
-
return result;
|
|
337
|
-
} catch (ex) {
|
|
338
|
-
try {
|
|
339
|
-
await rollback();
|
|
340
|
-
} catch (ex2) {
|
|
341
|
-
// In rare cases, a rollback may fail.
|
|
342
|
-
// Safe to ignore.
|
|
343
|
-
}
|
|
344
|
-
throw ex;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
267
|
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).
|
|
271
|
+
*
|
|
272
|
+
* @experimental
|
|
273
|
+
* @alpha This is currently experimental and may change without a major version bump.
|
|
274
|
+
*/
|
|
275
|
+
export class CapacitorSQLiteAdapter extends DBAdapterDefaultMixin(CapacitorConnectionPool) {}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { AbstractStreamingSyncImplementation, LockOptions, LockType,
|
|
2
|
-
import { Mutex } from 'async-mutex';
|
|
1
|
+
import { AbstractStreamingSyncImplementation, LockOptions, LockType, Mutex } from '@powersync/web';
|
|
3
2
|
|
|
4
3
|
type MutexMap = {
|
|
5
4
|
/**
|
|
@@ -56,11 +55,8 @@ export class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncI
|
|
|
56
55
|
mutexRecord.tracking.add(this.instanceId);
|
|
57
56
|
const mutex = mutexRecord.locks[lockOptions.type];
|
|
58
57
|
|
|
59
|
-
return
|
|
60
|
-
if (lockOptions.signal?.aborted) {
|
|
61
|
-
throw new Error('Aborted');
|
|
62
|
-
}
|
|
58
|
+
return mutex.runExclusive(async () => {
|
|
63
59
|
return await lockOptions.callback();
|
|
64
|
-
});
|
|
60
|
+
}, lockOptions.signal);
|
|
65
61
|
}
|
|
66
62
|
}
|