@powersync/common 1.22.2 → 1.24.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.
@@ -10,25 +10,18 @@ import { PowerSyncBackendConnector } from './connection/PowerSyncBackendConnecto
10
10
  import { BucketStorageAdapter } from './sync/bucket/BucketStorageAdapter.js';
11
11
  import { CrudBatch } from './sync/bucket/CrudBatch.js';
12
12
  import { CrudTransaction } from './sync/bucket/CrudTransaction.js';
13
- import { PowerSyncConnectionOptions, StreamingSyncImplementation, StreamingSyncImplementationListener } from './sync/stream/AbstractStreamingSyncImplementation.js';
13
+ import { type AdditionalConnectionOptions, type PowerSyncConnectionOptions, StreamingSyncImplementation, StreamingSyncImplementationListener, type RequiredAdditionalConnectionOptions } from './sync/stream/AbstractStreamingSyncImplementation.js';
14
14
  export interface DisconnectAndClearOptions {
15
15
  /** When set to false, data in local-only tables is preserved. */
16
16
  clearLocal?: boolean;
17
17
  }
18
- export interface BasePowerSyncDatabaseOptions {
18
+ export interface BasePowerSyncDatabaseOptions extends AdditionalConnectionOptions {
19
19
  /** Schema used for the local database. */
20
20
  schema: Schema;
21
21
  /**
22
- * Delay for retrying sync streaming operations
23
- * from the PowerSync backend after an error occurs.
22
+ * @deprecated Use {@link retryDelayMs} instead as this will be removed in future releases.
24
23
  */
25
24
  retryDelay?: number;
26
- /**
27
- * Backend Connector CRUD operations are throttled
28
- * to occur at most every `crudUploadThrottleMs`
29
- * milliseconds.
30
- */
31
- crudUploadThrottleMs?: number;
32
25
  logger?: ILogger;
33
26
  }
34
27
  export interface PowerSyncDatabaseOptions extends BasePowerSyncDatabaseOptions {
@@ -89,7 +82,7 @@ export interface PowerSyncCloseOptions {
89
82
  export declare const DEFAULT_POWERSYNC_CLOSE_OPTIONS: PowerSyncCloseOptions;
90
83
  export declare const DEFAULT_WATCH_THROTTLE_MS = 30;
91
84
  export declare const DEFAULT_POWERSYNC_DB_OPTIONS: {
92
- retryDelay: number;
85
+ retryDelayMs: number;
93
86
  logger: Logger.ILogger;
94
87
  crudUploadThrottleMs: number;
95
88
  };
@@ -148,11 +141,12 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
148
141
  * Whether a connection to the PowerSync service is currently open.
149
142
  */
150
143
  get connected(): boolean;
144
+ get connecting(): boolean;
151
145
  /**
152
146
  * Opens the DBAdapter given open options using a default open factory
153
147
  */
154
148
  protected abstract openDBAdapter(options: PowerSyncDatabaseOptionsWithSettings): DBAdapter;
155
- protected abstract generateSyncStreamImplementation(connector: PowerSyncBackendConnector): StreamingSyncImplementation;
149
+ protected abstract generateSyncStreamImplementation(connector: PowerSyncBackendConnector, options: RequiredAdditionalConnectionOptions): StreamingSyncImplementation;
156
150
  protected abstract generateBucketStorageAdapter(): BucketStorageAdapter;
157
151
  /**
158
152
  * @returns A promise which will resolve once initialization is completed.
@@ -185,6 +179,7 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
185
179
  * While initializing is automatic, this helps to catch and report initialization errors.
186
180
  */
187
181
  init(): Promise<void>;
182
+ resolvedConnectionOptions(options?: PowerSyncConnectionOptions): RequiredAdditionalConnectionOptions;
188
183
  /**
189
184
  * Connects to stream of events from the PowerSync instance.
190
185
  */
@@ -13,7 +13,7 @@ import { PSInternalTable } from './sync/bucket/BucketStorageAdapter.js';
13
13
  import { CrudBatch } from './sync/bucket/CrudBatch.js';
14
14
  import { CrudEntry } from './sync/bucket/CrudEntry.js';
15
15
  import { CrudTransaction } from './sync/bucket/CrudTransaction.js';
16
- import { DEFAULT_CRUD_UPLOAD_THROTTLE_MS } from './sync/stream/AbstractStreamingSyncImplementation.js';
16
+ import { DEFAULT_CRUD_UPLOAD_THROTTLE_MS, DEFAULT_RETRY_DELAY_MS } from './sync/stream/AbstractStreamingSyncImplementation.js';
17
17
  import { runOnSchemaChange } from './runOnSchemaChange.js';
18
18
  const POWERSYNC_TABLE_MATCH = /(^ps_data__|^ps_data_local__)/;
19
19
  const DEFAULT_DISCONNECT_CLEAR_OPTIONS = {
@@ -24,7 +24,7 @@ export const DEFAULT_POWERSYNC_CLOSE_OPTIONS = {
24
24
  };
25
25
  export const DEFAULT_WATCH_THROTTLE_MS = 30;
26
26
  export const DEFAULT_POWERSYNC_DB_OPTIONS = {
27
- retryDelay: 5000,
27
+ retryDelayMs: 5000,
28
28
  logger: Logger.get('PowerSyncDatabase'),
29
29
  crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
30
30
  };
@@ -114,6 +114,9 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
114
114
  get connected() {
115
115
  return this.currentStatus?.connected || false;
116
116
  }
117
+ get connecting() {
118
+ return this.currentStatus?.connecting || false;
119
+ }
117
120
  /**
118
121
  * @returns A promise which will resolve once initialization is completed.
119
122
  */
@@ -222,6 +225,13 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
222
225
  async init() {
223
226
  return this.waitForReady();
224
227
  }
228
+ // Use the options passed in during connect, or fallback to the options set during database creation or fallback to the default options
229
+ resolvedConnectionOptions(options) {
230
+ return {
231
+ retryDelayMs: options?.retryDelayMs ?? this.options.retryDelayMs ?? this.options.retryDelay ?? DEFAULT_RETRY_DELAY_MS,
232
+ crudUploadThrottleMs: options?.crudUploadThrottleMs ?? this.options.crudUploadThrottleMs ?? DEFAULT_CRUD_UPLOAD_THROTTLE_MS
233
+ };
234
+ }
225
235
  /**
226
236
  * Connects to stream of events from the PowerSync instance.
227
237
  */
@@ -232,7 +242,11 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
232
242
  if (this.closed) {
233
243
  throw new Error('Cannot connect using a closed client');
234
244
  }
235
- this.syncStreamImplementation = this.generateSyncStreamImplementation(connector);
245
+ const { retryDelayMs, crudUploadThrottleMs } = this.resolvedConnectionOptions(options);
246
+ this.syncStreamImplementation = this.generateSyncStreamImplementation(connector, {
247
+ retryDelayMs,
248
+ crudUploadThrottleMs,
249
+ });
236
250
  this.syncStatusListenerDisposer = this.syncStreamImplementation.registerListener({
237
251
  statusChanged: (status) => {
238
252
  this.currentStatus = new SyncStatus({
@@ -16,6 +16,21 @@ export type SyncStreamOptions = {
16
16
  abortSignal?: AbortSignal;
17
17
  fetchOptions?: Request;
18
18
  };
19
+ export declare enum FetchStrategy {
20
+ /**
21
+ * Queues multiple sync events before processing, reducing round-trips.
22
+ * This comes at the cost of more processing overhead, which may cause ACK timeouts on older/weaker devices for big enough datasets.
23
+ */
24
+ Buffered = "buffered",
25
+ /**
26
+ * Processes each sync event immediately before requesting the next.
27
+ * This reduces processing overhead and improves real-time responsiveness.
28
+ */
29
+ Sequential = "sequential"
30
+ }
31
+ export type SocketSyncStreamOptions = SyncStreamOptions & {
32
+ fetchStrategy: FetchStrategy;
33
+ };
19
34
  export type FetchImplementation = typeof fetch;
20
35
  /**
21
36
  * Class wrapper for providing a fetch implementation.
@@ -72,7 +87,7 @@ export declare abstract class AbstractRemote {
72
87
  /**
73
88
  * Connects to the sync/stream websocket endpoint
74
89
  */
75
- socketStream(options: SyncStreamOptions): Promise<DataStream<StreamingSyncLine>>;
90
+ socketStream(options: SocketSyncStreamOptions): Promise<DataStream<StreamingSyncLine>>;
76
91
  /**
77
92
  * Connects to the sync/stream http endpoint
78
93
  */
@@ -9,13 +9,25 @@ import { version as POWERSYNC_JS_VERSION } from '../../../../package.json';
9
9
  const POWERSYNC_TRAILING_SLASH_MATCH = /\/+$/;
10
10
  // Refresh at least 30 sec before it expires
11
11
  const REFRESH_CREDENTIALS_SAFETY_PERIOD_MS = 30_000;
12
- const SYNC_QUEUE_REQUEST_N = 10;
13
12
  const SYNC_QUEUE_REQUEST_LOW_WATER = 5;
14
13
  // Keep alive message is sent every period
15
14
  const KEEP_ALIVE_MS = 20_000;
16
15
  // The ACK must be received in this period
17
16
  const KEEP_ALIVE_LIFETIME_MS = 30_000;
18
17
  export const DEFAULT_REMOTE_LOGGER = Logger.get('PowerSyncRemote');
18
+ export var FetchStrategy;
19
+ (function (FetchStrategy) {
20
+ /**
21
+ * Queues multiple sync events before processing, reducing round-trips.
22
+ * This comes at the cost of more processing overhead, which may cause ACK timeouts on older/weaker devices for big enough datasets.
23
+ */
24
+ FetchStrategy["Buffered"] = "buffered";
25
+ /**
26
+ * Processes each sync event immediately before requesting the next.
27
+ * This reduces processing overhead and improves real-time responsiveness.
28
+ */
29
+ FetchStrategy["Sequential"] = "sequential";
30
+ })(FetchStrategy || (FetchStrategy = {}));
19
31
  /**
20
32
  * Class wrapper for providing a fetch implementation.
21
33
  * The class wrapper is used to distinguish the fetchImplementation
@@ -144,7 +156,8 @@ export class AbstractRemote {
144
156
  * Connects to the sync/stream websocket endpoint
145
157
  */
146
158
  async socketStream(options) {
147
- const { path } = options;
159
+ const { path, fetchStrategy = FetchStrategy.Buffered } = options;
160
+ const syncQueueRequestSize = fetchStrategy == FetchStrategy.Buffered ? 10 : 1;
148
161
  const request = await this.buildRequest(path);
149
162
  const bson = await this.getBSON();
150
163
  // Add the user agent in the setup payload - we can't set custom
@@ -197,7 +210,7 @@ export class AbstractRemote {
197
210
  // Helps to prevent double close scenarios
198
211
  rsocket.onClose(() => (socketIsClosed = true));
199
212
  // We initially request this amount and expect these to arrive eventually
200
- let pendingEventsCount = SYNC_QUEUE_REQUEST_N;
213
+ let pendingEventsCount = syncQueueRequestSize;
201
214
  const disposeClosedListener = stream.registerListener({
202
215
  closed: () => {
203
216
  closeSocket();
@@ -211,7 +224,7 @@ export class AbstractRemote {
211
224
  metadata: Buffer.from(bson.serialize({
212
225
  path
213
226
  }))
214
- }, SYNC_QUEUE_REQUEST_N, // The initial N amount
227
+ }, syncQueueRequestSize, // The initial N amount
215
228
  {
216
229
  onError: (e) => {
217
230
  // Don't log closed as an error
@@ -250,10 +263,10 @@ export class AbstractRemote {
250
263
  const l = stream.registerListener({
251
264
  lowWater: async () => {
252
265
  // Request to fill up the queue
253
- const required = SYNC_QUEUE_REQUEST_N - pendingEventsCount;
266
+ const required = syncQueueRequestSize - pendingEventsCount;
254
267
  if (required > 0) {
255
- socket.request(SYNC_QUEUE_REQUEST_N - pendingEventsCount);
256
- pendingEventsCount = SYNC_QUEUE_REQUEST_N;
268
+ socket.request(syncQueueRequestSize - pendingEventsCount);
269
+ pendingEventsCount = syncQueueRequestSize;
257
270
  }
258
271
  },
259
272
  closed: () => {
@@ -2,7 +2,7 @@ import Logger, { ILogger } from 'js-logger';
2
2
  import { SyncStatus, SyncStatusOptions } from '../../../db/crud/SyncStatus.js';
3
3
  import { BaseListener, BaseObserver, Disposable } from '../../../utils/BaseObserver.js';
4
4
  import { BucketStorageAdapter } from '../bucket/BucketStorageAdapter.js';
5
- import { AbstractRemote } from './AbstractRemote.js';
5
+ import { AbstractRemote, FetchStrategy } from './AbstractRemote.js';
6
6
  import { StreamingSyncRequestParameterType } from './streaming-sync-types.js';
7
7
  export declare enum LockType {
8
8
  CRUD = "crud",
@@ -20,10 +20,9 @@ export interface LockOptions<T> {
20
20
  type: LockType;
21
21
  signal?: AbortSignal;
22
22
  }
23
- export interface AbstractStreamingSyncImplementationOptions {
23
+ export interface AbstractStreamingSyncImplementationOptions extends AdditionalConnectionOptions {
24
24
  adapter: BucketStorageAdapter;
25
25
  uploadCrud: () => Promise<void>;
26
- crudUploadThrottleMs?: number;
27
26
  /**
28
27
  * An identifier for which PowerSync DB this sync implementation is
29
28
  * linked to. Most commonly DB name, but not restricted to DB name.
@@ -31,7 +30,6 @@ export interface AbstractStreamingSyncImplementationOptions {
31
30
  identifier?: string;
32
31
  logger?: ILogger;
33
32
  remote: AbstractRemote;
34
- retryDelayMs?: number;
35
33
  }
36
34
  export interface StreamingSyncImplementationListener extends BaseListener {
37
35
  /**
@@ -48,18 +46,41 @@ export interface StreamingSyncImplementationListener extends BaseListener {
48
46
  * Configurable options to be used when connecting to the PowerSync
49
47
  * backend instance.
50
48
  */
51
- export interface PowerSyncConnectionOptions {
49
+ export interface PowerSyncConnectionOptions extends BaseConnectionOptions, AdditionalConnectionOptions {
50
+ }
51
+ /** @internal */
52
+ export interface BaseConnectionOptions {
52
53
  /**
53
54
  * The connection method to use when streaming updates from
54
55
  * the PowerSync backend instance.
55
56
  * Defaults to a HTTP streaming connection.
56
57
  */
57
58
  connectionMethod?: SyncStreamConnectionMethod;
59
+ /**
60
+ * The fetch strategy to use when streaming updates from the PowerSync backend instance.
61
+ */
62
+ fetchStrategy?: FetchStrategy;
58
63
  /**
59
64
  * These parameters are passed to the sync rules, and will be available under the`user_parameters` object.
60
65
  */
61
66
  params?: Record<string, StreamingSyncRequestParameterType>;
62
67
  }
68
+ /** @internal */
69
+ export interface AdditionalConnectionOptions {
70
+ /**
71
+ * Delay for retrying sync streaming operations
72
+ * from the PowerSync backend after an error occurs.
73
+ */
74
+ retryDelayMs?: number;
75
+ /**
76
+ * Backend Connector CRUD operations are throttled
77
+ * to occur at most every `crudUploadThrottleMs`
78
+ * milliseconds.
79
+ */
80
+ crudUploadThrottleMs?: number;
81
+ }
82
+ /** @internal */
83
+ export type RequiredAdditionalConnectionOptions = Required<AdditionalConnectionOptions>;
63
84
  export interface StreamingSyncImplementation extends BaseObserver<StreamingSyncImplementationListener>, Disposable {
64
85
  /**
65
86
  * Connects to the sync service
@@ -80,12 +101,14 @@ export interface StreamingSyncImplementation extends BaseObserver<StreamingSyncI
80
101
  waitForStatus(status: SyncStatusOptions): Promise<void>;
81
102
  }
82
103
  export declare const DEFAULT_CRUD_UPLOAD_THROTTLE_MS = 1000;
104
+ export declare const DEFAULT_RETRY_DELAY_MS = 5000;
83
105
  export declare const DEFAULT_STREAMING_SYNC_OPTIONS: {
84
106
  retryDelayMs: number;
85
107
  logger: Logger.ILogger;
86
108
  crudUploadThrottleMs: number;
87
109
  };
88
- export declare const DEFAULT_STREAM_CONNECTION_OPTIONS: Required<PowerSyncConnectionOptions>;
110
+ export type RequiredPowerSyncConnectionOptions = Required<BaseConnectionOptions>;
111
+ export declare const DEFAULT_STREAM_CONNECTION_OPTIONS: RequiredPowerSyncConnectionOptions;
89
112
  export declare abstract class AbstractStreamingSyncImplementation extends BaseObserver<StreamingSyncImplementationListener> implements StreamingSyncImplementation {
90
113
  protected _lastSyncedAt: Date | null;
91
114
  protected options: AbstractStreamingSyncImplementationOptions;
@@ -4,6 +4,7 @@ import { AbortOperation } from '../../../utils/AbortOperation.js';
4
4
  import { BaseObserver } from '../../../utils/BaseObserver.js';
5
5
  import { throttleLeadingTrailing } from '../../../utils/throttle.js';
6
6
  import { SyncDataBucket } from '../bucket/SyncDataBucket.js';
7
+ import { FetchStrategy } from './AbstractRemote.js';
7
8
  import { isStreamingKeepalive, isStreamingSyncCheckpoint, isStreamingSyncCheckpointComplete, isStreamingSyncCheckpointDiff, isStreamingSyncData } from './streaming-sync-types.js';
8
9
  export var LockType;
9
10
  (function (LockType) {
@@ -16,13 +17,15 @@ export var SyncStreamConnectionMethod;
16
17
  SyncStreamConnectionMethod["WEB_SOCKET"] = "web-socket";
17
18
  })(SyncStreamConnectionMethod || (SyncStreamConnectionMethod = {}));
18
19
  export const DEFAULT_CRUD_UPLOAD_THROTTLE_MS = 1000;
20
+ export const DEFAULT_RETRY_DELAY_MS = 5000;
19
21
  export const DEFAULT_STREAMING_SYNC_OPTIONS = {
20
- retryDelayMs: 5000,
22
+ retryDelayMs: DEFAULT_RETRY_DELAY_MS,
21
23
  logger: Logger.get('PowerSyncStream'),
22
24
  crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
23
25
  };
24
26
  export const DEFAULT_STREAM_CONNECTION_OPTIONS = {
25
27
  connectionMethod: SyncStreamConnectionMethod.WEB_SOCKET,
28
+ fetchStrategy: FetchStrategy.Buffered,
26
29
  params: {}
27
30
  };
28
31
  export class AbstractStreamingSyncImplementation extends BaseObserver {
@@ -38,6 +41,7 @@ export class AbstractStreamingSyncImplementation extends BaseObserver {
38
41
  this.options = { ...DEFAULT_STREAMING_SYNC_OPTIONS, ...options };
39
42
  this.syncStatus = new SyncStatus({
40
43
  connected: false,
44
+ connecting: false,
41
45
  lastSyncedAt: undefined,
42
46
  dataFlow: {
43
47
  uploading: false,
@@ -207,7 +211,7 @@ The next upload iteration will be delayed.`);
207
211
  }
208
212
  this.streamingSyncPromise = undefined;
209
213
  this.abortController = null;
210
- this.updateSyncStatus({ connected: false });
214
+ this.updateSyncStatus({ connected: false, connecting: false });
211
215
  }
212
216
  /**
213
217
  * @deprecated use [connect instead]
@@ -238,6 +242,7 @@ The next upload iteration will be delayed.`);
238
242
  this.crudUpdateListener = undefined;
239
243
  this.updateSyncStatus({
240
244
  connected: false,
245
+ connecting: false,
241
246
  dataFlow: {
242
247
  downloading: false
243
248
  }
@@ -250,6 +255,7 @@ The next upload iteration will be delayed.`);
250
255
  * - Close any sync stream ReadableStreams (which will also close any established network requests)
251
256
  */
252
257
  while (true) {
258
+ this.updateSyncStatus({ connecting: true });
253
259
  try {
254
260
  if (signal?.aborted) {
255
261
  break;
@@ -280,6 +286,7 @@ The next upload iteration will be delayed.`);
280
286
  else {
281
287
  this.logger.error(ex);
282
288
  }
289
+ // On error, wait a little before retrying
283
290
  await this.delayRetry();
284
291
  }
285
292
  finally {
@@ -288,13 +295,13 @@ The next upload iteration will be delayed.`);
288
295
  nestedAbortController = new AbortController();
289
296
  }
290
297
  this.updateSyncStatus({
291
- connected: false
298
+ connected: false,
299
+ connecting: true // May be unnecessary
292
300
  });
293
- // On error, wait a little before retrying
294
301
  }
295
302
  }
296
303
  // Mark as disconnected if here
297
- this.updateSyncStatus({ connected: false });
304
+ this.updateSyncStatus({ connected: false, connecting: false });
298
305
  }
299
306
  async streamingSyncIteration(signal, options) {
300
307
  return await this.obtainLock({
@@ -334,9 +341,16 @@ The next upload iteration will be delayed.`);
334
341
  client_id: clientId
335
342
  }
336
343
  };
337
- const stream = resolvedOptions?.connectionMethod == SyncStreamConnectionMethod.HTTP
338
- ? await this.options.remote.postStream(syncOptions)
339
- : await this.options.remote.socketStream(syncOptions);
344
+ let stream;
345
+ if (resolvedOptions?.connectionMethod == SyncStreamConnectionMethod.HTTP) {
346
+ stream = await this.options.remote.postStream(syncOptions);
347
+ }
348
+ else {
349
+ stream = await this.options.remote.socketStream({
350
+ ...syncOptions,
351
+ ...{ fetchStrategy: resolvedOptions.fetchStrategy }
352
+ });
353
+ }
340
354
  this.logger.debug('Stream established. Processing events');
341
355
  while (!stream.closed) {
342
356
  const line = await stream.read();
@@ -489,6 +503,7 @@ The next upload iteration will be delayed.`);
489
503
  updateSyncStatus(options) {
490
504
  const updatedStatus = new SyncStatus({
491
505
  connected: options.connected ?? this.syncStatus.connected,
506
+ connecting: !options.connected && (options.connecting ?? this.syncStatus.connecting),
492
507
  lastSyncedAt: options.lastSyncedAt ?? this.syncStatus.lastSyncedAt,
493
508
  dataFlow: {
494
509
  ...this.syncStatus.dataFlowStatus,
@@ -4,6 +4,7 @@ export type SyncDataFlowStatus = Partial<{
4
4
  }>;
5
5
  export type SyncStatusOptions = {
6
6
  connected?: boolean;
7
+ connecting?: boolean;
7
8
  dataFlow?: SyncDataFlowStatus;
8
9
  lastSyncedAt?: Date;
9
10
  hasSynced?: boolean;
@@ -15,6 +16,7 @@ export declare class SyncStatus {
15
16
  * true if currently connected.
16
17
  */
17
18
  get connected(): boolean;
19
+ get connecting(): boolean;
18
20
  /**
19
21
  * Time that a last sync has fully completed, if any.
20
22
  * Currently this is reset to null after a restart.
@@ -9,6 +9,9 @@ export class SyncStatus {
9
9
  get connected() {
10
10
  return this.options.connected ?? false;
11
11
  }
12
+ get connecting() {
13
+ return this.options.connecting ?? false;
14
+ }
12
15
  /**
13
16
  * Time that a last sync has fully completed, if any.
14
17
  * Currently this is reset to null after a restart.
@@ -44,11 +47,12 @@ export class SyncStatus {
44
47
  }
45
48
  getMessage() {
46
49
  const dataFlow = this.dataFlowStatus;
47
- return `SyncStatus<connected: ${this.connected} lastSyncedAt: ${this.lastSyncedAt} hasSynced: ${this.hasSynced}. Downloading: ${dataFlow.downloading}. Uploading: ${dataFlow.uploading}`;
50
+ return `SyncStatus<connected: ${this.connected} connecting: ${this.connecting} lastSyncedAt: ${this.lastSyncedAt} hasSynced: ${this.hasSynced}. Downloading: ${dataFlow.downloading}. Uploading: ${dataFlow.uploading}`;
48
51
  }
49
52
  toJSON() {
50
53
  return {
51
54
  connected: this.connected,
55
+ connecting: this.connecting,
52
56
  dataFlow: this.dataFlowStatus,
53
57
  lastSyncedAt: this.lastSyncedAt,
54
58
  hasSynced: this.hasSynced
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powersync/common",
3
- "version": "1.22.2",
3
+ "version": "1.24.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"