@powersync/capacitor 0.0.0-dev-20250925184532 → 0.0.0-dev-20251030152724

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.
@@ -0,0 +1,29 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'PowerSyncCapacitor'
7
+ version = package['version']
8
+ if version.include?('-dev')
9
+ s.version = '0.0.0'
10
+ else
11
+ s.version = version
12
+ end
13
+ s.summary = package['description']
14
+ s.license = package['license']
15
+ s.homepage = package['repository']['url']
16
+ s.author = package['author']
17
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
18
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
19
+ s.dependency "SQLCipher", "~> 4.0"
20
+ s.public_header_files = 'ios/Sources/CPowerSyncPlugin/include/*.h'
21
+ s.ios.deployment_target = '14.0'
22
+ s.dependency 'Capacitor'
23
+ s.swift_version = '5.1'
24
+ s.dependency "powersync-sqlite-core", "~> 0.4.6"
25
+ s.xcconfig = {
26
+ 'OTHER_CFLAGS' => '$(inherited) -DSQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION=1',
27
+ 'HEADER_SEARCH_PATHS' => '$(inherited) "$(PODS_ROOT)/SQLCipher"'
28
+ }
29
+ end
@@ -3,7 +3,7 @@ require 'json'
3
3
  package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
4
 
5
5
  Pod::Spec.new do |s|
6
- s.name = 'PowersyncCapacitor'
6
+ s.name = 'PowerSyncCapacitor'
7
7
  version = package['version']
8
8
  if version.include?('-dev')
9
9
  s.version = '0.0.0'
@@ -21,7 +21,7 @@ Pod::Spec.new do |s|
21
21
  s.ios.deployment_target = '14.0'
22
22
  s.dependency 'Capacitor'
23
23
  s.swift_version = '5.1'
24
- s.dependency "powersync-sqlite-core", "~> 0.4.4"
24
+ s.dependency "powersync-sqlite-core", "~> 0.4.6"
25
25
  s.xcconfig = {
26
26
  'OTHER_CFLAGS' => '$(inherited) -DSQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION=1',
27
27
  'HEADER_SEARCH_PATHS' => '$(inherited) "$(PODS_ROOT)/SQLCipher"'
package/README.md CHANGED
@@ -82,11 +82,12 @@ const db = new PowerSyncDatabase({
82
82
 
83
83
  - Encryption for native mobile platforms is not yet supported.
84
84
  - Multiple tab support is not available for native Android and iOS targets.
85
- - The Capacitor Community SQLite APIs differ for execution and query operations. The `.execute()` method cannot be used for `SELECT` queries or `RETURNING` queries.
85
+ - `PowerSyncDatabase.executeRaw` does not support results where multiple columns would have the same name in SQLite
86
+ - `PowerSyncDatabase.execute` has limited support on Android. The SQLCipher Android driver exposes queries and executions as separate APIs, so there is no single method that handles both. While `PowerSyncDatabase.execute` accepts both, on Android we treat a statement as a query only when the SQL starts with `select` (case-insensitive).
86
87
 
87
88
  ## Examples
88
89
 
89
- See the [`demos/example-capacitor/`](https://github.com/journeyapps/powersync-react-native-sdk/blob/capacitor-sdk/demos/example-capacitor/README.md#L1) directory for a working example.
90
+ See the [`demos/example-capacitor/`](https://github.com/journeyapps/powersync-react-native-sdk/blob/main/demos/example-capacitor/README.md#L1) directory for a working example.
90
91
 
91
92
  ## Found a bug or need help?
92
93
 
@@ -3,7 +3,7 @@ ext {
3
3
  androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
4
4
  androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
5
5
  androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
6
- powerSyncCoreVersion = project.hasProperty('powerSyncCoreVersion') ? rootProject.ext.powerSyncCoreVersion : '0.4.5'
6
+ powerSyncCoreVersion = project.hasProperty('powerSyncCoreVersion') ? rootProject.ext.powerSyncCoreVersion : '0.4.6'
7
7
  }
8
8
 
9
9
  buildscript {
@@ -1,54 +1,8 @@
1
1
  #include <jni.h>
2
- #include <dlfcn.h>
3
- #include <android/log.h>
4
-
5
- #define LOG_TAG "PowerSyncNative"
6
-
7
- // Forward declarations (no need for full struct definitions)
8
- typedef struct sqlite3 sqlite3;
9
- typedef struct sqlite3_api_routines sqlite3_api_routines;
10
-
11
- typedef int (*sqlite3_auto_extension_fn)(void (*xEntryPoint)(void));
12
-
13
- extern int sqlite3_powersync_init(
14
- sqlite3 *db, // Database handle
15
- const char **pzErrMsg, // Error message out parameter
16
- const struct sqlite3_api_routines *pThunk // SQLite API routines
17
- );
18
2
 
3
+ // SQLCipher enables dynamic loading of extensions. We don't need to do anything here.
19
4
  int register_powersync(void) {
20
- void *handle = dlopen("libsqlcipher.so", RTLD_LAZY);
21
- if (!handle) {
22
- __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Failed to dlopen libsqlcipher.so, trying process handle");
23
- // Try loading from the process itself
24
- handle = dlopen(NULL, RTLD_LAZY);
25
- if (!handle) {
26
- __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to dlopen process handle. SQLCipher symbols not found.");
27
- return -1;
28
- }
29
- } else {
30
- __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Successfully loaded libsqlcipher.so");
31
- }
32
-
33
- __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Resolving sqlite3_auto_extension symbol");
34
- sqlite3_auto_extension_fn auto_ext = (sqlite3_auto_extension_fn)dlsym(handle, "sqlite3_auto_extension");
35
- if (!auto_ext) {
36
- __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Failed to resolve sqlite3_auto_extension symbol");
37
- }
38
-
39
-
40
- if (!auto_ext) {
41
- __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Required symbols not found. Aborting registration.");
42
- dlclose(handle);
43
- return -2;
44
- }
45
-
46
- __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Registering powersync extension");
47
- int result = auto_ext((void(*)(void))sqlite3_powersync_init);
48
- __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "register_powersync result: %d", result);
49
- dlclose(handle);
50
- __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Completed register_powersync");
51
- return result;
5
+ return 0;
52
6
  }
53
7
 
54
8
  // JNI wrapper
@@ -1,12 +1,8 @@
1
1
  package com.powersync.capacitor;
2
2
 
3
- import com.getcapacitor.Logger;
4
-
5
3
  public class PowerSync {
6
4
  static {
7
5
  System.loadLibrary("powersync_capacitor");
8
- // Ensures we load this early before registering.
9
- System.loadLibrary("sqlcipher");
10
6
  }
11
7
 
12
8
  public static native int registerPowersync();
package/dist/docs.json CHANGED
@@ -29,7 +29,7 @@
29
29
  "docs": "",
30
30
  "types": [
31
31
  {
32
- "text": "{\n /**\n * Zero for successful registration, non-zero for failure.\n * - [Android] -1: SQLCipher library not found.\n * - [Android] -2: Required symbols not found.\n * - The result of sqlite3_auto_extension\n */\n responseCode: number;\n}",
32
+ "text": "{\n /**\n * Zero for successful registration, non-zero for failure.\n */\n responseCode: number;\n}",
33
33
  "complexTypes": []
34
34
  }
35
35
  ]
@@ -26,9 +26,7 @@ export class PowerSyncDatabase extends WebPowerSyncDatabase {
26
26
  See https://github.com/capacitor-community/sqlite?tab=readme-ov-file#installation`);
27
27
  }
28
28
  (_b = options.logger) === null || _b === void 0 ? void 0 : _b.debug(`Using CapacitorSQLiteAdapter for platform: ${platform}`);
29
- return new CapacitorSQLiteAdapter({
30
- dbFilename: options.database.dbFilename
31
- });
29
+ return new CapacitorSQLiteAdapter(Object.assign({}, options.database));
32
30
  }
33
31
  else {
34
32
  (_c = options.logger) === null || _c === void 0 ? void 0 : _c.debug(`Using default web adapter for web platform`);
@@ -1 +1 @@
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';\nimport { CapacitorStreamingSyncImplementation } from './sync/CapacitorSyncImplementation';\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 dbFilename: options.database.dbFilename\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
+ {"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';\nimport { CapacitorStreamingSyncImplementation } from './sync/CapacitorSyncImplementation';\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,9 +1,25 @@
1
1
  import { CapacitorSQLite, SQLiteConnection } from '@capacitor-community/sqlite';
2
+ import { Capacitor } from '@capacitor/core';
2
3
  import { BaseObserver } from '@powersync/web';
3
4
  import Lock from 'async-lock';
4
5
  import { PowerSyncCore } from '../plugin/PowerSyncCore';
5
6
  import { messageForErrorCode } from '../plugin/PowerSyncPlugin';
6
7
  import { DEFAULT_SQLITE_OPTIONS } from './CapacitorSQLiteOpenFactory';
8
+ /**
9
+ * Monitors the execution time of a query and logs it to the performance timeline.
10
+ */
11
+ async function monitorQuery(sql, executor) {
12
+ const start = performance.now();
13
+ try {
14
+ const r = await executor();
15
+ performance.measure(`[SQL] ${sql}`, { start });
16
+ return r;
17
+ }
18
+ catch (e) {
19
+ performance.measure(`[SQL] [ERROR: ${e.message}] ${sql}`, { start });
20
+ throw e;
21
+ }
22
+ }
7
23
  /**
8
24
  * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).
9
25
  *
@@ -51,13 +67,23 @@ export class CapacitorSQLiteAdapter extends BaseObserver {
51
67
  this._readConnection = await sqlite.createConnection(this.options.dbFilename, false, 'no-encryption', 1, true);
52
68
  await this._writeConnection.open();
53
69
  const { cacheSizeKb, journalSizeLimit, synchronous } = Object.assign(Object.assign({}, DEFAULT_SQLITE_OPTIONS), this.options.sqliteOptions);
54
- await this.writeConnection.query("SELECT powersync_update_hooks('install')");
55
70
  await this.writeConnection.query('PRAGMA journal_mode = WAL');
56
71
  await this.writeConnection.query(`PRAGMA journal_size_limit = ${journalSizeLimit}`);
57
72
  await this.writeConnection.query(`PRAGMA temp_store = memory`);
58
73
  await this.writeConnection.query(`PRAGMA synchronous = ${synchronous}`);
59
74
  await this.writeConnection.query(`PRAGMA cache_size = -${cacheSizeKb}`);
60
75
  await this._readConnection.open();
76
+ const platform = Capacitor.getPlatform();
77
+ if (platform == 'android') {
78
+ /**
79
+ * SQLCipher for Android enables dynamic loading of extensions.
80
+ * On iOS we use a static auto extension registration.
81
+ */
82
+ const extensionQuery = "SELECT load_extension('libpowersync.so', 'sqlite3_powersync_init')";
83
+ await this.writeConnection.query(extensionQuery);
84
+ await this.readConnection.query(extensionQuery);
85
+ }
86
+ await this.writeConnection.query("SELECT powersync_update_hooks('install')");
61
87
  }
62
88
  async close() {
63
89
  await this.initializedPromise;
@@ -65,35 +91,54 @@ export class CapacitorSQLiteAdapter extends BaseObserver {
65
91
  await this.readConnection.close();
66
92
  }
67
93
  generateLockContext(db) {
68
- const execute = async (query, params = []) => {
69
- var _a, _b, _c, _d;
70
- // This driver does not support returning results for execute methods
71
- if (query.toLowerCase().trim().startsWith('select')) {
72
- let result = await db.query(query, params);
73
- let arrayResult = (_a = result.values) !== null && _a !== void 0 ? _a : [];
74
- return {
75
- rowsAffected: 0,
76
- rows: {
77
- _array: arrayResult,
78
- length: arrayResult.length,
79
- item: (idx) => arrayResult[idx]
80
- }
81
- };
82
- }
83
- else {
84
- let result = await db.executeSet([{ statement: query, values: params }], false);
85
- return {
86
- insertId: (_b = result.changes) === null || _b === void 0 ? void 0 : _b.lastId,
87
- rowsAffected: (_d = (_c = result.changes) === null || _c === void 0 ? void 0 : _c.changes) !== null && _d !== void 0 ? _d : 0,
88
- rows: {
89
- _array: [],
90
- length: 0,
91
- item: () => null
92
- }
93
- };
94
+ const _execute = async (query, params = []) => {
95
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
96
+ const platform = Capacitor.getPlatform();
97
+ if (platform == 'android') {
98
+ // Android: use query for SELECT and executeSet for mutations
99
+ // We cannot use `run` here for both cases.
100
+ if (query.toLowerCase().trim().startsWith('select')) {
101
+ const result = await db.query(query, params);
102
+ const arrayResult = (_a = result.values) !== null && _a !== void 0 ? _a : [];
103
+ return {
104
+ rowsAffected: 0,
105
+ rows: {
106
+ _array: arrayResult,
107
+ length: arrayResult.length,
108
+ item: (idx) => arrayResult[idx]
109
+ }
110
+ };
111
+ }
112
+ else {
113
+ const result = await db.executeSet([{ statement: query, values: params }], false);
114
+ return {
115
+ insertId: (_b = result.changes) === null || _b === void 0 ? void 0 : _b.lastId,
116
+ rowsAffected: (_d = (_c = result.changes) === null || _c === void 0 ? void 0 : _c.changes) !== null && _d !== void 0 ? _d : 0,
117
+ rows: {
118
+ _array: [],
119
+ length: 0,
120
+ item: () => null
121
+ }
122
+ };
123
+ }
94
124
  }
125
+ // iOS (and other platforms): use run("all")
126
+ const result = await db.run(query, params, false, 'all');
127
+ const resultSet = (_f = (_e = result.changes) === null || _e === void 0 ? void 0 : _e.values) !== null && _f !== void 0 ? _f : [];
128
+ return {
129
+ insertId: (_g = result.changes) === null || _g === void 0 ? void 0 : _g.lastId,
130
+ rowsAffected: (_j = (_h = result.changes) === null || _h === void 0 ? void 0 : _h.changes) !== null && _j !== void 0 ? _j : 0,
131
+ rows: {
132
+ _array: resultSet,
133
+ length: resultSet.length,
134
+ item: (idx) => resultSet[idx]
135
+ }
136
+ };
95
137
  };
96
- const executeQuery = async (query, params) => {
138
+ const execute = this.options.debugMode
139
+ ? (sql, params) => monitorQuery(sql, () => _execute(sql, params))
140
+ : _execute;
141
+ const _executeQuery = async (query, params) => {
97
142
  var _a;
98
143
  let result = await db.query(query, params);
99
144
  let arrayResult = (_a = result.values) !== null && _a !== void 0 ? _a : [];
@@ -106,6 +151,9 @@ export class CapacitorSQLiteAdapter extends BaseObserver {
106
151
  }
107
152
  };
108
153
  };
154
+ const executeQuery = this.options.debugMode
155
+ ? (sql, params) => monitorQuery(sql, () => _executeQuery(sql, params))
156
+ : _executeQuery;
109
157
  const getAll = async (query, params) => {
110
158
  var _a, _b;
111
159
  const result = await executeQuery(query, params);
@@ -123,7 +171,10 @@ export class CapacitorSQLiteAdapter extends BaseObserver {
123
171
  return result;
124
172
  };
125
173
  const executeRaw = async (query, params) => {
126
- throw new Error('Not supported');
174
+ var _a, _b;
175
+ // This is a workaround, we don't support multiple columns of the same name
176
+ const results = await execute(query, params);
177
+ return (_b = (_a = results.rows) === null || _a === void 0 ? void 0 : _a._array.map((row) => Object.values(row))) !== null && _b !== void 0 ? _b : [];
127
178
  };
128
179
  return {
129
180
  getAll,
@@ -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';\n\nimport {\n BaseObserver,\n BatchedUpdateNotification,\n DBAdapter,\n DBAdapterListener,\n DBLockOptions,\n LockContext,\n QueryResult,\n Transaction\n} from '@powersync/web';\nimport Lock from 'async-lock';\nimport { PowerSyncCore } from '../plugin/PowerSyncCore';\nimport { messageForErrorCode } from '../plugin/PowerSyncPlugin';\nimport { CapacitorSQLiteOpenFactoryOptions, DEFAULT_SQLITE_OPTIONS } from './CapacitorSQLiteOpenFactory';\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 lock: Lock;\n\n constructor(protected options: CapacitorSQLiteOpenFactoryOptions) {\n super();\n this._writeConnection = null;\n this._readConnection = null;\n this.lock = new Lock();\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 await this.writeConnection.query(\"SELECT powersync_update_hooks('install')\");\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\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 execute = async (query: string, params: any[] = []): Promise<QueryResult> => {\n // This driver does not support returning results for execute methods\n if (query.toLowerCase().trim().startsWith('select')) {\n let result = await db.query(query, params);\n let 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 } else {\n let 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 const executeQuery = async (query: string, params?: any[]): Promise<QueryResult> => {\n let result = await db.query(query, params);\n\n let arrayResult = result.values ?? [];\n\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 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 throw new Error('Not supported');\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 this.lock.acquire('read_lock', async () => {\n await this.initializedPromise;\n return await fn(this.generateLockContext(this.readConnection));\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 this.lock.acquire('write_lock', 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 }\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 DBAdapter,\n DBAdapterListener,\n DBLockOptions,\n LockContext,\n QueryResult,\n Transaction\n} from '@powersync/web';\nimport Lock from 'async-lock';\nimport { PowerSyncCore } from '../plugin/PowerSyncCore';\nimport { messageForErrorCode } from '../plugin/PowerSyncPlugin';\nimport { CapacitorSQLiteOpenFactoryOptions, DEFAULT_SQLITE_OPTIONS } from './CapacitorSQLiteOpenFactory';\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 lock: Lock;\n\n constructor(protected options: CapacitorSQLiteOpenFactoryOptions) {\n super();\n this._writeConnection = null;\n this._readConnection = null;\n this.lock = new Lock();\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 _execute = async (query: string, params: any[] = []): Promise<QueryResult> => {\n const platform = Capacitor.getPlatform();\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 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 } 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 = async (query: string, params?: any[]): Promise<QueryResult> => {\n let result = await db.query(query, params);\n\n let arrayResult = result.values ?? [];\n\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 executeQuery = this.options.debugMode\n ? (sql: string, params?: any[]) => monitorQuery(sql, () => _executeQuery(sql, params))\n : _executeQuery;\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 this.lock.acquire('read_lock', async () => {\n await this.initializedPromise;\n return await fn(this.generateLockContext(this.readConnection));\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 this.lock.acquire('write_lock', 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 }\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,9 +1,6 @@
1
1
  export type RegistrationResponse = {
2
2
  /**
3
3
  * Zero for successful registration, non-zero for failure.
4
- * - [Android] -1: SQLCipher library not found.
5
- * - [Android] -2: Required symbols not found.
6
- * - The result of sqlite3_auto_extension
7
4
  */
8
5
  responseCode: number;
9
6
  };
@@ -1,9 +1,5 @@
1
1
  export const messageForErrorCode = (code) => {
2
2
  switch (code) {
3
- case -1:
4
- return '[Android] SQLCipher library not found';
5
- case -2:
6
- return '[Android] Required symbols not found';
7
3
  case 0:
8
4
  return 'Success';
9
5
  default:
@@ -1 +1 @@
1
- {"version":3,"file":"PowerSyncPlugin.js","sourceRoot":"","sources":["../../../src/plugin/PowerSyncPlugin.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAU,EAAE;IAC1D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,CAAC,CAAC;YACL,OAAO,uCAAuC,CAAC;QACjD,KAAK,CAAC,CAAC;YACL,OAAO,sCAAsC,CAAC;QAChD,KAAK,CAAC;YACJ,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,yDAAyD,IAAI,EAAE,CAAC;IAC3E,CAAC;AACH,CAAC,CAAC","sourcesContent":["export type RegistrationResponse = {\n /**\n * Zero for successful registration, non-zero for failure.\n * - [Android] -1: SQLCipher library not found.\n * - [Android] -2: Required symbols not found.\n * - The result of sqlite3_auto_extension\n */\n responseCode: number;\n};\n\nexport const messageForErrorCode = (code: number): string => {\n switch (code) {\n case -1:\n return '[Android] SQLCipher library not found';\n case -2:\n return '[Android] Required symbols not found';\n case 0:\n return 'Success';\n default:\n return `Extension registration failed with SQLite error code: ${code}`;\n }\n};\n\nexport interface PowerSyncPlugin {\n /**\n * Registers the PowerSync core extension with the SQLite library.\n */\n registerCore(): Promise<RegistrationResponse>;\n}\n"]}
1
+ {"version":3,"file":"PowerSyncPlugin.js","sourceRoot":"","sources":["../../../src/plugin/PowerSyncPlugin.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAU,EAAE;IAC1D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,CAAC;YACJ,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,yDAAyD,IAAI,EAAE,CAAC;IAC3E,CAAC;AACH,CAAC,CAAC","sourcesContent":["export type RegistrationResponse = {\n /**\n * Zero for successful registration, non-zero for failure.\n */\n responseCode: number;\n};\n\nexport const messageForErrorCode = (code: number): string => {\n switch (code) {\n case 0:\n return 'Success';\n default:\n return `Extension registration failed with SQLite error code: ${code}`;\n }\n};\n\nexport interface PowerSyncPlugin {\n /**\n * Registers the PowerSync core extension with the SQLite library.\n */\n registerCore(): Promise<RegistrationResponse>;\n}\n"]}
@@ -1,7 +1,6 @@
1
- import { AbstractStreamingSyncImplementation, AbstractStreamingSyncImplementationOptions, LockOptions } from '@powersync/web';
1
+ import { AbstractStreamingSyncImplementation, LockOptions } from '@powersync/web';
2
2
  import Lock from 'async-lock';
3
3
  export declare class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncImplementation {
4
- protected lock: Lock;
5
- constructor(options: AbstractStreamingSyncImplementationOptions);
4
+ static GLOBAL_LOCK: Lock;
6
5
  obtainLock<T>(lockOptions: LockOptions<T>): Promise<T>;
7
6
  }
@@ -1,14 +1,9 @@
1
1
  import { AbstractStreamingSyncImplementation } from '@powersync/web';
2
2
  import Lock from 'async-lock';
3
3
  export class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncImplementation {
4
- constructor(options) {
5
- // Super will store and provide default values for options
6
- super(options);
7
- this.lock = new Lock();
8
- }
9
4
  async obtainLock(lockOptions) {
10
5
  const identifier = `streaming-sync-${lockOptions.type}-${this.options.identifier}`;
11
- return this.lock.acquire(identifier, async () => {
6
+ return CapacitorStreamingSyncImplementation.GLOBAL_LOCK.acquire(identifier, async () => {
12
7
  var _a;
13
8
  if ((_a = lockOptions.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
14
9
  throw new Error('Aborted');
@@ -17,4 +12,5 @@ export class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncI
17
12
  });
18
13
  }
19
14
  }
15
+ CapacitorStreamingSyncImplementation.GLOBAL_LOCK = new Lock();
20
16
  //# sourceMappingURL=CapacitorSyncImplementation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CapacitorSyncImplementation.js","sourceRoot":"","sources":["../../../src/sync/CapacitorSyncImplementation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mCAAmC,EAGpC,MAAM,gBAAgB,CAAC;AACxB,OAAO,IAAI,MAAM,YAAY,CAAC;AAE9B,MAAM,OAAO,oCAAqC,SAAQ,mCAAmC;IAE3F,YAAY,OAAmD;QAC7D,0DAA0D;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,UAAU,CAAI,WAA2B;QAC7C,MAAM,UAAU,GAAG,kBAAkB,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACnF,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;;YAC9C,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 {\n AbstractStreamingSyncImplementation,\n AbstractStreamingSyncImplementationOptions,\n LockOptions\n} from '@powersync/web';\nimport Lock from 'async-lock';\n\nexport class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncImplementation {\n protected lock: Lock;\n constructor(options: AbstractStreamingSyncImplementationOptions) {\n // Super will store and provide default values for options\n super(options);\n this.lock = new Lock();\n }\n\n async obtainLock<T>(lockOptions: LockOptions<T>): Promise<T> {\n const identifier = `streaming-sync-${lockOptions.type}-${this.options.identifier}`;\n return this.lock.acquire(identifier, 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,MAAM,gBAAgB,CAAC;AAClF,OAAO,IAAI,MAAM,YAAY,CAAC;AAE9B,MAAM,OAAO,oCAAqC,SAAQ,mCAAmC;IAG3F,KAAK,CAAC,UAAU,CAAI,WAA2B;QAC7C,MAAM,UAAU,GAAG,kBAAkB,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACnF,OAAO,oCAAoC,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE;;YACrF,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;;AAVM,gDAAW,GAAG,IAAI,IAAI,EAAE,CAAC","sourcesContent":["import { AbstractStreamingSyncImplementation, LockOptions } from '@powersync/web';\nimport Lock from 'async-lock';\n\nexport class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncImplementation {\n static GLOBAL_LOCK = new Lock();\n\n async obtainLock<T>(lockOptions: LockOptions<T>): Promise<T> {\n const identifier = `streaming-sync-${lockOptions.type}-${this.options.identifier}`;\n return CapacitorStreamingSyncImplementation.GLOBAL_LOCK.acquire(identifier, async () => {\n if (lockOptions.signal?.aborted) {\n throw new Error('Aborted');\n }\n return await lockOptions.callback();\n });\n }\n}\n"]}