@powersync/capacitor 0.0.0-dev-20250922105508

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 (43) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +95 -0
  3. package/android/build.gradle +71 -0
  4. package/android/src/main/AndroidManifest.xml +2 -0
  5. package/android/src/main/cpp/powersync_capacitor_jni.c +58 -0
  6. package/android/src/main/java/com/powersync/capacitor/PowerSync.java +13 -0
  7. package/android/src/main/java/com/powersync/capacitor/PowerSyncPlugin.java +20 -0
  8. package/android/src/main/res/.gitkeep +0 -0
  9. package/dist/docs.json +39 -0
  10. package/dist/esm/PowerSyncDatabase.d.ts +15 -0
  11. package/dist/esm/PowerSyncDatabase.js +70 -0
  12. package/dist/esm/PowerSyncDatabase.js.map +1 -0
  13. package/dist/esm/adapter/CapacitorSQLiteAdapter.d.ts +35 -0
  14. package/dist/esm/adapter/CapacitorSQLiteAdapter.js +234 -0
  15. package/dist/esm/adapter/CapacitorSQLiteAdapter.js.map +1 -0
  16. package/dist/esm/adapter/CapacitorSQLiteOpenFactory.d.ts +6 -0
  17. package/dist/esm/adapter/CapacitorSQLiteOpenFactory.js +10 -0
  18. package/dist/esm/adapter/CapacitorSQLiteOpenFactory.js.map +1 -0
  19. package/dist/esm/index.d.ts +3 -0
  20. package/dist/esm/index.js +4 -0
  21. package/dist/esm/index.js.map +1 -0
  22. package/dist/esm/plugin/PowerSyncCore.d.ts +2 -0
  23. package/dist/esm/plugin/PowerSyncCore.js +5 -0
  24. package/dist/esm/plugin/PowerSyncCore.js.map +1 -0
  25. package/dist/esm/plugin/PowerSyncPlugin.d.ts +15 -0
  26. package/dist/esm/plugin/PowerSyncPlugin.js +2 -0
  27. package/dist/esm/plugin/PowerSyncPlugin.js.map +1 -0
  28. package/dist/esm/plugin/web.d.ts +5 -0
  29. package/dist/esm/plugin/web.js +7 -0
  30. package/dist/esm/plugin/web.js.map +1 -0
  31. package/dist/esm/sync/CapacitorSyncImplementation.d.ts +7 -0
  32. package/dist/esm/sync/CapacitorSyncImplementation.js +20 -0
  33. package/dist/esm/sync/CapacitorSyncImplementation.js.map +1 -0
  34. package/dist/plugin.cjs.js +349 -0
  35. package/dist/plugin.cjs.js.map +1 -0
  36. package/dist/plugin.js +349 -0
  37. package/dist/plugin.js.map +1 -0
  38. package/ios/Sources/CPowerSyncCore/PowerSyncCore.c +13 -0
  39. package/ios/Sources/CPowerSyncCore/include/PowerSyncCore.h +6 -0
  40. package/ios/Sources/PowerSyncPlugin/PowerSync.swift +7 -0
  41. package/ios/Sources/PowerSyncPlugin/PowerSyncPlugin.swift +22 -0
  42. package/ios/Tests/PowerSyncPluginTests/PowerSyncPluginTests.swift +15 -0
  43. package/package.json +84 -0
package/dist/plugin.js ADDED
@@ -0,0 +1,349 @@
1
+ var capacitorPowerSync = (function (exports, sqlite, web$1, Lock, core) {
2
+ 'use strict';
3
+
4
+ const PowerSyncCore = core.registerPlugin('PowerSync', {
5
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.PowerSyncWeb())
6
+ });
7
+
8
+ /**
9
+ * An implementation of {@link DBAdapter} using the Capacitor Community SQLite [plugin](https://github.com/capacitor-community/sqlite).
10
+ *
11
+ * @experimental
12
+ * @alpha This is currently experimental and may change without a major version bump.
13
+ */
14
+ class CapacitorSQLiteAdapter extends web$1.BaseObserver {
15
+ constructor(options) {
16
+ super();
17
+ this.options = options;
18
+ this._writeConnection = null;
19
+ this._readConnection = null;
20
+ this.lock = new Lock();
21
+ this.initializedPromise = this.init();
22
+ }
23
+ get writeConnection() {
24
+ if (!this._writeConnection) {
25
+ throw new Error('Init not completed yet');
26
+ }
27
+ return this._writeConnection;
28
+ }
29
+ get readConnection() {
30
+ if (!this._readConnection) {
31
+ throw new Error('Init not completed yet');
32
+ }
33
+ return this._readConnection;
34
+ }
35
+ async init() {
36
+ await PowerSyncCore.registerCore();
37
+ const sqlite$1 = new sqlite.SQLiteConnection(sqlite.CapacitorSQLite);
38
+ // It seems like the isConnection and retrieveConnection methods
39
+ // only check a JS side map of connections.
40
+ // On hot reload this JS cache can be cleared, while the connection
41
+ // still exists natively. and `createConnection` will fail if it already exists.
42
+ await sqlite$1.closeConnection(this.options.dbFilename, false).catch(() => { });
43
+ await sqlite$1.closeConnection(this.options.dbFilename, true).catch(() => { });
44
+ // TODO support encryption eventually
45
+ this._writeConnection = await sqlite$1.createConnection(this.options.dbFilename, false, 'no-encryption', 1, false);
46
+ this._readConnection = await sqlite$1.createConnection(this.options.dbFilename, false, 'no-encryption', 1, true);
47
+ // TODO validate WAL mode
48
+ await this._writeConnection.open();
49
+ await this._readConnection.open();
50
+ this.writeConnection.query("SELECT powersync_update_hooks('install')");
51
+ }
52
+ async close() {
53
+ await this.initializedPromise;
54
+ await this.writeConnection.close();
55
+ await this.readConnection.close();
56
+ }
57
+ get name() {
58
+ return this.options.dbFilename;
59
+ }
60
+ generateLockContext(db) {
61
+ const execute = async (query, params = []) => {
62
+ var _a, _b, _c, _d;
63
+ // This driver does not support returning results for execute methods
64
+ if (query.toLowerCase().trim().startsWith('select')) {
65
+ let result = await db.query(query, params);
66
+ let arrayResult = (_a = result.values) !== null && _a !== void 0 ? _a : [];
67
+ return {
68
+ rowsAffected: 0,
69
+ rows: {
70
+ _array: arrayResult,
71
+ length: arrayResult.length,
72
+ item: (idx) => arrayResult[idx]
73
+ }
74
+ };
75
+ }
76
+ else {
77
+ let result = await db.executeSet([{ statement: query, values: params }], false);
78
+ return {
79
+ insertId: (_b = result.changes) === null || _b === void 0 ? void 0 : _b.lastId,
80
+ rowsAffected: (_d = (_c = result.changes) === null || _c === void 0 ? void 0 : _c.changes) !== null && _d !== void 0 ? _d : 0,
81
+ rows: {
82
+ _array: [],
83
+ length: 0,
84
+ item: () => null
85
+ }
86
+ };
87
+ }
88
+ };
89
+ const executeQuery = async (query, params) => {
90
+ var _a;
91
+ let result = await db.query(query, params);
92
+ let arrayResult = (_a = result.values) !== null && _a !== void 0 ? _a : [];
93
+ return {
94
+ rowsAffected: 0,
95
+ rows: {
96
+ _array: arrayResult,
97
+ length: arrayResult.length,
98
+ item: (idx) => arrayResult[idx]
99
+ }
100
+ };
101
+ };
102
+ const getAll = async (query, params) => {
103
+ var _a, _b;
104
+ const result = await executeQuery(query, params);
105
+ return (_b = (_a = result.rows) === null || _a === void 0 ? void 0 : _a._array) !== null && _b !== void 0 ? _b : [];
106
+ };
107
+ const getOptional = async (query, params) => {
108
+ const results = await getAll(query, params);
109
+ return results.length > 0 ? results[0] : null;
110
+ };
111
+ const get = async (query, params) => {
112
+ const result = await getOptional(query, params);
113
+ if (!result) {
114
+ throw new Error(`No results for query: ${query}`);
115
+ }
116
+ return result;
117
+ };
118
+ const executeRaw = async (query, params) => {
119
+ throw new Error('Not supported');
120
+ };
121
+ return {
122
+ getAll,
123
+ getOptional,
124
+ get,
125
+ executeRaw,
126
+ execute
127
+ };
128
+ }
129
+ execute(query, params) {
130
+ return this.writeLock((tx) => tx.execute(query, params));
131
+ }
132
+ executeRaw(query, params) {
133
+ return this.writeLock((tx) => tx.executeRaw(query, params));
134
+ }
135
+ async executeBatch(query, params = []) {
136
+ return this.writeLock(async (tx) => {
137
+ var _a, _b, _c;
138
+ let result = await this.writeConnection.executeSet(params.map((param) => ({
139
+ statement: query,
140
+ values: param
141
+ })));
142
+ return {
143
+ rowsAffected: (_b = (_a = result.changes) === null || _a === void 0 ? void 0 : _a.changes) !== null && _b !== void 0 ? _b : 0,
144
+ insertId: (_c = result.changes) === null || _c === void 0 ? void 0 : _c.lastId
145
+ };
146
+ });
147
+ }
148
+ readLock(fn, options) {
149
+ return this.lock.acquire('read_lock', async () => {
150
+ await this.initializedPromise;
151
+ return await fn(this.generateLockContext(this.readConnection));
152
+ });
153
+ }
154
+ readTransaction(fn, options) {
155
+ return this.readLock(async (ctx) => {
156
+ return this.internalTransaction(ctx, fn);
157
+ });
158
+ }
159
+ writeLock(fn, options) {
160
+ return this.lock.acquire('write_lock', async () => {
161
+ var _a;
162
+ await this.initializedPromise;
163
+ const result = await fn(this.generateLockContext(this.writeConnection));
164
+ // Fetch table updates
165
+ const updates = await this.writeConnection.query("SELECT powersync_update_hooks('get') AS table_name");
166
+ const jsonUpdates = (_a = updates.values) === null || _a === void 0 ? void 0 : _a[0];
167
+ if (!jsonUpdates || !jsonUpdates.table_name) {
168
+ throw new Error('Could not fetch table updates');
169
+ }
170
+ const notification = {
171
+ rawUpdates: [],
172
+ tables: JSON.parse(jsonUpdates.table_name),
173
+ groupedUpdates: {}
174
+ };
175
+ this.iterateListeners((l) => { var _a; return (_a = l.tablesUpdated) === null || _a === void 0 ? void 0 : _a.call(l, notification); });
176
+ return result;
177
+ });
178
+ }
179
+ writeTransaction(fn, options) {
180
+ return this.writeLock(async (ctx) => {
181
+ return this.internalTransaction(ctx, fn);
182
+ });
183
+ }
184
+ refreshSchema() {
185
+ return this.writeLock(async (writeTx) => {
186
+ return this.readLock(async (readTx) => {
187
+ const updateQuery = `PRAGMA table_info('sqlite_master')`;
188
+ await writeTx.get(updateQuery);
189
+ await readTx.get(updateQuery);
190
+ });
191
+ });
192
+ }
193
+ getAll(sql, parameters) {
194
+ return this.readLock((tx) => tx.getAll(sql, parameters));
195
+ }
196
+ getOptional(sql, parameters) {
197
+ return this.readLock((tx) => tx.getOptional(sql, parameters));
198
+ }
199
+ get(sql, parameters) {
200
+ return this.readLock((tx) => tx.get(sql, parameters));
201
+ }
202
+ async internalTransaction(ctx, fn) {
203
+ let finalized = false;
204
+ const commit = async () => {
205
+ if (finalized) {
206
+ return { rowsAffected: 0 };
207
+ }
208
+ finalized = true;
209
+ return ctx.execute('COMMIT');
210
+ };
211
+ const rollback = async () => {
212
+ if (finalized) {
213
+ return { rowsAffected: 0 };
214
+ }
215
+ finalized = true;
216
+ return ctx.execute('ROLLBACK');
217
+ };
218
+ try {
219
+ await ctx.execute('BEGIN');
220
+ const result = await fn(Object.assign(Object.assign({}, ctx), { commit,
221
+ rollback }));
222
+ await commit();
223
+ return result;
224
+ }
225
+ catch (ex) {
226
+ try {
227
+ await rollback();
228
+ }
229
+ catch (ex2) {
230
+ // In rare cases, a rollback may fail.
231
+ // Safe to ignore.
232
+ }
233
+ throw ex;
234
+ }
235
+ }
236
+ }
237
+
238
+ class CapacitorSQLiteOpenFactory {
239
+ constructor(options) {
240
+ this.options = options;
241
+ }
242
+ openDB() {
243
+ return new CapacitorSQLiteAdapter(this.options);
244
+ }
245
+ }
246
+
247
+ class CapacitorStreamingSyncImplementation extends web$1.AbstractStreamingSyncImplementation {
248
+ constructor(options) {
249
+ // Super will store and provide default values for options
250
+ super(options);
251
+ this.lock = new Lock();
252
+ }
253
+ async obtainLock(lockOptions) {
254
+ const identifier = `streaming-sync-${lockOptions.type}-${this.options.identifier}`;
255
+ return this.lock.acquire(identifier, async () => {
256
+ var _a;
257
+ if ((_a = lockOptions.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
258
+ throw new Error('Aborted');
259
+ }
260
+ return await lockOptions.callback();
261
+ });
262
+ }
263
+ }
264
+
265
+ /**
266
+ * PowerSyncDatabase class for managing database connections and sync implementations.
267
+ * This extends the WebPowerSyncDatabase to provide platform-specific implementations
268
+ * for Capacitor environments (iOS and Android).
269
+ *
270
+ * @experimental
271
+ * @alpha
272
+ */
273
+ class PowerSyncDatabase extends web$1.PowerSyncDatabase {
274
+ get isNativeCapacitorPlatform() {
275
+ const platform = core.Capacitor.getPlatform();
276
+ return platform == 'ios' || platform == 'android';
277
+ }
278
+ openDBAdapter(options) {
279
+ var _a, _b, _c;
280
+ const platform = core.Capacitor.getPlatform();
281
+ if (platform == 'ios' || platform == 'android') {
282
+ if (options.database.dbLocation) {
283
+ (_a = options.logger) === null || _a === void 0 ? void 0 : _a.warn(`
284
+ dbLocation is ignored on iOS and Android platforms.
285
+ The database directory can be configured in the Capacitor project.
286
+ See https://github.com/capacitor-community/sqlite?tab=readme-ov-file#installation`);
287
+ }
288
+ (_b = options.logger) === null || _b === void 0 ? void 0 : _b.debug(`Using CapacitorSQLiteAdapter for platform: ${platform}`);
289
+ return new CapacitorSQLiteAdapter({
290
+ dbFilename: options.database.dbFilename
291
+ });
292
+ }
293
+ else {
294
+ (_c = options.logger) === null || _c === void 0 ? void 0 : _c.debug(`Using default web adapter for web platform`);
295
+ return super.openDBAdapter(options);
296
+ }
297
+ }
298
+ runExclusive(cb) {
299
+ if (this.isNativeCapacitorPlatform) {
300
+ // Use mutex for mobile platforms.
301
+ // This is mainly for testing purposes since navigator.locks require secure contexts.
302
+ return this.runExclusiveMutex.runExclusive(cb);
303
+ }
304
+ else {
305
+ // Use navigator.locks for web platform
306
+ return super.runExclusive(cb);
307
+ }
308
+ }
309
+ generateSyncStreamImplementation(connector, options) {
310
+ var _a;
311
+ if (this.isNativeCapacitorPlatform) {
312
+ // We don't want to support multi-tab on mobile platforms.
313
+ // We technically can, but it's not a common use case and requires additional work/testing.
314
+ this.logger.debug(`Using Capacitor sync implementation`);
315
+ if ((_a = this.options.flags) === null || _a === void 0 ? void 0 : _a.enableMultiTabs) {
316
+ this.logger.warn(`enableMultiTabs is not supported on Capacitor mobile platforms. Ignoring the flag.`);
317
+ }
318
+ const remote = new web$1.WebRemote(connector, this.logger);
319
+ return new CapacitorStreamingSyncImplementation(Object.assign(Object.assign({}, this.options), { retryDelayMs: options.retryDelayMs, crudUploadThrottleMs: options.crudUploadThrottleMs, adapter: this.bucketStorageAdapter, remote, uploadCrud: async () => {
320
+ await this.waitForReady();
321
+ await connector.uploadData(this);
322
+ }, identifier: this.database.name, logger: this.logger, subscriptions: options.subscriptions }));
323
+ }
324
+ else {
325
+ this.logger.debug(`Using default web sync implementation for web platform`);
326
+ return super.generateSyncStreamImplementation(connector, options);
327
+ }
328
+ }
329
+ }
330
+
331
+ class PowerSyncWeb extends core.WebPlugin {
332
+ async registerCore() {
333
+ throw new Error('This code path is not supported on web.');
334
+ }
335
+ }
336
+
337
+ var web = /*#__PURE__*/Object.freeze({
338
+ __proto__: null,
339
+ PowerSyncWeb: PowerSyncWeb
340
+ });
341
+
342
+ exports.CapacitorSQLiteAdapter = CapacitorSQLiteAdapter;
343
+ exports.CapacitorSQLiteOpenFactory = CapacitorSQLiteOpenFactory;
344
+ exports.PowerSyncDatabase = PowerSyncDatabase;
345
+
346
+ return exports;
347
+
348
+ })({}, sqlite, web$1, Lock, capacitorExports);
349
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/plugin/PowerSyncCore.js","esm/adapter/CapacitorSQLiteAdapter.js","esm/adapter/CapacitorSQLiteOpenFactory.js","esm/sync/CapacitorSyncImplementation.js","esm/PowerSyncDatabase.js","esm/plugin/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nexport const PowerSyncCore = registerPlugin('PowerSync', {\n web: () => import('./web').then((m) => new m.PowerSyncWeb())\n});\n//# sourceMappingURL=PowerSyncCore.js.map","import { CapacitorSQLite, SQLiteConnection } from '@capacitor-community/sqlite';\nimport { BaseObserver } from '@powersync/web';\nimport Lock from 'async-lock';\nimport { PowerSyncCore } from '../plugin/PowerSyncCore';\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 {\n constructor(options) {\n super();\n this.options = options;\n this._writeConnection = null;\n this._readConnection = null;\n this.lock = new Lock();\n this.initializedPromise = this.init();\n }\n get writeConnection() {\n if (!this._writeConnection) {\n throw new Error('Init not completed yet');\n }\n return this._writeConnection;\n }\n get readConnection() {\n if (!this._readConnection) {\n throw new Error('Init not completed yet');\n }\n return this._readConnection;\n }\n async init() {\n await PowerSyncCore.registerCore();\n const sqlite = new SQLiteConnection(CapacitorSQLite);\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 // 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 // TODO validate WAL mode\n await this._writeConnection.open();\n await this._readConnection.open();\n this.writeConnection.query(\"SELECT powersync_update_hooks('install')\");\n }\n async close() {\n await this.initializedPromise;\n await this.writeConnection.close();\n await this.readConnection.close();\n }\n get name() {\n return this.options.dbFilename;\n }\n generateLockContext(db) {\n const execute = async (query, params = []) => {\n var _a, _b, _c, _d;\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 = (_a = result.values) !== null && _a !== void 0 ? _a : [];\n return {\n rowsAffected: 0,\n rows: {\n _array: arrayResult,\n length: arrayResult.length,\n item: (idx) => arrayResult[idx]\n }\n };\n }\n else {\n let result = await db.executeSet([{ statement: query, values: params }], false);\n return {\n insertId: (_b = result.changes) === null || _b === void 0 ? void 0 : _b.lastId,\n rowsAffected: (_d = (_c = result.changes) === null || _c === void 0 ? void 0 : _c.changes) !== null && _d !== void 0 ? _d : 0,\n rows: {\n _array: [],\n length: 0,\n item: () => null\n }\n };\n }\n };\n const executeQuery = async (query, params) => {\n var _a;\n let result = await db.query(query, params);\n let arrayResult = (_a = result.values) !== null && _a !== void 0 ? _a : [];\n return {\n rowsAffected: 0,\n rows: {\n _array: arrayResult,\n length: arrayResult.length,\n item: (idx) => arrayResult[idx]\n }\n };\n };\n const getAll = async (query, params) => {\n var _a, _b;\n const result = await executeQuery(query, params);\n return (_b = (_a = result.rows) === null || _a === void 0 ? void 0 : _a._array) !== null && _b !== void 0 ? _b : [];\n };\n const getOptional = async (query, params) => {\n const results = await getAll(query, params);\n return results.length > 0 ? results[0] : null;\n };\n const get = async (query, params) => {\n const result = await getOptional(query, params);\n if (!result) {\n throw new Error(`No results for query: ${query}`);\n }\n return result;\n };\n const executeRaw = async (query, params) => {\n throw new Error('Not supported');\n };\n return {\n getAll,\n getOptional,\n get,\n executeRaw,\n execute\n };\n }\n execute(query, params) {\n return this.writeLock((tx) => tx.execute(query, params));\n }\n executeRaw(query, params) {\n return this.writeLock((tx) => tx.executeRaw(query, params));\n }\n async executeBatch(query, params = []) {\n return this.writeLock(async (tx) => {\n var _a, _b, _c;\n let result = await this.writeConnection.executeSet(params.map((param) => ({\n statement: query,\n values: param\n })));\n return {\n rowsAffected: (_b = (_a = result.changes) === null || _a === void 0 ? void 0 : _a.changes) !== null && _b !== void 0 ? _b : 0,\n insertId: (_c = result.changes) === null || _c === void 0 ? void 0 : _c.lastId\n };\n });\n }\n readLock(fn, options) {\n return this.lock.acquire('read_lock', async () => {\n await this.initializedPromise;\n return await fn(this.generateLockContext(this.readConnection));\n });\n }\n readTransaction(fn, options) {\n return this.readLock(async (ctx) => {\n return this.internalTransaction(ctx, fn);\n });\n }\n writeLock(fn, options) {\n return this.lock.acquire('write_lock', async () => {\n var _a;\n await this.initializedPromise;\n const result = await fn(this.generateLockContext(this.writeConnection));\n // Fetch table updates\n const updates = await this.writeConnection.query(\"SELECT powersync_update_hooks('get') AS table_name\");\n const jsonUpdates = (_a = updates.values) === null || _a === void 0 ? void 0 : _a[0];\n if (!jsonUpdates || !jsonUpdates.table_name) {\n throw new Error('Could not fetch table updates');\n }\n const notification = {\n rawUpdates: [],\n tables: JSON.parse(jsonUpdates.table_name),\n groupedUpdates: {}\n };\n this.iterateListeners((l) => { var _a; return (_a = l.tablesUpdated) === null || _a === void 0 ? void 0 : _a.call(l, notification); });\n return result;\n });\n }\n writeTransaction(fn, options) {\n return this.writeLock(async (ctx) => {\n return this.internalTransaction(ctx, fn);\n });\n }\n refreshSchema() {\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 getAll(sql, parameters) {\n return this.readLock((tx) => tx.getAll(sql, parameters));\n }\n getOptional(sql, parameters) {\n return this.readLock((tx) => tx.getOptional(sql, parameters));\n }\n get(sql, parameters) {\n return this.readLock((tx) => tx.get(sql, parameters));\n }\n async internalTransaction(ctx, fn) {\n let finalized = false;\n const commit = async () => {\n if (finalized) {\n return { rowsAffected: 0 };\n }\n finalized = true;\n return ctx.execute('COMMIT');\n };\n const rollback = async () => {\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(Object.assign(Object.assign({}, ctx), { commit,\n rollback }));\n await commit();\n return result;\n }\n catch (ex) {\n try {\n await rollback();\n }\n catch (ex2) {\n // In rare cases, a rollback may fail.\n // Safe to ignore.\n }\n throw ex;\n }\n }\n}\n//# sourceMappingURL=CapacitorSQLiteAdapter.js.map","import { CapacitorSQLiteAdapter } from './CapacitorSQLiteAdapter';\nexport class CapacitorSQLiteOpenFactory {\n constructor(options) {\n this.options = options;\n }\n openDB() {\n return new CapacitorSQLiteAdapter(this.options);\n }\n}\n//# sourceMappingURL=CapacitorSQLiteOpenFactory.js.map","import { AbstractStreamingSyncImplementation } from '@powersync/web';\nimport Lock from 'async-lock';\nexport class CapacitorStreamingSyncImplementation extends AbstractStreamingSyncImplementation {\n constructor(options) {\n // Super will store and provide default values for options\n super(options);\n this.lock = new Lock();\n }\n async obtainLock(lockOptions) {\n const identifier = `streaming-sync-${lockOptions.type}-${this.options.identifier}`;\n return this.lock.acquire(identifier, async () => {\n var _a;\n if ((_a = lockOptions.signal) === null || _a === void 0 ? void 0 : _a.aborted) {\n throw new Error('Aborted');\n }\n return await lockOptions.callback();\n });\n }\n}\n//# sourceMappingURL=CapacitorSyncImplementation.js.map","import { Capacitor } from '@capacitor/core';\nimport { PowerSyncDatabase as WebPowerSyncDatabase, WebRemote } from '@powersync/web';\nimport { CapacitorSQLiteAdapter } from './adapter/CapacitorSQLiteAdapter';\nimport { CapacitorStreamingSyncImplementation } from './sync/CapacitorSyncImplementation';\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 get isNativeCapacitorPlatform() {\n const platform = Capacitor.getPlatform();\n return platform == 'ios' || platform == 'android';\n }\n openDBAdapter(options) {\n var _a, _b, _c;\n const platform = Capacitor.getPlatform();\n if (platform == 'ios' || platform == 'android') {\n if (options.database.dbLocation) {\n (_a = options.logger) === null || _a === void 0 ? void 0 : _a.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 (_b = options.logger) === null || _b === void 0 ? void 0 : _b.debug(`Using CapacitorSQLiteAdapter for platform: ${platform}`);\n return new CapacitorSQLiteAdapter({\n dbFilename: options.database.dbFilename\n });\n }\n else {\n (_c = options.logger) === null || _c === void 0 ? void 0 : _c.debug(`Using default web adapter for web platform`);\n return super.openDBAdapter(options);\n }\n }\n runExclusive(cb) {\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 }\n else {\n // Use navigator.locks for web platform\n return super.runExclusive(cb);\n }\n }\n generateSyncStreamImplementation(connector, options) {\n var _a;\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 ((_a = this.options.flags) === null || _a === void 0 ? void 0 : _a.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 return new CapacitorStreamingSyncImplementation(Object.assign(Object.assign({}, this.options), { retryDelayMs: options.retryDelayMs, crudUploadThrottleMs: options.crudUploadThrottleMs, adapter: this.bucketStorageAdapter, remote, uploadCrud: async () => {\n await this.waitForReady();\n await connector.uploadData(this);\n }, identifier: this.database.name, logger: this.logger, 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//# sourceMappingURL=PowerSyncDatabase.js.map","import { WebPlugin } from '@capacitor/core';\nexport class PowerSyncWeb extends WebPlugin {\n async registerCore() {\n throw new Error('This code path is not supported on web.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","BaseObserver","sqlite","SQLiteConnection","CapacitorSQLite","AbstractStreamingSyncImplementation","WebPowerSyncDatabase","Capacitor","WebRemote","WebPlugin"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ #include "PowerSyncCore.h"
2
+ #include <stdio.h>
3
+ #include "SQLCipher/sqlite3.h"
4
+
5
+ extern int sqlite3_powersync_init(
6
+ sqlite3 *db, // Database handle
7
+ const char **pzErrMsg, // Error message out parameter
8
+ const struct sqlite3_api_routines *pThunk // SQLite API routines
9
+ );
10
+
11
+ int register_powersync(void) {
12
+ return sqlite3_auto_extension((void(*)(void))sqlite3_powersync_init);
13
+ }
@@ -0,0 +1,6 @@
1
+ #ifndef CMyPackage_h
2
+ #define CMyPackage_h
3
+
4
+ int register_powersync();
5
+
6
+ #endif /* CMyPackage_h */
@@ -0,0 +1,7 @@
1
+ import Foundation
2
+
3
+ @objc public class PowerSync: NSObject {
4
+ @objc public func registerCore() -> Int32 {
5
+ return register_powersync()
6
+ }
7
+ }
@@ -0,0 +1,22 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ /**
5
+ * Please read the Capacitor iOS Plugin Development Guide
6
+ * here: https://capacitorjs.com/docs/plugins/ios
7
+ */
8
+ @objc(PowerSyncPlugin)
9
+ public class PowerSyncPlugin: CAPPlugin, CAPBridgedPlugin {
10
+ public let identifier = "PowerSyncPlugin"
11
+ public let jsName = "PowerSync"
12
+ public let pluginMethods: [CAPPluginMethod] = [
13
+ CAPPluginMethod(name: "registerCore", returnType: CAPPluginReturnPromise)
14
+ ]
15
+ private let implementation = PowerSync()
16
+
17
+ @objc func registerCore(_ call: CAPPluginCall) {
18
+ call.resolve([
19
+ "responseCode": implementation.registerCore()
20
+ ])
21
+ }
22
+ }
@@ -0,0 +1,15 @@
1
+ import XCTest
2
+ @testable import PowerSyncPlugin
3
+
4
+ class PowerSyncTests: XCTestCase {
5
+ func testEcho() {
6
+ // This is an example of a functional test case for a plugin.
7
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
8
+
9
+ let implementation = PowerSync()
10
+ let value = "Hello, World!"
11
+ let result = implementation.echo(value)
12
+
13
+ XCTAssertEqual(value, result)
14
+ }
15
+ }
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@powersync/capacitor",
3
+ "version": "0.0.0-dev-20250922105508",
4
+ "description": "Adds PowerSync Capacitor support for iOS/Android",
5
+ "publishConfig": {
6
+ "registry": "https://registry.npmjs.org/",
7
+ "access": "public"
8
+ },
9
+ "main": "dist/plugin.cjs.js",
10
+ "module": "dist/esm/index.js",
11
+ "types": "dist/esm/index.d.ts",
12
+ "unpkg": "dist/plugin.js",
13
+ "files": [
14
+ "android/src/main/",
15
+ "android/build.gradle",
16
+ "dist/",
17
+ "ios/Sources",
18
+ "ios/Tests",
19
+ "Package.swift",
20
+ "Powersync.podspec"
21
+ ],
22
+ "author": "",
23
+ "license": "Apache-2.0",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/powersync-ja/powersync-js.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/powersync-ja/powersync-js/issues"
30
+ },
31
+ "keywords": [
32
+ "capacitor",
33
+ "plugin",
34
+ "native"
35
+ ],
36
+ "devDependencies": {
37
+ "@capacitor-community/sqlite": "^7.0.1",
38
+ "@capacitor/android": "^7.0.0",
39
+ "@capacitor/core": "^7.0.0",
40
+ "@capacitor/docgen": "^0.3.0",
41
+ "@capacitor/ios": "^7.0.0",
42
+ "@ionic/eslint-config": "^0.4.0",
43
+ "@ionic/prettier-config": "^4.0.0",
44
+ "@ionic/swiftlint-config": "^2.0.0",
45
+ "eslint": "^8.57.0",
46
+ "prettier": "^3.4.2",
47
+ "prettier-plugin-java": "^2.6.6",
48
+ "rimraf": "^6.0.1",
49
+ "rollup": "^4.30.1",
50
+ "swiftlint": "^2.0.0"
51
+ },
52
+ "peerDependencies": {
53
+ "@capacitor-community/sqlite": "^7.0.1",
54
+ "@powersync/web": "^0.0.0-dev-20250922105508"
55
+ },
56
+ "swiftlint": "@ionic/swiftlint-config",
57
+ "capacitor": {
58
+ "ios": {
59
+ "src": "ios"
60
+ },
61
+ "android": {
62
+ "src": "android"
63
+ }
64
+ },
65
+ "dependencies": {
66
+ "async-lock": "^1.4.0"
67
+ },
68
+ "scripts": {
69
+ "verify": "pnpm verify:ios && pnpm verify:android && pnpm verify:web",
70
+ "verify:ios": "cd example-app && npm install && cd ios/App && pod install && xcodebuild -workspace App.xcworkspace -scheme App -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest'",
71
+ "verify:android": "cd android && ./gradlew clean build test && cd ..",
72
+ "verify:web": "pnpm build",
73
+ "lint": "pnpm eslint && pnpm prettier -- --check && pnpm swiftlint -- lint",
74
+ "fmt": "pnpm eslint -- --fix && pnpm prettier -- --write && pnpm swiftlint -- --fix --format",
75
+ "eslint": "eslint . --ext ts",
76
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
77
+ "swiftlint": "node-swiftlint",
78
+ "docgen": "docgen --api PowerSyncPlugin --output-readme README.md --output-json dist/docs.json",
79
+ "build": "pnpm clean && pnpm docgen && tsc && rollup -c rollup.config.mjs",
80
+ "build:prod": "pnpm build",
81
+ "clean": "rimraf ./dist",
82
+ "watch": "tsc --watch"
83
+ }
84
+ }