@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.
Files changed (213) hide show
  1. package/dist/bundle.cjs +548 -345
  2. package/dist/bundle.cjs.map +1 -1
  3. package/dist/bundle.mjs +548 -345
  4. package/dist/bundle.mjs.map +1 -1
  5. package/dist/bundle.node.cjs +548 -345
  6. package/dist/bundle.node.cjs.map +1 -1
  7. package/dist/bundle.node.mjs +548 -345
  8. package/dist/bundle.node.mjs.map +1 -1
  9. package/dist/index.d.cts +727 -189
  10. package/lib/attachments/AttachmentContext.d.ts +7 -6
  11. package/lib/attachments/AttachmentContext.js +2 -1
  12. package/lib/attachments/AttachmentContext.js.map +1 -1
  13. package/lib/attachments/AttachmentErrorHandler.d.ts +6 -6
  14. package/lib/attachments/AttachmentQueue.d.ts +61 -20
  15. package/lib/attachments/AttachmentQueue.js +16 -18
  16. package/lib/attachments/AttachmentQueue.js.map +1 -1
  17. package/lib/attachments/LocalStorageAdapter.d.ts +14 -8
  18. package/lib/attachments/LocalStorageAdapter.js +3 -0
  19. package/lib/attachments/LocalStorageAdapter.js.map +1 -1
  20. package/lib/attachments/RemoteStorageAdapter.d.ts +4 -4
  21. package/lib/attachments/Schema.d.ts +12 -4
  22. package/lib/attachments/Schema.js +8 -3
  23. package/lib/attachments/Schema.js.map +1 -1
  24. package/lib/attachments/WatchedAttachmentItem.d.ts +3 -1
  25. package/lib/client/AbstractPowerSyncDatabase.d.ts +110 -58
  26. package/lib/client/AbstractPowerSyncDatabase.js +59 -48
  27. package/lib/client/AbstractPowerSyncDatabase.js.map +1 -1
  28. package/lib/client/AbstractPowerSyncOpenFactory.d.ts +6 -0
  29. package/lib/client/AbstractPowerSyncOpenFactory.js +3 -0
  30. package/lib/client/AbstractPowerSyncOpenFactory.js.map +1 -1
  31. package/lib/client/ConnectionManager.d.ts +4 -1
  32. package/lib/client/ConnectionManager.js +1 -1
  33. package/lib/client/ConnectionManager.js.map +1 -1
  34. package/lib/client/Query.d.ts +9 -0
  35. package/lib/client/SQLOpenFactory.d.ts +12 -0
  36. package/lib/client/SQLOpenFactory.js +6 -0
  37. package/lib/client/SQLOpenFactory.js.map +1 -1
  38. package/lib/client/compilableQueryWatch.d.ts +6 -0
  39. package/lib/client/compilableQueryWatch.js +3 -0
  40. package/lib/client/compilableQueryWatch.js.map +1 -1
  41. package/lib/client/connection/PowerSyncBackendConnector.d.ts +3 -0
  42. package/lib/client/connection/PowerSyncCredentials.d.ts +3 -0
  43. package/lib/client/constants.d.ts +3 -0
  44. package/lib/client/constants.js +3 -0
  45. package/lib/client/constants.js.map +1 -1
  46. package/lib/client/runOnSchemaChange.d.ts +3 -0
  47. package/lib/client/runOnSchemaChange.js +3 -0
  48. package/lib/client/runOnSchemaChange.js.map +1 -1
  49. package/lib/client/sync/bucket/BucketStorageAdapter.d.ts +12 -0
  50. package/lib/client/sync/bucket/BucketStorageAdapter.js +6 -0
  51. package/lib/client/sync/bucket/BucketStorageAdapter.js.map +1 -1
  52. package/lib/client/sync/bucket/CrudBatch.d.ts +2 -0
  53. package/lib/client/sync/bucket/CrudBatch.js +2 -0
  54. package/lib/client/sync/bucket/CrudBatch.js.map +1 -1
  55. package/lib/client/sync/bucket/CrudEntry.d.ts +9 -0
  56. package/lib/client/sync/bucket/CrudEntry.js +4 -0
  57. package/lib/client/sync/bucket/CrudEntry.js.map +1 -1
  58. package/lib/client/sync/bucket/CrudTransaction.d.ts +3 -0
  59. package/lib/client/sync/bucket/CrudTransaction.js +3 -0
  60. package/lib/client/sync/bucket/CrudTransaction.js.map +1 -1
  61. package/lib/client/sync/bucket/SqliteBucketStorage.d.ts +3 -0
  62. package/lib/client/sync/bucket/SqliteBucketStorage.js +3 -0
  63. package/lib/client/sync/bucket/SqliteBucketStorage.js.map +1 -1
  64. package/lib/client/sync/stream/AbstractRemote.d.ts +30 -1
  65. package/lib/client/sync/stream/AbstractRemote.js +15 -1
  66. package/lib/client/sync/stream/AbstractRemote.js.map +1 -1
  67. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.d.ts +55 -5
  68. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +32 -4
  69. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js.map +1 -1
  70. package/lib/client/sync/stream/JsonValue.d.ts +3 -0
  71. package/lib/client/sync/stream/WebsocketClientTransport.js +2 -1
  72. package/lib/client/sync/stream/WebsocketClientTransport.js.map +1 -1
  73. package/lib/client/sync/sync-streams.d.ts +22 -7
  74. package/lib/client/triggers/TriggerManager.d.ts +19 -18
  75. package/lib/client/triggers/TriggerManager.js +2 -1
  76. package/lib/client/triggers/TriggerManager.js.map +1 -1
  77. package/lib/client/triggers/TriggerManagerImpl.d.ts +1 -1
  78. package/lib/client/triggers/TriggerManagerImpl.js +3 -3
  79. package/lib/client/triggers/TriggerManagerImpl.js.map +1 -1
  80. package/lib/client/triggers/sanitizeSQL.d.ts +4 -0
  81. package/lib/client/triggers/sanitizeSQL.js +4 -0
  82. package/lib/client/triggers/sanitizeSQL.js.map +1 -1
  83. package/lib/client/watched/GetAllQuery.d.ts +4 -0
  84. package/lib/client/watched/GetAllQuery.js +2 -0
  85. package/lib/client/watched/GetAllQuery.js.map +1 -1
  86. package/lib/client/watched/WatchedQuery.d.ts +24 -2
  87. package/lib/client/watched/WatchedQuery.js +9 -0
  88. package/lib/client/watched/WatchedQuery.js.map +1 -1
  89. package/lib/client/watched/processors/AbstractQueryProcessor.d.ts +1 -1
  90. package/lib/client/watched/processors/AbstractQueryProcessor.js.map +1 -1
  91. package/lib/client/watched/processors/DifferentialQueryProcessor.d.ts +20 -0
  92. package/lib/client/watched/processors/DifferentialQueryProcessor.js +4 -0
  93. package/lib/client/watched/processors/DifferentialQueryProcessor.js.map +1 -1
  94. package/lib/client/watched/processors/OnChangeQueryProcessor.d.ts +4 -0
  95. package/lib/client/watched/processors/OnChangeQueryProcessor.js.map +1 -1
  96. package/lib/client/watched/processors/comparators.d.ts +8 -0
  97. package/lib/client/watched/processors/comparators.js +4 -0
  98. package/lib/client/watched/processors/comparators.js.map +1 -1
  99. package/lib/db/ConnectionClosedError.d.ts +2 -0
  100. package/lib/db/ConnectionClosedError.js +2 -0
  101. package/lib/db/ConnectionClosedError.js.map +1 -1
  102. package/lib/db/DBAdapter.d.ts +56 -6
  103. package/lib/db/DBAdapter.js +15 -3
  104. package/lib/db/DBAdapter.js.map +1 -1
  105. package/lib/db/crud/SyncProgress.d.ts +6 -1
  106. package/lib/db/crud/SyncProgress.js +2 -0
  107. package/lib/db/crud/SyncProgress.js.map +1 -1
  108. package/lib/db/crud/SyncStatus.d.ts +36 -38
  109. package/lib/db/crud/SyncStatus.js +19 -14
  110. package/lib/db/crud/SyncStatus.js.map +1 -1
  111. package/lib/db/crud/UploadQueueStatus.d.ts +3 -0
  112. package/lib/db/crud/UploadQueueStatus.js +3 -0
  113. package/lib/db/crud/UploadQueueStatus.js.map +1 -1
  114. package/lib/db/schema/Column.d.ts +28 -0
  115. package/lib/db/schema/Column.js +16 -3
  116. package/lib/db/schema/Column.js.map +1 -1
  117. package/lib/db/schema/Index.d.ts +9 -0
  118. package/lib/db/schema/Index.js +6 -0
  119. package/lib/db/schema/Index.js.map +1 -1
  120. package/lib/db/schema/IndexedColumn.d.ts +9 -0
  121. package/lib/db/schema/IndexedColumn.js +6 -0
  122. package/lib/db/schema/IndexedColumn.js.map +1 -1
  123. package/lib/db/schema/RawTable.d.ts +7 -1
  124. package/lib/db/schema/Schema.d.ts +6 -1
  125. package/lib/db/schema/Schema.js +3 -1
  126. package/lib/db/schema/Schema.js.map +1 -1
  127. package/lib/db/schema/Table.d.ts +27 -3
  128. package/lib/db/schema/Table.js +9 -0
  129. package/lib/db/schema/Table.js.map +1 -1
  130. package/lib/db/schema/TableV2.d.ts +2 -0
  131. package/lib/db/schema/TableV2.js +2 -0
  132. package/lib/db/schema/TableV2.js.map +1 -1
  133. package/lib/index.d.ts +1 -1
  134. package/lib/types/types.d.ts +6 -0
  135. package/lib/utils/AbortOperation.d.ts +2 -0
  136. package/lib/utils/AbortOperation.js +2 -0
  137. package/lib/utils/AbortOperation.js.map +1 -1
  138. package/lib/utils/BaseObserver.d.ts +12 -0
  139. package/lib/utils/BaseObserver.js +3 -0
  140. package/lib/utils/BaseObserver.js.map +1 -1
  141. package/lib/utils/ControlledExecutor.d.ts +6 -0
  142. package/lib/utils/ControlledExecutor.js +3 -0
  143. package/lib/utils/ControlledExecutor.js.map +1 -1
  144. package/lib/utils/Logger.d.ts +9 -0
  145. package/lib/utils/Logger.js +6 -0
  146. package/lib/utils/Logger.js.map +1 -1
  147. package/lib/utils/mutex.d.ts +8 -0
  148. package/lib/utils/mutex.js +3 -0
  149. package/lib/utils/mutex.js.map +1 -1
  150. package/lib/utils/parseQuery.d.ts +6 -0
  151. package/lib/utils/parseQuery.js +3 -0
  152. package/lib/utils/parseQuery.js.map +1 -1
  153. package/lib/utils/stream_transform.d.ts +3 -1
  154. package/lib/utils/stream_transform.js.map +1 -1
  155. package/package.json +3 -2
  156. package/src/attachments/AttachmentContext.ts +7 -6
  157. package/src/attachments/AttachmentErrorHandler.ts +6 -6
  158. package/src/attachments/AttachmentQueue.ts +71 -23
  159. package/src/attachments/LocalStorageAdapter.ts +14 -8
  160. package/src/attachments/README.md +2 -0
  161. package/src/attachments/RemoteStorageAdapter.ts +4 -4
  162. package/src/attachments/Schema.ts +12 -4
  163. package/src/attachments/WatchedAttachmentItem.ts +3 -1
  164. package/src/client/AbstractPowerSyncDatabase.ts +117 -62
  165. package/src/client/AbstractPowerSyncOpenFactory.ts +6 -0
  166. package/src/client/ConnectionManager.ts +4 -1
  167. package/src/client/Query.ts +9 -0
  168. package/src/client/SQLOpenFactory.ts +12 -0
  169. package/src/client/compilableQueryWatch.ts +6 -0
  170. package/src/client/connection/PowerSyncBackendConnector.ts +3 -0
  171. package/src/client/connection/PowerSyncCredentials.ts +3 -0
  172. package/src/client/constants.ts +3 -0
  173. package/src/client/runOnSchemaChange.ts +3 -0
  174. package/src/client/sync/bucket/BucketStorageAdapter.ts +12 -0
  175. package/src/client/sync/bucket/CrudBatch.ts +2 -0
  176. package/src/client/sync/bucket/CrudEntry.ts +9 -0
  177. package/src/client/sync/bucket/CrudTransaction.ts +3 -0
  178. package/src/client/sync/bucket/SqliteBucketStorage.ts +3 -0
  179. package/src/client/sync/stream/AbstractRemote.ts +30 -1
  180. package/src/client/sync/stream/AbstractStreamingSyncImplementation.ts +55 -5
  181. package/src/client/sync/stream/JsonValue.ts +3 -0
  182. package/src/client/sync/stream/WebsocketClientTransport.ts +3 -1
  183. package/src/client/sync/sync-streams.ts +22 -9
  184. package/src/client/triggers/TriggerManager.ts +19 -18
  185. package/src/client/triggers/TriggerManagerImpl.ts +5 -5
  186. package/src/client/triggers/sanitizeSQL.ts +5 -0
  187. package/src/client/watched/GetAllQuery.ts +5 -1
  188. package/src/client/watched/WatchedQuery.ts +24 -2
  189. package/src/client/watched/processors/AbstractQueryProcessor.ts +6 -6
  190. package/src/client/watched/processors/DifferentialQueryProcessor.ts +28 -5
  191. package/src/client/watched/processors/OnChangeQueryProcessor.ts +9 -3
  192. package/src/client/watched/processors/comparators.ts +8 -0
  193. package/src/db/ConnectionClosedError.ts +2 -0
  194. package/src/db/DBAdapter.ts +58 -6
  195. package/src/db/crud/SyncProgress.ts +6 -1
  196. package/src/db/crud/SyncStatus.ts +40 -21
  197. package/src/db/crud/UploadQueueStatus.ts +3 -0
  198. package/src/db/schema/Column.ts +28 -3
  199. package/src/db/schema/Index.ts +9 -0
  200. package/src/db/schema/IndexedColumn.ts +9 -0
  201. package/src/db/schema/RawTable.ts +7 -1
  202. package/src/db/schema/Schema.ts +8 -3
  203. package/src/db/schema/Table.ts +30 -5
  204. package/src/db/schema/TableV2.ts +2 -0
  205. package/src/index.ts +1 -1
  206. package/src/types/types.ts +6 -0
  207. package/src/utils/AbortOperation.ts +2 -0
  208. package/src/utils/BaseObserver.ts +12 -0
  209. package/src/utils/ControlledExecutor.ts +6 -0
  210. package/src/utils/Logger.ts +9 -0
  211. package/src/utils/mutex.ts +12 -0
  212. package/src/utils/parseQuery.ts +6 -0
  213. package/src/utils/stream_transform.ts +3 -1
package/dist/bundle.mjs CHANGED
@@ -1,4 +1,7 @@
1
- // https://www.sqlite.org/lang_expr.html#castexpr
1
+ /**
2
+ * @see https://www.sqlite.org/lang_expr.html#castexpr
3
+ * @public
4
+ */
2
5
  var ColumnType;
3
6
  (function (ColumnType) {
4
7
  ColumnType["TEXT"] = "TEXT";
@@ -14,14 +17,24 @@ const integer = {
14
17
  const real = {
15
18
  type: ColumnType.REAL
16
19
  };
17
- // powersync-sqlite-core limits the number of column per table to 1999, due to internal SQLite limits.
18
- // In earlier versions this was limited to 63.
20
+ /**
21
+ * powersync-sqlite-core limits the number of column per table to 1999, due to internal SQLite limits.
22
+ * In earlier versions this was limited to 63.
23
+ *
24
+ * @internal
25
+ */
19
26
  const MAX_AMOUNT_OF_COLUMNS = 1999;
27
+ /**
28
+ * @public
29
+ */
20
30
  const column = {
21
31
  text,
22
32
  integer,
23
33
  real
24
34
  };
35
+ /**
36
+ * @public
37
+ */
25
38
  class Column {
26
39
  options;
27
40
  constructor(options) {
@@ -41,9 +54,15 @@ class Column {
41
54
  }
42
55
  }
43
56
 
57
+ /**
58
+ * @internal
59
+ */
44
60
  const DEFAULT_INDEX_COLUMN_OPTIONS = {
45
61
  ascending: true
46
62
  };
63
+ /**
64
+ * @public
65
+ */
47
66
  class IndexedColumn {
48
67
  options;
49
68
  static createAscending(column) {
@@ -70,9 +89,15 @@ class IndexedColumn {
70
89
  }
71
90
  }
72
91
 
92
+ /**
93
+ * @internal
94
+ */
73
95
  const DEFAULT_INDEX_OPTIONS = {
74
96
  columns: []
75
97
  };
98
+ /**
99
+ * @public
100
+ */
76
101
  class Index {
77
102
  options;
78
103
  static createAscending(options, columnNames) {
@@ -114,6 +139,9 @@ function encodeTableOptions(options) {
114
139
  };
115
140
  }
116
141
 
142
+ /**
143
+ * @internal
144
+ */
117
145
  const DEFAULT_TABLE_OPTIONS = {
118
146
  indexes: [],
119
147
  insertOnly: false,
@@ -122,7 +150,13 @@ const DEFAULT_TABLE_OPTIONS = {
122
150
  trackMetadata: false,
123
151
  ignoreEmptyUpdates: false
124
152
  };
153
+ /**
154
+ * @internal
155
+ */
125
156
  const InvalidSQLCharacters = /["'%,.#\s[\]]/;
157
+ /**
158
+ * @public
159
+ */
126
160
  class Table {
127
161
  options;
128
162
  _mappedColumns;
@@ -313,6 +347,11 @@ class Table {
313
347
  }
314
348
  }
315
349
 
350
+ /**
351
+ * The default name of the local table storing attachment data.
352
+ *
353
+ * @alpha
354
+ */
316
355
  const ATTACHMENT_TABLE = 'attachments';
317
356
  /**
318
357
  * Maps a database row to an AttachmentRecord.
@@ -320,7 +359,7 @@ const ATTACHMENT_TABLE = 'attachments';
320
359
  * @param row - The database row object
321
360
  * @returns The corresponding AttachmentRecord
322
361
  *
323
- * @experimental
362
+ * @alpha
324
363
  */
325
364
  function attachmentFromSql(row) {
326
365
  return {
@@ -338,7 +377,7 @@ function attachmentFromSql(row) {
338
377
  /**
339
378
  * AttachmentState represents the current synchronization state of an attachment.
340
379
  *
341
- * @experimental
380
+ * @alpha
342
381
  */
343
382
  var AttachmentState;
344
383
  (function (AttachmentState) {
@@ -351,7 +390,7 @@ var AttachmentState;
351
390
  /**
352
391
  * AttachmentTable defines the schema for the attachment queue table.
353
392
  *
354
- * @internal
393
+ * @alpha
355
394
  */
356
395
  class AttachmentTable extends Table {
357
396
  constructor(options) {
@@ -379,7 +418,8 @@ class AttachmentTable extends Table {
379
418
  * Provides methods to query, insert, update, and delete attachment records with
380
419
  * proper transaction management through PowerSync.
381
420
  *
382
- * @internal
421
+ * @experimental
422
+ * @alpha
383
423
  */
384
424
  class AttachmentContext {
385
425
  /** PowerSync database instance for executing queries */
@@ -601,6 +641,9 @@ class AttachmentContext {
601
641
  }
602
642
  }
603
643
 
644
+ /**
645
+ * @public
646
+ */
604
647
  var WatchedQueryListenerEvent;
605
648
  (function (WatchedQueryListenerEvent) {
606
649
  WatchedQueryListenerEvent["ON_DATA"] = "onData";
@@ -609,176 +652,18 @@ var WatchedQueryListenerEvent;
609
652
  WatchedQueryListenerEvent["SETTINGS_WILL_UPDATE"] = "settingsWillUpdate";
610
653
  WatchedQueryListenerEvent["CLOSED"] = "closed";
611
654
  })(WatchedQueryListenerEvent || (WatchedQueryListenerEvent = {}));
655
+ /**
656
+ * @internal
657
+ */
612
658
  const DEFAULT_WATCH_THROTTLE_MS = 30;
659
+ /**
660
+ * @internal
661
+ */
613
662
  const DEFAULT_WATCH_QUERY_OPTIONS = {
614
663
  throttleMs: DEFAULT_WATCH_THROTTLE_MS,
615
664
  reportFetching: true
616
665
  };
617
666
 
618
- /**
619
- * Orchestrates attachment synchronization between local and remote storage.
620
- * Handles uploads, downloads, deletions, and state transitions.
621
- *
622
- * @internal
623
- */
624
- class SyncingService {
625
- attachmentService;
626
- localStorage;
627
- remoteStorage;
628
- logger;
629
- errorHandler;
630
- constructor(attachmentService, localStorage, remoteStorage, logger, errorHandler) {
631
- this.attachmentService = attachmentService;
632
- this.localStorage = localStorage;
633
- this.remoteStorage = remoteStorage;
634
- this.logger = logger;
635
- this.errorHandler = errorHandler;
636
- }
637
- /**
638
- * Processes attachments based on their state (upload, download, or delete).
639
- * All updates are saved in a single batch after processing.
640
- *
641
- * @param attachments - Array of attachment records to process
642
- * @param context - Attachment context for database operations
643
- * @returns Promise that resolves when all attachments have been processed and saved
644
- */
645
- async processAttachments(attachments, context) {
646
- const updatedAttachments = [];
647
- for (const attachment of attachments) {
648
- switch (attachment.state) {
649
- case AttachmentState.QUEUED_UPLOAD:
650
- const uploaded = await this.uploadAttachment(attachment);
651
- updatedAttachments.push(uploaded);
652
- break;
653
- case AttachmentState.QUEUED_DOWNLOAD:
654
- const downloaded = await this.downloadAttachment(attachment);
655
- updatedAttachments.push(downloaded);
656
- break;
657
- case AttachmentState.QUEUED_DELETE:
658
- const deleted = await this.deleteAttachment(attachment, context);
659
- updatedAttachments.push(deleted);
660
- break;
661
- }
662
- }
663
- await context.saveAttachments(updatedAttachments);
664
- }
665
- /**
666
- * Uploads an attachment from local storage to remote storage.
667
- * On success, marks as SYNCED. On failure, defers to error handler or archives.
668
- *
669
- * @param attachment - The attachment record to upload
670
- * @returns Updated attachment record with new state
671
- * @throws Error if the attachment has no localUri
672
- */
673
- async uploadAttachment(attachment) {
674
- this.logger.info(`Uploading attachment ${attachment.filename}`);
675
- try {
676
- if (attachment.localUri == null) {
677
- throw new Error(`No localUri for attachment ${attachment.id}`);
678
- }
679
- const fileBlob = await this.localStorage.readFile(attachment.localUri);
680
- await this.remoteStorage.uploadFile(fileBlob, attachment);
681
- return {
682
- ...attachment,
683
- state: AttachmentState.SYNCED,
684
- hasSynced: true
685
- };
686
- }
687
- catch (error) {
688
- const shouldRetry = (await this.errorHandler?.onUploadError(attachment, error)) ?? true;
689
- if (!shouldRetry) {
690
- return {
691
- ...attachment,
692
- state: AttachmentState.ARCHIVED
693
- };
694
- }
695
- return attachment;
696
- }
697
- }
698
- /**
699
- * Downloads an attachment from remote storage to local storage.
700
- * Retrieves the file, converts to base64, and saves locally.
701
- * On success, marks as SYNCED. On failure, defers to error handler or archives.
702
- *
703
- * @param attachment - The attachment record to download
704
- * @returns Updated attachment record with local URI and new state
705
- */
706
- async downloadAttachment(attachment) {
707
- this.logger.info(`Downloading attachment ${attachment.filename}`);
708
- try {
709
- const fileData = await this.remoteStorage.downloadFile(attachment);
710
- const localUri = this.localStorage.getLocalUri(attachment.filename);
711
- await this.localStorage.saveFile(localUri, fileData);
712
- return {
713
- ...attachment,
714
- state: AttachmentState.SYNCED,
715
- localUri: localUri,
716
- hasSynced: true
717
- };
718
- }
719
- catch (error) {
720
- const shouldRetry = (await this.errorHandler?.onDownloadError(attachment, error)) ?? true;
721
- if (!shouldRetry) {
722
- return {
723
- ...attachment,
724
- state: AttachmentState.ARCHIVED
725
- };
726
- }
727
- return attachment;
728
- }
729
- }
730
- /**
731
- * Deletes an attachment from both remote and local storage.
732
- * Removes the remote file, local file (if exists), and the attachment record.
733
- * On failure, defers to error handler or archives.
734
- *
735
- * @param attachment - The attachment record to delete
736
- * @param context - Attachment context for database operations
737
- * @returns Updated attachment record
738
- */
739
- async deleteAttachment(attachment, context) {
740
- try {
741
- await this.remoteStorage.deleteFile(attachment);
742
- if (attachment.localUri) {
743
- await this.localStorage.deleteFile(attachment.localUri);
744
- }
745
- await context.deleteAttachment(attachment.id);
746
- return {
747
- ...attachment,
748
- state: AttachmentState.ARCHIVED
749
- };
750
- }
751
- catch (error) {
752
- const shouldRetry = (await this.errorHandler?.onDeleteError(attachment, error)) ?? true;
753
- if (!shouldRetry) {
754
- return {
755
- ...attachment,
756
- state: AttachmentState.ARCHIVED
757
- };
758
- }
759
- return attachment;
760
- }
761
- }
762
- /**
763
- * Performs cleanup of archived attachments by removing their local files and records.
764
- * Errors during local file deletion are logged but do not prevent record deletion.
765
- */
766
- async deleteArchivedAttachments(context) {
767
- return await context.deleteArchivedAttachments(async (archivedAttachments) => {
768
- for (const attachment of archivedAttachments) {
769
- if (attachment.localUri) {
770
- try {
771
- await this.localStorage.deleteFile(attachment.localUri);
772
- }
773
- catch (error) {
774
- this.logger.error('Error deleting local file for archived attachment', error);
775
- }
776
- }
777
- }
778
- });
779
- }
780
- }
781
-
782
667
  /**
783
668
  * A simple fixed-capacity queue implementation.
784
669
  *
@@ -935,93 +820,260 @@ class Semaphore {
935
820
  return { release, item: items[0] };
936
821
  }
937
822
  /**
938
- * Requests access to all items from the pool.
823
+ * Requests access to all items from the pool.
824
+ *
825
+ * The returned `release` callback must be invoked to return items into the pool.
826
+ */
827
+ requestAll(abort) {
828
+ return this.requestPermits(this.size, abort);
829
+ }
830
+ }
831
+ /**
832
+ * An asynchronous mutex implementation.
833
+ *
834
+ * @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
835
+ */
836
+ class Mutex {
837
+ inner = new Semaphore([null]);
838
+ async acquire(abort) {
839
+ const { release } = await this.inner.requestOne(abort);
840
+ return release;
841
+ }
842
+ async runExclusive(fn, abort) {
843
+ const returnMutex = await this.acquire(abort);
844
+ try {
845
+ return await fn();
846
+ }
847
+ finally {
848
+ returnMutex();
849
+ }
850
+ }
851
+ }
852
+ /**
853
+ * @internal
854
+ */
855
+ function timeoutSignal(timeout) {
856
+ if (timeout == null)
857
+ return;
858
+ if ('timeout' in AbortSignal)
859
+ return AbortSignal.timeout(timeout);
860
+ const controller = new AbortController();
861
+ setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
862
+ return controller.signal;
863
+ }
864
+
865
+ /**
866
+ * Service for querying and watching attachment records in the database.
867
+ *
868
+ * @internal
869
+ */
870
+ class AttachmentService {
871
+ db;
872
+ logger;
873
+ tableName;
874
+ mutex = new Mutex();
875
+ context;
876
+ constructor(db, logger, tableName = 'attachments', archivedCacheLimit = 100) {
877
+ this.db = db;
878
+ this.logger = logger;
879
+ this.tableName = tableName;
880
+ this.context = new AttachmentContext(db, tableName, logger, archivedCacheLimit);
881
+ }
882
+ /**
883
+ * Creates a differential watch query for active attachments requiring synchronization.
884
+ * @returns Watch query that emits changes for queued uploads, downloads, and deletes
885
+ */
886
+ watchActiveAttachments({ throttleMs } = {}) {
887
+ this.logger.info('Watching active attachments...');
888
+ const watch = this.db
889
+ .query({
890
+ sql: /* sql */ `
891
+ SELECT
892
+ *
893
+ FROM
894
+ ${this.tableName}
895
+ WHERE
896
+ state = ?
897
+ OR state = ?
898
+ OR state = ?
899
+ ORDER BY
900
+ timestamp ASC
901
+ `,
902
+ parameters: [AttachmentState.QUEUED_UPLOAD, AttachmentState.QUEUED_DOWNLOAD, AttachmentState.QUEUED_DELETE]
903
+ })
904
+ .differentialWatch({ throttleMs });
905
+ return watch;
906
+ }
907
+ /**
908
+ * Executes a callback with exclusive access to the attachment context.
909
+ */
910
+ async withContext(callback) {
911
+ return this.mutex.runExclusive(async () => {
912
+ return callback(this.context);
913
+ });
914
+ }
915
+ }
916
+
917
+ /**
918
+ * Orchestrates attachment synchronization between local and remote storage.
919
+ * Handles uploads, downloads, deletions, and state transitions.
920
+ *
921
+ * @internal
922
+ */
923
+ class SyncingService {
924
+ attachmentService;
925
+ localStorage;
926
+ remoteStorage;
927
+ logger;
928
+ errorHandler;
929
+ constructor(attachmentService, localStorage, remoteStorage, logger, errorHandler) {
930
+ this.attachmentService = attachmentService;
931
+ this.localStorage = localStorage;
932
+ this.remoteStorage = remoteStorage;
933
+ this.logger = logger;
934
+ this.errorHandler = errorHandler;
935
+ }
936
+ /**
937
+ * Processes attachments based on their state (upload, download, or delete).
938
+ * All updates are saved in a single batch after processing.
939
+ *
940
+ * @param attachments - Array of attachment records to process
941
+ * @param context - Attachment context for database operations
942
+ * @returns Promise that resolves when all attachments have been processed and saved
943
+ */
944
+ async processAttachments(attachments, context) {
945
+ const updatedAttachments = [];
946
+ for (const attachment of attachments) {
947
+ switch (attachment.state) {
948
+ case AttachmentState.QUEUED_UPLOAD:
949
+ const uploaded = await this.uploadAttachment(attachment);
950
+ updatedAttachments.push(uploaded);
951
+ break;
952
+ case AttachmentState.QUEUED_DOWNLOAD:
953
+ const downloaded = await this.downloadAttachment(attachment);
954
+ updatedAttachments.push(downloaded);
955
+ break;
956
+ case AttachmentState.QUEUED_DELETE:
957
+ const deleted = await this.deleteAttachment(attachment, context);
958
+ updatedAttachments.push(deleted);
959
+ break;
960
+ }
961
+ }
962
+ await context.saveAttachments(updatedAttachments);
963
+ }
964
+ /**
965
+ * Uploads an attachment from local storage to remote storage.
966
+ * On success, marks as SYNCED. On failure, defers to error handler or archives.
967
+ *
968
+ * @param attachment - The attachment record to upload
969
+ * @returns Updated attachment record with new state
970
+ * @throws Error if the attachment has no localUri
971
+ */
972
+ async uploadAttachment(attachment) {
973
+ this.logger.info(`Uploading attachment ${attachment.filename}`);
974
+ try {
975
+ if (attachment.localUri == null) {
976
+ throw new Error(`No localUri for attachment ${attachment.id}`);
977
+ }
978
+ const fileBlob = await this.localStorage.readFile(attachment.localUri);
979
+ await this.remoteStorage.uploadFile(fileBlob, attachment);
980
+ return {
981
+ ...attachment,
982
+ state: AttachmentState.SYNCED,
983
+ hasSynced: true
984
+ };
985
+ }
986
+ catch (error) {
987
+ const shouldRetry = (await this.errorHandler?.onUploadError(attachment, error)) ?? true;
988
+ if (!shouldRetry) {
989
+ return {
990
+ ...attachment,
991
+ state: AttachmentState.ARCHIVED
992
+ };
993
+ }
994
+ return attachment;
995
+ }
996
+ }
997
+ /**
998
+ * Downloads an attachment from remote storage to local storage.
999
+ * Retrieves the file, converts to base64, and saves locally.
1000
+ * On success, marks as SYNCED. On failure, defers to error handler or archives.
1001
+ *
1002
+ * @param attachment - The attachment record to download
1003
+ * @returns Updated attachment record with local URI and new state
1004
+ */
1005
+ async downloadAttachment(attachment) {
1006
+ this.logger.info(`Downloading attachment ${attachment.filename}`);
1007
+ try {
1008
+ const fileData = await this.remoteStorage.downloadFile(attachment);
1009
+ const localUri = this.localStorage.getLocalUri(attachment.filename);
1010
+ await this.localStorage.saveFile(localUri, fileData);
1011
+ return {
1012
+ ...attachment,
1013
+ state: AttachmentState.SYNCED,
1014
+ localUri: localUri,
1015
+ hasSynced: true
1016
+ };
1017
+ }
1018
+ catch (error) {
1019
+ const shouldRetry = (await this.errorHandler?.onDownloadError(attachment, error)) ?? true;
1020
+ if (!shouldRetry) {
1021
+ return {
1022
+ ...attachment,
1023
+ state: AttachmentState.ARCHIVED
1024
+ };
1025
+ }
1026
+ return attachment;
1027
+ }
1028
+ }
1029
+ /**
1030
+ * Deletes an attachment from both remote and local storage.
1031
+ * Removes the remote file, local file (if exists), and the attachment record.
1032
+ * On failure, defers to error handler or archives.
939
1033
  *
940
- * The returned `release` callback must be invoked to return items into the pool.
1034
+ * @param attachment - The attachment record to delete
1035
+ * @param context - Attachment context for database operations
1036
+ * @returns Updated attachment record
941
1037
  */
942
- requestAll(abort) {
943
- return this.requestPermits(this.size, abort);
944
- }
945
- }
946
- /**
947
- * An asynchronous mutex implementation.
948
- *
949
- * @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
950
- */
951
- class Mutex {
952
- inner = new Semaphore([null]);
953
- async acquire(abort) {
954
- const { release } = await this.inner.requestOne(abort);
955
- return release;
956
- }
957
- async runExclusive(fn, abort) {
958
- const returnMutex = await this.acquire(abort);
1038
+ async deleteAttachment(attachment, context) {
959
1039
  try {
960
- return await fn();
1040
+ await this.remoteStorage.deleteFile(attachment);
1041
+ if (attachment.localUri) {
1042
+ await this.localStorage.deleteFile(attachment.localUri);
1043
+ }
1044
+ await context.deleteAttachment(attachment.id);
1045
+ return {
1046
+ ...attachment,
1047
+ state: AttachmentState.ARCHIVED
1048
+ };
961
1049
  }
962
- finally {
963
- returnMutex();
1050
+ catch (error) {
1051
+ const shouldRetry = (await this.errorHandler?.onDeleteError(attachment, error)) ?? true;
1052
+ if (!shouldRetry) {
1053
+ return {
1054
+ ...attachment,
1055
+ state: AttachmentState.ARCHIVED
1056
+ };
1057
+ }
1058
+ return attachment;
964
1059
  }
965
1060
  }
966
- }
967
- function timeoutSignal(timeout) {
968
- if (timeout == null)
969
- return;
970
- if ('timeout' in AbortSignal)
971
- return AbortSignal.timeout(timeout);
972
- const controller = new AbortController();
973
- setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
974
- return controller.signal;
975
- }
976
-
977
- /**
978
- * Service for querying and watching attachment records in the database.
979
- *
980
- * @internal
981
- */
982
- class AttachmentService {
983
- db;
984
- logger;
985
- tableName;
986
- mutex = new Mutex();
987
- context;
988
- constructor(db, logger, tableName = 'attachments', archivedCacheLimit = 100) {
989
- this.db = db;
990
- this.logger = logger;
991
- this.tableName = tableName;
992
- this.context = new AttachmentContext(db, tableName, logger, archivedCacheLimit);
993
- }
994
- /**
995
- * Creates a differential watch query for active attachments requiring synchronization.
996
- * @returns Watch query that emits changes for queued uploads, downloads, and deletes
997
- */
998
- watchActiveAttachments({ throttleMs } = {}) {
999
- this.logger.info('Watching active attachments...');
1000
- const watch = this.db
1001
- .query({
1002
- sql: /* sql */ `
1003
- SELECT
1004
- *
1005
- FROM
1006
- ${this.tableName}
1007
- WHERE
1008
- state = ?
1009
- OR state = ?
1010
- OR state = ?
1011
- ORDER BY
1012
- timestamp ASC
1013
- `,
1014
- parameters: [AttachmentState.QUEUED_UPLOAD, AttachmentState.QUEUED_DOWNLOAD, AttachmentState.QUEUED_DELETE]
1015
- })
1016
- .differentialWatch({ throttleMs });
1017
- return watch;
1018
- }
1019
1061
  /**
1020
- * Executes a callback with exclusive access to the attachment context.
1062
+ * Performs cleanup of archived attachments by removing their local files and records.
1063
+ * Errors during local file deletion are logged but do not prevent record deletion.
1021
1064
  */
1022
- async withContext(callback) {
1023
- return this.mutex.runExclusive(async () => {
1024
- return callback(this.context);
1065
+ async deleteArchivedAttachments(context) {
1066
+ return await context.deleteArchivedAttachments(async (archivedAttachments) => {
1067
+ for (const attachment of archivedAttachments) {
1068
+ if (attachment.localUri) {
1069
+ try {
1070
+ await this.localStorage.deleteFile(attachment.localUri);
1071
+ }
1072
+ catch (error) {
1073
+ this.logger.error('Error deleting local file for archived attachment', error);
1074
+ }
1075
+ }
1076
+ }
1025
1077
  });
1026
1078
  }
1027
1079
  }
@@ -1082,16 +1134,6 @@ class AttachmentQueue {
1082
1134
  * Creates a new AttachmentQueue instance.
1083
1135
  *
1084
1136
  * @param options - Configuration options
1085
- * @param options.db - PowerSync database instance
1086
- * @param options.remoteStorage - Remote storage adapter for upload/download operations
1087
- * @param options.localStorage - Local storage adapter for file persistence
1088
- * @param options.watchAttachments - Callback for monitoring attachment changes in your data model
1089
- * @param options.tableName - Name of the table to store attachment records. Default: 'ps_attachment_queue'
1090
- * @param options.logger - Logger instance. Defaults to db.logger
1091
- * @param options.syncIntervalMs - Periodic polling interval in milliseconds for retrying failed uploads/downloads. Default: 30000
1092
- * @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
1093
- * @param options.downloadAttachments - Whether to automatically download remote attachments. Default: true
1094
- * @param options.archivedCacheLimit - Maximum archived attachments before cleanup. Default: 100
1095
1137
  */
1096
1138
  constructor({ db, localStorage, remoteStorage, watchAttachments, logger, tableName = ATTACHMENT_TABLE, syncIntervalMs = 30 * 1000, syncThrottleDuration = DEFAULT_WATCH_THROTTLE_MS, downloadAttachments = true, archivedCacheLimit = 100, errorHandler }) {
1097
1139
  this.db = db;
@@ -1180,6 +1222,7 @@ class AttachmentQueue {
1180
1222
  state: AttachmentState.QUEUED_DOWNLOAD,
1181
1223
  hasSynced: false,
1182
1224
  metaData: watchedAttachment.metaData,
1225
+ mediaType: watchedAttachment.mediaType,
1183
1226
  timestamp: new Date().getTime()
1184
1227
  });
1185
1228
  continue;
@@ -1267,17 +1310,24 @@ class AttachmentQueue {
1267
1310
  this.statusListenerDispose = undefined;
1268
1311
  }
1269
1312
  }
1313
+ /**
1314
+ * Provides an {@link AttachmentContext} to a callback.
1315
+ *
1316
+ * The callback runs while the attachment queue mutex is held. Do not call
1317
+ * other {@link AttachmentQueue} methods from within the callback, as they may
1318
+ * attempt to acquire the same mutex and block indefinitely.
1319
+ */
1320
+ withAttachmentContext(callback) {
1321
+ /**
1322
+ * AttachmentService is internal and private in this class.
1323
+ * We only need to expose its locking and context functionality for extending classes.
1324
+ */
1325
+ return this.attachmentService.withContext(callback);
1326
+ }
1270
1327
  /**
1271
1328
  * Saves a file to local storage and queues it for upload to remote storage.
1272
1329
  *
1273
1330
  * @param options - File save options
1274
- * @param options.data - The file data as ArrayBuffer, Blob, or base64 string
1275
- * @param options.fileExtension - File extension (e.g., 'jpg', 'pdf')
1276
- * @param options.mediaType - MIME type of the file (e.g., 'image/jpeg')
1277
- * @param options.metaData - Optional metadata to associate with the attachment
1278
- * @param options.id - Optional custom ID. If not provided, a UUID will be generated
1279
- * @param options.updateHook - Optional callback to execute additional database operations
1280
- * within the same transaction as the attachment creation
1281
1331
  * @returns Promise resolving to the created attachment record
1282
1332
  */
1283
1333
  async saveFile({ data, fileExtension, mediaType, metaData, id, updateHook }) {
@@ -1390,6 +1440,9 @@ class AttachmentQueue {
1390
1440
  }
1391
1441
  }
1392
1442
 
1443
+ /**
1444
+ * @alpha
1445
+ */
1393
1446
  var EncodingType;
1394
1447
  (function (EncodingType) {
1395
1448
  EncodingType["UTF8"] = "utf8";
@@ -1853,7 +1906,9 @@ var Logger = /*@__PURE__*/getDefaultExportFromCjs(loggerExports);
1853
1906
  * different SQLite DB implementations.
1854
1907
  */
1855
1908
  /**
1856
- * Implements {@link DBGetUtils} on a {@link SqlRunner}.
1909
+ * Implements {@link DBGetUtils} on a {@link SqlExecutor}.
1910
+ *
1911
+ * @internal
1857
1912
  */
1858
1913
  function DBGetUtilsDefaultMixin(Base) {
1859
1914
  return class extends Base {
@@ -1897,6 +1952,8 @@ function DBGetUtilsDefaultMixin(Base) {
1897
1952
  }
1898
1953
  /**
1899
1954
  * Update table operation numbers from SQLite
1955
+ *
1956
+ * @public
1900
1957
  */
1901
1958
  var RowUpdateType;
1902
1959
  (function (RowUpdateType) {
@@ -1905,8 +1962,10 @@ var RowUpdateType;
1905
1962
  RowUpdateType[RowUpdateType["SQLITE_UPDATE"] = 23] = "SQLITE_UPDATE";
1906
1963
  })(RowUpdateType || (RowUpdateType = {}));
1907
1964
  /**
1908
- * A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool.readLock} and
1909
- * {@link ConnectionPool.writeLock}.
1965
+ * A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool#readLock} and
1966
+ * {@link ConnectionPool#writeLock}.
1967
+ *
1968
+ * @internal
1910
1969
  */
1911
1970
  function DBAdapterDefaultMixin(Base) {
1912
1971
  return class extends Base {
@@ -1994,9 +2053,15 @@ class TransactionImplementation extends DBGetUtilsDefaultMixin(BaseTransaction)
1994
2053
  }
1995
2054
  }
1996
2055
  }
2056
+ /**
2057
+ * @internal
2058
+ */
1997
2059
  function isBatchedUpdateNotification(update) {
1998
2060
  return 'tables' in update;
1999
2061
  }
2062
+ /**
2063
+ * @internal
2064
+ */
2000
2065
  function extractTableUpdates(update) {
2001
2066
  return isBatchedUpdateNotification(update) ? update.tables : [update.table];
2002
2067
  }
@@ -2024,6 +2089,8 @@ const FULL_SYNC_PRIORITY = 2147483647;
2024
2089
  *
2025
2090
  * Also note that data is downloaded in bulk, which means that individual counters are unlikely
2026
2091
  * to be updated one-by-one.
2092
+ *
2093
+ * @public
2027
2094
  */
2028
2095
  class SyncProgress {
2029
2096
  internal;
@@ -2062,6 +2129,9 @@ class SyncProgress {
2062
2129
  }
2063
2130
  }
2064
2131
 
2132
+ /**
2133
+ * @public
2134
+ */
2065
2135
  class SyncStatus {
2066
2136
  options;
2067
2137
  constructor(options) {
@@ -2072,6 +2142,8 @@ class SyncStatus {
2072
2142
  * implementation).
2073
2143
  *
2074
2144
  * This information is only available after a connection has been requested.
2145
+ *
2146
+ * @deprecated This always returns the Rust client (the only option).
2075
2147
  */
2076
2148
  get clientImplementation() {
2077
2149
  return this.options.clientImplementation;
@@ -2079,7 +2151,7 @@ class SyncStatus {
2079
2151
  /**
2080
2152
  * Indicates if the client is currently connected to the PowerSync service.
2081
2153
  *
2082
- * @returns {boolean} True if connected, false otherwise. Defaults to false if not specified.
2154
+ * @returns True if connected, false otherwise. Defaults to false if not specified.
2083
2155
  */
2084
2156
  get connected() {
2085
2157
  return this.options.connected ?? false;
@@ -2087,7 +2159,7 @@ class SyncStatus {
2087
2159
  /**
2088
2160
  * Indicates if the client is in the process of establishing a connection to the PowerSync service.
2089
2161
  *
2090
- * @returns {boolean} True if connecting, false otherwise. Defaults to false if not specified.
2162
+ * @returns True if connecting, false otherwise. Defaults to false if not specified.
2091
2163
  */
2092
2164
  get connecting() {
2093
2165
  return this.options.connecting ?? false;
@@ -2096,7 +2168,7 @@ class SyncStatus {
2096
2168
  * Time that a last sync has fully completed, if any.
2097
2169
  * This timestamp is reset to null after a restart of the PowerSync service.
2098
2170
  *
2099
- * @returns {Date | undefined} The timestamp of the last successful sync, or undefined if no sync has completed.
2171
+ * @returns The timestamp of the last successful sync, or undefined if no sync has completed.
2100
2172
  */
2101
2173
  get lastSyncedAt() {
2102
2174
  return this.options.lastSyncedAt;
@@ -2104,7 +2176,7 @@ class SyncStatus {
2104
2176
  /**
2105
2177
  * Indicates whether there has been at least one full sync completed since initialization.
2106
2178
  *
2107
- * @returns {boolean | undefined} True if at least one sync has completed, false if no sync has completed,
2179
+ * @returns True if at least one sync has completed, false if no sync has completed,
2108
2180
  * or undefined when the state is still being loaded from the database.
2109
2181
  */
2110
2182
  get hasSynced() {
@@ -2113,10 +2185,10 @@ class SyncStatus {
2113
2185
  /**
2114
2186
  * Provides the current data flow status regarding uploads and downloads.
2115
2187
  *
2116
- * @returns {SyncDataFlowStatus} An object containing:
2188
+ * @returns An object containing:
2117
2189
  * - downloading: True if actively downloading changes (only when connected is also true)
2118
2190
  * - uploading: True if actively uploading changes
2119
- * Defaults to {downloading: false, uploading: false} if not specified.
2191
+ * Defaults to `{downloading: false, uploading: false}` if not specified.
2120
2192
  */
2121
2193
  get dataFlowStatus() {
2122
2194
  return (this.options.dataFlow ?? {
@@ -2141,7 +2213,7 @@ class SyncStatus {
2141
2213
  return this.options.dataFlow?.internalStreamSubscriptions?.map((core) => new SyncStreamStatusView(this, core));
2142
2214
  }
2143
2215
  /**
2144
- * If the `stream` appears in {@link syncStreams}, returns the current status for that stream.
2216
+ * If the `stream` appears in {@link SyncStatus.syncStreams}, returns the current status for that stream.
2145
2217
  */
2146
2218
  forStream(stream) {
2147
2219
  const asJson = JSON.stringify(stream.parameters);
@@ -2151,7 +2223,7 @@ class SyncStatus {
2151
2223
  /**
2152
2224
  * Provides sync status information for all bucket priorities, sorted by priority (highest first).
2153
2225
  *
2154
- * @returns {SyncPriorityStatus[]} An array of status entries for different sync priority levels,
2226
+ * @returns An array of status entries for different sync priority levels,
2155
2227
  * sorted with highest priorities (lower numbers) first.
2156
2228
  */
2157
2229
  get priorityStatusEntries() {
@@ -2186,8 +2258,8 @@ class SyncStatus {
2186
2258
  * For example, if PowerSync just finished synchronizing buckets in priority level 3, calling this method
2187
2259
  * with a priority of 1 may return information for priority level 3.
2188
2260
  *
2189
- * @param {number} priority The bucket priority for which the status should be reported
2190
- * @returns {SyncPriorityStatus} Status information for the requested priority level or the next higher level with available status
2261
+ * @param priority - The bucket priority for which the status should be reported
2262
+ * @returns Status information for the requested priority level or the next higher level with available status
2191
2263
  */
2192
2264
  statusForPriority(priority) {
2193
2265
  // priorityStatusEntries are sorted by ascending priorities (so higher numbers to lower numbers).
@@ -2208,8 +2280,8 @@ class SyncStatus {
2208
2280
  * Compares this SyncStatus instance with another to determine if they are equal.
2209
2281
  * Equality is determined by comparing the serialized JSON representation of both instances.
2210
2282
  *
2211
- * @param {SyncStatus} status The SyncStatus instance to compare against
2212
- * @returns {boolean} True if the instances are considered equal, false otherwise
2283
+ * @param status - The SyncStatus instance to compare against
2284
+ * @returns True if the instances are considered equal, false otherwise
2213
2285
  */
2214
2286
  isEqual(status) {
2215
2287
  /**
@@ -2232,7 +2304,7 @@ class SyncStatus {
2232
2304
  * Creates a human-readable string representation of the current sync status.
2233
2305
  * Includes information about connection state, sync completion, and data flow.
2234
2306
  *
2235
- * @returns {string} A string representation of the sync status
2307
+ * @returns A string representation of the sync status
2236
2308
  */
2237
2309
  getMessage() {
2238
2310
  const dataFlow = this.dataFlowStatus;
@@ -2241,7 +2313,7 @@ class SyncStatus {
2241
2313
  /**
2242
2314
  * Serializes the SyncStatus instance to a plain object.
2243
2315
  *
2244
- * @returns {SyncStatusOptions} A plain object representation of the sync status
2316
+ * @returns A plain object representation of the sync status
2245
2317
  */
2246
2318
  toJSON() {
2247
2319
  return {
@@ -2307,6 +2379,9 @@ class SyncStreamStatusView {
2307
2379
  }
2308
2380
  }
2309
2381
 
2382
+ /**
2383
+ * @public
2384
+ */
2310
2385
  class UploadQueueStats {
2311
2386
  count;
2312
2387
  size;
@@ -2332,6 +2407,9 @@ class UploadQueueStats {
2332
2407
  }
2333
2408
  }
2334
2409
 
2410
+ /**
2411
+ * @internal
2412
+ */
2335
2413
  class BaseObserver {
2336
2414
  listeners = new Set();
2337
2415
  constructor() { }
@@ -2359,6 +2437,9 @@ class BaseObserver {
2359
2437
  }
2360
2438
  }
2361
2439
 
2440
+ /**
2441
+ * @internal
2442
+ */
2362
2443
  class ControlledExecutor {
2363
2444
  task;
2364
2445
  /**
@@ -2626,7 +2707,7 @@ class ConnectionManager extends BaseObserver {
2626
2707
  /**
2627
2708
  * Close the sync connection.
2628
2709
  *
2629
- * Use {@link connect} to connect again.
2710
+ * Use {@link ConnectionManager.connect} to connect again.
2630
2711
  */
2631
2712
  async disconnect() {
2632
2713
  // This will help abort pending connects
@@ -2766,6 +2847,8 @@ const _finalizer = 'FinalizationRegistry' in globalThis
2766
2847
  /**
2767
2848
  * An efficient comparator for {@link WatchedQuery} created with {@link Query#watch}. This has the ability to determine if a query
2768
2849
  * result has changes without necessarily processing all items in the result.
2850
+ *
2851
+ * @public
2769
2852
  */
2770
2853
  class ArrayComparator {
2771
2854
  options;
@@ -2793,6 +2876,8 @@ class ArrayComparator {
2793
2876
  }
2794
2877
  /**
2795
2878
  * Watched query comparator that always reports changed result sets.
2879
+ *
2880
+ * @public
2796
2881
  */
2797
2882
  const FalsyComparator = {
2798
2883
  checkEquality: () => false // Default comparator that always returns false
@@ -3000,6 +3085,8 @@ class AbstractQueryProcessor extends MetaBaseObserver {
3000
3085
  /**
3001
3086
  * An empty differential result set.
3002
3087
  * This is used as the initial state for differential incrementally watched queries.
3088
+ *
3089
+ * @internal
3003
3090
  */
3004
3091
  const EMPTY_DIFFERENTIAL = {
3005
3092
  added: [],
@@ -3012,6 +3099,8 @@ const EMPTY_DIFFERENTIAL = {
3012
3099
  * Default implementation of the {@link DifferentialWatchedQueryComparator} for watched queries.
3013
3100
  * It keys items by their `id` property if available, alternatively it uses JSON stringification
3014
3101
  * of the entire item for the key and comparison.
3102
+ *
3103
+ * @internal
3015
3104
  */
3016
3105
  const DEFAULT_ROW_COMPARATOR = {
3017
3106
  keyBy: (item) => {
@@ -3292,6 +3381,8 @@ class CustomQuery {
3292
3381
 
3293
3382
  /**
3294
3383
  * Tests if the input is a {@link SQLOpenOptions}
3384
+ *
3385
+ * @internal
3295
3386
  */
3296
3387
  const isSQLOpenOptions = (test) => {
3297
3388
  // typeof null is `object`, but you cannot use the `in` operator on `null.
@@ -3299,17 +3390,24 @@ const isSQLOpenOptions = (test) => {
3299
3390
  };
3300
3391
  /**
3301
3392
  * Tests if input is a {@link SQLOpenFactory}
3393
+ *
3394
+ * @internal
3302
3395
  */
3303
3396
  const isSQLOpenFactory = (test) => {
3304
3397
  return typeof test?.openDB == 'function';
3305
3398
  };
3306
3399
  /**
3307
3400
  * Tests if input is a {@link DBAdapter}
3401
+ *
3402
+ * @internal
3308
3403
  */
3309
3404
  const isDBAdapter = (test) => {
3310
3405
  return typeof test?.writeTransaction == 'function';
3311
3406
  };
3312
3407
 
3408
+ /**
3409
+ * @internal
3410
+ */
3313
3411
  var PSInternalTable;
3314
3412
  (function (PSInternalTable) {
3315
3413
  PSInternalTable["DATA"] = "ps_data";
@@ -3318,6 +3416,9 @@ var PSInternalTable;
3318
3416
  PSInternalTable["OPLOG"] = "ps_oplog";
3319
3417
  PSInternalTable["UNTYPED"] = "ps_untyped";
3320
3418
  })(PSInternalTable || (PSInternalTable = {}));
3419
+ /**
3420
+ * @internal
3421
+ */
3321
3422
  var PowerSyncControlCommand;
3322
3423
  (function (PowerSyncControlCommand) {
3323
3424
  PowerSyncControlCommand["PROCESS_TEXT_LINE"] = "line_text";
@@ -3335,6 +3436,8 @@ var PowerSyncControlCommand;
3335
3436
 
3336
3437
  /**
3337
3438
  * A batch of client-side changes.
3439
+ *
3440
+ * @public
3338
3441
  */
3339
3442
  class CrudBatch {
3340
3443
  crud;
@@ -3361,6 +3464,8 @@ class CrudBatch {
3361
3464
 
3362
3465
  /**
3363
3466
  * Type of local change.
3467
+ *
3468
+ * @public
3364
3469
  */
3365
3470
  var UpdateType;
3366
3471
  (function (UpdateType) {
@@ -3373,6 +3478,8 @@ var UpdateType;
3373
3478
  })(UpdateType || (UpdateType = {}));
3374
3479
  /**
3375
3480
  * A single client-side change.
3481
+ *
3482
+ * @public
3376
3483
  */
3377
3484
  class CrudEntry {
3378
3485
  /**
@@ -3469,6 +3576,9 @@ class CrudEntry {
3469
3576
  }
3470
3577
  }
3471
3578
 
3579
+ /**
3580
+ * @public
3581
+ */
3472
3582
  class CrudTransaction extends CrudBatch {
3473
3583
  crud;
3474
3584
  complete;
@@ -3497,6 +3607,8 @@ class CrudTransaction extends CrudBatch {
3497
3607
  * Calls to Abortcontroller.abort(reason: any) will result in the
3498
3608
  * `reason` being thrown. This is not necessarily an error,
3499
3609
  * but extends error for better logging purposes.
3610
+ *
3611
+ * @internal
3500
3612
  */
3501
3613
  class AbortOperation extends Error {
3502
3614
  reason;
@@ -10667,7 +10779,7 @@ function requireDist () {
10667
10779
 
10668
10780
  var distExports = requireDist();
10669
10781
 
10670
- var version = "1.53.2";
10782
+ var version = "1.54.0";
10671
10783
  var PACKAGE = {
10672
10784
  version: version};
10673
10785
 
@@ -10797,7 +10909,8 @@ class WebsocketClientTransport {
10797
10909
  removeListeners();
10798
10910
  resolve(new WebsocketDuplexConnectionExports.WebsocketDuplexConnection(websocket, new distExports.Deserializer(), multiplexerDemultiplexerFactory));
10799
10911
  };
10800
- const errorListener = (ev) => {
10912
+ const errorListener = (event) => {
10913
+ const ev = event;
10801
10914
  removeListeners();
10802
10915
  // We add a default error in that case.
10803
10916
  if (ev.error != null) {
@@ -11040,7 +11153,13 @@ const SOCKET_TIMEOUT_MS = 30_000;
11040
11153
  // If there is a backlog of messages (for example on slow connections), keepalive messages could be delayed
11041
11154
  // significantly. Therefore this is longer than the socket timeout.
11042
11155
  const KEEP_ALIVE_LIFETIME_MS = 90_000;
11156
+ /**
11157
+ * @internal
11158
+ */
11043
11159
  const DEFAULT_REMOTE_LOGGER = Logger.get('PowerSyncRemote');
11160
+ /**
11161
+ * @public
11162
+ */
11044
11163
  var FetchStrategy;
11045
11164
  (function (FetchStrategy) {
11046
11165
  /**
@@ -11059,12 +11178,17 @@ var FetchStrategy;
11059
11178
  * The class wrapper is used to distinguish the fetchImplementation
11060
11179
  * option in [AbstractRemoteOptions] from the general fetch method
11061
11180
  * which is typeof "function"
11181
+ *
11182
+ * @internal
11062
11183
  */
11063
11184
  class FetchImplementationProvider {
11064
11185
  getFetch() {
11065
11186
  throw new Error('Unspecified fetch implementation');
11066
11187
  }
11067
11188
  }
11189
+ /**
11190
+ * @internal
11191
+ */
11068
11192
  const DEFAULT_REMOTE_OPTIONS = {
11069
11193
  socketUrlTransformer: (url) => url.replace(/^https?:\/\//, function (match) {
11070
11194
  return match === 'https://' ? 'wss://' : 'ws://';
@@ -11072,6 +11196,9 @@ const DEFAULT_REMOTE_OPTIONS = {
11072
11196
  fetchImplementation: new FetchImplementationProvider(),
11073
11197
  fetchOptions: {}
11074
11198
  };
11199
+ /**
11200
+ * @internal
11201
+ */
11075
11202
  class AbstractRemote {
11076
11203
  connector;
11077
11204
  logger;
@@ -11481,7 +11608,7 @@ class AbstractRemote {
11481
11608
  * Posts a `/sync/stream` request.
11482
11609
  *
11483
11610
  * Depending on the `Content-Type` of the response, this returns strings for sync lines or encoded BSON documents as
11484
- * {@link Uint8Array}s.
11611
+ * `Uint8Array`s.
11485
11612
  */
11486
11613
  async fetchStream(options) {
11487
11614
  const { isBson, stream } = await this.fetchStreamRaw(options);
@@ -11523,16 +11650,26 @@ function isInterruptingInstruction(instruction) {
11523
11650
  return 'EstablishSyncStream' in instruction || 'CloseSyncStream' in instruction;
11524
11651
  }
11525
11652
 
11653
+ /**
11654
+ * @internal
11655
+ */
11526
11656
  var LockType;
11527
11657
  (function (LockType) {
11528
11658
  LockType["CRUD"] = "crud";
11529
11659
  LockType["SYNC"] = "sync";
11530
11660
  })(LockType || (LockType = {}));
11661
+ /**
11662
+ * @public
11663
+ */
11531
11664
  var SyncStreamConnectionMethod;
11532
11665
  (function (SyncStreamConnectionMethod) {
11533
11666
  SyncStreamConnectionMethod["HTTP"] = "http";
11534
11667
  SyncStreamConnectionMethod["WEB_SOCKET"] = "web-socket";
11535
11668
  })(SyncStreamConnectionMethod || (SyncStreamConnectionMethod = {}));
11669
+ /**
11670
+ * @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
11671
+ * @public
11672
+ */
11536
11673
  var SyncClientImplementation;
11537
11674
  (function (SyncClientImplementation) {
11538
11675
  /**
@@ -11544,8 +11681,8 @@ var SyncClientImplementation;
11544
11681
  * ## Compatibility warning
11545
11682
  *
11546
11683
  * The Rust sync client stores sync data in a format that is slightly different than the one used
11547
- * by the old JavaScript client. When adopting the {@link RUST} client on existing databases, the PowerSync SDK will
11548
- * migrate the format automatically.
11684
+ * by the old JavaScript client. When adopting the {@link SyncClientImplementation.RUST} client on existing databases,
11685
+ * the PowerSync SDK will migrate the format automatically.
11549
11686
  *
11550
11687
  * SDK versions supporting both the JavaScript and the Rust client support both formats with the JavaScript client
11551
11688
  * implementaiton. However, downgrading to an SDK version that only supports the JavaScript client would not be
@@ -11555,14 +11692,29 @@ var SyncClientImplementation;
11555
11692
  })(SyncClientImplementation || (SyncClientImplementation = {}));
11556
11693
  /**
11557
11694
  * The default {@link SyncClientImplementation} to use, {@link SyncClientImplementation.RUST}.
11695
+ *
11696
+ * @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
11697
+ * @public
11558
11698
  */
11559
11699
  const DEFAULT_SYNC_CLIENT_IMPLEMENTATION = SyncClientImplementation.RUST;
11700
+ /**
11701
+ * @internal
11702
+ */
11560
11703
  const DEFAULT_CRUD_UPLOAD_THROTTLE_MS = 1000;
11704
+ /**
11705
+ * @internal
11706
+ */
11561
11707
  const DEFAULT_RETRY_DELAY_MS = 5000;
11708
+ /**
11709
+ * @internal
11710
+ */
11562
11711
  const DEFAULT_STREAMING_SYNC_OPTIONS = {
11563
11712
  retryDelayMs: DEFAULT_RETRY_DELAY_MS,
11564
11713
  crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
11565
11714
  };
11715
+ /**
11716
+ * @internal
11717
+ */
11566
11718
  const DEFAULT_STREAM_CONNECTION_OPTIONS = {
11567
11719
  appMetadata: {},
11568
11720
  connectionMethod: SyncStreamConnectionMethod.WEB_SOCKET,
@@ -11572,6 +11724,9 @@ const DEFAULT_STREAM_CONNECTION_OPTIONS = {
11572
11724
  serializedSchema: undefined,
11573
11725
  includeDefaultStreams: true
11574
11726
  };
11727
+ /**
11728
+ * @internal
11729
+ */
11575
11730
  class AbstractStreamingSyncImplementation extends BaseObserver {
11576
11731
  options;
11577
11732
  abortController;
@@ -11895,7 +12050,7 @@ The next upload iteration will be delayed.`);
11895
12050
  this.handleActiveStreamsChange?.();
11896
12051
  }
11897
12052
  /**
11898
- * Older versions of the JS SDK used to encode subkeys as JSON in {@link OplogEntry.toJSON}.
12053
+ * Older versions of the JS SDK used to encode subkeys as JSON in `OplogEntry.toJSON`.
11899
12054
  * Because subkeys are always strings, this leads to quotes being added around them in `ps_oplog`.
11900
12055
  * While this is not a problem as long as it's done consistently, it causes issues when a database
11901
12056
  * created by the JS SDK is used with other SDKs, or (more likely) when the new Rust sync client
@@ -11905,7 +12060,7 @@ The next upload iteration will be delayed.`);
11905
12060
  * migration is only triggered when necessary (for now). The function returns whether the new format
11906
12061
  * should be used, so that the JS SDK is able to write to updated databases.
11907
12062
  *
11908
- * @param requireFixedKeyFormat Whether we require the new format or also support the old one.
12063
+ * @param requireFixedKeyFormat - Whether we require the new format or also support the old one.
11909
12064
  * The Rust client requires the new subkey format.
11910
12065
  * @returns Whether the database is now using the new, fixed subkey format.
11911
12066
  */
@@ -12212,7 +12367,8 @@ const MEMORY_TRIGGER_CLAIM_MANAGER = {
12212
12367
 
12213
12368
  /**
12214
12369
  * SQLite operations to track changes for with {@link TriggerManager}
12215
- * @experimental
12370
+ *
12371
+ * @experimental @alpha
12216
12372
  */
12217
12373
  var DiffTriggerOperation;
12218
12374
  (function (DiffTriggerOperation) {
@@ -12274,8 +12430,8 @@ class TriggerManagerImpl {
12274
12430
  get db() {
12275
12431
  return this.options.db;
12276
12432
  }
12277
- async getUUID() {
12278
- const { id: uuid } = await this.db.get(/* sql */ `
12433
+ async getUUID(ctx) {
12434
+ const { id: uuid } = await (ctx ?? this.db).get(/* sql */ `
12279
12435
  SELECT
12280
12436
  uuid () as id
12281
12437
  `);
@@ -12388,7 +12544,7 @@ class TriggerManagerImpl {
12388
12544
  const replicatedColumns = columns ?? sourceDefinition.columns.map((col) => col.name);
12389
12545
  const internalSource = sourceDefinition.internalName;
12390
12546
  const triggerIds = [];
12391
- const id = await this.getUUID();
12547
+ const id = await this.getUUID(setupContext);
12392
12548
  const releaseStorageClaim = useStorage ? await this.options.claimManager.obtainClaim(id) : null;
12393
12549
  /**
12394
12550
  * We default to replicating all columns if no columns array is provided.
@@ -12628,18 +12784,29 @@ const POWERSYNC_TABLE_MATCH = /(^ps_data__|^ps_data_local__)/;
12628
12784
  const DEFAULT_DISCONNECT_CLEAR_OPTIONS = {
12629
12785
  clearLocal: true
12630
12786
  };
12787
+ /**
12788
+ * @internal
12789
+ */
12631
12790
  const DEFAULT_POWERSYNC_CLOSE_OPTIONS = {
12632
12791
  disconnect: true
12633
12792
  };
12793
+ /**
12794
+ * @internal
12795
+ */
12634
12796
  const DEFAULT_POWERSYNC_DB_OPTIONS = {
12635
12797
  retryDelayMs: 5000,
12636
12798
  crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
12637
12799
  };
12800
+ /**
12801
+ * @internal
12802
+ */
12638
12803
  const DEFAULT_CRUD_BATCH_LIMIT = 100;
12639
12804
  /**
12640
12805
  * Requesting nested or recursive locks can block the application in some circumstances.
12641
12806
  * This default lock timeout will act as a failsafe to throw an error if a lock cannot
12642
12807
  * be obtained.
12808
+ *
12809
+ * @internal
12643
12810
  */
12644
12811
  const DEFAULT_LOCK_TIMEOUT_MS = 120_000; // 2 mins
12645
12812
  /**
@@ -12649,6 +12816,9 @@ const DEFAULT_LOCK_TIMEOUT_MS = 120_000; // 2 mins
12649
12816
  const isPowerSyncDatabaseOptionsWithSettings = (test) => {
12650
12817
  return typeof test == 'object' && isSQLOpenOptions(test.database);
12651
12818
  };
12819
+ /**
12820
+ * @public
12821
+ */
12652
12822
  class AbstractPowerSyncDatabase extends BaseObserver {
12653
12823
  options;
12654
12824
  /**
@@ -12806,7 +12976,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
12806
12976
  /**
12807
12977
  * Wait for the first sync operation to complete.
12808
12978
  *
12809
- * @param request Either an abort signal (after which the promise will complete regardless of
12979
+ * @param request - Either an abort signal (after which the promise will complete regardless of
12810
12980
  * whether a full sync was completed) or an object providing an abort signal and a priority target.
12811
12981
  * When a priority target is set, the promise may complete when all buckets with the given (or higher)
12812
12982
  * priorities have been synchronized. This can be earlier than a complete sync.
@@ -12961,7 +13131,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
12961
13131
  /**
12962
13132
  * Close the sync connection.
12963
13133
  *
12964
- * Use {@link connect} to connect again.
13134
+ * Use {@link AbstractPowerSyncDatabase.connect} to connect again.
12965
13135
  */
12966
13136
  async disconnect() {
12967
13137
  return this.connectionManager.disconnect();
@@ -12988,8 +13158,8 @@ class AbstractPowerSyncDatabase extends BaseObserver {
12988
13158
  /**
12989
13159
  * Create a sync stream to query its status or to subscribe to it.
12990
13160
  *
12991
- * @param name The name of the stream to subscribe to.
12992
- * @param params Optional parameters for the stream subscription.
13161
+ * @param name - The name of the stream to subscribe to.
13162
+ * @param params - Optional parameters for the stream subscription.
12993
13163
  * @returns A {@link SyncStream} instance that can be subscribed to.
12994
13164
  * @experimental Sync streams are currently in alpha.
12995
13165
  */
@@ -13047,14 +13217,14 @@ class AbstractPowerSyncDatabase extends BaseObserver {
13047
13217
  * Once the data have been successfully uploaded, call {@link CrudBatch.complete} before
13048
13218
  * requesting the next batch.
13049
13219
  *
13050
- * Use {@link limit} to specify the maximum number of updates to return in a single
13220
+ * Use the `limit` parameter to specify the maximum number of updates to return in a single
13051
13221
  * batch.
13052
13222
  *
13053
13223
  * This method does include transaction ids in the result, but does not group
13054
13224
  * data by transaction. One batch may contain data from multiple transactions,
13055
13225
  * and a single transaction may be split over multiple batches.
13056
13226
  *
13057
- * @param limit Maximum number of CRUD entries to include in the batch
13227
+ * @param limit - Maximum number of CRUD entries to include in the batch
13058
13228
  * @returns A batch of CRUD operations to upload, or null if there are none
13059
13229
  */
13060
13230
  async getCrudBatch(limit = DEFAULT_CRUD_BATCH_LIMIT) {
@@ -13081,7 +13251,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
13081
13251
  * Once the data have been successfully uploaded, call {@link CrudTransaction.complete} before
13082
13252
  * requesting the next transaction.
13083
13253
  *
13084
- * Unlike {@link getCrudBatch}, this only returns data from a single transaction at a time.
13254
+ * Unlike {@link AbstractPowerSyncDatabase.getCrudBatch}, this only returns data from a single transaction at a time.
13085
13255
  * All data for the transaction is loaded into memory.
13086
13256
  *
13087
13257
  * @returns A transaction of CRUD operations to upload, or null if there are none
@@ -13096,7 +13266,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
13096
13266
  * This is typically used from the {@link PowerSyncBackendConnector.uploadData} callback. Each entry emitted by the
13097
13267
  * returned iterator is a full transaction containing all local writes made while that transaction was active.
13098
13268
  *
13099
- * Unlike {@link getNextCrudTransaction}, which always returns the oldest transaction that hasn't been
13269
+ * Unlike {@link AbstractPowerSyncDatabase.getNextCrudTransaction}, which always returns the oldest transaction that hasn't been
13100
13270
  * {@link CrudTransaction.complete}d yet, this iterator can be used to receive multiple transactions. Calling
13101
13271
  * {@link CrudTransaction.complete} will mark that and all prior transactions emitted by the iterator as completed.
13102
13272
  *
@@ -13190,8 +13360,8 @@ SELECT * FROM crud_entries;
13190
13360
  * the returned result's `rowsAffected` may be `0` for successful `UPDATE` and `DELETE` statements.
13191
13361
  * Use a `RETURNING` clause and inspect `result.rows` when you need to confirm which rows changed.
13192
13362
  *
13193
- * @param sql The SQL query to execute
13194
- * @param parameters Optional array of parameters to bind to the query
13363
+ * @param sql - The SQL query to execute
13364
+ * @param parameters - Optional array of parameters to bind to the query
13195
13365
  * @returns The query result as an object with structured key-value pairs
13196
13366
  */
13197
13367
  async execute(sql, parameters) {
@@ -13201,8 +13371,8 @@ SELECT * FROM crud_entries;
13201
13371
  * Execute a SQL write (INSERT/UPDATE/DELETE) query directly on the database without any PowerSync processing.
13202
13372
  * This bypasses certain PowerSync abstractions and is useful for accessing the raw database results.
13203
13373
  *
13204
- * @param sql The SQL query to execute
13205
- * @param parameters Optional array of parameters to bind to the query
13374
+ * @param sql - The SQL query to execute
13375
+ * @param parameters - Optional array of parameters to bind to the query
13206
13376
  * @returns The raw query result from the underlying database as a nested array of raw values, where each row is
13207
13377
  * represented as an array of column values without field names.
13208
13378
  */
@@ -13215,8 +13385,8 @@ SELECT * FROM crud_entries;
13215
13385
  * and optionally return results.
13216
13386
  * This is faster than executing separately with each parameter set.
13217
13387
  *
13218
- * @param sql The SQL query to execute
13219
- * @param parameters Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
13388
+ * @param sql - The SQL query to execute
13389
+ * @param parameters - Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
13220
13390
  * @returns The query result
13221
13391
  */
13222
13392
  async executeBatch(sql, parameters) {
@@ -13226,8 +13396,8 @@ SELECT * FROM crud_entries;
13226
13396
  /**
13227
13397
  * Execute a read-only query and return results.
13228
13398
  *
13229
- * @param sql The SQL query to execute
13230
- * @param parameters Optional array of parameters to bind to the query
13399
+ * @param sql - The SQL query to execute
13400
+ * @param parameters - Optional array of parameters to bind to the query
13231
13401
  * @returns An array of results
13232
13402
  */
13233
13403
  async getAll(sql, parameters) {
@@ -13237,8 +13407,8 @@ SELECT * FROM crud_entries;
13237
13407
  /**
13238
13408
  * Execute a read-only query and return the first result, or null if the ResultSet is empty.
13239
13409
  *
13240
- * @param sql The SQL query to execute
13241
- * @param parameters Optional array of parameters to bind to the query
13410
+ * @param sql - The SQL query to execute
13411
+ * @param parameters - Optional array of parameters to bind to the query
13242
13412
  * @returns The first result if found, or null if no results are returned
13243
13413
  */
13244
13414
  async getOptional(sql, parameters) {
@@ -13248,8 +13418,8 @@ SELECT * FROM crud_entries;
13248
13418
  /**
13249
13419
  * Execute a read-only query and return the first result, error if the ResultSet is empty.
13250
13420
  *
13251
- * @param sql The SQL query to execute
13252
- * @param parameters Optional array of parameters to bind to the query
13421
+ * @param sql - The SQL query to execute
13422
+ * @param parameters - Optional array of parameters to bind to the query
13253
13423
  * @returns The first result matching the query
13254
13424
  * @throws Error if no rows are returned
13255
13425
  */
@@ -13259,7 +13429,7 @@ SELECT * FROM crud_entries;
13259
13429
  }
13260
13430
  /**
13261
13431
  * Takes a read lock, without starting a transaction.
13262
- * In most cases, {@link readTransaction} should be used instead.
13432
+ * In most cases, {@link AbstractPowerSyncDatabase.readTransaction} should be used instead.
13263
13433
  */
13264
13434
  async readLock(callback) {
13265
13435
  await this.waitForReady();
@@ -13267,7 +13437,7 @@ SELECT * FROM crud_entries;
13267
13437
  }
13268
13438
  /**
13269
13439
  * Takes a global lock, without starting a transaction.
13270
- * In most cases, {@link writeTransaction} should be used instead.
13440
+ * In most cases, {@link AbstractPowerSyncDatabase.writeTransaction} should be used instead.
13271
13441
  */
13272
13442
  async writeLock(callback) {
13273
13443
  await this.waitForReady();
@@ -13278,8 +13448,8 @@ SELECT * FROM crud_entries;
13278
13448
  * Read transactions can run concurrently to a write transaction.
13279
13449
  * Changes from any write transaction are not visible to read transactions started before it.
13280
13450
  *
13281
- * @param callback Function to execute within the transaction
13282
- * @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
13451
+ * @param callback - Function to execute within the transaction
13452
+ * @param lockTimeout - Time in milliseconds to wait for a lock before throwing an error
13283
13453
  * @returns The result of the callback
13284
13454
  * @throws Error if the lock cannot be obtained within the timeout period
13285
13455
  */
@@ -13296,8 +13466,8 @@ SELECT * FROM crud_entries;
13296
13466
  * This takes a global lock - only one write transaction can execute against the database at a time.
13297
13467
  * Statements within the transaction must be done on the provided {@link Transaction} interface.
13298
13468
  *
13299
- * @param callback Function to execute within the transaction
13300
- * @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
13469
+ * @param callback - Function to execute within the transaction
13470
+ * @param lockTimeout - Time in milliseconds to wait for a lock before throwing an error
13301
13471
  * @returns The result of the callback
13302
13472
  * @throws Error if the lock cannot be obtained within the timeout period
13303
13473
  */
@@ -13374,15 +13544,15 @@ SELECT * FROM crud_entries;
13374
13544
  }
13375
13545
  /**
13376
13546
  * Execute a read query every time the source tables are modified.
13377
- * Use {@link SQLWatchOptions.throttleMs} to specify the minimum interval between queries.
13547
+ * Use {@link SQLOnChangeOptions.throttleMs} to specify the minimum interval between queries.
13378
13548
  * Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
13379
13549
  *
13380
13550
  * Note that the `onChange` callback member of the handler is required.
13381
13551
  *
13382
- * @param sql The SQL query to execute
13383
- * @param parameters Optional array of parameters to bind to the query
13384
- * @param handler Callbacks for handling results and errors
13385
- * @param options Options for configuring watch behavior
13552
+ * @param sql - The SQL query to execute
13553
+ * @param parameters - Optional array of parameters to bind to the query
13554
+ * @param handler - Callbacks for handling results and errors
13555
+ * @param options - Options for configuring watch behavior
13386
13556
  */
13387
13557
  watchWithCallback(sql, parameters, handler, options) {
13388
13558
  const { onResult, onError = (e) => this.logger.error(e) } = handler ?? {};
@@ -13395,7 +13565,7 @@ SELECT * FROM crud_entries;
13395
13565
  const watchedQuery = new OnChangeQueryProcessor({
13396
13566
  db: this,
13397
13567
  comparator,
13398
- placeholderData: null,
13568
+ placeholderData: null, // FIXME
13399
13569
  watchOptions: {
13400
13570
  query: {
13401
13571
  compile: () => ({
@@ -13428,12 +13598,12 @@ SELECT * FROM crud_entries;
13428
13598
  }
13429
13599
  /**
13430
13600
  * Execute a read query every time the source tables are modified.
13431
- * Use {@link SQLWatchOptions.throttleMs} to specify the minimum interval between queries.
13601
+ * Use {@link SQLOnChangeOptions.throttleMs} to specify the minimum interval between queries.
13432
13602
  * Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
13433
13603
  *
13434
- * @param sql The SQL query to execute
13435
- * @param parameters Optional array of parameters to bind to the query
13436
- * @param options Options for configuring watch behavior
13604
+ * @param sql - The SQL query to execute
13605
+ * @param parameters - Optional array of parameters to bind to the query
13606
+ * @param options - Options for configuring watch behavior
13437
13607
  * @returns An AsyncIterable that yields QueryResults whenever the data changes
13438
13608
  */
13439
13609
  watchWithAsyncGenerator(sql, parameters, options) {
@@ -13457,9 +13627,9 @@ SELECT * FROM crud_entries;
13457
13627
  * If tables are specified in the options, those are used directly.
13458
13628
  * Otherwise, analyzes the query using EXPLAIN to determine which tables are accessed.
13459
13629
  *
13460
- * @param sql The SQL query to analyze
13461
- * @param parameters Optional parameters for the SQL query
13462
- * @param options Optional watch options that may contain explicit table list
13630
+ * @param sql - The SQL query to analyze
13631
+ * @param parameters - Optional parameters for the SQL query
13632
+ * @param options - Optional watch options that may contain explicit table list
13463
13633
  * @returns Array of table names that the query depends on
13464
13634
  */
13465
13635
  async resolveTables(sql, parameters, options) {
@@ -13488,13 +13658,13 @@ SELECT * FROM crud_entries;
13488
13658
  /**
13489
13659
  * Invoke the provided callback on any changes to any of the specified tables.
13490
13660
  *
13491
- * This is preferred over {@link watchWithCallback} when multiple queries need to be performed
13661
+ * This is preferred over {@link AbstractPowerSyncDatabase.watchWithCallback} when multiple queries need to be performed
13492
13662
  * together when data is changed.
13493
13663
  *
13494
13664
  * Note that the `onChange` callback member of the handler is required.
13495
13665
  *
13496
- * @param handler Callbacks for handling change events and errors
13497
- * @param options Options for configuring watch behavior
13666
+ * @param handler - Callbacks for handling change events and errors
13667
+ * @param options - Options for configuring watch behavior
13498
13668
  * @returns A dispose function to stop watching for changes
13499
13669
  */
13500
13670
  onChangeWithCallback(handler, options) {
@@ -13537,12 +13707,12 @@ SELECT * FROM crud_entries;
13537
13707
  /**
13538
13708
  * Create a Stream of changes to any of the specified tables.
13539
13709
  *
13540
- * This is preferred over {@link watchWithAsyncGenerator} when multiple queries need to be performed
13541
- * together when data is changed.
13710
+ * This is preferred over {@link AbstractPowerSyncDatabase.watchWithAsyncGenerator} when multiple queries need to be
13711
+ * performed together when data is changed.
13542
13712
  *
13543
13713
  * Note: do not declare this as `async *onChange` as it will not work in React Native.
13544
13714
  *
13545
- * @param options Options for configuring watch behavior
13715
+ * @param options - Options for configuring watch behavior
13546
13716
  * @returns An AsyncIterable that yields change events whenever the specified tables change
13547
13717
  */
13548
13718
  onChangeWithAsyncGenerator(options) {
@@ -13580,15 +13750,15 @@ SELECT * FROM crud_entries;
13580
13750
  changedTables.add(table);
13581
13751
  }
13582
13752
  }
13583
- /**
13584
- * @ignore
13585
- */
13586
13753
  async executeReadOnly(sql, params) {
13587
13754
  await this.waitForReady();
13588
13755
  return this.database.readLock((tx) => tx.execute(sql, params));
13589
13756
  }
13590
13757
  }
13591
13758
 
13759
+ /**
13760
+ * @internal
13761
+ */
13592
13762
  class AbstractPowerSyncDatabaseOpenFactory {
13593
13763
  options;
13594
13764
  constructor(options) {
@@ -13613,6 +13783,9 @@ class AbstractPowerSyncDatabaseOpenFactory {
13613
13783
  }
13614
13784
  }
13615
13785
 
13786
+ /**
13787
+ * @internal
13788
+ */
13616
13789
  function runOnSchemaChange(callback, db, options) {
13617
13790
  const triggerWatchedQuery = () => {
13618
13791
  const abortController = new AbortController();
@@ -13637,6 +13810,9 @@ function runOnSchemaChange(callback, db, options) {
13637
13810
  triggerWatchedQuery();
13638
13811
  }
13639
13812
 
13813
+ /**
13814
+ * @public
13815
+ */
13640
13816
  function compilableQueryWatch(db, query, handler, options) {
13641
13817
  const { onResult, onError = (e) => { } } = handler ?? {};
13642
13818
  if (!onResult) {
@@ -13674,8 +13850,14 @@ function compilableQueryWatch(db, query, handler, options) {
13674
13850
  runOnSchemaChange(watchQuery, db, options);
13675
13851
  }
13676
13852
 
13853
+ /**
13854
+ * @internal
13855
+ */
13677
13856
  const MAX_OP_ID = '9223372036854775807';
13678
13857
 
13858
+ /**
13859
+ * @internal
13860
+ */
13679
13861
  class SqliteBucketStorage extends BaseObserver {
13680
13862
  db;
13681
13863
  logger;
@@ -13836,6 +14018,8 @@ class SqliteBucketStorage extends BaseObserver {
13836
14018
  * Thrown when an underlying database connection is closed.
13837
14019
  * This is particularly relevant when worker connections are marked as closed while
13838
14020
  * operations are still in progress.
14021
+ *
14022
+ * @internal
13839
14023
  */
13840
14024
  class ConnectionClosedError extends Error {
13841
14025
  static NAME = 'ConnectionClosedError';
@@ -13855,6 +14039,8 @@ class ConnectionClosedError extends Error {
13855
14039
 
13856
14040
  /**
13857
14041
  * A schema is a collection of tables. It is used to define the structure of a database.
14042
+ *
14043
+ * @public
13858
14044
  */
13859
14045
  class Schema {
13860
14046
  /*
@@ -13891,7 +14077,7 @@ class Schema {
13891
14077
  * Since raw tables are not backed by JSON, running complex queries on them may be more efficient. Further, they allow
13892
14078
  * using client-side table and column constraints.
13893
14079
  *
13894
- * @param tables An object of (table name, raw table definition) entries.
14080
+ * @param tables - An object of (table name, raw table definition) entries.
13895
14081
  */
13896
14082
  withRawTables(tables) {
13897
14083
  for (const [name, rawTableDefinition] of Object.entries(tables)) {
@@ -13937,6 +14123,8 @@ class Schema {
13937
14123
  Generate a new table from the columns and indexes
13938
14124
  @deprecated You should use {@link Table} instead as it now allows TableV2 syntax.
13939
14125
  This will be removed in the next major release.
14126
+
14127
+ @public
13940
14128
  */
13941
14129
  class TableV2 extends Table {
13942
14130
  }
@@ -13947,6 +14135,8 @@ function sanitizeString(input) {
13947
14135
  /**
13948
14136
  * Helper function for sanitizing UUID input strings.
13949
14137
  * Typically used with {@link sanitizeSQL}.
14138
+ *
14139
+ * @alpha
13950
14140
  */
13951
14141
  function sanitizeUUID(uuid) {
13952
14142
  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;
@@ -13983,6 +14173,8 @@ function sanitizeUUID(uuid) {
13983
14173
  * // Incorrect:
13984
14174
  * sanitizeSQL`New.id = '${myID}'` // Produces double quotes: New.id = ''O''Reilly''
13985
14175
  * ```
14176
+ *
14177
+ * @alpha
13986
14178
  */
13987
14179
  function sanitizeSQL(strings, ...values) {
13988
14180
  let result = '';
@@ -14012,6 +14204,8 @@ function sanitizeSQL(strings, ...values) {
14012
14204
 
14013
14205
  /**
14014
14206
  * Performs a {@link AbstractPowerSyncDatabase.getAll} operation for a watched query.
14207
+ *
14208
+ * @public
14015
14209
  */
14016
14210
  class GetAllQuery {
14017
14211
  options;
@@ -14036,6 +14230,9 @@ class GetAllQuery {
14036
14230
  }
14037
14231
 
14038
14232
  const TypedLogger = Logger;
14233
+ /**
14234
+ * @public
14235
+ */
14039
14236
  const LogLevel = {
14040
14237
  TRACE: TypedLogger.TRACE,
14041
14238
  DEBUG: TypedLogger.DEBUG,
@@ -14052,6 +14249,7 @@ const LogLevel = {
14052
14249
  * across all loggers created with `createLogger`. Adjusting settings on this
14053
14250
  * base logger affects all loggers derived from it unless explicitly overridden.
14054
14251
  *
14252
+ * @public
14055
14253
  */
14056
14254
  function createBaseLogger() {
14057
14255
  return Logger;
@@ -14062,6 +14260,8 @@ function createBaseLogger() {
14062
14260
  * Named loggers allow specific modules or areas of your application to have
14063
14261
  * their own logging levels and behaviors. These loggers inherit configuration
14064
14262
  * from the base logger by default but can override settings independently.
14263
+ *
14264
+ * @public
14065
14265
  */
14066
14266
  function createLogger(name, options = {}) {
14067
14267
  const logger = Logger.get(name);
@@ -14071,6 +14271,9 @@ function createLogger(name, options = {}) {
14071
14271
  return logger;
14072
14272
  }
14073
14273
 
14274
+ /**
14275
+ * @internal
14276
+ */
14074
14277
  const parseQuery = (query, parameters) => {
14075
14278
  let sqlStatement;
14076
14279
  if (typeof query == 'string') {