@powersync/common 1.53.1 → 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 (217) hide show
  1. package/dist/bundle.cjs +560 -353
  2. package/dist/bundle.cjs.map +1 -1
  3. package/dist/bundle.mjs +560 -353
  4. package/dist/bundle.mjs.map +1 -1
  5. package/dist/bundle.node.cjs +560 -353
  6. package/dist/bundle.node.cjs.map +1 -1
  7. package/dist/bundle.node.mjs +560 -353
  8. package/dist/bundle.node.mjs.map +1 -1
  9. package/dist/index.d.cts +733 -198
  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 +61 -14
  68. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +60 -47
  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/async.d.ts +13 -7
  148. package/lib/utils/async.js +38 -24
  149. package/lib/utils/async.js.map +1 -1
  150. package/lib/utils/mutex.d.ts +8 -0
  151. package/lib/utils/mutex.js +3 -0
  152. package/lib/utils/mutex.js.map +1 -1
  153. package/lib/utils/parseQuery.d.ts +6 -0
  154. package/lib/utils/parseQuery.js +3 -0
  155. package/lib/utils/parseQuery.js.map +1 -1
  156. package/lib/utils/stream_transform.d.ts +3 -1
  157. package/lib/utils/stream_transform.js.map +1 -1
  158. package/package.json +3 -2
  159. package/src/attachments/AttachmentContext.ts +7 -6
  160. package/src/attachments/AttachmentErrorHandler.ts +6 -6
  161. package/src/attachments/AttachmentQueue.ts +71 -23
  162. package/src/attachments/LocalStorageAdapter.ts +14 -8
  163. package/src/attachments/README.md +2 -0
  164. package/src/attachments/RemoteStorageAdapter.ts +4 -4
  165. package/src/attachments/Schema.ts +12 -4
  166. package/src/attachments/WatchedAttachmentItem.ts +3 -1
  167. package/src/client/AbstractPowerSyncDatabase.ts +117 -62
  168. package/src/client/AbstractPowerSyncOpenFactory.ts +6 -0
  169. package/src/client/ConnectionManager.ts +4 -1
  170. package/src/client/Query.ts +9 -0
  171. package/src/client/SQLOpenFactory.ts +12 -0
  172. package/src/client/compilableQueryWatch.ts +6 -0
  173. package/src/client/connection/PowerSyncBackendConnector.ts +3 -0
  174. package/src/client/connection/PowerSyncCredentials.ts +3 -0
  175. package/src/client/constants.ts +3 -0
  176. package/src/client/runOnSchemaChange.ts +3 -0
  177. package/src/client/sync/bucket/BucketStorageAdapter.ts +12 -0
  178. package/src/client/sync/bucket/CrudBatch.ts +2 -0
  179. package/src/client/sync/bucket/CrudEntry.ts +9 -0
  180. package/src/client/sync/bucket/CrudTransaction.ts +3 -0
  181. package/src/client/sync/bucket/SqliteBucketStorage.ts +3 -0
  182. package/src/client/sync/stream/AbstractRemote.ts +30 -1
  183. package/src/client/sync/stream/AbstractStreamingSyncImplementation.ts +86 -59
  184. package/src/client/sync/stream/JsonValue.ts +3 -0
  185. package/src/client/sync/stream/WebsocketClientTransport.ts +3 -1
  186. package/src/client/sync/sync-streams.ts +22 -9
  187. package/src/client/triggers/TriggerManager.ts +19 -18
  188. package/src/client/triggers/TriggerManagerImpl.ts +5 -5
  189. package/src/client/triggers/sanitizeSQL.ts +5 -0
  190. package/src/client/watched/GetAllQuery.ts +5 -1
  191. package/src/client/watched/WatchedQuery.ts +24 -2
  192. package/src/client/watched/processors/AbstractQueryProcessor.ts +6 -6
  193. package/src/client/watched/processors/DifferentialQueryProcessor.ts +28 -5
  194. package/src/client/watched/processors/OnChangeQueryProcessor.ts +9 -3
  195. package/src/client/watched/processors/comparators.ts +8 -0
  196. package/src/db/ConnectionClosedError.ts +2 -0
  197. package/src/db/DBAdapter.ts +58 -6
  198. package/src/db/crud/SyncProgress.ts +6 -1
  199. package/src/db/crud/SyncStatus.ts +40 -21
  200. package/src/db/crud/UploadQueueStatus.ts +3 -0
  201. package/src/db/schema/Column.ts +28 -3
  202. package/src/db/schema/Index.ts +9 -0
  203. package/src/db/schema/IndexedColumn.ts +9 -0
  204. package/src/db/schema/RawTable.ts +7 -1
  205. package/src/db/schema/Schema.ts +8 -3
  206. package/src/db/schema/Table.ts +30 -5
  207. package/src/db/schema/TableV2.ts +2 -0
  208. package/src/index.ts +1 -1
  209. package/src/types/types.ts +6 -0
  210. package/src/utils/AbortOperation.ts +2 -0
  211. package/src/utils/BaseObserver.ts +12 -0
  212. package/src/utils/ControlledExecutor.ts +6 -0
  213. package/src/utils/Logger.ts +9 -0
  214. package/src/utils/async.ts +51 -24
  215. package/src/utils/mutex.ts +12 -0
  216. package/src/utils/parseQuery.ts +6 -0
  217. package/src/utils/stream_transform.ts +3 -1
@@ -1,5 +1,8 @@
1
1
  import { AbstractPowerSyncDatabase, SQLWatchOptions } from './AbstractPowerSyncDatabase.js';
2
2
 
3
+ /**
4
+ * @internal
5
+ */
3
6
  export function runOnSchemaChange(
4
7
  callback: (signal: AbortSignal) => void,
5
8
  db: AbstractPowerSyncDatabase,
@@ -2,6 +2,9 @@ import { BaseListener, BaseObserverInterface, Disposable } from '../../../utils/
2
2
  import { CrudBatch } from './CrudBatch.js';
3
3
  import { CrudEntry } from './CrudEntry.js';
4
4
 
5
+ /**
6
+ * @internal
7
+ */
5
8
  export enum PSInternalTable {
6
9
  DATA = 'ps_data',
7
10
  CRUD = 'ps_crud',
@@ -10,6 +13,9 @@ export enum PSInternalTable {
10
13
  UNTYPED = 'ps_untyped'
11
14
  }
12
15
 
16
+ /**
17
+ * @internal
18
+ */
13
19
  export enum PowerSyncControlCommand {
14
20
  PROCESS_TEXT_LINE = 'line_text',
15
21
  PROCESS_BSON_LINE = 'line_binary',
@@ -24,10 +30,16 @@ export enum PowerSyncControlCommand {
24
30
  CONNECTION_STATE = 'connection'
25
31
  }
26
32
 
33
+ /**
34
+ * @internal
35
+ */
27
36
  export interface BucketStorageListener extends BaseListener {
28
37
  crudUpdate: () => void;
29
38
  }
30
39
 
40
+ /**
41
+ * @internal
42
+ */
31
43
  export interface BucketStorageAdapter extends BaseObserverInterface<BucketStorageListener>, Disposable {
32
44
  init(): Promise<void>;
33
45
 
@@ -2,6 +2,8 @@ import { CrudEntry } from './CrudEntry.js';
2
2
 
3
3
  /**
4
4
  * A batch of client-side changes.
5
+ *
6
+ * @public
5
7
  */
6
8
  export class CrudBatch {
7
9
  constructor(
@@ -2,11 +2,15 @@
2
2
  * 64-bit unsigned integer stored as a string in base-10.
3
3
  *
4
4
  * Not sortable as a string.
5
+ *
6
+ * @public
5
7
  */
6
8
  export type OpId = string;
7
9
 
8
10
  /**
9
11
  * Type of local change.
12
+ *
13
+ * @public
10
14
  */
11
15
  export enum UpdateType {
12
16
  /** Insert or replace existing row. All non-null columns are included in the data. Generated by INSERT statements. */
@@ -17,6 +21,9 @@ export enum UpdateType {
17
21
  DELETE = 'DELETE'
18
22
  }
19
23
 
24
+ /**
25
+ * @internal
26
+ */
20
27
  export type CrudEntryJSON = {
21
28
  id: string;
22
29
  data: string;
@@ -48,6 +55,8 @@ type CrudEntryOutputJSON = {
48
55
 
49
56
  /**
50
57
  * A single client-side change.
58
+ *
59
+ * @public
51
60
  */
52
61
  export class CrudEntry {
53
62
  /**
@@ -1,6 +1,9 @@
1
1
  import { CrudBatch } from './CrudBatch.js';
2
2
  import { CrudEntry } from './CrudEntry.js';
3
3
 
4
+ /**
5
+ * @public
6
+ */
4
7
  export class CrudTransaction extends CrudBatch {
5
8
  constructor(
6
9
  /**
@@ -11,6 +11,9 @@ import {
11
11
  import { CrudBatch } from './CrudBatch.js';
12
12
  import { CrudEntry, CrudEntryJSON } from './CrudEntry.js';
13
13
 
14
+ /**
15
+ * @internal
16
+ */
14
17
  export class SqliteBucketStorage extends BaseObserver<BucketStorageListener> implements BucketStorageAdapter {
15
18
  public tableNames: Set<string>;
16
19
  private updateListener: () => void;
@@ -14,6 +14,9 @@ import {
14
14
  import { EventIterator } from 'event-iterator';
15
15
  import type { Queue } from 'event-iterator/lib/event-iterator.js';
16
16
 
17
+ /**
18
+ * @internal
19
+ */
17
20
  export type RemoteConnector = {
18
21
  fetchCredentials: () => Promise<PowerSyncCredentials | null>;
19
22
  invalidateCredentials?: () => void;
@@ -36,8 +39,14 @@ const SOCKET_TIMEOUT_MS = 30_000;
36
39
  // significantly. Therefore this is longer than the socket timeout.
37
40
  const KEEP_ALIVE_LIFETIME_MS = 90_000;
38
41
 
42
+ /**
43
+ * @internal
44
+ */
39
45
  export const DEFAULT_REMOTE_LOGGER = Logger.get('PowerSyncRemote');
40
46
 
47
+ /**
48
+ * @internal
49
+ */
41
50
  export type SyncStreamOptions = {
42
51
  path: string;
43
52
  data: unknown;
@@ -46,6 +55,9 @@ export type SyncStreamOptions = {
46
55
  fetchOptions?: Request;
47
56
  };
48
57
 
58
+ /**
59
+ * @public
60
+ */
49
61
  export enum FetchStrategy {
50
62
  /**
51
63
  * Queues multiple sync events before processing, reducing round-trips.
@@ -60,10 +72,16 @@ export enum FetchStrategy {
60
72
  Sequential = 'sequential'
61
73
  }
62
74
 
75
+ /**
76
+ * @internal
77
+ */
63
78
  export type SocketSyncStreamOptions = SyncStreamOptions & {
64
79
  fetchStrategy: FetchStrategy;
65
80
  };
66
81
 
82
+ /**
83
+ * @internal
84
+ */
67
85
  export type FetchImplementation = typeof fetch;
68
86
 
69
87
  /**
@@ -71,6 +89,8 @@ export type FetchImplementation = typeof fetch;
71
89
  * The class wrapper is used to distinguish the fetchImplementation
72
90
  * option in [AbstractRemoteOptions] from the general fetch method
73
91
  * which is typeof "function"
92
+ *
93
+ * @internal
74
94
  */
75
95
  export class FetchImplementationProvider {
76
96
  getFetch(): FetchImplementation {
@@ -78,6 +98,9 @@ export class FetchImplementationProvider {
78
98
  }
79
99
  }
80
100
 
101
+ /**
102
+ * @internal
103
+ */
81
104
  export type AbstractRemoteOptions = {
82
105
  /**
83
106
  * Transforms the PowerSync base URL which might contain
@@ -102,6 +125,9 @@ export type AbstractRemoteOptions = {
102
125
  fetchOptions?: {};
103
126
  };
104
127
 
128
+ /**
129
+ * @internal
130
+ */
105
131
  export const DEFAULT_REMOTE_OPTIONS: AbstractRemoteOptions = {
106
132
  socketUrlTransformer: (url) =>
107
133
  url.replace(/^https?:\/\//, function (match) {
@@ -111,6 +137,9 @@ export const DEFAULT_REMOTE_OPTIONS: AbstractRemoteOptions = {
111
137
  fetchOptions: {}
112
138
  };
113
139
 
140
+ /**
141
+ * @internal
142
+ */
114
143
  export abstract class AbstractRemote {
115
144
  protected credentials: PowerSyncCredentials | null = null;
116
145
  protected options: AbstractRemoteOptions;
@@ -589,7 +618,7 @@ export abstract class AbstractRemote {
589
618
  * Posts a `/sync/stream` request.
590
619
  *
591
620
  * Depending on the `Content-Type` of the response, this returns strings for sync lines or encoded BSON documents as
592
- * {@link Uint8Array}s.
621
+ * `Uint8Array`s.
593
622
  */
594
623
  async fetchStream(options: SyncStreamOptions): Promise<SimpleAsyncIterator<Uint8Array | string>> {
595
624
  const { isBson, stream } = await this.fetchStreamRaw(options);
@@ -3,7 +3,6 @@ import Logger, { ILogger } from 'js-logger';
3
3
  import { SyncStatus, SyncStatusOptions } from '../../../db/crud/SyncStatus.js';
4
4
  import { AbortOperation } from '../../../utils/AbortOperation.js';
5
5
  import { BaseListener, BaseObserver, BaseObserverInterface, Disposable } from '../../../utils/BaseObserver.js';
6
- import { throttleLeadingTrailing } from '../../../utils/async.js';
7
6
  import { BucketStorageAdapter, PowerSyncControlCommand } from '../bucket/BucketStorageAdapter.js';
8
7
  import { CrudEntry } from '../bucket/CrudEntry.js';
9
8
  import { AbstractRemote, FetchStrategy, SyncStreamOptions } from './AbstractRemote.js';
@@ -17,22 +16,32 @@ import {
17
16
  doneResult,
18
17
  injectable,
19
18
  InjectableIterator,
20
- map,
21
19
  SimpleAsyncIterator,
22
20
  valueResult
23
21
  } from '../../../utils/stream_transform.js';
22
+ import { asyncNotifier } from '../../../utils/async.js';
24
23
  import { StreamingSyncRequestParameterType } from './JsonValue.js';
25
24
 
25
+ /**
26
+ * @internal
27
+ */
26
28
  export enum LockType {
27
29
  CRUD = 'crud',
28
30
  SYNC = 'sync'
29
31
  }
30
32
 
33
+ /**
34
+ * @public
35
+ */
31
36
  export enum SyncStreamConnectionMethod {
32
37
  HTTP = 'http',
33
38
  WEB_SOCKET = 'web-socket'
34
39
  }
35
40
 
41
+ /**
42
+ * @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
43
+ * @public
44
+ */
36
45
  export enum SyncClientImplementation {
37
46
  /**
38
47
  * This implementation offloads the sync line decoding and handling into the PowerSync
@@ -43,8 +52,8 @@ export enum SyncClientImplementation {
43
52
  * ## Compatibility warning
44
53
  *
45
54
  * The Rust sync client stores sync data in a format that is slightly different than the one used
46
- * by the old JavaScript client. When adopting the {@link RUST} client on existing databases, the PowerSync SDK will
47
- * migrate the format automatically.
55
+ * by the old JavaScript client. When adopting the {@link SyncClientImplementation.RUST} client on existing databases,
56
+ * the PowerSync SDK will migrate the format automatically.
48
57
  *
49
58
  * SDK versions supporting both the JavaScript and the Rust client support both formats with the JavaScript client
50
59
  * implementaiton. However, downgrading to an SDK version that only supports the JavaScript client would not be
@@ -55,11 +64,16 @@ export enum SyncClientImplementation {
55
64
 
56
65
  /**
57
66
  * The default {@link SyncClientImplementation} to use, {@link SyncClientImplementation.RUST}.
67
+ *
68
+ * @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
69
+ * @public
58
70
  */
59
71
  export const DEFAULT_SYNC_CLIENT_IMPLEMENTATION = SyncClientImplementation.RUST;
60
72
 
61
73
  /**
62
74
  * Abstract Lock to be implemented by various JS environments
75
+ *
76
+ * @internal
63
77
  */
64
78
  export interface LockOptions<T> {
65
79
  callback: () => Promise<T>;
@@ -67,6 +81,9 @@ export interface LockOptions<T> {
67
81
  signal?: AbortSignal;
68
82
  }
69
83
 
84
+ /**
85
+ * @internal
86
+ */
70
87
  export interface AbstractStreamingSyncImplementationOptions extends RequiredAdditionalConnectionOptions {
71
88
  adapter: BucketStorageAdapter;
72
89
  subscriptions: SubscribedStream[];
@@ -80,6 +97,9 @@ export interface AbstractStreamingSyncImplementationOptions extends RequiredAddi
80
97
  remote: AbstractRemote;
81
98
  }
82
99
 
100
+ /**
101
+ * @internal
102
+ */
83
103
  export interface StreamingSyncImplementationListener extends BaseListener {
84
104
  /**
85
105
  * Triggered whenever a status update has been attempted to be made or
@@ -95,12 +115,17 @@ export interface StreamingSyncImplementationListener extends BaseListener {
95
115
  /**
96
116
  * Configurable options to be used when connecting to the PowerSync
97
117
  * backend instance.
118
+ *
119
+ * @public
98
120
  */
99
121
  export type PowerSyncConnectionOptions = Omit<InternalConnectionOptions, 'serializedSchema'>;
100
122
 
123
+ /**
124
+ * @internal
125
+ */
101
126
  export interface InternalConnectionOptions extends BaseConnectionOptions, AdditionalConnectionOptions {}
102
127
 
103
- /** @internal */
128
+ /** @public */
104
129
  export interface BaseConnectionOptions {
105
130
  /**
106
131
  * A set of metadata to be included in service logs.
@@ -162,6 +187,9 @@ export interface RequiredAdditionalConnectionOptions extends Required<Additional
162
187
  subscriptions: SubscribedStream[];
163
188
  }
164
189
 
190
+ /**
191
+ * @internal
192
+ */
165
193
  export interface StreamingSyncImplementation
166
194
  extends BaseObserverInterface<StreamingSyncImplementationListener>, Disposable {
167
195
  /**
@@ -184,16 +212,31 @@ export interface StreamingSyncImplementation
184
212
  markConnectionMayHaveChanged(): void;
185
213
  }
186
214
 
215
+ /**
216
+ * @internal
217
+ */
187
218
  export const DEFAULT_CRUD_UPLOAD_THROTTLE_MS = 1000;
219
+ /**
220
+ * @internal
221
+ */
188
222
  export const DEFAULT_RETRY_DELAY_MS = 5000;
189
223
 
224
+ /**
225
+ * @internal
226
+ */
190
227
  export const DEFAULT_STREAMING_SYNC_OPTIONS = {
191
228
  retryDelayMs: DEFAULT_RETRY_DELAY_MS,
192
229
  crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
193
230
  };
194
231
 
232
+ /**
233
+ * @internal
234
+ */
195
235
  export type RequiredPowerSyncConnectionOptions = Required<BaseConnectionOptions>;
196
236
 
237
+ /**
238
+ * @internal
239
+ */
197
240
  export const DEFAULT_STREAM_CONNECTION_OPTIONS: RequiredPowerSyncConnectionOptions = {
198
241
  appMetadata: {},
199
242
  connectionMethod: SyncStreamConnectionMethod.WEB_SOCKET,
@@ -204,38 +247,34 @@ export const DEFAULT_STREAM_CONNECTION_OPTIONS: RequiredPowerSyncConnectionOptio
204
247
  includeDefaultStreams: true
205
248
  };
206
249
 
250
+ /**
251
+ * @internal
252
+ */
207
253
  export type SubscribedStream = {
208
254
  name: string;
209
255
  params: Record<string, any> | null;
210
256
  };
211
257
 
212
- // The priority we assume when we receive checkpoint lines where no priority is set.
213
- // This is the default priority used by the sync service, but can be set to an arbitrary
214
- // value since sync services without priorities also won't send partial sync completion
215
- // messages.
216
- const FALLBACK_PRIORITY = 3;
217
-
258
+ /**
259
+ * @internal
260
+ */
218
261
  export abstract class AbstractStreamingSyncImplementation
219
262
  extends BaseObserver<StreamingSyncImplementationListener>
220
263
  implements StreamingSyncImplementation
221
264
  {
222
265
  protected options: AbstractStreamingSyncImplementationOptions;
223
266
  protected abortController: AbortController | null;
224
- // In rare cases, mostly for tests, uploads can be triggered without being properly connected.
225
- // This allows ensuring that all upload processes can be aborted.
226
- protected uploadAbortController: AbortController | undefined;
227
267
  protected crudUpdateListener?: () => void;
228
- protected streamingSyncPromise?: Promise<void>;
268
+ protected streamingSyncPromise?: Promise<[void, void]>;
229
269
  protected logger: ILogger;
230
270
  private activeStreams: SubscribedStream[];
231
271
  private connectionMayHaveChanged = false;
272
+ private crudUploadNotifier = asyncNotifier();
232
273
 
233
- private isUploadingCrud: boolean = false;
234
274
  private notifyCompletedUploads?: () => void;
235
275
  private handleActiveStreamsChange?: () => void;
236
276
 
237
277
  syncStatus: SyncStatus;
238
- triggerCrudUpload: () => void;
239
278
 
240
279
  constructor(options: AbstractStreamingSyncImplementationOptions) {
241
280
  super();
@@ -253,18 +292,10 @@ export abstract class AbstractStreamingSyncImplementation
253
292
  }
254
293
  });
255
294
  this.abortController = null;
295
+ }
256
296
 
257
- this.triggerCrudUpload = throttleLeadingTrailing(() => {
258
- if (!this.syncStatus.connected || this.isUploadingCrud) {
259
- return;
260
- }
261
-
262
- this.isUploadingCrud = true;
263
- this._uploadAllCrud().finally(() => {
264
- this.notifyCompletedUploads?.();
265
- this.isUploadingCrud = false;
266
- });
267
- }, this.options.crudUploadThrottleMs!);
297
+ triggerCrudUpload() {
298
+ this.crudUploadNotifier.notify();
268
299
  }
269
300
 
270
301
  async waitForReady() {}
@@ -320,7 +351,6 @@ export abstract class AbstractStreamingSyncImplementation
320
351
  super.dispose();
321
352
  this.crudUpdateListener?.();
322
353
  this.crudUpdateListener = undefined;
323
- this.uploadAbortController?.abort();
324
354
  }
325
355
 
326
356
  abstract obtainLock<T>(lockOptions: LockOptions<T>): Promise<T>;
@@ -334,7 +364,19 @@ export abstract class AbstractStreamingSyncImplementation
334
364
  return checkpoint;
335
365
  }
336
366
 
337
- protected async _uploadAllCrud(): Promise<void> {
367
+ private async crudUploadLoop(signal: AbortSignal): Promise<void> {
368
+ while (!signal.aborted) {
369
+ await Promise.all([
370
+ // Start the initial CRUD upload on connect. Then, keep polling until we're done.
371
+ this._uploadAllCrud(signal),
372
+ this.delayRetry(signal, this.options.crudUploadThrottleMs!)
373
+ ]);
374
+
375
+ await this.crudUploadNotifier.waitForNotification(signal);
376
+ }
377
+ }
378
+
379
+ private async _uploadAllCrud(signal: AbortSignal): Promise<void> {
338
380
  return this.obtainLock({
339
381
  type: LockType.CRUD,
340
382
  callback: async () => {
@@ -343,17 +385,7 @@ export abstract class AbstractStreamingSyncImplementation
343
385
  */
344
386
  let checkedCrudItem: CrudEntry | undefined;
345
387
 
346
- const controller = new AbortController();
347
- this.uploadAbortController = controller;
348
- this.abortController?.signal.addEventListener(
349
- 'abort',
350
- () => {
351
- controller.abort();
352
- },
353
- { once: true }
354
- );
355
-
356
- while (!controller.signal.aborted) {
388
+ while (!signal.aborted) {
357
389
  try {
358
390
  /**
359
391
  * This is the first item in the FIFO CRUD queue.
@@ -384,7 +416,9 @@ The next upload iteration will be delayed.`);
384
416
  } else {
385
417
  // Uploading is completed
386
418
  const neededUpdate = await this.options.adapter.updateLocalTarget(() => this.getWriteCheckpoint());
387
- if (neededUpdate == false && checkedCrudItem != null) {
419
+ if (neededUpdate) {
420
+ this.notifyCompletedUploads?.();
421
+ } else if (checkedCrudItem != null) {
388
422
  // Only log this if there was something to upload
389
423
  this.logger.debug('Upload complete, no write checkpoint needed.');
390
424
  }
@@ -398,7 +432,7 @@ The next upload iteration will be delayed.`);
398
432
  uploadError: ex as Error
399
433
  }
400
434
  });
401
- await this.delayRetry(controller.signal);
435
+ await this.delayRetry(signal);
402
436
  if (!this.isConnected) {
403
437
  // Exit the upload loop if the sync stream is no longer connected
404
438
  break;
@@ -414,7 +448,6 @@ The next upload iteration will be delayed.`);
414
448
  });
415
449
  }
416
450
  }
417
- this.uploadAbortController = undefined;
418
451
  }
419
452
  });
420
453
  }
@@ -426,7 +459,10 @@ The next upload iteration will be delayed.`);
426
459
 
427
460
  const controller = new AbortController();
428
461
  this.abortController = controller;
429
- this.streamingSyncPromise = this.streamingSync(this.abortController.signal, options);
462
+ this.streamingSyncPromise = Promise.all([
463
+ this.crudUploadLoop(controller.signal).catch((ex) => this.logger.error('Error in crud upload loop', ex)),
464
+ this.streamingSync(controller.signal, options)
465
+ ]);
430
466
 
431
467
  // Return a promise that resolves when the connection status is updated to indicate that we're connected.
432
468
  return new Promise<void>((resolve) => {
@@ -469,15 +505,7 @@ The next upload iteration will be delayed.`);
469
505
  this.updateSyncStatus({ connected: false, connecting: false });
470
506
  }
471
507
 
472
- /**
473
- * @deprecated use [connect instead]
474
- */
475
- async streamingSync(signal?: AbortSignal, options?: PowerSyncConnectionOptions): Promise<void> {
476
- if (!signal) {
477
- this.abortController = new AbortController();
478
- signal = this.abortController.signal;
479
- }
480
-
508
+ private async streamingSync(signal: AbortSignal, options?: PowerSyncConnectionOptions): Promise<void> {
481
509
  /**
482
510
  * Listen for CRUD updates and trigger upstream uploads
483
511
  */
@@ -592,7 +620,7 @@ The next upload iteration will be delayed.`);
592
620
  }
593
621
 
594
622
  /**
595
- * Older versions of the JS SDK used to encode subkeys as JSON in {@link OplogEntry.toJSON}.
623
+ * Older versions of the JS SDK used to encode subkeys as JSON in `OplogEntry.toJSON`.
596
624
  * Because subkeys are always strings, this leads to quotes being added around them in `ps_oplog`.
597
625
  * While this is not a problem as long as it's done consistently, it causes issues when a database
598
626
  * created by the JS SDK is used with other SDKs, or (more likely) when the new Rust sync client
@@ -602,7 +630,7 @@ The next upload iteration will be delayed.`);
602
630
  * migration is only triggered when necessary (for now). The function returns whether the new format
603
631
  * should be used, so that the JS SDK is able to write to updated databases.
604
632
  *
605
- * @param requireFixedKeyFormat Whether we require the new format or also support the old one.
633
+ * @param requireFixedKeyFormat - Whether we require the new format or also support the old one.
606
634
  * The Rust client requires the new subkey format.
607
635
  * @returns Whether the database is now using the new, fixed subkey format.
608
636
  */
@@ -902,14 +930,13 @@ The next upload iteration will be delayed.`);
902
930
  this.iterateListeners((cb) => cb.statusUpdated?.(options));
903
931
  }
904
932
 
905
- private async delayRetry(signal?: AbortSignal): Promise<void> {
933
+ private async delayRetry(signal?: AbortSignal, delay = this.options.retryDelayMs): Promise<void> {
906
934
  return new Promise((resolve) => {
907
935
  if (signal?.aborted) {
908
936
  // If the signal is already aborted, resolve immediately
909
937
  resolve();
910
938
  return;
911
939
  }
912
- const { retryDelayMs } = this.options;
913
940
 
914
941
  let timeoutId: ReturnType<typeof setTimeout> | undefined;
915
942
 
@@ -923,7 +950,7 @@ The next upload iteration will be delayed.`);
923
950
  };
924
951
 
925
952
  signal?.addEventListener('abort', endDelay, { once: true });
926
- timeoutId = setTimeout(endDelay, retryDelayMs);
953
+ timeoutId = setTimeout(endDelay, delay);
927
954
  });
928
955
  }
929
956
 
@@ -5,4 +5,7 @@ interface JSONObject {
5
5
  }
6
6
  type JSONArray = JSONValue[];
7
7
 
8
+ /**
9
+ * @public
10
+ */
8
11
  export type StreamingSyncRequestParameterType = JSONValue;
@@ -42,7 +42,9 @@ export class WebsocketClientTransport implements ClientTransport {
42
42
  resolve(new WebsocketDuplexConnection(websocket, new Deserializer(), multiplexerDemultiplexerFactory));
43
43
  };
44
44
 
45
- const errorListener = (ev: ErrorEvent) => {
45
+ const errorListener = (event: Event) => {
46
+ const ev = event as ErrorEvent;
47
+
46
48
  removeListeners();
47
49
  // We add a default error in that case.
48
50
  if (ev.error != null) {
@@ -1,7 +1,8 @@
1
- import { AbstractPowerSyncDatabase } from '../AbstractPowerSyncDatabase.js';
2
-
3
1
  /**
4
- * A description of a sync stream, consisting of its {@link name} and the {@link parameters} used when subscribing.
2
+ * A description of a sync stream, consisting of its {@link SyncStreamDescription.name} and the
3
+ * {@link SyncStreamDescription.parameters} used when subscribing.
4
+ *
5
+ * @public
5
6
  */
6
7
  export interface SyncStreamDescription {
7
8
  /**
@@ -21,6 +22,8 @@ export interface SyncStreamDescription {
21
22
  * Information about a subscribed sync stream.
22
23
  *
23
24
  * This includes the {@link SyncStreamDescription}, along with information about the current sync status.
25
+ *
26
+ * @public
24
27
  */
25
28
  export interface SyncSubscriptionDescription extends SyncStreamDescription {
26
29
  active: boolean;
@@ -28,15 +31,17 @@ export interface SyncSubscriptionDescription extends SyncStreamDescription {
28
31
  * Whether this stream subscription is included by default, regardless of whether the stream has explicitly been
29
32
  * subscribed to or not.
30
33
  *
31
- * It's possible for both {@link isDefault} and {@link hasExplicitSubscription} to be true at the same time - this
32
- * happens when a default stream was subscribed explicitly.
34
+ * It's possible for both {@link SyncSubscriptionDescription.isDefault} and
35
+ * {@link SyncSubscriptionDescription.hasExplicitSubscription} to be true at the same time - this happens when a
36
+ * default stream was subscribed explicitly.
33
37
  */
34
38
  isDefault: boolean;
35
39
  /**
36
40
  * Whether this stream has been subscribed to explicitly.
37
41
  *
38
- * It's possible for both {@link isDefault} and {@link hasExplicitSubscription} to be true at the same time - this
39
- * happens when a default stream was subscribed explicitly.
42
+ * It's possible for both {@link SyncSubscriptionDescription.isDefault} and
43
+ * {@link SyncSubscriptionDescription.hasExplicitSubscription} to be true at the same time - this happens when a
44
+ * default stream was subscribed explicitly.
40
45
  */
41
46
  hasExplicitSubscription: boolean;
42
47
  /**
@@ -49,11 +54,14 @@ export interface SyncSubscriptionDescription extends SyncStreamDescription {
49
54
  */
50
55
  hasSynced: boolean;
51
56
  /**
52
- * If {@link hasSynced} is true, the last time data from this stream has been synced.
57
+ * If {@link SyncSubscriptionDescription.hasSynced} is true, the last time data from this stream has been synced.
53
58
  */
54
59
  lastSyncedAt: Date | null;
55
60
  }
56
61
 
62
+ /**
63
+ * @public
64
+ */
57
65
  export interface SyncStreamSubscribeOptions {
58
66
  /**
59
67
  * A "time to live" for this stream subscription, in seconds.
@@ -74,6 +82,8 @@ export interface SyncStreamSubscribeOptions {
74
82
  * A handle to a {@link SyncStreamDescription} that allows subscribing to the stream.
75
83
  *
76
84
  * To obtain an instance of {@link SyncStream}, call {@link AbstractPowerSyncDatabase.syncStream}.
85
+ *
86
+ * @public
77
87
  */
78
88
  export interface SyncStream extends SyncStreamDescription {
79
89
  /**
@@ -82,7 +92,7 @@ export interface SyncStream extends SyncStreamDescription {
82
92
  * You should keep a reference to the returned {@link SyncStreamSubscription} object along as you need data for that
83
93
  * stream. As soon as {@link SyncStreamSubscription.unsubscribe} is called for all subscriptions on this stream
84
94
  * (including subscriptions created on other tabs), the {@link SyncStreamSubscribeOptions.ttl} starts ticking and will
85
- * eventually evict the stream (unless {@link subscribe} is called again).
95
+ * eventually evict the stream (unless {@link SyncStream.subscribe} is called again).
86
96
  */
87
97
  subscribe(options?: SyncStreamSubscribeOptions): Promise<SyncStreamSubscription>;
88
98
 
@@ -94,6 +104,9 @@ export interface SyncStream extends SyncStreamDescription {
94
104
  unsubscribeAll(): Promise<void>;
95
105
  }
96
106
 
107
+ /**
108
+ * @public
109
+ */
97
110
  export interface SyncStreamSubscription extends SyncStreamDescription {
98
111
  /**
99
112
  * A promise that resolves once data from in this sync stream has been synced and applied.