@powersync/common 1.6.1

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 (93) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +6 -0
  3. package/lib/client/AbstractPowerSyncDatabase.d.ts +367 -0
  4. package/lib/client/AbstractPowerSyncDatabase.js +645 -0
  5. package/lib/client/AbstractPowerSyncDatabase.js.map +1 -0
  6. package/lib/client/AbstractPowerSyncOpenFactory.d.ts +29 -0
  7. package/lib/client/AbstractPowerSyncOpenFactory.js +25 -0
  8. package/lib/client/AbstractPowerSyncOpenFactory.js.map +1 -0
  9. package/lib/client/connection/PowerSyncBackendConnector.d.ts +23 -0
  10. package/lib/client/connection/PowerSyncBackendConnector.js +2 -0
  11. package/lib/client/connection/PowerSyncBackendConnector.js.map +1 -0
  12. package/lib/client/connection/PowerSyncCredentials.d.ts +5 -0
  13. package/lib/client/connection/PowerSyncCredentials.js +2 -0
  14. package/lib/client/connection/PowerSyncCredentials.js.map +1 -0
  15. package/lib/client/sync/bucket/BucketStorageAdapter.d.ts +71 -0
  16. package/lib/client/sync/bucket/BucketStorageAdapter.js +8 -0
  17. package/lib/client/sync/bucket/BucketStorageAdapter.js.map +1 -0
  18. package/lib/client/sync/bucket/CrudBatch.d.ts +31 -0
  19. package/lib/client/sync/bucket/CrudBatch.js +26 -0
  20. package/lib/client/sync/bucket/CrudBatch.js.map +1 -0
  21. package/lib/client/sync/bucket/CrudEntry.d.ts +86 -0
  22. package/lib/client/sync/bucket/CrudEntry.js +85 -0
  23. package/lib/client/sync/bucket/CrudEntry.js.map +1 -0
  24. package/lib/client/sync/bucket/CrudTransaction.d.ts +29 -0
  25. package/lib/client/sync/bucket/CrudTransaction.js +25 -0
  26. package/lib/client/sync/bucket/CrudTransaction.js.map +1 -0
  27. package/lib/client/sync/bucket/OpType.d.ts +16 -0
  28. package/lib/client/sync/bucket/OpType.js +23 -0
  29. package/lib/client/sync/bucket/OpType.js.map +1 -0
  30. package/lib/client/sync/bucket/OplogEntry.d.ts +23 -0
  31. package/lib/client/sync/bucket/OplogEntry.js +34 -0
  32. package/lib/client/sync/bucket/OplogEntry.js.map +1 -0
  33. package/lib/client/sync/bucket/SqliteBucketStorage.d.ts +66 -0
  34. package/lib/client/sync/bucket/SqliteBucketStorage.js +299 -0
  35. package/lib/client/sync/bucket/SqliteBucketStorage.js.map +1 -0
  36. package/lib/client/sync/bucket/SyncDataBatch.d.ts +6 -0
  37. package/lib/client/sync/bucket/SyncDataBatch.js +12 -0
  38. package/lib/client/sync/bucket/SyncDataBatch.js.map +1 -0
  39. package/lib/client/sync/bucket/SyncDataBucket.d.ts +40 -0
  40. package/lib/client/sync/bucket/SyncDataBucket.js +41 -0
  41. package/lib/client/sync/bucket/SyncDataBucket.js.map +1 -0
  42. package/lib/client/sync/stream/AbstractRemote.d.ts +25 -0
  43. package/lib/client/sync/stream/AbstractRemote.js +43 -0
  44. package/lib/client/sync/stream/AbstractRemote.js.map +1 -0
  45. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.d.ts +101 -0
  46. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +478 -0
  47. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js.map +1 -0
  48. package/lib/client/sync/stream/streaming-sync-types.d.ts +116 -0
  49. package/lib/client/sync/stream/streaming-sync-types.js +23 -0
  50. package/lib/client/sync/stream/streaming-sync-types.js.map +1 -0
  51. package/lib/db/Column.d.ts +19 -0
  52. package/lib/db/Column.js +26 -0
  53. package/lib/db/Column.js.map +1 -0
  54. package/lib/db/DBAdapter.d.ts +95 -0
  55. package/lib/db/DBAdapter.js +20 -0
  56. package/lib/db/DBAdapter.js.map +1 -0
  57. package/lib/db/crud/SyncStatus.d.ts +38 -0
  58. package/lib/db/crud/SyncStatus.js +58 -0
  59. package/lib/db/crud/SyncStatus.js.map +1 -0
  60. package/lib/db/crud/UploadQueueStatus.d.ts +20 -0
  61. package/lib/db/crud/UploadQueueStatus.js +25 -0
  62. package/lib/db/crud/UploadQueueStatus.js.map +1 -0
  63. package/lib/db/schema/Index.d.ts +22 -0
  64. package/lib/db/schema/Index.js +30 -0
  65. package/lib/db/schema/Index.js.map +1 -0
  66. package/lib/db/schema/IndexedColumn.d.ts +19 -0
  67. package/lib/db/schema/IndexedColumn.js +30 -0
  68. package/lib/db/schema/IndexedColumn.js.map +1 -0
  69. package/lib/db/schema/Schema.d.ts +38 -0
  70. package/lib/db/schema/Schema.js +38 -0
  71. package/lib/db/schema/Schema.js.map +1 -0
  72. package/lib/db/schema/Table.d.ts +51 -0
  73. package/lib/db/schema/Table.js +114 -0
  74. package/lib/db/schema/Table.js.map +1 -0
  75. package/lib/db/schema/TableV2.d.ts +30 -0
  76. package/lib/db/schema/TableV2.js +44 -0
  77. package/lib/db/schema/TableV2.js.map +1 -0
  78. package/lib/index.d.ts +30 -0
  79. package/lib/index.js +31 -0
  80. package/lib/index.js.map +1 -0
  81. package/lib/utils/AbortOperation.d.ts +9 -0
  82. package/lib/utils/AbortOperation.js +19 -0
  83. package/lib/utils/AbortOperation.js.map +1 -0
  84. package/lib/utils/BaseObserver.d.ts +20 -0
  85. package/lib/utils/BaseObserver.js +23 -0
  86. package/lib/utils/BaseObserver.js.map +1 -0
  87. package/lib/utils/mutex.d.ts +7 -0
  88. package/lib/utils/mutex.js +29 -0
  89. package/lib/utils/mutex.js.map +1 -0
  90. package/lib/utils/strings.d.ts +3 -0
  91. package/lib/utils/strings.js +10 -0
  92. package/lib/utils/strings.js.map +1 -0
  93. package/package.json +42 -0
@@ -0,0 +1,645 @@
1
+ import { Mutex } from 'async-mutex';
2
+ import { EventIterator } from 'event-iterator';
3
+ import Logger from 'js-logger';
4
+ import throttle from 'lodash/throttle';
5
+ import { isBatchedUpdateNotification } from '../db/DBAdapter';
6
+ import { SyncStatus } from '../db/crud/SyncStatus';
7
+ import { UploadQueueStats } from '../db/crud/UploadQueueStatus';
8
+ import { BaseObserver } from '../utils/BaseObserver';
9
+ import { mutexRunExclusive } from '../utils/mutex';
10
+ import { quoteIdentifier } from '../utils/strings';
11
+ import { PSInternalTable } from './sync/bucket/BucketStorageAdapter';
12
+ import { CrudBatch } from './sync/bucket/CrudBatch';
13
+ import { CrudEntry } from './sync/bucket/CrudEntry';
14
+ import { CrudTransaction } from './sync/bucket/CrudTransaction';
15
+ import { DEFAULT_CRUD_UPLOAD_THROTTLE_MS } from './sync/stream/AbstractStreamingSyncImplementation';
16
+ const POWERSYNC_TABLE_MATCH = /(^ps_data__|^ps_data_local__)/;
17
+ const DEFAULT_DISCONNECT_CLEAR_OPTIONS = {
18
+ clearLocal: true
19
+ };
20
+ export const DEFAULT_POWERSYNC_CLOSE_OPTIONS = {
21
+ disconnect: true
22
+ };
23
+ export const DEFAULT_WATCH_THROTTLE_MS = 30;
24
+ export const DEFAULT_POWERSYNC_DB_OPTIONS = {
25
+ retryDelay: 5000,
26
+ logger: Logger.get('PowerSyncDatabase'),
27
+ crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
28
+ };
29
+ /**
30
+ * Requesting nested or recursive locks can block the application in some circumstances.
31
+ * This default lock timeout will act as a failsafe to throw an error if a lock cannot
32
+ * be obtained.
33
+ */
34
+ export const DEFAULT_LOCK_TIMEOUT_MS = 120_000; // 2 mins
35
+ export class AbstractPowerSyncDatabase extends BaseObserver {
36
+ options;
37
+ /**
38
+ * Transactions should be queued in the DBAdapter, but we also want to prevent
39
+ * calls to `.execute` while an async transaction is running.
40
+ */
41
+ static transactionMutex = new Mutex();
42
+ /**
43
+ * Returns true if the connection is closed.
44
+ */
45
+ closed;
46
+ ready;
47
+ /**
48
+ * Current connection status.
49
+ */
50
+ currentStatus;
51
+ syncStreamImplementation;
52
+ sdkVersion;
53
+ bucketStorageAdapter;
54
+ syncStatusListenerDisposer;
55
+ _isReadyPromise;
56
+ hasSyncedWatchDisposer;
57
+ _schema;
58
+ constructor(options) {
59
+ super();
60
+ this.options = options;
61
+ this.bucketStorageAdapter = this.generateBucketStorageAdapter();
62
+ this.closed = false;
63
+ this.currentStatus = new SyncStatus({});
64
+ this.options = { ...DEFAULT_POWERSYNC_DB_OPTIONS, ...options };
65
+ this._schema = options.schema;
66
+ this.ready = false;
67
+ this.sdkVersion = '';
68
+ // Start async init
69
+ this._isReadyPromise = this.initialize();
70
+ }
71
+ /**
72
+ * Schema used for the local database.
73
+ */
74
+ get schema() {
75
+ return this._schema;
76
+ }
77
+ /**
78
+ * The underlying database.
79
+ *
80
+ * For the most part, behavior is the same whether querying on the underlying database, or on {@link AbstractPowerSyncDatabase}.
81
+ */
82
+ get database() {
83
+ return this.options.database;
84
+ }
85
+ /**
86
+ * Whether a connection to the PowerSync service is currently open.
87
+ */
88
+ get connected() {
89
+ return this.currentStatus?.connected || false;
90
+ }
91
+ /**
92
+ * @returns A promise which will resolve once initialization is completed.
93
+ */
94
+ async waitForReady() {
95
+ if (this.ready) {
96
+ return;
97
+ }
98
+ await this._isReadyPromise;
99
+ }
100
+ /**
101
+ * @returns A promise which will resolve once the first full sync has completed.
102
+ */
103
+ async waitForFirstSync(signal) {
104
+ if (this.currentStatus.hasSynced) {
105
+ return;
106
+ }
107
+ return new Promise((resolve) => {
108
+ const dispose = this.registerListener({
109
+ statusChanged: (status) => {
110
+ if (status.hasSynced) {
111
+ dispose();
112
+ resolve();
113
+ }
114
+ }
115
+ });
116
+ signal?.addEventListener('abort', () => {
117
+ dispose();
118
+ resolve();
119
+ });
120
+ });
121
+ }
122
+ /**
123
+ * Entry point for executing initialization logic.
124
+ * This is to be automatically executed in the constructor.
125
+ */
126
+ async initialize() {
127
+ await this._initialize();
128
+ await this.bucketStorageAdapter.init();
129
+ const version = await this.options.database.execute('SELECT powersync_rs_version()');
130
+ this.sdkVersion = version.rows?.item(0)['powersync_rs_version()'] ?? '';
131
+ await this.updateSchema(this.options.schema);
132
+ this.updateHasSynced();
133
+ await this.database.execute('PRAGMA RECURSIVE_TRIGGERS=TRUE');
134
+ this.ready = true;
135
+ this.iterateListeners((cb) => cb.initialized?.());
136
+ }
137
+ async updateHasSynced() {
138
+ const syncedSQL = 'SELECT 1 FROM ps_buckets WHERE last_applied_op > 0 LIMIT 1';
139
+ const abortController = new AbortController();
140
+ this.hasSyncedWatchDisposer = () => abortController.abort();
141
+ // Abort the watch after the first sync is detected
142
+ this.watch(syncedSQL, [], {
143
+ onResult: (result) => {
144
+ const hasSynced = !!result.rows?.length;
145
+ if (hasSynced != this.currentStatus.hasSynced) {
146
+ this.currentStatus = new SyncStatus({ ...this.currentStatus.toJSON(), hasSynced });
147
+ this.iterateListeners((l) => l.statusChanged?.(this.currentStatus));
148
+ }
149
+ if (hasSynced) {
150
+ abortController.abort();
151
+ }
152
+ },
153
+ onError: (ex) => {
154
+ this.options.logger?.warn('Failure while watching synced state', ex);
155
+ abortController.abort();
156
+ }
157
+ }, {
158
+ rawTableNames: true,
159
+ signal: abortController.signal
160
+ });
161
+ }
162
+ /**
163
+ * Replace the schema with a new version. This is for advanced use cases - typically the schema should just be specified once in the constructor.
164
+ *
165
+ * Cannot be used while connected - this should only be called before {@link AbstractPowerSyncDatabase.connect}.
166
+ */
167
+ async updateSchema(schema) {
168
+ if (this.syncStreamImplementation) {
169
+ throw new Error('Cannot update schema while connected');
170
+ }
171
+ /**
172
+ * TODO
173
+ * Validations only show a warning for now.
174
+ * The next major release should throw an exception.
175
+ */
176
+ try {
177
+ schema.validate();
178
+ }
179
+ catch (ex) {
180
+ this.options.logger?.warn('Schema validation failed. Unexpected behaviour could occur', ex);
181
+ }
182
+ this._schema = schema;
183
+ await this.database.execute('SELECT powersync_replace_schema(?)', [JSON.stringify(this.schema.toJSON())]);
184
+ }
185
+ /**
186
+ * Wait for initialization to complete.
187
+ * While initializing is automatic, this helps to catch and report initialization errors.
188
+ */
189
+ async init() {
190
+ return this.waitForReady();
191
+ }
192
+ /**
193
+ * Connects to stream of events from the PowerSync instance.
194
+ */
195
+ async connect(connector) {
196
+ await this.waitForReady();
197
+ // close connection if one is open
198
+ await this.disconnect();
199
+ if (this.closed) {
200
+ throw new Error('Cannot connect using a closed client');
201
+ }
202
+ this.syncStreamImplementation = this.generateSyncStreamImplementation(connector);
203
+ this.syncStatusListenerDisposer = this.syncStreamImplementation.registerListener({
204
+ statusChanged: (status) => {
205
+ this.currentStatus = new SyncStatus({ ...status.toJSON(), hasSynced: this.currentStatus?.hasSynced });
206
+ this.iterateListeners((cb) => cb.statusChanged?.(this.currentStatus));
207
+ }
208
+ });
209
+ await this.syncStreamImplementation.waitForReady();
210
+ this.syncStreamImplementation.triggerCrudUpload();
211
+ await this.syncStreamImplementation.connect();
212
+ }
213
+ /**
214
+ * Close the sync connection.
215
+ *
216
+ * Use {@link connect} to connect again.
217
+ */
218
+ async disconnect() {
219
+ await this.waitForReady();
220
+ await this.syncStreamImplementation?.disconnect();
221
+ this.syncStatusListenerDisposer?.();
222
+ await this.syncStreamImplementation?.dispose();
223
+ this.syncStreamImplementation = undefined;
224
+ }
225
+ /**
226
+ * Disconnect and clear the database.
227
+ * Use this when logging out.
228
+ * The database can still be queried after this is called, but the tables
229
+ * would be empty.
230
+ *
231
+ * To preserve data in local-only tables, set clearLocal to false.
232
+ */
233
+ async disconnectAndClear(options = DEFAULT_DISCONNECT_CLEAR_OPTIONS) {
234
+ await this.disconnect();
235
+ await this.waitForReady();
236
+ const { clearLocal } = options;
237
+ // TODO DB name, verify this is necessary with extension
238
+ await this.database.writeTransaction(async (tx) => {
239
+ await tx.execute(`DELETE FROM ${PSInternalTable.OPLOG}`);
240
+ await tx.execute(`DELETE FROM ${PSInternalTable.CRUD}`);
241
+ await tx.execute(`DELETE FROM ${PSInternalTable.BUCKETS}`);
242
+ const tableGlob = clearLocal ? 'ps_data_*' : 'ps_data__*';
243
+ const existingTableRows = await tx.execute(`
244
+ SELECT name FROM sqlite_master WHERE type='table' AND name GLOB ?
245
+ `, [tableGlob]);
246
+ if (!existingTableRows.rows?.length) {
247
+ return;
248
+ }
249
+ for (const row of existingTableRows.rows._array) {
250
+ await tx.execute(`DELETE FROM ${quoteIdentifier(row.name)} WHERE 1`);
251
+ }
252
+ });
253
+ }
254
+ /**
255
+ * Close the database, releasing resources.
256
+ *
257
+ * Also disconnects any active connection.
258
+ *
259
+ * Once close is called, this connection cannot be used again - a new one
260
+ * must be constructed.
261
+ */
262
+ async close(options = DEFAULT_POWERSYNC_CLOSE_OPTIONS) {
263
+ await this.waitForReady();
264
+ this.hasSyncedWatchDisposer?.();
265
+ const { disconnect } = options;
266
+ if (disconnect) {
267
+ await this.disconnect();
268
+ }
269
+ await this.syncStreamImplementation?.dispose();
270
+ this.database.close();
271
+ this.closed = true;
272
+ }
273
+ /**
274
+ * Get upload queue size estimate and count.
275
+ */
276
+ async getUploadQueueStats(includeSize) {
277
+ return this.readTransaction(async (tx) => {
278
+ if (includeSize) {
279
+ const result = await tx.execute(`SELECT SUM(cast(data as blob) + 20) as size, count(*) as count FROM ${PSInternalTable.CRUD}`);
280
+ const row = result.rows.item(0);
281
+ return new UploadQueueStats(row?.count ?? 0, row?.size ?? 0);
282
+ }
283
+ else {
284
+ const result = await tx.execute(`SELECT count(*) as count FROM ${PSInternalTable.CRUD}`);
285
+ const row = result.rows.item(0);
286
+ return new UploadQueueStats(row?.count ?? 0);
287
+ }
288
+ });
289
+ }
290
+ /**
291
+ * Get a batch of crud data to upload.
292
+ *
293
+ * Returns null if there is no data to upload.
294
+ *
295
+ * Use this from the {@link PowerSyncBackendConnector.uploadData} callback.
296
+ *
297
+ * Once the data have been successfully uploaded, call {@link CrudBatch.complete} before
298
+ * requesting the next batch.
299
+ *
300
+ * Use {@link limit} to specify the maximum number of updates to return in a single
301
+ * batch.
302
+ *
303
+ * This method does include transaction ids in the result, but does not group
304
+ * data by transaction. One batch may contain data from multiple transactions,
305
+ * and a single transaction may be split over multiple batches.
306
+ */
307
+ async getCrudBatch(limit) {
308
+ const result = await this.getAll(`SELECT id, tx_id, data FROM ${PSInternalTable.CRUD} ORDER BY id ASC LIMIT ?`, [limit + 1]);
309
+ const all = result.map((row) => CrudEntry.fromRow(row)) ?? [];
310
+ let haveMore = false;
311
+ if (all.length > limit) {
312
+ all.pop();
313
+ haveMore = true;
314
+ }
315
+ if (all.length == 0) {
316
+ return null;
317
+ }
318
+ const last = all[all.length - 1];
319
+ return new CrudBatch(all, haveMore, async (writeCheckpoint) => this.handleCrudCheckpoint(last.clientId, writeCheckpoint));
320
+ }
321
+ /**
322
+ * Get the next recorded transaction to upload.
323
+ *
324
+ * Returns null if there is no data to upload.
325
+ *
326
+ * Use this from the {@link PowerSyncBackendConnector.uploadData} callback.
327
+ *
328
+ * Once the data have been successfully uploaded, call {@link CrudTransaction.complete} before
329
+ * requesting the next transaction.
330
+ *
331
+ * Unlike {@link getCrudBatch}, this only returns data from a single transaction at a time.
332
+ * All data for the transaction is loaded into memory.
333
+ */
334
+ async getNextCrudTransaction() {
335
+ return await this.readTransaction(async (tx) => {
336
+ const first = await tx.getOptional(`SELECT id, tx_id, data FROM ${PSInternalTable.CRUD} ORDER BY id ASC LIMIT 1`);
337
+ if (!first) {
338
+ return null;
339
+ }
340
+ const txId = first.tx_id;
341
+ let all;
342
+ if (!txId) {
343
+ all = [CrudEntry.fromRow(first)];
344
+ }
345
+ else {
346
+ const result = await tx.getAll(`SELECT id, tx_id, data FROM ${PSInternalTable.CRUD} WHERE tx_id = ? ORDER BY id ASC`, [txId]);
347
+ all = result.map((row) => CrudEntry.fromRow(row));
348
+ }
349
+ const last = all[all.length - 1];
350
+ return new CrudTransaction(all, async (writeCheckpoint) => this.handleCrudCheckpoint(last.clientId, writeCheckpoint), txId);
351
+ });
352
+ }
353
+ async handleCrudCheckpoint(lastClientId, writeCheckpoint) {
354
+ return this.writeTransaction(async (tx) => {
355
+ await tx.execute(`DELETE FROM ${PSInternalTable.CRUD} WHERE id <= ?`, [lastClientId]);
356
+ if (writeCheckpoint) {
357
+ const check = await tx.execute(`SELECT 1 FROM ${PSInternalTable.CRUD} LIMIT 1`);
358
+ if (!check.rows?.length) {
359
+ await tx.execute(`UPDATE ${PSInternalTable.BUCKETS} SET target_op = ? WHERE name='$local'`, [
360
+ writeCheckpoint
361
+ ]);
362
+ }
363
+ }
364
+ else {
365
+ await tx.execute(`UPDATE ${PSInternalTable.BUCKETS} SET target_op = ? WHERE name='$local'`, [
366
+ this.bucketStorageAdapter.getMaxOpId()
367
+ ]);
368
+ }
369
+ });
370
+ }
371
+ /**
372
+ * Execute a write (INSERT/UPDATE/DELETE) query
373
+ * and optionally return results.
374
+ */
375
+ async execute(sql, parameters) {
376
+ await this.waitForReady();
377
+ return this.database.execute(sql, parameters);
378
+ }
379
+ /**
380
+ * Execute a write query (INSERT/UPDATE/DELETE) multiple times with each parameter set
381
+ * and optionally return results.
382
+ * This is faster than executing separately with each parameter set.
383
+ */
384
+ async executeBatch(sql, parameters) {
385
+ await this.waitForReady();
386
+ return this.database.executeBatch(sql, parameters);
387
+ }
388
+ /**
389
+ * Execute a read-only query and return results.
390
+ */
391
+ async getAll(sql, parameters) {
392
+ await this.waitForReady();
393
+ return this.database.getAll(sql, parameters);
394
+ }
395
+ /**
396
+ * Execute a read-only query and return the first result, or null if the ResultSet is empty.
397
+ */
398
+ async getOptional(sql, parameters) {
399
+ await this.waitForReady();
400
+ return this.database.getOptional(sql, parameters);
401
+ }
402
+ /**
403
+ * Execute a read-only query and return the first result, error if the ResultSet is empty.
404
+ */
405
+ async get(sql, parameters) {
406
+ await this.waitForReady();
407
+ return this.database.get(sql, parameters);
408
+ }
409
+ /**
410
+ * Takes a read lock, without starting a transaction.
411
+ * In most cases, {@link readTransaction} should be used instead.
412
+ */
413
+ async readLock(callback) {
414
+ await this.waitForReady();
415
+ return mutexRunExclusive(AbstractPowerSyncDatabase.transactionMutex, () => callback(this.database));
416
+ }
417
+ /**
418
+ * Takes a global lock, without starting a transaction.
419
+ * In most cases, {@link writeTransaction} should be used instead.
420
+ */
421
+ async writeLock(callback) {
422
+ await this.waitForReady();
423
+ return mutexRunExclusive(AbstractPowerSyncDatabase.transactionMutex, async () => {
424
+ const res = await callback(this.database);
425
+ return res;
426
+ });
427
+ }
428
+ /**
429
+ * Open a read-only transaction.
430
+ * Read transactions can run concurrently to a write transaction.
431
+ * Changes from any write transaction are not visible to read transactions started before it.
432
+ */
433
+ async readTransaction(callback, lockTimeout = DEFAULT_LOCK_TIMEOUT_MS) {
434
+ await this.waitForReady();
435
+ return this.database.readTransaction(async (tx) => {
436
+ const res = await callback({ ...tx });
437
+ await tx.rollback();
438
+ return res;
439
+ }, { timeoutMs: lockTimeout });
440
+ }
441
+ /**
442
+ * Open a read-write transaction.
443
+ * This takes a global lock - only one write transaction can execute against the database at a time.
444
+ * Statements within the transaction must be done on the provided {@link Transaction} interface.
445
+ */
446
+ async writeTransaction(callback, lockTimeout = DEFAULT_LOCK_TIMEOUT_MS) {
447
+ await this.waitForReady();
448
+ return this.database.writeTransaction(async (tx) => {
449
+ const res = await callback(tx);
450
+ await tx.commit();
451
+ return res;
452
+ }, { timeoutMs: lockTimeout });
453
+ }
454
+ watch(sql, parameters, handlerOrOptions, maybeOptions) {
455
+ if (handlerOrOptions && typeof handlerOrOptions === 'object' && 'onResult' in handlerOrOptions) {
456
+ const handler = handlerOrOptions;
457
+ const options = maybeOptions;
458
+ return this.watchWithCallback(sql, parameters, handler, options);
459
+ }
460
+ const options = handlerOrOptions;
461
+ return this.watchWithAsyncGenerator(sql, parameters, options);
462
+ }
463
+ /**
464
+ * Execute a read query every time the source tables are modified.
465
+ * Use {@link SQLWatchOptions.throttleMs} to specify the minimum interval between queries.
466
+ * Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
467
+ *
468
+ * Note that the `onChange` callback member of the handler is required.
469
+ */
470
+ watchWithCallback(sql, parameters, handler, options) {
471
+ const { onResult, onError = (e) => this.options.logger?.error(e) } = handler ?? {};
472
+ if (!onResult) {
473
+ throw new Error('onResult is required');
474
+ }
475
+ (async () => {
476
+ try {
477
+ const resolvedTables = await this.resolveTables(sql, parameters, options);
478
+ // Fetch initial data
479
+ const result = await this.executeReadOnly(sql, parameters);
480
+ onResult(result);
481
+ this.onChangeWithCallback({
482
+ onChange: async () => {
483
+ try {
484
+ const result = await this.executeReadOnly(sql, parameters);
485
+ onResult(result);
486
+ }
487
+ catch (error) {
488
+ onError?.(error);
489
+ }
490
+ },
491
+ onError
492
+ }, {
493
+ ...(options ?? {}),
494
+ tables: resolvedTables
495
+ });
496
+ }
497
+ catch (error) {
498
+ onError?.(error);
499
+ }
500
+ })();
501
+ }
502
+ /**
503
+ * Execute a read query every time the source tables are modified.
504
+ * Use {@link SQLWatchOptions.throttleMs} to specify the minimum interval between queries.
505
+ * Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
506
+ */
507
+ watchWithAsyncGenerator(sql, parameters, options) {
508
+ return new EventIterator((eventOptions) => {
509
+ (async () => {
510
+ const resolvedTables = await this.resolveTables(sql, parameters, options);
511
+ // Fetch initial data
512
+ eventOptions.push(await this.executeReadOnly(sql, parameters));
513
+ for await (const event of this.onChangeWithAsyncGenerator({
514
+ ...(options ?? {}),
515
+ tables: resolvedTables
516
+ })) {
517
+ eventOptions.push(await this.executeReadOnly(sql, parameters));
518
+ }
519
+ })();
520
+ });
521
+ }
522
+ async resolveTables(sql, parameters, options) {
523
+ const resolvedTables = options?.tables ? [...options.tables] : [];
524
+ if (!options?.tables) {
525
+ const explained = await this.getAll(`EXPLAIN ${sql}`, parameters);
526
+ const rootPages = explained
527
+ .filter((row) => row.opcode == 'OpenRead' && row.p3 == 0 && typeof row.p2 == 'number')
528
+ .map((row) => row.p2);
529
+ const tables = await this.getAll(`SELECT DISTINCT tbl_name FROM sqlite_master WHERE rootpage IN (SELECT json_each.value FROM json_each(?))`, [JSON.stringify(rootPages)]);
530
+ for (let table of tables) {
531
+ resolvedTables.push(table.tbl_name.replace(POWERSYNC_TABLE_MATCH, ''));
532
+ }
533
+ }
534
+ return resolvedTables;
535
+ }
536
+ onChange(handlerOrOptions, maybeOptions) {
537
+ if (handlerOrOptions && typeof handlerOrOptions === 'object' && 'onChange' in handlerOrOptions) {
538
+ const handler = handlerOrOptions;
539
+ const options = maybeOptions;
540
+ return this.onChangeWithCallback(handler, options);
541
+ }
542
+ const options = handlerOrOptions;
543
+ return this.onChangeWithAsyncGenerator(options);
544
+ }
545
+ /**
546
+ * Invoke the provided callback on any changes to any of the specified tables.
547
+ *
548
+ * This is preferred over {@link watchWithCallback} when multiple queries need to be performed
549
+ * together when data is changed.
550
+ *
551
+ * Note that the `onChange` callback member of the handler is required.
552
+ *
553
+ * Returns dispose function to stop watching.
554
+ */
555
+ onChangeWithCallback(handler, options) {
556
+ const { onChange, onError = (e) => this.options.logger?.error(e) } = handler ?? {};
557
+ if (!onChange) {
558
+ throw new Error('onChange is required');
559
+ }
560
+ const resolvedOptions = options ?? {};
561
+ const watchedTables = new Set(resolvedOptions.tables ?? []);
562
+ const changedTables = new Set();
563
+ const throttleMs = resolvedOptions.throttleMs ?? DEFAULT_WATCH_THROTTLE_MS;
564
+ const flushTableUpdates = throttle(() => this.handleTableChanges(changedTables, watchedTables, (intersection) => {
565
+ if (resolvedOptions?.signal?.aborted)
566
+ return;
567
+ onChange({ changedTables: intersection });
568
+ }), throttleMs, { leading: false, trailing: true });
569
+ const dispose = this.database.registerListener({
570
+ tablesUpdated: async (update) => {
571
+ try {
572
+ const { rawTableNames } = resolvedOptions;
573
+ this.processTableUpdates(update, rawTableNames, changedTables);
574
+ flushTableUpdates();
575
+ }
576
+ catch (error) {
577
+ onError?.(error);
578
+ }
579
+ }
580
+ });
581
+ resolvedOptions.signal?.addEventListener('abort', () => {
582
+ dispose();
583
+ });
584
+ return () => dispose();
585
+ }
586
+ /**
587
+ * Create a Stream of changes to any of the specified tables.
588
+ *
589
+ * This is preferred over {@link watchWithAsyncGenerator} when multiple queries need to be performed
590
+ * together when data is changed.
591
+ *
592
+ * Note, do not declare this as `async *onChange` as it will not work in React Native
593
+ */
594
+ onChangeWithAsyncGenerator(options) {
595
+ const resolvedOptions = options ?? {};
596
+ return new EventIterator((eventOptions) => {
597
+ const dispose = this.onChangeWithCallback({
598
+ onChange: (event) => {
599
+ eventOptions.push(event);
600
+ },
601
+ onError: (error) => {
602
+ eventOptions.fail(error);
603
+ }
604
+ }, options);
605
+ resolvedOptions.signal?.addEventListener('abort', () => {
606
+ eventOptions.stop();
607
+ // Maybe fail?
608
+ });
609
+ return () => dispose();
610
+ });
611
+ }
612
+ handleTableChanges(changedTables, watchedTables, onDetectedChanges) {
613
+ if (changedTables.size > 0) {
614
+ const intersection = Array.from(changedTables.values()).filter((change) => watchedTables.has(change));
615
+ if (intersection.length) {
616
+ onDetectedChanges(intersection);
617
+ }
618
+ }
619
+ changedTables.clear();
620
+ }
621
+ processTableUpdates(updateNotification, rawTableNames, changedTables) {
622
+ const tables = isBatchedUpdateNotification(updateNotification)
623
+ ? updateNotification.tables
624
+ : [updateNotification.table];
625
+ const filteredTables = rawTableNames ? tables : tables.filter((t) => !!t.match(POWERSYNC_TABLE_MATCH));
626
+ if (!filteredTables.length) {
627
+ return;
628
+ }
629
+ // Remove any PowerSync table prefixes if necessary
630
+ const mappedTableNames = rawTableNames
631
+ ? filteredTables
632
+ : filteredTables.map((t) => t.replace(POWERSYNC_TABLE_MATCH, ''));
633
+ for (let table of mappedTableNames) {
634
+ changedTables.add(table);
635
+ }
636
+ }
637
+ /**
638
+ * @ignore
639
+ */
640
+ async executeReadOnly(sql, params) {
641
+ await this.waitForReady();
642
+ return this.database.readLock((tx) => tx.execute(sql, params));
643
+ }
644
+ }
645
+ //# sourceMappingURL=AbstractPowerSyncDatabase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractPowerSyncDatabase.js","sourceRoot":"","sources":["../../src/client/AbstractPowerSyncDatabase.ts"],"names":[],"mappings":"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"}