@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.
Files changed (34) hide show
  1. package/package.json +5 -5
  2. package/src/PowerSyncDatabase.ts +14 -0
  3. package/src/adapter/CapacitorSQLiteAdapter.ts +36 -25
  4. package/src/sync/CapacitorSyncImplementation.ts +55 -5
  5. package/dist/docs.json +0 -39
  6. package/dist/esm/PowerSyncDatabase.d.ts +0 -15
  7. package/dist/esm/PowerSyncDatabase.js +0 -68
  8. package/dist/esm/PowerSyncDatabase.js.map +0 -1
  9. package/dist/esm/adapter/CapacitorSQLiteAdapter.d.ts +0 -36
  10. package/dist/esm/adapter/CapacitorSQLiteAdapter.js +0 -289
  11. package/dist/esm/adapter/CapacitorSQLiteAdapter.js.map +0 -1
  12. package/dist/esm/adapter/CapacitorSQLiteOpenFactory.d.ts +0 -35
  13. package/dist/esm/adapter/CapacitorSQLiteOpenFactory.js +0 -21
  14. package/dist/esm/adapter/CapacitorSQLiteOpenFactory.js.map +0 -1
  15. package/dist/esm/index.d.ts +0 -3
  16. package/dist/esm/index.js +0 -4
  17. package/dist/esm/index.js.map +0 -1
  18. package/dist/esm/plugin/PowerSyncCore.d.ts +0 -2
  19. package/dist/esm/plugin/PowerSyncCore.js +0 -5
  20. package/dist/esm/plugin/PowerSyncCore.js.map +0 -1
  21. package/dist/esm/plugin/PowerSyncPlugin.d.ts +0 -13
  22. package/dist/esm/plugin/PowerSyncPlugin.js +0 -9
  23. package/dist/esm/plugin/PowerSyncPlugin.js.map +0 -1
  24. package/dist/esm/plugin/web.d.ts +0 -5
  25. package/dist/esm/plugin/web.js +0 -7
  26. package/dist/esm/plugin/web.js.map +0 -1
  27. package/dist/esm/sync/CapacitorSyncImplementation.d.ts +0 -6
  28. package/dist/esm/sync/CapacitorSyncImplementation.js +0 -16
  29. package/dist/esm/sync/CapacitorSyncImplementation.js.map +0 -1
  30. package/dist/plugin.cjs +0 -415
  31. package/dist/plugin.cjs.map +0 -1
  32. package/dist/plugin.d.cts +0 -86
  33. package/dist/plugin.js +0 -415
  34. 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-20260128023420",
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.2",
61
+ "prettier": "^3.7.4",
62
62
  "prettier-plugin-java": "^2.6.6",
63
63
  "rimraf": "^6.0.1",
64
- "rollup": "^4.30.1",
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-20260128023420"
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-lock": "^1.4.0"
84
+ "async-mutex": "^0.5.0"
85
85
  },
86
86
  "scripts": {
87
87
  "verify": "pnpm verify:ios && pnpm verify:android && pnpm verify:web",
@@ -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 Lock from 'async-lock';
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 lock: Lock;
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.lock = new Lock();
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 this.lock.acquire('read_lock', async () => {
241
- await this.initializedPromise;
242
- return await fn(this.generateLockContext(this.readConnection));
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 this.lock.acquire('write_lock', async () => {
254
- await this.initializedPromise;
255
- const result = await fn(this.generateLockContext(this.writeConnection));
256
-
257
- // Fetch table updates
258
- const updates = await this.writeConnection.query("SELECT powersync_update_hooks('get') AS table_name");
259
- const jsonUpdates = updates.values?.[0];
260
- if (!jsonUpdates || !jsonUpdates.table_name) {
261
- throw new Error('Could not fetch table updates');
262
- }
263
- const notification: BatchedUpdateNotification = {
264
- rawUpdates: [],
265
- tables: JSON.parse(jsonUpdates.table_name),
266
- groupedUpdates: {}
267
- };
268
- this.iterateListeners((l) => l.tablesUpdated?.(notification));
269
- return result;
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 Lock from 'async-lock';
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
- static GLOBAL_LOCK = new Lock();
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
- const identifier = `streaming-sync-${lockOptions.type}-${this.options.identifier}`;
9
- return CapacitorStreamingSyncImplementation.GLOBAL_LOCK.acquire(identifier, async () => {
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":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAKL,iBAAiB,IAAI,oBAAoB,EAEzC,SAAS,EACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,oCAAoC,EAAE,MAAM,uCAAuC,CAAC;AAE7F;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAkB,SAAQ,oBAAoB;IACzD,IAAc,yBAAyB;QACrC,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,QAAQ,IAAI,KAAK,IAAI,QAAQ,IAAI,SAAS,CAAC;IACpD,CAAC;IAES,aAAa,CAAC,OAAgD;;QACtE,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QACzC,IAAI,QAAQ,IAAI,KAAK,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;YAC/C,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAChC,MAAA,OAAO,CAAC,MAAM,0CAAE,IAAI,CAAC;;;4FAG+D,CAAC,CAAC;YACxF,CAAC;YACD,MAAA,OAAO,CAAC,MAAM,0CAAE,KAAK,CAAC,8CAA8C,QAAQ,EAAE,CAAC,CAAC;YAChF,OAAO,IAAI,sBAAsB,mBAC5B,OAAO,CAAC,QAAQ,EACnB,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAA,OAAO,CAAC,MAAM,0CAAE,KAAK,CAAC,4CAA4C,CAAC,CAAC;YACpE,OAAO,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAES,YAAY,CAAI,EAAoB;QAC5C,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACnC,kCAAkC;YAClC,qFAAqF;YACrF,OAAO,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,uCAAuC;YACvC,OAAO,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAES,gCAAgC,CACxC,SAAoC,EACpC,OAA4C;;QAE5C,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACnC,0DAA0D;YAC1D,2FAA2F;YAC3F,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACzD,IAAI,MAAA,IAAI,CAAC,OAAO,CAAC,KAAK,0CAAE,eAAe,EAAE,CAAC;gBACxC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oFAAoF,CAAC,CAAC;YACzG,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAErD,OAAO,IAAI,oCAAoC,iCACzC,IAAI,CAAC,OAAc,KACvB,YAAY,EAAE,OAAO,CAAC,YAAY,EAClC,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,EAClD,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAClC,MAAM,EACN,UAAU,EAAE,KAAK,IAAI,EAAE;oBACrB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;oBAC1B,MAAM,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBACnC,CAAC,EACD,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,aAAa,EAAE,OAAO,CAAC,aAAa,IACpC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YAC5E,OAAO,KAAK,CAAC,gCAAgC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;CACF","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
- }