@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
@@ -1,7 +1,10 @@
1
1
  import { EventIterator } from 'event-iterator';
2
2
  import { Buffer } from 'node:buffer';
3
3
 
4
- // https://www.sqlite.org/lang_expr.html#castexpr
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
- // powersync-sqlite-core limits the number of column per table to 1999, due to internal SQLite limits.
21
- // In earlier versions this was limited to 63.
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
- * @experimental
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
- * @experimental
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
- * @internal
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
- * @internal
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
- * The returned `release` callback must be invoked to return items into the pool.
1037
+ * @param attachment - The attachment record to delete
1038
+ * @param context - Attachment context for database operations
1039
+ * @returns Updated attachment record
944
1040
  */
945
- requestAll(abort) {
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
- return await fn();
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
- finally {
966
- returnMutex();
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
- * Executes a callback with exclusive access to the attachment context.
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 withContext(callback) {
1026
- return this.mutex.runExclusive(async () => {
1027
- return callback(this.context);
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 SqlRunner}.
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.readLock} and
1757
- * {@link ConnectionPool.writeLock}.
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 {boolean} True if connected, false otherwise. Defaults to false if not specified.
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 {boolean} True if connecting, false otherwise. Defaults to false if not specified.
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 {Date | undefined} The timestamp of the last successful sync, or undefined if no sync has completed.
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 {boolean | undefined} True if at least one sync has completed, false if no sync has completed,
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 {SyncDataFlowStatus} An object containing:
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 {SyncPriorityStatus[]} An array of status entries for different sync priority levels,
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 {number} priority The bucket priority for which the status should be reported
2038
- * @returns {SyncPriorityStatus} Status information for the requested priority level or the next higher level with available status
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 {SyncStatus} status The SyncStatus instance to compare against
2060
- * @returns {boolean} True if the instances are considered equal, false otherwise
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 {string} A string representation of the sync status
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 {SyncStatusOptions} A plain object representation of the sync status
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.53.2";
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 = (ev) => {
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
- * {@link Uint8Array}s.
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, the PowerSync SDK will
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 {@link OplogEntry.toJSON}.
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
- * @experimental
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 {@link limit} to specify the maximum number of updates to return in a single
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 SQLWatchOptions.throttleMs} to specify the minimum interval between queries.
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 SQLWatchOptions.throttleMs} to specify the minimum interval between queries.
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 performed
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') {