@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.cjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @see https://www.sqlite.org/lang_expr.html#castexpr
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
4
7
|
exports.ColumnType = void 0;
|
|
5
8
|
(function (ColumnType) {
|
|
6
9
|
ColumnType["TEXT"] = "TEXT";
|
|
@@ -16,14 +19,24 @@ const integer = {
|
|
|
16
19
|
const real = {
|
|
17
20
|
type: exports.ColumnType.REAL
|
|
18
21
|
};
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
/**
|
|
23
|
+
* powersync-sqlite-core limits the number of column per table to 1999, due to internal SQLite limits.
|
|
24
|
+
* In earlier versions this was limited to 63.
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
21
28
|
const MAX_AMOUNT_OF_COLUMNS = 1999;
|
|
29
|
+
/**
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
22
32
|
const column = {
|
|
23
33
|
text,
|
|
24
34
|
integer,
|
|
25
35
|
real
|
|
26
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
27
40
|
class Column {
|
|
28
41
|
options;
|
|
29
42
|
constructor(options) {
|
|
@@ -43,9 +56,15 @@ class Column {
|
|
|
43
56
|
}
|
|
44
57
|
}
|
|
45
58
|
|
|
59
|
+
/**
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
46
62
|
const DEFAULT_INDEX_COLUMN_OPTIONS = {
|
|
47
63
|
ascending: true
|
|
48
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
49
68
|
class IndexedColumn {
|
|
50
69
|
options;
|
|
51
70
|
static createAscending(column) {
|
|
@@ -72,9 +91,15 @@ class IndexedColumn {
|
|
|
72
91
|
}
|
|
73
92
|
}
|
|
74
93
|
|
|
94
|
+
/**
|
|
95
|
+
* @internal
|
|
96
|
+
*/
|
|
75
97
|
const DEFAULT_INDEX_OPTIONS = {
|
|
76
98
|
columns: []
|
|
77
99
|
};
|
|
100
|
+
/**
|
|
101
|
+
* @public
|
|
102
|
+
*/
|
|
78
103
|
class Index {
|
|
79
104
|
options;
|
|
80
105
|
static createAscending(options, columnNames) {
|
|
@@ -116,6 +141,9 @@ function encodeTableOptions(options) {
|
|
|
116
141
|
};
|
|
117
142
|
}
|
|
118
143
|
|
|
144
|
+
/**
|
|
145
|
+
* @internal
|
|
146
|
+
*/
|
|
119
147
|
const DEFAULT_TABLE_OPTIONS = {
|
|
120
148
|
indexes: [],
|
|
121
149
|
insertOnly: false,
|
|
@@ -124,7 +152,13 @@ const DEFAULT_TABLE_OPTIONS = {
|
|
|
124
152
|
trackMetadata: false,
|
|
125
153
|
ignoreEmptyUpdates: false
|
|
126
154
|
};
|
|
155
|
+
/**
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
127
158
|
const InvalidSQLCharacters = /["'%,.#\s[\]]/;
|
|
159
|
+
/**
|
|
160
|
+
* @public
|
|
161
|
+
*/
|
|
128
162
|
class Table {
|
|
129
163
|
options;
|
|
130
164
|
_mappedColumns;
|
|
@@ -315,6 +349,11 @@ class Table {
|
|
|
315
349
|
}
|
|
316
350
|
}
|
|
317
351
|
|
|
352
|
+
/**
|
|
353
|
+
* The default name of the local table storing attachment data.
|
|
354
|
+
*
|
|
355
|
+
* @alpha
|
|
356
|
+
*/
|
|
318
357
|
const ATTACHMENT_TABLE = 'attachments';
|
|
319
358
|
/**
|
|
320
359
|
* Maps a database row to an AttachmentRecord.
|
|
@@ -322,7 +361,7 @@ const ATTACHMENT_TABLE = 'attachments';
|
|
|
322
361
|
* @param row - The database row object
|
|
323
362
|
* @returns The corresponding AttachmentRecord
|
|
324
363
|
*
|
|
325
|
-
* @
|
|
364
|
+
* @alpha
|
|
326
365
|
*/
|
|
327
366
|
function attachmentFromSql(row) {
|
|
328
367
|
return {
|
|
@@ -340,7 +379,7 @@ function attachmentFromSql(row) {
|
|
|
340
379
|
/**
|
|
341
380
|
* AttachmentState represents the current synchronization state of an attachment.
|
|
342
381
|
*
|
|
343
|
-
* @
|
|
382
|
+
* @alpha
|
|
344
383
|
*/
|
|
345
384
|
exports.AttachmentState = void 0;
|
|
346
385
|
(function (AttachmentState) {
|
|
@@ -353,7 +392,7 @@ exports.AttachmentState = void 0;
|
|
|
353
392
|
/**
|
|
354
393
|
* AttachmentTable defines the schema for the attachment queue table.
|
|
355
394
|
*
|
|
356
|
-
* @
|
|
395
|
+
* @alpha
|
|
357
396
|
*/
|
|
358
397
|
class AttachmentTable extends Table {
|
|
359
398
|
constructor(options) {
|
|
@@ -381,7 +420,8 @@ class AttachmentTable extends Table {
|
|
|
381
420
|
* Provides methods to query, insert, update, and delete attachment records with
|
|
382
421
|
* proper transaction management through PowerSync.
|
|
383
422
|
*
|
|
384
|
-
* @
|
|
423
|
+
* @experimental
|
|
424
|
+
* @alpha
|
|
385
425
|
*/
|
|
386
426
|
class AttachmentContext {
|
|
387
427
|
/** PowerSync database instance for executing queries */
|
|
@@ -603,6 +643,9 @@ class AttachmentContext {
|
|
|
603
643
|
}
|
|
604
644
|
}
|
|
605
645
|
|
|
646
|
+
/**
|
|
647
|
+
* @public
|
|
648
|
+
*/
|
|
606
649
|
exports.WatchedQueryListenerEvent = void 0;
|
|
607
650
|
(function (WatchedQueryListenerEvent) {
|
|
608
651
|
WatchedQueryListenerEvent["ON_DATA"] = "onData";
|
|
@@ -611,176 +654,18 @@ exports.WatchedQueryListenerEvent = void 0;
|
|
|
611
654
|
WatchedQueryListenerEvent["SETTINGS_WILL_UPDATE"] = "settingsWillUpdate";
|
|
612
655
|
WatchedQueryListenerEvent["CLOSED"] = "closed";
|
|
613
656
|
})(exports.WatchedQueryListenerEvent || (exports.WatchedQueryListenerEvent = {}));
|
|
657
|
+
/**
|
|
658
|
+
* @internal
|
|
659
|
+
*/
|
|
614
660
|
const DEFAULT_WATCH_THROTTLE_MS = 30;
|
|
661
|
+
/**
|
|
662
|
+
* @internal
|
|
663
|
+
*/
|
|
615
664
|
const DEFAULT_WATCH_QUERY_OPTIONS = {
|
|
616
665
|
throttleMs: DEFAULT_WATCH_THROTTLE_MS,
|
|
617
666
|
reportFetching: true
|
|
618
667
|
};
|
|
619
668
|
|
|
620
|
-
/**
|
|
621
|
-
* Orchestrates attachment synchronization between local and remote storage.
|
|
622
|
-
* Handles uploads, downloads, deletions, and state transitions.
|
|
623
|
-
*
|
|
624
|
-
* @internal
|
|
625
|
-
*/
|
|
626
|
-
class SyncingService {
|
|
627
|
-
attachmentService;
|
|
628
|
-
localStorage;
|
|
629
|
-
remoteStorage;
|
|
630
|
-
logger;
|
|
631
|
-
errorHandler;
|
|
632
|
-
constructor(attachmentService, localStorage, remoteStorage, logger, errorHandler) {
|
|
633
|
-
this.attachmentService = attachmentService;
|
|
634
|
-
this.localStorage = localStorage;
|
|
635
|
-
this.remoteStorage = remoteStorage;
|
|
636
|
-
this.logger = logger;
|
|
637
|
-
this.errorHandler = errorHandler;
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* Processes attachments based on their state (upload, download, or delete).
|
|
641
|
-
* All updates are saved in a single batch after processing.
|
|
642
|
-
*
|
|
643
|
-
* @param attachments - Array of attachment records to process
|
|
644
|
-
* @param context - Attachment context for database operations
|
|
645
|
-
* @returns Promise that resolves when all attachments have been processed and saved
|
|
646
|
-
*/
|
|
647
|
-
async processAttachments(attachments, context) {
|
|
648
|
-
const updatedAttachments = [];
|
|
649
|
-
for (const attachment of attachments) {
|
|
650
|
-
switch (attachment.state) {
|
|
651
|
-
case exports.AttachmentState.QUEUED_UPLOAD:
|
|
652
|
-
const uploaded = await this.uploadAttachment(attachment);
|
|
653
|
-
updatedAttachments.push(uploaded);
|
|
654
|
-
break;
|
|
655
|
-
case exports.AttachmentState.QUEUED_DOWNLOAD:
|
|
656
|
-
const downloaded = await this.downloadAttachment(attachment);
|
|
657
|
-
updatedAttachments.push(downloaded);
|
|
658
|
-
break;
|
|
659
|
-
case exports.AttachmentState.QUEUED_DELETE:
|
|
660
|
-
const deleted = await this.deleteAttachment(attachment, context);
|
|
661
|
-
updatedAttachments.push(deleted);
|
|
662
|
-
break;
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
await context.saveAttachments(updatedAttachments);
|
|
666
|
-
}
|
|
667
|
-
/**
|
|
668
|
-
* Uploads an attachment from local storage to remote storage.
|
|
669
|
-
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
670
|
-
*
|
|
671
|
-
* @param attachment - The attachment record to upload
|
|
672
|
-
* @returns Updated attachment record with new state
|
|
673
|
-
* @throws Error if the attachment has no localUri
|
|
674
|
-
*/
|
|
675
|
-
async uploadAttachment(attachment) {
|
|
676
|
-
this.logger.info(`Uploading attachment ${attachment.filename}`);
|
|
677
|
-
try {
|
|
678
|
-
if (attachment.localUri == null) {
|
|
679
|
-
throw new Error(`No localUri for attachment ${attachment.id}`);
|
|
680
|
-
}
|
|
681
|
-
const fileBlob = await this.localStorage.readFile(attachment.localUri);
|
|
682
|
-
await this.remoteStorage.uploadFile(fileBlob, attachment);
|
|
683
|
-
return {
|
|
684
|
-
...attachment,
|
|
685
|
-
state: exports.AttachmentState.SYNCED,
|
|
686
|
-
hasSynced: true
|
|
687
|
-
};
|
|
688
|
-
}
|
|
689
|
-
catch (error) {
|
|
690
|
-
const shouldRetry = (await this.errorHandler?.onUploadError(attachment, error)) ?? true;
|
|
691
|
-
if (!shouldRetry) {
|
|
692
|
-
return {
|
|
693
|
-
...attachment,
|
|
694
|
-
state: exports.AttachmentState.ARCHIVED
|
|
695
|
-
};
|
|
696
|
-
}
|
|
697
|
-
return attachment;
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
/**
|
|
701
|
-
* Downloads an attachment from remote storage to local storage.
|
|
702
|
-
* Retrieves the file, converts to base64, and saves locally.
|
|
703
|
-
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
704
|
-
*
|
|
705
|
-
* @param attachment - The attachment record to download
|
|
706
|
-
* @returns Updated attachment record with local URI and new state
|
|
707
|
-
*/
|
|
708
|
-
async downloadAttachment(attachment) {
|
|
709
|
-
this.logger.info(`Downloading attachment ${attachment.filename}`);
|
|
710
|
-
try {
|
|
711
|
-
const fileData = await this.remoteStorage.downloadFile(attachment);
|
|
712
|
-
const localUri = this.localStorage.getLocalUri(attachment.filename);
|
|
713
|
-
await this.localStorage.saveFile(localUri, fileData);
|
|
714
|
-
return {
|
|
715
|
-
...attachment,
|
|
716
|
-
state: exports.AttachmentState.SYNCED,
|
|
717
|
-
localUri: localUri,
|
|
718
|
-
hasSynced: true
|
|
719
|
-
};
|
|
720
|
-
}
|
|
721
|
-
catch (error) {
|
|
722
|
-
const shouldRetry = (await this.errorHandler?.onDownloadError(attachment, error)) ?? true;
|
|
723
|
-
if (!shouldRetry) {
|
|
724
|
-
return {
|
|
725
|
-
...attachment,
|
|
726
|
-
state: exports.AttachmentState.ARCHIVED
|
|
727
|
-
};
|
|
728
|
-
}
|
|
729
|
-
return attachment;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* Deletes an attachment from both remote and local storage.
|
|
734
|
-
* Removes the remote file, local file (if exists), and the attachment record.
|
|
735
|
-
* On failure, defers to error handler or archives.
|
|
736
|
-
*
|
|
737
|
-
* @param attachment - The attachment record to delete
|
|
738
|
-
* @param context - Attachment context for database operations
|
|
739
|
-
* @returns Updated attachment record
|
|
740
|
-
*/
|
|
741
|
-
async deleteAttachment(attachment, context) {
|
|
742
|
-
try {
|
|
743
|
-
await this.remoteStorage.deleteFile(attachment);
|
|
744
|
-
if (attachment.localUri) {
|
|
745
|
-
await this.localStorage.deleteFile(attachment.localUri);
|
|
746
|
-
}
|
|
747
|
-
await context.deleteAttachment(attachment.id);
|
|
748
|
-
return {
|
|
749
|
-
...attachment,
|
|
750
|
-
state: exports.AttachmentState.ARCHIVED
|
|
751
|
-
};
|
|
752
|
-
}
|
|
753
|
-
catch (error) {
|
|
754
|
-
const shouldRetry = (await this.errorHandler?.onDeleteError(attachment, error)) ?? true;
|
|
755
|
-
if (!shouldRetry) {
|
|
756
|
-
return {
|
|
757
|
-
...attachment,
|
|
758
|
-
state: exports.AttachmentState.ARCHIVED
|
|
759
|
-
};
|
|
760
|
-
}
|
|
761
|
-
return attachment;
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
/**
|
|
765
|
-
* Performs cleanup of archived attachments by removing their local files and records.
|
|
766
|
-
* Errors during local file deletion are logged but do not prevent record deletion.
|
|
767
|
-
*/
|
|
768
|
-
async deleteArchivedAttachments(context) {
|
|
769
|
-
return await context.deleteArchivedAttachments(async (archivedAttachments) => {
|
|
770
|
-
for (const attachment of archivedAttachments) {
|
|
771
|
-
if (attachment.localUri) {
|
|
772
|
-
try {
|
|
773
|
-
await this.localStorage.deleteFile(attachment.localUri);
|
|
774
|
-
}
|
|
775
|
-
catch (error) {
|
|
776
|
-
this.logger.error('Error deleting local file for archived attachment', error);
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
});
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
|
|
784
669
|
/**
|
|
785
670
|
* A simple fixed-capacity queue implementation.
|
|
786
671
|
*
|
|
@@ -937,93 +822,260 @@ class Semaphore {
|
|
|
937
822
|
return { release, item: items[0] };
|
|
938
823
|
}
|
|
939
824
|
/**
|
|
940
|
-
* Requests access to all items from the pool.
|
|
825
|
+
* Requests access to all items from the pool.
|
|
826
|
+
*
|
|
827
|
+
* The returned `release` callback must be invoked to return items into the pool.
|
|
828
|
+
*/
|
|
829
|
+
requestAll(abort) {
|
|
830
|
+
return this.requestPermits(this.size, abort);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* An asynchronous mutex implementation.
|
|
835
|
+
*
|
|
836
|
+
* @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
|
|
837
|
+
*/
|
|
838
|
+
class Mutex {
|
|
839
|
+
inner = new Semaphore([null]);
|
|
840
|
+
async acquire(abort) {
|
|
841
|
+
const { release } = await this.inner.requestOne(abort);
|
|
842
|
+
return release;
|
|
843
|
+
}
|
|
844
|
+
async runExclusive(fn, abort) {
|
|
845
|
+
const returnMutex = await this.acquire(abort);
|
|
846
|
+
try {
|
|
847
|
+
return await fn();
|
|
848
|
+
}
|
|
849
|
+
finally {
|
|
850
|
+
returnMutex();
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* @internal
|
|
856
|
+
*/
|
|
857
|
+
function timeoutSignal(timeout) {
|
|
858
|
+
if (timeout == null)
|
|
859
|
+
return;
|
|
860
|
+
if ('timeout' in AbortSignal)
|
|
861
|
+
return AbortSignal.timeout(timeout);
|
|
862
|
+
const controller = new AbortController();
|
|
863
|
+
setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
|
|
864
|
+
return controller.signal;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* Service for querying and watching attachment records in the database.
|
|
869
|
+
*
|
|
870
|
+
* @internal
|
|
871
|
+
*/
|
|
872
|
+
class AttachmentService {
|
|
873
|
+
db;
|
|
874
|
+
logger;
|
|
875
|
+
tableName;
|
|
876
|
+
mutex = new Mutex();
|
|
877
|
+
context;
|
|
878
|
+
constructor(db, logger, tableName = 'attachments', archivedCacheLimit = 100) {
|
|
879
|
+
this.db = db;
|
|
880
|
+
this.logger = logger;
|
|
881
|
+
this.tableName = tableName;
|
|
882
|
+
this.context = new AttachmentContext(db, tableName, logger, archivedCacheLimit);
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Creates a differential watch query for active attachments requiring synchronization.
|
|
886
|
+
* @returns Watch query that emits changes for queued uploads, downloads, and deletes
|
|
887
|
+
*/
|
|
888
|
+
watchActiveAttachments({ throttleMs } = {}) {
|
|
889
|
+
this.logger.info('Watching active attachments...');
|
|
890
|
+
const watch = this.db
|
|
891
|
+
.query({
|
|
892
|
+
sql: /* sql */ `
|
|
893
|
+
SELECT
|
|
894
|
+
*
|
|
895
|
+
FROM
|
|
896
|
+
${this.tableName}
|
|
897
|
+
WHERE
|
|
898
|
+
state = ?
|
|
899
|
+
OR state = ?
|
|
900
|
+
OR state = ?
|
|
901
|
+
ORDER BY
|
|
902
|
+
timestamp ASC
|
|
903
|
+
`,
|
|
904
|
+
parameters: [exports.AttachmentState.QUEUED_UPLOAD, exports.AttachmentState.QUEUED_DOWNLOAD, exports.AttachmentState.QUEUED_DELETE]
|
|
905
|
+
})
|
|
906
|
+
.differentialWatch({ throttleMs });
|
|
907
|
+
return watch;
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Executes a callback with exclusive access to the attachment context.
|
|
911
|
+
*/
|
|
912
|
+
async withContext(callback) {
|
|
913
|
+
return this.mutex.runExclusive(async () => {
|
|
914
|
+
return callback(this.context);
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Orchestrates attachment synchronization between local and remote storage.
|
|
921
|
+
* Handles uploads, downloads, deletions, and state transitions.
|
|
922
|
+
*
|
|
923
|
+
* @internal
|
|
924
|
+
*/
|
|
925
|
+
class SyncingService {
|
|
926
|
+
attachmentService;
|
|
927
|
+
localStorage;
|
|
928
|
+
remoteStorage;
|
|
929
|
+
logger;
|
|
930
|
+
errorHandler;
|
|
931
|
+
constructor(attachmentService, localStorage, remoteStorage, logger, errorHandler) {
|
|
932
|
+
this.attachmentService = attachmentService;
|
|
933
|
+
this.localStorage = localStorage;
|
|
934
|
+
this.remoteStorage = remoteStorage;
|
|
935
|
+
this.logger = logger;
|
|
936
|
+
this.errorHandler = errorHandler;
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Processes attachments based on their state (upload, download, or delete).
|
|
940
|
+
* All updates are saved in a single batch after processing.
|
|
941
|
+
*
|
|
942
|
+
* @param attachments - Array of attachment records to process
|
|
943
|
+
* @param context - Attachment context for database operations
|
|
944
|
+
* @returns Promise that resolves when all attachments have been processed and saved
|
|
945
|
+
*/
|
|
946
|
+
async processAttachments(attachments, context) {
|
|
947
|
+
const updatedAttachments = [];
|
|
948
|
+
for (const attachment of attachments) {
|
|
949
|
+
switch (attachment.state) {
|
|
950
|
+
case exports.AttachmentState.QUEUED_UPLOAD:
|
|
951
|
+
const uploaded = await this.uploadAttachment(attachment);
|
|
952
|
+
updatedAttachments.push(uploaded);
|
|
953
|
+
break;
|
|
954
|
+
case exports.AttachmentState.QUEUED_DOWNLOAD:
|
|
955
|
+
const downloaded = await this.downloadAttachment(attachment);
|
|
956
|
+
updatedAttachments.push(downloaded);
|
|
957
|
+
break;
|
|
958
|
+
case exports.AttachmentState.QUEUED_DELETE:
|
|
959
|
+
const deleted = await this.deleteAttachment(attachment, context);
|
|
960
|
+
updatedAttachments.push(deleted);
|
|
961
|
+
break;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
await context.saveAttachments(updatedAttachments);
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Uploads an attachment from local storage to remote storage.
|
|
968
|
+
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
969
|
+
*
|
|
970
|
+
* @param attachment - The attachment record to upload
|
|
971
|
+
* @returns Updated attachment record with new state
|
|
972
|
+
* @throws Error if the attachment has no localUri
|
|
973
|
+
*/
|
|
974
|
+
async uploadAttachment(attachment) {
|
|
975
|
+
this.logger.info(`Uploading attachment ${attachment.filename}`);
|
|
976
|
+
try {
|
|
977
|
+
if (attachment.localUri == null) {
|
|
978
|
+
throw new Error(`No localUri for attachment ${attachment.id}`);
|
|
979
|
+
}
|
|
980
|
+
const fileBlob = await this.localStorage.readFile(attachment.localUri);
|
|
981
|
+
await this.remoteStorage.uploadFile(fileBlob, attachment);
|
|
982
|
+
return {
|
|
983
|
+
...attachment,
|
|
984
|
+
state: exports.AttachmentState.SYNCED,
|
|
985
|
+
hasSynced: true
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
catch (error) {
|
|
989
|
+
const shouldRetry = (await this.errorHandler?.onUploadError(attachment, error)) ?? true;
|
|
990
|
+
if (!shouldRetry) {
|
|
991
|
+
return {
|
|
992
|
+
...attachment,
|
|
993
|
+
state: exports.AttachmentState.ARCHIVED
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
return attachment;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Downloads an attachment from remote storage to local storage.
|
|
1001
|
+
* Retrieves the file, converts to base64, and saves locally.
|
|
1002
|
+
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
1003
|
+
*
|
|
1004
|
+
* @param attachment - The attachment record to download
|
|
1005
|
+
* @returns Updated attachment record with local URI and new state
|
|
1006
|
+
*/
|
|
1007
|
+
async downloadAttachment(attachment) {
|
|
1008
|
+
this.logger.info(`Downloading attachment ${attachment.filename}`);
|
|
1009
|
+
try {
|
|
1010
|
+
const fileData = await this.remoteStorage.downloadFile(attachment);
|
|
1011
|
+
const localUri = this.localStorage.getLocalUri(attachment.filename);
|
|
1012
|
+
await this.localStorage.saveFile(localUri, fileData);
|
|
1013
|
+
return {
|
|
1014
|
+
...attachment,
|
|
1015
|
+
state: exports.AttachmentState.SYNCED,
|
|
1016
|
+
localUri: localUri,
|
|
1017
|
+
hasSynced: true
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
catch (error) {
|
|
1021
|
+
const shouldRetry = (await this.errorHandler?.onDownloadError(attachment, error)) ?? true;
|
|
1022
|
+
if (!shouldRetry) {
|
|
1023
|
+
return {
|
|
1024
|
+
...attachment,
|
|
1025
|
+
state: exports.AttachmentState.ARCHIVED
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
return attachment;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Deletes an attachment from both remote and local storage.
|
|
1033
|
+
* Removes the remote file, local file (if exists), and the attachment record.
|
|
1034
|
+
* On failure, defers to error handler or archives.
|
|
941
1035
|
*
|
|
942
|
-
*
|
|
1036
|
+
* @param attachment - The attachment record to delete
|
|
1037
|
+
* @param context - Attachment context for database operations
|
|
1038
|
+
* @returns Updated attachment record
|
|
943
1039
|
*/
|
|
944
|
-
|
|
945
|
-
return this.requestPermits(this.size, abort);
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
/**
|
|
949
|
-
* An asynchronous mutex implementation.
|
|
950
|
-
*
|
|
951
|
-
* @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
|
|
952
|
-
*/
|
|
953
|
-
class Mutex {
|
|
954
|
-
inner = new Semaphore([null]);
|
|
955
|
-
async acquire(abort) {
|
|
956
|
-
const { release } = await this.inner.requestOne(abort);
|
|
957
|
-
return release;
|
|
958
|
-
}
|
|
959
|
-
async runExclusive(fn, abort) {
|
|
960
|
-
const returnMutex = await this.acquire(abort);
|
|
1040
|
+
async deleteAttachment(attachment, context) {
|
|
961
1041
|
try {
|
|
962
|
-
|
|
1042
|
+
await this.remoteStorage.deleteFile(attachment);
|
|
1043
|
+
if (attachment.localUri) {
|
|
1044
|
+
await this.localStorage.deleteFile(attachment.localUri);
|
|
1045
|
+
}
|
|
1046
|
+
await context.deleteAttachment(attachment.id);
|
|
1047
|
+
return {
|
|
1048
|
+
...attachment,
|
|
1049
|
+
state: exports.AttachmentState.ARCHIVED
|
|
1050
|
+
};
|
|
963
1051
|
}
|
|
964
|
-
|
|
965
|
-
|
|
1052
|
+
catch (error) {
|
|
1053
|
+
const shouldRetry = (await this.errorHandler?.onDeleteError(attachment, error)) ?? true;
|
|
1054
|
+
if (!shouldRetry) {
|
|
1055
|
+
return {
|
|
1056
|
+
...attachment,
|
|
1057
|
+
state: exports.AttachmentState.ARCHIVED
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
return attachment;
|
|
966
1061
|
}
|
|
967
1062
|
}
|
|
968
|
-
}
|
|
969
|
-
function timeoutSignal(timeout) {
|
|
970
|
-
if (timeout == null)
|
|
971
|
-
return;
|
|
972
|
-
if ('timeout' in AbortSignal)
|
|
973
|
-
return AbortSignal.timeout(timeout);
|
|
974
|
-
const controller = new AbortController();
|
|
975
|
-
setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
|
|
976
|
-
return controller.signal;
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
/**
|
|
980
|
-
* Service for querying and watching attachment records in the database.
|
|
981
|
-
*
|
|
982
|
-
* @internal
|
|
983
|
-
*/
|
|
984
|
-
class AttachmentService {
|
|
985
|
-
db;
|
|
986
|
-
logger;
|
|
987
|
-
tableName;
|
|
988
|
-
mutex = new Mutex();
|
|
989
|
-
context;
|
|
990
|
-
constructor(db, logger, tableName = 'attachments', archivedCacheLimit = 100) {
|
|
991
|
-
this.db = db;
|
|
992
|
-
this.logger = logger;
|
|
993
|
-
this.tableName = tableName;
|
|
994
|
-
this.context = new AttachmentContext(db, tableName, logger, archivedCacheLimit);
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* Creates a differential watch query for active attachments requiring synchronization.
|
|
998
|
-
* @returns Watch query that emits changes for queued uploads, downloads, and deletes
|
|
999
|
-
*/
|
|
1000
|
-
watchActiveAttachments({ throttleMs } = {}) {
|
|
1001
|
-
this.logger.info('Watching active attachments...');
|
|
1002
|
-
const watch = this.db
|
|
1003
|
-
.query({
|
|
1004
|
-
sql: /* sql */ `
|
|
1005
|
-
SELECT
|
|
1006
|
-
*
|
|
1007
|
-
FROM
|
|
1008
|
-
${this.tableName}
|
|
1009
|
-
WHERE
|
|
1010
|
-
state = ?
|
|
1011
|
-
OR state = ?
|
|
1012
|
-
OR state = ?
|
|
1013
|
-
ORDER BY
|
|
1014
|
-
timestamp ASC
|
|
1015
|
-
`,
|
|
1016
|
-
parameters: [exports.AttachmentState.QUEUED_UPLOAD, exports.AttachmentState.QUEUED_DOWNLOAD, exports.AttachmentState.QUEUED_DELETE]
|
|
1017
|
-
})
|
|
1018
|
-
.differentialWatch({ throttleMs });
|
|
1019
|
-
return watch;
|
|
1020
|
-
}
|
|
1021
1063
|
/**
|
|
1022
|
-
*
|
|
1064
|
+
* Performs cleanup of archived attachments by removing their local files and records.
|
|
1065
|
+
* Errors during local file deletion are logged but do not prevent record deletion.
|
|
1023
1066
|
*/
|
|
1024
|
-
async
|
|
1025
|
-
return
|
|
1026
|
-
|
|
1067
|
+
async deleteArchivedAttachments(context) {
|
|
1068
|
+
return await context.deleteArchivedAttachments(async (archivedAttachments) => {
|
|
1069
|
+
for (const attachment of archivedAttachments) {
|
|
1070
|
+
if (attachment.localUri) {
|
|
1071
|
+
try {
|
|
1072
|
+
await this.localStorage.deleteFile(attachment.localUri);
|
|
1073
|
+
}
|
|
1074
|
+
catch (error) {
|
|
1075
|
+
this.logger.error('Error deleting local file for archived attachment', error);
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1027
1079
|
});
|
|
1028
1080
|
}
|
|
1029
1081
|
}
|
|
@@ -1084,16 +1136,6 @@ class AttachmentQueue {
|
|
|
1084
1136
|
* Creates a new AttachmentQueue instance.
|
|
1085
1137
|
*
|
|
1086
1138
|
* @param options - Configuration options
|
|
1087
|
-
* @param options.db - PowerSync database instance
|
|
1088
|
-
* @param options.remoteStorage - Remote storage adapter for upload/download operations
|
|
1089
|
-
* @param options.localStorage - Local storage adapter for file persistence
|
|
1090
|
-
* @param options.watchAttachments - Callback for monitoring attachment changes in your data model
|
|
1091
|
-
* @param options.tableName - Name of the table to store attachment records. Default: 'ps_attachment_queue'
|
|
1092
|
-
* @param options.logger - Logger instance. Defaults to db.logger
|
|
1093
|
-
* @param options.syncIntervalMs - Periodic polling interval in milliseconds for retrying failed uploads/downloads. Default: 30000
|
|
1094
|
-
* @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
|
|
1095
|
-
* @param options.downloadAttachments - Whether to automatically download remote attachments. Default: true
|
|
1096
|
-
* @param options.archivedCacheLimit - Maximum archived attachments before cleanup. Default: 100
|
|
1097
1139
|
*/
|
|
1098
1140
|
constructor({ db, localStorage, remoteStorage, watchAttachments, logger, tableName = ATTACHMENT_TABLE, syncIntervalMs = 30 * 1000, syncThrottleDuration = DEFAULT_WATCH_THROTTLE_MS, downloadAttachments = true, archivedCacheLimit = 100, errorHandler }) {
|
|
1099
1141
|
this.db = db;
|
|
@@ -1182,6 +1224,7 @@ class AttachmentQueue {
|
|
|
1182
1224
|
state: exports.AttachmentState.QUEUED_DOWNLOAD,
|
|
1183
1225
|
hasSynced: false,
|
|
1184
1226
|
metaData: watchedAttachment.metaData,
|
|
1227
|
+
mediaType: watchedAttachment.mediaType,
|
|
1185
1228
|
timestamp: new Date().getTime()
|
|
1186
1229
|
});
|
|
1187
1230
|
continue;
|
|
@@ -1269,17 +1312,24 @@ class AttachmentQueue {
|
|
|
1269
1312
|
this.statusListenerDispose = undefined;
|
|
1270
1313
|
}
|
|
1271
1314
|
}
|
|
1315
|
+
/**
|
|
1316
|
+
* Provides an {@link AttachmentContext} to a callback.
|
|
1317
|
+
*
|
|
1318
|
+
* The callback runs while the attachment queue mutex is held. Do not call
|
|
1319
|
+
* other {@link AttachmentQueue} methods from within the callback, as they may
|
|
1320
|
+
* attempt to acquire the same mutex and block indefinitely.
|
|
1321
|
+
*/
|
|
1322
|
+
withAttachmentContext(callback) {
|
|
1323
|
+
/**
|
|
1324
|
+
* AttachmentService is internal and private in this class.
|
|
1325
|
+
* We only need to expose its locking and context functionality for extending classes.
|
|
1326
|
+
*/
|
|
1327
|
+
return this.attachmentService.withContext(callback);
|
|
1328
|
+
}
|
|
1272
1329
|
/**
|
|
1273
1330
|
* Saves a file to local storage and queues it for upload to remote storage.
|
|
1274
1331
|
*
|
|
1275
1332
|
* @param options - File save options
|
|
1276
|
-
* @param options.data - The file data as ArrayBuffer, Blob, or base64 string
|
|
1277
|
-
* @param options.fileExtension - File extension (e.g., 'jpg', 'pdf')
|
|
1278
|
-
* @param options.mediaType - MIME type of the file (e.g., 'image/jpeg')
|
|
1279
|
-
* @param options.metaData - Optional metadata to associate with the attachment
|
|
1280
|
-
* @param options.id - Optional custom ID. If not provided, a UUID will be generated
|
|
1281
|
-
* @param options.updateHook - Optional callback to execute additional database operations
|
|
1282
|
-
* within the same transaction as the attachment creation
|
|
1283
1333
|
* @returns Promise resolving to the created attachment record
|
|
1284
1334
|
*/
|
|
1285
1335
|
async saveFile({ data, fileExtension, mediaType, metaData, id, updateHook }) {
|
|
@@ -1392,6 +1442,9 @@ class AttachmentQueue {
|
|
|
1392
1442
|
}
|
|
1393
1443
|
}
|
|
1394
1444
|
|
|
1445
|
+
/**
|
|
1446
|
+
* @alpha
|
|
1447
|
+
*/
|
|
1395
1448
|
exports.EncodingType = void 0;
|
|
1396
1449
|
(function (EncodingType) {
|
|
1397
1450
|
EncodingType["UTF8"] = "utf8";
|
|
@@ -1855,7 +1908,9 @@ var Logger = /*@__PURE__*/getDefaultExportFromCjs(loggerExports);
|
|
|
1855
1908
|
* different SQLite DB implementations.
|
|
1856
1909
|
*/
|
|
1857
1910
|
/**
|
|
1858
|
-
* Implements {@link DBGetUtils} on a {@link
|
|
1911
|
+
* Implements {@link DBGetUtils} on a {@link SqlExecutor}.
|
|
1912
|
+
*
|
|
1913
|
+
* @internal
|
|
1859
1914
|
*/
|
|
1860
1915
|
function DBGetUtilsDefaultMixin(Base) {
|
|
1861
1916
|
return class extends Base {
|
|
@@ -1899,6 +1954,8 @@ function DBGetUtilsDefaultMixin(Base) {
|
|
|
1899
1954
|
}
|
|
1900
1955
|
/**
|
|
1901
1956
|
* Update table operation numbers from SQLite
|
|
1957
|
+
*
|
|
1958
|
+
* @public
|
|
1902
1959
|
*/
|
|
1903
1960
|
exports.RowUpdateType = void 0;
|
|
1904
1961
|
(function (RowUpdateType) {
|
|
@@ -1907,8 +1964,10 @@ exports.RowUpdateType = void 0;
|
|
|
1907
1964
|
RowUpdateType[RowUpdateType["SQLITE_UPDATE"] = 23] = "SQLITE_UPDATE";
|
|
1908
1965
|
})(exports.RowUpdateType || (exports.RowUpdateType = {}));
|
|
1909
1966
|
/**
|
|
1910
|
-
* A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool
|
|
1911
|
-
* {@link ConnectionPool
|
|
1967
|
+
* A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool#readLock} and
|
|
1968
|
+
* {@link ConnectionPool#writeLock}.
|
|
1969
|
+
*
|
|
1970
|
+
* @internal
|
|
1912
1971
|
*/
|
|
1913
1972
|
function DBAdapterDefaultMixin(Base) {
|
|
1914
1973
|
return class extends Base {
|
|
@@ -1996,9 +2055,15 @@ class TransactionImplementation extends DBGetUtilsDefaultMixin(BaseTransaction)
|
|
|
1996
2055
|
}
|
|
1997
2056
|
}
|
|
1998
2057
|
}
|
|
2058
|
+
/**
|
|
2059
|
+
* @internal
|
|
2060
|
+
*/
|
|
1999
2061
|
function isBatchedUpdateNotification(update) {
|
|
2000
2062
|
return 'tables' in update;
|
|
2001
2063
|
}
|
|
2064
|
+
/**
|
|
2065
|
+
* @internal
|
|
2066
|
+
*/
|
|
2002
2067
|
function extractTableUpdates(update) {
|
|
2003
2068
|
return isBatchedUpdateNotification(update) ? update.tables : [update.table];
|
|
2004
2069
|
}
|
|
@@ -2026,6 +2091,8 @@ const FULL_SYNC_PRIORITY = 2147483647;
|
|
|
2026
2091
|
*
|
|
2027
2092
|
* Also note that data is downloaded in bulk, which means that individual counters are unlikely
|
|
2028
2093
|
* to be updated one-by-one.
|
|
2094
|
+
*
|
|
2095
|
+
* @public
|
|
2029
2096
|
*/
|
|
2030
2097
|
class SyncProgress {
|
|
2031
2098
|
internal;
|
|
@@ -2064,6 +2131,9 @@ class SyncProgress {
|
|
|
2064
2131
|
}
|
|
2065
2132
|
}
|
|
2066
2133
|
|
|
2134
|
+
/**
|
|
2135
|
+
* @public
|
|
2136
|
+
*/
|
|
2067
2137
|
class SyncStatus {
|
|
2068
2138
|
options;
|
|
2069
2139
|
constructor(options) {
|
|
@@ -2074,6 +2144,8 @@ class SyncStatus {
|
|
|
2074
2144
|
* implementation).
|
|
2075
2145
|
*
|
|
2076
2146
|
* This information is only available after a connection has been requested.
|
|
2147
|
+
*
|
|
2148
|
+
* @deprecated This always returns the Rust client (the only option).
|
|
2077
2149
|
*/
|
|
2078
2150
|
get clientImplementation() {
|
|
2079
2151
|
return this.options.clientImplementation;
|
|
@@ -2081,7 +2153,7 @@ class SyncStatus {
|
|
|
2081
2153
|
/**
|
|
2082
2154
|
* Indicates if the client is currently connected to the PowerSync service.
|
|
2083
2155
|
*
|
|
2084
|
-
* @returns
|
|
2156
|
+
* @returns True if connected, false otherwise. Defaults to false if not specified.
|
|
2085
2157
|
*/
|
|
2086
2158
|
get connected() {
|
|
2087
2159
|
return this.options.connected ?? false;
|
|
@@ -2089,7 +2161,7 @@ class SyncStatus {
|
|
|
2089
2161
|
/**
|
|
2090
2162
|
* Indicates if the client is in the process of establishing a connection to the PowerSync service.
|
|
2091
2163
|
*
|
|
2092
|
-
* @returns
|
|
2164
|
+
* @returns True if connecting, false otherwise. Defaults to false if not specified.
|
|
2093
2165
|
*/
|
|
2094
2166
|
get connecting() {
|
|
2095
2167
|
return this.options.connecting ?? false;
|
|
@@ -2098,7 +2170,7 @@ class SyncStatus {
|
|
|
2098
2170
|
* Time that a last sync has fully completed, if any.
|
|
2099
2171
|
* This timestamp is reset to null after a restart of the PowerSync service.
|
|
2100
2172
|
*
|
|
2101
|
-
* @returns
|
|
2173
|
+
* @returns The timestamp of the last successful sync, or undefined if no sync has completed.
|
|
2102
2174
|
*/
|
|
2103
2175
|
get lastSyncedAt() {
|
|
2104
2176
|
return this.options.lastSyncedAt;
|
|
@@ -2106,7 +2178,7 @@ class SyncStatus {
|
|
|
2106
2178
|
/**
|
|
2107
2179
|
* Indicates whether there has been at least one full sync completed since initialization.
|
|
2108
2180
|
*
|
|
2109
|
-
* @returns
|
|
2181
|
+
* @returns True if at least one sync has completed, false if no sync has completed,
|
|
2110
2182
|
* or undefined when the state is still being loaded from the database.
|
|
2111
2183
|
*/
|
|
2112
2184
|
get hasSynced() {
|
|
@@ -2115,10 +2187,10 @@ class SyncStatus {
|
|
|
2115
2187
|
/**
|
|
2116
2188
|
* Provides the current data flow status regarding uploads and downloads.
|
|
2117
2189
|
*
|
|
2118
|
-
* @returns
|
|
2190
|
+
* @returns An object containing:
|
|
2119
2191
|
* - downloading: True if actively downloading changes (only when connected is also true)
|
|
2120
2192
|
* - uploading: True if actively uploading changes
|
|
2121
|
-
* Defaults to {downloading: false, uploading: false} if not specified.
|
|
2193
|
+
* Defaults to `{downloading: false, uploading: false}` if not specified.
|
|
2122
2194
|
*/
|
|
2123
2195
|
get dataFlowStatus() {
|
|
2124
2196
|
return (this.options.dataFlow ?? {
|
|
@@ -2143,7 +2215,7 @@ class SyncStatus {
|
|
|
2143
2215
|
return this.options.dataFlow?.internalStreamSubscriptions?.map((core) => new SyncStreamStatusView(this, core));
|
|
2144
2216
|
}
|
|
2145
2217
|
/**
|
|
2146
|
-
* If the `stream` appears in {@link syncStreams}, returns the current status for that stream.
|
|
2218
|
+
* If the `stream` appears in {@link SyncStatus.syncStreams}, returns the current status for that stream.
|
|
2147
2219
|
*/
|
|
2148
2220
|
forStream(stream) {
|
|
2149
2221
|
const asJson = JSON.stringify(stream.parameters);
|
|
@@ -2153,7 +2225,7 @@ class SyncStatus {
|
|
|
2153
2225
|
/**
|
|
2154
2226
|
* Provides sync status information for all bucket priorities, sorted by priority (highest first).
|
|
2155
2227
|
*
|
|
2156
|
-
* @returns
|
|
2228
|
+
* @returns An array of status entries for different sync priority levels,
|
|
2157
2229
|
* sorted with highest priorities (lower numbers) first.
|
|
2158
2230
|
*/
|
|
2159
2231
|
get priorityStatusEntries() {
|
|
@@ -2188,8 +2260,8 @@ class SyncStatus {
|
|
|
2188
2260
|
* For example, if PowerSync just finished synchronizing buckets in priority level 3, calling this method
|
|
2189
2261
|
* with a priority of 1 may return information for priority level 3.
|
|
2190
2262
|
*
|
|
2191
|
-
* @param
|
|
2192
|
-
* @returns
|
|
2263
|
+
* @param priority - The bucket priority for which the status should be reported
|
|
2264
|
+
* @returns Status information for the requested priority level or the next higher level with available status
|
|
2193
2265
|
*/
|
|
2194
2266
|
statusForPriority(priority) {
|
|
2195
2267
|
// priorityStatusEntries are sorted by ascending priorities (so higher numbers to lower numbers).
|
|
@@ -2210,8 +2282,8 @@ class SyncStatus {
|
|
|
2210
2282
|
* Compares this SyncStatus instance with another to determine if they are equal.
|
|
2211
2283
|
* Equality is determined by comparing the serialized JSON representation of both instances.
|
|
2212
2284
|
*
|
|
2213
|
-
* @param
|
|
2214
|
-
* @returns
|
|
2285
|
+
* @param status - The SyncStatus instance to compare against
|
|
2286
|
+
* @returns True if the instances are considered equal, false otherwise
|
|
2215
2287
|
*/
|
|
2216
2288
|
isEqual(status) {
|
|
2217
2289
|
/**
|
|
@@ -2234,7 +2306,7 @@ class SyncStatus {
|
|
|
2234
2306
|
* Creates a human-readable string representation of the current sync status.
|
|
2235
2307
|
* Includes information about connection state, sync completion, and data flow.
|
|
2236
2308
|
*
|
|
2237
|
-
* @returns
|
|
2309
|
+
* @returns A string representation of the sync status
|
|
2238
2310
|
*/
|
|
2239
2311
|
getMessage() {
|
|
2240
2312
|
const dataFlow = this.dataFlowStatus;
|
|
@@ -2243,7 +2315,7 @@ class SyncStatus {
|
|
|
2243
2315
|
/**
|
|
2244
2316
|
* Serializes the SyncStatus instance to a plain object.
|
|
2245
2317
|
*
|
|
2246
|
-
* @returns
|
|
2318
|
+
* @returns A plain object representation of the sync status
|
|
2247
2319
|
*/
|
|
2248
2320
|
toJSON() {
|
|
2249
2321
|
return {
|
|
@@ -2309,6 +2381,9 @@ class SyncStreamStatusView {
|
|
|
2309
2381
|
}
|
|
2310
2382
|
}
|
|
2311
2383
|
|
|
2384
|
+
/**
|
|
2385
|
+
* @public
|
|
2386
|
+
*/
|
|
2312
2387
|
class UploadQueueStats {
|
|
2313
2388
|
count;
|
|
2314
2389
|
size;
|
|
@@ -2334,6 +2409,9 @@ class UploadQueueStats {
|
|
|
2334
2409
|
}
|
|
2335
2410
|
}
|
|
2336
2411
|
|
|
2412
|
+
/**
|
|
2413
|
+
* @internal
|
|
2414
|
+
*/
|
|
2337
2415
|
class BaseObserver {
|
|
2338
2416
|
listeners = new Set();
|
|
2339
2417
|
constructor() { }
|
|
@@ -2361,6 +2439,9 @@ class BaseObserver {
|
|
|
2361
2439
|
}
|
|
2362
2440
|
}
|
|
2363
2441
|
|
|
2442
|
+
/**
|
|
2443
|
+
* @internal
|
|
2444
|
+
*/
|
|
2364
2445
|
class ControlledExecutor {
|
|
2365
2446
|
task;
|
|
2366
2447
|
/**
|
|
@@ -2628,7 +2709,7 @@ class ConnectionManager extends BaseObserver {
|
|
|
2628
2709
|
/**
|
|
2629
2710
|
* Close the sync connection.
|
|
2630
2711
|
*
|
|
2631
|
-
* Use {@link connect} to connect again.
|
|
2712
|
+
* Use {@link ConnectionManager.connect} to connect again.
|
|
2632
2713
|
*/
|
|
2633
2714
|
async disconnect() {
|
|
2634
2715
|
// This will help abort pending connects
|
|
@@ -2768,6 +2849,8 @@ const _finalizer = 'FinalizationRegistry' in globalThis
|
|
|
2768
2849
|
/**
|
|
2769
2850
|
* An efficient comparator for {@link WatchedQuery} created with {@link Query#watch}. This has the ability to determine if a query
|
|
2770
2851
|
* result has changes without necessarily processing all items in the result.
|
|
2852
|
+
*
|
|
2853
|
+
* @public
|
|
2771
2854
|
*/
|
|
2772
2855
|
class ArrayComparator {
|
|
2773
2856
|
options;
|
|
@@ -2795,6 +2878,8 @@ class ArrayComparator {
|
|
|
2795
2878
|
}
|
|
2796
2879
|
/**
|
|
2797
2880
|
* Watched query comparator that always reports changed result sets.
|
|
2881
|
+
*
|
|
2882
|
+
* @public
|
|
2798
2883
|
*/
|
|
2799
2884
|
const FalsyComparator = {
|
|
2800
2885
|
checkEquality: () => false // Default comparator that always returns false
|
|
@@ -3002,6 +3087,8 @@ class AbstractQueryProcessor extends MetaBaseObserver {
|
|
|
3002
3087
|
/**
|
|
3003
3088
|
* An empty differential result set.
|
|
3004
3089
|
* This is used as the initial state for differential incrementally watched queries.
|
|
3090
|
+
*
|
|
3091
|
+
* @internal
|
|
3005
3092
|
*/
|
|
3006
3093
|
const EMPTY_DIFFERENTIAL = {
|
|
3007
3094
|
added: [],
|
|
@@ -3014,6 +3101,8 @@ const EMPTY_DIFFERENTIAL = {
|
|
|
3014
3101
|
* Default implementation of the {@link DifferentialWatchedQueryComparator} for watched queries.
|
|
3015
3102
|
* It keys items by their `id` property if available, alternatively it uses JSON stringification
|
|
3016
3103
|
* of the entire item for the key and comparison.
|
|
3104
|
+
*
|
|
3105
|
+
* @internal
|
|
3017
3106
|
*/
|
|
3018
3107
|
const DEFAULT_ROW_COMPARATOR = {
|
|
3019
3108
|
keyBy: (item) => {
|
|
@@ -3294,6 +3383,8 @@ class CustomQuery {
|
|
|
3294
3383
|
|
|
3295
3384
|
/**
|
|
3296
3385
|
* Tests if the input is a {@link SQLOpenOptions}
|
|
3386
|
+
*
|
|
3387
|
+
* @internal
|
|
3297
3388
|
*/
|
|
3298
3389
|
const isSQLOpenOptions = (test) => {
|
|
3299
3390
|
// typeof null is `object`, but you cannot use the `in` operator on `null.
|
|
@@ -3301,17 +3392,24 @@ const isSQLOpenOptions = (test) => {
|
|
|
3301
3392
|
};
|
|
3302
3393
|
/**
|
|
3303
3394
|
* Tests if input is a {@link SQLOpenFactory}
|
|
3395
|
+
*
|
|
3396
|
+
* @internal
|
|
3304
3397
|
*/
|
|
3305
3398
|
const isSQLOpenFactory = (test) => {
|
|
3306
3399
|
return typeof test?.openDB == 'function';
|
|
3307
3400
|
};
|
|
3308
3401
|
/**
|
|
3309
3402
|
* Tests if input is a {@link DBAdapter}
|
|
3403
|
+
*
|
|
3404
|
+
* @internal
|
|
3310
3405
|
*/
|
|
3311
3406
|
const isDBAdapter = (test) => {
|
|
3312
3407
|
return typeof test?.writeTransaction == 'function';
|
|
3313
3408
|
};
|
|
3314
3409
|
|
|
3410
|
+
/**
|
|
3411
|
+
* @internal
|
|
3412
|
+
*/
|
|
3315
3413
|
exports.PSInternalTable = void 0;
|
|
3316
3414
|
(function (PSInternalTable) {
|
|
3317
3415
|
PSInternalTable["DATA"] = "ps_data";
|
|
@@ -3320,6 +3418,9 @@ exports.PSInternalTable = void 0;
|
|
|
3320
3418
|
PSInternalTable["OPLOG"] = "ps_oplog";
|
|
3321
3419
|
PSInternalTable["UNTYPED"] = "ps_untyped";
|
|
3322
3420
|
})(exports.PSInternalTable || (exports.PSInternalTable = {}));
|
|
3421
|
+
/**
|
|
3422
|
+
* @internal
|
|
3423
|
+
*/
|
|
3323
3424
|
exports.PowerSyncControlCommand = void 0;
|
|
3324
3425
|
(function (PowerSyncControlCommand) {
|
|
3325
3426
|
PowerSyncControlCommand["PROCESS_TEXT_LINE"] = "line_text";
|
|
@@ -3337,6 +3438,8 @@ exports.PowerSyncControlCommand = void 0;
|
|
|
3337
3438
|
|
|
3338
3439
|
/**
|
|
3339
3440
|
* A batch of client-side changes.
|
|
3441
|
+
*
|
|
3442
|
+
* @public
|
|
3340
3443
|
*/
|
|
3341
3444
|
class CrudBatch {
|
|
3342
3445
|
crud;
|
|
@@ -3363,6 +3466,8 @@ class CrudBatch {
|
|
|
3363
3466
|
|
|
3364
3467
|
/**
|
|
3365
3468
|
* Type of local change.
|
|
3469
|
+
*
|
|
3470
|
+
* @public
|
|
3366
3471
|
*/
|
|
3367
3472
|
exports.UpdateType = void 0;
|
|
3368
3473
|
(function (UpdateType) {
|
|
@@ -3375,6 +3480,8 @@ exports.UpdateType = void 0;
|
|
|
3375
3480
|
})(exports.UpdateType || (exports.UpdateType = {}));
|
|
3376
3481
|
/**
|
|
3377
3482
|
* A single client-side change.
|
|
3483
|
+
*
|
|
3484
|
+
* @public
|
|
3378
3485
|
*/
|
|
3379
3486
|
class CrudEntry {
|
|
3380
3487
|
/**
|
|
@@ -3471,6 +3578,9 @@ class CrudEntry {
|
|
|
3471
3578
|
}
|
|
3472
3579
|
}
|
|
3473
3580
|
|
|
3581
|
+
/**
|
|
3582
|
+
* @public
|
|
3583
|
+
*/
|
|
3474
3584
|
class CrudTransaction extends CrudBatch {
|
|
3475
3585
|
crud;
|
|
3476
3586
|
complete;
|
|
@@ -3499,6 +3609,8 @@ class CrudTransaction extends CrudBatch {
|
|
|
3499
3609
|
* Calls to Abortcontroller.abort(reason: any) will result in the
|
|
3500
3610
|
* `reason` being thrown. This is not necessarily an error,
|
|
3501
3611
|
* but extends error for better logging purposes.
|
|
3612
|
+
*
|
|
3613
|
+
* @internal
|
|
3502
3614
|
*/
|
|
3503
3615
|
class AbortOperation extends Error {
|
|
3504
3616
|
reason;
|
|
@@ -10669,7 +10781,7 @@ function requireDist () {
|
|
|
10669
10781
|
|
|
10670
10782
|
var distExports = requireDist();
|
|
10671
10783
|
|
|
10672
|
-
var version = "1.
|
|
10784
|
+
var version = "1.54.0";
|
|
10673
10785
|
var PACKAGE = {
|
|
10674
10786
|
version: version};
|
|
10675
10787
|
|
|
@@ -10799,7 +10911,8 @@ class WebsocketClientTransport {
|
|
|
10799
10911
|
removeListeners();
|
|
10800
10912
|
resolve(new WebsocketDuplexConnectionExports.WebsocketDuplexConnection(websocket, new distExports.Deserializer(), multiplexerDemultiplexerFactory));
|
|
10801
10913
|
};
|
|
10802
|
-
const errorListener = (
|
|
10914
|
+
const errorListener = (event) => {
|
|
10915
|
+
const ev = event;
|
|
10803
10916
|
removeListeners();
|
|
10804
10917
|
// We add a default error in that case.
|
|
10805
10918
|
if (ev.error != null) {
|
|
@@ -11042,7 +11155,13 @@ const SOCKET_TIMEOUT_MS = 30_000;
|
|
|
11042
11155
|
// If there is a backlog of messages (for example on slow connections), keepalive messages could be delayed
|
|
11043
11156
|
// significantly. Therefore this is longer than the socket timeout.
|
|
11044
11157
|
const KEEP_ALIVE_LIFETIME_MS = 90_000;
|
|
11158
|
+
/**
|
|
11159
|
+
* @internal
|
|
11160
|
+
*/
|
|
11045
11161
|
const DEFAULT_REMOTE_LOGGER = Logger.get('PowerSyncRemote');
|
|
11162
|
+
/**
|
|
11163
|
+
* @public
|
|
11164
|
+
*/
|
|
11046
11165
|
exports.FetchStrategy = void 0;
|
|
11047
11166
|
(function (FetchStrategy) {
|
|
11048
11167
|
/**
|
|
@@ -11061,12 +11180,17 @@ exports.FetchStrategy = void 0;
|
|
|
11061
11180
|
* The class wrapper is used to distinguish the fetchImplementation
|
|
11062
11181
|
* option in [AbstractRemoteOptions] from the general fetch method
|
|
11063
11182
|
* which is typeof "function"
|
|
11183
|
+
*
|
|
11184
|
+
* @internal
|
|
11064
11185
|
*/
|
|
11065
11186
|
class FetchImplementationProvider {
|
|
11066
11187
|
getFetch() {
|
|
11067
11188
|
throw new Error('Unspecified fetch implementation');
|
|
11068
11189
|
}
|
|
11069
11190
|
}
|
|
11191
|
+
/**
|
|
11192
|
+
* @internal
|
|
11193
|
+
*/
|
|
11070
11194
|
const DEFAULT_REMOTE_OPTIONS = {
|
|
11071
11195
|
socketUrlTransformer: (url) => url.replace(/^https?:\/\//, function (match) {
|
|
11072
11196
|
return match === 'https://' ? 'wss://' : 'ws://';
|
|
@@ -11074,6 +11198,9 @@ const DEFAULT_REMOTE_OPTIONS = {
|
|
|
11074
11198
|
fetchImplementation: new FetchImplementationProvider(),
|
|
11075
11199
|
fetchOptions: {}
|
|
11076
11200
|
};
|
|
11201
|
+
/**
|
|
11202
|
+
* @internal
|
|
11203
|
+
*/
|
|
11077
11204
|
class AbstractRemote {
|
|
11078
11205
|
connector;
|
|
11079
11206
|
logger;
|
|
@@ -11483,7 +11610,7 @@ class AbstractRemote {
|
|
|
11483
11610
|
* Posts a `/sync/stream` request.
|
|
11484
11611
|
*
|
|
11485
11612
|
* Depending on the `Content-Type` of the response, this returns strings for sync lines or encoded BSON documents as
|
|
11486
|
-
*
|
|
11613
|
+
* `Uint8Array`s.
|
|
11487
11614
|
*/
|
|
11488
11615
|
async fetchStream(options) {
|
|
11489
11616
|
const { isBson, stream } = await this.fetchStreamRaw(options);
|
|
@@ -11525,16 +11652,26 @@ function isInterruptingInstruction(instruction) {
|
|
|
11525
11652
|
return 'EstablishSyncStream' in instruction || 'CloseSyncStream' in instruction;
|
|
11526
11653
|
}
|
|
11527
11654
|
|
|
11655
|
+
/**
|
|
11656
|
+
* @internal
|
|
11657
|
+
*/
|
|
11528
11658
|
exports.LockType = void 0;
|
|
11529
11659
|
(function (LockType) {
|
|
11530
11660
|
LockType["CRUD"] = "crud";
|
|
11531
11661
|
LockType["SYNC"] = "sync";
|
|
11532
11662
|
})(exports.LockType || (exports.LockType = {}));
|
|
11663
|
+
/**
|
|
11664
|
+
* @public
|
|
11665
|
+
*/
|
|
11533
11666
|
exports.SyncStreamConnectionMethod = void 0;
|
|
11534
11667
|
(function (SyncStreamConnectionMethod) {
|
|
11535
11668
|
SyncStreamConnectionMethod["HTTP"] = "http";
|
|
11536
11669
|
SyncStreamConnectionMethod["WEB_SOCKET"] = "web-socket";
|
|
11537
11670
|
})(exports.SyncStreamConnectionMethod || (exports.SyncStreamConnectionMethod = {}));
|
|
11671
|
+
/**
|
|
11672
|
+
* @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
|
|
11673
|
+
* @public
|
|
11674
|
+
*/
|
|
11538
11675
|
exports.SyncClientImplementation = void 0;
|
|
11539
11676
|
(function (SyncClientImplementation) {
|
|
11540
11677
|
/**
|
|
@@ -11546,8 +11683,8 @@ exports.SyncClientImplementation = void 0;
|
|
|
11546
11683
|
* ## Compatibility warning
|
|
11547
11684
|
*
|
|
11548
11685
|
* The Rust sync client stores sync data in a format that is slightly different than the one used
|
|
11549
|
-
* by the old JavaScript client. When adopting the {@link RUST} client on existing databases,
|
|
11550
|
-
* migrate the format automatically.
|
|
11686
|
+
* by the old JavaScript client. When adopting the {@link SyncClientImplementation.RUST} client on existing databases,
|
|
11687
|
+
* the PowerSync SDK will migrate the format automatically.
|
|
11551
11688
|
*
|
|
11552
11689
|
* SDK versions supporting both the JavaScript and the Rust client support both formats with the JavaScript client
|
|
11553
11690
|
* implementaiton. However, downgrading to an SDK version that only supports the JavaScript client would not be
|
|
@@ -11557,14 +11694,29 @@ exports.SyncClientImplementation = void 0;
|
|
|
11557
11694
|
})(exports.SyncClientImplementation || (exports.SyncClientImplementation = {}));
|
|
11558
11695
|
/**
|
|
11559
11696
|
* The default {@link SyncClientImplementation} to use, {@link SyncClientImplementation.RUST}.
|
|
11697
|
+
*
|
|
11698
|
+
* @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
|
|
11699
|
+
* @public
|
|
11560
11700
|
*/
|
|
11561
11701
|
const DEFAULT_SYNC_CLIENT_IMPLEMENTATION = exports.SyncClientImplementation.RUST;
|
|
11702
|
+
/**
|
|
11703
|
+
* @internal
|
|
11704
|
+
*/
|
|
11562
11705
|
const DEFAULT_CRUD_UPLOAD_THROTTLE_MS = 1000;
|
|
11706
|
+
/**
|
|
11707
|
+
* @internal
|
|
11708
|
+
*/
|
|
11563
11709
|
const DEFAULT_RETRY_DELAY_MS = 5000;
|
|
11710
|
+
/**
|
|
11711
|
+
* @internal
|
|
11712
|
+
*/
|
|
11564
11713
|
const DEFAULT_STREAMING_SYNC_OPTIONS = {
|
|
11565
11714
|
retryDelayMs: DEFAULT_RETRY_DELAY_MS,
|
|
11566
11715
|
crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
|
|
11567
11716
|
};
|
|
11717
|
+
/**
|
|
11718
|
+
* @internal
|
|
11719
|
+
*/
|
|
11568
11720
|
const DEFAULT_STREAM_CONNECTION_OPTIONS = {
|
|
11569
11721
|
appMetadata: {},
|
|
11570
11722
|
connectionMethod: exports.SyncStreamConnectionMethod.WEB_SOCKET,
|
|
@@ -11574,6 +11726,9 @@ const DEFAULT_STREAM_CONNECTION_OPTIONS = {
|
|
|
11574
11726
|
serializedSchema: undefined,
|
|
11575
11727
|
includeDefaultStreams: true
|
|
11576
11728
|
};
|
|
11729
|
+
/**
|
|
11730
|
+
* @internal
|
|
11731
|
+
*/
|
|
11577
11732
|
class AbstractStreamingSyncImplementation extends BaseObserver {
|
|
11578
11733
|
options;
|
|
11579
11734
|
abortController;
|
|
@@ -11897,7 +12052,7 @@ The next upload iteration will be delayed.`);
|
|
|
11897
12052
|
this.handleActiveStreamsChange?.();
|
|
11898
12053
|
}
|
|
11899
12054
|
/**
|
|
11900
|
-
* Older versions of the JS SDK used to encode subkeys as JSON in
|
|
12055
|
+
* Older versions of the JS SDK used to encode subkeys as JSON in `OplogEntry.toJSON`.
|
|
11901
12056
|
* Because subkeys are always strings, this leads to quotes being added around them in `ps_oplog`.
|
|
11902
12057
|
* While this is not a problem as long as it's done consistently, it causes issues when a database
|
|
11903
12058
|
* created by the JS SDK is used with other SDKs, or (more likely) when the new Rust sync client
|
|
@@ -11907,7 +12062,7 @@ The next upload iteration will be delayed.`);
|
|
|
11907
12062
|
* migration is only triggered when necessary (for now). The function returns whether the new format
|
|
11908
12063
|
* should be used, so that the JS SDK is able to write to updated databases.
|
|
11909
12064
|
*
|
|
11910
|
-
* @param requireFixedKeyFormat Whether we require the new format or also support the old one.
|
|
12065
|
+
* @param requireFixedKeyFormat - Whether we require the new format or also support the old one.
|
|
11911
12066
|
* The Rust client requires the new subkey format.
|
|
11912
12067
|
* @returns Whether the database is now using the new, fixed subkey format.
|
|
11913
12068
|
*/
|
|
@@ -12214,7 +12369,8 @@ const MEMORY_TRIGGER_CLAIM_MANAGER = {
|
|
|
12214
12369
|
|
|
12215
12370
|
/**
|
|
12216
12371
|
* SQLite operations to track changes for with {@link TriggerManager}
|
|
12217
|
-
*
|
|
12372
|
+
*
|
|
12373
|
+
* @experimental @alpha
|
|
12218
12374
|
*/
|
|
12219
12375
|
exports.DiffTriggerOperation = void 0;
|
|
12220
12376
|
(function (DiffTriggerOperation) {
|
|
@@ -12276,8 +12432,8 @@ class TriggerManagerImpl {
|
|
|
12276
12432
|
get db() {
|
|
12277
12433
|
return this.options.db;
|
|
12278
12434
|
}
|
|
12279
|
-
async getUUID() {
|
|
12280
|
-
const { id: uuid } = await this.db.get(/* sql */ `
|
|
12435
|
+
async getUUID(ctx) {
|
|
12436
|
+
const { id: uuid } = await (ctx ?? this.db).get(/* sql */ `
|
|
12281
12437
|
SELECT
|
|
12282
12438
|
uuid () as id
|
|
12283
12439
|
`);
|
|
@@ -12390,7 +12546,7 @@ class TriggerManagerImpl {
|
|
|
12390
12546
|
const replicatedColumns = columns ?? sourceDefinition.columns.map((col) => col.name);
|
|
12391
12547
|
const internalSource = sourceDefinition.internalName;
|
|
12392
12548
|
const triggerIds = [];
|
|
12393
|
-
const id = await this.getUUID();
|
|
12549
|
+
const id = await this.getUUID(setupContext);
|
|
12394
12550
|
const releaseStorageClaim = useStorage ? await this.options.claimManager.obtainClaim(id) : null;
|
|
12395
12551
|
/**
|
|
12396
12552
|
* We default to replicating all columns if no columns array is provided.
|
|
@@ -12630,18 +12786,29 @@ const POWERSYNC_TABLE_MATCH = /(^ps_data__|^ps_data_local__)/;
|
|
|
12630
12786
|
const DEFAULT_DISCONNECT_CLEAR_OPTIONS = {
|
|
12631
12787
|
clearLocal: true
|
|
12632
12788
|
};
|
|
12789
|
+
/**
|
|
12790
|
+
* @internal
|
|
12791
|
+
*/
|
|
12633
12792
|
const DEFAULT_POWERSYNC_CLOSE_OPTIONS = {
|
|
12634
12793
|
disconnect: true
|
|
12635
12794
|
};
|
|
12795
|
+
/**
|
|
12796
|
+
* @internal
|
|
12797
|
+
*/
|
|
12636
12798
|
const DEFAULT_POWERSYNC_DB_OPTIONS = {
|
|
12637
12799
|
retryDelayMs: 5000,
|
|
12638
12800
|
crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
|
|
12639
12801
|
};
|
|
12802
|
+
/**
|
|
12803
|
+
* @internal
|
|
12804
|
+
*/
|
|
12640
12805
|
const DEFAULT_CRUD_BATCH_LIMIT = 100;
|
|
12641
12806
|
/**
|
|
12642
12807
|
* Requesting nested or recursive locks can block the application in some circumstances.
|
|
12643
12808
|
* This default lock timeout will act as a failsafe to throw an error if a lock cannot
|
|
12644
12809
|
* be obtained.
|
|
12810
|
+
*
|
|
12811
|
+
* @internal
|
|
12645
12812
|
*/
|
|
12646
12813
|
const DEFAULT_LOCK_TIMEOUT_MS = 120_000; // 2 mins
|
|
12647
12814
|
/**
|
|
@@ -12651,6 +12818,9 @@ const DEFAULT_LOCK_TIMEOUT_MS = 120_000; // 2 mins
|
|
|
12651
12818
|
const isPowerSyncDatabaseOptionsWithSettings = (test) => {
|
|
12652
12819
|
return typeof test == 'object' && isSQLOpenOptions(test.database);
|
|
12653
12820
|
};
|
|
12821
|
+
/**
|
|
12822
|
+
* @public
|
|
12823
|
+
*/
|
|
12654
12824
|
class AbstractPowerSyncDatabase extends BaseObserver {
|
|
12655
12825
|
options;
|
|
12656
12826
|
/**
|
|
@@ -12808,7 +12978,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
12808
12978
|
/**
|
|
12809
12979
|
* Wait for the first sync operation to complete.
|
|
12810
12980
|
*
|
|
12811
|
-
* @param request Either an abort signal (after which the promise will complete regardless of
|
|
12981
|
+
* @param request - Either an abort signal (after which the promise will complete regardless of
|
|
12812
12982
|
* whether a full sync was completed) or an object providing an abort signal and a priority target.
|
|
12813
12983
|
* When a priority target is set, the promise may complete when all buckets with the given (or higher)
|
|
12814
12984
|
* priorities have been synchronized. This can be earlier than a complete sync.
|
|
@@ -12963,7 +13133,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
12963
13133
|
/**
|
|
12964
13134
|
* Close the sync connection.
|
|
12965
13135
|
*
|
|
12966
|
-
* Use {@link connect} to connect again.
|
|
13136
|
+
* Use {@link AbstractPowerSyncDatabase.connect} to connect again.
|
|
12967
13137
|
*/
|
|
12968
13138
|
async disconnect() {
|
|
12969
13139
|
return this.connectionManager.disconnect();
|
|
@@ -12990,8 +13160,8 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
12990
13160
|
/**
|
|
12991
13161
|
* Create a sync stream to query its status or to subscribe to it.
|
|
12992
13162
|
*
|
|
12993
|
-
* @param name The name of the stream to subscribe to.
|
|
12994
|
-
* @param params Optional parameters for the stream subscription.
|
|
13163
|
+
* @param name - The name of the stream to subscribe to.
|
|
13164
|
+
* @param params - Optional parameters for the stream subscription.
|
|
12995
13165
|
* @returns A {@link SyncStream} instance that can be subscribed to.
|
|
12996
13166
|
* @experimental Sync streams are currently in alpha.
|
|
12997
13167
|
*/
|
|
@@ -13049,14 +13219,14 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
13049
13219
|
* Once the data have been successfully uploaded, call {@link CrudBatch.complete} before
|
|
13050
13220
|
* requesting the next batch.
|
|
13051
13221
|
*
|
|
13052
|
-
* Use
|
|
13222
|
+
* Use the `limit` parameter to specify the maximum number of updates to return in a single
|
|
13053
13223
|
* batch.
|
|
13054
13224
|
*
|
|
13055
13225
|
* This method does include transaction ids in the result, but does not group
|
|
13056
13226
|
* data by transaction. One batch may contain data from multiple transactions,
|
|
13057
13227
|
* and a single transaction may be split over multiple batches.
|
|
13058
13228
|
*
|
|
13059
|
-
* @param limit Maximum number of CRUD entries to include in the batch
|
|
13229
|
+
* @param limit - Maximum number of CRUD entries to include in the batch
|
|
13060
13230
|
* @returns A batch of CRUD operations to upload, or null if there are none
|
|
13061
13231
|
*/
|
|
13062
13232
|
async getCrudBatch(limit = DEFAULT_CRUD_BATCH_LIMIT) {
|
|
@@ -13083,7 +13253,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
13083
13253
|
* Once the data have been successfully uploaded, call {@link CrudTransaction.complete} before
|
|
13084
13254
|
* requesting the next transaction.
|
|
13085
13255
|
*
|
|
13086
|
-
* Unlike {@link getCrudBatch}, this only returns data from a single transaction at a time.
|
|
13256
|
+
* Unlike {@link AbstractPowerSyncDatabase.getCrudBatch}, this only returns data from a single transaction at a time.
|
|
13087
13257
|
* All data for the transaction is loaded into memory.
|
|
13088
13258
|
*
|
|
13089
13259
|
* @returns A transaction of CRUD operations to upload, or null if there are none
|
|
@@ -13098,7 +13268,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
13098
13268
|
* This is typically used from the {@link PowerSyncBackendConnector.uploadData} callback. Each entry emitted by the
|
|
13099
13269
|
* returned iterator is a full transaction containing all local writes made while that transaction was active.
|
|
13100
13270
|
*
|
|
13101
|
-
* Unlike {@link getNextCrudTransaction}, which always returns the oldest transaction that hasn't been
|
|
13271
|
+
* Unlike {@link AbstractPowerSyncDatabase.getNextCrudTransaction}, which always returns the oldest transaction that hasn't been
|
|
13102
13272
|
* {@link CrudTransaction.complete}d yet, this iterator can be used to receive multiple transactions. Calling
|
|
13103
13273
|
* {@link CrudTransaction.complete} will mark that and all prior transactions emitted by the iterator as completed.
|
|
13104
13274
|
*
|
|
@@ -13192,8 +13362,8 @@ SELECT * FROM crud_entries;
|
|
|
13192
13362
|
* the returned result's `rowsAffected` may be `0` for successful `UPDATE` and `DELETE` statements.
|
|
13193
13363
|
* Use a `RETURNING` clause and inspect `result.rows` when you need to confirm which rows changed.
|
|
13194
13364
|
*
|
|
13195
|
-
* @param sql The SQL query to execute
|
|
13196
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
13365
|
+
* @param sql - The SQL query to execute
|
|
13366
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
13197
13367
|
* @returns The query result as an object with structured key-value pairs
|
|
13198
13368
|
*/
|
|
13199
13369
|
async execute(sql, parameters) {
|
|
@@ -13203,8 +13373,8 @@ SELECT * FROM crud_entries;
|
|
|
13203
13373
|
* Execute a SQL write (INSERT/UPDATE/DELETE) query directly on the database without any PowerSync processing.
|
|
13204
13374
|
* This bypasses certain PowerSync abstractions and is useful for accessing the raw database results.
|
|
13205
13375
|
*
|
|
13206
|
-
* @param sql The SQL query to execute
|
|
13207
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
13376
|
+
* @param sql - The SQL query to execute
|
|
13377
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
13208
13378
|
* @returns The raw query result from the underlying database as a nested array of raw values, where each row is
|
|
13209
13379
|
* represented as an array of column values without field names.
|
|
13210
13380
|
*/
|
|
@@ -13217,8 +13387,8 @@ SELECT * FROM crud_entries;
|
|
|
13217
13387
|
* and optionally return results.
|
|
13218
13388
|
* This is faster than executing separately with each parameter set.
|
|
13219
13389
|
*
|
|
13220
|
-
* @param sql The SQL query to execute
|
|
13221
|
-
* @param parameters Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
|
|
13390
|
+
* @param sql - The SQL query to execute
|
|
13391
|
+
* @param parameters - Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
|
|
13222
13392
|
* @returns The query result
|
|
13223
13393
|
*/
|
|
13224
13394
|
async executeBatch(sql, parameters) {
|
|
@@ -13228,8 +13398,8 @@ SELECT * FROM crud_entries;
|
|
|
13228
13398
|
/**
|
|
13229
13399
|
* Execute a read-only query and return results.
|
|
13230
13400
|
*
|
|
13231
|
-
* @param sql The SQL query to execute
|
|
13232
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
13401
|
+
* @param sql - The SQL query to execute
|
|
13402
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
13233
13403
|
* @returns An array of results
|
|
13234
13404
|
*/
|
|
13235
13405
|
async getAll(sql, parameters) {
|
|
@@ -13239,8 +13409,8 @@ SELECT * FROM crud_entries;
|
|
|
13239
13409
|
/**
|
|
13240
13410
|
* Execute a read-only query and return the first result, or null if the ResultSet is empty.
|
|
13241
13411
|
*
|
|
13242
|
-
* @param sql The SQL query to execute
|
|
13243
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
13412
|
+
* @param sql - The SQL query to execute
|
|
13413
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
13244
13414
|
* @returns The first result if found, or null if no results are returned
|
|
13245
13415
|
*/
|
|
13246
13416
|
async getOptional(sql, parameters) {
|
|
@@ -13250,8 +13420,8 @@ SELECT * FROM crud_entries;
|
|
|
13250
13420
|
/**
|
|
13251
13421
|
* Execute a read-only query and return the first result, error if the ResultSet is empty.
|
|
13252
13422
|
*
|
|
13253
|
-
* @param sql The SQL query to execute
|
|
13254
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
13423
|
+
* @param sql - The SQL query to execute
|
|
13424
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
13255
13425
|
* @returns The first result matching the query
|
|
13256
13426
|
* @throws Error if no rows are returned
|
|
13257
13427
|
*/
|
|
@@ -13261,7 +13431,7 @@ SELECT * FROM crud_entries;
|
|
|
13261
13431
|
}
|
|
13262
13432
|
/**
|
|
13263
13433
|
* Takes a read lock, without starting a transaction.
|
|
13264
|
-
* In most cases, {@link readTransaction} should be used instead.
|
|
13434
|
+
* In most cases, {@link AbstractPowerSyncDatabase.readTransaction} should be used instead.
|
|
13265
13435
|
*/
|
|
13266
13436
|
async readLock(callback) {
|
|
13267
13437
|
await this.waitForReady();
|
|
@@ -13269,7 +13439,7 @@ SELECT * FROM crud_entries;
|
|
|
13269
13439
|
}
|
|
13270
13440
|
/**
|
|
13271
13441
|
* Takes a global lock, without starting a transaction.
|
|
13272
|
-
* In most cases, {@link writeTransaction} should be used instead.
|
|
13442
|
+
* In most cases, {@link AbstractPowerSyncDatabase.writeTransaction} should be used instead.
|
|
13273
13443
|
*/
|
|
13274
13444
|
async writeLock(callback) {
|
|
13275
13445
|
await this.waitForReady();
|
|
@@ -13280,8 +13450,8 @@ SELECT * FROM crud_entries;
|
|
|
13280
13450
|
* Read transactions can run concurrently to a write transaction.
|
|
13281
13451
|
* Changes from any write transaction are not visible to read transactions started before it.
|
|
13282
13452
|
*
|
|
13283
|
-
* @param callback Function to execute within the transaction
|
|
13284
|
-
* @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
|
|
13453
|
+
* @param callback - Function to execute within the transaction
|
|
13454
|
+
* @param lockTimeout - Time in milliseconds to wait for a lock before throwing an error
|
|
13285
13455
|
* @returns The result of the callback
|
|
13286
13456
|
* @throws Error if the lock cannot be obtained within the timeout period
|
|
13287
13457
|
*/
|
|
@@ -13298,8 +13468,8 @@ SELECT * FROM crud_entries;
|
|
|
13298
13468
|
* This takes a global lock - only one write transaction can execute against the database at a time.
|
|
13299
13469
|
* Statements within the transaction must be done on the provided {@link Transaction} interface.
|
|
13300
13470
|
*
|
|
13301
|
-
* @param callback Function to execute within the transaction
|
|
13302
|
-
* @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
|
|
13471
|
+
* @param callback - Function to execute within the transaction
|
|
13472
|
+
* @param lockTimeout - Time in milliseconds to wait for a lock before throwing an error
|
|
13303
13473
|
* @returns The result of the callback
|
|
13304
13474
|
* @throws Error if the lock cannot be obtained within the timeout period
|
|
13305
13475
|
*/
|
|
@@ -13376,15 +13546,15 @@ SELECT * FROM crud_entries;
|
|
|
13376
13546
|
}
|
|
13377
13547
|
/**
|
|
13378
13548
|
* Execute a read query every time the source tables are modified.
|
|
13379
|
-
* Use {@link
|
|
13549
|
+
* Use {@link SQLOnChangeOptions.throttleMs} to specify the minimum interval between queries.
|
|
13380
13550
|
* Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
|
|
13381
13551
|
*
|
|
13382
13552
|
* Note that the `onChange` callback member of the handler is required.
|
|
13383
13553
|
*
|
|
13384
|
-
* @param sql The SQL query to execute
|
|
13385
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
13386
|
-
* @param handler Callbacks for handling results and errors
|
|
13387
|
-
* @param options Options for configuring watch behavior
|
|
13554
|
+
* @param sql - The SQL query to execute
|
|
13555
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
13556
|
+
* @param handler - Callbacks for handling results and errors
|
|
13557
|
+
* @param options - Options for configuring watch behavior
|
|
13388
13558
|
*/
|
|
13389
13559
|
watchWithCallback(sql, parameters, handler, options) {
|
|
13390
13560
|
const { onResult, onError = (e) => this.logger.error(e) } = handler ?? {};
|
|
@@ -13397,7 +13567,7 @@ SELECT * FROM crud_entries;
|
|
|
13397
13567
|
const watchedQuery = new OnChangeQueryProcessor({
|
|
13398
13568
|
db: this,
|
|
13399
13569
|
comparator,
|
|
13400
|
-
placeholderData: null,
|
|
13570
|
+
placeholderData: null, // FIXME
|
|
13401
13571
|
watchOptions: {
|
|
13402
13572
|
query: {
|
|
13403
13573
|
compile: () => ({
|
|
@@ -13430,12 +13600,12 @@ SELECT * FROM crud_entries;
|
|
|
13430
13600
|
}
|
|
13431
13601
|
/**
|
|
13432
13602
|
* Execute a read query every time the source tables are modified.
|
|
13433
|
-
* Use {@link
|
|
13603
|
+
* Use {@link SQLOnChangeOptions.throttleMs} to specify the minimum interval between queries.
|
|
13434
13604
|
* Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
|
|
13435
13605
|
*
|
|
13436
|
-
* @param sql The SQL query to execute
|
|
13437
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
13438
|
-
* @param options Options for configuring watch behavior
|
|
13606
|
+
* @param sql - The SQL query to execute
|
|
13607
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
13608
|
+
* @param options - Options for configuring watch behavior
|
|
13439
13609
|
* @returns An AsyncIterable that yields QueryResults whenever the data changes
|
|
13440
13610
|
*/
|
|
13441
13611
|
watchWithAsyncGenerator(sql, parameters, options) {
|
|
@@ -13459,9 +13629,9 @@ SELECT * FROM crud_entries;
|
|
|
13459
13629
|
* If tables are specified in the options, those are used directly.
|
|
13460
13630
|
* Otherwise, analyzes the query using EXPLAIN to determine which tables are accessed.
|
|
13461
13631
|
*
|
|
13462
|
-
* @param sql The SQL query to analyze
|
|
13463
|
-
* @param parameters Optional parameters for the SQL query
|
|
13464
|
-
* @param options Optional watch options that may contain explicit table list
|
|
13632
|
+
* @param sql - The SQL query to analyze
|
|
13633
|
+
* @param parameters - Optional parameters for the SQL query
|
|
13634
|
+
* @param options - Optional watch options that may contain explicit table list
|
|
13465
13635
|
* @returns Array of table names that the query depends on
|
|
13466
13636
|
*/
|
|
13467
13637
|
async resolveTables(sql, parameters, options) {
|
|
@@ -13490,13 +13660,13 @@ SELECT * FROM crud_entries;
|
|
|
13490
13660
|
/**
|
|
13491
13661
|
* Invoke the provided callback on any changes to any of the specified tables.
|
|
13492
13662
|
*
|
|
13493
|
-
* This is preferred over {@link watchWithCallback} when multiple queries need to be performed
|
|
13663
|
+
* This is preferred over {@link AbstractPowerSyncDatabase.watchWithCallback} when multiple queries need to be performed
|
|
13494
13664
|
* together when data is changed.
|
|
13495
13665
|
*
|
|
13496
13666
|
* Note that the `onChange` callback member of the handler is required.
|
|
13497
13667
|
*
|
|
13498
|
-
* @param handler Callbacks for handling change events and errors
|
|
13499
|
-
* @param options Options for configuring watch behavior
|
|
13668
|
+
* @param handler - Callbacks for handling change events and errors
|
|
13669
|
+
* @param options - Options for configuring watch behavior
|
|
13500
13670
|
* @returns A dispose function to stop watching for changes
|
|
13501
13671
|
*/
|
|
13502
13672
|
onChangeWithCallback(handler, options) {
|
|
@@ -13539,12 +13709,12 @@ SELECT * FROM crud_entries;
|
|
|
13539
13709
|
/**
|
|
13540
13710
|
* Create a Stream of changes to any of the specified tables.
|
|
13541
13711
|
*
|
|
13542
|
-
* This is preferred over {@link watchWithAsyncGenerator} when multiple queries need to be
|
|
13543
|
-
* together when data is changed.
|
|
13712
|
+
* This is preferred over {@link AbstractPowerSyncDatabase.watchWithAsyncGenerator} when multiple queries need to be
|
|
13713
|
+
* performed together when data is changed.
|
|
13544
13714
|
*
|
|
13545
13715
|
* Note: do not declare this as `async *onChange` as it will not work in React Native.
|
|
13546
13716
|
*
|
|
13547
|
-
* @param options Options for configuring watch behavior
|
|
13717
|
+
* @param options - Options for configuring watch behavior
|
|
13548
13718
|
* @returns An AsyncIterable that yields change events whenever the specified tables change
|
|
13549
13719
|
*/
|
|
13550
13720
|
onChangeWithAsyncGenerator(options) {
|
|
@@ -13582,15 +13752,15 @@ SELECT * FROM crud_entries;
|
|
|
13582
13752
|
changedTables.add(table);
|
|
13583
13753
|
}
|
|
13584
13754
|
}
|
|
13585
|
-
/**
|
|
13586
|
-
* @ignore
|
|
13587
|
-
*/
|
|
13588
13755
|
async executeReadOnly(sql, params) {
|
|
13589
13756
|
await this.waitForReady();
|
|
13590
13757
|
return this.database.readLock((tx) => tx.execute(sql, params));
|
|
13591
13758
|
}
|
|
13592
13759
|
}
|
|
13593
13760
|
|
|
13761
|
+
/**
|
|
13762
|
+
* @internal
|
|
13763
|
+
*/
|
|
13594
13764
|
class AbstractPowerSyncDatabaseOpenFactory {
|
|
13595
13765
|
options;
|
|
13596
13766
|
constructor(options) {
|
|
@@ -13615,6 +13785,9 @@ class AbstractPowerSyncDatabaseOpenFactory {
|
|
|
13615
13785
|
}
|
|
13616
13786
|
}
|
|
13617
13787
|
|
|
13788
|
+
/**
|
|
13789
|
+
* @internal
|
|
13790
|
+
*/
|
|
13618
13791
|
function runOnSchemaChange(callback, db, options) {
|
|
13619
13792
|
const triggerWatchedQuery = () => {
|
|
13620
13793
|
const abortController = new AbortController();
|
|
@@ -13639,6 +13812,9 @@ function runOnSchemaChange(callback, db, options) {
|
|
|
13639
13812
|
triggerWatchedQuery();
|
|
13640
13813
|
}
|
|
13641
13814
|
|
|
13815
|
+
/**
|
|
13816
|
+
* @public
|
|
13817
|
+
*/
|
|
13642
13818
|
function compilableQueryWatch(db, query, handler, options) {
|
|
13643
13819
|
const { onResult, onError = (e) => { } } = handler ?? {};
|
|
13644
13820
|
if (!onResult) {
|
|
@@ -13676,8 +13852,14 @@ function compilableQueryWatch(db, query, handler, options) {
|
|
|
13676
13852
|
runOnSchemaChange(watchQuery, db, options);
|
|
13677
13853
|
}
|
|
13678
13854
|
|
|
13855
|
+
/**
|
|
13856
|
+
* @internal
|
|
13857
|
+
*/
|
|
13679
13858
|
const MAX_OP_ID = '9223372036854775807';
|
|
13680
13859
|
|
|
13860
|
+
/**
|
|
13861
|
+
* @internal
|
|
13862
|
+
*/
|
|
13681
13863
|
class SqliteBucketStorage extends BaseObserver {
|
|
13682
13864
|
db;
|
|
13683
13865
|
logger;
|
|
@@ -13838,6 +14020,8 @@ class SqliteBucketStorage extends BaseObserver {
|
|
|
13838
14020
|
* Thrown when an underlying database connection is closed.
|
|
13839
14021
|
* This is particularly relevant when worker connections are marked as closed while
|
|
13840
14022
|
* operations are still in progress.
|
|
14023
|
+
*
|
|
14024
|
+
* @internal
|
|
13841
14025
|
*/
|
|
13842
14026
|
class ConnectionClosedError extends Error {
|
|
13843
14027
|
static NAME = 'ConnectionClosedError';
|
|
@@ -13857,6 +14041,8 @@ class ConnectionClosedError extends Error {
|
|
|
13857
14041
|
|
|
13858
14042
|
/**
|
|
13859
14043
|
* A schema is a collection of tables. It is used to define the structure of a database.
|
|
14044
|
+
*
|
|
14045
|
+
* @public
|
|
13860
14046
|
*/
|
|
13861
14047
|
class Schema {
|
|
13862
14048
|
/*
|
|
@@ -13893,7 +14079,7 @@ class Schema {
|
|
|
13893
14079
|
* Since raw tables are not backed by JSON, running complex queries on them may be more efficient. Further, they allow
|
|
13894
14080
|
* using client-side table and column constraints.
|
|
13895
14081
|
*
|
|
13896
|
-
* @param tables An object of (table name, raw table definition) entries.
|
|
14082
|
+
* @param tables - An object of (table name, raw table definition) entries.
|
|
13897
14083
|
*/
|
|
13898
14084
|
withRawTables(tables) {
|
|
13899
14085
|
for (const [name, rawTableDefinition] of Object.entries(tables)) {
|
|
@@ -13939,6 +14125,8 @@ class Schema {
|
|
|
13939
14125
|
Generate a new table from the columns and indexes
|
|
13940
14126
|
@deprecated You should use {@link Table} instead as it now allows TableV2 syntax.
|
|
13941
14127
|
This will be removed in the next major release.
|
|
14128
|
+
|
|
14129
|
+
@public
|
|
13942
14130
|
*/
|
|
13943
14131
|
class TableV2 extends Table {
|
|
13944
14132
|
}
|
|
@@ -13949,6 +14137,8 @@ function sanitizeString(input) {
|
|
|
13949
14137
|
/**
|
|
13950
14138
|
* Helper function for sanitizing UUID input strings.
|
|
13951
14139
|
* Typically used with {@link sanitizeSQL}.
|
|
14140
|
+
*
|
|
14141
|
+
* @alpha
|
|
13952
14142
|
*/
|
|
13953
14143
|
function sanitizeUUID(uuid) {
|
|
13954
14144
|
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;
|
|
@@ -13985,6 +14175,8 @@ function sanitizeUUID(uuid) {
|
|
|
13985
14175
|
* // Incorrect:
|
|
13986
14176
|
* sanitizeSQL`New.id = '${myID}'` // Produces double quotes: New.id = ''O''Reilly''
|
|
13987
14177
|
* ```
|
|
14178
|
+
*
|
|
14179
|
+
* @alpha
|
|
13988
14180
|
*/
|
|
13989
14181
|
function sanitizeSQL(strings, ...values) {
|
|
13990
14182
|
let result = '';
|
|
@@ -14014,6 +14206,8 @@ function sanitizeSQL(strings, ...values) {
|
|
|
14014
14206
|
|
|
14015
14207
|
/**
|
|
14016
14208
|
* Performs a {@link AbstractPowerSyncDatabase.getAll} operation for a watched query.
|
|
14209
|
+
*
|
|
14210
|
+
* @public
|
|
14017
14211
|
*/
|
|
14018
14212
|
class GetAllQuery {
|
|
14019
14213
|
options;
|
|
@@ -14038,6 +14232,9 @@ class GetAllQuery {
|
|
|
14038
14232
|
}
|
|
14039
14233
|
|
|
14040
14234
|
const TypedLogger = Logger;
|
|
14235
|
+
/**
|
|
14236
|
+
* @public
|
|
14237
|
+
*/
|
|
14041
14238
|
const LogLevel = {
|
|
14042
14239
|
TRACE: TypedLogger.TRACE,
|
|
14043
14240
|
DEBUG: TypedLogger.DEBUG,
|
|
@@ -14054,6 +14251,7 @@ const LogLevel = {
|
|
|
14054
14251
|
* across all loggers created with `createLogger`. Adjusting settings on this
|
|
14055
14252
|
* base logger affects all loggers derived from it unless explicitly overridden.
|
|
14056
14253
|
*
|
|
14254
|
+
* @public
|
|
14057
14255
|
*/
|
|
14058
14256
|
function createBaseLogger() {
|
|
14059
14257
|
return Logger;
|
|
@@ -14064,6 +14262,8 @@ function createBaseLogger() {
|
|
|
14064
14262
|
* Named loggers allow specific modules or areas of your application to have
|
|
14065
14263
|
* their own logging levels and behaviors. These loggers inherit configuration
|
|
14066
14264
|
* from the base logger by default but can override settings independently.
|
|
14265
|
+
*
|
|
14266
|
+
* @public
|
|
14067
14267
|
*/
|
|
14068
14268
|
function createLogger(name, options = {}) {
|
|
14069
14269
|
const logger = Logger.get(name);
|
|
@@ -14073,6 +14273,9 @@ function createLogger(name, options = {}) {
|
|
|
14073
14273
|
return logger;
|
|
14074
14274
|
}
|
|
14075
14275
|
|
|
14276
|
+
/**
|
|
14277
|
+
* @internal
|
|
14278
|
+
*/
|
|
14076
14279
|
const parseQuery = (query, parameters) => {
|
|
14077
14280
|
let sqlStatement;
|
|
14078
14281
|
if (typeof query == 'string') {
|