@powersync/common 0.0.0-dev-20260112083235 → 0.0.0-dev-20260120150240

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.
@@ -6793,6 +6793,16 @@ class DataStream extends BaseObserver {
6793
6793
  * @returns a Data payload or Null if the stream closed.
6794
6794
  */
6795
6795
  async read() {
6796
+ if (this.closed) {
6797
+ return null;
6798
+ }
6799
+ // Wait for any pending processing to complete first.
6800
+ // This ensures we register our listener before calling processQueue(),
6801
+ // avoiding a race where processQueue() sees no reader and returns early.
6802
+ if (this.processingPromise) {
6803
+ await this.processingPromise;
6804
+ }
6805
+ // Re-check after await - stream may have closed while we were waiting
6796
6806
  if (this.closed) {
6797
6807
  return null;
6798
6808
  }
@@ -6832,7 +6842,7 @@ class DataStream extends BaseObserver {
6832
6842
  }
6833
6843
  const promise = (this.processingPromise = this._processQueue());
6834
6844
  promise.finally(() => {
6835
- return (this.processingPromise = null);
6845
+ this.processingPromise = null;
6836
6846
  });
6837
6847
  return promise;
6838
6848
  }
@@ -6864,7 +6874,6 @@ class DataStream extends BaseObserver {
6864
6874
  this.notifyDataAdded = null;
6865
6875
  }
6866
6876
  if (this.dataQueue.length > 0) {
6867
- // Next tick
6868
6877
  setTimeout(() => this.processQueue());
6869
6878
  }
6870
6879
  }
@@ -7484,7 +7493,11 @@ class AbstractRemote {
7484
7493
  };
7485
7494
  const stream = new DataStream({
7486
7495
  logger: this.logger,
7487
- mapLine: mapLine
7496
+ mapLine: mapLine,
7497
+ pressure: {
7498
+ highWaterMark: 20,
7499
+ lowWaterMark: 10
7500
+ }
7488
7501
  });
7489
7502
  abortSignal?.addEventListener('abort', () => {
7490
7503
  closeReader();
@@ -7492,42 +7505,47 @@ class AbstractRemote {
7492
7505
  });
7493
7506
  const decoder = this.createTextDecoder();
7494
7507
  let buffer = '';
7495
- const l = stream.registerListener({
7496
- lowWater: async () => {
7497
- if (stream.closed || abortSignal?.aborted || readerReleased) {
7508
+ const consumeStream = async () => {
7509
+ while (!stream.closed && !abortSignal?.aborted && !readerReleased) {
7510
+ const { done, value } = await reader.read();
7511
+ if (done) {
7512
+ const remaining = buffer.trim();
7513
+ if (remaining.length != 0) {
7514
+ stream.enqueueData(remaining);
7515
+ }
7516
+ stream.close();
7517
+ await closeReader();
7498
7518
  return;
7499
7519
  }
7500
- try {
7501
- let didCompleteLine = false;
7502
- while (!didCompleteLine) {
7503
- const { done, value } = await reader.read();
7504
- if (done) {
7505
- const remaining = buffer.trim();
7506
- if (remaining.length != 0) {
7507
- stream.enqueueData(remaining);
7508
- }
7509
- stream.close();
7510
- await closeReader();
7511
- return;
7512
- }
7513
- const data = decoder.decode(value, { stream: true });
7514
- buffer += data;
7515
- const lines = buffer.split('\n');
7516
- for (var i = 0; i < lines.length - 1; i++) {
7517
- var l = lines[i].trim();
7518
- if (l.length > 0) {
7519
- stream.enqueueData(l);
7520
- didCompleteLine = true;
7521
- }
7522
- }
7523
- buffer = lines[lines.length - 1];
7520
+ const data = decoder.decode(value, { stream: true });
7521
+ buffer += data;
7522
+ const lines = buffer.split('\n');
7523
+ for (var i = 0; i < lines.length - 1; i++) {
7524
+ var l = lines[i].trim();
7525
+ if (l.length > 0) {
7526
+ stream.enqueueData(l);
7524
7527
  }
7525
7528
  }
7526
- catch (ex) {
7527
- stream.close();
7528
- throw ex;
7529
+ buffer = lines[lines.length - 1];
7530
+ // Implement backpressure by waiting for the low water mark to be reached
7531
+ if (stream.dataQueue.length > stream.highWatermark) {
7532
+ await new Promise((resolve) => {
7533
+ const dispose = stream.registerListener({
7534
+ lowWater: async () => {
7535
+ resolve();
7536
+ dispose();
7537
+ },
7538
+ closed: () => {
7539
+ resolve();
7540
+ dispose();
7541
+ }
7542
+ });
7543
+ });
7529
7544
  }
7530
- },
7545
+ }
7546
+ };
7547
+ consumeStream().catch(ex => this.logger.error('Error consuming stream', ex));
7548
+ const l = stream.registerListener({
7531
7549
  closed: () => {
7532
7550
  closeReader();
7533
7551
  l?.();
@@ -10834,6 +10852,7 @@ exports.MAX_OP_ID = MAX_OP_ID;
10834
10852
  exports.OnChangeQueryProcessor = OnChangeQueryProcessor;
10835
10853
  exports.OpType = OpType;
10836
10854
  exports.OplogEntry = OplogEntry;
10855
+ exports.RawTable = RawTable;
10837
10856
  exports.Schema = Schema;
10838
10857
  exports.SqliteBucketStorage = SqliteBucketStorage;
10839
10858
  exports.SyncDataBatch = SyncDataBatch;