@powersync/common 1.53.2 → 1.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.cjs +548 -345
- package/dist/bundle.cjs.map +1 -1
- package/dist/bundle.mjs +548 -345
- package/dist/bundle.mjs.map +1 -1
- package/dist/bundle.node.cjs +548 -345
- package/dist/bundle.node.cjs.map +1 -1
- package/dist/bundle.node.mjs +548 -345
- package/dist/bundle.node.mjs.map +1 -1
- package/dist/index.d.cts +727 -189
- package/lib/attachments/AttachmentContext.d.ts +7 -6
- package/lib/attachments/AttachmentContext.js +2 -1
- package/lib/attachments/AttachmentContext.js.map +1 -1
- package/lib/attachments/AttachmentErrorHandler.d.ts +6 -6
- package/lib/attachments/AttachmentQueue.d.ts +61 -20
- package/lib/attachments/AttachmentQueue.js +16 -18
- package/lib/attachments/AttachmentQueue.js.map +1 -1
- package/lib/attachments/LocalStorageAdapter.d.ts +14 -8
- package/lib/attachments/LocalStorageAdapter.js +3 -0
- package/lib/attachments/LocalStorageAdapter.js.map +1 -1
- package/lib/attachments/RemoteStorageAdapter.d.ts +4 -4
- package/lib/attachments/Schema.d.ts +12 -4
- package/lib/attachments/Schema.js +8 -3
- package/lib/attachments/Schema.js.map +1 -1
- package/lib/attachments/WatchedAttachmentItem.d.ts +3 -1
- package/lib/client/AbstractPowerSyncDatabase.d.ts +110 -58
- package/lib/client/AbstractPowerSyncDatabase.js +59 -48
- package/lib/client/AbstractPowerSyncDatabase.js.map +1 -1
- package/lib/client/AbstractPowerSyncOpenFactory.d.ts +6 -0
- package/lib/client/AbstractPowerSyncOpenFactory.js +3 -0
- package/lib/client/AbstractPowerSyncOpenFactory.js.map +1 -1
- package/lib/client/ConnectionManager.d.ts +4 -1
- package/lib/client/ConnectionManager.js +1 -1
- package/lib/client/ConnectionManager.js.map +1 -1
- package/lib/client/Query.d.ts +9 -0
- package/lib/client/SQLOpenFactory.d.ts +12 -0
- package/lib/client/SQLOpenFactory.js +6 -0
- package/lib/client/SQLOpenFactory.js.map +1 -1
- package/lib/client/compilableQueryWatch.d.ts +6 -0
- package/lib/client/compilableQueryWatch.js +3 -0
- package/lib/client/compilableQueryWatch.js.map +1 -1
- package/lib/client/connection/PowerSyncBackendConnector.d.ts +3 -0
- package/lib/client/connection/PowerSyncCredentials.d.ts +3 -0
- package/lib/client/constants.d.ts +3 -0
- package/lib/client/constants.js +3 -0
- package/lib/client/constants.js.map +1 -1
- package/lib/client/runOnSchemaChange.d.ts +3 -0
- package/lib/client/runOnSchemaChange.js +3 -0
- package/lib/client/runOnSchemaChange.js.map +1 -1
- package/lib/client/sync/bucket/BucketStorageAdapter.d.ts +12 -0
- package/lib/client/sync/bucket/BucketStorageAdapter.js +6 -0
- package/lib/client/sync/bucket/BucketStorageAdapter.js.map +1 -1
- package/lib/client/sync/bucket/CrudBatch.d.ts +2 -0
- package/lib/client/sync/bucket/CrudBatch.js +2 -0
- package/lib/client/sync/bucket/CrudBatch.js.map +1 -1
- package/lib/client/sync/bucket/CrudEntry.d.ts +9 -0
- package/lib/client/sync/bucket/CrudEntry.js +4 -0
- package/lib/client/sync/bucket/CrudEntry.js.map +1 -1
- package/lib/client/sync/bucket/CrudTransaction.d.ts +3 -0
- package/lib/client/sync/bucket/CrudTransaction.js +3 -0
- package/lib/client/sync/bucket/CrudTransaction.js.map +1 -1
- package/lib/client/sync/bucket/SqliteBucketStorage.d.ts +3 -0
- package/lib/client/sync/bucket/SqliteBucketStorage.js +3 -0
- package/lib/client/sync/bucket/SqliteBucketStorage.js.map +1 -1
- package/lib/client/sync/stream/AbstractRemote.d.ts +30 -1
- package/lib/client/sync/stream/AbstractRemote.js +15 -1
- package/lib/client/sync/stream/AbstractRemote.js.map +1 -1
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.d.ts +55 -5
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +32 -4
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js.map +1 -1
- package/lib/client/sync/stream/JsonValue.d.ts +3 -0
- package/lib/client/sync/stream/WebsocketClientTransport.js +2 -1
- package/lib/client/sync/stream/WebsocketClientTransport.js.map +1 -1
- package/lib/client/sync/sync-streams.d.ts +22 -7
- package/lib/client/triggers/TriggerManager.d.ts +19 -18
- package/lib/client/triggers/TriggerManager.js +2 -1
- package/lib/client/triggers/TriggerManager.js.map +1 -1
- package/lib/client/triggers/TriggerManagerImpl.d.ts +1 -1
- package/lib/client/triggers/TriggerManagerImpl.js +3 -3
- package/lib/client/triggers/TriggerManagerImpl.js.map +1 -1
- package/lib/client/triggers/sanitizeSQL.d.ts +4 -0
- package/lib/client/triggers/sanitizeSQL.js +4 -0
- package/lib/client/triggers/sanitizeSQL.js.map +1 -1
- package/lib/client/watched/GetAllQuery.d.ts +4 -0
- package/lib/client/watched/GetAllQuery.js +2 -0
- package/lib/client/watched/GetAllQuery.js.map +1 -1
- package/lib/client/watched/WatchedQuery.d.ts +24 -2
- package/lib/client/watched/WatchedQuery.js +9 -0
- package/lib/client/watched/WatchedQuery.js.map +1 -1
- package/lib/client/watched/processors/AbstractQueryProcessor.d.ts +1 -1
- package/lib/client/watched/processors/AbstractQueryProcessor.js.map +1 -1
- package/lib/client/watched/processors/DifferentialQueryProcessor.d.ts +20 -0
- package/lib/client/watched/processors/DifferentialQueryProcessor.js +4 -0
- package/lib/client/watched/processors/DifferentialQueryProcessor.js.map +1 -1
- package/lib/client/watched/processors/OnChangeQueryProcessor.d.ts +4 -0
- package/lib/client/watched/processors/OnChangeQueryProcessor.js.map +1 -1
- package/lib/client/watched/processors/comparators.d.ts +8 -0
- package/lib/client/watched/processors/comparators.js +4 -0
- package/lib/client/watched/processors/comparators.js.map +1 -1
- package/lib/db/ConnectionClosedError.d.ts +2 -0
- package/lib/db/ConnectionClosedError.js +2 -0
- package/lib/db/ConnectionClosedError.js.map +1 -1
- package/lib/db/DBAdapter.d.ts +56 -6
- package/lib/db/DBAdapter.js +15 -3
- package/lib/db/DBAdapter.js.map +1 -1
- package/lib/db/crud/SyncProgress.d.ts +6 -1
- package/lib/db/crud/SyncProgress.js +2 -0
- package/lib/db/crud/SyncProgress.js.map +1 -1
- package/lib/db/crud/SyncStatus.d.ts +36 -38
- package/lib/db/crud/SyncStatus.js +19 -14
- package/lib/db/crud/SyncStatus.js.map +1 -1
- package/lib/db/crud/UploadQueueStatus.d.ts +3 -0
- package/lib/db/crud/UploadQueueStatus.js +3 -0
- package/lib/db/crud/UploadQueueStatus.js.map +1 -1
- package/lib/db/schema/Column.d.ts +28 -0
- package/lib/db/schema/Column.js +16 -3
- package/lib/db/schema/Column.js.map +1 -1
- package/lib/db/schema/Index.d.ts +9 -0
- package/lib/db/schema/Index.js +6 -0
- package/lib/db/schema/Index.js.map +1 -1
- package/lib/db/schema/IndexedColumn.d.ts +9 -0
- package/lib/db/schema/IndexedColumn.js +6 -0
- package/lib/db/schema/IndexedColumn.js.map +1 -1
- package/lib/db/schema/RawTable.d.ts +7 -1
- package/lib/db/schema/Schema.d.ts +6 -1
- package/lib/db/schema/Schema.js +3 -1
- package/lib/db/schema/Schema.js.map +1 -1
- package/lib/db/schema/Table.d.ts +27 -3
- package/lib/db/schema/Table.js +9 -0
- package/lib/db/schema/Table.js.map +1 -1
- package/lib/db/schema/TableV2.d.ts +2 -0
- package/lib/db/schema/TableV2.js +2 -0
- package/lib/db/schema/TableV2.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/types/types.d.ts +6 -0
- package/lib/utils/AbortOperation.d.ts +2 -0
- package/lib/utils/AbortOperation.js +2 -0
- package/lib/utils/AbortOperation.js.map +1 -1
- package/lib/utils/BaseObserver.d.ts +12 -0
- package/lib/utils/BaseObserver.js +3 -0
- package/lib/utils/BaseObserver.js.map +1 -1
- package/lib/utils/ControlledExecutor.d.ts +6 -0
- package/lib/utils/ControlledExecutor.js +3 -0
- package/lib/utils/ControlledExecutor.js.map +1 -1
- package/lib/utils/Logger.d.ts +9 -0
- package/lib/utils/Logger.js +6 -0
- package/lib/utils/Logger.js.map +1 -1
- package/lib/utils/mutex.d.ts +8 -0
- package/lib/utils/mutex.js +3 -0
- package/lib/utils/mutex.js.map +1 -1
- package/lib/utils/parseQuery.d.ts +6 -0
- package/lib/utils/parseQuery.js +3 -0
- package/lib/utils/parseQuery.js.map +1 -1
- package/lib/utils/stream_transform.d.ts +3 -1
- package/lib/utils/stream_transform.js.map +1 -1
- package/package.json +3 -2
- package/src/attachments/AttachmentContext.ts +7 -6
- package/src/attachments/AttachmentErrorHandler.ts +6 -6
- package/src/attachments/AttachmentQueue.ts +71 -23
- package/src/attachments/LocalStorageAdapter.ts +14 -8
- package/src/attachments/README.md +2 -0
- package/src/attachments/RemoteStorageAdapter.ts +4 -4
- package/src/attachments/Schema.ts +12 -4
- package/src/attachments/WatchedAttachmentItem.ts +3 -1
- package/src/client/AbstractPowerSyncDatabase.ts +117 -62
- package/src/client/AbstractPowerSyncOpenFactory.ts +6 -0
- package/src/client/ConnectionManager.ts +4 -1
- package/src/client/Query.ts +9 -0
- package/src/client/SQLOpenFactory.ts +12 -0
- package/src/client/compilableQueryWatch.ts +6 -0
- package/src/client/connection/PowerSyncBackendConnector.ts +3 -0
- package/src/client/connection/PowerSyncCredentials.ts +3 -0
- package/src/client/constants.ts +3 -0
- package/src/client/runOnSchemaChange.ts +3 -0
- package/src/client/sync/bucket/BucketStorageAdapter.ts +12 -0
- package/src/client/sync/bucket/CrudBatch.ts +2 -0
- package/src/client/sync/bucket/CrudEntry.ts +9 -0
- package/src/client/sync/bucket/CrudTransaction.ts +3 -0
- package/src/client/sync/bucket/SqliteBucketStorage.ts +3 -0
- package/src/client/sync/stream/AbstractRemote.ts +30 -1
- package/src/client/sync/stream/AbstractStreamingSyncImplementation.ts +55 -5
- package/src/client/sync/stream/JsonValue.ts +3 -0
- package/src/client/sync/stream/WebsocketClientTransport.ts +3 -1
- package/src/client/sync/sync-streams.ts +22 -9
- package/src/client/triggers/TriggerManager.ts +19 -18
- package/src/client/triggers/TriggerManagerImpl.ts +5 -5
- package/src/client/triggers/sanitizeSQL.ts +5 -0
- package/src/client/watched/GetAllQuery.ts +5 -1
- package/src/client/watched/WatchedQuery.ts +24 -2
- package/src/client/watched/processors/AbstractQueryProcessor.ts +6 -6
- package/src/client/watched/processors/DifferentialQueryProcessor.ts +28 -5
- package/src/client/watched/processors/OnChangeQueryProcessor.ts +9 -3
- package/src/client/watched/processors/comparators.ts +8 -0
- package/src/db/ConnectionClosedError.ts +2 -0
- package/src/db/DBAdapter.ts +58 -6
- package/src/db/crud/SyncProgress.ts +6 -1
- package/src/db/crud/SyncStatus.ts +40 -21
- package/src/db/crud/UploadQueueStatus.ts +3 -0
- package/src/db/schema/Column.ts +28 -3
- package/src/db/schema/Index.ts +9 -0
- package/src/db/schema/IndexedColumn.ts +9 -0
- package/src/db/schema/RawTable.ts +7 -1
- package/src/db/schema/Schema.ts +8 -3
- package/src/db/schema/Table.ts +30 -5
- package/src/db/schema/TableV2.ts +2 -0
- package/src/index.ts +1 -1
- package/src/types/types.ts +6 -0
- package/src/utils/AbortOperation.ts +2 -0
- package/src/utils/BaseObserver.ts +12 -0
- package/src/utils/ControlledExecutor.ts +6 -0
- package/src/utils/Logger.ts +9 -0
- package/src/utils/mutex.ts +12 -0
- package/src/utils/parseQuery.ts +6 -0
- package/src/utils/stream_transform.ts +3 -1
package/dist/bundle.node.cjs
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
var eventIterator = require('event-iterator');
|
|
4
4
|
var node_buffer = require('node:buffer');
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @see https://www.sqlite.org/lang_expr.html#castexpr
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
7
10
|
exports.ColumnType = void 0;
|
|
8
11
|
(function (ColumnType) {
|
|
9
12
|
ColumnType["TEXT"] = "TEXT";
|
|
@@ -19,14 +22,24 @@ const integer = {
|
|
|
19
22
|
const real = {
|
|
20
23
|
type: exports.ColumnType.REAL
|
|
21
24
|
};
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
/**
|
|
26
|
+
* powersync-sqlite-core limits the number of column per table to 1999, due to internal SQLite limits.
|
|
27
|
+
* In earlier versions this was limited to 63.
|
|
28
|
+
*
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
24
31
|
const MAX_AMOUNT_OF_COLUMNS = 1999;
|
|
32
|
+
/**
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
25
35
|
const column = {
|
|
26
36
|
text,
|
|
27
37
|
integer,
|
|
28
38
|
real
|
|
29
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
30
43
|
class Column {
|
|
31
44
|
options;
|
|
32
45
|
constructor(options) {
|
|
@@ -46,9 +59,15 @@ class Column {
|
|
|
46
59
|
}
|
|
47
60
|
}
|
|
48
61
|
|
|
62
|
+
/**
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
49
65
|
const DEFAULT_INDEX_COLUMN_OPTIONS = {
|
|
50
66
|
ascending: true
|
|
51
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
52
71
|
class IndexedColumn {
|
|
53
72
|
options;
|
|
54
73
|
static createAscending(column) {
|
|
@@ -75,9 +94,15 @@ class IndexedColumn {
|
|
|
75
94
|
}
|
|
76
95
|
}
|
|
77
96
|
|
|
97
|
+
/**
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
78
100
|
const DEFAULT_INDEX_OPTIONS = {
|
|
79
101
|
columns: []
|
|
80
102
|
};
|
|
103
|
+
/**
|
|
104
|
+
* @public
|
|
105
|
+
*/
|
|
81
106
|
class Index {
|
|
82
107
|
options;
|
|
83
108
|
static createAscending(options, columnNames) {
|
|
@@ -119,6 +144,9 @@ function encodeTableOptions(options) {
|
|
|
119
144
|
};
|
|
120
145
|
}
|
|
121
146
|
|
|
147
|
+
/**
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
122
150
|
const DEFAULT_TABLE_OPTIONS = {
|
|
123
151
|
indexes: [],
|
|
124
152
|
insertOnly: false,
|
|
@@ -127,7 +155,13 @@ const DEFAULT_TABLE_OPTIONS = {
|
|
|
127
155
|
trackMetadata: false,
|
|
128
156
|
ignoreEmptyUpdates: false
|
|
129
157
|
};
|
|
158
|
+
/**
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
130
161
|
const InvalidSQLCharacters = /["'%,.#\s[\]]/;
|
|
162
|
+
/**
|
|
163
|
+
* @public
|
|
164
|
+
*/
|
|
131
165
|
class Table {
|
|
132
166
|
options;
|
|
133
167
|
_mappedColumns;
|
|
@@ -318,6 +352,11 @@ class Table {
|
|
|
318
352
|
}
|
|
319
353
|
}
|
|
320
354
|
|
|
355
|
+
/**
|
|
356
|
+
* The default name of the local table storing attachment data.
|
|
357
|
+
*
|
|
358
|
+
* @alpha
|
|
359
|
+
*/
|
|
321
360
|
const ATTACHMENT_TABLE = 'attachments';
|
|
322
361
|
/**
|
|
323
362
|
* Maps a database row to an AttachmentRecord.
|
|
@@ -325,7 +364,7 @@ const ATTACHMENT_TABLE = 'attachments';
|
|
|
325
364
|
* @param row - The database row object
|
|
326
365
|
* @returns The corresponding AttachmentRecord
|
|
327
366
|
*
|
|
328
|
-
* @
|
|
367
|
+
* @alpha
|
|
329
368
|
*/
|
|
330
369
|
function attachmentFromSql(row) {
|
|
331
370
|
return {
|
|
@@ -343,7 +382,7 @@ function attachmentFromSql(row) {
|
|
|
343
382
|
/**
|
|
344
383
|
* AttachmentState represents the current synchronization state of an attachment.
|
|
345
384
|
*
|
|
346
|
-
* @
|
|
385
|
+
* @alpha
|
|
347
386
|
*/
|
|
348
387
|
exports.AttachmentState = void 0;
|
|
349
388
|
(function (AttachmentState) {
|
|
@@ -356,7 +395,7 @@ exports.AttachmentState = void 0;
|
|
|
356
395
|
/**
|
|
357
396
|
* AttachmentTable defines the schema for the attachment queue table.
|
|
358
397
|
*
|
|
359
|
-
* @
|
|
398
|
+
* @alpha
|
|
360
399
|
*/
|
|
361
400
|
class AttachmentTable extends Table {
|
|
362
401
|
constructor(options) {
|
|
@@ -384,7 +423,8 @@ class AttachmentTable extends Table {
|
|
|
384
423
|
* Provides methods to query, insert, update, and delete attachment records with
|
|
385
424
|
* proper transaction management through PowerSync.
|
|
386
425
|
*
|
|
387
|
-
* @
|
|
426
|
+
* @experimental
|
|
427
|
+
* @alpha
|
|
388
428
|
*/
|
|
389
429
|
class AttachmentContext {
|
|
390
430
|
/** PowerSync database instance for executing queries */
|
|
@@ -606,6 +646,9 @@ class AttachmentContext {
|
|
|
606
646
|
}
|
|
607
647
|
}
|
|
608
648
|
|
|
649
|
+
/**
|
|
650
|
+
* @public
|
|
651
|
+
*/
|
|
609
652
|
exports.WatchedQueryListenerEvent = void 0;
|
|
610
653
|
(function (WatchedQueryListenerEvent) {
|
|
611
654
|
WatchedQueryListenerEvent["ON_DATA"] = "onData";
|
|
@@ -614,176 +657,18 @@ exports.WatchedQueryListenerEvent = void 0;
|
|
|
614
657
|
WatchedQueryListenerEvent["SETTINGS_WILL_UPDATE"] = "settingsWillUpdate";
|
|
615
658
|
WatchedQueryListenerEvent["CLOSED"] = "closed";
|
|
616
659
|
})(exports.WatchedQueryListenerEvent || (exports.WatchedQueryListenerEvent = {}));
|
|
660
|
+
/**
|
|
661
|
+
* @internal
|
|
662
|
+
*/
|
|
617
663
|
const DEFAULT_WATCH_THROTTLE_MS = 30;
|
|
664
|
+
/**
|
|
665
|
+
* @internal
|
|
666
|
+
*/
|
|
618
667
|
const DEFAULT_WATCH_QUERY_OPTIONS = {
|
|
619
668
|
throttleMs: DEFAULT_WATCH_THROTTLE_MS,
|
|
620
669
|
reportFetching: true
|
|
621
670
|
};
|
|
622
671
|
|
|
623
|
-
/**
|
|
624
|
-
* Orchestrates attachment synchronization between local and remote storage.
|
|
625
|
-
* Handles uploads, downloads, deletions, and state transitions.
|
|
626
|
-
*
|
|
627
|
-
* @internal
|
|
628
|
-
*/
|
|
629
|
-
class SyncingService {
|
|
630
|
-
attachmentService;
|
|
631
|
-
localStorage;
|
|
632
|
-
remoteStorage;
|
|
633
|
-
logger;
|
|
634
|
-
errorHandler;
|
|
635
|
-
constructor(attachmentService, localStorage, remoteStorage, logger, errorHandler) {
|
|
636
|
-
this.attachmentService = attachmentService;
|
|
637
|
-
this.localStorage = localStorage;
|
|
638
|
-
this.remoteStorage = remoteStorage;
|
|
639
|
-
this.logger = logger;
|
|
640
|
-
this.errorHandler = errorHandler;
|
|
641
|
-
}
|
|
642
|
-
/**
|
|
643
|
-
* Processes attachments based on their state (upload, download, or delete).
|
|
644
|
-
* All updates are saved in a single batch after processing.
|
|
645
|
-
*
|
|
646
|
-
* @param attachments - Array of attachment records to process
|
|
647
|
-
* @param context - Attachment context for database operations
|
|
648
|
-
* @returns Promise that resolves when all attachments have been processed and saved
|
|
649
|
-
*/
|
|
650
|
-
async processAttachments(attachments, context) {
|
|
651
|
-
const updatedAttachments = [];
|
|
652
|
-
for (const attachment of attachments) {
|
|
653
|
-
switch (attachment.state) {
|
|
654
|
-
case exports.AttachmentState.QUEUED_UPLOAD:
|
|
655
|
-
const uploaded = await this.uploadAttachment(attachment);
|
|
656
|
-
updatedAttachments.push(uploaded);
|
|
657
|
-
break;
|
|
658
|
-
case exports.AttachmentState.QUEUED_DOWNLOAD:
|
|
659
|
-
const downloaded = await this.downloadAttachment(attachment);
|
|
660
|
-
updatedAttachments.push(downloaded);
|
|
661
|
-
break;
|
|
662
|
-
case exports.AttachmentState.QUEUED_DELETE:
|
|
663
|
-
const deleted = await this.deleteAttachment(attachment, context);
|
|
664
|
-
updatedAttachments.push(deleted);
|
|
665
|
-
break;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
await context.saveAttachments(updatedAttachments);
|
|
669
|
-
}
|
|
670
|
-
/**
|
|
671
|
-
* Uploads an attachment from local storage to remote storage.
|
|
672
|
-
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
673
|
-
*
|
|
674
|
-
* @param attachment - The attachment record to upload
|
|
675
|
-
* @returns Updated attachment record with new state
|
|
676
|
-
* @throws Error if the attachment has no localUri
|
|
677
|
-
*/
|
|
678
|
-
async uploadAttachment(attachment) {
|
|
679
|
-
this.logger.info(`Uploading attachment ${attachment.filename}`);
|
|
680
|
-
try {
|
|
681
|
-
if (attachment.localUri == null) {
|
|
682
|
-
throw new Error(`No localUri for attachment ${attachment.id}`);
|
|
683
|
-
}
|
|
684
|
-
const fileBlob = await this.localStorage.readFile(attachment.localUri);
|
|
685
|
-
await this.remoteStorage.uploadFile(fileBlob, attachment);
|
|
686
|
-
return {
|
|
687
|
-
...attachment,
|
|
688
|
-
state: exports.AttachmentState.SYNCED,
|
|
689
|
-
hasSynced: true
|
|
690
|
-
};
|
|
691
|
-
}
|
|
692
|
-
catch (error) {
|
|
693
|
-
const shouldRetry = (await this.errorHandler?.onUploadError(attachment, error)) ?? true;
|
|
694
|
-
if (!shouldRetry) {
|
|
695
|
-
return {
|
|
696
|
-
...attachment,
|
|
697
|
-
state: exports.AttachmentState.ARCHIVED
|
|
698
|
-
};
|
|
699
|
-
}
|
|
700
|
-
return attachment;
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
/**
|
|
704
|
-
* Downloads an attachment from remote storage to local storage.
|
|
705
|
-
* Retrieves the file, converts to base64, and saves locally.
|
|
706
|
-
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
707
|
-
*
|
|
708
|
-
* @param attachment - The attachment record to download
|
|
709
|
-
* @returns Updated attachment record with local URI and new state
|
|
710
|
-
*/
|
|
711
|
-
async downloadAttachment(attachment) {
|
|
712
|
-
this.logger.info(`Downloading attachment ${attachment.filename}`);
|
|
713
|
-
try {
|
|
714
|
-
const fileData = await this.remoteStorage.downloadFile(attachment);
|
|
715
|
-
const localUri = this.localStorage.getLocalUri(attachment.filename);
|
|
716
|
-
await this.localStorage.saveFile(localUri, fileData);
|
|
717
|
-
return {
|
|
718
|
-
...attachment,
|
|
719
|
-
state: exports.AttachmentState.SYNCED,
|
|
720
|
-
localUri: localUri,
|
|
721
|
-
hasSynced: true
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
catch (error) {
|
|
725
|
-
const shouldRetry = (await this.errorHandler?.onDownloadError(attachment, error)) ?? true;
|
|
726
|
-
if (!shouldRetry) {
|
|
727
|
-
return {
|
|
728
|
-
...attachment,
|
|
729
|
-
state: exports.AttachmentState.ARCHIVED
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
return attachment;
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
/**
|
|
736
|
-
* Deletes an attachment from both remote and local storage.
|
|
737
|
-
* Removes the remote file, local file (if exists), and the attachment record.
|
|
738
|
-
* On failure, defers to error handler or archives.
|
|
739
|
-
*
|
|
740
|
-
* @param attachment - The attachment record to delete
|
|
741
|
-
* @param context - Attachment context for database operations
|
|
742
|
-
* @returns Updated attachment record
|
|
743
|
-
*/
|
|
744
|
-
async deleteAttachment(attachment, context) {
|
|
745
|
-
try {
|
|
746
|
-
await this.remoteStorage.deleteFile(attachment);
|
|
747
|
-
if (attachment.localUri) {
|
|
748
|
-
await this.localStorage.deleteFile(attachment.localUri);
|
|
749
|
-
}
|
|
750
|
-
await context.deleteAttachment(attachment.id);
|
|
751
|
-
return {
|
|
752
|
-
...attachment,
|
|
753
|
-
state: exports.AttachmentState.ARCHIVED
|
|
754
|
-
};
|
|
755
|
-
}
|
|
756
|
-
catch (error) {
|
|
757
|
-
const shouldRetry = (await this.errorHandler?.onDeleteError(attachment, error)) ?? true;
|
|
758
|
-
if (!shouldRetry) {
|
|
759
|
-
return {
|
|
760
|
-
...attachment,
|
|
761
|
-
state: exports.AttachmentState.ARCHIVED
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
return attachment;
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Performs cleanup of archived attachments by removing their local files and records.
|
|
769
|
-
* Errors during local file deletion are logged but do not prevent record deletion.
|
|
770
|
-
*/
|
|
771
|
-
async deleteArchivedAttachments(context) {
|
|
772
|
-
return await context.deleteArchivedAttachments(async (archivedAttachments) => {
|
|
773
|
-
for (const attachment of archivedAttachments) {
|
|
774
|
-
if (attachment.localUri) {
|
|
775
|
-
try {
|
|
776
|
-
await this.localStorage.deleteFile(attachment.localUri);
|
|
777
|
-
}
|
|
778
|
-
catch (error) {
|
|
779
|
-
this.logger.error('Error deleting local file for archived attachment', error);
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
});
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
|
|
787
672
|
/**
|
|
788
673
|
* A simple fixed-capacity queue implementation.
|
|
789
674
|
*
|
|
@@ -940,93 +825,260 @@ class Semaphore {
|
|
|
940
825
|
return { release, item: items[0] };
|
|
941
826
|
}
|
|
942
827
|
/**
|
|
943
|
-
* Requests access to all items from the pool.
|
|
828
|
+
* Requests access to all items from the pool.
|
|
829
|
+
*
|
|
830
|
+
* The returned `release` callback must be invoked to return items into the pool.
|
|
831
|
+
*/
|
|
832
|
+
requestAll(abort) {
|
|
833
|
+
return this.requestPermits(this.size, abort);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* An asynchronous mutex implementation.
|
|
838
|
+
*
|
|
839
|
+
* @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
|
|
840
|
+
*/
|
|
841
|
+
class Mutex {
|
|
842
|
+
inner = new Semaphore([null]);
|
|
843
|
+
async acquire(abort) {
|
|
844
|
+
const { release } = await this.inner.requestOne(abort);
|
|
845
|
+
return release;
|
|
846
|
+
}
|
|
847
|
+
async runExclusive(fn, abort) {
|
|
848
|
+
const returnMutex = await this.acquire(abort);
|
|
849
|
+
try {
|
|
850
|
+
return await fn();
|
|
851
|
+
}
|
|
852
|
+
finally {
|
|
853
|
+
returnMutex();
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* @internal
|
|
859
|
+
*/
|
|
860
|
+
function timeoutSignal(timeout) {
|
|
861
|
+
if (timeout == null)
|
|
862
|
+
return;
|
|
863
|
+
if ('timeout' in AbortSignal)
|
|
864
|
+
return AbortSignal.timeout(timeout);
|
|
865
|
+
const controller = new AbortController();
|
|
866
|
+
setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
|
|
867
|
+
return controller.signal;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Service for querying and watching attachment records in the database.
|
|
872
|
+
*
|
|
873
|
+
* @internal
|
|
874
|
+
*/
|
|
875
|
+
class AttachmentService {
|
|
876
|
+
db;
|
|
877
|
+
logger;
|
|
878
|
+
tableName;
|
|
879
|
+
mutex = new Mutex();
|
|
880
|
+
context;
|
|
881
|
+
constructor(db, logger, tableName = 'attachments', archivedCacheLimit = 100) {
|
|
882
|
+
this.db = db;
|
|
883
|
+
this.logger = logger;
|
|
884
|
+
this.tableName = tableName;
|
|
885
|
+
this.context = new AttachmentContext(db, tableName, logger, archivedCacheLimit);
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Creates a differential watch query for active attachments requiring synchronization.
|
|
889
|
+
* @returns Watch query that emits changes for queued uploads, downloads, and deletes
|
|
890
|
+
*/
|
|
891
|
+
watchActiveAttachments({ throttleMs } = {}) {
|
|
892
|
+
this.logger.info('Watching active attachments...');
|
|
893
|
+
const watch = this.db
|
|
894
|
+
.query({
|
|
895
|
+
sql: /* sql */ `
|
|
896
|
+
SELECT
|
|
897
|
+
*
|
|
898
|
+
FROM
|
|
899
|
+
${this.tableName}
|
|
900
|
+
WHERE
|
|
901
|
+
state = ?
|
|
902
|
+
OR state = ?
|
|
903
|
+
OR state = ?
|
|
904
|
+
ORDER BY
|
|
905
|
+
timestamp ASC
|
|
906
|
+
`,
|
|
907
|
+
parameters: [exports.AttachmentState.QUEUED_UPLOAD, exports.AttachmentState.QUEUED_DOWNLOAD, exports.AttachmentState.QUEUED_DELETE]
|
|
908
|
+
})
|
|
909
|
+
.differentialWatch({ throttleMs });
|
|
910
|
+
return watch;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Executes a callback with exclusive access to the attachment context.
|
|
914
|
+
*/
|
|
915
|
+
async withContext(callback) {
|
|
916
|
+
return this.mutex.runExclusive(async () => {
|
|
917
|
+
return callback(this.context);
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* Orchestrates attachment synchronization between local and remote storage.
|
|
924
|
+
* Handles uploads, downloads, deletions, and state transitions.
|
|
925
|
+
*
|
|
926
|
+
* @internal
|
|
927
|
+
*/
|
|
928
|
+
class SyncingService {
|
|
929
|
+
attachmentService;
|
|
930
|
+
localStorage;
|
|
931
|
+
remoteStorage;
|
|
932
|
+
logger;
|
|
933
|
+
errorHandler;
|
|
934
|
+
constructor(attachmentService, localStorage, remoteStorage, logger, errorHandler) {
|
|
935
|
+
this.attachmentService = attachmentService;
|
|
936
|
+
this.localStorage = localStorage;
|
|
937
|
+
this.remoteStorage = remoteStorage;
|
|
938
|
+
this.logger = logger;
|
|
939
|
+
this.errorHandler = errorHandler;
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Processes attachments based on their state (upload, download, or delete).
|
|
943
|
+
* All updates are saved in a single batch after processing.
|
|
944
|
+
*
|
|
945
|
+
* @param attachments - Array of attachment records to process
|
|
946
|
+
* @param context - Attachment context for database operations
|
|
947
|
+
* @returns Promise that resolves when all attachments have been processed and saved
|
|
948
|
+
*/
|
|
949
|
+
async processAttachments(attachments, context) {
|
|
950
|
+
const updatedAttachments = [];
|
|
951
|
+
for (const attachment of attachments) {
|
|
952
|
+
switch (attachment.state) {
|
|
953
|
+
case exports.AttachmentState.QUEUED_UPLOAD:
|
|
954
|
+
const uploaded = await this.uploadAttachment(attachment);
|
|
955
|
+
updatedAttachments.push(uploaded);
|
|
956
|
+
break;
|
|
957
|
+
case exports.AttachmentState.QUEUED_DOWNLOAD:
|
|
958
|
+
const downloaded = await this.downloadAttachment(attachment);
|
|
959
|
+
updatedAttachments.push(downloaded);
|
|
960
|
+
break;
|
|
961
|
+
case exports.AttachmentState.QUEUED_DELETE:
|
|
962
|
+
const deleted = await this.deleteAttachment(attachment, context);
|
|
963
|
+
updatedAttachments.push(deleted);
|
|
964
|
+
break;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
await context.saveAttachments(updatedAttachments);
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Uploads an attachment from local storage to remote storage.
|
|
971
|
+
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
972
|
+
*
|
|
973
|
+
* @param attachment - The attachment record to upload
|
|
974
|
+
* @returns Updated attachment record with new state
|
|
975
|
+
* @throws Error if the attachment has no localUri
|
|
976
|
+
*/
|
|
977
|
+
async uploadAttachment(attachment) {
|
|
978
|
+
this.logger.info(`Uploading attachment ${attachment.filename}`);
|
|
979
|
+
try {
|
|
980
|
+
if (attachment.localUri == null) {
|
|
981
|
+
throw new Error(`No localUri for attachment ${attachment.id}`);
|
|
982
|
+
}
|
|
983
|
+
const fileBlob = await this.localStorage.readFile(attachment.localUri);
|
|
984
|
+
await this.remoteStorage.uploadFile(fileBlob, attachment);
|
|
985
|
+
return {
|
|
986
|
+
...attachment,
|
|
987
|
+
state: exports.AttachmentState.SYNCED,
|
|
988
|
+
hasSynced: true
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
catch (error) {
|
|
992
|
+
const shouldRetry = (await this.errorHandler?.onUploadError(attachment, error)) ?? true;
|
|
993
|
+
if (!shouldRetry) {
|
|
994
|
+
return {
|
|
995
|
+
...attachment,
|
|
996
|
+
state: exports.AttachmentState.ARCHIVED
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
return attachment;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Downloads an attachment from remote storage to local storage.
|
|
1004
|
+
* Retrieves the file, converts to base64, and saves locally.
|
|
1005
|
+
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
1006
|
+
*
|
|
1007
|
+
* @param attachment - The attachment record to download
|
|
1008
|
+
* @returns Updated attachment record with local URI and new state
|
|
1009
|
+
*/
|
|
1010
|
+
async downloadAttachment(attachment) {
|
|
1011
|
+
this.logger.info(`Downloading attachment ${attachment.filename}`);
|
|
1012
|
+
try {
|
|
1013
|
+
const fileData = await this.remoteStorage.downloadFile(attachment);
|
|
1014
|
+
const localUri = this.localStorage.getLocalUri(attachment.filename);
|
|
1015
|
+
await this.localStorage.saveFile(localUri, fileData);
|
|
1016
|
+
return {
|
|
1017
|
+
...attachment,
|
|
1018
|
+
state: exports.AttachmentState.SYNCED,
|
|
1019
|
+
localUri: localUri,
|
|
1020
|
+
hasSynced: true
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
catch (error) {
|
|
1024
|
+
const shouldRetry = (await this.errorHandler?.onDownloadError(attachment, error)) ?? true;
|
|
1025
|
+
if (!shouldRetry) {
|
|
1026
|
+
return {
|
|
1027
|
+
...attachment,
|
|
1028
|
+
state: exports.AttachmentState.ARCHIVED
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
return attachment;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Deletes an attachment from both remote and local storage.
|
|
1036
|
+
* Removes the remote file, local file (if exists), and the attachment record.
|
|
1037
|
+
* On failure, defers to error handler or archives.
|
|
944
1038
|
*
|
|
945
|
-
*
|
|
1039
|
+
* @param attachment - The attachment record to delete
|
|
1040
|
+
* @param context - Attachment context for database operations
|
|
1041
|
+
* @returns Updated attachment record
|
|
946
1042
|
*/
|
|
947
|
-
|
|
948
|
-
return this.requestPermits(this.size, abort);
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
/**
|
|
952
|
-
* An asynchronous mutex implementation.
|
|
953
|
-
*
|
|
954
|
-
* @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
|
|
955
|
-
*/
|
|
956
|
-
class Mutex {
|
|
957
|
-
inner = new Semaphore([null]);
|
|
958
|
-
async acquire(abort) {
|
|
959
|
-
const { release } = await this.inner.requestOne(abort);
|
|
960
|
-
return release;
|
|
961
|
-
}
|
|
962
|
-
async runExclusive(fn, abort) {
|
|
963
|
-
const returnMutex = await this.acquire(abort);
|
|
1043
|
+
async deleteAttachment(attachment, context) {
|
|
964
1044
|
try {
|
|
965
|
-
|
|
1045
|
+
await this.remoteStorage.deleteFile(attachment);
|
|
1046
|
+
if (attachment.localUri) {
|
|
1047
|
+
await this.localStorage.deleteFile(attachment.localUri);
|
|
1048
|
+
}
|
|
1049
|
+
await context.deleteAttachment(attachment.id);
|
|
1050
|
+
return {
|
|
1051
|
+
...attachment,
|
|
1052
|
+
state: exports.AttachmentState.ARCHIVED
|
|
1053
|
+
};
|
|
966
1054
|
}
|
|
967
|
-
|
|
968
|
-
|
|
1055
|
+
catch (error) {
|
|
1056
|
+
const shouldRetry = (await this.errorHandler?.onDeleteError(attachment, error)) ?? true;
|
|
1057
|
+
if (!shouldRetry) {
|
|
1058
|
+
return {
|
|
1059
|
+
...attachment,
|
|
1060
|
+
state: exports.AttachmentState.ARCHIVED
|
|
1061
|
+
};
|
|
1062
|
+
}
|
|
1063
|
+
return attachment;
|
|
969
1064
|
}
|
|
970
1065
|
}
|
|
971
|
-
}
|
|
972
|
-
function timeoutSignal(timeout) {
|
|
973
|
-
if (timeout == null)
|
|
974
|
-
return;
|
|
975
|
-
if ('timeout' in AbortSignal)
|
|
976
|
-
return AbortSignal.timeout(timeout);
|
|
977
|
-
const controller = new AbortController();
|
|
978
|
-
setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
|
|
979
|
-
return controller.signal;
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
/**
|
|
983
|
-
* Service for querying and watching attachment records in the database.
|
|
984
|
-
*
|
|
985
|
-
* @internal
|
|
986
|
-
*/
|
|
987
|
-
class AttachmentService {
|
|
988
|
-
db;
|
|
989
|
-
logger;
|
|
990
|
-
tableName;
|
|
991
|
-
mutex = new Mutex();
|
|
992
|
-
context;
|
|
993
|
-
constructor(db, logger, tableName = 'attachments', archivedCacheLimit = 100) {
|
|
994
|
-
this.db = db;
|
|
995
|
-
this.logger = logger;
|
|
996
|
-
this.tableName = tableName;
|
|
997
|
-
this.context = new AttachmentContext(db, tableName, logger, archivedCacheLimit);
|
|
998
|
-
}
|
|
999
|
-
/**
|
|
1000
|
-
* Creates a differential watch query for active attachments requiring synchronization.
|
|
1001
|
-
* @returns Watch query that emits changes for queued uploads, downloads, and deletes
|
|
1002
|
-
*/
|
|
1003
|
-
watchActiveAttachments({ throttleMs } = {}) {
|
|
1004
|
-
this.logger.info('Watching active attachments...');
|
|
1005
|
-
const watch = this.db
|
|
1006
|
-
.query({
|
|
1007
|
-
sql: /* sql */ `
|
|
1008
|
-
SELECT
|
|
1009
|
-
*
|
|
1010
|
-
FROM
|
|
1011
|
-
${this.tableName}
|
|
1012
|
-
WHERE
|
|
1013
|
-
state = ?
|
|
1014
|
-
OR state = ?
|
|
1015
|
-
OR state = ?
|
|
1016
|
-
ORDER BY
|
|
1017
|
-
timestamp ASC
|
|
1018
|
-
`,
|
|
1019
|
-
parameters: [exports.AttachmentState.QUEUED_UPLOAD, exports.AttachmentState.QUEUED_DOWNLOAD, exports.AttachmentState.QUEUED_DELETE]
|
|
1020
|
-
})
|
|
1021
|
-
.differentialWatch({ throttleMs });
|
|
1022
|
-
return watch;
|
|
1023
|
-
}
|
|
1024
1066
|
/**
|
|
1025
|
-
*
|
|
1067
|
+
* Performs cleanup of archived attachments by removing their local files and records.
|
|
1068
|
+
* Errors during local file deletion are logged but do not prevent record deletion.
|
|
1026
1069
|
*/
|
|
1027
|
-
async
|
|
1028
|
-
return
|
|
1029
|
-
|
|
1070
|
+
async deleteArchivedAttachments(context) {
|
|
1071
|
+
return await context.deleteArchivedAttachments(async (archivedAttachments) => {
|
|
1072
|
+
for (const attachment of archivedAttachments) {
|
|
1073
|
+
if (attachment.localUri) {
|
|
1074
|
+
try {
|
|
1075
|
+
await this.localStorage.deleteFile(attachment.localUri);
|
|
1076
|
+
}
|
|
1077
|
+
catch (error) {
|
|
1078
|
+
this.logger.error('Error deleting local file for archived attachment', error);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1030
1082
|
});
|
|
1031
1083
|
}
|
|
1032
1084
|
}
|
|
@@ -1087,16 +1139,6 @@ class AttachmentQueue {
|
|
|
1087
1139
|
* Creates a new AttachmentQueue instance.
|
|
1088
1140
|
*
|
|
1089
1141
|
* @param options - Configuration options
|
|
1090
|
-
* @param options.db - PowerSync database instance
|
|
1091
|
-
* @param options.remoteStorage - Remote storage adapter for upload/download operations
|
|
1092
|
-
* @param options.localStorage - Local storage adapter for file persistence
|
|
1093
|
-
* @param options.watchAttachments - Callback for monitoring attachment changes in your data model
|
|
1094
|
-
* @param options.tableName - Name of the table to store attachment records. Default: 'ps_attachment_queue'
|
|
1095
|
-
* @param options.logger - Logger instance. Defaults to db.logger
|
|
1096
|
-
* @param options.syncIntervalMs - Periodic polling interval in milliseconds for retrying failed uploads/downloads. Default: 30000
|
|
1097
|
-
* @param options.syncThrottleDuration - Throttle duration in milliseconds for the reactive watch query that detects attachment changes. Prevents rapid-fire syncs during bulk changes. Default: 30
|
|
1098
|
-
* @param options.downloadAttachments - Whether to automatically download remote attachments. Default: true
|
|
1099
|
-
* @param options.archivedCacheLimit - Maximum archived attachments before cleanup. Default: 100
|
|
1100
1142
|
*/
|
|
1101
1143
|
constructor({ db, localStorage, remoteStorage, watchAttachments, logger, tableName = ATTACHMENT_TABLE, syncIntervalMs = 30 * 1000, syncThrottleDuration = DEFAULT_WATCH_THROTTLE_MS, downloadAttachments = true, archivedCacheLimit = 100, errorHandler }) {
|
|
1102
1144
|
this.db = db;
|
|
@@ -1185,6 +1227,7 @@ class AttachmentQueue {
|
|
|
1185
1227
|
state: exports.AttachmentState.QUEUED_DOWNLOAD,
|
|
1186
1228
|
hasSynced: false,
|
|
1187
1229
|
metaData: watchedAttachment.metaData,
|
|
1230
|
+
mediaType: watchedAttachment.mediaType,
|
|
1188
1231
|
timestamp: new Date().getTime()
|
|
1189
1232
|
});
|
|
1190
1233
|
continue;
|
|
@@ -1272,17 +1315,24 @@ class AttachmentQueue {
|
|
|
1272
1315
|
this.statusListenerDispose = undefined;
|
|
1273
1316
|
}
|
|
1274
1317
|
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Provides an {@link AttachmentContext} to a callback.
|
|
1320
|
+
*
|
|
1321
|
+
* The callback runs while the attachment queue mutex is held. Do not call
|
|
1322
|
+
* other {@link AttachmentQueue} methods from within the callback, as they may
|
|
1323
|
+
* attempt to acquire the same mutex and block indefinitely.
|
|
1324
|
+
*/
|
|
1325
|
+
withAttachmentContext(callback) {
|
|
1326
|
+
/**
|
|
1327
|
+
* AttachmentService is internal and private in this class.
|
|
1328
|
+
* We only need to expose its locking and context functionality for extending classes.
|
|
1329
|
+
*/
|
|
1330
|
+
return this.attachmentService.withContext(callback);
|
|
1331
|
+
}
|
|
1275
1332
|
/**
|
|
1276
1333
|
* Saves a file to local storage and queues it for upload to remote storage.
|
|
1277
1334
|
*
|
|
1278
1335
|
* @param options - File save options
|
|
1279
|
-
* @param options.data - The file data as ArrayBuffer, Blob, or base64 string
|
|
1280
|
-
* @param options.fileExtension - File extension (e.g., 'jpg', 'pdf')
|
|
1281
|
-
* @param options.mediaType - MIME type of the file (e.g., 'image/jpeg')
|
|
1282
|
-
* @param options.metaData - Optional metadata to associate with the attachment
|
|
1283
|
-
* @param options.id - Optional custom ID. If not provided, a UUID will be generated
|
|
1284
|
-
* @param options.updateHook - Optional callback to execute additional database operations
|
|
1285
|
-
* within the same transaction as the attachment creation
|
|
1286
1336
|
* @returns Promise resolving to the created attachment record
|
|
1287
1337
|
*/
|
|
1288
1338
|
async saveFile({ data, fileExtension, mediaType, metaData, id, updateHook }) {
|
|
@@ -1395,6 +1445,9 @@ class AttachmentQueue {
|
|
|
1395
1445
|
}
|
|
1396
1446
|
}
|
|
1397
1447
|
|
|
1448
|
+
/**
|
|
1449
|
+
* @alpha
|
|
1450
|
+
*/
|
|
1398
1451
|
exports.EncodingType = void 0;
|
|
1399
1452
|
(function (EncodingType) {
|
|
1400
1453
|
EncodingType["UTF8"] = "utf8";
|
|
@@ -1703,7 +1756,9 @@ var Logger = /*@__PURE__*/getDefaultExportFromCjs(loggerExports);
|
|
|
1703
1756
|
* different SQLite DB implementations.
|
|
1704
1757
|
*/
|
|
1705
1758
|
/**
|
|
1706
|
-
* Implements {@link DBGetUtils} on a {@link
|
|
1759
|
+
* Implements {@link DBGetUtils} on a {@link SqlExecutor}.
|
|
1760
|
+
*
|
|
1761
|
+
* @internal
|
|
1707
1762
|
*/
|
|
1708
1763
|
function DBGetUtilsDefaultMixin(Base) {
|
|
1709
1764
|
return class extends Base {
|
|
@@ -1747,6 +1802,8 @@ function DBGetUtilsDefaultMixin(Base) {
|
|
|
1747
1802
|
}
|
|
1748
1803
|
/**
|
|
1749
1804
|
* Update table operation numbers from SQLite
|
|
1805
|
+
*
|
|
1806
|
+
* @public
|
|
1750
1807
|
*/
|
|
1751
1808
|
exports.RowUpdateType = void 0;
|
|
1752
1809
|
(function (RowUpdateType) {
|
|
@@ -1755,8 +1812,10 @@ exports.RowUpdateType = void 0;
|
|
|
1755
1812
|
RowUpdateType[RowUpdateType["SQLITE_UPDATE"] = 23] = "SQLITE_UPDATE";
|
|
1756
1813
|
})(exports.RowUpdateType || (exports.RowUpdateType = {}));
|
|
1757
1814
|
/**
|
|
1758
|
-
* A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool
|
|
1759
|
-
* {@link ConnectionPool
|
|
1815
|
+
* A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool#readLock} and
|
|
1816
|
+
* {@link ConnectionPool#writeLock}.
|
|
1817
|
+
*
|
|
1818
|
+
* @internal
|
|
1760
1819
|
*/
|
|
1761
1820
|
function DBAdapterDefaultMixin(Base) {
|
|
1762
1821
|
return class extends Base {
|
|
@@ -1844,9 +1903,15 @@ class TransactionImplementation extends DBGetUtilsDefaultMixin(BaseTransaction)
|
|
|
1844
1903
|
}
|
|
1845
1904
|
}
|
|
1846
1905
|
}
|
|
1906
|
+
/**
|
|
1907
|
+
* @internal
|
|
1908
|
+
*/
|
|
1847
1909
|
function isBatchedUpdateNotification(update) {
|
|
1848
1910
|
return 'tables' in update;
|
|
1849
1911
|
}
|
|
1912
|
+
/**
|
|
1913
|
+
* @internal
|
|
1914
|
+
*/
|
|
1850
1915
|
function extractTableUpdates(update) {
|
|
1851
1916
|
return isBatchedUpdateNotification(update) ? update.tables : [update.table];
|
|
1852
1917
|
}
|
|
@@ -1874,6 +1939,8 @@ const FULL_SYNC_PRIORITY = 2147483647;
|
|
|
1874
1939
|
*
|
|
1875
1940
|
* Also note that data is downloaded in bulk, which means that individual counters are unlikely
|
|
1876
1941
|
* to be updated one-by-one.
|
|
1942
|
+
*
|
|
1943
|
+
* @public
|
|
1877
1944
|
*/
|
|
1878
1945
|
class SyncProgress {
|
|
1879
1946
|
internal;
|
|
@@ -1912,6 +1979,9 @@ class SyncProgress {
|
|
|
1912
1979
|
}
|
|
1913
1980
|
}
|
|
1914
1981
|
|
|
1982
|
+
/**
|
|
1983
|
+
* @public
|
|
1984
|
+
*/
|
|
1915
1985
|
class SyncStatus {
|
|
1916
1986
|
options;
|
|
1917
1987
|
constructor(options) {
|
|
@@ -1922,6 +1992,8 @@ class SyncStatus {
|
|
|
1922
1992
|
* implementation).
|
|
1923
1993
|
*
|
|
1924
1994
|
* This information is only available after a connection has been requested.
|
|
1995
|
+
*
|
|
1996
|
+
* @deprecated This always returns the Rust client (the only option).
|
|
1925
1997
|
*/
|
|
1926
1998
|
get clientImplementation() {
|
|
1927
1999
|
return this.options.clientImplementation;
|
|
@@ -1929,7 +2001,7 @@ class SyncStatus {
|
|
|
1929
2001
|
/**
|
|
1930
2002
|
* Indicates if the client is currently connected to the PowerSync service.
|
|
1931
2003
|
*
|
|
1932
|
-
* @returns
|
|
2004
|
+
* @returns True if connected, false otherwise. Defaults to false if not specified.
|
|
1933
2005
|
*/
|
|
1934
2006
|
get connected() {
|
|
1935
2007
|
return this.options.connected ?? false;
|
|
@@ -1937,7 +2009,7 @@ class SyncStatus {
|
|
|
1937
2009
|
/**
|
|
1938
2010
|
* Indicates if the client is in the process of establishing a connection to the PowerSync service.
|
|
1939
2011
|
*
|
|
1940
|
-
* @returns
|
|
2012
|
+
* @returns True if connecting, false otherwise. Defaults to false if not specified.
|
|
1941
2013
|
*/
|
|
1942
2014
|
get connecting() {
|
|
1943
2015
|
return this.options.connecting ?? false;
|
|
@@ -1946,7 +2018,7 @@ class SyncStatus {
|
|
|
1946
2018
|
* Time that a last sync has fully completed, if any.
|
|
1947
2019
|
* This timestamp is reset to null after a restart of the PowerSync service.
|
|
1948
2020
|
*
|
|
1949
|
-
* @returns
|
|
2021
|
+
* @returns The timestamp of the last successful sync, or undefined if no sync has completed.
|
|
1950
2022
|
*/
|
|
1951
2023
|
get lastSyncedAt() {
|
|
1952
2024
|
return this.options.lastSyncedAt;
|
|
@@ -1954,7 +2026,7 @@ class SyncStatus {
|
|
|
1954
2026
|
/**
|
|
1955
2027
|
* Indicates whether there has been at least one full sync completed since initialization.
|
|
1956
2028
|
*
|
|
1957
|
-
* @returns
|
|
2029
|
+
* @returns True if at least one sync has completed, false if no sync has completed,
|
|
1958
2030
|
* or undefined when the state is still being loaded from the database.
|
|
1959
2031
|
*/
|
|
1960
2032
|
get hasSynced() {
|
|
@@ -1963,10 +2035,10 @@ class SyncStatus {
|
|
|
1963
2035
|
/**
|
|
1964
2036
|
* Provides the current data flow status regarding uploads and downloads.
|
|
1965
2037
|
*
|
|
1966
|
-
* @returns
|
|
2038
|
+
* @returns An object containing:
|
|
1967
2039
|
* - downloading: True if actively downloading changes (only when connected is also true)
|
|
1968
2040
|
* - uploading: True if actively uploading changes
|
|
1969
|
-
* Defaults to {downloading: false, uploading: false} if not specified.
|
|
2041
|
+
* Defaults to `{downloading: false, uploading: false}` if not specified.
|
|
1970
2042
|
*/
|
|
1971
2043
|
get dataFlowStatus() {
|
|
1972
2044
|
return (this.options.dataFlow ?? {
|
|
@@ -1991,7 +2063,7 @@ class SyncStatus {
|
|
|
1991
2063
|
return this.options.dataFlow?.internalStreamSubscriptions?.map((core) => new SyncStreamStatusView(this, core));
|
|
1992
2064
|
}
|
|
1993
2065
|
/**
|
|
1994
|
-
* If the `stream` appears in {@link syncStreams}, returns the current status for that stream.
|
|
2066
|
+
* If the `stream` appears in {@link SyncStatus.syncStreams}, returns the current status for that stream.
|
|
1995
2067
|
*/
|
|
1996
2068
|
forStream(stream) {
|
|
1997
2069
|
const asJson = JSON.stringify(stream.parameters);
|
|
@@ -2001,7 +2073,7 @@ class SyncStatus {
|
|
|
2001
2073
|
/**
|
|
2002
2074
|
* Provides sync status information for all bucket priorities, sorted by priority (highest first).
|
|
2003
2075
|
*
|
|
2004
|
-
* @returns
|
|
2076
|
+
* @returns An array of status entries for different sync priority levels,
|
|
2005
2077
|
* sorted with highest priorities (lower numbers) first.
|
|
2006
2078
|
*/
|
|
2007
2079
|
get priorityStatusEntries() {
|
|
@@ -2036,8 +2108,8 @@ class SyncStatus {
|
|
|
2036
2108
|
* For example, if PowerSync just finished synchronizing buckets in priority level 3, calling this method
|
|
2037
2109
|
* with a priority of 1 may return information for priority level 3.
|
|
2038
2110
|
*
|
|
2039
|
-
* @param
|
|
2040
|
-
* @returns
|
|
2111
|
+
* @param priority - The bucket priority for which the status should be reported
|
|
2112
|
+
* @returns Status information for the requested priority level or the next higher level with available status
|
|
2041
2113
|
*/
|
|
2042
2114
|
statusForPriority(priority) {
|
|
2043
2115
|
// priorityStatusEntries are sorted by ascending priorities (so higher numbers to lower numbers).
|
|
@@ -2058,8 +2130,8 @@ class SyncStatus {
|
|
|
2058
2130
|
* Compares this SyncStatus instance with another to determine if they are equal.
|
|
2059
2131
|
* Equality is determined by comparing the serialized JSON representation of both instances.
|
|
2060
2132
|
*
|
|
2061
|
-
* @param
|
|
2062
|
-
* @returns
|
|
2133
|
+
* @param status - The SyncStatus instance to compare against
|
|
2134
|
+
* @returns True if the instances are considered equal, false otherwise
|
|
2063
2135
|
*/
|
|
2064
2136
|
isEqual(status) {
|
|
2065
2137
|
/**
|
|
@@ -2082,7 +2154,7 @@ class SyncStatus {
|
|
|
2082
2154
|
* Creates a human-readable string representation of the current sync status.
|
|
2083
2155
|
* Includes information about connection state, sync completion, and data flow.
|
|
2084
2156
|
*
|
|
2085
|
-
* @returns
|
|
2157
|
+
* @returns A string representation of the sync status
|
|
2086
2158
|
*/
|
|
2087
2159
|
getMessage() {
|
|
2088
2160
|
const dataFlow = this.dataFlowStatus;
|
|
@@ -2091,7 +2163,7 @@ class SyncStatus {
|
|
|
2091
2163
|
/**
|
|
2092
2164
|
* Serializes the SyncStatus instance to a plain object.
|
|
2093
2165
|
*
|
|
2094
|
-
* @returns
|
|
2166
|
+
* @returns A plain object representation of the sync status
|
|
2095
2167
|
*/
|
|
2096
2168
|
toJSON() {
|
|
2097
2169
|
return {
|
|
@@ -2157,6 +2229,9 @@ class SyncStreamStatusView {
|
|
|
2157
2229
|
}
|
|
2158
2230
|
}
|
|
2159
2231
|
|
|
2232
|
+
/**
|
|
2233
|
+
* @public
|
|
2234
|
+
*/
|
|
2160
2235
|
class UploadQueueStats {
|
|
2161
2236
|
count;
|
|
2162
2237
|
size;
|
|
@@ -2182,6 +2257,9 @@ class UploadQueueStats {
|
|
|
2182
2257
|
}
|
|
2183
2258
|
}
|
|
2184
2259
|
|
|
2260
|
+
/**
|
|
2261
|
+
* @internal
|
|
2262
|
+
*/
|
|
2185
2263
|
class BaseObserver {
|
|
2186
2264
|
listeners = new Set();
|
|
2187
2265
|
constructor() { }
|
|
@@ -2209,6 +2287,9 @@ class BaseObserver {
|
|
|
2209
2287
|
}
|
|
2210
2288
|
}
|
|
2211
2289
|
|
|
2290
|
+
/**
|
|
2291
|
+
* @internal
|
|
2292
|
+
*/
|
|
2212
2293
|
class ControlledExecutor {
|
|
2213
2294
|
task;
|
|
2214
2295
|
/**
|
|
@@ -2476,7 +2557,7 @@ class ConnectionManager extends BaseObserver {
|
|
|
2476
2557
|
/**
|
|
2477
2558
|
* Close the sync connection.
|
|
2478
2559
|
*
|
|
2479
|
-
* Use {@link connect} to connect again.
|
|
2560
|
+
* Use {@link ConnectionManager.connect} to connect again.
|
|
2480
2561
|
*/
|
|
2481
2562
|
async disconnect() {
|
|
2482
2563
|
// This will help abort pending connects
|
|
@@ -2616,6 +2697,8 @@ const _finalizer = 'FinalizationRegistry' in globalThis
|
|
|
2616
2697
|
/**
|
|
2617
2698
|
* An efficient comparator for {@link WatchedQuery} created with {@link Query#watch}. This has the ability to determine if a query
|
|
2618
2699
|
* result has changes without necessarily processing all items in the result.
|
|
2700
|
+
*
|
|
2701
|
+
* @public
|
|
2619
2702
|
*/
|
|
2620
2703
|
class ArrayComparator {
|
|
2621
2704
|
options;
|
|
@@ -2643,6 +2726,8 @@ class ArrayComparator {
|
|
|
2643
2726
|
}
|
|
2644
2727
|
/**
|
|
2645
2728
|
* Watched query comparator that always reports changed result sets.
|
|
2729
|
+
*
|
|
2730
|
+
* @public
|
|
2646
2731
|
*/
|
|
2647
2732
|
const FalsyComparator = {
|
|
2648
2733
|
checkEquality: () => false // Default comparator that always returns false
|
|
@@ -2850,6 +2935,8 @@ class AbstractQueryProcessor extends MetaBaseObserver {
|
|
|
2850
2935
|
/**
|
|
2851
2936
|
* An empty differential result set.
|
|
2852
2937
|
* This is used as the initial state for differential incrementally watched queries.
|
|
2938
|
+
*
|
|
2939
|
+
* @internal
|
|
2853
2940
|
*/
|
|
2854
2941
|
const EMPTY_DIFFERENTIAL = {
|
|
2855
2942
|
added: [],
|
|
@@ -2862,6 +2949,8 @@ const EMPTY_DIFFERENTIAL = {
|
|
|
2862
2949
|
* Default implementation of the {@link DifferentialWatchedQueryComparator} for watched queries.
|
|
2863
2950
|
* It keys items by their `id` property if available, alternatively it uses JSON stringification
|
|
2864
2951
|
* of the entire item for the key and comparison.
|
|
2952
|
+
*
|
|
2953
|
+
* @internal
|
|
2865
2954
|
*/
|
|
2866
2955
|
const DEFAULT_ROW_COMPARATOR = {
|
|
2867
2956
|
keyBy: (item) => {
|
|
@@ -3142,6 +3231,8 @@ class CustomQuery {
|
|
|
3142
3231
|
|
|
3143
3232
|
/**
|
|
3144
3233
|
* Tests if the input is a {@link SQLOpenOptions}
|
|
3234
|
+
*
|
|
3235
|
+
* @internal
|
|
3145
3236
|
*/
|
|
3146
3237
|
const isSQLOpenOptions = (test) => {
|
|
3147
3238
|
// typeof null is `object`, but you cannot use the `in` operator on `null.
|
|
@@ -3149,17 +3240,24 @@ const isSQLOpenOptions = (test) => {
|
|
|
3149
3240
|
};
|
|
3150
3241
|
/**
|
|
3151
3242
|
* Tests if input is a {@link SQLOpenFactory}
|
|
3243
|
+
*
|
|
3244
|
+
* @internal
|
|
3152
3245
|
*/
|
|
3153
3246
|
const isSQLOpenFactory = (test) => {
|
|
3154
3247
|
return typeof test?.openDB == 'function';
|
|
3155
3248
|
};
|
|
3156
3249
|
/**
|
|
3157
3250
|
* Tests if input is a {@link DBAdapter}
|
|
3251
|
+
*
|
|
3252
|
+
* @internal
|
|
3158
3253
|
*/
|
|
3159
3254
|
const isDBAdapter = (test) => {
|
|
3160
3255
|
return typeof test?.writeTransaction == 'function';
|
|
3161
3256
|
};
|
|
3162
3257
|
|
|
3258
|
+
/**
|
|
3259
|
+
* @internal
|
|
3260
|
+
*/
|
|
3163
3261
|
exports.PSInternalTable = void 0;
|
|
3164
3262
|
(function (PSInternalTable) {
|
|
3165
3263
|
PSInternalTable["DATA"] = "ps_data";
|
|
@@ -3168,6 +3266,9 @@ exports.PSInternalTable = void 0;
|
|
|
3168
3266
|
PSInternalTable["OPLOG"] = "ps_oplog";
|
|
3169
3267
|
PSInternalTable["UNTYPED"] = "ps_untyped";
|
|
3170
3268
|
})(exports.PSInternalTable || (exports.PSInternalTable = {}));
|
|
3269
|
+
/**
|
|
3270
|
+
* @internal
|
|
3271
|
+
*/
|
|
3171
3272
|
exports.PowerSyncControlCommand = void 0;
|
|
3172
3273
|
(function (PowerSyncControlCommand) {
|
|
3173
3274
|
PowerSyncControlCommand["PROCESS_TEXT_LINE"] = "line_text";
|
|
@@ -3185,6 +3286,8 @@ exports.PowerSyncControlCommand = void 0;
|
|
|
3185
3286
|
|
|
3186
3287
|
/**
|
|
3187
3288
|
* A batch of client-side changes.
|
|
3289
|
+
*
|
|
3290
|
+
* @public
|
|
3188
3291
|
*/
|
|
3189
3292
|
class CrudBatch {
|
|
3190
3293
|
crud;
|
|
@@ -3211,6 +3314,8 @@ class CrudBatch {
|
|
|
3211
3314
|
|
|
3212
3315
|
/**
|
|
3213
3316
|
* Type of local change.
|
|
3317
|
+
*
|
|
3318
|
+
* @public
|
|
3214
3319
|
*/
|
|
3215
3320
|
exports.UpdateType = void 0;
|
|
3216
3321
|
(function (UpdateType) {
|
|
@@ -3223,6 +3328,8 @@ exports.UpdateType = void 0;
|
|
|
3223
3328
|
})(exports.UpdateType || (exports.UpdateType = {}));
|
|
3224
3329
|
/**
|
|
3225
3330
|
* A single client-side change.
|
|
3331
|
+
*
|
|
3332
|
+
* @public
|
|
3226
3333
|
*/
|
|
3227
3334
|
class CrudEntry {
|
|
3228
3335
|
/**
|
|
@@ -3319,6 +3426,9 @@ class CrudEntry {
|
|
|
3319
3426
|
}
|
|
3320
3427
|
}
|
|
3321
3428
|
|
|
3429
|
+
/**
|
|
3430
|
+
* @public
|
|
3431
|
+
*/
|
|
3322
3432
|
class CrudTransaction extends CrudBatch {
|
|
3323
3433
|
crud;
|
|
3324
3434
|
complete;
|
|
@@ -3347,6 +3457,8 @@ class CrudTransaction extends CrudBatch {
|
|
|
3347
3457
|
* Calls to Abortcontroller.abort(reason: any) will result in the
|
|
3348
3458
|
* `reason` being thrown. This is not necessarily an error,
|
|
3349
3459
|
* but extends error for better logging purposes.
|
|
3460
|
+
*
|
|
3461
|
+
* @internal
|
|
3350
3462
|
*/
|
|
3351
3463
|
class AbortOperation extends Error {
|
|
3352
3464
|
reason;
|
|
@@ -8146,7 +8258,7 @@ function requireDist () {
|
|
|
8146
8258
|
|
|
8147
8259
|
var distExports = requireDist();
|
|
8148
8260
|
|
|
8149
|
-
var version = "1.
|
|
8261
|
+
var version = "1.54.0";
|
|
8150
8262
|
var PACKAGE = {
|
|
8151
8263
|
version: version};
|
|
8152
8264
|
|
|
@@ -8276,7 +8388,8 @@ class WebsocketClientTransport {
|
|
|
8276
8388
|
removeListeners();
|
|
8277
8389
|
resolve(new WebsocketDuplexConnectionExports.WebsocketDuplexConnection(websocket, new distExports.Deserializer(), multiplexerDemultiplexerFactory));
|
|
8278
8390
|
};
|
|
8279
|
-
const errorListener = (
|
|
8391
|
+
const errorListener = (event) => {
|
|
8392
|
+
const ev = event;
|
|
8280
8393
|
removeListeners();
|
|
8281
8394
|
// We add a default error in that case.
|
|
8282
8395
|
if (ev.error != null) {
|
|
@@ -8519,7 +8632,13 @@ const SOCKET_TIMEOUT_MS = 30_000;
|
|
|
8519
8632
|
// If there is a backlog of messages (for example on slow connections), keepalive messages could be delayed
|
|
8520
8633
|
// significantly. Therefore this is longer than the socket timeout.
|
|
8521
8634
|
const KEEP_ALIVE_LIFETIME_MS = 90_000;
|
|
8635
|
+
/**
|
|
8636
|
+
* @internal
|
|
8637
|
+
*/
|
|
8522
8638
|
const DEFAULT_REMOTE_LOGGER = Logger.get('PowerSyncRemote');
|
|
8639
|
+
/**
|
|
8640
|
+
* @public
|
|
8641
|
+
*/
|
|
8523
8642
|
exports.FetchStrategy = void 0;
|
|
8524
8643
|
(function (FetchStrategy) {
|
|
8525
8644
|
/**
|
|
@@ -8538,12 +8657,17 @@ exports.FetchStrategy = void 0;
|
|
|
8538
8657
|
* The class wrapper is used to distinguish the fetchImplementation
|
|
8539
8658
|
* option in [AbstractRemoteOptions] from the general fetch method
|
|
8540
8659
|
* which is typeof "function"
|
|
8660
|
+
*
|
|
8661
|
+
* @internal
|
|
8541
8662
|
*/
|
|
8542
8663
|
class FetchImplementationProvider {
|
|
8543
8664
|
getFetch() {
|
|
8544
8665
|
throw new Error('Unspecified fetch implementation');
|
|
8545
8666
|
}
|
|
8546
8667
|
}
|
|
8668
|
+
/**
|
|
8669
|
+
* @internal
|
|
8670
|
+
*/
|
|
8547
8671
|
const DEFAULT_REMOTE_OPTIONS = {
|
|
8548
8672
|
socketUrlTransformer: (url) => url.replace(/^https?:\/\//, function (match) {
|
|
8549
8673
|
return match === 'https://' ? 'wss://' : 'ws://';
|
|
@@ -8551,6 +8675,9 @@ const DEFAULT_REMOTE_OPTIONS = {
|
|
|
8551
8675
|
fetchImplementation: new FetchImplementationProvider(),
|
|
8552
8676
|
fetchOptions: {}
|
|
8553
8677
|
};
|
|
8678
|
+
/**
|
|
8679
|
+
* @internal
|
|
8680
|
+
*/
|
|
8554
8681
|
class AbstractRemote {
|
|
8555
8682
|
connector;
|
|
8556
8683
|
logger;
|
|
@@ -8960,7 +9087,7 @@ class AbstractRemote {
|
|
|
8960
9087
|
* Posts a `/sync/stream` request.
|
|
8961
9088
|
*
|
|
8962
9089
|
* Depending on the `Content-Type` of the response, this returns strings for sync lines or encoded BSON documents as
|
|
8963
|
-
*
|
|
9090
|
+
* `Uint8Array`s.
|
|
8964
9091
|
*/
|
|
8965
9092
|
async fetchStream(options) {
|
|
8966
9093
|
const { isBson, stream } = await this.fetchStreamRaw(options);
|
|
@@ -9002,16 +9129,26 @@ function isInterruptingInstruction(instruction) {
|
|
|
9002
9129
|
return 'EstablishSyncStream' in instruction || 'CloseSyncStream' in instruction;
|
|
9003
9130
|
}
|
|
9004
9131
|
|
|
9132
|
+
/**
|
|
9133
|
+
* @internal
|
|
9134
|
+
*/
|
|
9005
9135
|
exports.LockType = void 0;
|
|
9006
9136
|
(function (LockType) {
|
|
9007
9137
|
LockType["CRUD"] = "crud";
|
|
9008
9138
|
LockType["SYNC"] = "sync";
|
|
9009
9139
|
})(exports.LockType || (exports.LockType = {}));
|
|
9140
|
+
/**
|
|
9141
|
+
* @public
|
|
9142
|
+
*/
|
|
9010
9143
|
exports.SyncStreamConnectionMethod = void 0;
|
|
9011
9144
|
(function (SyncStreamConnectionMethod) {
|
|
9012
9145
|
SyncStreamConnectionMethod["HTTP"] = "http";
|
|
9013
9146
|
SyncStreamConnectionMethod["WEB_SOCKET"] = "web-socket";
|
|
9014
9147
|
})(exports.SyncStreamConnectionMethod || (exports.SyncStreamConnectionMethod = {}));
|
|
9148
|
+
/**
|
|
9149
|
+
* @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
|
|
9150
|
+
* @public
|
|
9151
|
+
*/
|
|
9015
9152
|
exports.SyncClientImplementation = void 0;
|
|
9016
9153
|
(function (SyncClientImplementation) {
|
|
9017
9154
|
/**
|
|
@@ -9023,8 +9160,8 @@ exports.SyncClientImplementation = void 0;
|
|
|
9023
9160
|
* ## Compatibility warning
|
|
9024
9161
|
*
|
|
9025
9162
|
* The Rust sync client stores sync data in a format that is slightly different than the one used
|
|
9026
|
-
* by the old JavaScript client. When adopting the {@link RUST} client on existing databases,
|
|
9027
|
-
* migrate the format automatically.
|
|
9163
|
+
* by the old JavaScript client. When adopting the {@link SyncClientImplementation.RUST} client on existing databases,
|
|
9164
|
+
* the PowerSync SDK will migrate the format automatically.
|
|
9028
9165
|
*
|
|
9029
9166
|
* SDK versions supporting both the JavaScript and the Rust client support both formats with the JavaScript client
|
|
9030
9167
|
* implementaiton. However, downgrading to an SDK version that only supports the JavaScript client would not be
|
|
@@ -9034,14 +9171,29 @@ exports.SyncClientImplementation = void 0;
|
|
|
9034
9171
|
})(exports.SyncClientImplementation || (exports.SyncClientImplementation = {}));
|
|
9035
9172
|
/**
|
|
9036
9173
|
* The default {@link SyncClientImplementation} to use, {@link SyncClientImplementation.RUST}.
|
|
9174
|
+
*
|
|
9175
|
+
* @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
|
|
9176
|
+
* @public
|
|
9037
9177
|
*/
|
|
9038
9178
|
const DEFAULT_SYNC_CLIENT_IMPLEMENTATION = exports.SyncClientImplementation.RUST;
|
|
9179
|
+
/**
|
|
9180
|
+
* @internal
|
|
9181
|
+
*/
|
|
9039
9182
|
const DEFAULT_CRUD_UPLOAD_THROTTLE_MS = 1000;
|
|
9183
|
+
/**
|
|
9184
|
+
* @internal
|
|
9185
|
+
*/
|
|
9040
9186
|
const DEFAULT_RETRY_DELAY_MS = 5000;
|
|
9187
|
+
/**
|
|
9188
|
+
* @internal
|
|
9189
|
+
*/
|
|
9041
9190
|
const DEFAULT_STREAMING_SYNC_OPTIONS = {
|
|
9042
9191
|
retryDelayMs: DEFAULT_RETRY_DELAY_MS,
|
|
9043
9192
|
crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
|
|
9044
9193
|
};
|
|
9194
|
+
/**
|
|
9195
|
+
* @internal
|
|
9196
|
+
*/
|
|
9045
9197
|
const DEFAULT_STREAM_CONNECTION_OPTIONS = {
|
|
9046
9198
|
appMetadata: {},
|
|
9047
9199
|
connectionMethod: exports.SyncStreamConnectionMethod.WEB_SOCKET,
|
|
@@ -9051,6 +9203,9 @@ const DEFAULT_STREAM_CONNECTION_OPTIONS = {
|
|
|
9051
9203
|
serializedSchema: undefined,
|
|
9052
9204
|
includeDefaultStreams: true
|
|
9053
9205
|
};
|
|
9206
|
+
/**
|
|
9207
|
+
* @internal
|
|
9208
|
+
*/
|
|
9054
9209
|
class AbstractStreamingSyncImplementation extends BaseObserver {
|
|
9055
9210
|
options;
|
|
9056
9211
|
abortController;
|
|
@@ -9374,7 +9529,7 @@ The next upload iteration will be delayed.`);
|
|
|
9374
9529
|
this.handleActiveStreamsChange?.();
|
|
9375
9530
|
}
|
|
9376
9531
|
/**
|
|
9377
|
-
* Older versions of the JS SDK used to encode subkeys as JSON in
|
|
9532
|
+
* Older versions of the JS SDK used to encode subkeys as JSON in `OplogEntry.toJSON`.
|
|
9378
9533
|
* Because subkeys are always strings, this leads to quotes being added around them in `ps_oplog`.
|
|
9379
9534
|
* While this is not a problem as long as it's done consistently, it causes issues when a database
|
|
9380
9535
|
* created by the JS SDK is used with other SDKs, or (more likely) when the new Rust sync client
|
|
@@ -9384,7 +9539,7 @@ The next upload iteration will be delayed.`);
|
|
|
9384
9539
|
* migration is only triggered when necessary (for now). The function returns whether the new format
|
|
9385
9540
|
* should be used, so that the JS SDK is able to write to updated databases.
|
|
9386
9541
|
*
|
|
9387
|
-
* @param requireFixedKeyFormat Whether we require the new format or also support the old one.
|
|
9542
|
+
* @param requireFixedKeyFormat - Whether we require the new format or also support the old one.
|
|
9388
9543
|
* The Rust client requires the new subkey format.
|
|
9389
9544
|
* @returns Whether the database is now using the new, fixed subkey format.
|
|
9390
9545
|
*/
|
|
@@ -9691,7 +9846,8 @@ const MEMORY_TRIGGER_CLAIM_MANAGER = {
|
|
|
9691
9846
|
|
|
9692
9847
|
/**
|
|
9693
9848
|
* SQLite operations to track changes for with {@link TriggerManager}
|
|
9694
|
-
*
|
|
9849
|
+
*
|
|
9850
|
+
* @experimental @alpha
|
|
9695
9851
|
*/
|
|
9696
9852
|
exports.DiffTriggerOperation = void 0;
|
|
9697
9853
|
(function (DiffTriggerOperation) {
|
|
@@ -9753,8 +9909,8 @@ class TriggerManagerImpl {
|
|
|
9753
9909
|
get db() {
|
|
9754
9910
|
return this.options.db;
|
|
9755
9911
|
}
|
|
9756
|
-
async getUUID() {
|
|
9757
|
-
const { id: uuid } = await this.db.get(/* sql */ `
|
|
9912
|
+
async getUUID(ctx) {
|
|
9913
|
+
const { id: uuid } = await (ctx ?? this.db).get(/* sql */ `
|
|
9758
9914
|
SELECT
|
|
9759
9915
|
uuid () as id
|
|
9760
9916
|
`);
|
|
@@ -9867,7 +10023,7 @@ class TriggerManagerImpl {
|
|
|
9867
10023
|
const replicatedColumns = columns ?? sourceDefinition.columns.map((col) => col.name);
|
|
9868
10024
|
const internalSource = sourceDefinition.internalName;
|
|
9869
10025
|
const triggerIds = [];
|
|
9870
|
-
const id = await this.getUUID();
|
|
10026
|
+
const id = await this.getUUID(setupContext);
|
|
9871
10027
|
const releaseStorageClaim = useStorage ? await this.options.claimManager.obtainClaim(id) : null;
|
|
9872
10028
|
/**
|
|
9873
10029
|
* We default to replicating all columns if no columns array is provided.
|
|
@@ -10107,18 +10263,29 @@ const POWERSYNC_TABLE_MATCH = /(^ps_data__|^ps_data_local__)/;
|
|
|
10107
10263
|
const DEFAULT_DISCONNECT_CLEAR_OPTIONS = {
|
|
10108
10264
|
clearLocal: true
|
|
10109
10265
|
};
|
|
10266
|
+
/**
|
|
10267
|
+
* @internal
|
|
10268
|
+
*/
|
|
10110
10269
|
const DEFAULT_POWERSYNC_CLOSE_OPTIONS = {
|
|
10111
10270
|
disconnect: true
|
|
10112
10271
|
};
|
|
10272
|
+
/**
|
|
10273
|
+
* @internal
|
|
10274
|
+
*/
|
|
10113
10275
|
const DEFAULT_POWERSYNC_DB_OPTIONS = {
|
|
10114
10276
|
retryDelayMs: 5000,
|
|
10115
10277
|
crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
|
|
10116
10278
|
};
|
|
10279
|
+
/**
|
|
10280
|
+
* @internal
|
|
10281
|
+
*/
|
|
10117
10282
|
const DEFAULT_CRUD_BATCH_LIMIT = 100;
|
|
10118
10283
|
/**
|
|
10119
10284
|
* Requesting nested or recursive locks can block the application in some circumstances.
|
|
10120
10285
|
* This default lock timeout will act as a failsafe to throw an error if a lock cannot
|
|
10121
10286
|
* be obtained.
|
|
10287
|
+
*
|
|
10288
|
+
* @internal
|
|
10122
10289
|
*/
|
|
10123
10290
|
const DEFAULT_LOCK_TIMEOUT_MS = 120_000; // 2 mins
|
|
10124
10291
|
/**
|
|
@@ -10128,6 +10295,9 @@ const DEFAULT_LOCK_TIMEOUT_MS = 120_000; // 2 mins
|
|
|
10128
10295
|
const isPowerSyncDatabaseOptionsWithSettings = (test) => {
|
|
10129
10296
|
return typeof test == 'object' && isSQLOpenOptions(test.database);
|
|
10130
10297
|
};
|
|
10298
|
+
/**
|
|
10299
|
+
* @public
|
|
10300
|
+
*/
|
|
10131
10301
|
class AbstractPowerSyncDatabase extends BaseObserver {
|
|
10132
10302
|
options;
|
|
10133
10303
|
/**
|
|
@@ -10285,7 +10455,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
10285
10455
|
/**
|
|
10286
10456
|
* Wait for the first sync operation to complete.
|
|
10287
10457
|
*
|
|
10288
|
-
* @param request Either an abort signal (after which the promise will complete regardless of
|
|
10458
|
+
* @param request - Either an abort signal (after which the promise will complete regardless of
|
|
10289
10459
|
* whether a full sync was completed) or an object providing an abort signal and a priority target.
|
|
10290
10460
|
* When a priority target is set, the promise may complete when all buckets with the given (or higher)
|
|
10291
10461
|
* priorities have been synchronized. This can be earlier than a complete sync.
|
|
@@ -10440,7 +10610,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
10440
10610
|
/**
|
|
10441
10611
|
* Close the sync connection.
|
|
10442
10612
|
*
|
|
10443
|
-
* Use {@link connect} to connect again.
|
|
10613
|
+
* Use {@link AbstractPowerSyncDatabase.connect} to connect again.
|
|
10444
10614
|
*/
|
|
10445
10615
|
async disconnect() {
|
|
10446
10616
|
return this.connectionManager.disconnect();
|
|
@@ -10467,8 +10637,8 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
10467
10637
|
/**
|
|
10468
10638
|
* Create a sync stream to query its status or to subscribe to it.
|
|
10469
10639
|
*
|
|
10470
|
-
* @param name The name of the stream to subscribe to.
|
|
10471
|
-
* @param params Optional parameters for the stream subscription.
|
|
10640
|
+
* @param name - The name of the stream to subscribe to.
|
|
10641
|
+
* @param params - Optional parameters for the stream subscription.
|
|
10472
10642
|
* @returns A {@link SyncStream} instance that can be subscribed to.
|
|
10473
10643
|
* @experimental Sync streams are currently in alpha.
|
|
10474
10644
|
*/
|
|
@@ -10526,14 +10696,14 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
10526
10696
|
* Once the data have been successfully uploaded, call {@link CrudBatch.complete} before
|
|
10527
10697
|
* requesting the next batch.
|
|
10528
10698
|
*
|
|
10529
|
-
* Use
|
|
10699
|
+
* Use the `limit` parameter to specify the maximum number of updates to return in a single
|
|
10530
10700
|
* batch.
|
|
10531
10701
|
*
|
|
10532
10702
|
* This method does include transaction ids in the result, but does not group
|
|
10533
10703
|
* data by transaction. One batch may contain data from multiple transactions,
|
|
10534
10704
|
* and a single transaction may be split over multiple batches.
|
|
10535
10705
|
*
|
|
10536
|
-
* @param limit Maximum number of CRUD entries to include in the batch
|
|
10706
|
+
* @param limit - Maximum number of CRUD entries to include in the batch
|
|
10537
10707
|
* @returns A batch of CRUD operations to upload, or null if there are none
|
|
10538
10708
|
*/
|
|
10539
10709
|
async getCrudBatch(limit = DEFAULT_CRUD_BATCH_LIMIT) {
|
|
@@ -10560,7 +10730,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
10560
10730
|
* Once the data have been successfully uploaded, call {@link CrudTransaction.complete} before
|
|
10561
10731
|
* requesting the next transaction.
|
|
10562
10732
|
*
|
|
10563
|
-
* Unlike {@link getCrudBatch}, this only returns data from a single transaction at a time.
|
|
10733
|
+
* Unlike {@link AbstractPowerSyncDatabase.getCrudBatch}, this only returns data from a single transaction at a time.
|
|
10564
10734
|
* All data for the transaction is loaded into memory.
|
|
10565
10735
|
*
|
|
10566
10736
|
* @returns A transaction of CRUD operations to upload, or null if there are none
|
|
@@ -10575,7 +10745,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
10575
10745
|
* This is typically used from the {@link PowerSyncBackendConnector.uploadData} callback. Each entry emitted by the
|
|
10576
10746
|
* returned iterator is a full transaction containing all local writes made while that transaction was active.
|
|
10577
10747
|
*
|
|
10578
|
-
* Unlike {@link getNextCrudTransaction}, which always returns the oldest transaction that hasn't been
|
|
10748
|
+
* Unlike {@link AbstractPowerSyncDatabase.getNextCrudTransaction}, which always returns the oldest transaction that hasn't been
|
|
10579
10749
|
* {@link CrudTransaction.complete}d yet, this iterator can be used to receive multiple transactions. Calling
|
|
10580
10750
|
* {@link CrudTransaction.complete} will mark that and all prior transactions emitted by the iterator as completed.
|
|
10581
10751
|
*
|
|
@@ -10669,8 +10839,8 @@ SELECT * FROM crud_entries;
|
|
|
10669
10839
|
* the returned result's `rowsAffected` may be `0` for successful `UPDATE` and `DELETE` statements.
|
|
10670
10840
|
* Use a `RETURNING` clause and inspect `result.rows` when you need to confirm which rows changed.
|
|
10671
10841
|
*
|
|
10672
|
-
* @param sql The SQL query to execute
|
|
10673
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
10842
|
+
* @param sql - The SQL query to execute
|
|
10843
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
10674
10844
|
* @returns The query result as an object with structured key-value pairs
|
|
10675
10845
|
*/
|
|
10676
10846
|
async execute(sql, parameters) {
|
|
@@ -10680,8 +10850,8 @@ SELECT * FROM crud_entries;
|
|
|
10680
10850
|
* Execute a SQL write (INSERT/UPDATE/DELETE) query directly on the database without any PowerSync processing.
|
|
10681
10851
|
* This bypasses certain PowerSync abstractions and is useful for accessing the raw database results.
|
|
10682
10852
|
*
|
|
10683
|
-
* @param sql The SQL query to execute
|
|
10684
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
10853
|
+
* @param sql - The SQL query to execute
|
|
10854
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
10685
10855
|
* @returns The raw query result from the underlying database as a nested array of raw values, where each row is
|
|
10686
10856
|
* represented as an array of column values without field names.
|
|
10687
10857
|
*/
|
|
@@ -10694,8 +10864,8 @@ SELECT * FROM crud_entries;
|
|
|
10694
10864
|
* and optionally return results.
|
|
10695
10865
|
* This is faster than executing separately with each parameter set.
|
|
10696
10866
|
*
|
|
10697
|
-
* @param sql The SQL query to execute
|
|
10698
|
-
* @param parameters Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
|
|
10867
|
+
* @param sql - The SQL query to execute
|
|
10868
|
+
* @param parameters - Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
|
|
10699
10869
|
* @returns The query result
|
|
10700
10870
|
*/
|
|
10701
10871
|
async executeBatch(sql, parameters) {
|
|
@@ -10705,8 +10875,8 @@ SELECT * FROM crud_entries;
|
|
|
10705
10875
|
/**
|
|
10706
10876
|
* Execute a read-only query and return results.
|
|
10707
10877
|
*
|
|
10708
|
-
* @param sql The SQL query to execute
|
|
10709
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
10878
|
+
* @param sql - The SQL query to execute
|
|
10879
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
10710
10880
|
* @returns An array of results
|
|
10711
10881
|
*/
|
|
10712
10882
|
async getAll(sql, parameters) {
|
|
@@ -10716,8 +10886,8 @@ SELECT * FROM crud_entries;
|
|
|
10716
10886
|
/**
|
|
10717
10887
|
* Execute a read-only query and return the first result, or null if the ResultSet is empty.
|
|
10718
10888
|
*
|
|
10719
|
-
* @param sql The SQL query to execute
|
|
10720
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
10889
|
+
* @param sql - The SQL query to execute
|
|
10890
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
10721
10891
|
* @returns The first result if found, or null if no results are returned
|
|
10722
10892
|
*/
|
|
10723
10893
|
async getOptional(sql, parameters) {
|
|
@@ -10727,8 +10897,8 @@ SELECT * FROM crud_entries;
|
|
|
10727
10897
|
/**
|
|
10728
10898
|
* Execute a read-only query and return the first result, error if the ResultSet is empty.
|
|
10729
10899
|
*
|
|
10730
|
-
* @param sql The SQL query to execute
|
|
10731
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
10900
|
+
* @param sql - The SQL query to execute
|
|
10901
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
10732
10902
|
* @returns The first result matching the query
|
|
10733
10903
|
* @throws Error if no rows are returned
|
|
10734
10904
|
*/
|
|
@@ -10738,7 +10908,7 @@ SELECT * FROM crud_entries;
|
|
|
10738
10908
|
}
|
|
10739
10909
|
/**
|
|
10740
10910
|
* Takes a read lock, without starting a transaction.
|
|
10741
|
-
* In most cases, {@link readTransaction} should be used instead.
|
|
10911
|
+
* In most cases, {@link AbstractPowerSyncDatabase.readTransaction} should be used instead.
|
|
10742
10912
|
*/
|
|
10743
10913
|
async readLock(callback) {
|
|
10744
10914
|
await this.waitForReady();
|
|
@@ -10746,7 +10916,7 @@ SELECT * FROM crud_entries;
|
|
|
10746
10916
|
}
|
|
10747
10917
|
/**
|
|
10748
10918
|
* Takes a global lock, without starting a transaction.
|
|
10749
|
-
* In most cases, {@link writeTransaction} should be used instead.
|
|
10919
|
+
* In most cases, {@link AbstractPowerSyncDatabase.writeTransaction} should be used instead.
|
|
10750
10920
|
*/
|
|
10751
10921
|
async writeLock(callback) {
|
|
10752
10922
|
await this.waitForReady();
|
|
@@ -10757,8 +10927,8 @@ SELECT * FROM crud_entries;
|
|
|
10757
10927
|
* Read transactions can run concurrently to a write transaction.
|
|
10758
10928
|
* Changes from any write transaction are not visible to read transactions started before it.
|
|
10759
10929
|
*
|
|
10760
|
-
* @param callback Function to execute within the transaction
|
|
10761
|
-
* @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
|
|
10930
|
+
* @param callback - Function to execute within the transaction
|
|
10931
|
+
* @param lockTimeout - Time in milliseconds to wait for a lock before throwing an error
|
|
10762
10932
|
* @returns The result of the callback
|
|
10763
10933
|
* @throws Error if the lock cannot be obtained within the timeout period
|
|
10764
10934
|
*/
|
|
@@ -10775,8 +10945,8 @@ SELECT * FROM crud_entries;
|
|
|
10775
10945
|
* This takes a global lock - only one write transaction can execute against the database at a time.
|
|
10776
10946
|
* Statements within the transaction must be done on the provided {@link Transaction} interface.
|
|
10777
10947
|
*
|
|
10778
|
-
* @param callback Function to execute within the transaction
|
|
10779
|
-
* @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
|
|
10948
|
+
* @param callback - Function to execute within the transaction
|
|
10949
|
+
* @param lockTimeout - Time in milliseconds to wait for a lock before throwing an error
|
|
10780
10950
|
* @returns The result of the callback
|
|
10781
10951
|
* @throws Error if the lock cannot be obtained within the timeout period
|
|
10782
10952
|
*/
|
|
@@ -10853,15 +11023,15 @@ SELECT * FROM crud_entries;
|
|
|
10853
11023
|
}
|
|
10854
11024
|
/**
|
|
10855
11025
|
* Execute a read query every time the source tables are modified.
|
|
10856
|
-
* Use {@link
|
|
11026
|
+
* Use {@link SQLOnChangeOptions.throttleMs} to specify the minimum interval between queries.
|
|
10857
11027
|
* Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
|
|
10858
11028
|
*
|
|
10859
11029
|
* Note that the `onChange` callback member of the handler is required.
|
|
10860
11030
|
*
|
|
10861
|
-
* @param sql The SQL query to execute
|
|
10862
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
10863
|
-
* @param handler Callbacks for handling results and errors
|
|
10864
|
-
* @param options Options for configuring watch behavior
|
|
11031
|
+
* @param sql - The SQL query to execute
|
|
11032
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
11033
|
+
* @param handler - Callbacks for handling results and errors
|
|
11034
|
+
* @param options - Options for configuring watch behavior
|
|
10865
11035
|
*/
|
|
10866
11036
|
watchWithCallback(sql, parameters, handler, options) {
|
|
10867
11037
|
const { onResult, onError = (e) => this.logger.error(e) } = handler ?? {};
|
|
@@ -10874,7 +11044,7 @@ SELECT * FROM crud_entries;
|
|
|
10874
11044
|
const watchedQuery = new OnChangeQueryProcessor({
|
|
10875
11045
|
db: this,
|
|
10876
11046
|
comparator,
|
|
10877
|
-
placeholderData: null,
|
|
11047
|
+
placeholderData: null, // FIXME
|
|
10878
11048
|
watchOptions: {
|
|
10879
11049
|
query: {
|
|
10880
11050
|
compile: () => ({
|
|
@@ -10907,12 +11077,12 @@ SELECT * FROM crud_entries;
|
|
|
10907
11077
|
}
|
|
10908
11078
|
/**
|
|
10909
11079
|
* Execute a read query every time the source tables are modified.
|
|
10910
|
-
* Use {@link
|
|
11080
|
+
* Use {@link SQLOnChangeOptions.throttleMs} to specify the minimum interval between queries.
|
|
10911
11081
|
* Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
|
|
10912
11082
|
*
|
|
10913
|
-
* @param sql The SQL query to execute
|
|
10914
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
10915
|
-
* @param options Options for configuring watch behavior
|
|
11083
|
+
* @param sql - The SQL query to execute
|
|
11084
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
11085
|
+
* @param options - Options for configuring watch behavior
|
|
10916
11086
|
* @returns An AsyncIterable that yields QueryResults whenever the data changes
|
|
10917
11087
|
*/
|
|
10918
11088
|
watchWithAsyncGenerator(sql, parameters, options) {
|
|
@@ -10936,9 +11106,9 @@ SELECT * FROM crud_entries;
|
|
|
10936
11106
|
* If tables are specified in the options, those are used directly.
|
|
10937
11107
|
* Otherwise, analyzes the query using EXPLAIN to determine which tables are accessed.
|
|
10938
11108
|
*
|
|
10939
|
-
* @param sql The SQL query to analyze
|
|
10940
|
-
* @param parameters Optional parameters for the SQL query
|
|
10941
|
-
* @param options Optional watch options that may contain explicit table list
|
|
11109
|
+
* @param sql - The SQL query to analyze
|
|
11110
|
+
* @param parameters - Optional parameters for the SQL query
|
|
11111
|
+
* @param options - Optional watch options that may contain explicit table list
|
|
10942
11112
|
* @returns Array of table names that the query depends on
|
|
10943
11113
|
*/
|
|
10944
11114
|
async resolveTables(sql, parameters, options) {
|
|
@@ -10967,13 +11137,13 @@ SELECT * FROM crud_entries;
|
|
|
10967
11137
|
/**
|
|
10968
11138
|
* Invoke the provided callback on any changes to any of the specified tables.
|
|
10969
11139
|
*
|
|
10970
|
-
* This is preferred over {@link watchWithCallback} when multiple queries need to be performed
|
|
11140
|
+
* This is preferred over {@link AbstractPowerSyncDatabase.watchWithCallback} when multiple queries need to be performed
|
|
10971
11141
|
* together when data is changed.
|
|
10972
11142
|
*
|
|
10973
11143
|
* Note that the `onChange` callback member of the handler is required.
|
|
10974
11144
|
*
|
|
10975
|
-
* @param handler Callbacks for handling change events and errors
|
|
10976
|
-
* @param options Options for configuring watch behavior
|
|
11145
|
+
* @param handler - Callbacks for handling change events and errors
|
|
11146
|
+
* @param options - Options for configuring watch behavior
|
|
10977
11147
|
* @returns A dispose function to stop watching for changes
|
|
10978
11148
|
*/
|
|
10979
11149
|
onChangeWithCallback(handler, options) {
|
|
@@ -11016,12 +11186,12 @@ SELECT * FROM crud_entries;
|
|
|
11016
11186
|
/**
|
|
11017
11187
|
* Create a Stream of changes to any of the specified tables.
|
|
11018
11188
|
*
|
|
11019
|
-
* This is preferred over {@link watchWithAsyncGenerator} when multiple queries need to be
|
|
11020
|
-
* together when data is changed.
|
|
11189
|
+
* This is preferred over {@link AbstractPowerSyncDatabase.watchWithAsyncGenerator} when multiple queries need to be
|
|
11190
|
+
* performed together when data is changed.
|
|
11021
11191
|
*
|
|
11022
11192
|
* Note: do not declare this as `async *onChange` as it will not work in React Native.
|
|
11023
11193
|
*
|
|
11024
|
-
* @param options Options for configuring watch behavior
|
|
11194
|
+
* @param options - Options for configuring watch behavior
|
|
11025
11195
|
* @returns An AsyncIterable that yields change events whenever the specified tables change
|
|
11026
11196
|
*/
|
|
11027
11197
|
onChangeWithAsyncGenerator(options) {
|
|
@@ -11059,15 +11229,15 @@ SELECT * FROM crud_entries;
|
|
|
11059
11229
|
changedTables.add(table);
|
|
11060
11230
|
}
|
|
11061
11231
|
}
|
|
11062
|
-
/**
|
|
11063
|
-
* @ignore
|
|
11064
|
-
*/
|
|
11065
11232
|
async executeReadOnly(sql, params) {
|
|
11066
11233
|
await this.waitForReady();
|
|
11067
11234
|
return this.database.readLock((tx) => tx.execute(sql, params));
|
|
11068
11235
|
}
|
|
11069
11236
|
}
|
|
11070
11237
|
|
|
11238
|
+
/**
|
|
11239
|
+
* @internal
|
|
11240
|
+
*/
|
|
11071
11241
|
class AbstractPowerSyncDatabaseOpenFactory {
|
|
11072
11242
|
options;
|
|
11073
11243
|
constructor(options) {
|
|
@@ -11092,6 +11262,9 @@ class AbstractPowerSyncDatabaseOpenFactory {
|
|
|
11092
11262
|
}
|
|
11093
11263
|
}
|
|
11094
11264
|
|
|
11265
|
+
/**
|
|
11266
|
+
* @internal
|
|
11267
|
+
*/
|
|
11095
11268
|
function runOnSchemaChange(callback, db, options) {
|
|
11096
11269
|
const triggerWatchedQuery = () => {
|
|
11097
11270
|
const abortController = new AbortController();
|
|
@@ -11116,6 +11289,9 @@ function runOnSchemaChange(callback, db, options) {
|
|
|
11116
11289
|
triggerWatchedQuery();
|
|
11117
11290
|
}
|
|
11118
11291
|
|
|
11292
|
+
/**
|
|
11293
|
+
* @public
|
|
11294
|
+
*/
|
|
11119
11295
|
function compilableQueryWatch(db, query, handler, options) {
|
|
11120
11296
|
const { onResult, onError = (e) => { } } = handler ?? {};
|
|
11121
11297
|
if (!onResult) {
|
|
@@ -11153,8 +11329,14 @@ function compilableQueryWatch(db, query, handler, options) {
|
|
|
11153
11329
|
runOnSchemaChange(watchQuery, db, options);
|
|
11154
11330
|
}
|
|
11155
11331
|
|
|
11332
|
+
/**
|
|
11333
|
+
* @internal
|
|
11334
|
+
*/
|
|
11156
11335
|
const MAX_OP_ID = '9223372036854775807';
|
|
11157
11336
|
|
|
11337
|
+
/**
|
|
11338
|
+
* @internal
|
|
11339
|
+
*/
|
|
11158
11340
|
class SqliteBucketStorage extends BaseObserver {
|
|
11159
11341
|
db;
|
|
11160
11342
|
logger;
|
|
@@ -11315,6 +11497,8 @@ class SqliteBucketStorage extends BaseObserver {
|
|
|
11315
11497
|
* Thrown when an underlying database connection is closed.
|
|
11316
11498
|
* This is particularly relevant when worker connections are marked as closed while
|
|
11317
11499
|
* operations are still in progress.
|
|
11500
|
+
*
|
|
11501
|
+
* @internal
|
|
11318
11502
|
*/
|
|
11319
11503
|
class ConnectionClosedError extends Error {
|
|
11320
11504
|
static NAME = 'ConnectionClosedError';
|
|
@@ -11334,6 +11518,8 @@ class ConnectionClosedError extends Error {
|
|
|
11334
11518
|
|
|
11335
11519
|
/**
|
|
11336
11520
|
* A schema is a collection of tables. It is used to define the structure of a database.
|
|
11521
|
+
*
|
|
11522
|
+
* @public
|
|
11337
11523
|
*/
|
|
11338
11524
|
class Schema {
|
|
11339
11525
|
/*
|
|
@@ -11370,7 +11556,7 @@ class Schema {
|
|
|
11370
11556
|
* Since raw tables are not backed by JSON, running complex queries on them may be more efficient. Further, they allow
|
|
11371
11557
|
* using client-side table and column constraints.
|
|
11372
11558
|
*
|
|
11373
|
-
* @param tables An object of (table name, raw table definition) entries.
|
|
11559
|
+
* @param tables - An object of (table name, raw table definition) entries.
|
|
11374
11560
|
*/
|
|
11375
11561
|
withRawTables(tables) {
|
|
11376
11562
|
for (const [name, rawTableDefinition] of Object.entries(tables)) {
|
|
@@ -11416,6 +11602,8 @@ class Schema {
|
|
|
11416
11602
|
Generate a new table from the columns and indexes
|
|
11417
11603
|
@deprecated You should use {@link Table} instead as it now allows TableV2 syntax.
|
|
11418
11604
|
This will be removed in the next major release.
|
|
11605
|
+
|
|
11606
|
+
@public
|
|
11419
11607
|
*/
|
|
11420
11608
|
class TableV2 extends Table {
|
|
11421
11609
|
}
|
|
@@ -11426,6 +11614,8 @@ function sanitizeString(input) {
|
|
|
11426
11614
|
/**
|
|
11427
11615
|
* Helper function for sanitizing UUID input strings.
|
|
11428
11616
|
* Typically used with {@link sanitizeSQL}.
|
|
11617
|
+
*
|
|
11618
|
+
* @alpha
|
|
11429
11619
|
*/
|
|
11430
11620
|
function sanitizeUUID(uuid) {
|
|
11431
11621
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
@@ -11462,6 +11652,8 @@ function sanitizeUUID(uuid) {
|
|
|
11462
11652
|
* // Incorrect:
|
|
11463
11653
|
* sanitizeSQL`New.id = '${myID}'` // Produces double quotes: New.id = ''O''Reilly''
|
|
11464
11654
|
* ```
|
|
11655
|
+
*
|
|
11656
|
+
* @alpha
|
|
11465
11657
|
*/
|
|
11466
11658
|
function sanitizeSQL(strings, ...values) {
|
|
11467
11659
|
let result = '';
|
|
@@ -11491,6 +11683,8 @@ function sanitizeSQL(strings, ...values) {
|
|
|
11491
11683
|
|
|
11492
11684
|
/**
|
|
11493
11685
|
* Performs a {@link AbstractPowerSyncDatabase.getAll} operation for a watched query.
|
|
11686
|
+
*
|
|
11687
|
+
* @public
|
|
11494
11688
|
*/
|
|
11495
11689
|
class GetAllQuery {
|
|
11496
11690
|
options;
|
|
@@ -11515,6 +11709,9 @@ class GetAllQuery {
|
|
|
11515
11709
|
}
|
|
11516
11710
|
|
|
11517
11711
|
const TypedLogger = Logger;
|
|
11712
|
+
/**
|
|
11713
|
+
* @public
|
|
11714
|
+
*/
|
|
11518
11715
|
const LogLevel = {
|
|
11519
11716
|
TRACE: TypedLogger.TRACE,
|
|
11520
11717
|
DEBUG: TypedLogger.DEBUG,
|
|
@@ -11531,6 +11728,7 @@ const LogLevel = {
|
|
|
11531
11728
|
* across all loggers created with `createLogger`. Adjusting settings on this
|
|
11532
11729
|
* base logger affects all loggers derived from it unless explicitly overridden.
|
|
11533
11730
|
*
|
|
11731
|
+
* @public
|
|
11534
11732
|
*/
|
|
11535
11733
|
function createBaseLogger() {
|
|
11536
11734
|
return Logger;
|
|
@@ -11541,6 +11739,8 @@ function createBaseLogger() {
|
|
|
11541
11739
|
* Named loggers allow specific modules or areas of your application to have
|
|
11542
11740
|
* their own logging levels and behaviors. These loggers inherit configuration
|
|
11543
11741
|
* from the base logger by default but can override settings independently.
|
|
11742
|
+
*
|
|
11743
|
+
* @public
|
|
11544
11744
|
*/
|
|
11545
11745
|
function createLogger(name, options = {}) {
|
|
11546
11746
|
const logger = Logger.get(name);
|
|
@@ -11550,6 +11750,9 @@ function createLogger(name, options = {}) {
|
|
|
11550
11750
|
return logger;
|
|
11551
11751
|
}
|
|
11552
11752
|
|
|
11753
|
+
/**
|
|
11754
|
+
* @internal
|
|
11755
|
+
*/
|
|
11553
11756
|
const parseQuery = (query, parameters) => {
|
|
11554
11757
|
let sqlStatement;
|
|
11555
11758
|
if (typeof query == 'string') {
|