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