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