@powersync/capacitor 0.0.0-dev-20260128023420 → 0.0.0-dev-20260202162549
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/package.json +5 -5
- package/src/PowerSyncDatabase.ts +14 -0
- package/src/adapter/CapacitorSQLiteAdapter.ts +36 -25
- package/src/sync/CapacitorSyncImplementation.ts +55 -5
- package/dist/docs.json +0 -39
- package/dist/esm/PowerSyncDatabase.d.ts +0 -15
- package/dist/esm/PowerSyncDatabase.js +0 -68
- package/dist/esm/PowerSyncDatabase.js.map +0 -1
- package/dist/esm/adapter/CapacitorSQLiteAdapter.d.ts +0 -36
- package/dist/esm/adapter/CapacitorSQLiteAdapter.js +0 -289
- package/dist/esm/adapter/CapacitorSQLiteAdapter.js.map +0 -1
- package/dist/esm/adapter/CapacitorSQLiteOpenFactory.d.ts +0 -35
- package/dist/esm/adapter/CapacitorSQLiteOpenFactory.js +0 -21
- package/dist/esm/adapter/CapacitorSQLiteOpenFactory.js.map +0 -1
- package/dist/esm/index.d.ts +0 -3
- package/dist/esm/index.js +0 -4
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/plugin/PowerSyncCore.d.ts +0 -2
- package/dist/esm/plugin/PowerSyncCore.js +0 -5
- package/dist/esm/plugin/PowerSyncCore.js.map +0 -1
- package/dist/esm/plugin/PowerSyncPlugin.d.ts +0 -13
- package/dist/esm/plugin/PowerSyncPlugin.js +0 -9
- package/dist/esm/plugin/PowerSyncPlugin.js.map +0 -1
- package/dist/esm/plugin/web.d.ts +0 -5
- package/dist/esm/plugin/web.js +0 -7
- package/dist/esm/plugin/web.js.map +0 -1
- package/dist/esm/sync/CapacitorSyncImplementation.d.ts +0 -6
- package/dist/esm/sync/CapacitorSyncImplementation.js +0 -16
- package/dist/esm/sync/CapacitorSyncImplementation.js.map +0 -1
- package/dist/plugin.cjs +0 -415
- package/dist/plugin.cjs.map +0 -1
- package/dist/plugin.d.cts +0 -86
- package/dist/plugin.js +0 -415
- package/dist/plugin.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powersync/capacitor",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20260202162549",
|
|
4
4
|
"description": "Adds PowerSync Capacitor support for iOS/Android",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -58,16 +58,16 @@
|
|
|
58
58
|
"@ionic/prettier-config": "^4.0.0",
|
|
59
59
|
"@ionic/swiftlint-config": "^2.0.0",
|
|
60
60
|
"eslint": "^8.57.0",
|
|
61
|
-
"prettier": "^3.4
|
|
61
|
+
"prettier": "^3.7.4",
|
|
62
62
|
"prettier-plugin-java": "^2.6.6",
|
|
63
63
|
"rimraf": "^6.0.1",
|
|
64
|
-
"rollup": "^4.
|
|
64
|
+
"rollup": "^4.52.5",
|
|
65
65
|
"rollup-plugin-dts": "^6.2.1",
|
|
66
66
|
"swiftlint": "^2.0.0"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"@capacitor-community/sqlite": "^7.0.2",
|
|
70
|
-
"@powersync/web": "0.0.0-dev-
|
|
70
|
+
"@powersync/web": "0.0.0-dev-20260202162549"
|
|
71
71
|
},
|
|
72
72
|
"swiftlint": "@ionic/swiftlint-config",
|
|
73
73
|
"capacitor": {
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"async-
|
|
84
|
+
"async-mutex": "^0.5.0"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"verify": "pnpm verify:ios && pnpm verify:android && pnpm verify:web",
|
package/src/PowerSyncDatabase.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Capacitor } from '@capacitor/core';
|
|
2
2
|
import {
|
|
3
3
|
DBAdapter,
|
|
4
|
+
MEMORY_TRIGGER_CLAIM_MANAGER,
|
|
4
5
|
PowerSyncBackendConnector,
|
|
5
6
|
RequiredAdditionalConnectionOptions,
|
|
6
7
|
StreamingSyncImplementation,
|
|
8
|
+
TriggerManagerConfig,
|
|
7
9
|
PowerSyncDatabase as WebPowerSyncDatabase,
|
|
8
10
|
WebPowerSyncDatabaseOptionsWithSettings,
|
|
9
11
|
WebRemote
|
|
@@ -44,6 +46,18 @@ export class PowerSyncDatabase extends WebPowerSyncDatabase {
|
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
protected generateTriggerManagerConfig(): TriggerManagerConfig {
|
|
50
|
+
const config = super.generateTriggerManagerConfig();
|
|
51
|
+
if (this.isNativeCapacitorPlatform) {
|
|
52
|
+
/**
|
|
53
|
+
* We usually only ever have a single tab for capacitor.
|
|
54
|
+
* Avoiding navigator locks allows insecure contexts (during development).
|
|
55
|
+
*/
|
|
56
|
+
config.claimManager = MEMORY_TRIGGER_CLAIM_MANAGER;
|
|
57
|
+
}
|
|
58
|
+
return config;
|
|
59
|
+
}
|
|
60
|
+
|
|
47
61
|
protected runExclusive<T>(cb: () => Promise<T>): Promise<T> {
|
|
48
62
|
if (this.isNativeCapacitorPlatform) {
|
|
49
63
|
// Use mutex for mobile platforms.
|
|
@@ -8,10 +8,11 @@ import {
|
|
|
8
8
|
DBAdapterListener,
|
|
9
9
|
DBLockOptions,
|
|
10
10
|
LockContext,
|
|
11
|
+
mutexRunExclusive,
|
|
11
12
|
QueryResult,
|
|
12
13
|
Transaction
|
|
13
14
|
} from '@powersync/web';
|
|
14
|
-
import
|
|
15
|
+
import { Mutex } from 'async-mutex';
|
|
15
16
|
import { PowerSyncCore } from '../plugin/PowerSyncCore.js';
|
|
16
17
|
import { messageForErrorCode } from '../plugin/PowerSyncPlugin.js';
|
|
17
18
|
import { CapacitorSQLiteOpenFactoryOptions, DEFAULT_SQLITE_OPTIONS } from './CapacitorSQLiteOpenFactory.js';
|
|
@@ -39,13 +40,15 @@ export class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> impl
|
|
|
39
40
|
protected _writeConnection: SQLiteDBConnection | null;
|
|
40
41
|
protected _readConnection: SQLiteDBConnection | null;
|
|
41
42
|
protected initializedPromise: Promise<void>;
|
|
42
|
-
protected
|
|
43
|
+
protected writeMutex: Mutex;
|
|
44
|
+
protected readMutex: Mutex;
|
|
43
45
|
|
|
44
46
|
constructor(protected options: CapacitorSQLiteOpenFactoryOptions) {
|
|
45
47
|
super();
|
|
46
48
|
this._writeConnection = null;
|
|
47
49
|
this._readConnection = null;
|
|
48
|
-
this.
|
|
50
|
+
this.writeMutex = new Mutex();
|
|
51
|
+
this.readMutex = new Mutex();
|
|
49
52
|
this.initializedPromise = this.init();
|
|
50
53
|
}
|
|
51
54
|
|
|
@@ -237,10 +240,14 @@ export class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> impl
|
|
|
237
240
|
}
|
|
238
241
|
|
|
239
242
|
readLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
240
|
-
return
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
243
|
+
return mutexRunExclusive(
|
|
244
|
+
this.readMutex,
|
|
245
|
+
async () => {
|
|
246
|
+
await this.initializedPromise;
|
|
247
|
+
return await fn(this.generateLockContext(this.readConnection));
|
|
248
|
+
},
|
|
249
|
+
options
|
|
250
|
+
);
|
|
244
251
|
}
|
|
245
252
|
|
|
246
253
|
readTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
@@ -250,24 +257,28 @@ export class CapacitorSQLiteAdapter extends BaseObserver<DBAdapterListener> impl
|
|
|
250
257
|
}
|
|
251
258
|
|
|
252
259
|
writeLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
253
|
-
return
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
260
|
+
return mutexRunExclusive(
|
|
261
|
+
this.writeMutex,
|
|
262
|
+
async () => {
|
|
263
|
+
await this.initializedPromise;
|
|
264
|
+
const result = await fn(this.generateLockContext(this.writeConnection));
|
|
265
|
+
|
|
266
|
+
// Fetch table updates
|
|
267
|
+
const updates = await this.writeConnection.query("SELECT powersync_update_hooks('get') AS table_name");
|
|
268
|
+
const jsonUpdates = updates.values?.[0];
|
|
269
|
+
if (!jsonUpdates || !jsonUpdates.table_name) {
|
|
270
|
+
throw new Error('Could not fetch table updates');
|
|
271
|
+
}
|
|
272
|
+
const notification: BatchedUpdateNotification = {
|
|
273
|
+
rawUpdates: [],
|
|
274
|
+
tables: JSON.parse(jsonUpdates.table_name),
|
|
275
|
+
groupedUpdates: {}
|
|
276
|
+
};
|
|
277
|
+
this.iterateListeners((l) => l.tablesUpdated?.(notification));
|
|
278
|
+
return result;
|
|
279
|
+
},
|
|
280
|
+
options
|
|
281
|
+
);
|
|
271
282
|
}
|
|
272
283
|
|
|
273
284
|
writeTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {
|
|
@@ -1,12 +1,62 @@
|
|
|
1
|
-
import { AbstractStreamingSyncImplementation, LockOptions } from '@powersync/web';
|
|
2
|
-
import
|
|
1
|
+
import { AbstractStreamingSyncImplementation, LockOptions, LockType, mutexRunExclusive } from '@powersync/web';
|
|
2
|
+
import { Mutex } from 'async-mutex';
|
|
3
|
+
|
|
4
|
+
type MutexMap = {
|
|
5
|
+
/**
|
|
6
|
+
* Used to track the consumers of this Mutex.
|
|
7
|
+
* It should be safe to dispose the Mutex if this is empty.
|
|
8
|
+
*/
|
|
9
|
+
tracking: Set<number>;
|
|
10
|
+
locks: {
|
|
11
|
+
[Type in LockType]: Mutex;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const GLOBAL_MUTEX_STORE: Map<string, MutexMap> = new Map();
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Used to identify multiple instances of CapacitorStreamingSyncImplementation
|
|
19
|
+
*/
|
|
20
|
+
let _CAPACITOR_STREAMING_SYNC_SEQUENCE = 0;
|
|
3
21
|
|
|
4
22
|
export class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncImplementation {
|
|
5
|
-
|
|
23
|
+
// A unique ID for tacking this specific instance of CapacitorStreamingSyncImplementation
|
|
24
|
+
protected instanceId = _CAPACITOR_STREAMING_SYNC_SEQUENCE++;
|
|
25
|
+
|
|
26
|
+
async dispose(): Promise<void> {
|
|
27
|
+
await super.dispose();
|
|
28
|
+
|
|
29
|
+
// Clear up any global mutexes which aren't used anymore
|
|
30
|
+
for (const mutexEntry of GLOBAL_MUTEX_STORE.entries()) {
|
|
31
|
+
const [identifier, mutex] = mutexEntry;
|
|
32
|
+
if (!mutex.tracking.has(this.instanceId)) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
mutex.tracking.delete(this.instanceId);
|
|
36
|
+
if (mutex.tracking.size == 0) {
|
|
37
|
+
GLOBAL_MUTEX_STORE.delete(identifier);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
6
41
|
|
|
7
42
|
async obtainLock<T>(lockOptions: LockOptions<T>): Promise<T> {
|
|
8
|
-
|
|
9
|
-
|
|
43
|
+
// If we don't have an identifier for some reason (should not happen), we use a shared Mutex
|
|
44
|
+
const { identifier: baseIdentifier = 'DEFAULT' } = this.options;
|
|
45
|
+
if (!GLOBAL_MUTEX_STORE.has(baseIdentifier)) {
|
|
46
|
+
GLOBAL_MUTEX_STORE.set(baseIdentifier, {
|
|
47
|
+
tracking: new Set([this.instanceId]),
|
|
48
|
+
locks: {
|
|
49
|
+
[LockType.CRUD]: new Mutex(),
|
|
50
|
+
[LockType.SYNC]: new Mutex()
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const mutexRecord = GLOBAL_MUTEX_STORE.get(baseIdentifier)!;
|
|
56
|
+
mutexRecord.tracking.add(this.instanceId);
|
|
57
|
+
const mutex = mutexRecord.locks[lockOptions.type];
|
|
58
|
+
|
|
59
|
+
return mutexRunExclusive(mutex, async () => {
|
|
10
60
|
if (lockOptions.signal?.aborted) {
|
|
11
61
|
throw new Error('Aborted');
|
|
12
62
|
}
|
package/dist/docs.json
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"api": {
|
|
3
|
-
"name": "PowerSyncPlugin",
|
|
4
|
-
"slug": "powersyncplugin",
|
|
5
|
-
"docs": "",
|
|
6
|
-
"tags": [],
|
|
7
|
-
"methods": [
|
|
8
|
-
{
|
|
9
|
-
"name": "registerCore",
|
|
10
|
-
"signature": "() => Promise<RegistrationResponse>",
|
|
11
|
-
"parameters": [],
|
|
12
|
-
"returns": "Promise<RegistrationResponse>",
|
|
13
|
-
"tags": [],
|
|
14
|
-
"docs": "Registers the PowerSync core extension with the SQLite library.",
|
|
15
|
-
"complexTypes": [
|
|
16
|
-
"RegistrationResponse"
|
|
17
|
-
],
|
|
18
|
-
"slug": "registercore"
|
|
19
|
-
}
|
|
20
|
-
],
|
|
21
|
-
"properties": []
|
|
22
|
-
},
|
|
23
|
-
"interfaces": [],
|
|
24
|
-
"enums": [],
|
|
25
|
-
"typeAliases": [
|
|
26
|
-
{
|
|
27
|
-
"name": "RegistrationResponse",
|
|
28
|
-
"slug": "registrationresponse",
|
|
29
|
-
"docs": "",
|
|
30
|
-
"types": [
|
|
31
|
-
{
|
|
32
|
-
"text": "{\n /**\n * Zero for successful registration, non-zero for failure.\n */\n responseCode: number;\n}",
|
|
33
|
-
"complexTypes": []
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
}
|
|
37
|
-
],
|
|
38
|
-
"pluginConfigs": []
|
|
39
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { DBAdapter, PowerSyncBackendConnector, RequiredAdditionalConnectionOptions, StreamingSyncImplementation, PowerSyncDatabase as WebPowerSyncDatabase, WebPowerSyncDatabaseOptionsWithSettings } from '@powersync/web';
|
|
2
|
-
/**
|
|
3
|
-
* PowerSyncDatabase class for managing database connections and sync implementations.
|
|
4
|
-
* This extends the WebPowerSyncDatabase to provide platform-specific implementations
|
|
5
|
-
* for Capacitor environments (iOS and Android).
|
|
6
|
-
*
|
|
7
|
-
* @experimental
|
|
8
|
-
* @alpha
|
|
9
|
-
*/
|
|
10
|
-
export declare class PowerSyncDatabase extends WebPowerSyncDatabase {
|
|
11
|
-
protected get isNativeCapacitorPlatform(): boolean;
|
|
12
|
-
protected openDBAdapter(options: WebPowerSyncDatabaseOptionsWithSettings): DBAdapter;
|
|
13
|
-
protected runExclusive<T>(cb: () => Promise<T>): Promise<T>;
|
|
14
|
-
protected generateSyncStreamImplementation(connector: PowerSyncBackendConnector, options: RequiredAdditionalConnectionOptions): StreamingSyncImplementation;
|
|
15
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { Capacitor } from '@capacitor/core';
|
|
2
|
-
import { PowerSyncDatabase as WebPowerSyncDatabase, WebRemote } from '@powersync/web';
|
|
3
|
-
import { CapacitorSQLiteAdapter } from './adapter/CapacitorSQLiteAdapter.js';
|
|
4
|
-
import { CapacitorStreamingSyncImplementation } from './sync/CapacitorSyncImplementation.js';
|
|
5
|
-
/**
|
|
6
|
-
* PowerSyncDatabase class for managing database connections and sync implementations.
|
|
7
|
-
* This extends the WebPowerSyncDatabase to provide platform-specific implementations
|
|
8
|
-
* for Capacitor environments (iOS and Android).
|
|
9
|
-
*
|
|
10
|
-
* @experimental
|
|
11
|
-
* @alpha
|
|
12
|
-
*/
|
|
13
|
-
export class PowerSyncDatabase extends WebPowerSyncDatabase {
|
|
14
|
-
get isNativeCapacitorPlatform() {
|
|
15
|
-
const platform = Capacitor.getPlatform();
|
|
16
|
-
return platform == 'ios' || platform == 'android';
|
|
17
|
-
}
|
|
18
|
-
openDBAdapter(options) {
|
|
19
|
-
var _a, _b, _c;
|
|
20
|
-
const platform = Capacitor.getPlatform();
|
|
21
|
-
if (platform == 'ios' || platform == 'android') {
|
|
22
|
-
if (options.database.dbLocation) {
|
|
23
|
-
(_a = options.logger) === null || _a === void 0 ? void 0 : _a.warn(`
|
|
24
|
-
dbLocation is ignored on iOS and Android platforms.
|
|
25
|
-
The database directory can be configured in the Capacitor project.
|
|
26
|
-
See https://github.com/capacitor-community/sqlite?tab=readme-ov-file#installation`);
|
|
27
|
-
}
|
|
28
|
-
(_b = options.logger) === null || _b === void 0 ? void 0 : _b.debug(`Using CapacitorSQLiteAdapter for platform: ${platform}`);
|
|
29
|
-
return new CapacitorSQLiteAdapter(Object.assign({}, options.database));
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
(_c = options.logger) === null || _c === void 0 ? void 0 : _c.debug(`Using default web adapter for web platform`);
|
|
33
|
-
return super.openDBAdapter(options);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
runExclusive(cb) {
|
|
37
|
-
if (this.isNativeCapacitorPlatform) {
|
|
38
|
-
// Use mutex for mobile platforms.
|
|
39
|
-
// This is mainly for testing purposes since navigator.locks require secure contexts.
|
|
40
|
-
return this.runExclusiveMutex.runExclusive(cb);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
// Use navigator.locks for web platform
|
|
44
|
-
return super.runExclusive(cb);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
generateSyncStreamImplementation(connector, options) {
|
|
48
|
-
var _a;
|
|
49
|
-
if (this.isNativeCapacitorPlatform) {
|
|
50
|
-
// We don't want to support multi-tab on mobile platforms.
|
|
51
|
-
// We technically can, but it's not a common use case and requires additional work/testing.
|
|
52
|
-
this.logger.debug(`Using Capacitor sync implementation`);
|
|
53
|
-
if ((_a = this.options.flags) === null || _a === void 0 ? void 0 : _a.enableMultiTabs) {
|
|
54
|
-
this.logger.warn(`enableMultiTabs is not supported on Capacitor mobile platforms. Ignoring the flag.`);
|
|
55
|
-
}
|
|
56
|
-
const remote = new WebRemote(connector, this.logger);
|
|
57
|
-
return new CapacitorStreamingSyncImplementation(Object.assign(Object.assign({}, this.options), { retryDelayMs: options.retryDelayMs, crudUploadThrottleMs: options.crudUploadThrottleMs, adapter: this.bucketStorageAdapter, remote, uploadCrud: async () => {
|
|
58
|
-
await this.waitForReady();
|
|
59
|
-
await connector.uploadData(this);
|
|
60
|
-
}, identifier: this.database.name, logger: this.logger, subscriptions: options.subscriptions }));
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
this.logger.debug(`Using default web sync implementation for web platform`);
|
|
64
|
-
return super.generateSyncStreamImplementation(connector, options);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
//# sourceMappingURL=PowerSyncDatabase.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PowerSyncDatabase.js","sourceRoot":"","sources":["../../src/PowerSyncDatabase.ts"],"names":[],"mappings":"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","sourcesContent":["import { Capacitor } from '@capacitor/core';\nimport {\n DBAdapter,\n PowerSyncBackendConnector,\n RequiredAdditionalConnectionOptions,\n StreamingSyncImplementation,\n PowerSyncDatabase as WebPowerSyncDatabase,\n WebPowerSyncDatabaseOptionsWithSettings,\n WebRemote\n} from '@powersync/web';\nimport { CapacitorSQLiteAdapter } from './adapter/CapacitorSQLiteAdapter.js';\nimport { CapacitorStreamingSyncImplementation } from './sync/CapacitorSyncImplementation.js';\n\n/**\n * PowerSyncDatabase class for managing database connections and sync implementations.\n * This extends the WebPowerSyncDatabase to provide platform-specific implementations\n * for Capacitor environments (iOS and Android).\n *\n * @experimental\n * @alpha\n */\nexport class PowerSyncDatabase extends WebPowerSyncDatabase {\n protected get isNativeCapacitorPlatform(): boolean {\n const platform = Capacitor.getPlatform();\n return platform == 'ios' || platform == 'android';\n }\n\n protected openDBAdapter(options: WebPowerSyncDatabaseOptionsWithSettings): DBAdapter {\n const platform = Capacitor.getPlatform();\n if (platform == 'ios' || platform == 'android') {\n if (options.database.dbLocation) {\n options.logger?.warn(`\n dbLocation is ignored on iOS and Android platforms. \n The database directory can be configured in the Capacitor project.\n See https://github.com/capacitor-community/sqlite?tab=readme-ov-file#installation`);\n }\n options.logger?.debug(`Using CapacitorSQLiteAdapter for platform: ${platform}`);\n return new CapacitorSQLiteAdapter({\n ...options.database\n });\n } else {\n options.logger?.debug(`Using default web adapter for web platform`);\n return super.openDBAdapter(options);\n }\n }\n\n protected runExclusive<T>(cb: () => Promise<T>): Promise<T> {\n if (this.isNativeCapacitorPlatform) {\n // Use mutex for mobile platforms.\n // This is mainly for testing purposes since navigator.locks require secure contexts.\n return this.runExclusiveMutex.runExclusive(cb);\n } else {\n // Use navigator.locks for web platform\n return super.runExclusive(cb);\n }\n }\n\n protected generateSyncStreamImplementation(\n connector: PowerSyncBackendConnector,\n options: RequiredAdditionalConnectionOptions\n ): StreamingSyncImplementation {\n if (this.isNativeCapacitorPlatform) {\n // We don't want to support multi-tab on mobile platforms.\n // We technically can, but it's not a common use case and requires additional work/testing.\n this.logger.debug(`Using Capacitor sync implementation`);\n if (this.options.flags?.enableMultiTabs) {\n this.logger.warn(`enableMultiTabs is not supported on Capacitor mobile platforms. Ignoring the flag.`);\n }\n const remote = new WebRemote(connector, this.logger);\n\n return new CapacitorStreamingSyncImplementation({\n ...(this.options as {}),\n retryDelayMs: options.retryDelayMs,\n crudUploadThrottleMs: options.crudUploadThrottleMs,\n adapter: this.bucketStorageAdapter,\n remote,\n uploadCrud: async () => {\n await this.waitForReady();\n await connector.uploadData(this);\n },\n identifier: this.database.name,\n logger: this.logger,\n subscriptions: options.subscriptions\n });\n } else {\n this.logger.debug(`Using default web sync implementation for web platform`);\n return super.generateSyncStreamImplementation(connector, options);\n }\n }\n}\n"]}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { SQLiteDBConnection } from '@capacitor-community/sqlite';
|
|
2
|
-
import { BaseObserver, DBAdapter, DBAdapterListener, DBLockOptions, LockContext, QueryResult, Transaction } from '@powersync/web';
|
|
3
|
-
import Lock from 'async-lock';
|
|
4
|
-
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 {
|
|
12
|
-
protected options: CapacitorSQLiteOpenFactoryOptions;
|
|
13
|
-
protected _writeConnection: SQLiteDBConnection | null;
|
|
14
|
-
protected _readConnection: SQLiteDBConnection | null;
|
|
15
|
-
protected initializedPromise: Promise<void>;
|
|
16
|
-
protected lock: Lock;
|
|
17
|
-
constructor(options: CapacitorSQLiteOpenFactoryOptions);
|
|
18
|
-
protected get writeConnection(): SQLiteDBConnection;
|
|
19
|
-
protected get readConnection(): SQLiteDBConnection;
|
|
20
|
-
get name(): string;
|
|
21
|
-
private init;
|
|
22
|
-
close(): Promise<void>;
|
|
23
|
-
protected generateLockContext(db: SQLiteDBConnection): LockContext;
|
|
24
|
-
execute(query: string, params?: any[]): Promise<QueryResult>;
|
|
25
|
-
executeRaw(query: string, params?: any[]): Promise<any[][]>;
|
|
26
|
-
executeBatch(query: string, params?: any[][]): Promise<QueryResult>;
|
|
27
|
-
readLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
28
|
-
readTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
29
|
-
writeLock<T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
30
|
-
writeTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T>;
|
|
31
|
-
refreshSchema(): Promise<void>;
|
|
32
|
-
getAll<T>(sql: string, parameters?: any[]): Promise<T[]>;
|
|
33
|
-
getOptional<T>(sql: string, parameters?: any[]): Promise<T | null>;
|
|
34
|
-
get<T>(sql: string, parameters?: any[]): Promise<T>;
|
|
35
|
-
protected internalTransaction<T>(ctx: LockContext, fn: (tx: Transaction) => Promise<T>): Promise<T>;
|
|
36
|
-
}
|